diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.ps1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.ps1 new file mode 100644 index 00000000..861a3bc6 --- /dev/null +++ b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.ps1 @@ -0,0 +1,750 @@ +# +# Add-AppxDevPackage.ps1 is a PowerShell script designed to install app +# packages created by Visual Studio for developers. To run this script from +# Explorer, right-click on its icon and choose "Run with PowerShell". +# +# Visual Studio supplies this script in the folder generated with its +# "Prepare Package" command. The same folder will also contain the app +# package (a .appx file), the signing certificate (a .cer file), and a +# "Dependencies" subfolder containing all the framework packages used by the +# app. +# +# This script simplifies installing these packages by automating the +# following functions: +# 1. Find the app package and signing certificate in the script directory +# 2. Prompt the user to acquire a developer license and to install the +# certificate if necessary +# 3. Find dependency packages that are applicable to the operating system's +# CPU architecture +# 4. Install the package along with all applicable dependencies +# +# All command line parameters are reserved for use internally by the script. +# Users should launch this script from Explorer. +# + +# .Link +# http://go.microsoft.com/fwlink/?LinkId=243053 + +param( + [switch]$Force = $false, + [switch]$GetDeveloperLicense = $false, + [string]$CertificatePath = $null +) + +$ErrorActionPreference = "Stop" + +# The language resources for this script are placed in the +# "Add-AppDevPackage.resources" subfolder alongside the script. Since the +# current working directory might not be the directory that contains the +# script, we need to create the full path of the resources directory to +# pass into Import-LocalizedData +$ScriptPath = $null +try +{ + $ScriptPath = (Get-Variable MyInvocation).Value.MyCommand.Path + $ScriptDir = Split-Path -Parent $ScriptPath +} +catch {} + +if (!$ScriptPath) +{ + PrintMessageAndExit $UiStrings.ErrorNoScriptPath $ErrorCodes.NoScriptPath +} + +$LocalizedResourcePath = Join-Path $ScriptDir "Add-AppDevPackage.resources" +Import-LocalizedData -BindingVariable UiStrings -BaseDirectory $LocalizedResourcePath + +$ErrorCodes = Data { + ConvertFrom-StringData @' + Success = 0 + NoScriptPath = 1 + NoPackageFound = 2 + ManyPackagesFound = 3 + NoCertificateFound = 4 + ManyCertificatesFound = 5 + BadCertificate = 6 + PackageUnsigned = 7 + CertificateMismatch = 8 + ForceElevate = 9 + LaunchAdminFailed = 10 + GetDeveloperLicenseFailed = 11 + InstallCertificateFailed = 12 + AddPackageFailed = 13 + ForceDeveloperLicense = 14 + CertUtilInstallFailed = 17 + CertIsCA = 18 + BannedEKU = 19 + NoBasicConstraints = 20 + NoCodeSigningEku = 21 + InstallCertificateCancelled = 22 + BannedKeyUsage = 23 + ExpiredCertificate = 24 +'@ +} + +function PrintMessageAndExit($ErrorMessage, $ReturnCode) +{ + Write-Host $ErrorMessage + if (!$Force) + { + Pause + } + exit $ReturnCode +} + +# +# Warns the user about installing certificates, and presents a Yes/No prompt +# to confirm the action. The default is set to No. +# +function ConfirmCertificateInstall +{ + $Answer = $host.UI.PromptForChoice( + "", + $UiStrings.WarningInstallCert, + [System.Management.Automation.Host.ChoiceDescription[]]@($UiStrings.PromptYesString, $UiStrings.PromptNoString), + 1) + + return $Answer -eq 0 +} + +# +# Validates whether a file is a valid certificate using CertUtil. +# This needs to be done before calling Get-PfxCertificate on the file, otherwise +# the user will get a cryptic "Password: " prompt for invalid certs. +# +function ValidateCertificateFormat($FilePath) +{ + # certutil -verify prints a lot of text that we don't need, so it's redirected to $null here + certutil.exe -verify $FilePath > $null + if ($LastExitCode -lt 0) + { + PrintMessageAndExit ($UiStrings.ErrorBadCertificate -f $FilePath, $LastExitCode) $ErrorCodes.BadCertificate + } + + # Check if certificate is expired + $cert = Get-PfxCertificate $FilePath + if (($cert.NotBefore -gt (Get-Date)) -or ($cert.NotAfter -lt (Get-Date))) + { + PrintMessageAndExit ($UiStrings.ErrorExpiredCertificate -f $FilePath) $ErrorCodes.ExpiredCertificate + } +} + +# +# Verify that the developer certificate meets the following restrictions: +# - The certificate must contain a Basic Constraints extension, and its +# Certificate Authority (CA) property must be false. +# - The certificate's Key Usage extension must be either absent, or set to +# only DigitalSignature. +# - The certificate must contain an Extended Key Usage (EKU) extension with +# Code Signing usage. +# - The certificate must NOT contain any other EKU except Code Signing and +# Lifetime Signing. +# +# These restrictions are enforced to decrease security risks that arise from +# trusting digital certificates. +# +function CheckCertificateRestrictions +{ + Set-Variable -Name BasicConstraintsExtensionOid -Value "2.5.29.19" -Option Constant + Set-Variable -Name KeyUsageExtensionOid -Value "2.5.29.15" -Option Constant + Set-Variable -Name EkuExtensionOid -Value "2.5.29.37" -Option Constant + Set-Variable -Name CodeSigningEkuOid -Value "1.3.6.1.5.5.7.3.3" -Option Constant + Set-Variable -Name LifetimeSigningEkuOid -Value "1.3.6.1.4.1.311.10.3.13" -Option Constant + + $CertificateExtensions = (Get-PfxCertificate $CertificatePath).Extensions + $HasBasicConstraints = $false + $HasCodeSigningEku = $false + + foreach ($Extension in $CertificateExtensions) + { + # Certificate must contain the Basic Constraints extension + if ($Extension.oid.value -eq $BasicConstraintsExtensionOid) + { + # CA property must be false + if ($Extension.CertificateAuthority) + { + PrintMessageAndExit $UiStrings.ErrorCertIsCA $ErrorCodes.CertIsCA + } + $HasBasicConstraints = $true + } + + # If key usage is present, it must be set to digital signature + elseif ($Extension.oid.value -eq $KeyUsageExtensionOid) + { + if ($Extension.KeyUsages -ne "DigitalSignature") + { + PrintMessageAndExit ($UiStrings.ErrorBannedKeyUsage -f $Extension.KeyUsages) $ErrorCodes.BannedKeyUsage + } + } + + elseif ($Extension.oid.value -eq $EkuExtensionOid) + { + # Certificate must contain the Code Signing EKU + $EKUs = $Extension.EnhancedKeyUsages.Value + if ($EKUs -contains $CodeSigningEkuOid) + { + $HasCodeSigningEKU = $True + } + + # EKUs other than code signing and lifetime signing are not allowed + foreach ($EKU in $EKUs) + { + if ($EKU -ne $CodeSigningEkuOid -and $EKU -ne $LifetimeSigningEkuOid) + { + PrintMessageAndExit ($UiStrings.ErrorBannedEKU -f $EKU) $ErrorCodes.BannedEKU + } + } + } + } + + if (!$HasBasicConstraints) + { + PrintMessageAndExit $UiStrings.ErrorNoBasicConstraints $ErrorCodes.NoBasicConstraints + } + if (!$HasCodeSigningEKU) + { + PrintMessageAndExit $UiStrings.ErrorNoCodeSigningEku $ErrorCodes.NoCodeSigningEku + } +} + +# +# Performs operations that require administrative privileges: +# - Prompt the user to obtain a developer license +# - Install the developer certificate (if -Force is not specified, also prompts the user to confirm) +# +function DoElevatedOperations +{ + if ($GetDeveloperLicense) + { + Write-Host $UiStrings.GettingDeveloperLicense + + if ($Force) + { + PrintMessageAndExit $UiStrings.ErrorForceDeveloperLicense $ErrorCodes.ForceDeveloperLicense + } + try + { + Show-WindowsDeveloperLicenseRegistration + } + catch + { + $Error[0] # Dump details about the last error + PrintMessageAndExit $UiStrings.ErrorGetDeveloperLicenseFailed $ErrorCodes.GetDeveloperLicenseFailed + } + } + + if ($CertificatePath) + { + Write-Host $UiStrings.InstallingCertificate + + # Make sure certificate format is valid and usage constraints are followed + ValidateCertificateFormat $CertificatePath + CheckCertificateRestrictions + + # If -Force is not specified, warn the user and get consent + if ($Force -or (ConfirmCertificateInstall)) + { + # Add cert to store + certutil.exe -addstore TrustedPeople $CertificatePath + if ($LastExitCode -lt 0) + { + PrintMessageAndExit ($UiStrings.ErrorCertUtilInstallFailed -f $LastExitCode) $ErrorCodes.CertUtilInstallFailed + } + } + else + { + PrintMessageAndExit $UiStrings.ErrorInstallCertificateCancelled $ErrorCodes.InstallCertificateCancelled + } + } +} + +# +# Checks whether the machine is missing a valid developer license. +# +function CheckIfNeedDeveloperLicense +{ + $Result = $true + try + { + $Result = (Get-WindowsDeveloperLicense | Where-Object { $_.IsValid } | Measure-Object).Count -eq 0 + } + catch {} + + return $Result +} + +# +# Launches an elevated process running the current script to perform tasks +# that require administrative privileges. This function waits until the +# elevated process terminates, and checks whether those tasks were successful. +# +function LaunchElevated +{ + # Set up command line arguments to the elevated process + $RelaunchArgs = '-ExecutionPolicy Unrestricted -file "' + $ScriptPath + '"' + + if ($Force) + { + $RelaunchArgs += ' -Force' + } + if ($NeedDeveloperLicense) + { + $RelaunchArgs += ' -GetDeveloperLicense' + } + if ($NeedInstallCertificate) + { + $RelaunchArgs += ' -CertificatePath "' + $DeveloperCertificatePath.FullName + '"' + } + + # Launch the process and wait for it to finish + try + { + $AdminProcess = Start-Process "$PsHome\PowerShell.exe" -Verb RunAs -ArgumentList $RelaunchArgs -PassThru + } + catch + { + $Error[0] # Dump details about the last error + PrintMessageAndExit $UiStrings.ErrorLaunchAdminFailed $ErrorCodes.LaunchAdminFailed + } + + while (!($AdminProcess.HasExited)) + { + Start-Sleep -Seconds 2 + } + + # Check if all elevated operations were successful + if ($NeedDeveloperLicense) + { + if (CheckIfNeedDeveloperLicense) + { + PrintMessageAndExit $UiStrings.ErrorGetDeveloperLicenseFailed $ErrorCodes.GetDeveloperLicenseFailed + } + else + { + Write-Host $UiStrings.AcquireLicenseSuccessful + } + } + if ($NeedInstallCertificate) + { + $Signature = Get-AuthenticodeSignature $DeveloperPackagePath -Verbose + if ($Signature.Status -ne "Valid") + { + PrintMessageAndExit ($UiStrings.ErrorInstallCertificateFailed -f $Signature.Status) $ErrorCodes.InstallCertificateFailed + } + else + { + Write-Host $UiStrings.InstallCertificateSuccessful + } + } +} + +# +# Finds all applicable dependency packages according to OS architecture, and +# installs the developer package with its dependencies. The expected layout +# of dependencies is: +# +# +# \Dependencies +# .appx +# \x86 +# .appx +# \x64 +# .appx +# \arm +# .appx +# +function InstallPackageWithDependencies +{ + $DependencyPackagesDir = (Join-Path $ScriptDir "Dependencies") + $DependencyPackages = @() + if (Test-Path $DependencyPackagesDir) + { + # Get architecture-neutral dependencies + $DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "*.appx") | Where-Object { $_.Mode -NotMatch "d" } + + # Get architecture-specific dependencies + if (($Env:Processor_Architecture -eq "x86" -or $Env:Processor_Architecture -eq "amd64") -and (Test-Path (Join-Path $DependencyPackagesDir "x86"))) + { + $DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x86\*.appx") | Where-Object { $_.Mode -NotMatch "d" } + } + if (($Env:Processor_Architecture -eq "amd64") -and (Test-Path (Join-Path $DependencyPackagesDir "x64"))) + { + $DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x64\*.appx") | Where-Object { $_.Mode -NotMatch "d" } + } + if (($Env:Processor_Architecture -eq "arm") -and (Test-Path (Join-Path $DependencyPackagesDir "arm"))) + { + $DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "arm\*.appx") | Where-Object { $_.Mode -NotMatch "d" } + } + } + Write-Host $UiStrings.InstallingPackage + + $AddPackageSucceeded = $False + try + { + if ($DependencyPackages.FullName.Count -gt 0) + { + Write-Host $UiStrings.DependenciesFound + $DependencyPackages.FullName + Add-AppxPackage -Path $DeveloperPackagePath.FullName -DependencyPath $DependencyPackages.FullName -ForceApplicationShutdown + } + else + { + Add-AppxPackage -Path $DeveloperPackagePath.FullName -ForceApplicationShutdown + } + $AddPackageSucceeded = $? + } + catch + { + $Error[0] # Dump details about the last error + } + + if (!$AddPackageSucceeded) + { + if ($NeedInstallCertificate) + { + PrintMessageAndExit $UiStrings.ErrorAddPackageFailedWithCert $ErrorCodes.AddPackageFailed + } + else + { + PrintMessageAndExit $UiStrings.ErrorAddPackageFailed $ErrorCodes.AddPackageFailed + } + } +} + +# +# Main script logic when the user launches the script without parameters. +# +function DoStandardOperations +{ + # List all .appx files in the script directory + $PackagePath = Get-ChildItem (Join-Path $ScriptDir "*.appx") | Where-Object { $_.Mode -NotMatch "d" } + $PackageCount = ($PackagePath | Measure-Object).Count + + # List all .appxbundle files in the script directory + $BundlePath = Get-ChildItem (Join-Path $ScriptDir "*.appxbundle") | Where-Object { $_.Mode -NotMatch "d" } + $BundleCount = ($BundlePath | Measure-Object).Count + + # List all .eappx files in the script directory + $EncryptedPackagePath = Get-ChildItem (Join-Path $ScriptDir "*.eappx") | Where-Object { $_.Mode -NotMatch "d" } + $EncryptedPackageCount = ($EncryptedPackagePath | Measure-Object).Count + + # List all .eappxbundle files in the script directory + $EncryptedBundlePath = Get-ChildItem (Join-Path $ScriptDir "*.eappxbundle") | Where-Object { $_.Mode -NotMatch "d" } + $EncryptedBundleCount = ($EncryptedBundlePath | Measure-Object).Count + + $NumberOfPackagesAndBundles = $PackageCount + $BundleCount + $EncryptedPackageCount + $EncryptedBundleCount + + # There must be exactly 1 package/bundle + if ($NumberOfPackagesAndBundles -lt 1) + { + PrintMessageAndExit $UiStrings.ErrorNoPackageFound $ErrorCodes.NoPackageFound + } + elseif ($NumberOfPackagesAndBundles -gt 1) + { + PrintMessageAndExit $UiStrings.ErrorManyPackagesFound $ErrorCodes.ManyPackagesFound + } + + if ($PackageCount -eq 1) + { + $DeveloperPackagePath = $PackagePath + Write-Host ($UiStrings.PackageFound -f $DeveloperPackagePath.FullName) + } + elseif ($BundleCount -eq 1) + { + $DeveloperPackagePath = $BundlePath + Write-Host ($UiStrings.BundleFound -f $DeveloperPackagePath.FullName) + } + elseif ($EncryptedPackageCount -eq 1) + { + $DeveloperPackagePath = $EncryptedPackagePath + Write-Host ($UiStrings.EncryptedPackageFound -f $DeveloperPackagePath.FullName) + } + elseif ($EncryptedBundleCount -eq 1) + { + $DeveloperPackagePath = $EncryptedBundlePath + Write-Host ($UiStrings.EncryptedBundleFound -f $DeveloperPackagePath.FullName) + } + + # The package must be signed + $PackageSignature = Get-AuthenticodeSignature $DeveloperPackagePath + $PackageCertificate = $PackageSignature.SignerCertificate + if (!$PackageCertificate) + { + PrintMessageAndExit $UiStrings.ErrorPackageUnsigned $ErrorCodes.PackageUnsigned + } + + # Test if the package signature is trusted. If not, the corresponding certificate + # needs to be present in the current directory and needs to be installed. + $NeedInstallCertificate = ($PackageSignature.Status -ne "Valid") + + if ($NeedInstallCertificate) + { + # List all .cer files in the script directory + $DeveloperCertificatePath = Get-ChildItem (Join-Path $ScriptDir "*.cer") | Where-Object { $_.Mode -NotMatch "d" } + $DeveloperCertificateCount = ($DeveloperCertificatePath | Measure-Object).Count + + # There must be exactly 1 certificate + if ($DeveloperCertificateCount -lt 1) + { + PrintMessageAndExit $UiStrings.ErrorNoCertificateFound $ErrorCodes.NoCertificateFound + } + elseif ($DeveloperCertificateCount -gt 1) + { + PrintMessageAndExit $UiStrings.ErrorManyCertificatesFound $ErrorCodes.ManyCertificatesFound + } + + Write-Host ($UiStrings.CertificateFound -f $DeveloperCertificatePath.FullName) + + # The .cer file must have the format of a valid certificate + ValidateCertificateFormat $DeveloperCertificatePath + + # The package signature must match the certificate file + if ($PackageCertificate -ne (Get-PfxCertificate $DeveloperCertificatePath)) + { + PrintMessageAndExit $UiStrings.ErrorCertificateMismatch $ErrorCodes.CertificateMismatch + } + } + + $NeedDeveloperLicense = CheckIfNeedDeveloperLicense + + # Relaunch the script elevated with the necessary parameters if needed + if ($NeedDeveloperLicense -or $NeedInstallCertificate) + { + Write-Host $UiStrings.ElevateActions + if ($NeedDeveloperLicense) + { + Write-Host $UiStrings.ElevateActionDevLicense + } + if ($NeedInstallCertificate) + { + Write-Host $UiStrings.ElevateActionCertificate + } + + $IsAlreadyElevated = ([Security.Principal.WindowsIdentity]::GetCurrent().Groups.Value -contains "S-1-5-32-544") + if ($IsAlreadyElevated) + { + if ($Force -and $NeedDeveloperLicense) + { + PrintMessageAndExit $UiStrings.ErrorForceDeveloperLicense $ErrorCodes.ForceDeveloperLicense + } + if ($Force -and $NeedInstallCertificate) + { + Write-Warning $UiStrings.WarningInstallCert + } + } + else + { + if ($Force) + { + PrintMessageAndExit $UiStrings.ErrorForceElevate $ErrorCodes.ForceElevate + } + else + { + Write-Host $UiStrings.ElevateActionsContinue + Pause + } + } + + LaunchElevated + } + + InstallPackageWithDependencies +} + +# +# Main script entry point +# +if ($GetDeveloperLicense -or $CertificatePath) +{ + DoElevatedOperations +} +else +{ + DoStandardOperations + PrintMessageAndExit $UiStrings.Success $ErrorCodes.Success +} + +# SIG # Begin signature block +# MIIiBQYJKoZIhvcNAQcCoIIh9jCCIfICAQExDzANBglghkgBZQMEAgEFADB5Bgor +# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG +# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAnYmBUpv/sjF9s +# UpSJeaz8bsgho4m0HYf/wsPXcJL9raCCC4QwggUMMIID9KADAgECAhMzAAABT+fG +# YslG9Kl/AAAAAAFPMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD +# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy +# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p +# bmcgUENBIDIwMTAwHhcNMTYxMTE3MjE1OTE0WhcNMTgwMjE3MjE1OTE0WjCBgzEL +# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v +# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9Q +# UjEeMBwGA1UEAxMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMIIBIjANBgkqhkiG9w0B +# AQEFAAOCAQ8AMIIBCgKCAQEAtImQinYMrMU9obyB6NdQCLtaaaeux8y4W704DyFR +# Rggj0b0imXO3KO/3B6sr+Uj3pRQFqU0kG21hlpyDnTPALHmZ8F3z7NVE36XNWfp2 +# rQY/xkoD5uotlBDCZm/9YtBQitEikSOXZTShxJoCXpLiuHwoeMJe40b3yu84V4is +# VgZYypgbx6jXXjaumkUw47a3PRjCpyeweU1T2DLmdqNQKvY/urtBHiSGTZibep72 +# LOK8kGBl+5Zp+uATaOKJKi51GJ3Cbbgh9JleKn8xoKcNzO9PEW7+SUJOYd43yyue +# QO/Oq15wCHOlcnu3Rs5bMlNdijlRb7DXqHjdoyhvXu5CHwIDAQABo4IBezCCAXcw +# HwYDVR0lBBgwFgYKKwYBBAGCNz0GAQYIKwYBBQUHAwMwHQYDVR0OBBYEFJIOoRFx +# ti9VDcMP9MlcdC5aDGq/MFIGA1UdEQRLMEmkRzBFMQ0wCwYDVQQLEwRNT1BSMTQw +# MgYDVQQFEysyMzA4NjUrYjRiMTI4NzgtZTI5My00M2U5LWIyMWUtN2QzMDcxOWQ0 +# NTJmMB8GA1UdIwQYMBaAFOb8X3u7IgBY5HJOtfQhdCMy5u+sMFYGA1UdHwRPME0w +# S6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3Rz +# L01pY0NvZFNpZ1BDQV8yMDEwLTA3LTA2LmNybDBaBggrBgEFBQcBAQROMEwwSgYI +# KwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWlj +# Q29kU2lnUENBXzIwMTAtMDctMDYuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN +# AQELBQADggEBABHAuWpDNf6FsTiADbh0dSyNcUm4PEHtLb3iBjaQdiuJ5baB6Ybj +# GIyWkzJCp6f2tzQlOdDGekPq23dwzNTpQuuoxVUCdXie2BC+BxvKlGP7PA9x7tRV +# Z9cp9mq/B7zlj4Lq+KHiczM/FJJeobplVzdFhYBc1izGizxqh6MHEcvs2XE4IDUk +# PVS9zFWJ9HcQm+WZqg+uxjyOn9oAT8994bPAIPdSMfciSNVhjX8mAhl9g8xhkyrd +# uNziCLOn3+EEd2DI9Kw1yzHlbHVRxTd7E2pOlWuPQJ7ITT6uvVnFINbCeK23ZFs7 +# 0MAVcDQU5cWephzH9P/2y0jB4o3zbs6qtKAwggZwMIIEWKADAgECAgphDFJMAAAA +# AAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz +# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv +# cnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBB +# dXRob3JpdHkgMjAxMDAeFw0xMDA3MDYyMDQwMTdaFw0yNTA3MDYyMDUwMTdaMH4x +# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt +# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p +# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTAwggEiMA0GCSqGSIb3DQEBAQUA +# A4IBDwAwggEKAoIBAQDpDmRQeWe1xOP9CQBMnpSs91Zo6kTYz8VYT6mldnxtRbrT +# OZK0pB75+WWC5BfSj/1EnAjoZZPOLFWEv30I4y4rqEErGLeiS25JTGsVB97R0sKJ +# HnGUzbV/S7SvCNjMiNZrF5Q6k84mP+zm/jSYV9UdXUn2siou1YW7WT/4kLQrg3TK +# K7M7RuPwRknBF2ZUyRy9HcRVYldy+Ge5JSA03l2mpZVeqyiAzdWynuUDtWPTshTI +# wciKJgpZfwfs/w7tgBI1TBKmvlJb9aba4IsLSHfWhUfVELnG6Krui2otBVxgxrQq +# W5wjHF9F4xoUHm83yxkzgGqJTaNqZmN4k9Uwz5UfAgMBAAGjggHjMIIB3zAQBgkr +# BgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU5vxfe7siAFjkck619CF0IzLm76wwGQYJ +# KwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +# MAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8w +# TTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVj +# dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBK +# BggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9N +# aWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwgZ0GA1UdIASBlTCBkjCBjwYJKwYB +# BAGCNy4DMIGBMD0GCCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v +# UEtJL2RvY3MvQ1BTL2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBn +# AGEAbABfAFAAbwBsAGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqG +# SIb3DQEBCwUAA4ICAQAadO9XTyl7xBaFeLhQ0yL8CZ2sgpf4NP8qLJeVEuXkv8+/ +# k8jjNKnbgbjcHgC+0jVvr+V/eZV35QLU8evYzU4eG2GiwlojGvCMqGJRRWcI4z88 +# HpP4MIUXyDlAptcOsyEp5aWhaYwik8x0mOehR0PyU6zADzBpf/7SJSBtb2HT3wfV +# 2XIALGmGdj1R26Y5SMk3YW0H3VMZy6fWYcK/4oOrD+Brm5XWfShRsIlKUaSabMi3 +# H0oaDmmp19zBftFJcKq2rbtyR2MX+qbWoqaG7KgQRJtjtrJpiQbHRoZ6GD/oxR0h +# 1Xv5AiMtxUHLvx1MyBbvsZx//CJLSYpuFeOmf3Zb0VN5kYWd1dLbPXM18zyuVLJS +# R2rAqhOV0o4R2plnXjKM+zeF0dx1hZyHxlpXhcK/3Q2PjJst67TuzyfTtV5p+qQW +# BAGnJGdzz01Ptt4FVpd69+lSTfR3BU+FxtgL8Y7tQgnRDXbjI1Z4IiY2vsqxjG6q +# HeSF2kczYo+kyZEzX3EeQK+YZcki6EIhJYocLWDZN4lBiSoWD9dhPJRoYFLv1keZ +# oIBA7hWBdz6c4FMYGlAdOJWbHmYzEyc5F3iHNs5Ow1+y9T1HU7bg5dsLYT0q15Is +# zjdaPkBCMaQfEAjCVpy/JF1RAp1qedIX09rBlI4HeyVxRKsGaubUxt8jmpZ1xTGC +# FdcwghXTAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u +# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp +# b24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTACEzMA +# AAFP58ZiyUb0qX8AAAAAAU8wDQYJYIZIAWUDBAIBBQCggcIwGQYJKoZIhvcNAQkD +# MQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJ +# KoZIhvcNAQkEMSIEIM6sGgl9EI3BKHGPaKRgrF1O/bVv8y7tQZuqLVzy8rFiMFYG +# CisGAQQBgjcCAQwxSDBGoCyAKgBBAGQAZAAtAEEAcABwAEQAZQB2AFAAYQBjAGsA +# YQBnAGUALgBwAHMAMaEWgBRodHRwOi8vbWljcm9zb2Z0LmNvbTANBgkqhkiG9w0B +# AQEFAASCAQB+h3AYSy8MV5bb3ZfjI9xGXZgMGVKhmRo9yYG3wIelD9RULoRtCN4J +# ScCz++xjjxhUEdJ57ZeRdobQGnjEKyepHccHJsnxiFXUqd8gHWN56LxVKXLK6lgH +# RnSmMm63Z/s6/qA7XdgHKjUGqG0MsZgFiX0DBfVQUQnPPPgkicc2xwWI1G4ZTDVn +# Qoi9zUNb1bvJJhcN1BlPcvKVrVOqBLLfsSDsYGMmLcrh0v9QkMPBefLexqGxoibs +# fvzJiwiCSRTRiC29aUrAP3s6EazYYP866d7F94qZfF5Qy8fy3RnnjErxD1PpgEVx +# EZus2pc23sNrQzNokH1A7q3beEKTKal8oYITTTCCE0kGCisGAQQBgjcDAwExghM5 +# MIITNQYJKoZIhvcNAQcCoIITJjCCEyICAQMxDzANBglghkgBZQMEAgEFADCCAT0G +# CyqGSIb3DQEJEAEEoIIBLASCASgwggEkAgEBBgorBgEEAYRZCgMBMDEwDQYJYIZI +# AWUDBAIBBQAEIJPdm/WIYp5J5+KJJMbxhHziKQ+l8HJ9bF3jCZXkxTgaAgZY1UYJ +# UwIYEzIwMTcwNDIwMDAzMzU5LjY0NFowBwIBAYACAfSggbmkgbYwgbMxCzAJBgNV +# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w +# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xDTALBgNVBAsTBE1PUFIxJzAl +# BgNVBAsTHm5DaXBoZXIgRFNFIEVTTjpCOEVDLTMwQTQtNzE0NDElMCMGA1UEAxMc +# TWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCDtAwggZxMIIEWaADAgECAgph +# CYEqAAAAAAACMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE +# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z +# b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZp +# Y2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0yNTA3MDEyMTQ2 +# NTVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH +# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV +# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjANBgkqhkiG9w0B +# AQEFAAOCAQ8AMIIBCgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RUENWlCgCChfvt +# fGhLLF/Fw+Vhwna3PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBED/FgiIRUQwzX +# Tbg4CLNC3ZOs1nMwVyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50YWeRX4FUsc+T +# TJLBxKZd0WETbijGGvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd/XcfPfBXday9 +# ikJNQFHRD5wGPmd/9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaRtogINeh4HLDp +# mc085y9Euqf03GS9pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQABo4IB5jCCAeIw +# EAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8RhvFM2hahW1V +# MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMB +# Af8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1Ud +# HwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3By +# b2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQRO +# MEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2Vy +# dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSABAf8EgZUwgZIw +# gY8GCSsGAQQBgjcuAzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3dy5taWNyb3Nv +# ZnQuY29tL1BLSS9kb2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEFBQcCAjA0HjIg +# HQBMAGUAZwBhAGwAXwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBtAGUAbgB0AC4g +# HTANBgkqhkiG9w0BAQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Ehb7Prpsz1Mb7P +# BeKp/vpXbRkws8LFZslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7uVOMzPRgEop2 +# zEBAQZvcXBf/XPleFzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqRUgCvOA8X9S95 +# gWXZqbVr5MfO9sp6AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9Va8v/rbljjO7 +# Yl+a21dA6fHOmWaQjP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8+n99lmqQeKZt +# 0uGc+R38ONiU9MalCpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+Y1klD3ouOVd2 +# onGqBooPiRa6YacRy5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh2rBQHm+98eEA +# 3+cxB6STOvdlR3jo+KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRyzR30uIUBHoD7 +# G4kqVDmyW9rIDVWZeodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoouLGp25ayp0Ki +# yc8ZQU3ghvkqmqMRZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx16HSxVXjad5X +# wdHeMMD9zOZN+w2/XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341Hgi62jbb01+P +# 3nSISRIwggTaMIIDwqADAgECAhMzAAAAn2fytagjBlt7AAAAAACfMA0GCSqGSIb3 +# DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD +# VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAk +# BgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTE2MDkwNzE3 +# NTY0N1oXDTE4MDkwNzE3NTY0N1owgbMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX +# YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg +# Q29ycG9yYXRpb24xDTALBgNVBAsTBE1PUFIxJzAlBgNVBAsTHm5DaXBoZXIgRFNF +# IEVTTjpCOEVDLTMwQTQtNzE0NDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3Rh +# bXAgU2VydmljZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALkI8SOc +# 3cQCLwKFoaMnl2T5A5wSVD9Tglq4Put9bhjFcsEn1XApDPCWS9aPhMcWOWKe+7EN +# I4Si4zD30nVQC9PZ0NDu+pK9XV83OfjGchFkKzOBRddOhpsQkxFgMF3RfLTNXAEq +# ffnNaReXwtVUkiGEJvW6KmABixzP0aeUVmJ6MHnJnmo+TKZdoVl7cg6TY6LCoze/ +# F6rhOXmi/P3X/K3jHtmAaxL9Ou53jjDgO5Rjxt6ZEamdEsGF2SWZ6wH6Dmg9G6iZ +# Pxgw+mjODwReL6jwh7H2XhsvzoFMrSERMzIIf2eJGAM9C0GR0BZHyRti17QqL5Ta +# CuWPjMxTKXX4DlkCAwEAAaOCARswggEXMB0GA1UdDgQWBBT9ixsiw30jR3amHt/g +# ZtRS6bb5oDAfBgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8E +# TzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9k +# dWN0cy9NaWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBM +# MEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRz +# L01pY1RpbVN0YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1Ud +# JQQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBlEMFsa88VHq8PSDbr +# 3y0LvAAA5pFmGlCWZbkxD2WMqfF0y8fnlvgb874z8sz8QZzByCmY1jHyHTc98Zek +# z7L2Y5SANUIa8jyU36c64Ck5fY6Pe9hUA1RG/1zP+eq080chUPCF2zezhfwuz9Ob +# 0obO64BwW0GZgYYz1hjsq+DBkSCBRV59ryFpzgKRwhWF8quXtHDpimiJx+ds2VZS +# wEVk/QRY7pLuUvedN8P5DNuLaaRw3oJcs2Wxh2jWS5T8Y3JevUo3K3VTtHPi2IBW +# ISkEG7TOnNEUcUXDMGSOeZ27kuPFzKkDVbtzvwEVepkGrsZ1W+1xuDYPQ1b3BMG8 +# C79HoYIDeTCCAmECAQEwgeOhgbmkgbYwgbMxCzAJBgNVBAYTAlVTMRMwEQYDVQQI +# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv +# ZnQgQ29ycG9yYXRpb24xDTALBgNVBAsTBE1PUFIxJzAlBgNVBAsTHm5DaXBoZXIg +# RFNFIEVTTjpCOEVDLTMwQTQtNzE0NDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt +# U3RhbXAgU2VydmljZaIlCgEBMAkGBSsOAwIaBQADFQBs0ycI8vnZqMv5Gd6SS0qt +# 2xmjwaCBwjCBv6SBvDCBuTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0 +# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh +# dGlvbjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBOVFMgRVNOOjU3 +# RjYtQzFFMC01NTRDMSswKQYDVQQDEyJNaWNyb3NvZnQgVGltZSBTb3VyY2UgTWFz +# dGVyIENsb2NrMA0GCSqGSIb3DQEBBQUAAgUA3KJ+BDAiGA8yMDE3MDQyMDAwMjMz +# MloYDzIwMTcwNDIxMDAyMzMyWjB3MD0GCisGAQQBhFkKBAExLzAtMAoCBQDcon4E +# AgEAMAoCAQACAgIpAgH/MAcCAQACAhpTMAoCBQDco8+EAgEAMDYGCisGAQQBhFkK +# BAIxKDAmMAwGCisGAQQBhFkKAwGgCjAIAgEAAgMW42ChCjAIAgEAAgMHoSAwDQYJ +# KoZIhvcNAQEFBQADggEBAMNu8xSY3BVCszbhzYVReDYtQq5osuZNWMIQG3z0VMBy +# 2CesXSvJhJ3FRfaH8T1oXKkKtpMKWzYRvoSN2QFLxsrja3QAWFpK+L2tc3SZn0Fh +# oAbA3wrGX+PPZc+7KCe1011rLLU3jpU5p8WyXhoLNc0YpGT3Rf50P+J4mK0NCOQt +# weBieStXSi7fvfxd7AyOnd/Sl/qVXaVWc7RWrHOxwyb3VMgFwPy73WWELCmHmtDa +# zmZE+kX8uwFCweFCTZraxXf/QCZ6S6qxWsUbmgL3og4DWk3KHUFLaXUAJCbYLkv2 +# 9/K2km3/D/pMnEuA97lLPkaTmS2qjPZ6OIwsefeQSvsxggL1MIIC8QIBATCBkzB8 +# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk +# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N +# aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAJ9n8rWoIwZbewAAAAAA +# nzANBglghkgBZQMEAgEFAKCCATIwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEE +# MC8GCSqGSIb3DQEJBDEiBCDOKIBEM8xfNhB0LPgIdV4IVpvEHSpJJY1OElQEf/7o +# 8TCB4gYLKoZIhvcNAQkQAgwxgdIwgc8wgcwwgbEEFGzTJwjy+dmoy/kZ3pJLSq3b +# GaPBMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x +# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv +# bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAACf +# Z/K1qCMGW3sAAAAAAJ8wFgQUuddYY/HPCoksb/xOBDjdPXlDGMEwDQYJKoZIhvcN +# AQELBQAEggEAO+i4nAivWpc98DvCdqDpFvPa1+YQ+w4w59An08W8QDzLFvr4nDLz +# SdXYQKnWFQaSI6qf81pe2tHfc4uehs/nbfFRK9CiVi321Ao7B31szkLCLWnClG7l +# Ar+FQv0vFx6cIe2fOZeobsm1GDsiAroe6MGz3wAM4LzuZ3FkO1i9K1RlrBrN+28C +# bjXmHksJHQNMBcGOLbRDrmpfrc6ijKjheepQekxBxfboGc0B57MM+LRIL2GC8mdn +# Q6Iv/mcJnYW1pjLzlnRRqW32fjjKa/iygkVsU+aNrj3XxLU4GyDsV5NWBLl5LJ7z +# dd+w7o1/PK5+wn4z52qQvpLt6luLRdHq9Q== +# SIG # End signature block diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..89c0d417 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/cs-CZ/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/cs-CZ/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..6de68269 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/cs-CZ/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/de-DE/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/de-DE/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..7f8ea728 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/de-DE/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/en-US/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/en-US/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..89c0d417 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/en-US/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/es-ES/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/es-ES/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..25f74983 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/es-ES/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/fr-FR/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/fr-FR/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..8ccf86c7 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/fr-FR/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/it-IT/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/it-IT/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..fbfe178a Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/it-IT/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/ja-JP/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/ja-JP/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..9ccfe666 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/ja-JP/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/ko-KR/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/ko-KR/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..de73c344 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/ko-KR/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/pl-PL/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/pl-PL/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..f73c27b0 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/pl-PL/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/pt-BR/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/pt-BR/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..4abe47c9 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/pt-BR/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/ru-RU/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/ru-RU/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..138c448b Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/ru-RU/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/tr-TR/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/tr-TR/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..4cfe1a8a Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/tr-TR/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/zh-CN/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/zh-CN/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..88c08a20 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/zh-CN/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/zh-TW/Add-AppDevPackage.psd1 b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/zh-TW/Add-AppDevPackage.psd1 new file mode 100644 index 00000000..717ed258 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/Add-AppDevPackage.resources/zh-TW/Add-AppDevPackage.psd1 differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/KiwixWebApp_0.7.5.0_AnyCPU.appxbundle b/AppPackages/KiwixWebApp_0.7.5.0_Test/KiwixWebApp_0.7.5.0_AnyCPU.appxbundle new file mode 100644 index 00000000..05b00d36 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/KiwixWebApp_0.7.5.0_AnyCPU.appxbundle differ diff --git a/AppPackages/KiwixWebApp_0.7.5.0_Test/KiwixWebApp_0.7.5.0_AnyCPU.cer b/AppPackages/KiwixWebApp_0.7.5.0_Test/KiwixWebApp_0.7.5.0_AnyCPU.cer new file mode 100644 index 00000000..8cafb5e4 Binary files /dev/null and b/AppPackages/KiwixWebApp_0.7.5.0_Test/KiwixWebApp_0.7.5.0_AnyCPU.cer differ diff --git a/BundleArtifacts/neutral.txt b/BundleArtifacts/neutral.txt index f5f789ef..451895dd 100644 --- a/BundleArtifacts/neutral.txt +++ b/BundleArtifacts/neutral.txt @@ -1,5 +1,5 @@ -MainPackage=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.4.0_AnyCPU.appx -ResourcePack=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.4.0_scale-100.appx -ResourcePack=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.4.0_scale-125.appx -ResourcePack=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.4.0_scale-150.appx -ResourcePack=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.4.0_scale-400.appx +MainPackage=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.5.0_AnyCPU.appx +ResourcePack=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.5.0_scale-100.appx +ResourcePack=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.5.0_scale-125.appx +ResourcePack=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.5.0_scale-150.appx +ResourcePack=C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\KiwixWebApp_0.7.5.0_scale-400.appx diff --git a/bin/Release/AppX/vs.appxrecipe b/bin/Release/AppX/vs.appxrecipe index eeeb86b8..ecd56752 100644 --- a/bin/Release/AppX/vs.appxrecipe +++ b/bin/Release/AppX/vs.appxrecipe @@ -32,7 +32,7 @@ AppxManifest.xml true - 2017-07-19T09:49:40.605 + 2017-07-19T16:00:03.995 @@ -407,7 +407,7 @@ www\js\app.js - 2017-07-19T09:49:27.424 + 2017-07-19T10:03:17.883 www\js\init.js @@ -443,7 +443,7 @@ www\js\lib\uiUtil.js - 2017-07-19T09:47:28.173 + 2017-07-19T10:03:58.143 www\js\lib\utf8.js diff --git a/bin/Release/AppX/www/js/app.js b/bin/Release/AppX/www/js/app.js index 7df2a4db..4a144cd4 100644 --- a/bin/Release/AppX/www/js/app.js +++ b/bin/Release/AppX/www/js/app.js @@ -783,11 +783,11 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles // This matches the href of all tags containing rel="stylesheet" in raw HTML var regexpSheetHref = /(]*rel\s*=\s*["']stylesheet)[^>]*href\s*=\s*["'])([^"']+)(["'][^>]*>)/ig; // This matches the title between ... - var regexpArticleTitle = /]*>\s*([^<]+)\s*]*>\s*([^<]+)\s* Title - var regexpType1ZIMTitle = /]*>\s*([^<]+)\s*]*>\s*([^<]+)\s*]*>\s*([^<]+)\s*]*>\s*([^<]+)\s*<< Return to ' + title + ''; + '$(\'#liAboutNav\').attr(\'class\', \'\');"><< Return to ' + shortTitle + ''; document.getElementById("returntoArticle_top").innerHTML = link; document.getElementById("returntoArticle_bottom").innerHTML = link; } function poll(msg) { - window.document.getElementById("progressMessage").innerHTML += '

' + msg + '

'; + document.getElementById("progressMessage").innerHTML += '

' + msg + '

'; } - function clear(msg) { - window.document.getElementById("progressMessage").innerHTML = "

"; + function clear() { + document.getElementById("progressMessage").innerHTML = "

"; } /** diff --git a/bin/Release/AppxManifest.xml b/bin/Release/AppxManifest.xml index 0c4b4cd2..9474fc55 100644 --- a/bin/Release/AppxManifest.xml +++ b/bin/Release/AppxManifest.xml @@ -7,7 +7,7 @@ For more information on package manifest files, see http://go.microsoft.com/fwlink/?LinkID=241727 --> - + Kiwix JS diff --git a/bin/Release/ForBundle/AppxManifest.xml b/bin/Release/ForBundle/AppxManifest.xml index 417537dc..38684b3c 100644 --- a/bin/Release/ForBundle/AppxManifest.xml +++ b/bin/Release/ForBundle/AppxManifest.xml @@ -7,7 +7,7 @@ For more information on package manifest files, see http://go.microsoft.com/fwlink/?LinkID=241727 --> - + Kiwix JS diff --git a/bin/Release/KiwixWebApp.build.appxrecipe b/bin/Release/KiwixWebApp.build.appxrecipe index e69bc461..9081dfb9 100644 --- a/bin/Release/KiwixWebApp.build.appxrecipe +++ b/bin/Release/KiwixWebApp.build.appxrecipe @@ -367,7 +367,7 @@ www\js\lib\zimfile.js - + resources.pri true diff --git a/bin/Release/KiwixWebApp_0.7.5.0_AnyCPU.appx b/bin/Release/KiwixWebApp_0.7.5.0_AnyCPU.appx new file mode 100644 index 00000000..7e4842c4 Binary files /dev/null and b/bin/Release/KiwixWebApp_0.7.5.0_AnyCPU.appx differ diff --git a/bin/Release/KiwixWebApp_0.7.5.0_scale-100.appx b/bin/Release/KiwixWebApp_0.7.5.0_scale-100.appx new file mode 100644 index 00000000..13dcd2fe Binary files /dev/null and b/bin/Release/KiwixWebApp_0.7.5.0_scale-100.appx differ diff --git a/bin/Release/KiwixWebApp_0.7.5.0_scale-125.appx b/bin/Release/KiwixWebApp_0.7.5.0_scale-125.appx new file mode 100644 index 00000000..f30056b8 Binary files /dev/null and b/bin/Release/KiwixWebApp_0.7.5.0_scale-125.appx differ diff --git a/bin/Release/KiwixWebApp_0.7.5.0_scale-150.appx b/bin/Release/KiwixWebApp_0.7.5.0_scale-150.appx new file mode 100644 index 00000000..5cbfda6e Binary files /dev/null and b/bin/Release/KiwixWebApp_0.7.5.0_scale-150.appx differ diff --git a/bin/Release/KiwixWebApp_0.7.5.0_scale-400.appx b/bin/Release/KiwixWebApp_0.7.5.0_scale-400.appx new file mode 100644 index 00000000..52125ab4 Binary files /dev/null and b/bin/Release/KiwixWebApp_0.7.5.0_scale-400.appx differ diff --git a/bin/Release/ReverseMap/resources.pri b/bin/Release/resources.pri similarity index 56% rename from bin/Release/ReverseMap/resources.pri rename to bin/Release/resources.pri index 11ec8731..1c205d00 100644 Binary files a/bin/Release/ReverseMap/resources.pri and b/bin/Release/resources.pri differ diff --git a/bld/Release/KiwixWebApp.jsproj.FileListAbsolute.txt b/bld/Release/KiwixWebApp.jsproj.FileListAbsolute.txt index e1291aca..77952dbc 100644 --- a/bld/Release/KiwixWebApp.jsproj.FileListAbsolute.txt +++ b/bld/Release/KiwixWebApp.jsproj.FileListAbsolute.txt @@ -45,4 +45,4 @@ C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\qualifiers.txt C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\qualifiers.txt.intermediate C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\MultipleQualifiersPerDimensionFound.txt C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\ProjectArchitectures.txt -C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\ReverseMap\resources.pri +C:\Users\geoff\Source\Repos\kiwix-js-windows\bin\Release\resources.pri diff --git a/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_AnyCPU.appx b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_AnyCPU.appx new file mode 100644 index 00000000..7e4842c4 Binary files /dev/null and b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_AnyCPU.appx differ diff --git a/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-100.appx b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-100.appx new file mode 100644 index 00000000..13dcd2fe Binary files /dev/null and b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-100.appx differ diff --git a/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-125.appx b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-125.appx new file mode 100644 index 00000000..f30056b8 Binary files /dev/null and b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-125.appx differ diff --git a/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-150.appx b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-150.appx new file mode 100644 index 00000000..5cbfda6e Binary files /dev/null and b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-150.appx differ diff --git a/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-400.appx b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-400.appx new file mode 100644 index 00000000..52125ab4 Binary files /dev/null and b/bld/Release/KiwixWebApp_0.7.5.0_Bundle/KiwixWebApp_0.7.5.0_scale-400.appx differ diff --git a/bld/Release/PackageLayout/www/-/s/vector.css b/bld/Release/PackageLayout/www/-/s/vector.css new file mode 100644 index 00000000..d5a65c15 --- /dev/null +++ b/bld/Release/PackageLayout/www/-/s/vector.css @@ -0,0 +1,866 @@ +@media screen { + /* Vector screen styles */ + /* + * Any rules which should not be flipped automatically in right-to-left situations should be + * prepended with @noflip in a comment block. + * + * This stylesheet employs a few CSS trick to accomplish compatibility with a wide range of web + * browsers. The most common trick is to use some styles in IE6 only. This is accomplished by using + * a rule that makes things work in IE6, and then following it with a rule that begins with + * "html > body" or use a child selector ">", which is ignored by IE6 because it does not support + * the child selector. You can spot this by looking for the "OVERRIDDEN BY COMPLIANT BROWSERS" and + * "IGNORED BY IE6" comments. + */ + /* stylelint-disable selector-no-vendor-prefix, at-rule-no-unknown */ + /* stylelint-enable selector-no-vendor-prefix, at-rule-no-unknown */ + /* Framework */ + html { + font-size: 100%; + } + html, + body { + height: 100%; + margin: 0; + padding: 0; + font-family: sans-serif; + } + body { + background-color: #f6f6f6; + } + /* Content */ + .mw-body, + .parsoid-body { + padding: 1em; + background-color: #ffffff; + color: #222222; + direction: ltr; + } + .mw-body { + margin-left: 10em; + /* Border on top, left, and bottom side */ + border: 1px solid #a7d7f9; + border-right-width: 0; + /* Merge the border with tabs' one (in their background image) */ + margin-top: -1px; + } + .mw-body h1, + .mw-body-content h1, + .mw-body-content h2 { + font-family: 'Linux Libertine', 'Georgia', 'Times', serif; + line-height: 1.3; + margin-bottom: 0.25em; + padding: 0; + /* Fallback heading font for scripts which render poorly in @content-heading-font-family. */ + /* See T73240 */ + } + .mw-body h1:lang( ja ), + .mw-body-content h1:lang( ja ), + .mw-body-content h2:lang( ja ), + .mw-body h1:lang( he ), + .mw-body-content h1:lang( he ), + .mw-body-content h2:lang( he ), + .mw-body h1:lang( ko ), + .mw-body-content h1:lang( ko ), + .mw-body-content h2:lang( ko ) { + /* See T65827 */ + font-family: sans-serif; + } + .mw-body h1, + .mw-body-content h1 { + font-size: 1.8em; + } + .mw-body .firstHeading { + /* Change the default from mediawiki.skinning CSS to let indicators float into heading area */ + overflow: visible; + } + .mw-body .mw-indicators { + float: right; + line-height: 1.6; + font-size: 0.875em; + /* Ensure that this is displayed on top of .mw-body-content and clickable */ + position: relative; + z-index: 1; + } + .mw-body .mw-indicator { + display: inline-block; + zoom: 1; + *display: inline; + } + .mw-body-content { + position: relative; + line-height: 1.6; + font-size: 0.875em; + z-index: 0; + } + .mw-body-content p { + line-height: inherit; + margin: 0.5em 0; + } + .mw-body-content h1 { + margin-top: 1em; + } + .mw-body-content h2 { + font-size: 1.5em; + margin-top: 1em; + } + .mw-body-content h3, + .mw-body-content h4, + .mw-body-content h5, + .mw-body-content h6 { + line-height: 1.6; + margin-top: 0.3em; + margin-bottom: 0; + padding-bottom: 0; + } + .mw-body-content h3 { + font-size: 1.2em; + } + .mw-body-content h3, + .mw-body-content h4 { + font-weight: bold; + } + .mw-body-content h4, + .mw-body-content h5, + .mw-body-content h6 { + font-size: 100%; + /* (reset) */ + } + .mw-body-content #toc h2, + .mw-body-content .toc h2 { + font-size: 100%; + /* (reset) */ + font-family: sans-serif; + } + /* Allow edit sections outside of mw-body-content (T160269) */ + .mw-editsection, + .mw-editsection-like { + font-family: sans-serif; + } + /* Hide empty portlets */ + div.emptyPortlet { + display: none; + } + ul { + list-style-type: disc; + list-style-image: url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20width%3D%225%22%20height%3D%2213%22%3E%0A%3Ccircle%20cx%3D%222.5%22%20cy%3D%229.5%22%20r%3D%222.5%22%20fill%3D%22%2300528c%22%2F%3E%0A%3C%2Fsvg%3E%0A); + /* Fallback to PNG bullet for IE 8 and below using CSS hack */ + list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAANCAIAAADuXjPfAAAABnRSTlMA/wD/AP83WBt9AAAAHklEQVR4AWP4jwrowWcI6oEgEBtIISNCfFT9mOYDACO/lbNIGC/yAAAAAElFTkSuQmCC) \9; + /* Fallback to PNG bullet for IE 8 and below using CSS hack */ + list-style-image: url(/w/skins/Vector/images/bullet-icon.png?e31f8) \9!ie; + } + pre, + .mw-code { + line-height: 1.3em; + } + /* Site Notice (includes notices from CentralNotice extension) */ + #siteNotice { + font-size: 0.8em; + } + /* Personal */ + #p-personal { + position: absolute; + top: 0.33em; + right: 0.75em; + /* Display on top of page tabs - bugs 37158, 48078 */ + z-index: 100; + } + #p-personal h3 { + display: none; + } + #p-personal ul { + list-style-type: none; + list-style-image: none; + margin: 0; + padding-left: 10em; + /* Keep from overlapping logo */ + } + #p-personal li { + line-height: 1.125em; + /* @noflip */ + float: left; + margin-left: 0.75em; + margin-top: 0.5em; + font-size: 0.75em; + white-space: nowrap; + } + /* Icon for Usernames */ + #pt-userpage, + #pt-anonuserpage { + background-position: left top; + background-repeat: no-repeat; + /* SVG support using a transparent gradient to guarantee cross-browser + * compatibility (browsers able to understand gradient syntax support also SVG) */ + background-image: url(/w/skins/Vector/images/user-icon.png?13155); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3C%21DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09width%3D%2212px%22%20height%3D%2213.836px%22%20viewBox%3D%220%200%2012%2013.836%22%20enable-background%3D%22new%200%200%2012%2013.836%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cpath%20fill%3D%22%23777777%22%20d%3D%22M1.938%2C6.656c-1.32%2C1.485-1.47%2C3.15-0.97%2C4.25c0.323%2C0.707%2C0.78%2C1.127%2C1.313%2C1.375%0A%09c0.496%2C0.229%2C1.074%2C0.273%2C1.658%2C0.282c0.023%2C0%2C0.04%2C0.03%2C0.062%2C0.03h4.187c0.61%2C0%2C1.225-0.125%2C1.75-0.405%0A%09c0.527-0.28%2C0.961-0.718%2C1.188-1.376c0.335-0.964%2C0.175-2.529-1.094-4.03C9.094%2C7.954%2C7.68%2C8.719%2C6.065%2C8.719%0A%09c-1.677%2C0-3.182-0.812-4.125-2.063H1.938z%22%2F%3E%0A%3Cpath%20fill%3D%22%23777777%22%20d%3D%22M6.063%2C0c-1.89%2C0-3.595%2C1.674-3.594%2C3.563C2.467%2C5.45%2C4.173%2C7.155%2C6.06%2C7.155%0A%09c1.89%2C0%2C3.564-1.705%2C3.563-3.593C9.625%2C1.673%2C7.95%2C0%2C6.063%2C0L6.063%2C0z%22%2F%3E%0A%3C%2Fsvg%3E%0A); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/user-icon.png?13155); + padding-left: 15px !important; + } + /* Show "Not logged in" text in gray */ + #pt-anonuserpage { + color: #707070; + } + /* Search */ + #p-search { + /* @noflip */ + float: left; + margin-right: 0.5em; + margin-left: 0.5em; + } + #p-search h3 { + display: block; + position: absolute !important; + /* stylelint-disable-line declaration-no-important */ + clip: rect(1px, 1px, 1px, 1px); + width: 1px; + height: 1px; + margin: -1px; + border: 0; + padding: 0; + overflow: hidden; + } + #p-search form, + #p-search input { + margin: 0; + margin-top: 0.4em; + } + div#simpleSearch { + display: block; + width: 12.6em; + width: 20vw; + /* responsive width */ + min-width: 5em; + max-width: 20em; + padding-right: 1.4em; + height: 1.4em; + margin-top: 0.65em; + position: relative; + min-height: 1px; + /* Gotta trigger hasLayout for IE7 */ + border: solid 1px #aaa; + color: #000; + background-color: #fff; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAQCAIAAABY/YLgAAAAJUlEQVQIHQXBsQEAAAjDoND/73UWdnerhmHVsDQZJrNWVg3Dqge6bgMe6bejNAAAAABJRU5ErkJggg==); + background-image: url(/w/skins/Vector/images/search-fade.png?50f7b)!ie; + background-position: top left; + background-repeat: repeat-x; + } + div#simpleSearch input { + margin: 0; + padding: 0; + border: 0; + background-color: transparent; + color: #000; + } + div#simpleSearch #searchInput { + width: 100%; + padding: 0.2em 0 0.2em 0.2em; + font-size: 13px; + direction: ltr; + /* stylelint-disable indentation */ + /* stylelint-enable indentation */ + -webkit-appearance: textfield; + } + div#simpleSearch #searchInput:focus { + outline: 0; + } + div#simpleSearch #searchInput::-webkit-input-placeholder { + color: #72777d; + opacity: 1; + } + div#simpleSearch #searchInput:-ms-input-placeholder { + color: #72777d; + opacity: 1; + } + div#simpleSearch #searchInput::-moz-placeholder { + color: #72777d; + opacity: 1; + } + div#simpleSearch #searchInput:-moz-placeholder { + color: #72777d; + opacity: 1; + } + div#simpleSearch #searchInput::placeholder { + color: #72777d; + opacity: 1; + } + div#simpleSearch #searchInput.placeholder { + color: #72777d; + opacity: 1; + } + div#simpleSearch #searchInput::-webkit-search-decoration, + div#simpleSearch #searchInput::-webkit-search-cancel-button, + div#simpleSearch #searchInput::-webkit-search-results-button, + div#simpleSearch #searchInput::-webkit-search-results-decoration { + -webkit-appearance: textfield; + } + div#simpleSearch #searchButton, + div#simpleSearch #mw-searchButton { + position: absolute; + top: 0; + right: 0; + width: 1.65em; + height: 100%; + cursor: pointer; + /* Hide button text and replace it with the image. */ + text-indent: -99999px; + /* Needed to make IE6 respect the text-indent. */ + line-height: 1; + /* Opera 12 on RTL flips the text in a funny way without this. */ + /* @noflip */ + direction: ltr; + white-space: nowrap; + overflow: hidden; + } + div#simpleSearch #searchButton { + background-image: url(/w/skins/Vector/images/search-ltr.png?39f97); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2213%22%3E%3Cg%20stroke-width%3D%222%22%20stroke%3D%22%236c6c6c%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M11.29%2011.71l-4-4%22%2F%3E%3Ccircle%20cx%3D%225%22%20cy%3D%225%22%20r%3D%224%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/search-ltr.png?39f97); + background-position: center center; + background-repeat: no-repeat; + } + div#simpleSearch #mw-searchButton { + z-index: 1; + } + /** + * Styling for namespace tabs (page, discussion) and views (read, edit, view history, watch and other actions) + */ + /* Navigation Labels */ + div.vectorTabs h3 { + display: none; + } + /* Namespaces and Views */ + div.vectorTabs { + /* @noflip */ + float: left; + height: 2.5em; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAuCAIAAABmjeQ9AAAAQ0lEQVR4AWVOhQEAIAzC/X+xAXbXeoDFGA3A9yk1n4juBROcUegfarWjP3ojZvEzxs6j+nygmo+zzsk79nY+tOxdEhlf3UHVgUFrVwAAAABJRU5ErkJggg==); + background-image: url(/w/skins/Vector/images/tab-break.png?09d4b)!ie; + background-position: bottom left; + background-repeat: no-repeat; + padding-left: 1px; + } + div.vectorTabs ul { + /* @noflip */ + float: left; + height: 100%; + list-style-type: none; + list-style-image: none; + margin: 0; + padding: 0; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAuCAIAAABmjeQ9AAAAQ0lEQVR4AWVOhQEAIAzC/X+xAXbXeoDFGA3A9yk1n4juBROcUegfarWjP3ojZvEzxs6j+nygmo+zzsk79nY+tOxdEhlf3UHVgUFrVwAAAABJRU5ErkJggg==); + background-image: url(/w/skins/Vector/images/tab-break.png?09d4b)!ie; + background-position: right bottom; + background-repeat: no-repeat; + /* IGNORED BY IE6 which doesn't support child selector */ + } + div.vectorTabs ul li { + /* @noflip */ + float: left; + line-height: 1.125em; + /* For IE6, overridden later to display:block by modern browsers */ + display: inline-block; + height: 100%; + margin: 0; + padding: 0; + background-color: #f3f3f3; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAABkCAIAAADITs03AAAAO0lEQVR4AeSKhREAMQzDdN5/5uixuEKDpqgBjl2f78wd2DVj1+26/h///PfteVMN7zoGebcg1/Y/ZQQAlAUtQCujIJMAAAAASUVORK5CYII=); + background-image: url(/w/skins/Vector/images/tab-normal-fade.png?1cc52)!ie; + background-position: bottom left; + background-repeat: repeat-x; + white-space: nowrap; + } + div.vectorTabs ul > li { + display: block; + } + div.vectorTabs li { + /* Ignored by IE6 which doesn't support child selector */ + } + div.vectorTabs li.new a, + div.vectorTabs li.new a:visited { + color: #a55858; + } + div.vectorTabs li.selected { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAABkAQAAAABvV2fNAAAADElEQVR4AWNoGB4QAInlMgFKeRKBAAAAAElFTkSuQmCC); + background-image: url(/w/skins/Vector/images/tab-current-fade.png?22887)!ie; + } + div.vectorTabs li.selected a, + div.vectorTabs li.selected a:visited { + color: #222; + text-decoration: none; + } + div.vectorTabs li.icon a { + background-position: bottom right; + background-repeat: no-repeat; + } + div.vectorTabs li a { + /* For IE6, overridden later to display:block by modern browsers */ + display: inline-block; + height: 1.9em; + padding-left: 0.5em; + padding-right: 0.5em; + color: #0645ad; + cursor: pointer; + font-size: 0.8em; + } + div.vectorTabs li > a { + display: block; + } + div.vectorTabs span { + display: inline-block; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAuCAIAAABmjeQ9AAAAQ0lEQVR4AWVOhQEAIAzC/X+xAXbXeoDFGA3A9yk1n4juBROcUegfarWjP3ojZvEzxs6j+nygmo+zzsk79nY+tOxdEhlf3UHVgUFrVwAAAABJRU5ErkJggg==); + background-image: url(/w/skins/Vector/images/tab-break.png?09d4b)!ie; + background-position: bottom right; + background-repeat: no-repeat; + height: 100%; + /* Ignored by IE6 which doesn't support child selector */ + } + div.vectorTabs span a { + /* For IE6, overridden later to display:block by modern browsers */ + display: inline-block; + padding-top: 1.25em; + } + div.vectorTabs span > a { + /* @noflip */ + float: left; + display: block; + } + /* Variants and Actions */ + div.vectorMenu { + /* @noflip */ + direction: ltr; + /* @noflip */ + float: left; + cursor: pointer; + position: relative; + } + body.rtl div.vectorMenu { + /* @noflip */ + direction: rtl; + } + div#mw-head div.vectorMenu h3 { + /* @noflip */ + float: left; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAuCAIAAABmjeQ9AAAAQ0lEQVR4AWVOhQEAIAzC/X+xAXbXeoDFGA3A9yk1n4juBROcUegfarWjP3ojZvEzxs6j+nygmo+zzsk79nY+tOxdEhlf3UHVgUFrVwAAAABJRU5ErkJggg==); + background-image: url(/w/skins/Vector/images/tab-break.png?09d4b)!ie; + background-repeat: no-repeat; + background-position: bottom right; + font-size: 1em; + height: 2.5em; + padding-right: 1px; + margin-right: -1px; + } + div.vectorMenu h3 span { + display: block; + font-size: 0.8em; + padding-left: 0.7em; + padding-top: 1.375em; + margin-right: 20px; + font-weight: normal; + color: #4d4d4d; + } + div.vectorMenu h3 a, + div.vectorMenu h3 div { + position: absolute; + top: 0; + right: 0; + width: 20px; + height: 2.5em; + background-image: url(/w/skins/Vector/images/arrow-down-icon.png?d72f0); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2222%22%20height%3D%2216%22%3E%3Cpath%20d%3D%22M15.502%206.001l-5%205.001-5-5.001z%22%20fill%3D%22%23797979%22%2F%3E%3C%2Fsvg%3E); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/arrow-down-icon.png?d72f0); + background-position: 100% 70%; + background-repeat: no-repeat; + -webkit-transition: background-position 250ms; + -moz-transition: background-position 250ms; + transition: background-position 250ms; + } + div.vectorMenu.menuForceShow h3 a, + div.vectorMenu.menuForceShow h3 div { + background-position: 100% 100%; + } + div.vectorMenuFocus h3 a, + div.vectorMenuFocus h3 div { + background-image: url(/w/skins/Vector/images/arrow-down-focus-icon.png?69899); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2222%22%20height%3D%2216%22%3E%3Cpath%20d%3D%22M15.502%206.001l-5%205.001-5-5.001z%22%20fill%3D%22%23929292%22%2F%3E%3C%2Fsvg%3E); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/arrow-down-focus-icon.png?69899); + } + div.vectorMenu div.menu { + min-width: 100%; + position: absolute; + top: 2.5em; + left: -1px; + background-color: #ffffff; + border: 1px solid #a2a9b1; + border-top-width: 0; + clear: both; + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); + text-align: left; + display: none; + z-index: 1; + } + /* Enable forcing showing of the menu for accessibility */ + div.vectorMenu:hover div.menu, + div.vectorMenu.menuForceShow div.menu { + display: block; + } + div.vectorMenu ul { + list-style-type: none; + list-style-image: none; + padding: 0; + margin: 0; + text-align: left; + } + /* Fixes old versions of FireFox */ + div.vectorMenu ul, + x:-moz-any-link { + min-width: 5em; + } + /* Returns things back to normal in modern versions of FireFox */ + div.vectorMenu ul, + x:-moz-any-link, + x:default { + min-width: 0; + } + div.vectorMenu li { + padding: 0; + margin: 0; + text-align: left; + line-height: 1em; + } + /* OVERRIDDEN BY COMPLIANT BROWSERS */ + div.vectorMenu li a { + display: inline-block; + padding: 0.5em; + white-space: nowrap; + color: #0645ad; + cursor: pointer; + font-size: 0.8em; + } + /* IGNORED BY IE6 */ + div.vectorMenu li > a { + display: block; + } + div.vectorMenu li.selected a, + div.vectorMenu li.selected a:visited { + color: #222; + text-decoration: none; + } + * html div.vectorMenu div.menu { + display: block; + position: static; + border: 0; + } + * html div#mw-head div.vectorMenu h3 { + display: none; + } + * html div.vectorMenu li { + float: left; + line-height: 1.125em; + border-right: 1px solid #a7d7f9; + } + * html div.vectorMenu li a { + padding-top: 1.25em; + } + @-webkit-keyframes rotate { + from { + -webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + transform: rotate(360deg); + } + } + @-moz-keyframes rotate { + from { + -webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + transform: rotate(360deg); + } + } + @keyframes rotate { + from { + -webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + transform: rotate(360deg); + } + } + /* Watch/Unwatch Icon Styling */ + #ca-unwatch.icon a, + #ca-watch.icon a { + margin: 0; + padding: 0; + display: block; + width: 26px; + /* This hides the text but shows the background image */ + padding-top: 3.1em; + margin-top: 0; + /* Only applied in IE6 */ + _margin-top: -0.8em; + height: 0; + overflow: hidden; + background-position: 5px 60%; + } + #ca-unwatch.icon a { + background-image: url(/w/skins/Vector/images/unwatch-icon.png?fccbe); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%2216%22%20height%3D%2216%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22a%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23c2edff%22%2F%3E%3Cstop%20offset%3D%22.5%22%20stop-color%3D%22%2368bdff%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23fff%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20x1%3D%2213.47%22%20y1%3D%2214.363%22%20x2%3D%224.596%22%20y2%3D%223.397%22%20id%3D%22b%22%20xlink%3Ahref%3D%22%23a%22%20gradientUnits%3D%22userSpaceOnUse%22%2F%3E%3C%2Fdefs%3E%3Cpath%20d%3D%22M8.103%201.146l2.175%204.408%204.864.707-3.52%203.431.831%204.845-4.351-2.287-4.351%202.287.831-4.845-3.52-3.431%204.864-.707z%22%20fill%3D%22url%28%23b%29%22%20stroke%3D%22%237cb5d1%22%20stroke-width%3D%220.9999199999999999%22%2F%3E%3C%2Fsvg%3E); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/unwatch-icon.png?fccbe); + } + #ca-watch.icon a { + background-image: url(/w/skins/Vector/images/watch-icon.png?e1b42); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%3E%3Cpath%20d%3D%22M8.103%201.146l2.175%204.408%204.864.707-3.52%203.431.831%204.845-4.351-2.287-4.351%202.287.831-4.845-3.52-3.431%204.864-.707z%22%20fill%3D%22%23fff%22%20stroke%3D%22%237cb5d1%22%20stroke-width%3D%220.9999199999999999%22%2F%3E%3C%2Fsvg%3E); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/watch-icon.png?e1b42); + } + #ca-unwatch.icon a:hover, + #ca-unwatch.icon a:focus { + background-image: url(/w/skins/Vector/images/unwatch-icon-hl.png?c4723); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%2216%22%20height%3D%2216%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22a%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23c2edff%22%2F%3E%3Cstop%20offset%3D%22.5%22%20stop-color%3D%22%2368bdff%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23fff%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20x1%3D%2213.47%22%20y1%3D%2214.363%22%20x2%3D%224.596%22%20y2%3D%223.397%22%20id%3D%22b%22%20xlink%3Ahref%3D%22%23a%22%20gradientUnits%3D%22userSpaceOnUse%22%2F%3E%3C%2Fdefs%3E%3Cpath%20d%3D%22M8.103%201.146l2.175%204.408%204.864.707-3.52%203.431.831%204.845-4.351-2.287-4.351%202.287.831-4.845-3.52-3.431%204.864-.707z%22%20fill%3D%22url%28%23b%29%22%20stroke%3D%22%23c8b250%22%20stroke-width%3D%220.9999199999999999%22%2F%3E%3C%2Fsvg%3E); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/unwatch-icon-hl.png?c4723); + } + #ca-watch.icon a:hover, + #ca-watch.icon a:focus { + background-image: url(/w/skins/Vector/images/watch-icon-hl.png?f4c7e); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%3E%3Cpath%20d%3D%22M8.103%201.146l2.175%204.408%204.864.707-3.52%203.431.831%204.845-4.351-2.287-4.351%202.287.831-4.845-3.52-3.431%204.864-.707z%22%20fill%3D%22%23fff%22%20stroke%3D%22%23c8b250%22%20stroke-width%3D%220.9999199999999999%22%2F%3E%3C%2Fsvg%3E); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/watch-icon-hl.png?f4c7e); + } + #ca-unwatch.icon a.loading, + #ca-watch.icon a.loading { + background-image: url(/w/skins/Vector/images/watch-icon-loading.png?5cb92); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%3E%3Cpath%20d%3D%22M8.103%201.146l2.175%204.408%204.864.707-3.52%203.431.831%204.845-4.351-2.287-4.351%202.287.831-4.845-3.52-3.431%204.864-.707z%22%20fill%3D%22%23fff%22%20stroke%3D%22%23d1d1d1%22%20stroke-width%3D%220.9999199999999999%22%2F%3E%3C%2Fsvg%3E); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/watch-icon-loading.png?5cb92); + -webkit-animation: rotate 700ms infinite linear; + -moz-animation: rotate 700ms infinite linear; + -o-animation: rotate 700ms infinite linear; + animation: rotate 700ms infinite linear; + /* Suppress the hilarious rotating focus outline on Firefox */ + outline: 0; + cursor: default; + pointer-events: none; + background-position: 50% 60%; + -webkit-transform-origin: 50% 57%; + transform-origin: 50% 57%; + } + #ca-unwatch.icon a span, + #ca-watch.icon a span { + display: none; + } + /* Hide, but keep accessible for screen-readers */ + #mw-navigation h2 { + position: absolute; + top: -9999px; + } + /* Head */ + #mw-page-base { + height: 5em; + background-position: bottom left; + background-repeat: repeat-x; + /* This image is only a fallback (for IE 6-9), so we do not @embed it. */ + background-image: url(/w/skins/Vector/images/page-fade.png?1d168); + background-color: #f6f6f6; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(50%, #ffffff), color-stop(100%, #f6f6f6)); + background-image: -webkit-linear-gradient(top, #ffffff 50%, #f6f6f6 100%); + background-image: -moz-linear-gradient(top, #ffffff 50%, #f6f6f6 100%); + background-image: linear-gradient(#ffffff 50%, #f6f6f6 100%); + background-color: #ffffff; + } + #mw-head-base { + margin-top: -5em; + margin-left: 10em; + height: 5em; + } + div#mw-head { + position: absolute; + top: 0; + right: 0; + width: 100%; + } + div#mw-head h3 { + margin: 0; + padding: 0; + } + /* Navigation Containers */ + #left-navigation { + float: left; + margin-left: 10em; + margin-top: 2.5em; + /* When right nav would overlap left nav, it's placed below it + (normal CSS floats behavior). This rule ensures that no empty space + is shown between them due to right nav's margin-top. Page layout + is still broken, but at least the nav overlaps only the page title + instead of half the content. */ + margin-bottom: -2.5em; + /* IE 6 double-margin bug fix */ + display: inline; + } + #right-navigation { + float: right; + margin-top: 2.5em; + } + /* Logo */ + #p-logo { + position: absolute; + top: -160px; + left: 0; + width: 10em; + height: 160px; + } + #p-logo a { + display: block; + width: 10em; + height: 160px; + background-repeat: no-repeat; + background-position: center center; + text-decoration: none; + } + /* Panel */ + div#mw-panel { + font-size: inherit; + position: absolute; + top: 160px; + padding-top: 1em; + width: 10em; + left: 0; + /* First sidebar portlet. Not using :first-of-type for IE<=8 support. */ + } + div#mw-panel div.portal { + margin: 0 0.6em 0 0.7em; + padding: 0.25em 0; + direction: ltr; + background-position: top left; + background-repeat: no-repeat; + } + div#mw-panel div.portal h3 { + font-size: 0.75em; + color: #4d4d4d; + font-weight: normal; + margin: 0.5em 0 0 0.66666667em; + padding: 0.25em 0; + cursor: default; + border: 0; + } + div#mw-panel div.portal div.body { + margin-left: 0.5em; + padding-top: 0; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAAABCAAAAAAphRnkAAAAJ0lEQVQIW7XFsQEAIAyAMPD/b7uLWz8wS5youFW1UREfiIpH1Q2VBz7fGPS1dOGeAAAAAElFTkSuQmCC); + background-image: url(/w/skins/Vector/images/portal-break.png?3ea1b)!ie; + background-repeat: no-repeat; + } + div#mw-panel div.portal div.body ul { + list-style-type: none; + list-style-image: none; + margin: 0; + padding: 0.3em 0 0 0; + } + div#mw-panel div.portal div.body ul li { + line-height: 1.125em; + margin: 0; + padding: 0.25em 0; + font-size: 0.75em; + word-wrap: break-word; + } + div#mw-panel div.portal div.body ul li a { + color: #0645ad; + } + div#mw-panel div.portal div.body ul li a:visited { + color: #0b0080; + } + div#mw-panel #p-logo + div.portal { + background-image: none; + margin-top: 0; + } + div#mw-panel #p-logo + div.portal h3 { + display: none; + } + div#mw-panel #p-logo + div.portal div.body { + background-image: none; + margin-left: 0.5em; + } + /* Footer */ + div#footer { + margin-left: 10em; + margin-top: 0; + padding: 0.75em; + direction: ltr; + } + div#footer ul { + list-style-type: none; + list-style-image: none; + margin: 0; + padding: 0; + } + div#footer ul li { + margin: 0; + padding: 0; + padding-top: 0.5em; + padding-bottom: 0.5em; + color: #333; + font-size: 0.7em; + } + div#footer #footer-icons { + float: right; + } + div#footer #footer-icons li { + float: left; + margin-left: 0.5em; + line-height: 2em; + text-align: right; + } + div#footer #footer-info li { + line-height: 1.4em; + } + div#footer #footer-places li { + float: left; + margin-right: 1em; + line-height: 2em; + } + body.ltr div#footer #footer-places { + /* @noflip */ + float: left; + } + .mw-body-content .external { + background-position: center right; + background-repeat: no-repeat; + background-image: url(/w/skins/Vector/images/external-link-ltr-icon.png?325de); + background-image: linear-gradient(transparent, transparent), url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%20standalone%3D%22no%22%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%3E%3Cpath%20fill%3D%22%23fff%22%20stroke%3D%22%2306c%22%20d%3D%22M1.5%204.518h5.982V10.5H1.5z%22%2F%3E%3Cpath%20d%3D%22M5.765%201H11v5.39L9.427%207.937l-1.31-1.31L5.393%209.35l-2.69-2.688%202.81-2.808L4.2%202.544z%22%20fill%3D%22%2306f%22%2F%3E%3Cpath%20d%3D%22M9.995%202.004l.022%204.885L8.2%205.07%205.32%207.95%204.09%206.723l2.882-2.88-1.85-1.852z%22%20fill%3D%22%23fff%22%2F%3E%3C%2Fsvg%3E); + background-image: -o-linear-gradient(transparent, transparent), url(/w/skins/Vector/images/external-link-ltr-icon.png?325de); + padding-right: 13px; + }}@media screen and (min-width: 982px) { + /* Vector screen styles for high definition displays */ + .mw-body { + margin-left: 11em; + padding: 1.25em 1.5em 1.5em 1.5em; + } + #p-logo { + left: 0.5em; + } + div#footer { + margin-left: 11em; + padding: 1.25em; + } + #mw-panel { + padding-left: 0.5em; + } + #p-search { + margin-right: 1em; + } + #left-navigation { + margin-left: 11em; + } + #p-personal { + right: 1em; + } + #mw-head-base { + margin-left: 11em; + }} \ No newline at end of file diff --git a/bld/Release/PackageLayout/www/js/app.js b/bld/Release/PackageLayout/www/js/app.js index 6975bc2f..4a144cd4 100644 --- a/bld/Release/PackageLayout/www/js/app.js +++ b/bld/Release/PackageLayout/www/js/app.js @@ -783,11 +783,11 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles // This matches the href of all tags containing rel="stylesheet" in raw HTML var regexpSheetHref = /(]*rel\s*=\s*["']stylesheet)[^>]*href\s*=\s*["'])([^"']+)(["'][^>]*>)/ig; // This matches the title between ... - var regexpArticleTitle = /]*>\s*([^<]+)\s*]*>\s*([^<]+)\s* Title - var regexpType1ZIMTitle = /]*>\s*([^<]+)\s*]*>\s*([^<]+)\s*]*>\s*([^<]+)\s*]*>\s*([^<]+)\s*]*\b)src(\s*=)/ig, - "$1style=\"display: none;\" onload=\"this.style.display='inline'\" data-kiwixsrc$2"); + "$1style=\"display: none;\" onload=\"this.style.display='inline';\" data-kiwixsrc$2"); //Preload stylesheets [kiwix-js @149] //Set up blobArray of promises @@ -923,12 +923,12 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles $("#articleContent").contents().scrollTop(0); $('#articleContent').contents().find('body').html(htmlContent); //Try to match Title - var articleTitle = htmlContent.match(regexpArticleTitle); + //var articleTitle = htmlContent.match(regexpArticleTitle); //If not found try to match mw-offliner ZIM format - var articleTitle = articleTitle ? articleTitle[1] : htmlContent.match(regexpType2ZIMTitle); + //var articleTitle = articleTitle ? articleTitle[1] : htmlContent.match(regexpType2ZIMTitle); //If not found, use "Article" - articleTitle = articleTitle ? articleTitle[1] : "Article"; - uiUtil.makeReturnLink(articleTitle); + //articleTitle = articleTitle ? articleTitle[1] : "Article"; + uiUtil.makeReturnLink(dirEntry); //[kiwix-js #127] // If the ServiceWorker is not useable, we need to fallback to parse the DOM // to inject math images, and replace some links with javascript calls diff --git a/bld/Release/PackageLayout/www/js/lib/transformStyles.js b/bld/Release/PackageLayout/www/js/lib/transformStyles.js index 7fc152c7..4cc79fd8 100644 --- a/bld/Release/PackageLayout/www/js/lib/transformStyles.js +++ b/bld/Release/PackageLayout/www/js/lib/transformStyles.js @@ -22,7 +22,8 @@ * along with Kiwix (file LICENSE-GPLv3.txt). If not, see */ 'use strict'; -define([], function () { + +define(['uiUtil'], function (uiUtil) { /* zl = zimLink; zim = zimType; cc = cssCache; cs = cssSource; i] */ function filterCSS(zl, zim, cc, cs, i) { @@ -32,9 +33,11 @@ define([], function () { zl = (cs == "mobile") ? "../-/s/style-mobile.css" : "../-/s/style.css"; //Take it from cache, because not in the ZIM console.log("Matched #" + i + " [" + zl + "] from local filesystem because style is not in ZIM" + "\nbut your display options require a " + cs + " style"); + uiUtil.poll("Matched [" + zl.substring(0, 30) + "] from cache" + " because your display options require a " + cs + " style..."); } if (cs == "desktop" && zl.match(/minerva|mobile|parsoid/)) { //If user selected desktop style and style is one of the mobile styles console.log("Voiding #" + i + " [" + zl + "] from document header \nbecause your display options require a desktop style"); + uiUtil.poll("Voiding [" + zl.substring(0, 30) + "] because your display options require a " + cs + " style..."); zl = "#"; //Void these mobile styles } //injectCSS(); @@ -60,13 +63,14 @@ define([], function () { zl = (cs == "mobile") ? "../-/s/style-mobile.css" : "../-/s/style.css"; } console.log("Matched #" + i + " [" + zl + "] from local filesystem"); + uiUtil.poll("Matched #" + i + " [" + zl.substring(0, 30) + "] from local filesystem"); //injectCSS(); return { zl: zl, rtnFunction: rtnFunction }; } else { //Try to get the stylesheet from the ZIM file unless it's the wrong ZIM type zl = zl.match(/^(?:\.\.\/|\/)+(-\/.*)$/)[1]; //Remove the directory path console.log("Attempting to resolve CSS link #" + i + " [" + zl + "] from ZIM file..." + (cc ? "\n(Consider adding file #" + i + " to the local filesystem)" : "")); - //resolveCSS(zl, i); //Pass link and index + uiUtil.poll("Attempting to resolve CSS link #" + i + " [" + zl.substring(0, 30) + "] from ZIM file..."); rtnFunction = "resolveCSS"; return { zl: zl, rtnFunction: rtnFunction }; } @@ -83,6 +87,7 @@ define([], function () { } if (cc || (zim == "desktop")) { //If user requested cached styles OR the ZIM does not contain mobile styles console.log(zim == "desktop" ? "Transforming display style to mobile..." : "Optimizing cached styles for mobile display..."); + uiUtil.poll("desktop" ? "Transforming display style to mobile..." : "Optimizing cached styles for mobile display..."); //Allow images to float right or left html = html.replace(/class\s*=\s*["']\s*thumb\s+tright\s*["']\s*/ig, 'style="float: right; clear: right; margin-left: 1.4em;"'); html = html.replace(/class\s*=\s*["']\s*thumb\s+tleft\s*["']\s*/ig, 'style="float: left; clear: left; margin-right: 1.4em;"'); @@ -100,19 +105,16 @@ define([], function () { } function toDesktopCSS(html, zim, cc, cs, css) { - //Test custom stylesheet switching - var customStylesheet = '\r\n'; - if (customStylesheet) { - css = customStylesheet; - } if (cc || (zim != cs)) { if (/class\s*=\s*["']gallery/i.test(html) && !/gallery/i.test(css)) { console.log("Inserting missing css required for gallery display [mediawiki.page.gallery.styles.css]..."); + uiUtil.poll("Inserting missing css required for gallery display [mediawiki.page.gallery.styles.css]..."); css += /-\/s\/css_modules\/mediawiki\.page\.gallery\.styles\.css/i.test(css) ? "" : '\r\n'; } } if (cc || (zim == "mobile")) { //If user requested cached styles OR the ZIM does not contain desktop styles console.log(zim == "mobile" ? "Transforming display style to desktop..." : "Optimizing cached styles for desktop display..."); + uiUtil.poll("mobile" ? "Transforming display style to desktop..." : "Optimizing cached styles for desktop display..."); //If it's in mobile position, move info-box above lead paragraph like on Wikipedia desktop //html = html.replace(/((?:\s*)?]*>(?:(?=([^<]+))\2|<(?!p\b[^>]*>))*?<\/p>(?:<\/span\s*>)?[^<]*)([\s\S]*?)(]*infobox)[\s\S]+?<\/table>)/i, "$4$3$1"); html = zim == "mobile" ? html.replace(/((?:\s*)?]*(?:infobox|vertical-navbox))[\s\S]+?<\/table>)/i, "$2\r\n$1") : html; diff --git a/bld/Release/PackageLayout/www/js/lib/uiUtil.js b/bld/Release/PackageLayout/www/js/lib/uiUtil.js index 2772b97a..a7449c7f 100644 --- a/bld/Release/PackageLayout/www/js/lib/uiUtil.js +++ b/bld/Release/PackageLayout/www/js/lib/uiUtil.js @@ -54,19 +54,22 @@ define([], function() { } function makeReturnLink(title) { + //Abbreviate title if necessary + var shortTitle = title.substring(0, 25); + shortTitle = shortTitle == title ? shortTitle : shortTitle + "..."; var link = '

<< Return to ' + title + '

'; + '$(\'#liAboutNav\').attr(\'class\', \'\');"><< Return to ' + shortTitle + ''; document.getElementById("returntoArticle_top").innerHTML = link; document.getElementById("returntoArticle_bottom").innerHTML = link; } function poll(msg) { - window.document.getElementById("progressMessage").innerHTML += '

' + msg + '

'; + document.getElementById("progressMessage").innerHTML += '

' + msg + '

'; } - function clear(msg) { - window.document.getElementById("progressMessage").innerHTML = "

"; + function clear() { + document.getElementById("progressMessage").innerHTML = "

"; } /** diff --git a/bld/Release/_pkginfo.txt b/bld/Release/_pkginfo.txt index ce6ef6b3..b3b2da85 100644 --- a/bld/Release/_pkginfo.txt +++ b/bld/Release/_pkginfo.txt @@ -1 +1 @@ -C:\Users\geoff\Source\Repos\kiwix-js-windows\AppPackages\KiwixWebApp_0.7.4.0_Test\KiwixWebApp_0.7.4.0_AnyCPU.appxbundle +C:\Users\geoff\Source\Repos\kiwix-js-windows\AppPackages\KiwixWebApp_0.7.5.0_Test\KiwixWebApp_0.7.5.0_AnyCPU.appxbundle diff --git a/bld/Release/filemap.map.txt b/bld/Release/filemap.map.txt index faf5487c..e6902e99 100644 --- a/bld/Release/filemap.map.txt +++ b/bld/Release/filemap.map.txt @@ -41,6 +41,7 @@ "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\css\bootstrap-theme.css" "www\css\bootstrap-theme.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\css\app.css" "www\css\app.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\A\dummyArticle.html" "www\A\dummyArticle.html" +"C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\vector.css" "www\-\s\vector.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\style.css" "www\-\s\style.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\style-mobile.css" "www\-\s\style-mobile.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\css_modules\mobile.css" "www\-\s\css_modules\mobile.css" diff --git a/bld/Release/filemap.pri b/bld/Release/filemap.pri index 223b3c03..a2fea9d8 100644 Binary files a/bld/Release/filemap.pri and b/bld/Release/filemap.pri differ diff --git a/bld/Release/filemap.scale-100.pri b/bld/Release/filemap.scale-100.pri index 53b68a64..451efb60 100644 Binary files a/bld/Release/filemap.scale-100.pri and b/bld/Release/filemap.scale-100.pri differ diff --git a/bld/Release/filemap.scale-125.pri b/bld/Release/filemap.scale-125.pri index 8ba3cb52..5d0db7d9 100644 Binary files a/bld/Release/filemap.scale-125.pri and b/bld/Release/filemap.scale-125.pri differ diff --git a/bld/Release/filemap.scale-150.pri b/bld/Release/filemap.scale-150.pri index 256cbc04..9141c353 100644 Binary files a/bld/Release/filemap.scale-150.pri and b/bld/Release/filemap.scale-150.pri differ diff --git a/bld/Release/filemap.scale-400.pri b/bld/Release/filemap.scale-400.pri index dfc9615a..f9b3ed74 100644 Binary files a/bld/Release/filemap.scale-400.pri and b/bld/Release/filemap.scale-400.pri differ diff --git a/bld/Release/main.map.txt b/bld/Release/main.map.txt index fcf57011..2d8b0bd8 100644 --- a/bld/Release/main.map.txt +++ b/bld/Release/main.map.txt @@ -42,6 +42,7 @@ "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\css\bootstrap-theme.css" "www\css\bootstrap-theme.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\css\app.css" "www\css\app.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\A\dummyArticle.html" "www\A\dummyArticle.html" +"C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\vector.css" "www\-\s\vector.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\style.css" "www\-\s\style.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\style-mobile.css" "www\-\s\style-mobile.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\css_modules\mobile.css" "www\-\s\css_modules\mobile.css" diff --git a/bld/Release/split.map.txt b/bld/Release/split.map.txt index d0365fce..5c821ffc 100644 --- a/bld/Release/split.map.txt +++ b/bld/Release/split.map.txt @@ -41,6 +41,7 @@ "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\css\bootstrap-theme.css" "www\css\bootstrap-theme.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\css\app.css" "www\css\app.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\A\dummyArticle.html" "www\A\dummyArticle.html" +"C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\vector.css" "www\-\s\vector.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\style.css" "www\-\s\style.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\style-mobile.css" "www\-\s\style-mobile.css" "C:\Users\geoff\Source\Repos\kiwix-js-windows\bld\Release\PackageLayout\www\-\s\css_modules\mobile.css" "www\-\s\css_modules\mobile.css" diff --git a/bld/Release/split.pri b/bld/Release/split.pri index 1cbb05a7..0067cf4e 100644 Binary files a/bld/Release/split.pri and b/bld/Release/split.pri differ diff --git a/bld/Release/split.pri.xml b/bld/Release/split.pri.xml index 50a8b29c..596044a1 100644 --- a/bld/Release/split.pri.xml +++ b/bld/Release/split.pri.xml @@ -102,6 +102,11 @@ www\-\s\style.css + + + www\-\s\vector.css + + diff --git a/bld/Release/split.scale-100.pri b/bld/Release/split.scale-100.pri index efdf607c..f834680c 100644 Binary files a/bld/Release/split.scale-100.pri and b/bld/Release/split.scale-100.pri differ diff --git a/bld/Release/split.scale-125.pri b/bld/Release/split.scale-125.pri index d0687348..44fc2599 100644 Binary files a/bld/Release/split.scale-125.pri and b/bld/Release/split.scale-125.pri differ diff --git a/bld/Release/split.scale-150.pri b/bld/Release/split.scale-150.pri index 7eee83a5..097a004f 100644 Binary files a/bld/Release/split.scale-150.pri and b/bld/Release/split.scale-150.pri differ diff --git a/bld/Release/split.scale-400.pri b/bld/Release/split.scale-400.pri index 827e7ddc..e9c11487 100644 Binary files a/bld/Release/split.scale-400.pri and b/bld/Release/split.scale-400.pri differ diff --git a/package.appxmanifest b/package.appxmanifest index 7fbbf58c..f78d419a 100644 --- a/package.appxmanifest +++ b/package.appxmanifest @@ -1,6 +1,6 @@  - + Kiwix JS