Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/duplicati/duplicati.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Duplicati')
-rw-r--r--Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj10
-rw-r--r--Duplicati/CommandLine/BackendTester/Program.cs11
-rw-r--r--Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj10
-rw-r--r--Duplicati/CommandLine/BackendTool/Program.cs42
-rw-r--r--Duplicati/CommandLine/Commands.cs763
-rw-r--r--Duplicati/CommandLine/ConsoleOutput.cs48
-rw-r--r--Duplicati/CommandLine/Duplicati.CommandLine.csproj10
-rw-r--r--Duplicati/CommandLine/Help.cs105
-rw-r--r--Duplicati/CommandLine/Program.cs208
-rw-r--r--Duplicati/CommandLine/RecoveryTool/Download.cs3
-rw-r--r--Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj12
-rw-r--r--Duplicati/CommandLine/RecoveryTool/List.cs2
-rw-r--r--Duplicati/CommandLine/RecoveryTool/Program.cs14
-rw-r--r--Duplicati/CommandLine/RecoveryTool/Recompress.cs8
-rw-r--r--Duplicati/CommandLine/RecoveryTool/Restore.cs8
-rw-r--r--Duplicati/CommandLine/RecoveryTool/help.txt2
-rw-r--r--Duplicati/CommandLine/RecoveryTool/packages.config2
-rw-r--r--Duplicati/CommandLine/Strings.cs12
-rw-r--r--Duplicati/CommandLine/help.txt130
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/AppIndicatorRunner.cs79
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj44
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/GtkRunner.cs167
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/HostedInstanceKeeper.cs13
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/HttpServerConnection.cs254
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/ImageLoader.cs2
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/OSXTrayHost/osx-trayicon-rumps.py1
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs231
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/Properties/AssemblyInfo.cs2
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_open.svg13
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_pause.svg14
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_quit.svg13
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_resume.svg13
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_open.svg13
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_pause.svg14
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_quit.svg13
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_resume.svg13
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/WinFormsRunner.cs8
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config4
-rw-r--r--Duplicati/Library/AutoUpdater/AutoUpdateSettings.cs4
-rw-r--r--Duplicati/Library/AutoUpdater/Duplicati.Library.AutoUpdater.csproj5
-rw-r--r--Duplicati/Library/AutoUpdater/Program.cs1
-rw-r--r--Duplicati/Library/AutoUpdater/UpdaterManager.cs126
-rw-r--r--Duplicati/Library/AutoUpdater/packages.config2
-rw-r--r--Duplicati/Library/Backend/AlternativeFTP/AlternativeFTPBackend.cs333
-rw-r--r--Duplicati/Library/Backend/AlternativeFTP/Duplicati.Library.Backend.AlternativeFTP.csproj168
-rw-r--r--Duplicati/Library/Backend/AlternativeFTP/Strings.cs3
-rw-r--r--Duplicati/Library/Backend/AmazonCloudDrive/AmzCD.cs65
-rw-r--r--Duplicati/Library/Backend/AmazonCloudDrive/Duplicati.Library.Backend.AmazonCloudDrive.csproj3
-rw-r--r--Duplicati/Library/Backend/AmazonCloudDrive/packages.config2
-rw-r--r--Duplicati/Library/Backend/AzureBlob/AzureBlobBackend.cs8
-rw-r--r--Duplicati/Library/Backend/AzureBlob/Duplicati.Library.Backend.AzureBlob.csproj26
-rw-r--r--Duplicati/Library/Backend/AzureBlob/packages.config19
-rw-r--r--Duplicati/Library/Backend/Backblaze/B2.cs42
-rw-r--r--Duplicati/Library/Backend/Backblaze/Duplicati.Library.Backend.Backblaze.csproj3
-rw-r--r--Duplicati/Library/Backend/Backblaze/Strings.cs7
-rw-r--r--Duplicati/Library/Backend/Backblaze/packages.config2
-rw-r--r--Duplicati/Library/Backend/Box/BoxBackend.cs9
-rw-r--r--Duplicati/Library/Backend/Box/Duplicati.Library.Backend.Box.csproj3
-rw-r--r--Duplicati/Library/Backend/Box/packages.config2
-rw-r--r--Duplicati/Library/Backend/CloudFiles/CloudFiles.cs21
-rw-r--r--Duplicati/Library/Backend/CloudFiles/Duplicati.Library.Backend.CloudFiles.csproj1
-rw-r--r--Duplicati/Library/Backend/CloudFiles/Strings.cs2
-rw-r--r--Duplicati/Library/Backend/Dropbox/Dropbox.cs36
-rw-r--r--Duplicati/Library/Backend/Dropbox/Duplicati.Library.Backend.Dropbox.csproj8
-rw-r--r--Duplicati/Library/Backend/Dropbox/packages.config2
-rw-r--r--Duplicati/Library/Backend/FTP/Duplicati.Library.Backend.FTP.csproj2
-rw-r--r--Duplicati/Library/Backend/FTP/FTPBackend.cs96
-rw-r--r--Duplicati/Library/Backend/FTP/Strings.cs2
-rw-r--r--Duplicati/Library/Backend/File/Duplicati.Library.Backend.File.csproj1
-rw-r--r--Duplicati/Library/Backend/File/FileBackend.cs96
-rw-r--r--Duplicati/Library/Backend/File/Strings.cs42
-rw-r--r--Duplicati/Library/Backend/GoogleServices/Duplicati.Library.Backend.GoogleServices.csproj3
-rw-r--r--Duplicati/Library/Backend/GoogleServices/GoogleCloudStorage.cs72
-rw-r--r--Duplicati/Library/Backend/GoogleServices/GoogleDrive.cs77
-rw-r--r--Duplicati/Library/Backend/GoogleServices/packages.config2
-rw-r--r--Duplicati/Library/Backend/HubiC/Duplicati.Library.Backend.HubiC.csproj1
-rw-r--r--Duplicati/Library/Backend/HubiC/HubiCBackend.cs2
-rw-r--r--Duplicati/Library/Backend/Jottacloud/Duplicati.Library.Backend.Jottacloud.csproj76
-rw-r--r--Duplicati/Library/Backend/Jottacloud/Duplicati.snkbin0 -> 596 bytes
-rw-r--r--Duplicati/Library/Backend/Jottacloud/Jottacloud.cs451
-rw-r--r--Duplicati/Library/Backend/Jottacloud/Properties/AssemblyInfo.cs54
-rw-r--r--Duplicati/Library/Backend/Jottacloud/Strings.cs21
-rw-r--r--Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj7
-rw-r--r--Duplicati/Library/Backend/Mega/MegaBackend.cs19
-rw-r--r--Duplicati/Library/Backend/Mega/Strings.cs2
-rw-r--r--Duplicati/Library/Backend/Mega/packages.config5
-rw-r--r--Duplicati/Library/Backend/OAuthHelper/Duplicati.Library.OAuthHelper.csproj7
-rw-r--r--Duplicati/Library/Backend/OAuthHelper/JSONWebHelper.cs2
-rw-r--r--Duplicati/Library/Backend/OAuthHelper/OAuthHelper.cs69
-rw-r--r--Duplicati/Library/Backend/OAuthHelper/packages.config2
-rw-r--r--Duplicati/Library/Backend/OneDrive/Duplicati.Library.Backend.OneDrive.csproj3
-rw-r--r--Duplicati/Library/Backend/OneDrive/OneDrive.cs139
-rw-r--r--Duplicati/Library/Backend/OneDrive/packages.config2
-rw-r--r--Duplicati/Library/Backend/OpenStack/Duplicati.Library.Backend.OpenStack.csproj3
-rw-r--r--Duplicati/Library/Backend/OpenStack/OpenStackStorage.cs87
-rw-r--r--Duplicati/Library/Backend/OpenStack/packages.config2
-rw-r--r--Duplicati/Library/Backend/S3/Duplicati.Library.Backend.S3.csproj11
-rw-r--r--Duplicati/Library/Backend/S3/S3Backend.cs67
-rw-r--r--Duplicati/Library/Backend/S3/S3IAM.cs8
-rw-r--r--Duplicati/Library/Backend/S3/S3Wrapper.cs41
-rw-r--r--Duplicati/Library/Backend/S3/Strings.cs4
-rw-r--r--Duplicati/Library/Backend/S3/packages.config6
-rw-r--r--Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj3
-rw-r--r--Duplicati/Library/Backend/SSHv2/KeyGenerator.cs6
-rw-r--r--Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs42
-rw-r--r--Duplicati/Library/Backend/SSHv2/Strings.cs10
-rw-r--r--Duplicati/Library/Backend/SSHv2/packages.config2
-rw-r--r--Duplicati/Library/Backend/SharePoint/Duplicati.Library.Backend.SharePoint.csproj176
-rw-r--r--Duplicati/Library/Backend/SharePoint/SharePointBackend.cs38
-rw-r--r--Duplicati/Library/Backend/SharePoint/Strings.cs72
-rw-r--r--Duplicati/Library/Backend/Sia/Duplicati.Library.Backend.Sia.csproj66
-rw-r--r--Duplicati/Library/Backend/Sia/Duplicati.snkbin0 -> 596 bytes
-rw-r--r--Duplicati/Library/Backend/Sia/Properties/AssemblyInfo.cs43
-rw-r--r--Duplicati/Library/Backend/Sia/Sia.cs458
-rw-r--r--Duplicati/Library/Backend/Sia/Strings.cs17
-rw-r--r--Duplicati/Library/Backend/Sia/packages.config4
-rw-r--r--Duplicati/Library/Backend/TahoeLAFS/Duplicati.Library.Backend.TahoeLAFS.csproj23
-rw-r--r--Duplicati/Library/Backend/TahoeLAFS/Properties/Resources.Designer.cs63
-rw-r--r--Duplicati/Library/Backend/TahoeLAFS/Properties/Resources.resx117
-rw-r--r--Duplicati/Library/Backend/TahoeLAFS/Properties/Settings.Designer.cs26
-rw-r--r--Duplicati/Library/Backend/TahoeLAFS/Properties/Settings.settings7
-rw-r--r--Duplicati/Library/Backend/TahoeLAFS/Strings.cs2
-rw-r--r--Duplicati/Library/Backend/TahoeLAFS/TahoeBackend.cs11
-rw-r--r--Duplicati/Library/Backend/TahoeLAFS/packages.config2
-rw-r--r--Duplicati/Library/Backend/WEBDAV/Duplicati.Library.Backend.WEBDAV.csproj2
-rw-r--r--Duplicati/Library/Backend/WEBDAV/Strings.cs5
-rw-r--r--Duplicati/Library/Backend/WEBDAV/WEBDAV.cs212
-rw-r--r--Duplicati/Library/Compression/Duplicati.Library.Compression.csproj9
-rw-r--r--Duplicati/Library/Compression/FileArchiveZip.cs309
-rw-r--r--Duplicati/Library/Compression/StreamWrapper.cs33
-rw-r--r--Duplicati/Library/Compression/Strings.cs52
-rw-r--r--Duplicati/Library/Compression/packages.config4
-rw-r--r--Duplicati/Library/DynamicLoader/BackendLoader.cs4
-rw-r--r--Duplicati/Library/DynamicLoader/Duplicati.Library.DynamicLoader.csproj1
-rw-r--r--Duplicati/Library/DynamicLoader/GenericLoader.cs2
-rw-r--r--Duplicati/Library/Encryption/AESEncryption.cs2
-rw-r--r--Duplicati/Library/Encryption/Duplicati.Library.Encryption.csproj1
-rw-r--r--Duplicati/Library/Encryption/Strings.cs2
-rw-r--r--Duplicati/Library/Interface/BackendExtensions.cs28
-rw-r--r--Duplicati/Library/Interface/CustomExceptions.cs30
-rw-r--r--Duplicati/Library/Interface/Duplicati.Library.Interface.csproj6
-rw-r--r--Duplicati/Library/Interface/IBackend.cs7
-rw-r--r--Duplicati/Library/Interface/IGenericModule.cs2
-rw-r--r--Duplicati/Library/Interface/IGenericServerModule.cs42
-rw-r--r--Duplicati/Library/Interface/IGenericSourceModule.cs49
-rw-r--r--Duplicati/Library/Interface/IQuotaEnabledBackend.cs14
-rw-r--r--Duplicati/Library/Interface/IQuotaInfo.cs24
-rw-r--r--Duplicati/Library/Interface/IRenameEnabledBackend.cs10
-rw-r--r--Duplicati/Library/Interface/QuotaInfo.cs21
-rw-r--r--Duplicati/Library/Interface/ResultInterfaces.cs54
-rw-r--r--Duplicati/Library/Localization/Duplicati.Library.Localization.csproj15
-rw-r--r--Duplicati/Library/Localization/LocalizationService.cs3
-rw-r--r--Duplicati/Library/Localization/MoLocalizationService.cs11
-rw-r--r--Duplicati/Library/Localization/packages.config2
-rw-r--r--Duplicati/Library/Logging/Duplicati.Library.Logging.csproj2
-rw-r--r--Duplicati/Library/Logging/Log.cs146
-rw-r--r--Duplicati/Library/Logging/LogScope.cs82
-rw-r--r--Duplicati/Library/Logging/StreamLog.cs2
-rw-r--r--Duplicati/Library/Main/BackendManager.cs282
-rw-r--r--Duplicati/Library/Main/Blockprocessor.cs6
-rw-r--r--Duplicati/Library/Main/Controller.cs387
-rw-r--r--Duplicati/Library/Main/Database/Database schema/7. Add index.sql3
-rw-r--r--Duplicati/Library/Main/Database/Database schema/Schema.sql5
-rw-r--r--Duplicati/Library/Main/Database/ExtensionMethods.cs4
-rw-r--r--Duplicati/Library/Main/Database/LocalBackupDatabase.cs289
-rw-r--r--Duplicati/Library/Main/Database/LocalBugReportDatabase.cs4
-rw-r--r--Duplicati/Library/Main/Database/LocalDatabase.cs257
-rw-r--r--Duplicati/Library/Main/Database/LocalDeleteDatabase.cs35
-rw-r--r--Duplicati/Library/Main/Database/LocalListBrokenFilesDatabase.cs134
-rw-r--r--Duplicati/Library/Main/Database/LocalListChangesDatabase.cs2
-rw-r--r--Duplicati/Library/Main/Database/LocalListDatabase.cs33
-rw-r--r--Duplicati/Library/Main/Database/LocalPurgeDatabase.cs198
-rw-r--r--Duplicati/Library/Main/Database/LocalRecreateDatabase.cs232
-rw-r--r--Duplicati/Library/Main/Database/LocalRepairDatabase.cs34
-rw-r--r--Duplicati/Library/Main/Database/LocalRestoreDatabase.cs92
-rw-r--r--Duplicati/Library/Main/Database/LocalTestDatabase.cs2
-rw-r--r--Duplicati/Library/Main/Database/PathLookupHelper.cs2
-rw-r--r--Duplicati/Library/Main/DatabaseLocator.cs58
-rw-r--r--Duplicati/Library/Main/Duplicati.Library.Main.csproj10
-rw-r--r--Duplicati/Library/Main/Enums.cs8
-rw-r--r--Duplicati/Library/Main/IMetahash.cs6
-rw-r--r--Duplicati/Library/Main/Operation/BackupHandler.cs568
-rw-r--r--Duplicati/Library/Main/Operation/CompactHandler.cs54
-rw-r--r--Duplicati/Library/Main/Operation/CreateBugReportHandler.cs13
-rw-r--r--Duplicati/Library/Main/Operation/DeleteHandler.cs165
-rw-r--r--Duplicati/Library/Main/Operation/FilelistProcessor.cs87
-rw-r--r--Duplicati/Library/Main/Operation/ListAffected.cs28
-rw-r--r--Duplicati/Library/Main/Operation/ListBrokenFilesHandler.cs209
-rw-r--r--Duplicati/Library/Main/Operation/ListChangesHandler.cs21
-rw-r--r--Duplicati/Library/Main/Operation/ListFilesHandler.cs15
-rw-r--r--Duplicati/Library/Main/Operation/PurgeBrokenFilesHandler.cs196
-rw-r--r--Duplicati/Library/Main/Operation/PurgeFilesHandler.cs250
-rw-r--r--Duplicati/Library/Main/Operation/RecreateDatabaseHandler.cs108
-rw-r--r--Duplicati/Library/Main/Operation/RepairHandler.cs43
-rw-r--r--Duplicati/Library/Main/Operation/RestoreHandler.cs34
-rw-r--r--Duplicati/Library/Main/Operation/RestoreHandlerMetadataStorage.cs132
-rw-r--r--Duplicati/Library/Main/Operation/TestFilterHandler.cs4
-rw-r--r--Duplicati/Library/Main/Operation/TestHandler.cs201
-rw-r--r--Duplicati/Library/Main/Operation/VacuumHandler.cs29
-rw-r--r--Duplicati/Library/Main/OperationPhase.cs8
-rw-r--r--Duplicati/Library/Main/Options.cs215
-rw-r--r--Duplicati/Library/Main/ProgressClasses.cs125
-rw-r--r--Duplicati/Library/Main/ResultClasses.cs509
-rw-r--r--Duplicati/Library/Main/Strings.cs59
-rw-r--r--Duplicati/Library/Main/Utility.cs32
-rw-r--r--Duplicati/Library/Main/Volumes/FilesetVolumeReader.cs52
-rw-r--r--Duplicati/Library/Main/Volumes/FilesetVolumeWriter.cs86
-rw-r--r--Duplicati/Library/Main/Volumes/IFileEntry.cs4
-rw-r--r--Duplicati/Library/Main/Volumes/VolumeBase.cs4
-rw-r--r--Duplicati/Library/Main/Volumes/VolumeWriterBase.cs2
-rw-r--r--Duplicati/Library/Main/default_compressed_extensions.txt1
-rw-r--r--Duplicati/Library/Main/packages.config2
-rw-r--r--Duplicati/Library/Modules/Builtin/CheckMonoSSL.cs22
-rw-r--r--Duplicati/Library/Modules/Builtin/ConsolePasswordInput.cs10
-rw-r--r--Duplicati/Library/Modules/Builtin/Duplicati.Library.Modules.Builtin.csproj34
-rw-r--r--Duplicati/Library/Modules/Builtin/HttpOptions.cs111
-rw-r--r--Duplicati/Library/Modules/Builtin/HyperVOptions.cs222
-rw-r--r--Duplicati/Library/Modules/Builtin/MSSQLOptions.cs219
-rw-r--r--Duplicati/Library/Modules/Builtin/RunScript.cs35
-rw-r--r--Duplicati/Library/Modules/Builtin/SendHttpMessage.cs334
-rw-r--r--Duplicati/Library/Modules/Builtin/SendJabberMessage.cs84
-rw-r--r--Duplicati/Library/Modules/Builtin/SendMail.cs131
-rw-r--r--Duplicati/Library/Modules/Builtin/Strings.cs78
-rw-r--r--Duplicati/Library/Modules/Builtin/packages.config6
-rw-r--r--Duplicati/Library/Modules/Builtin/run-script-example.bat5
-rw-r--r--Duplicati/Library/Modules/Builtin/run-script-example.sh4
-rw-r--r--Duplicati/Library/SQLiteHelper/DBSchemaUpgrades/DbUpgradesRegistry.cs19
-rw-r--r--Duplicati/Library/SQLiteHelper/DBSchemaUpgrades/IDbSchemaUpgrade.cs26
-rw-r--r--Duplicati/Library/SQLiteHelper/DatabaseUpgrader.cs38
-rw-r--r--Duplicati/Library/SQLiteHelper/Duplicati.Library.SQLiteHelper.csproj15
-rw-r--r--Duplicati/Library/SQLiteHelper/SQLiteLoader.cs93
-rw-r--r--Duplicati/Library/Snapshots/DefineDosDevice.cs2
-rw-r--r--Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj39
-rw-r--r--Duplicati/Library/Snapshots/HyperVUtility.cs176
-rw-r--r--Duplicati/Library/Snapshots/ISnapshotService.cs7
-rw-r--r--Duplicati/Library/Snapshots/ISystemIO.cs2
-rw-r--r--Duplicati/Library/Snapshots/LinuxSnapshot.cs16
-rw-r--r--Duplicati/Library/Snapshots/MSSQLUtility.cs167
-rw-r--r--Duplicati/Library/Snapshots/NoSnapshot.cs11
-rw-r--r--Duplicati/Library/Snapshots/NoSnapshotLinux.cs6
-rw-r--r--Duplicati/Library/Snapshots/NoSnapshotWindows.cs6
-rw-r--r--Duplicati/Library/Snapshots/SnapshotUtility.cs40
-rw-r--r--Duplicati/Library/Snapshots/SystemIOLinux.cs14
-rw-r--r--Duplicati/Library/Snapshots/SystemIOWindows.cs18
-rw-r--r--Duplicati/Library/Snapshots/USNHelper.cs2
-rw-r--r--Duplicati/Library/Snapshots/WinNativeMethods.cs4
-rw-r--r--Duplicati/Library/Snapshots/WindowsSnapshot.cs122
-rw-r--r--Duplicati/Library/Snapshots/lvm-scripts/create-lvm-snapshot.sh21
-rw-r--r--Duplicati/Library/Snapshots/lvm-scripts/find-volume.sh40
-rw-r--r--Duplicati/Library/Snapshots/packages.config6
-rw-r--r--Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj11
-rw-r--r--Duplicati/Library/UsageReporter/EventProcessor.cs176
-rw-r--r--Duplicati/Library/UsageReporter/OSInfoHelper.cs76
-rw-r--r--Duplicati/Library/UsageReporter/ReportSetUploader.cs116
-rw-r--r--Duplicati/Library/UsageReporter/Reporter.cs29
-rw-r--r--Duplicati/Library/UsageReporter/ShutdownHelper.cs117
-rw-r--r--Duplicati/Library/UsageReporter/packages.config4
-rw-r--r--Duplicati/Library/Utility/AsyncHttpRequest.cs35
-rw-r--r--Duplicati/Library/Utility/BlockingQueue.cs2
-rw-r--r--Duplicati/Library/Utility/CallContextSettings.cs325
-rw-r--r--Duplicati/Library/Utility/DefaultFilters.cs371
-rw-r--r--Duplicati/Library/Utility/Duplicati.Library.Utility.csproj18
-rw-r--r--Duplicati/Library/Utility/FileBackedList.cs6
-rw-r--r--Duplicati/Library/Utility/FilterCollector.cs27
-rw-r--r--Duplicati/Library/Utility/FilterExpression.cs20
-rw-r--r--Duplicati/Library/Utility/HashAlgorithmHelper.cs39
-rw-r--r--Duplicati/Library/Utility/HashCalculatingStream.cs2
-rw-r--r--Duplicati/Library/Utility/JoinedFilterExpression.cs10
-rw-r--r--Duplicati/Library/Utility/Power/DefaultPowerSupplyState.cs27
-rw-r--r--Duplicati/Library/Utility/Power/IPowerSupplyState.cs24
-rw-r--r--Duplicati/Library/Utility/Power/LinuxPowerSupplyState.cs107
-rw-r--r--Duplicati/Library/Utility/Power/PowerSupply.cs54
-rw-r--r--Duplicati/Library/Utility/Power/WindowsPowerSupplyState.cs46
-rw-r--r--Duplicati/Library/Utility/SslCertificateValidator.cs39
-rw-r--r--Duplicati/Library/Utility/Strings.cs7
-rw-r--r--Duplicati/Library/Utility/TempFolder.cs6
-rw-r--r--Duplicati/Library/Utility/ThrottledStream.cs334
-rw-r--r--Duplicati/Library/Utility/Uri.cs14
-rw-r--r--Duplicati/Library/Utility/Utility.cs299
-rw-r--r--Duplicati/Library/Utility/Win32.cs16
-rw-r--r--Duplicati/Library/Utility/app.config3
-rw-r--r--Duplicati/Library/Utility/packages.config4
-rw-r--r--Duplicati/License/Duplicati.License.csproj39
-rw-r--r--Duplicati/License/acknowledgements.txt1
-rw-r--r--Duplicati/Server/Database/Connection.cs131
-rw-r--r--Duplicati/Server/Database/Database schema/Schema.sql2
-rw-r--r--Duplicati/Server/Database/Schedule.cs4
-rw-r--r--Duplicati/Server/Database/ServerSettings.cs139
-rw-r--r--Duplicati/Server/Duplicati.Server.Serialization/Duplicati.Server.Serialization.csproj3
-rwxr-xr-xDuplicati/Server/Duplicati.Server.Serialization/Enums.cs6
-rw-r--r--Duplicati/Server/Duplicati.Server.Serialization/Interface/IProgressEventData.cs1
-rw-r--r--Duplicati/Server/Duplicati.Server.Serialization/Properties/AssemblyInfo.cs4
-rw-r--r--Duplicati/Server/Duplicati.Server.Serialization/packages.config2
-rw-r--r--Duplicati/Server/Duplicati.Server.csproj22
-rw-r--r--Duplicati/Server/LogWriteHandler.cs40
-rw-r--r--Duplicati/Server/Program.cs374
-rw-r--r--Duplicati/Server/Runner.cs295
-rw-r--r--Duplicati/Server/Scheduler.cs27
-rw-r--r--Duplicati/Server/Serializable/ServerSettings.cs17
-rw-r--r--Duplicati/Server/Serializable/ServerStatus.cs4
-rw-r--r--Duplicati/Server/SpecialFolders.cs46
-rw-r--r--Duplicati/Server/Strings.cs4
-rw-r--r--Duplicati/Server/UpdatePollThread.cs27
-rw-r--r--Duplicati/Server/WebServer/AuthenticationHandler.cs34
-rw-r--r--Duplicati/Server/WebServer/CaptchaUtil.cs115
-rw-r--r--Duplicati/Server/WebServer/ControlHandler.cs488
-rw-r--r--Duplicati/Server/WebServer/RESTHandler.cs8
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/Backup.cs110
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/Backups.cs64
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/Captcha.cs166
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/CommandLine.cs256
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/Filesystem.cs4
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/HyperV.cs63
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/LogData.cs90
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/MSSQL.cs86
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/ServerSetting.cs18
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs41
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/SystemInfo.cs2
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/UISettings.cs43
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/WebModule.cs17
-rw-r--r--Duplicati/Server/WebServer/Server.cs11
-rw-r--r--Duplicati/Server/WebServer/SynologyAuthenticationHandler.cs288
-rw-r--r--Duplicati/Server/packages.config3
-rwxr-xr-xDuplicati/Server/webroot/greeno/images/ajax-loader-16.gifbin1720 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/ajax-loader-32.gifbin3208 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/ajax-loader-66.gifbin6820 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/clock.pngbin927 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/donate.pngbin888 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/generic-file.pngbin308 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/hourglass.pngbin701 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/menu-grey-small.pngbin2396 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/menu-grey.pngbin2396 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/menu-white.pngbin313 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/pause.pngbin2396 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/play.pngbin2396 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/plus.pngbin2396 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/restore.pngbin2396 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/settings.pngbin2396 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/images/small-close.pngbin587 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/index.html713
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/app.js2239
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/config.js10
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/editdialog.js1121
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/edituri.js636
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/folderbrowser.js139
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/hideShowPassword.min.js1
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/jquery-1.11.0.min.js4
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/jquery-1.11.0.min.map1
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/jquery-2.0.3.min.map1
-rwxr-xr-xDuplicati/Server/webroot/greeno/scripts/jquery-ui-1.10.3.min.js7
-rwxr-xr-xDuplicati/Server/webroot/greeno/scripts/jquery.noty.packaged.min.js1
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/jquery.timeago.js214
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/jquery.tmpl.min.js10
-rwxr-xr-xDuplicati/Server/webroot/greeno/scripts/jquery.watermark.min.js8
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/json2.js489
-rwxr-xr-xDuplicati/Server/webroot/greeno/scripts/jstree.js5799
-rwxr-xr-xDuplicati/Server/webroot/greeno/scripts/jstree.min.js4
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/logwindow.js237
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/oldbrowsersupport.js52
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/plugins.js837
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/restoredialog.js972
-rw-r--r--Duplicati/Server/webroot/greeno/scripts/zxcvbn.js45
-rw-r--r--Duplicati/Server/webroot/greeno/stylesheets/common.css148
-rw-r--r--Duplicati/Server/webroot/greeno/stylesheets/editdialog.css302
-rw-r--r--Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/animated-overlay.gifbin1738 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_0_000000_40x100.pngbin205 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_10_365724_40x100.pngbin206 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_50_000000_40x100.pngbin205 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_55_f0f0f0_40x100.pngbin230 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_65_f0f0f0_40x100.pngbin230 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_365724_40x100.pngbin206 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_4e7f33_40x100.pngbin206 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_f0f0f0_40x100.pngbin230 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_95_f0f0f0_40x100.pngbin230 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_365724_256x240.pngbin4549 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_da3c3c_256x240.pngbin4549 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_e5ebe2_256x240.pngbin4549 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/jquery-ui-1.10.3.css1177
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/green-theme/jquery-ui-1.10.3.min.css7
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/jstree/32px.pngbin3121 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/jstree/40px.pngbin1037 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/jstree/style.css916
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/jstree/style.min.css1
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/jstree/throbber.gifbin1720 -> 0 bytes
-rw-r--r--Duplicati/Server/webroot/greeno/stylesheets/logwindow.css51
-rw-r--r--Duplicati/Server/webroot/greeno/stylesheets/main.css514
-rw-r--r--Duplicati/Server/webroot/greeno/stylesheets/restoredialog.css60
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/animated-overlay.gifbin1738 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.pngbin212 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_flat_75_ffffff_40x100.pngbin208 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.pngbin335 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_65_ffffff_1x400.pngbin207 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_75_dadada_1x400.pngbin262 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.pngbin262 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_95_fef1ec_1x400.pngbin332 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.pngbin280 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_222222_256x240.pngbin6922 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_2e83ff_256x240.pngbin4549 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_454545_256x240.pngbin6992 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_888888_256x240.pngbin6999 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_cd0a0a_256x240.pngbin4549 -> 0 bytes
-rwxr-xr-xDuplicati/Server/webroot/greeno/stylesheets/smoothness/jquery-ui-1.10.3.min.css7
-rw-r--r--Duplicati/Server/webroot/img/logo.pngbin0 -> 3270 bytes
-rw-r--r--Duplicati/Server/webroot/index.html2
-rw-r--r--Duplicati/Server/webroot/login.html6
-rw-r--r--Duplicati/Server/webroot/login/cryptojs.js (renamed from Duplicati/Server/webroot/greeno/scripts/cryptojs.js)0
-rw-r--r--Duplicati/Server/webroot/login/jquery-2.0.3.min.js (renamed from Duplicati/Server/webroot/greeno/scripts/jquery-2.0.3.min.js)0
-rw-r--r--Duplicati/Server/webroot/login/jquery-2.0.3.min.map (renamed from Duplicati/Server/webroot/greeno/jquery-2.0.3.min.map)0
-rw-r--r--Duplicati/Server/webroot/login/login.css16
-rw-r--r--Duplicati/Server/webroot/login/login.js8
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/android-icon-144x144.pngbin3606 -> 2247 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/android-icon-192x192.pngbin3383 -> 2489 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/android-icon-36x36.pngbin1664 -> 566 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/android-icon-48x48.pngbin2009 -> 788 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/android-icon-72x72.pngbin2301 -> 1019 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/android-icon-96x96.pngbin2659 -> 1342 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-114x114.pngbin3075 -> 1760 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-120x120.pngbin3138 -> 1839 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-144x144.pngbin3606 -> 2247 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-152x152.pngbin3801 -> 2425 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-180x180.pngbin4423 -> 2809 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-57x57.pngbin2178 -> 894 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-60x60.pngbin2144 -> 890 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-72x72.pngbin2301 -> 1019 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-76x76.pngbin2177 -> 1132 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon-precomposed.pngbin3957 -> 2489 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/apple-icon.pngbin3957 -> 2489 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/favicon-16x16.pngbin1183 -> 308 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/favicon-32x32.pngbin1622 -> 539 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/favicon-96x96.pngbin2659 -> 1342 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/ms-icon-144x144.pngbin3606 -> 2247 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/ms-icon-150x150.pngbin3713 -> 2329 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/ms-icon-310x310.pngbin8612 -> 5884 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/favicon/ms-icon-70x70.pngbin2069 -> 1010 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.eotbin23821 -> 69795 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.svg2784
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.ttfbin66912 -> 216288 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.woffbin27120 -> 88736 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.eotbin25570 -> 73618 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.svg2496
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.ttfbin69140 -> 224936 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.woffbin28700 -> 93516 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.eotbin26223 -> 76817 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.svg2938
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.ttfbin70736 -> 231548 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.woffbin29396 -> 96720 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.eotbin23490 -> 69544 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.svg2904
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.ttfbin67104 -> 215636 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.woffbin26764 -> 88140 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/arrow_collapse_blue.pngbin0 -> 142 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/arrow_collapse_green.pngbin0 -> 141 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/arrow_expand_blue.pngbin0 -> 145 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/arrow_expand_green.pngbin0 -> 144 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/backup.pngbin1759 -> 633 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/clippy.pngbin0 -> 165 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/donate/bitcoin.pngbin3797 -> 3499 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/donate/paypal.pngbin3477 -> 3385 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/about.pngbin0 -> 421 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/add.pngbin1200 -> 233 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/arrow_down.pngbin0 -> 159 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/arrow_right.pngbin0 -> 137 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/home.pngbin0 -> 434 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/log.pngbin1418 -> 384 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/logout.pngbin0 -> 296 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/over/about.pngbin0 -> 422 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/over/add.pngbin1189 -> 224 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/over/arrow_down.pngbin0 -> 148 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/over/arrow_right.pngbin0 -> 130 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/over/home.pngbin0 -> 431 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/over/log.pngbin1356 -> 368 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/over/logout.pngbin0 -> 280 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/over/pause.pngbin1121 -> 168 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/over/restore.pngbin1361 -> 337 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/over/resume.pngbin0 -> 176 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/over/settings.pngbin1573 -> 532 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/pause.pngbin1124 -> 176 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/restore.pngbin1385 -> 346 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/mainmenu/resume.pngbin0 -> 180 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/mainmenu/settings.pngbin1718 -> 559 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/menu.pngbin1014 -> 109 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/menu_active.pngbin1033 -> 109 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/pause.pngbin0 -> 176 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/progress-resume.pngbin0 -> 1799 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/progress-stop.pngbin0 -> 825 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/resume.pngbin0 -> 180 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/social/duplicati.pngbin0 -> 479 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/social/facebook.pngbin1507 -> 597 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/social/ggroups.pngbin5095 -> 4703 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/social/github.pngbin1459 -> 465 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/social/google.pngbin2093 -> 1055 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/img/steps/line-out.pngbin1026 -> 112 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/three_dots.pngbin0 -> 145 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/throttle-inactive.pngbin0 -> 507 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/throttle.pngbin0 -> 602 bytes
-rw-r--r--Duplicati/Server/webroot/ngax/img/treeicons.pngbin8632 -> 8428 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/index.html141
-rwxr-xr-xDuplicati/Server/webroot/ngax/less/fonts.less12
-rwxr-xr-xDuplicati/Server/webroot/ngax/less/form.less104
-rwxr-xr-xDuplicati/Server/webroot/ngax/less/style.less2761
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/angular-gettext-cli_compiled_js_output.js13
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/app.js53
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/AddWizardController.js13
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js176
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/CaptchaController.js21
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/CommandlineController.js174
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/DeleteController.js91
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/DialogController.js26
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/EditBackupController.js264
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/ExportController.js2
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/HomeController.js9
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/ImportController.js36
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/LogController.js14
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/PauseController.js16
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/RestoreController.js51
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/RestoreDirectController.js121
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/RestoreWizardController.js16
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/StateController.js62
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/SystemSettingsController.js52
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/controllers/ThrottleController.js22
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/directives/advancedOptionsEditor.js18
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/directives/backupEditUri.js53
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/directives/parseAdvancedOption.js4
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/directives/parseSizeNumber.js3
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/directives/restoreFilePicker.js18
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/directives/sourceFolderPicker.js152
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/directives/targetFolderPicker.js16
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/directives/timeFormatFixer.js16
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/libs/clipboard.min.js7
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/libs/ngclipboard.min.js4
-rwxr-xr-xDuplicati/Server/webroot/ngax/scripts/menu.js36
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/AppService.js8
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/AppUtils.js94
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/BrandingService.js6
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/CaptchaService.js55
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/DialogService.js36
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/EditUriBackendConfig.js13
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js95
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js24
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js6
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.pngbin212 -> 86 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_75_ffffff_40x100.pngbin208 -> 74 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.pngbin335 -> 183 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_65_ffffff_1x400.pngbin207 -> 73 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_dadada_1x400.pngbin262 -> 126 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.pngbin262 -> 128 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_95_fef1ec_1x400.pngbin332 -> 185 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.pngbin280 -> 122 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_222222_256x240.pngbin6922 -> 3756 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_2e83ff_256x240.pngbin4549 -> 3756 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_454545_256x240.pngbin6992 -> 3756 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_888888_256x240.pngbin6999 -> 3756 bytes
-rwxr-xr-xDuplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_cd0a0a_256x240.pngbin4549 -> 3756 bytes
-rw-r--r--[-rwxr-xr-x]Duplicati/Server/webroot/ngax/styles/style.css4
-rw-r--r--Duplicati/Server/webroot/ngax/styles/styles2.css625
-rw-r--r--Duplicati/Server/webroot/ngax/styles/themes.css59
-rw-r--r--Duplicati/Server/webroot/ngax/templates/about.html2
-rwxr-xr-xDuplicati/Server/webroot/ngax/templates/addoredit.html367
-rw-r--r--Duplicati/Server/webroot/ngax/templates/addwizard.html31
-rw-r--r--Duplicati/Server/webroot/ngax/templates/advancedoptionseditor.html12
-rw-r--r--Duplicati/Server/webroot/ngax/templates/backends/jottacloud.html13
-rw-r--r--Duplicati/Server/webroot/ngax/templates/backends/sia.html17
-rw-r--r--Duplicati/Server/webroot/ngax/templates/captcha.html15
-rw-r--r--Duplicati/Server/webroot/ngax/templates/commandline.html70
-rw-r--r--Duplicati/Server/webroot/ngax/templates/copy_clipboard_buttons.html4
-rw-r--r--Duplicati/Server/webroot/ngax/templates/delete.html59
-rw-r--r--Duplicati/Server/webroot/ngax/templates/edituri.html95
-rw-r--r--Duplicati/Server/webroot/ngax/templates/export.html5
-rw-r--r--Duplicati/Server/webroot/ngax/templates/home.html60
-rw-r--r--Duplicati/Server/webroot/ngax/templates/import.html19
-rw-r--r--Duplicati/Server/webroot/ngax/templates/log.html3
-rw-r--r--Duplicati/Server/webroot/ngax/templates/notificationarea.html7
-rw-r--r--Duplicati/Server/webroot/ngax/templates/pause.html61
-rw-r--r--Duplicati/Server/webroot/ngax/templates/restore.html45
-rw-r--r--Duplicati/Server/webroot/ngax/templates/restoredirect.html101
-rw-r--r--Duplicati/Server/webroot/ngax/templates/restorefilepicker.html10
-rw-r--r--Duplicati/Server/webroot/ngax/templates/restorewizard.html33
-rw-r--r--Duplicati/Server/webroot/ngax/templates/settings.html30
-rw-r--r--Duplicati/Server/webroot/ngax/templates/sourcefolderpicker.html12
-rw-r--r--Duplicati/Server/webroot/ngax/templates/targetfolderpicker.html8
-rw-r--r--Duplicati/Server/webroot/ngax/templates/throttle.html27
-rw-r--r--Duplicati/Server/webroot/oem/greeno/scripts/oem.js1
-rw-r--r--Duplicati/Server/webroot/oem/greeno/stylesheets/oem.css1
-rw-r--r--Duplicati/Server/webroot/theme.html8
-rw-r--r--Duplicati/Service/Duplicati.Service.csproj2
-rw-r--r--Duplicati/Tools/Duplicati.Tools.csproj14
-rw-r--r--Duplicati/UnitTest/BasicSetupHelper.cs2
-rw-r--r--Duplicati/UnitTest/BorderTests.cs63
-rw-r--r--Duplicati/UnitTest/CommandLineOperationsTests.cs7
-rw-r--r--Duplicati/UnitTest/CompressionTests.cs68
-rw-r--r--Duplicati/UnitTest/Duplicati.UnitTest.csproj6
-rw-r--r--Duplicati/UnitTest/PurgeTesting.cs252
-rw-r--r--Duplicati/UnitTest/RandomErrorBackend.cs2
-rw-r--r--Duplicati/UnitTest/SVNCheckoutsTest.cs503
-rw-r--r--Duplicati/UnitTest/SizeOmittingBackend.cs7
-rw-r--r--Duplicati/UnitTest/UtilityTests.cs61
-rw-r--r--Duplicati/UnitTest/packages.config2
-rw-r--r--Duplicati/WindowsService/ServiceControl.cs18
-rw-r--r--Duplicati/WindowsService/WindowsService.csproj2
599 files changed, 29754 insertions, 25907 deletions
diff --git a/Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj b/Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
index 61dfc5f14..5d0066f67 100644
--- a/Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
+++ b/Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
@@ -5,6 +5,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E7280DCA-7776-4A73-B9B5-41FD77FC8799}</ProjectGuid>
<OutputType>Exe</OutputType>
+ <Prefer32Bit>False</Prefer32Bit>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.CommandLine.BackendTester</RootNamespace>
<AssemblyName>Duplicati.CommandLine.BackendTester</AssemblyName>
@@ -17,6 +18,7 @@
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -68,10 +70,18 @@
<Project>{b20a7cee-9c5b-47b9-8b76-bc85adfe8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
+ <Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
+ <Name>Duplicati.Library.Backend.Jottacloud</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
+ <Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
+ <Name>Duplicati.Library.Backend.Sia</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Library\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
diff --git a/Duplicati/CommandLine/BackendTester/Program.cs b/Duplicati/CommandLine/BackendTester/Program.cs
index 6981ebcd6..47a578d3e 100644
--- a/Duplicati/CommandLine/BackendTester/Program.cs
+++ b/Duplicati/CommandLine/BackendTester/Program.cs
@@ -53,6 +53,7 @@ namespace Duplicati.CommandLine.BackendTester
[STAThread]
public static int Main(string[] args)
{
+ Duplicati.Library.AutoUpdater.UpdaterManager.IgnoreWebrootFolder = true;
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args);
}
@@ -160,7 +161,7 @@ namespace Duplicati.CommandLine.BackendTester
try
{
- List<Library.Interface.IFileEntry> curlist = null;
+ IEnumerable<Library.Interface.IFileEntry> curlist = null;
try
{
curlist = backend.List();
@@ -441,10 +442,10 @@ namespace Duplicati.CommandLine.BackendTester
new CommandLineArgument("tempdir", CommandLineArgument.ArgumentType.Path, "The path used to store temporary files", "The backend tester will use the system default temp path. You can set this option to choose another path."),
new CommandLineArgument("extended-chars", CommandLineArgument.ArgumentType.String, "A list of allowed extended filename chars", "A list of characters besides {a-z, A-Z, 0-9} to use when generating filenames", ExtendedChars),
new CommandLineArgument("number-of-files", CommandLineArgument.ArgumentType.Integer, "The number of files to test with", "An integer describing how many files to upload during a test run", "10"),
- new CommandLineArgument("min-file-size", CommandLineArgument.ArgumentType.Size, "The minimum allowed file size", "File sizes are chosen at random, this valus is the lower bound", "1kb"),
- new CommandLineArgument("max-file-size", CommandLineArgument.ArgumentType.Size, "The maximum allowed file size", "File sizes are chosen at random, this valus is the upper bound", "50mb"),
- new CommandLineArgument("min-filename-length", CommandLineArgument.ArgumentType.Integer, "The minimum allowed filename length", "File name lengths are chosen at random, this valus is the lower bound", "5"),
- new CommandLineArgument("max-filename-length", CommandLineArgument.ArgumentType.Integer, "The minimum allowed filename length", "File name lengths are chosen at random, this valus is the upper bound", "80"),
+ new CommandLineArgument("min-file-size", CommandLineArgument.ArgumentType.Size, "The minimum allowed file size", "File sizes are chosen at random, this value is the lower bound", "1kb"),
+ new CommandLineArgument("max-file-size", CommandLineArgument.ArgumentType.Size, "The maximum allowed file size", "File sizes are chosen at random, this value is the upper bound", "50mb"),
+ new CommandLineArgument("min-filename-length", CommandLineArgument.ArgumentType.Integer, "The minimum allowed filename length", "File name lengths are chosen at random, this value is the lower bound", "5"),
+ new CommandLineArgument("max-filename-length", CommandLineArgument.ArgumentType.Integer, "The minimum allowed filename length", "File name lengths are chosen at random, this value is the upper bound", "80"),
new CommandLineArgument("auto-create-folder", CommandLineArgument.ArgumentType.Boolean, "Allows automatic folder creation", "A value that indicates if missing folders are created automatically", "false"),
new CommandLineArgument("skip-overwrite-test", CommandLineArgument.ArgumentType.Boolean, "Bypasses the overwrite test", "A value that indicates if dummy files should be uploaded prior to uploading the real files", "false"),
new CommandLineArgument("auto-clean", CommandLineArgument.ArgumentType.Boolean, "Removes any files found in target folder", "A value that indicates if all files in the target folder should be deleted before starting the first test", "false"),
diff --git a/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj b/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
index faffbc2ed..b992fdc8d 100644
--- a/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
+++ b/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
@@ -5,12 +5,14 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2AF960C0-357D-4D44-A3D5-8B6E89DB0F11}</ProjectGuid>
<OutputType>Exe</OutputType>
+ <Prefer32Bit>False</Prefer32Bit>
<RootNamespace>Duplicati.CommandLine.BackendTool</RootNamespace>
<AssemblyName>Duplicati.CommandLine.BackendTool</AssemblyName>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>..\Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -62,6 +64,10 @@
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
+ <Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
+ <Name>Duplicati.Library.Backend.Jottacloud</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj">
<Project>{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}</Project>
<Name>Duplicati.Library.Backend.S3</Name>
@@ -70,6 +76,10 @@
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
+ <Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
+ <Name>Duplicati.Library.Backend.Sia</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
<Project>{FF2BF37C-E502-4C98-BEA0-701671DDFA08}</Project>
<Name>Duplicati.Library.Backend.SSHv2</Name>
diff --git a/Duplicati/CommandLine/BackendTool/Program.cs b/Duplicati/CommandLine/BackendTool/Program.cs
index a27b3dc83..2f8054575 100644
--- a/Duplicati/CommandLine/BackendTool/Program.cs
+++ b/Duplicati/CommandLine/BackendTool/Program.cs
@@ -19,6 +19,7 @@
#endregion
using System;
using System.Collections.Generic;
+using System.IO;
using System.Text;
using Duplicati.Library.Interface;
@@ -32,6 +33,7 @@ namespace Duplicati.CommandLine.BackendTool
[STAThread]
public static int Main(string[] args)
{
+ Duplicati.Library.AutoUpdater.UpdaterManager.IgnoreWebrootFolder = true;
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args);
}
@@ -57,17 +59,17 @@ namespace Duplicati.CommandLine.BackendTool
string command = null;
if (args.Count >= 2)
{
- if (args[0].Equals("list", StringComparison.InvariantCultureIgnoreCase))
+ if (args[0].Equals("list", StringComparison.OrdinalIgnoreCase))
command = "list";
- else if (args[0].Equals("get", StringComparison.InvariantCultureIgnoreCase))
+ else if (args[0].Equals("get", StringComparison.OrdinalIgnoreCase))
command = "get";
- else if (args[0].Equals("put", StringComparison.InvariantCultureIgnoreCase))
+ else if (args[0].Equals("put", StringComparison.OrdinalIgnoreCase))
command = "put";
- else if (args[0].Equals("delete", StringComparison.InvariantCultureIgnoreCase))
+ else if (args[0].Equals("delete", StringComparison.OrdinalIgnoreCase))
command = "delete";
- else if (args[0].Equals("create-folder", StringComparison.InvariantCultureIgnoreCase))
+ else if (args[0].Equals("create-folder", StringComparison.OrdinalIgnoreCase))
command = "create";
- else if (args[0].Equals("createfolder", StringComparison.InvariantCultureIgnoreCase))
+ else if (args[0].Equals("createfolder", StringComparison.OrdinalIgnoreCase))
command = "create";
}
@@ -92,12 +94,12 @@ namespace Duplicati.CommandLine.BackendTool
using(var backend = Library.DynamicLoader.BackendLoader.GetBackend(args[1], options))
{
if (backend == null)
- throw new Exception("Backend not supported");
+ throw new UserInformationException("Backend not supported");
if (command == "list")
{
if (args.Count != 2)
- throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
+ throw new UserInformationException(string.Format("too many arguments: {0}", string.Join(",", args)));
Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", "Name", "Dir/File", "LastChange", "Size"));
foreach(var e in backend.List())
@@ -108,7 +110,7 @@ namespace Duplicati.CommandLine.BackendTool
else if (command == "create")
{
if (args.Count != 2)
- throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
+ throw new UserInformationException(string.Format("too many arguments: {0}", string.Join(",", args)));
backend.CreateFolder();
@@ -117,33 +119,33 @@ namespace Duplicati.CommandLine.BackendTool
else if (command == "delete")
{
if (args.Count < 3)
- throw new Exception("DELETE requires a filename argument");
+ throw new UserInformationException("DELETE requires a filename argument");
if (args.Count > 3)
throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
- backend.Delete(args[2]);
+ backend.Delete(Path.GetFileName(args[2]));
return 0;
}
else if (command == "get")
{
if (args.Count < 3)
- throw new Exception("GET requires a filename argument");
+ throw new UserInformationException("GET requires a filename argument");
if (args.Count > 3)
- throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
- if (System.IO.File.Exists(args[2]))
- throw new Exception("File already exists, not overwriting!");
- backend.Get(args[2], args[2]);
+ throw new UserInformationException(string.Format("too many arguments: {0}", string.Join(",", args)));
+ if (File.Exists(args[2]))
+ throw new UserInformationException("File already exists, not overwriting!");
+ backend.Get(Path.GetFileName(args[2]), args[2]);
return 0;
}
else if (command == "put")
{
if (args.Count < 3)
- throw new Exception("PUT requires a filename argument");
+ throw new UserInformationException("PUT requires a filename argument");
if (args.Count > 3)
- throw new Exception(string.Format("too many arguments: {0}", string.Join(",", args)));
+ throw new UserInformationException(string.Format("too many arguments: {0}", string.Join(",", args)));
- backend.Put(args[2], args[2]);
+ backend.Put(Path.GetFileName(args[2]), args[2]);
return 0;
}
@@ -155,7 +157,7 @@ namespace Duplicati.CommandLine.BackendTool
catch (Exception ex)
{
Console.WriteLine("Command failed: " + ex.Message);
- if (debugoutput)
+ if (debugoutput || !(ex is UserInformationException))
Console.WriteLine(ex.ToString());
return 100;
}
diff --git a/Duplicati/CommandLine/Commands.cs b/Duplicati/CommandLine/Commands.cs
index 45b37adcd..e66ba7196 100644
--- a/Duplicati/CommandLine/Commands.cs
+++ b/Duplicati/CommandLine/Commands.cs
@@ -18,6 +18,7 @@
using System;
using System.Linq;
using System.Collections.Generic;
+using System.IO;
namespace Duplicati.CommandLine
{
@@ -124,30 +125,31 @@ namespace Duplicati.CommandLine
}
}
- public static int Examples(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int Examples(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
- Duplicati.CommandLine.Help.PrintUsage("example", options);
+ Duplicati.CommandLine.Help.PrintUsage(outwriter, "example", options);
return 0;
}
- public static int Help(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int Help(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
if (args.Count < 1)
- Duplicati.CommandLine.Help.PrintUsage("help", options);
+ Duplicati.CommandLine.Help.PrintUsage(outwriter, "help", options);
else
- Duplicati.CommandLine.Help.PrintUsage(args[0], options);
+ Duplicati.CommandLine.Help.PrintUsage(outwriter, args[0], options);
return 0;
}
- public static int Affected(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int Affected(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
+ var fullresult = Duplicati.Library.Utility.Utility.ParseBoolOption(options, "verbose") || Duplicati.Library.Utility.Utility.ParseBoolOption(options, "full-result");
var backend = args[0];
args.RemoveAt(0);
if (args.Count == 0)
{
- Console.WriteLine("You must specify at least a remote filename");
+ outwriter.WriteLine("You must specify at least a remote filename");
return 200;
}
@@ -170,61 +172,79 @@ namespace Duplicati.CommandLine
options["no-encryption"] = "true";
}
- using(var i = new Library.Main.Controller(backend, options, new ConsoleOutput(options)))
+ using(var i = new Library.Main.Controller(backend, options, new ConsoleOutput(outwriter, options)))
{
- var res = i.ListAffected(args);
-
- if (res.Filesets != null && res.Filesets.Count() != 0)
- {
- Console.WriteLine("The following filesets are affected:");
- foreach(var e in res.Filesets)
- Console.WriteLine("{0}\t: {1}", e.Version, e.Time);
- Console.WriteLine();
- }
+ setup(i);
+ i.ListAffected(args, res =>
+ {
+ if (res.Filesets != null && res.Filesets.Count() != 0)
+ {
+ outwriter.WriteLine("The following filesets are affected:");
+ foreach (var e in res.Filesets)
+ outwriter.WriteLine("{0}\t: {1}", e.Version, e.Time);
+ outwriter.WriteLine();
+ }
- if (res.RemoteVolumes != null && res.RemoteVolumes.Count() != 0)
- {
- }
-
+ if (res.Files != null)
+ {
+ var filecount = res.Files.Count();
+ if (filecount == 0)
+ {
+ outwriter.WriteLine("No files are affected");
+ }
+ else
+ {
+ var c = 0;
+ outwriter.WriteLine("A total of {0} file(s) are affected:", filecount);
+ foreach (var file in res.Files)
+ {
+ c++;
+ outwriter.WriteLine(file.Path);
+ if (c > 10 && filecount > 10 && !fullresult)
+ {
+ outwriter.WriteLine(" ... and {0} more (use --{1} to see all filenames)", filecount - c, "full-result");
+ break;
+ }
+ }
- var filecount = res.Files.Count();
- if (filecount == 0 || (filecount > 10 && !Duplicati.Library.Utility.Utility.ParseBoolOption(options, "verbose")))
- Console.WriteLine("A total of {0} file(s) are affected (use --{1} to see filenames)", res.Files.Count(), "verbose");
- else
- {
- Console.WriteLine("The following files are affected:");
- foreach(var file in res.Files)
- Console.WriteLine(file.Path);
- }
+ }
- Console.WriteLine();
+ outwriter.WriteLine();
+ }
- var logcount = res.LogMessages.Count();
- if (logcount == 0 || (logcount > 10 && !Duplicati.Library.Utility.Utility.ParseBoolOption(options, "verbose")))
- Console.WriteLine("Found {0} related log messages (use --{1} to see the data)", res.Files.Count(), "verbose");
- else
- {
- Console.WriteLine("The following related log messages were found:");
- foreach(var log in res.LogMessages)
- if (log.Message.Length > 100 && !Duplicati.Library.Utility.Utility.ParseBoolOption(options, "verbose"))
- Console.WriteLine("{0}: {1}", log.Timestamp, log.Message.Substring(0, 96) + " ...");
+ if (res.LogMessages != null)
+ {
+ var logcount = res.LogMessages.Count();
+ if (logcount == 0 || (logcount > 10 && !fullresult))
+ outwriter.WriteLine("Found {0} related log messages (use --{1} to see the data)", res.Files.Count(), "full-result");
else
- Console.WriteLine("{0}: {1}", log.Timestamp, log.Message);
- }
+ {
+ outwriter.WriteLine("The following related log messages were found:");
+ foreach (var log in res.LogMessages)
+ if (log.Message.Length > 100 && !fullresult)
+ outwriter.WriteLine("{0}: {1}", log.Timestamp, log.Message.Substring(0, 96) + " ...");
+ else
+ outwriter.WriteLine("{0}: {1}", log.Timestamp, log.Message);
+ }
+
+ outwriter.WriteLine();
+ }
+ });
+
- Console.WriteLine();
return 0;
}
}
- public static int List(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int List(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
filter = filter ?? new Duplicati.Library.Utility.FilterExpression();
if (Duplicati.Library.Utility.Utility.ParseBoolOption(options, "list-sets-only"))
filter = new Duplicati.Library.Utility.FilterExpression();
- using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(options)))
+ using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
{
+ setup(i);
var backend = args[0];
args.RemoveAt(0);
@@ -276,7 +296,14 @@ namespace Duplicati.CommandLine
string passphrase;
options.TryGetValue("passphrase", out passphrase);
if (string.IsNullOrEmpty(passphrase))
- options["no-encryption"] = "true";
+ {
+ string existing;
+ options.TryGetValue("disable-module", out existing);
+ if (string.IsNullOrWhiteSpace(existing))
+ options["disable-module"] = "console-password-input";
+ else
+ options["disable-module"] = string.Join(",", new string[] { existing, "console-password-input" });
+ }
}
@@ -295,7 +322,7 @@ namespace Duplicati.CommandLine
if (isRequestForFiles && !Library.Utility.Utility.ParseBoolOption(options, "all-versions"))
{
- Console.WriteLine("No files matching, looking in all versions");
+ outwriter.WriteLine("No files matching, looking in all versions");
options["all-versions"] = "true";
options.Remove("time");
options.Remove("version");
@@ -304,47 +331,47 @@ namespace Duplicati.CommandLine
if (res.Filesets.Count() != 0 && (res.Files == null || res.Files.Count() == 0) && compareFilter.Empty)
{
- Console.WriteLine("Listing filesets:");
+ outwriter.WriteLine("Listing filesets:");
foreach(var e in res.Filesets)
{
if (e.FileCount >= 0)
- Console.WriteLine("{0}\t: {1} ({2} files, {3})", e.Version, e.Time, e.FileCount, Library.Utility.Utility.FormatSizeString(e.FileSizes));
+ outwriter.WriteLine("{0}\t: {1} ({2} files, {3})", e.Version, e.Time, e.FileCount, Library.Utility.Utility.FormatSizeString(e.FileSizes));
else
- Console.WriteLine("{0}\t: {1}", e.Version, e.Time);
+ outwriter.WriteLine("{0}\t: {1}", e.Version, e.Time);
}
}
else if (isRequestForFiles)
{
- Console.WriteLine("No files matched expression");
+ outwriter.WriteLine("No files matched expression");
}
else
{
if (res.Filesets.Count() == 0)
{
- Console.WriteLine("No time or version matched a fileset");
+ outwriter.WriteLine("No time or version matched a fileset");
}
else if (res.Files == null || res.Files.Count() == 0)
{
- Console.WriteLine("Found {0} filesets, but no files matched", res.Filesets.Count());
+ outwriter.WriteLine("Found {0} filesets, but no files matched", res.Filesets.Count());
}
else if (res.Filesets.Count() == 1)
{
var f = res.Filesets.First();
- Console.WriteLine("Listing contents {0} ({1}):", f.Version, f.Time);
+ outwriter.WriteLine("Listing contents {0} ({1}):", f.Version, f.Time);
foreach(var e in res.Files)
- Console.WriteLine("{0} {1}", e.Path, e.Path.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) ? "" : "(" + Library.Utility.Utility.FormatSizeString(e.Sizes.First()) + ")");
+ outwriter.WriteLine("{0} {1}", e.Path, e.Path.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) ? "" : "(" + Library.Utility.Utility.FormatSizeString(e.Sizes.First()) + ")");
}
else
{
- Console.WriteLine("Listing files and versions:");
+ outwriter.WriteLine("Listing files and versions:");
foreach(var e in res.Files)
{
- Console.WriteLine(e.Path);
+ outwriter.WriteLine(e.Path);
foreach(var nx in res.Filesets.Zip(e.Sizes, (a, b) => new { Index = a.Version, Time = a.Time, Size = b } ))
- Console.WriteLine("{0}\t: {1} {2}", nx.Index, nx.Time, nx.Size < 0 ? " - " : Library.Utility.Utility.FormatSizeString(nx.Size));
+ outwriter.WriteLine("{0}\t: {1} {2}", nx.Index, nx.Time, nx.Size < 0 ? " - " : Library.Utility.Utility.FormatSizeString(nx.Size));
- Console.WriteLine();
+ outwriter.WriteLine();
}
}
@@ -354,34 +381,35 @@ namespace Duplicati.CommandLine
return 0;
}
- public static int Delete(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int Delete(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
var requiredOptions = new string[] { "keep-time", "keep-versions", "version" };
- if (!options.Keys.Where(x => requiredOptions.Contains(x, StringComparer.InvariantCultureIgnoreCase)).Any())
+ if (!options.Keys.Where(x => requiredOptions.Contains(x, StringComparer.OrdinalIgnoreCase)).Any())
{
- Console.WriteLine(Strings.Program.DeleteCommandNeedsOptions("delete", requiredOptions));
+ outwriter.WriteLine(Strings.Program.DeleteCommandNeedsOptions("delete", requiredOptions));
return 200;
}
- using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(options)))
+ using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
{
+ setup(i);
args.RemoveAt(0);
var res = i.Delete();
if (res.DeletedSets.Count() == 0)
{
- Console.WriteLine(Strings.Program.NoFilesetsMatching);
+ outwriter.WriteLine(Strings.Program.NoFilesetsMatching);
}
else
{
if (res.Dryrun)
- Console.WriteLine(Strings.Program.WouldDeleteBackups);
+ outwriter.WriteLine(Strings.Program.WouldDeleteBackups);
else
- Console.WriteLine(Strings.Program.DeletedBackups);
+ outwriter.WriteLine(Strings.Program.DeletedBackups);
foreach(var f in res.DeletedSets)
- Console.WriteLine(string.Format("{0}: {1}", f.Item1, f.Item2));
+ outwriter.WriteLine(string.Format("{0}: {1}", f.Item1, f.Item2));
}
}
@@ -389,21 +417,24 @@ namespace Duplicati.CommandLine
}
- public static int Repair(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int Repair(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
if (args.Count != 1)
- return PrintWrongNumberOfArguments(args, 1);
+ return PrintWrongNumberOfArguments(outwriter, args, 1);
- using(var i = new Duplicati.Library.Main.Controller(args[0], options, new ConsoleOutput(options)))
+ using (var i = new Duplicati.Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
+ {
+ setup(i);
i.Repair(filter);
+ }
return 0;
}
- public static int Restore(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int Restore(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
if (args.Count < 1)
- return PrintWrongNumberOfArguments(args, 1);
+ return PrintWrongNumberOfArguments(outwriter, args, 1);
string backend = args[0];
args.RemoveAt(0);
@@ -421,53 +452,62 @@ namespace Duplicati.CommandLine
if (args[ix].IndexOfAny(new char[] { '*', '?' }) < 0 && !args[ix].StartsWith("[") && args[ix].EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
args[ix] += "*";
- var output = new ConsoleOutput(options);
+ var output = new ConsoleOutput(outwriter, options);
output.MessageEvent(string.Format("Restore started at {0}", DateTime.Now));
- using(var i = new Library.Main.Controller(backend, options, output))
+ using (var i = new Library.Main.Controller(backend, options, output))
+ {
+ setup(i);
if (controlFiles)
{
var res = i.RestoreControlFiles(args.ToArray(), filter);
output.MessageEvent("Restore control files completed:");
- foreach(var s in res.Files)
- Console.WriteLine(s);
+ foreach (var s in res.Files)
+ outwriter.WriteLine(s);
}
else
{
- using(var periodicOutput = new PeriodicOutput(output, TimeSpan.FromSeconds(5)))
+ using (var periodicOutput = new PeriodicOutput(output, TimeSpan.FromSeconds(5)))
{
- output.PhaseChanged += (phase, previousPhase) => {
- if (phase == Duplicati.Library.Main.OperationPhase.Restore_PreRestoreVerify)
- output.MessageEvent("Checking remote backup ...");
- else if (phase == Duplicati.Library.Main.OperationPhase.Restore_ScanForExistingFiles)
- output.MessageEvent("Checking existing target files ...");
- /*else if (phase == Duplicati.Library.Main.OperationPhase.Restore_DownloadingRemoteFiles)
- output.MessageEvent("Downloading remote files ..."); */
- else if (phase == Duplicati.Library.Main.OperationPhase.Restore_PatchWithLocalBlocks)
- output.MessageEvent("Updating target files with local data ...");
- else if (phase == Duplicati.Library.Main.OperationPhase.Restore_PostRestoreVerify)
+ output.PhaseChanged += (phase, previousPhase) =>
+ {
+ switch (phase)
{
- periodicOutput.SetFinished();
- periodicOutput.Join(TimeSpan.FromMilliseconds(100));
- output.MessageEvent("Verifying restored files ...");
+ case Duplicati.Library.Main.OperationPhase.Restore_PreRestoreVerify:
+ output.MessageEvent("Checking remote backup ...");
+ break;
+ case Duplicati.Library.Main.OperationPhase.Restore_ScanForExistingFiles:
+ output.MessageEvent("Checking existing target files ...");
+ break;
+ case Duplicati.Library.Main.OperationPhase.Restore_PatchWithLocalBlocks:
+ output.MessageEvent("Updating target files with local data ...");
+ break;
+ case Duplicati.Library.Main.OperationPhase.Restore_PostRestoreVerify:
+ periodicOutput.SetFinished();
+ periodicOutput.Join(TimeSpan.FromMilliseconds(100));
+ output.MessageEvent("Verifying restored files ...");
+ break;
+ case Duplicati.Library.Main.OperationPhase.Restore_ScanForLocalBlocks:
+ output.MessageEvent("Scanning local files for needed data ...");
+ break;
+ case Duplicati.Library.Main.OperationPhase.Restore_CreateTargetFolders:
+ periodicOutput.SetReady();
+ break;
}
- else if (phase == Duplicati.Library.Main.OperationPhase.Restore_ScanForLocalBlocks)
- output.MessageEvent("Scanning local files for needed data ...");
- else if (phase == Duplicati.Library.Main.OperationPhase.Restore_CreateTargetFolders)
- periodicOutput.SetReady();
};
-
- periodicOutput.WriteOutput += (progress, files, size, counting) => {
+
+ periodicOutput.WriteOutput += (progress, files, size, counting) =>
+ {
output.MessageEvent(string.Format(" {0} files need to be restored ({1})", files, Library.Utility.Utility.FormatSizeString(size)));
};
-
+
var res = i.Restore(args.ToArray(), filter);
string restorePath;
options.TryGetValue("restore-path", out restorePath);
-
+
output.MessageEvent(string.Format("Restored {0} ({1}) files to {2}", res.FilesRestored, Library.Utility.Utility.FormatSizeString(res.SizeOfRestoredFiles), string.IsNullOrEmpty(restorePath) ? "original path" : restorePath));
output.MessageEvent(string.Format("Duration of restore: {0:hh\\:mm\\:ss}", res.Duration));
-
+
if (res.FilesRestored > 0 && !Library.Main.Utility.SuppressDonationMessages)
{
output.MessageEvent("***********************************************");
@@ -477,27 +517,28 @@ namespace Duplicati.CommandLine
output.MessageEvent("Bitcoin: 1L74qa1n5SFKwwyHhECTHBJgcf6WT2rJKf");
output.MessageEvent("***********************************************");
}
-
+
if (output.VerboseOutput)
- Library.Utility.Utility.PrintSerializeObject(res, Console.Out);
+ Library.Utility.Utility.PrintSerializeObject(res, outwriter);
if (res.Warnings.Count() > 0)
return 2;
}
}
+ }
return 0;
}
- public static int Backup(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int Backup(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
if (args.Count < 2)
- return PrintWrongNumberOfArguments(args, 2);
+ return PrintWrongNumberOfArguments(outwriter, args, 2);
var backend = args[0];
args.RemoveAt(0);
var dirs = args.ToArray();
- var output = new ConsoleOutput(options);
+ var output = new ConsoleOutput(outwriter, options);
Library.Interface.IBackupResults result;
@@ -509,50 +550,73 @@ namespace Duplicati.CommandLine
{
if (previousPhase == Duplicati.Library.Main.OperationPhase.Backup_PostBackupTest)
output.MessageEvent("Remote backup verification completed");
-
- if (phase == Duplicati.Library.Main.OperationPhase.Backup_ProcessingFiles)
+
+ switch (phase)
{
- output.MessageEvent("Scanning local files ...");
- periodicOutput.SetReady();
+ case Duplicati.Library.Main.OperationPhase.Backup_ProcessingFiles:
+ output.MessageEvent("Scanning local files ...");
+ periodicOutput.SetReady();
+ break;
+ case Duplicati.Library.Main.OperationPhase.Backup_Finalize:
+ periodicOutput.SetFinished();
+ break;
+ case Duplicati.Library.Main.OperationPhase.Backup_PreBackupVerify:
+ output.MessageEvent("Checking remote backup ...");
+ break;
+ case Duplicati.Library.Main.OperationPhase.Backup_PostBackupVerify:
+ output.MessageEvent("Checking remote backup ...");
+ break;
+ case Duplicati.Library.Main.OperationPhase.Backup_PostBackupTest:
+ output.MessageEvent("Verifying remote backup ...");
+ break;
+ case Duplicati.Library.Main.OperationPhase.Backup_Compact:
+ output.MessageEvent("Compacting remote backup ...");
+ break;
}
- else if (phase == Duplicati.Library.Main.OperationPhase.Backup_Finalize)
- periodicOutput.SetFinished();
- else if (phase == Duplicati.Library.Main.OperationPhase.Backup_PreBackupVerify)
- output.MessageEvent("Checking remote backup ...");
- else if (phase == Duplicati.Library.Main.OperationPhase.Backup_PostBackupVerify)
- output.MessageEvent("Checking remote backup ...");
- else if (phase == Duplicati.Library.Main.OperationPhase.Backup_PostBackupTest)
- output.MessageEvent("Verifying remote backup ...");
- else if (phase == Duplicati.Library.Main.OperationPhase.Backup_Compact)
- output.MessageEvent("Compacting remote backup ...");
};
periodicOutput.WriteOutput += (progress, files, size, counting) => {
output.MessageEvent(string.Format(" {0} files need to be examined ({1}){2}", files, Library.Utility.Utility.FormatSizeString(size), counting ? " (still counting)" : ""));
};
-
- using(var i = new Library.Main.Controller(backend, options, output))
+
+ using (var i = new Library.Main.Controller(backend, options, output))
+ {
+ setup(i);
result = i.Backup(dirs, filter);
+ }
}
if (output.VerboseOutput)
{
- Library.Utility.Utility.PrintSerializeObject(result, Console.Out);
+ Library.Utility.Utility.PrintSerializeObject(result, outwriter);
}
else
{
var parsedStats = result.BackendStatistics as Duplicati.Library.Interface.IParsedBackendStatistics;
output.MessageEvent(string.Format(" Duration of backup: {0:hh\\:mm\\:ss}", result.Duration));
- if (parsedStats != null && parsedStats.KnownFileCount > 0)
+ if (parsedStats != null)
{
- output.MessageEvent(string.Format(" Remote files: {0}", parsedStats.KnownFileCount));
- output.MessageEvent(string.Format(" Remote size: {0}", Library.Utility.Utility.FormatSizeString(parsedStats.KnownFileSize)));
+ if (parsedStats.KnownFileCount > 0)
+ {
+ output.MessageEvent(string.Format(" Remote files: {0}", parsedStats.KnownFileCount));
+ output.MessageEvent(string.Format(" Remote size: {0}", Library.Utility.Utility.FormatSizeString(parsedStats.KnownFileSize)));
+ }
+
+ if (parsedStats.TotalQuotaSpace >= 0)
+ {
+ output.MessageEvent(string.Format(" Total remote quota: {0}", Library.Utility.Utility.FormatSizeString(parsedStats.TotalQuotaSpace)));
+ }
+
+ if (parsedStats.FreeQuotaSpace >= 0)
+ {
+ output.MessageEvent(string.Format(" Available remote quota: {0}", Library.Utility.Utility.FormatSizeString(parsedStats.FreeQuotaSpace)));
+ }
}
output.MessageEvent(string.Format(" Files added: {0}", result.AddedFiles));
output.MessageEvent(string.Format(" Files deleted: {0}", result.DeletedFiles));
output.MessageEvent(string.Format(" Files changed: {0}", result.ModifiedFiles));
-
+
output.MessageEvent(string.Format(" Data uploaded: {0}", Library.Utility.Utility.FormatSizeString(result.BackendStatistics.BytesUploaded)));
output.MessageEvent(string.Format(" Data downloaded: {0}", Library.Utility.Utility.FormatSizeString(result.BackendStatistics.BytesDownloaded)));
}
@@ -566,8 +630,12 @@ namespace Duplicati.CommandLine
if (result.PartialBackup)
return 50;
+ //Completed with errors = 3
+ if (result.ParsedResult == Library.Interface.ParsedResultType.Error)
+ return 3;
+
//Completed with warnings = 2
- if (result.Warnings.Count() > 0 || result.Errors.Count() > 0)
+ if (result.ParsedResult == Library.Interface.ParsedResultType.Warning)
return 2;
//Success, but no upload = 1
@@ -577,89 +645,103 @@ namespace Duplicati.CommandLine
return 0;
}
- public static int Compact(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int Compact(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
if (args.Count != 1)
- return PrintWrongNumberOfArguments(args, 1);
-
- using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(options)))
+ return PrintWrongNumberOfArguments(outwriter, args, 1);
+
+ using (var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
+ {
+ setup(i);
i.Compact();
+ }
return 0;
}
- public static int Test(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int Test(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
+ var verbose = Library.Utility.Utility.ParseBoolOption(options, "verbose") || Duplicati.Library.Utility.Utility.ParseBoolOption(options, "full-result");
if (args.Count != 1 && args.Count != 2)
- return PrintWrongNumberOfArguments(args, 1);
+ return PrintWrongNumberOfArguments(outwriter, args, 1);
var tests = 1L;
if (args.Count == 2)
{
- if (new string[] { "all", "everything" }.Contains(args[1], StringComparer.InvariantCultureIgnoreCase))
+ if (new string[] { "all", "everything" }.Contains(args[1], StringComparer.OrdinalIgnoreCase))
tests = long.MaxValue;
else
tests = Convert.ToInt64(args[1]);
}
Library.Interface.ITestResults result;
- using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(options)))
+ using (var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
+ {
+ setup(i);
result = i.Test(tests);
+ }
- var totalFiles = result.Changes.Count();
+ var totalFiles = result.Verifications.Count();
if (totalFiles == 0)
{
- Console.WriteLine("No files examined, is the remote destination is empty?");
+ outwriter.WriteLine("No files examined, is the remote destination is empty?");
+ return 100;
}
else
{
- var filtered = from n in result.Changes where n.Value.Count() != 0 select n;
+ var filtered = from n in result.Verifications where n.Value.Count() != 0 select n;
if (filtered.Count() == 0)
- Console.WriteLine("Examined {0} files and found no errors", totalFiles);
+ {
+ outwriter.WriteLine("Examined {0} files and found no errors", totalFiles);
+ return 0;
+ }
else
{
- if (Library.Utility.Utility.ParseBoolOption(options, "verbose"))
+ foreach(var n in result.Verifications)
{
- foreach(var n in result.Changes)
+ var changecount = n.Value.Count();
+ if (changecount == 0)
{
- var changecount = n.Value.Count();
- if (changecount == 0)
+ if (verbose)
Console.WriteLine("{0}: No errors", n.Key);
- else
+ }
+ else
+ {
+ Console.WriteLine("{0}: {1} errors", n.Key, changecount);
+ var count = 0;
+ foreach (var c in n.Value)
{
- Console.WriteLine("{0}: {1} errors", n.Key, changecount);
- foreach(var c in n.Value)
- Console.WriteLine("{0}: {1}", c.Key, c.Value);
- Console.WriteLine();
+ count++;
+ Console.WriteLine("\t{0}: {1}", c.Key, c.Value);
+ if (!verbose && count == 10 && changecount > 10)
+ {
+ Console.WriteLine("\t... and {0} more", changecount - count);
+ break;
+ }
}
+
+ Console.WriteLine();
}
}
- else
- {
- Console.WriteLine("Examined {0} files and found errors in the following files:", totalFiles);
- foreach(var n in filtered)
- Console.WriteLine(n.Key);
- Console.WriteLine();
- }
- }
+ return 3;
+ }
}
- return 0;
}
- private static int PrintWrongNumberOfArguments(List<string> args, int expected)
+ private static int PrintWrongNumberOfArguments(TextWriter outwriter, List<string> args, int expected)
{
- Console.WriteLine(Strings.Program.WrongNumberOfCommandsError_v2(args.Count, expected, args.Select(n => "\"" + n + "\"").ToArray()));
+ outwriter.WriteLine(Strings.Program.WrongNumberOfCommandsError_v2(args.Count, expected, args.Select(n => "\"" + n + "\"").ToArray()));
return 200;
}
- public static int PrintInvalidCommand(string command, List<string> args)
+ public static int PrintInvalidCommand(TextWriter outwriter, string command, List<string> args)
{
- Console.WriteLine(Strings.Program.InvalidCommandError(command));
+ outwriter.WriteLine(Strings.Program.InvalidCommandError(command));
return 200;
}
- public static int CreateBugReport(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int CreateBugReport(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
// Support for not adding the --auth-username if possible
string dbpath = null;
@@ -671,7 +753,7 @@ namespace Duplicati.CommandLine
if (dbpath == null)
{
- Console.WriteLine("No local database found, please add --{0}", "dbpath");
+ outwriter.WriteLine("No local database found, please add --{0}", "dbpath");
return 100;
}
else
@@ -683,24 +765,29 @@ namespace Duplicati.CommandLine
args = new List<string>(new string[] { "file://unused", "report" });
else if (args.Count == 1)
args.Add("report");
-
- using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(options)))
+
+ using (var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
+ {
+ setup(i);
i.CreateLogDatabase(args[1]);
+ }
- Console.WriteLine("Completed!");
- Console.WriteLine();
- Console.WriteLine("Please examine the log table of the database to see that no filenames are accidentially left over.");
- Console.WriteLine("If you are concerned that your filenames may contain sensitive information,");
- Console.WriteLine(" do not attach the database to an issue!!!");
- Console.WriteLine();
+ outwriter.WriteLine("Completed!");
+ outwriter.WriteLine();
+ outwriter.WriteLine("Please examine the log table of the database to see that no filenames are accidentially left over.");
+ outwriter.WriteLine("If you are concerned that your filenames may contain sensitive information,");
+ outwriter.WriteLine(" do not attach the database to an issue!!!");
+ outwriter.WriteLine();
return 0;
}
- public static int ListChanges(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int ListChanges(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
+ var fullresult = Duplicati.Library.Utility.Utility.ParseBoolOption(options, "verbose") || Duplicati.Library.Utility.Utility.ParseBoolOption(options, "full-result");
+
if (args.Count < 1)
- return PrintWrongNumberOfArguments(args, 1);
+ return PrintWrongNumberOfArguments(outwriter, args, 1);
// Support for not adding the --auth-username if possible
string dbpath;
@@ -720,123 +807,281 @@ namespace Duplicati.CommandLine
if (string.IsNullOrEmpty(passphrase))
options["no-encryption"] = "true";
}
+
+ Action<Duplicati.Library.Interface.IListChangesResults, IEnumerable<Tuple<Library.Interface.ListChangesChangeType, Library.Interface.ListChangesElementType, string>>> handler =
+ (result, items) =>
+ {
+ outwriter.WriteLine("Listing changes");
+ outwriter.WriteLine(" {0}: {1}", result.BaseVersionIndex, result.BaseVersionTimestamp);
+ outwriter.WriteLine(" {0}: {1}", result.CompareVersionIndex, result.CompareVersionTimestamp);
+ outwriter.WriteLine();
+
+ outwriter.WriteLine("Size of backup {0}: {1}", result.BaseVersionIndex, Library.Utility.Utility.FormatSizeString(result.PreviousSize));
+
+ if (items != null)
+ {
+ outwriter.WriteLine();
+
+ var added = result.ChangeDetails.Where(x => x.Item1 == Library.Interface.ListChangesChangeType.Added);
+ var deleted = result.ChangeDetails.Where(x => x.Item1 == Library.Interface.ListChangesChangeType.Deleted);
+ var modified = result.ChangeDetails.Where(x => x.Item1 == Library.Interface.ListChangesChangeType.Modified);
+
+ var count = added.Count();
+ if (count > 0)
+ {
+ var c = 0;
+ outwriter.WriteLine(" {0} added entries:", count);
+ foreach (var n in added)
+ {
+ c++;
+ outwriter.WriteLine(" + {0}", n.Item3);
+ if (c > 10 && count > 10 && !fullresult)
+ {
+ outwriter.WriteLine(" ... and {0} more", count - c);
+ break;
+ }
+ }
+ outwriter.WriteLine();
+ }
+ count = modified.Count();
+ if (count > 0)
+ {
+ var c = 0;
+ outwriter.WriteLine(" {0} modified entries:", count);
+ foreach (var n in modified)
+ {
+ c++;
+ outwriter.WriteLine(" ~ {0}", n.Item3);
+ if (c > 10 && count > 10 && !fullresult)
+ {
+ outwriter.WriteLine(" ... and {0} more", count - c);
+ break;
+ }
+ }
+ outwriter.WriteLine();
+ }
+ count = deleted.Count();
+ if (count > 0)
+ {
+ var c = 0;
+ outwriter.WriteLine("{0} deleted entries:", count);
+ foreach (var n in deleted)
+ {
+ c++;
+ outwriter.WriteLine(" - {0}", n.Item3);
+ if (c > 10 && count > 10 && !fullresult)
+ {
+ outwriter.WriteLine(" ... and {0} more", count - c);
+ break;
+ }
+ }
+ outwriter.WriteLine();
+ }
+
+ outwriter.WriteLine();
+ }
+
+
+ if (result.AddedFolders > 0)
+ outwriter.WriteLine(" Added folders: {0}", result.AddedFolders);
+ if (result.AddedSymlinks > 0)
+ outwriter.WriteLine(" Added symlinks: {0}", result.AddedSymlinks);
+ if (result.AddedFiles > 0)
+ outwriter.WriteLine(" Added files: {0}", result.AddedFiles);
+ if (result.DeletedFolders > 0)
+ outwriter.WriteLine(" Deleted folders: {0}", result.DeletedFolders);
+ if (result.DeletedSymlinks > 0)
+ outwriter.WriteLine(" Deleted symlinks: {0}", result.DeletedSymlinks);
+ if (result.DeletedFiles > 0)
+ outwriter.WriteLine(" Deleted files: {0}", result.DeletedFiles);
+ if (result.ModifiedFolders > 0)
+ outwriter.WriteLine(" Modified folders: {0}", result.ModifiedFolders);
+ if (result.ModifiedSymlinks > 0)
+ outwriter.WriteLine(" Modified symlinka: {0}", result.ModifiedSymlinks);
+ if (result.ModifiedFiles > 0)
+ outwriter.WriteLine(" Modified files: {0}", result.ModifiedFiles);
+
+ if (result.AddedFolders + result.AddedSymlinks + result.AddedFolders +
+ result.ModifiedFolders + result.ModifiedSymlinks + result.ModifiedFiles +
+ result.DeletedFolders + result.DeletedSymlinks + result.DeletedFiles == 0)
+ outwriter.WriteLine(" No changes found");
+
+ outwriter.WriteLine("Size of backup {0}: {1}", result.CompareVersionIndex, Library.Utility.Utility.FormatSizeString(result.CurrentSize));
+ };
- Library.Interface.IListChangesResults result;
- using(var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(options)))
- if (args.Count == 2)
- result = i.ListChanges(null, args[1], null, filter);
- else
- result = i.ListChanges(args.Count > 1 ? args[1] : null, args.Count > 2 ? args[2] : null, null, filter);
-
- Console.WriteLine("Listing changes");
- Console.WriteLine(" {0}: {1}", result.BaseVersionIndex, result.BaseVersionTimestamp);
- Console.WriteLine(" {0}: {1}", result.CompareVersionIndex, result.CompareVersionTimestamp);
- Console.WriteLine();
-
- Console.WriteLine("Size of backup {0}: {1}", result.BaseVersionIndex, Library.Utility.Utility.FormatSizeString(result.PreviousSize));
-
- if (result.ChangeDetails != null)
- {
- Console.WriteLine();
-
- var added = result.ChangeDetails.Where(x => x.Item1 == Library.Interface.ListChangesChangeType.Added);
- var deleted = result.ChangeDetails.Where(x => x.Item1 == Library.Interface.ListChangesChangeType.Deleted);
- var modified = result.ChangeDetails.Where(x => x.Item1 == Library.Interface.ListChangesChangeType.Modified);
-
- var count = added.Count();
- if (count > 0)
- {
- Console.WriteLine(" {0} added entries:", count);
- foreach(var n in added)
- Console.WriteLine(" + {0}", n.Item3);
- Console.WriteLine();
- }
- count = modified.Count();
- if (count > 0)
- {
- Console.WriteLine(" {0} modified entries:", count);
- foreach(var n in modified)
- Console.WriteLine(" ~ {0}", n.Item3);
- Console.WriteLine();
- }
- count = deleted.Count();
- if (count > 0)
- {
- Console.WriteLine("{0} deleted entries:", count);
- foreach(var n in deleted)
- Console.WriteLine(" - {0}", n.Item3);
- Console.WriteLine();
- }
-
- Console.WriteLine();
- }
- else
+ using (var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
{
- if (result.AddedFolders > 0)
- Console.WriteLine(" Added folders: {0}", result.AddedFolders);
- if (result.AddedSymlinks > 0)
- Console.WriteLine(" Added symlinks: {0}", result.AddedSymlinks);
- if (result.AddedFiles > 0)
- Console.WriteLine(" Added files: {0}", result.AddedFiles);
- if (result.DeletedFolders > 0)
- Console.WriteLine(" Deleted folders: {0}", result.DeletedFolders);
- if (result.DeletedSymlinks > 0)
- Console.WriteLine(" Deleted symlinks: {0}", result.DeletedSymlinks);
- if (result.DeletedFiles > 0)
- Console.WriteLine(" Deleted files: {0}", result.DeletedFiles);
- if (result.ModifiedFolders > 0)
- Console.WriteLine(" Modified folders: {0}", result.ModifiedFolders);
- if (result.ModifiedSymlinks > 0)
- Console.WriteLine(" Modified symlinka: {0}", result.ModifiedSymlinks);
- if (result.ModifiedFiles > 0)
- Console.WriteLine(" Modified files: {0}", result.ModifiedFiles);
-
- if (result.AddedFolders + result.AddedSymlinks + result.AddedFolders +
- result.ModifiedFolders + result.ModifiedSymlinks + result.ModifiedFiles +
- result.DeletedFolders + result.DeletedSymlinks + result.DeletedFiles == 0)
- Console.WriteLine(" No changes found");
+ setup(i);
+ if (args.Count == 2)
+ i.ListChanges(null, args[1], null, filter, handler);
+ else
+ i.ListChanges(args.Count > 1 ? args[1] : null, args.Count > 2 ? args[2] : null, null, filter, handler);
}
-
- Console.WriteLine("Size of backup {0}: {1}", result.CompareVersionIndex, Library.Utility.Utility.FormatSizeString(result.CurrentSize));
-
+
return 0;
}
- public static int TestFilters(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int TestFilters(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
if (args == null || args.Count < 1)
{
- Console.WriteLine("No source paths given");
+ outwriter.WriteLine("No source paths given");
return 200;
}
options["verbose"] = "true";
- using(var i = new Library.Main.Controller("dummy://", options, new ConsoleOutput(options)))
+ using(var i = new Library.Main.Controller("dummy://", options, new ConsoleOutput(outwriter, options)))
{
+ setup(i);
var result = i.TestFilter(args.ToArray(), filter);
- Console.WriteLine("Matched {0} files ({1})", result.FileCount, Duplicati.Library.Utility.Utility.FormatSizeString(result.FileSize));
+ outwriter.WriteLine("Matched {0} files ({1})", result.FileCount, Duplicati.Library.Utility.Utility.FormatSizeString(result.FileSize));
}
return 0;
}
- public static int SystemInfo(List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ public static int SystemInfo(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
{
if (args != null && args.Count != 0)
{
- Console.WriteLine("Command takes no arguments");
+ outwriter.WriteLine("Command takes no arguments");
return 200;
}
- using(var i = new Library.Main.Controller("dummy://", options, new ConsoleOutput(options)))
- foreach(var line in i.SystemInfo().Lines)
- Console.WriteLine(line);
+ using (var i = new Library.Main.Controller("dummy://", options, new ConsoleOutput(outwriter, options)))
+ {
+ setup(i);
+ foreach (var line in i.SystemInfo().Lines)
+ outwriter.WriteLine(line);
+ }
+
+ outwriter.WriteLine("Know locales: {0}", string.Join(", ", Library.Localization.LocalizationService.AllLocales));
+ outwriter.WriteLine("Translated locales: {0}", string.Join(", ", Library.Localization.LocalizationService.SupportedCultures));
+
+ return 0;
+ }
+
+ public static int PurgeFiles(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ {
+ if (args.Count < 1)
+ return PrintWrongNumberOfArguments(outwriter, args, 1);
- Console.WriteLine("Know locales: {0}", string.Join(", ", Library.Localization.LocalizationService.AllLocales));
- Console.WriteLine("Translated locales: {0}", string.Join(", ", Library.Localization.LocalizationService.SupportedCultures));
+ var backend = args[0];
+ var paths = args.Skip(1).ToArray();
+
+ if (paths.Length > 0)
+ {
+ if (filter == null || filter.Empty)
+ filter = new Library.Utility.FilterExpression(paths);
+ else
+ {
+ outwriter.WriteLine("You cannot combine filters and paths on the commandline");
+ return 200;
+ }
+ }
+ else if (filter == null || filter.Empty)
+ {
+ outwriter.WriteLine("You must provide either filename filters, or a list of paths to remove");
+ return 200;
+ }
+
+ using (var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
+ {
+ setup(i);
+ i.PurgeFiles(filter);
+ }
+
+ return 0;
+ }
+
+ public static int ListBrokenFiles(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ {
+ if (args.Count != 1)
+ return PrintWrongNumberOfArguments(outwriter, args, 1);
+
+ var con = new ConsoleOutput(outwriter, options);
+ var previd = -1L;
+ var outputcount = 0L;
+ var verbose = Duplicati.Library.Utility.Utility.ParseBoolOption(options, "verbose") || Duplicati.Library.Utility.Utility.ParseBoolOption(options, "full-result");
+
+ using (var i = new Library.Main.Controller(args[0], options, con))
+ {
+ setup(i);
+ i.ListBrokenFiles(filter, (id, time, count, path, size) =>
+ {
+ if (previd != id)
+ {
+ previd = id;
+ outputcount = 0;
+ con.MessageEvent(string.Format("{0}\t: {1}\t({2} match(es))", id, time.ToLocalTime(), count));
+ }
+
+ con.MessageEvent(string.Format("\t{0} ({1})", path, Library.Utility.Utility.FormatSizeString(size)));
+ outputcount++;
+ if (outputcount >= 5 && !verbose && count != outputcount)
+ {
+ con.MessageEvent(string.Format("\t ... and {0} more, (use --{1} to list all)", count - outputcount, "full-result"));
+ return false;
+ }
+
+ return true;
+
+ });
+ }
+
+ return 0;
+ }
+
+ public static int PurgeBrokenFiles(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ {
+ if (args.Count != 1)
+ return PrintWrongNumberOfArguments(outwriter, args, 1);
+
+ using (var i = new Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
+ {
+ setup(i);
+ var res = i.PurgeBrokenFiles(filter);
+ }
+
+ return 0;
+ }
+
+ public static int SendMail(TextWriter outwriter, Action<Duplicati.Library.Main.Controller> setup, List<string> args, Dictionary<string, string> options, Library.Utility.IFilter filter)
+ {
+ if (args != null && args.Count != 0)
+ {
+ outwriter.WriteLine("Command takes no arguments");
+ return 200;
+ }
+
+ using (var i = new Library.Main.Controller("dummy://", options, new ConsoleOutput(outwriter, options)))
+ {
+ setup(i);
+ foreach (var l in i.SendMail().Lines)
+ outwriter.WriteLine(l);
+ }
+
+ return 0;
+ }
+
+ public static int Vacuum(
+ TextWriter outwriter,
+ Action<Duplicati.Library.Main.Controller> setup,
+ List<string> args, Dictionary<string, string> options,
+ Library.Utility.IFilter filter)
+ {
+ if (args.Count != 1)
+ return PrintWrongNumberOfArguments(outwriter, args, 1);
+
+ using (
+ var controller = new Library.Main.Controller(args[0], options, new ConsoleOutput(outwriter, options)))
+ {
+ setup(controller);
+ controller.Vacuum();
+ }
return 0;
}
}
diff --git a/Duplicati/CommandLine/ConsoleOutput.cs b/Duplicati/CommandLine/ConsoleOutput.cs
index 593d5d3c5..d64d59f34 100644
--- a/Duplicati/CommandLine/ConsoleOutput.cs
+++ b/Duplicati/CommandLine/ConsoleOutput.cs
@@ -17,6 +17,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Collections.Generic;
+using System.IO;
using Duplicati.Library.Main;
namespace Duplicati.CommandLine
@@ -28,9 +29,11 @@ namespace Duplicati.CommandLine
public bool QuietConsole { get; private set; }
public bool VerboseOutput { get; private set; }
public bool VerboseErrors { get; private set; }
+ public TextWriter Output { get; private set; }
- public ConsoleOutput(Dictionary<string, string> options)
+ public ConsoleOutput(TextWriter output, Dictionary<string, string> options)
{
+ this.Output = output;
this.QuietConsole = Library.Utility.Utility.ParseBoolOption(options, "quiet-console");
this.VerboseOutput = Library.Utility.Utility.ParseBoolOption(options, "verbose");
this.VerboseErrors = Library.Utility.Utility.ParseBoolOption(options, "debug-output");
@@ -69,16 +72,24 @@ namespace Duplicati.CommandLine
lock(m_lock)
if (type == BackendEventType.Started)
{
- if (action == BackendActionType.Put)
- Console.WriteLine(" Uploading file ({0}) ...", Library.Utility.Utility.FormatSizeString(size));
- else if (action == BackendActionType.Get)
- Console.WriteLine(" Downloading file ({0}) ...", size < 0 ? "unknown" : Library.Utility.Utility.FormatSizeString(size));
- else if (action == BackendActionType.List)
- Console.WriteLine(" Listing remote folder ...");
- else if (action == BackendActionType.CreateFolder)
- Console.WriteLine(" Creating remote folder ...");
- else if (action == BackendActionType.Delete)
- Console.WriteLine(" Deleting file {0}{1} ...", path, size < 0 ? "" : (" (" + Library.Utility.Utility.FormatSizeString(size) + ")"));
+ switch (action)
+ {
+ case BackendActionType.Put:
+ Output.WriteLine(" Uploading file ({0}) ...", Library.Utility.Utility.FormatSizeString(size));
+ break;
+ case BackendActionType.Get:
+ Output.WriteLine(" Downloading file ({0}) ...", size < 0 ? "unknown" : Library.Utility.Utility.FormatSizeString(size));
+ break;
+ case BackendActionType.List:
+ Output.WriteLine(" Listing remote folder ...");
+ break;
+ case BackendActionType.CreateFolder:
+ Output.WriteLine(" Creating remote folder ...");
+ break;
+ case BackendActionType.Delete:
+ Output.WriteLine(" Deleting file {0}{1} ...", path, size < 0 ? "" : (" (" + Library.Utility.Utility.FormatSizeString(size) + ")"));
+ break;
+ }
}
}
@@ -86,37 +97,38 @@ namespace Duplicati.CommandLine
{
if (VerboseOutput)
lock(m_lock)
- Console.WriteLine(message, args);
+ Output.WriteLine(message, args);
}
public void MessageEvent(string message)
{
if (!QuietConsole)
lock(m_lock)
- Console.WriteLine(message);
+ Output.WriteLine(message);
}
public void RetryEvent(string message, Exception ex)
{
if (!QuietConsole)
lock(m_lock)
- Console.WriteLine(ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message));
+ Output.WriteLine(ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message));
}
public void WarningEvent(string message, Exception ex)
{
if (!QuietConsole)
lock(m_lock)
- Console.WriteLine(ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message));
+ Output.WriteLine(ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message));
}
public void ErrorEvent(string message, Exception ex)
{
if (!QuietConsole)
lock(m_lock)
- Console.WriteLine(ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message));
+ Output.WriteLine(ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message));
}
public void DryrunEvent(string message)
{
- lock(m_lock)
- Console.WriteLine(string.Format("[Dryrun]: {0}", message));
+ if (!QuietConsole)
+ lock(m_lock)
+ Output.WriteLine(string.Format("[Dryrun]: {0}", message));
}
#endregion
}
diff --git a/Duplicati/CommandLine/Duplicati.CommandLine.csproj b/Duplicati/CommandLine/Duplicati.CommandLine.csproj
index 659271287..c105aabb8 100644
--- a/Duplicati/CommandLine/Duplicati.CommandLine.csproj
+++ b/Duplicati/CommandLine/Duplicati.CommandLine.csproj
@@ -5,6 +5,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{81765A64-3661-4E3E-B850-2F6F87A51F74}</ProjectGuid>
<OutputType>Exe</OutputType>
+ <Prefer32Bit>False</Prefer32Bit>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.CommandLine</RootNamespace>
<AssemblyName>Duplicati.CommandLine</AssemblyName>
@@ -18,6 +19,7 @@
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -62,10 +64,18 @@
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
<Name>Duplicati.Library.Backend.File</Name>
</ProjectReference>
+ <ProjectReference Include="..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
+ <Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
+ <Name>Duplicati.Library.Backend.Jottacloud</Name>
+ </ProjectReference>
<ProjectReference Include="..\Library\Backend\SharePoint\Duplicati.Library.Backend.SharePoint.csproj">
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
+ <ProjectReference Include="..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
+ <Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
+ <Name>Duplicati.Library.Backend.Sia</Name>
+ </ProjectReference>
<ProjectReference Include="..\Library\Compression\Duplicati.Library.Compression.csproj">
<Project>{19ECCE09-B5EB-406C-8C57-BAC66997D469}</Project>
<Name>Duplicati.Library.Compression</Name>
diff --git a/Duplicati/CommandLine/Help.cs b/Duplicati/CommandLine/Help.cs
index e14576559..c088eb0c7 100644
--- a/Duplicati/CommandLine/Help.cs
+++ b/Duplicati/CommandLine/Help.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text;
@@ -13,7 +14,7 @@ namespace Duplicati.CommandLine
static Help()
{
- _document = new Dictionary<string,string>(StringComparer.InvariantCultureIgnoreCase);
+ _document = new Dictionary<string,string>(StringComparer.OrdinalIgnoreCase);
using (System.IO.StreamReader sr = new System.IO.StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(RESOURCE_NAME)))
{
@@ -37,9 +38,9 @@ namespace Duplicati.CommandLine
}
string[] elems = line.Split(new string[] {" ", "\t"}, StringSplitOptions.RemoveEmptyEntries);
- if (elems.Length >= 2 && string.Equals(elems[elems.Length - 2], "help", StringComparison.InvariantCultureIgnoreCase))
+ if (elems.Length >= 2 && string.Equals(elems[elems.Length - 2], "help", StringComparison.OrdinalIgnoreCase))
keywords.Add(elems[elems.Length - 1]);
- else if (elems.Length == 3 && string.Equals(elems[elems.Length - 1], "help", StringComparison.InvariantCultureIgnoreCase))
+ else if (elems.Length == 3 && string.Equals(elems[elems.Length - 1], "help", StringComparison.OrdinalIgnoreCase))
keywords.Add("help");
}
else
@@ -57,13 +58,16 @@ namespace Duplicati.CommandLine
}
}
- public static void PrintUsage(string topic, IDictionary<string, string> options)
+ public static void PrintUsage(TextWriter outwriter, string topic, IDictionary<string, string> options)
{
try
{
- //Force translation off
- System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
- System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture;
+ //Force translation off if this is from the commandline
+ if (Program.FROM_COMMANDLINE)
+ {
+ System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
+ System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture;
+ }
}
catch
{
@@ -72,13 +76,13 @@ namespace Duplicati.CommandLine
if (string.IsNullOrWhiteSpace(topic))
topic = "help";
- if (string.Equals("help", topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals("help", topic, StringComparison.OrdinalIgnoreCase))
{
if (options.Count == 1)
topic = new List<string>(options.Keys)[0];
- else if (System.Environment.CommandLine.IndexOf("--exclude", StringComparison.InvariantCultureIgnoreCase) >= 0)
+ else if (System.Environment.CommandLine.IndexOf("--exclude", StringComparison.OrdinalIgnoreCase) >= 0)
topic = "exclude";
- else if (System.Environment.CommandLine.IndexOf("--include", StringComparison.InvariantCultureIgnoreCase) >= 0)
+ else if (System.Environment.CommandLine.IndexOf("--include", StringComparison.OrdinalIgnoreCase) >= 0)
topic = "include";
}
@@ -93,14 +97,36 @@ namespace Duplicati.CommandLine
tp = tp.Replace("%MONO%", Library.Utility.Utility.IsMono ? "mono " : "");
tp = tp.Replace("%APP_PATH%", System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location));
tp = tp.Replace("%PATH_SEPARATOR%", System.IO.Path.PathSeparator.ToString());
- tp = tp.Replace("%EXAMPLE_SOURCE_PATH%", Library.Utility.Utility.IsClientLinux ? "/source" : "D:\\source");
- tp = tp.Replace("%EXAMPLE_SOURCE_FILE%", Library.Utility.Utility.IsClientLinux ? "/source/myfile.txt" : "D:\\source\\file.txt");
- tp = tp.Replace("%EXAMPLE_RESTORE_PATH%", Library.Utility.Utility.IsClientLinux ? "/restore" : "D:\\restore");
+ tp = tp.Replace("%EXAMPLE_SOURCE_PATH%", Library.Utility.Utility.IsClientLinux ? "/source" : @"D:\source");
+ tp = tp.Replace("%EXAMPLE_SOURCE_FILE%", Library.Utility.Utility.IsClientLinux ? "/source/myfile.txt" : @"D:\source\file.txt");
+ tp = tp.Replace("%EXAMPLE_RESTORE_PATH%", Library.Utility.Utility.IsClientLinux ? "/restore" : @"D:\restore");
tp = tp.Replace("%ENCRYPTIONMODULES%", string.Join(", ", Library.DynamicLoader.EncryptionLoader.Keys));
tp = tp.Replace("%COMPRESSIONMODULES%", string.Join(", ", Library.DynamicLoader.CompressionLoader.Keys));
tp = tp.Replace("%DEFAULTENCRYPTIONMODULE%", opts.EncryptionModule);
tp = tp.Replace("%DEFAULTCOMPRESSIONMODULE%", opts.CompressionModule);
tp = tp.Replace("%GENERICMODULES%", string.Join(", ", Library.DynamicLoader.GenericLoader.Keys));
+
+ tp = tp.Replace("%COMMON_FILTERS%", string.Join(Environment.NewLine + " ", Library.Utility.DefaultFilters.Common.OrderBy(x => x)));
+ tp = tp.Replace("%WINDOWS_FILTERS%", string.Join(Environment.NewLine + " ", Library.Utility.DefaultFilters.Windows.OrderBy(x => x)));
+ tp = tp.Replace("%OSX_FILTERS%", string.Join(Environment.NewLine + " ", Library.Utility.DefaultFilters.OSX.OrderBy(x => x)));
+ tp = tp.Replace("%LINUX_FILTERS%", string.Join(Environment.NewLine + " ", Library.Utility.DefaultFilters.Linux.OrderBy(x => x)));
+
+ if (Library.Utility.Utility.IsClientWindows)
+ {
+ // These properties are only valid for Windows
+ tp = tp.Replace("%EXAMPLE_WILDCARD_DRIVE_SOURCE_PATH%", @"*:\source");
+ tp = tp.Replace("%EXAMPLE_VOLUME_GUID_SOURCE_PATH%", @"\\?\Volume{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\source");
+ tp = tp.Replace("%KNOWN_DRIVES_AND_VOLUMES%", string.Join(Environment.NewLine + " ", Library.Utility.Utility.GetVolumeGuidsAndDriveLetters().Select(pair => string.Format("{0} {1}", pair.Key, pair.Value))));
+
+ // We don't need to hide things between these tags on Windows
+ tp = tp.Replace("%IF_WINDOWS%", string.Empty);
+ tp = tp.Replace("%END_IF_WINDOWS%", string.Empty);
+ }
+ else
+ {
+ // Specifying the Singleline option allows . to match newlines, so this will detect spans that cover multiple lines
+ tp = System.Text.RegularExpressions.Regex.Replace(tp, @"\%IF_WINDOWS\%.*\%END_IF_WINDOWS\%", string.Empty, System.Text.RegularExpressions.RegexOptions.Singleline);
+ }
if (tp.Contains("%MAINOPTIONS%"))
{
@@ -109,7 +135,7 @@ namespace Duplicati.CommandLine
foreach (Library.Interface.ICommandLineArgument arg in opts.SupportedCommands)
sorted.Add(arg.Name, arg);
- foreach (Library.Interface.ICommandLineArgument arg in Program.SupportedCommands)
+ foreach (Library.Interface.ICommandLineArgument arg in Program.SupportedOptions)
sorted[arg.Name] = arg;
foreach (Library.Interface.ICommandLineArgument arg in sorted.Values)
@@ -125,7 +151,7 @@ namespace Duplicati.CommandLine
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
- foreach (Library.Interface.ICommandLineArgument arg in Program.SupportedCommands)
+ foreach (Library.Interface.ICommandLineArgument arg in Program.SupportedOptions)
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
lines.Add("");
@@ -165,7 +191,7 @@ namespace Duplicati.CommandLine
IList<Library.Interface.ICommandLineArgument> args = null;
bool found = false;
foreach (Duplicati.Library.Interface.IBackend backend in Library.DynamicLoader.BackendLoader.Backends)
- if (string.Equals(backend.ProtocolKey, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(backend.ProtocolKey, topic, StringComparison.OrdinalIgnoreCase))
{
args = backend.SupportedCommands;
found = true;
@@ -174,7 +200,7 @@ namespace Duplicati.CommandLine
if (args == null)
foreach (Duplicati.Library.Interface.IEncryption module in Library.DynamicLoader.EncryptionLoader.Modules)
- if (string.Equals(module.FilenameExtension, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(module.FilenameExtension, topic, StringComparison.OrdinalIgnoreCase))
{
args = module.SupportedCommands;
found = true;
@@ -183,7 +209,7 @@ namespace Duplicati.CommandLine
if (args == null)
foreach (Duplicati.Library.Interface.ICompression module in Library.DynamicLoader.CompressionLoader.Modules)
- if (string.Equals(module.FilenameExtension, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(module.FilenameExtension, topic, StringComparison.OrdinalIgnoreCase))
{
args = module.SupportedCommands;
found = true;
@@ -192,7 +218,7 @@ namespace Duplicati.CommandLine
if (args == null)
foreach (Duplicati.Library.Interface.IGenericModule module in Library.DynamicLoader.GenericLoader.Modules)
- if (string.Equals(module.Key, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(module.Key, topic, StringComparison.OrdinalIgnoreCase))
{
args = module.SupportedCommands;
found = true;
@@ -204,11 +230,11 @@ namespace Duplicati.CommandLine
tp = tp.Replace("%MODULEOPTIONS%", PrintArgsSimple(args));
else
{
- Console.WriteLine("Topic not found: {0}", topic);
- Console.WriteLine();
+ outwriter.WriteLine("Topic not found: {0}", topic);
+ outwriter.WriteLine();
//Prevent recursive lookups
if (topic != "help")
- PrintUsage("help", new Dictionary<string, string>());
+ PrintUsage(outwriter, "help", new Dictionary<string, string>());
return;
}
}
@@ -216,14 +242,14 @@ namespace Duplicati.CommandLine
if (NAMEDOPTION_REGEX.IsMatch(tp))
tp = NAMEDOPTION_REGEX.Replace(tp, new Matcher().MathEvaluator);
- PrintFormatted(tp.Split(new string[] { Environment.NewLine }, StringSplitOptions.None));
+ PrintFormatted(outwriter, tp.Split(new string[] { Environment.NewLine }, StringSplitOptions.None));
}
else
{
List<string> lines = new List<string>();
foreach (Duplicati.Library.Interface.IBackend backend in Library.DynamicLoader.BackendLoader.Backends)
- if (string.Equals(backend.ProtocolKey, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(backend.ProtocolKey, topic, StringComparison.OrdinalIgnoreCase))
{
PrintBackend(backend, lines);
break;
@@ -231,7 +257,7 @@ namespace Duplicati.CommandLine
if (lines.Count == 0)
foreach (Duplicati.Library.Interface.IEncryption mod in Library.DynamicLoader.EncryptionLoader.Modules)
- if (string.Equals(mod.FilenameExtension, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(mod.FilenameExtension, topic, StringComparison.OrdinalIgnoreCase))
{
PrintEncryptionModule(mod, lines);
break;
@@ -239,7 +265,7 @@ namespace Duplicati.CommandLine
if (lines.Count == 0)
foreach (Duplicati.Library.Interface.ICompression mod in Library.DynamicLoader.CompressionLoader.Modules)
- if (string.Equals(mod.FilenameExtension, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(mod.FilenameExtension, topic, StringComparison.OrdinalIgnoreCase))
{
PrintCompressionModule(mod, lines);
break;
@@ -247,7 +273,7 @@ namespace Duplicati.CommandLine
if (lines.Count == 0)
foreach (Duplicati.Library.Interface.IGenericModule mod in Library.DynamicLoader.GenericLoader.Modules)
- if (string.Equals(mod.Key, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(mod.Key, topic, StringComparison.OrdinalIgnoreCase))
{
PrintGenericModule(mod, lines);
break;
@@ -259,13 +285,13 @@ namespace Duplicati.CommandLine
if (lines.Count != 0)
{
- PrintFormatted(lines);
+ PrintFormatted(outwriter, lines);
}
else
{
- Console.WriteLine("Topic not found: {0}", topic);
- Console.WriteLine();
- PrintUsage("help", new Dictionary<string, string>());
+ outwriter.WriteLine("Topic not found: {0}", topic);
+ outwriter.WriteLine();
+ PrintUsage(outwriter, "help", new Dictionary<string, string>());
}
}
}
@@ -277,7 +303,7 @@ namespace Duplicati.CommandLine
foreach (Duplicati.Library.Interface.ICommandLineArgument arg in args)
{
- if (string.Equals(arg.Name, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(arg.Name, topic, StringComparison.OrdinalIgnoreCase))
{
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
return;
@@ -286,7 +312,7 @@ namespace Duplicati.CommandLine
if (arg.Aliases != null)
foreach (string k in arg.Aliases)
{
- if (string.Equals(k, topic, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(k, topic, StringComparison.OrdinalIgnoreCase))
{
Library.Interface.CommandLineArgument.PrintArgument(lines, arg, " ");
return;
@@ -361,14 +387,15 @@ namespace Duplicati.CommandLine
}
- private static void PrintFormatted(IEnumerable<string> lines)
+ private static void PrintFormatted(TextWriter outwriter, IEnumerable<string> lines)
{
int windowWidth = 80;
try
{
// This can go wrong if we have no attached console
- windowWidth = Math.Max(12, Console.WindowWidth == 0 ? 80 : Console.WindowWidth);
+ if (outwriter == Console.Out)
+ windowWidth = Math.Max(12, Console.WindowWidth == 0 ? 80 : Console.WindowWidth);
}
catch { }
@@ -376,7 +403,7 @@ namespace Duplicati.CommandLine
{
if (string.IsNullOrEmpty(s) || s.Trim().Length == 0)
{
- Console.WriteLine();
+ outwriter.WriteLine();
continue;
}
@@ -402,7 +429,7 @@ namespace Duplicati.CommandLine
len = ix;
}
- Console.WriteLine(leadingSpaces + c.Substring(0, len).Trim());
+ outwriter.WriteLine(leadingSpaces + c.Substring(0, len).Trim());
c = c.Remove(0, len);
if (extraIndent)
{
@@ -415,13 +442,13 @@ namespace Duplicati.CommandLine
private class Matcher
{
- Dictionary<string, Library.Interface.ICommandLineArgument> args = new Dictionary<string, Library.Interface.ICommandLineArgument>(StringComparer.InvariantCultureIgnoreCase);
+ Dictionary<string, Library.Interface.ICommandLineArgument> args = new Dictionary<string, Library.Interface.ICommandLineArgument>(StringComparer.OrdinalIgnoreCase);
public Matcher()
{
List<IList<Library.Interface.ICommandLineArgument>> foundArgs = new List<IList<Library.Interface.ICommandLineArgument>>();
foundArgs.Add(new Library.Main.Options(new Dictionary<string, string>()).SupportedCommands);
- foundArgs.Add(Program.SupportedCommands);
+ foundArgs.Add(Program.SupportedOptions);
foreach (Duplicati.Library.Interface.IBackend backend in Library.DynamicLoader.BackendLoader.Backends)
if (backend.SupportedCommands != null)
diff --git a/Duplicati/CommandLine/Program.cs b/Duplicati/CommandLine/Program.cs
index 6deb3fa92..3d6239d9e 100644
--- a/Duplicati/CommandLine/Program.cs
+++ b/Duplicati/CommandLine/Program.cs
@@ -22,40 +22,34 @@ using System.Collections.Generic;
using System.Text;
using System.Linq;
using Duplicati.Library.Localization.Short;
+using Duplicati.Library.Utility;
+using System.IO;
namespace Duplicati.CommandLine
{
public class Program
{
+ public static bool FROM_COMMANDLINE = false;
+
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static int Main(string[] args)
{
+ Duplicati.Library.AutoUpdater.UpdaterManager.IgnoreWebrootFolder = true;
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args);
}
public static int RealMain(string[] args)
{
Library.UsageReporter.Reporter.Initialize();
-
- bool verboseErrors = false;
- bool verbose = false;
+ FROM_COMMANDLINE = true;
try
{
- List<string> cargs = new List<string>(args);
-
- var tmpparsed = Library.Utility.FilterCollector.ExtractOptions(cargs);
- var options = tmpparsed.Item1;
- var filter = tmpparsed.Item2;
-
- verboseErrors = Library.Utility.Utility.ParseBoolOption(options, "debug-output");
- verbose = Library.Utility.Utility.ParseBoolOption(options, "verbose");
-
//If we are on Windows, append the bundled "win-tools" programs to the search path
//We add it last, to allow the user to override with other versions
- if (!Library.Utility.Utility.IsClientLinux)
+ if (Library.Utility.Utility.IsClientWindows)
{
string wintools = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "win-tools");
Environment.SetEnvironmentVariable("PATH",
@@ -67,22 +61,88 @@ namespace Duplicati.CommandLine
);
}
- if (cargs.Count == 1 && string.Equals(cargs[0], "changelog", StringComparison.InvariantCultureIgnoreCase))
+ return RunCommandLine(Console.Out, Console.Error, c => { }, args);
+ }
+ finally
+ {
+ Library.UsageReporter.Reporter.ShutDown();
+ }
+ }
+
+ private static Dictionary<string, Func<TextWriter, Action<Library.Main.Controller>, List<string>, Dictionary<string, string>, Library.Utility.IFilter, int>> CommandMap
+ {
+ get
+ {
+ var knownCommands = new Dictionary<string, Func<TextWriter, Action<Library.Main.Controller>, List<string>, Dictionary<string, string>, Library.Utility.IFilter, int>>(StringComparer.OrdinalIgnoreCase);
+ knownCommands["help"] = Commands.Help;
+ knownCommands["example"] = Commands.Examples;
+ knownCommands["examples"] = Commands.Examples;
+
+ knownCommands["find"] = Commands.List;
+ knownCommands["list"] = Commands.List;
+
+ knownCommands["delete"] = Commands.Delete;
+ knownCommands["backup"] = Commands.Backup;
+ knownCommands["restore"] = Commands.Restore;
+
+ knownCommands["repair"] = Commands.Repair;
+ knownCommands["purge"] = Commands.PurgeFiles;
+ knownCommands["list-broken-files"] = Commands.ListBrokenFiles;
+ knownCommands["purge-broken-files"] = Commands.PurgeBrokenFiles;
+
+ knownCommands["compact"] = Commands.Compact;
+ knownCommands["create-report"] = Commands.CreateBugReport;
+ knownCommands["compare"] = Commands.ListChanges;
+ knownCommands["test"] = Commands.Test;
+ knownCommands["verify"] = Commands.Test;
+ knownCommands["test-filters"] = Commands.TestFilters;
+ knownCommands["test-filter"] = Commands.TestFilters;
+ knownCommands["affected"] = Commands.Affected;
+ knownCommands["vacuum"] = Commands.Vacuum;
+
+ knownCommands["system-info"] = Commands.SystemInfo;
+ knownCommands["systeminfo"] = Commands.SystemInfo;
+
+ knownCommands["send-mail"] = Commands.SendMail;
+
+ return knownCommands;
+ }
+ }
+
+ public static IEnumerable<string> SupportedCommands { get { return CommandMap.Keys; } }
+
+ public static int RunCommandLine(TextWriter outwriter, TextWriter errwriter, Action<Library.Main.Controller> setup, string[] args)
+ {
+
+ bool verboseErrors = false;
+ bool verbose = false;
+ try
+ {
+ List<string> cargs = new List<string>(args);
+
+ var tmpparsed = Library.Utility.FilterCollector.ExtractOptions(cargs);
+ var options = tmpparsed.Item1;
+ var filter = tmpparsed.Item2;
+
+ verboseErrors = Library.Utility.Utility.ParseBoolOption(options, "debug-output");
+ verbose = Library.Utility.Utility.ParseBoolOption(options, "verbose");
+
+ if (cargs.Count == 1 && string.Equals(cargs[0], "changelog", StringComparison.OrdinalIgnoreCase))
{
var path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "changelog.txt");
- Console.WriteLine(System.IO.File.ReadAllText(path));
+ outwriter.WriteLine(System.IO.File.ReadAllText(path));
return 0;
}
foreach (string internaloption in Library.Main.Options.InternalOptions)
if (options.ContainsKey(internaloption))
{
- Console.WriteLine(Strings.Program.InternalOptionUsedError(internaloption));
+ outwriter.WriteLine(Strings.Program.InternalOptionUsedError(internaloption));
return 200;
}
-
+
// Probe for "help" to avoid extra processing
- bool isHelp = cargs.Count == 0 || (cargs.Count >= 1 && string.Equals(cargs[0], "help", StringComparison.InvariantCultureIgnoreCase));
+ bool isHelp = cargs.Count == 0 || (cargs.Count >= 1 && string.Equals(cargs[0], "help", StringComparison.OrdinalIgnoreCase));
if (!isHelp && ((options.ContainsKey("parameters-file") && !string.IsNullOrEmpty("parameters-file")) || (options.ContainsKey("parameter-file") && !string.IsNullOrEmpty("parameter-file")) || (options.ContainsKey("parameterfile") && !string.IsNullOrEmpty("parameterfile"))))
{
string filename;
@@ -102,7 +162,7 @@ namespace Duplicati.CommandLine
options.Remove("parameterfile");
}
- if (!ReadOptionsFromFile(filename, ref filter, cargs, options))
+ if (!ReadOptionsFromFile(outwriter, filename, ref filter, cargs, options))
return 100;
}
@@ -114,9 +174,9 @@ namespace Duplicati.CommandLine
}
else
command = "help";
-
+
// Update probe for help
- isHelp = string.Equals(command, "help", StringComparison.InvariantCultureIgnoreCase);
+ isHelp = string.Equals(command, "help", StringComparison.OrdinalIgnoreCase);
// Skip the env read if the command is help, otherwise we may report weirdness
if (!isHelp)
@@ -124,60 +184,37 @@ namespace Duplicati.CommandLine
if (!options.ContainsKey("passphrase"))
if (!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("PASSPHRASE")))
options["passphrase"] = System.Environment.GetEnvironmentVariable("PASSPHRASE");
-
+
if (!options.ContainsKey("auth-password"))
if (!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("AUTH_PASSWORD")))
options["auth-password"] = System.Environment.GetEnvironmentVariable("AUTH_PASSWORD");
-
+
if (!options.ContainsKey("auth-username"))
if (!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("AUTH_USERNAME")))
options["auth-username"] = System.Environment.GetEnvironmentVariable("AUTH_USERNAME");
}
-
- var knownCommands = new Dictionary<string, Func<List<string>, Dictionary<string, string>, Library.Utility.IFilter, int>>(StringComparer.InvariantCultureIgnoreCase);
- knownCommands["help"] = Commands.Help;
- knownCommands["example"] = Commands.Examples;
- knownCommands["examples"] = Commands.Examples;
- knownCommands["find"] = Commands.List;
- knownCommands["list"] = Commands.List;
-
- knownCommands["delete"] = Commands.Delete;
- knownCommands["backup"] = Commands.Backup;
- knownCommands["restore"] = Commands.Restore;
-
- knownCommands["repair"] = Commands.Repair;
-
- knownCommands["compact"] = Commands.Compact;
- knownCommands["create-report"] = Commands.CreateBugReport;
- knownCommands["compare"] = Commands.ListChanges;
- knownCommands["test"] = Commands.Test;
- knownCommands["verify"] = Commands.Test;
- knownCommands["test-filters"] = Commands.TestFilters;
- knownCommands["test-filter"] = Commands.TestFilters;
- knownCommands["affected"] = Commands.Affected;
-
- knownCommands["system-info"] = Commands.SystemInfo;
- knownCommands["systeminfo"] = Commands.SystemInfo;
+ var knownCommands = CommandMap;
if (!isHelp && verbose)
{
- Console.WriteLine("Input command: {0}", command);
-
- Console.WriteLine("Input arguments: ");
- foreach(var a in cargs)
- Console.WriteLine("\t{0}", a);
- Console.WriteLine();
-
- Console.WriteLine("Input options: ");
- foreach(var n in options)
- Console.WriteLine("{0}: {1}", n.Key, n.Value);
- Console.WriteLine();
+ outwriter.WriteLine("Input command: {0}", command);
+
+ outwriter.WriteLine("Input arguments: ");
+ foreach (var a in cargs)
+ outwriter.WriteLine("\t{0}", a);
+ outwriter.WriteLine();
+
+ outwriter.WriteLine("Input options: ");
+ foreach (var n in options)
+ outwriter.WriteLine("{0}: {1}", n.Key, n.Value);
+ outwriter.WriteLine();
}
- Duplicati.Library.Utility.TempFile.RemoveOldApplicationTempFiles((path, ex) => {
+ Duplicati.Library.Utility.TempFile.RemoveOldApplicationTempFiles((path, ex) =>
+ {
if (verbose)
- Console.WriteLine(string.Format("Failed to delete temp file: {0}", path));
+ outwriter.WriteLine(string.Format("Failed to delete temp file: {0}", path));
});
var autoupdate = Library.Utility.Utility.ParseBoolOption(options, "auto-update");
@@ -185,9 +222,9 @@ namespace Duplicati.CommandLine
if (knownCommands.ContainsKey(command))
{
- var res = knownCommands[command](cargs, options, filter);
+ var res = knownCommands[command](outwriter, setup, cargs, options, filter);
- if (autoupdate)
+ if (autoupdate && FROM_COMMANDLINE)
{
var update = Library.AutoUpdater.UpdaterManager.LastUpdateCheckVersion;
if (update == null)
@@ -195,17 +232,18 @@ namespace Duplicati.CommandLine
if (update != null && update.Version != Library.AutoUpdater.UpdaterManager.SelfVersion.Version)
{
- Console.WriteLine("Found update \"{0}\", downloading ...", update.Displayname);
+ outwriter.WriteLine("Found update \"{0}\", downloading ...", update.Displayname);
long lastpg = 0;
- Library.AutoUpdater.UpdaterManager.DownloadAndUnpackUpdate(update, f => {
- var npg = (long)(f*100);
+ Library.AutoUpdater.UpdaterManager.DownloadAndUnpackUpdate(update, f =>
+ {
+ var npg = (long)(f * 100);
if (Math.Abs(npg - lastpg) >= 5 || (npg == 100 && lastpg != 100))
{
lastpg = npg;
- Console.WriteLine("Downloading {0}% ...", npg);
+ outwriter.WriteLine("Downloading {0}% ...", npg);
}
});
- Console.WriteLine("Update \"{0}\" ({1}) installed, using on next launch", update.Displayname, update.Version);
+ outwriter.WriteLine("Update \"{0}\" ({1}) installed, using on next launch", update.Displayname, update.Version);
}
}
@@ -213,7 +251,7 @@ namespace Duplicati.CommandLine
}
else
{
- Commands.PrintInvalidCommand(command, cargs);
+ Commands.PrintInvalidCommand(outwriter, command, cargs);
return 200;
}
}
@@ -224,23 +262,25 @@ namespace Duplicati.CommandLine
while (ex is System.Reflection.TargetInvocationException && ex.InnerException != null)
ex = ex.InnerException;
- if (!(ex is Library.Interface.CancelException))
+ if (ex is Duplicati.Library.Interface.UserInformationException && !verboseErrors)
{
- if (!string.IsNullOrEmpty(ex.Message))
- {
- Console.Error.WriteLine();
- Console.Error.WriteLine(verboseErrors ? ex.ToString() : ex.Message);
- }
+ errwriter.WriteLine();
+ errwriter.WriteLine(ex.Message);
+ }
+ else if (!(ex is Library.Interface.CancelException))
+ {
+ errwriter.WriteLine();
+ errwriter.WriteLine(ex.ToString());
}
else
{
- Console.Error.WriteLine(Strings.Program.UnhandledException(ex.ToString()));
+ errwriter.WriteLine(Strings.Program.UnhandledException(ex.ToString()));
while (ex.InnerException != null)
{
ex = ex.InnerException;
- Console.Error.WriteLine();
- Console.Error.WriteLine(Strings.Program.UnhandledInnerException(ex.ToString()));
+ errwriter.WriteLine();
+ errwriter.WriteLine(Strings.Program.UnhandledInnerException(ex.ToString()));
}
}
@@ -249,7 +289,7 @@ namespace Duplicati.CommandLine
}
}
- public static IList<Library.Interface.ICommandLineArgument> SupportedCommands
+ public static IList<Library.Interface.ICommandLineArgument> SupportedOptions
{
get
{
@@ -264,7 +304,7 @@ namespace Duplicati.CommandLine
}
}
- private static bool ReadOptionsFromFile(string filename, ref Library.Utility.IFilter filter, List<string> cargs, Dictionary<string, string> options)
+ private static bool ReadOptionsFromFile(TextWriter outwriter, string filename, ref Library.Utility.IFilter filter, List<string> cargs, Dictionary<string, string> options)
{
try
{
@@ -311,7 +351,7 @@ namespace Duplicati.CommandLine
// If the user specifies parameters-file, all filters must be in the file.
// Allowing to specify some filters on the command line could result in wrong filter ordering
if (!filter.Empty && !newfilter.Empty)
- throw new Exception(Strings.Program.FiltersCannotBeUsedWithFileError2);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.Program.FiltersCannotBeUsedWithFileError2);
if (!newfilter.Empty)
filter = newfilter;
@@ -336,16 +376,16 @@ namespace Duplicati.CommandLine
cargs[1] = newtarget;
}
- if (cargs.Count >= 1 && cargs[0].Equals("backup", StringComparison.InvariantCultureIgnoreCase))
+ if (cargs.Count >= 1 && cargs[0].Equals("backup", StringComparison.OrdinalIgnoreCase))
cargs.AddRange(newsource);
else if (newsource.Count > 0 && Library.Utility.Utility.ParseBoolOption(options, "verbose"))
- Console.WriteLine(Strings.Program.SkippingSourceArgumentsOnNonBackupOperation);
+ outwriter.WriteLine(Strings.Program.SkippingSourceArgumentsOnNonBackupOperation);
return true;
}
catch (Exception e)
{
- Console.WriteLine(Strings.Program.FailedToParseParametersFileError(filename, e.Message));
+ outwriter.WriteLine(Strings.Program.FailedToParseParametersFileError(filename, e.Message));
return false;
}
}
diff --git a/Duplicati/CommandLine/RecoveryTool/Download.cs b/Duplicati/CommandLine/RecoveryTool/Download.cs
index e15635224..2a22a36ac 100644
--- a/Duplicati/CommandLine/RecoveryTool/Download.cs
+++ b/Duplicati/CommandLine/RecoveryTool/Download.cs
@@ -17,6 +17,7 @@
using System;
using System.IO;
using System.Collections.Generic;
+using System.Linq;
namespace Duplicati.CommandLine.RecoveryTool
{
@@ -48,7 +49,7 @@ namespace Duplicati.CommandLine.RecoveryTool
Console.WriteLine("Listing files on backend: {0} ...", backend.ProtocolKey);
- var lst = backend.List();
+ var lst = backend.List().ToList();
Console.WriteLine("Found {0} files", lst.Count);
diff --git a/Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj b/Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
index 51886a7e9..565830a4a 100644
--- a/Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
+++ b/Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
@@ -5,11 +5,13 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4A010589-76E6-4F05-A5C4-4598D5DF11F8}</ProjectGuid>
<OutputType>Exe</OutputType>
+ <Prefer32Bit>False</Prefer32Bit>
<RootNamespace>Duplicati.CommandLine.RecoveryTool</RootNamespace>
<AssemblyName>Duplicati.CommandLine.RecoveryTool</AssemblyName>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -38,7 +40,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -81,6 +83,10 @@
<Project>{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}</Project>
<Name>Duplicati.Library.Backend.HubiC</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
+ <Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
+ <Name>Duplicati.Library.Backend.Jottacloud</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj">
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
<Name>Duplicati.Library.Backend.OneDrive</Name>
@@ -97,6 +103,10 @@
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
+ <Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
+ <Name>Duplicati.Library.Backend.Sia</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
<Project>{FF2BF37C-E502-4C98-BEA0-701671DDFA08}</Project>
<Name>Duplicati.Library.Backend.SSHv2</Name>
diff --git a/Duplicati/CommandLine/RecoveryTool/List.cs b/Duplicati/CommandLine/RecoveryTool/List.cs
index aca6d7136..d14640f14 100644
--- a/Duplicati/CommandLine/RecoveryTool/List.cs
+++ b/Duplicati/CommandLine/RecoveryTool/List.cs
@@ -90,7 +90,7 @@ namespace Duplicati.CommandLine.RecoveryTool
{
var items = ParseListFiles(folder);
if (index < 0 || index >= items.Length)
- throw new Exception(string.Format("Valid range for version is 0 to {1}", items.Length - 1));
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Valid range for version is 0 to {0}", items.Length - 1));
return items[index].Value;
}
diff --git a/Duplicati/CommandLine/RecoveryTool/Program.cs b/Duplicati/CommandLine/RecoveryTool/Program.cs
index 5bfdbb013..e37eda13e 100644
--- a/Duplicati/CommandLine/RecoveryTool/Program.cs
+++ b/Duplicati/CommandLine/RecoveryTool/Program.cs
@@ -28,6 +28,7 @@ namespace Duplicati.CommandLine.RecoveryTool
[STAThread]
public static int Main(string[] args)
{
+ Duplicati.Library.AutoUpdater.UpdaterManager.IgnoreWebrootFolder = true;
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args);
}
@@ -51,7 +52,7 @@ namespace Duplicati.CommandLine.RecoveryTool
if (options.ContainsKey("tempdir") && !string.IsNullOrEmpty(options["tempdir"]))
Library.Utility.TempFolder.SetSystemTempPath(options["tempdir"]);
- bool isHelp = args.Count == 0 || (args.Count >= 1 && string.Equals(args[0], "help", StringComparison.InvariantCultureIgnoreCase));
+ bool isHelp = args.Count == 0 || (args.Count >= 1 && string.Equals(args[0], "help", StringComparison.OrdinalIgnoreCase));
if (!isHelp && ((options.ContainsKey("parameters-file") && !string.IsNullOrEmpty("parameters-file")) || (options.ContainsKey("parameter-file") && !string.IsNullOrEmpty("parameter-file")) || (options.ContainsKey("parameterfile") && !string.IsNullOrEmpty("parameterfile"))))
{
string filename;
@@ -75,7 +76,7 @@ namespace Duplicati.CommandLine.RecoveryTool
return 100;
}
- var actions = new Dictionary<string, CommandRunner>(StringComparer.InvariantCultureIgnoreCase);
+ var actions = new Dictionary<string, CommandRunner>(StringComparer.OrdinalIgnoreCase);
actions["download"] = Download.Run;
actions["recompress"] = Recompress.Run;
actions["index"] = Index.Run;
@@ -93,7 +94,10 @@ namespace Duplicati.CommandLine.RecoveryTool
}
catch(Exception ex)
{
- Console.WriteLine("Program crashed: {0}{1}", Environment.NewLine, ex.ToString());
+ if (ex is Duplicati.Library.Interface.UserInformationException)
+ Console.WriteLine(ex.Message);
+ else
+ Console.WriteLine("Program crashed: {0}{1}", Environment.NewLine, ex.ToString());
return 200;
}
}
@@ -111,7 +115,7 @@ namespace Duplicati.CommandLine.RecoveryTool
// If the user specifies parameters-file, all filters must be in the file.
// Allowing to specify some filters on the command line could result in wrong filter ordering
if (!filter.Empty && !newfilter.Empty)
- throw new Exception("Filters cannot be specified on the commandline if filters are also present in the parameter file");
+ throw new Duplicati.Library.Interface.UserInformationException("Filters cannot be specified on the commandline if filters are also present in the parameter file");
if (!newfilter.Empty)
filter = newfilter;
@@ -121,7 +125,7 @@ namespace Duplicati.CommandLine.RecoveryTool
cargs.AddRange(
from c in fargs
- where !string.IsNullOrWhiteSpace(c) && !c.StartsWith("#") && !c.StartsWith("!") && !c.StartsWith("REM ", StringComparison.InvariantCultureIgnoreCase)
+ where !string.IsNullOrWhiteSpace(c) && !c.StartsWith("#") && !c.StartsWith("!") && !c.StartsWith("REM ", StringComparison.OrdinalIgnoreCase)
select c
);
diff --git a/Duplicati/CommandLine/RecoveryTool/Recompress.cs b/Duplicati/CommandLine/RecoveryTool/Recompress.cs
index e8865341c..21dddd731 100644
--- a/Duplicati/CommandLine/RecoveryTool/Recompress.cs
+++ b/Duplicati/CommandLine/RecoveryTool/Recompress.cs
@@ -47,7 +47,7 @@ namespace Duplicati.CommandLine.RecoveryTool
Console.WriteLine("Listing files on backend: {0} ...", backend.ProtocolKey);
- var rawlist = backend.List();
+ var rawlist = backend.List().ToList();
Console.WriteLine("Found {0} files at remote storage", rawlist.Count);
@@ -79,9 +79,9 @@ namespace Duplicati.CommandLine.RecoveryTool
if (tmp.Length == 0)
Console.WriteLine("Found {0} files at the remote storage, but none that could be parsed", rawlist.Count);
else if (types.Length == 1)
- Console.WriteLine("Found {0} parse-able files with the prefix {1}, did you forget to set the backup-prefix?", tmp.Length, types[0]);
+ Console.WriteLine("Found {0} parse-able files with the prefix {1}, did you forget to set the backup prefix?", tmp.Length, types[0]);
else
- Console.WriteLine("Found {0} parse-able files (of {1} files) with different prefixes: {2}, did you forget to set the backup-prefix?", tmp.Length, rawlist.Count, string.Join(", ", types));
+ Console.WriteLine("Found {0} parse-able files (of {1} files) with different prefixes: {2}, did you forget to set the backup prefix?", tmp.Length, rawlist.Count, string.Join(", ", types));
}
return 100;
@@ -204,7 +204,7 @@ namespace Duplicati.CommandLine.RecoveryTool
textJSON = sourceStreamReader.ReadToEnd();
JToken token = JObject.Parse(textJSON);
var fileInfoBlocks = new FileInfo(Path.Combine(targetfolder, cmfileNew.Replace("vol/", "")));
- var filehasher = System.Security.Cryptography.HashAlgorithm.Create(m_Options.FileHashAlgorithm);
+ var filehasher = HashAlgorithmHelper.Create(m_Options.FileHashAlgorithm);
using (var fileStream = fileInfoBlocks.Open(FileMode.Open))
{
diff --git a/Duplicati/CommandLine/RecoveryTool/Restore.cs b/Duplicati/CommandLine/RecoveryTool/Restore.cs
index a441fd69a..8a357c941 100644
--- a/Duplicati/CommandLine/RecoveryTool/Restore.cs
+++ b/Duplicati/CommandLine/RecoveryTool/Restore.cs
@@ -90,13 +90,13 @@ namespace Duplicati.CommandLine.RecoveryTool
return 100;
}
- var blockhasher = string.IsNullOrWhiteSpace(blockhash_str) ? null : System.Security.Cryptography.HashAlgorithm.Create(blockhash_str);
- var filehasher = string.IsNullOrWhiteSpace(filehash_str) ? null : System.Security.Cryptography.HashAlgorithm.Create(filehash_str);
+ var blockhasher = string.IsNullOrWhiteSpace(blockhash_str) ? null : Library.Utility.HashAlgorithmHelper.Create(blockhash_str);
+ var filehasher = string.IsNullOrWhiteSpace(filehash_str) ? null : Library.Utility.HashAlgorithmHelper.Create(filehash_str);
if (blockhasher == null)
- throw new Exception(string.Format("Block hash algorithm not valid: {0}", blockhash_str));
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Block hash algorithm not valid: {0}", blockhash_str));
if (filehasher == null)
- throw new Exception(string.Format("File hash algorithm not valid: {0}", filehash_str));
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("File hash algorithm not valid: {0}", filehash_str));
var hashesprblock = blocksize / (blockhasher.HashSize / 8);
diff --git a/Duplicati/CommandLine/RecoveryTool/help.txt b/Duplicati/CommandLine/RecoveryTool/help.txt
index b3fb3c5ae..eeb488aef 100644
--- a/Duplicati/CommandLine/RecoveryTool/help.txt
+++ b/Duplicati/CommandLine/RecoveryTool/help.txt
@@ -58,7 +58,7 @@ Some files are created in the system temporary folder, use --tempdir to set an a
Restore
-------
-Duplicati.RecoveryTool.exe index <localfolder> [version] [options]
+Duplicati.RecoveryTool.exe restore <localfolder> [version] [options]
Restores all files to their respective destinations. Use --targetpath to choose another folder where the files are restored into.
Use the filters, --exclude, to perform a partial restore.
diff --git a/Duplicati/CommandLine/RecoveryTool/packages.config b/Duplicati/CommandLine/RecoveryTool/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/CommandLine/RecoveryTool/packages.config
+++ b/Duplicati/CommandLine/RecoveryTool/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/CommandLine/Strings.cs b/Duplicati/CommandLine/Strings.cs
index d281b0b02..ef9a45258 100644
--- a/Duplicati/CommandLine/Strings.cs
+++ b/Duplicati/CommandLine/Strings.cs
@@ -3,7 +3,7 @@ namespace Duplicati.CommandLine.Strings {
internal static class Program {
public static string DeleteCommandNeedsOptions(string commandname, string[] options) { return LC.L(@"The command {0} needs at least one of the following options set: {1}", commandname, string.Join(", ", options)); }
public static string WrongNumberOfCommandsError_v2(int actualcommands, int expectedcommands, string[] commands) { return LC.L(@"Found {0} commands but expected {1}, commands:
-{2}", actualcommands, expectedcommands, commands); }
+{2}", actualcommands, expectedcommands, string.Join(System.Environment.NewLine, commands ?? new string[0])); }
public static string InvalidCommandError(string commandname) { return LC.L(@"Command not supported: {0}", commandname); }
public static string NoFilesetsMatching { get { return LC.L(@"No filesets matched the criteria"); } }
public static string WouldDeleteBackups { get { return LC.L(@"The following filesets would be deleted:"); } }
@@ -12,19 +12,19 @@ namespace Duplicati.CommandLine.Strings {
public static string SupportedCompressionModulesHeader { get { return LC.L(@"Supported compression modules:"); } }
public static string SupportedEncryptionModulesHeader { get { return LC.L(@"Supported encryption modules:"); } }
public static string SupportedOptionsHeader { get { return LC.L(@"Supported options:"); } }
- public static string ModuleIsLoadedAutomatically { get { return LC.L(@"Module is loaded atomatically, use --disable-module to prevent this"); } }
- public static string ModuleIsNotLoadedAutomatically { get { return LC.L(@"Module is not loaded atomatically, use --enable-module to load it"); } }
+ public static string ModuleIsLoadedAutomatically { get { return LC.L(@"Module is loaded automatically, use --disable-module to prevent this"); } }
+ public static string ModuleIsNotLoadedAutomatically { get { return LC.L(@"Module is not loaded automatically, use --enable-module to load it"); } }
public static string GenericModulesHeader { get { return LC.L(@"Supported generic modules:"); } }
public static string FailedToParseParametersFileError(string path, string message) { return LC.L(@"Unable to read the parameters file ""{0}"", reason: {1}", path, message); }
- public static string FiltersCannotBeUsedWithFileError2 { get { return LC.L(@"Filters cannot be specified on the commandline if filters are also present in the parameter file. Use the special --{0}, --{1}, or --{2} options to specify filters inside the parameter file. Each filter must be prefixed with with either a + or a -, and multiple filters must be joined with {3}", "replace-filter", "append-filter", "prepend-filter", System.IO.Path.PathSeparator); } }
+ public static string FiltersCannotBeUsedWithFileError2 { get { return LC.L(@"Filters cannot be specified on the commandline if filters are also present in the parameter file. Use the special --{0}, --{1}, or --{2} options to specify filters inside the parameter file. Each filter must be prefixed with either a + or a -, and multiple filters must be joined with {3}", "replace-filter", "append-filter", "prepend-filter", System.IO.Path.PathSeparator); } }
public static string InternalOptionUsedError(string optionname) { return LC.L(@"The option --{0} was supplied, but it is reserved for internal use and may not be set on the commandline", optionname); }
- public static string ParametersFileOptionLong2 { get { return LC.L(@"This option can be used to store some or all of the options given to the commandline client. The file must be a plain text file, UTF-8 encoding is preferred. Each line in the file should be of the format --option=value. The special options --{0} and --{1} can be used to override the localpath and the remote destination uri, respectively. The options in this file take precedence over the options provided on the commandline. You cannot specify filters in both the file and on the commandline. Instead, you can use the special --{2}, --{3}, or --{4} options to specify filters inside the parameter file. Each filter must be prefixed with with either a + or a -, and multiple filters must be joined with {5} ", "source", "target", "replace-filter", "append-filter", "prepend-filter", System.IO.Path.PathSeparator); } }
+ public static string ParametersFileOptionLong2 { get { return LC.L(@"This option can be used to store some or all of the options given to the commandline client. The file must be a plain text file, UTF-8 encoding is preferred. Each line in the file should be of the format --option=value. The special options --{0} and --{1} can be used to override the localpath and the remote destination uri, respectively. The options in this file take precedence over the options provided on the commandline. You cannot specify filters in both the file and on the commandline. Instead, you can use the special --{2}, --{3}, or --{4} options to specify filters inside the parameter file. Each filter must be prefixed with either a + or a -, and multiple filters must be joined with {5} ", "source", "target", "replace-filter", "append-filter", "prepend-filter", System.IO.Path.PathSeparator); } }
public static string ParametersFileOptionShort { get { return LC.L(@"Path to a file with parameters"); } }
public static string UnhandledException(string message) { return LC.L(@"An error occured: {0}", message); }
public static string UnhandledInnerException(string message) { return LC.L(@"The inner error message is: {0}", message); }
public static string IncludeLong { get { return LC.L(@"Include files that match this filter. The special character * means any number of character, and the special character ? means any single character, use *.txt to include all files with a txt extension. Regular expressions are also supported and can be supplied by using hard braces, i.e. [.*\.txt]."); } }
public static string IncludeShort { get { return LC.L(@"Include files"); } }
- public static string ExcludeLong { get { return LC.L(@"Exclude files that match this filter. The special character * means any number of character, and the special character ? means any single character, use *.txt to include all files with a txt extension. Regular expressions are also supported and can be supplied by using hard braces, i.e. [.*\.txt]."); } }
+ public static string ExcludeLong { get { return LC.L(@"Exclude files that match this filter. The special character * means any number of character, and the special character ? means any single character, use *.txt to exclude all files with a txt extension. Regular expressions are also supported and can be supplied by using hard braces, i.e. [.*\.txt]."); } }
public static string ExcludeShort { get { return LC.L(@"Exclude files"); } }
public static string ControlFilesOptionShort { get { return LC.L(@"If this option is used with a backup operation, it is interpreted as a list of files to add to the filesets. When used with list or restore, it will list or restore the control files instead of the normal files."); } }
public static string ControlFilesOptionLong { get { return LC.L(@"Use control files"); } }
diff --git a/Duplicati/CommandLine/help.txt b/Duplicati/CommandLine/help.txt
index 05e75087a..cab82daf6 100644
--- a/Duplicati/CommandLine/help.txt
+++ b/Duplicati/CommandLine/help.txt
@@ -11,12 +11,13 @@
See duplicati.commandline.exe help <topic> for more information.
General: example, changelog
- Commands: backup, find, restore, delete, compact, test, compare, repair, affected
- Debugging: debug, logging, create-report, test-filters, system-info
+ Commands: backup, find, restore, delete, compact, test, compare, purge, vacuum
+ Reparing: repair, affected, list-broken-files, purge-broken-files
+ Debugging: debug, logging, create-report, test-filters, system-info, send-mail
Targets: %BACKENDS%
Modules: %ENCRYPTIONMODULES%, %COMPRESSIONMODULES%, %GENERICMODULES%
Formats: date, time, size, encryption, compression
- Advanced: mail, advanced, returncodes, filter, <option>
+ Advanced: mail, advanced, returncodes, filter, default-filter-sets, <option>
http://www.duplicati.com/ Version: %VERSION%
@@ -47,7 +48,7 @@ Show system information as seen by Duplicati
Make an encrypted backup
========================
- The following command will make an encrypted backup and store it on an FTP server. As no passphrase is specified, the user is prompted for a password. The upload speed is throttled to 500kB/s. Backups older than onemonth are considered old. Old backups are deleted automatically. The maximum file size is limited to 50MB (default).
+ The following command will make an encrypted backup and store it on an FTP server. As no passphrase is specified, the user is prompted for a password. The upload speed is throttled to 500kB/s. Backups older than one month are considered old. Old backups are deleted automatically. The maximum file size is limited to 50MB (default).
%MONO%"%APP_PATH%" backup ftp://me:example.com@ftp.example.com/target "%EXAMPLE_SOURCE_PATH%" --throttle=500kB
@@ -72,7 +73,12 @@ Usage: backup <storage-URL> "<source-path>" [<options>]
Makes a backup of <source-path> and stores it in <storage-URL>. The format for <storage-URL> is
protocol://username:password@hostname:port/path?backend_option1=value1&backend_option2=value2.
Multiple source paths can be specified if they are separated by a space.
-
+%IF_WINDOWS%
+ On Windows clients, there are two special ways to specify the drive for files to back up. These two methods may help to back up sources on removable drives, whose drive letters may not be reliable.
+ 1. The first is to specify the the drive using the volume guid, for example "%EXAMPLE_VOLUME_GUID_SOURCE_PATH%". In this case, the drive letter of the drive with the matching volume guid will be substituted to find the actual source path. The volume guid remains constant no matter which drive letter the drive is mounted to. These volume guids can be found using the 'mountvol' command line tool, or picked from the list below:
+ %KNOWN_DRIVES_AND_VOLUMES%
+ 2. The second is to use a wildcard (* or ?) in place of the drive name, for example "%EXAMPLE_WILDCARD_DRIVE_SOURCE_PATH%". In this case, the given source path will be backed up from all drives on which the path exists. This can be useful when backing up sources which may be present on multiple drives with different volume guids. When using --allow-missing-source, the backup will succeed as long as at least one path matches the wildcarded path.
+%END_IF_WINDOWS%
<username> must not contain : and <password> must not contain @. If they do, specify username and password using --auth-username and --auth-password, or url-encode them.
--auth-password=<string>
@@ -98,7 +104,7 @@ Usage: find <storage-URL> ["<filename>"] [<options>]
--time=<time>
Shows what the files looked like at a specific time. Absolute and relative times can be specified.
--version=<int>
- Shows what the files looked like in a specific backup. If no version is specified the latest backup (version=0) will be used. If nothing is found, older backups will besearched automatically.
+ Shows what the files looked like in a specific backup. If no version is specified the latest backup (version=0) will be used. If nothing is found, older backups will be searched automatically.
--include=<string>
Reduces the list of files in a backup to those that match the provided string. This is applied before the search is executed.
--exclude=<string>
@@ -124,7 +130,7 @@ Usage: restore <storage-URL> ["<filename>"] [<options>]
Restore files from a specific backup.
-
+
# =============================================================================
> duplicati.commandline.exe help delete
@@ -138,6 +144,8 @@ Usage: delete <storage-URL> [<options>]
Marks data outdated that is older than <int> versions.
--version=<int>
Deletes all files that belong to the specified version(s).
+ --allow-full-removal
+ Disables the protection against removing the final fileset
@@ -154,8 +162,8 @@ Usage: compact <storage-URL> [<options>]
Files smaller than this size are considered to be small and will be compacted with other small files as soon as there are <small-file-max-count> of them. --small-file-size=20 means 20% of <dblock-size>.
--threshold=<percent_value>
The amount of old data that a dblock file can contain before it is considered to be replaced.
-
-
+
+
# =============================================================================
@@ -193,6 +201,42 @@ Usage: repair <storage-URL> [<options>]
+# =============================================================================
+> duplicati.commandline.exe help purge
+
+Usage: purge <storage-URL> <filenames> [<options>]
+
+ Purges (removes) files from remote backup data. This command can either take a list of filenames or use the filters to choose which files to purge. The purge process creates new filesets on the remote destination with the purged files removed, and will start the compacting process after a purge. By default, the matching files are purged in all versions, but this can be limited by choosing one or more versions. To test what will happen, use the --dry-run flag.
+
+ --dry-run
+ Performs the operation, but does not write changes to the local database or the remote storage
+ --version=<int>
+ Selects specific versions to purge from, multiple versions can be specified with commas
+ --time=<time>
+ Selects a specific version to purge from
+ --no-auto-compact
+ Performs a compact process after purging files
+ --include=<filter>
+ Selects files to purge, using filter syntax
+
+
+# =============================================================================
+> duplicati.commandline.exe help broken
+> duplicati.commandline.exe help broken-files
+> duplicati.commandline.exe help list-broken-files
+> duplicati.commandline.exe help purge-broken-files
+
+Usage: list-broken-files <storage-URL> [<options>]
+
+ Checks the database for missing data that cause files not not be restoreable. Files can become unrestoreable if remote data files are defect or missing. Use the list-broken-files command to see what the purge-broken-files command will remove.
+
+Usage: purge-broken-files <storage-URL> [<options>]
+
+ Removes all files from the database and remote storage that are no longer restoreable. Use this operation with caution, and only if you cannot recover the missing remote files, but want to continue a backup. Even with missing remote files, it may be possible to restore parts of the files that will be removed with this command.
+
+ --dry-run
+ Performs the operation, but does not write changes to the local database or the remote storage
+
# =============================================================================
> duplicati.commandline.exe help test
@@ -225,8 +269,14 @@ Usage: test-filters <source-path> [<options>]
Usage: affected <storage-URL> <remote-filename> [<remote-filenames>] [<options>]
- Returns a report explaning what backup sets and files are affected by a remote file. You can use this option to see what source files are affected if one or more remote files are damaged or deleted.
-
+ Returns a report explaining what backup sets and files are affected by a remote file. You can use this option to see what source files are affected if one or more remote files are damaged or deleted.
+
+# =============================================================================
+> duplicati.commandline.exe help vacuum
+
+Usage: vacuum <storage-URL> [<options>]
+
+ Rebuilds the local database, repacking it into a minimal amount of disk space.
# =============================================================================
> duplicati.commandline.exe help debug
@@ -264,7 +314,7 @@ Duplicati offers various options for the used compression and encryption modules
# =============================================================================
> duplicati.commandline.exe help gpg
-Duplicati is shipped with an interface to GNU Privary Guard. It requires that the gpg executable is available on the system. On Windows it is assumed that this is in the default installation folder under program files, under Linux and OSX it is assumed that the program is available via the PATH environment variable. It is possible to supply the path to GPG using the --gpg-program-path switch.
+Duplicati is shipped with an interface to GNU Privacy Guard. It requires that the gpg executable is available on the system. On Windows it is assumed that this is in the default installation folder under program files, under Linux and OSX it is assumed that the program is available via the PATH environment variable. It is possible to supply the path to GPG using the --gpg-program-path switch.
Options:
%MODULEOPTIONS%
@@ -374,19 +424,49 @@ For speed limits, use the same format. If you enter 1MB this will be 1MB/sec.
> duplicati.commandline.exe help filter
> duplicati.commandline.exe help filters
-Duplicati can apply globbing and regex filter rules to backup and restore specific files only. Globbing filters can be used in file names. To specify a regex filter put the file name in [brackets].
+Duplicati can apply globbing and regex filter rules to backup and restore specific files only. Globbing filters can be used in file names. To specify a regex filter put the filter in [brackets].
Globbing: *.txt
Regex: [.*test\.txt]
+
+ --include=<filter>
+ Adds an include filter
+ --exclude=<filter>
+ Adds an exclude filter
+ --default-filters=<filter-sets>
+ Which default filter sets should be used. Valid sets are "Windows", "OSX", "Linux", and "All".
Inside scripts and the commandline --parameters-file, where multiple filters are supplied with a single option, filters must be prefixed with either a plus (+) or a (-), for include and exclude respectively. Example:
+*.txt%PATH_SEPARATOR%-[.*\.xyz]%PATH_SEPARATOR%+*
# =============================================================================
+> duplicati.commandline.exe help default-filter-set
+> duplicati.commandline.exe help default-filter-sets
+
+Duplicati has some built-in filters for different operating systems. In addition to the sets below, there is the special set "All", which selects all filters. These sets are specified via the --default-filters parameter.
+
+ Common
+ %COMMON_FILTERS%
+
+ Windows
+ %WINDOWS_FILTERS%
+
+ OSX
+ %OSX_FILTERS%
+
+ Linux
+ %LINUX_FILTERS%
+
+
+# =============================================================================
> duplicati.commandline.exe help mail
> duplicati.commandline.exe help email
+> duplicati.commandline.exe help send-mail
+
+Duplicati can send email notifications after each operation. Use the send-mail command to test this:
+
+ %MONO%"%APP_PATH%" send-mail --send-mail-to=<email-address>
-Duplicati can send email notifications.
--send-mail-to=<email-address>
Send an email to <email-address> after a backup. Valid formats are "Name <test@example.com>, Other <test2@example.com>, test3@example.com". Multiple addresses must be separated with a comma.
@@ -397,31 +477,29 @@ Duplicati can send email notifications.
--send-mail-body=<body>
The content of the email message. This should contain "%RESULT%".
--send-mail-url=<smtp-url>
- A URL to connect to an SMTP server to send out an email. Example: "tls://smtp.example.com:587" or "smtp://smtp.example.com:25"
+ A URL to connect to an SMTP server to send out an email. Example: "tls://smtp.example.com:587", "smtps://smtp.example.com:465" or "smtp://smtp.example.com:25"
--send-mail-username=<username>
Required username to authenticate with SMTP server.
--send-mail-password=<password>
Required password to authenticate with SMTP server.
--send-mail-level=<level>
- When email messages are sent: "Success", "Warning", "Error" are possible.
+ When email messages are sent: "Success", "Warning", "Error", "Fatal", "All" are possible.
--send-mail-any-operation=true
Also send emails after other operations like restore etc.
-
+
Allowed placeholders are:
%PARSEDRESULT%
The parsed result op the operation: Success, Warning, Error
%RESULT%
- When used in the body, this is the result/log of the backup,
+ When used in the body, this is the result/log of the backup,
When used in the subject line, this is the same as %PARSEDRESULT%
%OPERATIONNAME%
- The name of the operation, usually "backup", but could also be "restore" etc.
+ The name of the operation, usually "backup", but could also be "restore" etc.
%REMOTEURL%
- The backend url
+ The backend url
%LOCALPATH%
- The path to the local folders involved (i.e. the folders being backed up)
-
-
-
+ The path to the local folders involved (i.e. the folders being backed up)
+
# =============================================================================
> duplicati.commandline.exe help advanced
> duplicati.commandline.exe help option
@@ -439,8 +517,8 @@ Duplicati offers more options than listed in the other topics. Those additional
Duplicati reports the following return/exit codes:
0 - Success
- 1 - Successful backup, but no files were changed
- 2 - Successful backup, with warnings
+ 1 - Successful operation, but no files were changed
+ 2 - Successful operation, but with warnings
50 - Backup uploaded some files, but did not finish
100 - An error occurred
200 - Invalid commandline arguments found
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/AppIndicatorRunner.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/AppIndicatorRunner.cs
index ecacbbd8d..9205bf763 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/AppIndicatorRunner.cs
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/AppIndicatorRunner.cs
@@ -1,20 +1,20 @@
-// Copyright (C) 2015, The Duplicati Team
-// http://www.duplicati.com, info@duplicati.com
-//
-// This library is free software; you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as
-// published by the Free Software Foundation; either version 2.1 of the
-// License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#if __MonoCS__ || __WindowsGTK__
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
using System;
using AppIndicator;
using Gtk;
@@ -54,32 +54,29 @@ namespace Duplicati.GUI.TrayIcon
{
set
{
+ m_appIndicator.IconName = GetTrayIconFilename(value);
+
switch(value)
{
- case TrayIcons.Paused:
- m_appIndicator.IconName = "normal-pause";
- m_appIndicator.IconDesc = "Paused";
- break;
- case TrayIcons.Running:
- m_appIndicator.IconName = "normal-running";
- m_appIndicator.IconDesc = "Running";
- break;
- case TrayIcons.IdleError:
- m_appIndicator.IconName = "normal-error";
- m_appIndicator.IconDesc = "Error";
- break;
- case TrayIcons.RunningError:
- m_appIndicator.IconName = "normal-running";
- break;
- case TrayIcons.PausedError:
- m_appIndicator.IconName = "normal-pause";
- m_appIndicator.IconDesc = "Paused";
- break;
- case TrayIcons.Idle:
- default:
- m_appIndicator.IconName = "normal";
- m_appIndicator.IconDesc = "Ready";
- break;
+ case TrayIcons.Paused:
+ m_appIndicator.IconDesc = "Paused";
+ break;
+ case TrayIcons.Running:
+ m_appIndicator.IconDesc = "Running";
+ break;
+ case TrayIcons.IdleError:
+ m_appIndicator.IconDesc = "Error";
+ break;
+ case TrayIcons.RunningError:
+ m_appIndicator.IconDesc = "Running";
+ break;
+ case TrayIcons.PausedError:
+ m_appIndicator.IconDesc = "Paused";
+ break;
+ case TrayIcons.Idle:
+ default:
+ m_appIndicator.IconDesc = "Ready";
+ break;
}
}
}
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
index 9429b8ac5..2c1366d95 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
@@ -27,6 +27,7 @@
<ApplicationIcon>Duplicati.ico</ApplicationIcon>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<OutputPath>bin\Debug</OutputPath>
@@ -65,6 +66,7 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
<Reference Include="System.Windows.Forms" />
<Reference Include="appindicator-sharp">
<HintPath>..\..\..\thirdparty\appindicator-sharp\appindicator-sharp.dll</HintPath>
@@ -86,11 +88,11 @@
<Private>False</Private>
</Reference>
<Reference Include="System.Drawing" />
- <Reference Include="CoCoL">
- <HintPath>..\..\..\packages\CoCoL.1.5.0\lib\net45\CoCoL.dll</HintPath>
- </Reference>
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="CoCoL">
+ <HintPath>..\..\..\packages\CoCoL.1.5.1\lib\net45\CoCoL.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -136,11 +138,11 @@
</EmbeddedResource>
<Compile Include="WinFormsRunner.cs" />
<Compile Include="RumpsRunner.cs" />
- <None Include="packages.config" />
<EmbeddedResource Include="Resources\context_menu_open.ico" />
<EmbeddedResource Include="Resources\context_menu_pause.ico" />
<EmbeddedResource Include="Resources\context_menu_play.ico" />
<EmbeddedResource Include="Resources\context_menu_quit.ico" />
+ <None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\Backend\CloudFiles\Duplicati.Library.Backend.CloudFiles.csproj">
@@ -159,6 +161,10 @@
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
+ <Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
+ <Name>Duplicati.Library.Backend.Jottacloud</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj">
<Project>{d4c37c33-5e73-4b56-b2c3-dc4a6baa36bb}</Project>
<Name>Duplicati.Library.OAuthHelper</Name>
@@ -307,6 +313,10 @@
<Project>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</Project>
<Name>Duplicati.Library.Backend.AlternativeFTP</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
+ <Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
+ <Name>Duplicati.Library.Backend.Sia</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Dropbox\Duplicati.Library.Backend.Dropbox.csproj">
<Project>{B20A7CEE-9C5B-47B9-8B76-BC85ADFE8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
@@ -372,5 +382,29 @@
<Link>OSXTrayHost\rumps.py</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="SVGIcons\dark\context_menu_open.svg">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="SVGIcons\dark\context_menu_pause.svg">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="SVGIcons\dark\context_menu_quit.svg">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="SVGIcons\dark\context_menu_resume.svg">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="SVGIcons\light\context_menu_open.svg">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="SVGIcons\light\context_menu_pause.svg">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="SVGIcons\light\context_menu_quit.svg">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="SVGIcons\light\context_menu_resume.svg">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/GtkRunner.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/GtkRunner.cs
index caaa16377..07c124b03 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/GtkRunner.cs
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/GtkRunner.cs
@@ -1,20 +1,20 @@
-// Copyright (C) 2015, The Duplicati Team
-// http://www.duplicati.com, info@duplicati.com
-//
-// This library is free software; you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as
-// published by the Free Software Foundation; either version 2.1 of the
-// License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#if __MonoCS__ || __WindowsGTK__
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
using System;
using System.Collections.Generic;
using Gdk;
@@ -24,11 +24,16 @@ namespace Duplicati.GUI.TrayIcon
{
public class GtkRunner : TrayIconBase
{
+ private static string m_svgfolder;
+
/// <summary>
/// Static constructor that ensures the Gtk environment is initialized
/// </summary>
static GtkRunner()
{
+ m_svgfolder = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "SVGIcons");
+ m_svgfolder = System.IO.Path.Combine(m_svgfolder, "dark");
+
Gtk.Application.Init();
}
@@ -45,34 +50,36 @@ namespace Duplicati.GUI.TrayIcon
private static Dictionary<MenuIcons, Gtk.Image> _icons = new Dictionary<MenuIcons, Gtk.Image>();
public MenuItem MenuItem { get { return m_item; } }
-
- private Gtk.Image GetIcon(MenuIcons icon)
- {
- if (Duplicati.Library.Utility.Utility.IsClientOSX)
- return null;
- if (!_icons.ContainsKey(icon))
+ private string GetFilenameForIcon(MenuIcons icon)
+ {
+ switch (icon)
{
- switch(icon)
- {
- case MenuIcons.None:
- _icons[icon] = null;
- break;
case MenuIcons.Pause:
- _icons[icon] = ImageToGtk(ImageLoader.Pause);
- break;
+ return "context_menu_pause";
case MenuIcons.Quit:
- _icons[icon] = ImageToGtk(ImageLoader.CloseMenuIcon);
- break;
+ return "context_menu_quit";
case MenuIcons.Resume:
- _icons[icon] = ImageToGtk(ImageLoader.Play);
- break;
+ return "context_menu_resume";
case MenuIcons.Status:
- _icons[icon] = ImageToGtk(ImageLoader.StatusMenuIcon);
- break;
+ return "context_menu_open";
default:
- _icons[icon] = null;
- break;
+ return null;
+ }
+ }
+
+ private Gtk.Image GetIcon(MenuIcons icon)
+ {
+ if (!_icons.ContainsKey(icon))
+ {
+ _icons[icon] = null;
+
+ var filename = GetFilenameForIcon(icon);
+ if (filename != null)
+ {
+ filename = System.IO.Path.Combine(m_svgfolder, System.IO.Path.ChangeExtension(filename, ".svg"));
+ if (System.IO.File.Exists(filename))
+ _icons[icon] = new Gtk.Image(filename);
}
}
@@ -89,9 +96,9 @@ namespace Duplicati.GUI.TrayIcon
if (!Duplicati.Library.Utility.Utility.IsClientOSX)
if (icon != MenuIcons.None) {
((ImageMenuItem)m_item).Image = GetIcon(icon);
-
- //TODO: Not sure we should do this, it overrides policy?
- m_item.ExposeEvent += DrawImageMenuItemImage;
+
+ // On some (older versions) of GDK, this hack is required
+ //m_item.ExposeEvent += DrawImageMenuItemImage;
}
if (subitems != null && subitems.Count > 0)
@@ -116,6 +123,7 @@ namespace Duplicati.GUI.TrayIcon
m_callback();
}
+ /*
/// <summary> Draw the image to the image menu item. Taken from: http://mono.1490590.n4.nabble.com/ImageMenuItem-does-not-display-the-image-Linux-platform-tp3510861p3511376.html </summary>
/// The event source. <see cref="System.Object"/>
/// The event args. <see cref="Gtk.ExposeEventArgs"/>
@@ -133,7 +141,8 @@ namespace Duplicati.GUI.TrayIcon
args.Event.Window.DrawPixbuf(mainGC, image.Pixbuf, 0, 0, r.Left + 2,
r.Top + (r.Height - image.Pixbuf.Height) / 2, -1, -1, Gdk.RgbDither.None, 0, 0);
- }
+ }
+ */
public string Text
{
@@ -176,7 +185,9 @@ namespace Duplicati.GUI.TrayIcon
protected virtual void CreateTrayInstance()
{
- m_trayIcon = new StatusIcon();
+ // Sometimes the tray icon will not display
+ // if it is not created with an icon
+ m_trayIcon = StatusIcon.NewFromStock(Stock.About);
}
protected override void Run (string[] args)
@@ -231,33 +242,63 @@ namespace Duplicati.GUI.TrayIcon
Gtk.Image img = new Gtk.Image(stream);
return img;
}
- }
+ }
+
+ protected static string GetTrayIconFilename(TrayIcons icon)
+ {
+ switch (icon)
+ {
+ case TrayIcons.Paused:
+ return "normal-pause";
+ case TrayIcons.Running:
+ return "normal-running";
+ case TrayIcons.IdleError:
+ return "normal-error";
+ case TrayIcons.RunningError:
+ return "normal-running";
+ case TrayIcons.PausedError:
+ return "normal-pause";
+ case TrayIcons.Idle:
+ default:
+ return "normal";
+ }
+ }
protected static Pixbuf GetIcon(TrayIcons icon)
{
if (!_images.ContainsKey(icon))
{
- switch(icon)
+ if (Duplicati.Library.Utility.Utility.IsClientOSX)
{
- case TrayIcons.Paused:
- _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.PauseIcon).ToBitmap());
- break;
- case TrayIcons.Running:
- _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.WorkingIcon).ToBitmap());
- break;
- case TrayIcons.IdleError:
- _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.ErrorIcon).ToBitmap());
- break;
- case TrayIcons.RunningError:
- _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.WorkingIcon).ToBitmap());
- break;
- case TrayIcons.PausedError:
+ switch (icon)
+ {
+ case TrayIcons.Paused:
_images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.PauseIcon).ToBitmap());
- break;
- case TrayIcons.Idle:
- default:
- _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.NormalIcon).ToBitmap());
- break;
+ break;
+ case TrayIcons.Running:
+ _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.WorkingIcon).ToBitmap());
+ break;
+ case TrayIcons.IdleError:
+ _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.ErrorIcon).ToBitmap());
+ break;
+ case TrayIcons.RunningError:
+ _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.WorkingIcon).ToBitmap());
+ break;
+ case TrayIcons.PausedError:
+ _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.PauseIcon).ToBitmap());
+ break;
+ case TrayIcons.Idle:
+ default:
+ _images[icon] = ImageToPixbuf(ImageLoader.LoadIcon(ImageLoader.NormalIcon).ToBitmap());
+ break;
+ }
+ }
+ else
+ {
+ _images[icon] = null;
+ var filename = System.IO.Path.Combine(m_svgfolder, System.IO.Path.ChangeExtension(GetTrayIconFilename(icon), ".svg"));
+ if (System.IO.File.Exists(filename))
+ _images[icon] = new Pixbuf(filename);
}
}
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/HostedInstanceKeeper.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/HostedInstanceKeeper.cs
index dc3f88b1e..ab18b26c3 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/HostedInstanceKeeper.cs
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/HostedInstanceKeeper.cs
@@ -21,7 +21,7 @@ namespace Duplicati.GUI.TrayIcon
{
//When running the hosted instance we do not really care what port we are using,
// so we just throw a few out there and try them
- if (args == null || !args.Any(x => x.Trim().StartsWith("--" + Duplicati.Server.WebServer.Server.OPTION_PORT + "=", StringComparison.InvariantCultureIgnoreCase)))
+ if (args == null || !args.Any(x => x.Trim().StartsWith("--" + Duplicati.Server.WebServer.Server.OPTION_PORT + "=", StringComparison.OrdinalIgnoreCase)))
args = (args ?? new string[0]).Union(new string[] { "--" + Duplicati.Server.WebServer.Server.OPTION_PORT + "=8200,8300,8400,8500,8600,8700,8800,8900,8989" }).ToArray();
Duplicati.Server.Program.Main(args);
@@ -30,7 +30,14 @@ namespace Duplicati.GUI.TrayIcon
Duplicati.Server.Program.ServerStartedEvent.Set();
} finally {
if (InstanceShutdown != null)
- InstanceShutdown();
+ try { InstanceShutdown(); }
+ catch (Exception shutex)
+ {
+ if (m_runnerException != null)
+ m_runnerException = new AggregateException(m_runnerException, shutex);
+ else
+ m_runnerException = shutex;
+ }
}
});
@@ -42,7 +49,7 @@ namespace Duplicati.GUI.TrayIcon
if (m_runnerException != null)
throw m_runnerException;
else
- throw new Exception("Hosted server startup timed out");
+ throw new Duplicati.Library.Interface.UserInformationException("Hosted server startup timed out");
}
if (m_runnerException != null)
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/HttpServerConnection.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/HttpServerConnection.cs
index acc1c4c07..97c9ff33a 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/HttpServerConnection.cs
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/HttpServerConnection.cs
@@ -1,6 +1,7 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net;
using System.Text;
using Duplicati.Server.Serialization;
using Duplicati.Server.Serialization.Interface;
@@ -16,6 +17,8 @@ namespace Duplicati.GUI.TrayIcon
private const string XSRF_HEADER = "X-XSRF-Token";
private const string AUTH_COOKIE = "session-auth";
+ private const string TRAYICONPASSWORDSOURCE_HEADER = "X-TrayIcon-PasswordSource";
+
private class BackgroundRequest
{
public string Method;
@@ -58,13 +61,16 @@ namespace Duplicati.GUI.TrayIcon
private System.Threading.AutoResetEvent m_waitLock;
private readonly Dictionary<string, string> m_updateRequest;
+ private readonly Dictionary<string, string> m_options;
+ private readonly bool m_dbPasswordSourceDatabase;
+ private string m_TrayIconHeaderValue => m_dbPasswordSourceDatabase ? "database" : "user";
public IServerStatus Status { get { return m_status; } }
private object m_lock = new object();
private Queue<BackgroundRequest> m_workQueue = new Queue<BackgroundRequest>();
- public HttpServerConnection(Uri server, string password, bool saltedpassword)
+ public HttpServerConnection(Uri server, string password, bool saltedpassword, bool dbPasswordSourceDatabase, Dictionary<string, string> options)
{
m_baseUri = server.ToString();
if (!m_baseUri.EndsWith("/"))
@@ -76,6 +82,8 @@ namespace Duplicati.GUI.TrayIcon
m_password = password;
m_saltedpassword = saltedpassword;
+ m_options = options;
+ m_dbPasswordSourceDatabase = dbPasswordSourceDatabase;
m_updateRequest = new Dictionary<string, string>();
m_updateRequest["longpoll"] = "false";
@@ -209,33 +217,61 @@ namespace Duplicati.GUI.TrayIcon
private SaltAndNonce GetSaltAndNonce()
{
- var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(m_baseUri + LOGIN_SCRIPT + "?get-nonce=1");
- req.Method = "GET";
- req.UserAgent = "Duplicati TrayIcon Monitor, v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
-
- Duplicati.Library.Utility.AsyncHttpRequest areq = new Library.Utility.AsyncHttpRequest(req);
- using(var r = (System.Net.HttpWebResponse)areq.GetResponse())
- using(var s = areq.GetResponseStream())
- using (var sr = new System.IO.StreamReader(s, ENCODING, true))
- return Serializer.Deserialize<SaltAndNonce>(sr);
+ var httpOptions = new Duplicati.Library.Modules.Builtin.HttpOptions();
+ httpOptions.Configure(m_options);
+
+ using (httpOptions)
+ {
+ var req = (System.Net.HttpWebRequest) System.Net.WebRequest.Create(m_baseUri + LOGIN_SCRIPT);
+ req.Method = "POST";
+ req.UserAgent = "Duplicati TrayIcon Monitor, v" +
+ System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ req.Headers.Add(TRAYICONPASSWORDSOURCE_HEADER, m_TrayIconHeaderValue);
+ req.ContentType = "application/x-www-form-urlencoded";
+
+ Duplicati.Library.Utility.AsyncHttpRequest areq = new Library.Utility.AsyncHttpRequest(req);
+ var body = System.Text.Encoding.ASCII.GetBytes("get-nonce=1");
+ using (var f = areq.GetRequestStream(body.Length))
+ f.Write(body, 0, body.Length);
+
+ using (var r = (System.Net.HttpWebResponse) areq.GetResponse())
+ using (var s = areq.GetResponseStream())
+ using (var sr = new System.IO.StreamReader(s, ENCODING, true))
+ return Serializer.Deserialize<SaltAndNonce>(sr);
+ }
}
private string PerformLogin(string password, string nonce)
{
- System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(m_baseUri + LOGIN_SCRIPT + "?password=" + Duplicati.Library.Utility.Uri.UrlEncode(password));
- req.Method = "GET";
- req.UserAgent = "Duplicati TrayIcon Monitor, v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
- if (req.CookieContainer == null)
- req.CookieContainer = new System.Net.CookieContainer();
- req.CookieContainer.Add(new System.Net.Cookie("session-nonce", nonce, "/", req.RequestUri.Host));
-
- //Wrap it all in async stuff
- Duplicati.Library.Utility.AsyncHttpRequest areq = new Library.Utility.AsyncHttpRequest(req);
- using(var r = (System.Net.HttpWebResponse)areq.GetResponse())
- if (r.StatusCode == System.Net.HttpStatusCode.OK)
- return (r.Cookies[AUTH_COOKIE] ?? r.Cookies[Library.Utility.Uri.UrlEncode(AUTH_COOKIE)]).Value;
-
- return null;
+ var httpOptions = new Duplicati.Library.Modules.Builtin.HttpOptions();
+ httpOptions.Configure(m_options);
+
+ using (httpOptions)
+ {
+ System.Net.HttpWebRequest req =
+ (System.Net.HttpWebRequest) System.Net.WebRequest.Create(m_baseUri + LOGIN_SCRIPT);
+ req.Method = "POST";
+ req.UserAgent = "Duplicati TrayIcon Monitor, v" +
+ System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ req.Headers.Add(TRAYICONPASSWORDSOURCE_HEADER, m_TrayIconHeaderValue);
+ req.ContentType = "application/x-www-form-urlencoded";
+ if (req.CookieContainer == null)
+ req.CookieContainer = new System.Net.CookieContainer();
+ req.CookieContainer.Add(new System.Net.Cookie("session-nonce", nonce, "/", req.RequestUri.Host));
+
+ //Wrap it all in async stuff
+ Duplicati.Library.Utility.AsyncHttpRequest areq = new Library.Utility.AsyncHttpRequest(req);
+ var body = System.Text.Encoding.ASCII.GetBytes("password=" +
+ Duplicati.Library.Utility.Uri.UrlEncode(password));
+ using (var f = areq.GetRequestStream(body.Length))
+ f.Write(body, 0, body.Length);
+
+ using (var r = (System.Net.HttpWebResponse) areq.GetResponse())
+ if (r.StatusCode == System.Net.HttpStatusCode.OK)
+ return (r.Cookies[AUTH_COOKIE] ?? r.Cookies[Library.Utility.Uri.UrlEncode(AUTH_COOKIE)]).Value;
+
+ return null;
+ }
}
private string GetAuthToken()
@@ -244,6 +280,9 @@ namespace Duplicati.GUI.TrayIcon
var sha256 = System.Security.Cryptography.SHA256.Create();
var password = m_password;
+ if (string.IsNullOrWhiteSpace(m_password))
+ return "";
+
if (!m_saltedpassword)
{
var str = System.Text.Encoding.UTF8.GetBytes(m_password);
@@ -265,20 +304,28 @@ namespace Duplicati.GUI.TrayIcon
private string GetXSRFToken()
{
- System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(m_baseUri + STATUS_WINDOW);
- req.Method = "GET";
- req.UserAgent = "Duplicati TrayIcon Monitor, v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
- if (req.CookieContainer == null)
- req.CookieContainer = new System.Net.CookieContainer();
-
- //Wrap it all in async stuff
- Duplicati.Library.Utility.AsyncHttpRequest areq = new Library.Utility.AsyncHttpRequest(req);
- using(var r = (System.Net.HttpWebResponse)areq.GetResponse())
- if (r.StatusCode == System.Net.HttpStatusCode.OK)
- return (r.Cookies[XSRF_COOKIE] ?? r.Cookies[Library.Utility.Uri.UrlEncode(XSRF_COOKIE)]).Value;
-
- return null;
+ var httpOptions = new Duplicati.Library.Modules.Builtin.HttpOptions();
+ httpOptions.Configure(m_options);
+ using (httpOptions)
+ {
+ System.Net.HttpWebRequest req =
+ (System.Net.HttpWebRequest) System.Net.WebRequest.Create(m_baseUri + STATUS_WINDOW);
+ req.Method = "GET";
+ req.UserAgent = "Duplicati TrayIcon Monitor, v" +
+ System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ req.Headers.Add(TRAYICONPASSWORDSOURCE_HEADER, m_TrayIconHeaderValue);
+ if (req.CookieContainer == null)
+ req.CookieContainer = new System.Net.CookieContainer();
+
+ //Wrap it all in async stuff
+ Duplicati.Library.Utility.AsyncHttpRequest areq = new Library.Utility.AsyncHttpRequest(req);
+ using (var r = (System.Net.HttpWebResponse) areq.GetResponse())
+ if (r.StatusCode == System.Net.HttpStatusCode.OK)
+ return (r.Cookies[XSRF_COOKIE] ?? r.Cookies[Library.Utility.Uri.UrlEncode(XSRF_COOKIE)]).Value;
+
+ return null;
+ }
}
private T PerformRequest<T>(string method, string urlfragment, Dictionary<string, string> queryparams)
@@ -294,7 +341,7 @@ namespace Duplicati.GUI.TrayIcon
}
catch (System.Net.WebException wex)
{
- var httpex = wex.Response as System.Net.HttpWebResponse;
+ var httpex = wex.Response as HttpWebResponse;
if (httpex == null)
throw;
@@ -302,31 +349,32 @@ namespace Duplicati.GUI.TrayIcon
!hasTriedXSRF &&
wex.Status == System.Net.WebExceptionStatus.ProtocolError &&
httpex.StatusCode == System.Net.HttpStatusCode.BadRequest &&
- httpex.StatusDescription.IndexOf("XSRF", StringComparison.InvariantCultureIgnoreCase) >= 0)
+ httpex.StatusDescription.IndexOf("XSRF", StringComparison.OrdinalIgnoreCase) >= 0)
{
hasTriedXSRF = true;
- string t = null;
- try
- {
- var c = httpex.Cookies[XSRF_COOKIE];
- if (c != null)
- t = c.Value;
- }
- catch
- {
- }
+ var t = httpex.Cookies[XSRF_COOKIE]?.Value;
- if (!string.IsNullOrWhiteSpace(t))
- m_xsrftoken = Duplicati.Library.Utility.Uri.UrlDecode(t);
- else
- m_xsrftoken = Duplicati.Library.Utility.Uri.UrlDecode(GetXSRFToken());
+ if (string.IsNullOrWhiteSpace(t))
+ t = GetXSRFToken();
+
+ m_xsrftoken = Duplicati.Library.Utility.Uri.UrlDecode(t);
}
else if (
!hasTriedPassword &&
wex.Status == System.Net.WebExceptionStatus.ProtocolError &&
- httpex.StatusCode == System.Net.HttpStatusCode.Unauthorized &&
- !string.IsNullOrWhiteSpace(m_password))
+ httpex.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
+ if (m_dbPasswordSourceDatabase)
+ {
+ Program.databaseConnection.ApplicationSettings.ReloadSettings();
+
+ //Can survive if server password is changed via web ui
+ if (Program.databaseConnection.ApplicationSettings.WebserverPasswordTrayIcon != m_password)
+ m_password = Program.databaseConnection.ApplicationSettings.WebserverPasswordTrayIcon;
+ else
+ hasTriedPassword = true;
+ }
+
m_authtoken = GetAuthToken();
}
else
@@ -341,43 +389,57 @@ namespace Duplicati.GUI.TrayIcon
string query = EncodeQueryString(queryparams);
- var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(new Uri(m_apiUri + endpoint + '?' + query));
- req.Method = method;
- req.Headers.Add("Accept-Charset", ENCODING.BodyName);
- if (m_xsrftoken != null)
- req.Headers.Add(XSRF_HEADER, m_xsrftoken);
- req.UserAgent = "Duplicati TrayIcon Monitor, v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
- if (req.CookieContainer == null)
- req.CookieContainer = new System.Net.CookieContainer();
-
- if (m_authtoken != null)
- req.CookieContainer.Add(new System.Net.Cookie(AUTH_COOKIE, m_authtoken, "/", req.RequestUri.Host));
- if (m_xsrftoken != null)
- req.CookieContainer.Add(new System.Net.Cookie(XSRF_COOKIE, m_xsrftoken, "/", req.RequestUri.Host));
-
- //Wrap it all in async stuff
- var areq = new Library.Utility.AsyncHttpRequest(req);
-
- //Assign the timeout, and add a little processing time as well
- if (endpoint.Equals("/serverstate", StringComparison.InvariantCultureIgnoreCase) && queryparams.ContainsKey("duration"))
- areq.Timeout = (int)(Duplicati.Library.Utility.Timeparser.ParseTimeSpan(queryparams["duration"]) + TimeSpan.FromSeconds(5)).TotalMilliseconds;
-
- using(var r = (System.Net.HttpWebResponse)areq.GetResponse())
- using (var s = areq.GetResponseStream())
- if (typeof(T) == typeof(string))
- {
- using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
+ // TODO: This can interfere with running backups,
+ // as the System.Net.ServicePointManager is shared with
+ // all connections doing ftp/http requests
+ using (var httpOptions = new Duplicati.Library.Modules.Builtin.HttpOptions())
+ {
+ httpOptions.Configure(m_options);
+
+ var req =
+ (System.Net.HttpWebRequest) System.Net.WebRequest.Create(
+ new Uri(m_apiUri + endpoint + '?' + query));
+ req.Method = method;
+ req.Headers.Add("Accept-Charset", ENCODING.BodyName);
+ if (m_xsrftoken != null)
+ req.Headers.Add(XSRF_HEADER, m_xsrftoken);
+ req.UserAgent = "Duplicati TrayIcon Monitor, v" +
+ System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ req.Headers.Add(TRAYICONPASSWORDSOURCE_HEADER, m_TrayIconHeaderValue);
+ if (req.CookieContainer == null)
+ req.CookieContainer = new System.Net.CookieContainer();
+
+ if (m_authtoken != null)
+ req.CookieContainer.Add(new System.Net.Cookie(AUTH_COOKIE, m_authtoken, "/", req.RequestUri.Host));
+ if (m_xsrftoken != null)
+ req.CookieContainer.Add(new System.Net.Cookie(XSRF_COOKIE, m_xsrftoken, "/", req.RequestUri.Host));
+
+ //Wrap it all in async stuff
+ var areq = new Library.Utility.AsyncHttpRequest(req);
+ req.AllowWriteStreamBuffering = true;
+
+ //Assign the timeout, and add a little processing time as well
+ if (endpoint.Equals("/serverstate", StringComparison.OrdinalIgnoreCase) &&
+ queryparams.ContainsKey("duration"))
+ areq.Timeout = (int) (Duplicati.Library.Utility.Timeparser.ParseTimeSpan(queryparams["duration"]) +
+ TimeSpan.FromSeconds(5)).TotalMilliseconds;
+
+ using (var r = (System.Net.HttpWebResponse) areq.GetResponse())
+ using (var s = areq.GetResponseStream())
+ if (typeof(T) == typeof(string))
{
- s.CopyTo(ms);
- return (T)(object)ENCODING.GetString(ms.ToArray());
+ using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
+ {
+ s.CopyTo(ms);
+ return (T) (object) ENCODING.GetString(ms.ToArray());
+ }
}
- }
- else
- {
- using (var sr = new System.IO.StreamReader(s, ENCODING, true))
- return Serializer.Deserialize<T>(sr);
- }
-
+ else
+ {
+ using (var sr = new System.IO.StreamReader(s, ENCODING, true))
+ return Serializer.Deserialize<T>(sr);
+ }
+ }
}
private void ExecuteAndNotify(string method, string urifragment, Dictionary<string, string> req)
@@ -439,14 +501,8 @@ namespace Duplicati.GUI.TrayIcon
{
get
{
- try
- {
- if (m_authtoken != null)
- return m_baseUri + STATUS_WINDOW + "?auth-token=" + GetAuthToken();
- }
- catch
- {
- }
+ if (m_authtoken != null)
+ return m_baseUri + STATUS_WINDOW + "?auth-token=" + GetAuthToken();
return m_baseUri + STATUS_WINDOW;
}
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/ImageLoader.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/ImageLoader.cs
index 8f1dec438..be35ef172 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/ImageLoader.cs
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/ImageLoader.cs
@@ -56,7 +56,7 @@ namespace Duplicati.GUI.TrayIcon
if (ICONS.TryGetValue(cachename, out ico))
return ico;
- if (!filename.EndsWith(".ico", StringComparison.InvariantCultureIgnoreCase))
+ if (!filename.EndsWith(".ico", StringComparison.OrdinalIgnoreCase))
using(var ms = new System.IO.MemoryStream())
{
Icon ic;
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSXTrayHost/osx-trayicon-rumps.py b/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSXTrayHost/osx-trayicon-rumps.py
index f28f29107..3f52696df 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSXTrayHost/osx-trayicon-rumps.py
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSXTrayHost/osx-trayicon-rumps.py
@@ -116,6 +116,7 @@ def get_input():
img = NSImage.alloc().initWithData_(data)
img.setScalesWhenResized_(True)
img.setSize_((18, 18))
+ img.setTemplate_(True)
app.icon = img
print "info:Image updated"
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs
index 883a1c868..79324e237 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs
@@ -1,7 +1,7 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
-using System.Windows.Forms;
+using System.Net;
using Duplicati.Library.Interface;
namespace Duplicati.GUI.TrayIcon
@@ -19,22 +19,24 @@ namespace Duplicati.GUI.TrayIcon
private const string HOSTURL_OPTION = "hosturl";
private const string NOHOSTEDSERVER_OPTION = "no-hosted-server";
-
+ private const string READCONFIGFROMDB_OPTION = "read-config-from-db";
+
+ private const string DETACHED_PROCESS = "detached-process";
private const string BROWSER_COMMAND_OPTION = "browser-command";
- private const string DEFAULT_HOSTURL = "http://localhost:8080";
+ private const string DEFAULT_HOSTURL = "http://localhost:8200";
private static string _browser_command = null;
public static string BrowserCommand { get { return _browser_command; } }
-
-
+ public static Server.Database.Connection databaseConnection = null;
+
private static string GetDefaultToolKit(bool printwarnings)
{
// No longer using Cocoa directly as it fails on 32bit as well
if (Duplicati.Library.Utility.Utility.IsClientOSX)
return TOOLKIT_RUMPS;
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
if (Duplicati.Library.Utility.Utility.IsClientLinux)
{
if (SupportsAppIndicator)
@@ -65,12 +67,15 @@ namespace Duplicati.GUI.TrayIcon
List<string> args = new List<string>(_args);
Dictionary<string, string> options = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(args);
+ if (Duplicati.Library.Utility.Utility.IsClientWindows && (Duplicati.Library.AutoUpdater.UpdaterManager.IsRunningInUpdateEnvironment || !Duplicati.Library.Utility.Utility.ParseBoolOption(options, DETACHED_PROCESS)))
+ Duplicati.Library.Utility.Win32.AttachConsole(Duplicati.Library.Utility.Win32.ATTACH_PARENT_PROCESS);
+
foreach (string s in args)
if (
- s.Equals("help", StringComparison.InvariantCultureIgnoreCase) ||
- s.Equals("/help", StringComparison.InvariantCultureIgnoreCase) ||
- s.Equals("usage", StringComparison.InvariantCultureIgnoreCase) ||
- s.Equals("/usage", StringComparison.InvariantCultureIgnoreCase))
+ s.Equals("help", StringComparison.OrdinalIgnoreCase) ||
+ s.Equals("/help", StringComparison.OrdinalIgnoreCase) ||
+ s.Equals("usage", StringComparison.OrdinalIgnoreCase) ||
+ s.Equals("/usage", StringComparison.OrdinalIgnoreCase))
options["help"] = "";
if (options.ContainsKey("help"))
@@ -79,7 +84,11 @@ namespace Duplicati.GUI.TrayIcon
Console.WriteLine();
foreach (Library.Interface.ICommandLineArgument arg in SupportedCommands)
+ {
Console.WriteLine("--{0}: {1}", arg.Name, arg.LongDescription);
+ if (arg.Name == TOOLKIT_OPTION)
+ Console.WriteLine(" Supported toolkits: {0}{1}", string.Join(", ", arg.ValidValues), Environment.NewLine);
+ }
Console.WriteLine("Additionally, these server options are also supported:");
Console.WriteLine();
@@ -88,35 +97,43 @@ namespace Duplicati.GUI.TrayIcon
Console.WriteLine("--{0}: {1}", arg.Name, arg.LongDescription);
return;
- }
-
+ }
+
options.TryGetValue(BROWSER_COMMAND_OPTION, out _browser_command);
string toolkit;
if (!options.TryGetValue(TOOLKIT_OPTION, out toolkit))
+ {
+#if !(__MonoCS__ || __WindowsGTK__ || ENABLE_GTK)
+ if (Library.Utility.Utility.IsClientLinux && !Library.Utility.Utility.IsClientOSX)
+ Console.WriteLine("Warning: this build does not support GTK, rebuild with ENABLE_GTK defined");
+#endif
toolkit = GetDefaultToolKit(true);
+ }
else
{
- if (TOOLKIT_WINDOWS_FORMS.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+ if (TOOLKIT_WINDOWS_FORMS.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_WINDOWS_FORMS;
-#if __MonoCS__ || __WindowsGTK__
- else if (TOOLKIT_GTK.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
+ else if (TOOLKIT_GTK.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_GTK;
- else if (TOOLKIT_GTK_APP_INDICATOR.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+ else if (TOOLKIT_GTK_APP_INDICATOR.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_GTK_APP_INDICATOR;
#endif
- else if (TOOLKIT_COCOA.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+ else if (TOOLKIT_COCOA.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_COCOA;
- else if (TOOLKIT_RUMPS.Equals(toolkit, StringComparison.InvariantCultureIgnoreCase))
+ else if (TOOLKIT_RUMPS.Equals(toolkit, StringComparison.OrdinalIgnoreCase))
toolkit = TOOLKIT_RUMPS;
else
toolkit = GetDefaultToolKit(true);
}
HostedInstanceKeeper hosted = null;
- bool openui = false;
+ var openui = false;
string password = null;
- bool saltedpassword = false;
+ var saltedpassword = false;
+ var serverURL = new Uri(DEFAULT_HOSTURL);
+
if (!Library.Utility.Utility.ParseBoolOption(options, NOHOSTEDSERVER_OPTION))
{
try
@@ -133,78 +150,126 @@ namespace Duplicati.GUI.TrayIcon
openui = Duplicati.Server.Program.IsFirstRun || Duplicati.Server.Program.ServerPortChanged;
password = Duplicati.Server.Program.DataConnection.ApplicationSettings.WebserverPassword;
saltedpassword = true;
+ serverURL = (new UriBuilder(serverURL) { Port = Duplicati.Server.Program.ServerPort }).Uri;
}
+
+ if (Library.Utility.Utility.ParseBoolOption(options, NOHOSTEDSERVER_OPTION) && Library.Utility.Utility.ParseBoolOption(options, READCONFIGFROMDB_OPTION))
+ databaseConnection = Server.Program.GetDatabaseConnection(options);
- using (hosted)
+ string pwd;
+
+ if (options.TryGetValue("webserver-password", out pwd))
{
- string url;
- if (!options.TryGetValue(HOSTURL_OPTION, out url))
- {
- if (hosted == null)
- {
- url = DEFAULT_HOSTURL;
- }
- else
+ password = pwd;
+ saltedpassword = false;
+ }
+
+ if (databaseConnection != null)
+ {
+ password = databaseConnection.ApplicationSettings.WebserverPasswordTrayIcon;
+ saltedpassword = false;
+ }
+
+ if (databaseConnection != null)
+ {
+ var cert = databaseConnection.ApplicationSettings.ServerSSLCertificate;
+ var scheme = "http";
+
+ if (cert != null && cert.HasPrivateKey)
+ scheme = "https";
+
+ serverURL = (new UriBuilder(serverURL)
{
- int port = Duplicati.Server.Program.ServerPort;
- url = "http://127.0.0.1:" + port;
- }
- }
+ Port = databaseConnection.ApplicationSettings.LastWebserverPort == -1 ? serverURL.Port : databaseConnection.ApplicationSettings.LastWebserverPort,
+ Scheme = scheme
+ }).Uri;
+ }
- string pwd;
- if (options.TryGetValue("webserver-password", out pwd))
- {
- password = pwd;
- saltedpassword = false;
- }
+ string url;
+
+ if (options.TryGetValue(HOSTURL_OPTION, out url))
+ serverURL = new Uri(url);
+
+ using (hosted)
+ {
+ var reSpawn = 0;
- using (Connection = new HttpServerConnection(new Uri(url), password, saltedpassword))
+ do
{
- using(var tk = RunTrayIcon(toolkit))
+ try
{
- if (hosted != null && Server.Program.Instance != null)
- Server.Program.Instance.SecondInstanceDetected += new Server.SingleInstance.SecondInstanceDelegate(x => { tk.ShowUrlInWindow(url); });
-
- // TODO: If we change to hosted browser this should be a callback
- if (openui)
- {
- try
- {
- tk.ShowUrlInWindow(Connection.StatusWindowURL);
+ System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
- Duplicati.Server.Program.IsFirstRun = false;
- Duplicati.Server.Program.ServerPortChanged = false;
- }
- catch
+ using (Connection = new HttpServerConnection(serverURL, password, saltedpassword, databaseConnection != null, options))
+ {
+ using (var tk = RunTrayIcon(toolkit))
{
+ if (hosted != null && Server.Program.Instance != null)
+ Server.Program.Instance.SecondInstanceDetected +=
+ new Server.SingleInstance.SecondInstanceDelegate(
+ x => { tk.ShowUrlInWindow(serverURL.ToString()); });
+
+ // TODO: If we change to hosted browser this should be a callback
+ if (openui)
+ {
+ try
+ {
+ tk.ShowUrlInWindow(Connection.StatusWindowURL);
+
+ Duplicati.Server.Program.IsFirstRun = false;
+ Duplicati.Server.Program.ServerPortChanged = false;
+ }
+ catch
+ {
+ }
+ }
+
+ // If the server shuts down, shut down the tray-icon as well
+ Action shutdownEvent = () =>
+ {
+ // Make sure we do not start again after
+ // a controlled exit
+ reSpawn = 100;
+ tk.InvokeExit();
+ };
+
+ if (hosted != null)
+ hosted.InstanceShutdown += shutdownEvent;
+
+ tk.Init(_args);
+
+ // If the tray-icon quits, stop the server
+ reSpawn = 100;
+
+ // Make sure that the server shutdown does not access the tray-icon,
+ // as it would be disposed by now
+ if (hosted != null)
+ hosted.InstanceShutdown -= shutdownEvent;
}
}
+ }
+ catch (WebException ex)
+ {
+ System.Diagnostics.Trace.WriteLine("Request error: " + ex.ToString());
+ Console.WriteLine("Request error: " + ex.ToString());
- // If the server shuts down, shut down the tray-icon as well
- Action shutdownEvent = () =>
- {
- tk.InvokeExit();
- };
-
- if (hosted != null)
- hosted.InstanceShutdown += shutdownEvent;
-
- tk.Init(_args);
-
- // Make sure that the server shutdown does not access the tray-icon,
- // as it would be disposed by now
- if (hosted != null)
- hosted.InstanceShutdown -= shutdownEvent;
+ reSpawn++;
}
- }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Trace.WriteLine("Unexpected error: " + ex.ToString());
+ Console.WriteLine("Unexpected error: " + ex.ToString());
+ return;
+ }
+ } while (reSpawn < 3);
}
}
-
+
private static TrayIconBase RunTrayIcon(string toolkit)
{
if (toolkit == TOOLKIT_WINDOWS_FORMS)
return GetWinformsInstance();
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
else if (toolkit == TOOLKIT_GTK)
return GetGtkInstance();
else if (toolkit == TOOLKIT_GTK_APP_INDICATOR)
@@ -215,7 +280,7 @@ namespace Duplicati.GUI.TrayIcon
else if (toolkit == TOOLKIT_RUMPS)
return GetRumpsRunnerInstance();
else
- throw new Exception(string.Format("The selected toolkit '{0}' is invalid", toolkit));
+ throw new UserInformationException(string.Format("The selected toolkit '{0}' is invalid", toolkit));
}
//We keep these in functions to avoid attempting to load the instance,
@@ -227,7 +292,7 @@ namespace Duplicati.GUI.TrayIcon
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static TrayIconBase GetWinformsInstance() { return new Windows.WinFormsRunner(); }
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static TrayIconBase GetGtkInstance() { return new GtkRunner(); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
@@ -247,7 +312,7 @@ namespace Duplicati.GUI.TrayIcon
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static bool TryGetGtk()
{
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
return typeof(Gtk.StatusIcon) != null && typeof(Gdk.Image) != null;
#else
return false;
@@ -263,7 +328,7 @@ namespace Duplicati.GUI.TrayIcon
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static bool TryGetAppIndicator()
{
-#if __MonoCS__ || __WindowsGTK__
+#if __MonoCS__ || __WindowsGTK__ || ENABLE_GTK
return typeof(AppIndicator.ApplicationIndicator) != null;
#else
return false;
@@ -351,13 +416,21 @@ namespace Duplicati.GUI.TrayIcon
if (SupportsRumps)
toolkits.Add(TOOLKIT_RUMPS);
- return new Duplicati.Library.Interface.ICommandLineArgument[]
+ var args = new List<Duplicati.Library.Interface.ICommandLineArgument>()
{
new Duplicati.Library.Interface.CommandLineArgument(TOOLKIT_OPTION, CommandLineArgument.ArgumentType.Enumeration, "Selects the toolkit to use", "Choose the toolkit used to generate the TrayIcon, note that it will fail if the selected toolkit is not supported on this machine", GetDefaultToolKit(false), null, toolkits.ToArray()),
new Duplicati.Library.Interface.CommandLineArgument(HOSTURL_OPTION, CommandLineArgument.ArgumentType.String, "Selects the url to connect to", "Supply the url that the TrayIcon will connect to and show status for", DEFAULT_HOSTURL),
new Duplicati.Library.Interface.CommandLineArgument(NOHOSTEDSERVER_OPTION, CommandLineArgument.ArgumentType.String, "Disables local server", "Set this option to not spawn a local service, use if the TrayIcon should connect to a running service"),
- new Duplicati.Library.Interface.CommandLineArgument(BROWSER_COMMAND_OPTION, CommandLineArgument.ArgumentType.String, "Sets the browser comand", "Set this option to override the default browser detection"),
+ new Duplicati.Library.Interface.CommandLineArgument(READCONFIGFROMDB_OPTION, CommandLineArgument.ArgumentType.String, "Read server connection info from DB", $"Set this option to read server connection info for running service from its database (only together with {NOHOSTEDSERVER_OPTION})"),
+ new Duplicati.Library.Interface.CommandLineArgument(BROWSER_COMMAND_OPTION, CommandLineArgument.ArgumentType.String, "Sets the browser command", "Set this option to override the default browser detection"),
};
+
+ if (Duplicati.Library.Utility.Utility.IsClientWindows)
+ {
+ args.Add(new Duplicati.Library.Interface.CommandLineArgument(DETACHED_PROCESS, CommandLineArgument.ArgumentType.String, "Runs the tray-icon detached", "This option runs the tray-icon in detached mode, meaning that the process will exit immediately and not send output to the console of the caller"));
+ }
+
+ return args.ToArray();
}
}
}
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Properties/AssemblyInfo.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Properties/AssemblyInfo.cs
index adee441c6..9e1a1180a 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Properties/AssemblyInfo.cs
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Properties/AssemblyInfo.cs
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("Duplicati.GUI.TrayIcon")]
+[assembly: AssemblyTitle("Duplicati")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Duplicati Team")]
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_open.svg b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_open.svg
new file mode 100644
index 000000000..8dfe03665
--- /dev/null
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_open.svg
@@ -0,0 +1,13 @@
+<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #65b1dd;
+ }
+ </style>
+ </defs>
+ <title>tray context menu icons</title>
+ <g id="show_Kopie" data-name="show Kopie">
+ <polygon class="cls-1" points="8 4.001 2 10.301 3.5 11.876 8 7.072 12.5 11.876 14 10.301 8 4.001"/>
+ </g>
+</svg>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_pause.svg b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_pause.svg
new file mode 100644
index 000000000..8f646c100
--- /dev/null
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_pause.svg
@@ -0,0 +1,14 @@
+<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #65b1dd;
+ }
+ </style>
+ </defs>
+ <title>tray context menu icons</title>
+ <g id="pause_Kopie" data-name="pause Kopie">
+ <rect class="cls-1" x="4" y="2" width="3" height="12"/>
+ <rect class="cls-1" x="9" y="2" width="3" height="12"/>
+ </g>
+</svg>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_quit.svg b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_quit.svg
new file mode 100644
index 000000000..bc3cfae06
--- /dev/null
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_quit.svg
@@ -0,0 +1,13 @@
+<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="15.997" height="16" viewBox="0 0 15.997 16">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #65b1dd;
+ }
+ </style>
+ </defs>
+ <title>tray context menu icons</title>
+ <g id="stop_Kopie" data-name="stop Kopie">
+ <polygon id="stop" class="cls-1" points="13.998 3.95 12.048 2 7.998 6.05 3.948 2 1.998 3.95 6.049 8 1.998 12.05 3.948 14 7.998 9.95 12.048 14 13.998 12.05 9.949 8 13.998 3.95"/>
+ </g>
+</svg>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_resume.svg b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_resume.svg
new file mode 100644
index 000000000..b1c4ed79d
--- /dev/null
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/dark/context_menu_resume.svg
@@ -0,0 +1,13 @@
+<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #65b1dd;
+ }
+ </style>
+ </defs>
+ <title>tray context menu icons</title>
+ <g id="resume_Kopie" data-name="resume Kopie">
+ <polygon class="cls-1" points="5 14 13 8 5 2 5 14"/>
+ </g>
+</svg>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_open.svg b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_open.svg
new file mode 100644
index 000000000..8dfe03665
--- /dev/null
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_open.svg
@@ -0,0 +1,13 @@
+<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #65b1dd;
+ }
+ </style>
+ </defs>
+ <title>tray context menu icons</title>
+ <g id="show_Kopie" data-name="show Kopie">
+ <polygon class="cls-1" points="8 4.001 2 10.301 3.5 11.876 8 7.072 12.5 11.876 14 10.301 8 4.001"/>
+ </g>
+</svg>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_pause.svg b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_pause.svg
new file mode 100644
index 000000000..8f646c100
--- /dev/null
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_pause.svg
@@ -0,0 +1,14 @@
+<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #65b1dd;
+ }
+ </style>
+ </defs>
+ <title>tray context menu icons</title>
+ <g id="pause_Kopie" data-name="pause Kopie">
+ <rect class="cls-1" x="4" y="2" width="3" height="12"/>
+ <rect class="cls-1" x="9" y="2" width="3" height="12"/>
+ </g>
+</svg>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_quit.svg b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_quit.svg
new file mode 100644
index 000000000..bc3cfae06
--- /dev/null
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_quit.svg
@@ -0,0 +1,13 @@
+<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="15.997" height="16" viewBox="0 0 15.997 16">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #65b1dd;
+ }
+ </style>
+ </defs>
+ <title>tray context menu icons</title>
+ <g id="stop_Kopie" data-name="stop Kopie">
+ <polygon id="stop" class="cls-1" points="13.998 3.95 12.048 2 7.998 6.05 3.948 2 1.998 3.95 6.049 8 1.998 12.05 3.948 14 7.998 9.95 12.048 14 13.998 12.05 9.949 8 13.998 3.95"/>
+ </g>
+</svg>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_resume.svg b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_resume.svg
new file mode 100644
index 000000000..b1c4ed79d
--- /dev/null
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/SVGIcons/light/context_menu_resume.svg
@@ -0,0 +1,13 @@
+<svg id="tray_menu_icons" data-name="tray menu icons" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+ <defs>
+ <style>
+ .cls-1 {
+ fill: #65b1dd;
+ }
+ </style>
+ </defs>
+ <title>tray context menu icons</title>
+ <g id="resume_Kopie" data-name="resume Kopie">
+ <polygon class="cls-1" points="5 14 13 8 5 2 5 14"/>
+ </g>
+</svg>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/WinFormsRunner.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/WinFormsRunner.cs
index ece6b4d5f..8881a8337 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/WinFormsRunner.cs
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/WinFormsRunner.cs
@@ -107,15 +107,8 @@ namespace Duplicati.GUI.TrayIcon.Windows
private Form m_handleProvider;
private NotifyIcon m_trayIcon;
- public static WinFormsRunner Instance = null;
-
public override void Init (string[] args)
{
- if (WinFormsRunner.Instance != null)
- throw new Exception("Multiple trayicon instances not allowed!");
-
- WinFormsRunner.Instance = this;
-
//We need this ugly hack to get a handle that we can call Invoke on,
// and sadly the TrayIcon does not expose one, and forcing the context menu
// to create one causes weird "lost clicks"
@@ -133,6 +126,7 @@ namespace Duplicati.GUI.TrayIcon.Windows
m_trayIcon = new NotifyIcon();
m_trayIcon.DoubleClick += new EventHandler(m_trayIcon_DoubleClick);
m_trayIcon.Click += new EventHandler(m_trayIcon_Click);
+ m_trayIcon.Text = Duplicati.Library.AutoUpdater.AutoUpdateSettings.AppName;
base.Init(args);
}
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config b/Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config
index d325c137a..040b8a7cf 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CoCoL" version="1.5.0" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="CoCoL" version="1.5.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/AutoUpdater/AutoUpdateSettings.cs b/Duplicati/Library/AutoUpdater/AutoUpdateSettings.cs
index 850dab24b..43c3a48b3 100644
--- a/Duplicati/Library/AutoUpdater/AutoUpdateSettings.cs
+++ b/Duplicati/Library/AutoUpdater/AutoUpdateSettings.cs
@@ -145,9 +145,9 @@ namespace Duplicati.Library.AutoUpdater
// Update from older builds
- if (string.Equals(channelstring, "preview", StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(channelstring, "preview", StringComparison.OrdinalIgnoreCase))
channelstring = ReleaseType.Experimental.ToString();
- if (string.Equals(channelstring, "rene", StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(channelstring, "rene", StringComparison.OrdinalIgnoreCase))
channelstring = ReleaseType.Canary.ToString();
ReleaseType rt;
diff --git a/Duplicati/Library/AutoUpdater/Duplicati.Library.AutoUpdater.csproj b/Duplicati/Library/AutoUpdater/Duplicati.Library.AutoUpdater.csproj
index 1937be84c..99c1279a9 100644
--- a/Duplicati/Library/AutoUpdater/Duplicati.Library.AutoUpdater.csproj
+++ b/Duplicati/Library/AutoUpdater/Duplicati.Library.AutoUpdater.csproj
@@ -5,13 +5,14 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7E119745-1F62-43F0-936C-F312A1912C0B}</ProjectGuid>
<OutputType>Exe</OutputType>
+ <Prefer32Bit>False</Prefer32Bit>
<RootNamespace>Duplicati.Library.AutoUpdater</RootNamespace>
<AssemblyName>Duplicati.Library.AutoUpdater</AssemblyName>
- <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\GUI\Duplicati.GUI.TrayIcon\Duplicati.snk</AssemblyOriginatorKeyFile>
<StartupObject>Duplicati.Library.AutoUpdater.Program</StartupObject>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -36,7 +37,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/AutoUpdater/Program.cs b/Duplicati/Library/AutoUpdater/Program.cs
index ae15c0b64..4a9c2317c 100644
--- a/Duplicati/Library/AutoUpdater/Program.cs
+++ b/Duplicati/Library/AutoUpdater/Program.cs
@@ -25,6 +25,7 @@ namespace Duplicati.Library.AutoUpdater
{
public static int Main(string[] args)
{
+ Duplicati.Library.AutoUpdater.UpdaterManager.IgnoreWebrootFolder = true;
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args, AutoUpdateStrategy.Never);
}
diff --git a/Duplicati/Library/AutoUpdater/UpdaterManager.cs b/Duplicati/Library/AutoUpdater/UpdaterManager.cs
index c992e5015..6f0857cf8 100644
--- a/Duplicati/Library/AutoUpdater/UpdaterManager.cs
+++ b/Duplicati/Library/AutoUpdater/UpdaterManager.cs
@@ -18,6 +18,8 @@
using System;
using System.Linq;
using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
namespace Duplicati.Library.AutoUpdater
{
@@ -34,6 +36,11 @@ namespace Duplicati.Library.AutoUpdater
public static class UpdaterManager
{
+ /// <summary>
+ /// The magic exit code that signals an update has been installed and that the app should restart
+ /// </summary>
+ public const int MAGIC_EXIT_CODE = 126;
+
private static readonly System.Security.Cryptography.RSACryptoServiceProvider SIGN_KEY = AutoUpdateSettings.SignKey;
private static readonly string[] MANIFEST_URLS = AutoUpdateSettings.URLs;
private static readonly string APPNAME = AutoUpdateSettings.AppName;
@@ -49,6 +56,8 @@ namespace Duplicati.Library.AutoUpdater
public static bool RequiresRespawn { get; set; }
+ public static bool IgnoreWebrootFolder { get; set; }
+
private static KeyValuePair<string, UpdateInfo>? m_hasUpdateInstalled;
public static readonly UpdateInfo SelfVersion;
@@ -127,7 +136,7 @@ namespace Duplicati.Library.AutoUpdater
}
// Previous locations that we don't want to use,
- // but we keep them active to avoid breaking the update syste
+ // but we keep them active to avoid breaking the update system
var legacypaths = new List<string>();
if (!string.IsNullOrWhiteSpace(programfiles))
@@ -341,7 +350,7 @@ namespace Duplicati.Library.AutoUpdater
return null;
// Don't install a debug update on a release build and vice versa
- if (string.Equals(SelfVersion.ReleaseType, "Debug", StringComparison.InvariantCultureIgnoreCase) && !string.Equals(update.ReleaseType, SelfVersion.ReleaseType, StringComparison.CurrentCultureIgnoreCase))
+ if (string.Equals(SelfVersion.ReleaseType, "Debug", StringComparison.OrdinalIgnoreCase) && !string.Equals(update.ReleaseType, SelfVersion.ReleaseType, StringComparison.CurrentCultureIgnoreCase))
return null;
ReleaseType rt;
@@ -477,7 +486,7 @@ namespace Duplicati.Library.AutoUpdater
{
foreach(var file in zip.ListFilesWithSize(""))
{
- if (System.IO.Path.IsPathRooted(file.Key) || file.Key.Trim().StartsWith("..", StringComparison.InvariantCultureIgnoreCase))
+ if (System.IO.Path.IsPathRooted(file.Key) || file.Key.Trim().StartsWith("..", StringComparison.OrdinalIgnoreCase))
throw new Exception(string.Format("Out-of-place file path detected: {0}", file.Key));
var targetpath = System.IO.Path.Combine(tempfolder, file.Key);
@@ -604,6 +613,9 @@ namespace Duplicati.Library.AutoUpdater
if (string.IsNullOrWhiteSpace(relpath))
continue;
+ if (IgnoreWebrootFolder && relpath.StartsWith("webroot"))
+ continue;
+
FileEntry fe;
if (!paths.TryGetValue(relpath, out fe))
{
@@ -997,8 +1009,114 @@ namespace Duplicati.Library.AutoUpdater
}
}
+ private static KeyValuePair<string, UpdateInfo> GetBestUpdateVersion(bool forcecheck = false)
+ {
+ if (forcecheck)
+ m_hasUpdateInstalled = null;
+
+ // Check if there are updates installed, otherwise use current
+ KeyValuePair<string, UpdateInfo> best = new KeyValuePair<string, UpdateInfo>(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, SelfVersion);
+ if (HasUpdateInstalled)
+ best = m_hasUpdateInstalled.Value;
+
+ if (INSTALLDIR != null && System.IO.File.Exists(System.IO.Path.Combine(INSTALLDIR, CURRENT_FILE)))
+ {
+ try
+ {
+ var current = System.IO.File.ReadAllText(System.IO.Path.Combine(INSTALLDIR, CURRENT_FILE)).Trim();
+ if (!string.IsNullOrWhiteSpace(current))
+ {
+ var targetfolder = System.IO.Path.Combine(INSTALLDIR, current);
+ var currentmanifest = ReadInstalledManifest(targetfolder);
+ if (currentmanifest != null && TryParseVersion(currentmanifest.Version) > TryParseVersion(best.Value.Version) && VerifyUnpackedFolder(targetfolder, currentmanifest))
+ best = new KeyValuePair<string, UpdateInfo>(targetfolder, currentmanifest);
+ }
+ }
+ catch (Exception ex)
+ {
+ if (OnError != null)
+ OnError(ex);
+ }
+ }
+
+ return best;
+ }
+
+ public static bool IsRunningInUpdateEnvironment => !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(string.Format(BASEINSTALLDIR_ENVNAME_TEMPLATE, APPNAME)));
+
public static int RunFromMostRecent(System.Reflection.MethodInfo method, string[] cmdargs, AutoUpdateStrategy defaultstrategy = AutoUpdateStrategy.CheckDuring)
{
+ return RunFromMostRecentSpawn(method, cmdargs, defaultstrategy);
+ }
+
+ public static int RunFromMostRecentSpawn(System.Reflection.MethodInfo method, string[] cmdargs, AutoUpdateStrategy defaultstrategy = AutoUpdateStrategy.CheckDuring)
+ {
+ // If the update is disabled, go straight in
+ //if (DISABLE_UPDATE_DOMAIN)
+ // return RunMethod(method, cmdargs);
+
+ // If we are not the primary entry, just execute
+ if (IsRunningInUpdateEnvironment)
+ {
+ int r = 0;
+ WrapWithUpdater(defaultstrategy, () => {
+ r = RunMethod(method, cmdargs);
+ });
+
+ return r;
+ }
+
+ var args = Environment.CommandLine;
+ var app = Environment.GetCommandLineArgs().First();
+ args = args.Substring(app.Length);
+
+ if (!Path.IsPathRooted(app))
+ app = Path.Combine(InstalledBaseDir, app);
+
+ var executable = Path.GetFileName(app);
+
+ while (true)
+ {
+ var best = GetBestUpdateVersion(true);
+ var folder = best.Key;
+
+ var pi = new System.Diagnostics.ProcessStartInfo(Path.Combine(folder, executable), args)
+ {
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ RedirectStandardError = true,
+ RedirectStandardInput = true,
+ RedirectStandardOutput = true,
+ ErrorDialog = false,
+ };
+ pi.EnvironmentVariables.Clear();
+
+ var cur = Environment.GetEnvironmentVariables();
+ foreach (var e in cur.Keys)
+ if (e is string)
+ pi.EnvironmentVariables[(string)e] = cur[(string)e] as string;
+
+ pi.EnvironmentVariables[string.Format(BASEINSTALLDIR_ENVNAME_TEMPLATE, APPNAME)] = InstalledBaseDir;
+ pi.EnvironmentVariables["LOCALIZATION_FOLDER"] = InstalledBaseDir;
+
+ var proc = System.Diagnostics.Process.Start(pi);
+ var tasks = Task.WhenAll(
+ Console.OpenStandardInput().CopyToAsync(proc.StandardInput.BaseStream),
+ proc.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput()),
+ proc.StandardError.BaseStream.CopyToAsync(Console.OpenStandardError())
+ );
+
+ proc.WaitForExit();
+ tasks.Wait(1000);
+
+ if (proc.ExitCode != MAGIC_EXIT_CODE)
+ return proc.ExitCode;
+ }
+
+ }
+
+ public static int RunFromMostRecentAppDomain(System.Reflection.MethodInfo method, string[] cmdargs, AutoUpdateStrategy defaultstrategy = AutoUpdateStrategy.CheckDuring)
+ {
// If the update is disabled, go straight in
if (DISABLE_UPDATE_DOMAIN)
return RunMethod(method, cmdargs);
@@ -1036,7 +1154,7 @@ namespace Duplicati.Library.AutoUpdater
{
var targetfolder = System.IO.Path.Combine(INSTALLDIR, current);
var currentmanifest = ReadInstalledManifest(targetfolder);
- if (currentmanifest != null && VerifyUnpackedFolder(targetfolder, currentmanifest))
+ if (currentmanifest != null && TryParseVersion(currentmanifest.Version) > TryParseVersion(best.Value.Version) && VerifyUnpackedFolder(targetfolder, currentmanifest))
best = new KeyValuePair<string, UpdateInfo>(targetfolder, currentmanifest);
}
}
diff --git a/Duplicati/Library/AutoUpdater/packages.config b/Duplicati/Library/AutoUpdater/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/AutoUpdater/packages.config
+++ b/Duplicati/Library/AutoUpdater/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/AlternativeFTP/AlternativeFTPBackend.cs b/Duplicati/Library/Backend/AlternativeFTP/AlternativeFTPBackend.cs
index a96df6616..032854043 100644
--- a/Duplicati/Library/Backend/AlternativeFTP/AlternativeFTPBackend.cs
+++ b/Duplicati/Library/Backend/AlternativeFTP/AlternativeFTPBackend.cs
@@ -44,6 +44,9 @@ namespace Duplicati.Library.Backend.AlternativeFTP
private const string CONFIG_KEY_AFTP_DATA_CONNECTION_TYPE = "aftp-data-connection-type";
private const string CONFIG_KEY_AFTP_SSL_PROTOCOLS = "aftp-ssl-protocols";
+ private const string TEST_FILE_NAME = "duplicati-access-privileges-test.tmp";
+ private const string TEST_FILE_CONTENT = "This file used by Duplicati to test access permissions and could be safely deleted.";
+
// ReSharper disable InconsistentNaming
private static readonly string DEFAULT_DATA_CONNECTION_TYPE_STRING = DEFAULT_DATA_CONNECTION_TYPE.ToString();
private static readonly string DEFAULT_ENCRYPTION_MODE_STRING = DEFAULT_ENCRYPTION_MODE.ToString();
@@ -76,18 +79,21 @@ namespace Duplicati.Library.Backend.AlternativeFTP
get { return "aftp"; }
}
+ private FtpClient Client
+ { get; set; }
+
public IList<ICommandLineArgument> SupportedCommands
{
get
{
return new List<ICommandLineArgument>(new ICommandLineArgument[] {
- new CommandLineArgument("auth-password", CommandLineArgument.ArgumentType.Password, Strings.DescriptionAuthPasswordShort, Strings.DescriptionAuthPasswordLong),
- new CommandLineArgument("auth-username", CommandLineArgument.ArgumentType.String, Strings.DescriptionAuthUsernameShort, Strings.DescriptionAuthUsernameLong),
- new CommandLineArgument("disable-upload-verify", CommandLineArgument.ArgumentType.Boolean, Strings.DescriptionDisableUploadVerifyShort, Strings.DescriptionDisableUploadVerifyLong),
- new CommandLineArgument(CONFIG_KEY_AFTP_DATA_CONNECTION_TYPE, CommandLineArgument.ArgumentType.Enumeration, Strings.DescriptionFtpDataConnectionTypeShort, Strings.DescriptionFtpDataConnectionTypeLong, DEFAULT_DATA_CONNECTION_TYPE_STRING, null, Enum.GetNames(typeof(FtpDataConnectionType))),
- new CommandLineArgument(CONFIG_KEY_AFTP_ENCRYPTION_MODE, CommandLineArgument.ArgumentType.Enumeration, Strings.DescriptionFtpEncryptionModeShort, Strings.DescriptionFtpEncryptionModeLong, DEFAULT_ENCRYPTION_MODE_STRING, null, Enum.GetNames(typeof(FtpEncryptionMode))),
- new CommandLineArgument(CONFIG_KEY_AFTP_SSL_PROTOCOLS, CommandLineArgument.ArgumentType.Flags, Strings.DescriptionSslProtocolsShort, Strings.DescriptionSslProtocolsLong, DEFAULT_SSL_PROTOCOLS_STRING, null, Enum.GetNames(typeof(SslProtocols))),
- });
+ new CommandLineArgument("auth-password", CommandLineArgument.ArgumentType.Password, Strings.DescriptionAuthPasswordShort, Strings.DescriptionAuthPasswordLong),
+ new CommandLineArgument("auth-username", CommandLineArgument.ArgumentType.String, Strings.DescriptionAuthUsernameShort, Strings.DescriptionAuthUsernameLong),
+ new CommandLineArgument("disable-upload-verify", CommandLineArgument.ArgumentType.Boolean, Strings.DescriptionDisableUploadVerifyShort, Strings.DescriptionDisableUploadVerifyLong),
+ new CommandLineArgument(CONFIG_KEY_AFTP_DATA_CONNECTION_TYPE, CommandLineArgument.ArgumentType.Enumeration, Strings.DescriptionFtpDataConnectionTypeShort, Strings.DescriptionFtpDataConnectionTypeLong, DEFAULT_DATA_CONNECTION_TYPE_STRING, null, Enum.GetNames(typeof(FtpDataConnectionType))),
+ new CommandLineArgument(CONFIG_KEY_AFTP_ENCRYPTION_MODE, CommandLineArgument.ArgumentType.Enumeration, Strings.DescriptionFtpEncryptionModeShort, Strings.DescriptionFtpEncryptionModeLong, DEFAULT_ENCRYPTION_MODE_STRING, null, Enum.GetNames(typeof(FtpEncryptionMode))),
+ new CommandLineArgument(CONFIG_KEY_AFTP_SSL_PROTOCOLS, CommandLineArgument.ArgumentType.Flags, Strings.DescriptionSslProtocolsShort, Strings.DescriptionSslProtocolsLong, DEFAULT_SSL_PROTOCOLS_STRING, null, Enum.GetNames(typeof(SslProtocols))),
+ });
}
}
@@ -188,49 +194,48 @@ namespace Duplicati.Library.Backend.AlternativeFTP
}
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
return List("");
}
- public List<IFileEntry> List(string filename)
+ public IEnumerable<IFileEntry> List(string filename)
{
return List(filename, false);
}
- private List<IFileEntry> List(string filename, bool stripFile)
+ private IEnumerable<IFileEntry> List(string filename, bool stripFile)
{
var list = new List<IFileEntry>();
string remotePath = filename;
try
{
- using (var ftpClient = CreateClient())
- {
- var url = new Uri(_url);
+ var ftpClient = CreateClient();
- // Get the remote path
- remotePath = url.AbsolutePath.EndsWith("/") ? url.AbsolutePath.Substring(0, url.AbsolutePath.Length - 1) : url.AbsolutePath;
+ // Get the remote path
+ var url = new Uri(this._url);
+ remotePath = "/" + (url.AbsolutePath.EndsWith("/") ? url.AbsolutePath.Substring(0, url.AbsolutePath.Length - 1) : url.AbsolutePath);
- if (!string.IsNullOrEmpty(filename))
+ if (!string.IsNullOrEmpty(filename))
+ {
+ if (!stripFile)
{
- if (!stripFile)
- {
- // Append the filename
- remotePath += "/" + filename;
- }
- else if (filename.Contains("/"))
- {
- remotePath += filename.Substring(0, filename.LastIndexOf("/", StringComparison.InvariantCulture));
- }
- // else: stripping the filename in this case ignoring it
+ // Append the filename
+ remotePath += filename;
+ }
+ else if (filename.Contains("/"))
+ {
+ remotePath += filename.Substring(0, filename.LastIndexOf("/", StringComparison.Ordinal));
}
+ // else: stripping the filename in this case ignoring it
+ }
- foreach (FtpListItem item in ftpClient.GetListing(remotePath, FtpListOption.Modify | FtpListOption.Size | FtpListOption.DerefLinks))
+ foreach (FtpListItem item in ftpClient.GetListing(remotePath, FtpListOption.Modify | FtpListOption.Size | FtpListOption.DerefLinks))
+ {
+ switch (item.Type)
{
- switch (item.Type)
- {
- case FtpFileSystemObjectType.Directory:
+ case FtpFileSystemObjectType.Directory:
{
if (item.Name == "." || item.Name == "..")
{
@@ -244,13 +249,13 @@ namespace Duplicati.Library.Backend.AlternativeFTP
break;
}
- case FtpFileSystemObjectType.File:
+ case FtpFileSystemObjectType.File:
{
list.Add(new FileEntry(item.Name, item.Size, new DateTime(), item.Modified));
break;
}
- case FtpFileSystemObjectType.Link:
+ case FtpFileSystemObjectType.Link:
{
if (item.Name == "." || item.Name == "..")
{
@@ -262,30 +267,30 @@ namespace Duplicati.Library.Backend.AlternativeFTP
switch (item.LinkObject.Type)
{
case FtpFileSystemObjectType.Directory:
- {
- if (item.Name == "." || item.Name == "..")
{
- continue;
- }
+ if (item.Name == "." || item.Name == "..")
+ {
+ continue;
+ }
- list.Add(new FileEntry(item.Name, -1, new DateTime(), item.Modified)
- {
- IsFolder = true,
- });
+ list.Add(new FileEntry(item.Name, -1, new DateTime(), item.Modified)
+ {
+ IsFolder = true,
+ });
- break;
- }
+ break;
+ }
case FtpFileSystemObjectType.File:
- {
- list.Add(new FileEntry(item.Name, item.Size, new DateTime(), item.Modified));
+ {
+ list.Add(new FileEntry(item.Name, item.Size, new DateTime(), item.Modified));
- break;
- }
+ break;
+ }
}
}
break;
}
- }
+
}
}
}// Message "Directory not found." string
@@ -309,42 +314,40 @@ namespace Duplicati.Library.Backend.AlternativeFTP
try
{
- using (var ftpClient = CreateClient())
+ var ftpClient = CreateClient();
+
+ try
+ {
+ streamLen = input.Length;
+ }
+ // ReSharper disable once EmptyGeneralCatchClause
+ catch
{
- try
- {
- streamLen = input.Length;
- }
- // ReSharper disable once EmptyGeneralCatchClause
- catch
- {
- }
+ }
- var url = new Uri(_url);
+ // Get the remote path
+ remotePath = "";
- // Get the remote path
- remotePath = url.AbsolutePath.EndsWith("/") ? url.AbsolutePath.Substring(0, url.AbsolutePath.Length - 1) : url.AbsolutePath;
+ if (!string.IsNullOrEmpty(remotename))
+ {
+ // Append the filename
+ remotePath += remotename;
+ }
- if (!string.IsNullOrEmpty(remotename))
+ using (var outputStream = ftpClient.OpenWrite(remotePath))
+ {
+ try
{
- // Append the filename
- remotePath += "/" + remotename;
+ CoreUtility.CopyStream(input, outputStream, true, _copybuffer);
}
-
- using (var outputStream = ftpClient.OpenWrite(remotePath))
+ finally
{
- try
- {
- CoreUtility.CopyStream(input, outputStream, true, _copybuffer);
- }
- finally
- {
- outputStream.Close();
- }
+ outputStream.Close();
}
}
+
if (_listVerify)
{
var fileEntries = List(remotename, true);
@@ -358,11 +361,11 @@ namespace Duplicati.Library.Backend.AlternativeFTP
return;
}
- throw new Exception(Strings.ListVerifySizeFailure(remotename, fileEntry.Size, streamLen));
+ throw new UserInformationException(Strings.ListVerifySizeFailure(remotename, fileEntry.Size, streamLen));
}
}
- throw new Exception(Strings.ListVerifyFailure(remotename, fileEntries.Select(n => n.Name)));
+ throw new UserInformationException(Strings.ListVerifyFailure(remotename, fileEntries.Select(n => n.Name)));
}
}
catch (FtpCommandException ex)
@@ -386,31 +389,29 @@ namespace Duplicati.Library.Backend.AlternativeFTP
public void Get(string remotename, System.IO.Stream output)
{
- using (var ftpClient = CreateClient())
- {
- var url = new Uri(_url);
+ var ftpClient = CreateClient();
- // Get the remote path
- var remotePath = url.AbsolutePath.EndsWith("/") ? url.AbsolutePath.Substring(0, url.AbsolutePath.Length - 1) : url.AbsolutePath;
+ // Get the remote path
+ var remotePath = "";
- if (!string.IsNullOrEmpty(remotename))
+ if (!string.IsNullOrEmpty(remotename))
+ {
+ // Append the filename
+ remotePath += remotename;
+ }
+
+ using (var inputStream = ftpClient.OpenRead(remotePath))
+ {
+ try
{
- // Append the filename
- remotePath += "/" + remotename;
+ CoreUtility.CopyStream(inputStream, output, false, _copybuffer);
}
-
- using (var inputStream = ftpClient.OpenRead(remotePath))
+ finally
{
- try
- {
- CoreUtility.CopyStream(inputStream, output, false, _copybuffer);
- }
- finally
- {
- inputStream.Close();
- }
+ inputStream.Close();
}
}
+
}
public void Get(string remotename, string localname)
@@ -423,21 +424,19 @@ namespace Duplicati.Library.Backend.AlternativeFTP
public void Delete(string remotename)
{
- using (var ftpClient = CreateClient())
- {
- var url = new Uri(_url);
+ var ftpClient = CreateClient();
- // Get the remote path
- var remotePath = url.AbsolutePath.EndsWith("/") ? url.AbsolutePath.Substring(0, url.AbsolutePath.Length - 1) : url.AbsolutePath;
+ // Get the remote path
+ var remotePath = "";
- if (!string.IsNullOrEmpty(remotename))
- {
- // Append the filename
- remotePath += "/" + remotename;
- }
-
- ftpClient.DeleteFile(remotePath);
+ if (!string.IsNullOrEmpty(remotename))
+ {
+ // Append the filename
+ remotePath += remotename;
}
+
+ ftpClient.DeleteFile(remotePath);
+
}
/// <summary>
@@ -451,50 +450,124 @@ namespace Duplicati.Library.Backend.AlternativeFTP
}
}
- public void Test()
+ private static System.IO.Stream StringToStream(string str)
{
- List();
+ var stream = new System.IO.MemoryStream();
+ var writer = new System.IO.StreamWriter(stream) { AutoFlush = true };
+ writer.Write(str);
+ return stream;
}
- public void CreateFolder()
+ /// <summary>
+ /// Test FTP access permissions.
+ /// </summary>
+ public void Test()
{
- using (var client = CreateClient())
+ var list = List();
+
+ // Delete test file if exists
+ if (list.Any(entry => entry.Name == TEST_FILE_NAME))
{
- var url = new Uri(_url);
+ try
+ {
+ Delete(TEST_FILE_NAME);
+ }
+ catch (Exception e)
+ {
+ throw new Exception(string.Format(Strings.ErrorDeleteFile, e.Message), e);
+ }
+ }
- // Get the remote path
- var remotePath = url.AbsolutePath.EndsWith("/") ? url.AbsolutePath.Substring(0, url.AbsolutePath.Length - 1) : url.AbsolutePath;
+ // Test write permissions
+ using (var testStream = StringToStream(TEST_FILE_CONTENT))
+ {
+ try
+ {
+ Put(TEST_FILE_NAME, testStream);
+ }
+ catch (Exception e)
+ {
+ throw new Exception(string.Format(Strings.ErrorWriteFile, e.Message), e);
+ }
+ }
- // Try to create the directory
- client.CreateDirectory(remotePath, true);
+ // Test read permissions
+ using (var stream = new System.IO.MemoryStream())
+ {
+ try
+ {
+ Get(TEST_FILE_NAME, stream);
+ }
+ catch (Exception e)
+ {
+ throw new Exception(string.Format(Strings.ErrorReadFile, e.Message), e);
+ }
+ }
+
+ // Cleanup
+ try
+ {
+ Delete(TEST_FILE_NAME);
+ }
+ catch (Exception e)
+ {
+ throw new Exception(string.Format(Strings.ErrorDeleteFile, e.Message), e);
}
}
+ public void CreateFolder()
+ {
+ var client = CreateClient();
+
+ var url = new Uri(_url);
+
+ // Get the remote path
+ var remotePath = url.AbsolutePath.EndsWith("/") ? url.AbsolutePath.Substring(0, url.AbsolutePath.Length - 1) : url.AbsolutePath;
+
+ // Try to create the directory
+ client.CreateDirectory(remotePath, true);
+
+ }
+
public void Dispose()
{
+ if (Client != null)
+ Client.Dispose();
+
+ Client = null;
_userInfo = null;
}
private FtpClient CreateClient()
{
- var url = _url;
+ if (this.Client == null) // Create connection if it doesn't exist yet
+ {
- var uri = new Uri(url);
+ var url = _url;
- var ftpClient = new FtpClient
- {
- Host = uri.Host,
- Port = uri.Port == -1 ? 21 : uri.Port,
- Credentials = _userInfo,
- EncryptionMode = _encryptionMode,
- DataConnectionType = _dataConnectionType,
- SslProtocols = _sslProtocols,
- EnableThreadSafeDataConnections = true, // Required to work properly but can result in up to 3 connections being used even when you expect just one..
- };
-
- ftpClient.ValidateCertificate += HandleValidateCertificate;
-
- return ftpClient;
+ var uri = new Uri(url);
+
+ var ftpClient = new FtpClient
+ {
+ Host = uri.Host,
+ Port = uri.Port == -1 ? 21 : uri.Port,
+ Credentials = _userInfo,
+ EncryptionMode = _encryptionMode,
+ DataConnectionType = _dataConnectionType,
+ SslProtocols = _sslProtocols,
+ EnableThreadSafeDataConnections = true, // Required to work properly but can result in up to 3 connections being used even when you expect just one..
+ };
+
+ ftpClient.ValidateCertificate += HandleValidateCertificate;
+
+ // Get the remote path
+ var remotePath = uri.AbsolutePath.EndsWith("/") ? uri.AbsolutePath.Substring(0, uri.AbsolutePath.Length - 1) : uri.AbsolutePath;
+ ftpClient.SetWorkingDirectory(remotePath);
+
+ this.Client = ftpClient;
+ } // else reuse existing connection
+
+ return this.Client;
}
private void HandleValidateCertificate(FtpClient control, FtpSslValidationEventArgs e)
@@ -510,7 +583,7 @@ namespace Duplicati.Library.Backend.AlternativeFTP
var certHash = (_validHashes != null && _validHashes.Length > 0) ? CoreUtility.ByteArrayAsHexString(e.Certificate.GetCertHash()) : null;
if (certHash != null)
{
- if (_validHashes.Any(hash => !string.IsNullOrEmpty(hash) && certHash.Equals(hash, StringComparison.InvariantCultureIgnoreCase)))
+ if (_validHashes.Any(hash => !string.IsNullOrEmpty(hash) && certHash.Equals(hash, StringComparison.OrdinalIgnoreCase)))
{
e.Accept = true;
}
diff --git a/Duplicati/Library/Backend/AlternativeFTP/Duplicati.Library.Backend.AlternativeFTP.csproj b/Duplicati/Library/Backend/AlternativeFTP/Duplicati.Library.Backend.AlternativeFTP.csproj
index 3ff33aed6..3acbabe71 100644
--- a/Duplicati/Library/Backend/AlternativeFTP/Duplicati.Library.Backend.AlternativeFTP.csproj
+++ b/Duplicati/Library/Backend/AlternativeFTP/Duplicati.Library.Backend.AlternativeFTP.csproj
@@ -1,86 +1,84 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Duplicati.Library.Backend.AlternativeFTP</RootNamespace>
- <AssemblyName>Duplicati.Library.Backend.AlternativeFTP</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup>
- <SignAssembly>true</SignAssembly>
- </PropertyGroup>
- <PropertyGroup>
- <AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Net.Http" />
- <Reference Include="System.Xml" />
- <Reference Include="System.Net.FtpClient">
- <HintPath>..\..\..\..\thirdparty\System.Net.FtpClient\System.Net.FtpClient.dll</HintPath>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="AlternativeFTPBackend.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Strings.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="app.config" />
- <None Include="Duplicati.snk" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
- <Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
- <Name>Duplicati.Library.Interface</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Localization\Duplicati.Library.Localization.csproj">
- <Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
- <Name>Duplicati.Library.Localization</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj">
- <Project>{52826615-7964-47FE-B4B3-1B2DBDF605B9}</Project>
- <Name>Duplicati.Library.Modules.Builtin</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Utility\Duplicati.Library.Utility.csproj">
- <Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
- <Name>Duplicati.Library.Utility</Name>
- </ProjectReference>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{3F47CB0C-CEE1-447F-9C26-7F8E419E3E3F}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Duplicati.Library.Backend.AlternativeFTP</RootNamespace>
+ <AssemblyName>Duplicati.Library.Backend.AlternativeFTP</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Net.FtpClient">
+ <HintPath>..\..\..\..\thirdparty\System.Net.FtpClient\System.Net.FtpClient.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AlternativeFTPBackend.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Strings.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="Duplicati.snk" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
+ <Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
+ <Name>Duplicati.Library.Interface</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Localization\Duplicati.Library.Localization.csproj">
+ <Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
+ <Name>Duplicati.Library.Localization</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj">
+ <Project>{52826615-7964-47FE-B4B3-1B2DBDF605B9}</Project>
+ <Name>Duplicati.Library.Modules.Builtin</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Utility\Duplicati.Library.Utility.csproj">
+ <Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
+ <Name>Duplicati.Library.Utility</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
</Project> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/AlternativeFTP/Strings.cs b/Duplicati/Library/Backend/AlternativeFTP/Strings.cs
index 82b3df4f5..4b99e0fbb 100644
--- a/Duplicati/Library/Backend/AlternativeFTP/Strings.cs
+++ b/Duplicati/Library/Backend/AlternativeFTP/Strings.cs
@@ -23,5 +23,8 @@ namespace Duplicati.Library.Backend.AlternativeFTP
public static string DescriptionFtpEncryptionModeShort { get { return LC.L(@"Configure the FTP encryption mode"); } }
public static string DescriptionSslProtocolsLong { get { return LC.L(@"This flag controls the SSL policy to use when encryption is enabled."); } }
public static string DescriptionSslProtocolsShort { get { return LC.L(@"Configure the SSL policy to use when encryption is enabled"); } }
+ public static string ErrorDeleteFile { get { return LC.L(@"Error on deleting file: {0}"); } }
+ public static string ErrorReadFile { get { return LC.L(@"Error reading file: {0}"); } }
+ public static string ErrorWriteFile { get { return LC.L(@"Error writing file: {0}"); } }
}
}
diff --git a/Duplicati/Library/Backend/AmazonCloudDrive/AmzCD.cs b/Duplicati/Library/Backend/AmazonCloudDrive/AmzCD.cs
index 116ed5ca4..b68319333 100644
--- a/Duplicati/Library/Backend/AmazonCloudDrive/AmzCD.cs
+++ b/Duplicati/Library/Backend/AmazonCloudDrive/AmzCD.cs
@@ -54,6 +54,18 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
private DateTime m_waitUntil;
private TimeSpan m_delayTimeSpan;
+ private enum RemoteOperation
+ {
+ First,
+ List,
+ Get,
+ Put,
+ Delete,
+ Rename
+ }
+
+ private RemoteOperation m_lastOperation = RemoteOperation.First;
+
public AmzCD()
{
}
@@ -85,11 +97,27 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
m_delayTimeSpan = new TimeSpan(0);
else
m_delayTimeSpan = Library.Utility.Timeparser.ParseTimeSpan(delay);
+ m_waitUntil = DateTime.Now + m_delayTimeSpan;
m_oauth = new OAuthHelper(authid, this.ProtocolKey) { AutoAuthHeader = true };
m_userid = authid.Split(new string[] {":"}, StringSplitOptions.RemoveEmptyEntries).First();
}
-
+
+ private void EnforceConsistencyDelay(RemoteOperation lastop)
+ {
+ if (m_lastOperation == RemoteOperation.First)
+ m_lastOperation = lastop;
+
+ if (lastop == m_lastOperation)
+ return;
+
+ m_lastOperation = lastop;
+
+ var wait = m_waitUntil - DateTime.Now;
+ if (wait.Ticks > 0)
+ System.Threading.Thread.Sleep(wait);
+ }
+
private string CacheFilePath { get { return Path.Combine(Utility.TempFolder.SystemTempPath, string.Format(CACHE_FILE_NAME_TEMPLATE, m_userid)); } }
private void RefreshMetadataAndContentUrl()
@@ -193,9 +221,10 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
rs.Write(data, 0, data.Length);
}
);
+ m_waitUntil = DateTime.Now + m_delayTimeSpan;
}
else if (self != null && self.Count > 1)
- throw new Exception(Strings.AmzCD.MultipleEntries(p, "/" + string.Join("/", curpath)));
+ throw new UserInformationException(Strings.AmzCD.MultipleEntries(p, "/" + string.Join("/", curpath)));
else
parent = self.Data.First();
}
@@ -248,7 +277,7 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
#region IStreamingBackend implementation
public void Put(string remotename, System.IO.Stream stream)
{
- m_waitUntil = DateTime.Now + m_delayTimeSpan;
+ EnforceConsistencyDelay(RemoteOperation.Put);
var overwrite = FileCache.ContainsKey(remotename);
var fileid = overwrite ? m_filecache[remotename] : null;
@@ -291,9 +320,15 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
m_filecache = null;
throw;
}
+ finally
+ {
+ m_waitUntil = DateTime.Now + m_delayTimeSpan;
+ }
}
public void Get(string remotename, System.IO.Stream stream)
{
+ EnforceConsistencyDelay(RemoteOperation.Get);
+
using (var resp = m_oauth.GetResponse(string.Format("{0}/nodes/{1}/content", ContentUrl, GetFileID(remotename))))
using(var rs = Library.Utility.AsyncHttpRequest.TrySetTimeout(resp.GetResponseStream()))
Utility.Utility.CopyStream(rs, stream);
@@ -301,11 +336,9 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
#endregion
#region IBackend implementation
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
- var wait = m_waitUntil - DateTime.Now;
- if (wait.Ticks > 0)
- System.Threading.Thread.Sleep(wait);
+ EnforceConsistencyDelay(RemoteOperation.List);
var query = string.Format("{0}/nodes?filters=parents:{1}&limit={2}", MetadataUrl, Utility.Uri.UrlEncode(CurrentDirectory.ID), PAGE_SIZE);
var res = new List<IFileEntry>();
@@ -321,9 +354,9 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
foreach(var n in lst.Data)
{
- if (string.Equals(CONTENT_KIND_FOLDER, n.Kind, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(CONTENT_KIND_FOLDER, n.Kind, StringComparison.OrdinalIgnoreCase))
res.Add(new FileEntry(n.Name) { IsFolder = true });
- else if (string.Equals(CONTENT_KIND_FILE, n.Kind, StringComparison.InvariantCultureIgnoreCase))
+ else if (string.Equals(CONTENT_KIND_FILE, n.Kind, StringComparison.OrdinalIgnoreCase))
{
cache[n.Name] = n.ID;
@@ -365,10 +398,10 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
}
public void Delete(string remotename)
{
+ EnforceConsistencyDelay(RemoteOperation.Delete);
+
try
{
- m_waitUntil = DateTime.Now + m_delayTimeSpan;
-
using(m_oauth.GetResponse(string.Format("{0}/trash/{1}", MetadataUrl, GetFileID(remotename)), null, "PUT"))
{
}
@@ -379,13 +412,15 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
{
m_filecache = null;
}
+ m_waitUntil = DateTime.Now + m_delayTimeSpan;
}
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
{
+ EnforceConsistencyDelay(RemoteOperation.List);
GetCurrentDirectory(true);
}
public string DisplayName
@@ -432,6 +467,8 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
#region IRenameEnabledBackend
public void Rename(string oldname, string newname)
{
+ EnforceConsistencyDelay(RemoteOperation.Rename);
+
var id = GetFileID(oldname);
var data = System.Text.Encoding.UTF8.GetBytes(
@@ -464,6 +501,10 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
m_filecache = null;
throw;
}
+ finally
+ {
+ m_waitUntil = DateTime.Now + m_delayTimeSpan;
+ }
}
#endregion
diff --git a/Duplicati/Library/Backend/AmazonCloudDrive/Duplicati.Library.Backend.AmazonCloudDrive.csproj b/Duplicati/Library/Backend/AmazonCloudDrive/Duplicati.Library.Backend.AmazonCloudDrive.csproj
index 9d5e22c66..c8a3b4888 100644
--- a/Duplicati/Library/Backend/AmazonCloudDrive/Duplicati.Library.Backend.AmazonCloudDrive.csproj
+++ b/Duplicati/Library/Backend/AmazonCloudDrive/Duplicati.Library.Backend.AmazonCloudDrive.csproj
@@ -10,6 +10,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -32,7 +33,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/AmazonCloudDrive/packages.config b/Duplicati/Library/Backend/AmazonCloudDrive/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Backend/AmazonCloudDrive/packages.config
+++ b/Duplicati/Library/Backend/AmazonCloudDrive/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/AzureBlob/AzureBlobBackend.cs b/Duplicati/Library/Backend/AzureBlob/AzureBlobBackend.cs
index e2d7f0f6e..d55eb17b0 100644
--- a/Duplicati/Library/Backend/AzureBlob/AzureBlobBackend.cs
+++ b/Duplicati/Library/Backend/AzureBlob/AzureBlobBackend.cs
@@ -57,11 +57,11 @@ namespace Duplicati.Library.Backend.AzureBlob
if (string.IsNullOrWhiteSpace(storageAccountName))
{
- throw new Exception(Strings.AzureBlobBackend.NoStorageAccountName);
+ throw new UserInformationException(Strings.AzureBlobBackend.NoStorageAccountName);
}
if (string.IsNullOrWhiteSpace(accessKey))
{
- throw new Exception(Strings.AzureBlobBackend.NoAccessKey);
+ throw new UserInformationException(Strings.AzureBlobBackend.NoAccessKey);
}
_azureBlob = new AzureBlobWrapper(storageAccountName, accessKey, containerName);
@@ -82,7 +82,7 @@ namespace Duplicati.Library.Backend.AzureBlob
get { return true; }
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
return _azureBlob.ListContainerEntries();
}
@@ -161,7 +161,7 @@ namespace Duplicati.Library.Backend.AzureBlob
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
diff --git a/Duplicati/Library/Backend/AzureBlob/Duplicati.Library.Backend.AzureBlob.csproj b/Duplicati/Library/Backend/AzureBlob/Duplicati.Library.Backend.AzureBlob.csproj
index 37708d6d6..48e488838 100644
--- a/Duplicati/Library/Backend/AzureBlob/Duplicati.Library.Backend.AzureBlob.csproj
+++ b/Duplicati/Library/Backend/AzureBlob/Duplicati.Library.Backend.AzureBlob.csproj
@@ -2,6 +2,7 @@
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -37,30 +38,27 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
+ <Reference Include="System.Data" />
<Reference Include="Microsoft.Azure.KeyVault.Core">
- <HintPath>..\..\..\..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Microsoft.Azure.KeyVault.Core.2.0.4\lib\net45\Microsoft.Azure.KeyVault.Core.dll</HintPath>
</Reference>
- <Reference Include="System.Data" />
- <Reference Include="Microsoft.WindowsAzure.Storage">
- <HintPath>..\..\..\..\packages\WindowsAzure.Storage.7.0.0\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
+ <Reference Include="Microsoft.Data.Edm">
+ <HintPath>..\..\..\..\packages\Microsoft.Data.Edm.5.8.3\lib\net40\Microsoft.Data.Edm.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.WindowsAzure.Configuration">
- <HintPath>..\..\..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.3.2.1\lib\net40\Microsoft.WindowsAzure.Configuration.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Spatial">
- <HintPath>..\..\..\..\packages\System.Spatial.5.7.0\lib\net40\System.Spatial.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.Data.Edm">
- <HintPath>..\..\..\..\packages\Microsoft.Data.Edm.5.7.0\lib\net40\Microsoft.Data.Edm.dll</HintPath>
+ <HintPath>..\..\..\..\packages\System.Spatial.5.8.3\lib\net40\System.Spatial.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.OData">
- <HintPath>..\..\..\..\packages\Microsoft.Data.OData.5.7.0\lib\net40\Microsoft.Data.OData.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Microsoft.Data.OData.5.8.3\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Services.Client">
- <HintPath>..\..\..\..\packages\Microsoft.Data.Services.Client.5.7.0\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Microsoft.Data.Services.Client.5.8.3\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.WindowsAzure.Storage">
+ <HintPath>..\..\..\..\packages\WindowsAzure.Storage.8.4.0\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/AzureBlob/packages.config b/Duplicati/Library/Backend/AzureBlob/packages.config
index 08f04fd6c..720f12ed8 100644
--- a/Duplicati/Library/Backend/AzureBlob/packages.config
+++ b/Duplicati/Library/Backend/AzureBlob/packages.config
@@ -1,11 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net45" />
- <package id="Microsoft.Data.Edm" version="5.7.0" targetFramework="net45" />
- <package id="Microsoft.Data.OData" version="5.7.0" targetFramework="net45" />
- <package id="Microsoft.Data.Services.Client" version="5.7.0" targetFramework="net45" />
- <package id="Microsoft.WindowsAzure.ConfigurationManager" version="3.2.1" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
- <package id="System.Spatial" version="5.7.0" targetFramework="net45" />
- <package id="WindowsAzure.Storage" version="7.0.0" targetFramework="net45" />
+ <package id="Microsoft.Azure.KeyVault.Core" version="2.0.4" targetFramework="net45" />
+ <package id="Microsoft.Data.Edm" version="5.8.3" targetFramework="net45" />
+ <package id="Microsoft.Data.OData" version="5.8.3" targetFramework="net45" />
+ <package id="Microsoft.Data.Services.Client" version="5.8.3" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
+ <package id="System.ComponentModel.EventBasedAsync" version="4.3.0" targetFramework="net45" />
+ <package id="System.Dynamic.Runtime" version="4.3.0" targetFramework="net45" />
+ <package id="System.Linq.Queryable" version="4.3.0" targetFramework="net45" />
+ <package id="System.Net.Requests" version="4.3.0" targetFramework="net45" />
+ <package id="System.Spatial" version="5.8.3" targetFramework="net45" />
+ <package id="WindowsAzure.Storage" version="8.4.0" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/Backblaze/B2.cs b/Duplicati/Library/Backend/Backblaze/B2.cs
index 0f9e65f81..5b8838eab 100644
--- a/Duplicati/Library/Backend/Backblaze/B2.cs
+++ b/Duplicati/Library/Backend/Backblaze/B2.cs
@@ -27,17 +27,19 @@ namespace Duplicati.Library.Backend.Backblaze
public class B2 : IBackend, IStreamingBackend
{
private const string B2_ID_OPTION = "b2-accountid";
- private const string B2_KEY_OPTION = "b2-applicationkey";
-
- private const string B2_CREATE_BUCKET_TYPE_OPTION = "b2-create-bucket-type";
+ private const string B2_KEY_OPTION = "b2-applicationkey";
+ private const string B2_PAGESIZE_OPTION = "b2-page-size";
+
+ private const string B2_CREATE_BUCKET_TYPE_OPTION = "b2-create-bucket-type";
private const string DEFAULT_BUCKET_TYPE = "allPrivate";
- private const int PAGE_SIZE = 200;
+ private const int DEFAULT_PAGE_SIZE = 500;
private string m_bucketname;
private string m_prefix;
private string m_urlencodedprefix;
private string m_bucketType;
+ private int m_pagesize;
private B2AuthHelper m_helper;
private UploadUrlResponse m_uploadUrl;
@@ -86,12 +88,21 @@ namespace Duplicati.Library.Backend.Backblaze
accountKey = uri.Password;
if (string.IsNullOrEmpty(accountId))
- throw new Exception(Strings.B2.NoB2UserIDError);
+ throw new UserInformationException(Strings.B2.NoB2UserIDError);
if (string.IsNullOrEmpty(accountKey))
- throw new Exception(Strings.B2.NoB2KeyError);
+ throw new UserInformationException(Strings.B2.NoB2KeyError);
+
+ m_helper = new B2AuthHelper(accountId, accountKey);
+
+ m_pagesize = DEFAULT_PAGE_SIZE;
+ if (options.ContainsKey(B2_PAGESIZE_OPTION))
+ {
+ int.TryParse(options[B2_PAGESIZE_OPTION], out m_pagesize);
- m_helper = new B2AuthHelper(accountId, accountKey);
- }
+ if (m_pagesize <= 0)
+ throw new UserInformationException(Strings.B2.InvalidPageSizeError(B2_PAGESIZE_OPTION, options[B2_PAGESIZE_OPTION]));
+ }
+ }
private BucketEntity Bucket
{
@@ -107,7 +118,7 @@ namespace Duplicati.Library.Backend.Backblaze
);
if (buckets != null && buckets.Buckets != null)
- m_bucket = buckets.Buckets.Where(x => string.Equals(x.BucketName, m_bucketname, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
+ m_bucket = buckets.Buckets.Where(x => string.Equals(x.BucketName, m_bucketname, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (m_bucket == null)
throw new FolderMissingException();
@@ -152,8 +163,9 @@ namespace Duplicati.Library.Backend.Backblaze
new CommandLineArgument(B2_KEY_OPTION, CommandLineArgument.ArgumentType.Password, Strings.B2.B2applicationkeyDescriptionShort, Strings.B2.B2applicationkeyDescriptionLong, null, new string[] {"auth-username"}, null),
new CommandLineArgument("auth-password", CommandLineArgument.ArgumentType.Password, Strings.B2.AuthPasswordDescriptionShort, Strings.B2.AuthPasswordDescriptionLong),
new CommandLineArgument("auth-username", CommandLineArgument.ArgumentType.String, Strings.B2.AuthUsernameDescriptionShort, Strings.B2.AuthUsernameDescriptionLong),
- new CommandLineArgument(B2_CREATE_BUCKET_TYPE_OPTION, CommandLineArgument.ArgumentType.String, Strings.B2.B2createbuckettypeDescriptionShort, Strings.B2.B2createbuckettypeDescriptionLong, DEFAULT_BUCKET_TYPE),
- });
+ new CommandLineArgument(B2_CREATE_BUCKET_TYPE_OPTION, CommandLineArgument.ArgumentType.String, Strings.B2.B2createbuckettypeDescriptionShort, Strings.B2.B2createbuckettypeDescriptionLong, DEFAULT_BUCKET_TYPE),
+ new CommandLineArgument(B2_PAGESIZE_OPTION, CommandLineArgument.ArgumentType.Integer, Strings.B2.B2pagesizeDescriptionShort, Strings.B2.B2pagesizeDescriptionLong, DEFAULT_PAGE_SIZE.ToString()),
+ });
}
}
@@ -177,7 +189,7 @@ namespace Duplicati.Library.Backend.Backblaze
var p = measure.Position;
// Compute the hash
- using(var hashalg = System.Security.Cryptography.HashAlgorithm.Create("sha1"))
+ using(var hashalg = Duplicati.Library.Utility.HashAlgorithmHelper.Create("sha1"))
sha1 = Library.Utility.Utility.ByteArrayAsHexString(hashalg.ComputeHash(measure));
// Reset the stream position
@@ -285,7 +297,7 @@ namespace Duplicati.Library.Backend.Backblaze
}
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
m_filecache = null;
var cache = new Dictionary<string, List<FileEntity>>();
@@ -297,7 +309,7 @@ namespace Duplicati.Library.Backend.Backblaze
string.Format("{0}/b2api/v1/b2_list_file_versions", m_helper.APIUrl),
new ListFilesRequest() {
BucketID = Bucket.BucketID,
- MaxFileCount = PAGE_SIZE,
+ MaxFileCount = m_pagesize,
StartFileID = nextFileID,
StartFileName = nextFileName
}
@@ -380,7 +392,7 @@ namespace Duplicati.Library.Backend.Backblaze
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
diff --git a/Duplicati/Library/Backend/Backblaze/Duplicati.Library.Backend.Backblaze.csproj b/Duplicati/Library/Backend/Backblaze/Duplicati.Library.Backend.Backblaze.csproj
index db695f659..539d02496 100644
--- a/Duplicati/Library/Backend/Backblaze/Duplicati.Library.Backend.Backblaze.csproj
+++ b/Duplicati/Library/Backend/Backblaze/Duplicati.Library.Backend.Backblaze.csproj
@@ -10,6 +10,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -32,7 +33,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/Backblaze/Strings.cs b/Duplicati/Library/Backend/Backblaze/Strings.cs
index c33d850a3..8a50106a3 100644
--- a/Duplicati/Library/Backend/Backblaze/Strings.cs
+++ b/Duplicati/Library/Backend/Backblaze/Strings.cs
@@ -14,6 +14,9 @@ namespace Duplicati.Library.Backend.Strings {
public static string NoB2UserIDError { get { return LC.L(@"No ""B2 Cloud Storage Account ID"" given"); } }
public static string Description { get { return LC.L(@"This backend can read and write data to the Backblaze B2 Cloud Storage. Allowed formats are: ""b2://bucketname/prefix"""); } }
public static string B2createbuckettypeDescriptionLong { get { return LC.L(@"By default, a private bucket is created. Use this option to set the bucket type. Refer to the B2 documentation for allowed types "); } }
- public static string B2createbuckettypeDescriptionShort { get { return LC.L(@"The bucket type used when creating a bucket"); } }
- }
+ public static string B2createbuckettypeDescriptionShort { get { return LC.L(@"The bucket type used when creating a bucket"); } }
+ public static string B2pagesizeDescriptionLong { get { return LC.L(@"Use this option to set the page size for listing contents of B2 buckets. A lower number means less data, but can increase the number of Class C transaction on B2. Suggested values are between 100 and 1000"); } }
+ public static string B2pagesizeDescriptionShort { get { return LC.L(@"The size of file-listing pages"); } }
+ public static string InvalidPageSizeError(string argname, string value) { return LC.L(@"The setting ""{0}"" is invalid for ""{1}"", it must be an integer larger than zero", value, argname); }
+ }
}
diff --git a/Duplicati/Library/Backend/Backblaze/packages.config b/Duplicati/Library/Backend/Backblaze/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Backend/Backblaze/packages.config
+++ b/Duplicati/Library/Backend/Backblaze/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/Box/BoxBackend.cs b/Duplicati/Library/Backend/Box/BoxBackend.cs
index 51e3c838e..124a51fe7 100644
--- a/Duplicati/Library/Backend/Box/BoxBackend.cs
+++ b/Duplicati/Library/Backend/Box/BoxBackend.cs
@@ -252,12 +252,11 @@ namespace Duplicati.Library.Backend.Box
#region IBackend implementation
- public System.Collections.Generic.List<IFileEntry> List()
+ public System.Collections.Generic.IEnumerable<IFileEntry> List()
{
- return (
+ return
from n in PagedFileListResponse(CurrentFolder, false)
- select (IFileEntry)new FileEntry(n.Name, n.Size, n.ModifiedAt, n.ModifiedAt) { IsFolder = n.Type == "folder" }
- ).ToList();
+ select (IFileEntry)new FileEntry(n.Name, n.Size, n.ModifiedAt, n.ModifiedAt) { IsFolder = n.Type == "folder" };
}
public void Put(string remotename, string filename)
@@ -295,7 +294,7 @@ namespace Duplicati.Library.Backend.Box
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
diff --git a/Duplicati/Library/Backend/Box/Duplicati.Library.Backend.Box.csproj b/Duplicati/Library/Backend/Box/Duplicati.Library.Backend.Box.csproj
index 7af1b76de..2a9d73501 100644
--- a/Duplicati/Library/Backend/Box/Duplicati.Library.Backend.Box.csproj
+++ b/Duplicati/Library/Backend/Box/Duplicati.Library.Backend.Box.csproj
@@ -10,6 +10,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -32,7 +33,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/Box/packages.config b/Duplicati/Library/Backend/Box/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Backend/Box/packages.config
+++ b/Duplicati/Library/Backend/Box/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/CloudFiles/CloudFiles.cs b/Duplicati/Library/Backend/CloudFiles/CloudFiles.cs
index 0f0063343..29cbc2ba1 100644
--- a/Duplicati/Library/Backend/CloudFiles/CloudFiles.cs
+++ b/Duplicati/Library/Backend/CloudFiles/CloudFiles.cs
@@ -19,6 +19,7 @@
#endregion
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Text;
using System.Net;
using Duplicati.Library.Interface;
@@ -72,9 +73,9 @@ namespace Duplicati.Library.Backend
m_password = uri.Password;
if (string.IsNullOrEmpty(m_username))
- throw new Exception(Strings.CloudFiles.NoUserIDError);
+ throw new UserInformationException(Strings.CloudFiles.NoUserIDError);
if (string.IsNullOrEmpty(m_password))
- throw new Exception(Strings.CloudFiles.NoAPIKeyError);
+ throw new UserInformationException(Strings.CloudFiles.NoAPIKeyError);
//Fallback to the previous format
if (url.Contains(DUMMY_HOSTNAME))
@@ -128,9 +129,8 @@ namespace Duplicati.Library.Backend
get { return "cloudfiles"; }
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
- var files = new List<IFileEntry>();
string extraUrl = "?format=xml&limit=" + ITEM_LIST_LIMIT.ToString();
string markerUrl = "";
@@ -182,7 +182,7 @@ namespace Duplicati.Library.Backend
mod = new DateTime();
lastItemName = name;
- files.Add(new FileEntry(name, size, mod, mod));
+ yield return new FileEntry(name, size, mod, mod);
}
repeat = lst.Count == ITEM_LIST_LIMIT;
@@ -191,8 +191,6 @@ namespace Duplicati.Library.Backend
markerUrl = "&marker=" + Library.Utility.Uri.UrlEncode(lastItemName);
} while (repeat);
-
- return files;
}
public void Put(string remotename, string filename)
@@ -263,7 +261,7 @@ namespace Duplicati.Library.Backend
public void Test()
{
//The "Folder not found" is not detectable :(
- List();
+ this.TestList();
}
public void CreateFolder()
@@ -346,8 +344,13 @@ namespace Duplicati.Library.Backend
{
string fileHash = null;
+ long streamLen = -1;
+ try { streamLen = stream.Length; }
+ catch {}
+
+
Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
- using (System.IO.Stream s = areq.GetRequestStream())
+ using (System.IO.Stream s = areq.GetRequestStream(streamLen))
using (var mds = new Utility.MD5CalculatingStream(s))
{
Utility.Utility.CopyStream(stream, mds, true, m_copybuffer);
diff --git a/Duplicati/Library/Backend/CloudFiles/Duplicati.Library.Backend.CloudFiles.csproj b/Duplicati/Library/Backend/CloudFiles/Duplicati.Library.Backend.CloudFiles.csproj
index 416aa878f..e4987fe0f 100644
--- a/Duplicati/Library/Backend/CloudFiles/Duplicati.Library.Backend.CloudFiles.csproj
+++ b/Duplicati/Library/Backend/CloudFiles/Duplicati.Library.Backend.CloudFiles.csproj
@@ -17,6 +17,7 @@
</UpgradeBackupLocation>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/Duplicati/Library/Backend/CloudFiles/Strings.cs b/Duplicati/Library/Backend/CloudFiles/Strings.cs
index f0d07b39b..b6f0a8866 100644
--- a/Duplicati/Library/Backend/CloudFiles/Strings.cs
+++ b/Duplicati/Library/Backend/CloudFiles/Strings.cs
@@ -1,7 +1,7 @@
using Duplicati.Library.Localization.Short;
namespace Duplicati.Library.Backend.Strings {
internal static class CloudFiles {
- public static string DescriptionAuthenticationURLLong_v2(string optionname) { return LC.L(@"Cloudfiles use different servers for authentification based on where the account was resides, use this option to set an alternate authentication URL. This option overrides --{0}.", optionname); }
+ public static string DescriptionAuthenticationURLLong_v2(string optionname) { return LC.L(@"CloudFiles use different servers for authentication based on where the account resides, use this option to set an alternate authentication URL. This option overrides --{0}.", optionname); }
public static string DescriptionAuthenticationURLShort { get { return LC.L(@"Provide another authentication URL"); } }
public static string DescriptionAuthPasswordLong { get { return LC.L(@"The password used to connect to the server. This may also be supplied as the environment variable ""AUTH_PASSWORD""."); } }
public static string DescriptionAuthPasswordShort { get { return LC.L(@"Supplies the password used to connect to the server"); } }
diff --git a/Duplicati/Library/Backend/Dropbox/Dropbox.cs b/Duplicati/Library/Backend/Dropbox/Dropbox.cs
index 8a70684a0..289ec4f34 100644
--- a/Duplicati/Library/Backend/Dropbox/Dropbox.cs
+++ b/Duplicati/Library/Backend/Dropbox/Dropbox.cs
@@ -68,34 +68,36 @@ namespace Duplicati.Library.Backend
return ife;
}
- public List<IFileEntry> List()
+ private T HandleListExceptions<T>(Func<T> func)
{
try
{
- var list = new List<IFileEntry>();
- var lfr = dbx.ListFiles(m_path);
-
- foreach (var md in lfr.entries)
- list.Add(ParseEntry(md));
-
- while (lfr.has_more)
- {
- lfr = dbx.ListFilesContinue(lfr.cursor);
- foreach (var md in lfr.entries)
- list.Add(ParseEntry(md));
- }
-
- return list;
+ return func();
}
catch (DropboxException de)
{
if (de.errorJSON["error"][".tag"].ToString() == "path" && de.errorJSON["error"]["path"][".tag"].ToString() == "not_found")
throw new FolderMissingException();
-
+
throw;
}
}
+ public IEnumerable<IFileEntry> List()
+ {
+ var lfr = HandleListExceptions(() => dbx.ListFiles(m_path));
+
+ foreach (var md in lfr.entries)
+ yield return ParseEntry(md);
+
+ while (lfr.has_more)
+ {
+ lfr = HandleListExceptions(() => dbx.ListFilesContinue(lfr.cursor));
+ foreach (var md in lfr.entries)
+ yield return ParseEntry(md);
+ }
+ }
+
public void Put(string remotename, string filename)
{
using(FileStream fs = System.IO.File.OpenRead(filename))
@@ -136,7 +138,7 @@ namespace Duplicati.Library.Backend
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
diff --git a/Duplicati/Library/Backend/Dropbox/Duplicati.Library.Backend.Dropbox.csproj b/Duplicati/Library/Backend/Dropbox/Duplicati.Library.Backend.Dropbox.csproj
index 8c8377316..75e2c7264 100644
--- a/Duplicati/Library/Backend/Dropbox/Duplicati.Library.Backend.Dropbox.csproj
+++ b/Duplicati/Library/Backend/Dropbox/Duplicati.Library.Backend.Dropbox.csproj
@@ -11,6 +11,7 @@
<AssemblyName>Duplicati.Library.Backend.Dropbox</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -30,12 +31,11 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System" />
<Reference Include="System.Web" />
+ <Reference Include="Newtonsoft.Json">
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Dropbox.cs" />
diff --git a/Duplicati/Library/Backend/Dropbox/packages.config b/Duplicati/Library/Backend/Dropbox/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Backend/Dropbox/packages.config
+++ b/Duplicati/Library/Backend/Dropbox/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/FTP/Duplicati.Library.Backend.FTP.csproj b/Duplicati/Library/Backend/FTP/Duplicati.Library.Backend.FTP.csproj
index e15d090c5..098e28d96 100644
--- a/Duplicati/Library/Backend/FTP/Duplicati.Library.Backend.FTP.csproj
+++ b/Duplicati/Library/Backend/FTP/Duplicati.Library.Backend.FTP.csproj
@@ -8,7 +8,6 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.Library.Backend</RootNamespace>
<AssemblyName>Duplicati.Library.Backend.FTP</AssemblyName>
- <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
@@ -17,6 +16,7 @@
<TargetFrameworkProfile />
<UpgradeBackupLocation>
</UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/Duplicati/Library/Backend/FTP/FTPBackend.cs b/Duplicati/Library/Backend/FTP/FTPBackend.cs
index c39fa96db..57efcf866 100644
--- a/Duplicati/Library/Backend/FTP/FTPBackend.cs
+++ b/Duplicati/Library/Backend/FTP/FTPBackend.cs
@@ -170,41 +170,89 @@ namespace Duplicati.Library.Backend
get { return true; }
}
- public List<IFileEntry> List()
+ private T HandleListExceptions<T>(Func<T> func, System.Net.FtpWebRequest req)
+ {
+ T ret = default(T);
+ HandleListExceptions(() => ret = func(), req);
+ return ret;
+ }
+
+ private void HandleListExceptions(Action action, System.Net.FtpWebRequest req)
+ {
+ try
+ {
+ action();
+ }
+ catch (System.Net.WebException wex)
+ {
+ if (wex.Response as System.Net.FtpWebResponse != null && (wex.Response as System.Net.FtpWebResponse).StatusCode == System.Net.FtpStatusCode.ActionNotTakenFileUnavailable)
+ throw new Interface.FolderMissingException(Strings.FTPBackend.MissingFolderError(req.RequestUri.PathAndQuery, wex.Message), wex);
+ else
+ throw;
+ }
+ }
+
+ public IEnumerable<IFileEntry> List()
{
return List("");
}
-
- public List<IFileEntry> List(string filename)
+
+ public IEnumerable<IFileEntry> List(string filename)
{
var req = CreateRequest(filename);
req.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;
req.UseBinary = false;
+ System.Net.WebResponse resp = null;
+ System.IO.Stream rs = null;
+ System.IO.StreamReader sr = null;
+
try
{
- var lst = new List<IFileEntry>();
- var areq = new Utility.AsyncHttpRequest(req);
- using (var resp = areq.GetResponse())
- using (var rs = areq.GetResponseStream())
- using (var sr = new System.IO.StreamReader(new StreamReadHelper(rs)))
+ HandleListExceptions(
+ () =>
+ {
+ var areq = new Utility.AsyncHttpRequest(req);
+ resp = areq.GetResponse();
+ rs = areq.GetResponseStream();
+ sr = new System.IO.StreamReader(new StreamReadHelper(rs));
+ },
+ req);
+
+ string line;
+ while ((line = HandleListExceptions(() => sr.ReadLine(), req)) != null)
+ {
+ FileEntry f = ParseLine(line);
+ if (f != null)
+ yield return f;
+ }
+ }
+ finally
+ {
+ try
{
- string line;
- while ((line = sr.ReadLine()) != null)
+ if (sr != null)
{
- FileEntry f = ParseLine(line);
- if (f != null)
- lst.Add(f);
+ sr.Dispose();
+ }
+ }
+ finally
+ {
+ try
+ {
+ if (rs != null)
+ {
+ rs.Dispose();
+ }
+ }
+ finally
+ {
+ if (resp != null)
+ {
+ resp.Dispose();
+ }
}
}
- return lst;
- }
- catch (System.Net.WebException wex)
- {
- if (wex.Response as System.Net.FtpWebResponse != null && (wex.Response as System.Net.FtpWebResponse).StatusCode == System.Net.FtpStatusCode.ActionNotTakenFileUnavailable)
- throw new Interface.FolderMissingException(Strings.FTPBackend.MissingFolderError(req.RequestUri.PathAndQuery, wex.Message), wex);
- else
- throw;
}
}
@@ -222,12 +270,12 @@ namespace Duplicati.Library.Backend
catch {}
Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
- using (System.IO.Stream rs = areq.GetRequestStream())
+ using (System.IO.Stream rs = areq.GetRequestStream(streamLen))
Utility.Utility.CopyStream(input, rs, true, m_copybuffer);
if (m_listVerify)
{
- List<IFileEntry> files = List(remotename);
+ IEnumerable<IFileEntry> files = List(remotename);
foreach(IFileEntry fe in files)
if (fe.Name.Equals(remotename) || fe.Name.EndsWith("/" + remotename) || fe.Name.EndsWith("\\" + remotename))
{
@@ -308,7 +356,7 @@ namespace Duplicati.Library.Backend
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
diff --git a/Duplicati/Library/Backend/FTP/Strings.cs b/Duplicati/Library/Backend/FTP/Strings.cs
index e5c94c989..c018aec20 100644
--- a/Duplicati/Library/Backend/FTP/Strings.cs
+++ b/Duplicati/Library/Backend/FTP/Strings.cs
@@ -20,6 +20,6 @@ namespace Duplicati.Library.Backend.Strings {
public static string ListVerifyFailure(string filename, IEnumerable<string> files) { return LC.L(@"The file {0} was uploaded but not found afterwards, the file listing returned {1}", filename, string.Join(Environment.NewLine, files)); }
public static string ListVerifySizeFailure(string filename, long actualsize, long expectedsize) { return LC.L(@"The file {0} was uploaded but the returned size was {1} and it was expected to be {2}", filename, actualsize, expectedsize); }
public static string DescriptionDisableUploadVerifyShort { get { return LC.L(@"Disable upload verification"); } }
- public static string DescriptionDisableUploadVerifyLong { get { return LC.L(@"To protect against network failures, every upload will be attempted verified. Use this option to disable this verfication to make the upload faster but less reliable."); } }
+ public static string DescriptionDisableUploadVerifyLong { get { return LC.L(@"To protect against network failures, every upload will be attempted verified. Use this option to disable this verification to make the upload faster but less reliable."); } }
}
}
diff --git a/Duplicati/Library/Backend/File/Duplicati.Library.Backend.File.csproj b/Duplicati/Library/Backend/File/Duplicati.Library.Backend.File.csproj
index df1d615e1..f843c2f3d 100644
--- a/Duplicati/Library/Backend/File/Duplicati.Library.Backend.File.csproj
+++ b/Duplicati/Library/Backend/File/Duplicati.Library.Backend.File.csproj
@@ -17,6 +17,7 @@
<TargetFrameworkProfile />
<UpgradeBackupLocation>
</UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/Duplicati/Library/Backend/File/FileBackend.cs b/Duplicati/Library/Backend/File/FileBackend.cs
index a2aadbe65..18774c176 100644
--- a/Duplicati/Library/Backend/File/FileBackend.cs
+++ b/Duplicati/Library/Backend/File/FileBackend.cs
@@ -19,6 +19,7 @@
#endregion
using System;
using System.Collections.Generic;
+using System.Runtime.InteropServices;
using System.Text;
using Duplicati.Library.Interface;
@@ -112,7 +113,7 @@ namespace Duplicati.Library.Backend
}
if (m_path == null)
- throw new Exception(Strings.FileBackend.NoDestinationWithMarkerFileError(markerfile, paths.ToArray()));
+ throw new UserInformationException(Strings.FileBackend.NoDestinationWithMarkerFileError(markerfile, paths.ToArray()));
}
m_moveFile = Utility.Utility.ParseBoolOption(options, OPTION_MOVE_FILE);
@@ -164,30 +165,26 @@ namespace Duplicati.Library.Backend
get { return true; }
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
- List<IFileEntry> ls = new List<IFileEntry>();
-
PreAuthenticate();
if (!System.IO.Directory.Exists(m_path))
throw new FolderMissingException(Strings.FileBackend.FolderMissingError(m_path));
- foreach (string s in System.IO.Directory.GetFiles(m_path))
+ foreach (string s in System.IO.Directory.EnumerateFiles(m_path))
{
System.IO.FileInfo fi = new System.IO.FileInfo(s);
- ls.Add(new FileEntry(fi.Name, fi.Length, fi.LastAccessTime, fi.LastWriteTime));
+ yield return new FileEntry(fi.Name, fi.Length, fi.LastAccessTime, fi.LastWriteTime);
}
- foreach (string s in System.IO.Directory.GetDirectories(m_path))
+ foreach (string s in System.IO.Directory.EnumerateDirectories(m_path))
{
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(s);
FileEntry fe = new FileEntry(di.Name, 0, di.LastAccessTime, di.LastWriteTime);
fe.IsFolder = true;
- ls.Add(fe);
+ yield return fe;
}
-
- return ls;
}
#if DEBUG_RETRY
@@ -265,7 +262,7 @@ namespace Duplicati.Library.Backend
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
@@ -315,29 +312,42 @@ namespace Duplicati.Library.Backend
root = System.IO.Path.GetPathRoot(m_path);
}
- return new System.IO.DriveInfo(root);
- }
-
- public long TotalQuotaSpace
- {
- get
+ // On Windows, DriveInfo is only valid for lettered drives. (e.g., not for UNC paths and shares)
+ // So only attempt to get it if we aren't on Windows or if the root starts with a letter.
+ if (!Utility.Utility.IsClientWindows || (root.Length > 0 && char.IsLetter(root[0])))
{
- try { return GetDrive().TotalSize; }
- catch { }
-
- return -1;
+ try
+ {
+ return new System.IO.DriveInfo(root);
+ }
+ catch (ArgumentException)
+ {
+ // If there was a problem, fall back to returning null
+ }
}
- }
+ return null;
+ }
- public long FreeQuotaSpace
+ public IQuotaInfo Quota
{
get
{
- try { return GetDrive().AvailableFreeSpace; }
- catch { }
-
- return -1;
+ System.IO.DriveInfo driveInfo = this.GetDrive();
+ if (driveInfo != null)
+ {
+ return new QuotaInfo(driveInfo.TotalSize, driveInfo.AvailableFreeSpace);
+ }
+ else if (Utility.Utility.IsClientWindows)
+ {
+ // If we can't get the DriveInfo on Windows, fallback to GetFreeDiskSpaceEx
+ // https://stackoverflow.com/questions/2050343/programmatically-determining-space-available-from-unc-path
+ return GetDiskFreeSpace(m_path);
+ }
+ else
+ {
+ return null;
+ }
}
}
@@ -349,5 +359,37 @@ namespace Duplicati.Library.Backend
System.IO.File.Delete(target);
System.IO.File.Move(source, target);
}
+
+ /// <summary>
+ /// Get the disk free space using the Win32 API's GetDiskFreeSpaceEx function.
+ /// </summary>
+ /// <param name="directory">Directory</param>
+ /// <returns>Quota info</returns>
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public static QuotaInfo GetDiskFreeSpace(string directory)
+ {
+ ulong available;
+ ulong total;
+ ulong free;
+ if (WindowsDriveHelper.GetDiskFreeSpaceEx(directory, out available, out total, out free))
+ {
+ return new QuotaInfo((long)total, (long)available);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private static class WindowsDriveHelper
+ {
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetDiskFreeSpaceEx(
+ string lpDirectoryName,
+ out ulong lpFreeBytesAvailable,
+ out ulong lpTotalNumberOfBytes,
+ out ulong lpTotalNumberOfFreeBytes);
+ }
}
}
diff --git a/Duplicati/Library/Backend/File/Strings.cs b/Duplicati/Library/Backend/File/Strings.cs
index 6bba7afbc..062b7b66c 100644
--- a/Duplicati/Library/Backend/File/Strings.cs
+++ b/Duplicati/Library/Backend/File/Strings.cs
@@ -1,21 +1,21 @@
-using Duplicati.Library.Localization.Short;
-namespace Duplicati.Library.Backend.Strings {
- internal static class FileBackend {
- public static string AlternateDestinationMarkerLong(string optionname) { return LC.L(@"This option only works when the --{0} option is also specified. If there are alternate paths specified, this option indicates the name of a marker file that must be present in the folder. This can be used to handle situations where an external drive changes drive letter or mount point. By ensuring that a certain file exists, it is possible to prevent writing data to an unwanted external drive. The contents of the file are never examined, only file existence.", optionname); }
- public static string AlternateDestinationMarkerShort { get { return LC.L(@"Look for a file in the destination folder"); } }
- public static string AlternateTargetPathsLong(string optionname, char pathseperator) { return LC.L(@"This option allows multiple targets to be specified. The primary target path is placed before the list of paths supplied with this option. Before starting the backup, each folder in the list is checked for existence and optionally the presence of the marker file supplied by --{0}. The first existing path that optionally contains the marker file is then used as the destination. Multiple destinations are separated with a {1},. On Windows, the path may be a UNC path, and the drive letter may be substituted with an asterisk (*), eg.: ""*:\backup"", which will examine all drive letters. If a username and password is supplied, the same credentials are used for all destinations.", optionname, pathseperator); }
- public static string AlternateTargetPathsShort { get { return LC.L(@"A list of secondary target paths"); } }
- public static string Description { get { return LC.L(@"This backend can read and write data to an file based backend. Allowed formats are ""file://hostname/folder"" or ""file://username:password@hostname/folder"". You may supply UNC paths (eg: ""file://\\server\folder"") or local paths (eg: (win) ""file://c:\folder"", (linux) ""file:///usr/pub/files"")"); } }
- public static string DescriptionAuthPasswordLong { get { return LC.L(@"The password used to connect to the server. This may also be supplied as the environment variable ""AUTH_PASSWORD""."); } }
- public static string DescriptionAuthPasswordShort { get { return LC.L(@"Supplies the password used to connect to the server"); } }
- public static string DescriptionAuthUsernameLong { get { return LC.L(@"The username used to connect to the server. This may also be supplied as the environment variable ""AUTH_USERNAME""."); } }
- public static string DescriptionAuthUsernameShort { get { return LC.L(@"Supplies the username used to connect to the server"); } }
- public static string DisplayName { get { return LC.L(@"Local folder or drive"); } }
- public static string FolderMissingError(string foldername) { return LC.L(@"The folder {0} does not exist", foldername); }
- public static string NoDestinationWithMarkerFileError(string markername, string[] folders) { return LC.L(@"The marker file ""{0}"" was not found in any of the examined destinations: {1}", markername, string.Join(", ", folders)); }
- public static string UseMoveForPutLong { get { return LC.L(@"When storing the file, the standard operation is to copy the file and delete the original. This sequence ensures that the operation can be retried if something goes wrong. Activating this option may cause the retry operation to fail. This option has no effect unless the --disable-streaming-transfers options is activated."); } }
- public static string UseMoveForPutShort { get { return LC.L(@"Move the file instead of copying it"); } }
- public static string ForceReauthShort { get { return LC.L(@"Force authentication against remote share"); } }
- public static string ForceReauthLong { get { return LC.L(@"If this option is set, any existing authentication against the remote share is dropped before attempting to authenticate"); } }
- }
-}
+using Duplicati.Library.Localization.Short;
+namespace Duplicati.Library.Backend.Strings {
+ internal static class FileBackend {
+ public static string AlternateDestinationMarkerLong(string optionname) { return LC.L(@"This option only works when the --{0} option is also specified. If there are alternate paths specified, this option indicates the name of a marker file that must be present in the folder. This can be used to handle situations where an external drive changes drive letter or mount point. By ensuring that a certain file exists, it is possible to prevent writing data to an unwanted external drive. The contents of the file are never examined, only file existence.", optionname); }
+ public static string AlternateDestinationMarkerShort { get { return LC.L(@"Look for a file in the destination folder"); } }
+ public static string AlternateTargetPathsLong(string optionname, char pathseparator) { return LC.L(@"This option allows multiple targets to be specified. The primary target path is placed before the list of paths supplied with this option. Before starting the backup, each folder in the list is checked for existence and optionally the presence of the marker file supplied by --{0}. The first existing path that optionally contains the marker file is then used as the destination. Multiple destinations are separated with a ""{1}"". On Windows, the path may be a UNC path, and the drive letter may be substituted with an asterisk (*), eg.: ""*:\backup"", which will examine all drive letters. If a username and password is supplied, the same credentials are used for all destinations.", optionname, pathseparator); }
+ public static string AlternateTargetPathsShort { get { return LC.L(@"A list of secondary target paths"); } }
+ public static string Description { get { return LC.L(@"This backend can read and write data to an file based backend. Allowed formats are ""file://hostname/folder"" or ""file://username:password@hostname/folder"". You may supply UNC paths (eg: ""file://\\server\folder"") or local paths (eg: (win) ""file://c:\folder"", (linux) ""file:///usr/pub/files"")"); } }
+ public static string DescriptionAuthPasswordLong { get { return LC.L(@"The password used to connect to the server. This may also be supplied as the environment variable ""AUTH_PASSWORD""."); } }
+ public static string DescriptionAuthPasswordShort { get { return LC.L(@"Supplies the password used to connect to the server"); } }
+ public static string DescriptionAuthUsernameLong { get { return LC.L(@"The username used to connect to the server. This may also be supplied as the environment variable ""AUTH_USERNAME""."); } }
+ public static string DescriptionAuthUsernameShort { get { return LC.L(@"Supplies the username used to connect to the server"); } }
+ public static string DisplayName { get { return LC.L(@"Local folder or drive"); } }
+ public static string FolderMissingError(string foldername) { return LC.L(@"The folder {0} does not exist", foldername); }
+ public static string NoDestinationWithMarkerFileError(string markername, string[] folders) { return LC.L(@"The marker file ""{0}"" was not found in any of the examined destinations: {1}", markername, string.Join(", ", folders)); }
+ public static string UseMoveForPutLong { get { return LC.L(@"When storing the file, the standard operation is to copy the file and delete the original. This sequence ensures that the operation can be retried if something goes wrong. Activating this option may cause the retry operation to fail. This option has no effect unless the --disable-streaming-transfers options is activated."); } }
+ public static string UseMoveForPutShort { get { return LC.L(@"Move the file instead of copying it"); } }
+ public static string ForceReauthShort { get { return LC.L(@"Force authentication against remote share"); } }
+ public static string ForceReauthLong { get { return LC.L(@"If this option is set, any existing authentication against the remote share is dropped before attempting to authenticate"); } }
+ }
+}
diff --git a/Duplicati/Library/Backend/GoogleServices/Duplicati.Library.Backend.GoogleServices.csproj b/Duplicati/Library/Backend/GoogleServices/Duplicati.Library.Backend.GoogleServices.csproj
index 284c0c6f8..14fd2ea1c 100644
--- a/Duplicati/Library/Backend/GoogleServices/Duplicati.Library.Backend.GoogleServices.csproj
+++ b/Duplicati/Library/Backend/GoogleServices/Duplicati.Library.Backend.GoogleServices.csproj
@@ -10,6 +10,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -31,7 +32,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/GoogleServices/GoogleCloudStorage.cs b/Duplicati/Library/Backend/GoogleServices/GoogleCloudStorage.cs
index efb756a93..1ac463469 100644
--- a/Duplicati/Library/Backend/GoogleServices/GoogleCloudStorage.cs
+++ b/Duplicati/Library/Backend/GoogleServices/GoogleCloudStorage.cs
@@ -93,13 +93,12 @@ namespace Duplicati.Library.Backend.GoogleCloudStorage
options.TryGetValue(STORAGECLASS_OPTION, out m_storage_class);
if (string.IsNullOrEmpty(authid))
- throw new Exception(Strings.GoogleCloudStorage.MissingAuthID(AUTHID_OPTION));
+ throw new UserInformationException(Strings.GoogleCloudStorage.MissingAuthID(AUTHID_OPTION));
m_oauth = new OAuthHelper(authid, this.ProtocolKey);
m_oauth.AutoAuthHeader = true;
}
-
-
+
private class ListBucketResponse
{
@@ -130,39 +129,12 @@ namespace Duplicati.Library.Backend.GoogleCloudStorage
public string location { get; set; }
public string storageClass { get; set; }
}
- #region IBackend implementation
- public List<IFileEntry> List()
+
+ private T HandleListExceptions<T>(Func<T> func)
{
try
{
- var res = new List<IFileEntry>();
- string token = null;
- do
- {
- var url = string.Format("{0}/b/{1}/o?prefix={2}", API_URL, m_bucket, Library.Utility.Uri.UrlEncode(m_prefix));
- if (!string.IsNullOrEmpty(token))
- url += string.Format("&pageToken={0}", token);
- var resp = m_oauth.ReadJSONResponse<ListBucketResponse>(url);
-
- if (resp.items != null)
- foreach(var f in resp.items)
- {
- var name = f.name;
- if (name.StartsWith(m_prefix, StringComparison.InvariantCultureIgnoreCase))
- name = name.Substring(m_prefix.Length);
- if (f.size == null)
- res.Add(new FileEntry(name));
- else if (f.updated == null)
- res.Add(new FileEntry(name, f.size.Value));
- else
- res.Add(new FileEntry(name, f.size.Value, f.updated.Value, f.updated.Value));
- }
-
- token = resp.nextPageToken;
-
- } while(!string.IsNullOrEmpty(token));
-
- return res;
+ return func();
}
catch (WebException wex)
{
@@ -173,6 +145,36 @@ namespace Duplicati.Library.Backend.GoogleCloudStorage
}
}
+ #region IBackend implementation
+ public IEnumerable<IFileEntry> List()
+ {
+ string token = null;
+ do
+ {
+ var url = string.Format("{0}/b/{1}/o?prefix={2}", API_URL, m_bucket, Library.Utility.Uri.UrlEncode(m_prefix));
+ if (!string.IsNullOrEmpty(token))
+ url += string.Format("&pageToken={0}", token);
+ var resp = HandleListExceptions(() => m_oauth.ReadJSONResponse<ListBucketResponse>(url));
+
+ if (resp.items != null)
+ foreach (var f in resp.items)
+ {
+ var name = f.name;
+ if (name.StartsWith(m_prefix, StringComparison.OrdinalIgnoreCase))
+ name = name.Substring(m_prefix.Length);
+ if (f.size == null)
+ yield return new FileEntry(name);
+ else if (f.updated == null)
+ yield return new FileEntry(name, f.size.Value);
+ else
+ yield return new FileEntry(name, f.size.Value, f.updated.Value, f.updated.Value);
+ }
+
+ token = resp.nextPageToken;
+
+ } while (!string.IsNullOrEmpty(token));
+ }
+
public void Put(string remotename, string filename)
{
using (System.IO.FileStream fs = System.IO.File.OpenRead(filename))
@@ -195,13 +197,13 @@ namespace Duplicati.Library.Backend.GoogleCloudStorage
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
{
if (string.IsNullOrEmpty(m_project))
- throw new Exception(Strings.GoogleCloudStorage.ProjectIDMissingError(PROJECT_OPTION));
+ throw new UserInformationException(Strings.GoogleCloudStorage.ProjectIDMissingError(PROJECT_OPTION));
var data = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new CreateBucketRequest() {
name = m_bucket,
diff --git a/Duplicati/Library/Backend/GoogleServices/GoogleDrive.cs b/Duplicati/Library/Backend/GoogleServices/GoogleDrive.cs
index 74bde3659..feec7f4e8 100644
--- a/Duplicati/Library/Backend/GoogleServices/GoogleDrive.cs
+++ b/Duplicati/Library/Backend/GoogleServices/GoogleDrive.cs
@@ -76,7 +76,7 @@ namespace Duplicati.Library.Backend.GoogleDrive
curparent = CreateFolder(p, curparent).id;
}
else if (res.Length > 1)
- throw new Exception(Strings.GoogleDrive.MultipleEntries(p, curdisplay));
+ throw new UserInformationException(Strings.GoogleDrive.MultipleEntries(p, curdisplay));
else
curparent = res[0].id;
@@ -131,7 +131,7 @@ namespace Duplicati.Library.Backend.GoogleDrive
{
// Figure out if we update or create the file
if (m_filecache.Count == 0)
- List();
+ foreach (var file in List()) { /* Enumerate the full listing */ }
GoogleDriveFolderItem[] files;
m_filecache.TryGetValue(remotename, out files);
@@ -174,7 +174,7 @@ namespace Duplicati.Library.Backend.GoogleDrive
{
// Prevent repeated download url lookups
if (m_filecache.Count == 0)
- List();
+ foreach (var file in List()) { /* Enumerate the full listing */ }
var fileid = GetFileEntries(remotename).OrderByDescending(x => x.createdDate).First().id;
@@ -189,14 +189,15 @@ namespace Duplicati.Library.Backend.GoogleDrive
#region IBackend implementation
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
+ bool success = false;
try
{
- var res = new List<IFileEntry>();
m_filecache.Clear();
- foreach(var n in ListFolder(CurrentFolderId))
+ // For now, this class assumes that List() fully populates the file cache
+ foreach (var n in ListFolder(CurrentFolderId))
{
FileEntry fe = null;
@@ -209,34 +210,39 @@ namespace Duplicati.Library.Backend.GoogleDrive
if (fe != null)
{
- fe.IsFolder = FOLDER_MIMETYPE.Equals(n.mimeType, StringComparison.InvariantCultureIgnoreCase);
- res.Add(fe);
+ fe.IsFolder = FOLDER_MIMETYPE.Equals(n.mimeType, StringComparison.OrdinalIgnoreCase);
if (!fe.IsFolder)
{
GoogleDriveFolderItem[] lst;
if (!m_filecache.TryGetValue(fe.Name, out lst))
+ {
m_filecache[fe.Name] = new GoogleDriveFolderItem[] { n };
+ }
else
{
Array.Resize(ref lst, lst.Length + 1);
lst[lst.Length - 1] = n;
}
}
+
+ yield return fe;
}
}
- return res;
+ success = true;
}
- catch
+ finally
{
- m_filecache.Clear();
-
- throw;
+ // If the enumeration either failed or didn't complete, clear the file cache.
+ // This way, other operations which require a fully populated file cache will see an empty one and can populate it themselves.
+ if (!success)
+ {
+ m_filecache.Clear();
+ }
}
-
}
-
+
public void Put(string remotename, string filename)
{
using (System.IO.FileStream fs = System.IO.File.OpenRead(filename))
@@ -274,7 +280,7 @@ namespace Duplicati.Library.Backend.GoogleDrive
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
@@ -319,25 +325,19 @@ namespace Duplicati.Library.Backend.GoogleDrive
#endregion
#region IQuotaEnabledBackend implementation
- public long TotalQuotaSpace
+ public IQuotaInfo Quota
{
get
{
- try { return GetAboutInfo().quotaBytesTotal ?? -1; }
- catch { }
-
- return -1;
- }
- }
-
- public long FreeQuotaSpace
- {
- get
- {
- try { return GetAboutInfo().quotaBytesUsed ?? -1; }
- catch { }
-
- return -1;
+ try
+ {
+ GoogleDriveAboutResponse about = this.GetAboutInfo();
+ return new QuotaInfo(about.quotaBytesTotal ?? -1, about.quotaBytesUsed ?? -1);
+ }
+ catch
+ {
+ return null;
+ }
}
}
#endregion
@@ -349,7 +349,7 @@ namespace Duplicati.Library.Backend.GoogleDrive
{
var files = GetFileEntries(oldname, true);
if (files.Length > 1)
- throw new Exception(string.Format(Strings.GoogleDrive.MultipleEntries(oldname, m_path)));
+ throw new UserInformationException(string.Format(Strings.GoogleDrive.MultipleEntries(oldname, m_path)));
var newfile = JsonConvert.DeserializeObject<GoogleDriveFolderItem>(JsonConvert.SerializeObject(files[0]));
newfile.title = newname;
@@ -465,15 +465,16 @@ namespace Duplicati.Library.Backend.GoogleDrive
};
var url = string.Format("{0}/files?q={1}", DRIVE_API_URL, Library.Utility.Uri.UrlEncode(string.Join(" and ", p.Where(x => x != null))));
+ var token = string.Empty;
- while (!string.IsNullOrEmpty(url))
+ do
{
- var res = m_oauth.GetJSONData<GoogleDriveListResponse>(url);
- foreach(var n in res.items)
+ var res = m_oauth.GetJSONData<GoogleDriveListResponse>(url + (string.IsNullOrWhiteSpace(token) ? "" : "&pageToken=" + Library.Utility.Uri.UrlEncode(token)));
+ foreach (var n in res.items)
yield return n;
- url = res.nextLink;
- }
+ token = res.nextPageToken;
+ } while (!string.IsNullOrWhiteSpace(token));
}
private GoogleDriveAboutResponse GetAboutInfo()
diff --git a/Duplicati/Library/Backend/GoogleServices/packages.config b/Duplicati/Library/Backend/GoogleServices/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Backend/GoogleServices/packages.config
+++ b/Duplicati/Library/Backend/GoogleServices/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/HubiC/Duplicati.Library.Backend.HubiC.csproj b/Duplicati/Library/Backend/HubiC/Duplicati.Library.Backend.HubiC.csproj
index 23b2ee43b..de4f144e9 100644
--- a/Duplicati/Library/Backend/HubiC/Duplicati.Library.Backend.HubiC.csproj
+++ b/Duplicati/Library/Backend/HubiC/Duplicati.Library.Backend.HubiC.csproj
@@ -10,6 +10,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/Duplicati/Library/Backend/HubiC/HubiCBackend.cs b/Duplicati/Library/Backend/HubiC/HubiCBackend.cs
index 748842d59..1f8fb03c0 100644
--- a/Duplicati/Library/Backend/HubiC/HubiCBackend.cs
+++ b/Duplicati/Library/Backend/HubiC/HubiCBackend.cs
@@ -21,6 +21,6 @@ namespace Duplicati.Library.Backend.HubiC
public class HubiCBackend : IBackend, IStreamingBackend
{ private const string AUTHID_OPTION = "authid"; private const string HUBIC_API_URL = "https://api.hubic.com/1.0/"; private const string HUBIC_API_CREDENTIAL_URL = HUBIC_API_URL + "account/credentials"; private OpenStackStorage m_openstack; private class HubiCAuthResponse { public string token { get; set; } public string endpoint { get; set; } public DateTime? expires { get; set;} } private class OpenStackHelper : OpenStackStorage { private OAuthHelper m_helper; private HubiCAuthResponse m_token; public OpenStackHelper(string authid, string url) : base(url, MockOptions()) { m_helper = new OAuthHelper(authid, "hubic") { AutoAuthHeader = true }; } private static Dictionary<string, string> MockOptions() { var res = new Dictionary<string, string>(); res["openstack-authuri"] = "invalid://dont-use"; res["openstack-apikey"] = "invalid"; res["auth-username"] = "invalid"; return res; } private HubiCAuthResponse AuthToken { get { if (m_token == null || (m_token.expires != null && (m_token.expires.Value - DateTime.UtcNow).TotalSeconds < 30)) m_token = m_helper.ReadJSONResponse<HubiCAuthResponse>(HUBIC_API_CREDENTIAL_URL); return m_token; } } protected override string AccessToken { get { return AuthToken.token; } } protected override string SimpleStorageEndPoint { get { return AuthToken.endpoint; } } } public HubiCBackend()
{ }
- public HubiCBackend(string url, Dictionary<string, string> options) { string authid = null; if (options.ContainsKey(AUTHID_OPTION)) authid = options[AUTHID_OPTION]; m_openstack = new OpenStackHelper(authid, url); } #region IStreamingBackend implementation public void Put(string remotename, System.IO.Stream stream) { m_openstack.Put(remotename, stream); } public void Get(string remotename, System.IO.Stream stream) { m_openstack.Get(remotename, stream); } #endregion #region IBackend implementation public List<IFileEntry> List() { return m_openstack.List(); } public void Put(string remotename, string filename) { m_openstack.Put(remotename, filename); } public void Get(string remotename, string filename) { m_openstack.Get(remotename, filename); } public void Delete(string remotename) { m_openstack.Delete(remotename); } public void Test() { m_openstack.Test(); } public void CreateFolder() { m_openstack.CreateFolder(); } public string DisplayName { get { return Strings.HubiC.DisplayName; } } public string ProtocolKey { get { return "hubic"; } } public System.Collections.Generic.IList<ICommandLineArgument> SupportedCommands { get { return new List<ICommandLineArgument>(new ICommandLineArgument[] { new CommandLineArgument(AUTHID_OPTION, CommandLineArgument.ArgumentType.Password, Strings.HubiC.AuthidShort, Strings.HubiC.AuthidLong(OAuthHelper.OAUTH_LOGIN_URL("hubic"))), }); } } public string Description { get { return Strings.HubiC.Description; } } #endregion #region IDisposable implementation public void Dispose() { if (m_openstack != null) { m_openstack.Dispose(); m_openstack = null; } } #endregion }
+ public HubiCBackend(string url, Dictionary<string, string> options) { string authid = null; if (options.ContainsKey(AUTHID_OPTION)) authid = options[AUTHID_OPTION]; m_openstack = new OpenStackHelper(authid, url); } #region IStreamingBackend implementation public void Put(string remotename, System.IO.Stream stream) { m_openstack.Put(remotename, stream); } public void Get(string remotename, System.IO.Stream stream) { m_openstack.Get(remotename, stream); } #endregion #region IBackend implementation public IEnumerable<IFileEntry> List() { return m_openstack.List(); } public void Put(string remotename, string filename) { m_openstack.Put(remotename, filename); } public void Get(string remotename, string filename) { m_openstack.Get(remotename, filename); } public void Delete(string remotename) { m_openstack.Delete(remotename); } public void Test() { m_openstack.Test(); } public void CreateFolder() { m_openstack.CreateFolder(); } public string DisplayName { get { return Strings.HubiC.DisplayName; } } public string ProtocolKey { get { return "hubic"; } } public System.Collections.Generic.IList<ICommandLineArgument> SupportedCommands { get { return new List<ICommandLineArgument>(new ICommandLineArgument[] { new CommandLineArgument(AUTHID_OPTION, CommandLineArgument.ArgumentType.Password, Strings.HubiC.AuthidShort, Strings.HubiC.AuthidLong(OAuthHelper.OAUTH_LOGIN_URL("hubic"))), }); } } public string Description { get { return Strings.HubiC.Description; } } #endregion #region IDisposable implementation public void Dispose() { if (m_openstack != null) { m_openstack.Dispose(); m_openstack = null; } } #endregion }
}
diff --git a/Duplicati/Library/Backend/Jottacloud/Duplicati.Library.Backend.Jottacloud.csproj b/Duplicati/Library/Backend/Jottacloud/Duplicati.Library.Backend.Jottacloud.csproj
new file mode 100644
index 000000000..e308a8103
--- /dev/null
+++ b/Duplicati/Library/Backend/Jottacloud/Duplicati.Library.Backend.Jottacloud.csproj
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{2CD5DBC3-3DA6-432D-BA97-F0B8D24501C2}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Duplicati.Library.Backend</RootNamespace>
+ <AssemblyName>Duplicati.Library.Backend.Jottacloud</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <TargetFrameworkProfile />
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Jottacloud.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Strings.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj">
+ <Project>{52826615-7964-47FE-B4B3-1B2DBDF605B9}</Project>
+ <Name>Duplicati.Library.Modules.Builtin</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Utility\Duplicati.Library.Utility.csproj">
+ <Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
+ <Name>Duplicati.Library.Utility</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
+ <Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
+ <Name>Duplicati.Library.Interface</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Localization\Duplicati.Library.Localization.csproj">
+ <Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
+ <Name>Duplicati.Library.Localization</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Duplicati.snk" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/Jottacloud/Duplicati.snk b/Duplicati/Library/Backend/Jottacloud/Duplicati.snk
new file mode 100644
index 000000000..e0c1e2dd8
--- /dev/null
+++ b/Duplicati/Library/Backend/Jottacloud/Duplicati.snk
Binary files differ
diff --git a/Duplicati/Library/Backend/Jottacloud/Jottacloud.cs b/Duplicati/Library/Backend/Jottacloud/Jottacloud.cs
new file mode 100644
index 000000000..ba1bbd0d5
--- /dev/null
+++ b/Duplicati/Library/Backend/Jottacloud/Jottacloud.cs
@@ -0,0 +1,451 @@
+#region Disclaimer / License
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#endregion
+using System;
+using System.Collections.Generic;
+using Duplicati.Library.Interface;
+
+namespace Duplicati.Library.Backend
+{
+ public class Jottacloud : IBackend, IStreamingBackend
+ {
+ private const string JFS_ROOT = "https://jfs.jottacloud.com/jfs";
+ private const string JFS_ROOT_UPLOAD = "https://up.jottacloud.com/jfs"; // Separate host for uploading files
+ private const string API_VERSION = "2.4"; // Hard coded per 09. March 2017.
+ private const string JFS_BUILTIN_DEVICE = "Jotta"; // The built-in device used for the built-in Sync and Archive mount points.
+ private static readonly string JFS_DEFAULT_BUILTIN_MOUNT_POINT = "Archive"; // When using the built-in device we pick this mount point as our default.
+ private static readonly string JFS_DEFAULT_CUSTOM_MOUNT_POINT = "Duplicati"; // When custom device is specified then we pick this mount point as our default.
+ private static readonly string[] JFS_BUILTIN_MOUNT_POINTS = { "Archive", "Sync" }; // Name of built-in mount points that we can use.
+ private static readonly string[] JFS_BUILTIN_ILLEGAL_MOUNT_POINTS = { "Trash", "Links", "Latest", "Shared" }; // Name of built-in mount points that we can not use. These are treated as mount points in the API, but they are for used for special functionality and we cannot upload files to them!
+ private const string JFS_DEVICE_OPTION = "jottacloud-device";
+ private const string JFS_MOUNT_POINT_OPTION = "jottacloud-mountpoint";
+ private const string JFS_DATE_FORMAT = "yyyy'-'MM'-'dd-'T'HH':'mm':'ssK";
+ private const bool ALLOW_USER_DEFINED_MOUNT_POINTS = false;
+ private readonly string m_device;
+ private readonly bool m_device_builtin;
+ private readonly string m_mountPoint;
+ private readonly string m_path;
+ private readonly string m_url_device;
+ private readonly string m_url;
+ private readonly string m_url_upload;
+ private System.Net.NetworkCredential m_userInfo;
+ private readonly byte[] m_copybuffer = new byte[Duplicati.Library.Utility.Utility.DEFAULT_BUFFER_SIZE];
+
+ public Jottacloud()
+ {
+ }
+
+ public Jottacloud(string url, Dictionary<string, string> options)
+ {
+ // Duplicati back-end url for Jottacloud is in format "jottacloud://folder/subfolder", we transform them to
+ // the Jottacloud REST API (JFS) url format "https://jfs.jottacloud.com/jfs/[username]/[device]/[mountpoint]/[folder]/[subfolder]".
+
+ // Find out what JFS device to use.
+ if (options.ContainsKey(JFS_DEVICE_OPTION))
+ {
+ // Custom device specified.
+ m_device = options[JFS_DEVICE_OPTION];
+ if (string.Equals(m_device, JFS_BUILTIN_DEVICE, StringComparison.OrdinalIgnoreCase))
+ {
+ m_device_builtin = true; // Device is configured, but value set to the built-in device!
+ m_device = JFS_BUILTIN_DEVICE; // Ensure correct casing (doesn't seem to matter, but in theory it could).
+ }
+ else
+ {
+ m_device_builtin = false;
+ }
+ }
+ else
+ {
+ // Use default: The built-in device.
+ m_device = JFS_BUILTIN_DEVICE;
+ m_device_builtin = true;
+ }
+
+ // Find out what JFS mount point to use on the device.
+ if (options.ContainsKey(JFS_MOUNT_POINT_OPTION))
+ {
+ // Custom mount point specified.
+ m_mountPoint = options[JFS_MOUNT_POINT_OPTION];
+
+ // If we are using the built-in device make sure we have picked a mount point that we can use.
+ if (m_device_builtin)
+ {
+ // Check that it is not set to one of the special built-in mount points that we definitely cannot make use of.
+ if (Array.FindIndex(JFS_BUILTIN_ILLEGAL_MOUNT_POINTS, x => x.Equals(m_mountPoint, StringComparison.OrdinalIgnoreCase)) != -1)
+ throw new UserInformationException(Strings.Jottacloud.IllegalMountPoint);
+ // Check if it is one of the legal built-in mount points.
+ // What to do if it is not is open for discussion: The JFS API supports creation of custom mount points not only
+ // for custom (backup) devices, but also for the built-in device. But this will not be visible via the official
+ // web interface, so you are kind of working in the dark and need to use the REST API to delete it etc. Therefore
+ // we do not allow this for now, although in future maybe we could consider it, as a "hidden" location?
+ var i = Array.FindIndex(JFS_BUILTIN_MOUNT_POINTS, x => x.Equals(m_mountPoint, StringComparison.OrdinalIgnoreCase));
+ if (i != -1)
+ m_mountPoint = JFS_BUILTIN_MOUNT_POINTS[i]; // Ensure correct casing (doesn't seem to matter, but in theory it could).
+ else
+ throw new UserInformationException(Strings.Jottacloud.IllegalMountPoint); // User defined mount points on built-in device currently not allowed.
+ }
+ }
+ else
+ {
+ if (m_device_builtin)
+ m_mountPoint = JFS_DEFAULT_BUILTIN_MOUNT_POINT; // Set a suitable built-in mount point for the built-in device.
+ else
+ m_mountPoint = JFS_DEFAULT_CUSTOM_MOUNT_POINT; // Set a suitable default mount point for custom (backup) devices.
+ }
+
+ // Build URL
+ var u = new Utility.Uri(url);
+ m_path = u.HostAndPath; // Host and path of "jottacloud://folder/subfolder" is "folder/subfolder", so the actual folder path within the mount point.
+ if (string.IsNullOrEmpty(m_path)) // Require a folder. Actually it is possible to store files directly on the root level of the mount point, but that does not seem to be a good option.
+ throw new UserInformationException(Strings.Jottacloud.NoPathError);
+ if (!m_path.EndsWith("/"))
+ m_path += "/";
+ if (!string.IsNullOrEmpty(u.Username))
+ {
+ m_userInfo = new System.Net.NetworkCredential();
+ m_userInfo.UserName = u.Username;
+ if (!string.IsNullOrEmpty(u.Password))
+ m_userInfo.Password = u.Password;
+ else if (options.ContainsKey("auth-password"))
+ m_userInfo.Password = options["auth-password"];
+ }
+ else
+ {
+ if (options.ContainsKey("auth-username"))
+ {
+ m_userInfo = new System.Net.NetworkCredential();
+ m_userInfo.UserName = options["auth-username"];
+ if (options.ContainsKey("auth-password"))
+ m_userInfo.Password = options["auth-password"];
+ }
+ }
+ if (m_userInfo == null || string.IsNullOrEmpty(m_userInfo.UserName))
+ throw new UserInformationException(Strings.Jottacloud.NoUsernameError);
+ if (m_userInfo == null || string.IsNullOrEmpty(m_userInfo.Password))
+ throw new UserInformationException(Strings.Jottacloud.NoPasswordError);
+ if (m_userInfo != null) // Bugfix, see http://connect.microsoft.com/VisualStudio/feedback/details/695227/networkcredential-default-constructor-leaves-domain-null-leading-to-null-object-reference-exceptions-in-framework-code
+ m_userInfo.Domain = "";
+ m_url_device = JFS_ROOT + "/" + m_userInfo.UserName + "/" + m_device;
+ m_url = m_url_device + "/" + m_mountPoint + "/" + m_path;
+ m_url_upload = JFS_ROOT_UPLOAD + "/" + m_userInfo.UserName + "/" + m_device + "/" + m_mountPoint + "/" + m_path; // Different hostname, else identical to m_url.
+ }
+
+ #region IBackend Members
+
+ public string DisplayName
+ {
+ get { return Strings.Jottacloud.DisplayName; }
+ }
+
+ public string ProtocolKey
+ {
+ get { return "jottacloud"; }
+ }
+
+ public IEnumerable<IFileEntry> List()
+ {
+ var doc = new System.Xml.XmlDocument();
+ try
+ {
+ // Send request and load XML response.
+ var req = CreateRequest(System.Net.WebRequestMethods.Http.Get, "", "", false);
+ var areq = new Utility.AsyncHttpRequest(req);
+ using (var resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ using (var rs = areq.GetResponseStream())
+ doc.Load(rs);
+ }
+ catch (System.Net.WebException wex)
+ {
+ if (wex.Response is System.Net.HttpWebResponse && ((System.Net.HttpWebResponse)wex.Response).StatusCode == System.Net.HttpStatusCode.NotFound)
+ throw new FolderMissingException(wex);
+ throw;
+ }
+ // Handle XML response. Since we in the constructor demand a folder below the mount point we know the root
+ // element must be a "folder", else it could also have been a "mountPoint" (which has a very similar structure).
+ // We must check for "deleted" attribute, because files/folders which has it is deleted (attribute contains the timestamp of deletion)
+ // so we treat them as non-existant here.
+ var xRoot = doc.DocumentElement;
+ if (xRoot.Attributes["deleted"] != null)
+ {
+ throw new FolderMissingException();
+ }
+ foreach (System.Xml.XmlNode xFolder in xRoot.SelectNodes("folders/folder[not(@deleted)]"))
+ {
+ // Subfolders are only listed with name. We can get a timestamp by sending a request for each folder, but that is probably not necessary?
+ FileEntry fe = new FileEntry(xFolder.Attributes["name"].Value);
+ fe.IsFolder = true;
+ yield return fe;
+ }
+ foreach (System.Xml.XmlNode xFile in xRoot.SelectNodes("files/file[not(@deleted)]"))
+ {
+ string name = xFile.Attributes["name"].Value;
+ // Normal files have an "currentRevision", which represent the most recent successfully upload
+ // (could also checked that currentRevision/state is "COMPLETED", but should not be necessary).
+ // There might also be a newer "latestRevision" coming from an incomplete or corrupt upload,
+ // but we ignore that here and use the information about the last valid version.
+ System.Xml.XmlNode xRevision = xFile.SelectSingleNode("currentRevision");
+ if (xRevision != null)
+ {
+ System.Xml.XmlNode xNode = xRevision.SelectSingleNode("state");
+ if (xNode.InnerText == "COMPLETED") // Think "currentRevision" always is a complete version, but just to be on the safe side..
+ {
+ xNode = xRevision.SelectSingleNode("size");
+ long size;
+ if (xNode == null || !long.TryParse(xNode.InnerText, out size))
+ size = -1;
+ DateTime lastModified;
+ xNode = xRevision.SelectSingleNode("modified"); // There is created, modified and updated time stamps, but not last accessed.
+ if (xNode == null || !DateTime.TryParseExact(xNode.InnerText, JFS_DATE_FORMAT, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal, out lastModified))
+ lastModified = new DateTime();
+ FileEntry fe = new FileEntry(name, size, lastModified, lastModified);
+ yield return fe;
+ }
+ }
+ }
+ }
+
+ public void Put(string remotename, string filename)
+ {
+ using (System.IO.FileStream fs = System.IO.File.OpenRead(filename))
+ Put(remotename, fs);
+ }
+
+ public void Get(string remotename, string filename)
+ {
+ using (System.IO.FileStream fs = System.IO.File.Create(filename))
+ Get(remotename, fs);
+ }
+
+ public void Delete(string remotename)
+ {
+ System.Net.HttpWebRequest req = CreateRequest(System.Net.WebRequestMethods.Http.Post, remotename, "rm=true", false); // rm=true means permanent delete, dl=true would be move to trash.
+ Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
+ using (System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ { }
+ }
+
+ public IList<ICommandLineArgument> SupportedCommands
+ {
+ get
+ {
+ return new List<ICommandLineArgument>(new ICommandLineArgument[] {
+ new CommandLineArgument("auth-password", CommandLineArgument.ArgumentType.Password, Strings.Jottacloud.DescriptionAuthPasswordShort, Strings.Jottacloud.DescriptionAuthPasswordLong),
+ new CommandLineArgument("auth-username", CommandLineArgument.ArgumentType.String, Strings.Jottacloud.DescriptionAuthUsernameShort, Strings.Jottacloud.DescriptionAuthUsernameLong),
+ new CommandLineArgument(JFS_DEVICE_OPTION, CommandLineArgument.ArgumentType.String, Strings.Jottacloud.DescriptionDeviceShort, Strings.Jottacloud.DescriptionDeviceLong(JFS_MOUNT_POINT_OPTION)),
+ new CommandLineArgument(JFS_MOUNT_POINT_OPTION, CommandLineArgument.ArgumentType.String, Strings.Jottacloud.DescriptionMountPointShort, Strings.Jottacloud.DescriptionMountPointLong(JFS_DEVICE_OPTION)),
+ });
+ }
+ }
+
+ public string Description
+ {
+ get { return Strings.Jottacloud.Description; }
+ }
+
+ public void Test()
+ {
+ this.TestList();
+ }
+
+ public void CreateFolder()
+ {
+ // When using custom (backup) device we must create the device first (if not already exists).
+ if (!m_device_builtin)
+ {
+ System.Net.HttpWebRequest req = CreateRequest(System.Net.WebRequestMethods.Http.Post, m_url_device, "type=WORKSTATION"); // Hard-coding device type. Must be one of "WORKSTATION", "LAPTOP", "IMAC", "MACBOOK", "IPAD", "ANDROID", "IPHONE" or "WINDOWS_PHONE".
+ Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
+ using (System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ { }
+ }
+ // Create the folder path, and if using custom mount point it will be created as well in the same operation.
+ {
+ System.Net.HttpWebRequest req = CreateRequest(System.Net.WebRequestMethods.Http.Post, "", "mkDir=true", false);
+ Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
+ using (System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ { }
+ }
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+
+ private System.Net.HttpWebRequest CreateRequest(string method, string url, string queryparams)
+ {
+ System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url + (string.IsNullOrEmpty(queryparams) || queryparams.Trim().Length == 0 ? "" : "?" + queryparams));
+ req.Method = method;
+ req.Credentials = m_userInfo;
+ req.PreAuthenticate = true; // We need this under Mono for some reason, and it appears some servers require this as well
+ req.KeepAlive = false;
+ req.UserAgent = "Duplicati Jottacloud Client v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ req.Headers.Add("x-jftp-version", API_VERSION);
+ return req;
+ }
+
+ private System.Net.HttpWebRequest CreateRequest(string method, string remotename, string queryparams, bool upload)
+ {
+ var url = (upload ? m_url_upload : m_url) + Library.Utility.Uri.UrlEncode(remotename).Replace("+", "%20");
+ return CreateRequest(method, url, queryparams);
+ }
+
+ #region IStreamingBackend Members
+
+ public bool SupportsStreaming
+ {
+ get { return true; }
+ }
+
+ public void Get(string remotename, System.IO.Stream stream)
+ {
+ // Downloading from Jottacloud: Will only succeed if the file has a completed revision,
+ // and if there are multiple versions of the file we will only get the latest completed version,
+ // ignoring any incomplete or corrupt versions.
+ var req = CreateRequest(System.Net.WebRequestMethods.Http.Get, remotename, "mode=bin", false);
+ var areq = new Utility.AsyncHttpRequest(req);
+ using (var resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ using (var s = areq.GetResponseStream())
+ Utility.Utility.CopyStream(s, stream, true, m_copybuffer);
+ }
+
+ public void Put(string remotename, System.IO.Stream stream)
+ {
+ // Some challenges with uploading to Jottacloud:
+ // - Jottacloud supports use of a custom header where we can tell the server the MD5 hash of the file
+ // we are uploading, and then it will verify the content of our request against it. But the HTTP
+ // status code we get back indicates success even if there is a mismatch, so we must dig into the
+ // XML response to see if we were able to correctly upload the new content or not. Another issue
+ // is that if the stream is not seek-able we have a challenge pre-calculating MD5 hash on it before
+ // writing it out on the HTTP request stream. And even if the stream is seek-able it may be throttled.
+ // One way to avoid using the throttled stream for calculating the MD5 is to try to get the
+ // underlying stream from the "m_basestream" field, with fall-back to a temporary file.
+ // - We can instead chose to upload the data without setting the MD5 hash header. The server will
+ // calculate the MD5 on its side and return it in the response back to use. We can then compare it
+ // with the MD5 hash of the stream (using a MD5CalculatingStream), and if there is a mismatch we can
+ // request the server to remove the file again and throw an exception. But there is a requirement that
+ // we specify the file size in a custom header. And if the stream is not seek-able we are not able
+ // to use stream.Length, so we are back at square one.
+ Duplicati.Library.Utility.TempFile tmpFile = null;
+ var baseStream = stream;
+ while (baseStream is Duplicati.Library.Utility.OverrideableStream)
+ baseStream = typeof(Duplicati.Library.Utility.OverrideableStream).GetField("m_basestream", System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(baseStream) as System.IO.Stream;
+ if (baseStream == null)
+ throw new Exception(string.Format("Unable to unwrap stream from: {0}", stream.GetType()));
+ string md5Hash;
+ if (baseStream.CanSeek)
+ {
+ var originalPosition = baseStream.Position;
+ using (var md5 = System.Security.Cryptography.MD5.Create())
+ md5Hash = Library.Utility.Utility.ByteArrayAsHexString(md5.ComputeHash(baseStream));
+ baseStream.Position = originalPosition;
+ }
+ else
+ {
+ // No seeking possible, use a temp file
+ tmpFile = new Duplicati.Library.Utility.TempFile();
+ using (var os = System.IO.File.OpenWrite(tmpFile))
+ using (var md5 = new Utility.MD5CalculatingStream(baseStream))
+ {
+ Library.Utility.Utility.CopyStream(md5, os, true, m_copybuffer);
+ md5Hash = md5.GetFinalHashString();
+ }
+ stream = System.IO.File.OpenRead(tmpFile);
+ }
+ try
+ {
+ // Create request, with query parameter, and a few custom headers.
+ // NB: If we wanted to we could send the same POST request as below but without the file contents
+ // and with "cphash=[md5Hash]" as the only query parameter. Then we will get an HTTP 200 (OK) response
+ // if an identical file already exists, and we can skip uploading the new file. We will get
+ // HTTP 404 (Not Found) if file does not exists or it exists with a different hash, in which
+ // case we must send a new request to upload the new content.
+ var fileSize = stream.Length;
+ var req = CreateRequest(System.Net.WebRequestMethods.Http.Post, remotename, "umode=nomultipart", true);
+ req.Headers.Add("JMd5", md5Hash); // Not required, but it will make the server verify the content and mark the file as corrupt if there is a mismatch.
+ req.Headers.Add("JSize", fileSize.ToString()); // Required, and used to mark file as incomplete if we upload something be the total size of the original file!
+ // File time stamp headers: Since we are working with a stream here we do not know the local file's timestamps,
+ // and then we can just omit the JCreated and JModified and let the server automatically set the current time.
+ //req.Headers.Add("JCreated", timeCreated);
+ //req.Headers.Add("JModified", timeModified);
+ req.ContentType = "application/octet-stream";
+ req.ContentLength = fileSize;
+ // Write post data request
+ var areq = new Utility.AsyncHttpRequest(req);
+ using (var rs = areq.GetRequestStream())
+ Utility.Utility.CopyStream(stream, rs, true, m_copybuffer);
+ // Send request, and check response
+ using (var resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ {
+ if (resp.StatusCode != System.Net.HttpStatusCode.Created)
+ throw new System.Net.WebException(Strings.Jottacloud.FileUploadError, null, System.Net.WebExceptionStatus.ProtocolError, resp);
+
+ // Request seems to be successful, but we must verify the response XML content to be sure that the file
+ // was correctly uploaded: The server will verify the JSize header and mark the file as incomplete if
+ // there was mismatch, and it will verify the JMd5 header and mark the file as corrupt if there was a hash
+ // mismatch. The returned XML contains a file element, and if upload was error free it contains a single
+ // child element "currentRevision", which has a "state" child element with the string "COMPLETED".
+ // If there was a problem we should have a "latestRevision" child element, and this will have state with
+ // value "INCOMPLETE" or "CORRUPT". If the file was new or had no previous complete versions the latestRevision
+ // will be the only child, but if not there may also be a "currentRevision" representing the previous
+ // complete version - and then we need to detect the case where our upload failed but there was an existing
+ // complete version!
+ using (var rs = areq.GetResponseStream())
+ {
+ var doc = new System.Xml.XmlDocument();
+ try { doc.Load(rs); }
+ catch (System.Xml.XmlException)
+ {
+ throw new System.Net.WebException(Strings.Jottacloud.FileUploadError, System.Net.WebExceptionStatus.ProtocolError);
+ }
+ bool uploadCompletedSuccessfully = false;
+ var xFile = doc["file"];
+ if (xFile != null)
+ {
+ var xRevState = xFile.SelectSingleNode("latestRevision");
+ if (xRevState == null) {
+ xRevState = xFile.SelectSingleNode("currentRevision/state");
+ if (xRevState != null)
+ uploadCompletedSuccessfully = xRevState.InnerText == "COMPLETED"; // Success: There is no "latestRevision", only a "currentRevision" (and it specifies the file is complete, but I think it always will).
+ }
+ }
+ if (!uploadCompletedSuccessfully) // Report error (and we just let the incomplete/corrupt file revision stay on the server..)
+ throw new System.Net.WebException(Strings.Jottacloud.FileUploadError, System.Net.WebExceptionStatus.ProtocolError);
+ }
+ }
+ }
+ finally
+ {
+ try
+ {
+ if (tmpFile != null)
+ tmpFile.Dispose();
+ }
+ catch { }
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Duplicati/Library/Backend/Jottacloud/Properties/AssemblyInfo.cs b/Duplicati/Library/Backend/Jottacloud/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..3b65be92d
--- /dev/null
+++ b/Duplicati/Library/Backend/Jottacloud/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+#region Disclaimer / License
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#endregion
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Duplicati.Library.Backend.Jottacloud")]
+[assembly: AssemblyDescription("A Jottacloud backend for Duplicati")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Duplicati Team")]
+[assembly: AssemblyProduct("Duplicati.Backend.Jottacloud")]
+[assembly: AssemblyCopyright("Copyright © Duplicati Team 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("4fb0b20e-c5c6-4085-a8fa-e0e0722fb5a2")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.0.0.7")]
+[assembly: AssemblyFileVersion("2.0.0.7")]
diff --git a/Duplicati/Library/Backend/Jottacloud/Strings.cs b/Duplicati/Library/Backend/Jottacloud/Strings.cs
new file mode 100644
index 000000000..871ddb815
--- /dev/null
+++ b/Duplicati/Library/Backend/Jottacloud/Strings.cs
@@ -0,0 +1,21 @@
+using Duplicati.Library.Localization.Short;
+namespace Duplicati.Library.Backend.Strings {
+ internal static class Jottacloud
+ {
+ public static string DisplayName { get { return LC.L(@"Jottacloud"); } }
+ public static string Description { get { return LC.L(@"This backend can read and write data to Jottacloud using it's REST protocol. Allowed format is ""jottacloud://folder/subfolder""."); } }
+ public static string NoUsernameError { get { return LC.L(@"No username given"); } }
+ public static string NoPasswordError { get { return LC.L(@"No password given"); } }
+ public static string NoPathError { get { return LC.L(@"No path given, cannot upload files to the root folder"); } }
+ public static string IllegalMountPoint { get { return LC.L(@"Illegal mount point given."); } }
+ public static string FileUploadError { get { return LC.L(@"Failed to upload file"); } }
+ public static string DescriptionAuthUsernameShort { get { return LC.L(@"Supplies the username used to connect to the server"); } }
+ public static string DescriptionAuthUsernameLong { get { return LC.L(@"The username used to connect to the server. This may also be supplied as the environment variable ""AUTH_USERNAME""."); } }
+ public static string DescriptionAuthPasswordShort { get { return LC.L(@"Supplies the password used to connect to the server"); } }
+ public static string DescriptionAuthPasswordLong { get { return LC.L(@"The password used to connect to the server. This may also be supplied as the environment variable ""AUTH_PASSWORD""."); } }
+ public static string DescriptionDeviceShort { get { return LC.L(@"Supplies the backup device to use"); } }
+ public static string DescriptionDeviceLong(string mountPointOption) { return LC.L(@"The backup device to use. Will be created if not already exists. You can manage your devices from the backup panel in the Jottacloud web interface. When you specify a custom device you should also specify the mount point to use on this device with the ""{0}"" option.", mountPointOption); }
+ public static string DescriptionMountPointShort { get { return LC.L(@"Supplies the mount point to use on the server"); } }
+ public static string DescriptionMountPointLong(string deviceOptionName) { return LC.L(@"The mount point to use on the server. The default is ""Archive"" for using the built-in archive mount point. Set this option to ""Sync"" to use the built-in synchronization mount point instead, or if you have specified a custom device with option ""{0}"" you are free to name the mount point as you like.", deviceOptionName); }
+ }
+}
diff --git a/Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj b/Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj
index f18b63f4e..bbfaad3be 100644
--- a/Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj
+++ b/Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj
@@ -10,6 +10,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -31,11 +32,13 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
+ <Reference Include="System.Net.Http" />
<Reference Include="MegaApiClient">
- <HintPath>..\..\..\..\packages\MegaApiClient.1.2.2\lib\net45\MegaApiClient.dll</HintPath>
+ <HintPath>..\..\..\..\packages\MegaApiClient.1.6.0\lib\net45\MegaApiClient.dll</HintPath>
</Reference>
+ <Reference Include="System.Web" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/Mega/MegaBackend.cs b/Duplicati/Library/Backend/Mega/MegaBackend.cs
index 46c16123b..e9261717f 100644
--- a/Duplicati/Library/Backend/Mega/MegaBackend.cs
+++ b/Duplicati/Library/Backend/Mega/MegaBackend.cs
@@ -66,9 +66,9 @@ namespace Duplicati.Library.Backend.Mega
m_password = uri.Password;
if (string.IsNullOrEmpty(m_username))
- throw new Exception(Strings.MegaBackend.NoUsernameError);
+ throw new UserInformationException(Strings.MegaBackend.NoUsernameError);
if (string.IsNullOrEmpty(m_password))
- throw new Exception(Strings.MegaBackend.NoPasswordError);
+ throw new UserInformationException(Strings.MegaBackend.NoPasswordError);
m_prefix = uri.HostAndPath ?? "";
}
@@ -112,12 +112,12 @@ namespace Duplicati.Library.Backend.Mega
private INode GetFileNode(string name)
{
if (m_filecache != null && m_filecache.ContainsKey(name))
- return m_filecache[name].OrderByDescending(x => x.LastModificationDate).First();
+ return m_filecache[name].OrderByDescending(x => x.ModificationDate).First();
ResetFileCache();
if (m_filecache != null && m_filecache.ContainsKey(name))
- return m_filecache[name].OrderByDescending(x => x.LastModificationDate).First();
+ return m_filecache[name].OrderByDescending(x => x.ModificationDate).First();
throw new FileMissingException();
}
@@ -170,16 +170,15 @@ namespace Duplicati.Library.Backend.Mega
#region IBackend implementation
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
if (m_filecache == null)
ResetFileCache();
- return (
+ return
from n in m_filecache.Values
- let item = n.OrderByDescending(x => x.LastModificationDate).First()
- select (IFileEntry)new FileEntry(item.Name, item.Size, item.LastModificationDate, item.LastModificationDate)
- ).ToList();
+ let item = n.OrderByDescending(x => x.ModificationDate).First()
+ select new FileEntry(item.Name, item.Size, item.ModificationDate ?? new DateTime(0), item.ModificationDate ?? new DateTime(0));
}
public void Put(string remotename, string filename)
@@ -218,7 +217,7 @@ namespace Duplicati.Library.Backend.Mega
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
diff --git a/Duplicati/Library/Backend/Mega/Strings.cs b/Duplicati/Library/Backend/Mega/Strings.cs
index 00d56dd09..d44925690 100644
--- a/Duplicati/Library/Backend/Mega/Strings.cs
+++ b/Duplicati/Library/Backend/Mega/Strings.cs
@@ -9,6 +9,6 @@ namespace Duplicati.Library.Backend.Strings {
public static string NoPasswordError { get { return LC.L(@"No password given"); } }
public static string NoUsernameError { get { return LC.L(@"No username given"); } }
public static string NoPathError { get { return LC.L(@"No path given, cannot upload files to the root folder"); } }
- public static string Description { get { return LC.L(@"This backend can read and write data to Mega.co.nz. Allowed formats are: ""mega://folder/subfolder"""); } }
+ public static string Description { get { return LC.L(@"This backend can read and write data to Mega.co.nz. Allowed formats are: ""mega://folder/subfolder"""); } }
}
}
diff --git a/Duplicati/Library/Backend/Mega/packages.config b/Duplicati/Library/Backend/Mega/packages.config
index f08d64620..d8d29881e 100644
--- a/Duplicati/Library/Backend/Mega/packages.config
+++ b/Duplicati/Library/Backend/Mega/packages.config
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="MegaApiClient" version="1.2.2" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="MegaApiClient" version="1.6.0" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
+ <package id="System.Net.Http" version="4.3.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/OAuthHelper/Duplicati.Library.OAuthHelper.csproj b/Duplicati/Library/Backend/OAuthHelper/Duplicati.Library.OAuthHelper.csproj
index a1416d98a..7079ee68f 100644
--- a/Duplicati/Library/Backend/OAuthHelper/Duplicati.Library.OAuthHelper.csproj
+++ b/Duplicati/Library/Backend/OAuthHelper/Duplicati.Library.OAuthHelper.csproj
@@ -10,6 +10,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -32,7 +33,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -52,6 +53,10 @@
<Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
<Name>Duplicati.Library.Localization</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
+ <Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
+ <Name>Duplicati.Library.Interface</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
diff --git a/Duplicati/Library/Backend/OAuthHelper/JSONWebHelper.cs b/Duplicati/Library/Backend/OAuthHelper/JSONWebHelper.cs
index 6b4137dfe..426ede3dc 100644
--- a/Duplicati/Library/Backend/OAuthHelper/JSONWebHelper.cs
+++ b/Duplicati/Library/Backend/OAuthHelper/JSONWebHelper.cs
@@ -219,7 +219,7 @@ namespace Duplicati.Library
/// <summary>
/// Use this method to register an exception handler,
- /// which can throw another, more meaningfull exception
+ /// which can throw another, more meaningful exception
/// </summary>
/// <param name="ex">The exception being processed.</param>
protected virtual void ParseException(Exception ex)
diff --git a/Duplicati/Library/Backend/OAuthHelper/OAuthHelper.cs b/Duplicati/Library/Backend/OAuthHelper/OAuthHelper.cs
index 6a624a03d..2b7a83b90 100644
--- a/Duplicati/Library/Backend/OAuthHelper/OAuthHelper.cs
+++ b/Duplicati/Library/Backend/OAuthHelper/OAuthHelper.cs
@@ -20,27 +20,58 @@ using Duplicati.Library.Utility;
using System.Collections.Generic;
using System.Web;
namespace Duplicati.Library
-{
+{
+ /// <summary>
+ /// Class for providing call-context access to http settings
+ /// </summary>
+ public static class OAuthContextSettings
+ {
+ /// <summary>
+ /// The struct wrapping the OAuth settings
+ /// </summary>
+ private struct OAuthSettings
+ {
+ /// <summary>
+ /// The server url
+ /// </summary>
+ public string ServerURL;
+ }
+
+ /// <summary>
+ /// Starts the session.
+ /// </summary>
+ /// <returns>The session.</returns>
+ /// <param name="serverurl">The url to use for the server.</param>
+ public static IDisposable StartSession(string serverurl)
+ {
+ return CallContextSettings<OAuthSettings>.StartContext(new OAuthSettings() { ServerURL = serverurl });
+ }
+
+ /// <summary>
+ /// Gets the server URL to use for OAuth.
+ /// </summary>
+ public static string ServerURL
+ {
+ get
+ {
+ var r = CallContextSettings<OAuthSettings>.Settings.ServerURL;
+ return string.IsNullOrWhiteSpace(r) ? OAuthHelper.DUPLICATI_OAUTH_SERVICE : r;
+ }
+ }
+ }
+
public class OAuthHelper : JSONWebHelper
{
private string m_token;
private string m_authid;
private DateTime m_tokenExpires = DateTime.UtcNow;
- private static string _override_server = null;
-
- public static string OAUTH_SERVER
- {
- get { return string.IsNullOrWhiteSpace(_override_server) ? DUPLICATI_OAUTH_SERVICE : _override_server; }
- set { _override_server = value; }
- }
-
public const string DUPLICATI_OAUTH_SERVICE = "https://duplicati-oauth-handler.appspot.com/refresh";
private const string OAUTH_LOGIN_URL_TEMPLATE = "https://duplicati-oauth-handler.appspot.com/?type={0}";
public static string OAUTH_LOGIN_URL(string modulename)
{
- var u = new Library.Utility.Uri(OAUTH_SERVER);
+ var u = new Library.Utility.Uri(OAuthContextSettings.ServerURL);
var addr = u.SetPath("").SetQuery((u.Query ?? "") + (string.IsNullOrWhiteSpace(u.Query) ? "" : "&") + "type={0}");
return string.Format(addr.ToString(), modulename);
}
@@ -61,12 +92,12 @@ namespace Duplicati.Library
OAuthLoginUrl = OAUTH_LOGIN_URL(servicename);
if (string.IsNullOrEmpty(authid))
- throw new Exception(Strings.OAuthHelper.MissingAuthID(OAuthLoginUrl));
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.OAuthHelper.MissingAuthID(OAuthLoginUrl));
}
public T GetTokenResponse<T>()
{
- var req = CreateRequest(OAUTH_SERVER);
+ var req = CreateRequest(OAuthContextSettings.ServerURL);
req.Headers["X-AuthID"] = m_authid;
req.Timeout = (int)TimeSpan.FromSeconds(25).TotalMilliseconds;
@@ -76,7 +107,7 @@ namespace Duplicati.Library
public override HttpWebRequest CreateRequest(string url, string method = null)
{
var r = base.CreateRequest(url, method);
- if (AutoAuthHeader && !OAUTH_SERVER.Equals(url))
+ if (AutoAuthHeader && !string.Equals(OAuthContextSettings.ServerURL, url))
r.Headers["Authorization"] = string.Format("Bearer {0}", AccessToken);
return r;
}
@@ -119,9 +150,9 @@ namespace Duplicati.Library
if (resp.StatusCode == HttpStatusCode.ServiceUnavailable)
{
if (msg == resp.StatusDescription)
- throw new Exception(Strings.OAuthHelper.OverQuotaError);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.OAuthHelper.OverQuotaError);
else
- throw new Exception(Strings.OAuthHelper.AuthorizationFailure(msg, OAuthLoginUrl), ex);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.OAuthHelper.AuthorizationFailure(msg, OAuthLoginUrl), ex);
}
//Fail faster on client errors
@@ -130,7 +161,7 @@ namespace Duplicati.Library
}
if (retries >= (clienterror ? 1 : 5))
- throw new Exception(Strings.OAuthHelper.AuthorizationFailure(msg, OAuthLoginUrl), ex);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.OAuthHelper.AuthorizationFailure(msg, OAuthLoginUrl), ex);
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(Math.Pow(2, retries)));
retries++;
@@ -144,15 +175,15 @@ namespace Duplicati.Library
public void ThrowOverQuotaError()
{
- throw new Exception(Strings.OAuthHelper.OverQuotaError);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.OAuthHelper.OverQuotaError);
}
public void ThrowAuthException(string msg, Exception ex)
{
if (ex == null)
- throw new Exception(Strings.OAuthHelper.AuthorizationFailure(msg, OAuthLoginUrl));
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.OAuthHelper.AuthorizationFailure(msg, OAuthLoginUrl));
else
- throw new Exception(Strings.OAuthHelper.AuthorizationFailure(msg, OAuthLoginUrl), ex);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.OAuthHelper.AuthorizationFailure(msg, OAuthLoginUrl), ex);
}
diff --git a/Duplicati/Library/Backend/OAuthHelper/packages.config b/Duplicati/Library/Backend/OAuthHelper/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Backend/OAuthHelper/packages.config
+++ b/Duplicati/Library/Backend/OAuthHelper/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/OneDrive/Duplicati.Library.Backend.OneDrive.csproj b/Duplicati/Library/Backend/OneDrive/Duplicati.Library.Backend.OneDrive.csproj
index 6586af949..c03f0b385 100644
--- a/Duplicati/Library/Backend/OneDrive/Duplicati.Library.Backend.OneDrive.csproj
+++ b/Duplicati/Library/Backend/OneDrive/Duplicati.Library.Backend.OneDrive.csproj
@@ -17,6 +17,7 @@
<UpgradeBackupLocation />
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
@@ -44,7 +45,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/OneDrive/OneDrive.cs b/Duplicati/Library/Backend/OneDrive/OneDrive.cs
index f160daf62..f93f6102d 100644
--- a/Duplicati/Library/Backend/OneDrive/OneDrive.cs
+++ b/Duplicati/Library/Backend/OneDrive/OneDrive.cs
@@ -7,7 +7,7 @@ using Duplicati.Library.Interface;
namespace Duplicati.Library.Backend
{
- public class OneDrive : IBackend, IStreamingBackend
+ public class OneDrive : IBackend, IStreamingBackend, IQuotaEnabledBackend, IRenameEnabledBackend
{
private const string AUTHID_OPTION = "authid";
@@ -30,7 +30,7 @@ namespace Duplicati.Library.Backend
private OAuthHelper m_oauth;
- private Dictionary<string, string> m_fileidCache = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
+ private Dictionary<string, string> m_fileidCache = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private readonly byte[] m_copybuffer = new byte[Duplicati.Library.Utility.Utility.DEFAULT_BUFFER_SIZE];
@@ -73,11 +73,11 @@ namespace Duplicati.Library.Backend
public string upload_location { get; set; }
public string type { get; set; }
[Newtonsoft.Json.JsonProperty(NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public DateTime created_time { get; set; }
+ public DateTime? created_time { get; set; }
[Newtonsoft.Json.JsonProperty(NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public DateTime updated_time { get; set; }
+ public DateTime? updated_time { get; set; }
[Newtonsoft.Json.JsonProperty(NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public long size { get; set; }
+ public long? size { get; set; }
}
private class WLID_CreateFolderData
@@ -106,19 +106,27 @@ namespace Duplicati.Library.Backend
public string locale { get; set; }
}
+ private class WLID_QuotaInfo
+ {
+ [Newtonsoft.Json.JsonProperty("quota")]
+ public long? Quota { get; set; }
+ [Newtonsoft.Json.JsonProperty("available")]
+ public long? Available { get; set; }
+ }
+
private WLID_FolderItem FindFolder(string folder, string parentfolder = null)
{
if (string.IsNullOrWhiteSpace(parentfolder))
parentfolder = ROOT_FOLDER_ID;
var url = string.Format("{0}/{1}?access_token={2}", WLID_SERVER, string.Format(FOLDER_TEMPLATE, parentfolder), Library.Utility.Uri.UrlEncode(m_oauth.AccessToken));
- var res = m_oauth.GetJSONData<WLID_DataItem>(url);
+ var res = m_oauth.GetJSONData<WLID_DataItem>(url, x => x.UserAgent = USER_AGENT);
if (res == null || res.data == null)
return null;
foreach(var r in res.data)
- if (string.Equals(r.name, folder, StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(r.name, folder, StringComparison.OrdinalIgnoreCase))
return r;
return null;
@@ -130,7 +138,7 @@ namespace Duplicati.Library.Backend
if (folders.Length == 0)
{
var url = string.Format("{0}/{1}?access_token={2}", WLID_SERVER, ROOT_FOLDER_ID, Library.Utility.Uri.UrlEncode(m_oauth.AccessToken));
- return m_oauth.GetJSONData<WLID_FolderItem>(url);
+ return m_oauth.GetJSONData<WLID_FolderItem>(url, x => x.UserAgent = USER_AGENT);
}
WLID_FolderItem cur = null;
@@ -204,7 +212,7 @@ namespace Duplicati.Library.Backend
if (string.IsNullOrWhiteSpace(id))
{
// Refresh the list of files, just in case
- List();
+ foreach (IFileEntry file in List()) { /* We just need to iterate the whole list */ }
m_fileidCache.TryGetValue(name, out id);
if (string.IsNullOrWhiteSpace(id) && throwIfMissing)
@@ -214,11 +222,17 @@ namespace Duplicati.Library.Backend
return id;
}
+ private WLID_QuotaInfo GetQuotaInfo()
+ {
+ var url = string.Format("{0}/me/skydrive/quota?access_token={1}", WLID_SERVER, Library.Utility.Uri.UrlEncode(m_oauth.AccessToken));
+ return m_oauth.GetJSONData<WLID_QuotaInfo>(url, x => x.UserAgent = USER_AGENT);
+ }
+
#region IBackend Members
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
@@ -236,19 +250,17 @@ namespace Duplicati.Library.Backend
get { return "onedrive"; }
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
int offset = 0;
int count = FILE_LIST_PAGE_SIZE;
-
- var files = new List<IFileEntry>();
-
+
m_fileidCache.Clear();
while(count == FILE_LIST_PAGE_SIZE)
{
var url = string.Format("{0}/{1}?access_token={2}&limit={3}&offset={4}", WLID_SERVER, string.Format(FOLDER_TEMPLATE, FolderID), Library.Utility.Uri.UrlEncode(m_oauth.AccessToken), FILE_LIST_PAGE_SIZE, offset);
- var res = m_oauth.GetJSONData<WLID_DataItem>(url);
+ var res = m_oauth.GetJSONData<WLID_DataItem>(url, x => x.UserAgent = USER_AGENT);
if (res != null && res.data != null)
{
@@ -257,9 +269,9 @@ namespace Duplicati.Library.Backend
{
m_fileidCache.Add(r.name, r.id);
- var fe = new FileEntry(r.name, r.size, r.updated_time, r.updated_time);
- fe.IsFolder = string.Equals(r.type, "folder", StringComparison.InvariantCultureIgnoreCase);
- files.Add(fe);
+ var fe = new FileEntry(r.name, r.size.Value, r.updated_time.Value, r.updated_time.Value);
+ fe.IsFolder = string.Equals(r.type, "folder", StringComparison.OrdinalIgnoreCase);
+ yield return fe;
}
}
else
@@ -268,10 +280,7 @@ namespace Duplicati.Library.Backend
}
offset += count;
-
}
-
- return files;
}
public void Put(string remotename, string filename)
@@ -293,6 +302,7 @@ namespace Duplicati.Library.Backend
var id = GetFileID(remotename);
var url = string.Format("{0}/{1}?access_token={2}", WLID_SERVER, id, Library.Utility.Uri.UrlEncode(m_oauth.AccessToken));
var req = (HttpWebRequest)WebRequest.Create(url);
+ req.UserAgent = USER_AGENT;
req.Method = "DELETE";
var areq = new Utility.AsyncHttpRequest(req);
@@ -354,8 +364,9 @@ namespace Duplicati.Library.Backend
{
var url = string.Format("{0}/me?access_token={1}", WLID_SERVER, Library.Utility.Uri.UrlEncode(m_oauth.AccessToken));
var req = (HttpWebRequest)WebRequest.Create(url);
+ req.UserAgent = USER_AGENT;
var areq = new Utility.AsyncHttpRequest(req);
-
+
using(var resp = (HttpWebResponse)areq.GetResponse())
using(var rs = areq.GetResponseStream())
using(var tr = new System.IO.StreamReader(rs))
@@ -367,6 +378,88 @@ namespace Duplicati.Library.Backend
}
}
+ #region IRenameEnabledBackend
+
+ public void Rename(string oldname, string newname)
+ {
+ try
+ {
+ try
+ {
+ var id = GetFileID(oldname);
+ var url = string.Format("{0}/{1}?access_token={2}", WLID_SERVER, id, Library.Utility.Uri.UrlEncode(m_oauth.AccessToken));
+ var req = (HttpWebRequest)WebRequest.Create(url);
+ req.UserAgent = USER_AGENT;
+ req.Method = "PUT";
+
+ var updateData = new WLID_FolderItem() { name = newname };
+ var data = System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(updateData));
+ req.ContentLength = data.Length;
+ req.ContentType = "application/json; charset=UTF-8";
+ using (var requestStream = req.GetRequestStream())
+ requestStream.Write(data, 0, data.Length);
+
+ var areq = new Utility.AsyncHttpRequest(req);
+ using (var resp = (HttpWebResponse)areq.GetResponse())
+ {
+ if (resp.StatusCode == System.Net.HttpStatusCode.NotFound)
+ throw new FileMissingException();
+
+ if ((int)resp.StatusCode < 200 || (int)resp.StatusCode > 299)
+ throw new ProtocolViolationException(Strings.OneDrive.UnexpectedError(resp.StatusCode, resp.StatusDescription));
+
+ m_fileidCache[newname] = id;
+ m_fileidCache.Remove(oldname);
+ }
+ }
+ catch
+ {
+ // Since we don't know the state of file IDs, clear the cache
+ m_fileidCache.Clear();
+
+ throw;
+ }
+ }
+ catch (System.Net.WebException wex)
+ {
+ if (wex.Response is System.Net.HttpWebResponse && ((System.Net.HttpWebResponse)wex.Response).StatusCode == System.Net.HttpStatusCode.NotFound)
+ throw new FileMissingException(wex);
+ else
+ throw;
+ }
+ }
+
+ #endregion
+
+ #region IQuotaEnabledBackend Members
+
+ public IQuotaInfo Quota
+ {
+ get
+ {
+ WLID_QuotaInfo quota = this.GetQuotaInfo();
+ return new QuotaInfo(quota.Quota ?? -1, quota.Available ?? -1);
+ }
+ }
+
+ public long TotalQuotaSpace
+ {
+ get
+ {
+ return this.GetQuotaInfo().Quota ?? -1;
+ }
+ }
+
+ public long FreeQuotaSpace
+ {
+ get
+ {
+ return this.GetQuotaInfo().Available ?? -1;
+ }
+ }
+
+ #endregion
+
#region IStreamingBackend Members
public void Put(string remotename, System.IO.Stream stream)
@@ -397,7 +490,7 @@ namespace Duplicati.Library.Backend
using(var resp = (HttpWebResponse)areq.GetResponse())
{
var packtype = resp.Headers["BITS-Packet-Type"];
- if (!packtype.Equals("Ack", StringComparison.InvariantCultureIgnoreCase))
+ if (!packtype.Equals("Ack", StringComparison.OrdinalIgnoreCase))
throw new Exception(string.Format("Unable to create BITS transfer, got status: {0}", packtype));
sessionid = resp.Headers["BITS-Session-Id"];
diff --git a/Duplicati/Library/Backend/OneDrive/packages.config b/Duplicati/Library/Backend/OneDrive/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Backend/OneDrive/packages.config
+++ b/Duplicati/Library/Backend/OneDrive/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/OpenStack/Duplicati.Library.Backend.OpenStack.csproj b/Duplicati/Library/Backend/OpenStack/Duplicati.Library.Backend.OpenStack.csproj
index 1f4dc2c78..29289d27c 100644
--- a/Duplicati/Library/Backend/OpenStack/Duplicati.Library.Backend.OpenStack.csproj
+++ b/Duplicati/Library/Backend/OpenStack/Duplicati.Library.Backend.OpenStack.csproj
@@ -10,6 +10,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -32,7 +33,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/OpenStack/OpenStackStorage.cs b/Duplicati/Library/Backend/OpenStack/OpenStackStorage.cs
index eea8d266a..fa801bd77 100644
--- a/Duplicati/Library/Backend/OpenStack/OpenStackStorage.cs
+++ b/Duplicati/Library/Backend/OpenStack/OpenStackStorage.cs
@@ -57,6 +57,7 @@ namespace Duplicati.Library.Backend.OpenStack
new KeyValuePair<string, string>("Rackspace US", "https://identity.api.rackspacecloud.com/v2.0"),
new KeyValuePair<string, string>("Rackspace UK", "https://lon.identity.api.rackspacecloud.com/v2.0"),
new KeyValuePair<string, string>("OVH Cloud Storage", "https://auth.cloud.ovh.net/v2.0"),
+ new KeyValuePair<string, string>("Selectel Cloud Storage", "https://auth.selcdn.ru"),
};
private class OpenStackAuthRequest
@@ -202,16 +203,16 @@ namespace Duplicati.Library.Backend.OpenStack
options.TryGetValue(REGION_OPTION, out m_region);
if (string.IsNullOrWhiteSpace(m_username))
- throw new Exception(Strings.OpenStack.MissingOptionError(USERNAME_OPTION));
+ throw new UserInformationException(Strings.OpenStack.MissingOptionError(USERNAME_OPTION));
if (string.IsNullOrWhiteSpace(m_authUri))
- throw new Exception(Strings.OpenStack.MissingOptionError(AUTHURI_OPTION));
+ throw new UserInformationException(Strings.OpenStack.MissingOptionError(AUTHURI_OPTION));
if (string.IsNullOrWhiteSpace(m_apikey))
{
if (string.IsNullOrWhiteSpace(m_password))
- throw new Exception(Strings.OpenStack.MissingOptionError(PASSWORD_OPTION));
+ throw new UserInformationException(Strings.OpenStack.MissingOptionError(PASSWORD_OPTION));
if (string.IsNullOrWhiteSpace(m_tenantName))
- throw new Exception(Strings.OpenStack.MissingOptionError(TENANTNAME_OPTION));
+ throw new UserInformationException(Strings.OpenStack.MissingOptionError(TENANTNAME_OPTION));
}
m_helper = new WebHelper(this);
@@ -254,7 +255,7 @@ namespace Duplicati.Library.Backend.OpenStack
m_accessToken = resp.access.token;
// Grab the endpoint now that we have received it anyway
- var fileservice = resp.access.serviceCatalog.Where(x => string.Equals(x.type, "object-store", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
+ var fileservice = resp.access.serviceCatalog.Where(x => string.Equals(x.type, "object-store", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (fileservice == null)
throw new Exception("No object-store service found, is this service supported by the provider?");
@@ -304,52 +305,58 @@ namespace Duplicati.Library.Backend.OpenStack
}
#endregion
#region IBackend implementation
- public List<IFileEntry> List()
+
+ private T HandleListExceptions<T>(Func<T> func)
+ {
+ try
+ {
+ return func();
+ }
+ catch (WebException wex)
+ {
+ if (wex.Response is HttpWebResponse && (((HttpWebResponse)wex.Response).StatusCode == HttpStatusCode.NotFound))
+ throw new FolderMissingException();
+ else
+ throw;
+ }
+ }
+
+ public IEnumerable<IFileEntry> List()
{
- var res = new List<IFileEntry>();
var plainurl = JoinUrls(SimpleStorageEndPoint, m_container) + string.Format("?format=json&delimiter=/&limit={0}", PAGE_LIMIT);
if (!string.IsNullOrEmpty(m_prefix))
plainurl += "&prefix=" + Library.Utility.Uri.UrlEncode(m_prefix);
var url = plainurl;
- try
+ while (true)
{
- while(true)
+ var req = m_helper.CreateRequest(url);
+ req.Accept = "application/json";
+
+ var items = HandleListExceptions(() => m_helper.ReadJSONResponse<OpenStackStorageItem[]>(req));
+ foreach (var n in items)
{
- var req = m_helper.CreateRequest(url);
- req.Accept = "application/json";
-
- var items = m_helper.ReadJSONResponse<OpenStackStorageItem[]>(req);
- foreach(var n in items)
- {
- var name = n.name;
- if (name.StartsWith(m_prefix))
- name = name.Substring(m_prefix.Length);
-
- if (n.bytes == null)
- res.Add(new FileEntry(name));
- else if (n.last_modified == null)
- res.Add(new FileEntry(name, n.bytes.Value));
- else
- res.Add(new FileEntry(name, n.bytes.Value, n.last_modified.Value, n.last_modified.Value));
- }
-
- if (items.Length != PAGE_LIMIT)
- return res;
-
- // Prepare next listing entry
- url = plainurl + string.Format("&marker={0}", Library.Utility.Uri.UrlEncode(items.Last().name));
+ var name = n.name;
+ if (name.StartsWith(m_prefix))
+ name = name.Substring(m_prefix.Length);
+
+ if (n.bytes == null)
+ yield return new FileEntry(name);
+ else if (n.last_modified == null)
+ yield return new FileEntry(name, n.bytes.Value);
+ else
+ yield return new FileEntry(name, n.bytes.Value, n.last_modified.Value, n.last_modified.Value);
}
- }
- catch(WebException wex)
- {
- if (wex.Response is HttpWebResponse && (((HttpWebResponse)wex.Response).StatusCode == HttpStatusCode.NotFound))
- throw new FolderMissingException();
- else
- throw;
+
+ if (items.Length != PAGE_LIMIT)
+ yield break;
+
+ // Prepare next listing entry
+ url = plainurl + string.Format("&marker={0}", Library.Utility.Uri.UrlEncode(items.Last().name));
}
}
+
public void Put(string remotename, string filename)
{
using (System.IO.FileStream fs = System.IO.File.OpenRead(filename))
@@ -368,7 +375,7 @@ namespace Duplicati.Library.Backend.OpenStack
}
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
{
diff --git a/Duplicati/Library/Backend/OpenStack/packages.config b/Duplicati/Library/Backend/OpenStack/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Backend/OpenStack/packages.config
+++ b/Duplicati/Library/Backend/OpenStack/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/S3/Duplicati.Library.Backend.S3.csproj b/Duplicati/Library/Backend/S3/Duplicati.Library.Backend.S3.csproj
index 181d148c2..415e63aef 100644
--- a/Duplicati/Library/Backend/S3/Duplicati.Library.Backend.S3.csproj
+++ b/Duplicati/Library/Backend/S3/Duplicati.Library.Backend.S3.csproj
@@ -17,6 +17,7 @@
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -38,13 +39,13 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="AWSSDK.Core">
- <HintPath>..\..\..\..\packages\AWSSDK.Core.3.1.7.0\lib\net45\AWSSDK.Core.dll</HintPath>
- </Reference>
- <Reference Include="AWSSDK.S3">
- <HintPath>..\..\..\..\packages\AWSSDK.S3.3.1.7.2\lib\net45\AWSSDK.S3.dll</HintPath>
+ <HintPath>..\..\..\..\packages\AWSSDK.Core.3.3.17.10\lib\net45\AWSSDK.Core.dll</HintPath>
</Reference>
<Reference Include="AWSSDK.IdentityManagement">
- <HintPath>..\..\..\..\packages\AWSSDK.IdentityManagement.3.1.4.4\lib\net45\AWSSDK.IdentityManagement.dll</HintPath>
+ <HintPath>..\..\..\..\packages\AWSSDK.IdentityManagement.3.3.5\lib\net45\AWSSDK.IdentityManagement.dll</HintPath>
+ </Reference>
+ <Reference Include="AWSSDK.S3">
+ <HintPath>..\..\..\..\packages\AWSSDK.S3.3.3.11\lib\net45\AWSSDK.S3.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/S3/S3Backend.cs b/Duplicati/Library/Backend/S3/S3Backend.cs
index 793cb0119..c287fe491 100644
--- a/Duplicati/Library/Backend/S3/S3Backend.cs
+++ b/Duplicati/Library/Backend/S3/S3Backend.cs
@@ -35,37 +35,52 @@ namespace Duplicati.Library.Backend
public const string LOCATION_OPTION = "s3-location-constraint";
public const string SSL_OPTION = "use-ssl";
- public static readonly KeyValuePair<string, string>[] KNOWN_S3_PROVIDERS = new KeyValuePair<string,string>[] {
+ public static readonly KeyValuePair<string, string>[] KNOWN_S3_PROVIDERS = new KeyValuePair<string, string>[] {
new KeyValuePair<string, string>("Amazon S3", "s3.amazonaws.com"),
new KeyValuePair<string, string>("Hosteurope", "cs.hosteurope.de"),
new KeyValuePair<string, string>("Dunkel", "dcs.dunkel.de"),
new KeyValuePair<string, string>("DreamHost", "objects.dreamhost.com"),
new KeyValuePair<string, string>("dinCloud - Chicago", "d3-ord.dincloud.com"),
new KeyValuePair<string, string>("dinCloud - Los Angeles", "d3-lax.dincloud.com"),
+ new KeyValuePair<string, string>("IBM COS (S3) Public US", "s3-api.us-geo.objectstorage.softlayer.net"),
+ new KeyValuePair<string, string>("Wasabi Hot Storage", "s3.wasabisys.com"),
};
//Updated list: http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region
public static readonly KeyValuePair<string, string>[] KNOWN_S3_LOCATIONS = new KeyValuePair<string, string>[] {
new KeyValuePair<string, string>("(default)", ""),
- new KeyValuePair<string, string>("Europe (EU, Ireland)", "EU"),
+ new KeyValuePair<string, string>("Europe (EU)", "EU"),
+ new KeyValuePair<string, string>("Europe (EU, Frankfurt)", "eu-central-1"),
+ new KeyValuePair<string, string>("Europe (EU, Ireland)", "eu-west-1"),
+ new KeyValuePair<string, string>("Europe (EU, London)", "eu-west-2"),
new KeyValuePair<string, string>("US East (Northern Virginia)", "us-east-1"),
- new KeyValuePair<string, string>("US West (Northen California)", "us-west-1"),
+ new KeyValuePair<string, string>("US East (Ohio)", "us-east-2"),
+ new KeyValuePair<string, string>("US West (Northern California)", "us-west-1"),
new KeyValuePair<string, string>("US West (Oregon)", "us-west-2"),
+ new KeyValuePair<string, string>("Canada (Central)", "ca-central-1"),
+ new KeyValuePair<string, string>("Asia Pacific (Mumbai)", "ap-south-1"),
new KeyValuePair<string, string>("Asia Pacific (Singapore)", "ap-southeast-1"),
new KeyValuePair<string, string>("Asia Pacific (Sydney)", "ap-southeast-2"),
new KeyValuePair<string, string>("Asia Pacific (Tokyo)", "ap-northeast-1"),
- new KeyValuePair<string, string>("South America (Sao Paulo)", "sa-east-1"),
+ new KeyValuePair<string, string>("Asia Pacific (Seoul)", "ap-northeast-2"),
+ new KeyValuePair<string, string>("South America (São Paulo)", "sa-east-1"),
};
public static readonly KeyValuePair<string, string>[] DEFAULT_S3_LOCATION_BASED_HOSTS = new KeyValuePair<string, string>[] {
new KeyValuePair<string, string>("EU", "s3-eu-west-1.amazonaws.com"),
+ new KeyValuePair<string, string>("ca-central-1", "s3-ca-central-1.amazonaws.com"),
new KeyValuePair<string, string>("eu-west-1", "s3-eu-west-1.amazonaws.com"),
+ new KeyValuePair<string, string>("eu-west-2", "s3-eu-west-2.amazonaws.com"),
+ new KeyValuePair<string, string>("eu-central-1", "s3-eu-central-1.amazonaws.com"),
new KeyValuePair<string, string>("us-east-1", "s3.amazonaws.com"),
+ new KeyValuePair<string, string>("us-east-2", "s3.us-east-2.amazonaws.com"),
new KeyValuePair<string, string>("us-west-1", "s3-us-west-1.amazonaws.com"),
new KeyValuePair<string, string>("us-west-2", "s3-us-west-2.amazonaws.com"),
+ new KeyValuePair<string, string>("ap-south-1", "s3-ap-south-1.amazonaws.com"),
new KeyValuePair<string, string>("ap-southeast-1", "s3-ap-southeast-1.amazonaws.com"),
new KeyValuePair<string, string>("ap-southeast-2", "s3-ap-southeast-2.amazonaws.com"),
new KeyValuePair<string, string>("ap-northeast-1", "s3-ap-northeast-1.amazonaws.com"),
+ new KeyValuePair<string, string>("ap-northeast-2", "s3-ap-northeast-2.amazonaws.com"),
new KeyValuePair<string, string>("sa-east-1", "s3-sa-east-1.amazonaws.com"),
};
@@ -154,9 +169,9 @@ namespace Duplicati.Library.Backend
awsKey = uri.Password;
if (string.IsNullOrEmpty(awsID))
- throw new Exception(Strings.S3Backend.NoAMZUserIDError);
+ throw new UserInformationException(Strings.S3Backend.NoAMZUserIDError);
if (string.IsNullOrEmpty(awsKey))
- throw new Exception(Strings.S3Backend.NoAMZKeyError);
+ throw new UserInformationException(Strings.S3Backend.NoAMZKeyError);
bool euBuckets = Utility.Utility.ParseBoolOption(options, EU_BUCKETS_OPTION);
bool useRRS = Utility.Utility.ParseBoolOption(options, RRS_OPTION);
@@ -166,7 +181,7 @@ namespace Duplicati.Library.Backend
options.TryGetValue(LOCATION_OPTION, out locationConstraint);
if (!string.IsNullOrEmpty(locationConstraint) && euBuckets)
- throw new Exception(Strings.S3Backend.OptionsAreMutuallyExclusiveError(LOCATION_OPTION, EU_BUCKETS_OPTION));
+ throw new UserInformationException(Strings.S3Backend.OptionsAreMutuallyExclusiveError(LOCATION_OPTION, EU_BUCKETS_OPTION));
if (euBuckets)
locationConstraint = S3_EU_REGION_NAME;
@@ -185,7 +200,7 @@ namespace Duplicati.Library.Backend
//Change in S3, now requires that you use location specific endpoint
if (!string.IsNullOrEmpty(locationConstraint))
foreach(KeyValuePair<string, string> kvp in DEFAULT_S3_LOCATION_BASED_HOSTS)
- if (kvp.Key.Equals(locationConstraint, StringComparison.InvariantCultureIgnoreCase))
+ if (kvp.Key.Equals(locationConstraint, StringComparison.OrdinalIgnoreCase))
{
s3host = kvp.Value;
break;
@@ -225,7 +240,7 @@ namespace Duplicati.Library.Backend
m_prefix = m_prefix.Substring(1);
}
else
- throw new Exception(Strings.S3Backend.UnableToDecodeBucketnameError(url));
+ throw new UserInformationException(Strings.S3Backend.UnableToDecodeBucketnameError(url));
}
try { Console.Error.WriteLine(Strings.S3Backend.DeprecatedUrlFormat("s3://" + m_bucket + "/" + m_prefix)); }
@@ -243,6 +258,11 @@ namespace Duplicati.Library.Backend
if (m_prefix.Length != 0 && !m_prefix.EndsWith("/"))
m_prefix += "/";
+ // Auto-disable dns lookup for non AWS configurations
+ var hasForcePathStyle = options.ContainsKey("s3-ext-forcepathstyle");
+ if (!hasForcePathStyle && !DEFAULT_S3_LOCATION_BASED_HOSTS.Any(x => string.Equals(x.Value, host, StringComparison.OrdinalIgnoreCase)) && !string.Equals(host, "s3.amazonaws.com", StringComparison.OrdinalIgnoreCase))
+ options["s3-ext-forcepathstyle"] = "true";
+
m_wrapper = new S3Wrapper(awsID, awsKey, locationConstraint, host, storageClass, useSSL, options);
}
@@ -271,20 +291,11 @@ namespace Duplicati.Library.Backend
get { return true; }
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
try
{
- List<IFileEntry> lst = Connection.ListBucket(m_bucket, m_prefix);
- for (int i = 0; i < lst.Count; i++)
- {
- ((FileEntry)lst[i]).Name = lst[i].Name.Substring(m_prefix.Length);
-
- //Fix for a bug in Duplicati 1.0 beta 3 and earlier, where filenames are incorrectly prefixed with a slash
- if (lst[i].Name.StartsWith("/") && !m_prefix.StartsWith("/"))
- ((FileEntry)lst[i]).Name = lst[i].Name.Substring(1);
- }
- return lst;
+ return ListWithouExceptionCatch();
}
catch (Exception ex)
{
@@ -297,6 +308,20 @@ namespace Duplicati.Library.Backend
}
}
+ private IEnumerable<IFileEntry> ListWithouExceptionCatch()
+ {
+ foreach (IFileEntry file in Connection.ListBucket(m_bucket, m_prefix))
+ {
+ ((FileEntry)file).Name = file.Name.Substring(m_prefix.Length);
+
+ //Fix for a bug in Duplicati 1.0 beta 3 and earlier, where filenames are incorrectly prefixed with a slash
+ if (file.Name.StartsWith("/") && !m_prefix.StartsWith("/"))
+ ((FileEntry)file).Name = file.Name.Substring(1);
+
+ yield return file;
+ }
+ }
+
public void Put(string remotename, string localname)
{
using (System.IO.FileStream fs = System.IO.File.Open(localname, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
@@ -409,7 +434,7 @@ namespace Duplicati.Library.Backend
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
diff --git a/Duplicati/Library/Backend/S3/S3IAM.cs b/Duplicati/Library/Backend/S3/S3IAM.cs
index ab5b02c91..606f52d89 100644
--- a/Duplicati/Library/Backend/S3/S3IAM.cs
+++ b/Duplicati/Library/Backend/S3/S3IAM.cs
@@ -52,8 +52,8 @@ namespace Duplicati.Library.Backend
""s3:DeleteObject""
],
""Resource"": [
- ""arn:aws:s3:::bucket-name-and-path"",
- ""arn:aws:s3:::bucket-name-and-path/*""
+ ""arn:aws:s3:::bucket-name"",
+ ""arn:aws:s3:::bucket-name/*""
]
}
]
@@ -145,7 +145,9 @@ namespace Duplicati.Library.Backend
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("Invalid value for path");
- return POLICY_DOCUMENT_TEMPLATE.Replace("bucket-name-and-path", path).Trim();
+ var bucketname = path.Split('/').First();
+
+ return POLICY_DOCUMENT_TEMPLATE.Replace("bucket-name", bucketname).Trim();
}
private Dictionary<string, string> CanCreateUser(string awsid, string awskey)
diff --git a/Duplicati/Library/Backend/S3/S3Wrapper.cs b/Duplicati/Library/Backend/S3/S3Wrapper.cs
index 36cec0ab7..667d6f5f9 100644
--- a/Duplicati/Library/Backend/S3/S3Wrapper.cs
+++ b/Duplicati/Library/Backend/S3/S3Wrapper.cs
@@ -47,9 +47,9 @@ namespace Duplicati.Library.Backend
//cfg.UserAgent = "Duplicati v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + " S3 client with AWS SDK v" + cfg.GetType().Assembly.GetName().Version.ToString();
cfg.BufferSize = (int)Duplicati.Library.Utility.Utility.DEFAULT_BUFFER_SIZE;
- foreach(var opt in options.Keys.Where(x => x.StartsWith("s3-ext-")))
+ foreach(var opt in options.Keys.Where(x => x.StartsWith("s3-ext-", StringComparison.OrdinalIgnoreCase)))
{
- var prop = cfg.GetType().GetProperties().Where(x => string.Equals(x.Name, opt.Substring("s3-ext-".Length), StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
+ var prop = cfg.GetType().GetProperties().Where(x => string.Equals(x.Name, opt.Substring("s3-ext-".Length), StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (prop != null && prop.CanWrite)
{
if (prop.PropertyType == typeof(bool))
@@ -135,12 +135,15 @@ namespace Duplicati.Library.Backend
m_client.DeleteObject(objectDeleteRequest);
}
- public virtual List<IFileEntry> ListBucket(string bucketName, string prefix)
+ public virtual IEnumerable<IFileEntry> ListBucket(string bucketName, string prefix)
{
bool isTruncated = true;
string filename = null;
- List<IFileEntry> files = new List<IFileEntry>();
+ //TODO: Figure out if this is the case with AWSSDK too
+ //Unfortunately S3 sometimes reports duplicate values when requesting more than one page of results
+ //So, track the files that have already been returned and skip any duplicates.
+ HashSet<string> alreadyReturned = new HashSet<string>();
//We truncate after ITEM_LIST_LIMIT elements, and then repeat
while (isTruncated)
@@ -161,29 +164,17 @@ namespace Duplicati.Library.Backend
foreach (S3Object obj in listResponse.S3Objects)
{
- files.Add(new FileEntry(
- obj.Key,
- obj.Size,
- obj.LastModified,
- obj.LastModified
- ));
-
+ if (alreadyReturned.Add(obj.Key))
+ {
+ yield return new FileEntry(
+ obj.Key,
+ obj.Size,
+ obj.LastModified,
+ obj.LastModified
+ );
+ }
}
}
-
- //TODO: Figure out if this is the case with AWSSDK too
- //Unfortunately S3 sometimes reports duplicate values when requesting more than one page of results
- Dictionary<string, string> tmp = new Dictionary<string, string>();
- for (int i = 0; i < files.Count; i++)
- if (tmp.ContainsKey(files[i].Name))
- {
- files.RemoveAt(i);
- i--;
- }
- else
- tmp.Add(files[i].Name, null);
-
- return files;
}
public void RenameFile(string bucketName, string source, string target)
diff --git a/Duplicati/Library/Backend/S3/Strings.cs b/Duplicati/Library/Backend/S3/Strings.cs
index 952ebccc6..d0cb721c3 100644
--- a/Duplicati/Library/Backend/S3/Strings.cs
+++ b/Duplicati/Library/Backend/S3/Strings.cs
@@ -12,12 +12,12 @@ namespace Duplicati.Library.Backend.Strings {
public static string AuthUsernameDescriptionShort { get { return LC.L(@"Supplies the username used to connect to the server"); } }
public static string NoAMZKeyError { get { return LC.L(@"No Amazon S3 secret key given"); } }
public static string NoAMZUserIDError { get { return LC.L(@"No Amazon S3 userID given"); } }
- public static string S3EurobucketDescriptionLong { get { return LC.L(@"This flag is only used when creating new buckets. If the flag is set, the bucket is created on a european server. This flag forces the ""s3-use-new-style"" flag. Amazon charges slightly more for european buckets."); } }
+ public static string S3EurobucketDescriptionLong { get { return LC.L(@"This flag is only used when creating new buckets. If the flag is set, the bucket is created on a European server. This flag forces the ""s3-use-new-style"" flag. Amazon charges slightly more for European buckets."); } }
public static string S3EurobucketDescriptionShort { get { return LC.L(@"Use a European server"); } }
public static string S3NewStyleDescriptionLong { get { return LC.L(@"Specify this argument to make the S3 backend use subdomains rather than the previous url prefix method. See the Amazon S3 documentation for more details."); } }
public static string S3NewStyleDescriptionShort { get { return LC.L(@"Use subdomain calling style"); } }
public static string UnableToDecodeBucketnameError(string url) { return LC.L(@"Unable to determine the bucket name for host: {0}", url); }
- public static string S3UseRRSDescriptionLong { get { return LC.L(@"This flag toggles the use of the special RRS header. Files stored using RRS are more likely to disapear than those stored normally, but also costs less to store. See the full description here: http://aws.amazon.com/about-aws/whats-new/2010/05/19/announcing-amazon-s3-reduced-redundancy-storage/"); } }
+ public static string S3UseRRSDescriptionLong { get { return LC.L(@"This flag toggles the use of the special RRS header. Files stored using RRS are more likely to disappear than those stored normally, but also costs less to store. See the full description here: http://aws.amazon.com/about-aws/whats-new/2010/05/19/announcing-amazon-s3-reduced-redundancy-storage/"); } }
public static string S3UseRRSDescriptionShort { get { return LC.L(@"Use Reduced Redundancy Storage"); } }
public static string DeprecatedUrlFormat(string url) { return LC.L(@"You are using a deprected url format, please change it to: {0}", url); }
public static string Description_v2 { get { return LC.L(@"This backend can read and write data to an Amazon S3 compatible server. Allowed formats are: ""s3://bucketname/prefix"""); } }
diff --git a/Duplicati/Library/Backend/S3/packages.config b/Duplicati/Library/Backend/S3/packages.config
index e688f07d4..fc1424bcc 100644
--- a/Duplicati/Library/Backend/S3/packages.config
+++ b/Duplicati/Library/Backend/S3/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="AWSSDK.Core" version="3.1.7.0" targetFramework="net45" />
- <package id="AWSSDK.IdentityManagement" version="3.1.4.4" targetFramework="net45" />
- <package id="AWSSDK.S3" version="3.1.7.2" targetFramework="net45" />
+ <package id="AWSSDK.Core" version="3.3.17.10" targetFramework="net45" />
+ <package id="AWSSDK.IdentityManagement" version="3.3.5" targetFramework="net45" />
+ <package id="AWSSDK.S3" version="3.3.11" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj b/Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj
index 273ecf89a..96c3b453b 100644
--- a/Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj
+++ b/Duplicati/Library/Backend/SSHv2/Duplicati.Library.Backend.SSHv2.csproj
@@ -12,6 +12,7 @@
<SignAssembly>false</SignAssembly>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -39,7 +40,7 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Renci.SshNet">
- <HintPath>..\..\..\..\packages\SSH.NET.2016.0.0-beta2\lib\net40\Renci.SshNet.dll</HintPath>
+ <HintPath>..\..\..\..\packages\SSH.NET.2016.1.0-beta3\lib\net40\Renci.SshNet.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Library/Backend/SSHv2/KeyGenerator.cs b/Duplicati/Library/Backend/SSHv2/KeyGenerator.cs
index 7be5b322a..bc0e1140f 100644
--- a/Duplicati/Library/Backend/SSHv2/KeyGenerator.cs
+++ b/Duplicati/Library/Backend/SSHv2/KeyGenerator.cs
@@ -161,7 +161,7 @@ namespace Duplicati.Library.Backend
if (!int.TryParse(keylen_s, out keylen))
keylen = DEFAULT_KEYLEN;
- if (KEYTYPE_RSA.Equals(keytype, StringComparison.InvariantCultureIgnoreCase))
+ if (KEYTYPE_RSA.Equals(keytype, StringComparison.OrdinalIgnoreCase))
{
var rsa = RSACryptoServiceProvider.Create();
if (keylen > 0)
@@ -180,7 +180,7 @@ namespace Duplicati.Library.Backend
return OutputKey(EncodeDER(privateEntries), EncodePEM(publicEntries), KEY_TEMPLATE_RSA, PUB_KEY_FORMAT_RSA, username);
}
- else if (KEYTYPE_DSA.Equals(keytype, StringComparison.InvariantCultureIgnoreCase))
+ else if (KEYTYPE_DSA.Equals(keytype, StringComparison.OrdinalIgnoreCase))
{
var dsa = DSACryptoServiceProvider.Create();
@@ -204,7 +204,7 @@ namespace Duplicati.Library.Backend
}
else
{
- throw new Exception(string.Format("Unsupported key type: {0}", keytype));
+ throw new UserInformationException(string.Format("Unsupported key type: {0}", keytype));
}
}
public string Key { get { return "ssh-keygen"; } }
diff --git a/Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs b/Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs
index a2a44e249..1131c521f 100644
--- a/Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs
+++ b/Duplicati/Library/Backend/SSHv2/SSHv2Backend.cs
@@ -34,6 +34,8 @@ namespace Duplicati.Library.Backend
public const string SSH_FINGERPRINT_OPTION = "ssh-fingerprint";
public const string SSH_FINGERPRINT_ACCEPT_ANY_OPTION = "ssh-accept-any-fingerprints";
public const string KEYFILE_URI = "sshkey://";
+ public const string SSH_TIMEOUT_OPTION = "ssh-operation-timeout";
+ public const string SSH_KEEPALIVE_OPTION = "ssh-keepalive";
Dictionary<string, string> m_options;
@@ -43,6 +45,8 @@ namespace Duplicati.Library.Backend
private string m_password;
private string m_fingerprint;
private bool m_fingerprintallowall;
+ private TimeSpan m_operationtimeout;
+ private TimeSpan m_keepaliveinterval;
private int m_port = 22;
@@ -69,8 +73,6 @@ namespace Duplicati.Library.Backend
m_username = uri.Username;
if (!string.IsNullOrEmpty(uri.Password))
m_password = uri.Password;
- if (uri.QueryParameters != null && uri.QueryParameters[SSH_FINGERPRINT_OPTION] != null)
- m_fingerprint = uri.QueryParameters[SSH_FINGERPRINT_OPTION];
m_fingerprintallowall = Utility.Utility.ParseBoolOption(options, SSH_FINGERPRINT_ACCEPT_ANY_OPTION);
@@ -86,13 +88,25 @@ namespace Duplicati.Library.Backend
if (uri.Port > 0)
m_port = uri.Port;
+
+ string timeoutstr;
+ options.TryGetValue(SSH_TIMEOUT_OPTION, out timeoutstr);
+
+ if (!string.IsNullOrWhiteSpace(timeoutstr))
+ m_operationtimeout = Library.Utility.Timeparser.ParseTimeSpan(timeoutstr);
+
+ options.TryGetValue(SSH_KEEPALIVE_OPTION, out timeoutstr);
+
+ if (!string.IsNullOrWhiteSpace(timeoutstr))
+ m_keepaliveinterval = Library.Utility.Timeparser.ParseTimeSpan(timeoutstr);
+
}
#region IBackend Members
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
@@ -150,8 +164,11 @@ namespace Duplicati.Library.Backend
new CommandLineArgument("auth-password", CommandLineArgument.ArgumentType.Password, Strings.SSHv2Backend.DescriptionAuthPasswordShort, Strings.SSHv2Backend.DescriptionAuthPasswordLong),
new CommandLineArgument("auth-username", CommandLineArgument.ArgumentType.String, Strings.SSHv2Backend.DescriptionAuthUsernameShort, Strings.SSHv2Backend.DescriptionAuthUsernameLong),
new CommandLineArgument(SSH_FINGERPRINT_OPTION, CommandLineArgument.ArgumentType.String, Strings.SSHv2Backend.DescriptionFingerprintShort, Strings.SSHv2Backend.DescriptionFingerprintLong),
+ new CommandLineArgument(SSH_FINGERPRINT_ACCEPT_ANY_OPTION, CommandLineArgument.ArgumentType.Boolean, Strings.SSHv2Backend.DescriptionAnyFingerprintShort, Strings.SSHv2Backend.DescriptionAnyFingerprintLong),
new CommandLineArgument(SSH_KEYFILE_OPTION, CommandLineArgument.ArgumentType.Path, Strings.SSHv2Backend.DescriptionSshkeyfileShort, Strings.SSHv2Backend.DescriptionSshkeyfileLong),
new CommandLineArgument(SSH_KEYFILE_INLINE, CommandLineArgument.ArgumentType.Password, Strings.SSHv2Backend.DescriptionSshkeyShort, Strings.SSHv2Backend.DescriptionSshkeyLong(KEYFILE_URI)),
+ new CommandLineArgument(SSH_TIMEOUT_OPTION, CommandLineArgument.ArgumentType.Timespan, Strings.SSHv2Backend.DescriptionSshtimeoutShort, Strings.SSHv2Backend.DescriptionSshtimeoutLong, "0"),
+ new CommandLineArgument(SSH_KEEPALIVE_OPTION, CommandLineArgument.ArgumentType.Timespan, Strings.SSHv2Backend.DescriptionSshkeepaliveShort, Strings.SSHv2Backend.DescriptionSshkeepaliveLong, "0"),
});
}
@@ -240,7 +257,7 @@ namespace Duplicati.Library.Backend
if (!string.IsNullOrWhiteSpace(keyfile))
con = new SftpClient(m_server, m_port, m_username, ValidateKeyFile(keyfile, m_password));
else
- con = new SftpClient(m_server, m_port, m_username, m_password);
+ con = new SftpClient(m_server, m_port, m_username, m_password ?? string.Empty);
con.HostKeyReceived += delegate (object sender, HostKeyEventArgs e)
{
@@ -263,6 +280,11 @@ namespace Duplicati.Library.Backend
e.CanTrust = true;
};
+ if (m_operationtimeout.Ticks != 0)
+ con.OperationTimeout = m_operationtimeout;
+ if (m_keepaliveinterval.Ticks != 0)
+ con.KeepAliveInterval = m_keepaliveinterval;
+
con.Connect();
m_con = con;
@@ -291,10 +313,8 @@ namespace Duplicati.Library.Backend
}
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
- var files = new List<IFileEntry>();
-
string path = ".";
CreateConnection();
@@ -302,14 +322,12 @@ namespace Duplicati.Library.Backend
foreach (Renci.SshNet.Sftp.SftpFile ls in m_con.ListDirectory(path))
if (ls.Name.ToString() != "." && ls.Name.ToString() != "..")
- files.Add(new FileEntry(ls.Name.ToString(), ls.Length, ls.LastAccessTime, ls.LastWriteTime) { IsFolder = ls.Attributes.IsDirectory });
-
- return files;
+ yield return new FileEntry(ls.Name.ToString(), ls.Length, ls.LastAccessTime, ls.LastWriteTime) { IsFolder = ls.Attributes.IsDirectory };
}
public static Renci.SshNet.PrivateKeyFile ValidateKeyFile(string filename, string password)
{
- if (filename.StartsWith(KEYFILE_URI, StringComparison.InvariantCultureIgnoreCase))
+ if (filename.StartsWith(KEYFILE_URI, StringComparison.OrdinalIgnoreCase))
{
using (var ms = new System.IO.MemoryStream())
using (var sr = new System.IO.StreamWriter(ms))
@@ -344,4 +362,4 @@ namespace Duplicati.Library.Backend
}
}
}
-}
+}
diff --git a/Duplicati/Library/Backend/SSHv2/Strings.cs b/Duplicati/Library/Backend/SSHv2/Strings.cs
index fb8f74f83..41de44419 100644
--- a/Duplicati/Library/Backend/SSHv2/Strings.cs
+++ b/Duplicati/Library/Backend/SSHv2/Strings.cs
@@ -26,11 +26,17 @@ namespace Duplicati.Library.Backend.Strings {
public static string DescriptionAuthUsernameShort { get { return LC.L(@"Supplies the username used to connect to the server"); } }
public static string DescriptionFingerprintLong { get { return LC.L(@"The server fingerprint used for validation of server identity. Format is eg. ""ssh-rsa 4096 11:22:33:44:55:66:77:88:99:00:11:22:33:44:55:66""."); } }
public static string DescriptionFingerprintShort { get { return LC.L(@"Supplies server fingerprint used for validation of server identity"); } }
+ public static string DescriptionAnyFingerprintLong { get { return LC.L(@"To guard against man-in-the-middle attacks, the server fingerprint is verified on connection. Use this option to disable host-key fingerprint verification. You should only use this option for testing."); } }
+ public static string DescriptionAnyFingerprintShort { get { return LC.L(@"Disables fingerprint validation"); } }
public static string DescriptionSshkeyfileLong { get { return LC.L(@"Points to a valid OpenSSH keyfile. If the file is encrypted, the password supplied is used to decrypt the keyfile. If this option is supplied, the password is not used to authenticate. This option only works when using the managed SSH client."); } }
public static string DescriptionSshkeyfileShort { get { return LC.L(@"Uses a SSH private key to authenticate"); } }
public static string DescriptionSshkeyLong(string urlprefix) { return LC.L(@"An url-encoded SSH private key. The private key must be prefixed with {0}. If the file is encrypted, the password supplied is used to decrypt the keyfile. If this option is supplied, the password is not used to authenticate. This option only works when using the managed SSH client.", urlprefix); }
- public static string DescriptionSshkeyShort { get { return LC.L(@"Uses a SSH private key to authenticate"); } }
- public static string DisplayName { get { return LC.L(@"SFTP (SSH)"); } }
+ public static string DescriptionSshkeyShort { get { return LC.L(@"Uses a SSH private key to authenticate"); } }
+ public static string DescriptionSshtimeoutLong { get { return LC.L(@"Use this option to manage the internal timeout for SSH operations. If this options is set to zero, the operations will not time out"); } }
+ public static string DescriptionSshtimeoutShort { get { return LC.L(@"Sets the operation timeout value"); } }
+ public static string DescriptionSshkeepaliveLong { get { return LC.L(@"This option can be used to enable the keep-alive interval for the SSH connection. If the connection is idle, aggressive firewalls might close the connection. Using keep-alive will keep the connection open in this scenario. If this value is set to zero, the keep-alive is disabled."); } }
+ public static string DescriptionSshkeepaliveShort { get { return LC.L(@"Sets a keepalive value"); } }
+ public static string DisplayName { get { return LC.L(@"SFTP (SSH)"); } }
public static string FolderNotFoundManagedError(string foldername, string message) { return LC.L(@"Unable to set folder to {0}, error message: {1}", foldername, message); }
public static string FingerprintNotMatchManagedError(string fingerprint) { return LC.L(@"Validation of server fingerprint failed. Server returned fingerprint ""{0}"". Cause of this message is either not correct configuration or Man-in-the-middle attack!", fingerprint); }
public static string FingerprintNotSpecifiedManagedError(string fingerprint, string hostkeyoption, string allkeysoptions) { return LC.L(@"Please add --{1}=""{0}"" to trust this host. Optionally you can use --{2} (NOT SECURE) for testing!", fingerprint, hostkeyoption, allkeysoptions); }
diff --git a/Duplicati/Library/Backend/SSHv2/packages.config b/Duplicati/Library/Backend/SSHv2/packages.config
index 68bf4c6ac..5df54958b 100644
--- a/Duplicati/Library/Backend/SSHv2/packages.config
+++ b/Duplicati/Library/Backend/SSHv2/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="SSH.NET" version="2016.0.0-beta2" targetFramework="net45" />
+ <package id="SSH.NET" version="2016.1.0-beta3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/SharePoint/Duplicati.Library.Backend.SharePoint.csproj b/Duplicati/Library/Backend/SharePoint/Duplicati.Library.Backend.SharePoint.csproj
index 929c59a88..bf6530f3f 100644
--- a/Duplicati/Library/Backend/SharePoint/Duplicati.Library.Backend.SharePoint.csproj
+++ b/Duplicati/Library/Backend/SharePoint/Duplicati.Library.Backend.SharePoint.csproj
@@ -1,90 +1,88 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Duplicati.Library.Backend</RootNamespace>
- <AssemblyName>Duplicati.Library.Backend.SharePoint</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup>
- <SignAssembly>true</SignAssembly>
- </PropertyGroup>
- <PropertyGroup>
- <AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Web" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- <Reference Include="Microsoft.SharePoint.Client">
- <HintPath>..\..\..\..\thirdparty\SharePoint.CSOM\Microsoft.SharePoint.Client.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.SharePoint.Client.Runtime">
- <HintPath>..\..\..\..\thirdparty\SharePoint.CSOM\Microsoft.SharePoint.Client.Runtime.dll</HintPath>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="OneDriveForBusinessBackend.cs" />
- <Compile Include="SharePointBackend.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Strings.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="app.config" />
- <None Include="Duplicati.snk" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
- <Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
- <Name>Duplicati.Library.Interface</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Localization\Duplicati.Library.Localization.csproj">
- <Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
- <Name>Duplicati.Library.Localization</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj">
- <Project>{52826615-7964-47FE-B4B3-1B2DBDF605B9}</Project>
- <Name>Duplicati.Library.Modules.Builtin</Name>
- </ProjectReference>
- <ProjectReference Include="..\..\Utility\Duplicati.Library.Utility.csproj">
- <Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
- <Name>Duplicati.Library.Utility</Name>
- </ProjectReference>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Duplicati.Library.Backend</RootNamespace>
+ <AssemblyName>Duplicati.Library.Backend.SharePoint</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ <Reference Include="Microsoft.SharePoint.Client">
+ <HintPath>..\..\..\..\thirdparty\SharePoint.CSOM\Microsoft.SharePoint.Client.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.SharePoint.Client.Runtime">
+ <HintPath>..\..\..\..\thirdparty\SharePoint.CSOM\Microsoft.SharePoint.Client.Runtime.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="OneDriveForBusinessBackend.cs" />
+ <Compile Include="SharePointBackend.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Strings.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="Duplicati.snk" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
+ <Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
+ <Name>Duplicati.Library.Interface</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Localization\Duplicati.Library.Localization.csproj">
+ <Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
+ <Name>Duplicati.Library.Localization</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Modules\Builtin\Duplicati.Library.Modules.Builtin.csproj">
+ <Project>{52826615-7964-47FE-B4B3-1B2DBDF605B9}</Project>
+ <Name>Duplicati.Library.Modules.Builtin</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Utility\Duplicati.Library.Utility.csproj">
+ <Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
+ <Name>Duplicati.Library.Utility</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
</Project> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/SharePoint/SharePointBackend.cs b/Duplicati/Library/Backend/SharePoint/SharePointBackend.cs
index 962aae9b4..9d2bd0e77 100644
--- a/Duplicati/Library/Backend/SharePoint/SharePointBackend.cs
+++ b/Duplicati/Library/Backend/SharePoint/SharePointBackend.cs
@@ -303,7 +303,7 @@ namespace Duplicati.Library.Backend
// Now go through path and see where we land a success.
string[] pathParts = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
// first we look for the doc library
- int docLibrary = Array.FindIndex(pathParts, p => StringComparer.InvariantCultureIgnoreCase.Equals(p, "documents"));
+ int docLibrary = Array.FindIndex(pathParts, p => StringComparer.OrdinalIgnoreCase.Equals(p, "documents"));
if (docLibrary >= 0)
{
string testUrl = new Utility.Uri(orgUrl.Scheme, orgUrl.Host,
@@ -392,41 +392,51 @@ namespace Duplicati.Library.Backend
SP.ClientContext ctx = getSpClientContext(true);
testContextForWeb(ctx, true);
}
-
- public List<IFileEntry> List() { return doList(false); }
- private List<IFileEntry> doList(bool useNewContext)
+
+ public IEnumerable<IFileEntry> List() { return doList(false); }
+ private IEnumerable<IFileEntry> doList(bool useNewContext)
{
SP.ClientContext ctx = getSpClientContext(useNewContext);
+ SP.Folder remoteFolder = null;
+ bool retry = false;
try
{
- SP.Folder remoteFolder = ctx.Web.GetFolderByServerRelativeUrl(m_serverRelPath);
+ remoteFolder = ctx.Web.GetFolderByServerRelativeUrl(m_serverRelPath);
ctx.Load(remoteFolder, f => f.Exists);
ctx.Load(remoteFolder, f => f.Files, f => f.Folders);
wrappedExecuteQueryOnConext(ctx, m_serverRelPath, true);
if (!remoteFolder.Exists)
throw new Interface.FolderMissingException(Strings.SharePoint.MissingElementError(m_serverRelPath, m_spWebUrl));
+ }
+ catch (ServerException) { throw; /* rethrow if Server answered */ }
+ catch (Interface.FileMissingException) { throw; }
+ catch (Interface.FolderMissingException) { throw; }
+ catch { if (!useNewContext) /* retry */ retry = true; else throw; }
- List<IFileEntry> files = new List<IFileEntry>(remoteFolder.Folders.Count + remoteFolder.Files.Count);
+ if (retry)
+ {
+ // An exception was caught, and List() should be retried.
+ foreach (IFileEntry file in doList(true))
+ {
+ yield return file;
+ }
+ }
+ else
+ {
foreach (var f in remoteFolder.Folders.Where(ff => ff.Exists))
{
FileEntry fe = new FileEntry(f.Name, -1, f.TimeLastModified, f.TimeLastModified); // f.TimeCreated
fe.IsFolder = true;
- files.Add(fe);
+ yield return fe;
}
foreach (var f in remoteFolder.Files.Where(ff => ff.Exists))
{
FileEntry fe = new FileEntry(f.Name, f.Length, f.TimeLastModified, f.TimeLastModified); // f.TimeCreated
fe.IsFolder = false;
- files.Add(fe);
+ yield return fe;
}
- return files;
}
- catch (ServerException) { throw; /* rethrow if Server answered */ }
- catch (Interface.FileMissingException) { throw; }
- catch (Interface.FolderMissingException) { throw; }
- catch { if (!useNewContext) /* retry */ return doList(true); else throw; }
- finally { }
}
public void Get(string remotename, string filename)
diff --git a/Duplicati/Library/Backend/SharePoint/Strings.cs b/Duplicati/Library/Backend/SharePoint/Strings.cs
index 09df57e73..ae5eb49e2 100644
--- a/Duplicati/Library/Backend/SharePoint/Strings.cs
+++ b/Duplicati/Library/Backend/SharePoint/Strings.cs
@@ -1,36 +1,36 @@
-using Duplicati.Library.Localization.Short;
-namespace Duplicati.Library.Backend.Strings
-{
- internal static class SharePoint
- {
- public static string DisplayName { get { return LC.L(@"Microsoft SharePoint"); } }
- public static string Description { get { return LC.L(@"Supports connections to a SharePoint server (including OneDrive for Business). Allowed formats are ""mssp://tennant.sharepoint.com/PathToWeb//BaseDocLibrary/subfolder"" or ""mssp://username:password@tennant.sharepoint.com/PathToWeb//BaseDocLibrary/subfolder"". Use a double slash '//' in the path to denote the web from the documents library."); } }
- public static string DescriptionAuthPasswordLong { get { return LC.L(@"The password used to connect to the server. This may also be supplied as the environment variable ""AUTH_PASSWORD""."); } }
- public static string DescriptionAuthPasswordShort { get { return LC.L(@"Supplies the password used to connect to the server"); } }
- public static string DescriptionAuthUsernameLong { get { return LC.L(@"The username used to connect to the server. This may also be supplied as the environment variable ""AUTH_USERNAME""."); } }
- public static string DescriptionAuthUsernameShort { get { return LC.L(@"Supplies the username used to connect to the server"); } }
- public static string DescriptionIntegratedAuthenticationLong { get { return LC.L(@"If the server and client both supports integrated authentication, this option enables that authentication method. This is likely only available with windows servers and clients."); } }
- public static string DescriptionIntegratedAuthenticationShort { get { return LC.L(@"Use windows integrated authentication to connect to the server"); } }
- public static string DescriptionUseRecyclerLong { get { return LC.L(@"Use this option to have files moved to the recycle bin folder instead of removing them permanently when compacting or deleting backups."); } }
- public static string DescriptionUseRecyclerShort { get { return LC.L(@"Move deleted files to the recycle bin"); } }
-
- public static string DescriptionBinaryDirectModeLong { get { return LC.L(@"Use this option to upload files to SharePoint as a whole with BinaryDirect mode. This is the most efficient way of uploading, but can cause non-recoverable timouts under certain conditions. Use this option only with very fast and stable internet connections."); } }
- public static string DescriptionBinaryDirectModeShort { get { return LC.L(@"Upload files using binary direct mode."); } }
-
- public static string DescriptionWebTimeoutLong { get { return LC.L(@"Use this option to specify a custom value for timeouts of web operation when communicating with SharePoint Server. Recommended value is 180s."); } }
- public static string DescriptionWebTimeoutShort { get { return LC.L(@"Set timeout for SharePoint web operations."); } }
-
- public static string DescriptionChunkSizeLong { get { return LC.L(@"Use this option to specify the size of each chunk when uploading to SharePoint Server. Recommended value is 4MB."); } }
- public static string DescriptionChunkSizeShort { get { return LC.L(@"Set blocksize for chunked uploads to SharePoint."); } }
-
- public static string MissingElementError(string serverrelpath, string hosturl) { return LC.L(@"Element with path '{0}' not found on host '{1}'.", serverrelpath, hosturl); }
- public static string NoSharePointWebFoundError(string url) { return LC.L(@"No SharePoint web could be logged in to at path '{0}'. Maybe wrong credentials. Or try using '//' in path to separate web from folder path.", url); }
- public static string WebTitleReadFailedError { get { return LC.L(@"Everything seemed alright, but then web title could not be read to test connection. Something's wrong."); } }
- }
-
- internal static class OneDriveForBusiness
- {
- public static string DisplayName { get { return LC.L(@"Microsoft OneDrive for Business"); } }
- public static string Description { get { return LC.L(@"Supports connections to Microsoft OneDrive for Business. Allowed formats are ""od4b://tennant.sharepoint.com/personal/username_domain/Documents/subfolder"" or ""od4b://username:password@tennant.sharepoint.com/personal/username_domain/Documents/folder"". You can use a double slash '//' in the path to denote the base path from the documents folder."); } }
- }
-}
+using Duplicati.Library.Localization.Short;
+namespace Duplicati.Library.Backend.Strings
+{
+ internal static class SharePoint
+ {
+ public static string DisplayName { get { return LC.L(@"Microsoft SharePoint"); } }
+ public static string Description { get { return LC.L(@"Supports connections to a SharePoint server (including OneDrive for Business). Allowed formats are ""mssp://tennant.sharepoint.com/PathToWeb//BaseDocLibrary/subfolder"" or ""mssp://username:password@tennant.sharepoint.com/PathToWeb//BaseDocLibrary/subfolder"". Use a double slash '//' in the path to denote the web from the documents library."); } }
+ public static string DescriptionAuthPasswordLong { get { return LC.L(@"The password used to connect to the server. This may also be supplied as the environment variable ""AUTH_PASSWORD""."); } }
+ public static string DescriptionAuthPasswordShort { get { return LC.L(@"Supplies the password used to connect to the server"); } }
+ public static string DescriptionAuthUsernameLong { get { return LC.L(@"The username used to connect to the server. This may also be supplied as the environment variable ""AUTH_USERNAME""."); } }
+ public static string DescriptionAuthUsernameShort { get { return LC.L(@"Supplies the username used to connect to the server"); } }
+ public static string DescriptionIntegratedAuthenticationLong { get { return LC.L(@"If the server and client both supports integrated authentication, this option enables that authentication method. This is likely only available with windows servers and clients."); } }
+ public static string DescriptionIntegratedAuthenticationShort { get { return LC.L(@"Use windows integrated authentication to connect to the server"); } }
+ public static string DescriptionUseRecyclerLong { get { return LC.L(@"Use this option to have files moved to the recycle bin folder instead of removing them permanently when compacting or deleting backups."); } }
+ public static string DescriptionUseRecyclerShort { get { return LC.L(@"Move deleted files to the recycle bin"); } }
+
+ public static string DescriptionBinaryDirectModeLong { get { return LC.L(@"Use this option to upload files to SharePoint as a whole with BinaryDirect mode. This is the most efficient way of uploading, but can cause non-recoverable timeouts under certain conditions. Use this option only with very fast and stable internet connections."); } }
+ public static string DescriptionBinaryDirectModeShort { get { return LC.L(@"Upload files using binary direct mode."); } }
+
+ public static string DescriptionWebTimeoutLong { get { return LC.L(@"Use this option to specify a custom value for timeouts of web operation when communicating with SharePoint Server. Recommended value is 180s."); } }
+ public static string DescriptionWebTimeoutShort { get { return LC.L(@"Set timeout for SharePoint web operations."); } }
+
+ public static string DescriptionChunkSizeLong { get { return LC.L(@"Use this option to specify the size of each chunk when uploading to SharePoint Server. Recommended value is 4MB."); } }
+ public static string DescriptionChunkSizeShort { get { return LC.L(@"Set block size for chunked uploads to SharePoint."); } }
+
+ public static string MissingElementError(string serverrelpath, string hosturl) { return LC.L(@"Element with path '{0}' not found on host '{1}'.", serverrelpath, hosturl); }
+ public static string NoSharePointWebFoundError(string url) { return LC.L(@"No SharePoint web could be logged in to at path '{0}'. Maybe wrong credentials. Or try using '//' in path to separate web from folder path.", url); }
+ public static string WebTitleReadFailedError { get { return LC.L(@"Everything seemed alright, but then web title could not be read to test connection. Something's wrong."); } }
+ }
+
+ internal static class OneDriveForBusiness
+ {
+ public static string DisplayName { get { return LC.L(@"Microsoft OneDrive for Business"); } }
+ public static string Description { get { return LC.L(@"Supports connections to Microsoft OneDrive for Business. Allowed formats are ""od4b://tennant.sharepoint.com/personal/username_domain/Documents/subfolder"" or ""od4b://username:password@tennant.sharepoint.com/personal/username_domain/Documents/folder"". You can use a double slash '//' in the path to denote the base path from the documents folder."); } }
+ }
+}
diff --git a/Duplicati/Library/Backend/Sia/Duplicati.Library.Backend.Sia.csproj b/Duplicati/Library/Backend/Sia/Duplicati.Library.Backend.Sia.csproj
new file mode 100644
index 000000000..fefb04749
--- /dev/null
+++ b/Duplicati/Library/Backend/Sia/Duplicati.Library.Backend.Sia.csproj
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{32A74526-3E5F-413A-8CB4-1EFDAD4C8B91}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <RootNamespace>Duplicati.Library.Backend.Sia</RootNamespace>
+ <AssemblyName>Duplicati.Library.Backend.Sia</AssemblyName>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug</OutputPath>
+ <DefineConstants>DEBUG;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>full</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="Newtonsoft.Json">
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Sia.cs" />
+ <Compile Include="Strings.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ItemGroup>
+ <ProjectReference Include="..\..\Utility\Duplicati.Library.Utility.csproj">
+ <Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
+ <Name>Duplicati.Library.Utility</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\OAuthHelper\Duplicati.Library.OAuthHelper.csproj">
+ <Project>{D4C37C33-5E73-4B56-B2C3-DC4A6BAA36BB}</Project>
+ <Name>Duplicati.Library.OAuthHelper</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Localization\Duplicati.Library.Localization.csproj">
+ <Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
+ <Name>Duplicati.Library.Localization</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
+ <Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
+ <Name>Duplicati.Library.Interface</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/Sia/Duplicati.snk b/Duplicati/Library/Backend/Sia/Duplicati.snk
new file mode 100644
index 000000000..e0c1e2dd8
--- /dev/null
+++ b/Duplicati/Library/Backend/Sia/Duplicati.snk
Binary files differ
diff --git a/Duplicati/Library/Backend/Sia/Properties/AssemblyInfo.cs b/Duplicati/Library/Backend/Sia/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..5c49552a7
--- /dev/null
+++ b/Duplicati/Library/Backend/Sia/Properties/AssemblyInfo.cs
@@ -0,0 +1,43 @@
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("Duplicati.Library.Backend.Sia")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("2.0.0.7")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/Duplicati/Library/Backend/Sia/Sia.cs b/Duplicati/Library/Backend/Sia/Sia.cs
new file mode 100644
index 000000000..636c2dc63
--- /dev/null
+++ b/Duplicati/Library/Backend/Sia/Sia.cs
@@ -0,0 +1,458 @@
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.Net;
+
+using Duplicati.Library.Interface;
+using Duplicati.Library.Utility;
+using Newtonsoft.Json;
+
+namespace Duplicati.Library.Backend.Sia
+{
+ public class Sia : IBackend
+ {
+ private const string SIA_PASSWORD = "sia-password";
+ private const string SIA_TARGETPATH = "sia-targetpath";
+ private const string SIA_REDUNDANCY = "sia-redundancy";
+
+ private string m_apihost;
+ private int m_apiport;
+ private string m_targetpath;
+ private float m_redundancy;
+ private System.Net.NetworkCredential m_user;
+
+ public Sia() {
+
+ }
+
+ public Sia(string url, Dictionary<string, string> options)
+ {
+ var uri = new Utility.Uri(url);
+
+ m_apihost = uri.Host;
+ m_apiport = uri.Port;
+ m_targetpath = uri.Path;
+
+ m_redundancy = 1.5F;
+ if (options.ContainsKey(SIA_REDUNDANCY))
+ m_redundancy = float.Parse(options[SIA_REDUNDANCY]);
+
+ if (m_apiport <= 0)
+ m_apiport = 9980;
+
+ if (options.ContainsKey(SIA_TARGETPATH))
+ {
+ m_targetpath = options[SIA_TARGETPATH];
+ }
+ while(m_targetpath.Contains("//"))
+ m_targetpath = m_targetpath.Replace("//","/");
+ while (m_targetpath.StartsWith("/"))
+ m_targetpath = m_targetpath.Substring(1);
+ while (m_targetpath.EndsWith("/"))
+ m_targetpath = m_targetpath.Remove(m_targetpath.Length - 1);
+
+ if (m_targetpath.Length == 0)
+ m_targetpath = "backup";
+
+ m_user = new System.Net.NetworkCredential();
+ if (options.ContainsKey(SIA_PASSWORD))
+ {
+ m_user.Password = options[SIA_PASSWORD];
+ }
+ }
+
+ private System.Net.HttpWebRequest CreateRequest(string endpoint)
+ {
+ string baseurl = "http://" + m_apihost + ":" + m_apiport;
+ System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(baseurl + endpoint);
+
+ if (!string.IsNullOrEmpty(m_user.Password))
+ {
+ req.Credentials = m_user;
+ req.PreAuthenticate = true;
+ }
+
+ req.KeepAlive = false;
+ req.UserAgent = string.Format("Sia-Agent (Duplicati SIA client {0})", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
+
+ return req;
+ }
+
+ private string getResponseBodyOnError(string context, System.Net.WebException wex)
+ {
+ string body = "";
+ System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)wex.Response;
+ using (System.IO.Stream data = response.GetResponseStream())
+ using (var reader = new System.IO.StreamReader(data))
+ {
+ body = reader.ReadToEnd();
+ }
+ return string.Format("{0} failed, response: {1}", context, body);
+ }
+
+ public class SiaFile
+ {
+ [JsonProperty("siapath")]
+ public string Siapath { get; set; }
+ [JsonProperty("available")]
+ public bool Available { get; set; }
+ [JsonProperty("filesize")]
+ public long Filesize { get; set; }
+ [JsonProperty("uploadprogress")]
+ public float Uploadprogress { get; set; }
+ [JsonProperty("redundancy")]
+ public float Redundancy { get; set; }
+ }
+
+ public class SiaFileList
+ {
+ [JsonProperty("files")]
+ public SiaFile[] Files { get; set; }
+ }
+
+ public class SiaDownloadFile
+ {
+ [JsonProperty("siapath")]
+ public string Siapath { get; set; }
+ [JsonProperty("destination")]
+ public string Destination { get; set; }
+ [JsonProperty("filesize")]
+ public long Filesize { get; set; }
+ [JsonProperty("received")]
+ public long Received { get; set; }
+ [JsonProperty("starttime")]
+ public string Starttime { get; set; }
+ [JsonProperty("error")]
+ public string Error { get; set; }
+ }
+
+ public class SiaDownloadList
+ {
+ [JsonProperty("downloads")]
+ public SiaDownloadFile[] Files { get; set; }
+ }
+
+ private SiaFileList GetFiles()
+ {
+ var fl = new SiaFileList();
+ string endpoint = string.Format("/renter/files");
+
+ try
+ {
+ System.Net.HttpWebRequest req = CreateRequest(endpoint);
+ req.Method = System.Net.WebRequestMethods.Http.Get;
+
+ Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
+
+ using (System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ {
+ int code = (int)resp.StatusCode;
+ if (code < 200 || code >= 300)
+ throw new System.Net.WebException(resp.StatusDescription, null, System.Net.WebExceptionStatus.ProtocolError, resp);
+
+ var serializer = new JsonSerializer();
+
+ using (var rs = areq.GetResponseStream())
+ using (var sr = new System.IO.StreamReader(rs))
+ using (var jr = new Newtonsoft.Json.JsonTextReader(sr))
+ {
+ fl = (SiaFileList)serializer.Deserialize(jr, typeof(SiaFileList));
+ }
+ }
+ }
+ catch (System.Net.WebException wex)
+ {
+ throw new Exception(getResponseBodyOnError(endpoint, wex));
+ }
+ return fl;
+ }
+
+ private bool IsUploadComplete(string siafilename)
+ {
+ SiaFileList fl = GetFiles();
+ if (fl.Files == null)
+ return false;
+
+ foreach (var f in fl.Files)
+ {
+ if (f.Siapath == siafilename)
+ {
+ if (f.Available == true && f.Redundancy >= m_redundancy /* && f.Uploadprogress >= 100 */ )
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private SiaDownloadList GetDownloads()
+ {
+ var fl = new SiaDownloadList();
+ string endpoint = string.Format("/renter/downloads");
+
+ try
+ {
+ System.Net.HttpWebRequest req = CreateRequest(endpoint);
+ req.Method = System.Net.WebRequestMethods.Http.Get;
+
+ Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
+
+ using (System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ {
+ int code = (int)resp.StatusCode;
+ if (code < 200 || code >= 300)
+ throw new System.Net.WebException(resp.StatusDescription, null, System.Net.WebExceptionStatus.ProtocolError, resp);
+
+ var serializer = new JsonSerializer();
+
+ using (var rs = areq.GetResponseStream())
+ using (var sr = new System.IO.StreamReader(rs))
+ using (var jr = new Newtonsoft.Json.JsonTextReader(sr))
+ {
+ fl = (SiaDownloadList)serializer.Deserialize(jr, typeof(SiaDownloadList));
+ }
+ }
+ }
+ catch (System.Net.WebException wex)
+ {
+ throw new Exception(getResponseBodyOnError(endpoint, wex));
+ }
+ return fl;
+ }
+
+ private bool IsDownloadComplete(string siafilename, string localname)
+ {
+ SiaDownloadList fl = GetDownloads();
+ if (fl.Files == null)
+ return false;
+
+ foreach (var f in fl.Files)
+ {
+ if (f.Siapath == siafilename)
+ {
+ if (f.Error != "")
+ {
+ throw new Exception("failed to download " + siafilename + "err: " + f.Error);
+ }
+ if (f.Filesize == f.Received)
+ {
+ try
+ {
+ // Sia seems to keep the file open/locked for a while, make sure we can open it
+ System.IO.FileStream fs = new System.IO.FileStream(localname, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
+ fs.Close();
+ }
+ catch (System.IO.IOException)
+ {
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ #region IBackend Members
+
+ public void Test()
+ {
+ this.TestList();
+ }
+
+ public void CreateFolder()
+ {
+ // Dummy method, Sia doesn't have folders
+ }
+
+ public string DisplayName
+ {
+ get { return Strings.Sia.DisplayName; }
+ }
+
+ public string ProtocolKey
+ {
+ get { return "sia"; }
+ }
+
+ public IEnumerable<IFileEntry> List()
+ {
+ SiaFileList fl;
+ try
+ {
+ fl = GetFiles();
+ }
+ catch (System.Net.WebException wex)
+ {
+ throw new Exception("failed to call /renter/files "+wex.Message);
+ }
+
+ if (fl.Files != null)
+ {
+ foreach (var f in fl.Files)
+ {
+ // Sia returns a complete file list, but we're only interested in files that are
+ // in our target path
+ if (f.Siapath.StartsWith(m_targetpath))
+ {
+ FileEntry fe = new FileEntry(f.Siapath.Substring(m_targetpath.Length + 1));
+ fe.Size = f.Filesize;
+ fe.IsFolder = false;
+ yield return fe;
+ }
+ }
+ }
+ }
+
+ public void Put(string remotename, string filename)
+ {
+ string endpoint ="";
+ string siafile = m_targetpath + "/" + remotename;
+
+ try {
+ endpoint = string.Format("/renter/upload/{0}/{1}?source={2}",
+ m_targetpath,
+ Library.Utility.Uri.UrlEncode(remotename).Replace("+", "%20"),
+ Library.Utility.Uri.UrlEncode(filename).Replace("+", "%20")
+ );
+
+ System.Net.HttpWebRequest req = CreateRequest(endpoint);
+ req.Method = System.Net.WebRequestMethods.Http.Post;
+
+ Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
+
+ using (System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ {
+ int code = (int)resp.StatusCode;
+ if (code < 200 || code >= 300)
+ throw new System.Net.WebException(resp.StatusDescription, null, System.Net.WebExceptionStatus.ProtocolError, resp);
+
+ while (! IsUploadComplete( siafile ))
+ {
+ System.Threading.Thread.Sleep(5000);
+ }
+ }
+ }
+ catch (System.Net.WebException wex)
+ {
+ throw new Exception(getResponseBodyOnError(endpoint, wex));
+ }
+ }
+
+ public void Get(string remotename, string localname)
+ {
+ string endpoint = "";
+ string siafile = m_targetpath + "/" + remotename;
+ string tmpfilename = localname + ".tmp";
+
+ try
+ {
+ endpoint = string.Format("/renter/download/{0}/{1}?destination={2}",
+ m_targetpath,
+ Library.Utility.Uri.UrlEncode(remotename).Replace("+", "%20"),
+ Library.Utility.Uri.UrlEncode(tmpfilename).Replace("+", "%20")
+ );
+ System.Net.HttpWebRequest req = CreateRequest(endpoint);
+ req.Method = System.Net.WebRequestMethods.Http.Get;
+
+ Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
+
+ using (System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ {
+ int code = (int)resp.StatusCode;
+ if (code < 200 || code >= 300)
+ throw new System.Net.WebException(resp.StatusDescription, null, System.Net.WebExceptionStatus.ProtocolError, resp);
+
+ while (!IsDownloadComplete(siafile, localname))
+ {
+ System.Threading.Thread.Sleep(5000);
+ }
+
+ System.IO.File.Copy(tmpfilename, localname, true);
+ try
+ {
+ System.IO.File.Delete(tmpfilename);
+ } catch (Exception)
+ {
+
+ }
+ }
+ }
+ catch (System.Net.WebException wex)
+ {
+ if (wex.Response is System.Net.HttpWebResponse && ((System.Net.HttpWebResponse)wex.Response).StatusCode == System.Net.HttpStatusCode.NotFound)
+ throw new FileMissingException(wex);
+ else
+ throw new Exception(getResponseBodyOnError(endpoint, wex));
+ }
+ }
+
+ public void Delete(string remotename)
+ {
+ string endpoint = "";
+
+ try
+ {
+ endpoint = string.Format("/renter/delete/{0}/{1}",
+ m_targetpath,
+ Library.Utility.Uri.UrlEncode(remotename).Replace("+", "%20")
+ );
+ System.Net.HttpWebRequest req = CreateRequest(endpoint);
+ req.Method = System.Net.WebRequestMethods.Http.Post;
+
+ Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
+
+ using (System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ {
+ int code = (int)resp.StatusCode;
+ if (code < 200 || code >= 300)
+ throw new System.Net.WebException(resp.StatusDescription, null, System.Net.WebExceptionStatus.ProtocolError, resp);
+ }
+ }
+ catch (System.Net.WebException wex)
+ {
+ if (wex.Response is System.Net.HttpWebResponse && ((System.Net.HttpWebResponse)wex.Response).StatusCode == System.Net.HttpStatusCode.NotFound)
+ throw new FileMissingException(wex);
+ else
+ throw new Exception(getResponseBodyOnError(endpoint, wex));
+ }
+ }
+
+
+ public IList<ICommandLineArgument> SupportedCommands
+ {
+ get
+ {
+ return new List<ICommandLineArgument>(new ICommandLineArgument[] {
+ new CommandLineArgument(SIA_TARGETPATH, CommandLineArgument.ArgumentType.String, Strings.Sia.SiaPathDescriptionShort, Strings.Sia.SiaPathDescriptionLong, "/backup"),
+ new CommandLineArgument(SIA_PASSWORD, CommandLineArgument.ArgumentType.Password, Strings.Sia.SiaPasswordShort, Strings.Sia.SiaPasswordLong, null),
+ new CommandLineArgument(SIA_REDUNDANCY, CommandLineArgument.ArgumentType.String, Strings.Sia.SiaRedundancyDescriptionShort, Strings.Sia.SiaRedundancyDescriptionLong, "1.5"),
+ });
+ }
+ }
+
+ public string Description
+ {
+ get
+ {
+ return Strings.Sia.Description;
+ }
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+
+ }
+
+ #endregion
+
+
+ }
+
+
+}
diff --git a/Duplicati/Library/Backend/Sia/Strings.cs b/Duplicati/Library/Backend/Sia/Strings.cs
new file mode 100644
index 000000000..1786d39b0
--- /dev/null
+++ b/Duplicati/Library/Backend/Sia/Strings.cs
@@ -0,0 +1,17 @@
+using Duplicati.Library.Localization.Short;
+namespace Duplicati.Library.Backend.Strings
+{
+ internal static class Sia
+ {
+ public static string DisplayName { get { return LC.L(@"Sia Decentralized Cloud"); } }
+ public static string Description { get { return LC.L(@"This backend can read and write data to Sia."); } }
+ public static string SiaHostDescriptionShort { get { return LC.L(@"Sia address"); } }
+ public static string SiaHostDescriptionLong { get { return LC.L(@"Sia address, ie 127.0.0.1:9980"); } }
+ public static string SiaPathDescriptionShort { get { return LC.L(@"Backup path"); } }
+ public static string SiaPathDescriptionLong { get { return LC.L(@"Target path, ie /backup"); } }
+ public static string SiaPasswordShort { get { return LC.L(@"Sia password"); } }
+ public static string SiaPasswordLong { get { return LC.L(@"Sia password"); } }
+ public static string SiaRedundancyDescriptionShort { get { return LC.L(@"3"); } }
+ public static string SiaRedundancyDescriptionLong { get { return LC.L(@"Minimum value is 3."); } }
+ }
+}
diff --git a/Duplicati/Library/Backend/Sia/packages.config b/Duplicati/Library/Backend/Sia/packages.config
new file mode 100644
index 000000000..ee51c2373
--- /dev/null
+++ b/Duplicati/Library/Backend/Sia/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/TahoeLAFS/Duplicati.Library.Backend.TahoeLAFS.csproj b/Duplicati/Library/Backend/TahoeLAFS/Duplicati.Library.Backend.TahoeLAFS.csproj
index 53534ec74..ff93fd131 100644
--- a/Duplicati/Library/Backend/TahoeLAFS/Duplicati.Library.Backend.TahoeLAFS.csproj
+++ b/Duplicati/Library/Backend/TahoeLAFS/Duplicati.Library.Backend.TahoeLAFS.csproj
@@ -14,9 +14,9 @@
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
- <SignAssembly>true</SignAssembly>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -41,31 +41,12 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
- <EmbeddedResource Include="Properties\Resources.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>Resources.Designer.cs</LastGenOutput>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- <Compile Include="Properties\Resources.Designer.cs">
- <AutoGen>True</AutoGen>
- <DependentUpon>Resources.resx</DependentUpon>
- <DesignTime>True</DesignTime>
- </Compile>
<None Include="Duplicati.snk" />
- <None Include="Properties\Settings.settings">
- <Generator>SettingsSingleFileGenerator</Generator>
- <LastGenOutput>Settings.Designer.cs</LastGenOutput>
- </None>
- <Compile Include="Properties\Settings.Designer.cs">
- <AutoGen>True</AutoGen>
- <DependentUpon>Settings.settings</DependentUpon>
- <DesignTimeSharedInput>True</DesignTimeSharedInput>
- </Compile>
<Compile Include="TahoeBackend.cs" />
<Compile Include="Strings.cs" />
<None Include="packages.config" />
diff --git a/Duplicati/Library/Backend/TahoeLAFS/Properties/Resources.Designer.cs b/Duplicati/Library/Backend/TahoeLAFS/Properties/Resources.Designer.cs
deleted file mode 100644
index 549506e94..000000000
--- a/Duplicati/Library/Backend/TahoeLAFS/Properties/Resources.Designer.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.1
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace Duplicati.Library.Backend.Properties {
- using System;
-
-
- /// <summary>
- /// A strongly-typed resource class, for looking up localized strings, etc.
- /// </summary>
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- /// <summary>
- /// Returns the cached ResourceManager instance used by this class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Duplicati.Library.Backend.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- /// <summary>
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- /// </summary>
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
- }
-}
diff --git a/Duplicati/Library/Backend/TahoeLAFS/Properties/Resources.resx b/Duplicati/Library/Backend/TahoeLAFS/Properties/Resources.resx
deleted file mode 100644
index ffecec851..000000000
--- a/Duplicati/Library/Backend/TahoeLAFS/Properties/Resources.resx
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">2.0</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- <value>[base64 mime encoded serialized .NET Framework object]</value>
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
- <comment>This is a comment</comment>
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
-</root> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/TahoeLAFS/Properties/Settings.Designer.cs b/Duplicati/Library/Backend/TahoeLAFS/Properties/Settings.Designer.cs
deleted file mode 100644
index 24bcb016c..000000000
--- a/Duplicati/Library/Backend/TahoeLAFS/Properties/Settings.Designer.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.1
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace Duplicati.Library.Backend.Properties {
-
-
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
- internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
-
- private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
- public static Settings Default {
- get {
- return defaultInstance;
- }
- }
- }
-}
diff --git a/Duplicati/Library/Backend/TahoeLAFS/Properties/Settings.settings b/Duplicati/Library/Backend/TahoeLAFS/Properties/Settings.settings
deleted file mode 100644
index abf36c5d3..000000000
--- a/Duplicati/Library/Backend/TahoeLAFS/Properties/Settings.settings
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
- <Profiles>
- <Profile Name="(Default)" />
- </Profiles>
- <Settings />
-</SettingsFile>
diff --git a/Duplicati/Library/Backend/TahoeLAFS/Strings.cs b/Duplicati/Library/Backend/TahoeLAFS/Strings.cs
index 42fc191ec..91c12f96f 100644
--- a/Duplicati/Library/Backend/TahoeLAFS/Strings.cs
+++ b/Duplicati/Library/Backend/TahoeLAFS/Strings.cs
@@ -6,6 +6,6 @@ namespace Duplicati.Library.Backend.Strings {
public static string DescriptionUseSSLShort { get { return LC.L(@"Instructs Duplicati to use an SSL (https) connection"); } }
public static string Displayname { get { return LC.L(@"Tahoe-LAFS"); } }
public static string MissingFolderError(string foldername, string message) { return LC.L(@"The folder {0} was not found, message: {1}", foldername, message); }
- public static string UnrecognizedUriError { get { return LC.L(@"Unsupported URL format, must start with ""/uri/URI:DIR2:"""); } }
+ public static string UnrecognizedUriError { get { return LC.L(@"Unsupported URL format, must start with ""uri/URI:DIR2:"""); } }
}
}
diff --git a/Duplicati/Library/Backend/TahoeLAFS/TahoeBackend.cs b/Duplicati/Library/Backend/TahoeLAFS/TahoeBackend.cs
index 7edf747fb..2c78d77a9 100644
--- a/Duplicati/Library/Backend/TahoeLAFS/TahoeBackend.cs
+++ b/Duplicati/Library/Backend/TahoeLAFS/TahoeBackend.cs
@@ -100,7 +100,7 @@ namespace Duplicati.Library.Backend
u.RequireHost();
if (!u.Path.StartsWith("uri/URI:DIR2:") && !u.Path.StartsWith("uri/URI%3ADIR2%3A"))
- throw new Exception(Strings.TahoeBackend.UnrecognizedUriError);
+ throw new UserInformationException(Strings.TahoeBackend.UnrecognizedUriError);
m_useSSL = Utility.Utility.ParseBoolOption(options, "use-ssl");
@@ -123,7 +123,7 @@ namespace Duplicati.Library.Backend
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
@@ -145,7 +145,7 @@ namespace Duplicati.Library.Backend
get { return "tahoe"; }
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
TahoeEl data;
@@ -184,7 +184,6 @@ namespace Duplicati.Library.Backend
if (data == null || data.node == null || data.nodetype != "dirnode")
throw new Exception("Invalid folder listing response");
- var files = new List<IFileEntry>();
foreach (var e in data.node.children)
{
if (e.Value == null || e.Value.node == null)
@@ -205,10 +204,8 @@ namespace Duplicati.Library.Backend
if (isFile)
fe.Size = e.Value.node.size;
- files.Add(fe);
+ yield return fe;
}
-
- return files;
}
public void Put(string remotename, string filename)
diff --git a/Duplicati/Library/Backend/TahoeLAFS/packages.config b/Duplicati/Library/Backend/TahoeLAFS/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Backend/TahoeLAFS/packages.config
+++ b/Duplicati/Library/Backend/TahoeLAFS/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/WEBDAV/Duplicati.Library.Backend.WEBDAV.csproj b/Duplicati/Library/Backend/WEBDAV/Duplicati.Library.Backend.WEBDAV.csproj
index 5d1e519e7..287a66ce6 100644
--- a/Duplicati/Library/Backend/WEBDAV/Duplicati.Library.Backend.WEBDAV.csproj
+++ b/Duplicati/Library/Backend/WEBDAV/Duplicati.Library.Backend.WEBDAV.csproj
@@ -15,8 +15,8 @@
<TargetFrameworkProfile />
<UpgradeBackupLocation>
</UpgradeBackupLocation>
- <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/Duplicati/Library/Backend/WEBDAV/Strings.cs b/Duplicati/Library/Backend/WEBDAV/Strings.cs
index d505dc729..7d263e84e 100644
--- a/Duplicati/Library/Backend/WEBDAV/Strings.cs
+++ b/Duplicati/Library/Backend/WEBDAV/Strings.cs
@@ -11,8 +11,9 @@ namespace Duplicati.Library.Backend.Strings {
public static string DescriptionIntegratedAuthenticationLong { get { return LC.L(@"If the server and client both supports integrated authentication, this option enables that authentication method. This is likely only available with windows servers and clients."); } }
public static string DescriptionIntegratedAuthenticationShort { get { return LC.L(@"Use windows integrated authentication to connect to the server"); } }
public static string DisplayName { get { return LC.L(@"WebDAV"); } }
- public static string MissingFolderError(string foldername, string message) { return LC.L(@"The folder {0} was not found, message: {1}", foldername, message); }
- public static string SeenThenNotFoundError(string foldername, string filename, string extension, string errormessage) { return LC.L(@"When listing the folder {0} the file {1} was listed, but the server now reports that the file is not found.
+ public static string MethodNotAllowedError(System.Net.HttpStatusCode statuscode) { return LC.L(@"The server returned the error code {0} ({1}), indicating that the server does not support WebDAV connections", (int)statuscode, statuscode); }
+ public static string MissingFolderError(string foldername, string message) { return LC.L(@"The folder {0} was not found, message: {1}", foldername, message); }
+ public static string SeenThenNotFoundError(string foldername, string filename, string extension, string errormessage) { return LC.L(@"When listing the folder {0} the file {1} was listed, but the server now reports that the file is not found.
This can be because the file is deleted or unavailable, but it can also be because the file extension {2} is blocked by the web server. IIS blocks unknown extensions by default.
Error message: {3}", foldername, filename, extension, errormessage); }
public static string DescriptionUseSSLLong { get { return LC.L(@"Use this flag to communicate using Secure Socket Layer (SSL) over http (https)."); } }
diff --git a/Duplicati/Library/Backend/WEBDAV/WEBDAV.cs b/Duplicati/Library/Backend/WEBDAV/WEBDAV.cs
index c5149d53a..d35815f16 100644
--- a/Duplicati/Library/Backend/WEBDAV/WEBDAV.cs
+++ b/Duplicati/Library/Backend/WEBDAV/WEBDAV.cs
@@ -125,123 +125,129 @@ namespace Duplicati.Library.Backend
get { return "webdav"; }
}
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
try
{
- var req = CreateRequest("");
+ return this.ListWithouExceptionCatch();
+ }
+ catch (System.Net.WebException wex)
+ {
+ if (wex.Response as System.Net.HttpWebResponse != null &&
+ ((wex.Response as System.Net.HttpWebResponse).StatusCode == System.Net.HttpStatusCode.NotFound || (wex.Response as System.Net.HttpWebResponse).StatusCode == System.Net.HttpStatusCode.Conflict))
+ throw new Interface.FolderMissingException(Strings.WEBDAV.MissingFolderError(m_path, wex.Message), wex);
- req.Method = "PROPFIND";
- req.Headers.Add("Depth", "1");
- req.ContentType = "text/xml";
- req.ContentLength = PROPFIND_BODY.Length;
+ if (wex.Response as System.Net.HttpWebResponse != null && (wex.Response as System.Net.HttpWebResponse).StatusCode == System.Net.HttpStatusCode.MethodNotAllowed)
+ throw new UserInformationException(Strings.WEBDAV.MethodNotAllowedError((wex.Response as System.Net.HttpWebResponse).StatusCode), wex);
- var areq = new Utility.AsyncHttpRequest(req);
- using (System.IO.Stream s = areq.GetRequestStream())
- s.Write(PROPFIND_BODY, 0, PROPFIND_BODY.Length);
-
- var doc = new System.Xml.XmlDocument();
- using (var resp = (System.Net.HttpWebResponse)areq.GetResponse())
- {
- int code = (int)resp.StatusCode;
- if (code < 200 || code >= 300) //For some reason Mono does not throw this automatically
- throw new System.Net.WebException(resp.StatusDescription, null, System.Net.WebExceptionStatus.ProtocolError, resp);
+ throw;
+ }
+ }
- if (!string.IsNullOrEmpty(m_debugPropfindFile))
- {
- using (var rs = areq.GetResponseStream())
- using (var fs = new System.IO.FileStream(m_debugPropfindFile, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
- Utility.Utility.CopyStream(rs, fs, false, m_copybuffer);
+ private IEnumerable<IFileEntry> ListWithouExceptionCatch()
+ {
+ var req = CreateRequest("");
- doc.Load(m_debugPropfindFile);
- }
- else
- {
- using (var rs = areq.GetResponseStream())
- doc.Load(rs);
- }
- }
+ req.Method = "PROPFIND";
+ req.Headers.Add("Depth", "1");
+ req.ContentType = "text/xml";
+ req.ContentLength = PROPFIND_BODY.Length;
- System.Xml.XmlNamespaceManager nm = new System.Xml.XmlNamespaceManager(doc.NameTable);
- nm.AddNamespace("D", "DAV:");
+ var areq = new Utility.AsyncHttpRequest(req);
+ using (System.IO.Stream s = areq.GetRequestStream())
+ s.Write(PROPFIND_BODY, 0, PROPFIND_BODY.Length);
- List<IFileEntry> files = new List<IFileEntry>();
- m_filenamelist = new List<string>();
+ var doc = new System.Xml.XmlDocument();
+ using (var resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ {
+ int code = (int)resp.StatusCode;
+ if (code < 200 || code >= 300) //For some reason Mono does not throw this automatically
+ throw new System.Net.WebException(resp.StatusDescription, null, System.Net.WebExceptionStatus.ProtocolError, resp);
- foreach (System.Xml.XmlNode n in doc.SelectNodes("D:multistatus/D:response/D:href", nm))
+ if (!string.IsNullOrEmpty(m_debugPropfindFile))
{
- //IIS uses %20 for spaces and %2B for +
- //Apache uses %20 for spaces and + for +
- string name = Library.Utility.Uri.UrlDecode(n.InnerText.Replace("+", "%2B"));
-
- string cmp_path;
-
- //TODO: This list is getting ridiculous, should change to regexps
-
- if (name.StartsWith(m_url))
- cmp_path = m_url;
- else if (name.StartsWith(m_rawurl))
- cmp_path = m_rawurl;
- else if (name.StartsWith(m_rawurlPort))
- cmp_path = m_rawurlPort;
- else if (name.StartsWith(m_path))
- cmp_path = m_path;
- else if (name.StartsWith("/" + m_path))
- cmp_path = "/" + m_path;
- else if (name.StartsWith(m_sanitizedUrl))
- cmp_path = m_sanitizedUrl;
- else if (name.StartsWith(m_reverseProtocolUrl))
- cmp_path = m_reverseProtocolUrl;
- else
- continue;
-
- if (name.Length <= cmp_path.Length)
- continue;
-
- name = name.Substring(cmp_path.Length);
-
- long size = -1;
- DateTime lastAccess = new DateTime();
- DateTime lastModified = new DateTime();
- bool isCollection = false;
-
- System.Xml.XmlNode stat = n.ParentNode.SelectSingleNode("D:propstat/D:prop", nm);
- if (stat != null)
- {
- System.Xml.XmlNode s = stat.SelectSingleNode("D:getcontentlength", nm);
- if (s != null)
- size = long.Parse(s.InnerText);
- s = stat.SelectSingleNode("D:getlastmodified", nm);
- if (s != null)
- try
- {
- //Not important if this succeeds
- lastAccess = lastModified = DateTime.Parse(s.InnerText, System.Globalization.CultureInfo.InvariantCulture);
- }
- catch { }
-
- s = stat.SelectSingleNode("D:iscollection", nm);
- if (s != null)
- isCollection = s.InnerText.Trim() == "1";
- else
- isCollection = (stat.SelectSingleNode("D:resourcetype/D:collection", nm) != null);
- }
-
- FileEntry fe = new FileEntry(name, size, lastAccess, lastModified);
- fe.IsFolder = isCollection;
- files.Add(fe);
- m_filenamelist.Add(name);
- }
+ using (var rs = areq.GetResponseStream())
+ using (var fs = new System.IO.FileStream(m_debugPropfindFile, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
+ Utility.Utility.CopyStream(rs, fs, false, m_copybuffer);
- return files;
+ doc.Load(m_debugPropfindFile);
+ }
+ else
+ {
+ using (var rs = areq.GetResponseStream())
+ doc.Load(rs);
+ }
}
- catch (System.Net.WebException wex)
+
+ System.Xml.XmlNamespaceManager nm = new System.Xml.XmlNamespaceManager(doc.NameTable);
+ nm.AddNamespace("D", "DAV:");
+
+ List<IFileEntry> files = new List<IFileEntry>();
+ m_filenamelist = new List<string>();
+
+ foreach (System.Xml.XmlNode n in doc.SelectNodes("D:multistatus/D:response/D:href", nm))
{
- if (wex.Response as System.Net.HttpWebResponse != null &&
- ((wex.Response as System.Net.HttpWebResponse).StatusCode == System.Net.HttpStatusCode.NotFound || (wex.Response as System.Net.HttpWebResponse).StatusCode == System.Net.HttpStatusCode.Conflict))
- throw new Interface.FolderMissingException(Strings.WEBDAV.MissingFolderError(m_path, wex.Message), wex);
+ //IIS uses %20 for spaces and %2B for +
+ //Apache uses %20 for spaces and + for +
+ string name = Library.Utility.Uri.UrlDecode(n.InnerText.Replace("+", "%2B"));
+
+ string cmp_path;
+
+ //TODO: This list is getting ridiculous, should change to regexps
+
+ if (name.StartsWith(m_url))
+ cmp_path = m_url;
+ else if (name.StartsWith(m_rawurl))
+ cmp_path = m_rawurl;
+ else if (name.StartsWith(m_rawurlPort))
+ cmp_path = m_rawurlPort;
+ else if (name.StartsWith(m_path))
+ cmp_path = m_path;
+ else if (name.StartsWith("/" + m_path))
+ cmp_path = "/" + m_path;
+ else if (name.StartsWith(m_sanitizedUrl))
+ cmp_path = m_sanitizedUrl;
+ else if (name.StartsWith(m_reverseProtocolUrl))
+ cmp_path = m_reverseProtocolUrl;
+ else
+ continue;
- throw;
+ if (name.Length <= cmp_path.Length)
+ continue;
+
+ name = name.Substring(cmp_path.Length);
+
+ long size = -1;
+ DateTime lastAccess = new DateTime();
+ DateTime lastModified = new DateTime();
+ bool isCollection = false;
+
+ System.Xml.XmlNode stat = n.ParentNode.SelectSingleNode("D:propstat/D:prop", nm);
+ if (stat != null)
+ {
+ System.Xml.XmlNode s = stat.SelectSingleNode("D:getcontentlength", nm);
+ if (s != null)
+ size = long.Parse(s.InnerText);
+ s = stat.SelectSingleNode("D:getlastmodified", nm);
+ if (s != null)
+ try
+ {
+ //Not important if this succeeds
+ lastAccess = lastModified = DateTime.Parse(s.InnerText, System.Globalization.CultureInfo.InvariantCulture);
+ }
+ catch { }
+
+ s = stat.SelectSingleNode("D:iscollection", nm);
+ if (s != null)
+ isCollection = s.InnerText.Trim() == "1";
+ else
+ isCollection = (stat.SelectSingleNode("D:resourcetype/D:collection", nm) != null);
+ }
+
+ FileEntry fe = new FileEntry(name, size, lastAccess, lastModified);
+ fe.IsFolder = isCollection;
+ m_filenamelist.Add(name);
+ yield return fe;
}
}
@@ -305,7 +311,7 @@ namespace Duplicati.Library.Backend
public void Test()
{
- List();
+ this.TestList();
}
public void CreateFolder()
diff --git a/Duplicati/Library/Compression/Duplicati.Library.Compression.csproj b/Duplicati/Library/Compression/Duplicati.Library.Compression.csproj
index 3e27196db..6b1e5e8b4 100644
--- a/Duplicati/Library/Compression/Duplicati.Library.Compression.csproj
+++ b/Duplicati/Library/Compression/Duplicati.Library.Compression.csproj
@@ -8,7 +8,6 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.Library.Compression</RootNamespace>
<AssemblyName>Duplicati.Library.Compression</AssemblyName>
- <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
@@ -17,6 +16,7 @@
<TargetFrameworkProfile />
<UpgradeBackupLocation>
</UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -37,13 +37,13 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
- <Reference Include="SharpCompress">
- <HintPath>..\..\..\thirdparty\SharpCompress\SharpCompress.dll</HintPath>
- </Reference>
<Reference Include="System.Core" />
<Reference Include="managed-lzma">
<HintPath>..\..\..\thirdparty\ManagedLZMA\managed-lzma.dll</HintPath>
</Reference>
+ <Reference Include="SharpCompress">
+ <HintPath>..\..\..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="FileArchiveDirectory.cs" />
@@ -74,6 +74,7 @@
<ItemGroup>
<None Include="app.config" />
<None Include="Duplicati.snk" />
+ <None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/Duplicati/Library/Compression/FileArchiveZip.cs b/Duplicati/Library/Compression/FileArchiveZip.cs
index 89d55ecdd..4f1dc9c07 100644
--- a/Duplicati/Library/Compression/FileArchiveZip.cs
+++ b/Duplicati/Library/Compression/FileArchiveZip.cs
@@ -21,13 +21,14 @@ using System;
using System.Collections.Generic;
using System.IO;
using Duplicati.Library.Interface;
-using System.Linq;
using SharpCompress.Common;
-using SharpCompress.Archive;
-using SharpCompress.Archive.Zip;
-using SharpCompress.Writer;
-using SharpCompress.Writer.Zip;
+using SharpCompress.Archives;
+using SharpCompress.Archives.Zip;
+using SharpCompress.Writers;
+using SharpCompress.Writers.Zip;
+using SharpCompress.Readers;
+using System.Linq;
namespace Duplicati.Library.Compression
{
@@ -50,17 +51,26 @@ namespace Duplicati.Library.Compression
/// <summary>
/// The commandline option for toggling the compression method
/// </summary>
- private const string COMPRESSION_METHOD_OPTION = "zip-compression-method";
+ private const string COMPRESSION_METHOD_OPTION = "zip-compression-method";
+ /// <summary>
+ /// The commandline option for toggling the zip64 support
+ /// </summary>
+ private const string COMPRESSION_ZIP64_OPTION = "zip-compression-zip64";
+
+ /// <summary>
+ /// The default compression level
+ /// </summary>
+ private const SharpCompress.Compressors.Deflate.CompressionLevel DEFAULT_COMPRESSION_LEVEL = SharpCompress.Compressors.Deflate.CompressionLevel.Level9;
/// <summary>
- /// The default compression level
+ /// The default compression method
/// </summary>
- private const SharpCompress.Compressor.Deflate.CompressionLevel DEFAULT_COMPRESSION_LEVEL = SharpCompress.Compressor.Deflate.CompressionLevel.Level9;
+ private const CompressionType DEFAULT_COMPRESSION_METHOD = CompressionType.Deflate;
/// <summary>
- /// The default compression method
+ /// The default setting for the zip64 support
/// </summary>
- private const CompressionType DEFAULT_COMPRESSION_METHOD = CompressionType.Deflate;
+ private const bool DEFAULT_ZIP64 = false;
/// <summary>
/// Taken from SharpCompress ZipCentralDirectorEntry.cs
@@ -68,6 +78,11 @@ namespace Duplicati.Library.Compression
private const int CENTRAL_HEADER_ENTRY_SIZE = 8 + 2 + 2 + 4 + 4 + 4 + 4 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 4;
/// <summary>
+ /// The size of the extended zip64 header
+ /// </summary>
+ private const int CENTRAL_HEADER_ENTRY_SIZE_ZIP64_EXTRA = 2 + 2 + 8 + 8 + 8 + 4;
+
+ /// <summary>
/// This property indicates that this current instance should write to a file
/// </summary>
private bool m_isWriting;
@@ -89,7 +104,7 @@ namespace Duplicati.Library.Compression
/// <summary>
/// Lookup table for faster access to entries based on their name.
/// </summary>
- private Dictionary<string, IArchiveEntry> m_entryDict;
+ private Dictionary<string, IEntry> m_entryDict;
/// <summary>
/// The writer instance used when creating archives
@@ -97,40 +112,29 @@ namespace Duplicati.Library.Compression
private IWriter m_writer;
/// <summary>
- /// Instance of the CompresisonInfo class, used to hack in compression hints
+ /// A flag indicating if we are using the fail-over reader interface
/// </summary>
- private CompressionInfo m_compressionInfo;
+ public bool m_using_reader = false;
/// <summary>
/// The compression level applied when the hint does not indicate incompressible
/// </summary>
- private SharpCompress.Compressor.Deflate.CompressionLevel m_defaultCompressionLevel;
+ private SharpCompress.Compressors.Deflate.CompressionLevel m_defaultCompressionLevel;
- /// <summary>
- /// The name of the file being read
+ /// <summary>
+ /// The compression level applied when the hint does not indicate incompressible
/// </summary>
- private string m_filename;
+ private CompressionType m_compressionType;
/// <summary>
- /// The reflection entry used to manipulate the deflate level on the compressor
+ /// The name of the file being read
/// </summary>
- private static readonly System.Reflection.FieldInfo _zipCompressionInfoField;
+ private string m_filename;
/// <summary>
- /// Static initializer to read the deflateLevelField
+ /// A flag indicating if zip64 is in use
/// </summary>
- static FileArchiveZip()
- {
- System.Reflection.FieldInfo fi = null;
-
- try { fi = typeof(ZipWriter).GetField("zipCompressionInfo", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); }
- catch { }
-
- _zipCompressionInfoField = fi;
-
- if (fi == null)
- Logging.Log.WriteMessage("DeflateCompressionLevel is not supported, please report to developers", Duplicati.Library.Logging.LogMessageType.Warning);
- }
+ private bool m_usingZip64;
/// <summary>
/// Default constructor, used to read file extension and supported commands
@@ -149,6 +153,50 @@ namespace Duplicati.Library.Compression
}
}
+ public void SwitchToReader()
+ {
+ if (!m_using_reader)
+ {
+ // Close what we have
+ using (m_stream)
+ using (m_archive)
+ { }
+
+ m_using_reader = true;
+ }
+ }
+
+ public Stream GetStreamFromReader(IEntry entry)
+ {
+ Stream fs = null;
+ SharpCompress.Readers.Zip.ZipReader rd = null;
+
+ try
+ {
+ fs = new System.IO.FileStream(m_filename, FileMode.Open, FileAccess.Read, FileShare.Read);
+ rd = SharpCompress.Readers.Zip.ZipReader.Open(fs);
+
+ while (rd.MoveToNextEntry())
+ if (entry.Key == rd.Entry.Key)
+ return new StreamWrapper(rd.OpenEntryStream(), stream => {
+ rd.Dispose();
+ fs.Dispose();
+ });
+
+ throw new Exception(string.Format("Stream not found: {0}", entry.Key));
+ }
+ catch
+ {
+ if (rd != null)
+ rd.Dispose();
+ if (fs != null)
+ fs.Dispose();
+
+ throw;
+ }
+
+ }
+
/// <summary>
/// Constructs a new zip instance.
/// If the file exists and has a non-zero length we read it,
@@ -159,7 +207,7 @@ namespace Duplicati.Library.Compression
public FileArchiveZip(string filename, Dictionary<string, string> options)
{
if (string.IsNullOrEmpty(filename) && filename.Trim().Length == 0)
- throw new ArgumentException("filename");
+ throw new ArgumentException("Invalid filename.", nameof(filename));
if (File.Exists(filename) && new FileInfo(filename).Length > 0)
{
@@ -168,27 +216,34 @@ namespace Duplicati.Library.Compression
}
else
{
- m_compressionInfo = new CompressionInfo();
- m_compressionInfo.Type = DEFAULT_COMPRESSION_METHOD;
- m_compressionInfo.DeflateCompressionLevel = DEFAULT_COMPRESSION_LEVEL;
+ var compression = new ZipWriterOptions(CompressionType.Deflate);
+
+ compression.CompressionType = DEFAULT_COMPRESSION_METHOD;
+ compression.DeflateCompressionLevel = DEFAULT_COMPRESSION_LEVEL;
+
+ m_usingZip64 = compression.UseZip64 =
+ options.ContainsKey(COMPRESSION_ZIP64_OPTION)
+ ? Duplicati.Library.Utility.Utility.ParseBoolOption(options, COMPRESSION_ZIP64_OPTION)
+ : DEFAULT_ZIP64;
string cpmethod;
CompressionType tmptype;
if (options.TryGetValue(COMPRESSION_METHOD_OPTION, out cpmethod) && Enum.TryParse<SharpCompress.Common.CompressionType>(cpmethod, true, out tmptype))
- m_compressionInfo.Type = tmptype;
+ compression.CompressionType = tmptype;
string cplvl;
int tmplvl;
if (options.TryGetValue(COMPRESSION_LEVEL_OPTION, out cplvl) && int.TryParse(cplvl, out tmplvl))
- m_compressionInfo.DeflateCompressionLevel = (SharpCompress.Compressor.Deflate.CompressionLevel)Math.Max(Math.Min(9, tmplvl), 0);
+ compression.DeflateCompressionLevel = (SharpCompress.Compressors.Deflate.CompressionLevel)Math.Max(Math.Min(9, tmplvl), 0);
else if (options.TryGetValue(COMPRESSION_LEVEL_OPTION_ALIAS, out cplvl) && int.TryParse(cplvl, out tmplvl))
- m_compressionInfo.DeflateCompressionLevel = (SharpCompress.Compressor.Deflate.CompressionLevel)Math.Max(Math.Min(9, tmplvl), 0);
+ compression.DeflateCompressionLevel = (SharpCompress.Compressors.Deflate.CompressionLevel)Math.Max(Math.Min(9, tmplvl), 0);
- m_defaultCompressionLevel = m_compressionInfo.DeflateCompressionLevel;
+ m_defaultCompressionLevel = compression.DeflateCompressionLevel;
+ m_compressionType = compression.CompressionType;
m_isWriting = true;
m_stream = new System.IO.FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read);
- m_writer = WriterFactory.Open(m_stream, ArchiveType.Zip, m_compressionInfo);
+ m_writer = WriterFactory.Open(m_stream, ArchiveType.Zip, compression);
//Size of endheader, taken from SharpCompress ZipWriter
m_flushBufferSize = 8 + 2 + 2 + 4 + 4 + 2 + 0;
@@ -215,12 +270,26 @@ namespace Duplicati.Library.Compression
public IList<ICommandLineArgument> SupportedCommands
{
get
- {
+ {
+ // This is the cross between these two:
+ // https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Zip/ZipCompressionMethod.cs
+ // https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/CompressionType.cs
+
+ var methods = new[]
+ {
+ CompressionType.None.ToString(),
+ CompressionType.Deflate.ToString(),
+ CompressionType.BZip2.ToString(),
+ CompressionType.LZMA.ToString(),
+ CompressionType.PPMd.ToString(),
+ };
+
return new List<ICommandLineArgument>(new ICommandLineArgument[] {
new CommandLineArgument(COMPRESSION_LEVEL_OPTION, CommandLineArgument.ArgumentType.Enumeration, Strings.FileArchiveZip.CompressionlevelShort, Strings.FileArchiveZip.CompressionlevelLong, DEFAULT_COMPRESSION_LEVEL.ToString(), null, new string[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}),
new CommandLineArgument(COMPRESSION_LEVEL_OPTION_ALIAS, CommandLineArgument.ArgumentType.Enumeration, Strings.FileArchiveZip.CompressionlevelShort, Strings.FileArchiveZip.CompressionlevelLong, DEFAULT_COMPRESSION_LEVEL.ToString(), null, new string[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, Strings.FileArchiveZip.CompressionlevelDeprecated(COMPRESSION_LEVEL_OPTION)),
- new CommandLineArgument(COMPRESSION_METHOD_OPTION, CommandLineArgument.ArgumentType.Enumeration, Strings.FileArchiveZip.CompressionmethodShort, Strings.FileArchiveZip.CompressionmethodLong(COMPRESSION_LEVEL_OPTION), DEFAULT_COMPRESSION_METHOD.ToString(), null, Enum.GetNames(typeof(CompressionType)))
- });
+ new CommandLineArgument(COMPRESSION_METHOD_OPTION, CommandLineArgument.ArgumentType.Enumeration, Strings.FileArchiveZip.CompressionmethodShort, Strings.FileArchiveZip.CompressionmethodLong(COMPRESSION_LEVEL_OPTION), DEFAULT_COMPRESSION_METHOD.ToString(), null, methods),
+ new CommandLineArgument(COMPRESSION_ZIP64_OPTION, CommandLineArgument.ArgumentType.Boolean, Strings.FileArchiveZip.Compressionzip64Short, Strings.FileArchiveZip.Compressionzip64Long, DEFAULT_ZIP64.ToString())
+ });
}
}
@@ -231,24 +300,7 @@ namespace Duplicati.Library.Compression
/// <returns>A list of files matching the prefix</returns>
public string[] ListFiles(string prefix)
{
- List<string> results = new List<string>();
- foreach (IArchiveEntry e in Archive.Entries)
- {
- if (prefix == null)
- {
- results.Add(e.Key);
- }
- else
- {
- if (e.Key.StartsWith(prefix, Duplicati.Library.Utility.Utility.ClientFilenameStringComparision))
- results.Add(e.Key);
- //Some old archives may have been created with windows style paths
- else if (e.Key.Replace('\\', '/').StartsWith(prefix, Duplicati.Library.Utility.Utility.ClientFilenameStringComparision))
- results.Add(e.Key);
- }
- }
-
- return results.ToArray();
+ return ListFilesWithSize(prefix).Select(x => x.Key).ToArray();
}
/// <summary>
@@ -258,25 +310,18 @@ namespace Duplicati.Library.Compression
/// <returns>A list of files matching the prefix</returns>
public IEnumerable<KeyValuePair<string, long>> ListFilesWithSize(string prefix)
{
- List<KeyValuePair<string, long>> results = new List<KeyValuePair<string, long>>();
- foreach (IArchiveEntry e in Archive.Entries)
- {
- if (prefix == null)
- {
- results.Add(new KeyValuePair<string, long>(e.Key, e.Size));
- }
- else
- {
- if (e.Key.StartsWith(prefix, Duplicati.Library.Utility.Utility.ClientFilenameStringComparision))
- results.Add(new KeyValuePair<string, long>(e.Key, e.Size));
- //Some old archives may have been created with windows style paths
- else if (e.Key.Replace('\\', '/').StartsWith(prefix, Duplicati.Library.Utility.Utility.ClientFilenameStringComparision))
- results.Add(new KeyValuePair<string, long>(e.Key, e.Size));
- }
- }
-
- return results;
+ LoadEntryTable();
+ var q = m_entryDict.Values.AsEnumerable();
+ if (!string.IsNullOrEmpty(prefix))
+ q = q.Where(x =>
+ x.Key.StartsWith(prefix, Duplicati.Library.Utility.Utility.ClientFilenameStringComparision)
+ ||
+ x.Key.Replace('\\', '/').StartsWith(prefix, Duplicati.Library.Utility.Utility.ClientFilenameStringComparision)
+ );
+
+ return q.Select(x => new KeyValuePair<string, long>(x.Key, x.Size)).ToArray();
}
+
/// <summary>
/// Opens an file for reading
/// </summary>
@@ -287,9 +332,71 @@ namespace Duplicati.Library.Compression
if (m_isWriting)
throw new InvalidOperationException("Cannot read while writing");
- IArchiveEntry ze = GetEntry(file);
+ var ze = GetEntry(file);
+ if (ze == null)
+ return null;
+
+ if (ze is IArchiveEntry)
+ return ((IArchiveEntry)ze).OpenEntryStream();
+ else if (ze is SharpCompress.Common.Zip.ZipEntry)
+ return GetStreamFromReader(ze);
+
+ throw new Exception(string.Format("Unexpected result: {0}", ze.GetType().FullName));
- return ze == null ? null : ze.OpenEntryStream();
+ }
+
+ /// <summary>
+ /// Helper method to load the entry table
+ /// </summary>
+ private void LoadEntryTable()
+ {
+ if (m_entryDict == null)
+ {
+ try
+ {
+ var d = new Dictionary<string, IEntry>(Duplicati.Library.Utility.Utility.ClientFilenameStringComparer);
+ foreach (var en in Archive.Entries)
+ d[en.Key] = en;
+ m_entryDict = d;
+ }
+ catch (Exception ex)
+ {
+ // If we get an exception here, it may be caused by the Central Header
+ // being defect, so we switch to the less efficient reader interface
+ if (m_using_reader)
+ throw;
+
+ Logging.Log.WriteMessage("Zip archive appears to have a broken Central Record Header, switching to stream mode", Logging.LogMessageType.Warning, ex);
+ SwitchToReader();
+
+ var d = new Dictionary<string, IEntry>(Duplicati.Library.Utility.Utility.ClientFilenameStringComparer);
+
+ try
+ {
+ using (var fs = new System.IO.FileStream(m_filename, FileMode.Open, FileAccess.Read, FileShare.Read))
+ using (var rd = SharpCompress.Readers.Zip.ZipReader.Open(fs, new ReaderOptions() { LookForHeader = false }))
+ while (rd.MoveToNextEntry())
+ {
+ d[rd.Entry.Key] = rd.Entry;
+
+ // Some streams require this
+ // to correctly find the next entry
+ using (rd.OpenEntryStream())
+ { }
+ }
+ }
+ catch (Exception ex2)
+ {
+ // If we have zero files, or just a manifest, don't bother
+ if (d.Count < 2)
+ throw;
+
+ Logging.Log.WriteMessage(string.Format("Zip archive appears to have broken records, returning the {0} records that could be recovered", d.Count), Logging.LogMessageType.Warning, ex2);
+ }
+
+ m_entryDict = d;
+ }
+ }
}
/// <summary>
@@ -297,19 +404,14 @@ namespace Duplicati.Library.Compression
/// </summary>
/// <param name="file">The name of the file to find</param>
/// <returns>The ZipEntry for the file or null if no such file was found</returns>
- private IArchiveEntry GetEntry(string file)
+ private IEntry GetEntry(string file)
{
if (m_isWriting)
throw new InvalidOperationException("Cannot read while writing");
- if (m_entryDict == null)
- {
- m_entryDict = new Dictionary<string, IArchiveEntry>(Duplicati.Library.Utility.Utility.ClientFilenameStringComparer);
- foreach(IArchiveEntry en in Archive.Entries)
- m_entryDict[en.Key] = en;
- }
+ LoadEntryTable();
- IArchiveEntry e;
+ IEntry e;
if (m_entryDict.TryGetValue(file, out e))
return e;
if (m_entryDict.TryGetValue(file.Replace('/', '\\'), out e))
@@ -331,25 +433,16 @@ namespace Duplicati.Library.Compression
throw new InvalidOperationException("Cannot write while reading");
m_flushBufferSize += CENTRAL_HEADER_ENTRY_SIZE + System.Text.Encoding.UTF8.GetByteCount(file);
- m_compressionInfo.DeflateCompressionLevel = hint == CompressionHint.Noncompressible ? SharpCompress.Compressor.Deflate.CompressionLevel.None : m_defaultCompressionLevel;
- SetStreamCompressionLevel();
- return ((ZipWriter)m_writer).WriteToStream(file, lastWrite, null, m_compressionInfo);
-
- }
+ if (m_usingZip64)
+ m_flushBufferSize += CENTRAL_HEADER_ENTRY_SIZE_ZIP64_EXTRA;
+
+ return ((ZipWriter)m_writer).WriteToStream(file, new ZipWriterEntryOptions()
+ {
+ DeflateCompressionLevel = hint == CompressionHint.Noncompressible ? SharpCompress.Compressors.Deflate.CompressionLevel.None : m_defaultCompressionLevel,
+ ModificationDateTime = lastWrite,
+ CompressionType = m_compressionType
+ });
- /// <summary>
- /// Hack to set compression level for stream
- /// </summary>
- private void SetStreamCompressionLevel()
- {
- if (_zipCompressionInfoField != null)
- try
- {
- var compInstance = _zipCompressionInfoField.GetValue(m_writer);
- var prop = compInstance.GetType().GetProperty("DeflateCompressionLevel", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
- prop.SetValue(compInstance, m_compressionInfo.DeflateCompressionLevel);
- }
- catch { }
}
/// <summary>
diff --git a/Duplicati/Library/Compression/StreamWrapper.cs b/Duplicati/Library/Compression/StreamWrapper.cs
index 66d3cdbd8..309426572 100644
--- a/Duplicati/Library/Compression/StreamWrapper.cs
+++ b/Duplicati/Library/Compression/StreamWrapper.cs
@@ -1,31 +1,42 @@
-using System.IO;
+using System;
+using System.IO;
namespace Duplicati.Library.Compression
{
-
/// <summary>
/// CompressionStream wrapper to prevent closing the base stream when disposing the entry stream
/// </summary>
public class StreamWrapper : Utility.OverrideableStream
{
- public delegate void DisposingHandler(StreamWrapper sender);
-
- public event DisposingHandler Disposing;
-
- public StreamWrapper(Stream stream)
+ /// <summary>
+ /// The callback to invoke when the stream is disposed
+ /// </summary>
+ private readonly Action<StreamWrapper> m_onCloseCallback;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:Duplicati.Library.Compression.StreamWrapper"/> class.
+ /// </summary>
+ /// <param name="stream">Stream.</param>
+ /// <param name="onClose">On close.</param>
+ public StreamWrapper(Stream stream, Action<StreamWrapper> onClose)
: base(stream)
{
+ m_onCloseCallback = onClose;
}
+ /// <summary>
+ /// Disposes the stream, and calls the close handler if required
+ /// </summary>
+ /// <param name="disposing">If set to <c>true</c>, this call originates from the dispose method.</param>
protected override void Dispose(bool disposing)
{
if (!disposing || m_basestream == null) return;
- if (Disposing != null)
- Disposing(this);
-
m_basestream.Dispose();
m_basestream = null;
+
+ if (m_onCloseCallback != null)
+ m_onCloseCallback(this);
}
public long GetSize()
@@ -33,4 +44,4 @@ namespace Duplicati.Library.Compression
return m_basestream == null ? 0 : m_basestream.Length;
}
}
-}
+}
diff --git a/Duplicati/Library/Compression/Strings.cs b/Duplicati/Library/Compression/Strings.cs
index a3fe180e5..8a1e336b0 100644
--- a/Duplicati/Library/Compression/Strings.cs
+++ b/Duplicati/Library/Compression/Strings.cs
@@ -1,26 +1,28 @@
-using Duplicati.Library.Localization.Short;
-namespace Duplicati.Library.Compression.Strings {
- internal static class FileArchiveZip {
- public static string CompressionlevelDeprecated(string optionname) { return LC.L(@"Please use the {0} option instead", optionname); }
- public static string CompressionlevelLong { get { return LC.L(@"This option controls the compression level used. A setting of zero gives no compression, and a setting of 9 gives maximum compression."); } }
- public static string CompressionlevelShort { get { return LC.L(@"Sets the Zip compression level"); } }
- public static string CompressionmethodLong(string optionname) { return LC.L(@"This option can be used to set an alternative compressor method, such as LZMA. Note that using another value than Deflate will cause the {0} option to be ignored.", optionname); }
+using Duplicati.Library.Localization.Short;
+namespace Duplicati.Library.Compression.Strings {
+ internal static class FileArchiveZip {
+ public static string CompressionlevelDeprecated(string optionname) { return LC.L(@"Please use the {0} option instead", optionname); }
+ public static string CompressionlevelLong { get { return LC.L(@"This option controls the compression level used. A setting of zero gives no compression, and a setting of 9 gives maximum compression."); } }
+ public static string CompressionlevelShort { get { return LC.L(@"Sets the Zip compression level"); } }
+ public static string CompressionmethodLong(string optionname) { return LC.L(@"This option can be used to set an alternative compressor method, such as LZMA. Note that using another value than Deflate will cause the {0} option to be ignored.", optionname); }
public static string CompressionmethodShort { get { return LC.L(@"Sets the Zip compression method"); } }
- public static string Description { get { return LC.L(@"This module provides the industry standard Zip compression. Files created with this module can be read by any standard compliant zip application."); } }
- public static string DisplayName { get { return LC.L(@"Zip compression"); } }
- public static string FileNotFoundError(string filename) { return LC.L(@"File not found: {0}", filename); }
- }
- internal static class SevenZipCompression {
- public static string NoWriterError { get { return LC.L(@"Archive not opened for writing"); } }
- public static string NoReaderError { get { return LC.L(@"Archive not opened for reading"); } }
- public static string FileNotFoundError { get { return LC.L(@"The given file is not part of this archive"); } }
- public static string Description { get { return LC.L(@"7z Archive with LZMA2 support."); } }
- public static string DisplayName { get { return LC.L(@"7z Archive"); } }
- public static string ThreadcountLong { get { return LC.L(@"The number of threads used in LZMA 2 compression. Defaults to the number of processor cores.."); } }
- public static string ThreadcountShort { get { return LC.L(@"Number of threads used in compression"); } }
- public static string CompressionlevelLong { get { return LC.L(@"This option controls the compression level used. A setting of zero gives no compression, and a setting of 9 gives maximum compression."); } }
- public static string CompressionlevelShort { get { return LC.L(@"Sets the 7z compression level"); } }
- public static string FastalgoLong { get { return LC.L(@"This option controls the compression algorithm used. Enabling this option will cause 7z to use the fast algorithm, which produces slightly less compression."); } }
- public static string FastalgoShort { get { return LC.L(@"Sets the 7z fast algorithm usage"); } }
- }
-}
+ public static string Compressionzip64Short { get { return LC.L(@"Toggles Zip64 support"); } }
+ public static string Compressionzip64Long { get { return LC.L(@"The zip64 format is required for files larger than 4GiB, use this flag to toggle it"); } }
+ public static string Description { get { return LC.L(@"This module provides the industry standard Zip compression. Files created with this module can be read by any standard-compliant zip application."); } }
+ public static string DisplayName { get { return LC.L(@"Zip compression"); } }
+ public static string FileNotFoundError(string filename) { return LC.L(@"File not found: {0}", filename); }
+ }
+ internal static class SevenZipCompression {
+ public static string NoWriterError { get { return LC.L(@"Archive not opened for writing"); } }
+ public static string NoReaderError { get { return LC.L(@"Archive not opened for reading"); } }
+ public static string FileNotFoundError { get { return LC.L(@"The given file is not part of this archive"); } }
+ public static string Description { get { return LC.L(@"7z Archive with LZMA2 support."); } }
+ public static string DisplayName { get { return LC.L(@"7z Archive"); } }
+ public static string ThreadcountLong { get { return LC.L(@"The number of threads used in LZMA 2 compression. Defaults to the number of processor cores."); } }
+ public static string ThreadcountShort { get { return LC.L(@"Number of threads used in compression"); } }
+ public static string CompressionlevelLong { get { return LC.L(@"This option controls the compression level used. A setting of zero gives no compression, and a setting of 9 gives maximum compression."); } }
+ public static string CompressionlevelShort { get { return LC.L(@"Sets the 7z compression level"); } }
+ public static string FastalgoLong { get { return LC.L(@"This option controls the compression algorithm used. Enabling this option will cause 7z to use the fast algorithm, which produces slightly less compression."); } }
+ public static string FastalgoShort { get { return LC.L(@"Sets the 7z fast algorithm usage"); } }
+ }
+}
diff --git a/Duplicati/Library/Compression/packages.config b/Duplicati/Library/Compression/packages.config
new file mode 100644
index 000000000..2c846c9a5
--- /dev/null
+++ b/Duplicati/Library/Compression/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="SharpCompress" version="0.18.2" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Duplicati/Library/DynamicLoader/BackendLoader.cs b/Duplicati/Library/DynamicLoader/BackendLoader.cs
index 6d48516d5..fab99a87d 100644
--- a/Duplicati/Library/DynamicLoader/BackendLoader.cs
+++ b/Duplicati/Library/DynamicLoader/BackendLoader.cs
@@ -84,8 +84,8 @@ namespace Duplicati.Library.DynamicLoader
{
var commands = m_interfaces[tmpscheme].SupportedCommands;
if (commands != null && (commands.Where(x =>
- x.Name.Equals("use-ssl", StringComparison.InvariantCultureIgnoreCase) ||
- (x.Aliases != null && x.Aliases.Where(y => y.Equals("use-ssl", StringComparison.InvariantCultureIgnoreCase)).Any())
+ x.Name.Equals("use-ssl", StringComparison.OrdinalIgnoreCase) ||
+ (x.Aliases != null && x.Aliases.Where(y => y.Equals("use-ssl", StringComparison.OrdinalIgnoreCase)).Any())
).Any()))
{
newOpts["use-ssl"] = "true";
diff --git a/Duplicati/Library/DynamicLoader/Duplicati.Library.DynamicLoader.csproj b/Duplicati/Library/DynamicLoader/Duplicati.Library.DynamicLoader.csproj
index 37d80f7a5..21c4d58df 100644
--- a/Duplicati/Library/DynamicLoader/Duplicati.Library.DynamicLoader.csproj
+++ b/Duplicati/Library/DynamicLoader/Duplicati.Library.DynamicLoader.csproj
@@ -17,6 +17,7 @@
<TargetFrameworkProfile />
<UpgradeBackupLocation>
</UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/Duplicati/Library/DynamicLoader/GenericLoader.cs b/Duplicati/Library/DynamicLoader/GenericLoader.cs
index 31ba5e6ae..51cdf67bc 100644
--- a/Duplicati/Library/DynamicLoader/GenericLoader.cs
+++ b/Duplicati/Library/DynamicLoader/GenericLoader.cs
@@ -25,7 +25,7 @@ using Duplicati.Library.Interface;
namespace Duplicati.Library.DynamicLoader
{
/// <summary>
- /// An interface class that provides easy loading of plugable setting controls
+ /// An interface class that provides easy loading of pluggable setting controls
/// </summary>
public static class GenericLoader
{
diff --git a/Duplicati/Library/Encryption/AESEncryption.cs b/Duplicati/Library/Encryption/AESEncryption.cs
index dc8b0c8c1..d342e35c1 100644
--- a/Duplicati/Library/Encryption/AESEncryption.cs
+++ b/Duplicati/Library/Encryption/AESEncryption.cs
@@ -71,7 +71,7 @@ namespace Duplicati.Library.Encryption
public AESEncryption(string passphrase, Dictionary<string, string> options)
{
if(string.IsNullOrEmpty(passphrase))
- throw new ArgumentException(Strings.AESEncryption.EmptyKeyError, "passphrase");
+ throw new ArgumentException(Strings.AESEncryption.EmptyKeyError, nameof(passphrase));
m_key = passphrase;
diff --git a/Duplicati/Library/Encryption/Duplicati.Library.Encryption.csproj b/Duplicati/Library/Encryption/Duplicati.Library.Encryption.csproj
index 022e12ef5..1db4e3674 100644
--- a/Duplicati/Library/Encryption/Duplicati.Library.Encryption.csproj
+++ b/Duplicati/Library/Encryption/Duplicati.Library.Encryption.csproj
@@ -17,6 +17,7 @@
<TargetFrameworkProfile />
<UpgradeBackupLocation>
</UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/Duplicati/Library/Encryption/Strings.cs b/Duplicati/Library/Encryption/Strings.cs
index cd08ad033..ac6fedb0e 100644
--- a/Duplicati/Library/Encryption/Strings.cs
+++ b/Duplicati/Library/Encryption/Strings.cs
@@ -3,7 +3,7 @@ namespace Duplicati.Library.Encryption.Strings {
internal static class AESEncryption {
public static string Description_v2 { get { return LC.L(@"This module encrypts all files in the same way that AESCrypt does, using 256 bit AES encryption."); } }
public static string DisplayName { get { return LC.L(@"AES-256 encryption, built in"); } }
- public static string EmptyKeyError { get { return LC.L(@"Blank or empty passphrase not allowed"); } }
+ public static string EmptyKeyError { get { return LC.L(@"Empty passphrase not allowed"); } }
public static string AessetthreadlevelLong { get { return LC.L(@"Use this option to set the thread level allowed for AES crypt operations. Valid values are 0 (uses default), or from 1 (no multithreading) to 4 (max. multithreading)"); } }
public static string AessetthreadlevelShort { get { return LC.L(@"Set thread level utilized for crypting (0-4)"); } }
}
diff --git a/Duplicati/Library/Interface/BackendExtensions.cs b/Duplicati/Library/Interface/BackendExtensions.cs
new file mode 100644
index 000000000..486632d76
--- /dev/null
+++ b/Duplicati/Library/Interface/BackendExtensions.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Duplicati.Library.Interface
+{
+ /// <summary>
+ /// Contains extension methods for the IBackend interfaces
+ /// </summary>
+ public static class BackendExtensions
+ {
+ /// <summary>
+ /// Tests a backend by invoking the List() method.
+ /// As long as the iteration can either complete or find at least one file without throwing, the test is successful
+ /// </summary>
+ /// <param name="backend">Backend to test</param>
+ public static void TestList(this IBackend backend)
+ {
+ // If we can iterate successfully, even if it's empty, then the backend test is successful
+ foreach (IFileEntry file in backend.List())
+ {
+ break;
+ }
+ }
+ }
+}
diff --git a/Duplicati/Library/Interface/CustomExceptions.cs b/Duplicati/Library/Interface/CustomExceptions.cs
index 360cf7ae9..fcdfe32bf 100644
--- a/Duplicati/Library/Interface/CustomExceptions.cs
+++ b/Duplicati/Library/Interface/CustomExceptions.cs
@@ -25,10 +25,30 @@ using Duplicati.Library.Localization.Short;
namespace Duplicati.Library.Interface
{
/// <summary>
+ /// A special exception that gives the user information on how to proceed.
+ /// Use this execption if the message is directed at the end user, and supplies
+ /// some guidance or explanation for the error. Exceptions of this type will
+ /// suppress the stack trace by default, on commandline output
+ /// </summary>
+ [Serializable]
+ public class UserInformationException : Exception
+ {
+ public UserInformationException(string message)
+ : base(message)
+ {
+ }
+
+ public UserInformationException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+ }
+
+ /// <summary>
/// An exception indicating that the requested folder is missing
/// </summary>
[Serializable]
- public class FolderMissingException : Exception
+ public class FolderMissingException : UserInformationException
{
public FolderMissingException()
: base(Strings.Common.FolderMissingError)
@@ -51,7 +71,7 @@ namespace Duplicati.Library.Interface
/// An exception indicating that the requested folder is missing
/// </summary>
[Serializable]
- public class FileMissingException : Exception
+ public class FileMissingException : UserInformationException
{
public FileMissingException()
: base(LC.L("The requested file does not exist"))
@@ -74,7 +94,7 @@ namespace Duplicati.Library.Interface
/// An exception indicating that the requested folder already existed
/// </summary>
[Serializable]
- public class FolderAreadyExistedException : Exception
+ public class FolderAreadyExistedException : UserInformationException
{
public FolderAreadyExistedException()
: base(Strings.Common.FolderAlreadyExistsError)
@@ -97,10 +117,10 @@ namespace Duplicati.Library.Interface
/// An exception indicating that the user has cancelled the action
/// </summary>
[Serializable]
- public class CancelException : Exception
+ public class CancelException : UserInformationException
{
public CancelException()
- : base()
+ : base(Strings.Common.CancelExceptionError)
{ }
public CancelException(string message)
diff --git a/Duplicati/Library/Interface/Duplicati.Library.Interface.csproj b/Duplicati/Library/Interface/Duplicati.Library.Interface.csproj
index 0957eaa0e..8d9cd26f4 100644
--- a/Duplicati/Library/Interface/Duplicati.Library.Interface.csproj
+++ b/Duplicati/Library/Interface/Duplicati.Library.Interface.csproj
@@ -17,6 +17,7 @@
<UpgradeBackupLocation />
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -41,6 +42,7 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="BackendExtensions.cs" />
<Compile Include="CommandLineArgument.cs" />
<Compile Include="CommonStrings.cs" />
<Compile Include="CustomExceptions.cs" />
@@ -50,16 +52,20 @@
<Compile Include="IEncryption.cs" />
<Compile Include="ICompression.cs" />
<Compile Include="IFileEntry.cs" />
+ <Compile Include="IGenericSourceModule.cs" />
<Compile Include="IGenericModule.cs" />
<Compile Include="IQuotaEnabledBackend.cs" />
+ <Compile Include="IQuotaInfo.cs" />
<Compile Include="IStreamingBackend.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="IGenericCallbackModule.cs" />
+ <Compile Include="QuotaInfo.cs" />
<Compile Include="ResultInterfaces.cs" />
<Compile Include="IWebModule.cs" />
<Compile Include="IConnectionModule.cs" />
<Compile Include="IRenameEnabledBackend.cs" />
<Compile Include="Strings.cs" />
+ <Compile Include="IGenericServerModule.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Duplicati.snk" />
diff --git a/Duplicati/Library/Interface/IBackend.cs b/Duplicati/Library/Interface/IBackend.cs
index df78a28d7..8281a9372 100644
--- a/Duplicati/Library/Interface/IBackend.cs
+++ b/Duplicati/Library/Interface/IBackend.cs
@@ -46,11 +46,10 @@ namespace Duplicati.Library.Interface
string ProtocolKey { get; }
/// <summary>
- /// Returns a list of files found on the remote location
+ /// Enumerates a list of files found on the remote location
/// </summary>
- /// <param name="url">The url passed</param>
/// <returns>The list of files</returns>
- List<IFileEntry> List();
+ IEnumerable<IFileEntry> List();
/// <summary>
/// Puts the content of the file to the url passed
@@ -82,7 +81,7 @@ namespace Duplicati.Library.Interface
/// </summary>
string Description { get; }
- /// <summary>
+ /// <summary>
/// The purpose of this method is to test the connection to the remote backend.
/// If any problem is encountered, this method should throw an exception.
/// If the encountered problem is a missing target &quot;folder&quot;,
diff --git a/Duplicati/Library/Interface/IGenericModule.cs b/Duplicati/Library/Interface/IGenericModule.cs
index 0db3eb7e0..9e6d1acaa 100644
--- a/Duplicati/Library/Interface/IGenericModule.cs
+++ b/Duplicati/Library/Interface/IGenericModule.cs
@@ -24,7 +24,7 @@ using System.Text;
namespace Duplicati.Library.Interface
{
/// <summary>
- /// An interface for a plugable generic module.
+ /// An interface for a pluggable generic module.
/// An instance of a module is loaded prior to a backup or restore operation,
/// and can perform tasks relating to the general execution environment, as
/// well as modify the options used in Duplicati.
diff --git a/Duplicati/Library/Interface/IGenericServerModule.cs b/Duplicati/Library/Interface/IGenericServerModule.cs
new file mode 100644
index 000000000..9c00d1373
--- /dev/null
+++ b/Duplicati/Library/Interface/IGenericServerModule.cs
@@ -0,0 +1,42 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+
+namespace Duplicati.Library.Interface
+{
+ /// <summary>
+ /// A module that displays a set of options in the general setup area
+ /// </summary>
+ public interface IGenericServerModule : IGenericModule
+ {
+ /// <summary>
+ /// Gets a list of supported global module arguments
+ /// </summary>
+ IList<ICommandLineArgument> SupportedGlobalCommands { get; }
+
+ /// <summary>
+ /// Gets a list of supported local module arguments
+ /// </summary>
+ IList<ICommandLineArgument> SupportedLocalCommands { get; }
+
+ /// <summary>
+ /// Gets an optional link that helps the user understand this server module
+ /// </summary>
+ string ServiceLink { get; }
+ }
+}
diff --git a/Duplicati/Library/Interface/IGenericSourceModule.cs b/Duplicati/Library/Interface/IGenericSourceModule.cs
new file mode 100644
index 000000000..a48eaee38
--- /dev/null
+++ b/Duplicati/Library/Interface/IGenericSourceModule.cs
@@ -0,0 +1,49 @@
+#region Disclaimer / License
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#endregion
+using System;
+using System.Collections.Generic;
+
+namespace Duplicati.Library.Interface
+{
+ /// <summary>
+ /// An interface for a pluggable source module.
+ /// An instance of a module is loaded prior to a backup or restore operation,
+ /// and can perform tasks relating to the source plugins, as
+ /// well as modify backup source, the options and filters used in Duplicati.
+ /// </summary>
+ public interface IGenericSourceModule : IGenericModule
+ {
+ /// <summary>
+ /// This method parse and alter backup source paths, apply and alter filters and returns changed or added options values.
+ /// </summary>
+ /// <param name="paths">Backup source paths</param>
+ /// <param name="filter">Filters that are applied to backup paths (include, exclude)</param>
+ /// <param name="commandlineOptions">A set of commandline options passed to Duplicati</param>
+ /// <returns>A list of changed or added options values</returns>
+ Dictionary<string, string> ParseSourcePaths(ref string[] paths, ref string filter, Dictionary<string, string> commandlineOptions);
+
+ /// <summary>
+ /// This method decides if input variables contains something to backup.
+ /// </summary>
+ /// <param name="paths">A set of source paths</param>
+ /// <returns>If module is going to backup anything, it returns true, otherwise false</returns>
+ bool ContainFilesForBackup(string[] paths);
+ }
+}
diff --git a/Duplicati/Library/Interface/IQuotaEnabledBackend.cs b/Duplicati/Library/Interface/IQuotaEnabledBackend.cs
index 57964f5d6..a813c1f85 100644
--- a/Duplicati/Library/Interface/IQuotaEnabledBackend.cs
+++ b/Duplicati/Library/Interface/IQuotaEnabledBackend.cs
@@ -11,16 +11,10 @@ namespace Duplicati.Library.Interface
public interface IQuotaEnabledBackend : IBackend
{
/// <summary>
- /// The total number of bytes available on the backend,
- /// may return -1 if the particular host implementation
- /// does not support quotas, but the backend does
+ /// Gets information about the quota on this backend.
+ /// This may return null if the particular host implementation
+ /// does not support quotas, but the backend does.
/// </summary>
- long TotalQuotaSpace { get; }
- /// <summary>
- /// The total number of unused bytes on the backend,
- /// may return -1 if the particular host implementation
- /// does not support quotas, but the backend does
- /// </summary>
- long FreeQuotaSpace { get; }
+ IQuotaInfo Quota { get; }
}
}
diff --git a/Duplicati/Library/Interface/IQuotaInfo.cs b/Duplicati/Library/Interface/IQuotaInfo.cs
new file mode 100644
index 000000000..81eb48153
--- /dev/null
+++ b/Duplicati/Library/Interface/IQuotaInfo.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Duplicati.Library.Interface
+{
+ public interface IQuotaInfo
+ {
+ /// <summary>
+ /// The total number of bytes available on the backend,
+ /// This may return -1 if the particular host implementation
+ /// does not support quotas, but the backend does
+ /// </summary>
+ long TotalQuotaSpace { get; }
+ /// <summary>
+ /// The total number of unused bytes on the backend,
+ /// This may return -1 if the particular host implementation
+ /// does not support quotas, but the backend does
+ /// </summary>
+ long FreeQuotaSpace { get; }
+ }
+}
diff --git a/Duplicati/Library/Interface/IRenameEnabledBackend.cs b/Duplicati/Library/Interface/IRenameEnabledBackend.cs
index 1185b8c53..550e098e9 100644
--- a/Duplicati/Library/Interface/IRenameEnabledBackend.cs
+++ b/Duplicati/Library/Interface/IRenameEnabledBackend.cs
@@ -24,17 +24,15 @@ using System.Text;
namespace Duplicati.Library.Interface
{
/// <summary>
- /// An interface a backend may implement if it supports streaming operations.
- /// Backends that implement this interface can be throttled and correctly shows
- /// the progressbar when transfering data.
+ /// An interface a backend may implement if it supports rename operations.
/// </summary>
public interface IRenameEnabledBackend : IBackend
{
/// <summary>
- /// Puts the content of the file to the url passed
+ /// Renames the file
/// </summary>
- /// <param name="remotename">The remote filename, relative to the URL</param>
- /// <param name="stream">The stream to read from</param>
+ /// <param name="oldname">The old filename, relative to the root</param>
+ /// <param name="newname">The new filename, relative to the root</param>
void Rename(string oldname, string newname);
}
}
diff --git a/Duplicati/Library/Interface/QuotaInfo.cs b/Duplicati/Library/Interface/QuotaInfo.cs
new file mode 100644
index 000000000..6158e1c7c
--- /dev/null
+++ b/Duplicati/Library/Interface/QuotaInfo.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Duplicati.Library.Interface
+{
+ public class QuotaInfo : IQuotaInfo
+ {
+ public QuotaInfo(long totalSpace, long freeSpace)
+ {
+ this.TotalQuotaSpace = totalSpace;
+ this.FreeQuotaSpace = freeSpace;
+ }
+
+ public long TotalQuotaSpace { get; private set; }
+
+ public long FreeQuotaSpace { get; private set; }
+ }
+}
diff --git a/Duplicati/Library/Interface/ResultInterfaces.cs b/Duplicati/Library/Interface/ResultInterfaces.cs
index a2aa45dba..3e582c304 100644
--- a/Duplicati/Library/Interface/ResultInterfaces.cs
+++ b/Duplicati/Library/Interface/ResultInterfaces.cs
@@ -20,6 +20,15 @@ using System.Collections.Generic;
namespace Duplicati.Library.Interface
{
+ public enum ParsedResultType
+ {
+ Unknown,
+ Success,
+ Warning,
+ Error,
+ Fatal
+ }
+
public interface IBasicResults
{
DateTime BeginTime { get; }
@@ -29,6 +38,7 @@ namespace Duplicati.Library.Interface
IEnumerable<string> Errors { get; }
IEnumerable<string> Warnings { get; }
IEnumerable<string> Messages { get; }
+ ParsedResultType ParsedResult { get; }
}
public interface IBackendStatstics
@@ -56,6 +66,11 @@ namespace Duplicati.Library.Interface
long AssignedQuotaSpace { get; }
}
+ public interface IBackendStatsticsReporter
+ {
+ IBackendStatstics BackendStatistics { get; }
+ }
+
public interface IListResultFile
{
string Path { get; }
@@ -103,7 +118,7 @@ namespace Duplicati.Library.Interface
bool Dryrun { get; }
}
- public interface IBackupResults : IBasicResults
+ public interface IBackupResults : IBasicResults, IBackendStatsticsReporter
{
long DeletedFiles { get; }
long DeletedFolders { get; }
@@ -129,7 +144,6 @@ namespace Duplicati.Library.Interface
ICompactResults CompactResults { get; }
IDeleteResults DeleteResults { get; }
IRepairResults RepairResults { get; }
- IBackendStatstics BackendStatistics { get; }
}
public interface IRestoreResults : IBasicResults
@@ -149,7 +163,12 @@ namespace Duplicati.Library.Interface
public interface IRecreateDatabaseResults : IBasicResults
{
}
-
+
+ public interface IListRemoteResults : IBasicResults, IBackendStatsticsReporter
+ {
+ IEnumerable<IFileEntry> Files { get; }
+ }
+
public interface ICompactResults : IBasicResults
{
long DeletedFileCount { get; }
@@ -268,7 +287,7 @@ namespace Duplicati.Library.Interface
public interface ITestResults : IBasicResults
{
- IEnumerable<KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>> Changes { get; }
+ IEnumerable<KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>> Verifications { get; }
}
public interface ITestFilterResults : IBasicResults
@@ -282,5 +301,32 @@ namespace Duplicati.Library.Interface
IEnumerable<string> Lines { get; }
}
+ public interface IPurgeFilesResults : IBasicResults
+ {
+ long RemovedFileCount { get; }
+ long RemovedFileSize { get; }
+ long RewrittenFileLists { get; }
+ ICompactResults CompactResults { get; }
+ }
+
+ public interface IListBrokenFilesResults : IBasicResults
+ {
+ IEnumerable<Tuple<long, DateTime, IEnumerable<Tuple<string, long>>>> BrokenFiles { get; }
+ }
+
+ public interface IPurgeBrokenFilesResults : IBasicResults
+ {
+ IPurgeFilesResults PurgeResults { get; }
+ IDeleteResults DeleteResults { get; }
+ }
+
+ public interface ISendMailResults : IBasicResults
+ {
+ IEnumerable<string> Lines { get; }
+ }
+
+ public interface IVacuumResults : IBasicResults
+ {
+ }
}
diff --git a/Duplicati/Library/Localization/Duplicati.Library.Localization.csproj b/Duplicati/Library/Localization/Duplicati.Library.Localization.csproj
index 2df14af27..1fff0eee3 100644
--- a/Duplicati/Library/Localization/Duplicati.Library.Localization.csproj
+++ b/Duplicati/Library/Localization/Duplicati.Library.Localization.csproj
@@ -11,6 +11,7 @@
<AssemblyOriginatorKeyFile>..\Main\Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -33,11 +34,11 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
- <Reference Include="NGettext, Version=0.6.1.0, Culture=neutral, PublicKeyToken=08d3d1c89dfd2985, processorArchitecture=MSIL">
- <HintPath>..\..\..\packages\NGettext.0.6.2\lib\net45\NGettext.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System" />
+ <Reference Include="NGettext">
+ <HintPath>..\..\..\packages\NGettext.0.6.3\lib\net45\NGettext.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -49,11 +50,11 @@
<Compile Include="LocalizationContext.cs" />
</ItemGroup>
<ItemGroup />
- <ItemGroup>
- <None Include="packages.config" />
- </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\..\..\Localizations\duplicati\*.mo" />
</ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/Duplicati/Library/Localization/LocalizationService.cs b/Duplicati/Library/Localization/LocalizationService.cs
index ad65f3051..1e2750bd0 100644
--- a/Duplicati/Library/Localization/LocalizationService.cs
+++ b/Duplicati/Library/Localization/LocalizationService.cs
@@ -42,7 +42,7 @@ namespace Duplicati.Library.Localization
/// <summary>
/// Regular expression to match a locale
/// </summary>
- public static readonly Regex CI_MATCHER = new Regex(@"[A-z]{2}(-[A-z]{4})?(-[A-z]{2})?");
+ public static readonly Regex CI_MATCHER = new Regex(@"[A-z]{2}([-_][A-z]{4})?([-_][A-z]{2})?");
/// <summary>
/// Returns a temporary disposable localization context
@@ -77,6 +77,7 @@ namespace Duplicati.Library.Localization
public static CultureInfo ParseCulture(string culture, bool returninvariant = false)
{
var ci = returninvariant ? CultureInfo.InvariantCulture : null;
+ culture = culture.Replace("_", "-");
if (CI_MATCHER.Match(culture).Success)
try { ci = new CultureInfo(culture); }
diff --git a/Duplicati/Library/Localization/MoLocalizationService.cs b/Duplicati/Library/Localization/MoLocalizationService.cs
index ff3f4b8e1..38667a471 100644
--- a/Duplicati/Library/Localization/MoLocalizationService.cs
+++ b/Duplicati/Library/Localization/MoLocalizationService.cs
@@ -40,13 +40,18 @@ namespace Duplicati.Library.Localization
/// </summary>
public const string LOCALIZATIONDIR_ENVNAME = "LOCALIZATION_FOLDER";
+ private static string LOCALIZATIONDIR_VALUE =
+ string.IsNullOrWhiteSpace(AppDomain.CurrentDomain.GetData(LOCALIZATIONDIR_ENVNAME) as string)
+ ? Environment.GetEnvironmentVariable(LOCALIZATIONDIR_ENVNAME)
+ : AppDomain.CurrentDomain.GetData(LOCALIZATIONDIR_ENVNAME) as string;
+
/// <summary>
/// Path to search for extra .mo files in
/// </summary>
public static string[] SearchPaths =
- string.IsNullOrWhiteSpace(AppDomain.CurrentDomain.GetData(LOCALIZATIONDIR_ENVNAME) as string)
+ string.IsNullOrWhiteSpace(LOCALIZATIONDIR_VALUE)
? new string[] { Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) }
- : (AppDomain.CurrentDomain.GetData(LOCALIZATIONDIR_ENVNAME) as string).Split(new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);
+ : (LOCALIZATIONDIR_VALUE).Split(new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);
/// <summary>
@@ -92,7 +97,7 @@ namespace Duplicati.Library.Localization
var names =
from name in SearchAssembly.GetManifestResourceNames()
let m = CI_MATCHER.Match(name)
- let c = m.Success && string.Equals(m.Value, fn, StringComparison.InvariantCultureIgnoreCase) ? LocalizationService.ParseCulture(m.Groups["culture"].Value) : null
+ let c = m.Success && string.Equals(m.Value, fn, StringComparison.OrdinalIgnoreCase) ? LocalizationService.ParseCulture(m.Groups["culture"].Value) : null
where c != null
select name;
diff --git a/Duplicati/Library/Localization/packages.config b/Duplicati/Library/Localization/packages.config
index e1ed09554..dd9f8d80b 100644
--- a/Duplicati/Library/Localization/packages.config
+++ b/Duplicati/Library/Localization/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="NGettext" version="0.6.2" targetFramework="net45" />
+ <package id="NGettext" version="0.6.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Logging/Duplicati.Library.Logging.csproj b/Duplicati/Library/Logging/Duplicati.Library.Logging.csproj
index db9e22960..670f652fd 100644
--- a/Duplicati/Library/Logging/Duplicati.Library.Logging.csproj
+++ b/Duplicati/Library/Logging/Duplicati.Library.Logging.csproj
@@ -17,6 +17,7 @@
<TargetFrameworkProfile />
<UpgradeBackupLocation>
</UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -44,6 +45,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StreamLog.cs" />
<Compile Include="Timer.cs" />
+ <Compile Include="LogScope.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
diff --git a/Duplicati/Library/Logging/Log.cs b/Duplicati/Library/Logging/Log.cs
index 60eca9cef..126be4010 100644
--- a/Duplicati/Library/Logging/Log.cs
+++ b/Duplicati/Library/Logging/Log.cs
@@ -52,17 +52,34 @@ namespace Duplicati.Library.Logging
public static class Log
{
/// <summary>
+ /// The key used to assign the current scope into the current call-context
+ /// </summary>
+ private const string LOGICAL_CONTEXT_KEY = "Duplicati:LoggingEntry";
+
+ /// <summary>
+ /// The root scope
+ /// </summary>
+ private static readonly LogScope m_root = new LogScope(null, LogMessageType.Error, null);
+
+ /// <summary>
+ /// The stored log instances
+ /// </summary>
+ private static readonly Dictionary<string, LogScope> m_log_instances = new Dictionary<string, LogScope>();
+
+ /// <summary>
/// Static lock object to provide thread safe logging
/// </summary>
private static object m_lock = new object();
+
/// <summary>
- /// The log destination, may be null
+ /// Flag used to block recursion
/// </summary>
- private static ILog m_log = null;
+ private static bool m_is_active = false;
+
/// <summary>
- /// The minimum level of logged messages
+ /// Gets the lock instance used to protect the logging calls
/// </summary>
- private static LogMessageType m_logLevel = LogMessageType.Error;
+ public static object Lock { get { return m_lock; } }
/// <summary>
/// Writes a message to the current log destination
@@ -82,17 +99,27 @@ namespace Duplicati.Library.Logging
/// <param name="ex">An exception value</param>
public static void WriteMessage(string message, LogMessageType type, Exception ex)
{
- if (m_log == null)
- return;
-
lock (m_lock)
- if (m_log == null)
+ {
+ if (m_is_active)
return;
- else
+
+ try
+ {
+ m_is_active = true;
+ var cs = CurrentScope;
+ while (cs != null)
+ {
+ if (cs.Log != null && type >= cs.LogLevel)
+ cs.Log.WriteMessage(message, type, ex);
+ cs = cs.Parent;
+ }
+ }
+ finally
{
- if (type >= m_logLevel)
- m_log.WriteMessage(message, type, ex);
+ m_is_active = false;
}
+ }
}
/// <summary>
@@ -100,11 +127,20 @@ namespace Duplicati.Library.Logging
/// </summary>
public static LogMessageType LogLevel
{
- get { return m_logLevel; }
+ get
+ {
+ var cs = CurrentScope;
+ var ll = (int)cs.LogLevel;
+ while (cs != null)
+ {
+ ll = Math.Min(ll, (int)cs.LogLevel);
+ cs = cs.Parent;
+ }
+ return (LogMessageType)ll;
+ }
set
{
- lock (m_lock)
- m_logLevel = value;
+ CurrentScope.LogLevel = value;
}
}
@@ -115,12 +151,90 @@ namespace Duplicati.Library.Logging
{
get
{
- return m_log;
+ return CurrentScope.Log;
}
set
{
+ CurrentScope.Log = value;
+ }
+ }
+
+ /// <summary>
+ /// Starts a new scope, that can be closed by disposing the returned instance
+ /// </summary>
+ /// <returns>The new scope.</returns>
+ public static IDisposable StartScope()
+ {
+ return StartScope((ILog)null);
+ }
+
+ /// <summary>
+ /// Starts a new scope, that can be stopped by disposing the returned instance
+ /// </summary>
+ /// <returns>The new scope.</returns>
+ public static IDisposable StartScope(ILog log)
+ {
+ return new LogScope(log, LogLevel, CurrentScope);
+ }
+
+ /// <summary>
+ /// Starts the scope.
+ /// </summary>
+ /// <param name="scope">The scope to start.</param>
+ internal static void StartScope(LogScope scope)
+ {
+ CurrentScope = scope;
+ }
+
+ /// <summary>
+ /// Closes the scope.
+ /// </summary>
+ /// <param name="scope">The scope to finish.</param>
+ internal static void CloseScope(LogScope scope)
+ {
+ lock(m_lock)
+ {
+ if (CurrentScope == scope && scope != m_root)
+ CurrentScope = scope.Parent;
+ m_log_instances.Remove(scope.InstanceID);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the current log destination in a call-context aware fashion
+ /// </summary>
+ internal static LogScope CurrentScope
+ {
+ get
+ {
lock (m_lock)
- m_log = value;
+ {
+ var cur = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData(LOGICAL_CONTEXT_KEY) as string;
+ if (cur == null || cur == m_root.InstanceID)
+ return m_root;
+
+ LogScope sc;
+ if (!m_log_instances.TryGetValue(cur, out sc))
+ throw new Exception(string.Format("Unable to find log in lookup table, this may be caused by attempting to transport call contexts between AppDomains (eg. with remoting calls)"));
+
+ return sc;
+ }
+ }
+ private set
+ {
+ lock (m_lock)
+ {
+ if (value != null)
+ {
+ m_log_instances[value.InstanceID] = value;
+ System.Runtime.Remoting.Messaging.CallContext.LogicalSetData(LOGICAL_CONTEXT_KEY, value.InstanceID);
+ }
+ else
+ {
+ System.Runtime.Remoting.Messaging.CallContext.LogicalSetData(LOGICAL_CONTEXT_KEY, null);
+ }
+
+ }
}
}
}
diff --git a/Duplicati/Library/Logging/LogScope.cs b/Duplicati/Library/Logging/LogScope.cs
new file mode 100644
index 000000000..a0de5a09c
--- /dev/null
+++ b/Duplicati/Library/Logging/LogScope.cs
@@ -0,0 +1,82 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+namespace Duplicati.Library.Logging
+{
+ /// <summary>
+ /// Internal class for keeping log instance relations
+ /// </summary>
+ internal class LogScope : IDisposable
+ {
+ /// <summary>
+ /// The unique ID of this log instance
+ /// </summary>
+ public readonly string InstanceID = Guid.NewGuid().ToString();
+
+ /// <summary>
+ /// The log instance assigned to this scope
+ /// </summary>
+ public ILog Log;
+
+ /// <summary>
+ /// The current log level
+ /// </summary>
+ public LogMessageType LogLevel;
+
+ /// <summary>
+ /// The log scope parent
+ /// </summary>
+ public readonly LogScope Parent;
+
+ /// <summary>
+ /// A flag indicating if the scope is disposed
+ /// </summary>
+ private bool m_isDisposed = false;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:Duplicati.Library.Logging.LogWrapper"/> class.
+ /// </summary>
+ /// <param name="self">The log instance to wrap.</param>
+ public LogScope(ILog self, LogMessageType level, LogScope parent)
+ {
+ Log = self;
+ LogLevel = level;
+ Parent = parent;
+
+ if (parent != null)
+ Logging.Log.StartScope(this);
+ }
+
+ /// <summary>
+ /// Releases all resource used by the <see cref="T:Duplicati.Library.Logging.LogScope"/> object.
+ /// </summary>
+ /// <remarks>Call <see cref="Dispose"/> when you are finished using the
+ /// <see cref="T:Duplicati.Library.Logging.LogScope"/>. The <see cref="Dispose"/> method leaves the
+ /// <see cref="T:Duplicati.Library.Logging.LogScope"/> in an unusable state. After calling
+ /// <see cref="Dispose"/>, you must release all references to the
+ /// <see cref="T:Duplicati.Library.Logging.LogScope"/> so the garbage collector can reclaim the memory that the
+ /// <see cref="T:Duplicati.Library.Logging.LogScope"/> was occupying.</remarks>
+ public void Dispose()
+ {
+ if (!m_isDisposed && Parent != null)
+ {
+ Logging.Log.CloseScope(this);
+ m_isDisposed = true;
+ }
+ }
+ }
+}
diff --git a/Duplicati/Library/Logging/StreamLog.cs b/Duplicati/Library/Logging/StreamLog.cs
index fca105fe4..314fa0a68 100644
--- a/Duplicati/Library/Logging/StreamLog.cs
+++ b/Duplicati/Library/Logging/StreamLog.cs
@@ -59,7 +59,7 @@ namespace Duplicati.Library.Logging
/// <param name="exception">An exception, may be null</param>
public virtual void WriteMessage(string message, LogMessageType type, Exception exception)
{
- m_stream.WriteLine("{0:u} - {1}: {2}", DateTime.Now, type, message);
+ m_stream.WriteLine("{0:u} - {1}: {2}", DateTime.UtcNow.ToString("u"), type, message);
if (exception != null)
{
m_stream.WriteLine(exception.ToString());
diff --git a/Duplicati/Library/Main/BackendManager.cs b/Duplicati/Library/Main/BackendManager.cs
index b06599b48..bae356016 100644
--- a/Duplicati/Library/Main/BackendManager.cs
+++ b/Duplicati/Library/Main/BackendManager.cs
@@ -374,7 +374,7 @@ namespace Duplicati.Library.Main
db.LogRemoteOperation(((DbOperation)e).Action, ((DbOperation)e).File, ((DbOperation)e).Result, transaction);
else if (e is DbUpdate && ((DbUpdate)e).State == RemoteVolumeState.Deleted)
{
- db.UpdateRemoteVolume(((DbUpdate)e).Remotename, RemoteVolumeState.Deleted, ((DbUpdate)e).Size, ((DbUpdate)e).Hash, true, transaction);
+ db.UpdateRemoteVolume(((DbUpdate)e).Remotename, RemoteVolumeState.Deleted, ((DbUpdate)e).Size, ((DbUpdate)e).Hash, true, TimeSpan.FromHours(2), transaction);
volsRemoved.Add(((DbUpdate)e).Remotename);
}
else if (e is DbUpdate)
@@ -392,7 +392,7 @@ namespace Duplicati.Library.Main
}
}
- private BlockingQueue<FileEntryItem> m_queue;
+ private readonly BlockingQueue<FileEntryItem> m_queue;
private Options m_options;
private volatile Exception m_lastException;
private Library.Interface.IEncryption m_encryption;
@@ -402,7 +402,7 @@ namespace Duplicati.Library.Main
private IBackendWriter m_statwriter;
private System.Threading.Thread m_thread;
private BasicResults m_taskControl;
- private DatabaseCollector m_db;
+ private readonly DatabaseCollector m_db;
public string BackendUrl { get { return m_backendurl; } }
@@ -426,14 +426,14 @@ namespace Duplicati.Library.Main
try { shortname = new Library.Utility.Uri(shortname).Scheme; }
catch { }
- throw new Exception(string.Format("Backend not supported: {0}", shortname));
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Backend not supported: {0}", shortname));
}
if (!m_options.NoEncryption)
{
m_encryption = DynamicLoader.EncryptionLoader.GetModule(m_options.EncryptionModule, m_options.Passphrase, m_options.RawOptions);
if (m_encryption == null)
- throw new Exception(string.Format("Encryption method not supported: {0}", m_options.EncryptionModule));
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Encryption method not supported: {0}", m_options.EncryptionModule));
}
if (m_taskControl != null)
@@ -451,14 +451,14 @@ namespace Duplicati.Library.Main
public static string CalculateFileHash(string filename)
{
using (System.IO.FileStream fs = System.IO.File.OpenRead(filename))
- using (var hasher = System.Security.Cryptography.HashAlgorithm.Create(VOLUME_HASH))
+ using (var hasher = HashAlgorithmHelper.Create(VOLUME_HASH))
return Convert.ToBase64String(hasher.ComputeHash(fs));
}
/// <summary> Calculate file hash directly on stream object (for piping) </summary>
public static string CalculateFileHash(System.IO.Stream stream)
{
- using (var hasher = System.Security.Cryptography.HashAlgorithm.Create(VOLUME_HASH))
+ using (var hasher = HashAlgorithmHelper.Create(VOLUME_HASH))
return Convert.ToBase64String(hasher.ComputeHash(stream));
}
@@ -469,7 +469,7 @@ namespace Duplicati.Library.Main
public static System.Security.Cryptography.CryptoStream GetFileHasherStream
(System.IO.Stream stream, System.Security.Cryptography.CryptoStreamMode mode, out Func<string> getHash)
{
- var hasher = System.Security.Cryptography.HashAlgorithm.Create(VOLUME_HASH);
+ var hasher = HashAlgorithmHelper.Create(VOLUME_HASH);
System.Security.Cryptography.CryptoStream retHasherStream =
new System.Security.Cryptography.CryptoStream(stream, hasher, mode);
getHash = () =>
@@ -588,9 +588,18 @@ namespace Duplicati.Library.Main
catch(Exception dex) { m_statwriter.AddWarning(LC.L("Failed to dispose backend instance: {0}", ex.Message), dex); }
m_backend = null;
-
+
if (retries < m_options.NumberOfRetries && m_options.RetryDelay.Ticks != 0)
- System.Threading.Thread.Sleep(m_options.RetryDelay);
+ {
+ var target = DateTime.Now.AddTicks(m_options.RetryDelay.Ticks);
+ while (target > DateTime.Now)
+ {
+ if (m_taskControl != null && m_taskControl.IsAbortRequested())
+ break;
+
+ System.Threading.Thread.Sleep(500);
+ }
+ }
}
}
@@ -669,7 +678,7 @@ namespace Duplicati.Library.Main
IndexVolumeWriter wr = null;
try
{
- var hashsize = System.Security.Cryptography.HashAlgorithm.Create(m_options.BlockHashAlgorithm).HashSize / 8;
+ var hashsize = HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm).HashSize / 8;
wr = new IndexVolumeWriter(m_options);
using(var rd = new IndexVolumeReader(p.CompressionModule, item.Indexfile.Item2.LocalFilename, m_options, hashsize))
wr.CopyFrom(rd, x => x == oldname ? newname : x);
@@ -690,14 +699,33 @@ namespace Duplicati.Library.Main
}
}
}
-
- private void HandleProgress(long pg)
+
+ private string m_lastThrottleUploadValue = null;
+ private string m_lastThrottleDownloadValue = null;
+
+ private void HandleProgress(ThrottledStream ts, long pg)
{
// TODO: Should we pause here as well?
// It might give annoying timeouts for transfers
if (m_taskControl != null)
m_taskControl.TaskControlRendevouz();
+ // Update the throttle speeds if they have changed
+ string tmp;
+ m_options.RawOptions.TryGetValue("throttle-upload", out tmp);
+ if (tmp != m_lastThrottleUploadValue)
+ {
+ ts.WriteSpeed = m_options.MaxUploadPrSecond;
+ m_lastThrottleUploadValue = tmp;
+ }
+
+ m_options.RawOptions.TryGetValue("throttle-download", out tmp);
+ if (tmp != m_lastThrottleDownloadValue)
+ {
+ ts.ReadSpeed = m_options.MaxDownloadPrSecond;
+ m_lastThrottleDownloadValue = tmp;
+ }
+
m_statwriter.BackendProgressUpdater.UpdateProgress(pg);
}
@@ -726,7 +754,7 @@ namespace Duplicati.Library.Main
{
using (var fs = System.IO.File.OpenRead(item.LocalFilename))
using (var ts = new ThrottledStream(fs, m_options.MaxUploadPrSecond, m_options.MaxDownloadPrSecond))
- using (var pgs = new Library.Utility.ProgressReportingStream(ts, item.Size, HandleProgress))
+ using (var pgs = new Library.Utility.ProgressReportingStream(ts, item.Size, pg => HandleProgress(ts, pg)))
((Library.Interface.IStreamingBackend)m_backend).Put(item.RemoteFilename, pgs);
}
else
@@ -742,9 +770,9 @@ namespace Duplicati.Library.Main
if (m_options.ListVerifyUploads)
{
- var f = m_backend.List().Where(n => n.Name.Equals(item.RemoteFilename, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
+ var f = m_backend.List().Where(n => n.Name.Equals(item.RemoteFilename, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (f == null)
- throw new Exception(string.Format("List verify failed, file was not found after upload: {0}", f.Name));
+ throw new Exception(string.Format("List verify failed, file was not found after upload: {0}", item.RemoteFilename));
else if (f.Size != item.Size && f.Size >= 0)
throw new Exception(string.Format("List verify failed for file: {0}, size was {1} but expected to be {2}", f.Name, f.Size, item.Size));
}
@@ -820,7 +848,7 @@ namespace Duplicati.Library.Main
using (var ss = new ShaderStream(nextTierWriter, false))
{
using (var ts = new ThrottledStream(ss, m_options.MaxUploadPrSecond, m_options.MaxDownloadPrSecond))
- using (var pgs = new Library.Utility.ProgressReportingStream(ts, item.Size, HandleProgress))
+ using (var pgs = new Library.Utility.ProgressReportingStream(ts, item.Size, pg => HandleProgress(ts, pg)))
{
taskHasher.Start(); // We do not start tasks earlier to be sure the input always gets closed.
if (taskDecrypter != null) taskDecrypter.Start();
@@ -905,7 +933,7 @@ namespace Duplicati.Library.Main
using (var ss = new ShaderStream(hs, true))
{
using (var ts = new ThrottledStream(ss, m_options.MaxUploadPrSecond, m_options.MaxDownloadPrSecond))
- using (var pgs = new Library.Utility.ProgressReportingStream(ts, item.Size, HandleProgress))
+ using (var pgs = new Library.Utility.ProgressReportingStream(ts, item.Size, pg => HandleProgress(ts, pg)))
{ ((Library.Interface.IStreamingBackend)m_backend).Get(item.RemoteFilename, pgs); }
ss.Flush();
retDownloadSize = ss.TotalBytesWritten;
@@ -972,17 +1000,17 @@ namespace Duplicati.Library.Main
{
// Auto-guess the encryption module
var ext = (System.IO.Path.GetExtension(item.RemoteFilename) ?? "").TrimStart('.');
- if (!m_encryption.FilenameExtension.Equals(ext, StringComparison.InvariantCultureIgnoreCase))
+ if (!m_encryption.FilenameExtension.Equals(ext, StringComparison.OrdinalIgnoreCase))
{
// Check if the file is encrypted with something else
- if (DynamicLoader.EncryptionLoader.Keys.Contains(ext, StringComparer.InvariantCultureIgnoreCase))
+ if (DynamicLoader.EncryptionLoader.Keys.Contains(ext, StringComparer.OrdinalIgnoreCase))
{
m_statwriter.AddVerboseMessage("Filename extension \"{0}\" does not match encryption module \"{1}\", using matching encryption module", ext, m_options.EncryptionModule);
useDecrypter = DynamicLoader.EncryptionLoader.GetModule(ext, m_options.Passphrase, m_options.RawOptions);
useDecrypter = useDecrypter ?? m_encryption;
}
// Check if the file is not encrypted
- else if (DynamicLoader.CompressionLoader.Keys.Contains(ext, StringComparer.InvariantCultureIgnoreCase))
+ else if (DynamicLoader.CompressionLoader.Keys.Contains(ext, StringComparer.OrdinalIgnoreCase))
{
m_statwriter.AddVerboseMessage("Filename extension \"{0}\" does not match encryption module \"{1}\", guessing that it is not encrypted", ext, m_options.EncryptionModule);
useDecrypter = null;
@@ -1034,12 +1062,17 @@ namespace Duplicati.Library.Main
else
item.Hash = fileHash;
}
-
- if (!item.VerifyHashOnly)
+
+ if (item.VerifyHashOnly)
+ {
+ tmpfile.Dispose();
+ }
+ else
{
item.Result = tmpfile;
tmpfile = null;
}
+
}
catch
{
@@ -1054,7 +1087,7 @@ namespace Duplicati.Library.Main
{
m_statwriter.SendEvent(BackendActionType.List, BackendEventType.Started, null, -1);
- var r = m_backend.List();
+ var r = m_backend.List().ToList();
StringBuilder sb = new StringBuilder();
sb.AppendLine("[");
@@ -1153,19 +1186,27 @@ namespace Duplicati.Library.Main
req.SetLocalfilename(localpath);
req.Encrypted = true; //Prevent encryption
req.NotTrackedInDb = true; //Prevent Db updates
-
- if (m_queue.Enqueue(req) && m_options.SynchronousUpload)
+
+ try
{
- req.WaitForComplete();
- if (req.Exception != null)
- throw req.Exception;
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ if (m_queue.Enqueue(req) && m_options.SynchronousUpload)
+ {
+ req.WaitForComplete();
+ if (req.Exception != null)
+ throw req.Exception;
+ }
+ }
+ finally
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
}
if (m_lastException != null)
throw m_lastException;
}
- public void Put(VolumeWriterBase item, IndexVolumeWriter indexfile = null)
+ public void Put(VolumeWriterBase item, IndexVolumeWriter indexfile = null, bool synchronous = false)
{
if (m_lastException != null)
throw m_lastException;
@@ -1199,20 +1240,28 @@ namespace Duplicati.Library.Main
req.Indexfile = new Tuple<IndexVolumeWriter, FileEntryItem>(indexfile, req2);
}
- m_db.FlushDbMessages(true);
-
- if (m_queue.Enqueue(req) && m_options.SynchronousUpload)
+ try
{
- req.WaitForComplete();
- if (req.Exception != null)
- throw req.Exception;
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ m_db.FlushDbMessages(true);
+
+ if (m_queue.Enqueue(req) && (m_options.SynchronousUpload || synchronous))
+ {
+ req.WaitForComplete();
+ if (req.Exception != null)
+ throw req.Exception;
+ }
+
+ if (req2 != null && m_queue.Enqueue(req2) && (m_options.SynchronousUpload || synchronous))
+ {
+ req2.WaitForComplete();
+ if (req2.Exception != null)
+ throw req2.Exception;
+ }
}
-
- if (req2 != null && m_queue.Enqueue(req2) && m_options.SynchronousUpload)
+ finally
{
- req2.WaitForComplete();
- if (req2.Exception != null)
- throw req2.Exception;
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
}
if (m_lastException != null)
@@ -1226,8 +1275,16 @@ namespace Duplicati.Library.Main
hash = null; size = -1;
var req = new FileEntryItem(OperationType.Get, remotename, -1, null);
- if (m_queue.Enqueue(req))
- ((IDownloadWaitHandle) req).Wait(out hash, out size);
+ try
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ if (m_queue.Enqueue(req))
+ ((IDownloadWaitHandle)req).Wait(out hash, out size);
+ }
+ finally
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
+ }
if (m_lastException != null)
throw m_lastException;
@@ -1241,8 +1298,16 @@ namespace Duplicati.Library.Main
throw m_lastException;
var req = new FileEntryItem(OperationType.Get, remotename, size, hash);
- if (m_queue.Enqueue(req))
- ((IDownloadWaitHandle)req).Wait();
+ try
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ if (m_queue.Enqueue(req))
+ ((IDownloadWaitHandle)req).Wait();
+ }
+ finally
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
+ }
if (m_lastException != null)
throw m_lastException;
@@ -1256,8 +1321,16 @@ namespace Duplicati.Library.Main
throw m_lastException;
var req = new FileEntryItem(OperationType.Get, remotename, size, hash);
- if (m_queue.Enqueue(req))
- return req;
+ try
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ if (m_queue.Enqueue(req))
+ return req;
+ }
+ finally
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
+ }
if (m_lastException != null)
throw m_lastException;
@@ -1275,11 +1348,19 @@ namespace Duplicati.Library.Main
var req = new FileEntryItem(OperationType.Get, remotename, size, hash);
req.VerifyHashOnly = true;
- if (m_queue.Enqueue(req))
+ try
{
- req.WaitForComplete();
- if (req.Exception != null)
- throw req.Exception;
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ if (m_queue.Enqueue(req))
+ {
+ req.WaitForComplete();
+ if (req.Exception != null)
+ throw req.Exception;
+ }
+ }
+ finally
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
}
if (m_lastException != null)
@@ -1292,11 +1373,19 @@ namespace Duplicati.Library.Main
throw m_lastException;
var req = new FileEntryItem(OperationType.List, null);
- if (m_queue.Enqueue(req))
+ try
{
- req.WaitForComplete();
- if (req.Exception != null)
- throw req.Exception;
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ if (m_queue.Enqueue(req))
+ {
+ req.WaitForComplete();
+ if (req.Exception != null)
+ throw req.Exception;
+ }
+ }
+ finally
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
}
if (m_lastException != null)
@@ -1307,34 +1396,49 @@ namespace Duplicati.Library.Main
public void WaitForComplete(LocalDatabase db, System.Data.IDbTransaction transation)
{
- m_db.FlushDbMessages(db, transation);
- if (m_lastException != null)
- throw m_lastException;
+ try
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ m_db.FlushDbMessages(db, transation);
+ if (m_lastException != null)
+ throw m_lastException;
- var item = new FileEntryItem(OperationType.Terminate, null);
- if (m_queue.Enqueue(item))
- item.WaitForComplete();
+ var item = new FileEntryItem(OperationType.Terminate, null);
+ if (m_queue.Enqueue(item))
+ item.WaitForComplete();
- m_db.FlushDbMessages(db, transation);
+ m_db.FlushDbMessages(db, transation);
- if (m_lastException != null)
- throw m_lastException;
+ if (m_lastException != null)
+ throw m_lastException;
+ }
+ finally
+ {
+ }
}
public void WaitForEmpty(LocalDatabase db, System.Data.IDbTransaction transation)
{
- m_db.FlushDbMessages(db, transation);
- if (m_lastException != null)
- throw m_lastException;
+ try
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ m_db.FlushDbMessages(db, transation);
+ if (m_lastException != null)
+ throw m_lastException;
- var item = new FileEntryItem(OperationType.Nothing, null);
- if (m_queue.Enqueue(item))
- item.WaitForComplete();
+ var item = new FileEntryItem(OperationType.Nothing, null);
+ if (m_queue.Enqueue(item))
+ item.WaitForComplete();
- m_db.FlushDbMessages(db, transation);
+ m_db.FlushDbMessages(db, transation);
- if (m_lastException != null)
- throw m_lastException;
+ if (m_lastException != null)
+ throw m_lastException;
+ }
+ finally
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
+ }
}
public void CreateFolder(string remotename)
@@ -1343,11 +1447,19 @@ namespace Duplicati.Library.Main
throw m_lastException;
var req = new FileEntryItem(OperationType.CreateFolder, remotename);
- if (m_queue.Enqueue(req))
+ try
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ if (m_queue.Enqueue(req))
+ {
+ req.WaitForComplete();
+ if (req.Exception != null)
+ throw req.Exception;
+ }
+ }
+ finally
{
- req.WaitForComplete();
- if (req.Exception != null)
- throw req.Exception;
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
}
if (m_lastException != null)
@@ -1361,11 +1473,19 @@ namespace Duplicati.Library.Main
m_db.LogDbUpdate(remotename, RemoteVolumeState.Deleting, size, null);
var req = new FileEntryItem(OperationType.Delete, remotename, size, null);
- if (m_queue.Enqueue(req) && synchronous)
+ try
+ {
+ m_statwriter.BackendProgressUpdater.SetBlocking(true);
+ if (m_queue.Enqueue(req) && synchronous)
+ {
+ req.WaitForComplete();
+ if (req.Exception != null)
+ throw req.Exception;
+ }
+ }
+ finally
{
- req.WaitForComplete();
- if (req.Exception != null)
- throw req.Exception;
+ m_statwriter.BackendProgressUpdater.SetBlocking(false);
}
if (m_lastException != null)
diff --git a/Duplicati/Library/Main/Blockprocessor.cs b/Duplicati/Library/Main/Blockprocessor.cs
index 81bf49621..fa8d8e75a 100644
--- a/Duplicati/Library/Main/Blockprocessor.cs
+++ b/Duplicati/Library/Main/Blockprocessor.cs
@@ -10,6 +10,7 @@ namespace Duplicati.Library.Main
{
private Stream m_stream;
private byte[] m_buffer;
+ private bool m_depleted = false;
public Blockprocessor(Stream stream, byte[] buffer)
{
@@ -25,6 +26,9 @@ namespace Duplicati.Library.Main
public int Readblock()
{
+ if (m_depleted)
+ return 0;
+
var bytesleft = m_buffer.Length;
var bytesread = 0;
var read = 1;
@@ -36,6 +40,8 @@ namespace Duplicati.Library.Main
bytesread += read;
}
+ m_depleted = bytesleft != 0;
+
return bytesread;
}
diff --git a/Duplicati/Library/Main/Controller.cs b/Duplicati/Library/Main/Controller.cs
index 6310103bd..8bdf91a92 100644
--- a/Duplicati/Library/Main/Controller.cs
+++ b/Duplicati/Library/Main/Controller.cs
@@ -43,9 +43,14 @@ namespace Duplicati.Library.Main
private IMessageSink m_messageSink;
/// <summary>
- /// A flag indicating if logging has been set, used to dispose the logging
+ /// The stream log, if any
/// </summary>
- private bool m_hasSetLogging = false;
+ private Logging.StreamLog m_logfile = null;
+
+ /// <summary>
+ /// The logging filescope
+ /// </summary>
+ private IDisposable m_logfilescope = null;
/// <summary>
/// The current executing task
@@ -168,49 +173,127 @@ namespace Duplicati.Library.Main
m_messageSink = messageSink;
}
+ /// <summary>
+ /// Appends another message sink to the controller
+ /// </summary>
+ /// <param name="sink">The sink to use.</param>
+ public void AppendSink(IMessageSink sink)
+ {
+ if (m_messageSink is MultiMessageSink)
+ ((MultiMessageSink)m_messageSink).Append(sink);
+ else
+ m_messageSink = new MultiMessageSink(m_messageSink, sink);
+ }
+
public Duplicati.Library.Interface.IBackupResults Backup(string[] inputsources, IFilter filter = null)
{
Library.UsageReporter.Reporter.Report("USE_BACKEND", new Library.Utility.Uri(m_backend).Scheme);
Library.UsageReporter.Reporter.Report("USE_COMPRESSION", m_options.CompressionModule);
Library.UsageReporter.Reporter.Report("USE_ENCRYPTION", m_options.EncryptionModule);
-
+
return RunAction(new BackupResults(), ref inputsources, ref filter, (result) => {
if (inputsources == null || inputsources.Length == 0)
- throw new Exception(Strings.Controller.NoSourceFoldersError);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.Controller.NoSourceFoldersError);
- var sources = new List<string>(inputsources);
+ var sources = new List<string>(inputsources.Length);
+
+ System.IO.DriveInfo[] drives = null;
//Make sure they all have the same format and exist
- for(int i = 0; i < sources.Count; i++)
+ for (int i = 0; i < inputsources.Length; i++)
{
- try
+ List<string> expandedSources = new List<string>();
+
+ if (Library.Utility.Utility.IsClientWindows && (inputsources[i].StartsWith("*:") || inputsources[i].StartsWith("?:")))
{
- sources[i] = System.IO.Path.GetFullPath(sources[i]);
+ // *: drive paths are only supported on Windows clients
+ // Lazily load the drive info
+ drives = drives ?? System.IO.DriveInfo.GetDrives();
+
+ // Replace the drive letter with each available drive
+ string sourcePath = inputsources[i].Substring(1);
+ foreach (System.IO.DriveInfo drive in drives)
+ {
+ string expandedSource = drive.Name[0] + sourcePath;
+ result.AddVerboseMessage(@"Adding source path ""{0}"" due to wildcard source path ""{1}""", expandedSource, inputsources[i]);
+ expandedSources.Add(expandedSource);
+ }
}
- catch (Exception ex)
+ else if (Library.Utility.Utility.IsClientWindows && inputsources[i].StartsWith(@"\\?\Volume{", StringComparison.OrdinalIgnoreCase))
{
- throw new ArgumentException(Strings.Controller.InvalidPathError(sources[i], ex.Message), ex);
+ // In order to specify a drive by it's volume name, adopt the volume guid path syntax:
+ // \\?\Volume{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
+ // The volume guid can be found using the 'mountvol' commandline tool.
+ // However, instead of using this path with Windows APIs directory, it is adapted here to a standard path.
+ Guid volumeGuid;
+ if (Guid.TryParse(inputsources[i].Substring(@"\\?\Volume{".Length, @"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX".Length), out volumeGuid))
+ {
+ string driveLetter = Library.Utility.Utility.GetDriveLetterFromVolumeGuid(volumeGuid);
+ if (!string.IsNullOrEmpty(driveLetter))
+ {
+ string expandedSource = driveLetter + inputsources[i].Substring(@"\\?\Volume{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".Length);
+ result.AddVerboseMessage(@"Adding source path ""{0}"" in place of volume guid source path ""{1}""", expandedSource, inputsources[i]);
+ expandedSources.Add(expandedSource);
+ }
+ else
+ {
+ // If we aren't allow to have missing sources, throw an exception indicating we couldn't find a drive where this volume is mounted
+ if (!m_options.AllowMissingSource)
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.Controller.SourceVolumeNameNotFoundError(inputsources[i], volumeGuid));
+ }
+ }
+ else
+ {
+ // If we aren't allow to have missing sources, throw an exception indicating we couldn't find this volume
+ if (!m_options.AllowMissingSource)
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.Controller.SourceVolumeNameInvalidError(inputsources[i]));
+ }
+ }
+ else
+ {
+ expandedSources.Add(inputsources[i]);
}
- var fi = new System.IO.FileInfo(sources[i]);
- var di = new System.IO.DirectoryInfo(sources[i]);
- if (!(fi.Exists || di.Exists) && !m_options.AllowMissingSource)
- throw new System.IO.IOException(Strings.Controller.SourceIsMissingError(sources[i]));
+ bool foundAnyPaths = false;
+ foreach (string expandedSource in expandedSources)
+ {
+ string source;
+ try
+ {
+ source = System.IO.Path.GetFullPath(expandedSource);
+ }
+ catch (Exception ex)
+ {
+ // Note that we use the original source (with the *) in the error
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.Controller.InvalidPathError(expandedSource, ex.Message), ex);
+ }
- if (!fi.Exists)
- sources[i] = Library.Utility.Utility.AppendDirSeparator(sources[i]);
+ var fi = new System.IO.FileInfo(source);
+ var di = new System.IO.DirectoryInfo(source);
+ if (fi.Exists || di.Exists)
+ {
+ foundAnyPaths = true;
+
+ if (!fi.Exists)
+ source = Library.Utility.Utility.AppendDirSeparator(source);
+
+ sources.Add(source);
+ }
+ }
+
+ // If no paths were found, and we aren't allowed to have missing sources, throw an error
+ if (!foundAnyPaths && !m_options.AllowMissingSource)
+ throw new System.IO.IOException(Strings.Controller.SourceIsMissingError(inputsources[i]));
}
//Sanity check for duplicate files/folders
- var pathDuplicates = sources.GroupBy(x => x, Library.Utility.Utility.ClientFilenameStringComparer)
- .Where(g => g.Count() > 1).Select(y => y.Key).ToList();
+ ISet<string> pathDuplicates;
+ sources = Library.Utility.Utility.GetUniqueItems(sources, Library.Utility.Utility.ClientFilenameStringComparer, out pathDuplicates).OrderBy(a => a).ToList();
foreach (var pathDuplicate in pathDuplicates)
result.AddVerboseMessage(string.Format("Removing duplicate source: {0}", pathDuplicate));
- sources = sources.Distinct(Library.Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList();
-
//Sanity check for multiple inclusions of the same folder
for (int i = 0; i < sources.Count; i++)
for (int j = 0; j < sources.Count; j++)
@@ -305,6 +388,52 @@ namespace Duplicati.Library.Main
});
}
+ public Duplicati.Library.Interface.IListRemoteResults ListRemote()
+ {
+ return RunAction(new ListRemoteResults(), (result) =>
+ {
+ using (var tf = System.IO.File.Exists(m_options.Dbpath) ? null : new Library.Utility.TempFile())
+ using (var db = new Database.LocalDatabase(((string)tf) ?? m_options.Dbpath, "list-remote", true))
+ using (var bk = new BackendManager(m_backend, m_options, result.BackendWriter, null))
+ result.SetResult(bk.List());
+ });
+ }
+
+ public Duplicati.Library.Interface.IListRemoteResults DeleteAllRemoteFiles()
+ {
+ return RunAction(new ListRemoteResults(), (result) =>
+ {
+ result.OperationProgressUpdater.UpdatePhase(OperationPhase.Delete_Listing);
+ using (var tf = System.IO.File.Exists(m_options.Dbpath) ? null : new Library.Utility.TempFile())
+ using (var db = new Database.LocalDatabase(((string)tf) ?? m_options.Dbpath, "list-remote", true))
+ using (var bk = new BackendManager(m_backend, m_options, result.BackendWriter, null))
+ {
+ // Only delete files that match the expected pattern and prefix
+ var list = bk.List()
+ .Select(x => Volumes.VolumeBase.ParseFilename(x))
+ .Where(x => x != null)
+ .Where(x => x.Prefix == m_options.Prefix)
+ .ToList();
+
+ result.OperationProgressUpdater.UpdatePhase(OperationPhase.Delete_Deleting);
+ result.OperationProgressUpdater.UpdateProgress(0);
+ for (var i = 0; i < list.Count; i++)
+ {
+ try
+ {
+ bk.Delete(list[i].File.Name, list[i].File.Size, true);
+ }
+ catch (Exception ex)
+ {
+ result.AddWarning(string.Format("Failed to delete remote file: {0}", list[i].File.Name), ex);
+ }
+ result.OperationProgressUpdater.UpdateProgress((float)i / list.Count);
+ }
+ result.OperationProgressUpdater.UpdateProgress(1);
+ }
+ });
+ }
+
public Duplicati.Library.Interface.ICompactResults Compact()
{
return RunAction(new CompactResults(), (result) => {
@@ -343,24 +472,27 @@ namespace Duplicati.Library.Main
});
}
- public Duplicati.Library.Interface.IListChangesResults ListChanges(string baseVersion, string targetVersion, IEnumerable<string> filterstrings = null, Library.Utility.IFilter filter = null)
+ public Duplicati.Library.Interface.IListChangesResults ListChanges(string baseVersion, string targetVersion, IEnumerable<string> filterstrings = null, Library.Utility.IFilter filter = null, Action<Duplicati.Library.Interface.IListChangesResults, IEnumerable<Tuple<Library.Interface.ListChangesChangeType, Library.Interface.ListChangesElementType, string>>> callback = null)
{
var t = new string[] { baseVersion, targetVersion };
return RunAction(new ListChangesResults(), ref t, ref filter, (result) => {
- new Operation.ListChangesHandler(m_backend, m_options, result).Run(t[0], t[1], filterstrings, filter);
+ new Operation.ListChangesHandler(m_backend, m_options, result).Run(t[0], t[1], filterstrings, filter, callback);
});
}
- public Duplicati.Library.Interface.IListAffectedResults ListAffected(List<string> args)
+ public Duplicati.Library.Interface.IListAffectedResults ListAffected(List<string> args, Action<Duplicati.Library.Interface.IListAffectedResults> callback = null)
{
return RunAction(new ListAffectedResults(), (result) => {
- new Operation.ListAffected(m_options, result).Run(args);
+ new Operation.ListAffected(m_options, result).Run(args, callback);
});
}
public Duplicati.Library.Interface.ITestResults Test(long samples = 1)
{
+ if (!m_options.RawOptions.ContainsKey("full-remote-verification"))
+ m_options.RawOptions["full-remote-verification"] = "true";
+
return RunAction(new TestResults(), (result) => {
new Operation.TestHandler(m_backend, m_options, result).Run(samples);
});
@@ -384,8 +516,67 @@ namespace Duplicati.Library.Main
});
}
+ public Library.Interface.IPurgeFilesResults PurgeFiles(Library.Utility.IFilter filter)
+ {
+ return RunAction(new PurgeFilesResults(), result =>
+ {
+ new Operation.PurgeFilesHandler(m_backend, m_options, result).Run(filter);
+ });
+ }
+
+ public Library.Interface.IListBrokenFilesResults ListBrokenFiles(Library.Utility.IFilter filter, Func<long, DateTime, long, string, long, bool> callbackhandler = null)
+ {
+ return RunAction(new ListBrokenFilesResults(), result =>
+ {
+ new Operation.ListBrokenFilesHandler(m_backend, m_options, result).Run(filter, callbackhandler);
+ });
+ }
+
+ public Library.Interface.IPurgeBrokenFilesResults PurgeBrokenFiles(Library.Utility.IFilter filter)
+ {
+ return RunAction(new PurgeBrokenFilesResults(), result =>
+ {
+ new Operation.PurgeBrokenFilesHandler(m_backend, m_options, result).Run(filter);
+ });
+ }
+
+ public Library.Interface.ISendMailResults SendMail()
+ {
+ m_options.RawOptions["send-mail-level"] = "all";
+ m_options.RawOptions["send-mail-any-operation"] = "true";
+ string targetmail;
+ m_options.RawOptions.TryGetValue("send-mail-to", out targetmail);
+ if (string.IsNullOrWhiteSpace(targetmail))
+ throw new Exception(string.Format("No email specified, please use --{0}", "send-mail-to"));
+
+ if (m_options.Loglevel == Logging.LogMessageType.Error)
+ m_options.RawOptions["log-level"] = Logging.LogMessageType.Warning.ToString();
+
+ m_options.RawOptions["disable-module"] = string.Join(
+ ",",
+ DynamicLoader.GenericLoader.Modules
+ .Where(m =>
+ !(m is Library.Interface.IConnectionModule) && m.GetType().FullName != "Duplicati.Library.Modules.Builtin.SendMail"
+ )
+ .Select(x => x.Key)
+ );
+
+ return RunAction(new SendMailResults(), result =>
+ {
+ result.Lines = new string[0];
+ System.Threading.Thread.Sleep(5);
+ });
+ }
+
+ public Library.Interface.IVacuumResults Vacuum()
+ {
+ return RunAction(new VacuumResult(), result => {
+ new Operation.VacuumHandler(m_options, result).Run();
+ });
+ }
+
private T RunAction<T>(T result, Action<T> method)
- where T : ISetCommonOptions, ITaskControl
+ where T : ISetCommonOptions, ITaskControl, Logging.ILog
{
var tmp = new string[0];
IFilter tempfilter = null;
@@ -393,57 +584,63 @@ namespace Duplicati.Library.Main
}
private T RunAction<T>(T result, ref string[] paths, Action<T> method)
- where T : ISetCommonOptions, ITaskControl
+ where T : ISetCommonOptions, ITaskControl, Logging.ILog
{
IFilter tempfilter = null;
return RunAction<T>(result, ref paths, ref tempfilter, method);
}
private T RunAction<T>(T result, ref IFilter filter, Action<T> method)
- where T : ISetCommonOptions, ITaskControl
+ where T : ISetCommonOptions, ITaskControl, Logging.ILog
{
var tmp = new string[0];
return RunAction<T>(result, ref tmp, ref filter, method);
}
private T RunAction<T>(T result, ref string[] paths, ref IFilter filter, Action<T> method)
- where T : ISetCommonOptions, ITaskControl
+ where T : ISetCommonOptions, ITaskControl, Logging.ILog
{
- try
+ using (Logging.Log.StartScope(result))
{
- m_currentTask = result;
- m_currentTaskThread = System.Threading.Thread.CurrentThread;
- using(new Logging.Timer(string.Format("Running {0}", result.MainOperation)))
+ try
{
+ m_currentTask = result;
+ m_currentTaskThread = System.Threading.Thread.CurrentThread;
SetupCommonOptions(result, ref paths, ref filter);
- method(result);
+ result.WriteLogMessageDirect(Strings.Controller.StartingOperationMessage(m_options.MainAction), Logging.LogMessageType.Information, null);
- result.EndTime = DateTime.UtcNow;
+ using (new Logging.Timer(string.Format("Running {0}", result.MainOperation)))
+ method(result);
+
+ if (result.EndTime.Ticks == 0)
+ result.EndTime = DateTime.UtcNow;
result.SetDatabase(null);
OnOperationComplete(result);
- Library.Logging.Log.WriteMessage(Strings.Controller.CompletedOperationMessage(m_options.MainAction), Logging.LogMessageType.Information);
+ result.WriteLogMessageDirect(Strings.Controller.CompletedOperationMessage(m_options.MainAction), Logging.LogMessageType.Information, null);
return result;
}
- }
- catch (Exception ex)
- {
- OnOperationComplete(ex);
+ catch (Exception ex)
+ {
+ result.EndTime = DateTime.UtcNow;
- try { (result as BasicResults).OperationProgressUpdater.UpdatePhase(OperationPhase.Error); }
- catch { }
+ try { (result as BasicResults).OperationProgressUpdater.UpdatePhase(OperationPhase.Error); }
+ catch { }
- Library.Logging.Log.WriteMessage(Strings.Controller.FailedOperationMessage(m_options.MainAction, ex.Message), Logging.LogMessageType.Error, ex);
+ OnOperationComplete(ex);
- throw;
- }
- finally
- {
- m_currentTask = null;
- m_currentTaskThread = null;
+ result.WriteLogMessageDirect(Strings.Controller.FailedOperationMessage(m_options.MainAction, ex.Message), Logging.LogMessageType.Error, ex);
+
+ throw;
+ }
+ finally
+ {
+ m_currentTask = null;
+ m_currentTaskThread = null;
+ }
}
}
@@ -516,13 +713,18 @@ namespace Duplicati.Library.Main
}
}
- if (m_hasSetLogging && Logging.Log.CurrentLog is Logging.StreamLog)
+ if (m_logfilescope != null)
+ {
+ m_logfilescope.Dispose();
+ m_logfilescope = null;
+ }
+
+ if (m_logfile != null)
{
- Logging.StreamLog sl = (Logging.StreamLog)Logging.Log.CurrentLog;
- Logging.Log.CurrentLog = null;
- sl.Dispose();
- m_hasSetLogging = false;
+ m_logfile.Dispose();
+ m_logfile = null;
}
+
}
private void SetupCommonOptions(ISetCommonOptions result, ref string[] paths, ref IFilter filter)
@@ -548,15 +750,17 @@ namespace Duplicati.Library.Main
foreach (Library.Interface.IGenericModule m in DynamicLoader.GenericLoader.Modules)
m_options.LoadedModules.Add(new KeyValuePair<bool, Library.Interface.IGenericModule>(Array.IndexOf<string>(m_options.DisableModules, m.Key.ToLower()) < 0 && (m.LoadAsDefault || Array.IndexOf<string>(m_options.EnableModules, m.Key.ToLower()) >= 0), m));
+ // Make the filter read-n-write able in the generic modules
+ var pristinefilter = string.Join(System.IO.Path.PathSeparator.ToString(), FilterExpression.Serialize(filter));
+ m_options.RawOptions["filter"] = pristinefilter;
+
+ // Store the URL connection options separately, as these should only be visible to modules implementing IConnectionModule
var conopts = new Dictionary<string, string>(m_options.RawOptions);
var qp = new Library.Utility.Uri(m_backend).QueryParameters;
- foreach(var k in qp.Keys)
+ foreach (var k in qp.Keys)
conopts[(string)k] = qp[(string)k];
- // Make the filter read-n-write able in the generic modules
- var pristinefilter = conopts["filter"] = string.Join(System.IO.Path.PathSeparator.ToString(), FilterExpression.Serialize(filter));
-
- foreach (KeyValuePair<bool, Library.Interface.IGenericModule> mx in m_options.LoadedModules)
+ foreach (var mx in m_options.LoadedModules)
if (mx.Key)
{
if (mx.Value is Library.Interface.IConnectionModule)
@@ -564,13 +768,29 @@ namespace Duplicati.Library.Main
else
mx.Value.Configure(m_options.RawOptions);
+ if (mx.Value is Library.Interface.IGenericSourceModule)
+ {
+ var sourcemodule = (Library.Interface.IGenericSourceModule)mx.Value;
+
+ if (sourcemodule.ContainFilesForBackup(paths))
+ {
+ var sourceoptions = sourcemodule.ParseSourcePaths(ref paths, ref pristinefilter, m_options.RawOptions);
+
+ foreach (var sourceoption in sourceoptions)
+ m_options.RawOptions[sourceoption.Key] = sourceoption.Value;
+ }
+ }
+
if (mx.Value is Library.Interface.IGenericCallbackModule)
((Library.Interface.IGenericCallbackModule)mx.Value).OnStart(result.MainOperation.ToString(), ref m_backend, ref paths);
}
- // If the filters were changed, read them back in
- if (pristinefilter != conopts["filter"])
- filter = FilterExpression.Deserialize(conopts["filter"].Split(new string[] {System.IO.Path.PathSeparator.ToString()}, StringSplitOptions.RemoveEmptyEntries));
+ // If the filters were changed by a module, read them back in
+ if (pristinefilter != m_options.RawOptions["filter"])
+ {
+ filter = FilterExpression.Deserialize(m_options.RawOptions["filter"].Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries));
+ }
+ m_options.RawOptions.Remove("filter"); // "--filter" is not a supported command line option
OperationRunning(true);
@@ -579,11 +799,11 @@ namespace Duplicati.Library.Main
if (!string.IsNullOrEmpty(m_options.Logfile))
{
- m_hasSetLogging = true;
var path = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(m_options.Logfile));
if (!System.IO.Directory.Exists(path))
System.IO.Directory.CreateDirectory(path);
- Library.Logging.Log.CurrentLog = new Library.Logging.StreamLog(m_options.Logfile);
+
+ m_logfilescope = Logging.Log.StartScope(m_logfile = new Library.Logging.StreamLog(m_options.Logfile));
}
result.VerboseErrors = m_options.DebugOutput;
@@ -634,21 +854,36 @@ namespace Duplicati.Library.Main
m_options.Dbpath = DatabaseLocator.GetDatabasePath(m_backend, m_options);
ValidateOptions(result);
-
- Library.Logging.Log.WriteMessage(Strings.Controller.StartingOperationMessage(m_options.MainAction), Logging.LogMessageType.Information);
}
/// <summary>
/// This function will examine all options passed on the commandline, and test for unsupported or deprecated values.
/// Any errors will be logged into the statistics module.
/// </summary>
- /// <param name="options">The commandline options given</param>
- /// <param name="backend">The backend url</param>
- /// <param name="stats">The statistics into which warnings are written</param>
+ /// <param name="log">The log instance</param>
private void ValidateOptions(ILogWriter log)
{
if (m_options.KeepTime.Ticks > 0 && m_options.KeepVersions > 0)
- throw new Exception(string.Format("Setting both --{0} and --{1} is not permitted", "keep-versions", "keep-time"));
+ throw new Interface.UserInformationException(string.Format("Setting both --{0} and --{1} is not permitted", "keep-versions", "keep-time"));
+
+ if (!string.IsNullOrWhiteSpace(m_options.Prefix) && m_options.Prefix.Contains("-"))
+ throw new Interface.UserInformationException("The prefix cannot contain hyphens (-)");
+
+ //Check validity of retention-policy option value
+ try
+ {
+ foreach (var configEntry in m_options.RetentionPolicy)
+ {
+ if (configEntry.Value >= configEntry.Key)
+ {
+ throw new Interface.UserInformationException("A time frame cannot be smaller than its interval");
+ }
+ }
+ }
+ catch (Exception e) // simply reading the option value might also result in an exception due to incorrect formatting
+ {
+ throw new Interface.UserInformationException(string.Format("An error occoured while processing the value of --{0}", "retention-policy"), e);
+ }
//No point in going through with this if we can't report
if (log == null)
@@ -673,7 +908,6 @@ namespace Duplicati.Library.Main
if (m.Key)
moduleOptions.AddRange(m.Value.SupportedCommands);
else
- {
foreach (Library.Interface.ICommandLineArgument c in m.Value.SupportedCommands)
{
disabledModuleOptions[c.Name] = m.Value.DisplayName + " (" + m.Value.Key + ")";
@@ -682,7 +916,6 @@ namespace Duplicati.Library.Main
foreach (string s in c.Aliases)
disabledModuleOptions[s] = disabledModuleOptions[c.Name];
}
- }
// Throw url-encoded options into the mix
//TODO: This can hide values if both commandline and url-parameters supply the same key
@@ -879,6 +1112,18 @@ namespace Duplicati.Library.Main
t.Abort();
}
+ public long MaxUploadSpeed
+ {
+ get { return m_options.MaxUploadPrSecond; }
+ set { m_options.MaxUploadPrSecond = value; }
+ }
+
+ public long MaxDownloadSpeed
+ {
+ get { return m_options.MaxDownloadPrSecond; }
+ set { m_options.MaxDownloadPrSecond = value; }
+ }
+
#region IDisposable Members
public void Dispose()
diff --git a/Duplicati/Library/Main/Database/Database schema/7. Add index.sql b/Duplicati/Library/Main/Database/Database schema/7. Add index.sql
new file mode 100644
index 000000000..0a06fb65a
--- /dev/null
+++ b/Duplicati/Library/Main/Database/Database schema/7. Add index.sql
@@ -0,0 +1,3 @@
+CREATE UNIQUE INDEX "BlocklistHashBlocksetIDIndex" ON "BlocklistHash" ("BlocksetID", "Index");
+
+UPDATE "Version" SET "Version" = 7;
diff --git a/Duplicati/Library/Main/Database/Database schema/Schema.sql b/Duplicati/Library/Main/Database/Database schema/Schema.sql
index e292d7335..74109b6c0 100644
--- a/Duplicati/Library/Main/Database/Database schema/Schema.sql
+++ b/Duplicati/Library/Main/Database/Database schema/Schema.sql
@@ -110,6 +110,9 @@ CREATE TABLE "BlocklistHash" (
"Hash" TEXT NOT NULL
);
+/* Faster database recreation */
+CREATE UNIQUE INDEX "BlocklistHashBlocksetIDIndex" ON "BlocklistHash" ("BlocksetID", "Index");
+
/*
The blockset is a list of blocks
Note that Length is actually redundant,
@@ -241,4 +244,4 @@ CREATE TABLE "Configuration" (
"Value" TEXT NOT NULL
);
-INSERT INTO "Version" ("Version") VALUES (6);
+INSERT INTO "Version" ("Version") VALUES (7);
diff --git a/Duplicati/Library/Main/Database/ExtensionMethods.cs b/Duplicati/Library/Main/Database/ExtensionMethods.cs
index 351269721..55b39ccda 100644
--- a/Duplicati/Library/Main/Database/ExtensionMethods.cs
+++ b/Duplicati/Library/Main/Database/ExtensionMethods.cs
@@ -87,7 +87,7 @@ namespace Duplicati.Library.Main.Database
self.AddParameter(n);
}
- using(new Logging.Timer(LC.L("ExecuteScalar: {0}", self.CommandText)))
+ using(new Logging.Timer(LC.L("ExecuteScalarInt64: {0}", self.CommandText)))
using(var rd = self.ExecuteReader())
if (rd.Read())
return ConvertValueToInt64(rd, 0, defaultvalue);
@@ -138,7 +138,7 @@ namespace Duplicati.Library.Main.Database
{
}
- return -1;
+ return defaultvalue;
}
public static System.Data.IDbCommand CreateCommand(this System.Data.IDbConnection self, System.Data.IDbTransaction transaction)
diff --git a/Duplicati/Library/Main/Database/LocalBackupDatabase.cs b/Duplicati/Library/Main/Database/LocalBackupDatabase.cs
index 2de6fe011..d4d7bea62 100644
--- a/Duplicati/Library/Main/Database/LocalBackupDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalBackupDatabase.cs
@@ -77,18 +77,15 @@ namespace Duplicati.Library.Main.Database
private readonly System.Data.IDbCommand m_insertmetadatasetCommand;
- private readonly System.Data.IDbCommand m_selectfileSimpleCommand;
+ private readonly System.Data.IDbCommand m_findfileCommand;
+ private readonly System.Data.IDbCommand m_selectfilelastmodifiedCommand;
private readonly System.Data.IDbCommand m_selectfileHashCommand;
private readonly System.Data.IDbCommand m_selectblocklistHashesCommand;
private readonly System.Data.IDbCommand m_insertfileOperationCommand;
- private HashLookupHelper<KeyValuePair<long, long>> m_blockHashLookup;
- private HashLookupHelper<long> m_fileHashLookup;
- private HashLookupHelper<long> m_metadataLookup;
private PathLookupHelper<PathEntryKeeper> m_pathLookup;
-
- private long m_missingBlockHashes;
+ private Dictionary<string, long> m_blockCache;
private long m_filesetId;
@@ -113,7 +110,8 @@ namespace Duplicati.Library.Main.Database
m_insertblocklistHashesCommand = m_connection.CreateCommand();
m_selectblocklistHashesCommand = m_connection.CreateCommand();
m_insertfileOperationCommand = m_connection.CreateCommand();
- m_selectfileSimpleCommand = m_connection.CreateCommand();
+ m_findfileCommand = m_connection.CreateCommand();
+ m_selectfilelastmodifiedCommand = m_connection.CreateCommand();
m_selectfileHashCommand = m_connection.CreateCommand();
m_insertblocksetentryFastCommand = m_connection.CreateCommand();
@@ -153,8 +151,11 @@ namespace Duplicati.Library.Main.Database
m_insertmetadatasetCommand.CommandText = @"INSERT INTO ""Metadataset"" (""BlocksetID"") VALUES (?); SELECT last_insert_rowid();";
m_insertmetadatasetCommand.AddParameter();
+ m_selectfilelastmodifiedCommand.CommandText = @"SELECT ""A"".""ID"", ""B"".""LastModified"" FROM (SELECT ""ID"" FROM ""File"" WHERE ""Path"" = ?) ""A"" CROSS JOIN ""FilesetEntry"" ""B"" WHERE ""A"".""ID"" = ""B"".""FileID"" AND ""B"".""FilesetID"" = ?";
+ m_selectfilelastmodifiedCommand.AddParameters(2);
+
//Need a temporary table with path/lastmodified lookups
- m_selectfileSimpleCommand.CommandText =
+ m_findfileCommand.CommandText =
@" SELECT ""File"".""ID"" AS ""FileID"", ""FilesetEntry"".""Lastmodified"", ""FileBlockset"".""Length"", ""MetaBlockset"".""Fullhash"" AS ""Metahash"", ""MetaBlockset"".""Length"" AS ""Metasize"" " +
@" FROM ""File"", ""FilesetEntry"", ""Fileset"", ""Blockset"" ""FileBlockset"", ""Metadataset"", ""Blockset"" ""MetaBlockset"" " +
@" WHERE ""File"".""Path"" = ? " +
@@ -163,7 +164,7 @@ namespace Duplicati.Library.Main.Database
@" AND ""Metadataset"".""ID"" = ""File"".""MetadataID"" AND ""MetaBlockset"".""ID"" = ""Metadataset"".""BlocksetID"" " +
@" ORDER BY ""Fileset"".""Timestamp"" DESC " +
@" LIMIT 1 ";
- m_selectfileSimpleCommand.AddParameters(1);
+ m_findfileCommand.AddParameters(1);
m_selectfileHashCommand.CommandText = @"SELECT ""Blockset"".""Fullhash"" FROM ""Blockset"", ""File"" WHERE ""Blockset"".""ID"" = ""File"".""BlocksetID"" AND ""File"".""ID"" = ? ";
m_selectfileHashCommand.AddParameters(1);
@@ -178,12 +179,6 @@ namespace Duplicati.Library.Main.Database
/// <param name="options">The option settings</param>
public void BuildLookupTable(Options options)
{
- if (options.BlockHashLookupMemory > 0)
- m_blockHashLookup = new HashLookupHelper<KeyValuePair<long, long>>((ulong)options.BlockHashLookupMemory);
- if (options.FileHashLookupMemory > 0)
- m_fileHashLookup = new HashLookupHelper<long>((ulong)options.FileHashLookupMemory);
- if (options.MetadataHashMemory > 0)
- m_metadataLookup = new HashLookupHelper<long>((ulong)options.MetadataHashMemory);
if (options.UseFilepathCache)
m_pathLookup = new PathLookupHelper<PathEntryKeeper>(true);
@@ -206,61 +201,6 @@ namespace Duplicati.Library.Main.Database
@" AND ""A1"".""MetadataID"" = ""E"".""ID"" " +
@" AND ""F"".""ID"" = ""E"".""BlocksetID"" ";
- if (m_blockHashLookup != null)
- try
- {
- using(new Logging.Timer("Build blockhash lookup table"))
- using (var rd = cmd.ExecuteReader(@"SELECT DISTINCT ""Block"".""Hash"", ""Block"".""ID"", ""Block"".""Size"" FROM ""Block"" "))
- while (rd.Read())
- {
- var str = rd.GetValue(0).ToString();
- var id = rd.GetInt64(1);
- var size = rd.GetInt64(2);
- m_blockHashLookup.Add(str, size, new KeyValuePair<long, long>(id, size));
- }
- }
- catch (Exception ex)
- {
- throw new InvalidDataException("Duplicate blockhashes detected, either repair the database or rebuild it", ex);
- }
-
- if (m_fileHashLookup != null)
- try
- {
- using(new Logging.Timer("Build filehash lookup table"))
- using (var rd = cmd.ExecuteReader(@"SELECT DISTINCT ""FullHash"", ""Length"", ""ID"" FROM ""BlockSet"""))
- while (rd.Read())
- {
- var str = rd.GetValue(0).ToString();
- var size = rd.GetInt64(1);
- var id = rd.GetInt64(2);
- m_fileHashLookup.Add(str, size, id);
- }
- }
- catch (Exception ex)
- {
- throw new InvalidDataException("Duplicate filehashes detected, either repair the database or rebuild it", ex);
- }
-
-
- if (m_metadataLookup != null)
- try
- {
- using(new Logging.Timer("Build metahash lookup table"))
- using (var rd = cmd.ExecuteReader(@"SELECT ""Metadataset"".""ID"", ""Blockset"".""FullHash"", ""Blockset"".""Length"" FROM ""Metadataset"", ""Blockset"" WHERE ""Metadataset"".""BlocksetID"" = ""Blockset"".""ID"" "))
- while (rd.Read())
- {
- var metadataid = rd.GetInt64(0);
- var hash = rd.GetValue(1).ToString();
- var size = rd.GetInt64(2);;
- m_metadataLookup.Add(hash, size, metadataid);
- }
- }
- catch (Exception ex)
- {
- throw new InvalidDataException("Duplicate metadatahash detected, run repair to fix it", ex);
- }
-
if (m_pathLookup != null)
using(new Logging.Timer("Build path lastmodified lookup table"))
using (var rd = cmd.ExecuteReader(string.Format(@" SELECT ""FileID"", ""Lastmodified"", ""Length"", ""Path"", ""Metahash"", ""Metasize"" FROM ({0}) WHERE ""BlocksetID"" >= 0 ", scantableDefinition)))
@@ -302,15 +242,34 @@ namespace Duplicati.Library.Main.Database
{
throw new InvalidDataException("Duplicate file entries detected, run repair to fix it", ex);
}
-
- m_missingBlockHashes = cmd.ExecuteScalarInt64(@"SELECT COUNT (*) FROM (SELECT DISTINCT ""Block"".""Hash"", ""Block"".""Size"" FROM ""Block"", ""RemoteVolume"" WHERE ""RemoteVolume"".""ID"" = ""Block"".""VolumeID"" AND ""RemoteVolume"".""State"" NOT IN (?,?,?,?))", 0, RemoteVolumeState.Temporary.ToString(), RemoteVolumeState.Uploading.ToString(), RemoteVolumeState.Uploaded.ToString(), RemoteVolumeState.Verified.ToString());
var tc = cmd.ExecuteScalarInt64(@"SELECT COUNT(*) FROM ""Remotevolume"" WHERE ""ID"" IN (SELECT DISTINCT ""VolumeID"" FROM ""Block"") AND ""State"" NOT IN (?, ?, ?, ?);", 0, RemoteVolumeState.Temporary.ToString(), RemoteVolumeState.Uploading.ToString(), RemoteVolumeState.Uploaded.ToString(), RemoteVolumeState.Verified.ToString());
if (tc > 0)
throw new InvalidDataException("Detected blocks that are not reachable in the block table");
-
- }
- }
+ }
+
+ if (options.UseBlockCache)
+ {
+ string failedhash = null;
+ try
+ {
+ var cache = new Dictionary<string, long>();
+ using (var cmd = m_connection.CreateCommand())
+ {
+ cmd.CommandText = @"SELECT ""Hash"", ""Size"" From ""Block""";
+ using (var rd = cmd.ExecuteReader())
+ while (rd.Read())
+ cache.Add(failedhash = rd.ConvertValueToString(0), rd.ConvertValueToInt64(1));
+ }
+ m_blockCache = cache;
+ }
+ catch (Exception ex)
+ {
+ Logging.Log.WriteMessage(string.Format("Failed to create block cache, this could mean you have hash collisions in your table, the hash that failed is {0}. Error message: {1}.", failedhash, ex.Message), Logging.LogMessageType.Warning);
+ Logging.Log.WriteMessage(string.Format("Disabling block cache due to error"), Logging.LogMessageType.Warning);
+ }
+ }
+ }
/// <summary>
/// Adds a block to the local database, returning a value indicating if the value presents a new block
@@ -320,21 +279,22 @@ namespace Duplicati.Library.Main.Database
/// <returns>True if the block should be added to the current output</returns>
public bool AddBlock (string key, long size, long volumeid, System.Data.IDbTransaction transaction = null)
{
- var r = -1L;
- if (m_blockHashLookup != null)
+ long exsize;
+
+ if (m_blockCache != null && m_blockCache.TryGetValue(key, out exsize))
{
- KeyValuePair<long, long> blockid;
- if (m_blockHashLookup.TryGet(key, size, out blockid))
+ if (exsize == size)
return false;
- }
- else
- {
- m_findblockCommand.Transaction = transaction;
- m_findblockCommand.SetParameterValue(0, key);
- m_findblockCommand.SetParameterValue(1, size);
- r = m_findblockCommand.ExecuteScalarInt64(-1);
+
+ Logging.Log.WriteMessage(string.Format("Found hash collision on {0}, sizes {1} vs {2}. Disabling cache from now on.", key, size, exsize), Logging.LogMessageType.Warning);
+ m_blockCache = null;
}
+ m_findblockCommand.Transaction = transaction;
+ m_findblockCommand.SetParameterValue(0, key);
+ m_findblockCommand.SetParameterValue(1, size);
+ var r = m_findblockCommand.ExecuteScalarInt64(-1);
+
if (r == -1L)
{
m_insertblockCommand.Transaction = transaction;
@@ -342,16 +302,13 @@ namespace Duplicati.Library.Main.Database
m_insertblockCommand.SetParameterValue(1, volumeid);
m_insertblockCommand.SetParameterValue(2, size);
r = m_insertblockCommand.ExecuteScalarInt64();
- if (m_blockHashLookup != null)
- m_blockHashLookup.Add(key, size, new KeyValuePair<long, long>(r, size));
+ if (m_blockCache != null)
+ m_blockCache.Add(key, size);
return true;
}
else
{
//Update lookup cache if required
- if (m_blockHashLookup != null)
- m_blockHashLookup.Add(key, size, new KeyValuePair<long, long>(r, size));
-
return false;
}
}
@@ -369,27 +326,17 @@ namespace Duplicati.Library.Main.Database
/// <returns>True if the blockset was created, false otherwise</returns>
public bool AddBlockset(string filehash, long size, int blocksize, IEnumerable<string> hashes, IEnumerable<string> blocklistHashes, out long blocksetid, System.Data.IDbTransaction transaction = null)
{
- if (m_fileHashLookup != null)
- {
- if (m_fileHashLookup.TryGet(filehash, size, out blocksetid))
- return false;
- }
- else
- {
- m_findblocksetCommand.Transaction = transaction;
- blocksetid = m_findblocksetCommand.ExecuteScalarInt64(null, -1, filehash, size);
- if (blocksetid != -1)
- return false; //Found it
- }
-
+ m_findblocksetCommand.Transaction = transaction;
+ blocksetid = m_findblocksetCommand.ExecuteScalarInt64(null, -1, filehash, size);
+ if (blocksetid != -1)
+ return false; //Found it
+
using(var tr = new TemporaryTransactionWrapper(m_connection, transaction))
{
m_insertblocksetCommand.Transaction = tr.Parent;
m_insertblocksetCommand.SetParameterValue(0, size);
m_insertblocksetCommand.SetParameterValue(1, filehash);
blocksetid = m_insertblocksetCommand.ExecuteScalarInt64();
- if (m_fileHashLookup != null)
- m_fileHashLookup.Add(filehash, size, blocksetid);
long ix = 0;
if (blocklistHashes != null)
@@ -416,29 +363,23 @@ namespace Duplicati.Library.Main.Database
foreach(var h in hashes)
{
var exsize = remainsize < blocksize ? remainsize : blocksize;
- var found = false;
- if (m_blockHashLookup != null)
+ m_insertblocksetentryCommand.SetParameterValue(1, ix);
+ m_insertblocksetentryCommand.SetParameterValue(2, h);
+ m_insertblocksetentryCommand.SetParameterValue(3, exsize);
+ var c = m_insertblocksetentryCommand.ExecuteNonQuery();
+ if (c != 1)
{
- KeyValuePair<long, long> id;
- if (m_blockHashLookup.TryGet(h, exsize, out id) && id.Value == exsize)
+ m_result.AddError(string.Format("Checking errors, related to #1400. Unexpected result count: {0}, expected {1}, hash: {2}, size: {3}, blocksetid: {4}, ix: {5}, fullhash: {6}, fullsize: {7}", c, 1, h, exsize, blocksetid, ix, filehash, size), null);
+ using (var cmd = m_connection.CreateCommand(tr.Parent))
{
- m_insertblocksetentryFastCommand.SetParameterValue(1, ix);
- m_insertblocksetentryFastCommand.SetParameterValue(2, id.Key);
- var cx = m_insertblocksetentryFastCommand.ExecuteNonQuery();
- if (cx != 1)
- throw new Exception(string.Format("Unexpected result count: {0}, expected {1}", cx, 1));
- found = true;
+ var bid = cmd.ExecuteScalarInt64(@"SELECT ""ID"" FROM ""Block"" WHERE ""Hash"" = ?", -1, h);
+ if (bid == -1)
+ throw new Exception(string.Format("Could not find any blocks with the given hash: {0}", h));
+ foreach(var rd in cmd.ExecuteReaderEnumerable(@"SELECT ""Size"" FROM ""Block"" WHERE ""Hash"" = ?", h))
+ m_result.AddError(string.Format("Found block with ID {0} and hash {1} and size {2}", bid, h, rd.ConvertValueToInt64(0, -1)), null);
}
- }
-
- if (!found)
- {
- m_insertblocksetentryCommand.SetParameterValue(1, ix);
- m_insertblocksetentryCommand.SetParameterValue(2, h);
- m_insertblocksetentryCommand.SetParameterValue(3, exsize);
- var c = m_insertblocksetentryCommand.ExecuteNonQuery();
- if (c != 1)
- throw new Exception(string.Format("Unexpected result count: {0}, expected {1}", c, 1));
+
+ throw new Exception(string.Format("Unexpected result count: {0}, expected {1}, check log for more messages", c, 1));
}
ix++;
@@ -458,26 +399,18 @@ namespace Duplicati.Library.Main.Database
/// <param name="hash">The metadata hash</param>
/// <param name="metadataid">The id of the metadata set</param>
/// <returns>True if the set was added to the database, false otherwise</returns>
- public bool AddMetadataset(string hash, long size, out long metadataid, System.Data.IDbTransaction transaction = null)
+ public bool AddMetadataset(string filehash, long size, int blocksize, IEnumerable<string> blockhashes, IEnumerable<string> blocklisthashes, out long metadataid, System.Data.IDbTransaction transaction = null)
{
if (size > 0)
{
- if (m_metadataLookup != null)
- {
- if(m_metadataLookup.TryGet(hash, size, out metadataid))
- return false;
- }
- else
- {
- m_findmetadatasetCommand.Transaction = transaction;
- metadataid = m_findmetadatasetCommand.ExecuteScalarInt64(null, -1, hash, size);
- if (metadataid != -1)
- return false;
- }
+ m_findmetadatasetCommand.Transaction = transaction;
+ metadataid = m_findmetadatasetCommand.ExecuteScalarInt64(null, -1, filehash, size);
+ if (metadataid != -1)
+ return false;
long blocksetid;
- AddBlockset(hash, size, (int)size, new string[] { hash }, null, out blocksetid, transaction);
+ AddBlockset(filehash, size, blocksize, blockhashes, blocklisthashes, out blocksetid, transaction);
using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
{
@@ -485,8 +418,6 @@ namespace Duplicati.Library.Main.Database
m_insertmetadatasetCommand.SetParameterValue(0, blocksetid);
metadataid = m_insertmetadatasetCommand.ExecuteScalarInt64();
tr.Commit();
- if (m_metadataLookup != null)
- m_metadataLookup.Add(hash, size, metadataid);
}
return true;
@@ -583,7 +514,22 @@ namespace Duplicati.Library.Main.Database
AddFile(path, lastmodified, SYMLINK_BLOCKSET_ID, metadataID, transaction);
}
- public long GetFileEntry(string path, out DateTime oldModified, out long lastFileSize, out string oldMetahash, out long oldMetasize)
+ public long GetFileLastModified(string path, long filesetid, out DateTime oldModified)
+ {
+ m_selectfilelastmodifiedCommand.SetParameterValue(0, path);
+ m_selectfilelastmodifiedCommand.SetParameterValue(1, filesetid);
+ using (var rd = m_selectfilelastmodifiedCommand.ExecuteReader())
+ if (rd.Read())
+ {
+ oldModified = new DateTime(rd.ConvertValueToInt64(1), DateTimeKind.Utc);
+ return rd.ConvertValueToInt64(0);
+ }
+
+ oldModified = new DateTime(0, DateTimeKind.Utc);
+ return -1;
+ }
+
+ public long GetFileEntry(string path, long filesetid, out DateTime oldModified, out long lastFileSize, out string oldMetahash, out long oldMetasize)
{
if (m_pathLookup != null)
{
@@ -607,15 +553,16 @@ namespace Duplicati.Library.Main.Database
}
else
{
- m_selectfileSimpleCommand.SetParameterValue(0, path);
- using(var rd = m_selectfileSimpleCommand.ExecuteReader())
+ m_findfileCommand.SetParameterValue(0, path);
+
+ using(var rd = m_findfileCommand.ExecuteReader())
if (rd.Read())
{
- oldModified = new DateTime(rd.GetInt64(1), DateTimeKind.Utc);
+ oldModified = new DateTime(rd.ConvertValueToInt64(1), DateTimeKind.Utc);
lastFileSize = rd.GetInt64(2);
oldMetahash = rd.GetString(3);
oldMetasize = rd.GetInt64(4);
- return rd.GetInt64(0);
+ return rd.ConvertValueToInt64(0);
}
else
{
@@ -645,9 +592,6 @@ namespace Duplicati.Library.Main.Database
public override void Dispose ()
{
- m_fileHashLookup = null;
- m_metadataLookup = null;
- m_blockHashLookup = null;
m_pathLookup = null;
base.Dispose();
@@ -711,7 +655,8 @@ namespace Duplicati.Library.Main.Database
public void AppendFilesFromPreviousSet(System.Data.IDbTransaction transaction, IEnumerable<string> deleted, long filesetid, long prevId, DateTime timestamp)
{
using(var cmd = m_connection.CreateCommand())
- using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
+ using(var cmdDelete = m_connection.CreateCommand())
+ using(var tr = new TemporaryTransactionWrapper(m_connection, transaction))
{
long lastFilesetId = prevId < 0 ? GetPreviousFilesetID(cmd, timestamp, filesetid) : prevId;
@@ -720,14 +665,15 @@ namespace Duplicati.Library.Main.Database
if (deleted != null)
{
- cmd.CommandText = @"DELETE FROM ""FilesetEntry"" WHERE ""FilesetID"" = ? AND ""FileID"" IN (SELECT ""ID"" FROM ""File"" WHERE ""Path"" = ?) ";
- cmd.AddParameter(filesetid);
- cmd.AddParameter();
+ cmdDelete.Transaction = tr.Parent;
+ cmdDelete.CommandText = @"DELETE FROM ""FilesetEntry"" WHERE ""FilesetID"" = ? AND ""FileID"" IN (SELECT ""ID"" FROM ""File"" WHERE ""Path"" = ?) ";
+ cmdDelete.AddParameters(2);
+ cmdDelete.SetParameterValue(0, filesetid);
foreach (string s in deleted)
{
- cmd.SetParameterValue(1, s);
- cmd.ExecuteNonQuery();
+ cmdDelete.SetParameterValue(1, s);
+ cmdDelete.ExecuteNonQuery();
}
}
@@ -772,6 +718,23 @@ namespace Duplicati.Library.Main.Database
return null;
}
+ public RemoteVolumeEntry GetRemoteVolumeFromID(long id)
+ {
+ using (var cmd = m_connection.CreateCommand())
+ using (var rd = cmd.ExecuteReader(@"SELECT ""Name"", ""Type"", ""Size"", ""Hash"", ""State"", ""DeleteGraceTime"" FROM ""RemoteVolume"" WHERE ""ID"" = ?", id))
+ if (rd.Read())
+ return new RemoteVolumeEntry(
+ rd.GetValue(0).ToString(),
+ (rd.GetValue(3) == null || rd.GetValue(3) == DBNull.Value) ? null : rd.GetValue(3).ToString(),
+ rd.ConvertValueToInt64(2, -1),
+ (RemoteVolumeType)Enum.Parse(typeof(RemoteVolumeType), rd.GetValue(1).ToString()),
+ (RemoteVolumeState)Enum.Parse(typeof(RemoteVolumeState), rd.GetValue(4).ToString()),
+ new DateTime(rd.ConvertValueToInt64(5, 0), DateTimeKind.Utc)
+ );
+ else
+ return default(RemoteVolumeEntry);
+ }
+
public IEnumerable<string> GetMissingIndexFiles()
{
using(var cmd = m_connection.CreateCommand())
@@ -790,5 +753,19 @@ namespace Duplicati.Library.Main.Database
throw new Exception(string.Format("Failed to link filesetid {0} to volumeid {1}", filesetid, volumeid));
}
}
+
+ public string GetFirstPath()
+ {
+ using (var cmd = m_connection.CreateCommand())
+ {
+ cmd.CommandText = string.Format(@"SELECT ""Path"" FROM ""File"" ORDER BY LENGTH(""Path"") DESC LIMIT 1");
+ var v0 = cmd.ExecuteScalar();
+ if (v0 == null || v0 == DBNull.Value)
+ return null;
+
+ return v0.ToString();
+ }
+ }
+
}
}
diff --git a/Duplicati/Library/Main/Database/LocalBugReportDatabase.cs b/Duplicati/Library/Main/Database/LocalBugReportDatabase.cs
index 85620f4ad..ec1fccc5b 100644
--- a/Duplicati/Library/Main/Database/LocalBugReportDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalBugReportDatabase.cs
@@ -43,13 +43,14 @@ namespace Duplicati.Library.Main.Database
upcmd.ExecuteNonQuery(string.Format(@"INSERT INTO ""{0}"" (""RealPath"") SELECT DISTINCT ""Path"" FROM ""File"" ORDER BY ""Path"" ", tablename));
upcmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Obfuscated"" = ? || length(""RealPath"") || ? || ""ID"" || (CASE WHEN substr(""RealPath"", length(""RealPath"")) = ? THEN ? ELSE ? END) ", tablename), Library.Utility.Utility.IsClientLinux ? "/" : "X:\\", Library.Utility.Utility.DirectorySeparatorString, Library.Utility.Utility.DirectorySeparatorString, Library.Utility.Utility.DirectorySeparatorString, ".bin");
- long id = 1;
+ /*long id = 1;
using(var rd = cmd.ExecuteReader(string.Format(@"SELECT ""RealPath"", ""Obfuscated"" FROM ""{0}"" ", tablename)))
while(rd.Read())
{
upcmd.ExecuteNonQuery(@"UPDATE ""LogData"" SET ""Message"" = replace(""Message"", ?, ?), ""Exception"" = replace(""Exception"", ?, ?)", rd.GetValue(0), rd.GetValue(1), rd.GetValue(0), rd.GetValue(1) );
id++;
}
+ */
}
cmd.ExecuteNonQuery(@"UPDATE ""LogData"" SET ""Message"" = ""ERASED!"" WHERE ""Message"" LIKE ""%/%"" OR ""Message"" LIKE ""%:\%"" ");
@@ -62,7 +63,6 @@ namespace Duplicati.Library.Main.Database
tr.Commit();
cmd.Transaction = null;
- cmd.ExecuteNonQuery("VACUUM");
}
}
}
diff --git a/Duplicati/Library/Main/Database/LocalDatabase.cs b/Duplicati/Library/Main/Database/LocalDatabase.cs
index 589ee7ae7..35da7c843 100644
--- a/Duplicati/Library/Main/Database/LocalDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalDatabase.cs
@@ -39,9 +39,10 @@ namespace Duplicati.Library.Main.Database
protected static System.Data.IDbConnection CreateConnection(string path)
{
path = System.IO.Path.GetFullPath(path);
- var c = (System.Data.IDbConnection)Activator.CreateInstance(Duplicati.Library.SQLiteHelper.SQLiteLoader.SQLiteConnectionType);
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(path)))
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path));
+
+ var c = Duplicati.Library.SQLiteHelper.SQLiteLoader.LoadConnection(path);
Library.SQLiteHelper.DatabaseUpgrader.UpgradeDatabase(c, path, typeof(LocalDatabase));
@@ -120,8 +121,8 @@ namespace Duplicati.Library.Main.Database
m_selectremotevolumeCommand.CommandText = @"SELECT ""Type"", ""Size"", ""Hash"", ""State"" FROM ""Remotevolume"" WHERE ""Name"" = ?";
m_selectremotevolumeCommand.AddParameter();
- m_removeremotevolumeCommand.CommandText = @"DELETE FROM ""Remotevolume"" WHERE ""Name"" = ?";
- m_removeremotevolumeCommand.AddParameter();
+ m_removeremotevolumeCommand.CommandText = @"DELETE FROM ""Remotevolume"" WHERE ""Name"" = ? AND (""DeleteGraceTime"" < ? OR ""State"" != ?)";
+ m_removeremotevolumeCommand.AddParameters(3);
m_selectremotevolumeIdCommand.CommandText = @"SELECT ""ID"" FROM ""Remotevolume"" WHERE ""Name"" = ?";
@@ -365,9 +366,9 @@ namespace Duplicati.Library.Main.Database
RemoveRemoteVolumes(new string[] { name }, transaction);
}
- public void RemoveRemoteVolumes(ICollection<string> names, System.Data.IDbTransaction transaction = null)
+ public void RemoveRemoteVolumes(IEnumerable<string> names, System.Data.IDbTransaction transaction = null)
{
- if (names.Count == 0) return;
+ if (names == null || !names.Any()) return;
using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
using (var deletecmd = m_connection.CreateCommand())
@@ -433,12 +434,14 @@ namespace Duplicati.Library.Main.Database
deletecmd.ExecuteNonQuery(string.Format(@"DROP TABLE IF EXISTS ""{0}"" ", blocksetidstable));
deletecmd.ExecuteNonQuery(string.Format(@"DROP TABLE IF EXISTS ""{0}"" ", volidstable));
}
- catch { /* Ignore, will be deleted on close anyway. */ }
-
- foreach (var name in names)
+ catch { /* Ignore, will be deleted on close anyway. */ }
+
+ m_removeremotevolumeCommand.Transaction = tr.Parent;
+ m_removeremotevolumeCommand.SetParameterValue(1, DateTime.UtcNow.Ticks);
+ m_removeremotevolumeCommand.SetParameterValue(2, RemoteVolumeState.Deleted.ToString());
+ foreach (var name in names)
{
m_removeremotevolumeCommand.SetParameterValue(0, name);
- m_removeremotevolumeCommand.Transaction = tr.Parent;
m_removeremotevolumeCommand.ExecuteNonQuery();
}
tr.Commit();
@@ -515,10 +518,10 @@ namespace Duplicati.Library.Main.Database
cmd.Parameters.Clear();
using(var rd = cmd.ExecuteReader(@"SELECT ""ID"" FROM ""Fileset"" ORDER BY ""Timestamp"" DESC "))
while (rd.Read())
- res.Add(rd.GetInt64(0));
+ res.Add(rd.ConvertValueToInt64(0));
if (res.Count == 0)
- throw new Exception("No backup at the specified date");
+ throw new Duplicati.Library.Interface.UserInformationException("No backup at the specified date");
else
m_result.AddWarning(string.Format("Restore time or version did not match any existing backups, selecting newest backup"), null);
}
@@ -723,14 +726,35 @@ namespace Duplicati.Library.Main.Database
return cmd.ExecuteScalarInt64(@"SELECT COUNT(*) FROM ""Block"" WHERE ""Size"" > ?", -1, fhblocksize);
}
- public void VerifyConsistency(System.Data.IDbTransaction transaction, long blocksize, long hashsize)
+ public void VerifyConsistency(System.Data.IDbTransaction transaction, long blocksize, long hashsize, bool verifyfilelists)
{
- using (var cmd = m_connection.CreateCommand())
+ using (var cmd = m_connection.CreateCommand(transaction))
{
- cmd.Transaction = transaction;
-
// Calculate the lengths for each blockset
- var combinedLengths = @"SELECT ""BlocksetEntry"".""BlocksetID"" AS ""BlocksetID"", SUM(""Block"".""Size"") AS ""CalcLen"", ""Blockset"".""Length"" AS ""Length"" FROM ""Block"", ""BlocksetEntry"", ""Blockset"" WHERE ""BlocksetEntry"".""BlockID"" = ""Block"".""ID"" AND ""BlocksetEntry"".""BlocksetID"" = ""Blockset"".""ID"" GROUP BY ""BlocksetEntry"".""BlocksetID""";
+ var combinedLengths = @"
+SELECT
+ ""A"".""ID"" AS ""BlocksetID"",
+ IFNULL(""B"".""CalcLen"", 0) AS ""CalcLen"",
+ ""A"".""Length""
+FROM
+ ""Blockset"" A
+LEFT OUTER JOIN
+ (
+ SELECT
+ ""BlocksetEntry"".""BlocksetID"",
+ SUM(""Block"".""Size"") AS ""CalcLen""
+ FROM
+ ""BlocksetEntry""
+ LEFT OUTER JOIN
+ ""Block""
+ ON
+ ""Block"".""ID"" = ""BlocksetEntry"".""BlockID""
+ GROUP BY ""BlocksetEntry"".""BlocksetID""
+ ) B
+ON
+ ""A"".""ID"" = ""B"".""BlocksetID""
+
+";
// For each blockset with wrong lengths, fetch the file path
var reportDetails = @"SELECT ""CalcLen"", ""Length"", ""A"".""BlocksetID"", ""File"".""Path"" FROM (" + combinedLengths + @") A, ""File"" WHERE ""A"".""BlocksetID"" = ""File"".""BlocksetID"" AND ""A"".""CalcLen"" != ""A"".""Length"" ";
@@ -768,6 +792,20 @@ namespace Duplicati.Library.Main.Database
if (cmd.ExecuteScalarInt64(@"SELECT COUNT(*) FROM ""File"" WHERE ""BlocksetID"" != ? AND ""BlocksetID"" != ? AND NOT ""BlocksetID"" IN (SELECT ""BlocksetID"" FROM ""BlocksetEntry"")", 0, FOLDER_BLOCKSET_ID, SYMLINK_BLOCKSET_ID) != 0)
throw new Exception("Detected file entries with not associated blocks");
+
+ if (verifyfilelists)
+ {
+ using(var cmd2 = m_connection.CreateCommand(transaction))
+ foreach(var filesetid in cmd.ExecuteReaderEnumerable(@"SELECT ""ID"" FROM ""Fileset"" ").Select(x => x.ConvertValueToInt64(0, -1)))
+ {
+ var expandedlist = cmd2.ExecuteScalarInt64(string.Format(@"SELECT COUNT(*) FROM (SELECT DISTINCT ""Path"" FROM ({0}) UNION SELECT DISTINCT ""Path"" FROM ({1}))", LocalDatabase.LIST_FILESETS, LocalDatabase.LIST_FOLDERS_AND_SYMLINKS), 0, filesetid, FOLDER_BLOCKSET_ID, SYMLINK_BLOCKSET_ID, filesetid);
+ //var storedfilelist = cmd2.ExecuteScalarInt64(string.Format(@"SELECT COUNT(*) FROM ""FilesetEntry"", ""File"" WHERE ""FilesetEntry"".""FilesetID"" = ? AND ""File"".""ID"" = ""FilesetEntry"".""FileID"" AND ""File"".""BlocksetID"" != ? AND ""File"".""BlocksetID"" != ?"), 0, filesetid, FOLDER_BLOCKSET_ID, SYMLINK_BLOCKSET_ID);
+ var storedlist = cmd2.ExecuteScalarInt64(string.Format(@"SELECT COUNT(*) FROM ""FilesetEntry"" WHERE ""FilesetEntry"".""FilesetID"" = ?"), 0, filesetid);
+
+ if (expandedlist != storedlist)
+ throw new Exception(string.Format("Unexpected difference in fileset {0}, found {1} entries, but expected {2}", filesetid, expandedlist, storedlist));
+ }
+ }
}
}
@@ -885,31 +923,168 @@ namespace Duplicati.Library.Main.Database
}
}
+ public const string LIST_FILESETS = @"
+SELECT
+ ""L"".""Path"",
+ ""L"".""Lastmodified"",
+ ""L"".""Filelength"",
+ ""L"".""Filehash"",
+ ""L"".""Metahash"",
+ ""L"".""Metalength"",
+ ""L"".""BlocklistHash"",
+ ""L"".""FirstBlockHash"",
+ ""L"".""FirstBlockSize"",
+ ""L"".""FirstMetaBlockHash"",
+ ""L"".""FirstMetaBlockSize"",
+ ""M"".""Hash"" AS ""MetaBlocklistHash""
+FROM
+ (
+ SELECT
+ ""J"".""Path"",
+ ""J"".""Lastmodified"",
+ ""J"".""Filelength"",
+ ""J"".""Filehash"",
+ ""J"".""Metahash"",
+ ""J"".""Metalength"",
+ ""K"".""Hash"" AS ""BlocklistHash"",
+ ""J"".""FirstBlockHash"",
+ ""J"".""FirstBlockSize"",
+ ""J"".""FirstMetaBlockHash"",
+ ""J"".""FirstMetaBlockSize"",
+ ""J"".""MetablocksetID""
+ FROM
+ (
+ SELECT
+ ""A"".""Path"" AS ""Path"",
+ ""D"".""Lastmodified"" AS ""Lastmodified"",
+ ""B"".""Length"" AS ""Filelength"",
+ ""B"".""FullHash"" AS ""Filehash"",
+ ""E"".""FullHash"" AS ""Metahash"",
+ ""E"".""Length"" AS ""Metalength"",
+ ""A"".""BlocksetID"" AS ""BlocksetID"",
+ ""F"".""Hash"" AS ""FirstBlockHash"",
+ ""F"".""Size"" AS ""FirstBlockSize"",
+ ""H"".""Hash"" AS ""FirstMetaBlockHash"",
+ ""H"".""Size"" AS ""FirstMetaBlockSize"",
+ ""C"".""BlocksetID"" AS ""MetablocksetID""
+ FROM
+ ""File"" A,
+ ""Blockset"" B,
+ ""Metadataset"" C,
+ ""FilesetEntry"" D,
+ ""Blockset"" E,
+ ""Block"" F,
+ ""BlocksetEntry"" G,
+ ""Block"" H,
+ ""BlocksetEntry"" I
+ WHERE
+ ""A"".""ID"" = ""D"".""FileID""
+ AND ""D"".""FilesetID"" = ?
+ AND ""A"".""BlocksetID"" = ""B"".""ID""
+ AND ""A"".""MetadataID"" = ""C"".""ID""
+ AND ""E"".""ID"" = ""C"".""BlocksetID""
+ AND ""B"".""ID"" = ""G"".""BlocksetID""
+ AND ""G"".""BlockID"" = ""F"".""ID""
+ AND ""G"".""Index"" = 0
+ AND ""I"".""BlocksetID"" = ""E"".""ID""
+ AND ""I"".""BlockID"" = ""H"".""ID""
+ AND ""I"".""Index"" = 0
+ ) J
+ LEFT OUTER JOIN
+ ""BlocklistHash"" K
+ ON
+ ""K"".""BlocksetID"" = ""J"".""BlocksetID""
+ ORDER BY ""J"".""Path"", ""K"".""Index""
+ ) L
+
+LEFT OUTER JOIN
+ ""BlocklistHash"" M
+ON
+ ""M"".""BlocksetID"" = ""L"".""MetablocksetID""
+";
+
+ public const string LIST_FOLDERS_AND_SYMLINKS = @"
+SELECT
+ ""G"".""BlocksetID"",
+ ""G"".""ID"",
+ ""G"".""Path"",
+ ""G"".""Length"",
+ ""G"".""FullHash"",
+ ""G"".""Lastmodified"",
+ ""G"".""FirstMetaBlockHash"",
+ ""H"".""Hash"" AS ""MetablocklistHash""
+FROM
+ (
+ SELECT
+ ""B"".""BlocksetID"",
+ ""B"".""ID"",
+ ""B"".""Path"",
+ ""D"".""Length"",
+ ""D"".""FullHash"",
+ ""A"".""Lastmodified"",
+ ""F"".""Hash"" AS ""FirstMetaBlockHash"",
+ ""C"".""BlocksetID"" AS ""MetaBlocksetID""
+ FROM
+ ""FilesetEntry"" A,
+ ""File"" B,
+ ""Metadataset"" C,
+ ""Blockset"" D,
+ ""BlocksetEntry"" E,
+ ""Block"" F
+ WHERE
+ ""A"".""FileID"" = ""B"".""ID""
+ AND ""B"".""MetadataID"" = ""C"".""ID""
+ AND ""C"".""BlocksetID"" = ""D"".""ID""
+ AND ""E"".""BlocksetID"" = ""C"".""BlocksetID""
+ AND ""E"".""BlockID"" = ""F"".""ID""
+ AND ""E"".""Index"" = 0
+ AND (""B"".""BlocksetID"" = ? OR ""B"".""BlocksetID"" = ?)
+ AND ""A"".""FilesetID"" = ?
+ ) G
+LEFT OUTER JOIN
+ ""BlocklistHash"" H
+ON
+ ""H"".""BlocksetID"" = ""G"".""MetaBlocksetID""
+ORDER BY
+ ""G"".""Path"", ""H"".""Index""
+
+";
+
public void WriteFileset(Volumes.FilesetVolumeWriter filesetvolume, System.Data.IDbTransaction transaction, long filesetId)
{
using (var cmd = m_connection.CreateCommand())
{
- cmd.Transaction = transaction;
- cmd.CommandText = @"SELECT ""B"".""BlocksetID"", ""B"".""ID"", ""B"".""Path"", ""D"".""Length"", ""D"".""FullHash"", ""A"".""Lastmodified"" FROM ""FilesetEntry"" A, ""File"" B, ""Metadataset"" C, ""Blockset"" D WHERE ""A"".""FileID"" = ""B"".""ID"" AND ""B"".""MetadataID"" = ""C"".""ID"" AND ""C"".""BlocksetID"" = ""D"".""ID"" AND (""B"".""BlocksetID"" = ? OR ""B"".""BlocksetID"" = ?) AND ""A"".""FilesetID"" = ? ";
+ cmd.Transaction = transaction;
+ cmd.CommandText = LIST_FOLDERS_AND_SYMLINKS;
cmd.AddParameter(FOLDER_BLOCKSET_ID);
cmd.AddParameter(SYMLINK_BLOCKSET_ID);
cmd.AddParameter(filesetId);
+ string lastpath = null;
using (var rd = cmd.ExecuteReader())
while(rd.Read())
{
- var blocksetID = rd.GetInt64(0);
- var path = rd.GetValue(2).ToString();
- var metalength = rd.GetInt64(3);
- var metahash = rd.GetValue(4).ToString();
+ var blocksetID = rd.ConvertValueToInt64(0, -1);
+ var path = rd.GetValue(2).ToString();
+ var metalength = rd.ConvertValueToInt64(3, -1);
+ var metahash = rd.GetValue(4).ToString();
+ var metablockhash = rd.GetValue(6).ToString();
+ var metablocklisthash = rd.GetValue(7).ToString();
+
+ if (path == lastpath)
+ m_result.AddWarning(string.Format("Duplicate path detected: {0}!", path), null);
+
+ lastpath = path;
if (blocksetID == FOLDER_BLOCKSET_ID)
- filesetvolume.AddDirectory(path, metahash, metalength);
+ filesetvolume.AddDirectory(path, metahash, metalength, metablockhash, string.IsNullOrWhiteSpace(metablocklisthash) ? null : new string[] { metablocklisthash });
else if (blocksetID == SYMLINK_BLOCKSET_ID)
- filesetvolume.AddSymlink(path, metahash, metalength);
+ filesetvolume.AddSymlink(path, metahash, metalength, metablockhash, string.IsNullOrWhiteSpace(metablocklisthash) ? null : new string[] { metablocklisthash });
}
+
+ // TODO: Perhaps run the above query after recreate and compare count(*) with count(*) from filesetentry where id = x
- cmd.CommandText = @"SELECT ""F"".""Path"", ""F"".""Lastmodified"", ""F"".""Filelength"", ""F"".""Filehash"", ""F"".""Metahash"", ""F"".""Metalength"", ""G"".""Hash"" FROM (SELECT ""A"".""Path"" AS ""Path"", ""D"".""Lastmodified"" AS ""Lastmodified"", ""B"".""Length"" AS ""Filelength"", ""B"".""FullHash"" AS ""Filehash"", ""E"".""FullHash"" AS ""Metahash"", ""E"".""Length"" AS ""Metalength"", ""A"".""BlocksetID"" AS ""BlocksetID"" FROM ""File"" A, ""Blockset"" B, ""Metadataset"" C, ""FilesetEntry"" D, ""Blockset"" E WHERE ""A"".""ID"" = ""D"".""FileID"" AND ""D"".""FilesetID"" = ? AND ""A"".""BlocksetID"" = ""B"".""ID"" AND ""A"".""MetadataID"" = ""C"".""ID"" AND ""E"".""ID"" = ""C"".""BlocksetID"") F LEFT OUTER JOIN ""BlocklistHash"" G ON ""G"".""BlocksetID"" = ""F"".""BlocksetID"" ORDER BY ""F"".""Path"", ""G"".""Index"" ";
+ cmd.CommandText = LIST_FILESETS;
cmd.Parameters.Clear();
cmd.AddParameter(filesetId);
@@ -927,8 +1102,19 @@ namespace Duplicati.Library.Main.Database
var metasize = rd.ConvertValueToInt64(5, -1);
var p = rd.GetValue(6);
var blrd = (p == null || p == DBNull.Value) ? null : new BlocklistHashEnumerable(rd);
+ var blockhash = rd.GetValue(7).ToString();
+ var blocksize = rd.ConvertValueToInt64(8, -1);
+ var metablockhash = rd.GetValue(9).ToString();
+ //var metablocksize = rd.ConvertValueToInt64(10, -1);
+ var metablocklisthash = rd.GetValue(11).ToString();
- filesetvolume.AddFile(path, filehash, size, lastmodified, metahash, metasize, blrd);
+ if (blockhash == filehash)
+ blockhash = null;
+
+ if (metablockhash == metahash)
+ metablockhash = null;
+
+ filesetvolume.AddFile(path, filehash, size, lastmodified, metahash, metasize, metablockhash, blockhash, blocksize, blrd, string.IsNullOrWhiteSpace(metablocklisthash) ? null : new string[] { metablocklisthash });
if (blrd == null)
more = rd.Read();
else
@@ -1131,8 +1317,6 @@ namespace Duplicati.Library.Main.Database
tr.Commit();
}
- using(var cmd = m_connection.CreateCommand())
- cmd.ExecuteNonQuery("VACUUM");
}
public virtual void Dispose()
@@ -1201,14 +1385,23 @@ namespace Duplicati.Library.Main.Database
if (m_connection != null && m_result != null)
{
m_result.FlushLog();
+ if (m_result.EndTime.Ticks == 0)
+ m_result.EndTime = DateTime.UtcNow;
+
LogMessage("Result",
Library.Utility.Utility.PrintSerializeObject(
m_result,
(StringBuilder)null,
- x =>
- !typeof(IBackendProgressUpdater).IsAssignableFrom(x.PropertyType) &&
- !typeof(IMessageSink).IsAssignableFrom(x.PropertyType) &&
- !typeof(ILogWriter).IsAssignableFrom(x.PropertyType),
+ (prop, item) =>
+ !typeof(IBackendProgressUpdater).IsAssignableFrom(prop.PropertyType) &&
+ !typeof(IMessageSink).IsAssignableFrom(prop.PropertyType) &&
+ !typeof(ILogWriter).IsAssignableFrom(prop.PropertyType) &&
+ prop.Name != "VerboseOutput" &&
+ prop.Name != "VerboseErrors" &&
+ !(prop.Name == "MainOperation" && item is BackendWriter) &&
+ !(prop.Name == "EndTime" && item is BackendWriter) &&
+ !(prop.Name == "Duration" && item is BackendWriter) &&
+ !(prop.Name == "BeginTime" && item is BackendWriter),
recurseobjects: true,
collectionlimit: 5
).ToString(),
diff --git a/Duplicati/Library/Main/Database/LocalDeleteDatabase.cs b/Duplicati/Library/Main/Database/LocalDeleteDatabase.cs
index 600f04cb1..c2d179e80 100644
--- a/Duplicati/Library/Main/Database/LocalDeleteDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalDeleteDatabase.cs
@@ -27,8 +27,8 @@ namespace Duplicati.Library.Main.Database
{
private System.Data.IDbCommand m_moveBlockToNewVolumeCommand;
- public LocalDeleteDatabase(string path, bool isCompact)
- : base(path, isCompact ? "Compact" : "Delete", true)
+ public LocalDeleteDatabase(string path, string operation)
+ : base(path, operation, true)
{
InitializeCommands();
}
@@ -273,41 +273,19 @@ namespace Duplicati.Library.Main.Database
private class BlockQuery : IBlockQuery
{
private System.Data.IDbCommand m_command;
- private HashLookupHelper<long> m_lookup;
-
+
public BlockQuery(System.Data.IDbConnection con, Options options, System.Data.IDbTransaction transaction)
{
m_command = con.CreateCommand();
m_command.Transaction = transaction;
-
- if (options.BlockHashLookupMemory > 0)
- {
- m_lookup = new HashLookupHelper<long>((ulong)options.BlockHashLookupMemory);
- using(var reader = m_command.ExecuteReader(@"SELECT ""Hash"", ""Size"" FROM ""Block"" "))
- while (reader.Read())
- {
- var hash = reader.GetString(0);
- var size = reader.GetInt64(1);
- m_lookup.Add(hash, size, size);
- }
- }
-
+
m_command.Parameters.Clear();
m_command.CommandText = @"SELECT ""VolumeID"" FROM ""Block"" WHERE ""Hash"" = ? AND ""Size"" = ? ";
m_command.AddParameters(2);
}
public bool UseBlock(string hash, long size, System.Data.IDbTransaction transaction)
- {
- if (m_lookup != null)
- {
- long nsize;
- if(m_lookup.TryGet(hash, size, out nsize) && nsize == size)
- return true;
- else
- return false;
- }
-
+ {
m_command.Transaction = transaction;
m_command.SetParameterValue(0, hash);
m_command.SetParameterValue(1, size);
@@ -317,7 +295,6 @@ namespace Duplicati.Library.Main.Database
public void Dispose()
{
- m_lookup = null;
if (m_command != null)
try { m_command.Dispose(); }
finally { m_command = null; }
@@ -345,7 +322,7 @@ namespace Duplicati.Library.Main.Database
}
/// <summary>
- /// Calculates the sequence in which files should be deleted based on their releations.
+ /// Calculates the sequence in which files should be deleted based on their relations.
/// </summary>
/// <returns>The deletable volumes.</returns>
/// <param name="deleteableVolumes">Block volumes slated for deletion.</param>
diff --git a/Duplicati/Library/Main/Database/LocalListBrokenFilesDatabase.cs b/Duplicati/Library/Main/Database/LocalListBrokenFilesDatabase.cs
new file mode 100644
index 000000000..77755401d
--- /dev/null
+++ b/Duplicati/Library/Main/Database/LocalListBrokenFilesDatabase.cs
@@ -0,0 +1,134 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Duplicati.Library.Main.Database
+{
+ internal class LocalListBrokenFilesDatabase : LocalDatabase
+ {
+ private const string BROKEN_FILE_IDS = @"
+SELECT DISTINCT ""ID"" FROM (
+ SELECT ""ID"" AS ""ID"", ""BlocksetID"" AS ""BlocksetID"" FROM ""File"" WHERE ""BlocksetID"" != {0} AND ""BlocksetID"" != {1}
+UNION
+ SELECT ""A"".""ID"" AS ""ID"", ""B"".""BlocksetID"" AS ""BlocksetID"" FROM ""File"" A LEFT JOIN ""Metadataset"" B ON ""A"".""MetadataID"" = ""B"".""ID""
+)
+WHERE ""BlocksetID"" IS NULL OR ""BlocksetID"" IN
+ (
+ SELECT ""BlocksetID"" FROM ""BlocksetEntry"" WHERE ""BlockID"" NOT IN (SELECT ""ID"" FROM ""Block"")
+ )
+";
+ private const string BROKEN_FILE_SETS = @"SELECT DISTINCT ""B"".""Timestamp"", ""A"".""FilesetID"", COUNT(""A"".""FileID"") AS ""FileCount"" FROM ""FilesetEntry"" A, ""Fileset"" B WHERE ""A"".""FilesetID"" = ""B"".""ID"" AND ""A"".""FileID"" IN (" + BROKEN_FILE_IDS + @")";
+
+ private const string BROKEN_FILE_NAMES = @"
+SELECT ""A"".""Path"", ""B"".""Length"" FROM ""File"" A, ""Blockset"" B WHERE ""A"".""BlocksetID"" = ""B"".""ID"" AND ""A"".""ID"" IN ("
++ BROKEN_FILE_IDS +
+@") AND ""A"".""ID"" IN (SELECT ""FileID"" FROM ""FilesetEntry"" WHERE ""FilesetID"" = ?)";
+
+ private const string INSERT_BROKEN_IDS = @"INSERT INTO ""{2}"" (""{3}"") " + BROKEN_FILE_IDS
+ + @" AND ""ID"" IN (SELECT ""FileID"" FROM ""FilesetEntry"" WHERE ""FilesetID"" = ?)";
+
+ public LocalListBrokenFilesDatabase(string path)
+ : base(path, "ListBrokenFiles", false)
+ {
+ ShouldCloseConnection = true;
+ }
+
+ public LocalListBrokenFilesDatabase(LocalDatabase parent)
+ : base(parent)
+ {
+ ShouldCloseConnection = false;
+ }
+
+ public IEnumerable<Tuple<DateTime, long, long>> GetBrokenFilesets(DateTime time, long[] versions, System.Data.IDbTransaction transaction)
+ {
+ var query = string.Format(BROKEN_FILE_SETS, FOLDER_BLOCKSET_ID, SYMLINK_BLOCKSET_ID);
+ var clause = GetFilelistWhereClause(time, versions);
+ if (!string.IsNullOrWhiteSpace(clause.Item1))
+ query += @" AND ""A"".""FilesetID"" IN (SELECT ""ID"" FROM ""Fileset"" " + clause.Item1 + ")";
+
+ query += @" GROUP BY ""A"".""FilesetID""";
+
+ using (var cmd = Connection.CreateCommand(transaction))
+ foreach (var rd in cmd.ExecuteReaderEnumerable(query, clause.Item2))
+ if (!rd.IsDBNull(0))
+ yield return new Tuple<DateTime, long, long>(ParseFromEpochSeconds(rd.ConvertValueToInt64(0, 0)), rd.ConvertValueToInt64(1, -1), rd.ConvertValueToInt64(2, 0));
+ }
+
+ public IEnumerable<Tuple<string, long>> GetBrokenFilenames(long filesetid, System.Data.IDbTransaction transaction)
+ {
+ using (var cmd = Connection.CreateCommand(transaction))
+ foreach (var rd in cmd.ExecuteReaderEnumerable(string.Format(BROKEN_FILE_NAMES, FOLDER_BLOCKSET_ID, SYMLINK_BLOCKSET_ID), filesetid))
+ if (!rd.IsDBNull(0))
+ yield return new Tuple<string, long>(rd.ConvertValueToString(0), rd.ConvertValueToInt64(1));
+ }
+
+ public void InsertBrokenFileIDsIntoTable(long filesetid, string tablename, string IDfieldname, System.Data.IDbTransaction transaction)
+ {
+ using (var cmd = Connection.CreateCommand(transaction))
+ cmd.ExecuteNonQuery(string.Format(INSERT_BROKEN_IDS, FOLDER_BLOCKSET_ID, SYMLINK_BLOCKSET_ID, tablename, IDfieldname), filesetid);
+ }
+
+ public void RemoveMissingBlocks(IEnumerable<string> names, System.Data.IDbTransaction transaction)
+ {
+ if (names == null || !names.Any()) return;
+ if (transaction == null)
+ throw new Exception("This function cannot be called when not in a transaction, as it leaves the database in an inconsistent state");
+
+ using (var deletecmd = m_connection.CreateCommand(transaction))
+ {
+ string temptransguid = Library.Utility.Utility.ByteArrayAsHexString(Guid.NewGuid().ToByteArray());
+ var volidstable = "DelVolSetIds-" + temptransguid;
+
+ // Create and fill a temp table with the volids to delete. We avoid using too many parameters that way.
+ deletecmd.ExecuteNonQuery(string.Format(@"CREATE TEMP TABLE ""{0}"" (""ID"" INTEGER PRIMARY KEY)", volidstable));
+ deletecmd.CommandText = string.Format(@"INSERT OR IGNORE INTO ""{0}"" (""ID"") VALUES (?)", volidstable);
+ deletecmd.Parameters.Clear();
+ deletecmd.AddParameters(1);
+ foreach (var name in names)
+ {
+ var volumeid = GetRemoteVolumeID(name, transaction);
+ deletecmd.SetParameterValue(0, volumeid);
+ deletecmd.ExecuteNonQuery();
+ }
+ var volIdsSubQuery = string.Format(@"SELECT ""ID"" FROM ""{0}"" ", volidstable);
+ deletecmd.Parameters.Clear();
+
+ deletecmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""IndexBlockLink"" WHERE ""BlockVolumeID"" IN ({0}) OR ""IndexVolumeID"" IN ({0})", volIdsSubQuery));
+ deletecmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""Block"" WHERE ""VolumeID"" IN ({0})", volIdsSubQuery));
+
+ // Clean up temp tables for subqueries. We truncate content and then try to delete.
+ // Drop in try-block, as it fails in nested transactions (SQLite problem)
+ // System.Data.SQLite.SQLiteException (0x80004005): database table is locked
+ deletecmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""{0}"" ", volidstable));
+ try
+ {
+ deletecmd.CommandTimeout = 2;
+ deletecmd.ExecuteNonQuery(string.Format(@"DROP TABLE IF EXISTS ""{0}"" ", volidstable));
+ }
+ catch { /* Ignore, will be deleted on close anyway. */ }
+ }
+ }
+
+ public long GetFilesetFileCount(long filesetid, System.Data.IDbTransaction transaction)
+ {
+ using (var cmd = m_connection.CreateCommand(transaction))
+ return cmd.ExecuteScalarInt64(@"SELECT COUNT(*) FROM ""FilesetEntry"" WHERE ""FilesetID"" = ?", 0, filesetid);
+ }
+ }
+}
diff --git a/Duplicati/Library/Main/Database/LocalListChangesDatabase.cs b/Duplicati/Library/Main/Database/LocalListChangesDatabase.cs
index 5c9e71a47..e46ffc345 100644
--- a/Duplicati/Library/Main/Database/LocalListChangesDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalListChangesDatabase.cs
@@ -173,7 +173,7 @@ namespace Duplicati.Library.Main.Database
cmd2.AddParameters(5);
cmd2.Transaction = m_transaction;
- using(var rd = cmd.ExecuteReader(@"SELECT ""Path"", ""FileHash"", ""MetaHash"", ""Size"", ""Type"" FROM {1} A WHERE ""A"".""FilesetID"" = ?", filesetId))
+ using(var rd = cmd.ExecuteReader(string.Format(@"SELECT ""A"".""Path"", ""A"".""FileHash"", ""A"".""MetaHash"", ""A"".""Size"", ""A"".""Type"" FROM {0} A WHERE ""A"".""FilesetID"" = ?", combined), filesetId))
while (rd.Read())
{
rd.GetValues(values);
diff --git a/Duplicati/Library/Main/Database/LocalListDatabase.cs b/Duplicati/Library/Main/Database/LocalListDatabase.cs
index d634eb6ec..9c9072ce5 100644
--- a/Duplicati/Library/Main/Database/LocalListDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalListDatabase.cs
@@ -147,6 +147,8 @@ namespace Duplicati.Library.Main.Database
string maxpath = "";
if (v0 != null)
maxpath = v0.ToString();
+
+ var dirsep = Duplicati.Library.Utility.Utility.GuessDirSeparator(maxpath);
cmd.CommandText = string.Format(@"SELECT COUNT(*) FROM ""{0}""", tmpnames.Tablename);
var filecount = cmd.ExecuteScalarInt64(0);
@@ -159,7 +161,7 @@ namespace Duplicati.Library.Main.Database
while (filecount != foundfiles && maxpath.Length > 0)
{
- var mp = Library.Utility.Utility.AppendDirSeparator(maxpath);
+ var mp = Duplicati.Library.Utility.Utility.AppendDirSeparator(maxpath, dirsep);
cmd.SetParameterValue(0, mp.Length);
cmd.SetParameterValue(1, mp);
foundfiles = cmd.ExecuteScalarInt64(0);
@@ -167,8 +169,9 @@ namespace Duplicati.Library.Main.Database
if (filecount != foundfiles)
{
var oldlen = maxpath.Length;
- maxpath = Library.Snapshots.SnapshotUtility.SystemIO.PathGetDirectoryName(maxpath);
- if (string.IsNullOrWhiteSpace(maxpath) || maxpath.Length == oldlen)
+ var lix = maxpath.LastIndexOf(dirsep, maxpath.Length - 2, StringComparison.Ordinal);
+ maxpath = maxpath.Substring(0, lix + 1);
+ if (string.IsNullOrWhiteSpace(maxpath) || maxpath.Length == oldlen || maxpath == "\\\\")
maxpath = "";
}
}
@@ -182,7 +185,7 @@ namespace Duplicati.Library.Main.Database
return
new IFileversion[] {
- new FileversionFixed() { Path = maxpath == "" ? "" : Library.Utility.Utility.AppendDirSeparator(maxpath) }
+ new FileversionFixed() { Path = maxpath == "" ? "" : Duplicati.Library.Utility.Utility.AppendDirSeparator(maxpath, dirsep) }
};
}
@@ -191,7 +194,7 @@ namespace Duplicati.Library.Main.Database
private IEnumerable<string> SelectFolderEntries(System.Data.IDbCommand cmd, string prefix, string table)
{
if (!string.IsNullOrEmpty(prefix))
- prefix = Duplicati.Library.Utility.Utility.AppendDirSeparator(prefix);
+ prefix = Duplicati.Library.Utility.Utility.AppendDirSeparator(prefix, Duplicati.Library.Utility.Utility.GuessDirSeparator(prefix));
var ppl = prefix.Length;
using(var rd = cmd.ExecuteReader(string.Format(@"SELECT DISTINCT ""Path"" FROM ""{0}"" ", table)))
@@ -200,9 +203,11 @@ namespace Duplicati.Library.Main.Database
var s = rd.GetString(0);
if (!s.StartsWith(prefix))
continue;
-
+
+ var dirsep = Duplicati.Library.Utility.Utility.GuessDirSeparator(s);
+
s = s.Substring(ppl);
- var ix = s.IndexOf(System.IO.Path.DirectorySeparatorChar);
+ var ix = s.IndexOf(dirsep, StringComparison.Ordinal);
if (ix > 0 && ix != s.Length - 1)
s = s.Substring(0, ix + 1);
yield return prefix + s;
@@ -218,14 +223,16 @@ namespace Duplicati.Library.Main.Database
if (filter == null || filter.Empty)
pathprefix = "";
else if (filter as Library.Utility.FilterExpression == null || ((Library.Utility.FilterExpression)filter).Type != Duplicati.Library.Utility.FilterType.Simple || ((Library.Utility.FilterExpression)filter).GetSimpleList().Length != 1)
- throw new ArgumentException("Filter for list-folder-contents must be a path prefix with no wildcards", "filter");
+ throw new ArgumentException("Filter for list-folder-contents must be a path prefix with no wildcards", nameof(filter));
else
pathprefix = ((Library.Utility.FilterExpression)filter).GetSimpleList().First();
+
+ var dirsep = Duplicati.Library.Utility.Utility.GuessDirSeparator(pathprefix);
+
+ if (pathprefix.Length > 0 || dirsep == "/")
+ pathprefix = Duplicati.Library.Utility.Utility.AppendDirSeparator(pathprefix, dirsep);
- if (pathprefix.Length > 0 || Duplicati.Library.Utility.Utility.IsClientLinux)
- pathprefix = Duplicati.Library.Utility.Utility.AppendDirSeparator(pathprefix);
-
- using(var tmpnames = new FilteredFilenameTable(m_connection, new Library.Utility.FilterExpression(pathprefix + "*", true), null))
+ using(var tmpnames = new FilteredFilenameTable(m_connection, new Library.Utility.FilterExpression(new string[] { pathprefix + "*" }, true), null))
using(var cmd = m_connection.CreateCommand())
{
//First we trim the filelist to exclude filenames not found in any of the filesets
@@ -342,7 +349,7 @@ namespace Duplicati.Library.Main.Database
dict[m_filesets[i].Key] = i;
using(var cmd = m_connection.CreateCommand())
- using(var rd = cmd.ExecuteReader(string.Format(@"SELECT DISTINCT ""ID"" FROM ""Fileset"" ORDER BY ""Timestamp"" DESC ", m_tablename)))
+ using(var rd = cmd.ExecuteReader(@"SELECT DISTINCT ""ID"" FROM ""Fileset"" ORDER BY ""Timestamp"" DESC "))
while (rd.Read())
{
var id = rd.GetInt64(0);
diff --git a/Duplicati/Library/Main/Database/LocalPurgeDatabase.cs b/Duplicati/Library/Main/Database/LocalPurgeDatabase.cs
new file mode 100644
index 000000000..e0d9938b2
--- /dev/null
+++ b/Duplicati/Library/Main/Database/LocalPurgeDatabase.cs
@@ -0,0 +1,198 @@
+// Copyright (C) 2016, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+
+namespace Duplicati.Library.Main.Database
+{
+ internal class LocalPurgeDatabase : LocalDeleteDatabase
+ {
+ public LocalPurgeDatabase(string path)
+ : base(path, "Purge")
+ {
+ ShouldCloseConnection = true;
+ }
+
+ public LocalPurgeDatabase(LocalDatabase db)
+ : base(db)
+ {
+ }
+
+ public ITemporaryFileset CreateTemporaryFileset(long parentid, System.Data.IDbTransaction transaction)
+ {
+ return new TemporaryFileset(parentid, this, m_connection, transaction);
+ }
+
+ public string GetRemoteVolumeNameForFileset(long id, System.Data.IDbTransaction transaction)
+ {
+ using (var cmd = m_connection.CreateCommand(transaction))
+ using (var rd = cmd.ExecuteReader(string.Format(@"SELECT ""B"".""Name"" FROM ""Fileset"" A, ""RemoteVolume"" B WHERE ""A"".""VolumeID"" = ""B"".""ID"" AND ""A"".""ID"" = ? "), id))
+ if (!rd.Read())
+ throw new Exception(string.Format("No remote volume found for fileset with id {0}", id));
+ else
+ return rd.ConvertValueToString(0);
+ }
+
+ internal long CountOrphanFiles(System.Data.IDbTransaction transaction)
+ {
+ using (var cmd = m_connection.CreateCommand(transaction))
+ using (var rd = cmd.ExecuteReader(@"SELECT COUNT(*) FROM ""File"" WHERE ""ID"" NOT IN (SELECT DISTINCT ""FileID"" FROM ""FilesetEntry"")"))
+ if (rd.Read())
+ return rd.ConvertValueToInt64(0, 0);
+ else
+ return 0;
+ }
+
+ public interface ITemporaryFileset : IDisposable
+ {
+ long ParentID { get; }
+ long RemovedFileCount { get; }
+ long RemovedFileSize { get; }
+
+ void ApplyFilter(Library.Utility.IFilter filter);
+ void ApplyFilter(Action<System.Data.IDbCommand, long, string> filtercommand);
+ Tuple<long, long> ConvertToPermanentFileset(string name, DateTime timestamp);
+ IEnumerable<KeyValuePair<string, long>> ListAllDeletedFiles();
+ }
+
+ private class TemporaryFileset : ITemporaryFileset
+ {
+ private readonly System.Data.IDbConnection m_connection;
+ private readonly System.Data.IDbTransaction m_transaction;
+ private readonly string m_tablename;
+ private LocalPurgeDatabase m_parentdb;
+
+ public long ParentID { get; private set; }
+ public long RemovedFileCount { get; private set; }
+ public long RemovedFileSize { get; private set; }
+
+ public TemporaryFileset(long parentid, LocalPurgeDatabase parentdb, System.Data.IDbConnection connection, System.Data.IDbTransaction transaction)
+ {
+ this.ParentID = parentid;
+ m_parentdb = parentdb;
+ m_connection = connection;
+ m_transaction = transaction;
+ m_tablename = "TempDeletedFilesTable-" + Library.Utility.Utility.ByteArrayAsHexString(Guid.NewGuid().ToByteArray());
+
+ using (var cmd = m_connection.CreateCommand(m_transaction))
+ cmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""FileID"" INTEGER PRIMARY KEY) ", m_tablename));
+ }
+
+ public void ApplyFilter(Action<System.Data.IDbCommand, long, string> filtercommand)
+ {
+ using (var cmd = m_connection.CreateCommand(m_transaction))
+ filtercommand(cmd, ParentID, m_tablename);
+
+ PostFilterChecks();
+ }
+
+ public void ApplyFilter(Library.Utility.IFilter filter)
+ {
+ if (Library.Utility.Utility.IsFSCaseSensitive && filter is Library.Utility.FilterExpression && (filter as Library.Utility.FilterExpression).Type == Duplicati.Library.Utility.FilterType.Simple)
+ {
+ // File list based
+ // unfortunately we cannot do this if the filesystem is case sensitive as
+ // SQLite only supports ASCII compares
+ var p = (filter as Library.Utility.FilterExpression).GetSimpleList();
+ var filenamestable = "Filenames-" + Library.Utility.Utility.ByteArrayAsHexString(Guid.NewGuid().ToByteArray());
+ using (var cmd = m_connection.CreateCommand(m_transaction))
+ {
+ cmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""Path"" TEXT NOT NULL) ", filenamestable));
+ cmd.CommandText = string.Format(@"INSERT INTO ""{0}"" (""Path"") VALUES (?)", filenamestable);
+ cmd.AddParameter();
+
+ foreach (var s in p)
+ {
+ cmd.SetParameterValue(0, s);
+ cmd.ExecuteNonQuery();
+ }
+
+ cmd.ExecuteNonQuery(string.Format(@"INSERT INTO ""{0}"" (""FileID"") SELECT DISTINCT ""A"".""FileID"" FROM ""FilesetEntry"" A, ""File"" B WHERE ""A"".""FilesetID"" = ? AND ""A"".""FileID"" = ""B"".""ID"" AND ""B"".""Path"" NOT IN ""{1}""", m_tablename, filenamestable), ParentID);
+ cmd.ExecuteNonQuery(string.Format(@"DROP TABLE IF EXISTS ""{0}"" ", filenamestable));
+ }
+ }
+ else
+ {
+ // Do row-wise iteration
+ object[] values = new object[2];
+ using (var cmd = m_connection.CreateCommand(m_transaction))
+ using (var cmd2 = m_connection.CreateCommand(m_transaction))
+ {
+ cmd2.CommandText = string.Format(@"INSERT INTO ""{0}"" (""FileID"") VALUES (?)", m_tablename);
+ cmd2.AddParameters(1);
+
+ using (var rd = cmd.ExecuteReader(@"SELECT ""B"".""Path"", ""A"".""FileID"" FROM ""FilesetEntry"" A, ""File"" B WHERE ""A"".""FilesetID"" = ? AND ""A"".""FileID"" = ""B"".""ID"" ", ParentID))
+ while (rd.Read())
+ {
+ rd.GetValues(values);
+ if (values[0] != null && values[0] != DBNull.Value && Library.Utility.FilterExpression.Matches(filter, values[0].ToString()))
+ {
+ cmd2.SetParameterValue(0, values[1]);
+ cmd2.ExecuteNonQuery();
+ }
+ }
+ }
+ }
+
+ PostFilterChecks();
+ }
+
+ private void PostFilterChecks()
+ {
+ using (var cmd = m_connection.CreateCommand(m_transaction))
+ {
+ RemovedFileCount = cmd.ExecuteScalarInt64(string.Format(@"SELECT COUNT(*) FROM ""{0}""", m_tablename), 0);
+ RemovedFileSize = cmd.ExecuteScalarInt64(string.Format(@"SELECT SUM(""C"".""Length"") FROM ""{0}"" A, ""File"" B, ""Blockset"" C WHERE ""A"".""FileID"" = ""B"".""ID"" AND ""B"".""BlocksetID"" = ""C"".""ID"" ", m_tablename), 0);
+ var filesetcount = cmd.ExecuteScalarInt64(string.Format(@"SELECT COUNT(*) FROM ""FilesetEntry"" WHERE ""FilesetID"" = " + ParentID), 0);
+ if (filesetcount == RemovedFileCount)
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Refusing to purge {0} files from fileset with ID {1}, as that would remove the entire fileset.\nTo delete a fileset, use the \"delete\" command.", RemovedFileCount, ParentID));
+ }
+ }
+
+ public Tuple<long, long> ConvertToPermanentFileset(string name, DateTime timestamp)
+ {
+ var remotevolid = m_parentdb.RegisterRemoteVolume(name, RemoteVolumeType.Files, RemoteVolumeState.Temporary, m_transaction);
+ var filesetid = m_parentdb.CreateFileset(remotevolid, timestamp, m_transaction);
+ using (var cmd = m_connection.CreateCommand(m_transaction))
+ cmd.ExecuteNonQuery(string.Format(@"INSERT INTO ""FilesetEntry"" (""FilesetID"", ""FileID"", ""Lastmodified"") SELECT ?, ""FileID"", ""LastModified"" FROM ""FilesetEntry"" WHERE ""FilesetID"" = ? AND ""FileID"" NOT IN ""{0}"" ", m_tablename), filesetid, ParentID);
+
+ return new Tuple<long, long>(remotevolid, filesetid);
+ }
+
+ public IEnumerable<KeyValuePair<string, long>> ListAllDeletedFiles()
+ {
+ using (var cmd = m_connection.CreateCommand(m_transaction))
+ using (var rd = cmd.ExecuteReader(string.Format(@"SELECT ""B"".""Path"", ""C"".""Length"" FROM ""{0}"" A, ""File"" B, ""Blockset"" C WHERE ""A"".""FileID"" = ""B"".""ID"" AND ""B"".""BlocksetID"" = ""C"".""ID"" ", m_tablename)))
+ while (rd.Read())
+ yield return new KeyValuePair<string, long>(rd.ConvertValueToString(0), rd.ConvertValueToInt64(1));
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ using (var cmd = m_connection.CreateCommand(m_transaction))
+ cmd.ExecuteNonQuery(@"DROP TABLE IF EXISTS ""{0}""", m_tablename);
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ }
+}
diff --git a/Duplicati/Library/Main/Database/LocalRecreateDatabase.cs b/Duplicati/Library/Main/Database/LocalRecreateDatabase.cs
index 1d1ce6ab8..c927b411a 100644
--- a/Duplicati/Library/Main/Database/LocalRecreateDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalRecreateDatabase.cs
@@ -51,6 +51,7 @@ namespace Duplicati.Library.Main.Database
private System.Data.IDbCommand m_insertBlocklistHashCommand;
private System.Data.IDbCommand m_updateBlockVolumeCommand;
private System.Data.IDbCommand m_insertBlockset;
+ private System.Data.IDbCommand m_insertSmallBlockset;
private System.Data.IDbCommand m_findBlocksetCommand;
private System.Data.IDbCommand m_findMetadatasetCommand;
private System.Data.IDbCommand m_findFilesetCommand;
@@ -59,13 +60,10 @@ namespace Duplicati.Library.Main.Database
private System.Data.IDbCommand m_insertBlockCommand;
private System.Data.IDbCommand m_insertDuplicateBlockCommand;
- private HashLookupHelper<bool> m_blockListHashLookup;
- private HashLookupHelper<long> m_blockHashLookup;
- private HashLookupHelper<long> m_fileHashLookup;
- private HashLookupHelper<long> m_metadataLookup;
private PathLookupHelper<PathEntryKeeper> m_filesetLookup;
private string m_tempblocklist;
+ private string m_tempsmalllist;
/// <summary>
/// A lookup table that prevents multiple downloads of the same volume
@@ -80,7 +78,7 @@ namespace Duplicati.Library.Main.Database
// {3} --> FullBlocklist-BlockCount [equals ({0} / {1}), if SQLite pays respect to ints]
private const string SELECT_BLOCKLIST_ENTRIES =
@"
- SELECT DISTINCT
+ SELECT
""E"".""BlocksetID"",
""F"".""Index"" + (""E"".""BlocklistIndex"" * {3}) AS ""FullIndex"",
""F"".""BlockHash"",
@@ -122,11 +120,16 @@ namespace Duplicati.Library.Main.Database
: base(parentdb)
{
m_tempblocklist = "TempBlocklist-" + Library.Utility.Utility.ByteArrayAsHexString(Guid.NewGuid().ToByteArray());
+ m_tempsmalllist = "TempSmalllist-" + Library.Utility.Utility.ByteArrayAsHexString(Guid.NewGuid().ToByteArray());
using(var cmd = m_connection.CreateCommand())
{
cmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""BlockListHash"" TEXT NOT NULL, ""BlockHash"" TEXT NOT NULL, ""Index"" INTEGER NOT NULL)", m_tempblocklist));
cmd.ExecuteNonQuery(string.Format(@"CREATE INDEX ""Index_{0}"" ON ""{0}"" (""BlockListHash"");", m_tempblocklist));
+
+ cmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""FileHash"" TEXT NOT NULL, ""BlockHash"" TEXT NOT NULL, ""BlockSize"" INTEGER NOT NULL)", m_tempsmalllist));
+ cmd.ExecuteNonQuery(string.Format(@"CREATE UNIQUE INDEX ""Index_File_{0}"" ON ""{0}"" (""FileHash"", ""BlockSize"");", m_tempsmalllist));
+ cmd.ExecuteNonQuery(string.Format(@"CREATE UNIQUE INDEX ""Index_Block_{0}"" ON ""{0}"" (""BlockHash"", ""BlockSize"");", m_tempsmalllist));
}
m_insertFileCommand = m_connection.CreateCommand();
@@ -136,6 +139,7 @@ namespace Duplicati.Library.Main.Database
m_insertBlocklistHashCommand = m_connection.CreateCommand();
m_updateBlockVolumeCommand = m_connection.CreateCommand();
m_insertBlockset = m_connection.CreateCommand();
+ m_insertSmallBlockset = m_connection.CreateCommand();
m_findBlocksetCommand = m_connection.CreateCommand();
m_findMetadatasetCommand = m_connection.CreateCommand();
m_findFilesetCommand = m_connection.CreateCommand();
@@ -164,7 +168,10 @@ namespace Duplicati.Library.Main.Database
m_insertBlockset.CommandText = string.Format(@"INSERT INTO ""{0}"" (""BlocklistHash"", ""BlockHash"", ""Index"") VALUES (?,?,?) ", m_tempblocklist);
m_insertBlockset.AddParameters(3);
-
+
+ m_insertSmallBlockset.CommandText = string.Format(@"INSERT OR IGNORE INTO ""{0}"" (""FileHash"", ""BlockHash"", ""BlockSize"") VALUES (?,?,?) ", m_tempsmalllist);
+ m_insertSmallBlockset.AddParameters(3);
+
m_findBlocksetCommand.CommandText = @"SELECT ""ID"" FROM ""Blockset"" WHERE ""Length"" = ? AND ""FullHash"" = ? ";
m_findBlocksetCommand.AddParameters(2);
@@ -186,15 +193,6 @@ namespace Duplicati.Library.Main.Database
m_insertDuplicateBlockCommand.CommandText = @"INSERT INTO ""DuplicateBlock"" (""BlockID"", ""VolumeID"") VALUES ((SELECT ""ID"" FROM ""Block"" WHERE ""Hash"" = ? AND ""Size"" = ?), ?)";
m_insertDuplicateBlockCommand.AddParameters(3);
- if (options.BlockHashLookupMemory > 0)
- {
- m_blockHashLookup = new HashLookupHelper<long>((ulong)options.BlockHashLookupMemory/2);
- m_blockListHashLookup = new HashLookupHelper<bool>((ulong)options.BlockHashLookupMemory/2);
- }
- if (options.FileHashLookupMemory > 0)
- m_fileHashLookup = new HashLookupHelper<long>((ulong)options.FileHashLookupMemory);
- if (options.MetadataHashMemory > 0)
- m_metadataLookup = new HashLookupHelper<long>((ulong)options.MetadataHashMemory);
if (options.UseFilepathCache)
m_filesetLookup = new PathLookupHelper<PathEntryKeeper>();
}
@@ -206,7 +204,8 @@ namespace Duplicati.Library.Main.Database
cmd.Transaction = transaction;
//Update all small blocklists and matching blocks
- var selectSmallBlocks = string.Format(@"SELECT ""Blockset"".""Fullhash"", ""Blockset"".""Length"" FROM ""Blockset"" WHERE ""Blockset"".""Length"" <= {0}", blocksize);
+
+ var selectSmallBlocks = string.Format(@"SELECT ""BlockHash"", ""BlockSize"" FROM ""{0}""", m_tempsmalllist);
var selectBlockHashes = string.Format(
@"SELECT ""BlockHash"" AS ""FullHash"", ""BlockSize"" AS ""Length"" FROM ( " +
@@ -235,31 +234,25 @@ namespace Duplicati.Library.Main.Database
// Insert all known blocks into block table with volumeid = -1
cmd.ExecuteNonQuery(insertBlocksCommand);
- // Update the cache with new blocks
- if (m_blockHashLookup != null)
- {
- using(var rd = cmd.ExecuteReader(@"SELECT DISTINCT ""Hash"", ""Size"" FROM ""Block"" WHERE ""VolumeID"" = -1 "))
- while(rd.Read())
- {
- var hash = rd.GetString(0);
- var size = rd.GetInt64(1);
- m_blockHashLookup.TryAdd(hash, size, -1);
- }
- }
-
var selectBlocklistBlocksetEntries = string.Format(
@"SELECT ""E"".""BlocksetID"" AS ""BlocksetID"", ""D"".""FullIndex"" AS ""Index"", ""F"".""ID"" AS ""BlockID"" FROM ( " +
SELECT_BLOCKLIST_ENTRIES +
- @") D, ""BlocklistHash"" E, ""Block"" F, ""Block"" G WHERE ""D"".""BlocklistHash"" = ""E"".""Hash"" AND ""D"".""BlocklistSize"" = ""G"".""Size"" AND ""D"".""BlocklistHash"" = ""G"".""Hash"" AND ""D"".""Blockhash"" = ""F"".""Hash"" AND ""D"".""BlockSize"" = ""F"".""Size"" ",
+ @") D, ""BlocklistHash"" E, ""Block"" F, ""Block"" G WHERE ""D"".""BlocksetID"" = ""E"".""BlocksetID"" AND ""D"".""BlocklistHash"" = ""E"".""Hash"" AND ""D"".""BlocklistSize"" = ""G"".""Size"" AND ""D"".""BlocklistHash"" = ""G"".""Hash"" AND ""D"".""Blockhash"" = ""F"".""Hash"" AND ""D"".""BlockSize"" = ""F"".""Size"" ",
+
+ // TODO: The BlocklistHash join seems to be unnecessary, but the join might be required to work around a from really old versions of Duplicati
+ // this could be used instead
+ //@") D, ""Block"" WHERE ""BlockQuery"".""BlockHash"" = ""Block"".""Hash"" AND ""BlockQuery"".""BlockSize"" = ""Block"".""Size"" ";
+
blocksize,
hashsize,
m_tempblocklist,
blocksize / hashsize
);
-
+
var selectBlocksetEntries = string.Format(
- @"SELECT ""Blockset"".""ID"" AS ""BlocksetID"", 0 AS ""Index"", ""Block"".""ID"" AS ""BlockID"" FROM ""Blockset"", ""Block"" WHERE ""Blockset"".""Fullhash"" = ""Block"".""Hash"" AND ""Blockset"".""Length"" <= {0} ",
- blocksize
+ @"SELECT ""Blockset"".""ID"" AS ""BlocksetID"", 0 AS ""Index"", ""Block"".""ID"" AS ""BlockID"" FROM ""Blockset"", ""Block"", ""{1}"" S WHERE ""Blockset"".""Fullhash"" = ""S"".""FileHash"" AND ""S"".""BlockHash"" = ""Block"".""Hash"" AND ""S"".""BlockSize"" = ""Block"".""Size"" AND ""Blockset"".""Length"" = ""S"".""BlockSize"" AND ""Blockset"".""Length"" <= {0} ",
+ blocksize,
+ m_tempsmalllist
);
var selectAllBlocksetEntries =
@@ -268,36 +261,50 @@ namespace Duplicati.Library.Main.Database
selectBlocksetEntries;
var selectFiltered =
- @"SELECT DISTINCT ""BlocksetID"", ""Index"", ""BlockID"" FROM (" +
+ @"SELECT DISTINCT ""H"".""BlocksetID"", ""H"".""Index"", ""H"".""BlockID"" FROM (" +
selectAllBlocksetEntries +
- @") A WHERE (""A"".""BlocksetID"" || ':' || ""A"".""Index"") NOT IN (SELECT (""BlocksetID"" || ':' || ""Index"") FROM ""BlocksetEntry"" )";
+ @") H WHERE (""H"".""BlocksetID"" || ':' || ""H"".""Index"") NOT IN (SELECT (""ExistingBlocksetEntries"".""BlocksetID"" || ':' || ""ExistingBlocksetEntries"".""Index"") FROM ""BlocksetEntry"" ""ExistingBlocksetEntries"" )";
var insertBlocksetEntriesCommand =
- @"INSERT INTO ""BlocksetEntry"" (""BlocksetID"", ""Index"", ""BlockID"") " + selectFiltered;
-
- cmd.ExecuteNonQuery(insertBlocksetEntriesCommand);
+ @"INSERT INTO ""BlocksetEntry"" (""BlocksetID"", ""Index"", ""BlockID"") " + selectFiltered;
+
+ try
+ {
+ cmd.ExecuteNonQuery(insertBlocksetEntriesCommand);
+ }
+ catch (Exception ex)
+ {
+ m_result.AddError("Blockset insert failed, comitting temporary tables for trace purposes", ex);
+
+ using (var fixcmd = m_connection.CreateCommand())
+ {
+ fixcmd.ExecuteNonQuery(string.Format(@"CREATE TABLE ""{0}-Failure"" AS SELECT * FROM ""{0}"" ", m_tempblocklist));
+ fixcmd.ExecuteNonQuery(string.Format(@"CREATE TABLE ""{0}-Failure"" AS SELECT * FROM ""{0}"" ", m_tempsmalllist));
+ }
+
+ throw new Exception("The recreate failed, please create a bug-report from this database and send it to the developers for further analysis");
+ }
}
}
- public void AddDirectoryEntry(long filesetid, string path, DateTime time, string metahash, long metahashsize, System.Data.IDbTransaction transaction)
+ public void AddDirectoryEntry(long filesetid, string path, DateTime time, long metadataid, System.Data.IDbTransaction transaction)
{
- AddEntry(FilelistEntryType.Folder, filesetid, path, time, FOLDER_BLOCKSET_ID, metahash, metahashsize, transaction);
+ AddEntry(FilelistEntryType.Folder, filesetid, path, time, FOLDER_BLOCKSET_ID, metadataid, transaction);
}
- public void AddSymlinkEntry(long filesetid, string path, DateTime time, string metahash, long metahashsize, System.Data.IDbTransaction transaction)
+ public void AddSymlinkEntry(long filesetid, string path, DateTime time, long metadataid, System.Data.IDbTransaction transaction)
{
- AddEntry(FilelistEntryType.Symlink, filesetid, path, time, SYMLINK_BLOCKSET_ID, metahash, metahashsize, transaction);
+ AddEntry(FilelistEntryType.Symlink, filesetid, path, time, SYMLINK_BLOCKSET_ID, metadataid, transaction);
}
- public void AddFileEntry(long filesetid, string path, DateTime time, long blocksetid, string metahash, long metahashsize, System.Data.IDbTransaction transaction)
+ public void AddFileEntry(long filesetid, string path, DateTime time, long blocksetid, long metadataid, System.Data.IDbTransaction transaction)
{
- AddEntry(FilelistEntryType.File , filesetid, path, time, blocksetid, metahash, metahashsize, transaction);
+ AddEntry(FilelistEntryType.File , filesetid, path, time, blocksetid, metadataid, transaction);
}
- private void AddEntry(FilelistEntryType type, long filesetid, string path, DateTime time, long blocksetid, string metahash, long metahashsize, System.Data.IDbTransaction transaction)
+ private void AddEntry(FilelistEntryType type, long filesetid, string path, DateTime time, long blocksetid, long metadataid, System.Data.IDbTransaction transaction)
{
var fileid = -1L;
- var metadataid = AddMetadataset(metahash, metahashsize, transaction);
if (m_filesetLookup != null)
{
@@ -342,76 +349,49 @@ namespace Duplicati.Library.Main.Database
m_insertFilesetEntryCommand.ExecuteNonQuery();
}
- private long AddMetadataset(string metahash, long metahashsize, System.Data.IDbTransaction transaction)
+ public long AddMetadataset(string metahash, long metahashsize, IEnumerable<string> metablocklisthashes, long expectedmetablocklisthashes, System.Data.IDbTransaction transaction)
{
var metadataid = -1L;
if (metahash == null)
return metadataid;
- if (m_metadataLookup != null)
- {
- if (m_metadataLookup.TryGet(metahash, metahashsize, out metadataid))
- return metadataid;
- else
- metadataid = -1;
- }
- else
- {
- m_findMetadatasetCommand.Transaction = transaction;
- m_findMetadatasetCommand.SetParameterValue(0, metahash);
- m_findMetadatasetCommand.SetParameterValue(1, metahashsize);
- metadataid = m_findMetadatasetCommand.ExecuteScalarInt64(-1);
- if (metadataid != -1)
- return metadataid;
- }
-
- var blocksetid = AddBlockset(metahash, metahashsize, null, 0, transaction);
+ m_findMetadatasetCommand.Transaction = transaction;
+ m_findMetadatasetCommand.SetParameterValue(0, metahash);
+ m_findMetadatasetCommand.SetParameterValue(1, metahashsize);
+ metadataid = m_findMetadatasetCommand.ExecuteScalarInt64(-1);
+ if (metadataid != -1)
+ return metadataid;
+
+ var blocksetid = AddBlockset(metahash, metahashsize, metablocklisthashes, expectedmetablocklisthashes, transaction);
m_insertMetadatasetCommand.Transaction = transaction;
m_insertMetadatasetCommand.SetParameterValue(0, blocksetid);
metadataid = m_insertMetadatasetCommand.ExecuteScalarInt64(-1);
-
- if (m_metadataLookup != null)
- m_metadataLookup.Add(metahash, metahashsize, metadataid);
-
+
return metadataid;
}
public long AddBlockset(string fullhash, long size, IEnumerable<string> blocklisthashes, long expectedblocklisthashes, System.Data.IDbTransaction transaction)
{
- var blocksetid = -1L;
- if (m_fileHashLookup != null)
- {
- if (m_fileHashLookup.TryGet(fullhash, size, out blocksetid))
- return blocksetid;
- else
- blocksetid = -1;
- }
- else
- {
- m_findBlocksetCommand.Transaction = transaction;
- m_findBlocksetCommand.SetParameterValue(0, size);
- m_findBlocksetCommand.SetParameterValue(1, fullhash);
- blocksetid = m_findBlocksetCommand.ExecuteScalarInt64(-1);
- if (blocksetid != -1)
- return blocksetid;
- }
+ m_findBlocksetCommand.Transaction = transaction;
+ m_findBlocksetCommand.SetParameterValue(0, size);
+ m_findBlocksetCommand.SetParameterValue(1, fullhash);
+ var blocksetid = m_findBlocksetCommand.ExecuteScalarInt64(-1);
+ if (blocksetid != -1)
+ return blocksetid;
m_insertBlocksetCommand.Transaction = transaction;
m_insertBlocksetCommand.SetParameterValue(0, size);
m_insertBlocksetCommand.SetParameterValue(1, fullhash);
blocksetid = m_insertBlocksetCommand.ExecuteScalarInt64(-1);
- if (m_fileHashLookup != null)
- m_fileHashLookup.Add(fullhash, size, blocksetid);
-
+ long c = 0;
if (blocklisthashes != null)
{
var index = 0L;
m_insertBlocklistHashCommand.Transaction = transaction;
m_insertBlocklistHashCommand.SetParameterValue(0, blocksetid);
- long c = 0;
foreach(var hash in blocklisthashes)
{
if (!string.IsNullOrEmpty(hash))
@@ -425,31 +405,21 @@ namespace Duplicati.Library.Main.Database
}
}
}
-
- if (c != expectedblocklisthashes) // or is there a legacy with single element blocklist hashes? --> && !(c == 1 && hash == computeBlockHash(fullhash))
- m_result.AddWarning(string.Format("Mismatching number of blocklist hashes detected on blockset {2}. Expected {0} blocklist hashes, but found {1}", expectedblocklisthashes, c, blocksetid), null);
-
}
+ if (c != expectedblocklisthashes)
+ m_result.AddWarning(string.Format("Mismatching number of blocklist hashes detected on blockset {2}. Expected {0} blocklist hashes, but found {1}", expectedblocklisthashes, c, blocksetid), null);
+
return blocksetid;
}
public bool UpdateBlock(string hash, long size, long volumeID, System.Data.IDbTransaction transaction)
{
- var currentVolumeId = -2L;
- if (m_blockHashLookup != null)
- {
- if (!m_blockHashLookup.TryGet(hash, size, out currentVolumeId))
- currentVolumeId = -2;
- }
- else
- {
- m_findHashBlockCommand.Transaction = transaction;
- m_findHashBlockCommand.SetParameterValue(0, hash);
- m_findHashBlockCommand.SetParameterValue(1, size);
- currentVolumeId = m_findHashBlockCommand.ExecuteScalarInt64(-2);
- }
-
+ m_findHashBlockCommand.Transaction = transaction;
+ m_findHashBlockCommand.SetParameterValue(0, hash);
+ m_findHashBlockCommand.SetParameterValue(1, size);
+ var currentVolumeId = m_findHashBlockCommand.ExecuteScalarInt64(-2);
+
if (currentVolumeId == volumeID)
return false;
@@ -462,9 +432,6 @@ namespace Duplicati.Library.Main.Database
m_insertBlockCommand.SetParameterValue(2, volumeID);
m_insertBlockCommand.ExecuteNonQuery();
- if (m_blockHashLookup != null)
- m_blockHashLookup.Add(hash, size, volumeID);
-
return true;
}
else if (currentVolumeId == -1)
@@ -478,9 +445,6 @@ namespace Duplicati.Library.Main.Database
if (c != 1)
throw new Exception(string.Format("Failed to update table, found {0} entries for key {1} with size {2}", c ,hash, size));
- if (m_blockHashLookup != null)
- m_blockHashLookup.Add(hash, size, volumeID);
-
return true;
}
else
@@ -494,26 +458,23 @@ namespace Duplicati.Library.Main.Database
return false;
}
}
+
+ public void AddSmallBlocksetLink(string filehash, string blockhash, long blocksize, System.Data.IDbTransaction transaction)
+ {
+ m_insertSmallBlockset.Transaction = transaction;
+ m_insertSmallBlockset.SetParameterValue(0, filehash);
+ m_insertSmallBlockset.SetParameterValue(1, blockhash);
+ m_insertSmallBlockset.SetParameterValue(2, blocksize);
+ m_insertSmallBlockset.ExecuteNonQuery();
+ }
public bool UpdateBlockset(string hash, IEnumerable<string> blocklisthashes, System.Data.IDbTransaction transaction)
{
- if (m_blockListHashLookup != null)
- {
- bool b;
- if (m_blockListHashLookup.TryGet(hash, -1, out b))
- return false;
- }
- else
- {
- m_findblocklisthashCommand.Transaction = transaction;
- m_findblocklisthashCommand.SetParameterValue(0, hash);
- var r = m_findblocklisthashCommand.ExecuteScalar();
- if (r != null && r != DBNull.Value)
- return false;
- }
-
- if (m_blockListHashLookup != null)
- m_blockListHashLookup.Add(hash, -1, false);
+ m_findblocklisthashCommand.Transaction = transaction;
+ m_findblocklisthashCommand.SetParameterValue(0, hash);
+ var r = m_findblocklisthashCommand.ExecuteScalar();
+ if (r != null && r != DBNull.Value)
+ return false;
m_insertBlockset.Transaction = transaction;
m_insertBlockset.SetParameterValue(0, hash);
@@ -643,8 +604,17 @@ namespace Duplicati.Library.Main.Database
catch { }
finally { m_tempblocklist = null; }
+ if (m_tempsmalllist != null)
+ try
+ {
+ cmd.CommandText = string.Format(@"DROP TABLE IF EXISTS ""{0}""", m_tempsmalllist);
+ cmd.ExecuteNonQuery();
+ }
+ catch { }
+ finally { m_tempsmalllist = null; }
+
}
-
+
base.Dispose();
}
}
diff --git a/Duplicati/Library/Main/Database/LocalRepairDatabase.cs b/Duplicati/Library/Main/Database/LocalRepairDatabase.cs
index b10679f61..ed4236980 100644
--- a/Duplicati/Library/Main/Database/LocalRepairDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalRepairDatabase.cs
@@ -288,7 +288,7 @@ namespace Duplicati.Library.Main.Database
cmd.CommandText = sql_count;
x = cmd.ExecuteScalarInt64(0);
if (x > 1)
- throw new Exception("Repair failed, there are still duplicate metadatahashes!");
+ throw new Duplicati.Library.Interface.UserInformationException("Repair failed, there are still duplicate metadatahashes!");
m_result.AddMessage("Duplicate metadatahashes repaired succesfully");
tr.Commit();
@@ -323,7 +323,7 @@ namespace Duplicati.Library.Main.Database
cmd.CommandText = sql_count;
x = cmd.ExecuteScalarInt64(0);
if (x > 1)
- throw new Exception("Repair failed, there are still duplicate file entries!");
+ throw new Duplicati.Library.Interface.UserInformationException("Repair failed, there are still duplicate file entries!");
m_result.AddMessage("Duplicate file entries repaired succesfully");
tr.Commit();
@@ -334,7 +334,7 @@ namespace Duplicati.Library.Main.Database
public void FixMissingBlocklistHashes(string blockhashalgorithm, long blocksize)
{
- var blockhasher = System.Security.Cryptography.HashAlgorithm.Create(blockhashalgorithm);
+ var blockhasher = Library.Utility.HashAlgorithmHelper.Create(blockhashalgorithm);
var hashsize = blockhasher.HashSize / 8;
var blocklistbuffer = new byte[blocksize];
int blocklistoffset = 0;
@@ -429,7 +429,7 @@ namespace Duplicati.Library.Main.Database
itemswithnoblocklisthash = cmd.ExecuteScalarInt64(countsql, 0);
if (itemswithnoblocklisthash != 0)
- throw new Exception(string.Format("Failed to repair, after repair {0} blocklisthashes were missing", itemswithnoblocklisthash));
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Failed to repair, after repair {0} blocklisthashes were missing", itemswithnoblocklisthash));
m_result.AddMessage("Missing blocklisthashes repaired succesfully");
tr.Commit();
@@ -474,15 +474,15 @@ namespace Duplicati.Library.Main.Database
var real_count = cmd.ExecuteScalarInt64(@"SELECT Count(*) FROM ""BlocklistHash""", 0);
if (real_count != unique_count)
- throw new Exception(string.Format("Failed to repair, result should have been {0} blocklist hashes, but result was {1} blocklist hashes", unique_count, real_count));
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Failed to repair, result should have been {0} blocklist hashes, but result was {1} blocklist hashes", unique_count, real_count));
try
{
- VerifyConsistency(tr, blocksize, hashsize);
+ VerifyConsistency(tr, blocksize, hashsize, true);
}
catch(Exception ex)
{
- throw new Exception("Repaired blocklisthashes, but the database was broken afterwards, rolled back changes", ex);
+ throw new Duplicati.Library.Interface.UserInformationException("Repaired blocklisthashes, but the database was broken afterwards, rolled back changes", ex);
}
m_result.AddMessage("Duplicate blocklisthashes repaired succesfully");
@@ -558,17 +558,19 @@ ORDER BY
"
,blocksize, blockhashlength);
- var en = blocklist.GetEnumerator();
- foreach(var r in cmd.ExecuteReaderEnumerable(query, hash, length))
+ using (var en = blocklist.GetEnumerator())
{
- if (!en.MoveNext())
- throw new Exception(string.Format("Too few entries in source blocklist with hash {0}", hash));
- if (en.Current != r.GetString(0))
- throw new Exception(string.Format("Mismatch in blocklist with hash {0}", hash));
- }
+ foreach (var r in cmd.ExecuteReaderEnumerable(query, hash, length))
+ {
+ if (!en.MoveNext())
+ throw new Exception(string.Format("Too few entries in source blocklist with hash {0}", hash));
+ if (en.Current != r.GetString(0))
+ throw new Exception(string.Format("Mismatch in blocklist with hash {0}", hash));
+ }
- if (en.MoveNext())
- throw new Exception(string.Format("Too many source blocklist entries in {0}", hash));
+ if (en.MoveNext())
+ throw new Exception(string.Format("Too many source blocklist entries in {0}", hash));
+ }
}
}
}
diff --git a/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs b/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs
index bc4220ac7..41f034efa 100644
--- a/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs
@@ -201,7 +201,7 @@ namespace Duplicati.Library.Main.Database
cmd.ExecuteNonQuery(string.Format(@"DROP TABLE IF EXISTS ""{0}"" ", m_tempfiletable));
cmd.ExecuteNonQuery(string.Format(@"DROP TABLE IF EXISTS ""{0}"" ", m_tempblocktable));
- cmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""ID"" INTEGER PRIMARY KEY, ""Path"" TEXT NOT NULL, ""BlocksetID"" INTEGER NOT NULL, ""MetadataID"" INTEGER NOT NULL, ""Targetpath"" TEXT NULL, ""DataVerified"" BOOLEAN NOT NULL) ", m_tempfiletable));
+ cmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""ID"" INTEGER PRIMARY KEY, ""Path"" TEXT NOT NULL, ""BlocksetID"" INTEGER NOT NULL, ""MetadataID"" INTEGER NOT NULL, ""TargetPath"" TEXT NULL, ""DataVerified"" BOOLEAN NOT NULL) ", m_tempfiletable));
cmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""ID"" INTEGER PRIMARY KEY, ""FileID"" INTEGER NOT NULL, ""Index"" INTEGER NOT NULL, ""Hash"" TEXT NOT NULL, ""Size"" INTEGER NOT NULL, ""Restored"" BOOLEAN NOT NULL, ""Metadata"" BOOLEAN NOT NULL)", m_tempblocktable));
cmd.ExecuteNonQuery(string.Format(@"CREATE INDEX ""{0}_Index"" ON ""{0}"" (""TargetPath"")", m_tempfiletable));
cmd.ExecuteNonQuery(string.Format(@"CREATE INDEX ""{0}_HashSizeIndex"" ON ""{0}"" (""Hash"", ""Size"")", m_tempblocktable));
@@ -315,6 +315,19 @@ namespace Duplicati.Library.Main.Database
return new Tuple<long, long>(0, 0);
}
+ public string GetFirstPath()
+ {
+ using (var cmd = m_connection.CreateCommand())
+ {
+ cmd.CommandText = string.Format(@"SELECT ""Path"" FROM ""{0}"" ORDER BY LENGTH(""Path"") DESC LIMIT 1", m_tempfiletable);
+ var v0 = cmd.ExecuteScalar();
+ if (v0 == null || v0 == DBNull.Value)
+ return null;
+
+ return v0.ToString();
+ }
+ }
+
public string GetLargestPrefix()
{
using (var cmd = m_connection.CreateCommand())
@@ -322,9 +335,11 @@ namespace Duplicati.Library.Main.Database
cmd.CommandText = string.Format(@"SELECT ""Path"" FROM ""{0}"" ORDER BY LENGTH(""Path"") DESC LIMIT 1", m_tempfiletable);
var v0 = cmd.ExecuteScalar();
string maxpath = "";
- if (v0 != null)
+ if (v0 != null && v0 != DBNull.Value)
maxpath = v0.ToString();
+ var dirsep = Duplicati.Library.Utility.Utility.GuessDirSeparator(maxpath);
+
cmd.CommandText = string.Format(@"SELECT COUNT(*) FROM ""{0}""", m_tempfiletable);
var filecount = cmd.ExecuteScalarInt64(-1);
long foundfiles = -1;
@@ -336,7 +351,7 @@ namespace Duplicati.Library.Main.Database
while (filecount != foundfiles && maxpath.Length > 0)
{
- var mp = Library.Utility.Utility.AppendDirSeparator(maxpath);
+ var mp = Library.Utility.Utility.AppendDirSeparator(maxpath, dirsep);
cmd.SetParameterValue(0, mp.Length);
cmd.SetParameterValue(1, mp);
foundfiles = cmd.ExecuteScalarInt64(-1);
@@ -344,19 +359,22 @@ namespace Duplicati.Library.Main.Database
if (filecount != foundfiles)
{
var oldlen = maxpath.Length;
- maxpath = Duplicati.Library.Snapshots.SnapshotUtility.SystemIO.PathGetDirectoryName(maxpath);
+
+ var lix = maxpath.LastIndexOf(dirsep, maxpath.Length - 2, StringComparison.Ordinal);
+ maxpath = maxpath.Substring(0, lix + 1);
if (string.IsNullOrWhiteSpace(maxpath) || maxpath.Length == oldlen)
maxpath = "";
}
}
- return maxpath == "" ? "" : Library.Utility.Utility.AppendDirSeparator(maxpath);
+ return maxpath == "" ? "" : Library.Utility.Utility.AppendDirSeparator(maxpath, dirsep);
}
-
}
public void SetTargetPaths(string largest_prefix, string destination)
{
+ var dirsep = Duplicati.Library.Utility.Utility.GuessDirSeparator(string.IsNullOrWhiteSpace(largest_prefix) ? GetFirstPath() : largest_prefix);
+
using(var cmd = m_connection.CreateCommand())
{
if (string.IsNullOrEmpty(destination))
@@ -364,33 +382,61 @@ namespace Duplicati.Library.Main.Database
//The string fixing here is meant to provide some non-random
// defaults when restoring cross OS, e.g. backup on Linux, restore on Windows
//This is mostly meaningless, and the user really should use --restore-path
-
- if (Library.Utility.Utility.IsClientLinux)
+
+ if (Library.Utility.Utility.IsClientLinux && dirsep == "\\")
+ {
// For Win -> Linux, we remove the colon from the drive letter, and use the drive letter as root folder
- cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = CASE WHEN SUBSTR(""Path"", 2, 1) == "":"" THEN ""/"" || SUBSTR(""Path"", 1, 1) || SUBSTR(""Path"", 3) ELSE ""Path"" END", m_tempfiletable));
- else
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = CASE WHEN SUBSTR(""Path"", 2, 1) == "":"" THEN ""\\"" || SUBSTR(""Path"", 1, 1) || SUBSTR(""Path"", 3) ELSE ""Path"" END", m_tempfiletable));
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = CASE WHEN SUBSTR(""Path"", 1, 2) == ""\\"" THEN ""\\"" || SUBSTR(""Path"", 2) ELSE ""Path"" END", m_tempfiletable));
+
+ }
+ else if (Library.Utility.Utility.IsClientWindows && dirsep == "/")
+ {
// For Linux -> Win, we use the temporary folder's drive as the root path
- cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = CASE WHEN SUBSTR(""Path"", 1, 1) == ""/"" THEN ? || SUBSTR(""Path"", 2) ELSE ""Path"" END", m_tempfiletable), Library.Utility.Utility.AppendDirSeparator(System.IO.Path.GetPathRoot(Library.Utility.TempFolder.SystemTempPath)));
-
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = CASE WHEN SUBSTR(""Path"", 1, 1) == ""/"" THEN ? || SUBSTR(""Path"", 2) ELSE ""Path"" END", m_tempfiletable), Library.Utility.Utility.AppendDirSeparator(System.IO.Path.GetPathRoot(Library.Utility.TempFolder.SystemTempPath)).Replace("\\", "/"));
+ }
+ else
+ {
+ // Same OS, just use the path directly
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = ""Path"" ", m_tempfiletable));
+ }
}
else
{
if (string.IsNullOrEmpty(largest_prefix))
{
- //Special case, restoring to new folder, but files are from different drives
- // So we use the format <restore path> / <drive letter> / <source path>
- // To avoid generating paths with a colon
- cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = ? || CASE WHEN SUBSTR(""Path"", 2, 1) == "":"" THEN SUBSTR(""Path"", 1, 1) || SUBSTR(""Path"", 3) ELSE ""Path"" END", m_tempfiletable), destination);
+ //Special case, restoring to new folder, but files are from different drives (no shared root on Windows)
+
+ // We use the format <restore path> / <drive letter> / <source path>
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""TargetPath"" = CASE WHEN SUBSTR(""Path"", 2, 1) == "":"" THEN SUBSTR(""Path"", 1, 1) || SUBSTR(""Path"", 3) ELSE ""Path"" END", m_tempfiletable));
+
+ // For UNC paths, we use \\server\folder -> <restore path> / <servername> / <source path>
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""TargetPath"" = CASE WHEN SUBSTR(""Path"", 1, 2) == ""\\"" THEN SUBSTR(""Path"", 2) ELSE ""TargetPath"" END", m_tempfiletable));
}
else
{
- largest_prefix = Library.Utility.Utility.AppendDirSeparator(largest_prefix);
- cmd.CommandText = string.Format(@"UPDATE ""{0}"" SET ""Targetpath"" = ? || SUBSTR(""Path"", ?)", m_tempfiletable);
- cmd.AddParameter(destination);
- cmd.AddParameter(largest_prefix.Length + 1);
- cmd.ExecuteNonQuery();
+ largest_prefix = Library.Utility.Utility.AppendDirSeparator(largest_prefix, dirsep);
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""TargetPath"" = SUBSTR(""Path"", ?)", m_tempfiletable), largest_prefix.Length + 1);
}
- }
+ }
+
+ // Cross-os path remapping support
+ if (Library.Utility.Utility.IsClientLinux && dirsep == "\\")
+ // For Win paths on Linux
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""TargetPath"" = REPLACE(""TargetPath"", ""\"", ""/"")", m_tempfiletable));
+ else if (Library.Utility.Utility.IsClientWindows && dirsep == "/")
+ // For Linux paths on Windows
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""TargetPath"" = REPLACE(REPLACE(""TargetPath"", ""\"", ""_""), ""/"", ""\"")", m_tempfiletable));
+
+ if (!string.IsNullOrEmpty(destination))
+ {
+ // Paths are now relative with target-os naming system
+ // so we prefix them with the target path
+
+ cmd.ExecuteNonQuery(string.Format(@"UPDATE ""{0}"" SET ""TargetPath"" = ? || ""TargetPath"" ", m_tempfiletable), Library.Utility.Utility.AppendDirSeparator(destination));
+ }
+
+
}
}
@@ -887,7 +933,7 @@ namespace Duplicati.Library.Main.Database
cmd.AddParameter(!onlyNonVerified);
using (var rd = cmd.ExecuteReader(string.Format(@"SELECT ""{0}"".""ID"", ""{0}"".""TargetPath"", ""Blockset"".""FullHash"", ""Blockset"".""Length"" FROM ""{0}"",""Blockset"" WHERE ""{0}"".""BlocksetID"" = ""Blockset"".""ID"" AND ""{0}"".""DataVerified"" <= ?", m_tempfiletable)))
while (rd.Read())
- yield return new FileToRestore(rd.GetInt64(0), rd.GetString(1), rd.GetString(2), rd.GetInt64(3));
+ yield return new FileToRestore(rd.ConvertValueToInt64(0), rd.ConvertValueToString(1), rd.ConvertValueToString(2), rd.ConvertValueToInt64(3));
}
}
diff --git a/Duplicati/Library/Main/Database/LocalTestDatabase.cs b/Duplicati/Library/Main/Database/LocalTestDatabase.cs
index 0801556ac..e367ed68c 100644
--- a/Duplicati/Library/Main/Database/LocalTestDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalTestDatabase.cs
@@ -117,7 +117,7 @@ namespace Duplicati.Library.Main.Database
using(var cmd = m_connection.CreateCommand())
{
// Select any broken items
- using(var rd = cmd.ExecuteReader(@"SELECT ""ID"", ""Name"", ""Size"", ""Hash"", ""VerificationCount"" FROM ""Remotevolume"" WHERE (""State"" = ? OR ""State"" = ?) AND (""Hash"" = """" OR ""Hash"" IS NULL OR ""Size"" < 0) ", RemoteVolumeState.Verified.ToString(), RemoteVolumeState.Uploaded.ToString()))
+ using(var rd = cmd.ExecuteReader(@"SELECT ""ID"", ""Name"", ""Size"", ""Hash"", ""VerificationCount"" FROM ""Remotevolume"" WHERE (""State"" = ? OR ""State"" = ?) AND (""Hash"" = """" OR ""Hash"" IS NULL OR ""Size"" <= 0) ", RemoteVolumeState.Verified.ToString(), RemoteVolumeState.Uploaded.ToString()))
while (rd.Read())
yield return new RemoteVolume(rd);
diff --git a/Duplicati/Library/Main/Database/PathLookupHelper.cs b/Duplicati/Library/Main/Database/PathLookupHelper.cs
index 39d093b71..80cd71767 100644
--- a/Duplicati/Library/Main/Database/PathLookupHelper.cs
+++ b/Duplicati/Library/Main/Database/PathLookupHelper.cs
@@ -165,7 +165,7 @@ namespace Duplicati.Library.Main.Database
public bool TryGetChild(string name, out FolderEntry v)
{
if (string.IsNullOrEmpty(name))
- throw new ArgumentException("name");
+ throw new ArgumentException("Invalid pathname.", nameof(name));
if (m_folders == null)
{
diff --git a/Duplicati/Library/Main/DatabaseLocator.cs b/Duplicati/Library/Main/DatabaseLocator.cs
index 0e5c4410b..c2d54616f 100644
--- a/Duplicati/Library/Main/DatabaseLocator.cs
+++ b/Duplicati/Library/Main/DatabaseLocator.cs
@@ -44,8 +44,34 @@ namespace Duplicati.Library.Main
if (!string.IsNullOrEmpty(options.Dbpath))
return options.Dbpath;
-
- var folder = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Duplicati");
+
+ //Normal mode uses the systems "(Local) Application Data" folder
+ // %LOCALAPPDATA% on Windows, ~/.config on Linux
+
+ // Special handling for Windows:
+ // - Older versions use %APPDATA%
+ // - but new versions use %LOCALAPPDATA%
+ //
+ // If we find a new version, lets use that
+ // otherwise use the older location
+ //
+
+ var folder = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Duplicati");
+
+ if (Duplicati.Library.Utility.Utility.IsClientWindows)
+ {
+ var newlocation = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Duplicati");
+
+ var prevfile = System.IO.Path.Combine(folder, "dbconfig.json");
+ var curfile = System.IO.Path.Combine(newlocation, "dbconfig.json");
+
+ // If the new file exists, we use that
+ // If the new file does not exist, and the old file exists we use the old
+ // Otherwise we use the new location
+ if (System.IO.File.Exists(curfile) || !System.IO.File.Exists(prevfile))
+ folder = newlocation;
+ }
+
if (!System.IO.Directory.Exists(folder))
System.IO.Directory.CreateDirectory(folder);
@@ -76,17 +102,17 @@ namespace Duplicati.Library.Main
{
foreach(var o in sopts)
{
- if (username == null && o.Aliases != null && o.Aliases.Contains("auth-username", StringComparer.InvariantCultureIgnoreCase) && ropts.ContainsKey(o.Name))
+ if (username == null && o.Aliases != null && o.Aliases.Contains("auth-username", StringComparer.OrdinalIgnoreCase) && ropts.ContainsKey(o.Name))
username = ropts[o.Name];
- if (password == null && o.Aliases != null && o.Aliases.Contains("auth-password", StringComparer.InvariantCultureIgnoreCase) && ropts.ContainsKey(o.Name))
+ if (password == null && o.Aliases != null && o.Aliases.Contains("auth-password", StringComparer.OrdinalIgnoreCase) && ropts.ContainsKey(o.Name))
password = ropts[o.Name];
}
foreach(var o in sopts)
{
- if (username == null && o.Name.Equals("auth-username", StringComparison.InvariantCultureIgnoreCase) && ropts.ContainsKey("auth-username"))
+ if (username == null && o.Name.Equals("auth-username", StringComparison.OrdinalIgnoreCase) && ropts.ContainsKey("auth-username"))
username = ropts["auth-username"];
- if (password == null && o.Name.Equals("auth-password", StringComparison.InvariantCultureIgnoreCase) && ropts.ContainsKey("auth-password"))
+ if (password == null && o.Name.Equals("auth-password", StringComparison.OrdinalIgnoreCase) && ropts.ContainsKey("auth-password"))
password = ropts["auth-password"];
}
}
@@ -108,7 +134,7 @@ namespace Duplicati.Library.Main
select n).ToList();
if (matches.Count > 1)
- throw new Exception(string.Format("Multiple sources found for: {0}", backend));
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Multiple sources found for: {0}", backend));
// Re-select
if (matches.Count == 0 && anyUsername && string.IsNullOrEmpty(username))
@@ -123,7 +149,7 @@ namespace Duplicati.Library.Main
select n).ToList();
if (matches.Count > 1)
- throw new Exception(String.Format("Multiple sources found for \"{0}\", try supplying --{1}", backend, "auth-username"));
+ throw new Duplicati.Library.Interface.UserInformationException(String.Format("Multiple sources found for \"{0}\", try supplying --{1}", backend, "auth-username"));
}
if (matches.Count == 0 && !autoCreate)
@@ -146,7 +172,7 @@ namespace Duplicati.Library.Main
newpath = System.IO.Path.Combine(folder, GenerateRandomName());
if (System.IO.File.Exists(newpath))
- throw new Exception("Unable to find a unique name for the database, please use --dbpath");
+ throw new Duplicati.Library.Interface.UserInformationException("Unable to find a unique name for the database, please use --dbpath");
//Create a new one, add it to the list, and save it
configs.Add(new BackendEntry() {
@@ -183,6 +209,20 @@ namespace Duplicati.Library.Main
return backupname;
}
+
+ public static bool IsDatabasePathInUse(string path)
+ {
+ var folder = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Duplicati");
+ if (!System.IO.Directory.Exists(folder))
+ return false;
+
+ var file = System.IO.Path.Combine(folder, "dbconfig.json");
+ List<BackendEntry> configs;
+ if (!System.IO.File.Exists(file))
+ return false;
+
+ return Newtonsoft.Json.JsonConvert.DeserializeObject<List<BackendEntry>>(System.IO.File.ReadAllText(file, System.Text.Encoding.UTF8)).Any(x => string.Equals(path, x.Databasepath, Library.Utility.Utility.ClientFilenameStringComparision));
+ }
}
}
diff --git a/Duplicati/Library/Main/Duplicati.Library.Main.csproj b/Duplicati/Library/Main/Duplicati.Library.Main.csproj
index d46afc47f..3d3c9773a 100644
--- a/Duplicati/Library/Main/Duplicati.Library.Main.csproj
+++ b/Duplicati/Library/Main/Duplicati.Library.Main.csproj
@@ -17,6 +17,7 @@
<TargetFrameworkProfile />
<UpgradeBackupLocation>
</UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
@@ -40,10 +41,11 @@
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="Operation\VacuumHandler.cs" />
<Compile Include="Options.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Database\ILocalFileEntry.cs" />
@@ -105,6 +107,11 @@
<Compile Include="Strings.cs" />
<Compile Include="Operation\RestoreHandlerMetadataStorage.cs" />
<Compile Include="Operation\SystemInfoHandler.cs" />
+ <Compile Include="Operation\PurgeFilesHandler.cs" />
+ <Compile Include="Database\LocalPurgeDatabase.cs" />
+ <Compile Include="Database\LocalListBrokenFilesDatabase.cs" />
+ <Compile Include="Operation\ListBrokenFilesHandler.cs" />
+ <Compile Include="Operation\PurgeBrokenFilesHandler.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Utility\Duplicati.Library.Utility.csproj">
@@ -167,6 +174,7 @@
<ItemGroup>
<EmbeddedResource Include="Database\Database schema\5. Optimize BlockSet-Tables.sql" />
<EmbeddedResource Include="Database\Database schema\6. Optimize FileSetEntry-Table.sql" />
+ <EmbeddedResource Include="Database\Database schema\7. Add index.sql" />
<Content Include="default_compressed_extensions.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
diff --git a/Duplicati/Library/Main/Enums.cs b/Duplicati/Library/Main/Enums.cs
index f0d1a4f11..b3de3d83d 100644
--- a/Duplicati/Library/Main/Enums.cs
+++ b/Duplicati/Library/Main/Enums.cs
@@ -42,7 +42,13 @@ namespace Duplicati.Library.Main
Compact,
Test,
TestFilters,
- SystemInfo
+ SystemInfo,
+ ListRemote,
+ ListBrokenFiles,
+ PurgeBrokenFiles,
+ PurgeFiles,
+ SendMail,
+ Vacuum,
}
/// <summary>
diff --git a/Duplicati/Library/Main/IMetahash.cs b/Duplicati/Library/Main/IMetahash.cs
index e9a830900..2fdfd7880 100644
--- a/Duplicati/Library/Main/IMetahash.cs
+++ b/Duplicati/Library/Main/IMetahash.cs
@@ -28,11 +28,7 @@ namespace Duplicati.Library.Main
/// <summary>
/// The base64 encoded hash of the metadata
/// </summary>
- string Hash { get; }
- /// <summary>
- /// The size of the metadata in bytes
- /// </summary>
- long Size { get; }
+ string FileHash { get; }
/// <summary>
/// The UTF-8 encoded json element with the metadata
/// </summary>
diff --git a/Duplicati/Library/Main/Operation/BackupHandler.cs b/Duplicati/Library/Main/Operation/BackupHandler.cs
index 3e2f33101..d9c6fe934 100644
--- a/Duplicati/Library/Main/Operation/BackupHandler.cs
+++ b/Duplicati/Library/Main/Operation/BackupHandler.cs
@@ -41,6 +41,8 @@ namespace Duplicati.Library.Main.Operation
private readonly FileAttributes m_attributeFilter;
private readonly Options.SymlinkStrategy m_symlinkPolicy;
private int m_blocksize;
+ private long m_maxmetadatasize;
+ private long m_lastfilesetid;
public BackupHandler(string backendurl, Options options, BackupResults results)
{
@@ -54,7 +56,7 @@ namespace Duplicati.Library.Main.Operation
m_symlinkPolicy = m_options.SymlinkPolicy;
if (options.AllowPassphraseChange)
- throw new Exception(Strings.Common.PassphraseChangeUnsupported);
+ throw new UserInformationException(Strings.Common.PassphraseChangeUnsupported);
}
@@ -92,17 +94,16 @@ namespace Duplicati.Library.Main.Operation
}
else
m_enumeratefilter = m_emitfilter;
+ }
+ public void ReportError(string rootpath, string path, Exception ex)
+ {
+ if (m_logWriter != null)
+ m_logWriter.AddWarning(string.Format("Error reported while accessing file: {0}", path), ex);
}
-
+
public bool AttributeFilter(string rootpath, string path, FileAttributes attributes)
{
- if ((attributes & Library.Utility.Utility.ATTRIBUTE_ERROR) == Library.Utility.Utility.ATTRIBUTE_ERROR)
- {
- if (m_logWriter != null)
- m_logWriter.AddWarning(string.Format("Error reported while accessing file {0}", path), null);
- }
-
try
{
if (m_snapshot.IsBlockDevice(path))
@@ -208,7 +209,7 @@ namespace Duplicati.Library.Main.Operation
public IEnumerable<string> EnumerateFilesAndFolders()
{
- foreach(var s in m_snapshot.EnumerateFilesAndFolders(this.AttributeFilter))
+ foreach(var s in m_snapshot.EnumerateFilesAndFolders(this.AttributeFilter, this.ReportError))
{
while (m_mixinqueue.Count > 0)
yield return m_mixinqueue.Dequeue();
@@ -248,12 +249,6 @@ namespace Duplicati.Library.Main.Operation
public static Snapshots.ISnapshotService GetSnapshot(string[] sources, Options options, ILogWriter log)
{
- if (!Library.Utility.Utility.IsClientWindows && options.RawOptions.ContainsKey("hyperv-backup-vm"))
- log.AddWarning("hyperv-backup-vm is efective only on Windows OS.", null);
-
- if (Library.Utility.Utility.IsClientWindows && options.RawOptions.ContainsKey("hyperv-backup-vm") && options.SnapShotStrategy == Options.OptimizationStrategy.Off)
- throw new Exception("Snapshot strategy cannot be Off when backuping Hyper-V using hyperv-backup-vm"); //VSS is required for Hyper-V backups
-
try
{
if (options.SnapShotStrategy != Options.OptimizationStrategy.Off)
@@ -263,12 +258,8 @@ namespace Duplicati.Library.Main.Operation
{
if (options.SnapShotStrategy == Options.OptimizationStrategy.Required)
throw;
- else if (options.SnapShotStrategy == Options.OptimizationStrategy.On && options.RawOptions.ContainsKey("hyperv-backup-vm"))
- throw; //VSS is required for Hyper-V backups
else if (options.SnapShotStrategy == Options.OptimizationStrategy.On)
- {
log.AddWarning(Strings.Common.SnapshotFailedError(ex.ToString()), ex);
- }
}
return Library.Utility.Utility.IsClientLinux ?
@@ -310,86 +301,87 @@ namespace Duplicati.Library.Main.Operation
private void UploadSyntheticFilelist(BackendManager backend)
{
- var incompleteFilesets = m_database.GetIncompleteFilesets(null).OrderBy(x => x.Value).ToArray();
- if (incompleteFilesets.Length != 0)
+ var incompleteFilesets = m_database.GetIncompleteFilesets(null).OrderBy(x => x.Value).ToList();
+
+ m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_PreviousBackupFinalize);
+ m_result.AddMessage(string.Format("Uploading filelist from previous interrupted backup"));
+ using(var trn = m_database.BeginTransaction())
{
- m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_PreviousBackupFinalize);
- m_result.AddMessage(string.Format("Uploading filelist from previous interrupted backup"));
- using(var trn = m_database.BeginTransaction())
- {
- var incompleteSet = incompleteFilesets.Last();
- var badIds = from n in incompleteFilesets select n.Key;
+ var incompleteSet = incompleteFilesets.Last();
+ var badIds = from n in incompleteFilesets select n.Key;
- var prevs = (from n in m_database.FilesetTimes
- where
- n.Key < incompleteSet.Key
- &&
- !badIds.Contains(n.Key)
- orderby n.Key
- select n.Key).ToArray();
+ var prevs = (from n in m_database.FilesetTimes
+ where
+ n.Key < incompleteSet.Key
+ &&
+ !badIds.Contains(n.Key)
+ orderby n.Key
+ select n.Key).ToArray();
- var prevId = prevs.Length == 0 ? -1 : prevs.Last();
+ var prevId = prevs.Length == 0 ? -1 : prevs.Last();
- FilesetVolumeWriter fsw = null;
- try
- {
- var s = 1;
- var fileTime = incompleteSet.Value + TimeSpan.FromSeconds(s);
- var oldFilesetID = incompleteSet.Key;
+ FilesetVolumeWriter fsw = null;
+ try
+ {
+ var s = 1;
+ var fileTime = incompleteSet.Value + TimeSpan.FromSeconds(s);
+ var oldFilesetID = incompleteSet.Key;
- // Probe for an unused filename
- while (s < 60)
- {
- var id = m_database.GetRemoteVolumeID(VolumeBase.GenerateFilename(RemoteVolumeType.Files, m_options, null, fileTime));
- if (id < 0)
- break;
+ // Probe for an unused filename
+ while (s < 60)
+ {
+ var id = m_database.GetRemoteVolumeID(VolumeBase.GenerateFilename(RemoteVolumeType.Files, m_options, null, fileTime));
+ if (id < 0)
+ break;
- fileTime = incompleteSet.Value + TimeSpan.FromSeconds(++s);
- }
+ fileTime = incompleteSet.Value + TimeSpan.FromSeconds(++s);
+ }
- fsw = new FilesetVolumeWriter(m_options, fileTime);
- fsw.VolumeID = m_database.RegisterRemoteVolume(fsw.RemoteFilename, RemoteVolumeType.Files, RemoteVolumeState.Temporary, m_transaction);
+ fsw = new FilesetVolumeWriter(m_options, fileTime);
+ fsw.VolumeID = m_database.RegisterRemoteVolume(fsw.RemoteFilename, RemoteVolumeType.Files, RemoteVolumeState.Temporary, m_transaction);
- if (!string.IsNullOrEmpty(m_options.ControlFiles))
- foreach(var p in m_options.ControlFiles.Split(new char[] { System.IO.Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries))
- fsw.AddControlFile(p, m_options.GetCompressionHintFromFilename(p));
+ if (!string.IsNullOrEmpty(m_options.ControlFiles))
+ foreach(var p in m_options.ControlFiles.Split(new char[] { System.IO.Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries))
+ fsw.AddControlFile(p, m_options.GetCompressionHintFromFilename(p));
- var newFilesetID = m_database.CreateFileset(fsw.VolumeID, fileTime, trn);
- m_database.LinkFilesetToVolume(newFilesetID, fsw.VolumeID, trn);
- m_database.AppendFilesFromPreviousSet(trn, null, newFilesetID, prevId, fileTime);
+ var newFilesetID = m_database.CreateFileset(fsw.VolumeID, fileTime, trn);
+ m_database.LinkFilesetToVolume(newFilesetID, fsw.VolumeID, trn);
+ m_database.AppendFilesFromPreviousSet(trn, null, newFilesetID, prevId, fileTime);
- m_database.WriteFileset(fsw, trn, newFilesetID);
+ m_database.WriteFileset(fsw, trn, newFilesetID);
- if (m_options.Dryrun)
- {
- m_result.AddDryrunMessage(string.Format("Would upload fileset: {0}, size: {1}", fsw.RemoteFilename, Library.Utility.Utility.FormatSizeString(new FileInfo(fsw.LocalFilename).Length)));
- }
- else
- {
- m_database.UpdateRemoteVolume(fsw.RemoteFilename, RemoteVolumeState.Uploading, -1, null, trn);
+ if (m_options.Dryrun)
+ {
+ m_result.AddDryrunMessage(string.Format("Would upload fileset: {0}, size: {1}", fsw.RemoteFilename, Library.Utility.Utility.FormatSizeString(new FileInfo(fsw.LocalFilename).Length)));
+ }
+ else
+ {
+ m_database.UpdateRemoteVolume(fsw.RemoteFilename, RemoteVolumeState.Uploading, -1, null, trn);
- using(new Logging.Timer("CommitUpdateFilelistVolume"))
- trn.Commit();
+ using(new Logging.Timer("CommitUpdateFilelistVolume"))
+ trn.Commit();
- backend.Put(fsw);
- fsw = null;
- }
+ backend.Put(fsw);
+ fsw = null;
}
- finally
- {
- if (fsw != null)
- try { fsw.Dispose(); }
- catch { fsw = null; }
- }
}
+ finally
+ {
+ if (fsw != null)
+ try { fsw.Dispose(); }
+ catch { fsw = null; }
+ }
}
+ }
+ private void RecreateMissingIndexFiles(BackendManager backend)
+ {
if (m_options.IndexfilePolicy != Options.IndexFileStrategy.None)
{
- var blockhasher = System.Security.Cryptography.HashAlgorithm.Create(m_options.BlockHashAlgorithm);
+ var blockhasher = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
var hashsize = blockhasher.HashSize / 8;
- foreach(var blockfile in m_database.GetMissingIndexFiles())
+ foreach (var blockfile in m_database.GetMissingIndexFiles())
{
m_result.AddMessage(string.Format("Re-creating missing index file for {0}", blockfile));
var w = new IndexVolumeWriter(m_options);
@@ -399,13 +391,13 @@ namespace Duplicati.Library.Main.Operation
w.StartVolume(blockvolume.Name);
var volumeid = m_database.GetRemoteVolumeID(blockvolume.Name);
- foreach(var b in m_database.GetBlocks(volumeid))
+ foreach (var b in m_database.GetBlocks(volumeid))
w.AddBlock(b.Hash, b.Size);
w.FinishVolume(blockvolume.Hash, blockvolume.Size);
if (m_options.IndexfilePolicy == Options.IndexFileStrategy.Full)
- foreach(var b in m_database.GetBlocklists(volumeid, m_options.Blocksize, hashsize))
+ foreach (var b in m_database.GetBlocklists(volumeid, m_options.Blocksize, hashsize))
w.WriteBlocklist(b.Item1, b.Item2, 0, b.Item3);
w.Close();
@@ -423,20 +415,20 @@ namespace Duplicati.Library.Main.Operation
}
}
- private void PreBackupVerify(BackendManager backend)
+ private void PreBackupVerify(BackendManager backend, string protectedfile)
{
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_PreBackupVerify);
using(new Logging.Timer("PreBackupVerify"))
{
try
{
- if (m_options.NoBackendverification)
- {
- FilelistProcessor.VerifyLocalList(backend, m_options, m_database, m_result.BackendWriter);
- UpdateStorageStatsFromDatabase();
- }
- else
- FilelistProcessor.VerifyRemoteList(backend, m_options, m_database, m_result.BackendWriter);
+ if (m_options.NoBackendverification)
+ {
+ FilelistProcessor.VerifyLocalList(backend, m_options, m_database, m_result.BackendWriter);
+ UpdateStorageStatsFromDatabase();
+ }
+ else
+ FilelistProcessor.VerifyRemoteList(backend, m_options, m_database, m_result.BackendWriter, protectedfile);
}
catch (Exception ex)
{
@@ -609,12 +601,12 @@ namespace Duplicati.Library.Main.Operation
{
var currentIsSmall = lastVolumeSize != -1 && lastVolumeSize <= m_options.SmallFileSize;
- if (m_options.KeepTime.Ticks > 0 || m_options.KeepVersions != 0)
+ if (m_options.KeepTime.Ticks > 0 || m_options.KeepVersions != 0 || m_options.RetentionPolicy.Count > 0)
{
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_Delete);
m_result.DeleteResults = new DeleteResults(m_result);
using(var db = new LocalDeleteDatabase(m_database))
- new DeleteHandler(backend.BackendUrl, m_options, (DeleteResults)m_result.DeleteResults).DoRun(db, ref m_transaction, true, currentIsSmall);
+ new DeleteHandler(backend.BackendUrl, m_options, (DeleteResults)m_result.DeleteResults).DoRun(db, ref m_transaction, true, currentIsSmall, backend);
}
else if (currentIsSmall && !m_options.NoAutoCompact)
@@ -622,7 +614,7 @@ namespace Duplicati.Library.Main.Operation
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_Compact);
m_result.CompactResults = new CompactResults(m_result);
using(var db = new LocalDeleteDatabase(m_database))
- new CompactHandler(backend.BackendUrl, m_options, (CompactResults)m_result.CompactResults).DoCompact(db, true, ref m_transaction);
+ new CompactHandler(backend.BackendUrl, m_options, (CompactResults)m_result.CompactResults).DoCompact(db, true, ref m_transaction, backend);
}
}
@@ -643,38 +635,44 @@ namespace Duplicati.Library.Main.Operation
using(var testdb = new LocalTestDatabase(m_database))
using(var backend = new BackendManager(m_backendurl, m_options, m_result.BackendWriter, testdb))
- new TestHandler(m_backendurl, m_options, new TestResults(m_result))
+ new TestHandler(m_backendurl, m_options, (TestResults)m_result.TestResults)
.DoRun(m_options.BackupTestSampleCount, testdb, backend);
}
}
- /// <summary>
- /// Handler for computing backend statistics, without relying on a remote folder listing
- /// </summary>
- private void UpdateStorageStatsFromDatabase()
- {
- if (m_result.BackendWriter != null)
- {
- m_result.BackendWriter.KnownFileCount = m_database.GetRemoteVolumes().Count();
- m_result.BackendWriter.KnownFileSize = m_database.GetRemoteVolumes().Select(x => Math.Max(0, x.Size)).Sum();
-
- m_result.BackendWriter.UnknownFileCount = 0;
- m_result.BackendWriter.UnknownFileSize = 0;
-
- m_result.BackendWriter.BackupListCount = m_database.FilesetTimes.Count();
- m_result.BackendWriter.LastBackupDate = m_database.FilesetTimes.FirstOrDefault().Value.ToLocalTime();
-
- // TODO: If we have a BackendManager, we should query through that
- using (var backend = DynamicLoader.BackendLoader.GetBackend(m_backendurl, m_options.RawOptions))
- if (backend is Library.Interface.IQuotaEnabledBackend)
- {
- m_result.BackendWriter.TotalQuotaSpace = ((Library.Interface.IQuotaEnabledBackend)backend).TotalQuotaSpace;
- m_result.BackendWriter.FreeQuotaSpace = ((Library.Interface.IQuotaEnabledBackend)backend).FreeQuotaSpace;
- }
- }
-
- m_result.BackendWriter.AssignedQuotaSpace = m_options.QuotaSize;
- }
+ /// <summary>
+ /// Handler for computing backend statistics, without relying on a remote folder listing
+ /// </summary>
+ private void UpdateStorageStatsFromDatabase()
+ {
+ if (m_result.BackendWriter != null)
+ {
+ m_result.BackendWriter.KnownFileCount = m_database.GetRemoteVolumes().Count();
+ m_result.BackendWriter.KnownFileSize = m_database.GetRemoteVolumes().Select(x => Math.Max(0, x.Size)).Sum();
+
+ m_result.BackendWriter.UnknownFileCount = 0;
+ m_result.BackendWriter.UnknownFileSize = 0;
+
+ m_result.BackendWriter.BackupListCount = m_database.FilesetTimes.Count();
+ m_result.BackendWriter.LastBackupDate = m_database.FilesetTimes.FirstOrDefault().Value.ToLocalTime();
+
+ // TODO: If we have a BackendManager, we should query through that
+ using (var backend = DynamicLoader.BackendLoader.GetBackend(m_backendurl, m_options.RawOptions))
+ {
+ if (backend is Library.Interface.IQuotaEnabledBackend)
+ {
+ Library.Interface.IQuotaInfo quota = ((Library.Interface.IQuotaEnabledBackend)backend).Quota;
+ if (quota != null)
+ {
+ m_result.BackendWriter.TotalQuotaSpace = quota.TotalQuotaSpace;
+ m_result.BackendWriter.FreeQuotaSpace = quota.FreeQuotaSpace;
+ }
+ }
+ }
+ }
+
+ m_result.BackendWriter.AssignedQuotaSpace = m_options.QuotaSize;
+ }
public void Run(string[] sources, Library.Utility.IFilter filter)
{
@@ -688,31 +686,36 @@ namespace Duplicati.Library.Main.Operation
Utility.UpdateOptionsFromDb(m_database, m_options);
Utility.VerifyParameters(m_database, m_options);
+ var probe_path = m_database.GetFirstPath();
+ if (probe_path != null && Duplicati.Library.Utility.Utility.GuessDirSeparator(probe_path) != System.IO.Path.DirectorySeparatorChar.ToString())
+ throw new UserInformationException(string.Format("The backup contains files that belong to another operating system. Proceeding with a backup would cause the database to contain paths from two different operation systems, which is not supported. To proceed without losing remote data, delete all filesets and make sure the --{0} option is set, then run the backup again to re-use the existing data on the remote store.", "no-auto-compact"));
+
if (m_database.PartiallyRecreated)
- throw new Exception("The database was only partially recreated. This database may be incomplete and the repair process is not allowed to alter remote files as that could result in data loss.");
+ throw new UserInformationException("The database was only partially recreated. This database may be incomplete and the repair process is not allowed to alter remote files as that could result in data loss.");
if (m_database.RepairInProgress)
- throw new Exception("The database was attempted repaired, but the repair did not complete. This database may be incomplete and the backup process cannot continue. You may delete the local database and attempt to repair it again.");
+ throw new UserInformationException("The database was attempted repaired, but the repair did not complete. This database may be incomplete and the backup process cannot continue. You may delete the local database and attempt to repair it again.");
m_blocksize = m_options.Blocksize;
+ m_maxmetadatasize = (m_blocksize / (long)m_options.BlockhashSize) * m_blocksize;
m_blockbuffer = new byte[m_options.Blocksize * Math.Max(1, m_options.FileReadBufferSize / m_options.Blocksize)];
m_blocklistbuffer = new byte[m_options.Blocksize];
- m_blockhasher = System.Security.Cryptography.HashAlgorithm.Create(m_options.BlockHashAlgorithm);
- m_filehasher = System.Security.Cryptography.HashAlgorithm.Create(m_options.FileHashAlgorithm);
+ m_blockhasher = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
+ m_filehasher = Library.Utility.HashAlgorithmHelper.Create(m_options.FileHashAlgorithm);
if (m_blockhasher == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
if (m_filehasher == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(m_options.FileHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidHashAlgorithm(m_options.FileHashAlgorithm));
if (!m_blockhasher.CanReuseTransform)
- throw new Exception(Strings.Common.InvalidCryptoSystem(m_options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidCryptoSystem(m_options.BlockHashAlgorithm));
if (!m_filehasher.CanReuseTransform)
- throw new Exception(Strings.Common.InvalidCryptoSystem(m_options.FileHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidCryptoSystem(m_options.FileHashAlgorithm));
- m_database.VerifyConsistency(null, m_options.Blocksize, m_options.BlockhashSize);
+ m_database.VerifyConsistency(null, m_options.Blocksize, m_options.BlockhashSize, false);
// If there is no filter, we set an empty filter to simplify the code
// If there is a filter, we make sure that the sources are included
m_filter = filter ?? new Library.Utility.FilterExpression();
@@ -720,11 +723,9 @@ namespace Duplicati.Library.Main.Operation
m_backendLogFlushTimer = DateTime.Now.Add(FLUSH_TIMESPAN);
System.Threading.Thread parallelScanner = null;
-
try
{
-
using(var backend = new BackendManager(m_backendurl, m_options, m_result.BackendWriter, m_database))
using(var filesetvolume = new FilesetVolumeWriter(m_options, m_database.OperationTimestamp))
{
@@ -740,11 +741,54 @@ namespace Duplicati.Library.Main.Operation
parallelScanner.Start(snapshot);
}
- PreBackupVerify(backend);
+ string lasttempfilelist = null;
+ long lasttempfileid = -1;
+ if (!m_options.DisableSyntheticFilelist)
+ {
+ var candidates = m_database.GetIncompleteFilesets(null).OrderBy(x => x.Value).ToArray();
+ if (candidates.Length > 0)
+ {
+ lasttempfileid = candidates.Last().Key;
+ lasttempfilelist = m_database.GetRemoteVolumeFromID(lasttempfileid).Name;
+ }
+ }
// Verify before uploading a synthetic list
- m_database.VerifyConsistency(null, m_options.Blocksize, m_options.BlockhashSize);
- UploadSyntheticFilelist(backend);
+ PreBackupVerify(backend, lasttempfilelist);
+
+ // If we have an incomplete entry, upload it now
+ if (!m_options.DisableSyntheticFilelist && !string.IsNullOrWhiteSpace(lasttempfilelist) && lasttempfileid >= 0)
+ {
+ // Check that we still need to process this after the cleanup has performed its duties
+ var syntbase = m_database.GetRemoteVolumeFromID(lasttempfileid);
+ if (syntbase.Name != null && (syntbase.State == RemoteVolumeState.Uploading || syntbase.State == RemoteVolumeState.Temporary))
+ {
+ UploadSyntheticFilelist(backend);
+
+ // Remove the protected file
+ if (syntbase.State == RemoteVolumeState.Uploading)
+ {
+ m_result.AddMessage(string.Format("removing incomplete remote file listed as {0}: {1}", syntbase.State, syntbase.Name));
+ backend.Delete(syntbase.Name, syntbase.Size);
+ }
+ else if (syntbase.State == RemoteVolumeState.Temporary)
+ {
+ m_result.AddMessage(string.Format("removing file listed as {0}: {1}", syntbase.State, syntbase.Name));
+ m_database.RemoveRemoteVolume(syntbase.Name);
+ }
+ }
+ else if (syntbase.Name == null || syntbase.State != RemoteVolumeState.Uploaded)
+ m_result.AddWarning(string.Format("Expected there to be a temporary fileset for synthetic filelist ({0}, {1}), but none was found?", lasttempfileid, lasttempfilelist), null);
+ }
+
+ var prevfileset = m_database.FilesetTimes.FirstOrDefault();
+ if (prevfileset.Value.ToUniversalTime() > m_database.OperationTimestamp.ToUniversalTime())
+ throw new UserInformationException(string.Format("The previous backup has time {0}, but this backup has time {1}. Something is wrong with the clock.", prevfileset.Value.ToLocalTime(), m_database.OperationTimestamp.ToLocalTime()));
+
+ m_lastfilesetid = prevfileset.Value.Ticks == 0 ? -1 : prevfileset.Key;
+
+ // Rebuild any index files that are missing
+ RecreateMissingIndexFiles(backend);
m_database.BuildLookupTable(m_options);
m_transaction = m_database.BeginTransaction();
@@ -772,18 +816,21 @@ namespace Duplicati.Library.Main.Operation
using(new Logging.Timer("UpdateChangeStatistics"))
m_database.UpdateChangeStatistics(m_result);
using(new Logging.Timer("VerifyConsistency"))
- m_database.VerifyConsistency(m_transaction, m_options.Blocksize, m_options.BlockhashSize);
+ m_database.VerifyConsistency(m_transaction, m_options.Blocksize, m_options.BlockhashSize, false);
UploadRealFileList(backend, filesetvolume);
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_WaitForUpload);
using(new Logging.Timer("Async backend wait"))
- backend.WaitForComplete(m_database, m_transaction);
+ backend.WaitForEmpty(m_database, m_transaction);
if (m_result.TaskControlRendevouz() != TaskControlState.Stop)
- CompactIfRequired(backend, lastVolumeSize);
-
- if (m_options.UploadVerificationFile)
+ CompactIfRequired(backend, lastVolumeSize);
+
+ using (new Logging.Timer("Async backend wait"))
+ backend.WaitForComplete(m_database, m_transaction);
+
+ if (m_options.UploadVerificationFile)
{
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_VerificationUpload);
FilelistProcessor.UploadVerificationFile(backend.BackendUrl, m_options, m_result.BackendWriter, m_database, m_transaction);
@@ -800,20 +847,23 @@ namespace Duplicati.Library.Main.Operation
m_transaction.Commit();
m_transaction = null;
- m_database.Vacuum();
- if (m_result.TaskControlRendevouz() != TaskControlState.Stop)
- {
- if (m_options.NoBackendverification)
- UpdateStorageStatsFromDatabase();
- else
- PostBackupVerification();
- }
+ if (m_result.TaskControlRendevouz() != TaskControlState.Stop)
+ {
+ if (m_options.NoBackendverification)
+ UpdateStorageStatsFromDatabase();
+ else
+ PostBackupVerification();
+ }
}
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_Complete);
m_database.WriteResults();
m_database.PurgeLogData(m_options.LogRetention);
+ if (m_options.AutoVacuum)
+ {
+ m_database.Vacuum();
+ }
return;
}
}
@@ -847,7 +897,7 @@ namespace Duplicati.Library.Main.Operation
if (m_options.StoreMetadata)
{
- metadata = snapshot.GetMetadata(path);
+ metadata = snapshot.GetMetadata(path, attributes.HasFlag(System.IO.FileAttributes.ReparsePoint), m_symlinkPolicy == Options.SymlinkStrategy.Follow);
if (metadata == null)
metadata = new Dictionary<string, string>();
@@ -973,10 +1023,10 @@ namespace Duplicati.Library.Main.Operation
// Last scan time
DateTime oldModified;
- long lastFileSize = -1;
+ long lastFileSize;
string oldMetahash;
long oldMetasize;
- var oldId = m_database.GetFileEntry(path, out oldModified, out lastFileSize, out oldMetahash, out oldMetasize);
+ long oldId;
long filestatsize = -1;
try { filestatsize = snapshot.GetFileSize(path); }
@@ -984,10 +1034,22 @@ namespace Duplicati.Library.Main.Operation
IMetahash metahashandsize = m_options.StoreMetadata ? Utility.WrapMetadata(GenerateMetadata(snapshot, path, attributes), m_options) : EMPTY_METADATA;
+ if (m_options.CheckFiletimeOnly || m_options.DisableFiletimeCheck)
+ {
+ lastFileSize = filestatsize;
+ oldMetahash = metahashandsize.FileHash;
+ oldMetasize = metahashandsize.Blob.Length;
+ oldId = m_database.GetFileLastModified(path, m_lastfilesetid, out oldModified);
+ }
+ else
+ {
+ oldId = m_database.GetFileEntry(path, m_lastfilesetid, out oldModified, out lastFileSize, out oldMetahash, out oldMetasize);
+ }
+
var timestampChanged = lastwrite != oldModified || lastwrite.Ticks == 0 || oldModified.Ticks == 0;
var filesizeChanged = filestatsize < 0 || lastFileSize < 0 || filestatsize != lastFileSize;
var tooLargeFile = m_options.SkipFilesLargerThan != long.MaxValue && m_options.SkipFilesLargerThan != 0 && filestatsize >= 0 && filestatsize > m_options.SkipFilesLargerThan;
- var metadatachanged = !m_options.SkipMetadata && (metahashandsize.Size != oldMetasize || metahashandsize.Hash != oldMetahash);
+ var metadatachanged = !m_options.SkipMetadata && (metahashandsize.Blob.Length != oldMetasize || metahashandsize.FileHash != oldMetahash);
if ((oldId < 0 || m_options.DisableFiletimeCheck || timestampChanged || filesizeChanged || metadatachanged) && !tooLargeFile)
{
@@ -1003,67 +1065,16 @@ namespace Duplicati.Library.Main.Operation
using (var blocklisthashes = new Library.Utility.FileBackedStringList())
using (var hashcollector = new Library.Utility.FileBackedStringList())
{
- using (var fs = new Blockprocessor(snapshot.OpenRead(path), m_blockbuffer))
+ using (var fs = snapshot.OpenRead(path))
{
try { m_result.OperationProgressUpdater.StartFile(path, fs.Length); }
catch (Exception ex) { m_result.AddWarning(string.Format("Failed to read file length for file {0}", path), ex); }
- int blocklistoffset = 0;
-
- m_filehasher.Initialize();
-
-
- var offset = 0;
- var remaining = fs.Readblock();
-
- do
- {
- var size = Math.Min(m_blocksize, remaining);
-
- m_filehasher.TransformBlock(m_blockbuffer, offset, size, m_blockbuffer, offset);
- var blockkey = m_blockhasher.ComputeHash(m_blockbuffer, offset, size);
- if (m_blocklistbuffer.Length - blocklistoffset < blockkey.Length)
- {
- var blkey = Convert.ToBase64String(m_blockhasher.ComputeHash(m_blocklistbuffer, 0, blocklistoffset));
- blocklisthashes.Add(blkey);
- AddBlockToOutput(backend, blkey, m_blocklistbuffer, 0, blocklistoffset, CompressionHint.Noncompressible, true);
- blocklistoffset = 0;
- }
-
- Array.Copy(blockkey, 0, m_blocklistbuffer, blocklistoffset, blockkey.Length);
- blocklistoffset += blockkey.Length;
-
- var key = Convert.ToBase64String(blockkey);
- AddBlockToOutput(backend, key, m_blockbuffer, offset, size, hint, false);
- hashcollector.Add(key);
- filesize += size;
-
- m_result.OperationProgressUpdater.UpdateFileProgress(filesize);
- if (m_result.TaskControlRendevouz() == TaskControlState.Stop)
- return false;
-
- remaining -= size;
- offset += size;
-
- if (remaining == 0)
- {
- offset = 0;
- remaining = fs.Readblock();
- }
-
- } while (remaining > 0);
-
- //If all fits in a single block, don't bother with blocklists
- if (hashcollector.Count > 1)
- {
- var blkeyfinal = Convert.ToBase64String(m_blockhasher.ComputeHash(m_blocklistbuffer, 0, blocklistoffset));
- blocklisthashes.Add(blkeyfinal);
- AddBlockToOutput(backend, blkeyfinal, m_blocklistbuffer, 0, blocklistoffset, CompressionHint.Noncompressible, true);
- }
+ if ((filesize = ProcessStream(fs, hint, backend, blocklisthashes, hashcollector, false)) < 0)
+ return false;
}
m_result.SizeOfOpenedFiles += filesize;
- m_filehasher.TransformFinalBlock(m_blockbuffer, 0, 0);
var filekey = Convert.ToBase64String(m_filehasher.Hash);
if (oldHash != filekey)
@@ -1109,13 +1120,17 @@ namespace Duplicati.Library.Main.Operation
}
else
{
- if (m_options.SkipFilesLargerThan == long.MaxValue || m_options.SkipFilesLargerThan == 0 || snapshot.GetFileSize(path) < m_options.SkipFilesLargerThan)
- m_result.AddVerboseMessage("Skipped checking file, because timestamp was not updated {0}", path);
+ if (tooLargeFile)
+ m_result.AddVerboseMessage("Excluding file because the size {0} exceeds limit ({1}): {2}", Library.Utility.Utility.FormatSizeString(filestatsize), Library.Utility.Utility.FormatSizeString(m_options.SkipFilesLargerThan), path);
else
- m_result.AddVerboseMessage("Skipped checking file, because the size exceeds limit {0}", path);
+ m_result.AddVerboseMessage("Skipped checking file, because timestamp was not updated {0}", path);
}
- if (!changed)
+ // If the file was not previously found, we cannot add it
+ // If the file was too large, we treat it as missing,
+ // otherwise the backups appear to contain the file
+ // but has an old version
+ if (!changed && oldId >= 0 && !tooLargeFile)
AddUnmodifiedFile(oldId, lastwrite);
m_result.SizeOfExaminedFiles += filestatsize;
@@ -1131,6 +1146,76 @@ namespace Duplicati.Library.Main.Operation
return true;
}
+ private long ProcessStream(System.IO.Stream stream, Library.Interface.CompressionHint hint, BackendManager backend, Library.Utility.FileBackedStringList blocklisthashes, Library.Utility.FileBackedStringList hashcollector, bool skipfilehash)
+ {
+ int blocklistoffset = 0;
+ long filesize = 0;
+
+ using(var fs = new Blockprocessor(stream, m_blockbuffer))
+ {
+ m_filehasher.Initialize();
+
+ var offset = 0;
+ var remaining = fs.Readblock();
+
+ do
+ {
+ var size = Math.Min(m_blocksize, remaining);
+
+ if (!skipfilehash)
+ m_filehasher.TransformBlock(m_blockbuffer, offset, size, m_blockbuffer, offset);
+
+ var blockkey = m_blockhasher.ComputeHash(m_blockbuffer, offset, size);
+ if (m_blocklistbuffer.Length - blocklistoffset < blockkey.Length)
+ {
+ var blkey = Convert.ToBase64String(m_blockhasher.ComputeHash(m_blocklistbuffer, 0, blocklistoffset));
+ blocklisthashes.Add(blkey);
+ AddBlockToOutput(backend, blkey, m_blocklistbuffer, 0, blocklistoffset, CompressionHint.Noncompressible, true);
+ blocklistoffset = 0;
+ }
+
+ Array.Copy(blockkey, 0, m_blocklistbuffer, blocklistoffset, blockkey.Length);
+ blocklistoffset += blockkey.Length;
+
+ var key = Convert.ToBase64String(blockkey);
+ AddBlockToOutput(backend, key, m_blockbuffer, offset, size, hint, false);
+ hashcollector.Add(key);
+ filesize += size;
+
+ if (!skipfilehash)
+ {
+ m_result.OperationProgressUpdater.UpdateFileProgress(filesize);
+ if (m_result.TaskControlRendevouz() == TaskControlState.Stop)
+ return -1;
+ }
+
+ remaining -= size;
+ offset += size;
+
+ if (remaining == 0)
+ {
+ offset = 0;
+ remaining = fs.Readblock();
+ }
+
+ } while (remaining > 0);
+
+ //If all fits in a single block, don't bother with blocklists
+ if (hashcollector.Count > 1)
+ {
+ var blkeyfinal = Convert.ToBase64String(m_blockhasher.ComputeHash(m_blocklistbuffer, 0, blocklistoffset));
+ blocklisthashes.Add(blkeyfinal);
+ AddBlockToOutput(backend, blkeyfinal, m_blocklistbuffer, 0, blocklistoffset, CompressionHint.Noncompressible, true);
+ }
+ }
+
+ if (!skipfilehash)
+ m_filehasher.TransformFinalBlock(m_blockbuffer, 0, 0);
+
+ return filesize;
+
+ }
+
/// <summary>
/// Adds the found file data to the output unless the block already exists
/// </summary>
@@ -1183,8 +1268,6 @@ namespace Duplicati.Library.Main.Operation
m_blockvolume.Dispose();
m_blockvolume = null;
- m_indexvolume.Dispose();
- m_indexvolume = null;
}
else
{
@@ -1223,6 +1306,33 @@ namespace Duplicati.Library.Main.Operation
m_database.AddUnmodifiedFile(oldId, lastModified, m_transaction);
}
+ private long AddMetadataToOutput(BackendManager backend, IMetahash meta)
+ {
+ long metadataid;
+
+ if (meta.Blob.Length > m_maxmetadatasize)
+ {
+ //TODO: To fix this, the "WriteFileset" method in BackupHandler needs to
+ // be updated such that it can select sets even when there are multiple
+ // blocklist hashes for the metadata.
+ // This could be done such that an extra query is made if the metadata
+ // spans multiple blocklist hashes, as it is not expected to be common
+
+ m_result.AddWarning(string.Format("Metadata size is {0}, but the largest accepted size is {1}, recording empty metadata", meta.Blob.Length, m_maxmetadatasize), null);
+ meta = EMPTY_METADATA;
+ }
+
+ using(var blocklisthashes = new Library.Utility.FileBackedStringList())
+ using(var hashcollector = new Library.Utility.FileBackedStringList())
+ {
+ using(var ms = new MemoryStream(meta.Blob))
+ ProcessStream(ms, CompressionHint.Compressible, backend, blocklisthashes, hashcollector, true);
+
+ m_database.AddMetadataset(meta.FileHash, meta.Blob.Length, m_blocksize, hashcollector, blocklisthashes, out metadataid, m_transaction);
+ }
+
+ return metadataid;
+ }
/// <summary>
/// Adds a file to the output,
@@ -1233,19 +1343,10 @@ namespace Duplicati.Library.Main.Operation
/// <param name="size">The size of the file</param>
/// <param name="fragmentoffset">The offset into a fragment block where the last few bytes are stored</param>
/// <param name="metadata">A lookup table with various metadata values describing the file</param>
- private bool AddFolderToOutput(BackendManager backend, string filename, DateTime lastModified, IMetahash meta)
+ private void AddFolderToOutput(BackendManager backend, string filename, DateTime lastModified, IMetahash metadata)
{
- long metadataid;
- bool r = false;
-
- if (meta.Size > m_blocksize)
- throw new InvalidDataException(string.Format("Too large metadata, cannot handle more than {0} bytes", m_blocksize));
-
- r |= AddBlockToOutput(backend, meta.Hash, meta.Blob, 0, (int)meta.Size, CompressionHint.Default, false);
- r |= m_database.AddMetadataset(meta.Hash, meta.Size, out metadataid, m_transaction);
-
+ var metadataid = AddMetadataToOutput(backend, metadata);
m_database.AddDirectoryEntry(filename, metadataid, lastModified, m_transaction);
- return r;
}
/// <summary>
@@ -1257,19 +1358,10 @@ namespace Duplicati.Library.Main.Operation
/// <param name="size">The size of the file</param>
/// <param name="fragmentoffset">The offset into a fragment block where the last few bytes are stored</param>
/// <param name="metadata">A lookup table with various metadata values describing the file</param>
- private bool AddSymlinkToOutput(BackendManager backend, string filename, DateTime lastModified, IMetahash meta)
+ private void AddSymlinkToOutput(BackendManager backend, string filename, DateTime lastModified, IMetahash metadata)
{
- long metadataid;
- bool r = false;
-
- if (meta.Size > m_blocksize)
- throw new InvalidDataException(string.Format("Too large metadata, cannot handle more than {0} bytes", m_blocksize));
-
- r |= AddBlockToOutput(backend, meta.Hash, meta.Blob, 0, (int)meta.Size, CompressionHint.Default, false);
- r |= m_database.AddMetadataset(meta.Hash, meta.Size, out metadataid, m_transaction);
-
+ var metadataid = AddMetadataToOutput(backend, metadata);
m_database.AddSymlinkEntry(filename, metadataid, lastModified, m_transaction);
- return r;
}
/// <summary>
@@ -1283,17 +1375,10 @@ namespace Duplicati.Library.Main.Operation
/// <param name="metadata">A lookup table with various metadata values describing the file</param>
private void AddFileToOutput(BackendManager backend, string filename, long size, DateTime lastmodified, IMetahash metadata, IEnumerable<string> hashlist, string filehash, IEnumerable<string> blocklisthashes)
{
- long metadataid;
long blocksetid;
-
- if (metadata.Size > m_blocksize)
- throw new InvalidDataException(string.Format("Too large metadata, cannot handle more than {0} bytes", m_blocksize));
-
- AddBlockToOutput(backend, metadata.Hash, metadata.Blob, 0, (int)metadata.Size, CompressionHint.Default, false);
- m_database.AddMetadataset(metadata.Hash, metadata.Size, out metadataid, m_transaction);
+ var metadataid = AddMetadataToOutput(backend, metadata);
m_database.AddBlockset(filehash, size, m_blocksize, hashlist, blocklisthashes, out blocksetid, m_transaction);
-
m_database.AddFile(filename, lastmodified, blocksetid, metadataid, m_transaction);
}
@@ -1328,7 +1413,8 @@ namespace Duplicati.Library.Main.Operation
finally { m_indexvolume = null; }
}
- m_result.EndTime = DateTime.UtcNow;
+ if (m_result.EndTime.Ticks == 0)
+ m_result.EndTime = DateTime.UtcNow;
}
}
}
diff --git a/Duplicati/Library/Main/Operation/CompactHandler.cs b/Duplicati/Library/Main/Operation/CompactHandler.cs
index b9f34b694..e8a99d244 100644
--- a/Duplicati/Library/Main/Operation/CompactHandler.cs
+++ b/Duplicati/Library/Main/Operation/CompactHandler.cs
@@ -42,7 +42,7 @@ namespace Duplicati.Library.Main.Operation
if (!System.IO.File.Exists(m_options.Dbpath))
throw new Exception(string.Format("Database file does not exist: {0}", m_options.Dbpath));
- using(var db = new LocalDeleteDatabase(m_options.Dbpath, true))
+ using(var db = new LocalDeleteDatabase(m_options.Dbpath, "Compact"))
{
var tr = db.BeginTransaction();
try
@@ -51,7 +51,7 @@ namespace Duplicati.Library.Main.Operation
Utility.UpdateOptionsFromDb(db, m_options);
Utility.VerifyParameters(db, m_options);
- var changed = DoCompact(db, false, ref tr);
+ var changed = DoCompact(db, false, ref tr, null);
if (changed && m_options.UploadVerificationFile)
FilelistProcessor.UploadVerificationFile(m_backendurl, m_options, m_result.BackendWriter, db, null);
@@ -62,8 +62,11 @@ namespace Duplicati.Library.Main.Operation
tr.Commit();
if (changed)
{
- db.WriteResults();
- db.Vacuum();
+ db.WriteResults();
+ if (m_options.AutoVacuum)
+ {
+ db.Vacuum();
+ }
}
}
else
@@ -80,15 +83,17 @@ namespace Duplicati.Library.Main.Operation
}
}
- internal bool DoCompact(LocalDeleteDatabase db, bool hasVerifiedBackend, ref System.Data.IDbTransaction transaction)
+ internal bool DoCompact(LocalDeleteDatabase db, bool hasVerifiedBackend, ref System.Data.IDbTransaction transaction, BackendManager sharedBackend)
{
var report = db.GetCompactReport(m_options.VolumeSize, m_options.Threshold, m_options.SmallFileSize, m_options.SmallFileMaxCount, transaction);
report.ReportCompactData(m_result);
if (report.ShouldReclaim || report.ShouldCompact)
- {
- using(var backend = new BackendManager(m_backendurl, m_options, m_result.BackendWriter, db))
+ {
+ // Workaround where we allow a running backendmanager to be used
+ using(var bk = sharedBackend == null ? new BackendManager(m_backendurl, m_options, m_result.BackendWriter, db) : null)
{
+ var backend = bk ?? sharedBackend;
if (!hasVerifiedBackend && !m_options.NoBackendverification)
FilelistProcessor.VerifyRemoteList(backend, m_options, db, m_result.BackendWriter);
@@ -165,14 +170,14 @@ namespace Duplicati.Library.Main.Operation
if (newvol.Filesize > m_options.VolumeSize)
{
- uploadedVolumes.Add(new KeyValuePair<string, long>(newvol.RemoteFilename, new System.IO.FileInfo(newvol.LocalFilename).Length));
+ uploadedVolumes.Add(new KeyValuePair<string, long>(newvol.RemoteFilename, newvol.Filesize));
if (newvolindex != null)
- uploadedVolumes.Add(new KeyValuePair<string, long>(newvolindex.RemoteFilename, new System.IO.FileInfo(newvolindex.LocalFilename).Length));
+ uploadedVolumes.Add(new KeyValuePair<string, long>(newvolindex.RemoteFilename, newvolindex.Filesize));
if (!m_options.Dryrun)
backend.Put(newvol, newvolindex);
else
- m_result.AddDryrunMessage(string.Format("Would upload generated blockset of size {0}", Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(newvol.LocalFilename).Length)));
+ m_result.AddDryrunMessage(string.Format("Would upload generated blockset of size {0}", Library.Utility.Utility.FormatSizeString(newvol.Filesize)));
newvol = new BlockVolumeWriter(m_options);
@@ -206,13 +211,13 @@ namespace Duplicati.Library.Main.Operation
if (blocksInVolume > 0)
{
- uploadedVolumes.Add(new KeyValuePair<string, long>(newvol.RemoteFilename, new System.IO.FileInfo(newvol.LocalFilename).Length));
+ uploadedVolumes.Add(new KeyValuePair<string, long>(newvol.RemoteFilename, newvol.Filesize));
if (newvolindex != null)
- uploadedVolumes.Add(new KeyValuePair<string, long>(newvolindex.RemoteFilename, new System.IO.FileInfo(newvolindex.LocalFilename).Length));
+ uploadedVolumes.Add(new KeyValuePair<string, long>(newvolindex.RemoteFilename, newvolindex.Filesize));
if (!m_options.Dryrun)
backend.Put(newvol, newvolindex);
else
- m_result.AddDryrunMessage(string.Format("Would upload generated blockset of size {0}", Library.Utility.Utility.FormatSizeString(new System.IO.FileInfo(newvol.LocalFilename).Length)));
+ m_result.AddDryrunMessage(string.Format("Would upload generated blockset of size {0}", Library.Utility.Utility.FormatSizeString(newvol.Filesize)));
}
else
{
@@ -245,23 +250,40 @@ namespace Duplicati.Library.Main.Operation
if (downloadedVolumes.Count == 0)
m_result.AddDryrunMessage(string.Format("Would delete {0} files, which would reduce storage by {1}", m_result.DeletedFileCount, Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize)));
else
- m_result.AddDryrunMessage(string.Format("Would download {0} file(s) with a total size of {1}, delete {2} file(s) with a total size of {3}, and compact to {4} file(s) with a size of {5}, which would reduce storage by {6} file(s) and {7}", m_result.DownloadedFileCount, Library.Utility.Utility.FormatSizeString(m_result.DownloadedFileSize), m_result.DeletedFileCount, Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize), m_result.UploadedFileCount, Library.Utility.Utility.FormatSizeString(m_result.UploadedFileSize), m_result.DeletedFileCount - m_result.UploadedFileCount, Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize - m_result.UploadedFileSize)));
+ m_result.AddDryrunMessage(string.Format("Would download {0} file(s) with a total size of {1}, delete {2} file(s) with a total size of {3}, and compact to {4} file(s) with a size of {5}, which would reduce storage by {6} file(s) and {7}",
+ m_result.DownloadedFileCount,
+ Library.Utility.Utility.FormatSizeString(m_result.DownloadedFileSize),
+ m_result.DeletedFileCount,
+ Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize), m_result.UploadedFileCount,
+ Library.Utility.Utility.FormatSizeString(m_result.UploadedFileSize),
+ m_result.DeletedFileCount - m_result.UploadedFileCount,
+ Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize - m_result.UploadedFileSize)));
}
else
{
if (m_result.DownloadedFileCount == 0)
m_result.AddMessage(string.Format("Deleted {0} files, which reduced storage by {1}", m_result.DeletedFileCount, Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize)));
else
- m_result.AddMessage(string.Format("Downloaded {0} file(s) with a total size of {1}, deleted {2} file(s) with a total size of {3}, and compacted to {4} file(s) with a size of {5}, which reduced storage by {6} file(s) and {7}", m_result.DownloadedFileCount, Library.Utility.Utility.FormatSizeString(downloadSize), m_result.DeletedFileCount, Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize), m_result.UploadedFileCount, Library.Utility.Utility.FormatSizeString(m_result.UploadedFileSize), m_result.DeletedFileCount - m_result.UploadedFileCount, Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize - m_result.UploadedFileSize)));
+ m_result.AddMessage(string.Format("Downloaded {0} file(s) with a total size of {1}, deleted {2} file(s) with a total size of {3}, and compacted to {4} file(s) with a size of {5}, which reduced storage by {6} file(s) and {7}",
+ m_result.DownloadedFileCount,
+ Library.Utility.Utility.FormatSizeString(downloadSize),
+ m_result.DeletedFileCount,
+ Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize),
+ m_result.UploadedFileCount,
+ Library.Utility.Utility.FormatSizeString(m_result.UploadedFileSize),
+ m_result.DeletedFileCount - m_result.UploadedFileCount,
+ Library.Utility.Utility.FormatSizeString(m_result.DeletedFileSize - m_result.UploadedFileSize)));
}
backend.WaitForComplete(db, transaction);
}
-
+
+ m_result.EndTime = DateTime.UtcNow;
return (m_result.DeletedFileCount + m_result.UploadedFileCount) > 0;
}
else
{
+ m_result.EndTime = DateTime.UtcNow;
return false;
}
}
diff --git a/Duplicati/Library/Main/Operation/CreateBugReportHandler.cs b/Duplicati/Library/Main/Operation/CreateBugReportHandler.cs
index 7246be56d..066d0d4d4 100644
--- a/Duplicati/Library/Main/Operation/CreateBugReportHandler.cs
+++ b/Duplicati/Library/Main/Operation/CreateBugReportHandler.cs
@@ -16,6 +16,7 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
+using Duplicati.Library.Interface;
using Duplicati.Library.Main.Database;
namespace Duplicati.Library.Main.Operation
@@ -37,15 +38,15 @@ namespace Duplicati.Library.Main.Operation
{
var ext = System.IO.Path.GetExtension(m_targetpath);
var module = m_options.CompressionModule;
-
- if (ext != module)
+
+ if (ext == "" || string.Compare(ext, 1, module, 0, module.Length, StringComparison.OrdinalIgnoreCase) != 0)
m_targetpath = m_targetpath + "." + module;
if (System.IO.File.Exists(m_targetpath))
- throw new Exception(string.Format("Output file already exists, not overwriting: {0}", m_targetpath));
+ throw new UserInformationException(string.Format("Output file already exists, not overwriting: {0}", m_targetpath));
if (!System.IO.File.Exists(m_options.Dbpath))
- throw new Exception(string.Format("Database file does not exist: {0}", m_options.Dbpath));
+ throw new UserInformationException(string.Format("Database file does not exist: {0}", m_options.Dbpath));
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.BugReport_Running);
m_result.OperationProgressUpdater.UpdateProgress(0);
@@ -59,6 +60,10 @@ namespace Duplicati.Library.Main.Operation
{
m_result.SetDatabase(db);
db.Fix();
+ if (m_options.AutoVacuum)
+ {
+ db.Vacuum();
+ }
}
using(var cm = DynamicLoader.CompressionLoader.GetModule(module, m_targetpath, m_options.RawOptions))
diff --git a/Duplicati/Library/Main/Operation/DeleteHandler.cs b/Duplicati/Library/Main/Operation/DeleteHandler.cs
index e77df5b1a..3e6bf8341 100644
--- a/Duplicati/Library/Main/Operation/DeleteHandler.cs
+++ b/Duplicati/Library/Main/Operation/DeleteHandler.cs
@@ -19,6 +19,7 @@ using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
+using Duplicati.Library.Interface;
namespace Duplicati.Library.Main.Operation
{
@@ -38,9 +39,9 @@ namespace Duplicati.Library.Main.Operation
public void Run()
{
if (!System.IO.File.Exists(m_options.Dbpath))
- throw new Exception(string.Format("Database file does not exist: {0}", m_options.Dbpath));
+ throw new UserInformationException(string.Format("Database file does not exist: {0}", m_options.Dbpath));
- using(var db = new Database.LocalDeleteDatabase(m_options.Dbpath, false))
+ using(var db = new Database.LocalDeleteDatabase(m_options.Dbpath, "Delete"))
{
var tr = db.BeginTransaction();
try
@@ -49,7 +50,7 @@ namespace Duplicati.Library.Main.Operation
Utility.UpdateOptionsFromDb(db, m_options);
Utility.VerifyParameters(db, m_options);
- DoRun(db, ref tr, false, false);
+ DoRun(db, ref tr, false, false, null);
if (!m_options.Dryrun)
{
@@ -72,16 +73,26 @@ namespace Duplicati.Library.Main.Operation
}
}
- public void DoRun(Database.LocalDeleteDatabase db, ref System.Data.IDbTransaction transaction, bool hasVerifiedBacked, bool forceCompact)
- {
- using(var backend = new BackendManager(m_backendurl, m_options, m_result.BackendWriter, db))
+ public void DoRun(Database.LocalDeleteDatabase db, ref System.Data.IDbTransaction transaction, bool hasVerifiedBacked, bool forceCompact, BackendManager sharedManager)
+ {
+ // Workaround where we allow a running backendmanager to be used
+ using(var bk = sharedManager == null ? new BackendManager(m_backendurl, m_options, m_result.BackendWriter, db) : null)
{
+ var backend = bk ?? sharedManager;
+
if (!hasVerifiedBacked && !m_options.NoBackendverification)
FilelistProcessor.VerifyRemoteList(backend, m_options, db, m_result.BackendWriter);
- var filesetNumbers = db.FilesetTimes.Zip(Enumerable.Range(0, db.FilesetTimes.Count()), (a, b) => new Tuple<long, DateTime>(b, a.Value));
- var toDelete = m_options.GetFilesetsToDelete(db.FilesetTimes.Select(x => x.Value).ToArray());
-
+ var filesetNumbers = db.FilesetTimes.Zip(Enumerable.Range(0, db.FilesetTimes.Count()), (a, b) => new Tuple<long, DateTime>(b, a.Value)).ToList();
+ var sets = db.FilesetTimes.Select(x => x.Value).ToArray();
+ var toDelete = GetFilesetsToDelete(sets);
+
+ if (!m_options.AllowFullRemoval && sets.Length == toDelete.Length)
+ {
+ m_result.AddMessage(string.Format("Preventing removal of last fileset, use --{0} to allow removal ...", "allow-full-removal"));
+ toDelete = toDelete.Skip(1).ToArray();
+ }
+
if (toDelete != null && toDelete.Length > 0)
m_result.AddMessage(string.Format("Deleting {0} remote fileset(s) ...", toDelete.Length));
@@ -108,8 +119,11 @@ namespace Duplicati.Library.Main.Operation
else
m_result.AddDryrunMessage(string.Format("Would delete remote fileset: {0}", f.Key));
}
-
- backend.WaitForComplete(db, transaction);
+
+ if (sharedManager == null)
+ backend.WaitForComplete(db, transaction);
+ else
+ backend.WaitForEmpty(db, transaction);
var count = lst.Length;
if (!m_options.Dryrun)
@@ -134,7 +148,7 @@ namespace Duplicati.Library.Main.Operation
if (!m_options.NoAutoCompact && (forceCompact || (toDelete != null && toDelete.Length > 0)))
{
m_result.CompactResults = new CompactResults(m_result);
- new CompactHandler(m_backendurl, m_options, (CompactResults)m_result.CompactResults).DoCompact(db, true, ref transaction);
+ new CompactHandler(m_backendurl, m_options, (CompactResults)m_result.CompactResults).DoCompact(db, true, ref transaction, sharedManager);
}
m_result.SetResults(
@@ -144,6 +158,133 @@ namespace Duplicati.Library.Main.Operation
m_options.Dryrun);
}
}
+
+ /// <summary>
+ /// Gets the filesets selected for deletion
+ /// </summary>
+ /// <returns>The filesets to delete</returns>
+ /// <param name="backups">The list of backups that can be deleted</param>
+ private DateTime[] GetFilesetsToDelete(DateTime[] backups)
+ {
+ if (backups.Length == 0)
+ return backups;
+
+ if (backups.Distinct().Count() != backups.Length)
+ throw new Exception(string.Format("List of backup timestamps contains duplicates: {0}", string.Join(", ", backups.Select(x => x.ToString()))));
+
+ List<DateTime> res = new List<DateTime>();
+
+ var versions = m_options.Version;
+ if (versions != null && versions.Length > 0)
+ foreach (var ix in versions.Distinct())
+ if (ix >= 0 && ix < backups.Length)
+ res.Add(backups[ix]);
+
+ var keepVersions = m_options.KeepVersions;
+ if (keepVersions > 0 && keepVersions < backups.Length)
+ res.AddRange(backups.Skip(keepVersions));
+
+ var keepTime = m_options.KeepTime;
+ if (keepTime.Ticks > 0)
+ res.AddRange(backups.SkipWhile(x => x >= keepTime));
+
+ res.AddRange(ApplyRetentionPolicy(backups));
+
+ var filtered = res.Distinct().OrderByDescending(x => x).AsEnumerable();
+
+ var removeCount = filtered.Count();
+ if (removeCount > backups.Length)
+ throw new Exception(string.Format("Too many entries {0} vs {1}, lists: {2} vs {3}", removeCount, backups.Length, string.Join(", ", filtered.Select(x => x.ToString())), string.Join(", ", backups.Select(x => x.ToString()))));
+
+ return filtered.ToArray();
+ }
+
+ /// <summary>
+ /// Deletes backups according to the retention policy configuration.
+ /// Backups that are not within any of the specified time frames will will NOT be deleted.
+ /// </summary>
+ /// <returns>The filesets to delete</returns>
+ /// <param name="backups">The list of backups that can be deleted</param>
+ private List<DateTime> ApplyRetentionPolicy(DateTime[] backups)
+ {
+ // Any work to do?
+ Dictionary<TimeSpan, TimeSpan> retentionPolicyOptionValue = m_options.RetentionPolicy;
+ if (retentionPolicyOptionValue.Count == 0 || backups.Length == 0)
+ {
+ return new List<DateTime>(); // don't delete any backups
+ }
+
+ Logging.Log.WriteMessage("[Retention Policy]: Start checking if backups can be removed", Logging.LogMessageType.Information);
+
+ // Work with a copy to not modify the enumeration that the caller passed
+ List<DateTime> clonedBackupList = new List<DateTime>(backups);
+
+ // Make sure the backups are in descending order (newest backup in the beginning)
+ clonedBackupList = clonedBackupList.OrderByDescending(x => x).ToList();
+
+ // Most current backup should never get deleted in this process, so exclude it
+ clonedBackupList.RemoveAt(0);
+
+ Logging.Log.WriteMessage(string.Format("[Retention Policy]: Time frames and intervals pairs: {0}",
+ string.Join(", ", retentionPolicyOptionValue.Select(x => x.Key + " / " + x.Value))), Logging.LogMessageType.Information);
+
+ Logging.Log.WriteMessage(string.Format("[Retention Policy]: Backups to consider: {0}",
+ string.Join(", ", clonedBackupList)), Logging.LogMessageType.Information);
+
+ // Collect all potential backups in each time frame and thin out according to the specified interval,
+ // starting with the oldest backup in that time frame.
+ // The order in which the time frames values are checked has to be from the smallest to the largest.
+ // If backups are not within any time frame, they will NOT be deleted here.
+ // The --keep-time and --keep-versions switched should be used to ultimately delete backups that are too old
+ List<DateTime> backupsToDelete = new List<DateTime>();
+ var now = DateTime.Now;
+ foreach (var singleRetentionPolicyOptionValue in retentionPolicyOptionValue.OrderBy(x => x.Key))
+ {
+ var period = singleRetentionPolicyOptionValue.Key;
+ var interval = singleRetentionPolicyOptionValue.Value;
+
+ DateTime timeFrame = (period > TimeSpan.Zero) ? (now - period) : DateTime.MinValue; // period equal or below 0 means "biggest time frame possible"
+
+ Logging.Log.WriteMessage(string.Format("[Retention Policy]: Next time frame and interval pair: {0} / {1}", timeFrame, interval), Logging.LogMessageType.Profiling);
+
+ List<DateTime> backupsInTimeFrame = new List<DateTime>();
+ while (clonedBackupList.Count > 0 && clonedBackupList[0] >= timeFrame)
+ {
+ backupsInTimeFrame.Insert(0, clonedBackupList[0]); // Insert at begining to reverse order, which is nessecary for next step
+ clonedBackupList.RemoveAt(0); // remove from here to not handle the same backup in two time frames
+ }
+
+ Logging.Log.WriteMessage(string.Format("[Retention Policy]: Backups in this time frame: {0}",
+ string.Join(", ", backupsInTimeFrame)), Logging.LogMessageType.Profiling);
+
+ // Run through backups in this time frame
+ DateTime? lastKept = null;
+ foreach (DateTime backup in backupsInTimeFrame)
+ {
+ // Keep this backup if
+ // - no backup has yet been added to the time frame (keeps at least the oldest backup in a time frame)
+ // - difference between last added backup and this backup is bigger than the specified interval
+ if (lastKept == null || (backup - lastKept.Value) >= interval)
+ {
+ Logging.Log.WriteMessage(string.Format("[Retention Policy]: Keeping backup: {0}", backup), Logging.LogMessageType.Profiling);
+ lastKept = backup;
+ }
+ else
+ {
+ Logging.Log.WriteMessage(string.Format("[Retention Policy]: Marking backup for deletion: {0}", backup), Logging.LogMessageType.Profiling);
+ backupsToDelete.Add(backup);
+ }
+ }
+ }
+
+ Logging.Log.WriteMessage(string.Format("[Retention Policy]: Backups outside of all time frames and thus not checked: {0}",
+ string.Join(", ", clonedBackupList)), Logging.LogMessageType.Profiling);
+
+ Logging.Log.WriteMessage(string.Format("[Retention Policy]: Backups to delete: {0}",
+ string.Join(", ", backupsToDelete.OrderByDescending(x => x))), Logging.LogMessageType.Information);
+
+ return backupsToDelete;
+ }
}
}
diff --git a/Duplicati/Library/Main/Operation/FilelistProcessor.cs b/Duplicati/Library/Main/Operation/FilelistProcessor.cs
index 85d4e062f..042bd6e15 100644
--- a/Duplicati/Library/Main/Operation/FilelistProcessor.cs
+++ b/Duplicati/Library/Main/Operation/FilelistProcessor.cs
@@ -75,9 +75,10 @@ namespace Duplicati.Library.Main.Operation
/// <param name="options">The options used</param>
/// <param name="database">The database to compare with</param>
/// <param name="log">The log instance to use</param>
- public static void VerifyRemoteList(BackendManager backend, Options options, LocalDatabase database, IBackendWriter log)
+ /// <param name="protectedfile">A filename that should be excempted for deletion</param>
+ public static void VerifyRemoteList(BackendManager backend, Options options, LocalDatabase database, IBackendWriter log, string protectedfile = null)
{
- var tp = RemoteListAnalysis(backend, options, database, log);
+ var tp = RemoteListAnalysis(backend, options, database, log, protectedfile);
long extraCount = 0;
long missingCount = 0;
@@ -97,24 +98,17 @@ namespace Duplicati.Library.Main.Operation
{
var s = string.Format("Found {0} remote files that are not recorded in local storage, please run repair", extraCount);
log.AddError(s, null);
- throw new Exception(s);
+ throw new Duplicati.Library.Interface.UserInformationException(s);
}
- var lookup = new Dictionary<string, string>();
- var doubles = new Dictionary<string, string>();
- foreach(var v in tp.ParsedVolumes)
- {
- if (lookup.ContainsKey(v.File.Name))
- doubles[v.File.Name] = null;
- else
- lookup[v.File.Name] = null;
- }
+ ISet<string> doubles;
+ Library.Utility.Utility.GetUniqueItems(tp.ParsedVolumes.Select(x => x.File.Name), out doubles);
if (doubles.Count > 0)
{
- var s = string.Format("Found remote files reported as duplicates, either the backend module is broken or you need to manually remove the extra copies.\nThe following files were found multiple times: {0}", string.Join(", ", doubles.Keys));
+ var s = string.Format("Found remote files reported as duplicates, either the backend module is broken or you need to manually remove the extra copies.\nThe following files were found multiple times: {0}", string.Join(", ", doubles));
log.AddError(s, null);
- throw new Exception(s);
+ throw new Duplicati.Library.Interface.UserInformationException(s);
}
if (missingCount > 0)
@@ -126,7 +120,7 @@ namespace Duplicati.Library.Main.Operation
s = string.Format("Found {0} files that are missing from the remote storage, please run repair", missingCount);
log.AddError(s, null);
- throw new Exception(s);
+ throw new Duplicati.Library.Interface.UserInformationException(s);
}
}
@@ -189,10 +183,12 @@ namespace Duplicati.Library.Main.Operation
/// <param name="backend">The backend instance to use</param>
/// <param name="options">The options used</param>
/// <param name="database">The database to compare with</param>
- public static RemoteAnalysisResult RemoteListAnalysis(BackendManager backend, Options options, LocalDatabase database, IBackendWriter log)
+ /// <param name="protectedfile">A filename that should be excempted for deletion</param>
+ public static RemoteAnalysisResult RemoteListAnalysis(BackendManager backend, Options options, LocalDatabase database, IBackendWriter log, string protectedfile)
{
var rawlist = backend.List();
var lookup = new Dictionary<string, Volumes.IParsedVolume>();
+ protectedfile = protectedfile ?? string.Empty;
var remotelist = (from n in rawlist
let p = Volumes.VolumeBase.ParseFilename(n)
@@ -213,20 +209,24 @@ namespace Duplicati.Library.Main.Operation
where n.FileType == RemoteVolumeType.Files orderby n.Time descending
select n).ToList();
- log.KnownFileCount = remotelist.Count();
+ log.KnownFileCount = remotelist.Count;
log.KnownFileSize = remotelist.Select(x => Math.Max(0, x.File.Size)).Sum();
- log.UnknownFileCount = unknownlist.Count();
+ log.UnknownFileCount = unknownlist.Count;
log.UnknownFileSize = unknownlist.Select(x => Math.Max(0, x.Size)).Sum();
log.BackupListCount = filesets.Count;
log.LastBackupDate = filesets.Count == 0 ? new DateTime(0) : filesets[0].Time.ToLocalTime();
- // TODO: We should query through the backendmanager
- using (var bk = DynamicLoader.BackendLoader.GetBackend(backend.BackendUrl, options.RawOptions))
- if (bk is Library.Interface.IQuotaEnabledBackend)
- {
- log.TotalQuotaSpace = ((Library.Interface.IQuotaEnabledBackend)bk).TotalQuotaSpace;
- log.FreeQuotaSpace = ((Library.Interface.IQuotaEnabledBackend)bk).FreeQuotaSpace;
- }
+ // TODO: We should query through the backendmanager
+ using (var bk = DynamicLoader.BackendLoader.GetBackend(backend.BackendUrl, options.RawOptions))
+ if (bk is Library.Interface.IQuotaEnabledBackend)
+ {
+ Library.Interface.IQuotaInfo quota = ((Library.Interface.IQuotaEnabledBackend)bk).Quota;
+ if (quota != null)
+ {
+ log.TotalQuotaSpace = quota.TotalQuotaSpace;
+ log.FreeQuotaSpace = quota.FreeQuotaSpace;
+ }
+ }
log.AssignedQuotaSpace = options.QuotaSize;
@@ -277,8 +277,15 @@ namespace Duplicati.Library.Main.Operation
}
else
{
- log.AddMessage(string.Format("removing file listed as {0}: {1}", i.State, i.Name));
- cleanupRemovedRemoteVolumes.Add(i.Name);
+ if (string.Equals(i.Name, protectedfile) && i.State == RemoteVolumeState.Temporary)
+ {
+ log.AddMessage(string.Format("keeping protected incomplete remote file listed as {0}: {1}", i.State, i.Name));
+ }
+ else
+ {
+ log.AddMessage(string.Format("removing file listed as {0}: {1}", i.State, i.Name));
+ cleanupRemovedRemoteVolumes.Add(i.Name);
+ }
}
}
break;
@@ -290,14 +297,30 @@ namespace Duplicati.Library.Main.Operation
}
else if (!remoteFound)
{
- log.AddMessage(string.Format("scheduling missing file for deletion, currently listed as {0}: {1}", i.State, i.Name));
- cleanupRemovedRemoteVolumes.Add(i.Name);
- database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Deleting, i.Size, i.Hash, false, TimeSpan.FromHours(2), null);
+
+ if (string.Equals(i.Name, protectedfile))
+ {
+ log.AddMessage(string.Format("keeping protected incomplete remote file listed as {0}: {1}", i.State, i.Name));
+ database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Temporary, i.Size, i.Hash, false, new TimeSpan(0), null);
+ }
+ else
+ {
+ log.AddMessage(string.Format("scheduling missing file for deletion, currently listed as {0}: {1}", i.State, i.Name));
+ cleanupRemovedRemoteVolumes.Add(i.Name);
+ database.UpdateRemoteVolume(i.Name, RemoteVolumeState.Deleting, i.Size, i.Hash, false, TimeSpan.FromHours(2), null);
+ }
}
else
{
- log.AddMessage(string.Format("removing incomplete remote file listed as {0}: {1}", i.State, i.Name));
- backend.Delete(i.Name, i.Size, true);
+ if (string.Equals(i.Name, protectedfile))
+ {
+ log.AddMessage(string.Format("keeping protected incomplete remote file listed as {0}: {1}", i.State, i.Name));
+ }
+ else
+ {
+ log.AddMessage(string.Format("removing incomplete remote file listed as {0}: {1}", i.State, i.Name));
+ backend.Delete(i.Name, i.Size, true);
+ }
}
break;
diff --git a/Duplicati/Library/Main/Operation/ListAffected.cs b/Duplicati/Library/Main/Operation/ListAffected.cs
index b2ae3ab6e..b5a491269 100644
--- a/Duplicati/Library/Main/Operation/ListAffected.cs
+++ b/Duplicati/Library/Main/Operation/ListAffected.cs
@@ -32,17 +32,31 @@ namespace Duplicati.Library.Main.Operation
m_result = result;
}
- public void Run(List<string> args)
+ public void Run(List<string> args, Action<Duplicati.Library.Interface.IListAffectedResults> callback = null)
{
using(var db = new Database.LocalListAffectedDatabase(m_options.Dbpath))
{
m_result.SetDatabase(db);
- m_result.SetResult(
- db.GetFilesets(args).OrderByDescending(x => x.Time).ToArray(),
- db.GetFiles(args).ToArray(),
- db.GetLogLines(args).ToArray(),
- db.GetVolumes(args).ToArray()
- );
+ if (callback == null)
+ {
+ m_result.SetResult(
+ db.GetFilesets(args).OrderByDescending(x => x.Time).ToArray(),
+ db.GetFiles(args).ToArray(),
+ db.GetLogLines(args).ToArray(),
+ db.GetVolumes(args).ToArray()
+ );
+ }
+ else
+ {
+ m_result.SetResult(
+ db.GetFilesets(args).OrderByDescending(x => x.Time),
+ db.GetFiles(args),
+ db.GetLogLines(args),
+ db.GetVolumes(args)
+ );
+
+ callback(m_result);
+ }
}
}
}
diff --git a/Duplicati/Library/Main/Operation/ListBrokenFilesHandler.cs b/Duplicati/Library/Main/Operation/ListBrokenFilesHandler.cs
new file mode 100644
index 000000000..1083f6165
--- /dev/null
+++ b/Duplicati/Library/Main/Operation/ListBrokenFilesHandler.cs
@@ -0,0 +1,209 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Duplicati.Library.Interface;
+
+namespace Duplicati.Library.Main.Operation
+{
+ internal class ListBrokenFilesHandler
+ {
+ protected string m_backendurl;
+ protected Options m_options;
+ protected ListBrokenFilesResults m_result;
+
+ public ListBrokenFilesHandler(string backend, Options options, ListBrokenFilesResults result)
+ {
+ m_backendurl = backend;
+ m_options = options;
+ m_result = result;
+ }
+
+ public void Run(Library.Utility.IFilter filter, Func<long, DateTime, long, string, long, bool> callbackhandler = null)
+ {
+ if (!System.IO.File.Exists(m_options.Dbpath))
+ throw new UserInformationException(string.Format("Database file does not exist: {0}", m_options.Dbpath));
+
+ using (var db = new Database.LocalListBrokenFilesDatabase(m_options.Dbpath))
+ using (var tr = db.BeginTransaction())
+ DoRun(db, tr, filter, callbackhandler);
+ }
+
+ public static Tuple<DateTime, long, long>[] GetBrokenFilesetsFromRemote(string backendurl, BasicResults result, Database.LocalListBrokenFilesDatabase db, System.Data.IDbTransaction transaction, Options options, out List<Database.RemoteVolumeEntry> missing)
+ {
+ missing = null;
+ var brokensets = db.GetBrokenFilesets(options.Time, options.Version, transaction).ToArray();
+
+ if (brokensets.Length == 0)
+ {
+ if (db.RepairInProgress)
+ throw new UserInformationException("Cannot continue because the database is marked as being under repair, but does not have broken files.");
+
+ result.AddMessage("No broken filesets found in database, checking for missing remote files");
+
+ using (var backend = new BackendManager(backendurl, options, result.BackendWriter, db))
+ {
+ var remotestate = FilelistProcessor.RemoteListAnalysis(backend, options, db, result.BackendWriter, null);
+ if (!remotestate.ParsedVolumes.Any())
+ throw new UserInformationException("No remote volumes were found, refusing purge");
+
+ missing = remotestate.MissingVolumes.ToList();
+ if (missing.Count == 0)
+ {
+ result.AddMessage("Skipping operation because no files were found to be missing, and no filesets were recorded as broken.");
+ return null;
+ }
+
+ // Mark all volumes as disposable
+ foreach (var f in missing)
+ db.UpdateRemoteVolume(f.Name, RemoteVolumeState.Deleting, f.Size, f.Hash, transaction);
+
+ result.AddMessage(string.Format("Marked {0} remote files for deletion", missing.Count));
+
+ // Drop all content from tables
+ db.RemoveMissingBlocks(missing.Select(x => x.Name), transaction);
+ }
+ brokensets = db.GetBrokenFilesets(options.Time, options.Version, transaction).ToArray();
+ }
+
+ return brokensets;
+ }
+
+ private void DoRun(Database.LocalListBrokenFilesDatabase db, System.Data.IDbTransaction transaction, Library.Utility.IFilter filter, Func<long, DateTime, long, string, long, bool> callbackhandler)
+ {
+ if (filter != null && !filter.Empty)
+ throw new UserInformationException("Filters are not supported for this operation");
+
+ if (db.PartiallyRecreated)
+ throw new UserInformationException("The command does not work on partially recreated databases");
+
+ List<Database.RemoteVolumeEntry> missing;
+ var brokensets = GetBrokenFilesetsFromRemote(m_backendurl, m_result, db, transaction, m_options, out missing);
+ if (brokensets == null)
+ return;
+
+ if (brokensets.Length == 0)
+ {
+ m_result.BrokenFiles = new Tuple<long, DateTime, IEnumerable<Tuple<string, long>>>[0];
+ m_result.AddMessage("No broken filesets found");
+ return;
+ }
+
+ var fstimes = db.FilesetTimes.ToList();
+
+ var brokenfilesets =
+ brokensets.Select(x => new
+ {
+ Version = fstimes.FindIndex(y => y.Key == x.Item2),
+ Timestamp = x.Item1,
+ FilesetID = x.Item2,
+ BrokenCount = x.Item3
+ }
+ )
+ .ToArray();
+
+
+ m_result.BrokenFiles =
+ brokenfilesets.Select(
+ x => new Tuple<long, DateTime, IEnumerable<Tuple<string, long>>>(
+ x.Version,
+ x.Timestamp,
+ callbackhandler == null && !m_options.ListSetsOnly
+ ? db.GetBrokenFilenames(x.FilesetID, transaction).ToArray().AsEnumerable()
+ : new MockList<Tuple<string, long>>((int)x.BrokenCount)
+ ))
+ .ToArray();
+
+
+ if (callbackhandler != null)
+ foreach (var bs in brokenfilesets)
+ foreach (var fe in db.GetBrokenFilenames(bs.FilesetID, transaction))
+ if (!callbackhandler(bs.Version, bs.Timestamp, bs.BrokenCount, fe.Item1, fe.Item2))
+ break;
+ }
+
+ private class MockList<T> : IList<T>
+ {
+ public MockList(int count)
+ {
+ Count = count;
+ }
+
+ public T this[int index]
+ {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
+
+ public int Count { get; private set; }
+
+ public bool IsReadOnly { get { return true; }}
+
+ public void Add(T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Clear()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Contains(T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerator<T> GetEnumerator()
+ {
+ throw new NotImplementedException();
+ }
+
+ public int IndexOf(T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Insert(int index, T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Remove(T item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveAt(int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/Duplicati/Library/Main/Operation/ListChangesHandler.cs b/Duplicati/Library/Main/Operation/ListChangesHandler.cs
index 4e43a3b98..13bbb3f9c 100644
--- a/Duplicati/Library/Main/Operation/ListChangesHandler.cs
+++ b/Duplicati/Library/Main/Operation/ListChangesHandler.cs
@@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Duplicati.Library.Interface;
namespace Duplicati.Library.Main.Operation
{
@@ -54,7 +55,7 @@ namespace Duplicati.Library.Main.Operation
return res;
}
- public void Run(string baseVersion, string compareVersion, IEnumerable<string> filterstrings = null, Library.Utility.IFilter compositefilter = null)
+ public void Run(string baseVersion, string compareVersion, IEnumerable<string> filterstrings = null, Library.Utility.IFilter compositefilter = null, Action<IListChangesResults, IEnumerable<Tuple<Library.Interface.ListChangesChangeType, Library.Interface.ListChangesElementType, string>>> callback = null)
{
var filter = Library.Utility.JoinedFilterExpression.Join(new Library.Utility.FilterExpression(filterstrings), compositefilter);
@@ -79,7 +80,7 @@ namespace Duplicati.Library.Main.Operation
{
var dbtimes = db.FilesetTimes.ToList();
if (dbtimes.Count < 2)
- throw new Exception(string.Format("Need at least two backups to show differences, database contains {0} backups", dbtimes.Count));
+ throw new UserInformationException(string.Format("Need at least two backups to show differences, database contains {0} backups", dbtimes.Count));
long baseVersionId;
long compareVersionId;
@@ -104,7 +105,7 @@ namespace Duplicati.Library.Main.Operation
var numberedList = parsedlist.Zip(Enumerable.Range(0, parsedlist.Length), (a, b) => new Tuple<long, DateTime, Volumes.IParsedVolume>(b, a.Time, a)).ToList();
if (numberedList.Count < 2)
- throw new Exception(string.Format("Need at least two backups to show differences, database contains {0} backups", numberedList.Count));
+ throw new UserInformationException(string.Format("Need at least two backups to show differences, database contains {0} backups", numberedList.Count));
Volumes.IParsedVolume baseFile;
Volumes.IParsedVolume compareFile;
@@ -148,19 +149,23 @@ namespace Duplicati.Library.Main.Operation
var changes = storageKeeper.CreateChangeCountReport();
var sizes = storageKeeper.CreateChangeSizeReport();
-
+
+ var lst = (m_options.Verbose || m_options.FullResult || callback != null) ?
+ (from n in storageKeeper.CreateChangedFileReport()
+ select n) : null;
+
m_result.SetResult(
baseVersionTime, baseVersionIndex, compareVersionTime, compareVersionIndex,
changes.AddedFolders, changes.AddedSymlinks, changes.AddedFiles,
changes.DeletedFolders, changes.DeletedSymlinks, changes.DeletedFiles,
changes.ModifiedFolders, changes.ModifiedSymlinks, changes.ModifiedFiles,
sizes.AddedSize, sizes.DeletedSize, sizes.PreviousSize, sizes.CurrentSize,
-
- m_options.Verbose ?
- (from n in storageKeeper.CreateChangedFileReport()
- select n).ToArray() : null
+ (lst == null || callback == null) ? null : lst.ToArray()
);
+ if (callback != null)
+ callback(m_result, lst);
+
return;
}
}
diff --git a/Duplicati/Library/Main/Operation/ListFilesHandler.cs b/Duplicati/Library/Main/Operation/ListFilesHandler.cs
index fdb279ce3..78524ccaf 100644
--- a/Duplicati/Library/Main/Operation/ListFilesHandler.cs
+++ b/Duplicati/Library/Main/Operation/ListFilesHandler.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Duplicati.Library.Interface;
namespace Duplicati.Library.Main.Operation
{
@@ -21,8 +22,8 @@ namespace Duplicati.Library.Main.Operation
public void Run(IEnumerable<string> filterstrings = null, Library.Utility.IFilter compositefilter = null)
{
var parsedfilter = new Library.Utility.FilterExpression(filterstrings);
- var simpleList = !(parsedfilter.Type == Library.Utility.FilterType.Simple || m_options.AllVersions);
var filter = Library.Utility.JoinedFilterExpression.Join(parsedfilter, compositefilter);
+ var simpleList = !((filter is Library.Utility.FilterExpression && ((Library.Utility.FilterExpression)filter).Type == Library.Utility.FilterType.Simple) || m_options.AllVersions);
//Use a speedy local query
if (!m_options.NoLocalDb && System.IO.File.Exists(m_options.Dbpath))
@@ -31,7 +32,7 @@ namespace Duplicati.Library.Main.Operation
m_result.SetDatabase(db);
using(var filesets = db.SelectFileSets(m_options.Time, m_options.Version))
{
- if (parsedfilter.Type != Library.Utility.FilterType.Empty)
+ if (!filter.Empty)
{
if (simpleList || (m_options.ListFolderContents && !m_options.AllVersions))
filesets.TakeFirst();
@@ -42,7 +43,7 @@ namespace Duplicati.Library.Main.Operation
files = filesets.SelectFolderContents(filter);
else if (m_options.ListPrefixOnly)
files = filesets.GetLargestPrefix(filter);
- else if (parsedfilter.Type == Duplicati.Library.Utility.FilterType.Empty)
+ else if (filter.Empty)
files = null;
else
files = filesets.SelectFiles(filter);
@@ -70,9 +71,9 @@ namespace Duplicati.Library.Main.Operation
//TODO: Add prefix and foldercontents
if (m_options.ListFolderContents)
- throw new Exception("Listing folder contents is not supported without a local database, consider using the \"repair\" option to rebuild the database.");
+ throw new UserInformationException("Listing folder contents is not supported without a local database, consider using the \"repair\" option to rebuild the database.");
else if (m_options.ListPrefixOnly)
- throw new Exception("Listing prefixes is not supported without a local database, consider using the \"repair\" option to rebuild the database.");
+ throw new UserInformationException("Listing prefixes is not supported without a local database, consider using the \"repair\" option to rebuild the database.");
// Otherwise, grab info from remote location
using (var tmpdb = new Library.Utility.TempFile())
@@ -83,10 +84,10 @@ namespace Duplicati.Library.Main.Operation
var filteredList = ParseAndFilterFilesets(backend.List(), m_options);
if (filteredList.Count == 0)
- throw new Exception("No filesets found on remote target");
+ throw new UserInformationException("No filesets found on remote target");
var numberSeq = CreateResultSequence(filteredList);
- if (parsedfilter.Type == Library.Utility.FilterType.Empty)
+ if (filter.Empty)
{
m_result.SetResult(numberSeq, null);
m_result.EncryptedFiles = filteredList.Any(x => !string.IsNullOrWhiteSpace(x.Value.EncryptionModule));
diff --git a/Duplicati/Library/Main/Operation/PurgeBrokenFilesHandler.cs b/Duplicati/Library/Main/Operation/PurgeBrokenFilesHandler.cs
new file mode 100644
index 000000000..6c2755610
--- /dev/null
+++ b/Duplicati/Library/Main/Operation/PurgeBrokenFilesHandler.cs
@@ -0,0 +1,196 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Duplicati.Library.Interface;
+
+namespace Duplicati.Library.Main.Operation
+{
+ internal class PurgeBrokenFilesHandler
+ {
+ protected string m_backendurl;
+ protected Options m_options;
+ protected PurgeBrokenFilesResults m_result;
+
+ public PurgeBrokenFilesHandler(string backend, Options options, PurgeBrokenFilesResults result)
+ {
+ m_backendurl = backend;
+ m_options = options;
+ m_result = result;
+ }
+
+ public void Run(Library.Utility.IFilter filter)
+ {
+ if (!System.IO.File.Exists(m_options.Dbpath))
+ throw new UserInformationException(string.Format("Database file does not exist: {0}", m_options.Dbpath));
+
+ if (filter != null && !filter.Empty)
+ throw new UserInformationException("Filters are not supported for this operation");
+
+ List<Database.RemoteVolumeEntry> missing = null;
+
+ using (var db = new Database.LocalListBrokenFilesDatabase(m_options.Dbpath))
+ using (var tr = db.BeginTransaction())
+ {
+ if (db.PartiallyRecreated)
+ throw new UserInformationException("The command does not work on partially recreated databases");
+
+ var sets = ListBrokenFilesHandler.GetBrokenFilesetsFromRemote(m_backendurl, m_result, db, tr, m_options, out missing);
+ if (sets == null)
+ return;
+
+ if (sets.Length == 0)
+ {
+ if (missing == null)
+ m_result.AddMessage("Found no broken filesets");
+ else if (missing.Count == 0)
+ m_result.AddMessage("Found no broken filesets and no missing remote files");
+ else
+ throw new UserInformationException(string.Format("Found no broken filesets, but {0} missing remote files", sets.Length));
+ }
+
+ m_result.AddMessage(string.Format("Found {0} broken filesets with {1} affected files, purging files", sets.Length, sets.Sum(x => x.Item3)));
+
+ var pgoffset = 0.0f;
+ var pgspan = 0.95f / sets.Length;
+
+ var filesets = db.FilesetTimes.ToList();
+
+ var compare_list = sets.Select(x => new
+ {
+ FilesetID = x.Item2,
+ Timestamp = x.Item1,
+ RemoveCount = x.Item3,
+ Version = filesets.FindIndex(y => y.Key == x.Item2),
+ SetCount = db.GetFilesetFileCount(x.Item2, tr)
+ }).ToArray();
+
+ var fully_emptied = compare_list.Where(x => x.RemoveCount == x.SetCount).ToArray();
+ var to_purge = compare_list.Where(x => x.RemoveCount != x.SetCount).ToArray();
+
+ if (fully_emptied.Length != 0)
+ {
+ if (fully_emptied.Length == 1)
+ m_result.AddMessage(string.Format("Removing entire fileset {1} as all {0} file(s) are broken", fully_emptied.First().Timestamp, fully_emptied.First().RemoveCount));
+ else
+ m_result.AddMessage(string.Format("Removing {0} filesets where all file(s) are broken: {1}", fully_emptied.Length, string.Join(", ", fully_emptied.Select(x => x.Timestamp.ToLocalTime().ToString()))));
+
+ m_result.DeleteResults = new DeleteResults(m_result);
+ using (var rmdb = new Database.LocalDeleteDatabase(db))
+ {
+ var deltr = rmdb.BeginTransaction();
+ try
+ {
+ var opts = new Options(new Dictionary<string, string>(m_options.RawOptions));
+ opts.RawOptions["version"] = string.Join(",", fully_emptied.Select(x => x.Version.ToString()));
+ opts.RawOptions.Remove("time");
+ opts.RawOptions["no-auto-compact"] = "true";
+
+ new DeleteHandler(m_backendurl, opts, (DeleteResults)m_result.DeleteResults)
+ .DoRun(rmdb, ref deltr, true, false, null);
+
+ if (!m_options.Dryrun)
+ {
+ using (new Logging.Timer("CommitDelete"))
+ deltr.Commit();
+
+ rmdb.WriteResults();
+ }
+ else
+ deltr.Rollback();
+ }
+ finally
+ {
+ if (deltr != null)
+ try { deltr.Rollback(); }
+ catch { }
+ }
+
+ }
+
+ pgoffset += (pgspan * fully_emptied.Length);
+ m_result.OperationProgressUpdater.UpdateProgress(pgoffset);
+ }
+
+ if (to_purge.Length > 0)
+ {
+ m_result.PurgeResults = new PurgeFilesResults(m_result);
+
+ foreach (var bs in to_purge)
+ {
+ m_result.AddMessage(string.Format("Purging {0} file(s) from fileset {1}", bs.RemoveCount, bs.Timestamp.ToLocalTime()));
+ var opts = new Options(new Dictionary<string, string>(m_options.RawOptions));
+
+ using (var pgdb = new Database.LocalPurgeDatabase(db))
+ {
+ // Recompute the version number after we deleted the versions before
+ filesets = pgdb.FilesetTimes.ToList();
+ var thisversion = filesets.FindIndex(y => y.Key == bs.FilesetID);
+ if (thisversion < 0)
+ throw new Exception(string.Format("Failed to find match for {0} ({1}) in {2}", bs.FilesetID, bs.Timestamp.ToLocalTime(), string.Join(", ", filesets.Select(x => x.ToString()))));
+
+ opts.RawOptions["version"] = thisversion.ToString();
+ opts.RawOptions.Remove("time");
+ opts.RawOptions["no-auto-compact"] = "true";
+
+ new PurgeFilesHandler(m_backendurl, opts, (PurgeFilesResults)m_result.PurgeResults).Run(pgdb, pgoffset, pgspan, (cmd, filesetid, tablename) =>
+ {
+ if (filesetid != bs.FilesetID)
+ throw new Exception(string.Format("Unexpected filesetid: {0}, expected {1}", filesetid, bs.FilesetID));
+ db.InsertBrokenFileIDsIntoTable(filesetid, tablename, "FileID", cmd.Transaction);
+ });
+ }
+
+ pgoffset += pgspan;
+ m_result.OperationProgressUpdater.UpdateProgress(pgoffset);
+ }
+ }
+
+ if (m_options.Dryrun)
+ tr.Rollback();
+ else
+ tr.Commit();
+
+ m_result.OperationProgressUpdater.UpdateProgress(0.95f);
+
+ if (missing != null && missing.Count > 0)
+ {
+ using (var backend = new BackendManager(m_backendurl, m_options, m_result.BackendWriter, db))
+ {
+ foreach (var f in missing)
+ if (m_options.Dryrun)
+ m_result.AddDryrunMessage(string.Format("Would delete remote file: {0}, size: {1}", f.Name, Library.Utility.Utility.FormatSizeString(f.Size)));
+ else
+ backend.Delete(f.Name, f.Size);
+ }
+ }
+
+ if (!m_options.Dryrun && db.RepairInProgress)
+ {
+ m_result.AddMessage("Database was previously marked as in-progress, checking if it is valid after purging files");
+ db.VerifyConsistency(null, m_options.Blocksize, m_options.BlockhashSize, true);
+ m_result.AddMessage("Purge completed, and consistency checks completed, marking database as complete");
+ db.RepairInProgress = false;
+ }
+
+ m_result.OperationProgressUpdater.UpdateProgress(1.0f);
+
+ }
+ }
+ }
+}
diff --git a/Duplicati/Library/Main/Operation/PurgeFilesHandler.cs b/Duplicati/Library/Main/Operation/PurgeFilesHandler.cs
new file mode 100644
index 000000000..fc91ddb64
--- /dev/null
+++ b/Duplicati/Library/Main/Operation/PurgeFilesHandler.cs
@@ -0,0 +1,250 @@
+// Copyright (C) 2016, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Linq;
+using Duplicati.Library.Interface;
+
+namespace Duplicati.Library.Main.Operation
+{
+ internal class PurgeFilesHandler
+ {
+ protected string m_backendurl;
+ protected Options m_options;
+ protected PurgeFilesResults m_result;
+
+ public PurgeFilesHandler(string backend, Options options, PurgeFilesResults result)
+ {
+ m_backendurl = backend;
+ m_options = options;
+ m_result = result;
+ }
+
+ public void Run(Library.Utility.IFilter filter)
+ {
+ if (filter == null || filter.Empty)
+ throw new UserInformationException("Cannot purge with an empty filter, as that would cause all files to be removed.\nTo remove an entire backup set, use the \"delete\" command.");
+
+ if (!System.IO.File.Exists(m_options.Dbpath))
+ throw new UserInformationException(string.Format("Database file does not exist: {0}", m_options.Dbpath));
+
+ using (var db = new Database.LocalPurgeDatabase(m_options.Dbpath))
+ DoRun(db, filter, null, 0, 1);
+ }
+
+ public void Run(Database.LocalPurgeDatabase db, float pgoffset, float pgspan, Action<System.Data.IDbCommand, long, string> filtercommand)
+ {
+ DoRun(db, null, filtercommand, pgoffset, pgspan);
+ }
+
+ private void DoRun(Database.LocalPurgeDatabase db, Library.Utility.IFilter filter, Action<System.Data.IDbCommand, long, string> filtercommand, float pgoffset, float pgspan)
+ {
+ m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.PurgeFiles_Begin);
+ m_result.AddMessage("Starting purge operation");
+
+ var doCompactStep = !m_options.NoAutoCompact && filtercommand == null;
+
+ using (var backend = new BackendManager(m_backendurl, m_options, m_result.BackendWriter, db))
+ {
+ if (db.PartiallyRecreated)
+ throw new UserInformationException("The purge command does not work on partially recreated databases");
+
+ if (db.RepairInProgress && filtercommand == null)
+ throw new UserInformationException(string.Format("The purge command does not work on an incomplete database, try the {0} operation.", "purge-broken-files"));
+
+ var versions = db.GetFilesetIDs(m_options.Time, m_options.Version).ToArray();
+ if (versions.Length <= 0)
+ throw new UserInformationException("No filesets matched the supplied time or versions");
+
+ var orphans = db.CountOrphanFiles(null);
+ if (orphans != 0)
+ throw new UserInformationException(string.Format("Unable to start the purge process as there are {0} orphan file(s)", orphans));
+
+ Utility.UpdateOptionsFromDb(db, m_options);
+ Utility.VerifyParameters(db, m_options);
+
+ if (filtercommand == null)
+ {
+ db.VerifyConsistency(null, m_options.Blocksize, m_options.BlockhashSize, false);
+
+ if (m_options.NoBackendverification)
+ FilelistProcessor.VerifyLocalList(backend, m_options, db, m_result.BackendWriter);
+ else
+ FilelistProcessor.VerifyRemoteList(backend, m_options, db, m_result.BackendWriter, null);
+ }
+
+ var filesets = db.FilesetTimes.ToArray();
+
+ var versionprogress = ((doCompactStep ? 0.75f : 1.0f) / versions.Length) * pgspan;
+ var currentprogress = pgoffset;
+
+ m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.PurgeFiles_Process);
+ m_result.OperationProgressUpdater.UpdateProgress(currentprogress);
+
+ // Reverse makes sure we re-write the old versions first
+ foreach (var versionid in versions.Reverse())
+ {
+ using (var tr = db.BeginTransaction())
+ {
+ var ix = -1;
+ for (var i = 0; i < filesets.Length; i++)
+ if (filesets[i].Key == versionid)
+ {
+ ix = i;
+ break;
+ }
+
+ if (ix < 0)
+ throw new InvalidProgramException(string.Format("Fileset was reported with id {0}, but could not be found?", versionid));
+
+ var secs = 0;
+ while (secs < 60)
+ {
+ secs++;
+ var tfn = Volumes.VolumeBase.GenerateFilename(RemoteVolumeType.Files, m_options, null, filesets[ix].Value.AddSeconds(secs));
+ if (db.GetRemoteVolumeID(tfn, tr) < 0)
+ break;
+ }
+
+ var ts = filesets[ix].Value.AddSeconds(secs);
+ var prevfilename = db.GetRemoteVolumeNameForFileset(filesets[ix].Key, tr);
+
+ if (secs >= 60)
+ throw new Exception(string.Format("Unable to create a new fileset for {0} because the resulting timestamp {1} is more than 60 seconds away", prevfilename, ts));
+
+ if (ix != 0 && filesets[ix - 1].Value <= ts)
+ throw new Exception(string.Format("Unable to create a new fileset for {0} because the resulting timestamp {1} is larger than the next timestamp {2}", prevfilename, ts, filesets[ix - 1].Value));
+
+ using (var tempset = db.CreateTemporaryFileset(versionid, tr))
+ {
+ if (filtercommand == null)
+ tempset.ApplyFilter(filter);
+ else
+ tempset.ApplyFilter(filtercommand);
+
+ if (tempset.RemovedFileCount == 0)
+ {
+ m_result.AddMessage(string.Format("Not writing a new fileset for {0} as it was not changed", prevfilename));
+ currentprogress += versionprogress;
+ tr.Rollback();
+ continue;
+ }
+ else
+ {
+ using (var tf = new Library.Utility.TempFile())
+ using (var vol = new Volumes.FilesetVolumeWriter(m_options, ts))
+ {
+ var newids = tempset.ConvertToPermanentFileset(vol.RemoteFilename, ts);
+ vol.VolumeID = newids.Item1;
+
+ m_result.AddMessage(string.Format("Replacing fileset {0} with {1} which has with {2} fewer file(s) ({3} reduction)", prevfilename, vol.RemoteFilename, tempset.RemovedFileCount, Library.Utility.Utility.FormatSizeString(tempset.RemovedFileSize)));
+
+ db.WriteFileset(vol, tr, newids.Item2);
+
+ m_result.RemovedFileSize += tempset.RemovedFileSize;
+ m_result.RemovedFileCount += tempset.RemovedFileCount;
+ m_result.RewrittenFileLists++;
+
+ currentprogress += (versionprogress / 2);
+ m_result.OperationProgressUpdater.UpdateProgress(currentprogress);
+
+ if (m_options.Dryrun || m_options.Verbose || Logging.Log.LogLevel == Logging.LogMessageType.Profiling)
+ {
+ foreach (var fe in tempset.ListAllDeletedFiles())
+ {
+ var msg = string.Format(" Purging file {0} ({1})", fe.Key, Library.Utility.Utility.FormatSizeString(fe.Value));
+
+ if (Logging.Log.LogLevel == Logging.LogMessageType.Profiling)
+ Logging.Log.WriteMessage(msg, Logging.LogMessageType.Profiling);
+
+ if (m_options.Dryrun)
+ m_result.AddDryrunMessage(msg);
+ else if (m_options.Verbose)
+ m_result.AddVerboseMessage(msg);
+ }
+
+ if (m_options.Dryrun)
+ m_result.AddDryrunMessage("Writing files to remote storage");
+ else if (m_options.Verbose)
+ m_result.AddVerboseMessage("Writing files to remote storage");
+ }
+
+ if (m_options.Dryrun)
+ {
+ m_result.AddDryrunMessage(string.Format("Would upload file {0} ({1}) and delete file {2}, removing {3} files", vol.RemoteFilename, Library.Utility.Utility.FormatSizeString(vol.Filesize), prevfilename, tempset.RemovedFileCount));
+ tr.Rollback();
+ }
+ else
+ {
+ var lst = db.DropFilesetsFromTable(new[] { filesets[ix].Value }, tr).ToArray();
+ foreach (var f in lst)
+ db.UpdateRemoteVolume(f.Key, RemoteVolumeState.Deleting, f.Value, null, tr);
+
+ tr.Commit();
+ backend.Put(vol, synchronous: true);
+ backend.Delete(prevfilename, -1, true);
+ backend.FlushDbMessages();
+ }
+ }
+ }
+ }
+ }
+
+ currentprogress += (versionprogress / 2);
+ m_result.OperationProgressUpdater.UpdateProgress(currentprogress);
+ }
+
+
+ if (doCompactStep)
+ {
+ if (m_result.RewrittenFileLists == 0)
+ {
+ m_result.AddMessage("Skipping compacting as no new volumes were written");
+ }
+ else
+ {
+ m_result.OperationProgressUpdater.UpdateProgress(pgoffset + (0.75f * pgspan));
+ m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.PurgeFiles_Compact);
+ m_result.CompactResults = new CompactResults(m_result);
+ using (var cdb = new Database.LocalDeleteDatabase(db))
+ {
+ var tr = cdb.BeginTransaction();
+ try
+ {
+ new CompactHandler(backend.BackendUrl, m_options, (CompactResults)m_result.CompactResults).DoCompact(cdb, true, ref tr, backend);
+ }
+ catch
+ {
+ try { tr.Rollback(); }
+ catch { }
+ }
+ finally
+ {
+ try { tr.Commit(); }
+ catch { }
+ }
+ }
+ }
+
+ m_result.OperationProgressUpdater.UpdateProgress(pgoffset + pgspan);
+ m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.PurgeFiles_Complete);
+ }
+
+ backend.WaitForComplete(db, null);
+ }
+ }
+ }
+}
diff --git a/Duplicati/Library/Main/Operation/RecreateDatabaseHandler.cs b/Duplicati/Library/Main/Operation/RecreateDatabaseHandler.cs
index e95429545..cffa779ef 100644
--- a/Duplicati/Library/Main/Operation/RecreateDatabaseHandler.cs
+++ b/Duplicati/Library/Main/Operation/RecreateDatabaseHandler.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Duplicati.Library.Interface;
using Duplicati.Library.Main.Database;
using Duplicati.Library.Main.Volumes;
@@ -32,7 +33,7 @@ namespace Duplicati.Library.Main.Operation
public void Run(string path, Library.Utility.IFilter filter = null, NumberedFilterFilelistDelegate filelistfilter = null, BlockVolumePostProcessor blockprocessor = null)
{
if (System.IO.File.Exists(path))
- throw new Exception(string.Format("Cannot recreate database because file already exists: {0}", path));
+ throw new UserInformationException(string.Format("Cannot recreate database because file already exists: {0}", path));
using(var db = new LocalDatabase(path, "Recreate", true))
{
@@ -51,14 +52,14 @@ namespace Duplicati.Library.Main.Operation
public void RunUpdate(Library.Utility.IFilter filter = null, NumberedFilterFilelistDelegate filelistfilter = null, BlockVolumePostProcessor blockprocessor = null)
{
if (!m_options.RepairOnlyPaths)
- throw new Exception(string.Format("Can only update with paths, try setting {0}", "--repair-only-paths"));
+ throw new UserInformationException(string.Format("Can only update with paths, try setting {0}", "--repair-only-paths"));
using(var db = new LocalDatabase(m_options.Dbpath, "Recreate", true))
{
m_result.SetDatabase(db);
if (db.FindMatchingFilesets(m_options.Time, m_options.Version).Any())
- throw new Exception(string.Format("The version(s) being updated to, already exists"));
+ throw new UserInformationException(string.Format("The version(s) being updated to, already exists"));
// Mark as incomplete
db.PartiallyRecreated = true;
@@ -105,7 +106,7 @@ namespace Duplicati.Library.Main.Operation
if (remotefiles.Length == 0)
{
if (rawlist.Count == 0)
- throw new Exception("No files were found at the remote location, perhaps the target url is incorrect?");
+ throw new UserInformationException("No files were found at the remote location, perhaps the target url is incorrect?");
else
{
var tmp =
@@ -117,11 +118,11 @@ namespace Duplicati.Library.Main.Operation
var types = tmp.Distinct().ToArray();
if (tmp.Length == 0)
- throw new Exception(string.Format("Found {0} files at the remote storage, but none that could be parsed", rawlist.Count));
+ throw new UserInformationException(string.Format("Found {0} files at the remote storage, but none that could be parsed", rawlist.Count));
else if (types.Length == 1)
- throw new Exception(string.Format("Found {0} parse-able files with the prefix {1}, did you forget to set the backup-prefix?", tmp.Length, types[0]));
+ throw new UserInformationException(string.Format("Found {0} parse-able files with the prefix {1}, did you forget to set the backup prefix?", tmp.Length, types[0]));
else
- throw new Exception(string.Format("Found {0} parse-able files (of {1} files) with different prefixes: {2}, did you forget to set the backup-prefix?", tmp.Length, rawlist.Count, string.Join(", ", types)));
+ throw new UserInformationException(string.Format("Found {0} parse-able files (of {1} files) with different prefixes: {2}, did you forget to set the backup prefix?", tmp.Length, rawlist.Count, string.Join(", ", types)));
}
}
@@ -134,13 +135,13 @@ namespace Duplicati.Library.Main.Operation
select n;
if (filelists.Count() <= 0)
- throw new Exception(string.Format("No filelists found on the remote destination"));
+ throw new UserInformationException(string.Format("No filelists found on the remote destination"));
if (filelistfilter != null)
filelists = filelistfilter(filelists).Select(x => x.Value).ToArray();
if (filelists.Count() <= 0)
- throw new Exception(string.Format("No filelists"));
+ throw new UserInformationException(string.Format("No filelists"));
// If we are updating, all files should be accounted for
foreach(var fl in remotefiles)
@@ -180,6 +181,7 @@ namespace Duplicati.Library.Main.Operation
if (m_result.TaskControlRendevouz() == TaskControlState.Stop)
{
backend.WaitForComplete(restoredb, null);
+ m_result.EndTime = DateTime.UtcNow;
return;
}
@@ -215,26 +217,54 @@ namespace Duplicati.Library.Main.Operation
{
try
{
- if (fe.Type == FilelistEntryType.Folder)
- {
- restoredb.AddDirectoryEntry(filesetid, fe.Path, fe.Time, fe.Metahash, fe.Metahash == null ? -1 : fe.Metasize, tr);
- }
- else if (fe.Type == FilelistEntryType.File)
- {
- var expectedblocks = (fe.Size + blocksize - 1) / blocksize;
- var expectedblocklisthashes = (expectedblocks + hashes_pr_block - 1) / hashes_pr_block;
- if (expectedblocks <= 1) expectedblocklisthashes = 0;
+ var expectedmetablocks = (fe.Metasize + blocksize - 1) / blocksize;
+ var expectedmetablocklisthashes = (expectedmetablocks + hashes_pr_block - 1) / hashes_pr_block;
+ if (expectedmetablocks <= 1) expectedmetablocklisthashes = 0;
- var blocksetid = restoredb.AddBlockset(fe.Hash, fe.Size, fe.BlocklistHashes, expectedblocklisthashes, tr);
- restoredb.AddFileEntry(filesetid, fe.Path, fe.Time, blocksetid, fe.Metahash, fe.Metahash == null ? -1 : fe.Metasize, tr);
- }
- else if (fe.Type == FilelistEntryType.Symlink)
+ var metadataid = long.MinValue;
+ switch (fe.Type)
{
- restoredb.AddSymlinkEntry(filesetid, fe.Path, fe.Time, fe.Metahash, fe.Metahash == null ? -1 : fe.Metasize, tr);
+ case FilelistEntryType.Folder:
+ metadataid = restoredb.AddMetadataset(fe.Metahash, fe.Metasize, fe.MetaBlocklistHashes, expectedmetablocklisthashes, tr);
+ restoredb.AddDirectoryEntry(filesetid, fe.Path, fe.Time, metadataid, tr);
+ break;
+ case FilelistEntryType.File:
+ var expectedblocks = (fe.Size + blocksize - 1) / blocksize;
+ var expectedblocklisthashes = (expectedblocks + hashes_pr_block - 1) / hashes_pr_block;
+ if (expectedblocks <= 1) expectedblocklisthashes = 0;
+
+ var blocksetid = restoredb.AddBlockset(fe.Hash, fe.Size, fe.BlocklistHashes, expectedblocklisthashes, tr);
+ metadataid = restoredb.AddMetadataset(fe.Metahash, fe.Metasize, fe.MetaBlocklistHashes, expectedmetablocklisthashes, tr);
+ restoredb.AddFileEntry(filesetid, fe.Path, fe.Time, blocksetid, metadataid, tr);
+
+ if (fe.Size <= blocksize)
+ {
+ if (!string.IsNullOrWhiteSpace(fe.Blockhash))
+ restoredb.AddSmallBlocksetLink(fe.Hash, fe.Blockhash, fe.Blocksize, tr);
+ else if (m_options.BlockHashAlgorithm == m_options.FileHashAlgorithm)
+ restoredb.AddSmallBlocksetLink(fe.Hash, fe.Hash, fe.Size, tr);
+ else
+ m_result.AddWarning(string.Format("No block hash found for file: {0}", fe.Path), null);
+ }
+
+ break;
+ case FilelistEntryType.Symlink:
+ metadataid = restoredb.AddMetadataset(fe.Metahash, fe.Metasize, fe.MetaBlocklistHashes, expectedmetablocklisthashes, tr);
+ restoredb.AddSymlinkEntry(filesetid, fe.Path, fe.Time, metadataid, tr);
+ break;
+ default:
+ m_result.AddWarning(string.Format("Skipping file-entry with unknown type {0}: {1} ", fe.Type, fe.Path), null);
+ break;
}
- else
+
+ if (fe.Metasize <= blocksize && (fe.Type == FilelistEntryType.Folder || fe.Type == FilelistEntryType.File || fe.Type == FilelistEntryType.Symlink))
{
- m_result.AddWarning(string.Format("Skipping file-entry with unknown type {0}: {1} ", fe.Type, fe.Path), null);
+ if (!string.IsNullOrWhiteSpace(fe.Metablockhash))
+ restoredb.AddSmallBlocksetLink(fe.Metahash, fe.Metablockhash, fe.Metasize, tr);
+ else if (m_options.BlockHashAlgorithm == m_options.FileHashAlgorithm)
+ restoredb.AddSmallBlocksetLink(fe.Metahash, fe.Metahash, fe.Metasize, tr);
+ else
+ m_result.AddWarning(string.Format("No block hash found for file metadata: {0}", fe.Path), null);
}
}
catch (Exception ex)
@@ -248,10 +278,16 @@ namespace Duplicati.Library.Main.Operation
{
m_result.AddWarning(string.Format("Failed to process file: {0}", entry.Name), ex);
if (ex is System.Threading.ThreadAbortException)
+ {
+ m_result.EndTime = DateTime.UtcNow;
throw;
+ }
if (isFirstFilelist && ex is System.Security.Cryptography.CryptographicException)
+ {
+ m_result.EndTime = DateTime.UtcNow;
throw;
+ }
}
//Make sure we write the config
@@ -264,9 +300,9 @@ namespace Duplicati.Library.Main.Operation
if (!m_options.RepairOnlyPaths)
{
- var hashalg = System.Security.Cryptography.HashAlgorithm.Create(m_options.BlockHashAlgorithm);
+ var hashalg = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
if (hashalg == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
var hashsize = hashalg.HashSize / 8;
//Grab all index files, and update the block table
@@ -287,6 +323,7 @@ namespace Duplicati.Library.Main.Operation
if (m_result.TaskControlRendevouz() == TaskControlState.Stop)
{
backend.WaitForComplete(restoredb, null);
+ m_result.EndTime = DateTime.UtcNow;
return;
}
@@ -338,7 +375,10 @@ namespace Duplicati.Library.Main.Operation
//Not fatal
m_result.AddWarning(string.Format("Failed to process index file: {0}", sf.Name), ex);
if (ex is System.Threading.ThreadAbortException)
+ {
+ m_result.EndTime = DateTime.UtcNow;
throw;
+ }
}
using(new Logging.Timer("CommitRecreatedDb"))
@@ -391,6 +431,7 @@ namespace Duplicati.Library.Main.Operation
if (m_result.TaskControlRendevouz() == TaskControlState.Stop)
{
backend.WaitForComplete(restoredb, null);
+ m_result.EndTime = DateTime.UtcNow;
return;
}
@@ -435,12 +476,23 @@ namespace Duplicati.Library.Main.Operation
//All done, we must verify that we have all blocklist fully intact
// if this fails, the db will not be deleted, so it can be used,
// except to continue a backup
- restoredb.VerifyConsistency(null, m_options.Blocksize, m_options.BlockhashSize);
+ m_result.EndTime = DateTime.UtcNow;
+
+ using (var lbfdb = new LocalListBrokenFilesDatabase(restoredb))
+ {
+ var broken = lbfdb.GetBrokenFilesets(new DateTime(0), null, null).Count();
+ if (broken != 0)
+ throw new UserInformationException(string.Format("Recreated database has missing blocks and {0} broken filelists. Consider using \"{1}\" and \"{2}\" to purge broken data from the remote store and the database.", broken, "list-broken-files", "purge-broken-files"));
+ }
+
+ restoredb.VerifyConsistency(null, m_options.Blocksize, m_options.BlockhashSize, true);
m_result.AddMessage("Recreate completed, and consistency checks completed, marking database as complete");
restoredb.RepairInProgress = false;
}
+
+ m_result.EndTime = DateTime.UtcNow;
}
}
diff --git a/Duplicati/Library/Main/Operation/RepairHandler.cs b/Duplicati/Library/Main/Operation/RepairHandler.cs
index 294bb58e3..27b8bd564 100644
--- a/Duplicati/Library/Main/Operation/RepairHandler.cs
+++ b/Duplicati/Library/Main/Operation/RepairHandler.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Duplicati.Library.Interface;
using Duplicati.Library.Main.Database;
using Duplicati.Library.Main.Volumes;
@@ -20,7 +21,7 @@ namespace Duplicati.Library.Main.Operation
m_result = result;
if (options.AllowPassphraseChange)
- throw new Exception(Strings.Common.PassphraseChangeUnsupported);
+ throw new UserInformationException(Strings.Common.PassphraseChangeUnsupported);
}
public void Run(Library.Utility.IFilter filter = null)
@@ -29,6 +30,7 @@ namespace Duplicati.Library.Main.Operation
{
RunRepairLocal(filter);
RunRepairCommon();
+ m_result.EndTime = DateTime.UtcNow;
return;
}
@@ -69,6 +71,8 @@ namespace Duplicati.Library.Main.Operation
RunRepairRemote();
}
+ m_result.EndTime = DateTime.UtcNow;
+
}
public void RunRepairLocal(Library.Utility.IFilter filter = null)
@@ -90,7 +94,7 @@ namespace Duplicati.Library.Main.Operation
public void RunRepairRemote()
{
if (!System.IO.File.Exists(m_options.Dbpath))
- throw new Exception(string.Format("Database file does not exist: {0}", m_options.Dbpath));
+ throw new UserInformationException(string.Format("Database file does not exist: {0}", m_options.Dbpath));
m_result.OperationProgressUpdater.UpdateProgress(0);
@@ -102,20 +106,20 @@ namespace Duplicati.Library.Main.Operation
Utility.VerifyParameters(db, m_options);
if (db.PartiallyRecreated)
- throw new Exception("The database was only partially recreated. This database may be incomplete and the repair process is not allowed to alter remote files as that could result in data loss.");
+ throw new UserInformationException("The database was only partially recreated. This database may be incomplete and the repair process is not allowed to alter remote files as that could result in data loss.");
if (db.RepairInProgress)
- throw new Exception("The database was attempted repaired, but the repair did not complete. This database may be incomplete and the repair process is not allowed to alter remote files as that could result in data loss.");
+ throw new UserInformationException("The database was attempted repaired, but the repair did not complete. This database may be incomplete and the repair process is not allowed to alter remote files as that could result in data loss.");
- var tp = FilelistProcessor.RemoteListAnalysis(backend, m_options, db, m_result.BackendWriter);
+ var tp = FilelistProcessor.RemoteListAnalysis(backend, m_options, db, m_result.BackendWriter, null);
var buffer = new byte[m_options.Blocksize];
- var blockhasher = System.Security.Cryptography.HashAlgorithm.Create(m_options.BlockHashAlgorithm);
+ var blockhasher = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
var hashsize = blockhasher.HashSize / 8;
if (blockhasher == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
if (!blockhasher.CanReuseTransform)
- throw new Exception(Strings.Common.InvalidCryptoSystem(m_options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidCryptoSystem(m_options.BlockHashAlgorithm));
var progress = 0;
var targetProgess = tp.ExtraVolumes.Count() + tp.MissingVolumes.Count() + tp.VerificationRequiredVolumes.Count();
@@ -125,13 +129,13 @@ namespace Duplicati.Library.Main.Operation
if (tp.ParsedVolumes.Count() == 0 && tp.OtherVolumes.Count() > 0)
{
if (tp.BackupPrefixes.Length == 1)
- throw new Exception(string.Format("Found no backup files with prefix {0}, but files with prefix {1}, did you forget to set the backup-prefix?", m_options.Prefix, tp.BackupPrefixes[0]));
+ throw new UserInformationException(string.Format("Found no backup files with prefix {0}, but files with prefix {1}, did you forget to set the backup prefix?", m_options.Prefix, tp.BackupPrefixes[0]));
else
- throw new Exception(string.Format("Found no backup files with prefix {0}, but files with prefixes {1}, did you forget to set the backup-prefix?", m_options.Prefix, string.Join(", ", tp.BackupPrefixes)));
+ throw new UserInformationException(string.Format("Found no backup files with prefix {0}, but files with prefixes {1}, did you forget to set the backup prefix?", m_options.Prefix, string.Join(", ", tp.BackupPrefixes)));
}
else if (tp.ParsedVolumes.Count() == 0 && tp.ExtraVolumes.Count() > 0)
{
- throw new Exception(string.Format("No files were missing, but {0} remote files were, found, did you mean to run recreate-database?", tp.ExtraVolumes.Count()));
+ throw new UserInformationException(string.Format("No files were missing, but {0} remote files were, found, did you mean to run recreate-database?", tp.ExtraVolumes.Count()));
}
}
@@ -296,7 +300,7 @@ namespace Duplicati.Library.Main.Operation
newEntry = w;
w.SetRemoteFilename(n.Name);
- var h = System.Security.Cryptography.HashAlgorithm.Create(m_options.BlockHashAlgorithm);
+ var h = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
foreach(var blockvolume in db.GetBlockVolumesFromIndexName(n.Name))
{
@@ -395,16 +399,21 @@ namespace Duplicati.Library.Main.Operation
var missingBlocks = mbl.GetMissingBlocks().Count();
if (missingBlocks > 0)
{
- //TODO: How do we handle this situation?
m_result.AddMessage(string.Format("Repair cannot acquire {0} required blocks for volume {1}, which are required by the following filesets: ", missingBlocks, n.Name));
foreach(var f in mbl.GetFilesetsUsingMissingBlocks())
m_result.AddMessage(f.Name);
-
+
+ var recoverymsg = string.Format("If you want to continue working with the database, you can use the \"{0}\" and \"{1}\" commands to purge the missing data from the database and the remote storage.", "list-broken-files", "purge-broken-files");
+
if (!m_options.Dryrun)
{
m_result.AddMessage("This may be fixed by deleting the filesets and running repair again");
-
- throw new Exception(string.Format("Repair not possible, missing {0} blocks!!!", missingBlocks));
+
+ throw new UserInformationException(string.Format("Repair not possible, missing {0} blocks.\n" + recoverymsg, missingBlocks));
+ }
+ else
+ {
+ m_result.AddMessage(recoverymsg);
}
}
else
@@ -448,7 +457,7 @@ namespace Duplicati.Library.Main.Operation
public void RunRepairCommon()
{
if (!System.IO.File.Exists(m_options.Dbpath))
- throw new Exception(string.Format("Database file does not exist: {0}", m_options.Dbpath));
+ throw new UserInformationException(string.Format("Database file does not exist: {0}", m_options.Dbpath));
m_result.OperationProgressUpdater.UpdateProgress(0);
diff --git a/Duplicati/Library/Main/Operation/RestoreHandler.cs b/Duplicati/Library/Main/Operation/RestoreHandler.cs
index a780bb056..1d02eb6ed 100644
--- a/Duplicati/Library/Main/Operation/RestoreHandler.cs
+++ b/Duplicati/Library/Main/Operation/RestoreHandler.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Duplicati.Library.Interface;
using Duplicati.Library.Main.Database;
using Duplicati.Library.Main.Volumes;
@@ -32,7 +33,7 @@ namespace Duplicati.Library.Main.Operation
{
var tmp = VolumeBase.ParseFilename(filename);
if (tmp == null)
- throw new Exception(string.Format("Unable to parse filename to valid entry: {0}", filename));
+ throw new UserInformationException(string.Format("Unable to parse filename to valid entry: {0}", filename));
return tmp.CompressionModule;
}
@@ -123,17 +124,17 @@ namespace Duplicati.Library.Main.Operation
//Figure out what files are to be patched, and what blocks are needed
PrepareBlockAndFileList(database, m_options, filter, m_result);
- blockhasher = System.Security.Cryptography.HashAlgorithm.Create(m_options.BlockHashAlgorithm);
- filehasher = System.Security.Cryptography.HashAlgorithm.Create(m_options.FileHashAlgorithm);
+ blockhasher = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
+ filehasher = Library.Utility.HashAlgorithmHelper.Create(m_options.FileHashAlgorithm);
if (blockhasher == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
if (!blockhasher.CanReuseTransform)
- throw new Exception(Strings.Common.InvalidCryptoSystem(m_options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidCryptoSystem(m_options.BlockHashAlgorithm));
if (filehasher == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(m_options.FileHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidHashAlgorithm(m_options.FileHashAlgorithm));
if (!filehasher.CanReuseTransform)
- throw new Exception(Strings.Common.InvalidCryptoSystem(m_options.FileHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidCryptoSystem(m_options.FileHashAlgorithm));
// Don't run this again
first = false;
@@ -193,7 +194,7 @@ namespace Duplicati.Library.Main.Operation
var blocksize = options.Blocksize;
var updateCounter = 0L;
var fullblockverification = options.FullBlockVerification;
- var blockhasher = fullblockverification ? System.Security.Cryptography.HashAlgorithm.Create(options.BlockHashAlgorithm) : null;
+ var blockhasher = fullblockverification ? Library.Utility.HashAlgorithmHelper.Create(options.BlockHashAlgorithm) : null;
using (var blockmarker = database.CreateBlockMarker())
using(var volumekeeper = database.GetMissingBlockData(blocks, options.Blocksize))
@@ -344,17 +345,17 @@ namespace Duplicati.Library.Main.Operation
Utility.VerifyParameters(database, m_options);
m_blockbuffer = new byte[m_options.Blocksize];
- var blockhasher = System.Security.Cryptography.HashAlgorithm.Create(m_options.BlockHashAlgorithm);
- var filehasher = System.Security.Cryptography.HashAlgorithm.Create(m_options.FileHashAlgorithm);
+ var blockhasher = Library.Utility.HashAlgorithmHelper.Create(m_options.BlockHashAlgorithm);
+ var filehasher = Library.Utility.HashAlgorithmHelper.Create(m_options.FileHashAlgorithm);
if (blockhasher == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidHashAlgorithm(m_options.BlockHashAlgorithm));
if (!blockhasher.CanReuseTransform)
- throw new Exception(Strings.Common.InvalidCryptoSystem(m_options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidCryptoSystem(m_options.BlockHashAlgorithm));
if (filehasher == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(m_options.FileHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidHashAlgorithm(m_options.FileHashAlgorithm));
if (!filehasher.CanReuseTransform)
- throw new Exception(Strings.Common.InvalidCryptoSystem(m_options.FileHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidCryptoSystem(m_options.FileHashAlgorithm));
if (!m_options.NoBackendverification)
{
@@ -776,7 +777,10 @@ namespace Duplicati.Library.Main.Operation
if (!string.IsNullOrEmpty(options.Restorepath))
{
// Find the largest common prefix
- string largest_prefix = database.GetLargestPrefix();
+ var largest_prefix = options.DontCompressRestorePaths ? "" : database.GetLargestPrefix();
+ if (options.DontCompressRestorePaths)
+ largest_prefix = "";
+
result.AddVerboseMessage("Mapping restore path prefix to \"{0}\" to \"{1}\"", largest_prefix, Library.Utility.Utility.AppendDirSeparator(options.Restorepath));
// Set the target paths, special care with C:\ and /
diff --git a/Duplicati/Library/Main/Operation/RestoreHandlerMetadataStorage.cs b/Duplicati/Library/Main/Operation/RestoreHandlerMetadataStorage.cs
index 83897fa91..131ed1f1b 100644
--- a/Duplicati/Library/Main/Operation/RestoreHandlerMetadataStorage.cs
+++ b/Duplicati/Library/Main/Operation/RestoreHandlerMetadataStorage.cs
@@ -1 +1,131 @@
-// Copyright (C) 2015, The Duplicati Team // http://www.duplicati.com, info@duplicati.com // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA using System; using System.IO; using Duplicati.Library.Utility; using System.Collections.Generic; namespace Duplicati.Library.Main.Operation { public class RestoreHandlerMetadataStorage : IDisposable { private TempFile m_temp; private FileStream m_stream; private long m_entries; private long m_filepos; public RestoreHandlerMetadataStorage() { m_temp = new TempFile(); m_stream = File.Open(m_temp, FileMode.Truncate, FileAccess.ReadWrite, FileShare.None); } public void Add(string path, Stream data) { var datalen = data.Length; if (datalen > Int32.MaxValue) throw new ArgumentOutOfRangeException("Metadata is larger than int32"); var pathbytes = System.Text.Encoding.UTF8.GetBytes(path); var pathlen = BitConverter.GetBytes(pathbytes.LongLength); var entrylen = BitConverter.GetBytes(datalen); var totalsize = pathbytes.Length + pathlen.Length + entrylen.Length + datalen; m_stream.Position = m_filepos; m_stream.Write(pathlen, 0, pathlen.Length); m_stream.Write(pathbytes, 0, pathbytes.Length); m_stream.Write(entrylen, 0, entrylen.Length); data.CopyTo(m_stream); if (m_stream.Position != m_filepos + totalsize) throw new Exception("Bad file write!"); m_filepos += totalsize; m_entries++; } private void CheckedRead(byte[] buffer, int offset, int count) { int r; while (count > 0 && (r = m_stream.Read(buffer, offset, count)) > 0) { offset += r; count -= r; } if (count != 0) throw new Exception("Bad file read"); } public IEnumerable<KeyValuePair<string, Stream>> Records { get { long pos = 0; var bf = BitConverter.GetBytes(0L); var buf = new byte[8 * 1024]; Logging.Log.WriteMessage(string.Format("The metadata storage file has {0} entries and takes up {1}", m_entries, Library.Utility.Utility.FormatSizeString(m_stream.Length)), Duplicati.Library.Logging.LogMessageType.Profiling); using(new Logging.Timer("Read metadata from file")) for(var e = 0L; e < m_entries; e++) { m_stream.Position = pos; CheckedRead(bf, 0, bf.Length); var stringlen = BitConverter.ToInt64(bf, 0); var strbuf = stringlen > buf.Length ? new byte[stringlen] : buf; CheckedRead(strbuf, 0, (int)stringlen); var path = System.Text.Encoding.UTF8.GetString(strbuf, 0, (int)stringlen); CheckedRead(bf, 0, bf.Length); var datalen = BitConverter.ToInt64(bf, 0); if (datalen > Int32.MaxValue) throw new ArgumentOutOfRangeException("Metadata is larger than int32"); var databuf = datalen > buf.Length ? new byte[datalen] : buf; CheckedRead(databuf, 0, (int)datalen); pos += datalen + stringlen + bf.Length + bf.Length; yield return new KeyValuePair<string, Stream>(path, new MemoryStream(databuf, 0, (int)datalen)); } } } #region IDisposable implementation public void Dispose() { if (m_stream != null) try { m_stream.Dispose(); } catch { } finally { m_stream = null; } if (m_temp != null) try { m_temp.Dispose(); } catch { } finally { m_temp = null; } } #endregion } }
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.IO;
+using Duplicati.Library.Utility;
+using System.Collections.Generic;
+namespace Duplicati.Library.Main.Operation
+{
+ public class RestoreHandlerMetadataStorage : IDisposable
+ {
+ private TempFile m_temp;
+ private FileStream m_stream;
+ private long m_entries;
+
+ private long m_filepos;
+ public RestoreHandlerMetadataStorage()
+ {
+ m_temp = new TempFile();
+ m_stream = File.Open(m_temp, FileMode.Truncate, FileAccess.ReadWrite, FileShare.None);
+ }
+
+ public void Add(string path, Stream data)
+ {
+ var datalen = data.Length;
+
+ if (datalen > Int32.MaxValue)
+ throw new ArgumentOutOfRangeException("Metadata is larger than int32");
+
+ var pathbytes = System.Text.Encoding.UTF8.GetBytes(path);
+ var pathlen = BitConverter.GetBytes(pathbytes.LongLength);
+ var entrylen = BitConverter.GetBytes(datalen);
+
+ var totalsize = pathbytes.Length + pathlen.Length + entrylen.Length + datalen;
+
+ m_stream.Position = m_filepos;
+ m_stream.Write(pathlen, 0, pathlen.Length);
+ m_stream.Write(pathbytes, 0, pathbytes.Length);
+ m_stream.Write(entrylen, 0, entrylen.Length);
+ data.CopyTo(m_stream);
+
+
+ if (m_stream.Position != m_filepos + totalsize)
+ throw new Exception("Bad file write!");
+
+ m_filepos += totalsize;
+ m_entries++;
+ }
+
+ private void CheckedRead(byte[] buffer, int offset, int count)
+ {
+ int r;
+ while (count > 0 && (r = m_stream.Read(buffer, offset, count)) > 0)
+ {
+ offset += r;
+ count -= r;
+ }
+
+ if (count != 0)
+ throw new Exception("Bad file read");
+ }
+
+ public IEnumerable<KeyValuePair<string, Stream>> Records
+ {
+ get
+ {
+ long pos = 0;
+ var bf = BitConverter.GetBytes(0L);
+ var buf = new byte[8 * 1024];
+
+ Logging.Log.WriteMessage(string.Format("The metadata storage file has {0} entries and takes up {1}", m_entries, Library.Utility.Utility.FormatSizeString(m_stream.Length)), Duplicati.Library.Logging.LogMessageType.Profiling);
+
+ using(new Logging.Timer("Read metadata from file"))
+ for(var e = 0L; e < m_entries; e++)
+ {
+ m_stream.Position = pos;
+ CheckedRead(bf, 0, bf.Length);
+ var stringlen = BitConverter.ToInt64(bf, 0);
+
+ var strbuf = stringlen > buf.Length ? new byte[stringlen] : buf;
+ CheckedRead(strbuf, 0, (int)stringlen);
+ var path = System.Text.Encoding.UTF8.GetString(strbuf, 0, (int)stringlen);
+
+ CheckedRead(bf, 0, bf.Length);
+ var datalen = BitConverter.ToInt64(bf, 0);
+ if (datalen > Int32.MaxValue)
+ throw new ArgumentOutOfRangeException("Metadata is larger than int32");
+
+ var databuf = datalen > buf.Length ? new byte[datalen] : buf;
+ CheckedRead(databuf, 0, (int)datalen);
+
+ pos += datalen + stringlen + bf.Length + bf.Length;
+
+ yield return new KeyValuePair<string, Stream>(path, new MemoryStream(databuf, 0, (int)datalen));
+
+ }
+ }
+ }
+
+ #region IDisposable implementation
+
+ public void Dispose()
+ {
+ if (m_stream != null)
+ try { m_stream.Dispose(); }
+ catch { }
+ finally { m_stream = null; }
+
+ if (m_temp != null)
+ try { m_temp.Dispose(); }
+ catch { }
+ finally { m_temp = null; }
+
+ }
+
+ #endregion
+ }
+}
diff --git a/Duplicati/Library/Main/Operation/TestFilterHandler.cs b/Duplicati/Library/Main/Operation/TestFilterHandler.cs
index 7ebb99166..366a2ff4b 100644
--- a/Duplicati/Library/Main/Operation/TestFilterHandler.cs
+++ b/Duplicati/Library/Main/Operation/TestFilterHandler.cs
@@ -68,9 +68,9 @@ namespace Duplicati.Library.Main.Operation
if (m_options.SkipFilesLargerThan == long.MaxValue || m_options.SkipFilesLargerThan == 0 || size < m_options.SkipFilesLargerThan)
- m_result.AddVerboseMessage("Including file: {0} ({1})", path, size <= 0 ? "unknown" : Duplicati.Library.Utility.Utility.FormatSizeString(size));
+ m_result.AddVerboseMessage("Including file: {0} ({1})", path, size < 0 ? "unknown" : Duplicati.Library.Utility.Utility.FormatSizeString(size));
else
- m_result.AddVerboseMessage("Excluding file due to size: {0} ({1})", path, size <= 0 ? "unknown" : Duplicati.Library.Utility.Utility.FormatSizeString(size));
+ m_result.AddVerboseMessage("Excluding file due to size: {0} ({1})", path, size < 0 ? "unknown" : Duplicati.Library.Utility.Utility.FormatSizeString(size));
}
}
diff --git a/Duplicati/Library/Main/Operation/TestHandler.cs b/Duplicati/Library/Main/Operation/TestHandler.cs
index 208b537bf..b0dd5617e 100644
--- a/Duplicati/Library/Main/Operation/TestHandler.cs
+++ b/Duplicati/Library/Main/Operation/TestHandler.cs
@@ -39,7 +39,7 @@ namespace Duplicati.Library.Main.Operation
public void Run(long samples)
{
if (!System.IO.File.Exists(m_options.Dbpath))
- throw new Exception(string.Format("Database file does not exist: {0}", m_options.Dbpath));
+ throw new UserInformationException(string.Format("Database file does not exist: {0}", m_options.Dbpath));
using(var db = new LocalTestDatabase(m_options.Dbpath))
using(var backend = new BackendManager(m_backendurl, m_options, m_results.BackendWriter, db))
@@ -73,6 +73,7 @@ namespace Duplicati.Library.Main.Operation
if (m_results.TaskControlRendevouz() == TaskControlState.Stop)
{
backend.WaitForComplete(db, null);
+ m_results.EndTime = DateTime.UtcNow;
return;
}
@@ -83,6 +84,33 @@ namespace Duplicati.Library.Main.Operation
using(var tf = vol.TempFile)
res = TestVolumeInternals(db, vol, tf, m_options, m_results, m_options.FullBlockVerification ? 1.0 : 0.2);
m_results.AddResult(res.Key, res.Value);
+
+ if (!string.IsNullOrWhiteSpace(vol.Hash) && vol.Size > 0)
+ {
+ if (res.Value == null || !res.Value.Any())
+ {
+ string dbhash;
+ long dbsize;
+ RemoteVolumeType dbtype;
+ RemoteVolumeState dbstate;
+
+ if (db.GetRemoteVolume(vol.Name, out dbhash, out dbsize, out dbtype, out dbstate))
+ {
+ if (string.IsNullOrWhiteSpace(dbhash) || dbsize <= 0)
+ {
+ if (m_options.Dryrun)
+ {
+ m_results.AddDryrunMessage(string.Format("Sucessfully captured hash and size for {0}, would update database", vol.Name));
+ }
+ else
+ {
+ m_results.AddMessage(string.Format("Sucessfully captured hash and size for {0}, updating database", vol.Name));
+ db.UpdateRemoteVolume(vol.Name, RemoteVolumeState.Verified, vol.Size, vol.Hash);
+ }
+ }
+ }
+ }
+ }
db.UpdateVerificationCount(vol.Name);
}
@@ -91,7 +119,10 @@ namespace Duplicati.Library.Main.Operation
m_results.AddResult(vol.Name, new KeyValuePair<Duplicati.Library.Interface.TestEntryStatus, string>[] { new KeyValuePair<Duplicati.Library.Interface.TestEntryStatus, string>(Duplicati.Library.Interface.TestEntryStatus.Error, ex.Message) });
m_results.AddError(string.Format("Failed to process file {0}", vol.Name), ex);
if (ex is System.Threading.ThreadAbortException)
+ {
+ m_results.EndTime = DateTime.UtcNow;
throw;
+ }
}
}
}
@@ -100,16 +131,19 @@ namespace Duplicati.Library.Main.Operation
foreach(var f in files)
{
try
- {
+ {
if (m_results.TaskControlRendevouz() == TaskControlState.Stop)
+ {
+ m_results.EndTime = DateTime.UtcNow;
return;
+ }
progress++;
m_results.OperationProgressUpdater.UpdateProgress((float)progress / files.Count);
- if (f.Size < 0 || string.IsNullOrWhiteSpace(f.Hash))
+ if (f.Size <= 0 || string.IsNullOrWhiteSpace(f.Hash))
{
- m_results.AddMessage(string.Format("No hash recorded for {0}, performing full verification", f.Name));
+ m_results.AddMessage(string.Format("No hash or size recorded for {0}, performing full verification", f.Name));
KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>> res;
string hash;
long size;
@@ -117,18 +151,26 @@ namespace Duplicati.Library.Main.Operation
using (var tf = backend.GetWithInfo(f.Name, out size, out hash))
res = TestVolumeInternals(db, f, tf, m_options, m_results, 1);
m_results.AddResult(res.Key, res.Value);
-
- if (res.Value != null && !res.Value.Any() && !string.IsNullOrWhiteSpace(hash))
+
+ if (!string.IsNullOrWhiteSpace(hash) && size > 0)
{
- if (!m_options.Dryrun)
+ if (res.Value == null || !res.Value.Any())
{
- m_results.AddMessage(string.Format("Sucessfully captured hash for {0}, updating database", f.Name));
- db.UpdateRemoteVolume(f.Name, RemoteVolumeState.Verified, size, hash);
+ if (m_options.Dryrun)
+ {
+ m_results.AddDryrunMessage(string.Format("Sucessfully captured hash and size for {0}, would update database", f.Name));
+ }
+ else
+ {
+ m_results.AddMessage(string.Format("Sucessfully captured hash and size for {0}, updating database", f.Name));
+ db.UpdateRemoteVolume(f.Name, RemoteVolumeState.Verified, size, hash);
+ }
}
}
}
else
backend.GetForTesting(f.Name, f.Size, f.Hash);
+
db.UpdateVerificationCount(f.Name);
m_results.AddResult(f.Name, new KeyValuePair<Duplicati.Library.Interface.TestEntryStatus, string>[0]);
}
@@ -137,10 +179,15 @@ namespace Duplicati.Library.Main.Operation
m_results.AddResult(f.Name, new KeyValuePair<Duplicati.Library.Interface.TestEntryStatus, string>[] { new KeyValuePair<Duplicati.Library.Interface.TestEntryStatus, string>(Duplicati.Library.Interface.TestEntryStatus.Error, ex.Message) });
m_results.AddError(string.Format("Failed to process file {0}", f.Name), ex);
if (ex is System.Threading.ThreadAbortException)
+ {
+ m_results.EndTime = DateTime.UtcNow;
throw;
+ }
}
}
}
+
+ m_results.EndTime = DateTime.UtcNow;
}
/// <summary>
@@ -151,93 +198,91 @@ namespace Duplicati.Library.Main.Operation
/// <param name="sample_percent">A value between 0 and 1 that indicates how many blocks are tested in a dblock file</param>
public static KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>> TestVolumeInternals(LocalTestDatabase db, IRemoteVolume vol, string tf, Options options, ILogWriter log, double sample_percent)
{
- var blockhasher = System.Security.Cryptography.HashAlgorithm.Create(options.BlockHashAlgorithm);
+ var blockhasher = Library.Utility.HashAlgorithmHelper.Create(options.BlockHashAlgorithm);
if (blockhasher == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidHashAlgorithm(options.BlockHashAlgorithm));
if (!blockhasher.CanReuseTransform)
- throw new Exception(Strings.Common.InvalidCryptoSystem(options.BlockHashAlgorithm));
+ throw new UserInformationException(Strings.Common.InvalidCryptoSystem(options.BlockHashAlgorithm));
var hashsize = blockhasher.HashSize / 8;
var parsedInfo = Volumes.VolumeBase.ParseFilename(vol.Name);
sample_percent = Math.Min(1, Math.Max(sample_percent, 0.01));
- if (parsedInfo.FileType == RemoteVolumeType.Files)
+ switch (parsedInfo.FileType)
{
- //Compare with db and see if all files are accounted for
- // with correct file hashes and blocklist hashes
- using(var fl = db.CreateFilelist(vol.Name))
- {
- using(var rd = new Volumes.FilesetVolumeReader(parsedInfo.CompressionModule, tf, options))
- foreach(var f in rd.Files)
- fl.Add(f.Path, f.Size, f.Hash, f.Metasize, f.Metahash, f.BlocklistHashes, f.Type, f.Time);
-
- return new KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>(vol.Name, fl.Compare().ToList());
- }
- }
- else if (parsedInfo.FileType == RemoteVolumeType.Index)
- {
- var blocklinks = new List<Tuple<string, string, long>>();
- IEnumerable<KeyValuePair<Duplicati.Library.Interface.TestEntryStatus, string>> combined = new KeyValuePair<Duplicati.Library.Interface.TestEntryStatus, string>[0];
-
- //Compare with db and see that all hashes and volumes are listed
- using(var rd = new Volumes.IndexVolumeReader(parsedInfo.CompressionModule, tf, options, hashsize))
- foreach(var v in rd.Volumes)
+ case RemoteVolumeType.Files:
+ //Compare with db and see if all files are accounted for
+ // with correct file hashes and blocklist hashes
+ using (var fl = db.CreateFilelist(vol.Name))
{
- blocklinks.Add(new Tuple<string, string, long>(v.Filename, v.Hash, v.Length));
- using(var bl = db.CreateBlocklist(v.Filename))
+ using (var rd = new Volumes.FilesetVolumeReader(parsedInfo.CompressionModule, tf, options))
+ foreach (var f in rd.Files)
+ fl.Add(f.Path, f.Size, f.Hash, f.Metasize, f.Metahash, f.BlocklistHashes, f.Type, f.Time);
+
+ return new KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>(vol.Name, fl.Compare().ToList());
+ }
+
+ case RemoteVolumeType.Index:
+ var blocklinks = new List<Tuple<string, string, long>>();
+ IEnumerable<KeyValuePair<Duplicati.Library.Interface.TestEntryStatus, string>> combined = new KeyValuePair<Duplicati.Library.Interface.TestEntryStatus, string>[0];
+
+ //Compare with db and see that all hashes and volumes are listed
+ using (var rd = new Volumes.IndexVolumeReader(parsedInfo.CompressionModule, tf, options, hashsize))
+ foreach (var v in rd.Volumes)
{
- foreach(var h in v.Blocks)
- bl.AddBlock(h.Key, h.Value);
-
- combined = combined.Union(bl.Compare().ToArray());
+ blocklinks.Add(new Tuple<string, string, long>(v.Filename, v.Hash, v.Length));
+ using (var bl = db.CreateBlocklist(v.Filename))
+ {
+ foreach (var h in v.Blocks)
+ bl.AddBlock(h.Key, h.Value);
+
+ combined = combined.Union(bl.Compare().ToArray());
+ }
}
+
+ using (var il = db.CreateIndexlist(vol.Name))
+ {
+ foreach (var t in blocklinks)
+ il.AddBlockLink(t.Item1, t.Item2, t.Item3);
+
+ combined = combined.Union(il.Compare()).ToList();
}
-
- using(var il = db.CreateIndexlist(vol.Name))
- {
- foreach(var t in blocklinks)
- il.AddBlockLink(t.Item1, t.Item2, t.Item3);
-
- combined = combined.Union(il.Compare()).ToList();
- }
-
- return new KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>(vol.Name, combined.ToList());
- }
- else if (parsedInfo.FileType == RemoteVolumeType.Blocks)
- {
- using(var bl = db.CreateBlocklist(vol.Name))
- using(var rd = new Volumes.BlockVolumeReader(parsedInfo.CompressionModule, tf, options))
- {
- //Verify that all blocks are in the file
- foreach(var b in rd.Blocks)
- bl.AddBlock(b.Key, b.Value);
-
- //Select random blocks and verify their hashes match the filename and size
- var hashsamples = new List<KeyValuePair<string, long>>(rd.Blocks);
- var sampleCount = Math.Min(Math.Max(0, (int)(hashsamples.Count * sample_percent)), hashsamples.Count - 1);
- var rnd = new Random();
-
- while (hashsamples.Count > sampleCount)
- hashsamples.RemoveAt(rnd.Next(hashsamples.Count));
-
- var blockbuffer = new byte[options.Blocksize];
- var changes = new List<KeyValuePair<Library.Interface.TestEntryStatus, string>>();
- foreach(var s in hashsamples)
+
+ return new KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>(vol.Name, combined.ToList());
+ case RemoteVolumeType.Blocks:
+ using (var bl = db.CreateBlocklist(vol.Name))
+ using (var rd = new Volumes.BlockVolumeReader(parsedInfo.CompressionModule, tf, options))
{
- var size = rd.ReadBlock(s.Key, blockbuffer);
- if (size != s.Value)
- changes.Add(new KeyValuePair<Library.Interface.TestEntryStatus, string>(Library.Interface.TestEntryStatus.Modified, s.Key));
- else
+ //Verify that all blocks are in the file
+ foreach (var b in rd.Blocks)
+ bl.AddBlock(b.Key, b.Value);
+
+ //Select random blocks and verify their hashes match the filename and size
+ var hashsamples = new List<KeyValuePair<string, long>>(rd.Blocks);
+ var sampleCount = Math.Min(Math.Max(0, (int)(hashsamples.Count * sample_percent)), hashsamples.Count - 1);
+ var rnd = new Random();
+
+ while (hashsamples.Count > sampleCount)
+ hashsamples.RemoveAt(rnd.Next(hashsamples.Count));
+
+ var blockbuffer = new byte[options.Blocksize];
+ var changes = new List<KeyValuePair<Library.Interface.TestEntryStatus, string>>();
+ foreach (var s in hashsamples)
{
- var hash = Convert.ToBase64String(blockhasher.ComputeHash(blockbuffer, 0, size));
- if (hash != s.Key)
+ var size = rd.ReadBlock(s.Key, blockbuffer);
+ if (size != s.Value)
changes.Add(new KeyValuePair<Library.Interface.TestEntryStatus, string>(Library.Interface.TestEntryStatus.Modified, s.Key));
+ else
+ {
+ var hash = Convert.ToBase64String(blockhasher.ComputeHash(blockbuffer, 0, size));
+ if (hash != s.Key)
+ changes.Add(new KeyValuePair<Library.Interface.TestEntryStatus, string>(Library.Interface.TestEntryStatus.Modified, s.Key));
+ }
}
+
+ return new KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>(vol.Name, changes.Union(bl.Compare().ToList()));
}
-
- return new KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>(vol.Name, changes.Union(bl.Compare().ToList()));
- }
}
log.AddWarning(string.Format("Unexpected file type {0} for {1}", parsedInfo.FileType, vol.Name), null);
diff --git a/Duplicati/Library/Main/Operation/VacuumHandler.cs b/Duplicati/Library/Main/Operation/VacuumHandler.cs
new file mode 100644
index 000000000..454366667
--- /dev/null
+++ b/Duplicati/Library/Main/Operation/VacuumHandler.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Duplicati.Library.Main.Operation
+{
+ internal class VacuumHandler
+ {
+ private Options m_options;
+ private VacuumResult m_result;
+
+ public VacuumHandler(Options options, VacuumResult result)
+ {
+ m_options = options;
+ m_result = result;
+ }
+
+ public virtual void Run()
+ {
+ using (var db = new Database.LocalDatabase(m_options.Dbpath, "Vacuum", false))
+ {
+ m_result.SetDatabase(db);
+ db.Vacuum();
+ }
+ }
+ }
+}
diff --git a/Duplicati/Library/Main/OperationPhase.cs b/Duplicati/Library/Main/OperationPhase.cs
index 0170aff41..6c30bd55e 100644
--- a/Duplicati/Library/Main/OperationPhase.cs
+++ b/Duplicati/Library/Main/OperationPhase.cs
@@ -50,6 +50,14 @@ namespace Duplicati.Library.Main
BugReport_Running,
+ Delete_Listing,
+ Delete_Deleting,
+
+ PurgeFiles_Begin,
+ PurgeFiles_Process,
+ PurgeFiles_Compact,
+ PurgeFiles_Complete,
+
Error
}
}
diff --git a/Duplicati/Library/Main/Options.cs b/Duplicati/Library/Main/Options.cs
index dffbfe506..bd93568fd 100644
--- a/Duplicati/Library/Main/Options.cs
+++ b/Duplicati/Library/Main/Options.cs
@@ -22,6 +22,7 @@ using System.Linq;
using System.Collections.Generic;
using System.Text;
using Duplicati.Library.Interface;
+using Duplicati.Library.Utility;
namespace Duplicati.Library.Main
{
@@ -233,6 +234,7 @@ namespace Duplicati.Library.Main
"dblock-size",
"disable-autocreate-folder",
"disable-filetime-check",
+ "check-filetime-only",
"disable-time-tolerance",
"allow-missing-source",
"skip-files-larger-than",
@@ -248,7 +250,8 @@ namespace Duplicati.Library.Main
"hardlink-policy",
"exclude-files-attributes",
"compression-extension-file",
- "full-remote-verification"
+ "full-remote-verification",
+ "disable-synthetic-filelist"
};
}
}
@@ -346,7 +349,8 @@ namespace Duplicati.Library.Main
get
{
return new string[] {
- "dry-run"
+ "dry-run",
+ "allow-full-removal"
};
}
}
@@ -367,7 +371,8 @@ namespace Duplicati.Library.Main
"allow-passphrase-change",
"no-local-db",
"no-local-blocks",
- "full-block-verification"
+ "full-block-verification",
+ "dont-compress-restore-paths"
};
}
}
@@ -408,6 +413,7 @@ namespace Duplicati.Library.Main
new CommandLineArgument("allow-missing-source", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AllowmissingsourceShort, Strings.Options.AllowmissingsourceLong, "false"),
new CommandLineArgument("disable-filetime-check", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisablefiletimecheckShort, Strings.Options.DisablefiletimecheckLong, "false"),
+ new CommandLineArgument("check-filetime-only", CommandLineArgument.ArgumentType.Boolean, Strings.Options.CheckfiletimeonlyShort, Strings.Options.CheckfiletimeonlyLong, "false"),
//new CommandLineArgument("disable-usn-diff-check", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisableusndiffcheckShort, Strings.Options.DisableusndiffcheckLong, "false"),
new CommandLineArgument("disable-time-tolerance", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisabletimetoleranceShort, Strings.Options.DisabletimetoleranceLong, "false"),
@@ -428,8 +434,8 @@ namespace Duplicati.Library.Main
new CommandLineArgument("disable-streaming-transfers", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisableStreamingShort, Strings.Options.DisableStreamingLong, "false"),
- new CommandLineArgument("throttle-upload", CommandLineArgument.ArgumentType.Size, Strings.Options.ThrottleuploadShort, Strings.Options.ThrottleuploadLong, "0"),
- new CommandLineArgument("throttle-download", CommandLineArgument.ArgumentType.Size, Strings.Options.ThrottledownloadShort, Strings.Options.ThrottledownloadLong, "0"),
+ new CommandLineArgument("throttle-upload", CommandLineArgument.ArgumentType.Size, Strings.Options.ThrottleuploadShort, Strings.Options.ThrottleuploadLong, "0kb"),
+ new CommandLineArgument("throttle-download", CommandLineArgument.ArgumentType.Size, Strings.Options.ThrottledownloadShort, Strings.Options.ThrottledownloadLong, "0kb"),
new CommandLineArgument("skip-files-larger-than", CommandLineArgument.ArgumentType.Size, Strings.Options.SkipfileslargerthanShort, Strings.Options.SkipfileslargerthanLong),
new CommandLineArgument("upload-unchanged-backups", CommandLineArgument.ArgumentType.Boolean, Strings.Options.UploadUnchangedBackupsShort, Strings.Options.UploadUnchangedBackupsLong, "false"),
@@ -438,7 +444,6 @@ namespace Duplicati.Library.Main
new CommandLineArgument("vss-exclude-writers", CommandLineArgument.ArgumentType.String, Strings.Options.VssexcludewritersShort, Strings.Options.VssexcludewritersLong),
new CommandLineArgument("vss-use-mapping", CommandLineArgument.ArgumentType.Boolean, Strings.Options.VssusemappingShort, Strings.Options.VssusemappingLong, "false"),
new CommandLineArgument("usn-policy", CommandLineArgument.ArgumentType.Enumeration, Strings.Options.UsnpolicyShort, Strings.Options.UsnpolicyLong, "off", null, Enum.GetNames(typeof(OptimizationStrategy))),
- new CommandLineArgument("hyperv-backup-vm", CommandLineArgument.ArgumentType.String, Strings.Options.HypervbackupvmShort, Strings.Options.HypervbackupvmLong),
new CommandLineArgument("encryption-module", CommandLineArgument.ArgumentType.String, Strings.Options.EncryptionmoduleShort, Strings.Options.EncryptionmoduleLong, "aes"),
new CommandLineArgument("compression-module", CommandLineArgument.ArgumentType.String, Strings.Options.CompressionmoduleShort, Strings.Options.CompressionmoduleLong, "zip"),
@@ -458,6 +463,8 @@ namespace Duplicati.Library.Main
new CommandLineArgument("quota-size", CommandLineArgument.ArgumentType.Size, Strings.Options.QuotasizeShort, Strings.Options.QuotasizeLong),
+ new CommandLineArgument("default-filters", CommandLineArgument.ArgumentType.String, Strings.Options.DefaultFiltersShort, Strings.Options.DefaultFiltersLong(DefaultFilterSet.Windows.ToString(), DefaultFilterSet.OSX.ToString(), DefaultFilterSet.Linux.ToString(), DefaultFilterSet.All.ToString()), string.Empty, new[] { "default-filter" }),
+
new CommandLineArgument("symlink-policy", CommandLineArgument.ArgumentType.Enumeration, Strings.Options.SymlinkpolicyShort, Strings.Options.SymlinkpolicyLong("store", "ignore", "follow"), Enum.GetName(typeof(SymlinkStrategy), SymlinkStrategy.Store), null, Enum.GetNames(typeof(SymlinkStrategy))),
new CommandLineArgument("hardlink-policy", CommandLineArgument.ArgumentType.Enumeration, Strings.Options.HardlinkpolicyShort, Strings.Options.HardlinkpolicyLong("first", "all", "none"), Enum.GetName(typeof(HardlinkStrategy), HardlinkStrategy.All), null, Enum.GetNames(typeof(HardlinkStrategy))),
new CommandLineArgument("exclude-files-attributes", CommandLineArgument.ArgumentType.String, Strings.Options.ExcludefilesattributesShort, Strings.Options.ExcludefilesattributesLong(Enum.GetNames(typeof(System.IO.FileAttributes)))),
@@ -465,25 +472,24 @@ namespace Duplicati.Library.Main
new CommandLineArgument("compression-extension-file", CommandLineArgument.ArgumentType.Path, Strings.Options.CompressionextensionfileShort, Strings.Options.CompressionextensionfileLong(DEFAULT_COMPRESSED_EXTENSION_FILE), DEFAULT_COMPRESSED_EXTENSION_FILE),
new CommandLineArgument("verbose", CommandLineArgument.ArgumentType.Boolean, Strings.Options.VerboseShort, Strings.Options.VerboseLong, "false"),
+ new CommandLineArgument("full-result", CommandLineArgument.ArgumentType.Boolean, Strings.Options.FullresultShort, Strings.Options.FullresultLong, "false"),
new CommandLineArgument("overwrite", CommandLineArgument.ArgumentType.Boolean, Strings.Options.OverwriteShort, Strings.Options.OverwriteLong, "false"),
new CommandLineArgument("dbpath", CommandLineArgument.ArgumentType.Path, Strings.Options.DbpathShort, Strings.Options.DbpathLong),
new CommandLineArgument("blocksize", CommandLineArgument.ArgumentType.Size, Strings.Options.BlocksizeShort, Strings.Options.BlocksizeLong, DEFAULT_BLOCKSIZE),
- new CommandLineArgument("file-read-buffer-size", CommandLineArgument.ArgumentType.Size, Strings.Options.FilereadbuffersizeShort, Strings.Options.FilereadbuffersizeLong, "0"),
+ new CommandLineArgument("file-read-buffer-size", CommandLineArgument.ArgumentType.Size, Strings.Options.FilereadbuffersizeShort, Strings.Options.FilereadbuffersizeLong, "0kb"),
new CommandLineArgument("store-metadata", CommandLineArgument.ArgumentType.Boolean, Strings.Options.StoremetadataShort, Strings.Options.StoremetadataLong, "true", null, null, Strings.Options.StoremetadataDeprecated),
new CommandLineArgument("skip-metadata", CommandLineArgument.ArgumentType.Boolean, Strings.Options.SkipmetadataShort, Strings.Options.SkipmetadataLong, "false"),
new CommandLineArgument("restore-permissions", CommandLineArgument.ArgumentType.Boolean, Strings.Options.RestorepermissionsShort, Strings.Options.RestorepermissionsLong, "false"),
new CommandLineArgument("skip-restore-verification", CommandLineArgument.ArgumentType.Boolean, Strings.Options.SkiprestoreverificationShort, Strings.Options.SkiprestoreverificationLong, "false"),
- new CommandLineArgument("blockhash-lookup-memory", CommandLineArgument.ArgumentType.Size, Strings.Options.BlockhashlookupsizeShort, Strings.Options.BlockhashlookupsizeLong, "0"),
- new CommandLineArgument("filehash-lookup-memory", CommandLineArgument.ArgumentType.Size, Strings.Options.FilehashlookupsizeShort, Strings.Options.FilehashlookupsizeLong, "0"),
- new CommandLineArgument("metadatahash-lookup-memory", CommandLineArgument.ArgumentType.Size, Strings.Options.MetadatahashlookupsizeShort, Strings.Options.MetadatahashlookupsizeLong, "0"),
- new CommandLineArgument("old-lookup-memory-defaults", CommandLineArgument.ArgumentType.Size, Strings.Options.OldmemorylookupdefaultsShort, Strings.Options.OldmemorylookupdefaultsLong, "false"),
new CommandLineArgument("disable-filepath-cache", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisablefilepathcacheShort, Strings.Options.DisablefilepathcacheLong, "true"),
+ new CommandLineArgument("use-block-cache", CommandLineArgument.ArgumentType.Boolean, Strings.Options.UseblockcacheShort, Strings.Options.UseblockcacheLong, "false"),
new CommandLineArgument("changed-files", CommandLineArgument.ArgumentType.Path, Strings.Options.ChangedfilesShort, Strings.Options.ChangedfilesLong),
new CommandLineArgument("deleted-files", CommandLineArgument.ArgumentType.Path, Strings.Options.DeletedfilesShort, Strings.Options.DeletedfilesLong("changed-files")),
+ new CommandLineArgument("disable-synthetic-filelist", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisablesyntheticfilelistShort, Strings.Options.DisablesyntehticfilelistLong, "false"),
- new CommandLineArgument("threshold", CommandLineArgument.ArgumentType.Size, Strings.Options.ThresholdShort, Strings.Options.ThresholdLong, DEFAULT_THRESHOLD.ToString()),
+ new CommandLineArgument("threshold", CommandLineArgument.ArgumentType.Integer, Strings.Options.ThresholdShort, Strings.Options.ThresholdLong, DEFAULT_THRESHOLD.ToString()),
new CommandLineArgument("index-file-policy", CommandLineArgument.ArgumentType.Enumeration, Strings.Options.IndexfilepolicyShort, Strings.Options.IndexfilepolicyLong, IndexFileStrategy.Full.ToString(), null, Enum.GetNames(typeof(IndexFileStrategy))),
new CommandLineArgument("no-backend-verification", CommandLineArgument.ArgumentType.Boolean, Strings.Options.NobackendverificationShort, Strings.Options.NobackendverificationLong, "false"),
new CommandLineArgument("backup-test-samples", CommandLineArgument.ArgumentType.Integer, Strings.Options.BackendtestsamplesShort, Strings.Options.BackendtestsamplesLong("no-backend-verification"), "1"),
@@ -495,17 +501,20 @@ namespace Duplicati.Library.Main
new CommandLineArgument("no-auto-compact", CommandLineArgument.ArgumentType.Boolean, Strings.Options.NoautocompactShort, Strings.Options.NoautocompactLong, "false"),
new CommandLineArgument("small-file-size", CommandLineArgument.ArgumentType.Size, Strings.Options.SmallfilesizeShort, Strings.Options.SmallfilesizeLong),
- new CommandLineArgument("small-file-max-count", CommandLineArgument.ArgumentType.Size, Strings.Options.SmallfilemaxcountShort, Strings.Options.SmallfilemaxcountLong, DEFAULT_SMALL_FILE_MAX_COUNT.ToString()),
+ new CommandLineArgument("small-file-max-count", CommandLineArgument.ArgumentType.Integer, Strings.Options.SmallfilemaxcountShort, Strings.Options.SmallfilemaxcountLong, DEFAULT_SMALL_FILE_MAX_COUNT.ToString()),
new CommandLineArgument("patch-with-local-blocks", CommandLineArgument.ArgumentType.Boolean, Strings.Options.PatchwithlocalblocksShort, Strings.Options.PatchwithlocalblocksLong, "false"),
new CommandLineArgument("no-local-db", CommandLineArgument.ArgumentType.Boolean, Strings.Options.NolocaldbShort, Strings.Options.NolocaldbLong, "false"),
-
+ new CommandLineArgument("dont-compress-restore-paths", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DontcompressrestorepathsShort, Strings.Options.DontcompressrestorepathsLong, "false"),
+
new CommandLineArgument("keep-versions", CommandLineArgument.ArgumentType.Integer, Strings.Options.KeepversionsShort, Strings.Options.KeepversionsLong, DEFAULT_KEEP_VERSIONS.ToString()),
new CommandLineArgument("keep-time", CommandLineArgument.ArgumentType.Timespan, Strings.Options.KeeptimeShort, Strings.Options.KeeptimeLong),
+ new CommandLineArgument("retention-policy", CommandLineArgument.ArgumentType.String, Strings.Options.RetentionPolicyShort, Strings.Options.RetentionPolicyLong),
new CommandLineArgument("upload-verification-file", CommandLineArgument.ArgumentType.Boolean, Strings.Options.UploadverificationfileShort, Strings.Options.UploadverificationfileLong, "false"),
new CommandLineArgument("allow-passphrase-change", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AllowpassphrasechangeShort, Strings.Options.AllowpassphrasechangeLong, "false"),
new CommandLineArgument("no-local-blocks", CommandLineArgument.ArgumentType.Boolean, Strings.Options.NolocalblocksShort, Strings.Options.NolocalblocksLong, "false"),
new CommandLineArgument("full-block-verification", CommandLineArgument.ArgumentType.Boolean, Strings.Options.FullblockverificationShort, Strings.Options.FullblockverificationLong, "false"),
+ new CommandLineArgument("allow-full-removal", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AllowfullremovalShort, Strings.Options.AllowfullremovalLong, "false"),
new CommandLineArgument("log-retention", CommandLineArgument.ArgumentType.Timespan, Strings.Options.LogretentionShort, Strings.Options.LogretentionLong, DEFAULT_LOG_RETENTION),
@@ -513,6 +522,8 @@ namespace Duplicati.Library.Main
new CommandLineArgument("force-locale", CommandLineArgument.ArgumentType.String, Strings.Options.ForcelocaleShort, Strings.Options.ForcelocaleLong),
new CommandLineArgument("disable-piped-streaming", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisablepipingShort, Strings.Options.DisablepipingLong, "false"),
+
+ new CommandLineArgument("auto-vacuum", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AutoVacuumShort, Strings.Options.AutoVacuumLong, "false"),
});
return lst;
@@ -662,6 +673,11 @@ namespace Duplicati.Library.Main
public bool DisableFiletimeCheck { get { return GetBool("disable-filetime-check"); } }
/// <summary>
+ /// A value indicating if file time checks are skipped
+ /// </summary>
+ public bool CheckFiletimeOnly { get { return GetBool("check-filetime-only"); } }
+
+ /// <summary>
/// A value indicating if USN numbers are used to get list of changed files
/// </summary>
//public bool DisableUSNDiffCheck { get { return GetBool("disable-usn-diff-check"); } }
@@ -788,40 +804,34 @@ namespace Duplicati.Library.Main
return Library.Utility.Timeparser.ParseTimeInterval(v, DateTime.Now, true) - tolerance;
}
}
-
+
/// <summary>
- /// Gets the filesets selected for deletion
- /// </summary>
- /// <returns>The filesets to delete</returns>
- /// <param name="backups">The list of backups that can be deleted</param>
- public DateTime[] GetFilesetsToDelete (DateTime[] backups)
+ /// Gets the time frames and intervals for the retention policy
+ /// </summary>
+ public Dictionary<TimeSpan, TimeSpan> RetentionPolicy
{
- if (backups.Length == 0)
- return backups;
-
- List<DateTime> res = new List<DateTime>();
-
- var versions = this.Version;
- if (versions != null && versions.Length > 0)
- foreach (var ix in versions.Distinct())
- if (ix >= 0 && ix < backups.Length)
- res.Add(backups[ix]);
-
- var keepVersions = this.KeepVersions;
- if (keepVersions > 0 && keepVersions < backups.Length)
- res.AddRange(backups.Skip(keepVersions));
-
- var keepTime = this.KeepTime;
- if (keepTime.Ticks > 0)
- res.AddRange(backups.SkipWhile(x => x >= keepTime));
-
- var filtered = res.Distinct().OrderByDescending(x => x).AsEnumerable();
-
- var removeCount = filtered.Count();
- if (removeCount >= backups.Length)
- filtered = filtered.Skip(removeCount - backups.Length + (AllowFullRemoval ? 0 : 1));
-
- return filtered.ToArray();
+ get {
+ var retentionPolicyConfig = new Dictionary<TimeSpan, TimeSpan>();
+
+ string v;
+ m_options.TryGetValue("retention-policy", out v);
+ if (string.IsNullOrEmpty(v)) {
+ return retentionPolicyConfig;
+ }
+
+ var periodIntervalStrings = v.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+
+ foreach (var periodIntervalString in periodIntervalStrings)
+ {
+ var periodInterval = periodIntervalString.Split(':');
+ var period = Library.Utility.Timeparser.ParseTimeSpan(periodInterval[0]);
+ var interval = Library.Utility.Timeparser.ParseTimeSpan(periodInterval[1]);
+
+ retentionPolicyConfig.Add(period, interval);
+ }
+
+ return retentionPolicyConfig;
+ }
}
/// <summary>
@@ -919,7 +929,7 @@ namespace Duplicati.Library.Main
{
int x = int.Parse(m_options["number-of-retries"]);
if (x < 0)
- throw new Exception("Invalid count for number-of-retries");
+ throw new UserInformationException("Invalid count for number-of-retries");
return x;
}
@@ -1068,13 +1078,13 @@ namespace Duplicati.Library.Main
if (!m_options.TryGetValue("snapshot-policy", out strategy))
strategy = "";
- if (string.Equals(strategy, "on", StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(strategy, "on", StringComparison.OrdinalIgnoreCase))
return OptimizationStrategy.On;
- else if (string.Equals(strategy, "off", StringComparison.InvariantCultureIgnoreCase))
+ else if (string.Equals(strategy, "off", StringComparison.OrdinalIgnoreCase))
return OptimizationStrategy.Off;
- else if (string.Equals(strategy, "required", StringComparison.InvariantCultureIgnoreCase))
+ else if (string.Equals(strategy, "required", StringComparison.OrdinalIgnoreCase))
return OptimizationStrategy.Required;
- else if (string.Equals(strategy, "auto", StringComparison.InvariantCultureIgnoreCase))
+ else if (string.Equals(strategy, "auto", StringComparison.OrdinalIgnoreCase))
return OptimizationStrategy.Auto;
else
return OptimizationStrategy.Off;
@@ -1129,13 +1139,13 @@ namespace Duplicati.Library.Main
if (!m_options.TryGetValue("usn-policy", out strategy))
strategy = "";
- if (string.Equals(strategy, "on", StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(strategy, "on", StringComparison.OrdinalIgnoreCase))
return OptimizationStrategy.On;
- else if (string.Equals(strategy, "off", StringComparison.InvariantCultureIgnoreCase))
+ else if (string.Equals(strategy, "off", StringComparison.OrdinalIgnoreCase))
return OptimizationStrategy.Off;
- else if (string.Equals(strategy, "required", StringComparison.InvariantCultureIgnoreCase))
+ else if (string.Equals(strategy, "required", StringComparison.OrdinalIgnoreCase))
return OptimizationStrategy.Required;
- else if (string.Equals(strategy, "auto", StringComparison.InvariantCultureIgnoreCase))
+ else if (string.Equals(strategy, "auto", StringComparison.OrdinalIgnoreCase))
return OptimizationStrategy.Auto;
else
return OptimizationStrategy.Off;
@@ -1205,7 +1215,7 @@ namespace Duplicati.Library.Main
value = null;
foreach (string s in Enum.GetNames(typeof(Duplicati.Library.Logging.LogMessageType)))
- if (s.Equals(value, StringComparison.InvariantCultureIgnoreCase))
+ if (s.Equals(value, StringComparison.OrdinalIgnoreCase))
return true;
return false;
@@ -1224,7 +1234,7 @@ namespace Duplicati.Library.Main
value = null;
foreach (string s in Enum.GetNames(typeof(Duplicati.Library.Logging.LogMessageType)))
- if (s.Equals(value, StringComparison.InvariantCultureIgnoreCase))
+ if (s.Equals(value, StringComparison.OrdinalIgnoreCase))
return (Duplicati.Library.Logging.LogMessageType)Enum.Parse(typeof(Duplicati.Library.Logging.LogMessageType), s);
return Duplicati.Library.Logging.LogMessageType.Warning;
@@ -1268,7 +1278,12 @@ namespace Duplicati.Library.Main
/// A value indicating if the output should be verbose
/// </summary>
public bool Verbose { get { return GetBool("verbose"); } }
-
+
+ /// <summary>
+ /// A value indicating if the returned value should not be truncated
+ /// </summary>
+ public bool FullResult { get { return GetBool("full-result"); } }
+
/// <summary>
/// A value indicating restored files overwrite existing ones
/// </summary>
@@ -1352,7 +1367,7 @@ namespace Duplicati.Library.Main
{
get
{
- return System.Security.Cryptography.HashAlgorithm.Create(BlockHashAlgorithm).HashSize / 8;
+ return Duplicati.Library.Utility.HashAlgorithmHelper.Create(BlockHashAlgorithm).HashSize / 8;
}
}
@@ -1415,77 +1430,34 @@ namespace Duplicati.Library.Main
}
/// <summary>
- /// Gets a flag indicating whether this <see cref="Duplicati.Library.Main.Options"/> old memory defaults.
- /// </summary>
- public bool OldMemoryDefaults
- {
- get { return Library.Utility.Utility.ParseBoolOption(m_options, "old-lookup-memory-defaults"); }
- }
-
- /// <summary>
- /// Gets the block hash lookup size
+ /// Gets a flag indicating if synthetic filelist generation is disabled
/// </summary>
- public long BlockHashLookupMemory
+ public bool DisableSyntheticFilelist
{
- get
- {
- string v;
- m_options.TryGetValue("blockhash-lookup-memory", out v);
- if (string.IsNullOrEmpty(v))
- v = OldMemoryDefaults ? DEFAULT_BLOCK_HASH_LOOKUP_SIZE : "0";
-
- return Library.Utility.Sizeparser.ParseSize(v, "mb");
- }
+ get { return Library.Utility.Utility.ParseBoolOption(m_options, "disable-synthetic-filelist"); }
}
/// <summary>
- /// Gets the file hash size
+ /// Flag indicating if the filepath cache is disabled
/// </summary>
- public long FileHashLookupMemory
+ public bool UseFilepathCache
{
get
{
- string v;
- m_options.TryGetValue("filehash-lookup-memory", out v);
- if (string.IsNullOrEmpty(v))
- v = OldMemoryDefaults ? DEFAULT_FILE_HASH_LOOKUP_SIZE : "0";
-
- return Library.Utility.Sizeparser.ParseSize(v, "mb");
+ string s;
+ m_options.TryGetValue("disable-filepath-cache", out s);
+ return !Library.Utility.Utility.ParseBool(s, true);
}
}
/// <summary>
- /// Gets the block hash size
- /// </summary>
- public long MetadataHashMemory
- {
- get
- {
- string v;
- m_options.TryGetValue("metadatahash-lookup-memory", out v);
- if (string.IsNullOrEmpty(v))
- v = OldMemoryDefaults ? DEFAULT_METADATA_HASH_LOOKUP_SIZE : "0";
-
- return Library.Utility.Sizeparser.ParseSize(v, "mb");
- }
- }
-
- /// <summary>
- /// Gets the file hash size
+ /// Flag indicating if the in-memory block cache is used
/// </summary>
- public bool UseFilepathCache
+ public bool UseBlockCache
{
get
{
-
- if (OldMemoryDefaults)
- return !Library.Utility.Utility.ParseBoolOption(m_options, "disable-filepath-cache");
- else
- {
- string s;
- m_options.TryGetValue("disable-filepath-cache", out s);
- return !Library.Utility.Utility.ParseBool(s, true);
- }
+ return Library.Utility.Utility.ParseBoolOption(m_options, "use-block-cache");
}
}
@@ -1756,6 +1728,15 @@ namespace Duplicati.Library.Main
}
/// <summary>
+ /// Gets a flag indicating if the local database should not be used
+ /// </summary>
+ /// <value><c>true</c> if no local db is used; otherwise, <c>false</c>.</value>
+ public bool DontCompressRestorePaths
+ {
+ get { return Library.Utility.Utility.ParseBoolOption(m_options, "dont-compress-restore-paths"); }
+ }
+
+ /// <summary>
/// Gets a flag indicating if block hashes are checked before being applied
/// </summary>
/// <value><c>true</c> if block hashes are checked; otherwise, <c>false</c>.</value>
@@ -1774,6 +1755,14 @@ namespace Duplicati.Library.Main
}
/// <summary>
+ /// Gets a flag indicating whether the VACUUM operation should ever be run automatically.
+ /// </summary>
+ public bool AutoVacuum
+ {
+ get { return GetBool("auto-vacuum"); }
+ }
+
+ /// <summary>
/// Gets the threshold for when log data should be cleaned
/// </summary>
public DateTime LogRetention
diff --git a/Duplicati/Library/Main/ProgressClasses.cs b/Duplicati/Library/Main/ProgressClasses.cs
index 00886ae34..15cd8fb01 100644
--- a/Duplicati/Library/Main/ProgressClasses.cs
+++ b/Duplicati/Library/Main/ProgressClasses.cs
@@ -16,6 +16,7 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
+using System.Linq;
namespace Duplicati.Library.Main
{
@@ -44,6 +45,101 @@ namespace Duplicati.Library.Main
/// <value>The operation progress update object</value>
IOperationProgress OperationProgress { set; }
}
+
+ /// <summary>
+ /// Helper class to allow setting multiple message sinks on a single controller
+ /// </summary>
+ public class MultiMessageSink : IMessageSink
+ {
+ /// <summary>
+ /// The sinks in this instance
+ /// </summary>
+ private IMessageSink[] m_sinks;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:Duplicati.Library.Main.MultiMessageSink"/> class.
+ /// </summary>
+ /// <param name="sinks">The sinks to use.</param>
+ public MultiMessageSink(params IMessageSink[] sinks)
+ {
+ m_sinks = (sinks ?? new IMessageSink[0]).Where(x => x != null).ToArray();
+ }
+
+ /// <summary>
+ /// Appends a new sink to the list
+ /// </summary>
+ /// <param name="sink">The sink to append.</param>
+ public void Append(IMessageSink sink)
+ {
+ if (sink == null)
+ return;
+
+ var na = new IMessageSink[m_sinks.Length + 1];
+ Array.Copy(m_sinks, na, m_sinks.Length);
+ na[na.Length - 1] = sink;
+ m_sinks = na;
+ }
+
+ public IBackendProgress BackendProgress
+ {
+ set
+ {
+ foreach (var s in m_sinks)
+ s.BackendProgress = value;
+ }
+ }
+
+ public IOperationProgress OperationProgress
+ {
+ set
+ {
+ foreach (var s in m_sinks)
+ s.OperationProgress = value;
+ }
+ }
+
+ public void BackendEvent(BackendActionType action, BackendEventType type, string path, long size)
+ {
+ foreach (var s in m_sinks)
+ s.BackendEvent(action, type, path, size);
+ }
+
+ public void DryrunEvent(string message)
+ {
+ foreach (var s in m_sinks)
+ s.DryrunEvent(message);
+ }
+
+ public void ErrorEvent(string message, Exception ex)
+ {
+ foreach (var s in m_sinks)
+ s.ErrorEvent(message, ex);
+ }
+
+ public void MessageEvent(string message)
+ {
+ foreach (var s in m_sinks)
+ s.MessageEvent(message);
+ }
+
+ public void RetryEvent(string message, Exception ex)
+ {
+ foreach (var s in m_sinks)
+ s.RetryEvent(message, ex);
+ }
+
+ public void VerboseEvent(string message, object[] args)
+ {
+ foreach (var s in m_sinks)
+ s.VerboseEvent(message, args);
+ }
+
+ public void WarningEvent(string message, Exception ex)
+ {
+ foreach (var s in m_sinks)
+ s.WarningEvent(message, ex);
+ }
+ }
/// <summary>
/// Backend progress update object.
@@ -62,7 +158,8 @@ namespace Duplicati.Library.Main
/// <param name="size">The current size</param>
/// <param name="progress">The current number of transferred bytes</param>
/// <param name="bytes_pr_second">Transfer speed in bytes pr second, -1 for unknown</param>
- void Update(out BackendActionType action, out string path, out long size, out long progress, out long bytes_pr_second);
+ /// <param name="isBlocking">A value indicating if the backend is blocking operation progress</param>
+ void Update(out BackendActionType action, out string path, out long size, out long progress, out long bytes_pr_second, out bool isBlocking);
}
/// <summary>
@@ -82,6 +179,11 @@ namespace Duplicati.Library.Main
/// </summary>
/// <param name="progress">he current number of transferred bytes</param>
void UpdateProgress(long progress);
+ /// <summary>
+ /// Sets a flag indicating if the backend operation is blocking progress
+ /// </summary>
+ /// <param name="isBlocking">If set to <c>true</c> the backend is blocking.</param>
+ void SetBlocking(bool isBlocking);
}
/// <summary>
@@ -120,6 +222,10 @@ namespace Duplicati.Library.Main
/// The time the last action started
/// </summary>
private DateTime m_actionStart;
+ /// <summary>
+ /// A value indicating when the last blocking was done
+ /// </summary>
+ private DateTime m_blockingSince;
/// <summary>
/// Register the start of a new action
@@ -157,7 +263,8 @@ namespace Duplicati.Library.Main
/// <param name="size">The current size</param>
/// <param name="progress">The current number of transferred bytes</param>
/// <param name="bytes_pr_second">Transfer speed in bytes pr second, -1 for unknown</param>
- public void Update(out BackendActionType action, out string path, out long size, out long progress, out long bytes_pr_second)
+ /// <param name="isBlocking">A value indicating if the backend is blocking operation progress</param>
+ public void Update(out BackendActionType action, out string path, out long size, out long progress, out long bytes_pr_second, out bool isBlocking)
{
lock(m_lock)
{
@@ -165,7 +272,8 @@ namespace Duplicati.Library.Main
path = m_path;
size = m_size;
progress = m_progress;
-
+ isBlocking = m_blockingSince.Ticks > 0 && (DateTime.Now - m_blockingSince).TotalSeconds > 1;
+
//TODO: The speed should be more dynamic,
// so we need a sample window instead of always
// calculating from the beginning
@@ -174,8 +282,17 @@ namespace Duplicati.Library.Main
else
bytes_pr_second = (long)(m_progress / (DateTime.Now - m_actionStart).TotalSeconds);
}
+ }
+
+ /// <summary>
+ /// Sets a flag indicating if the backend operation is blocking progress
+ /// </summary>
+ /// <param name="isBlocking">If set to <c>true</c> the backend is blocking.</param>
+ public void SetBlocking(bool isBlocking)
+ {
+ lock (m_lock)
+ m_blockingSince = isBlocking ? DateTime.Now : new DateTime(0);
}
-
}
public delegate void PhaseChangedDelegate(OperationPhase phase, OperationPhase previousPhase);
diff --git a/Duplicati/Library/Main/ResultClasses.cs b/Duplicati/Library/Main/ResultClasses.cs
index f5b4df91b..97d7eed70 100644
--- a/Duplicati/Library/Main/ResultClasses.cs
+++ b/Duplicati/Library/Main/ResultClasses.cs
@@ -19,6 +19,8 @@ using System;
using Duplicati.Library.Interface;
using System.Collections.Generic;
using Duplicati.Library.Main.Database;
+using Duplicati.Library.Logging;
+using System.Linq;
namespace Duplicati.Library.Main
{
@@ -30,6 +32,7 @@ namespace Duplicati.Library.Main
void AddWarning(string message, Exception ex);
void AddError(string message, Exception ex);
void AddDryrunMessage(string message);
+ void WriteLogMessageDirect(string message, LogMessageType type, Exception ex);
}
internal interface IBackendWriter : ILogWriter
@@ -67,7 +70,7 @@ namespace Duplicati.Library.Main
bool VerboseOutput { set; }
bool VerboseErrors { set; }
- DateTime EndTime { set; }
+ DateTime EndTime { get; set; }
DateTime BeginTime { set; }
void SetDatabase(LocalDatabase db);
@@ -180,7 +183,7 @@ namespace Duplicati.Library.Main
Abort
}
- internal abstract class BasicResults : IBasicResults, ILogWriter, ISetCommonOptions, ITaskControl
+ internal abstract class BasicResults : IBasicResults, ILogWriter, ISetCommonOptions, ITaskControl, Logging.ILog
{
protected class DbMessage
{
@@ -242,10 +245,23 @@ namespace Duplicati.Library.Main
m_verboseErrors = value;
}
}
-
+
+ public virtual ParsedResultType ParsedResult
+ {
+ get
+ {
+ if (Errors != null && Errors.Any())
+ return ParsedResultType.Error;
+ else if (Warnings != null && Warnings.Any())
+ return ParsedResultType.Warning;
+ else
+ return ParsedResultType.Success;
+ }
+ }
+
public DateTime EndTime { get; set; }
public DateTime BeginTime { get; set; }
- public TimeSpan Duration { get { return EndTime - BeginTime; } }
+ public TimeSpan Duration { get { return EndTime.Ticks == 0 ? new TimeSpan(0) : EndTime - BeginTime; } }
public abstract OperationMode MainOperation { get; }
@@ -339,7 +355,9 @@ namespace Duplicati.Library.Main
m_db.LogMessage("Message", message, ex, null);
}
}
-
+
+ private static bool m_is_reporting = false;
+
public void AddBackendEvent(BackendActionType action, BackendEventType type, string path, long size)
{
if (m_parent != null)
@@ -348,13 +366,27 @@ namespace Duplicati.Library.Main
}
else
{
- if (type == BackendEventType.Started)
- this.BackendProgressUpdater.StartAction(action, path, size);
+ lock(Logging.Log.Lock)
+ {
+ if (m_is_reporting)
+ return;
+
+ try
+ {
+ m_is_reporting = true;
+ if (type == BackendEventType.Started)
+ this.BackendProgressUpdater.StartAction(action, path, size);
- Logging.Log.WriteMessage(string.Format("Backend event: {0} - {1}: {2} ({3})", action, type, path, size <= 0 ? "" : Library.Utility.Utility.FormatSizeString(size)), Duplicati.Library.Logging.LogMessageType.Information);
+ Logging.Log.WriteMessage(string.Format("Backend event: {0} - {1}: {2} ({3})", action, type, path, size <= 0 ? "" : Library.Utility.Utility.FormatSizeString(size)), Duplicati.Library.Logging.LogMessageType.Information, null);
- if (MessageSink != null)
- MessageSink.BackendEvent(action, type, path, size);
+ if (MessageSink != null)
+ MessageSink.BackendEvent(action, type, path, size);
+ }
+ finally
+ {
+ m_is_reporting = false;
+ }
+ }
}
}
@@ -365,62 +397,117 @@ namespace Duplicati.Library.Main
m_parent.AddDryrunMessage(message);
else
{
- Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Information);
- if (MessageSink != null)
- MessageSink.DryrunEvent(message);
+ lock(Logging.Log.Lock)
+ {
+ if (m_is_reporting)
+ return;
+
+ try
+ {
+ m_is_reporting = true;
+ Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Information, null);
+ if (MessageSink != null)
+ MessageSink.DryrunEvent(message);
+ }
+ finally
+ {
+ m_is_reporting = false;
+ }
+ }
}
}
-
+
public void AddVerboseMessage(string message, params object[] args)
{
if (m_parent != null)
m_parent.AddVerboseMessage(message, args);
else
{
- if (Logging.Log.LogLevel == Duplicati.Library.Logging.LogMessageType.Profiling || VerboseOutput)
- Logging.Log.WriteMessage(string.Format(message, args), Duplicati.Library.Logging.LogMessageType.Information);
-
- if (MessageSink != null)
- MessageSink.VerboseEvent(message, args);
+ lock(Logging.Log.Lock)
+ {
+ if (m_is_reporting)
+ return;
+
+ try
+ {
+ m_is_reporting = true;
+ Logging.Log.WriteMessage(string.Format(message, args), Duplicati.Library.Logging.LogMessageType.Profiling, null);
+
+ if (MessageSink != null)
+ MessageSink.VerboseEvent(message, args);
+ }
+ finally
+ {
+ m_is_reporting = false;
+ }
+ }
}
}
-
+
public void AddMessage(string message)
{
if (m_parent != null)
m_parent.AddMessage(message);
else
{
- lock(m_lock)
+ lock(Logging.Log.Lock)
{
- Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Information);
- m_messages.Add(message);
-
- if (MessageSink != null)
- MessageSink.MessageEvent(message);
-
- if (m_db != null && !m_db.IsDisposed)
- LogDbMessage("Message", message, null);
+ if (m_is_reporting)
+ return;
+
+ try
+ {
+ m_is_reporting = true;
+ Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Information, null);
+
+ m_messages.Add(message);
+
+ if (MessageSink != null)
+ MessageSink.MessageEvent(message);
+
+ lock(m_lock)
+ if (m_db != null && !m_db.IsDisposed)
+ LogDbMessage("Message", message, null);
+ }
+ finally
+ {
+ m_is_reporting = false;
+ }
}
}
}
-
+
public void AddWarning(string message, Exception ex)
{
if (m_parent != null)
m_parent.AddWarning(message, ex);
else
{
- Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Warning, ex);
-
- var s = ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message);
- m_warnings.Add(s);
-
- if (MessageSink != null)
- MessageSink.WarningEvent(message, ex);
-
- if (m_db != null && !m_db.IsDisposed)
- LogDbMessage("Warning", message, ex);
+ lock(Logging.Log.Lock)
+ {
+ if (m_is_reporting)
+ return;
+
+ try
+ {
+ m_is_reporting = true;
+ Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Warning, ex);
+
+ var s = ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message);
+ m_warnings.Add(s);
+
+ if (MessageSink != null)
+ MessageSink.WarningEvent(message, ex);
+
+ lock(m_lock)
+ if (m_db != null && !m_db.IsDisposed)
+ LogDbMessage("Warning", message, ex);
+ }
+ finally
+ {
+ m_is_reporting = false;
+ }
+ }
}
}
@@ -430,35 +517,65 @@ namespace Duplicati.Library.Main
m_parent.AddRetryAttempt(message, ex);
else
{
- Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Warning, ex);
-
- var s = ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message);
- m_retryAttempts.Add(s);
+ lock(Logging.Log.Lock)
+ {
+ if (m_is_reporting)
+ return;
- if (MessageSink != null)
- MessageSink.RetryEvent(message, ex);
-
- if (m_db != null && !m_db.IsDisposed)
- LogDbMessage("Retry", message, ex);
+ try
+ {
+ m_is_reporting = true;
+ Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Warning, ex);
+
+ var s = ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message);
+ m_retryAttempts.Add(s);
+
+ if (MessageSink != null)
+ MessageSink.RetryEvent(message, ex);
+
+ lock(m_lock)
+ if (m_db != null && !m_db.IsDisposed)
+ LogDbMessage("Retry", message, ex);
+ }
+ finally
+ {
+ m_is_reporting = false;
+ }
+ }
}
}
-
+
public void AddError(string message, Exception ex)
{
if (m_parent != null)
m_parent.AddError(message, ex);
else
{
- Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Error, ex);
-
- var s = ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message);
- m_errors.Add(s);
-
- if (MessageSink != null)
- MessageSink.ErrorEvent(message, ex);
+ lock(Logging.Log.Lock)
+ {
+ if (m_is_reporting)
+ return;
- if (m_db != null && !m_db.IsDisposed)
- LogDbMessage("Error", message, ex);
+ try
+ {
+ m_is_reporting = true;
+ Logging.Log.WriteMessage(message, Duplicati.Library.Logging.LogMessageType.Error, ex);
+
+ var s = ex == null ? message : string.Format("{0} => {1}", message, VerboseErrors ? ex.ToString() : ex.Message);
+ m_errors.Add(s);
+
+ if (MessageSink != null)
+ MessageSink.ErrorEvent(message, ex);
+
+ lock(m_lock)
+ if (m_db != null && !m_db.IsDisposed)
+ LogDbMessage("Error", message, ex);
+ }
+ finally
+ {
+ m_is_reporting = false;
+ }
+ }
}
}
@@ -508,15 +625,20 @@ namespace Duplicati.Library.Main
/// </summary>
public void Pause()
{
- lock(m_lock)
- if (m_controlState == TaskControlState.Run)
- {
- m_pauseEvent.Reset();
- m_controlState = TaskControlState.Pause;
- }
-
- if (StateChangedEvent != null)
- StateChangedEvent(m_controlState);
+ if (m_parent != null)
+ m_parent.Pause();
+ else
+ {
+ lock (m_lock)
+ if (m_controlState == TaskControlState.Run)
+ {
+ m_pauseEvent.Reset();
+ m_controlState = TaskControlState.Pause;
+ }
+
+ if (StateChangedEvent != null)
+ StateChangedEvent(m_controlState);
+ }
}
/// <summary>
@@ -524,15 +646,20 @@ namespace Duplicati.Library.Main
/// </summary>
public void Resume()
{
- lock(m_lock)
- if (m_controlState == TaskControlState.Pause)
- {
- m_pauseEvent.Set();
- m_controlState = TaskControlState.Run;
- }
-
- if (StateChangedEvent != null)
- StateChangedEvent(m_controlState);
+ if (m_parent != null)
+ m_parent.Resume();
+ else
+ {
+ lock (m_lock)
+ if (m_controlState == TaskControlState.Pause)
+ {
+ m_pauseEvent.Set();
+ m_controlState = TaskControlState.Run;
+ }
+
+ if (StateChangedEvent != null)
+ StateChangedEvent(m_controlState);
+ }
}
/// <summary>
@@ -540,15 +667,20 @@ namespace Duplicati.Library.Main
/// </summary>
public void Stop()
{
- lock(m_lock)
- if (m_controlState != TaskControlState.Abort)
- {
- m_controlState = TaskControlState.Stop;
- m_pauseEvent.Set();
- }
-
- if (StateChangedEvent != null)
- StateChangedEvent(m_controlState);
+ if (m_parent != null)
+ m_parent.Stop();
+ else
+ {
+ lock (m_lock)
+ if (m_controlState != TaskControlState.Abort)
+ {
+ m_controlState = TaskControlState.Stop;
+ m_pauseEvent.Set();
+ }
+
+ if (StateChangedEvent != null)
+ StateChangedEvent(m_controlState);
+ }
}
/// <summary>
@@ -556,14 +688,19 @@ namespace Duplicati.Library.Main
/// </summary>
public void Abort()
{
- lock(m_lock)
+ if (m_parent != null)
+ m_parent.Abort();
+ else
{
- m_controlState = TaskControlState.Abort;
- m_pauseEvent.Set();
+ lock (m_lock)
+ {
+ m_controlState = TaskControlState.Abort;
+ m_pauseEvent.Set();
+ }
+
+ if (StateChangedEvent != null)
+ StateChangedEvent(m_controlState);
}
-
- if (StateChangedEvent != null)
- StateChangedEvent(m_controlState);
}
/// <summary>
@@ -571,16 +708,37 @@ namespace Duplicati.Library.Main
/// </summary>
public TaskControlState TaskControlRendevouz()
{
- // If we are paused, go into pause mode
- m_pauseEvent.WaitOne();
-
- // If we are aborted, throw exception
- if (m_controlState == TaskControlState.Abort)
- System.Threading.Thread.CurrentThread.Abort();
-
- return m_controlState;
+ if (m_parent != null)
+ return m_parent.TaskControlRendevouz();
+ else
+ {
+ // If we are paused, go into pause mode
+ m_pauseEvent.WaitOne();
+
+ // If we are aborted, throw exception
+ if (m_controlState == TaskControlState.Abort)
+ {
+ System.Threading.Thread.CurrentThread.Abort();
+
+ // For some reason, aborting the current thread does not always throw an exception
+ throw new CancelException();
+ }
+
+ return m_controlState;
+ }
}
-
+
+ /// <summary>
+ /// Helper method to check if abort is requested
+ /// </summary>
+ public bool IsAbortRequested()
+ {
+ if (m_parent != null)
+ return m_parent.IsAbortRequested();
+ else
+ return m_controlState == TaskControlState.Abort;
+ }
+
/// <summary>
/// Returns a <see cref="System.String"/> that represents the current <see cref="Duplicati.Library.Main.BasicResults"/>.
/// </summary>
@@ -589,15 +747,69 @@ namespace Duplicati.Library.Main
{
return Library.Utility.Utility.PrintSerializeObject(
this,
- filter: x =>
- !typeof(IBackendProgressUpdater).IsAssignableFrom(x.PropertyType) &&
- !typeof(IMessageSink).IsAssignableFrom(x.PropertyType) &&
- !typeof(ILogWriter).IsAssignableFrom(x.PropertyType),
+ filter: (prop, item) =>
+ !typeof(IBackendProgressUpdater).IsAssignableFrom(prop.PropertyType) &&
+ !typeof(IMessageSink).IsAssignableFrom(prop.PropertyType) &&
+ !typeof(ILogWriter).IsAssignableFrom(prop.PropertyType) &&
+ prop.Name != "VerboseOutput" &&
+ prop.Name != "VerboseErrors" &&
+ !(prop.Name == "MainOperation" && item is BackendWriter) &&
+ !(prop.Name == "EndTime" && item is BackendWriter) &&
+ !(prop.Name == "Duration" && item is BackendWriter) &&
+ !(prop.Name == "BeginTime" && item is BackendWriter),
recurseobjects: true
).ToString();
}
+
+ public void WriteMessage(string message, LogMessageType type, Exception exception)
+ {
+ switch (type)
+ {
+ case LogMessageType.Error:
+ AddError(message, exception);
+ break;
+ case LogMessageType.Warning:
+ AddWarning(message, exception);
+ break;
+ case LogMessageType.Profiling:
+ if (Log.LogLevel == LogMessageType.Profiling && VerboseOutput)
+ AddVerboseMessage(message, new object[0]);
+ break;
+ default:
+ AddMessage(message);
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Writes a message to the log, bypassing injection as normal messages
+ /// </summary>
+ /// <param name="message">The message to write to the log.</param>
+ /// <param name="type">Type.</param>
+ /// <param name="exception">Exception.</param>
+ public void WriteLogMessageDirect(string message, LogMessageType type, Exception exception)
+ {
+ if (m_parent != null)
+ m_parent.WriteLogMessageDirect(message, type, exception);
+ else
+ {
+ lock (Logging.Log.Lock)
+ {
+ try
+ {
+ m_is_reporting = true;
+ WriteMessage(message, type, exception);
+ }
+ finally
+ {
+ m_is_reporting = false;
+ }
+ }
+ }
+ }
+
}
-
+
internal class BackupResults : BasicResults, IBackupResults
{
public long DeletedFiles { get; internal set; }
@@ -620,13 +832,26 @@ namespace Duplicati.Library.Main
public long DeletedSymlinks { get; internal set; }
public bool PartialBackup { get; internal set; }
public bool Dryrun { get; internal set; }
-
+
public override OperationMode MainOperation { get { return OperationMode.Backup; } }
-
+
public ICompactResults CompactResults { get; internal set; }
public IDeleteResults DeleteResults { get; internal set; }
- public IRepairResults RepairResults { get; internal set; }
- public ITestResults TestResults { get; internal set; }
+ public IRepairResults RepairResults { get; internal set; }
+ public ITestResults TestResults { get; internal set; }
+
+ public override ParsedResultType ParsedResult
+ {
+ get
+ {
+ if ((Errors != null && Errors.Any()) || FilesWithError > 0)
+ return ParsedResultType.Error;
+ else if ((Warnings != null && Warnings.Any()) || PartialBackup)
+ return ParsedResultType.Warning;
+ else
+ return ParsedResultType.Success;
+ }
+ }
}
internal class RestoreResults : BasicResults, Library.Interface.IRestoreResults
@@ -643,6 +868,19 @@ namespace Duplicati.Library.Main
public override OperationMode MainOperation { get { return OperationMode.Restore; } }
public IRecreateDatabaseResults RecreateDatabaseResults { get; internal set; }
+
+ public override ParsedResultType ParsedResult
+ {
+ get
+ {
+ if (Errors != null && Errors.Any())
+ return ParsedResultType.Error;
+ else if ((Warnings != null && Warnings.Any()) || FilesRestored == 0)
+ return ParsedResultType.Warning;
+ else
+ return ParsedResultType.Success;
+ }
+ }
}
internal class ListResultFile : Duplicati.Library.Interface.IListResultFile
@@ -719,6 +957,7 @@ namespace Duplicati.Library.Main
public void SetResults(IEnumerable<Tuple<long, DateTime>> deletedSets, bool dryrun)
{
+ EndTime = DateTime.UtcNow;
DeletedSets = deletedSets;
Dryrun = dryrun;
}
@@ -771,6 +1010,14 @@ namespace Duplicati.Library.Main
public void SetResult(IEnumerable<string> files) { this.Files = files; }
}
+ internal class ListRemoteResults : BasicResults, Library.Interface.IListRemoteResults
+ {
+ public IEnumerable<IFileEntry> Files { get; private set; }
+
+ public override OperationMode MainOperation { get { return OperationMode.ListRemote; } }
+ public void SetResult(IEnumerable<IFileEntry> files) { this.Files = files; }
+ }
+
internal class RepairResults : BasicResults, Library.Interface.IRepairResults
{
public override OperationMode MainOperation { get { return OperationMode.Repair; } }
@@ -867,13 +1114,13 @@ namespace Duplicati.Library.Main
public TestResults(BasicResults p) : base(p) { }
public override OperationMode MainOperation { get { return OperationMode.Test; } }
- public IEnumerable<KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>> Changes { get { return m_changes; } }
- private List<KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>> m_changes = new List<KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>>();
+ public IEnumerable<KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>> Verifications { get { return m_verifications; } }
+ private List<KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>> m_verifications = new List<KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>>();
public KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>> AddResult(string volume, IEnumerable<KeyValuePair<TestEntryStatus, string>> changes)
{
var res = new KeyValuePair<string, IEnumerable<KeyValuePair<TestEntryStatus, string>>>(volume, changes);
- m_changes.Add(res);
+ m_verifications.Add(res);
return res;
}
}
@@ -892,5 +1139,41 @@ namespace Duplicati.Library.Main
public IEnumerable<string> Lines { get; set; }
}
+ internal class PurgeFilesResults : BasicResults, IPurgeFilesResults
+ {
+ public PurgeFilesResults() : base() { }
+ public PurgeFilesResults(BasicResults p) : base(p) { }
+
+ public override OperationMode MainOperation { get { return OperationMode.PurgeFiles; } }
+ public long RemovedFileCount { get; set; }
+ public long RemovedFileSize { get; set; }
+ public long RewrittenFileLists { get; set; }
+
+ public ICompactResults CompactResults { get; set; }
+ }
+
+ internal class ListBrokenFilesResults : BasicResults, IListBrokenFilesResults
+ {
+ public override OperationMode MainOperation { get { return OperationMode.ListBrokenFiles; } }
+ public IEnumerable<Tuple<long, DateTime, IEnumerable<Tuple<string, long>>>> BrokenFiles { get; set; }
+ }
+
+ internal class PurgeBrokenFilesResults : BasicResults, IPurgeBrokenFilesResults
+ {
+ public override OperationMode MainOperation { get { return OperationMode.PurgeBrokenFiles; } }
+ public IPurgeFilesResults PurgeResults { get; set; }
+ public IDeleteResults DeleteResults { get; set; }
+ }
+
+ internal class SendMailResults : BasicResults, ISendMailResults
+ {
+ public override OperationMode MainOperation { get { return OperationMode.SendMail; } }
+ public IEnumerable<string> Lines { get; set; }
+ }
+
+ internal class VacuumResult : BasicResults, IVacuumResults
+ {
+ public override OperationMode MainOperation { get { return OperationMode.Vacuum; } }
+ }
}
diff --git a/Duplicati/Library/Main/Strings.cs b/Duplicati/Library/Main/Strings.cs
index 2c719cdb3..39b0f27ad 100644
--- a/Duplicati/Library/Main/Strings.cs
+++ b/Duplicati/Library/Main/Strings.cs
@@ -1,3 +1,4 @@
+using System;
using Duplicati.Library.Localization.Short;
namespace Duplicati.Library.Main.Strings
@@ -24,13 +25,15 @@ namespace Duplicati.Library.Main.Strings
public static string FailedOperationMessage(OperationMode operationname, string errormessage) { return LC.L(@"The operation {0} has failed with error: {1}", operationname, errormessage); }
public static string InvalidPathError(string path, string message) { return LC.L(@"Invalid path: ""{0}"" ({1})", path, message); }
public static string FailedForceLocaleError(string exMsg) { return LC.L(@"Failed to apply 'force-locale' setting. Please try to update .NET-Framework. Exception was: ""{0}"" ", exMsg); }
+ public static string SourceVolumeNameInvalidError(string filename) { return LC.L(@"The source {0} uses an invalid volume name, aborting backup", filename); }
+ public static string SourceVolumeNameNotFoundError(string filename, Guid volumeGuid) { return LC.L(@"The source {0} is on volume {1}, which could not be found, aborting backup", filename, volumeGuid); }
}
internal static class Options
{
public static string AutocleanupLong { get { return LC.L(@"If a backup is interrupted there will likely be partial files present on the backend. Using this flag, Duplicati will automatically remove such files when encountered."); } }
public static string AutocleanupShort { get { return LC.L(@"A flag indicating that Duplicati should remove unused files"); } }
- public static string PrefixLong { get { return LC.L(@"A string used to prefix the filenames of the remote volumes, can be used to store multiple backups in the same remote folder."); } }
+ public static string PrefixLong { get { return LC.L(@"A string used to prefix the filenames of the remote volumes, can be used to store multiple backups in the same remote folder. The prefix cannot contain a hyphen (-), but can contain all other characters allowed by the remote storage."); } }
public static string PrefixShort { get { return LC.L(@"Remote filename prefix"); } }
public static string DisablefiletimecheckLong { get { return LC.L(@"The operating system keeps track of the last time a file was written. Using this information, Duplicati can quickly determine if the file has been modified. If some application deliberately modifies this information, Duplicati won't work correctly unless this flag is set."); } }
public static string DisablefiletimecheckShort { get { return LC.L(@"Disable checks based on file time"); } }
@@ -58,7 +61,7 @@ namespace Duplicati.Library.Main.Strings
public static string ListprefixonlyShort { get { return LC.L(@"Show largest prefix"); } }
public static string ListfoldercontentsLong { get { return LC.L(@"When searching for files, all matching files are returned. Use this option to return only the entries found in the folder specified as filter."); } }
public static string ListfoldercontentsShort { get { return LC.L(@"Show folder contents"); } }
- public static string RetrydelayLong { get { return LC.L(@"After a failed transmission, Duplicati will wait a short period before attempting again. This is usefull if the network drops out occasionally during transmissions."); } }
+ public static string RetrydelayLong { get { return LC.L(@"After a failed transmission, Duplicati will wait a short period before attempting again. This is useful if the network drops out occasionally during transmissions."); } }
public static string RetrydelayShort { get { return LC.L(@"Time to wait between retries"); } }
public static string ControlfilesLong { get { return LC.L(@"Use this option to attach extra files to the newly uploaded filelists."); } }
public static string ControlfilesShort { get { return LC.L(@"Set control files"); } }
@@ -76,15 +79,15 @@ namespace Duplicati.Library.Main.Strings
public static string DisableStreamingShort { get { return LC.L(@"Disables use of the streaming transfer method"); } }
public static string DontreadmanifestsLong { get { return LC.L(@"This option will make sure the contents of the manifest file are not read. This also implies that file hashes are not checked either. Use only for disaster recovery."); } }
public static string DontreadmanifestsShort { get { return LC.L(@"An option that prevents verifying the manifests"); } }
- public static string CompressionmoduleLong { get { return LC.L(@"Duplicati supports plugable compression modules. Use this option to select a module to use for compression. This is only applied when creating new volumes, when reading an existing file, the filename is used to select the compression module."); } }
+ public static string CompressionmoduleLong { get { return LC.L(@"Duplicati supports pluggable compression modules. Use this option to select a module to use for compression. This is only applied when creating new volumes, when reading an existing file, the filename is used to select the compression module."); } }
public static string CompressionmoduleShort { get { return LC.L(@"Select what module to use for compression"); } }
- public static string EncryptionmoduleLong { get { return LC.L(@"Duplicati supports plugable encryption modules. Use this option to select a module to use for encryption. This is only applied when creating new volumes, when reading an existing file, the filename is used to select the encryption module."); } }
+ public static string EncryptionmoduleLong { get { return LC.L(@"Duplicati supports pluggable encryption modules. Use this option to select a module to use for encryption. This is only applied when creating new volumes, when reading an existing file, the filename is used to select the encryption module."); } }
public static string EncryptionmoduleShort { get { return LC.L(@"Select what module to use for encryption"); } }
public static string DisablemoduleLong { get { return LC.L(@"Supply one or more module names, separated by commas to unload them"); } }
public static string DisablemoduleShort { get { return LC.L(@"Disabled one or more modules"); } }
public static string EnablemoduleLong { get { return LC.L(@"Supply one or more module names, separated by commas to load them"); } }
public static string EnablemoduleShort { get { return LC.L(@"Enables one or more modules"); } }
- public static string SnapshotpolicyLong { get { return LC.L(@"This settings controls the usage of snapshots, which allows Duplicati to backup files that are locked by other programs. If this is set to ""off"", Duplicati will not attempt to create a disk snapshot. Setting this to ""auto"" makes Duplicati attempt to create a snapshot, and fail silently if that was not allowed or supported. A setting of ""on"" will also make Duplicati attempt to create a snapshot, but will produce a warning message in the log if it fails. Setting it to ""required"" will make Duplicati abort the backup if the snapshot creation fails. On windows this uses the Volume Shadow Copy Services (VSS) and requires administrative privileges. On linux this uses Logical Volume Management (LVM) and requires root privileges."); } }
+ public static string SnapshotpolicyLong { get { return LC.L(@"This setting controls the usage of snapshots, which allows Duplicati to backup files that are locked by other programs. If this is set to ""off"", Duplicati will not attempt to create a disk snapshot. Setting this to ""auto"" makes Duplicati attempt to create a snapshot, and fail silently if that was not allowed or supported. A setting of ""on"" will also make Duplicati attempt to create a snapshot, but will produce a warning message in the log if it fails. Setting it to ""required"" will make Duplicati abort the backup if the snapshot creation fails. On windows this uses the Volume Shadow Copy Services (VSS) and requires administrative privileges. On Linux this uses Logical Volume Management (LVM) and requires root privileges."); } }
public static string SnapshotpolicyShort { get { return LC.L(@"Controls the use of disk snapshots"); } }
public static string AsynchronousuploadfolderLong { get { return LC.L(@"The pre-generated volumes will be placed into the temporary folder by default, this option can set a different folder for placing the temporary volumes, despite the name, this also works for synchronous runs"); } }
public static string AsynchronousuploadfolderShort { get { return LC.L(@"The path where ready volumes are placed until uploaded"); } }
@@ -99,11 +102,11 @@ namespace Duplicati.Library.Main.Strings
public static string DisableautocreatefolderShort { get { return LC.L(@"Disables automatic folder creation"); } }
public static string VssexcludewritersLong { get { return LC.L(@"Use this option to exclude faulty writers from a snapshot. This is equivalent to the -wx flag of the vshadow.exe tool, except that it only accepts writer class GUIDs, and not component names or instance GUIDs. Multiple GUIDs must be separated with a semicolon, and most forms of GUIDs are allowed, including with and without curly braces."); } }
public static string VssexcludewritersShort { get { return LC.L(@"A semicolon separated list of guids of VSS writers to exclude (Windows only)"); } }
- public static string UsnpolicyLong { get { return LC.L(@"This settings controls the usage of NTFS USN numbers, which allows Duplicati to obtain a list of files and folders much faster. If this is set to ""off"", Duplicati will not attempt to use USN. Setting this to ""auto"" makes Duplicati attempt to use USN, and fail silently if that was not allowed or supported. A setting of ""on"" will also make Duplicati attempt to use USN, but will produce a warning message in the log if it fails. Setting it to ""required"" will make Duplicati abort the backup if the USN usage fails. This feature is only supported on Windows and requires administrative privileges."); } }
+ public static string UsnpolicyLong { get { return LC.L(@"This setting controls the usage of NTFS USN numbers, which allows Duplicati to obtain a list of files and folders much faster. If this is set to ""off"", Duplicati will not attempt to use USN. Setting this to ""auto"" makes Duplicati attempt to use USN, and fail silently if that was not allowed or supported. A setting of ""on"" will also make Duplicati attempt to use USN, but will produce a warning message in the log if it fails. Setting it to ""required"" will make Duplicati abort the backup if the USN usage fails. This feature is only supported on Windows and requires administrative privileges."); } }
public static string UsnpolicyShort { get { return LC.L(@"Controls the use of NTFS Update Sequence Numbers"); } }
public static string DisableusndiffcheckLong { get { return LC.L(@"If USN is enabled the USN numbers are used to find all changed files since last backup. Use this option to disable the use of USN numbers, which will make Duplicati investigate all source files. This option is primarily intended for testing and should not be disabled in a production environment. If USN is not enabled, this option has no effect."); } }
public static string DisableusndiffcheckShort { get { return LC.L(@"Disables changelist by USN numbers"); } }
- public static string DisabletimetoleranceLong { get { return LC.L(@"When deciding if a full backup should be made or an old backup should be deleted, Duplicati will adjust the times by a small fraction to ensure that minor time differences do not interfer with expected operation. If the backup is set to produce a full backup each day, and a full backup is made at, say 12:00:01, and the backup is executed again at 12:00:00, a full day has not passed and thus an incremental backup is performed. To avoid this, Duplicati inserts a 1% tolerance (max 1 hour). Use this option to disable the tolerance, and use strict time checking"); } }
+ public static string DisabletimetoleranceLong { get { return LC.L(@"When matching timestamps, Duplicati will adjust the times by a small fraction to ensure that minor time differences do not cause unexpected updates. If the option --{0} is set to keep a week of backups, and the backup is made the same time each week, it is possible that the clock drifts slightly, such that full week has just passed, causing Duplicati to delete the older backup earlier than expected. To avoid this, Duplicati inserts a 1% tolerance (max 1 hour). Use this option to disable the tolerance, and use strict time checking", "--keep-time"); } }
public static string DisabletimetoleranceShort { get { return LC.L(@"Deactivates tolerance when comparing times"); } }
public static string ListverifyuploadsShort { get { return LC.L(@"Verify uploads by listing contents"); } }
public static string SynchronousuploadLong { get { return LC.L(@"Duplicati will upload files while scanning the disk and producing volumes, which usually makes the backup faster. Use this flag to turn the behavior off, so that Duplicati will wait for each volume to complete."); } }
@@ -116,12 +119,14 @@ namespace Duplicati.Library.Main.Strings
public static string UploadUnchangedBackupsShort { get { return LC.L(@"Upload empty backup files"); } }
public static string QuotasizeLong { get { return LC.L(@"This value can be used to set a known upper limit on the amount of space a backend has. If the backend reports the size itself, this value is ignored"); } }
public static string QuotasizeShort { get { return LC.L(@"A reported maximum storage"); } }
+ public static string DefaultFiltersLong(string windows, string osx, string linux, string all) { return LC.L(@"Exclude files that match the given filter sets. Which default filter sets should be used. Valid sets are ""{0}"", ""{1}"", ""{2}"", and ""{3}"". If this parameter is set with no value, the set for the current operating system will be used.", windows, osx, linux, all); }
+ public static string DefaultFiltersShort { get { return LC.L(@"Default filter sets"); } }
public static string SymlinkpolicyShort { get { return LC.L(@"Symlink handling"); } }
- public static string SymlinkpolicyLong(string store, string ignore, string follow) { return LC.L(@"Using this option to handle symlinks different. The ""{0}"" option will simply record a symlink with its name and destination, and a restore will recreate the symlink as a link. Use the option ""{1}"" to ignore all symlinks and not store any information about them. Previous versions of Duplicati used the setting ""{2}"", which will cause symlinked files to be included and restore as normal files.", store, ignore, follow); }
+ public static string SymlinkpolicyLong(string store, string ignore, string follow) { return LC.L(@"Use this option to handle symlinks differently. The ""{0}"" option will simply record a symlink with its name and destination, and a restore will recreate the symlink as a link. Use the option ""{1}"" to ignore all symlinks and not store any information about them. Previous versions of Duplicati used the setting ""{2}"", which will cause symlinked files to be included and restore as normal files.", store, ignore, follow); }
public static string HardlinkpolicyShort { get { return LC.L(@"Hardlink handling"); } }
- public static string HardlinkpolicyLong(string first, string all, string none) { return LC.L(@"Using this option to handle hardlinks (only works on Linux/OSX). The ""{0}"" option will record a hardlink ID for each hardlink to avoid storing hardlinked paths multiple times. The option ""{1}"" will ignore hardlink information, and treat each hardlink as a unique path. The option ""{2}"" will ignore all hardlinks with more than one link.", first, all, none); }
+ public static string HardlinkpolicyLong(string first, string all, string none) { return LC.L(@"Use this option to handle hardlinks (only works on Linux/OSX). The ""{0}"" option will record a hardlink ID for each hardlink to avoid storing hardlinked paths multiple times. The option ""{1}"" will ignore hardlink information, and treat each hardlink as a unique path. The option ""{2}"" will ignore all hardlinks with more than one link.", first, all, none); }
public static string ExcludefilesattributesShort { get { return LC.L(@"Exclude files by attribute"); } }
- public static string ExcludefilesattributesLong(string[] attributes) { return LC.L(@"Use this option to exclude files with certain attributes. Use a comma separated list of attribute names to specify more that one. Possible values are: {0}", string.Join(", ", attributes)); }
+ public static string ExcludefilesattributesLong(string[] attributes) { return LC.L(@"Use this option to exclude files with certain attributes. Use a comma separated list of attribute names to specify more than one. Possible values are: {0}", string.Join(", ", attributes)); }
public static string VssusemappingLong { get { return LC.L(@"Activate this option to map VSS snapshots to a drive (similar to SUBST, using Win32 DefineDosDevice). This will create temporary drives that are then used to access the contents of a snapshot. This workaround can speed up file access on Windows XP."); } }
public static string VssusemappingShort { get { return LC.L(@"Map snapshots to a drive (Windows only)"); } }
public static string BackupnameLong { get { return LC.L(@"A display name that is attached to this backup. Can be used to identify the backup when sending mail or running scripts."); } }
@@ -130,8 +135,8 @@ namespace Duplicati.Library.Main.Strings
public static string CompressionextensionfileShort { get { return LC.L(@"Manage non-compressible file extensions"); } }
public static string BlockhashlookupsizeLong { get { return LC.L(@"A fragment of memory is used to reduce database lookups. You should not change this value unless you get warnings in the log."); } }
public static string BlockhashlookupsizeShort { get { return LC.L(@"Memory used by the block hash"); } }
- public static string BlocksizeLong { get { return LC.L(@"The blocksize determines how files are fragmented. Choosing a large value will cause a larger overhead on file changes, choosing a small value will cause a large overhead on storage of file lists. Note that the value cannot be changed after remote files are created."); } }
- public static string BlocksizeShort { get { return LC.L(@"Blocksize used in hashing"); } }
+ public static string BlocksizeLong { get { return LC.L(@"The block size determines how files are fragmented. Choosing a large value will cause a larger overhead on file changes, choosing a small value will cause a large overhead on storage of file lists. Note that the value cannot be changed after remote files are created."); } }
+ public static string BlocksizeShort { get { return LC.L(@"Block size used in hashing"); } }
public static string ChangedfilesLong { get { return LC.L(@"This option can be used to limit the scan to only files that are known to have changed. This is usually only activated in combination with a filesystem watcher that keeps track of file changes."); } }
public static string ChangedfilesShort { get { return LC.L(@"List of files to examine for changes"); } }
public static string DbpathLong { get { return LC.L(@"Path to the file containing the local cache of the remote file database"); } }
@@ -140,9 +145,11 @@ namespace Duplicati.Library.Main.Strings
public static string DeletedfilesShort { get { return LC.L(@"List of deleted files"); } }
public static string FilehashlookupsizeLong { get { return LC.L(@"A fragment of memory is used to reduce database lookups. You should not change this value unless you get warnings in the log."); } }
public static string FilehashlookupsizeShort { get { return LC.L(@"Memory used by the file hash"); } }
- public static string DisablefilepathcacheShort { get { return LC.L(@"This option can be used to reduce the memory footprint by not keeping paths and modification timestamps in memory"); } }
- public static string DisablefilepathcacheLong { get { return LC.L(@"Reduce memory footprint by disabling in-memory lookups"); } }
- public static string StoremetadataLong { get { return LC.L(@"Stores metadata, such as file timestamps and attributes. This increases the required storage space as well as the processing time."); } }
+ public static string DisablefilepathcacheLong { get { return LC.L(@"This option can be used to reduce the memory footprint by not keeping paths and modification timestamps in memory"); } }
+ public static string DisablefilepathcacheShort { get { return LC.L(@"Reduce memory footprint by disabling in-memory lookups"); } }
+ public static string UseblockcacheShort { get { return LC.L(@"This option can be used to increase speed in exchange for extra memory use."); } }
+ public static string UseblockcacheLong { get { return LC.L(@"Store an in-memory block cache"); } }
+ public static string StoremetadataLong { get { return LC.L(@"Stores metadata, such as file timestamps and attributes. This increases the required storage space as well as the processing time."); } }
public static string StoremetadataShort { get { return LC.L(@"Enables storing file metadata"); } }
public static string StoremetadataDeprecated { get { return LC.L(@"This option is no longer used as metadata is now stored by default"); } }
public static string MetadatahashlookupsizeLong { get { return LC.L(@"A fragment of memory is used to reduce database lookups. You should not change this value unless you get warnings in the log."); } }
@@ -160,8 +167,8 @@ namespace Duplicati.Library.Main.Strings
public static string FilehashalgorithmLong { get { return LC.L(@"This is a very advanced option! This option can be used to select a file hash algorithm with smaller or larger hash size, for performance or storage space reasons."); } }
public static string FilehashalgorithmShort { get { return LC.L(@"The hash algorithm used on files"); } }
public static string NoautocompactLong { get { return LC.L(@"If a large number of small files are detected during a backup, or wasted space is found after deleting backups, the remote data will be compacted. Use this option to disable such automatic compacting and only compact when running the compact command."); } }
- public static string NoautocompactShort { get { return LC.L(@"Disable automatic compating"); } }
- public static string SmallfilesizeLong { get { return LC.L(@"When examining the size of a volume in consideration for compating, a small tolerance value is used, by default 20 percent of the volume size. This ensures that large volumes which may have a few bytes wasted space are not downloaded and rewritten."); } }
+ public static string NoautocompactShort { get { return LC.L(@"Disable automatic compacting"); } }
+ public static string SmallfilesizeLong { get { return LC.L(@"When examining the size of a volume in consideration for compacting, a small tolerance value is used, by default 20 percent of the volume size. This ensures that large volumes which may have a few bytes wasted space are not downloaded and rewritten."); } }
public static string SmallfilesizeShort { get { return LC.L(@"Volume size threshold"); } }
public static string SmallfilemaxcountLong { get { return LC.L(@"To avoid filling the remote storage with small files, this value can force grouping small files. The small volumes will always be combined when they can fill an entire volume."); } }
public static string SmallfilemaxcountShort { get { return LC.L(@"Maximum number of small volumes"); } }
@@ -173,18 +180,22 @@ namespace Duplicati.Library.Main.Strings
public static string KeepversionsLong { get { return LC.L(@"Use this option to set number of versions to keep, supply -1 to keep all versions"); } }
public static string KeeptimeShort { get { return LC.L(@"Keep all versions within a timespan"); } }
public static string KeeptimeLong { get { return LC.L(@"Use this option to set the timespan in which backups are kept."); } }
+ public static string RetentionPolicyShort { get { return LC.L(@"Reduce number of versions by deleting old intermediate backups"); } }
+ public static string RetentionPolicyLong { get { return LC.L(@"Use this option to reduce the number of versions that are kept with increasing version age by deleting most of the old backups. The expected format is a comma seperated list of collon sperated time frame and interval pairs. For example the value ""7D:0s,3M:1D,10Y:2M"" means ""For 7 day keep all backups, for 3 months keep one backup per day and for 10 years one backup every 2nd month"); } }
public static string AllowmissingsourceShort { get { return LC.L(@"Ignore missing source elements"); } }
public static string AllowmissingsourceLong { get { return LC.L(@"Use this option to continue even if some source entries are missing."); } }
public static string OverwriteShort { get { return LC.L(@"Overwrite files when restoring"); } }
public static string OverwriteLong { get { return LC.L(@"Use this option to overwrite target files when restoring, if this option is not set the files will be restored with a timestamp and a number appended."); } }
public static string VerboseShort { get { return LC.L(@"Output more progress information"); } }
public static string VerboseLong { get { return LC.L(@"Use this option to increase the amount of output generated when running an option. Generally this option will produce a line for each file processed."); } }
+ public static string FullresultShort { get { return LC.L(@"Output full results"); } }
+ public static string FullresultLong { get { return LC.L(@"Use this option to increase the amount of output generated as the result of the operation, including all filenames."); } }
public static string UploadverificationfileShort { get { return LC.L(@"Determine if verification files are uploaded"); } }
public static string UploadverificationfileLong { get { return LC.L(@"Use this option to upload a verification file after changing the remote storage. The file is not encrypted and contains the size and SHA256 hashes of all the remote files and can be used to verify the integrity of the files."); } }
public static string BackendtestsamplesShort { get { return LC.L(@"The number of samples to test after a backup"); } }
public static string BackendtestsamplesLong(string optionname) { return LC.L(@"After a backup is completed, some files are selected for verification on the remote backend. Use this option to change how many. If this value is set to 0 or the option --{0} is set, no remote files are verified", optionname); }
public static string FullremoteverificationShort { get { return LC.L(@"Activates in-depth verification of files"); } }
- public static string FullremoteverificationLong(string optionname) { return LC.L(@"After a backup is completed, some files are selected for verification on the remote backend. Use this option to turn on full verification, which will decrypt the files and examine the insides of each volume, instead of simply verifying the external hash, If the option --{0} is set, no remote files are verified", optionname); }
+ public static string FullremoteverificationLong(string optionname) { return LC.L(@"After a backup is completed, some files are selected for verification on the remote backend. Use this option to turn on full verification, which will decrypt the files and examine the insides of each volume, instead of simply verifying the external hash, If the option --{0} is set, no remote files are verified. This option is automatically set when then verification is performed directly.", optionname); }
public static string FilereadbuffersizeShort { get { return LC.L(@"Size of the file read buffer"); } }
public static string FilereadbuffersizeLong { get { return LC.L(@"Use this size to control how many bytes a read from a file before processing"); } }
public static string AllowpassphrasechangeShort { get { return LC.L(@"Allow the passphrase to change"); } }
@@ -197,7 +208,7 @@ namespace Duplicati.Library.Main.Strings
public static string RestorepermissionsShort { get { return LC.L(@"Restore file permissions"); } }
public static string RestorepermissionsLong { get { return LC.L(@"By default permissions are not restored as they might prevent you from accessing your files. Use this option to restore the permissions as well."); } }
public static string SkiprestoreverificationShort { get { return LC.L(@"Skip restored file check"); } }
- public static string SkiprestoreverificationLong { get { return LC.L(@"After restoring files, the file hash of all restored files are checked to verify that the restore was successfull. Use this option to disable the check and avoid waiting for the verification."); } }
+ public static string SkiprestoreverificationLong { get { return LC.L(@"After restoring files, the file hash of all restored files are checked to verify that the restore was successful. Use this option to disable the check and avoid waiting for the verification."); } }
public static string OldmemorylookupdefaultsShort { get { return LC.L(@"Activate caches"); } }
public static string OldmemorylookupdefaultsLong { get { return LC.L(@"Activate in-memory caches, which are now off by default"); } }
public static string NolocalblocksShort { get { return LC.L(@"Do not use local data"); } }
@@ -214,6 +225,16 @@ namespace Duplicati.Library.Main.Strings
public static string DisablepipingLong { get { return LC.L(@"Use this option to disable multithreaded handling of up- and downloads, that can significantly speed up backend operations depending on the hardware you're running on and the transfer rate of your backend."); } }
public static string HypervbackupvmShort { get { return LC.L(@"Perform backup of Hyper-V machines (Windows only)"); } }
public static string HypervbackupvmLong { get { return LC.L(@"Use this option to specify the IDs of machines to include in the backup. Specify multiple machine IDs with a semicolon separator. (You can use this Powershell command to get ID 'Get-VM | ft VMName, ID')"); } }
+ public static string DisablesyntehticfilelistLong { get { return LC.L(@"If Duplicati detects that the previous backup did not complete, it will generate a filelist that is a merge of the last completed backup and the contents that were uploaded in the incomplete backup session."); } }
+ public static string DisablesyntheticfilelistShort { get { return LC.L(@"Disables synthetic filelist"); } }
+ public static string CheckfiletimeonlyLong { get { return LC.L(@"This flag instructs Duplicati to not look at metadata or filesize when deciding to scan a file for changes. Use this option if you have a large number of files and notice that the scanning takes a long time with unmodified files."); } }
+ public static string CheckfiletimeonlyShort { get { return LC.L(@"Checks only file lastmodified"); } }
+ public static string DontcompressrestorepathsShort { get { return LC.L(@"Disables path compresion on restore"); } }
+ public static string DontcompressrestorepathsLong { get { return LC.L(@"When restore a subset of a backup into a new folder, the shortest possible path is used to avoid generating deep paths with empty folders. Use this flag to skip this compression, such that the entire original folder structure is preserved, including upper level empty folders."); } }
+ public static string AllowfullremovalShort { get { return LC.L(@"Allow removing all filesets"); } }
+ public static string AllowfullremovalLong { get { return LC.L(@"By default, the last fileset cannot be removed. This is a safeguard to make sure that all remote data is not deleted by a configuration mistake. Use this flag to disable that protection, such that all filesets can be deleted."); } }
+ public static string AutoVacuumShort { get { return LC.L(@"Allow automatic rebuilding of local database to save space."); } }
+ public static string AutoVacuumLong { get { return LC.L(@"Some operations that manipulate the local database leave unused entries behind. These entries are not deleted from a hard drive until a VACUUM operation is run. This operation saves disk space in the long run but needs to temporarily create a copy of all valid entries in the database. Setting this to true will allow Duplicati to perform VACUUM operations at its discretion."); } }
}
internal static class Common
diff --git a/Duplicati/Library/Main/Utility.cs b/Duplicati/Library/Main/Utility.cs
index 663f31196..5fd8584a5 100644
--- a/Duplicati/Library/Main/Utility.cs
+++ b/Duplicati/Library/Main/Utility.cs
@@ -34,7 +34,7 @@ namespace Duplicati.Library.Main
/// <summary>
/// The base64 encoded hash
/// </summary>
- private readonly string m_hash;
+ private readonly string m_filehash;
/// <summary>
/// The UTF-8 encoded json element with the metadata
/// </summary>
@@ -47,30 +47,29 @@ namespace Duplicati.Library.Main
public Metahash(Dictionary<string, string> values, Options options)
{
m_values = values;
- var hasher = System.Security.Cryptography.HashAlgorithm.Create(options.BlockHashAlgorithm);
- if (hasher == null)
- throw new Exception(Strings.Common.InvalidHashAlgorithm(options.BlockHashAlgorithm));
- if (!hasher.CanReuseTransform)
- throw new Exception(Strings.Common.InvalidCryptoSystem(options.BlockHashAlgorithm));
using (var ms = new System.IO.MemoryStream())
using (var w = new StreamWriter(ms, Encoding.UTF8))
+ using(var filehasher = Library.Utility.HashAlgorithmHelper.Create(options.FileHashAlgorithm))
{
+ if (filehasher == null)
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.Common.InvalidHashAlgorithm(options.FileHashAlgorithm));
+
w.Write(JsonConvert.SerializeObject(values));
w.Flush();
m_blob = ms.ToArray();
ms.Position = 0;
- m_hash = Convert.ToBase64String(hasher.ComputeHash(ms));
+ m_filehash = Convert.ToBase64String(filehasher.ComputeHash(ms));
}
}
- public string Hash
+ public string FileHash
{
- get { return m_hash; }
+ get { return m_filehash; }
}
-
+
public long Size
{
get { return m_blob.Length; }
@@ -154,21 +153,21 @@ namespace Duplicati.Library.Main
if (!options.AllowPassphraseChange)
{
if (newDict[k.Key] == "no-encryption")
- throw new Exception("Unsupported removal of passphrase");
+ throw new Duplicati.Library.Interface.UserInformationException("You have attempted to remove the passphrase on an existing backup, which is not supported. Please configure a new clean backup if you want to remove the passphrase.");
else if (opts[k.Key] == "no-encryption")
- throw new Exception("Unsupported addition of passphrase");
+ throw new Duplicati.Library.Interface.UserInformationException("You have attempted to add a passphrase to an existing backup, which is not supported. Please configure a new clean backup if you want to add a passphrase.");
else
- throw new Exception("Unsupported change of passphrase");
+ throw new Duplicati.Library.Interface.UserInformationException("You have attempted to change a passphrase to an existing backup, which is not supported. Please configure a new clean backup if you want to change the passphrase.");
}
}
else
- throw new Exception(string.Format("Unsupported change of parameter \"{0}\" from \"{1}\" to \"{2}\"", k.Key, opts[k.Key], k.Value));
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("You have attempted to change the parameter \"{0}\" from \"{1}\" to \"{2}\", which is not supported. Please configure a new clean backup if you want to change the parameter.", k.Key, opts[k.Key], k.Value));
}
//Extra sanity check
if (db.GetBlocksLargerThan(options.Blocksize) > 0)
- throw new Exception("Unsupported block-size change detected");
+ throw new Duplicati.Library.Interface.UserInformationException("You have attempted to change the block-size on an existing backup, which is not supported. Please configure a new clean backup if you want to change the block-size.");
if (needsUpdate)
{
@@ -197,9 +196,6 @@ namespace Duplicati.Library.Main
try
{
var folder = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), AutoUpdater.AutoUpdateSettings.AppName);
- if (!Directory.Exists(folder))
- Directory.CreateDirectory(folder);
-
return File.Exists(Path.Combine(folder, SUPPRESS_DONATIONS_FILENAME));
}
catch
diff --git a/Duplicati/Library/Main/Volumes/FilesetVolumeReader.cs b/Duplicati/Library/Main/Volumes/FilesetVolumeReader.cs
index 742fa653c..483d35981 100644
--- a/Duplicati/Library/Main/Volumes/FilesetVolumeReader.cs
+++ b/Duplicati/Library/Main/Volumes/FilesetVolumeReader.cs
@@ -97,8 +97,12 @@ namespace Duplicati.Library.Main.Volumes
public long Size { get; private set; }
public DateTime Time { get; private set; }
public string Metahash { get; private set; }
+ public string Metablockhash { get; private set; }
public long Metasize { get; private set; }
+ public string Blockhash { get; private set; }
+ public long Blocksize { get; private set; }
public IEnumerable<string> BlocklistHashes { get; private set; }
+ public IEnumerable<string> MetaBlocklistHashes { get; private set; }
private JsonReader m_reader;
public FileEntry(JsonReader reader)
@@ -150,16 +154,60 @@ namespace Duplicati.Library.Main.Volumes
if (!m_reader.Read())
throw new InvalidDataException(string.Format("Invalid JSON, EOF found while reading entry {0}", this.Path));
+
+ if (m_reader.TokenType == JsonToken.PropertyName && m_reader.Value != null && m_reader.Value.ToString() == "metablocklists")
+ {
+ var metadatablocklisthashes = new List<string>();
+ SkipJsonToken(m_reader, JsonToken.StartArray);
+
+ if (!m_reader.Read())
+ throw new InvalidDataException(string.Format("Invalid JSON, EOF found while reading entry {0}", this.Path));
+
+ while(m_reader.TokenType == JsonToken.String)
+ {
+ metadatablocklisthashes.Add(m_reader.Value.ToString());
+ if (!m_reader.Read())
+ throw new InvalidDataException(string.Format("Invalid JSON, EOF found while reading entry {0}", this.Path));
+ }
+
+ if (m_reader.TokenType != JsonToken.EndArray)
+ throw new InvalidDataException(string.Format("Invalid JSON, unexpected token {1} found while reading entry {0}", this.Path, m_reader.TokenType));
+ if (!m_reader.Read())
+ throw new InvalidDataException(string.Format("Invalid JSON, EOF found while reading entry {0}", this.Path));
+
+ this.MetaBlocklistHashes = metadatablocklisthashes;
+ this.Metablockhash = null;
+ }
+ else if (m_reader.TokenType == JsonToken.PropertyName && m_reader.Value != null && m_reader.Value.ToString() == "metablockhash")
+ {
+ if (!m_reader.Read())
+ throw new InvalidDataException(string.Format("Invalid JSON, EOF found while reading entry {0}", this.Path));
+ this.Metablockhash = m_reader.Value.ToString();
+
+ if (!m_reader.Read())
+ throw new InvalidDataException(string.Format("Invalid JSON, EOF found while reading entry {0}", this.Path));
+
+ this.MetaBlocklistHashes = null;
+ }
}
if ((this.Type == FilelistEntryType.File || this.Type == FilelistEntryType.AlternateStream) && m_reader.TokenType == JsonToken.PropertyName && m_reader.Value != null && m_reader.Value.ToString() == "blocklists")
{
SkipJsonToken(m_reader, JsonToken.StartArray);
- BlocklistHashes = new BlocklistHashEnumerable(m_reader);
+ this.BlocklistHashes = new BlocklistHashEnumerable(m_reader);
+ }
+ else if ((this.Type == FilelistEntryType.File || this.Type == FilelistEntryType.AlternateStream) && m_reader.TokenType == JsonToken.PropertyName && m_reader.Value != null && m_reader.Value.ToString() == "blockhash")
+ {
+ if (!m_reader.Read())
+ throw new InvalidDataException(string.Format("Invalid JSON, EOF found while reading entry {0}", this.Path));
+
+ this.Blockhash = m_reader.Value.ToString();
+ this.Blocksize = ReadJsonInt64Property(m_reader, "blocksize");
+ this.BlocklistHashes = null;
}
else
{
- BlocklistHashes = null;
+ this.BlocklistHashes = null;
if (m_reader.TokenType != JsonToken.EndObject)
throw new InvalidDataException(string.Format("Invalid JSON, expected EndObject, but found {0}, \"{1}\" while reading entry {2}", m_reader.TokenType, m_reader.Value, this.Path));
}
diff --git a/Duplicati/Library/Main/Volumes/FilesetVolumeWriter.cs b/Duplicati/Library/Main/Volumes/FilesetVolumeWriter.cs
index 1a86d2f09..7fb76a585 100644
--- a/Duplicati/Library/Main/Volumes/FilesetVolumeWriter.cs
+++ b/Duplicati/Library/Main/Volumes/FilesetVolumeWriter.cs
@@ -25,17 +25,45 @@ namespace Duplicati.Library.Main.Volumes
m_writer.WriteStartArray();
}
- public void AddFile(string name, string filehash, long size, DateTime lastmodified, string metahash, long metasize, IEnumerable<string> blocklisthashes)
+ private void WriteMetaProperties(string metahash, long metasize, string metablockhash, IEnumerable<string> metablocklisthashes)
{
- AddFileEntry(FilelistEntryType.File, name, filehash, size, lastmodified, metahash, metasize, blocklisthashes);
+ m_writer.WritePropertyName("metahash");
+ m_writer.WriteValue(metahash);
+ m_writer.WritePropertyName("metasize");
+ m_writer.WriteValue(metasize);
+
+ if (metablocklisthashes != null)
+ {
+ //Slightly akward, but we avoid writing if there are no entries
+ var en = metablocklisthashes.GetEnumerator();
+ if (en.MoveNext() && !string.IsNullOrEmpty(en.Current))
+ {
+ m_writer.WritePropertyName("metablocklists");
+ m_writer.WriteStartArray();
+ m_writer.WriteValue(en.Current);
+ while (en.MoveNext())
+ m_writer.WriteValue(en.Current);
+ m_writer.WriteEndArray();
+ }
+ }
+ else if (!string.IsNullOrWhiteSpace(metablockhash))
+ {
+ m_writer.WritePropertyName("metablockhash");
+ m_writer.WriteValue(metablockhash);
+ }
}
- public void AddAlternateStream(string name, string filehash, long size, DateTime lastmodified, string metahash, long metasize, IEnumerable<string> blocklisthashes)
+ public void AddFile(string name, string filehash, long size, DateTime lastmodified, string metahash, long metasize, string metablockhash, string blockhash, long blocksize, IEnumerable<string> blocklisthashes, IEnumerable<string> metablocklisthashes)
{
- AddFileEntry(FilelistEntryType.AlternateStream, name, filehash, size, lastmodified, metahash, metasize, blocklisthashes);
+ AddFileEntry(FilelistEntryType.File, name, filehash, size, lastmodified, metahash, metasize, metablockhash, blockhash, blocksize, blocklisthashes, metablocklisthashes);
}
- private void AddFileEntry(FilelistEntryType type, string name, string filehash, long size, DateTime lastmodified, string metahash, long metasize, IEnumerable<string> blocklisthashes)
+ public void AddAlternateStream(string name, string filehash, long size, DateTime lastmodified, string metahash, string metablockhash, long metasize, string blockhash, long blocksize, IEnumerable<string> blocklisthashes, IEnumerable<string> metablocklisthashes)
+ {
+ AddFileEntry(FilelistEntryType.AlternateStream, name, filehash, size, lastmodified, metahash, metasize, metablockhash, blockhash, blocksize, blocklisthashes, metablocklisthashes);
+ }
+
+ private void AddFileEntry(FilelistEntryType type, string name, string filehash, long size, DateTime lastmodified, string metahash, long metasize, string metablockhash, string blockhash, long blocksize, IEnumerable<string> blocklisthashes, IEnumerable<string> metablocklisthashes)
{
m_filecount++;
m_writer.WriteStartObject();
@@ -50,37 +78,41 @@ namespace Duplicati.Library.Main.Volumes
m_writer.WritePropertyName("time");
m_writer.WriteValue(Library.Utility.Utility.SerializeDateTime(lastmodified));
if (metahash != null)
- {
- m_writer.WritePropertyName("metahash");
- m_writer.WriteValue(metahash);
- m_writer.WritePropertyName("metasize");
- m_writer.WriteValue(metasize);
- }
+ WriteMetaProperties(metahash, metasize, metablockhash, metablocklisthashes);
if (blocklisthashes != null)
{
//Slightly akward, but we avoid writing if there are no entries
- var en = blocklisthashes.GetEnumerator();
- if (en.MoveNext() && !string.IsNullOrEmpty(en.Current))
+ using (var en = blocklisthashes.GetEnumerator())
{
- m_writer.WritePropertyName("blocklists");
- m_writer.WriteStartArray();
- m_writer.WriteValue(en.Current);
- while(en.MoveNext())
+ if (en.MoveNext() && !string.IsNullOrEmpty(en.Current))
+ {
+ m_writer.WritePropertyName("blocklists");
+ m_writer.WriteStartArray();
m_writer.WriteValue(en.Current);
- m_writer.WriteEndArray();
+ while (en.MoveNext())
+ m_writer.WriteValue(en.Current);
+ m_writer.WriteEndArray();
+ }
}
}
+ else if (!string.IsNullOrWhiteSpace(blockhash))
+ {
+ m_writer.WritePropertyName("blockhash");
+ m_writer.WriteValue(blockhash);
+ m_writer.WritePropertyName("blocksize");
+ m_writer.WriteValue(blocksize);
+ }
m_writer.WriteEndObject();
}
- public void AddDirectory(string name, string metahash, long metasize)
+ public void AddDirectory(string name, string metahash, long metasize, string metablockhash, IEnumerable<string> metablocklisthashes)
{
- AddMetaEntry(FilelistEntryType.Folder, name, metahash, metasize);
+ AddMetaEntry(FilelistEntryType.Folder, name, metahash, metasize, metablockhash, metablocklisthashes);
}
- public void AddMetaEntry(FilelistEntryType type, string name, string metahash, long metasize)
+ public void AddMetaEntry(FilelistEntryType type, string name, string metahash, long metasize, string metablockhash, IEnumerable<string> metablocklisthashes)
{
m_foldercount++;
m_writer.WriteStartObject();
@@ -89,12 +121,8 @@ namespace Duplicati.Library.Main.Volumes
m_writer.WritePropertyName("path");
m_writer.WriteValue(name);
if (metahash != null)
- {
- m_writer.WritePropertyName("metahash");
- m_writer.WriteValue(metahash);
- m_writer.WritePropertyName("metasize");
- m_writer.WriteValue(metasize);
- }
+ WriteMetaProperties(metahash, metasize, metablockhash, metablocklisthashes);
+
m_writer.WriteEndObject();
}
@@ -127,9 +155,9 @@ namespace Duplicati.Library.Main.Volumes
public long FileCount { get { return m_filecount; } }
public long FolderCount { get { return m_foldercount; } }
- public void AddSymlink(string name, string metahash, long metasize)
+ public void AddSymlink(string name, string metahash, long metasize, string metablockhash, IEnumerable<string> metablocklisthashes)
{
- AddMetaEntry(FilelistEntryType.Symlink, name, metahash, metasize);
+ AddMetaEntry(FilelistEntryType.Symlink, name, metahash, metasize, metablockhash, metablocklisthashes);
}
}
}
diff --git a/Duplicati/Library/Main/Volumes/IFileEntry.cs b/Duplicati/Library/Main/Volumes/IFileEntry.cs
index 836f99d44..8be20f37b 100644
--- a/Duplicati/Library/Main/Volumes/IFileEntry.cs
+++ b/Duplicati/Library/Main/Volumes/IFileEntry.cs
@@ -14,7 +14,11 @@ namespace Duplicati.Library.Main.Volumes
long Size { get; }
DateTime Time { get; }
string Metahash { get; }
+ string Metablockhash { get; }
long Metasize { get; }
+ string Blockhash { get; }
+ long Blocksize { get; }
IEnumerable<string> BlocklistHashes { get; }
+ IEnumerable<string> MetaBlocklistHashes { get; }
}
}
diff --git a/Duplicati/Library/Main/Volumes/VolumeBase.cs b/Duplicati/Library/Main/Volumes/VolumeBase.cs
index c96e03e93..c0af0a228 100644
--- a/Duplicati/Library/Main/Volumes/VolumeBase.cs
+++ b/Duplicati/Library/Main/Volumes/VolumeBase.cs
@@ -11,7 +11,7 @@ namespace Duplicati.Library.Main.Volumes
protected class ManifestData
{
public const string ENCODING = "utf8";
- public const long VERSION = 1;
+ public const long VERSION = 2;
public long Version;
public string Created;
@@ -73,7 +73,7 @@ namespace Duplicati.Library.Main.Volumes
dict[RemoteVolumeType.Files] = "dlist";
dict[RemoteVolumeType.Index] = "dindex";
- var reversedict = new Dictionary<string, RemoteVolumeType>(System.StringComparer.InvariantCultureIgnoreCase);
+ var reversedict = new Dictionary<string, RemoteVolumeType>(System.StringComparer.OrdinalIgnoreCase);
foreach(var x in dict)
reversedict[x.Value] = x.Key;
diff --git a/Duplicati/Library/Main/Volumes/VolumeWriterBase.cs b/Duplicati/Library/Main/Volumes/VolumeWriterBase.cs
index a97b2aecc..d3b14404f 100644
--- a/Duplicati/Library/Main/Volumes/VolumeWriterBase.cs
+++ b/Duplicati/Library/Main/Volumes/VolumeWriterBase.cs
@@ -57,7 +57,7 @@ namespace Duplicati.Library.Main.Volumes
m_compression = DynamicLoader.CompressionLoader.GetModule(options.CompressionModule, m_localfile, options.RawOptions);
if(m_compression == null)
- throw new Exception(string.Format("Unsupported compression module: {0}", options.CompressionModule));
+ throw new UserInformationException(string.Format("Unsupported compression module: {0}", options.CompressionModule));
if ((this is IndexVolumeWriter || this is FilesetVolumeWriter) && m_compression is Library.Interface.ICompressionHinting)
((Library.Interface.ICompressionHinting)m_compression).LowOverheadMode = true;
diff --git a/Duplicati/Library/Main/default_compressed_extensions.txt b/Duplicati/Library/Main/default_compressed_extensions.txt
index df8134ff9..f1b2740bf 100644
--- a/Duplicati/Library/Main/default_compressed_extensions.txt
+++ b/Duplicati/Library/Main/default_compressed_extensions.txt
@@ -96,6 +96,7 @@
.tif #TIFF image
.dng #Adobe Digital Negative
.cr2 #Canon RAW Image Format
+.webp #WebP Image
# Compressed Font files
diff --git a/Duplicati/Library/Main/packages.config b/Duplicati/Library/Main/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Library/Main/packages.config
+++ b/Duplicati/Library/Main/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Modules/Builtin/CheckMonoSSL.cs b/Duplicati/Library/Modules/Builtin/CheckMonoSSL.cs
index 425899a83..1bd6e21b7 100644
--- a/Duplicati/Library/Modules/Builtin/CheckMonoSSL.cs
+++ b/Duplicati/Library/Modules/Builtin/CheckMonoSSL.cs
@@ -104,7 +104,8 @@ namespace Duplicati.Library.Modules.Builtin
private enum ConfigType
{
List,
- Install
+ Install,
+ Test
}
@@ -139,6 +140,25 @@ namespace Duplicati.Library.Modules.Builtin
d["count"] = CheckForInstalledCerts().ToString();
break;
+ case ConfigType.Test:
+ try
+ {
+ var req = System.Net.WebRequest.CreateHttp("https://updates.duplicati.com");
+ req.Method = "HEAD";
+ req.AllowAutoRedirect = false;
+
+ using (var resp = (System.Net.HttpWebResponse)req.GetResponse())
+ {
+ d["status"] = resp.StatusDescription;
+ d["status_code"] = ((int)resp.StatusCode).ToString();
+ }
+ }
+ catch(Exception ex)
+ {
+ d["error"] = ex.ToString();
+ }
+ break;
+
case ConfigType.List:
default:
d["count"] = CheckForInstalledCerts().ToString();
diff --git a/Duplicati/Library/Modules/Builtin/ConsolePasswordInput.cs b/Duplicati/Library/Modules/Builtin/ConsolePasswordInput.cs
index c5df52472..7b7bb9302 100644
--- a/Duplicati/Library/Modules/Builtin/ConsolePasswordInput.cs
+++ b/Duplicati/Library/Modules/Builtin/ConsolePasswordInput.cs
@@ -29,7 +29,7 @@ namespace Duplicati.Library.Modules.Builtin
/// These actions only use the local database and do not require access to the data inside the files.
/// For List and ListChanges this may not be true if there is no local database
/// </summary>
- private readonly static string[] PASSPHRASELESS_ACTIONS = { "CreateLogDb", "TestFilters", "ListAffected", "SystemInfo" };
+ private readonly static string[] PASSPHRASELESS_ACTIONS = { "CreateLogDb", "TestFilters", "ListAffected", "SystemInfo", "SendMail" };
#region IGenericModule Members
@@ -47,14 +47,14 @@ namespace Duplicati.Library.Modules.Builtin
//First see if a password is actually required for the action
foreach (string s in PASSPHRASELESS_ACTIONS)
- if (string.Equals(s, commandlineOptions["main-action"], StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(s, commandlineOptions["main-action"], StringComparison.OrdinalIgnoreCase))
return;
//See if a password is already present or encryption is disabled
if (!commandlineOptions.ContainsKey("passphrase") && !Duplicati.Library.Utility.Utility.ParseBoolOption(commandlineOptions, "no-encryption"))
{
//Get the passphrase
- bool confirm = string.Equals(commandlineOptions["main-action"], "backup", StringComparison.InvariantCultureIgnoreCase);
+ bool confirm = string.Equals(commandlineOptions["main-action"], "backup", StringComparison.OrdinalIgnoreCase);
commandlineOptions["passphrase"] = ReadPassphraseFromConsole(confirm);
}
}
@@ -107,11 +107,11 @@ namespace Duplicati.Library.Modules.Builtin
Console.WriteLine();
if (passphrase.ToString() != password2.ToString())
- throw new Exception(Strings.ConsolePasswordInput.PassphraseMismatchError);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.ConsolePasswordInput.PassphraseMismatchError);
}
if (passphrase.ToString().Length == 0)
- throw new Exception(Strings.ConsolePasswordInput.EmptyPassphraseError);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.ConsolePasswordInput.EmptyPassphraseError);
return passphrase.ToString();
}
diff --git a/Duplicati/Library/Modules/Builtin/Duplicati.Library.Modules.Builtin.csproj b/Duplicati/Library/Modules/Builtin/Duplicati.Library.Modules.Builtin.csproj
index 5240600ad..a23687eed 100644
--- a/Duplicati/Library/Modules/Builtin/Duplicati.Library.Modules.Builtin.csproj
+++ b/Duplicati/Library/Modules/Builtin/Duplicati.Library.Modules.Builtin.csproj
@@ -9,7 +9,6 @@
<RootNamespace>Duplicati.Library.Modules.Builtin</RootNamespace>
<AssemblyName>Duplicati.Library.Modules.Builtin</AssemblyName>
<FileAlignment>512</FileAlignment>
- <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
@@ -17,6 +16,7 @@
<UpgradeBackupLocation />
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -42,42 +42,50 @@
<HintPath>..\..\..\..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="DnsLib">
- <HintPath>..\..\..\..\thirdparty\DnsLite\DnsLib.dll</HintPath>
- </Reference>
- <Reference Include="MailKit, Version=1.2.0.0, Culture=neutral, PublicKeyToken=4e064fe7c44a8f1b, processorArchitecture=MSIL">
- <HintPath>..\..\..\..\packages\MailKit.1.2.24\lib\net45\MailKit.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="MimeKit, Version=1.2.0.0, Culture=neutral, PublicKeyToken=bede1c8a46c66814, processorArchitecture=MSIL">
- <HintPath>..\..\..\..\packages\MimeKit.1.2.25\lib\net45\MimeKit.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System" />
<Reference Include="System.Net" />
<Reference Include="Mono.Security" />
<Reference Include="agsXMPP">
<HintPath>..\..\..\..\packages\agsXMPP.1.1.1.0\lib\agsXMPP.dll</HintPath>
</Reference>
+ <Reference Include="System.Core" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Security" />
+ <Reference Include="MimeKit">
+ <HintPath>..\..\..\..\packages\MimeKit.1.18.1\lib\net45\MimeKit.dll</HintPath>
+ </Reference>
+ <Reference Include="MailKit">
+ <HintPath>..\..\..\..\packages\MailKit.1.18.1.1\lib\net45\MailKit.dll</HintPath>
+ </Reference>
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ConsolePasswordInput.cs" />
+ <Compile Include="MSSQLOptions.cs" />
+ <Compile Include="HyperVOptions.cs" />
<Compile Include="HttpOptions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SendHttpMessage.cs" />
<Compile Include="SendMail.cs" />
<Compile Include="RunScript.cs" />
<Compile Include="SendJabberMessage.cs" />
<Compile Include="Strings.cs" />
<Compile Include="CheckMonoSSL.cs" />
+ <Compile Include="..\..\..\..\thirdparty\DnsLite\DnsLite.cs">
+ <Link>DnsLite.cs</Link>
+ </Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
<Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
<Name>Duplicati.Library.Interface</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Snapshots\Duplicati.Library.Snapshots.csproj">
+ <Project>{D63E53E4-A458-4C2F-914D-92F715F58ACE}</Project>
+ <Name>Duplicati.Library.Snapshots</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Utility\Duplicati.Library.Utility.csproj">
<Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
<Name>Duplicati.Library.Utility</Name>
diff --git a/Duplicati/Library/Modules/Builtin/HttpOptions.cs b/Duplicati/Library/Modules/Builtin/HttpOptions.cs
index 82514f188..ead8691a5 100644
--- a/Duplicati/Library/Modules/Builtin/HttpOptions.cs
+++ b/Duplicati/Library/Modules/Builtin/HttpOptions.cs
@@ -33,14 +33,33 @@ namespace Duplicati.Library.Modules.Builtin
private const string OPTION_OAUTH_URL = "oauth-url";
private const string OPTION_SSL_VERSIONS = "allowed-ssl-versions";
- private IDisposable m_certificateValidator;
+ private const string OPTION_BUFFER_REQUESTS = "http-enable-buffering";
+ private const string OPTION_OPERATION_TIMEOUT = "http-operation-timeout";
+ private const string OPTION_READWRITE_TIMEOUT = "http-readwrite-timeout";
+
+
private bool m_useNagle;
private bool m_useExpect;
- private bool m_dispose;
private System.Net.SecurityProtocolType m_securityProtocol;
-
- // Copied from system reference
- [Flags]
+
+ private bool m_dispose;
+
+ private bool m_resetNagle;
+ private bool m_resetExpect;
+ private bool m_resetSecurity;
+
+ /// <summary>
+ /// The handle to the call-context http settings
+ /// </summary>
+ private IDisposable m_httpsettings;
+
+ /// <summary>
+ /// The handle to the call-contet oauth setttings
+ /// </summary>
+ private IDisposable m_oauthsettings;
+
+ // Copied from system reference
+ [Flags]
private enum CopySecurityProtocolType
{
Ssl3 = 48,
@@ -109,7 +128,11 @@ namespace Duplicati.Library.Modules.Builtin
new Duplicati.Library.Interface.CommandLineArgument(OPTION_ACCEPT_SPECIFIED_CERTIFICATE, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.String, Strings.HttpOptions.DescriptionAcceptHashShort, Strings.HttpOptions.DescriptionAcceptHashLong2),
new Duplicati.Library.Interface.CommandLineArgument(OPTION_ACCEPT_ANY_CERTIFICATE, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Boolean, Strings.HttpOptions.DescriptionAcceptAnyCertificateShort, Strings.HttpOptions.DescriptionAcceptAnyCertificateLong),
new Duplicati.Library.Interface.CommandLineArgument(OPTION_OAUTH_URL, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.String, Strings.HttpOptions.OauthurlShort, Strings.HttpOptions.OauthurlLong, OAuthHelper.DUPLICATI_OAUTH_SERVICE),
- new Duplicati.Library.Interface.CommandLineArgument(OPTION_SSL_VERSIONS, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Flags, Strings.HttpOptions.SslversionsShort, Strings.HttpOptions.SslversionsLong, defaultssl, null, sslnames),
+ new Duplicati.Library.Interface.CommandLineArgument(OPTION_SSL_VERSIONS, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Flags, Strings.HttpOptions.SslversionsShort, Strings.HttpOptions.SslversionsLong, defaultssl, null, sslnames),
+
+ new Duplicati.Library.Interface.CommandLineArgument(OPTION_OPERATION_TIMEOUT, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Timespan, Strings.HttpOptions.OperationtimeoutShort, Strings.HttpOptions.OperationtimeoutLong),
+ new Duplicati.Library.Interface.CommandLineArgument(OPTION_READWRITE_TIMEOUT, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Timespan, Strings.HttpOptions.ReadwritetimeoutShort, Strings.HttpOptions.ReadwritetimeoutLong),
+ new Duplicati.Library.Interface.CommandLineArgument(OPTION_BUFFER_REQUESTS, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Boolean, Strings.HttpOptions.BufferrequestsShort, Strings.HttpOptions.BufferrequestsLong, "false"),
});
}
}
@@ -117,33 +140,60 @@ namespace Duplicati.Library.Modules.Builtin
public void Configure(IDictionary<string, string> commandlineOptions)
{
m_dispose = true;
+ TimeSpan operationTimeout = new TimeSpan(0);
+ TimeSpan readwriteTimeout = new TimeSpan(0);
+
+ string timetmp;
+ commandlineOptions.TryGetValue(OPTION_OPERATION_TIMEOUT, out timetmp);
+ if (!string.IsNullOrWhiteSpace(timetmp))
+ operationTimeout = Utility.Timeparser.ParseTimeSpan(timetmp);
+
+ commandlineOptions.TryGetValue(OPTION_READWRITE_TIMEOUT, out timetmp);
+ if (!string.IsNullOrWhiteSpace(timetmp))
+ readwriteTimeout = Utility.Timeparser.ParseTimeSpan(timetmp);
+
+ bool accepAllCertificates = Utility.Utility.ParseBoolOption(commandlineOptions, OPTION_ACCEPT_ANY_CERTIFICATE);
+
+ string certHash;
+ commandlineOptions.TryGetValue(OPTION_ACCEPT_SPECIFIED_CERTIFICATE, out certHash);
+
+ m_httpsettings = Duplicati.Library.Utility.HttpContextSettings.StartSession(
+ operationTimeout,
+ readwriteTimeout,
+ Utility.Utility.ParseBoolOption(commandlineOptions, OPTION_BUFFER_REQUESTS),
+ accepAllCertificates,
+ certHash == null ? null : certHash.Split(new string[] { ",", ";" }, StringSplitOptions.RemoveEmptyEntries)
+ );
- bool accepAllCertificates = Utility.Utility.ParseBoolOption(commandlineOptions, OPTION_ACCEPT_ANY_CERTIFICATE);
-
- string certHash;
- commandlineOptions.TryGetValue(OPTION_ACCEPT_SPECIFIED_CERTIFICATE, out certHash);
-
- m_certificateValidator = new Library.Utility.SslCertificateValidator(accepAllCertificates, certHash == null ? null : certHash.Split(new string[] {",", ";"}, StringSplitOptions.RemoveEmptyEntries));
-
bool disableNagle = Utility.Utility.ParseBoolOption(commandlineOptions, OPTION_DISABLE_NAGLING);
bool disableExpect100 = Utility.Utility.ParseBoolOption(commandlineOptions, OPTION_DISABLE_EXPECT100);
+ // TODO: This is done to avoid conflicting settings,
+ // but ideally, we should run each operation in a seperate
+ // app-domain to ensure that multiple invocations of this module
+ // does not interfere, as the options are shared in the app-domain
+ m_resetNagle = commandlineOptions.ContainsKey(OPTION_DISABLE_NAGLING);
+ m_resetExpect = commandlineOptions.ContainsKey(OPTION_DISABLE_EXPECT100);
+ m_resetSecurity = commandlineOptions.ContainsKey(OPTION_SSL_VERSIONS);
+
m_useNagle = System.Net.ServicePointManager.UseNagleAlgorithm;
m_useExpect = System.Net.ServicePointManager.Expect100Continue;
m_securityProtocol = System.Net.ServicePointManager.SecurityProtocol;
- System.Net.ServicePointManager.UseNagleAlgorithm = !disableNagle;
- System.Net.ServicePointManager.Expect100Continue = !disableExpect100;
+ if (m_resetNagle)
+ System.Net.ServicePointManager.UseNagleAlgorithm = !disableNagle;
+ if (m_resetExpect)
+ System.Net.ServicePointManager.Expect100Continue = !disableExpect100;
string sslprotocol;
commandlineOptions.TryGetValue(OPTION_SSL_VERSIONS, out sslprotocol);
- if (!string.IsNullOrWhiteSpace(sslprotocol))
+ if (!string.IsNullOrWhiteSpace(sslprotocol) && m_resetSecurity)
System.Net.ServicePointManager.SecurityProtocol = ParseSSLProtocols(sslprotocol);
string url;
commandlineOptions.TryGetValue(OPTION_OAUTH_URL, out url);
- OAuthHelper.OAUTH_SERVER = url;
-
+ if (!string.IsNullOrWhiteSpace(url))
+ m_oauthsettings = OAuthContextSettings.StartSession(url);
}
#endregion
@@ -155,13 +205,24 @@ namespace Duplicati.Library.Modules.Builtin
if (m_dispose)
{
m_dispose = false;
- System.Net.ServicePointManager.UseNagleAlgorithm = m_useNagle;
- System.Net.ServicePointManager.Expect100Continue = m_useExpect;
- System.Net.ServicePointManager.SecurityProtocol = m_securityProtocol;
- if (m_certificateValidator != null)
- m_certificateValidator.Dispose();
- m_certificateValidator = null;
- OAuthHelper.OAUTH_SERVER = null;
+ if (m_resetNagle)
+ System.Net.ServicePointManager.UseNagleAlgorithm = m_useNagle;
+ if (m_resetExpect)
+ System.Net.ServicePointManager.Expect100Continue = m_useExpect;
+ if (m_resetSecurity)
+ System.Net.ServicePointManager.SecurityProtocol = m_securityProtocol;
+ }
+
+ if (m_httpsettings != null)
+ {
+ m_httpsettings.Dispose();
+ m_httpsettings = null;
+ }
+
+ if (m_oauthsettings != null)
+ {
+ m_oauthsettings.Dispose();
+ m_oauthsettings = null;
}
}
diff --git a/Duplicati/Library/Modules/Builtin/HyperVOptions.cs b/Duplicati/Library/Modules/Builtin/HyperVOptions.cs
new file mode 100644
index 000000000..81938bf9b
--- /dev/null
+++ b/Duplicati/Library/Modules/Builtin/HyperVOptions.cs
@@ -0,0 +1,222 @@
+#region Disclaimer / License
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Duplicati.Library.Snapshots;
+
+namespace Duplicati.Library.Modules.Builtin
+{
+ public class HyperVOptions : Interface.IGenericSourceModule
+ {
+ private const string m_HyperVPathGuidRegExp = @"\%HYPERV\%\\([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})";
+ private const string m_HyperVPathAllRegExp = @"%HYPERV%";
+
+ #region IGenericModule Members
+
+ public string Key
+ {
+ get { return "hyperv-options"; }
+ }
+
+ public string DisplayName
+ {
+ get { return Strings.HyperVOptions.DisplayName; }
+ }
+
+ public string Description
+ {
+ get { return Strings.HyperVOptions.Description; }
+ }
+
+ public bool LoadAsDefault
+ {
+ get { return Utility.Utility.IsClientWindows; }
+ }
+
+ public IList<Interface.ICommandLineArgument> SupportedCommands
+ {
+ get { return null; }
+ }
+
+ public void Configure(IDictionary<string, string> commandlineOptions)
+ {
+ }
+
+ #endregion
+
+ #region Implementation of IGenericSourceModule
+ public Dictionary<string, string> ParseSourcePaths(ref string[] paths, ref string filter, Dictionary<string, string> commandlineOptions)
+ {
+ // Early exit in case we are non-windows to prevent attempting to load Windows-only components
+ if (!Utility.Utility.IsClientWindows)
+ {
+ Logging.Log.WriteMessage("Hyper-V backup works only on Windows OS", Logging.LogMessageType.Warning);
+
+ if (paths != null)
+ paths = paths.Where(x => !x.Equals(m_HyperVPathAllRegExp, StringComparison.OrdinalIgnoreCase) && !Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToArray();
+
+ if (!string.IsNullOrEmpty(filter))
+ {
+ var filters = filter.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries);
+ var remainingfilters = filters.Where(x => !Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToArray();
+ filter = string.Join(System.IO.Path.PathSeparator.ToString(), remainingfilters);
+ }
+
+ return new Dictionary<string, string>();
+ }
+
+ // Windows, do the real stuff!
+ return RealParseSourcePaths(ref paths, ref filter, commandlineOptions);
+ }
+
+ // Make sure the JIT does not attempt to inline this call and thus load
+ // referenced types from System.Management here
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ private Dictionary<string, string> RealParseSourcePaths(ref string[] paths, ref string filter, Dictionary<string, string> commandlineOptions)
+ {
+ var changedOptions = new Dictionary<string, string>();
+ var filtersInclude = new List<string>();
+ var filtersExclude = new List<string>();
+
+ if (!string.IsNullOrEmpty(filter))
+ {
+ var filters = filter.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries);
+
+ filtersInclude = filters.Where(x => x.StartsWith("+") && Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ .Select(x => Regex.Match(x.Substring(1), m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Groups[1].Value).ToList();
+ filtersExclude = filters.Where(x => x.StartsWith("-") && Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ .Select(x => Regex.Match(x.Substring(1), m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Groups[1].Value).ToList();
+
+ var remainingfilters = filters.Where(x => !Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToArray();
+ filter = string.Join(System.IO.Path.PathSeparator.ToString(), remainingfilters);
+ }
+
+ var hypervUtility = new HyperVUtility();
+
+ if (paths == null || !ContainFilesForBackup(paths) || !hypervUtility.IsHyperVInstalled)
+ return changedOptions;
+
+ if (commandlineOptions.Keys.Contains("vss-exclude-writers"))
+ {
+ var excludedWriters = commandlineOptions["vss-exclude-writers"].Split(';').Where(x => !string.IsNullOrWhiteSpace(x) && x.Trim().Length > 0).Select(x => new Guid(x)).ToArray();
+
+ if (excludedWriters.Contains(HyperVUtility.HyperVWriterGuid))
+ {
+ Logging.Log.WriteMessage(string.Format("Excluded writers for VSS cannot contain Hyper-V writer when backuping Hyper-V virtual machines. Removing \"{0}\" to continue", HyperVUtility.HyperVWriterGuid.ToString()), Logging.LogMessageType.Warning);
+ changedOptions["vss-exclude-writers"] = string.Join(";", excludedWriters.Where(x => x != HyperVUtility.HyperVWriterGuid));
+ }
+ }
+
+ if (!commandlineOptions.Keys.Contains("snapshot-policy") || !commandlineOptions["snapshot-policy"].Equals("required", StringComparison.OrdinalIgnoreCase))
+ {
+ Logging.Log.WriteMessage("Snapshot strategy have to be set to \"required\" when backuping Hyper-V virtual machines. Changing to \"required\" to continue", Logging.LogMessageType.Warning);
+ changedOptions["snapshot-policy"] = "required";
+ }
+
+ if (!hypervUtility.IsVSSWriterSupported)
+ Logging.Log.WriteMessage("This is client version of Windows. Hyper-V VSS writer is present only on Server version. Backup will continue, but will be crash consistent only in opposite to application consistent in Server version", Logging.LogMessageType.Warning);
+
+ Logging.Log.WriteMessage("Starting to gather Hyper-V information", Logging.LogMessageType.Information);
+ hypervUtility.QueryHyperVGuestsInfo(true);
+ Logging.Log.WriteMessage(string.Format("Found {0} virtual machines on Hyper-V", hypervUtility.Guests.Count), Logging.LogMessageType.Information);
+
+ foreach (var guest in hypervUtility.Guests)
+ Logging.Log.WriteMessage(string.Format("Found VM name {0}, ID {1}, files {2}", guest.Name, guest.ID, string.Join(";", guest.DataPaths)), Logging.LogMessageType.Profiling);
+
+ List<HyperVGuest> guestsForBackup = new List<HyperVGuest>();
+
+ if (paths.Contains(m_HyperVPathAllRegExp, StringComparer.OrdinalIgnoreCase))
+ guestsForBackup = hypervUtility.Guests;
+ else
+ foreach (var guestID in paths.Where(x => Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ .Select(x => Regex.Match(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Groups[1].Value).ToArray())
+ {
+ var foundGuest = hypervUtility.Guests.Where(x => x.ID == new Guid(guestID));
+
+ if (foundGuest.Count() != 1)
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Hyper-V guest specified in source with ID {0} cannot be found", guestID));
+
+ guestsForBackup.Add(foundGuest.First());
+ }
+
+ if (filtersInclude.Count > 0)
+ foreach (var guestID in filtersInclude)
+ {
+ var foundGuest = hypervUtility.Guests.Where(x => x.ID == new Guid(guestID));
+
+ if (foundGuest.Count() != 1)
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Hyper-V guest specified in include filter with ID {0} cannot be found", guestID));
+
+ guestsForBackup.Add(foundGuest.First());
+ Logging.Log.WriteMessage(string.Format("Including {0} based on including filters", guestID), Logging.LogMessageType.Information);
+ }
+
+ guestsForBackup = guestsForBackup.Distinct().ToList();
+
+ if (filtersExclude.Count > 0)
+ foreach (var guestID in filtersExclude)
+ {
+ var foundGuest = guestsForBackup.Where(x => x.ID == new Guid(guestID));
+
+ if (foundGuest.Count() != 1)
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("Hyper-V guest specified in exclude filter with ID {0} cannot be found", guestID));
+
+ guestsForBackup.Remove(foundGuest.First());
+ Logging.Log.WriteMessage(string.Format("Excluding {0} based on excluding filters", guestID), Logging.LogMessageType.Information);
+ }
+
+ var pathsForBackup = new List<string>(paths);
+ var filterhandler = new Utility.FilterExpression(
+ filter.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries).Where(x => x.StartsWith("-")).Select(x => x.Substring(1)).ToList());
+
+ foreach (var guestForBackup in guestsForBackup)
+ foreach (var pathForBackup in guestForBackup.DataPaths)
+ {
+ bool bResult;
+ Utility.IFilter matchFilter;
+
+ if (!filterhandler.Matches(pathForBackup, out bResult, out matchFilter))
+ {
+ Logging.Log.WriteMessage(string.Format("For VM {0} - adding {1}", guestForBackup.Name, pathForBackup), Logging.LogMessageType.Information);
+ pathsForBackup.Add(pathForBackup);
+ }
+ else
+ Logging.Log.WriteMessage(string.Format("Excluding {0} based on excluding filters", pathForBackup), Logging.LogMessageType.Information);
+ }
+
+ paths = pathsForBackup.Where(x => !x.Equals(m_HyperVPathAllRegExp, StringComparison.OrdinalIgnoreCase) && !Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ .Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToArray();
+
+ return changedOptions;
+ }
+
+ public bool ContainFilesForBackup(string[] paths)
+ {
+ if (paths == null || !Utility.Utility.IsClientWindows)
+ return false;
+
+ return paths.Where(x => !string.IsNullOrWhiteSpace(x)).Where(x => x.Equals(m_HyperVPathAllRegExp, StringComparison.OrdinalIgnoreCase) || Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).Any();
+ }
+
+ #endregion
+ }
+}
diff --git a/Duplicati/Library/Modules/Builtin/MSSQLOptions.cs b/Duplicati/Library/Modules/Builtin/MSSQLOptions.cs
new file mode 100644
index 000000000..3c8bcbf3c
--- /dev/null
+++ b/Duplicati/Library/Modules/Builtin/MSSQLOptions.cs
@@ -0,0 +1,219 @@
+#region Disclaimer / License
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Duplicati.Library.Snapshots;
+
+namespace Duplicati.Library.Modules.Builtin
+{
+ public class MSSQLOptions : Interface.IGenericSourceModule
+ {
+ private const string m_MSSQLPathDBRegExp = @"\%MSSQL\%\\(.+)";
+ private const string m_MSSQLPathAllRegExp = @"%MSSQL%";
+
+ #region IGenericModule Members
+
+ public string Key
+ {
+ get { return "mssql-options"; }
+ }
+
+ public string DisplayName
+ {
+ get { return Strings.MSSQLOptions.DisplayName; }
+ }
+
+ public string Description
+ {
+ get { return Strings.MSSQLOptions.Description; }
+ }
+
+ public bool LoadAsDefault
+ {
+ get { return Utility.Utility.IsClientWindows; }
+ }
+
+ public IList<Interface.ICommandLineArgument> SupportedCommands
+ {
+ get { return null; }
+ }
+
+ public void Configure(IDictionary<string, string> commandlineOptions)
+ {
+ }
+
+ #endregion
+
+ #region Implementation of IGenericSourceModule
+ public Dictionary<string, string> ParseSourcePaths(ref string[] paths, ref string filter, Dictionary<string, string> commandlineOptions)
+ {
+ // Early exit in case we are non-windows to prevent attempting to load Windows-only components
+ if (!Utility.Utility.IsClientWindows)
+ {
+ Logging.Log.WriteMessage("Microsoft SQL Server databases backup works only on Windows OS", Logging.LogMessageType.Warning);
+
+ if (paths != null)
+ paths = paths.Where(x => !x.Equals(m_MSSQLPathAllRegExp, StringComparison.OrdinalIgnoreCase) && !Regex.IsMatch(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToArray();
+
+ if (!string.IsNullOrEmpty(filter))
+ {
+ var filters = filter.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries);
+ var remainingfilters = filters.Where(x => !Regex.IsMatch(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToArray();
+ filter = string.Join(System.IO.Path.PathSeparator.ToString(), remainingfilters);
+ }
+
+ return new Dictionary<string, string>();
+ }
+
+ // Windows, do the real stuff!
+ return RealParseSourcePaths(ref paths, ref filter, commandlineOptions);
+ }
+
+ // Make sure the JIT does not attempt to inline this call and thus load
+ // referenced types from System.Management here
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ private Dictionary<string, string> RealParseSourcePaths(ref string[] paths, ref string filter, Dictionary<string, string> commandlineOptions)
+ {
+ var changedOptions = new Dictionary<string, string>();
+ var filtersInclude = new List<string>();
+ var filtersExclude = new List<string>();
+
+ if (!string.IsNullOrEmpty(filter))
+ {
+ var filters = filter.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries);
+
+ filtersInclude = filters.Where(x => x.StartsWith("+") && Regex.IsMatch(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ .Select(x => Regex.Match(x.Substring(1), m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Groups[1].Value).ToList();
+ filtersExclude = filters.Where(x => x.StartsWith("-") && Regex.IsMatch(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ .Select(x => Regex.Match(x.Substring(1), m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Groups[1].Value).ToList();
+
+ var remainingfilters = filters.Where(x => !Regex.IsMatch(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToArray();
+ filter = string.Join(System.IO.Path.PathSeparator.ToString(), remainingfilters);
+ }
+
+ var mssqlUtility = new MSSQLUtility();
+
+ if (paths == null || !ContainFilesForBackup(paths) || !mssqlUtility.IsMSSQLInstalled)
+ return changedOptions;
+
+ if (commandlineOptions.Keys.Contains("vss-exclude-writers"))
+ {
+ var excludedWriters = commandlineOptions["vss-exclude-writers"].Split(';').Where(x => !string.IsNullOrWhiteSpace(x) && x.Trim().Length > 0).Select(x => new Guid(x)).ToArray();
+
+ if (excludedWriters.Contains(MSSQLUtility.MSSQLWriterGuid))
+ {
+ Logging.Log.WriteMessage(string.Format("Excluded writers for VSS cannot contain MS SQL writer when backuping Microsoft SQL Server databases. Removing \"{0}\" to continue", MSSQLUtility.MSSQLWriterGuid.ToString()), Logging.LogMessageType.Warning);
+ changedOptions["vss-exclude-writers"] = string.Join(";", excludedWriters.Where(x => x != MSSQLUtility.MSSQLWriterGuid));
+ }
+ }
+
+ if (!commandlineOptions.Keys.Contains("snapshot-policy") || !commandlineOptions["snapshot-policy"].Equals("required", StringComparison.OrdinalIgnoreCase))
+ {
+ Logging.Log.WriteMessage("Snapshot strategy have to be set to \"required\" when backuping Microsoft SQL Server databases. Changing to \"required\" to continue", Logging.LogMessageType.Warning);
+ changedOptions["snapshot-policy"] = "required";
+ }
+
+ Logging.Log.WriteMessage("Starting to gather Microsoft SQL Server information", Logging.LogMessageType.Information);
+ mssqlUtility.QueryDBsInfo();
+ Logging.Log.WriteMessage(string.Format("Found {0} databases on Microsoft SQL Server", mssqlUtility.DBs.Count), Logging.LogMessageType.Information);
+
+ foreach(var db in mssqlUtility.DBs)
+ Logging.Log.WriteMessage(string.Format("Found DB name {0}, ID {1}, files {2}", db.Name, db.ID, string.Join(";", db.DataPaths)), Logging.LogMessageType.Profiling);
+
+ List<MSSQLDB> dbsForBackup = new List<MSSQLDB>();
+
+ if (paths.Contains(m_MSSQLPathAllRegExp, StringComparer.OrdinalIgnoreCase))
+ dbsForBackup = mssqlUtility.DBs;
+ else
+ foreach (var dbID in paths.Where(x => Regex.IsMatch(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ .Select(x => Regex.Match(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Groups[1].Value).ToArray())
+ {
+ var foundDB = mssqlUtility.DBs.Where(x => x.ID.Equals(dbID, StringComparison.OrdinalIgnoreCase));
+
+ if (foundDB.Count() != 1)
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("DB name specified in source with ID {0} cannot be found", dbID));
+
+ dbsForBackup.Add(foundDB.First());
+ }
+
+ if (filtersInclude.Count > 0)
+ foreach (var dbID in filtersInclude)
+ {
+ var foundDB = mssqlUtility.DBs.Where(x => x.ID.Equals(dbID, StringComparison.OrdinalIgnoreCase));
+
+ if (foundDB.Count() != 1)
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("DB name specified in include filter with ID {0} cannot be found", dbID));
+
+ dbsForBackup.Add(foundDB.First());
+ Logging.Log.WriteMessage(string.Format("Including {0} based on including filters", dbID), Logging.LogMessageType.Information);
+ }
+
+ dbsForBackup = dbsForBackup.Distinct().ToList();
+
+ if (filtersExclude.Count > 0)
+ foreach (var dbID in filtersExclude)
+ {
+ var foundDB = dbsForBackup.Where(x => x.ID.Equals(dbID, StringComparison.OrdinalIgnoreCase));
+
+ if (foundDB.Count() != 1)
+ throw new Duplicati.Library.Interface.UserInformationException(string.Format("DB name specified in exclude filter with ID {0} cannot be found", dbID));
+
+ dbsForBackup.Remove(foundDB.First());
+ Logging.Log.WriteMessage(string.Format("Excluding {0} based on excluding filters", dbID), Logging.LogMessageType.Information);
+ }
+
+ var pathsForBackup = new List<string>(paths);
+ var filterhandler = new Utility.FilterExpression(
+ filter.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries).Where(x => x.StartsWith("-")).Select(x => x.Substring(1)).ToList());
+
+ foreach (var dbForBackup in dbsForBackup)
+ foreach (var pathForBackup in dbForBackup.DataPaths)
+ {
+ bool bResult;
+ Utility.IFilter matchFilter;
+
+ if (!filterhandler.Matches(pathForBackup, out bResult, out matchFilter))
+ {
+ Logging.Log.WriteMessage(string.Format("For DB {0} - adding {1}", dbForBackup.Name, pathForBackup), Logging.LogMessageType.Information);
+ pathsForBackup.Add(pathForBackup);
+ }
+ else
+ Logging.Log.WriteMessage(string.Format("Excluding {0} based on excluding filters", pathForBackup), Logging.LogMessageType.Information);
+ }
+
+ paths = pathsForBackup.Where(x => !x.Equals(m_MSSQLPathAllRegExp, StringComparison.OrdinalIgnoreCase) && !Regex.IsMatch(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
+ .Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToArray();
+
+ return changedOptions;
+ }
+
+ public bool ContainFilesForBackup(string[] paths)
+ {
+ if (paths == null || !Utility.Utility.IsClientWindows)
+ return false;
+
+ return paths.Where(x => !string.IsNullOrWhiteSpace(x)).Where(x => x.Equals(m_MSSQLPathAllRegExp, StringComparison.OrdinalIgnoreCase) || Regex.IsMatch(x, m_MSSQLPathDBRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).Any();
+ }
+
+ #endregion
+ }
+}
diff --git a/Duplicati/Library/Modules/Builtin/RunScript.cs b/Duplicati/Library/Modules/Builtin/RunScript.cs
index e4c331da6..6f9f69cf6 100644
--- a/Duplicati/Library/Modules/Builtin/RunScript.cs
+++ b/Duplicati/Library/Modules/Builtin/RunScript.cs
@@ -21,6 +21,7 @@ using System.IO;
using System.Text;
using System.Collections.Generic;
using Duplicati.Library.Utility;
+using Duplicati.Library.Interface;
namespace Duplicati.Library.Modules.Builtin
{
@@ -87,10 +88,10 @@ namespace Duplicati.Library.Modules.Builtin
if (!string.IsNullOrEmpty(m_requiredScript))
- Execute(m_requiredScript, "BEFORE", m_operationName, ref m_remoteurl, ref m_localpath, m_timeout, true, m_options, null);
+ Execute(m_requiredScript, "BEFORE", m_operationName, ref m_remoteurl, ref m_localpath, m_timeout, true, m_options, null, null);
if (!string.IsNullOrEmpty(m_startScript))
- Execute(m_startScript, "BEFORE", m_operationName, ref m_remoteurl, ref m_localpath, m_timeout, false, m_options, null);
+ Execute(m_startScript, "BEFORE", m_operationName, ref m_remoteurl, ref m_localpath, m_timeout, false, m_options, null, null);
}
public void OnFinish (object result)
@@ -98,10 +99,19 @@ namespace Duplicati.Library.Modules.Builtin
if (string.IsNullOrEmpty(m_finishScript))
return;
+
+ ParsedResultType level;
+ if (result is Exception)
+ level = ParsedResultType.Fatal;
+ else if (result != null && result is Library.Interface.IBasicResults)
+ level = ((IBasicResults)result).ParsedResult;
+ else
+ level = ParsedResultType.Error;
+
using (TempFile tmpfile = new TempFile())
{
SerializeResult(tmpfile, result);
- Execute(m_finishScript, "AFTER", m_operationName, ref m_remoteurl, ref m_localpath, m_timeout, false, m_options, tmpfile);
+ Execute(m_finishScript, "AFTER", m_operationName, ref m_remoteurl, ref m_localpath, m_timeout, false, m_options, tmpfile, level);
}
}
#endregion
@@ -171,7 +181,7 @@ namespace Duplicati.Library.Modules.Builtin
}
}
- private static void Execute(string scriptpath, string eventname, string operationname, ref string remoteurl, ref string[] localpath, int timeout, bool requiredScript, IDictionary<string, string> options, string datafile)
+ private static void Execute(string scriptpath, string eventname, string operationname, ref string remoteurl, ref string[] localpath, int timeout, bool requiredScript, IDictionary<string, string> options, string datafile, ParsedResultType? level)
{
try
{
@@ -191,6 +201,9 @@ namespace Duplicati.Library.Modules.Builtin
psi.EnvironmentVariables["DUPLICATI__EVENTNAME"] = eventname;
psi.EnvironmentVariables["DUPLICATI__OPERATIONNAME"] = operationname;
psi.EnvironmentVariables["DUPLICATI__REMOTEURL"] = remoteurl;
+ if (level != null)
+ psi.EnvironmentVariables["DUPLICATI__PARSED_RESULT"] = level.Value.ToString();
+
if (localpath != null)
psi.EnvironmentVariables["DUPLICATI__LOCALPATH"] = string.Join(System.IO.Path.PathSeparator.ToString(), localpath);
@@ -212,9 +225,9 @@ namespace Duplicati.Library.Modules.Builtin
if (requiredScript)
{
if (!p.HasExited)
- throw new Exception(Strings.RunScript.ScriptTimeoutError(scriptpath));
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.RunScript.ScriptTimeoutError(scriptpath));
else if (p.ExitCode != 0)
- throw new Exception(Strings.RunScript.InvalidExitCodeError(scriptpath, p.ExitCode));
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.RunScript.InvalidExitCodeError(scriptpath, p.ExitCode));
}
if (p.HasExited)
@@ -264,18 +277,18 @@ namespace Duplicati.Library.Modules.Builtin
value = value.Substring(1, value.Length - 2);
}
- if (string.Equals(key, "remoteurl", StringComparison.InvariantCultureIgnoreCase))
+ if (string.Equals(key, "remoteurl", StringComparison.OrdinalIgnoreCase))
{
remoteurl = value;
}
- else if (string.Equals(key, "localpath", StringComparison.InvariantCultureIgnoreCase))
+ else if (string.Equals(key, "localpath", StringComparison.OrdinalIgnoreCase))
{
localpath = value.Split(System.IO.Path.PathSeparator);
}
else if (
- string.Equals(key, "eventname", StringComparison.InvariantCultureIgnoreCase) ||
- string.Equals(key, "operationname", StringComparison.InvariantCultureIgnoreCase) ||
- string.Equals(key, "main-action", StringComparison.InvariantCultureIgnoreCase) ||
+ string.Equals(key, "eventname", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(key, "operationname", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(key, "main-action", StringComparison.OrdinalIgnoreCase) ||
key == ""
)
{
diff --git a/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs b/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs
new file mode 100644
index 000000000..fa78ea256
--- /dev/null
+++ b/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs
@@ -0,0 +1,334 @@
+using Duplicati.Library.Interface;
+using Duplicati.Library.Logging;
+using Duplicati.Library.Utility;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Duplicati.Library.Modules.Builtin {
+ public class SendHttpMessage : Interface.IGenericCallbackModule
+ {
+ #region Option names
+
+ /// <summary>
+ /// Option used to specify server URL
+ /// </summary>
+ private const string OPTION_URL = "send-http-url";
+ /// <summary>
+ /// Option used to specify report body
+ /// </summary>
+ private const string OPTION_MESSAGE = "send-http-message";
+ /// <summary>
+ /// Option used to specify the parameter name for the message
+ /// </summary>
+ private const string OPTION_MESSAGE_PARAMETER_NAME = "send-http-message-parameter-name";
+ /// <summary>
+ /// Option used to specify extra parameters
+ /// </summary>
+ private const string OPTION_EXTRA_PARAMETERS = "send-http-extra-parameters";
+ /// <summary>
+ /// Option used to specify report level
+ /// </summary>
+ private const string OPTION_SENDLEVEL = "send-http-level";
+ /// <summary>
+ /// Option used to specify if reports are sent for other operations than backups
+ /// </summary>
+ private const string OPTION_SENDALL = "send-http-any-operation";
+
+ #endregion
+
+ #region Option defaults
+ /// <summary>
+ /// The default message parameter name
+ /// </summary>
+ private const string DEFAULT_MESSAGE_PARAMETER_NAME = "message";
+ /// <summary>
+ /// The default mail level
+ /// </summary>
+ private const string DEFAULT_LEVEL = "all";
+ /// <summary>
+ /// The default message body
+ /// </summary>
+ private readonly string DEFAULT_MESSAGE = string.Format("Duplicati %OPERATIONNAME% report for %backup-name%{0}{0}%RESULT%", Environment.NewLine);
+ #endregion
+
+ #region Private variables
+
+ /// <summary>
+ /// The cached name of the operation
+ /// </summary>
+ private string m_operationname;
+ /// <summary>
+ /// The cached remote url
+ /// </summary>
+ private string m_remoteurl;
+ /// <summary>
+ /// The cached local path
+ /// </summary>
+ private string[] m_localpath;
+ /// <summary>
+ /// The cached set of options
+ /// </summary>
+ private IDictionary<string, string> m_options;
+ /// <summary>
+ /// The parsed result level
+ /// </summary>
+ private string m_parsedresultlevel = string.Empty;
+
+ /// <summary>
+ /// The HTTP report URL
+ /// </summary>
+ private string m_url;
+ /// <summary>
+ /// The message parameter name
+ /// </summary>
+ private string m_messageParameterName;
+ /// <summary>
+ /// The message parameter name
+ /// </summary>
+ private string m_extraParameters;
+ /// <summary>
+ /// The HTTP message
+ /// </summary>
+ private string m_body;
+ /// <summary>
+ /// The HTTP send level
+ /// </summary>
+ private string[] m_levels;
+ /// <summary>
+ /// True to send all operations
+ /// </summary>
+ private bool m_sendAll;
+
+ #endregion
+
+
+ #region Implementation of IGenericModule
+
+ /// <summary>
+ /// The module key, used to activate or deactivate the module on the commandline
+ /// </summary>
+ public string Key { get { return "sendhttp"; } }
+
+ /// <summary>
+ /// A localized string describing the module with a friendly name
+ /// </summary>
+ public string DisplayName { get { return Strings.SendHttpMessage.DisplayName;} }
+
+ /// <summary>
+ /// A localized description of the module
+ /// </summary>
+ public string Description { get { return Strings.SendHttpMessage.Description; } }
+
+ /// <summary>
+ /// A boolean value that indicates if the module should always be loaded.
+ /// If true, the user can choose to not load the module by entering the appropriate commandline option.
+ /// If false, the user can choose to load the module by entering the appropriate commandline option.
+ /// </summary>
+ public bool LoadAsDefault { get { return true; } }
+
+ /// <summary>
+ /// Gets a list of supported commandline arguments
+ /// </summary>
+ public IList<ICommandLineArgument> SupportedCommands
+ {
+ get
+ {
+ return new List<ICommandLineArgument>(new ICommandLineArgument[] {
+ new CommandLineArgument(OPTION_URL, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpurlShort, Strings.SendHttpMessage.SendhttpurlLong),
+ new CommandLineArgument(OPTION_MESSAGE, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpmessageShort, Strings.SendHttpMessage.SendhttpmessageLong, DEFAULT_MESSAGE),
+ new CommandLineArgument(OPTION_MESSAGE_PARAMETER_NAME, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpmessageparameternameShort, Strings.SendHttpMessage.SendhttpmessageparameternameLong, DEFAULT_MESSAGE_PARAMETER_NAME),
+ new CommandLineArgument(OPTION_EXTRA_PARAMETERS, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpextraparametersShort, Strings.SendHttpMessage.SendhttpextraparametersLong),
+ new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.SendHttpMessage.SendhttplevelShort, Strings.SendHttpMessage.SendhttplevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string[] { "All" } ).ToArray()),
+ new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendHttpMessage.SendhttpanyoperationShort, Strings.SendHttpMessage.SendhttpanyoperationLong)
+ });
+ }
+ }
+
+ /// <summary>
+ /// This method is the interception where the module can interact with the execution environment and modify the settings.
+ /// </summary>
+ /// <param name="commandlineOptions">A set of commandline options passed to Duplicati</param>
+ public void Configure(IDictionary<string, string> commandlineOptions)
+ {
+ //We need a URL to report to
+ commandlineOptions.TryGetValue(OPTION_URL, out m_url);
+ if (string.IsNullOrEmpty(m_url))
+ return;
+
+ commandlineOptions.TryGetValue(OPTION_MESSAGE_PARAMETER_NAME, out m_messageParameterName);
+ if (string.IsNullOrEmpty(m_messageParameterName))
+ m_messageParameterName = DEFAULT_MESSAGE_PARAMETER_NAME;
+
+ commandlineOptions.TryGetValue(OPTION_EXTRA_PARAMETERS, out m_extraParameters);
+
+ m_options = commandlineOptions;
+
+ string tmp;
+ commandlineOptions.TryGetValue(OPTION_SENDLEVEL, out tmp);
+ if (!string.IsNullOrEmpty(tmp))
+ m_levels =
+ tmp
+ .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x.Trim())
+ .ToArray();
+
+ if (m_levels == null || m_levels.Length == 0)
+ m_levels =
+ DEFAULT_LEVEL
+ .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x.Trim())
+ .ToArray();
+
+ m_sendAll = Utility.Utility.ParseBoolOption(commandlineOptions, OPTION_SENDALL);
+
+ commandlineOptions.TryGetValue(OPTION_MESSAGE, out m_body);
+ if (string.IsNullOrEmpty(m_body))
+ m_body = DEFAULT_MESSAGE;
+ }
+
+ #endregion
+
+ #region Implementation of IGenericCallbackModule
+
+ /// <summary>
+ /// Called when the operation starts
+ /// </summary>
+ /// <param name="operationname">The full name of the operation</param>
+ /// <param name="remoteurl">The remote backend url</param>
+ /// <param name="localpath">The local path, if required</param>
+ public void OnStart(string operationname, ref string remoteurl, ref string[] localpath)
+ {
+ m_operationname = operationname;
+ m_remoteurl = remoteurl;
+ m_localpath = localpath;
+ }
+
+ /// <summary>
+ /// Called when the operation finishes
+ /// </summary>
+ /// <param name="result">The result object, if this derives from an exception, the operation failed</param>
+ public void OnFinish(object result)
+ {
+ //If no URL is supplied, then skip
+ if (string.IsNullOrEmpty(m_url))
+ return;
+
+ //If we do not report this action, then skip
+ if (!m_sendAll && !string.Equals(m_operationname, "Backup", StringComparison.OrdinalIgnoreCase))
+ return;
+
+ ParsedResultType level;
+ if (result is Exception)
+ level = ParsedResultType.Fatal;
+ else if (result != null && result is Library.Interface.IBasicResults)
+ level = ((IBasicResults)result).ParsedResult;
+ else
+ level = ParsedResultType.Error;
+
+ m_parsedresultlevel = level.ToString();
+
+ if (string.Equals(m_operationname, "Backup", StringComparison.OrdinalIgnoreCase))
+ {
+ if (!m_levels.Any(x => string.Equals(x, "all", StringComparison.OrdinalIgnoreCase)))
+ {
+ //Check if this level should send mail
+ if (!m_levels.Any(x => string.Equals(x, level.ToString(), StringComparison.OrdinalIgnoreCase)))
+ return;
+ }
+ }
+
+ try
+ {
+ string body = m_body;
+ if (body != DEFAULT_MESSAGE && System.IO.File.Exists(body))
+ body = System.IO.File.ReadAllText(body);
+
+ body = ReplaceTemplate(body, result);
+
+ SendMessages(body);
+ }
+ catch (Exception ex)
+ {
+ Exception top = ex;
+ var sb = new StringBuilder();
+ while (top != null)
+ {
+ if (sb.Length != 0)
+ sb.Append("--> ");
+ sb.AppendFormat("{0}: {1}{2}", top.GetType().FullName, top.Message, Environment.NewLine);
+ top = top.InnerException;
+ }
+
+ Logging.Log.WriteMessage(Strings.SendHttpMessage.SendMessageError(sb.ToString()), LogMessageType.Warning, ex);
+ }
+ }
+
+ #endregion
+
+ private void SendMessages(string message) {
+ Exception ex = null;
+
+ var request = (HttpWebRequest)WebRequest.Create(m_url);
+
+ var postData = $"{m_messageParameterName}={System.Uri.EscapeDataString(message)}";
+ if (!string.IsNullOrEmpty(m_extraParameters))
+ {
+ postData += $"&{System.Uri.EscapeUriString(m_extraParameters)}";
+ }
+ var data = Encoding.UTF8.GetBytes(postData);
+
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded";
+ request.ContentLength = data.Length;
+
+ try
+ {
+ using (var stream = request.GetRequestStream())
+ {
+ stream.Write(data, 0, data.Length);
+ }
+
+ var response = (HttpWebResponse)request.GetResponse();
+ var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
+ }
+ catch (Exception e)
+ {
+ ex = e;
+ }
+
+ if (ex != null)
+ throw ex;
+ }
+
+ private string ReplaceTemplate(string input, object result)
+ {
+ input = Regex.Replace(input, "\\%OPERATIONNAME\\%", m_operationname ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+ input = Regex.Replace(input, "\\%REMOTEURL\\%", m_remoteurl ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+ input = Regex.Replace(input, "\\%LOCALPATH\\%", m_localpath == null ? "" : string.Join(System.IO.Path.PathSeparator.ToString(), m_localpath), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+ input = Regex.Replace(input, "\\%PARSEDRESULT\\%", m_parsedresultlevel ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+ if (input.IndexOf("%RESULT%", StringComparison.OrdinalIgnoreCase) >= 0)
+ using (TempFile tf = new TempFile())
+ {
+ RunScript.SerializeResult(tf, result);
+ input = Regex.Replace(input, "\\%RESULT\\%", System.IO.File.ReadAllText(tf), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+ }
+
+ foreach (KeyValuePair<string, string> kv in m_options)
+ input = Regex.Replace(input, "\\%" + kv.Key + "\\%", kv.Value ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+
+ if (!m_options.ContainsKey("backup-name"))
+ input = Regex.Replace(input, "\\%backup-name\\%", System.IO.Path.GetFileNameWithoutExtension(Duplicati.Library.Utility.Utility.getEntryAssembly().Location) ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+
+ input = Regex.Replace(input, "\\%[^\\%]+\\%", "");
+ return input;
+ }
+
+ }
+}
diff --git a/Duplicati/Library/Modules/Builtin/SendJabberMessage.cs b/Duplicati/Library/Modules/Builtin/SendJabberMessage.cs
index a692d8c53..e57d3bbf3 100644
--- a/Duplicati/Library/Modules/Builtin/SendJabberMessage.cs
+++ b/Duplicati/Library/Modules/Builtin/SendJabberMessage.cs
@@ -51,29 +51,13 @@ namespace Duplicati.Library.Modules.Builtin
/// <summary>
/// The default mail level
/// </summary>
- private const ReportLevels DEFAULT_LEVEL = ReportLevels.All;
+ private const string DEFAULT_LEVEL = "all";
/// <summary>
- /// The default mail body
+ /// The default message body
/// </summary>
private readonly string DEFAULT_MESSAGE = string.Format("Duplicati %OPERATIONNAME% report for %backup-name%{0}{0}%RESULT%", Environment.NewLine);
- /// <summary>
- /// The default mail sender
- /// </summary>
- private const string DEFAULT_SENDER = "no-reply";
#endregion
- /// <summary>
- /// The allowed mail levels
- /// </summary>
- [Flags]
- private enum ReportLevels
- {
- Success = 0x1,
- Warning = 0x2,
- Error = 0x4,
- All = Success | Warning | Error
- }
-
#region Private variables
/// <summary>
@@ -93,7 +77,7 @@ namespace Duplicati.Library.Modules.Builtin
/// </summary>
private IDictionary<string, string> m_options;
/// <summary>
- /// The parsed result level if the operation is a backup, empty otherwise
+ /// The parsed result level if
/// </summary>
private string m_parsedresultlevel = string.Empty;
@@ -116,7 +100,7 @@ namespace Duplicati.Library.Modules.Builtin
/// <summary>
/// The XMPP send level
/// </summary>
- private ReportLevels m_level;
+ private string[] m_levels;
/// <summary>
/// True to send all operations
/// </summary>
@@ -161,7 +145,7 @@ namespace Duplicati.Library.Modules.Builtin
new CommandLineArgument(OPTION_MESSAGE, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmppmessageShort, Strings.SendJabberMessage.SendxmppmessageLong, DEFAULT_MESSAGE),
new CommandLineArgument(OPTION_USERNAME, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmppusernameShort, Strings.SendJabberMessage.SendxmppusernameLong),
new CommandLineArgument(OPTION_PASSWORD, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmpppasswordShort, Strings.SendJabberMessage.SendxmpppasswordLong),
- new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.SendJabberMessage.SendxmpplevelShort, Strings.SendJabberMessage.SendxmpplevelLong(ReportLevels.Success.ToString(), ReportLevels.Warning.ToString(), ReportLevels.Error.ToString(), ReportLevels.All.ToString()), DEFAULT_LEVEL.ToString(), null, Enum.GetNames(typeof(ReportLevels))),
+ new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.SendJabberMessage.SendxmpplevelShort, Strings.SendJabberMessage.SendxmpplevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string[] { "All" } ).ToArray()),
new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendJabberMessage.SendxmppanyoperationShort, Strings.SendJabberMessage.SendxmppanyoperationLong),
});
}
@@ -183,23 +167,23 @@ namespace Duplicati.Library.Modules.Builtin
commandlineOptions.TryGetValue(OPTION_MESSAGE, out m_body);
m_options = commandlineOptions;
- m_level = 0;
-
string tmp;
commandlineOptions.TryGetValue(OPTION_SENDLEVEL, out tmp);
if (!string.IsNullOrEmpty(tmp))
- foreach(var s in tmp.Split(new string[] {","}, StringSplitOptions.RemoveEmptyEntries))
- {
- if (string.IsNullOrEmpty(s))
- continue;
-
- ReportLevels m;
- if (Enum.TryParse(s.Trim(), true, out m))
- m_level |= m;
- }
-
- if (m_level == 0)
- m_level = DEFAULT_LEVEL;
+ m_levels =
+ tmp
+ .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x.Trim())
+ .ToArray();
+
+ if (m_levels == null || m_levels.Length == 0)
+ m_levels =
+ DEFAULT_LEVEL
+ .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x.Trim())
+ .ToArray();
m_sendAll = Utility.Utility.ParseBoolOption(commandlineOptions, OPTION_SENDALL);
@@ -235,25 +219,25 @@ namespace Duplicati.Library.Modules.Builtin
return;
//If we do not report this action, then skip
- if (!m_sendAll && !string.Equals(m_operationname, "Backup", StringComparison.InvariantCultureIgnoreCase))
+ if (!m_sendAll && !string.Equals(m_operationname, "Backup", StringComparison.OrdinalIgnoreCase))
return;
- if (string.Equals(m_operationname, "Backup", StringComparison.InvariantCultureIgnoreCase))
- {
- ReportLevels level;
- if (result is Exception)
- level = ReportLevels.Error;
- else if (result != null && result is Library.Interface.IBackupResults && (result as Library.Interface.IBackupResults).Errors.Count() > 0)
- level = ReportLevels.Warning;
- else
- level = ReportLevels.Success;
+ ParsedResultType level;
+ if (result is Exception)
+ level = ParsedResultType.Fatal;
+ else if (result != null && result is Library.Interface.IBasicResults)
+ level = ((IBasicResults)result).ParsedResult;
+ else
+ level = ParsedResultType.Error;
- m_parsedresultlevel = level.ToString();
+ m_parsedresultlevel = level.ToString();
- if (m_level != ReportLevels.All)
+ if (string.Equals(m_operationname, "Backup", StringComparison.OrdinalIgnoreCase))
+ {
+ if (!m_levels.Any(x => string.Equals(x, "all", StringComparison.OrdinalIgnoreCase)))
{
//Check if this level should send mail
- if ((m_level & level) == 0)
+ if (!m_levels.Any(x => string.Equals(x, level.ToString(), StringComparison.OrdinalIgnoreCase)))
return;
}
}
@@ -297,7 +281,7 @@ namespace Duplicati.Library.Modules.Builtin
con.UseSSL = true;
var resource = uri.Path ?? "";
- if (resource.StartsWith("/"))
+ if (resource.StartsWith("/", StringComparison.Ordinal))
resource = resource.Substring(1);
if (string.IsNullOrWhiteSpace(resource))
@@ -365,7 +349,7 @@ namespace Duplicati.Library.Modules.Builtin
input = Regex.Replace(input, "\\%REMOTEURL\\%", m_remoteurl ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%LOCALPATH\\%", m_localpath == null ? "" : string.Join(System.IO.Path.PathSeparator.ToString(), m_localpath), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%PARSEDRESULT\\%", m_parsedresultlevel ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
- if (input.IndexOf("%RESULT%", StringComparison.InvariantCultureIgnoreCase) >= 0)
+ if (input.IndexOf("%RESULT%", StringComparison.OrdinalIgnoreCase) >= 0)
using (TempFile tf = new TempFile())
{
RunScript.SerializeResult(tf, result);
diff --git a/Duplicati/Library/Modules/Builtin/SendMail.cs b/Duplicati/Library/Modules/Builtin/SendMail.cs
index 438959e1a..2afb0a733 100644
--- a/Duplicati/Library/Modules/Builtin/SendMail.cs
+++ b/Duplicati/Library/Modules/Builtin/SendMail.cs
@@ -68,7 +68,7 @@ namespace Duplicati.Library.Modules.Builtin
/// <summary>
/// The default mail level
/// </summary>
- private const MailLevels DEFAULT_LEVEL = MailLevels.All;
+ private const string DEFAULT_LEVEL = "all";
/// <summary>
/// The default mail body
/// </summary>
@@ -79,20 +79,7 @@ namespace Duplicati.Library.Modules.Builtin
private const string DEFAULT_SENDER = "no-reply";
#endregion
- /// <summary>
- /// The allowed mail levels
- /// </summary>
- [Flags]
- private enum MailLevels
- {
- Success = 0x1,
- Warning = 0x2,
- Error = 0x4,
- All = Success | Warning | Error
- }
-
#region Private variables
-
/// <summary>
/// The cached name of the operation
/// </summary>
@@ -110,7 +97,7 @@ namespace Duplicati.Library.Modules.Builtin
/// </summary>
private IDictionary<string, string> m_options;
/// <summary>
- /// The parsed result level if the operation is a backup, empty otherwise
+ /// The parsed result level
/// </summary>
private string m_parsedresultlevel = string.Empty;
@@ -145,7 +132,7 @@ namespace Duplicati.Library.Modules.Builtin
/// <summary>
/// The mail send level
/// </summary>
- private MailLevels m_level;
+ private string[] m_levels;
/// <summary>
/// True to send all operations
/// </summary>
@@ -193,7 +180,7 @@ namespace Duplicati.Library.Modules.Builtin
new CommandLineArgument(OPTION_SERVER, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionServerShort, Strings.SendMail.OptionServerLong),
new CommandLineArgument(OPTION_USERNAME, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionUsernameShort, Strings.SendMail.OptionUsernameLong),
new CommandLineArgument(OPTION_PASSWORD, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionPasswordShort, Strings.SendMail.OptionPasswordLong),
- new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionSendlevelShort, Strings.SendMail.OptionSendlevelLong(MailLevels.Success.ToString(), MailLevels.Warning.ToString(), MailLevels.Error.ToString(), MailLevels.All.ToString()), DEFAULT_LEVEL.ToString(), null, Enum.GetNames(typeof(MailLevels))),
+ new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionSendlevelShort, Strings.SendMail.OptionSendlevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string [] { "All" }).ToArray()),
new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendMail.OptionSendallShort, Strings.SendMail.OptionSendallLong),
});
}
@@ -218,24 +205,24 @@ namespace Duplicati.Library.Modules.Builtin
commandlineOptions.TryGetValue(OPTION_BODY, out m_body);
m_options = commandlineOptions;
- m_level = 0;
-
string tmp;
commandlineOptions.TryGetValue(OPTION_SENDLEVEL, out tmp);
if (!string.IsNullOrEmpty(tmp))
- foreach(var s in tmp.Split(new string[] {","}, StringSplitOptions.RemoveEmptyEntries))
- {
- if (string.IsNullOrEmpty(s))
- continue;
-
- MailLevels m;
- if (Enum.TryParse(s.Trim(), true, out m))
- m_level |= m;
- }
-
- if (m_level == 0)
- m_level = DEFAULT_LEVEL;
-
+ m_levels =
+ tmp
+ .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x.Trim())
+ .ToArray();
+
+ if (m_levels == null || m_levels.Length == 0)
+ m_levels =
+ DEFAULT_LEVEL
+ .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .Select(x => x.Trim())
+ .ToArray();
+
m_sendAll = Utility.Utility.ParseBoolOption(commandlineOptions, OPTION_SENDALL);
if (string.IsNullOrEmpty(m_subject))
@@ -274,25 +261,25 @@ namespace Duplicati.Library.Modules.Builtin
return;
//If we do not report this action, then skip
- if (!m_sendAll && !string.Equals(m_operationname, "Backup", StringComparison.InvariantCultureIgnoreCase))
+ if (!m_sendAll && !string.Equals(m_operationname, "Backup", StringComparison.OrdinalIgnoreCase))
return;
- if (string.Equals(m_operationname, "Backup", StringComparison.InvariantCultureIgnoreCase))
- {
- MailLevels level;
- if (result is Exception)
- level = MailLevels.Error;
- else if (result != null && result is Library.Interface.IBackupResults && (result as Library.Interface.IBackupResults).Errors.Count() > 0)
- level = MailLevels.Warning;
- else
- level = MailLevels.Success;
-
- m_parsedresultlevel = level.ToString();
+ ParsedResultType level;
+ if (result is Exception)
+ level = ParsedResultType.Fatal;
+ else if (result != null && result is Library.Interface.IBasicResults)
+ level = ((IBasicResults)result).ParsedResult;
+ else
+ level = ParsedResultType.Error;
+
+ m_parsedresultlevel = level.ToString();
- if (m_level != MailLevels.All)
+ if (string.Equals(m_operationname, "Backup", StringComparison.OrdinalIgnoreCase))
+ {
+ if (!m_levels.Any(x => string.Equals(x, "all", StringComparison.OrdinalIgnoreCase)))
{
//Check if this level should send mail
- if ((m_level & level) == 0)
+ if (!m_levels.Any(x => string.Equals(x, level.ToString(), StringComparison.OrdinalIgnoreCase)))
return;
}
}
@@ -301,7 +288,7 @@ namespace Duplicati.Library.Modules.Builtin
{
string body = m_body;
string subject = m_subject;
- if (body != DEFAULT_BODY && System.IO.File.Exists(body))
+ if (body != DEFAULT_BODY && System.IO.Path.IsPathRooted(body) && System.IO.File.Exists(body))
body = System.IO.File.ReadAllText(body);
body = ReplaceTemplate(body, result, false);
@@ -313,13 +300,13 @@ namespace Duplicati.Library.Modules.Builtin
if(MailboxAddress.TryParse(s.Replace("\"", ""), out mailbox))
message.To.Add(mailbox);
- MailboxAddress mailboxToFirst = (MailboxAddress) message.To[0];
- string toMailDomain = mailboxToFirst.Address.Substring(mailboxToFirst.Address.LastIndexOf("@") + 1);
+ var mailboxToFirst = (MailboxAddress) message.To.First();
+ string toMailDomain = mailboxToFirst.Address.Substring(mailboxToFirst.Address.LastIndexOf("@", StringComparison.Ordinal) + 1);
string from = m_from.Trim().Replace("\"", "");
if (from.IndexOf('@') < 0)
{
- if (from.EndsWith(">"))
+ if (from.EndsWith(">", StringComparison.Ordinal))
from = from.Insert(from.Length - 1, "@" + toMailDomain);
else
from = string.Format("No Reply - Backup report <{0}@{1}>", from, toMailDomain);
@@ -337,13 +324,13 @@ namespace Duplicati.Library.Modules.Builtin
var dnslite = new DnsLib.DnsLite();
var dnslist = new List<string>();
- //Grab all IPv4 adresses
+ //Grab all IPv4 addresses
foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
try
{
- foreach (IPAddress dnsAdress in networkInterface.GetIPProperties().DnsAddresses)
- if (dnsAdress.AddressFamily == AddressFamily.InterNetwork)
- dnslist.Add(dnsAdress.ToString());
+ foreach (IPAddress dnsAddress in networkInterface.GetIPProperties().DnsAddresses)
+ if (dnsAddress.AddressFamily == AddressFamily.InterNetwork)
+ dnslist.Add(dnsAddress.ToString());
}
catch { }
@@ -360,23 +347,25 @@ namespace Duplicati.Library.Modules.Builtin
dnslist.Add("208.67.222.222");
dnslist.Add("208.67.220.220");
}
-
- var oldStyleList = new ArrayList();
- foreach(var s in dnslist)
- oldStyleList.Add(s);
-
- dnslite.setDnsServers(oldStyleList);
-
- servers = dnslite.getMXRecords(toMailDomain).OfType<MXRecord>().OrderBy(record => record.preference).Select(x => "smtp://" + x.exchange).Distinct().ToList();
+
+ var records = new List<MXRecord>();
+ foreach (var s in dnslist)
+ {
+ var res = dnslite.getMXRecords(toMailDomain, s);
+ if (res != null)
+ records.AddRange(res.OfType<MXRecord>());
+ }
+
+ servers = records.OrderBy(record => record.preference).Select(x => "smtp://" + x.exchange).Distinct().ToList();
if (servers.Count == 0)
throw new IOException(Strings.SendMail.FailedToLookupMXServer(OPTION_SERVER));
}
else
{
servers = (from n in m_server.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
- let srv = (n == null || n.IndexOf("://", StringComparison.InvariantCultureIgnoreCase) > 0) ? n : "smtp://" + n
- where !string.IsNullOrEmpty(srv)
- select srv).Distinct().ToList();
+ let srv = (n == null || n.IndexOf("://", StringComparison.OrdinalIgnoreCase) > 0) ? n : "smtp://" + n
+ where !string.IsNullOrEmpty(srv)
+ select srv).Distinct().ToList();
}
Exception lastEx = null;
@@ -398,7 +387,12 @@ namespace Duplicati.Library.Modules.Builtin
{
client.Timeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;
- client.Connect(new System.Uri(server));
+ // Backward compatibility fix for setup prior to using MailKit
+ var uri = new System.Uri(server);
+ if (uri.Scheme.ToLowerInvariant() == "tls")
+ uri = new System.Uri("smtp://" + uri.Host + ":" + (uri.Port <= 0 ? 587 : uri.Port) + "/?starttls=always");
+
+ client.Connect(uri);
if (!string.IsNullOrEmpty(m_username) && !string.IsNullOrEmpty(m_password))
client.Authenticate(m_username, m_password);
@@ -410,7 +404,8 @@ namespace Duplicati.Library.Modules.Builtin
finally
{
var log = Encoding.UTF8.GetString(ms.GetBuffer());
- Logging.Log.WriteMessage(Strings.SendMail.SendMailLog(log), LogMessageType.Profiling);
+ if (!string.IsNullOrWhiteSpace(log))
+ Logging.Log.WriteMessage(Strings.SendMail.SendMailLog(log), LogMessageType.Profiling);
}
}
@@ -457,7 +452,7 @@ namespace Duplicati.Library.Modules.Builtin
}
else
{
- if (input.IndexOf("%RESULT%", StringComparison.InvariantCultureIgnoreCase) >= 0)
+ if (input.IndexOf("%RESULT%", StringComparison.OrdinalIgnoreCase) >= 0)
using(TempFile tf = new TempFile())
{
RunScript.SerializeResult(tf, result);
diff --git a/Duplicati/Library/Modules/Builtin/Strings.cs b/Duplicati/Library/Modules/Builtin/Strings.cs
index c5db3f410..60f86ddd5 100644
--- a/Duplicati/Library/Modules/Builtin/Strings.cs
+++ b/Duplicati/Library/Modules/Builtin/Strings.cs
@@ -5,7 +5,7 @@ using System;
namespace Duplicati.Library.Modules.Builtin.Strings {
internal static class ConsolePasswordInput {
public static string ConfirmPassphrasePrompt { get { return LC.L(@"Confirm encryption passphrase"); } }
- public static string Description { get { return LC.L(@"This module will ask the user for a encryption password on the commandline unless encryption is disabled or the password is supplied by other means"); } }
+ public static string Description { get { return LC.L(@"This module will ask the user for an encryption password on the command line unless encryption is disabled or the password is supplied by other means"); } }
public static string Displayname { get { return LC.L(@"Password prompt"); } }
public static string EmptyPassphraseError { get { return LC.L(@"Empty passphrases are not allowed"); } }
public static string EnterPassphrasePrompt { get { return LC.L(@"Enter encryption passphrase"); } }
@@ -14,7 +14,7 @@ namespace Duplicati.Library.Modules.Builtin.Strings {
internal static class CheckMonoSSL {
public static string Description { get { return LC.L(@"When running with Mono, this module will check if any certificates are installed and suggest installing them otherwise"); } }
public static string Displayname { get { return LC.L(@"Check for SSL certificates"); } }
- public static string ErrorMessage { get { return LC.L(@"No certificates found, you can install some with this command:{0} mozroots --import --sync{0}Read more: {1}", Environment.NewLine, "http://manpages.ubuntu.com/manpages/natty/man1/mozroots.1.html"); } }
+ public static string ErrorMessage { get { return LC.L(@"No certificates found, you can install some with one of these commands:{0} cert-sync /etc/ssl/certs/ca-certificates.crt #for Debian based systems{0} cert-sync /etc/pki/tls/certs/ca-bundle.crt #for RedHat derivatives{0}Read more: {1}", Environment.NewLine, "http://www.mono-project.com/docs/about-mono/releases/3.12.0/#cert-sync"); } }
}
internal static class HttpOptions {
public static string Description { get { return LC.L(@"This module exposes a number of properties that can be used to change the way http requests are issued"); } }
@@ -24,14 +24,29 @@ namespace Duplicati.Library.Modules.Builtin.Strings {
public static string DescriptionAcceptHashShort { get { return LC.L(@"Optionally accept a known SSL certificate"); } }
public static string DisableExpect100Long { get { return LC.L(@"The default HTTP request has the header ""Expect: 100-Continue"" attached, which allows some optimizations when authenticating, but also breaks some web servers, causing them to report ""417 - Expectation failed"""); } }
public static string DisableExpect100Short { get { return LC.L(@"Disable the expect header"); } }
- public static string DisableNagleLong { get { return LC.L(@"By default the http requests use the RFC 896 nagling algorithm to support transfer of small packages more effeciently."); } }
+ public static string DisableNagleLong { get { return LC.L(@"By default the http requests use the RFC 896 nagling algorithm to support transfer of small packages more efficiently."); } }
public static string DisableNagleShort { get { return LC.L(@"Disable nagling"); } }
public static string DisplayName { get { return LC.L(@"Configure http requests"); } }
public static string OauthurlShort { get { return LC.L(@"Alternate OAuth URL"); } }
public static string OauthurlLong { get { return LC.L(@"Duplicati uses an external server to support the OAuth authentication flow. If you have set up your own Duplicati OAuth server, you can supply the refresh url."); } }
public static string SslversionsShort { get { return LC.L(@"Sets allowed SSL versions"); } }
public static string SslversionsLong { get { return LC.L(@"This option changes the default SSL versions allowed. This is an advanced option and should only be used if you want to enhance security or work around an issue with a particular SSL protocol."); } }
- }
+ public static string OperationtimeoutShort { get { return LC.L(@"Sets the default operation timeout"); } }
+ public static string OperationtimeoutLong { get { return LC.L(@"This option changes the default timeout for any HTTP request, the time covers the entire operation from initial packet to shutdown"); } }
+ public static string ReadwritetimeoutShort { get { return LC.L(@"Sets readwrite"); } }
+ public static string ReadwritetimeoutLong { get { return LC.L(@"This option changes the default read-write timeout. Read-write timeouts are used to detect a stalled requests, and this option configures the maximum time between activity on a connection."); } }
+ public static string BufferrequestsShort { get { return LC.L(@"Sets HTTP buffering"); } }
+ public static string BufferrequestsLong { get { return LC.L(@"This option sets the HTTP buffering. Setting this to ""{0}"" can cause memory leaks, but can also improve performance in some cases.", "true"); } }
+ }
+ internal static class HyperVOptions {
+ public static string Description { get { return LC.L(@"This module works internaly to parse source parameters to backup Hyper-V virtual machines"); } }
+ public static string DisplayName { get { return LC.L(@"Configure Hyper-V module"); } }
+ }
+ internal static class MSSQLOptions
+ {
+ public static string Description { get { return LC.L(@"This module works internaly to parse source parameters to backup Microsoft SQL Server databases"); } }
+ public static string DisplayName { get { return LC.L(@"Configure Microsoft SQL Server module"); } }
+ }
internal static class RunScript {
public static string Description { get { return LC.L(@"Executes a script before starting an operation, and again on completion"); } }
public static string DisplayName { get { return LC.L(@"Run script"); } }
@@ -52,7 +67,7 @@ namespace Duplicati.Library.Modules.Builtin.Strings {
public static string Description { get { return LC.L(@"This module can send email after an operation completes"); } }
public static string Displayname { get { return LC.L(@"Send mail"); } }
public static string FailedToLookupMXServer(string optionname) { return LC.L(@"Unable to find the destination mail server through MX lookup, please use the option {0} to specify what smtp server to use.", optionname); }
- public static string OptionBodyLong { get { return LC.L(@"This value can be a filename. If a the file exists, the file contents will be used as the message body.
+ public static string OptionBodyLong { get { return LC.L(@"This value can be a filename. If the file exists, the file contents will be used as the message body.
In the message body, certain tokens are replaced:
%OPERATIONNAME% - The name of the operation, normally ""Backup""
@@ -60,30 +75,30 @@ In the message body, certain tokens are replaced:
%LOCALPATH% - The path to the local files or folders involved in the operation (if any)
%PARSEDRESULT% - The parsed result, if the operation is a backup. Possible values are: Error, Warning, Success
-All commandline options are also reported within %value%, e.g. %volsize%. Any unknown/unset value is removed."); } }
+All command line options are also reported within %value%, e.g. %volsize%. Any unknown/unset value is removed."); } }
public static string OptionBodyShort { get { return LC.L(@"The message body"); } }
public static string OptionPasswordLong { get { return LC.L(@"The password used to authenticate with the SMTP server if required."); } }
public static string OptionPasswordShort { get { return LC.L(@"SMTP Password"); } }
- public static string OptionRecipientLong { get { return LC.L(@"This setting is required if mail should be sent, all other settings have default values. You can supply multiple email adresses seperated with commas, and you can use the normal adress format as specified by RFC2822 section 3.4.
+ public static string OptionRecipientLong { get { return LC.L(@"This setting is required if mail should be sent, all other settings have default values. You can supply multiple email addresses separated with commas, and you can use the normal address format as specified by RFC2822 section 3.4.
Example with 3 recipients:
Peter Sample <peter@example.com>, John Sample <john@example.com>, admin@example.com"); } }
public static string OptionRecipientShort { get { return LC.L(@"Email recipient(s)"); } }
public static string OptionSendallLong { get { return LC.L(@"By default, mail will only be sent after a Backup operation. Use this option to send mail for all operations."); } }
public static string OptionSendallShort { get { return LC.L(@"Send email for all operations"); } }
- public static string OptionSenderLong { get { return LC.L(@"Adress of the email sender. If no host is supplied, the hostname of the first recipient is used. Examples of allowed formats:
+ public static string OptionSenderLong { get { return LC.L(@"Address of the email sender. If no host is supplied, the hostname of the first recipient is used. Examples of allowed formats:
sender
sender@example.com
Mail Sender <sender>
Mail Sender <sender@example.com>"); } }
public static string OptionSenderShort { get { return LC.L(@"Email sender"); } }
- public static string OptionSendlevelLong(string success, string warning, string error, string all) { return LC.L(@"You can specify one of ""{0}"", ""{1}"", ""{2}"". You can supply multiple options with a comma seperator, e.g. ""{0},{1}"". The special value ""{3}"" is a shorthand for ""{0},{1},{2}"" and will cause all backup operations to send an email.", success, warning, error, all); }
+ public static string OptionSendlevelLong(string success, string warning, string error, string fatal, string all) { return LC.L(@"You can specify one of ""{0}"", ""{1}"", ""{2}"", ""{3}"". You can supply multiple options with a comma separator, e.g. ""{0},{1}"". The special value ""{4}"" is a shorthand for ""{0},{1},{2},{3}"" and will cause all backup operations to send an email.", success, warning, error, fatal, all); }
public static string OptionSendlevelShort { get { return LC.L(@"The messages to send"); } }
- public static string OptionServerLong { get { return LC.L(@"A url for the SMTP server, e.g. smtp://example.com:25. Multiple servers can be supplied in a prioritized list, seperated with semicolon. If a server fails, the next server in the list is tried, until the message has been sent.
+ public static string OptionServerLong { get { return LC.L(@"A url for the SMTP server, e.g. smtp://example.com:25. Multiple servers can be supplied in a prioritized list, separated with semicolon. If a server fails, the next server in the list is tried, until the message has been sent.
If no server is supplied, a DNS lookup is performed to find the first recipient's MX record, and all SMTP servers are tried in their priority order until the message is sent.
-To enable SMTP over SSL, use the format smtps://example.com. To enable SMTP STARTTLS, use the format smtp://example.com:25/?starttls=when-available or smtp://example.com:25/?starttls=always. If no port is specified, port 25 is used for non-ssl, and 587 for SSL connections."); } }
+To enable SMTP over SSL, use the format smtps://example.com. To enable SMTP STARTTLS, use the format smtp://example.com:25/?starttls=when-available or smtp://example.com:25/?starttls=always. If no port is specified, port 25 is used for non-ssl, and 465 for SSL connections. To force not to use STARTTLS use smtp://example.com:25/?starttls=never."); } }
public static string OptionServerShort { get { return LC.L(@"SMTP Url"); } }
public static string OptionSubjectLong(string optionname) { return LC.L(@"This setting supplies the email subject. Values are replaced as described in the description for --{0}.", optionname); }
public static string OptionSubjectShort { get { return LC.L(@"The email subject"); } }
@@ -96,9 +111,9 @@ To enable SMTP over SSL, use the format smtps://example.com. To enable SMTP STAR
}
internal static class SendJabberMessage {
public static string SendxmpptoShort { get { return LC.L(@"XMPP recipient email"); } }
- public static string SendxmpptoLong { get { return LC.L(@"The users who should have the messages sent, specify multiple users seperated with commas"); } }
+ public static string SendxmpptoLong { get { return LC.L(@"The users who should have the messages sent, specify multiple users separated with commas"); } }
public static string SendxmppmessageShort { get { return LC.L(@"The message template"); } }
- public static string SendxmppmessageLong { get { return LC.L(@"This value can be a filename. If a the file exists, the file contents will be used as the message.
+ public static string SendxmppmessageLong { get { return LC.L(@"This value can be a filename. If the file exists, the file contents will be used as the message.
In the message, certain tokens are replaced:
%OPERATIONNAME% - The name of the operation, normally ""Backup""
@@ -106,19 +121,46 @@ In the message, certain tokens are replaced:
%LOCALPATH% - The path to the local files or folders involved in the operation (if any)
%PARSEDRESULT% - The parsed result, if the operation is a backup. Possible values are: Error, Warning, Success
-All commandline options are also reported within %value%, e.g. %volsize%. Any unknown/unset value is removed."); } }
+All command line options are also reported within %value%, e.g. %volsize%. Any unknown/unset value is removed."); } }
public static string SendxmppusernameShort { get { return LC.L(@"The XMPP username"); } }
public static string SendxmppusernameLong { get { return LC.L(@"The username for the account that will send the message, including the hostname. I.e. ""account@jabber.org/Home"""); } }
public static string SendxmpppasswordShort { get { return LC.L(@"The XMPP password"); } }
public static string SendxmpppasswordLong { get { return LC.L(@"The password for the account that will send the message"); } }
public static string SendxmpplevelShort { get { return LC.L(@"The messages to send"); } }
- public static string SendxmpplevelLong(string success, string warning, string error, string all) { return LC.L(@"You can specify one of ""{0}"", ""{1}"", ""{2}"".
-You can supply multiple options with a comma seperator, e.g. ""{0},{1}"". The special value ""{3}"" is a shorthand for ""{0},{1},{2}"" and will cause all backup operations to send a message.", success, warning, error, all); }
+ public static string SendxmpplevelLong(string success, string warning, string error, string fatal, string all) { return LC.L(@"You can specify one of ""{0}"", ""{1}"", ""{2}"", ""{3}"".
+You can supply multiple options with a comma separator, e.g. ""{0},{1}"". The special value ""{4}"" is a shorthand for ""{0},{1},{2},{3}"" and will cause all backup operations to send a message.", success, warning, error, fatal, all); }
public static string SendxmppanyoperationShort { get { return LC.L(@"Send messages for all operations"); } }
public static string SendxmppanyoperationLong { get { return LC.L(@"By default, messages will only be sent after a Backup operation. Use this option to send messages for all operations"); } }
public static string DisplayName { get { return LC.L(@"XMPP report module"); } }
- public static string Description { get { return LC.L(@"This module provides support for sending status reports via XMPP messagesß"); } }
- public static string LoginTimeoutError { get { return LC.L(@"Timeout occured while logging in to jabber server"); } }
+ public static string Description { get { return LC.L(@"This module provides support for sending status reports via XMPP messages"); } }
+ public static string LoginTimeoutError { get { return LC.L(@"Timeout occurred while logging in to jabber server"); } }
public static string SendMessageError(string message) { return LC.L(@"Failed to send jabber message: {0}", message); }
}
+
+ internal static class SendHttpMessage {
+ public static string DisplayName { get { return LC.L(@"HTTP report module"); } }
+ public static string Description { get { return LC.L(@"This module provides support for sending status reports via HTTP messages"); } }
+ public static string SendhttpurlShort { get { return LC.L(@"HTTP report url"); } }
+ public static string SendhttpurlLong { get { return LC.L(@"HTTP report url"); } }
+ public static string SendhttpmessageShort { get { return LC.L(@"The message template"); } }
+ public static string SendhttpmessageLong { get { return LC.L(@"This value can be a filename. If the file exists, the file contents will be used as the message.
+
+In the message, certain tokens are replaced:
+%OPERATIONNAME% - The name of the operation, normally ""Backup""
+%REMOTEURL% - Remote server url
+%LOCALPATH% - The path to the local files or folders involved in the operation (if any)
+%PARSEDRESULT% - The parsed result, if the operation is a backup. Possible values are: Error, Warning, Success
+
+All command line options are also reported within %value%, e.g. %volsize%. Any unknown/unset value is removed."); } }
+ public static string SendhttpmessageparameternameShort { get { return LC.L(@"The name of the parameter to send the message as"); } }
+ public static string SendhttpmessageparameternameLong { get { return LC.L(@"The name of the parameter to send the message as."); } }
+ public static string SendhttpextraparametersShort { get { return LC.L(@"Extra parameters to add to the http message"); } }
+ public static string SendhttpextraparametersLong { get { return LC.L(@"Extra parameters to add to the http message. I.e. ""parameter1=value1&parameter2=value2"""); } }
+ public static string SendhttplevelShort { get { return LC.L(@"The messages to send"); } }
+ public static string SendhttplevelLong(string success, string warning, string error, string fatal, string all) { return LC.L(@"You can specify one of ""{0}"", ""{1}"", ""{2}"", ""{3}"".
+You can supply multiple options with a comma separator, e.g. ""{0},{1}"". The special value ""{4}"" is a shorthand for ""{0},{1},{2},{3}"" and will cause all backup operations to send a message.", success, warning, error, fatal, all); }
+ public static string SendhttpanyoperationShort { get { return LC.L(@"Send messages for all operations"); } }
+ public static string SendhttpanyoperationLong { get { return LC.L(@"By default, messages will only be sent after a Backup operation. Use this option to send messages for all operations"); } }
+ public static string SendMessageError(string message) { return LC.L(@"Failed to send http message: {0}", message); }
+ }
}
diff --git a/Duplicati/Library/Modules/Builtin/packages.config b/Duplicati/Library/Modules/Builtin/packages.config
index 7a5834e6c..75d5024ea 100644
--- a/Duplicati/Library/Modules/Builtin/packages.config
+++ b/Duplicati/Library/Modules/Builtin/packages.config
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="agsXMPP" version="1.1.1.0" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="BouncyCastle" version="1.8.1" targetFramework="net45" />
- <package id="MailKit" version="1.2.24" targetFramework="net45" />
- <package id="MimeKit" version="1.2.25" targetFramework="net45" />
+ <package id="MailKit" version="1.18.1.1" targetFramework="net45" />
+ <package id="MimeKit" version="1.18.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Modules/Builtin/run-script-example.bat b/Duplicati/Library/Modules/Builtin/run-script-example.bat
index 93f24709d..b6ecdb00a 100644
--- a/Duplicati/Library/Modules/Builtin/run-script-example.bat
+++ b/Duplicati/Library/Modules/Builtin/run-script-example.bat
@@ -100,6 +100,9 @@ REM is empty operations other than backup or restore. The local path can
REM contain : to separate multiple folders. This value can be changed by echoing
REM --localpath = "new value".
+REM DUPLICATI__PARSED_RESULT
+REM This is a value indicating how well the operation was performed.
+REM It can take the values: Unknown, Success, Warning, Error, Fatal.
REM ###############################################################################
@@ -154,7 +157,7 @@ GOTO end
IF "%OPERATIONNAME%" == "Backup" GOTO ON_AFTER_BACKUP
REM This will be ignored
-echo "Got operation "%OPERATIONNAME%", ignoring
+echo "Got operation "%OPERATIONNAME%", ignoring "
GOTO end
:ON_AFTER_BACKUP
diff --git a/Duplicati/Library/Modules/Builtin/run-script-example.sh b/Duplicati/Library/Modules/Builtin/run-script-example.sh
index 6ab7c51f3..150ac0d61 100644
--- a/Duplicati/Library/Modules/Builtin/run-script-example.sh
+++ b/Duplicati/Library/Modules/Builtin/run-script-example.sh
@@ -100,6 +100,10 @@
# contain : to separate multiple folders. This value can be changed by echoing
# --localpath = "new value".
+# DUPLICATI__PARSED_RESULT
+# This is a value indicating how well the operation was performed.
+# It can take the values: Unknown, Success, Warning, Error, Fatal.
+
###############################################################################
diff --git a/Duplicati/Library/SQLiteHelper/DBSchemaUpgrades/DbUpgradesRegistry.cs b/Duplicati/Library/SQLiteHelper/DBSchemaUpgrades/DbUpgradesRegistry.cs
new file mode 100644
index 000000000..a0eecc779
--- /dev/null
+++ b/Duplicati/Library/SQLiteHelper/DBSchemaUpgrades/DbUpgradesRegistry.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+using Duplicati.Library.SQLiteHelper.DBUpdates;
+
+namespace Duplicati.Library.SQLiteHelper.DBSchemaUpgrades
+{
+ class DbUpgradesRegistry
+ {
+ /// <summary>
+ /// Registry of custom code to be executed along a SQL schema upgrade. The key of the map
+ /// represents a 1-based version the upgrade code applies to (after performing the update
+ /// the database will be at that version), the value is an instance of upgrader that
+ /// implements the hooks code.
+ /// </summary>
+ public static readonly IDictionary<int, IDbSchemaUpgrade> CodeChanges =
+ new Dictionary<int, IDbSchemaUpgrade>()
+ {
+ };
+ }
+}
diff --git a/Duplicati/Library/SQLiteHelper/DBSchemaUpgrades/IDbSchemaUpgrade.cs b/Duplicati/Library/SQLiteHelper/DBSchemaUpgrades/IDbSchemaUpgrade.cs
new file mode 100644
index 000000000..4033d9242
--- /dev/null
+++ b/Duplicati/Library/SQLiteHelper/DBSchemaUpgrades/IDbSchemaUpgrade.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Duplicati.Library.SQLiteHelper.DBUpdates
+{
+
+ // TODO: Consider passing in a transaction and performing everything in one go.
+
+ public interface IDbSchemaUpgrade
+ {
+ /// <summary>
+ /// Executed before the textual SQL command is executed.
+ /// </summary>
+ /// <param name="connection"></param>
+ void BeforeSql(System.Data.IDbConnection connection);
+
+ /// <summary>
+ /// Executed after the textual SQL command is executed.
+ /// </summary>
+ /// <param name="connection"></param>
+ void AfterSql(System.Data.IDbConnection connection);
+ }
+}
diff --git a/Duplicati/Library/SQLiteHelper/DatabaseUpgrader.cs b/Duplicati/Library/SQLiteHelper/DatabaseUpgrader.cs
index 8e679b76e..f3a9a987a 100644
--- a/Duplicati/Library/SQLiteHelper/DatabaseUpgrader.cs
+++ b/Duplicati/Library/SQLiteHelper/DatabaseUpgrader.cs
@@ -23,13 +23,24 @@ using System.Text;
using System.Data;
using System.Text.RegularExpressions;
using System.Linq;
+using Duplicati.Library.SQLiteHelper.DBUpdates;
+using Duplicati.Library.SQLiteHelper.DBSchemaUpgrades;
namespace Duplicati.Library.SQLiteHelper
{
/// <summary>
/// This class will read embedded files from the given folder.
/// Updates should have the form &quot;1.Sample upgrade.sql&quot;.
- /// When the database schema changes, simply put a new file into the folder.
+ /// When the database schema changes, simply put a new file into the folder
+ /// and set it to be emnbedded in the binary.
+ ///
+ /// Additionally, it's possible to execute custom code before and after
+ /// the SQL is executed. To set up a custom upgrade stage, add your
+ /// code to DbUpgradesRegistry along with the DB version to apply it with.
+ ///
+ /// Even if all the DB upgrade code is handled in C#, you still have to add
+ /// a dummy SQL file to indicate the version ID is already taken.
+ ///
/// Each upgrade file should ONLY upgrade from the previous version.
/// If done correctly, a user may be upgrade from the very first version
/// to the very latest.
@@ -206,16 +217,16 @@ namespace Duplicati.Library.SQLiteHelper
catch (Exception ex)
{
//Hopefully a more explanatory error message
- throw new Exception(Strings.DatabaseUpgrader.DatabaseFormatError(ex.Message), ex);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.DatabaseUpgrader.DatabaseFormatError(ex.Message), ex);
}
Dictionary<string, IComparable> preparserVars = null;
if (dbversion > versions.Count)
- throw new Exception(Strings.DatabaseUpgrader.InvalidVersionError(dbversion, versions.Count, System.IO.Path.GetDirectoryName(sourcefile)));
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.DatabaseUpgrader.InvalidVersionError(dbversion, versions.Count, System.IO.Path.GetDirectoryName(sourcefile)));
else if (dbversion < versions.Count) // will need action, collect vars for preparser
{
- preparserVars = new Dictionary<string, IComparable>(StringComparer.InvariantCultureIgnoreCase);
+ preparserVars = new Dictionary<string, IComparable>(StringComparer.OrdinalIgnoreCase);
cmd.CommandText = "SELECT sqlite_version()";
System.Version sqliteversion;
if (Version.TryParse(cmd.ExecuteScalar().ToString(), out sqliteversion))
@@ -235,7 +246,9 @@ namespace Duplicati.Library.SQLiteHelper
}
else if (versions.Count > dbversion)
{
- string backupfile = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(sourcefile), Strings.DatabaseUpgrader.BackupFilenamePrefix + " " + DateTime.Now.ToString("yyyyMMddhhmmss", System.Globalization.CultureInfo.InvariantCulture) + ".sqlite");
+ string backupfile = System.IO.Path.Combine(
+ System.IO.Path.GetDirectoryName(sourcefile),
+ Strings.DatabaseUpgrader.BackupFilenamePrefix + " " + DateTime.Now.ToString("yyyyMMddhhmmss", System.Globalization.CultureInfo.InvariantCulture) + ".sqlite");
try
{
@@ -247,6 +260,16 @@ namespace Duplicati.Library.SQLiteHelper
for (int i = dbversion; i < versions.Count; i++)
{
+ IDbSchemaUpgrade dbCodeUpgrade;
+
+ // The versions in the registry are 1-based, the loop index is zero based.
+ bool hookFound = DbUpgradesRegistry.CodeChanges.TryGetValue(i + 1, out dbCodeUpgrade);
+
+ if (hookFound)
+ {
+ dbCodeUpgrade.BeforeSql(connection);
+ }
+
//TODO: Find a better way to split SQL statements, as there may be embedded semicolons
//in the SQL, like "UPDATE x WHERE y = ';';"
@@ -261,6 +284,11 @@ namespace Duplicati.Library.SQLiteHelper
cmd.ExecuteNonQuery();
}
+ if (hookFound)
+ {
+ dbCodeUpgrade.AfterSql(connection);
+ }
+
// after upgrade, db_version should have changed to i + 1. If logic changes, just requery.
preparserVars["db_version"] = i + 1;
}
diff --git a/Duplicati/Library/SQLiteHelper/Duplicati.Library.SQLiteHelper.csproj b/Duplicati/Library/SQLiteHelper/Duplicati.Library.SQLiteHelper.csproj
index 9df0243ed..06d9deab3 100644
--- a/Duplicati/Library/SQLiteHelper/Duplicati.Library.SQLiteHelper.csproj
+++ b/Duplicati/Library/SQLiteHelper/Duplicati.Library.SQLiteHelper.csproj
@@ -11,6 +11,7 @@
<AssemblyOriginatorKeyFile>..\..\GUI\Duplicati.GUI.TrayIcon\Duplicati.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -37,6 +38,8 @@
<Reference Include="System.Data" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="DBSchemaUpgrades\DbUpgradesRegistry.cs" />
+ <Compile Include="DBSchemaUpgrades\IDbSchemaUpgrade.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="DatabaseUpgrader.cs" />
<Compile Include="SQLiteLoader.cs" />
@@ -56,6 +59,14 @@
<Link>SQLite\pinvoke\System.Data.SQLite.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="..\..\..\thirdparty\SQLite\win32\SQLite.Interop.dll">
+ <Link>SQLite\win32\SQLite.Interop.dll</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\..\thirdparty\SQLite\win64\SQLite.Interop.dll">
+ <Link>SQLite\win64\SQLite.Interop.dll</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@@ -67,5 +78,9 @@
<Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
<Name>Duplicati.Library.Localization</Name>
</ProjectReference>
+ <ProjectReference Include="..\Interface\Duplicati.Library.Interface.csproj">
+ <Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
+ <Name>Duplicati.Library.Interface</Name>
+ </ProjectReference>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/Duplicati/Library/SQLiteHelper/SQLiteLoader.cs b/Duplicati/Library/SQLiteHelper/SQLiteLoader.cs
index 53c3364b4..1424aa506 100644
--- a/Duplicati/Library/SQLiteHelper/SQLiteLoader.cs
+++ b/Duplicati/Library/SQLiteHelper/SQLiteLoader.cs
@@ -31,6 +31,65 @@ namespace Duplicati.Library.SQLiteHelper
private static Type m_type = null;
/// <summary>
+ /// Loads an SQLite connection instance, optionally setting the tempfolder and opening the the database
+ /// </summary>
+ /// <returns>The SQLite connection instance.</returns>
+ /// <param name="targetpath">The optional path to the database.</param>
+ /// <param name="tempdir">The optional tempdir to set.</param>
+ public static System.Data.IDbConnection LoadConnection(string targetpath = null, string tempdir = null)
+ {
+ if (string.IsNullOrWhiteSpace(tempdir))
+ tempdir = Library.Utility.TempFolder.SystemTempPath;
+
+ var prev = System.Environment.GetEnvironmentVariable("SQLITE_TMPDIR");
+
+ System.Data.IDbConnection con = null;
+
+ try
+ {
+ System.Environment.SetEnvironmentVariable("SQLITE_TMPDIR", tempdir);
+ con = (System.Data.IDbConnection)Activator.CreateInstance(Duplicati.Library.SQLiteHelper.SQLiteLoader.SQLiteConnectionType);
+ if (!string.IsNullOrWhiteSpace(targetpath))
+ {
+ con.ConnectionString = "Data Source=" + targetpath;
+ con.Open();
+
+ // Try to set the temp_dir even tough it is deprecated
+ if (!string.IsNullOrWhiteSpace(tempdir))
+ {
+ try
+ {
+ using (var cmd = con.CreateCommand())
+ {
+ cmd.CommandText = string.Format("PRAGMA temp_store_directory = '{0}'", tempdir);
+ cmd.ExecuteNonQuery();
+ }
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ }
+ catch
+ {
+ if (con != null)
+ try { con.Dispose(); }
+ catch { }
+
+ throw;
+ }
+ finally
+ {
+ System.Environment.SetEnvironmentVariable("SQLITE_TMPDIR", prev);
+ }
+
+
+ return con;
+ }
+
+ /// <summary>
/// Returns the SQLiteCommand type for the current architecture
/// </summary>
public static Type SQLiteConnectionType
@@ -39,11 +98,14 @@ namespace Duplicati.Library.SQLiteHelper
{
if (m_type == null)
{
- string filename = "System.Data.SQLite.dll";
- string basePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "SQLite");
+ var filename = "System.Data.SQLite.dll";
+ var basePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "SQLite");
+
+ // Set this to make SQLite preload automatically
+ Environment.SetEnvironmentVariable("PreLoadSQLite_BaseDirectory", basePath);
//Default is to use the pinvoke version which requires a native .dll/.so
- string assemblyPath = System.IO.Path.Combine(basePath, "pinvoke");
+ var assemblyPath = System.IO.Path.Combine(basePath, "pinvoke");
if (!Duplicati.Library.Utility.Utility.IsMono)
{
@@ -58,6 +120,15 @@ namespace Duplicati.Library.SQLiteHelper
if (System.IO.File.Exists(System.IO.Path.Combine(System.IO.Path.Combine(basePath, "win32"), filename)))
assemblyPath = System.IO.Path.Combine(basePath, "win32");
}
+
+ // If we have a new path, try to force load the mixed-mode assembly for the current architecture
+ // This can be avoided if the preload in SQLite works, but it is easy to do it here as well
+ if (assemblyPath != System.IO.Path.Combine(basePath, "pinvoke"))
+ {
+ try { PInvoke.LoadLibraryEx(System.IO.Path.Combine(basePath, "SQLite.Interop.dll"), IntPtr.Zero, 0); }
+ catch { }
+ }
+
} else {
//On Mono, we try to find the Mono version of SQLite
@@ -95,4 +166,20 @@ namespace Duplicati.Library.SQLiteHelper
}
}
}
+
+ /// <summary>
+ /// Helper class with PInvoke methods
+ /// </summary>
+ internal static class PInvoke
+ {
+ /// <summary>
+ /// Loads the specified module into the address space of the calling process.
+ /// </summary>
+ /// <returns>The library ex.</returns>
+ /// <param name="lpFileName">The filename of the module to load.</param>
+ /// <param name="hReservedNull">Reserved for future use.</param>
+ /// <param name="dwFlags">Action to take on load.</param>
+ [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, uint dwFlags);
+ }
}
diff --git a/Duplicati/Library/Snapshots/DefineDosDevice.cs b/Duplicati/Library/Snapshots/DefineDosDevice.cs
index 52d74915f..adc45c668 100644
--- a/Duplicati/Library/Snapshots/DefineDosDevice.cs
+++ b/Duplicati/Library/Snapshots/DefineDosDevice.cs
@@ -114,7 +114,7 @@ namespace Duplicati.Library.Snapshots
drive = drive.Substring(0, drive.Length - 1);
if (!drive.EndsWith(":"))
- throw new ArgumentException("drive");
+ throw new ArgumentException("The drive specification must end with a colon.", nameof(drive));
Win32API.DDD_Flags flags = 0;
if (!notifyShell)
diff --git a/Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj b/Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj
index e52cf7384..c8aeceac0 100644
--- a/Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj
+++ b/Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj
@@ -5,11 +5,11 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D63E53E4-A458-4C2F-914D-92F715F58ACE}</ProjectGuid>
<OutputType>Exe</OutputType>
+ <Prefer32Bit>False</Prefer32Bit>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.Library.Snapshots</RootNamespace>
<AssemblyName>Duplicati.Library.Snapshots</AssemblyName>
<FileAlignment>512</FileAlignment>
- <SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
<FileUpgradeFlags>
</FileUpgradeFlags>
@@ -17,6 +17,7 @@
<UpgradeBackupLocation />
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -44,41 +45,22 @@
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Management" />
- <Reference Include="AlphaFS">
- <HintPath>..\..\..\packages\AlphaFS.2.0.1\lib\net45\AlphaFS.dll</HintPath>
- </Reference>
- <Reference Include="AlphaVSS.51.x86">
- <HintPath>..\..\..\packages\AlphaVSS.1.2.4000.3\lib\net40\AlphaVSS.51.x86.dll</HintPath>
- </Reference>
- <Reference Include="AlphaVSS.52.x64">
- <HintPath>..\..\..\packages\AlphaVSS.1.2.4000.3\lib\net40\AlphaVSS.52.x64.dll</HintPath>
- </Reference>
- <Reference Include="AlphaVSS.52.x86">
- <HintPath>..\..\..\packages\AlphaVSS.1.2.4000.3\lib\net40\AlphaVSS.52.x86.dll</HintPath>
- </Reference>
- <Reference Include="AlphaVSS.60.x64">
- <HintPath>..\..\..\packages\AlphaVSS.1.2.4000.3\lib\net40\AlphaVSS.60.x64.dll</HintPath>
- </Reference>
- <Reference Include="AlphaVSS.60.x86">
- <HintPath>..\..\..\packages\AlphaVSS.1.2.4000.3\lib\net40\AlphaVSS.60.x86.dll</HintPath>
- </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Transactions" />
<Reference Include="AlphaVSS.Common">
- <HintPath>..\..\..\packages\AlphaVSS.1.2.4000.3\lib\net40\AlphaVSS.Common.dll</HintPath>
- </Reference>
- <Reference Include="AlphaShadow">
- <HintPath>..\..\..\packages\AlphaVSS.1.2.4000.3\lib\net40\AlphaShadow.exe</HintPath>
+ <HintPath>..\..\..\packages\AlphaVSS.1.4.0\lib\net45\AlphaVSS.Common.dll</HintPath>
</Reference>
- <Reference Include="SnapshotQuery">
- <HintPath>..\..\..\packages\AlphaVSS.1.2.4000.3\lib\net40\SnapshotQuery.exe</HintPath>
+ <Reference Include="AlphaFS">
+ <HintPath>..\..\..\packages\AlphaFS.2.1.3\lib\net45\AlphaFS.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
- <Reference Include="System.Xml" />
- <Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="DefineDosDevice.cs" />
+ <Compile Include="MSSQLUtility.cs" />
<Compile Include="HyperVUtility.cs" />
<Compile Include="ISnapshotService.cs" />
<Compile Include="LinuxSnapshot.cs" />
@@ -142,4 +124,5 @@
</Target>
-->
<ItemGroup />
+ <Import Project="..\..\..\packages\AlphaVSS.1.4.0\build\net45\AlphaVSS.targets" Condition="Exists('..\..\..\packages\AlphaVSS.1.4.0\build\net45\AlphaVSS.targets')" />
</Project> \ No newline at end of file
diff --git a/Duplicati/Library/Snapshots/HyperVUtility.cs b/Duplicati/Library/Snapshots/HyperVUtility.cs
index a3b3d7dba..215a60d27 100644
--- a/Duplicati/Library/Snapshots/HyperVUtility.cs
+++ b/Duplicati/Library/Snapshots/HyperVUtility.cs
@@ -1,4 +1,5 @@
-using System;
+using Alphaleonis.Win32.Vss;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -6,18 +7,59 @@ using System.Management;
namespace Duplicati.Library.Snapshots
{
- public class HyperVGuest
+ public class HyperVGuest : IEquatable<HyperVGuest>
{
public string Name { get; }
- public string ID { get; }
+ public Guid ID { get; }
public List<string> DataPaths { get; }
- public HyperVGuest(string Name, string ID, List<string> DataPaths)
+ public HyperVGuest(string Name, Guid ID, List<string> DataPaths)
{
this.Name = Name;
this.ID = ID;
this.DataPaths = DataPaths;
}
+
+ bool IEquatable<HyperVGuest>.Equals(HyperVGuest other)
+ {
+ return ID.Equals(other.ID);
+ }
+
+ public override int GetHashCode()
+ {
+ return ID.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ HyperVGuest guest = obj as HyperVGuest;
+ if (guest != null)
+ {
+ return Equals(guest);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public static bool operator ==(HyperVGuest guest1, HyperVGuest guest2)
+ {
+ if (object.ReferenceEquals(guest1, guest2)) return true;
+ if (object.ReferenceEquals(guest1, null)) return false;
+ if (object.ReferenceEquals(guest2, null)) return false;
+
+ return guest1.Equals(guest2);
+ }
+
+ public static bool operator !=(HyperVGuest guest1, HyperVGuest guest2)
+ {
+ if (object.ReferenceEquals(guest1, guest2)) return false;
+ if (object.ReferenceEquals(guest1, null)) return true;
+ if (object.ReferenceEquals(guest2, null)) return true;
+
+ return !guest1.Equals(guest2);
+ }
}
public class HyperVUtility
@@ -26,14 +68,32 @@ namespace Duplicati.Library.Snapshots
private readonly string _vmIdField;
private readonly string _wmiHost = "localhost";
private readonly bool _wmiv2Namespace;
+ /// <summary>
+ /// The Hyper-V VSS Writer Guid
+ /// </summary>
+ public static readonly Guid HyperVWriterGuid = new Guid("66841cd4-6ded-4f4b-8f17-fd23f8ddc3de");
+ /// <summary>
+ /// Hyper-V is supported only on Windows platform
+ /// </summary>
public bool IsHyperVInstalled { get; }
+ /// <summary>
+ /// Hyper-V writer is supported only on Server version of Windows
+ /// </summary>
+ public bool IsVSSWriterSupported { get; }
+ /// <summary>
+ /// Enumerated Hyper-V guests
+ /// </summary>
+ public List<HyperVGuest> Guests { get { return m_Guests; } }
+ private List<HyperVGuest> m_Guests;
public HyperVUtility()
{
- if (!Library.Utility.Utility.IsClientWindows)
+ m_Guests = new List<HyperVGuest>();
+
+ if (!Utility.Utility.IsClientWindows)
{
IsHyperVInstalled = false;
- Logging.Log.WriteMessage("Hyper-V Guests are supported only on Windows.", Logging.LogMessageType.Information);
+ IsVSSWriterSupported = false;
return;
}
@@ -48,7 +108,11 @@ namespace Duplicati.Library.Snapshots
_vmIdField = _wmiv2Namespace ? "VirtualSystemIdentifier" : "SystemName";
Logging.Log.WriteMessage(string.Format("Using WMI provider {0}", _wmiScope.Path), Logging.LogMessageType.Profiling);
-
+
+ IsVSSWriterSupported = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
+ .Get().OfType<ManagementObject>()
+ .Select(o => (uint)o.GetPropertyValue("ProductType")).First() != 1;
+
try
{
var classesCount = new ManagementObjectSearcher(_wmiScope, new ObjectQuery(
@@ -63,38 +127,96 @@ namespace Duplicati.Library.Snapshots
}
/// <summary>
- /// We query the Hyper-V for all requested Virtual Machines
+ /// Query Hyper-V for all Virtual Machines info
/// </summary>
+ /// <param name="bIncludePaths">Specify if returned data should contain VM paths</param>
/// <returns>List of Hyper-V Machines</returns>
- public List<HyperVGuest> GetHyperVGuests()
+ public void QueryHyperVGuestsInfo(bool bIncludePaths = false)
{
- var hyperVMachines = new List<HyperVGuest>();
-
- if(!IsHyperVInstalled)
- return hyperVMachines;
+ if (!IsHyperVInstalled)
+ return;
+ m_Guests.Clear();
var wmiQuery = _wmiv2Namespace
? "SELECT * FROM Msvm_VirtualSystemSettingData WHERE VirtualSystemType = 'Microsoft:Hyper-V:System:Realized'"
: "SELECT * FROM Msvm_VirtualSystemSettingData WHERE SettingType = 3";
- using (var moCollection = new ManagementObjectSearcher(_wmiScope, new ObjectQuery(wmiQuery)).Get())
- foreach (var mObject in moCollection)
+ if (IsVSSWriterSupported)
+ using (var moCollection = new ManagementObjectSearcher(_wmiScope, new ObjectQuery(wmiQuery)).Get())
+ foreach (var mObject in moCollection)
+ m_Guests.Add(new HyperVGuest((string)mObject["ElementName"], new Guid((string)mObject[_vmIdField]), bIncludePaths ? GetAllVMsPathsVSS()[(string)mObject[_vmIdField]] : null));
+ else
+ using (var moCollection = new ManagementObjectSearcher(_wmiScope, new ObjectQuery(wmiQuery)).Get())
+ foreach (var mObject in moCollection)
+ m_Guests.Add(new HyperVGuest((string)mObject["ElementName"], new Guid((string)mObject[_vmIdField]), bIncludePaths ?
+ GetVMVhdPathsWMI((string)mObject[_vmIdField])
+ .Union(GetVMConfigPathsWMI((string)mObject[_vmIdField]))
+ .Distinct(Utility.Utility.ClientFilenameStringComparer)
+ .OrderBy(a => a).ToList() : null));
+ }
+
+ /// <summary>
+ /// For all Hyper-V guests it enumerate all associated paths using VSS data
+ /// </summary>
+ /// <returns>A collection of VMs and paths</returns>
+ private Dictionary<string, List<string>> GetAllVMsPathsVSS()
+ {
+ var ret = new Dictionary<string, List<string>>();
+
+ //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC
+ string alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss");
+ string alphadll = Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll");
+ IVssImplementation vss = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation");
+
+ using (var m_backup = vss.CreateVssBackupComponents())
+ {
+ m_backup.InitializeForBackup(null);
+ m_backup.SetContext(VssSnapshotContext.Backup);
+ m_backup.SetBackupState(false, true, VssBackupType.Full, false);
+ m_backup.EnableWriterClasses(new Guid[] { HyperVWriterGuid });
+
+ try
{
- var paths = GetAllVmVhdPaths((string)mObject[_vmIdField]);
- paths.AddRange(GetAllVmConfigPaths((string)mObject[_vmIdField]));
+ m_backup.GatherWriterMetadata();
+ var writerMetaData = m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(HyperVWriterGuid));
+
+ if (writerMetaData == null)
+ throw new Duplicati.Library.Interface.UserInformationException("Microsoft Hyper-V VSS Writer not found - cannot backup Hyper-V machines.");
- hyperVMachines.Add(new HyperVGuest((string)mObject["ElementName"], (string)mObject[_vmIdField], paths));
+ foreach (var component in writerMetaData.Components)
+ {
+ var paths = new List<string>();
+
+ foreach (var file in component.Files)
+ if (file.FileSpecification.Contains("*"))
+ {
+ if (Directory.Exists(Utility.Utility.AppendDirSeparator(file.Path)))
+ paths.Add(Utility.Utility.AppendDirSeparator(file.Path));
+ }
+ else
+ {
+ if (File.Exists(Path.Combine(file.Path, file.FileSpecification)))
+ paths.Add(Path.Combine(file.Path, file.FileSpecification));
+ }
+
+ ret.Add(component.ComponentName, paths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList());
+ }
}
+ finally
+ {
+ m_backup.FreeWriterMetadata();
+ }
+ }
- return hyperVMachines;
+ return ret;
}
/// <summary>
- /// For given Hyper-V guest it enumerate all associated configuration files
+ /// For given Hyper-V guest it enumerate all associated configuration files using WMI data
/// </summary>
- /// <param name="query"></param>
+ /// <param name="vmID">ID of VM to get paths for</param>
/// <returns>A collection of configuration paths</returns>
- private List<string> GetAllVmConfigPaths(string vmID)
+ private List<string> GetVMConfigPathsWMI(string vmID)
{
var result = new List<string>();
string path;
@@ -148,15 +270,15 @@ namespace Duplicati.Library.Snapshots
}
}
- return result.Distinct(Utility.Utility.ClientFilenameStringComparer).ToList();
+ return result;
}
/// <summary>
- /// For given Hyper-V guest it enumerate all associated VHD files
+ /// For given Hyper-V guest it enumerate all associated VHD files using WMI data
/// </summary>
- /// <param name="query"></param>
+ /// <param name="vmID">ID of VM to get paths for</param>
/// <returns>A collection of VHD paths</returns>
- private List<string> GetAllVmVhdPaths(string vmID)
+ private List<string> GetVMVhdPathsWMI(string vmID)
{
var result = new List<string>();
using (var vm = new ManagementObjectSearcher(_wmiScope, new ObjectQuery(string.Format("select * from Msvm_ComputerSystem where Name = '{0}'", vmID)))
@@ -208,7 +330,7 @@ namespace Duplicati.Library.Snapshots
result.AddRange(ParentPaths);
}
- return result.Distinct(Utility.Utility.ClientFilenameStringComparer).ToList();
+ return result;
}
}
} \ No newline at end of file
diff --git a/Duplicati/Library/Snapshots/ISnapshotService.cs b/Duplicati/Library/Snapshots/ISnapshotService.cs
index 2060a466e..4e8d5c20c 100644
--- a/Duplicati/Library/Snapshots/ISnapshotService.cs
+++ b/Duplicati/Library/Snapshots/ISnapshotService.cs
@@ -32,7 +32,8 @@ namespace Duplicati.Library.Snapshots
/// Enumerates all files and folders in the snapshot
/// </summary>
/// <param name="callback">The callback to invoke with each found path</param>
- IEnumerable<string> EnumerateFilesAndFolders(Duplicati.Library.Utility.Utility.EnumerationFilterDelegate callback);
+ /// <param name="errorCallback">The callback used to report errors</param>
+ IEnumerable<string> EnumerateFilesAndFolders(Duplicati.Library.Utility.Utility.EnumerationFilterDelegate callback, Duplicati.Library.Utility.Utility.ReportAccessError errorCallback);
/// <summary>
/// Gets the last write time of a given file in UTC
@@ -81,7 +82,9 @@ namespace Duplicati.Library.Snapshots
/// </summary>
/// <returns>The metadata for the given file or folder</returns>
/// <param name="file">The file or folder to examine</param>
- Dictionary<string, string> GetMetadata(string file);
+ /// <param name="isSymlink">A flag indicating if the target is a symlink</param>
+ /// <param name="followSymlink">A flag indicating if a symlink should be followed</param>
+ Dictionary<string, string> GetMetadata(string file, bool isSymlink, bool followSymlink);
/// <summary>
/// Gets a value indicating if the path points to a block device
diff --git a/Duplicati/Library/Snapshots/ISystemIO.cs b/Duplicati/Library/Snapshots/ISystemIO.cs
index 417f0698b..cf3fef902 100644
--- a/Duplicati/Library/Snapshots/ISystemIO.cs
+++ b/Duplicati/Library/Snapshots/ISystemIO.cs
@@ -57,7 +57,7 @@ namespace Duplicati.Library.Snapshots
IEnumerable<string> EnumerateFileSystemEntries(string path);
void SetMetadata(string path, Dictionary<string, string> metdata, bool restorePermissions);
- Dictionary<string, string> GetMetadata(string path);
+ Dictionary<string, string> GetMetadata(string path, bool isSymlink, bool followSymlink);
}
}
diff --git a/Duplicati/Library/Snapshots/LinuxSnapshot.cs b/Duplicati/Library/Snapshots/LinuxSnapshot.cs
index 8978cfa26..ff5ff1375 100644
--- a/Duplicati/Library/Snapshots/LinuxSnapshot.cs
+++ b/Duplicati/Library/Snapshots/LinuxSnapshot.cs
@@ -148,7 +148,7 @@ namespace Duplicati.Library.Snapshots
p.Kill();
p.WaitForExit(5 * 1000); //This should work, and if it does, prevents a race with any cleanup invocations
- throw new Exception(Strings.LinuxSnapshot.ExternalProgramTimeoutError(program, commandline));
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.LinuxSnapshot.ExternalProgramTimeoutError(program, commandline));
}
//Build the output string. Since the process has exited, these cannot block
@@ -156,7 +156,7 @@ namespace Duplicati.Library.Snapshots
//Throw an exception if something went wrong
if (p.ExitCode != expectedExitCode)
- throw new Exception(Strings.LinuxSnapshot.ScriptExitCodeError(p.ExitCode, expectedExitCode, output));
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.LinuxSnapshot.ScriptExitCodeError(p.ExitCode, expectedExitCode, output));
return output;
}
@@ -388,12 +388,12 @@ namespace Duplicati.Library.Snapshots
/// <summary>
/// Enumerates all files and folders in the snapshot
/// </summary>
- /// <param name="filter">The filter to apply when evaluating files and folders</param>
/// <param name="callback">The callback to invoke with each found path</param>
- public IEnumerable<string> EnumerateFilesAndFolders(Duplicati.Library.Utility.Utility.EnumerationFilterDelegate callback)
+ /// <param name="errorCallback">The callback used to report errors</param>
+ public IEnumerable<string> EnumerateFilesAndFolders(Duplicati.Library.Utility.Utility.EnumerationFilterDelegate callback, Duplicati.Library.Utility.Utility.ReportAccessError errorCallback)
{
return m_entries.SelectMany(
- s => Utility.Utility.EnumerateFileSystemEntries(s.Key, callback, this.ListFolders, this.ListFiles, this.GetAttributes)
+ s => Utility.Utility.EnumerateFileSystemEntries(s.Key, callback, this.ListFolders, this.ListFiles, this.GetAttributes, errorCallback)
);
}
@@ -463,10 +463,12 @@ namespace Duplicati.Library.Snapshots
/// </summary>
/// <returns>The metadata for the given file or folder</returns>
/// <param name="file">The file or folder to examine</param>
- public Dictionary<string, string> GetMetadata(string file)
+ /// <param name="isSymlink">A flag indicating if the target is a symlink</param>
+ /// <param name="followSymlink">A flag indicating if a symlink should be followed</param>
+ public Dictionary<string, string> GetMetadata(string file, bool isSymlink, bool followSymlink)
{
var local = ConvertToSnapshotPath(FindSnapShotByLocalPath(file), file);
- return _sysIO.GetMetadata(local);
+ return _sysIO.GetMetadata(local, isSymlink, followSymlink);
}
/// <summary>
diff --git a/Duplicati/Library/Snapshots/MSSQLUtility.cs b/Duplicati/Library/Snapshots/MSSQLUtility.cs
new file mode 100644
index 000000000..1b5e6fb88
--- /dev/null
+++ b/Duplicati/Library/Snapshots/MSSQLUtility.cs
@@ -0,0 +1,167 @@
+using Alphaleonis.Win32.Vss;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace Duplicati.Library.Snapshots
+{
+ public class MSSQLDB : IEquatable<MSSQLDB>
+ {
+ public string Name { get; }
+ public string ID { get; }
+ public List<string> DataPaths { get; }
+
+ public MSSQLDB(string Name, string ID, List<string> DataPaths)
+ {
+ this.Name = Name;
+ this.ID = ID;
+ this.DataPaths = DataPaths;
+ }
+
+ bool IEquatable<MSSQLDB>.Equals(MSSQLDB other)
+ {
+ return ID.Equals(other.ID);
+ }
+
+ public override int GetHashCode()
+ {
+ return ID.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ MSSQLDB db = obj as MSSQLDB;
+ if (db != null)
+ {
+ return Equals(db);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public static bool operator ==(MSSQLDB db1, MSSQLDB db2)
+ {
+ if (object.ReferenceEquals(db1, db2)) return true;
+ if (object.ReferenceEquals(db1, null)) return false;
+ if (object.ReferenceEquals(db2, null)) return false;
+
+ return db1.Equals(db2);
+ }
+
+ public static bool operator !=(MSSQLDB db1, MSSQLDB db2)
+ {
+ if (object.ReferenceEquals(db1, db2)) return false;
+ if (object.ReferenceEquals(db1, null)) return true;
+ if (object.ReferenceEquals(db2, null)) return true;
+
+ return !db1.Equals(db2);
+ }
+ }
+
+ public class MSSQLUtility
+ {
+ /// <summary>
+ /// The MS SQL VSS Writer Guid
+ /// </summary>
+ public static readonly Guid MSSQLWriterGuid = new Guid("a65faa63-5ea8-4ebc-9dbd-a0c4db26912a");
+ /// <summary>
+ /// MS SQL is supported only on Windows platform
+ /// </summary>
+ public bool IsMSSQLInstalled { get; }
+ /// <summary>
+ /// Enumerated MS SQL DBs
+ /// </summary>
+ public List<MSSQLDB> DBs { get { return m_DBs; } }
+ private List<MSSQLDB> m_DBs;
+
+ public MSSQLUtility()
+ {
+ m_DBs = new List<MSSQLDB>();
+
+ if (!Utility.Utility.IsClientWindows)
+ {
+ IsMSSQLInstalled = false;
+ return;
+ }
+
+ string[] arrInstalledInstances = null;
+
+ var installed = Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server", "InstalledInstances", "");
+ if (installed is string)
+ {
+ if (!string.IsNullOrWhiteSpace(installed as string))
+ arrInstalledInstances = new string[] { installed as string };
+ }
+ else if (installed is string[])
+ arrInstalledInstances = (string[])installed;
+ else if (installed != null)
+ try { arrInstalledInstances = (string[])installed; }
+ catch { }
+
+ IsMSSQLInstalled = arrInstalledInstances == null ? false : arrInstalledInstances.Length > 0;
+
+ if (!IsMSSQLInstalled)
+ Logging.Log.WriteMessage("Cannot find any MS SQL Server instance. MS SQL Server is probably not installed.", Logging.LogMessageType.Information);
+ }
+
+ /// <summary>
+ /// For all MS SQL databases it enumerate all associated paths using VSS data
+ /// </summary>
+ /// <returns>A collection of DBs and paths</returns>
+ public void QueryDBsInfo()
+ {
+ if (!IsMSSQLInstalled)
+ return;
+
+ m_DBs.Clear();
+
+ //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC
+ string alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss");
+ string alphadll = Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll");
+ IVssImplementation vss = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation");
+
+ using (var m_backup = vss.CreateVssBackupComponents())
+ {
+ m_backup.InitializeForBackup(null);
+ m_backup.SetContext(VssSnapshotContext.Backup);
+ m_backup.SetBackupState(false, true, VssBackupType.Full, false);
+ m_backup.EnableWriterClasses(new Guid[] { MSSQLWriterGuid });
+
+ try
+ {
+ m_backup.GatherWriterMetadata();
+ var writerMetaData = m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(MSSQLWriterGuid));
+
+ if (writerMetaData == null)
+ throw new Duplicati.Library.Interface.UserInformationException("Microsoft SQL Server VSS Writer not found - cannot backup SQL databases.");
+
+ foreach (var component in writerMetaData.Components)
+ {
+ var paths = new List<string>();
+
+ foreach (var file in component.Files)
+ if (file.FileSpecification.Contains("*"))
+ {
+ if (Directory.Exists(Utility.Utility.AppendDirSeparator(file.Path)))
+ paths.Add(Utility.Utility.AppendDirSeparator(file.Path));
+ }
+ else
+ {
+ if (File.Exists(Path.Combine(file.Path, file.FileSpecification)))
+ paths.Add(Path.Combine(file.Path, file.FileSpecification));
+ }
+
+ m_DBs.Add(new MSSQLDB(component.ComponentName, component.LogicalPath + "\\" + component.ComponentName, paths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList()));
+ }
+ }
+ finally
+ {
+ m_backup.FreeWriterMetadata();
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Duplicati/Library/Snapshots/NoSnapshot.cs b/Duplicati/Library/Snapshots/NoSnapshot.cs
index bd228a3e0..7c4f7c5de 100644
--- a/Duplicati/Library/Snapshots/NoSnapshot.cs
+++ b/Duplicati/Library/Snapshots/NoSnapshot.cs
@@ -107,10 +107,11 @@ namespace Duplicati.Library.Snapshots
/// Enumerates all files and folders in the snapshot
/// </summary>
/// <param name="callback">The callback to invoke with each found path</param>
- public IEnumerable<string> EnumerateFilesAndFolders(Duplicati.Library.Utility.Utility.EnumerationFilterDelegate callback)
+ /// <param name="errorCallback">The callback used to report errors</param>
+ public IEnumerable<string> EnumerateFilesAndFolders(Duplicati.Library.Utility.Utility.EnumerationFilterDelegate callback, Duplicati.Library.Utility.Utility.ReportAccessError errorCallback)
{
return m_sources.SelectMany(
- s => Utility.Utility.EnumerateFileSystemEntries(s, callback, this.ListFolders, this.ListFiles, this.GetAttributes)
+ s => Utility.Utility.EnumerateFileSystemEntries(s, callback, this.ListFolders, this.ListFiles, this.GetAttributes, errorCallback)
);
}
@@ -176,7 +177,9 @@ namespace Duplicati.Library.Snapshots
/// </summary>
/// <returns>The metadata for the given file or folder</returns>
/// <param name="file">The file or folder to examine</param>
- public abstract Dictionary<string, string> GetMetadata(string file);
+ /// <param name="isSymlink">A flag indicating if the target is a symlink</param>
+ /// <param name="followSymlink">A flag indicating if a symlink should be followed</param>
+ public abstract Dictionary<string, string> GetMetadata(string file, bool isSymlink, bool followSymlink);
/// <summary>
/// Gets a value indicating if the path points to a block device
@@ -189,7 +192,7 @@ namespace Duplicati.Library.Snapshots
/// Gets a unique hardlink target ID
/// </summary>
/// <returns>The hardlink ID</returns>
- /// <param name="file">The file or folder to examine</param>
+ /// <param name="path">The file or folder to examine</param>
public abstract string HardlinkTargetID(string path);
#endregion
}
diff --git a/Duplicati/Library/Snapshots/NoSnapshotLinux.cs b/Duplicati/Library/Snapshots/NoSnapshotLinux.cs
index cd586349e..a6d18c3b7 100644
--- a/Duplicati/Library/Snapshots/NoSnapshotLinux.cs
+++ b/Duplicati/Library/Snapshots/NoSnapshotLinux.cs
@@ -53,9 +53,11 @@ namespace Duplicati.Library.Snapshots
/// </summary>
/// <returns>The metadata for the given file or folder</returns>
/// <param name="file">The file or folder to examine</param>
- public override Dictionary<string, string> GetMetadata(string file)
+ /// <param name="isSymlink">A flag indicating if the target is a symlink</param>
+ /// <param name="followSymlink">A flag indicating if a symlink should be followed</param>
+ public override Dictionary<string, string> GetMetadata(string file, bool isSymlink, bool followSymlink)
{
- return _sysIO.GetMetadata(file);
+ return _sysIO.GetMetadata(file, isSymlink, followSymlink);
}
/// <summary>
diff --git a/Duplicati/Library/Snapshots/NoSnapshotWindows.cs b/Duplicati/Library/Snapshots/NoSnapshotWindows.cs
index 00cb23c86..e708042ac 100644
--- a/Duplicati/Library/Snapshots/NoSnapshotWindows.cs
+++ b/Duplicati/Library/Snapshots/NoSnapshotWindows.cs
@@ -146,9 +146,11 @@ namespace Duplicati.Library.Snapshots
/// </summary>
/// <returns>The metadata for the given file or folder</returns>
/// <param name="file">The file or folder to examine</param>
- public override Dictionary<string, string> GetMetadata(string file)
+ /// <param name="isSymlink">A flag indicating if the target is a symlink</param>
+ /// <param name="followSymlink">A flag indicating if a symlink should be followed</param>
+ public override Dictionary<string, string> GetMetadata(string file, bool isSymlink, bool followSymlink)
{
- return m_sysIO.GetMetadata(file);
+ return m_sysIO.GetMetadata(file, isSymlink, followSymlink);
}
/// <summary>
diff --git a/Duplicati/Library/Snapshots/SnapshotUtility.cs b/Duplicati/Library/Snapshots/SnapshotUtility.cs
index dfd45a07f..9d02515be 100644
--- a/Duplicati/Library/Snapshots/SnapshotUtility.cs
+++ b/Duplicati/Library/Snapshots/SnapshotUtility.cs
@@ -36,12 +36,44 @@ namespace Duplicati.Library.Snapshots
/// <returns>The ISnapshotService implementation</returns>
public static ISnapshotService CreateSnapshot(string[] folders, Dictionary<string, string> options)
{
- if (Utility.Utility.IsClientLinux)
- return new LinuxSnapshot(folders, options);
- else
- return new WindowsSnapshot(folders, options);
+ return
+ Utility.Utility.IsClientLinux
+ ? CreateLinuxSnapshot(folders, options)
+ : CreateWindowsSnapshot(folders, options);
+
}
+ // The two loader methods below guard agains the type system attempting to load types
+ // related to the OS specific implementations which may not be present for
+ // the operation system we are not running on (i.e. prevent loading AlphaVSS on Linux)
+
+ /// <summary>
+ /// Loads a snapshot implementation for Linux
+ /// </summary>
+ /// <param name="folders">The list of folders to create snapshots of</param>
+ /// <param name="options">A set of commandline options</param>
+ /// <returns>The ISnapshotService implementation</returns>
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ private static ISnapshotService CreateLinuxSnapshot(string[] folders, Dictionary<string, string> options)
+ {
+ return new LinuxSnapshot(folders, options);
+ }
+
+ /// <summary>
+ /// Loads a snapshot implementation for Windows
+ /// </summary>
+ /// <param name="folders">The list of folders to create snapshots of</param>
+ /// <param name="options">A set of commandline options</param>
+ /// <returns>The ISnapshotService implementation</returns>
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ private static ISnapshotService CreateWindowsSnapshot(string[] folders, Dictionary<string, string> options)
+ {
+ return new WindowsSnapshot(folders, options);
+ }
+
+ /// <summary>
+ /// Gets an interface for System.IO, which wraps all operations in a platform consistent manner.
+ /// </summary>
public static ISystemIO SystemIO
{
get
diff --git a/Duplicati/Library/Snapshots/SystemIOLinux.cs b/Duplicati/Library/Snapshots/SystemIOLinux.cs
index 785d04f98..2e05cabc9 100644
--- a/Duplicati/Library/Snapshots/SystemIOLinux.cs
+++ b/Duplicati/Library/Snapshots/SystemIOLinux.cs
@@ -165,20 +165,26 @@ namespace Duplicati.Library.Snapshots
Directory.Delete(NoSnapshot.NormalizePath(path), recursive);
}
- public Dictionary<string, string> GetMetadata(string file)
+ public Dictionary<string, string> GetMetadata(string file, bool isSymlink, bool followSymlink)
{
var f = NoSnapshot.NormalizePath(file);
var dict = new Dictionary<string, string>();
- var n = UnixSupport.File.GetExtendedAttributes(f);
+ var n = UnixSupport.File.GetExtendedAttributes(f, isSymlink, followSymlink);
if (n != null)
foreach(var x in n)
dict["unix-ext:" + x.Key] = Convert.ToBase64String(x.Value);
var fse = UnixSupport.File.GetUserGroupAndPermissions(f);
dict["unix:uid-gid-perm"] = string.Format("{0}-{1}-{2}", fse.UID, fse.GID, fse.Permissions);
- dict["unix:owner-name"] = fse.OwnerName;
- dict["unix:group-name"] = fse.GroupName;
+ if (fse.OwnerName != null)
+ {
+ dict["unix:owner-name"] = fse.OwnerName;
+ }
+ if (fse.GroupName != null)
+ {
+ dict["unix:group-name"] = fse.GroupName;
+ }
return dict;
}
diff --git a/Duplicati/Library/Snapshots/SystemIOWindows.cs b/Duplicati/Library/Snapshots/SystemIOWindows.cs
index cba47b071..943611f8e 100644
--- a/Duplicati/Library/Snapshots/SystemIOWindows.cs
+++ b/Duplicati/Library/Snapshots/SystemIOWindows.cs
@@ -27,11 +27,13 @@ namespace Duplicati.Library.Snapshots
public struct SystemIOWindows : ISystemIO
{
private const string UNCPREFIX = @"\\?\";
+ private const string UNCPREFIX_SERVER = @"\\?\UNC\";
+ private const string PATHPREFIX_SERVER = @"\\";
private static readonly string DIRSEP = System.IO.Path.DirectorySeparatorChar.ToString();
public static bool IsPathTooLong(string path)
{
- if (path.StartsWith(UNCPREFIX) || path.Length > 260)
+ if (path.StartsWith(UNCPREFIX) || path.StartsWith(UNCPREFIX_SERVER) || path.Length > 260)
return true;
return false;
@@ -39,10 +41,16 @@ namespace Duplicati.Library.Snapshots
public static string PrefixWithUNC(string path)
{
- if (!path.StartsWith(UNCPREFIX))
- return UNCPREFIX + path;
- else
+ if (path.StartsWith(UNCPREFIX_SERVER))
+ return path;
+
+ if (path.StartsWith(UNCPREFIX))
return path;
+
+ if (path.StartsWith(PATHPREFIX_SERVER))
+ return UNCPREFIX_SERVER + path.Remove(0, PATHPREFIX_SERVER.Length);
+
+ return UNCPREFIX + path;
}
public static string StripUNCPrefix(string path)
@@ -500,7 +508,7 @@ namespace Duplicati.Library.Snapshots
Alphaleonis.Win32.Filesystem.Directory.SetAccessControl(PrefixWithUNC(path), rules, AccessControlSections.All);
}
- public Dictionary<string, string> GetMetadata(string path)
+ public Dictionary<string, string> GetMetadata(string path, bool isSymlink, bool followSymlink)
{
var isDirTarget = path.EndsWith(DIRSEP);
var targetpath = isDirTarget ? path.Substring(0, path.Length - 1) : path;
diff --git a/Duplicati/Library/Snapshots/USNHelper.cs b/Duplicati/Library/Snapshots/USNHelper.cs
index 2b928023b..4099e73ad 100644
--- a/Duplicati/Library/Snapshots/USNHelper.cs
+++ b/Duplicati/Library/Snapshots/USNHelper.cs
@@ -74,7 +74,7 @@ namespace Duplicati.Library.Snapshots
internal USNHelper(string path, string volumeRoot)
{
if (Utility.Utility.IsClientLinux)
- throw new Exception(Strings.USNHelper.LinuxNotSupportedError);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.USNHelper.LinuxNotSupportedError);
if (!System.IO.Path.IsPathRooted(path))
throw new Exception(string.Format("Path {0} is not rooted", path));
diff --git a/Duplicati/Library/Snapshots/WinNativeMethods.cs b/Duplicati/Library/Snapshots/WinNativeMethods.cs
index 24ce042c4..bd2af622b 100644
--- a/Duplicati/Library/Snapshots/WinNativeMethods.cs
+++ b/Duplicati/Library/Snapshots/WinNativeMethods.cs
@@ -235,14 +235,14 @@ namespace Duplicati.Library.Snapshots
GetBackupPrivilege(out hasPrivilege, out isEnabled);
if (!hasPrivilege)
- throw new Exception(Strings.WinNativeMethod.MissingBackupPrivilegeError);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.WinNativeMethod.MissingBackupPrivilegeError);
return isEnabled;
}
set
{
if (!CanEnableBackupPrivilege)
- throw new Exception(Strings.WinNativeMethod.MissingBackupPrivilegeError);
+ throw new Duplicati.Library.Interface.UserInformationException(Strings.WinNativeMethod.MissingBackupPrivilegeError);
int token = 0;
int outsize = 0;
diff --git a/Duplicati/Library/Snapshots/WindowsSnapshot.cs b/Duplicati/Library/Snapshots/WindowsSnapshot.cs
index c9b11a970..f8f7b4ca1 100644
--- a/Duplicati/Library/Snapshots/WindowsSnapshot.cs
+++ b/Duplicati/Library/Snapshots/WindowsSnapshot.cs
@@ -24,7 +24,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using Alphaleonis.Win32.Vss;
-using System.Management;
namespace Duplicati.Library.Snapshots
{
@@ -68,11 +67,6 @@ namespace Duplicati.Library.Snapshots
/// </summary>
private static readonly SystemIOWindows _ioWin = new SystemIOWindows();
/// <summary>
- /// The Hyper-V VSS Writer Guid
- /// </summary>
- private static readonly Guid HyperVWriterGuid = new Guid("66841cd4-6ded-4f4b-8f17-fd23f8ddc3de");
-
- /// <summary>
/// Constructs a new backup snapshot, using all the required disks
/// </summary>
/// <param name="sourcepaths">The folders that are about to be backed up</param>
@@ -103,33 +97,23 @@ namespace Duplicati.Library.Snapshots
m_backup.DisableWriterClasses(excludedWriters.ToArray());
m_sourcepaths = sourcepaths.Select(x => Directory.Exists(x) ? Utility.Utility.AppendDirSeparator(x) : x).ToList();
-
- List<string> hypervPaths;
-
+
try
{
m_backup.GatherWriterMetadata();
-
- hypervPaths = PrepareHyperVBackup(options, m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(HyperVWriterGuid)));
}
finally
{
m_backup.FreeWriterMetadata();
}
- if (hypervPaths != null)
- m_sourcepaths.AddRange(hypervPaths);
-
//Sanity check for duplicate files/folders
- var pathDuplicates = m_sourcepaths.GroupBy(x => x, Utility.Utility.ClientFilenameStringComparer)
- .Where(g => g.Count() > 1).Select(y => y.Key).ToList();
+ ISet<string> pathDuplicates;
+ m_sourcepaths = Utility.Utility.GetUniqueItems(m_sourcepaths, Utility.Utility.ClientFilenameStringComparer, out pathDuplicates).ToList();
foreach(var pathDuplicate in pathDuplicates)
Logging.Log.WriteMessage(string.Format("Removing duplicate source: {0}", pathDuplicate), Logging.LogMessageType.Information);
- if(pathDuplicates.Count > 0)
- m_sourcepaths = m_sourcepaths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList();
-
//Sanity check for multiple inclusions of the same files/folders
var pathIncludedPaths = m_sourcepaths.Where(x => m_sourcepaths.Where(y => y != x).Any(z => x.StartsWith(z, Utility.Utility.ClientFilenameStringComparision))).ToList();
@@ -142,7 +126,7 @@ namespace Duplicati.Library.Snapshots
m_backup.StartSnapshotSet();
//Figure out which volumes are in the set
- m_volumes = new Dictionary<string, Guid>(StringComparer.InvariantCultureIgnoreCase);
+ m_volumes = new Dictionary<string, Guid>(StringComparer.OrdinalIgnoreCase);
foreach (string s in m_sourcepaths)
{
string drive = Alphaleonis.Win32.Filesystem.Path.GetPathRoot(s);
@@ -162,7 +146,7 @@ namespace Duplicati.Library.Snapshots
m_backup.DoSnapshotSet();
//Make a little lookup table for faster translation
- m_volumeMap = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
+ m_volumeMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (KeyValuePair<string, Guid> kvp in m_volumes)
m_volumeMap.Add(kvp.Key, m_backup.GetSnapshotProperties(kvp.Value).SnapshotDeviceObject);
@@ -192,88 +176,6 @@ namespace Duplicati.Library.Snapshots
}
}
- private List<string> PrepareHyperVBackup(Dictionary<string, string> options, IVssExamineWriterMetadata writerMetaData)
- {
- var resultPaths = new List<string>();
- var requestedHyperVMs = new List<string>();
-
- if (options.ContainsKey("hyperv-backup-vm"))
- requestedHyperVMs = options["hyperv-backup-vm"].Split(';').Where(x => !string.IsNullOrWhiteSpace(x) && x.Trim().Length > 0).ToList();
-
- if (requestedHyperVMs.Count == 0)
- return resultPaths;
-
- Logging.Log.WriteMessage("Starting to gather Hyper-V information.", Logging.LogMessageType.Information);
-
- var hyperVGuests = new HyperVUtility().GetHyperVGuests();
-
- Logging.Log.WriteMessage(string.Format("Found {0} virtual machines on Hyper-V.", hyperVGuests.Count), Logging.LogMessageType.Information);
-
- bool bNotFound = false;
- var notFoundVM = new List<string>();
-
- foreach (var requestedHyperVM in requestedHyperVMs)
- {
- var foundVMs = hyperVGuests.FindAll(x => (string.Equals(requestedHyperVM, x.ID, StringComparison.CurrentCultureIgnoreCase)));
-
- if (foundVMs.Count != 1)
- {
- bNotFound = true;
- notFoundVM.Add(requestedHyperVM);
- Logging.Log.WriteMessage(string.Format("Cannot find virtual machine with ID {0} on Hyper-V.", requestedHyperVM), Logging.LogMessageType.Error);
- }
- else
- Logging.Log.WriteMessage(string.Format("Found virtual machine {0} with ID {1} on Hyper-V.", foundVMs[0].Name, requestedHyperVM), Logging.LogMessageType.Information);
- }
-
- if (bNotFound)
- throw new Exception(string.Format("Cannot find virtual machine with ID {0} on Hyper-V.", string.Join(", ", notFoundVM.ToArray())));
-
- var productType = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
- .Get().OfType<ManagementObject>()
- .Select(o => (uint)o.GetPropertyValue("ProductType")).First();
-
- if (productType != 1) // Hyper-V writer is present only on Server version of Windows
- {
- if (writerMetaData == null)
- throw new Exception("Microsoft Hyper-V VSS Writer not found - cannot backup Hyper-V machines.");
-
- foreach (var component in writerMetaData.Components)
- if (requestedHyperVMs.Contains(component.ComponentName, StringComparer.CurrentCultureIgnoreCase))
- foreach (var file in component.Files)
- if (file.FileSpecification.Contains("*"))
- {
- if (Directory.Exists(Utility.Utility.AppendDirSeparator(file.Path)))
- {
- resultPaths.Add(Utility.Utility.AppendDirSeparator(file.Path));
- Logging.Log.WriteMessage(string.Format("For VM {0} - adding {1}.", component.ComponentName, Utility.Utility.AppendDirSeparator(file.Path)), Logging.LogMessageType.Profiling);
- }
- }
- else
- {
- if (File.Exists(Path.Combine(file.Path, file.FileSpecification)))
- {
- resultPaths.Add(Path.Combine(file.Path, file.FileSpecification));
- Logging.Log.WriteMessage(string.Format("For VM {0} - adding {1}.", component.ComponentName, Path.Combine(file.Path, file.FileSpecification)), Logging.LogMessageType.Profiling);
- }
- }
- }
- else
- {
- Logging.Log.WriteMessage("This is client version of Windows. Hyper-V VSS writer is present only on Server version. Backup will continue, but will be crash consistent only in opposite to application consistent in Server version.", Logging.LogMessageType.Warning);
-
- foreach (var hyperVGuest in hyperVGuests)
- if (requestedHyperVMs.Contains(hyperVGuest.ID, StringComparer.CurrentCultureIgnoreCase))
- foreach (var path in hyperVGuest.DataPaths)
- {
- resultPaths.Add(path);
- Logging.Log.WriteMessage(string.Format("For VM {0} - adding {1}.", hyperVGuest.ID, path), Logging.LogMessageType.Profiling);
- }
- }
-
- return resultPaths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList();
- }
-
#if DEBUG
/// <summary>
/// Returns all files found in the shadow copies
@@ -281,7 +183,7 @@ namespace Duplicati.Library.Snapshots
/// <returns>A list of filenames to files found in the shadow volumes</returns>
public List<string> AllFiles()
{
- return EnumerateFilesAndFolders(null).ToList();
+ return EnumerateFilesAndFolders(null, null).ToList();
}
#endif
@@ -392,12 +294,12 @@ namespace Duplicati.Library.Snapshots
/// <summary>
/// Enumerates all files and folders in the shadow copy
/// </summary>
- /// <param name="filter">The filter to apply when evaluating files and folders</param>
/// <param name="callback">The callback to invoke with each found path</param>
- public IEnumerable<string> EnumerateFilesAndFolders(Utility.Utility.EnumerationFilterDelegate callback)
+ /// <param name="errorCallback">The callback used to report errors</param>
+ public IEnumerable<string> EnumerateFilesAndFolders(Duplicati.Library.Utility.Utility.EnumerationFilterDelegate callback, Duplicati.Library.Utility.Utility.ReportAccessError errorCallback)
{
return m_sourcepaths.SelectMany(
- s => Utility.Utility.EnumerateFileSystemEntries(s, callback, this.ListFolders, this.ListFiles, this.GetAttributes)
+ s => Utility.Utility.EnumerateFileSystemEntries(s, callback, this.ListFolders, this.ListFiles, this.GetAttributes, errorCallback)
);
}
@@ -489,9 +391,11 @@ namespace Duplicati.Library.Snapshots
/// </summary>
/// <returns>The metadata for the given file or folder</returns>
/// <param name="file">The file or folder to examine</param>
- public Dictionary<string, string> GetMetadata(string file)
+ /// <param name="isSymlink">A flag indicating if the target is a symlink</param>
+ /// <param name="followSymlink">A flag indicating if a symlink should be followed</param>
+ public Dictionary<string, string> GetMetadata(string file, bool isSymlink, bool followSymlink)
{
- return _ioWin.GetMetadata(GetSnapshotPath(file));
+ return _ioWin.GetMetadata(GetSnapshotPath(file), isSymlink, followSymlink);
}
/// <summary>
diff --git a/Duplicati/Library/Snapshots/lvm-scripts/create-lvm-snapshot.sh b/Duplicati/Library/Snapshots/lvm-scripts/create-lvm-snapshot.sh
index a83c0b605..693d9fc81 100644
--- a/Duplicati/Library/Snapshots/lvm-scripts/create-lvm-snapshot.sh
+++ b/Duplicati/Library/Snapshots/lvm-scripts/create-lvm-snapshot.sh
@@ -23,7 +23,7 @@ TMPDIR=$3$NAME
# the snapshot is active.
# Adjust these numbers to your system needs.
MIN_FREE_BLOCKS=20
-MAX_FREE_BLOCKS=100
+MAX_FREE_BLOCKS=1000
#
# Get the number of free blocks on the volume
@@ -117,13 +117,26 @@ then
fi
#
+# Find filesystem used on $DEVICE.
+# XFS filesystems need to be mounted with option -o nouuid.
+# Other filesystems do not support that option.
+#
+
+FILESYSTEM=`df -PT /dev/"$DEVICE" | tail -1 | awk '{print $2}'`
+if [ "$FILESYSTEM" == "xfs" ]; then
+ MOUNT_OPTIONS="ro,nouuid"
+else
+ MOUNT_OPTIONS="ro"
+fi
+
+#
# Mount the snapshot on the mount point
#
-mount -o ro "$LV_SNAPSHOT" "$TMPDIR"
+mount -o "$MOUNT_OPTIONS" "$LV_SNAPSHOT" "$TMPDIR"
if [ "$?" -ne 0 ]
then
EXIT_CODE=$?
- echo "Error: mount -o ro \"$LV_SNAPSHOT\" \"$TMPDIR\" failed!"
+ echo "Error: mount -o \"$MOUNTOPTIONS\" \"$LV_SNAPSHOT\" \"$TMPDIR\" failed!"
#We have created the volume, so remove it before exit
lvremove --force "$LV_GROUP/$NAME"
@@ -134,4 +147,4 @@ fi
# Report back to the caller what the name of the snapshot volume is
#
echo "tmpdir=\"$TMPDIR\""
-exit 0 \ No newline at end of file
+exit 0
diff --git a/Duplicati/Library/Snapshots/lvm-scripts/find-volume.sh b/Duplicati/Library/Snapshots/lvm-scripts/find-volume.sh
index 0bb652035..7ae2029ed 100644
--- a/Duplicati/Library/Snapshots/lvm-scripts/find-volume.sh
+++ b/Duplicati/Library/Snapshots/lvm-scripts/find-volume.sh
@@ -20,17 +20,17 @@ NAME=$1
# Get the reported mount point for the current folder
#
VOLUME=`df -P "$NAME" | tail -1 | awk '{ print $1}'`
-if [ "$?" -ne 0 ]
+if [ "$?" -ne 0 ] || [ -z "$VOLUME" ]
then
- EXIT_CODE=$?
+ [[ "$?" -ne 0 ]] && EXIT_CODE=$? || EXIT_CODE=-1
echo "Error: unable to determine device for $NAME"
exit $EXIT_CODE
fi
MOUNTPOINT=`df -P "$NAME" | tail -1 | awk '{ print $NF}'`
-if [ "$?" -ne 0 ]
+if [ "$?" -ne 0 ] || [ -z "$MOUNTPOINT" ]
then
- EXIT_CODE=$?
+ [[ "$?" -ne 0 ]] && EXIT_CODE=$? || EXIT_CODE=-1
echo "Error: unable to determine mount point for $NAME"
exit $EXIT_CODE
fi
@@ -38,15 +38,37 @@ fi
#
# Get the LVM path for the mapped volume
#
-LVMID=`lvs "$VOLUME" --options vg_name,lv_name --noheadings | tail -1 | awk '{ print $1 "/" $2}'`
-if [ "$?" -ne 0 ]
+
+function get_lvmid {
+ LVMID=`lvs "$1" --options vg_name,lv_name --noheadings 2>/dev/null | tail -1 | awk '{ print $1 "/" $2}'`
+ if [ "$?" -ne 0 ]
+ then
+ EXIT_CODE=$?
+ echo "Error: Unable to determine volume group (VG) for mapped volume $VOLUME"
+ exit $EXIT_CODE
+ fi
+ export LVMID
+}
+
+get_lvmid $VOLUME
+
+#
+# Get the LVM path for the mapped volume (second try)
+#
+if [ -z "$LVMID" ]
+then
+ VOLUME=`mount | awk '($3 == "'$MOUNTPOINT'") {print $1}'`
+ get_lvmid $VOLUME
+fi
+
+if [ -z "$LVMID" ]
then
- EXIT_CODE=$?
- echo "Error: Unable to determine volume group (VG) for mapped volume $VOLUME"
+ EXIT_CODE=-1
+ echo "Error: unable to determine volume group (VG) for $NAME"
exit $EXIT_CODE
fi
echo "mountpoint=\"$MOUNTPOINT\""
echo "device=\"$LVMID\""
-exit 0 \ No newline at end of file
+exit 0
diff --git a/Duplicati/Library/Snapshots/packages.config b/Duplicati/Library/Snapshots/packages.config
index ff4bef1ee..7f058e904 100644
--- a/Duplicati/Library/Snapshots/packages.config
+++ b/Duplicati/Library/Snapshots/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="AlphaFS" version="2.0.1" targetFramework="net45" />
- <package id="AlphaVSS" version="1.2.4000.3" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="AlphaFS" version="2.1.3" targetFramework="net45" />
+ <package id="AlphaVSS" version="1.4.0" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj b/Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj
index 0e85ce05d..b00614bad 100644
--- a/Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj
+++ b/Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj
@@ -8,8 +8,8 @@
<RootNamespace>Duplicati.Library.UsageReporter</RootNamespace>
<AssemblyName>Duplicati.Library.UsageReporter</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -31,11 +31,11 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
- <Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
- </Reference>
<Reference Include="CoCoL">
- <HintPath>..\..\..\packages\CoCoL.1.5.0\lib\net45\CoCoL.dll</HintPath>
+ <HintPath>..\..\..\packages\CoCoL.1.5.1\lib\net45\CoCoL.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json">
+ <HintPath>..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -46,7 +46,6 @@
<Compile Include="ReportSet.cs" />
<Compile Include="OSInfoHelper.cs" />
<Compile Include="EventProcessor.cs" />
- <Compile Include="ShutdownHelper.cs" />
<Compile Include="ReportSetUploader.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
diff --git a/Duplicati/Library/UsageReporter/EventProcessor.cs b/Duplicati/Library/UsageReporter/EventProcessor.cs
index fa21607aa..998f91019 100644
--- a/Duplicati/Library/UsageReporter/EventProcessor.cs
+++ b/Duplicati/Library/UsageReporter/EventProcessor.cs
@@ -25,7 +25,7 @@ using System.Collections.Generic;
namespace Duplicati.Library.UsageReporter
{
- public class EventProcessor : ShutdownHelper
+ public static class EventProcessor
{
/// <summary>
/// The maximum number of events to collect before transmitting
@@ -40,27 +40,7 @@ namespace Duplicati.Library.UsageReporter
/// <summary>
/// The time to wait before sending event
/// </summary>
- private readonly TimeSpan WAIT_TIME = TimeSpan.FromMinutes(5);
-
- /// <summary>
- /// The input channel for receiving events
- /// </summary>
- internal readonly IWriteChannel<ReportItem> Channel;
-
- /// <summary>
- /// The input channel for receiving events
- /// </summary>
- private readonly IChannel<ReportItem> m_channel;
-
- /// <summary>
- /// The completion task
- /// </summary>
- public readonly Task Terminated;
-
- /// <summary>
- /// The forwarding destination
- /// </summary>
- private readonly IWriteChannel<string> m_forward;
+ private static readonly TimeSpan WAIT_TIME = TimeSpan.FromMinutes(5);
/// <summary>
/// The prefix for generated filenames
@@ -78,67 +58,103 @@ namespace Duplicati.Library.UsageReporter
private static readonly Regex FILNAME_MATCHER = new Regex(string.Format(FILENAME_TEMPLATE, "(?<id>[0-9]+)", "(?<time>[0-9]+)"));
/// <summary>
- /// The current process ID
- /// </summary>
- private readonly string INSTANCE_ID;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Duplicati.Library.UsageReporter.EventProcessor"/> class.
- /// </summary>
- /// <param name="forwardChannel">The forwarding destination.</param>
- public EventProcessor(IWriteChannel<string> forwardChannel)
- {
- INSTANCE_ID = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
-
- Channel = m_channel = ChannelManager.CreateChannel<ReportItem>(null, MAX_QUEUE_SIZE);
- m_forward = forwardChannel;
- Terminated = RunProtected(Run);
- }
-
- /// <summary>
- /// Run the processing of incomming requests
+ /// Runs the report processor
/// </summary>
- private async Task Run()
+ /// <param name="forward">The channel accepting filenames with usage reports.</param>
+ internal static Tuple<Task, IWriteChannel<ReportItem>> Run(IWriteChannel<string> forward)
{
- var rs = new ReportSet();
- var tf = GetTempFilename();
-
- foreach(var f in GetAbandonedFiles(null))
- await m_forward.WriteAsync(f);
-
- while(true)
- {
- var forceSend = false;
- try
+ var instanceid = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
+ var channel = ChannelManager.CreateChannel<ReportItem>(
+ maxPendingWriters: MAX_QUEUE_SIZE,
+ pendingWritersOverflowStrategy: QueueOverflowStrategy.LIFO
+ );
+
+ var task = AutomationExtensions.RunTask(
+ new
{
- var item = await m_channel.ReadAsync(rs.Items.Count == 0 ? Timeout.Infinite : WAIT_TIME);
- if (item != null)
+ Input = channel.AsRead(),
+ Output = forward
+ },
+ async (self) =>
+ {
+ // Wait 20 seconds before we start transmitting
+ for(var i = 0; i < 20; i++)
{
- forceSend = item.Type == ReportType.Crash;
- rs.Items.Add(item);
- File.WriteAllText(tf, JsonConvert.SerializeObject(rs));
+ await Task.Delay(TimeSpan.FromSeconds(1));
+ if (await self.Input.IsRetiredAsync)
+ return;
}
- }
- catch(TimeoutException)
- {
- forceSend = true;
- }
- if ((forceSend && rs.Items.Count > 0) || (rs.Items.Count > MAX_ITEMS_IN_SET))
- {
- var nextFilename = GetTempFilename();
- await m_forward.WriteAsync(tf);
- rs = new ReportSet();
+ foreach (var f in GetAbandonedFiles(null))
+ {
+ // Check if we should exit
+ if (await self.Input.IsRetiredAsync)
+ return;
+
+ await self.Output.WriteAsync(f);
+ }
- foreach(var f in GetAbandonedFiles(tf))
- await m_forward.WriteAsync(f);
+ var rs = new ReportSet();
+ var tf = GetTempFilename(instanceid);
+ var nextTransmitTarget = new DateTime(0);
- tf = nextFilename;
+ while (true)
+ {
+ var forceSend = false;
+ try
+ {
+ // We wait until we get an item, or WAIT_TIME from the last event
+ var waittime =
+ rs.Items.Count == 0
+ ? Timeout.Infinite
+ : new TimeSpan(Math.Max(0, (nextTransmitTarget - DateTime.UtcNow).Ticks));
+
+ var item = await self.Input.ReadAsync(waittime);
+ if (item != null)
+ {
+ if (rs.Items.Count == 0)
+ nextTransmitTarget = DateTime.UtcNow + WAIT_TIME;
+
+ forceSend = item.Type == ReportType.Crash;
+ rs.Items.Add(item);
+ File.WriteAllText(tf, JsonConvert.SerializeObject(rs));
+ }
+ }
+ catch (TimeoutException)
+ {
+ forceSend = true;
+ }
+
+ if ((forceSend && rs.Items.Count > 0) || (rs.Items.Count > MAX_ITEMS_IN_SET))
+ {
+ var nextFilename = GetTempFilename(instanceid);
+ self.Output.WriteNoWait(tf);
+ rs = new ReportSet();
+
+ foreach (var f in GetAbandonedFiles(tf))
+ {
+ if (await self.Input.IsRetiredAsync)
+ return;
+
+ self.Output.WriteNoWait(f);
+ }
+
+ tf = nextFilename;
+ }
+ }
}
- }
+ );
+
+ return new Tuple<Task, IWriteChannel<ReportItem>>(task, channel);
}
- private IEnumerable<string> GetAbandonedFiles(string current)
+ /// <summary>
+ /// Gets a list of abandoned files, meaning files that appear to be Duplicati files.
+ /// These should have been uploaded, but if they are found they are somehow left-over.
+ /// </summary>
+ /// <returns>The abandoned files.</returns>
+ /// <param name="current">The current file, which is excluded from the results.</param>
+ private static IEnumerable<string> GetAbandonedFiles(string current)
{
return
from n in GetAbandonedMatches(current)
@@ -146,7 +162,12 @@ namespace Duplicati.Library.UsageReporter
select n.Key;
}
- private IEnumerable<KeyValuePair<string, long>> GetAbandonedMatches(string current)
+ /// <summary>
+ /// Gets files that match the temporary file prefix
+ /// </summary>
+ /// <returns>The abandoned matches.</returns>
+ /// <param name="current">The current file, which is excluded from the results.</param>
+ private static IEnumerable<KeyValuePair<string, long>> GetAbandonedMatches(string current)
{
foreach(var f in Directory.EnumerateFiles(Path.GetTempPath(), FILENAME_PREFIX + "*", SearchOption.TopDirectoryOnly))
{
@@ -171,9 +192,14 @@ namespace Duplicati.Library.UsageReporter
}
}
- private string GetTempFilename()
+ /// <summary>
+ /// Gets a unique timestamped filename using the template
+ /// </summary>
+ /// <returns>The temporary filename.</returns>
+ /// <param name="instanceid">The instance ID of this process.</param>
+ private static string GetTempFilename(string instanceid)
{
- return Path.Combine(Path.GetTempPath(), string.Format(FILENAME_TEMPLATE, INSTANCE_ID, DateTime.UtcNow.ToString("yyyyMMddHHmmss")));
+ return Path.Combine(Path.GetTempPath(), string.Format(FILENAME_TEMPLATE, instanceid, DateTime.UtcNow.ToString("yyyyMMddHHmmss")));
}
}
}
diff --git a/Duplicati/Library/UsageReporter/OSInfoHelper.cs b/Duplicati/Library/UsageReporter/OSInfoHelper.cs
index 3eee098d0..8246300b9 100644
--- a/Duplicati/Library/UsageReporter/OSInfoHelper.cs
+++ b/Duplicati/Library/UsageReporter/OSInfoHelper.cs
@@ -15,21 +15,33 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
+using System.Collections.Generic;
using System.Linq;
namespace Duplicati.Library.UsageReporter
{
- internal static class OSInfoHelper
+ /// <summary>
+ /// Helper class for extracting operating system info
+ /// </summary>
+ public static class OSInfoHelper
{
+ /// <summary>
+ /// Runs a commandline program and returns stdout as a string.
+ /// </summary>
+ /// <returns>The stdout value.</returns>
+ /// <param name="cmd">The command to run.</param>
+ /// <param name="args">The commandline arguments.</param>
private static string RunProgramAndReadOutput(string cmd, string args)
{
+ System.Diagnostics.Process pi = null;
try
{
var psi = new System.Diagnostics.ProcessStartInfo(cmd, args);
psi.RedirectStandardOutput = true;
+ psi.RedirectStandardError = true; // Suppress error messages
psi.UseShellExecute = false;
- var pi = System.Diagnostics.Process.Start(psi);
+ pi = System.Diagnostics.Process.Start(psi);
pi.WaitForExit(5000);
if (pi.HasExited)
return pi.StandardOutput.ReadToEnd().Trim();
@@ -37,6 +49,12 @@ namespace Duplicati.Library.UsageReporter
catch
{
}
+ finally
+ {
+ if (pi != null && !pi.HasExited)
+ try { pi.Kill(); }
+ catch { }
+ }
return null;
}
@@ -71,6 +89,58 @@ namespace Duplicati.Library.UsageReporter
}
else
{
+ // Manual extraction, this grabs the distro identication files directly
+ try
+ {
+ var keys = new List<Tuple<string, string>>();
+ foreach (var fn in System.IO.Directory.GetFiles("/etc/", "*-release"))
+ {
+ var fi = new System.IO.FileInfo(fn);
+ if (fi.Exists && fi.Length < 1024 * 10)
+ {
+ try
+ {
+ keys.AddRange(
+ System.IO.File.ReadAllLines(fi.FullName)
+ .Select(x =>
+ {
+ var items = (x ?? string.Empty).Split(new char[] { '=' }, 2).Select(y => (y ?? string.Empty).Trim('"')).ToArray();
+ if (items.Length != 2 || items.Any(y => string.IsNullOrWhiteSpace(y)))
+ return null;
+
+ return new Tuple<string, string>(items[0], items[1]);
+ })
+ .Where(x => x != null)
+ );
+ }
+ catch { }
+
+ }
+ }
+
+ var primary = keys.FirstOrDefault(x => string.Equals(x.Item1, "PRETTY_NAME", StringComparison.OrdinalIgnoreCase));
+ if (primary != null)
+ return primary.Item2;
+
+ var name = keys.FirstOrDefault(x => string.Equals(x.Item1, "NAME", StringComparison.OrdinalIgnoreCase));
+ var version = keys.FirstOrDefault(x => string.Equals(x.Item1, "VERSION", StringComparison.OrdinalIgnoreCase));
+
+ name = name ?? keys.FirstOrDefault(x => string.Equals(x.Item1, "DISTRIB_ID", StringComparison.OrdinalIgnoreCase));
+ name = name ?? keys.FirstOrDefault(x => string.Equals(x.Item1, "ID", StringComparison.OrdinalIgnoreCase));
+
+ version = version ?? keys.FirstOrDefault(x => string.Equals(x.Item1, "DISTRIB_RELEASE", StringComparison.OrdinalIgnoreCase));
+ version = version ?? keys.FirstOrDefault(x => string.Equals(x.Item1, "VERSION_ID", StringComparison.OrdinalIgnoreCase));
+
+ if (name != null && version != null)
+ return string.Format("{0} {1}", name.Item2, version.Item2);
+ if (name != null)
+ return name.Item2;
+ }
+ catch
+ {
+ }
+
+ // This works on debian based distros, but emits a warning to stderr
var m = RunProgramAndReadOutput("lsb_release", "-a");
if (m != null)
{
@@ -80,8 +150,8 @@ namespace Duplicati.Library.UsageReporter
return line;
}
+ // This should work on all Linux based systems
return RunProgramAndReadOutput("uname", "-srvmpio");
-
}
return null;
diff --git a/Duplicati/Library/UsageReporter/ReportSetUploader.cs b/Duplicati/Library/UsageReporter/ReportSetUploader.cs
index 84bd9c350..a2e9f7600 100644
--- a/Duplicati/Library/UsageReporter/ReportSetUploader.cs
+++ b/Duplicati/Library/UsageReporter/ReportSetUploader.cs
@@ -24,12 +24,12 @@ using System.Net;
namespace Duplicati.Library.UsageReporter
{
- public class ReportSetUploader : ShutdownHelper
+ public static class ReportSetUploader
{
/// <summary>
/// The maximum number of pending uploads
/// </summary>
- private const int MAX_PENDING_UPLOADS = 500;
+ private const int MAX_PENDING_UPLOADS = 50;
/// <summary>
/// The target upload url
@@ -37,88 +37,66 @@ namespace Duplicati.Library.UsageReporter
private const string UPLOAD_URL = "https://usage-reporter.duplicati.com/api/v1/report";
/// <summary>
- /// The input channel for receiving events
+ /// Runs the upload process
/// </summary>
- private readonly IChannel<string> m_channel;
-
- /// <summary>
- /// The input channel for receiving events
- /// </summary>
- public readonly IWriteChannel<string> Channel;
-
- /// <summary>
- /// The internal channel for passing filtered requests
- /// </summary>
- private readonly IChannel<string> FilterChannel;
-
- /// <summary>
- /// The completion task
- /// </summary>
- public readonly Task Terminated;
-
- public ReportSetUploader()
+ /// <returns>A tuple with the completion task and the channel to use</returns>
+ public static Tuple<Task, IWriteChannel<string>> Run()
{
- Channel = m_channel = ChannelManager.CreateChannel<string>(buffersize: MAX_PENDING_UPLOADS);
- FilterChannel = ChannelManager.CreateChannel<string>();
-
- Terminated = Task.WhenAll(
- RunProtected(async () => {
- // If we have more than MAX_PENDING_UPLOADS
- // the newest ones are just discarded
- // they will be picked up on the later runs
-
- while (true)
- FilterChannel.TryWrite(await m_channel.ReadAsync());
- }),
- RunProtected(Run)
+ var channel = ChannelManager.CreateChannel<string>(
+ buffersize: MAX_PENDING_UPLOADS,
+ pendingWritersOverflowStrategy: QueueOverflowStrategy.LIFO
);
- }
- /// <summary>
- /// Run the processing of incomming requests
- /// </summary>
- private async Task Run()
- {
- while (true)
- {
- var f = await FilterChannel.ReadAsync();
+ var task = AutomationExtensions.RunTask(
+ channel.AsRead(),
- try
+ async (chan) =>
{
- if (File.Exists(f))
+ while (true)
{
- var req = (HttpWebRequest)WebRequest.Create(UPLOAD_URL);
- req.Method = "POST";
- req.ContentType = "application/json; charset=utf-8";
+ var f = await chan.ReadAsync();
- int rc;
- using(var fs = File.OpenRead(f))
+ try
{
- if (fs.Length > 0)
+ if (File.Exists(f))
{
- req.ContentLength = fs.Length;
- var areq = new Library.Utility.AsyncHttpRequest(req);
-
- using(var rs =areq.GetRequestStream())
- Library.Utility.Utility.CopyStream(fs, rs);
-
- using(var resp = (HttpWebResponse)areq.GetResponse())
- rc = (int)resp.StatusCode;
+ var req = (HttpWebRequest)WebRequest.Create(UPLOAD_URL);
+ req.Method = "POST";
+ req.ContentType = "application/json; charset=utf-8";
+
+ int rc;
+ using (var fs = File.OpenRead(f))
+ {
+ if (fs.Length > 0)
+ {
+ req.ContentLength = fs.Length;
+ var areq = new Library.Utility.AsyncHttpRequest(req);
+
+ using (var rs = areq.GetRequestStream())
+ Library.Utility.Utility.CopyStream(fs, rs);
+
+ using (var resp = (HttpWebResponse)areq.GetResponse())
+ rc = (int)resp.StatusCode;
+ }
+ else
+ rc = 200;
+ }
+
+ if (rc >= 200 && rc <= 299)
+ File.Delete(f);
}
- else
- rc = 200;
}
-
- if (rc >= 200 && rc <= 299)
- File.Delete(f);
+ catch (Exception ex)
+ {
+ Logging.Log.WriteMessage("UsageReporter failed", Duplicati.Library.Logging.LogMessageType.Error, ex);
+ }
}
}
- catch (Exception ex)
- {
- Logging.Log.WriteMessage("UsageReporter failed", Duplicati.Library.Logging.LogMessageType.Error, ex);
- }
- }
+ );
+
+ return new Tuple<Task, IWriteChannel<string>>(task, channel);
}
+
}
}
diff --git a/Duplicati/Library/UsageReporter/Reporter.cs b/Duplicati/Library/UsageReporter/Reporter.cs
index 3f987a9c9..e89a154ed 100644
--- a/Duplicati/Library/UsageReporter/Reporter.cs
+++ b/Duplicati/Library/UsageReporter/Reporter.cs
@@ -44,7 +44,7 @@ namespace Duplicati.Library.UsageReporter
public static void Report(string key, string data = null, ReportType type = ReportType.Information)
{
if (_eventChannel != null && type >= MaxReportLevel)
- try { _eventChannel.TryWrite(new ReportItem(type, null, key, data)); }
+ try { _eventChannel.WriteNoWait(new ReportItem(type, null, key, data)); }
catch { }
}
@@ -57,20 +57,19 @@ namespace Duplicati.Library.UsageReporter
public static void Report(string key, long count, ReportType type = ReportType.Information)
{
if (_eventChannel != null && type >= MaxReportLevel)
- try { _eventChannel.TryWrite(new ReportItem(type, count, key, count.ToString())); }
+ try { _eventChannel.WriteNoWait(new ReportItem(type, count, key, count.ToString())); }
catch { }
}
/// <summary>
/// Reports an exception event, error by default
/// </summary>
- /// <param name="key">The event name</param>
- /// <param name="count">The event count</param>
+ /// <param name="ex">The exception</param>
/// <param name="type">The event type</param>
public static void Report(Exception ex, ReportType type = ReportType.Warning)
{
if (_eventChannel != null && type >= MaxReportLevel)
- try { _eventChannel.TryWrite(new ReportItem(type, null, "EXCEPTION", ex.ToString())); }
+ try { _eventChannel.WriteNoWait(new ReportItem(type, null, "EXCEPTION", ex.ToString())); }
catch { }
}
@@ -79,16 +78,16 @@ namespace Duplicati.Library.UsageReporter
/// </summary>
public static void Initialize()
{
- if (_eventChannel == null || _eventChannel.IsRetired)
+ if (_eventChannel == null || _eventChannel.IsRetiredAsync.Result)
{
if (IsDisabled)
return;
- var rsu = new ReportSetUploader();
- var ep = new EventProcessor(rsu.Channel);
- _eventChannel = ep.Channel;
+ var rsu = ReportSetUploader.Run();
+ var ep = EventProcessor.Run(rsu.Item2);
+ _eventChannel = ep.Item2;
- ShutdownTask = Task.WhenAll(ep.Terminated, rsu.Terminated);
+ ShutdownTask = Task.WhenAll(ep.Item1, rsu.Item1);
// TODO: Disable on debug builds
AppDomain.CurrentDomain.UnhandledException += HandleUncaughtException;
@@ -116,11 +115,15 @@ namespace Duplicati.Library.UsageReporter
/// </summary>
public static void ShutDown()
{
- if (_eventChannel != null && !_eventChannel.IsRetired)
+ if (_eventChannel != null && !_eventChannel.IsRetiredAsync.Result)
_eventChannel.Retire();
if (ShutdownTask != null)
- ShutdownTask.Wait();
+ {
+ ShutdownTask.Wait(TimeSpan.FromSeconds(30));
+ if (!ShutdownTask.IsCompleted)
+ Logging.Log.WriteMessage("Failed to shut down usage reporter after 30 seconds, leaving hanging ...", Logging.LogMessageType.Warning);
+ }
AppDomain.CurrentDomain.UnhandledException -= HandleUncaughtException;
@@ -205,7 +208,7 @@ namespace Duplicati.Library.UsageReporter
if (string.IsNullOrWhiteSpace(str))
str = "none";
#endif
- return string.Equals(str, "none", StringComparison.InvariantCultureIgnoreCase) || Utility.Utility.ParseBool(str, false);
+ return string.Equals(str, "none", StringComparison.OrdinalIgnoreCase) || Utility.Utility.ParseBool(str, false);
}
}
diff --git a/Duplicati/Library/UsageReporter/ShutdownHelper.cs b/Duplicati/Library/UsageReporter/ShutdownHelper.cs
deleted file mode 100644
index decc19513..000000000
--- a/Duplicati/Library/UsageReporter/ShutdownHelper.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (C) 2015, The Duplicati Team
-// http://www.duplicati.com, info@duplicati.com
-//
-// This library is free software; you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as
-// published by the Free Software Foundation; either version 2.1 of the
-// License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using CoCoL;
-
-namespace Duplicati.Library.UsageReporter
-{
- public abstract class ShutdownHelper : IDisposable
- {
- /// <summary>
- /// Uses reflection to find all properties and fields that are of type ContinuationChannel
- /// and calls the Retire method on them
- /// </summary>
- /// <param name="item">The instance to examine.</param>
- public static void RetireAllChannels(object item)
- {
- if (item == null)
- return;
-
- foreach(var f in item.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Instance))
- if (typeof(IRetireAbleChannel).IsAssignableFrom(f.FieldType))
- {
- try
- {
- ((IRetireAbleChannel)f.GetValue(item)).Retire();
- }
- catch
- {
- }
- }
-
- foreach(var f in item.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Instance))
- if (typeof(IRetireAbleChannel).IsAssignableFrom(f.PropertyType))
- {
- try
- {
- ((IRetireAbleChannel)f.GetValue(item)).Retire();
- }
- catch
- {
- }
- }
- }
-
- /// <summary>
- /// Runs a method and disposes this instance afterwards
- /// </summary>
- /// <returns>The task for completion.</returns>
- /// <param name="method">The callback method that does the actual work.</param>
- /// <param name="catchRetiredExceptions">If set to <c>true</c> any RetiredExceptions are caught and ignored.</param>
- protected async Task RunProtected(Func<Task> method, bool catchRetiredExceptions = true)
- {
- try
- {
- using(this)
- await method();
- }
- catch(AggregateException ex)
- {
- if (catchRetiredExceptions)
- {
- var lst = from n in ex.Flatten().InnerExceptions
- where !(n is RetiredException)
- select n;
-
- if (lst.Count() == 0)
- return;
- else if (lst.Count() == 1)
- throw lst.First();
- else
- throw new AggregateException(lst);
- }
-
- if (ex.Flatten().InnerExceptions.Count == 1)
- throw ex.Flatten().InnerExceptions.First();
-
- throw;
- }
- catch(RetiredException)
- {
- if (!catchRetiredExceptions)
- throw;
- }
- }
-
- /// <summary>
- /// Releases all resource used by the <see cref="Duplicati.Library.UsageReporter.ShutdownHelper"/> object.
- /// </summary>
- /// <remarks>Call <see cref="Dispose"/> when you are finished using the
- /// <see cref="Duplicati.Library.UsageReporter.ShutdownHelper"/>. The <see cref="Dispose"/> method leaves the
- /// <see cref="Duplicati.Library.UsageReporter.ShutdownHelper"/> in an unusable state. After calling
- /// <see cref="Dispose"/>, you must release all references to the
- /// <see cref="Duplicati.Library.UsageReporter.ShutdownHelper"/> so the garbage collector can reclaim the memory
- /// that the <see cref="Duplicati.Library.UsageReporter.ShutdownHelper"/> was occupying.</remarks>
- public void Dispose()
- {
- RetireAllChannels(this);
- }
- }
-}
-
diff --git a/Duplicati/Library/UsageReporter/packages.config b/Duplicati/Library/UsageReporter/packages.config
index d325c137a..040b8a7cf 100644
--- a/Duplicati/Library/UsageReporter/packages.config
+++ b/Duplicati/Library/UsageReporter/packages.config
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CoCoL" version="1.5.0" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="CoCoL" version="1.5.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Library/Utility/AsyncHttpRequest.cs b/Duplicati/Library/Utility/AsyncHttpRequest.cs
index 1c57d255f..87aa8ef99 100644
--- a/Duplicati/Library/Utility/AsyncHttpRequest.cs
+++ b/Duplicati/Library/Utility/AsyncHttpRequest.cs
@@ -82,19 +82,34 @@ namespace Duplicati.Library.Utility
throw new ArgumentNullException("request");
m_request = request;
m_timeout = m_request.Timeout;
+ if (m_timeout != System.Threading.Timeout.Infinite)
+ {
+ var tmp = (int)HttpContextSettings.OperationTimeout.TotalMilliseconds;
+ if (tmp <= 0)
+ m_timeout = System.Threading.Timeout.Infinite;
+ else
+ m_timeout = Math.Max(m_timeout, tmp);
+ }
+
+ m_activity_timeout = (int)HttpContextSettings.ReadWriteTimeout.TotalMilliseconds;
+ if (m_activity_timeout <= 0)
+ m_activity_timeout = System.Threading.Timeout.Infinite;
//We set this to prevent timeout related stuff from happening outside this module
m_request.Timeout = System.Threading.Timeout.Infinite;
- //Then we register a custom setting of 30 secs timeout on read/write activity
+ //Then we register custom settings
if (m_request is HttpWebRequest)
{
if (((HttpWebRequest)m_request).ReadWriteTimeout != System.Threading.Timeout.Infinite)
m_activity_timeout = ((HttpWebRequest)m_request).ReadWriteTimeout;
((HttpWebRequest)m_request).ReadWriteTimeout = System.Threading.Timeout.Infinite;
- }
- }
+
+ // Prevent in-memory buffering causing out-of-memory issues
+ ((HttpWebRequest)m_request).AllowReadStreamBuffering = HttpContextSettings.BufferRequests;
+ }
+ }
/// <summary>
/// Gets the request that is wrapped
@@ -102,7 +117,7 @@ namespace Duplicati.Library.Utility
public WebRequest Request { get { return m_request; } }
/// <summary>
- /// Gets or sets the timeout used to guard the <see cref="GetRequestStream()"/> and <see cref="GetResponse()"/> calls
+ /// Gets or sets the timeout used to guard the <see cref="GetRequestStream(long)"/> and <see cref="GetResponse()"/> calls
/// </summary>
public int Timeout { get { return m_timeout; } set { m_timeout = value; } }
@@ -110,8 +125,18 @@ namespace Duplicati.Library.Utility
/// Gets the request stream
/// </summary>
/// <returns>The request stream</returns>
- public Stream GetRequestStream()
+ /// <param name="contentlength">The content length to use</param>
+ public Stream GetRequestStream(long contentlength = -1)
{
+ // Prevent in-memory buffering causing out-of-memory issues
+ if (m_request is HttpWebRequest)
+ {
+ if (contentlength >= 0)
+ ((HttpWebRequest)m_request).ContentLength = contentlength;
+ if (m_request.ContentLength >= 0)
+ ((HttpWebRequest)m_request).AllowWriteStreamBuffering = false;
+ }
+
if (m_state == RequestStates.GetRequest)
return (Stream)m_asyncRequest.GetResponseOrStream();
diff --git a/Duplicati/Library/Utility/BlockingQueue.cs b/Duplicati/Library/Utility/BlockingQueue.cs
index 6473e1f18..0709434b9 100644
--- a/Duplicati/Library/Utility/BlockingQueue.cs
+++ b/Duplicati/Library/Utility/BlockingQueue.cs
@@ -157,7 +157,7 @@ namespace Duplicati.Library.Utility
: this()
{
if (maxCapacity <= 0)
- throw new ArgumentException("maxCapacity", "maxCapacity must be a positive number");
+ throw new ArgumentException("The maximum capacity must be a positive number", nameof(maxCapacity));
m_maxCapacity = maxCapacity;
}
diff --git a/Duplicati/Library/Utility/CallContextSettings.cs b/Duplicati/Library/Utility/CallContextSettings.cs
new file mode 100644
index 000000000..d8115cbac
--- /dev/null
+++ b/Duplicati/Library/Utility/CallContextSettings.cs
@@ -0,0 +1,325 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Security;
+using System.Runtime.Remoting.Messaging;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Duplicati.Library.Utility
+{
+ internal static class SystemContextSettings
+ {
+ private struct SystemSettings
+ {
+ public string Tempdir;
+ public long Buffersize;
+ }
+
+ public static IDisposable StartSession(string tempdir = null, long buffersize = 0)
+ {
+ if (string.IsNullOrWhiteSpace(tempdir))
+ tempdir = System.IO.Path.GetTempPath();
+
+ if (buffersize < 1024)
+ buffersize = 64 * 1024;
+
+ return CallContextSettings<SystemSettings>.StartContext(new SystemSettings()
+ {
+ Tempdir = tempdir,
+ Buffersize = buffersize
+ });
+ }
+
+ public static string Tempdir
+ {
+ get
+ {
+ var tf = CallContextSettings<SystemSettings>.Settings.Tempdir;
+ if (string.IsNullOrWhiteSpace(tf))
+ tf = System.IO.Path.GetTempPath();
+ return tf;
+ }
+ set
+ {
+ lock (CallContextSettings<SystemSettings>._lock)
+ {
+ var st = CallContextSettings<SystemSettings>.Settings;
+ st.Tempdir = value;
+ CallContextSettings<SystemSettings>.Settings = st;
+ }
+ }
+ }
+
+ public static long Buffersize
+ {
+ get
+ {
+ var bs = CallContextSettings<SystemSettings>.Settings.Buffersize;
+ if (bs < 1024)
+ bs = 64 * 1024;
+ return bs;
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Class for providing call-context access to http settings
+ /// </summary>
+ public static class HttpContextSettings
+ {
+ /// <summary>
+ /// Internal struct with properties
+ /// </summary>
+ private struct HttpSettings
+ {
+ /// <summary>
+ /// Gets or sets the operation timeout.
+ /// </summary>
+ /// <value>The operation timeout.</value>
+ public TimeSpan OperationTimeout;
+ /// <summary>
+ /// Gets or sets the read write timeout.
+ /// </summary>
+ /// <value>The read write timeout.</value>
+ public TimeSpan ReadWriteTimeout;
+ /// <summary>
+ /// Gets or sets a value indicating whether http requests are buffered.
+ /// </summary>
+ /// <value><c>true</c> if buffer requests; otherwise, <c>false</c>.</value>
+ public bool BufferRequests;
+ /// <summary>
+ /// Gets or sets the certificate validator.
+ /// </summary>
+ /// <value>The certificate validator.</value>
+ public SslCertificateValidator CertificateValidator;
+ }
+
+ /// <summary>
+ /// Starts a new session
+ /// </summary>
+ /// <returns>The session.</returns>
+ /// <param name="operationTimeout">The operation timeout.</param>
+ /// <param name="readwriteTimeout">The readwrite timeout.</param>
+ /// <param name="bufferRequests">If set to <c>true</c> http requests are buffered.</param>
+ public static IDisposable StartSession(TimeSpan operationTimeout = default(TimeSpan), TimeSpan readwriteTimeout = default(TimeSpan), bool bufferRequests = false, bool acceptAnyCertificate = false, string[] allowedCertificates = null)
+ {
+ // Make sure we always use our own version of the callback
+ System.Net.ServicePointManager.ServerCertificateValidationCallback = ServicePointManagerCertificateCallback;
+
+ return CallContextSettings<HttpSettings>.StartContext(new HttpSettings()
+ {
+ OperationTimeout = operationTimeout,
+ ReadWriteTimeout = readwriteTimeout,
+ BufferRequests = bufferRequests,
+ CertificateValidator = acceptAnyCertificate || (allowedCertificates != null)
+ ? new SslCertificateValidator(acceptAnyCertificate, allowedCertificates)
+ : null
+ });
+ }
+
+ /// <summary>
+ /// The callback used to defer the call context, such that each scope can have its own callback
+ /// </summary>
+ /// <returns><c>true</c>, if point manager certificate callback was serviced, <c>false</c> otherwise.</returns>
+ /// <param name="sender">The sender of the validation.</param>
+ /// <param name="certificate">The certificate to validate.</param>
+ /// <param name="chain">The certificate chain.</param>
+ /// <param name="sslPolicyErrors">Errors discovered.</param>
+ private static bool ServicePointManagerCertificateCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ {
+ // If we have a custom SSL validator, invoke it
+ if (HttpContextSettings.CertificateValidator != null)
+ return CertificateValidator.ValidateServerCertficate(sender, certificate, chain, sslPolicyErrors);
+
+ // Default is to only approve certificates without errors
+ var result = sslPolicyErrors == SslPolicyErrors.None;
+
+ // Hack: If we have no validator, see if the context is all messed up
+ // This is not the right way, but ServicePointManager is not designed right for this
+ var any = false;
+ foreach (var v in CallContextSettings<HttpSettings>.GetAllInstances())
+ if (v.CertificateValidator != null)
+ {
+ var t = v.CertificateValidator.ValidateServerCertficate(sender, certificate, chain, sslPolicyErrors);
+
+ // First instance overrides framework result
+ if (!any)
+ result = t;
+
+ // If there are more, we see if anyone will accept it
+ else
+ result |= t;
+
+ any = true;
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Gets the operation timeout.
+ /// </summary>
+ /// <value>The operation timeout.</value>
+ public static TimeSpan OperationTimeout => CallContextSettings<HttpSettings>.Settings.OperationTimeout;
+ /// <summary>
+ /// Gets the read-write timeout.
+ /// </summary>
+ /// <value>The read write timeout.</value>
+ public static TimeSpan ReadWriteTimeout => CallContextSettings<HttpSettings>.Settings.ReadWriteTimeout;
+ /// <summary>
+ /// Gets a value indicating whether https requests are buffered.
+ /// </summary>
+ /// <value><c>true</c> if buffer requests; otherwise, <c>false</c>.</value>
+ public static bool BufferRequests => CallContextSettings<HttpSettings>.Settings.BufferRequests;
+ /// <summary>
+ /// Gets or sets the certificate validator.
+ /// </summary>
+ /// <value>The certificate validator.</value>
+ public static SslCertificateValidator CertificateValidator => CallContextSettings<HttpSettings>.Settings.CertificateValidator;
+
+ }
+
+ /// <summary>
+ /// Help class for providing settings in the current call context
+ /// </summary>
+ public static class CallContextSettings<T>
+ {
+ /// <summary>
+ /// Shared key for storing a value in the call context
+ /// </summary>
+ private const string SETTINGS_KEY_NAME = "duplicati-session-settings";
+
+ /// <summary>
+ /// The settings that are stored in the call context, which are not serializable
+ /// </summary>
+ private static Dictionary<string, T> _setttings = new Dictionary<string, T>();
+
+ /// <summary>
+ /// Lock for protecting the dictionary
+ /// </summary>
+ public static readonly object _lock = new object();
+
+ /// <summary>
+ /// Gets all instances currently registered
+ /// </summary>
+ internal static T[] GetAllInstances()
+ {
+ lock (_lock)
+ return _setttings.Values.ToArray();
+ }
+
+ /// <summary>
+ /// Gets or sets the values in the current call context
+ /// </summary>
+ /// <value>The settings.</value>
+ public static T Settings
+ {
+ get
+ {
+ T res;
+ var key = ContextID;
+ if (string.IsNullOrWhiteSpace(key))
+ return default(T);
+
+ if (!_setttings.TryGetValue(key, out res))
+ lock (_lock)
+ if (!_setttings.TryGetValue(key, out res))
+ return default(T);
+
+ return res;
+ }
+ set
+ {
+ var key = ContextID;
+ if (!string.IsNullOrWhiteSpace(key))
+ lock (_lock)
+ _setttings[key] = value;
+ }
+ }
+
+ /// <summary>
+ /// Help class for providing a way to release resources associated with a call context
+ /// </summary>
+ private class ContextGuard : IDisposable
+ {
+ /// <summary>
+ /// Randomly generated identifier
+ /// </summary>
+ private readonly string ID = Guid.NewGuid().ToString();
+
+ /// <summary>
+ /// Initializes a new instance of the
+ /// <see cref="T:Duplicati.Library.Utility.CallContextSettings`1.ContextGuard"/> class,
+ /// and sets up the call context
+ /// </summary>
+ public ContextGuard()
+ {
+ CallContext.LogicalSetData(SETTINGS_KEY_NAME, ID);
+ }
+
+ /// <summary>
+ /// Releases all resource used by the
+ /// <see cref="T:Duplicati.Library.Utility.CallContextSettings`1.ContextGuard"/> object.
+ /// </summary>
+ /// <remarks>Call <see cref="Dispose"/> when you are finished using the
+ /// <see cref="T:Duplicati.Library.Utility.CallContextSettings`1.ContextGuard"/>. The <see cref="Dispose"/>
+ /// method leaves the <see cref="T:Duplicati.Library.Utility.CallContextSettings`1.ContextGuard"/> in an
+ /// unusable state. After calling <see cref="Dispose"/>, you must release all references to the
+ /// <see cref="T:Duplicati.Library.Utility.CallContextSettings`1.ContextGuard"/> so the garbage collector
+ /// can reclaim the memory that the
+ /// <see cref="T:Duplicati.Library.Utility.CallContextSettings`1.ContextGuard"/> was occupying.</remarks>
+ public void Dispose()
+ {
+ lock (_lock)
+ {
+ // Release the resources, if any
+ _setttings.Remove(ID);
+ }
+
+ CallContext.LogicalSetData(SETTINGS_KEY_NAME, null);
+ }
+ }
+
+ /// <summary>
+ /// Starts the context wit a default value.
+ /// </summary>
+ /// <returns>The disposable handle for the context.</returns>
+ /// <param name="initial">The initial value.</param>
+ public static IDisposable StartContext(T initial = default(T))
+ {
+ var res = new ContextGuard();
+ Settings = initial;
+ return res;
+ }
+
+ /// <summary>
+ /// Gets the context ID for this call.
+ /// </summary>
+ /// <value>The context identifier.</value>
+ private static string ContextID
+ {
+ get
+ {
+ return CallContext.LogicalGetData(SETTINGS_KEY_NAME) as string;
+ }
+ }
+
+ }
+}
diff --git a/Duplicati/Library/Utility/DefaultFilters.cs b/Duplicati/Library/Utility/DefaultFilters.cs
new file mode 100644
index 000000000..2a7b35fc0
--- /dev/null
+++ b/Duplicati/Library/Utility/DefaultFilters.cs
@@ -0,0 +1,371 @@
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Duplicati.Library.Utility
+{
+ public enum DefaultFilterSet
+ {
+ None = 0,
+ Windows = 1,
+ OSX = 2,
+ Linux = 4,
+ All = Windows | OSX | Linux,
+ }
+
+ /// <summary>
+ /// This class defines a set of common filters for files that don't typically need to be backed up.
+ /// These filters are largely based on the filters described here:
+ /// https://superuser.com/questions/443890/what-files-file-types-and-folders-to-exclude-from-user-folder-backup
+ /// </summary>
+ public static class DefaultFilters
+ {
+ /// <summary>
+ /// Case insensitive mapping from strings to filter sets
+ /// /// </summary>
+ private static readonly Dictionary<string, DefaultFilterSet> defaultFilterSetMapping =
+ ((DefaultFilterSet[])Enum.GetValues(typeof(DefaultFilterSet)))
+ .ToDictionary(val => val.ToString(), val => val, StringComparer.OrdinalIgnoreCase);
+
+ /// <summary>
+ /// Filters common for all operating systems
+ /// </summary>
+ public static IEnumerable<string> Common
+ {
+ get
+ {
+ return DefaultFilters.CreateCommonFilters();
+ }
+ }
+
+ /// <summary>
+ /// Filters for Windows
+ /// </summary>
+ public static IEnumerable<string> Windows
+ {
+ get
+ {
+ return DefaultFilters.CreateWindowsFilters();
+ }
+ }
+
+ /// <summary>
+ /// Filters for OSX
+ /// </summary>
+ public static IEnumerable<string> OSX
+ {
+ get
+ {
+ return DefaultFilters.CreateOSXFilters();
+ }
+ }
+
+ /// <summary>
+ /// Filters for Linux
+ /// </summary>
+ public static IEnumerable<string> Linux
+ {
+ get
+ {
+ return DefaultFilters.CreateLinuxFilters();
+ }
+ }
+
+ /// <summary>
+ /// Gets the filters indicated by the given filter sets
+ /// </summary>
+ /// <param name="options">Filter set options</param>
+ /// <returns>Default filters</returns>
+ public static IEnumerable<FilterExpression> GetFilters(string options)
+ {
+ bool anyOptions = false;
+ DefaultFilterSet filterSets = DefaultFilterSet.None;
+ foreach (string option in options.Split(new[] { ',', '|', ';' }, StringSplitOptions.RemoveEmptyEntries))
+ {
+ anyOptions = true;
+ DefaultFilterSet filter;
+ if (DefaultFilters.defaultFilterSetMapping.TryGetValue(option, out filter))
+ {
+ filterSets |= filter;
+ }
+ else
+ {
+ throw new ArgumentException(Strings.Filters.UnknownDefaultFilterSet(option));
+ }
+ }
+
+ // If no filter sets are specified, we use the default for the platform we're on
+ if (!anyOptions)
+ {
+ if (Utility.IsClientWindows)
+ {
+ filterSets |= DefaultFilterSet.Windows;
+ }
+
+ if (Utility.IsClientOSX)
+ {
+ filterSets |= DefaultFilterSet.OSX;
+ }
+
+ if (Utility.IsClientLinux)
+ {
+ filterSets |= DefaultFilterSet.Linux;
+ }
+ }
+
+ if (filterSets == DefaultFilterSet.None)
+ {
+ return Enumerable.Empty<FilterExpression>();
+ }
+
+ IEnumerable<string> filters = DefaultFilters.Common;
+
+ if ((filterSets & DefaultFilterSet.Windows) == DefaultFilterSet.Windows)
+ {
+ filters = filters.Concat(DefaultFilters.Windows);
+ }
+
+ if ((filterSets & DefaultFilterSet.OSX) == DefaultFilterSet.OSX)
+ {
+ filters = filters.Concat(DefaultFilters.OSX);
+ }
+
+ if ((filterSets & DefaultFilterSet.Linux) == DefaultFilterSet.Linux)
+ {
+ filters = filters.Concat(DefaultFilters.Linux);
+ }
+
+ // Filter down to distinct filters, then convert them to filter expressions
+ return filters.Distinct(Utility.ClientFilenameStringComparer).Select(filter => new FilterExpression(filter, false));
+ }
+
+ /// <summary>
+ /// Creates common filters
+ /// </summary>
+ /// <returns>Common filters</returns>
+ private static string[] CreateCommonFilters()
+ {
+ return new[]
+ {
+ DefaultFilters.CreateWildcardFilter(@"*/Google/Chrome/*cache*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Google/Chrome/Safe Browsing*"),
+ DefaultFilters.CreateWildcardFilter(@"*/iPhoto Library/iPod Photo Cache/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Mozilla/Firefox/*cache*"),
+ DefaultFilters.CreateRegexFilter(@".*/(cookies|permissions).sqllite(-.{3})?"),
+ };
+ }
+
+ /// <summary>
+ /// Creates Windows filters
+ /// </summary>
+ /// <returns>Windows filters</returns>
+ private static string[] CreateWindowsFilters()
+ {
+ return new[]
+ {
+ DefaultFilters.CreateWildcardFilter(@"*.rbf"),
+ DefaultFilters.CreateWildcardFilter(@"*.tmp"),
+ DefaultFilters.CreateWildcardFilter(@"*.tmp/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/$RECYCLE.BIN/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/AppData/Apple Computer/Mobile Sync/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/AppData/Local/Microsoft/Windows Store/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/AppData/Local/Packages/*"), // https://superuser.com/questions/490925/explain-windows-8-windows-store-appdata-packages-and-what-to-backup
+ DefaultFilters.CreateWildcardFilter(@"*/AppData/Local/Temp*"),
+ DefaultFilters.CreateWildcardFilter(@"*/AppData/LocalLow/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/AppData/Temp*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Application Data/Apple Computer/Mobile Sync/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Application Data/Application Data*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Cookies/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Google/Chrome/User Data/Default/Cookies"),
+ DefaultFilters.CreateWildcardFilter(@"*/Google/Chrome/User Data/Default/Cookies-journal"),
+ DefaultFilters.CreateWildcardFilter(@"*/I386*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Internet Explorer/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Local Settings/History/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Local Settings/Temp*"),
+ DefaultFilters.CreateWildcardFilter(@"*/LocalService/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Microsoft*/RecoveryStore*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Microsoft*/Windows/*.edb"),
+ DefaultFilters.CreateWildcardFilter(@"*/Microsoft*/Windows/*.log"),
+ DefaultFilters.CreateWildcardFilter(@"*/Microsoft*/Windows/Cookies*"),
+ DefaultFilters.CreateWildcardFilter(@"*/MSOCache*"),
+ DefaultFilters.CreateWildcardFilter(@"*/NetHood/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/NetworkService/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/NTUSER*"),
+ DefaultFilters.CreateWildcardFilter(@"*/ntuser.dat*"),
+ DefaultFilters.CreateWildcardFilter(@"*/PrintHood/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Recent/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/RECYCLER/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Safari/Library/Caches/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/SendTo/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Start Menu/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Temporary Internet Files/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Thumbs.db"),
+ DefaultFilters.CreateWildcardFilter(@"*UsrClass.dat"),
+ DefaultFilters.CreateWildcardFilter(@"*UsrClass.dat.LOG"),
+ DefaultFilters.CreateWildcardFilter(@"?:/autoexec.bat"),
+ DefaultFilters.CreateWildcardFilter(@"?:/Config.Msi*"),
+ DefaultFilters.CreateWildcardFilter(@"?:/hiberfil.sys"),
+ DefaultFilters.CreateWildcardFilter(@"?:/pagefile.sys"),
+ DefaultFilters.CreateWildcardFilter(@"?:/Program Files (x86)/*"),
+ DefaultFilters.CreateWildcardFilter(@"?:/Program Files/*"),
+ DefaultFilters.CreateWildcardFilter(@"?:/ProgramData/*"),
+ DefaultFilters.CreateWildcardFilter(@"?:/swapfile.sys"),
+ DefaultFilters.CreateWildcardFilter(@"?:/System Volume Information/*"),
+ DefaultFilters.CreateWildcardFilter(@"?:/Windows.old/*"),
+ DefaultFilters.CreateWildcardFilter(@"?:/Windows/*"),
+ DefaultFilters.CreateWildcardFilter(@"?:/Windows/Installer*"),
+ DefaultFilters.CreateWildcardFilter(@"?:/Windows/Temp*"),
+ };
+ }
+
+ /// <summary>
+ /// Creates OSX filters
+ /// </summary>
+ /// <returns>OSX filters</returns>
+ private static string[] CreateOSXFilters()
+ {
+ return new[]
+ {
+ DefaultFilters.CreateWildcardFilter(@"*.fseventsd*"),
+ DefaultFilters.CreateWildcardFilter(@"*.hotfiles.btree*"),
+ DefaultFilters.CreateWildcardFilter(@"*.Spotlight-*/*"),
+ DefaultFilters.CreateWildcardFilter(@"*.Trash*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Application Support/Google/Chrome/Default/Cookies"),
+ DefaultFilters.CreateWildcardFilter(@"*/Application Support/Google/Chrome/Default/Cookies-journal"),
+ DefaultFilters.CreateWildcardFilter(@"*/backups.backupdb/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/iP* Software Updates/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/iPhoto Library/iPod Photo Cache*"),
+ DefaultFilters.CreateWildcardFilter(@"*/iTunes/Album Artwork/Cache/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Application Support/SyncServices/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Caches/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Calendars/*/Info.plist"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Calendars/Calendar Cache"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Cookies/com.apple.appstore.plist"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Cookies/Cookies.binarycookies"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Logs/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Mail/*/Info.plist"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Mail/AvailableFeeds/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Mail/Envelope Index"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Mirrors/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/PubSub/Database/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/PubSub/Downloads/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/PubSub/Feeds/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Safari/HistoryIndex.sk"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Safari/Icons.db"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Safari/WebpageIcons.db"),
+ DefaultFilters.CreateWildcardFilter(@"*/Library/Saved Application State/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/lost+found/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Microsoft User Data/Entourage Temp/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Network Trash Folder/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/Trash/*"),
+ DefaultFilters.CreateWildcardFilter(@"*/VM Storage"),
+ DefaultFilters.CreateWildcardFilter(@"*Mobile.*Backups/*"),
+ DefaultFilters.CreateWildcardFilter(@"/.vol/*"),
+ DefaultFilters.CreateWildcardFilter(@"/afs/*"),
+ DefaultFilters.CreateWildcardFilter(@"/automount/*"),
+ DefaultFilters.CreateWildcardFilter(@"/bin/*"),
+ DefaultFilters.CreateWildcardFilter(@"/cores/*"),
+ DefaultFilters.CreateWildcardFilter(@"/Desktop DB"),
+ DefaultFilters.CreateWildcardFilter(@"/Desktop DF"),
+ DefaultFilters.CreateWildcardFilter(@"/dev/.*"),
+ DefaultFilters.CreateWildcardFilter(@"/etc/*"),
+ DefaultFilters.CreateWildcardFilter(@"/mach.sym"),
+ DefaultFilters.CreateWildcardFilter(@"/mach_kernel"),
+ DefaultFilters.CreateWildcardFilter(@"/net/*"),
+ DefaultFilters.CreateWildcardFilter(@"/Network/*"),
+ DefaultFilters.CreateWildcardFilter(@"/Network/Servers*"),
+ DefaultFilters.CreateWildcardFilter(@"/Previous Systems*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/Network/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/tmp/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/var/automount/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/var/db/dhcpclient/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/var/db/fseventsd/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/var/folders/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/var/run/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/var/spool/postfix/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/var/tmp/*"),
+ DefaultFilters.CreateWildcardFilter(@"/private/var/vm/*"),
+ DefaultFilters.CreateWildcardFilter(@"/sbin/*"),
+ DefaultFilters.CreateWildcardFilter(@"/sw/*"),
+ DefaultFilters.CreateWildcardFilter(@"/System/*"),
+ DefaultFilters.CreateWildcardFilter(@"/System/Library/Extensions/Caches/*"),
+ DefaultFilters.CreateWildcardFilter(@"/tmp/*"),
+ DefaultFilters.CreateWildcardFilter(@"/Users/Shared/SC Info*"),
+ DefaultFilters.CreateWildcardFilter(@"/usr/*"),
+ };
+ }
+
+ /// <summary>
+ /// Creates Linux filters
+ /// </summary>
+ /// <returns>Linux filters</returns>
+ private static string[] CreateLinuxFilters()
+ {
+ return new[]
+ {
+ DefaultFilters.CreateWildcardFilter(@"*/.config/google-chrome/Default/Cookies"),
+ DefaultFilters.CreateWildcardFilter(@"*/.config/google-chrome/Default/Cookies-journal"),
+ DefaultFilters.CreateWildcardFilter(@"*/lost+found/*"),
+ DefaultFilters.CreateWildcardFilter(@"*~"),
+ DefaultFilters.CreateWildcardFilter(@"/bin/*"),
+ DefaultFilters.CreateWildcardFilter(@"/boot/*"),
+ DefaultFilters.CreateWildcardFilter(@"/dev/*"),
+ DefaultFilters.CreateWildcardFilter(@"/etc/*"),
+ DefaultFilters.CreateWildcardFilter(@"/initrd/*"),
+ DefaultFilters.CreateWildcardFilter(@"/lib/*"),
+ DefaultFilters.CreateWildcardFilter(@"/opt/*"),
+ DefaultFilters.CreateWildcardFilter(@"/proc/*"),
+ DefaultFilters.CreateWildcardFilter(@"/sbin/*"),
+ DefaultFilters.CreateWildcardFilter(@"/selinux/*"),
+ DefaultFilters.CreateWildcardFilter(@"/srv/*"),
+ DefaultFilters.CreateWildcardFilter(@"/sys/*"),
+ DefaultFilters.CreateWildcardFilter(@"/tmp/*"),
+ DefaultFilters.CreateWildcardFilter(@"/usr/*"),
+ DefaultFilters.CreateWildcardFilter(@"/var/*"),
+ };
+ }
+
+ /// <summary>
+ /// Creates a wildcard filter
+ /// </summary>
+ /// <param name="filter">Filter text</param>
+ /// <returns>Wildcard filter</returns>
+ private static string CreateWildcardFilter(string filter)
+ {
+ // Create a filter with the given name.
+ // However, in order to match paths correctly, the directory separators need to be normalized to match the system default.
+ return filter.Replace(System.IO.Path.AltDirectorySeparatorChar, System.IO.Path.DirectorySeparatorChar);
+ }
+
+ /// <summary>
+ /// Creates a Regex filter
+ /// </summary>
+ /// <param name="filter">Filter text</param>
+ /// <returns>Regex filter</returns>
+ private static string CreateRegexFilter(string filter)
+ {
+ // Create a filter with the given name.
+ // However, in order to match paths correctly, the directory separators need to be normalized to match the system default.
+ string escapedAlt = System.Text.RegularExpressions.Regex.Escape(System.IO.Path.AltDirectorySeparatorChar.ToString());
+ string escaped = System.Text.RegularExpressions.Regex.Escape(System.IO.Path.DirectorySeparatorChar.ToString());
+ return "[" + filter.Replace(escapedAlt, escaped) + "]";
+ }
+ }
+}
diff --git a/Duplicati/Library/Utility/Duplicati.Library.Utility.csproj b/Duplicati/Library/Utility/Duplicati.Library.Utility.csproj
index c3f9e9fbf..c32d167dd 100644
--- a/Duplicati/Library/Utility/Duplicati.Library.Utility.csproj
+++ b/Duplicati/Library/Utility/Duplicati.Library.Utility.csproj
@@ -17,6 +17,7 @@
<TargetFrameworkProfile />
<UpgradeBackupLocation>
</UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
@@ -38,9 +39,15 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
+ <Reference Include="System.Management" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="FasterHashing">
+ <HintPath>..\..\..\packages\FasterHashing.1.2.3\lib\net45\FasterHashing.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AsyncHttpRequest.cs" />
+ <Compile Include="DefaultFilters.cs" />
<Compile Include="KeyGenerator.cs" />
<Compile Include="OverrideableStream.cs" />
<Compile Include="ProgressReportingStream.cs" />
@@ -68,10 +75,18 @@
<Compile Include="HashCalculatingStream.cs" />
<Compile Include="DirectStreamLink.cs" />
<Compile Include="HostKeyException.cs" />
+ <Compile Include="CallContextSettings.cs" />
+ <Compile Include="HashAlgorithmHelper.cs" />
+ <Compile Include="Power\PowerSupply.cs" />
+ <Compile Include="Power\IPowerSupplyState.cs" />
+ <Compile Include="Power\DefaultPowerSupplyState.cs" />
+ <Compile Include="Power\LinuxPowerSupplyState.cs" />
+ <Compile Include="Power\WindowsPowerSupplyState.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="Duplicati.snk" />
+ <None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -87,4 +102,7 @@
<Name>Duplicati.Library.Localization</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <Folder Include="Power\" />
+ </ItemGroup>
</Project>
diff --git a/Duplicati/Library/Utility/FileBackedList.cs b/Duplicati/Library/Utility/FileBackedList.cs
index d7ec0a4aa..e7d667977 100644
--- a/Duplicati/Library/Utility/FileBackedList.cs
+++ b/Duplicati/Library/Utility/FileBackedList.cs
@@ -126,9 +126,13 @@ namespace Duplicati.Library.Utility
oldstream.CopyTo(m_stream);
}
}
-
+
+ m_stream.Position = m_stream.Length;
m_stream.Write(BitConverter.GetBytes(size), 0, 8);
+ var pos = m_stream.Position;
Serialize(value, m_stream);
+ if (m_stream.Position - pos != size)
+ throw new Exception(string.Format("Stream serializer wrote a different set of bytes than it was supposed to. Expected {0} bytes, but wrote {1} bytes", m_stream.Position - pos, size));
m_count++;
}
diff --git a/Duplicati/Library/Utility/FilterCollector.cs b/Duplicati/Library/Utility/FilterCollector.cs
index 5cdbeed3d..f22b120ee 100644
--- a/Duplicati/Library/Utility/FilterCollector.cs
+++ b/Duplicati/Library/Utility/FilterCollector.cs
@@ -39,14 +39,25 @@ namespace Duplicati.Library.Utility
private Dictionary<string, string> DoExtractOptions(List<string> args, Func<string, string, bool> callbackHandler = null)
{
return Library.Utility.CommandLineParser.ExtractOptions(args, (key, value) => {
- if (key.Equals("include", StringComparison.InvariantCultureIgnoreCase))
+ if (key.Equals("include", StringComparison.OrdinalIgnoreCase))
{
- m_filters.Add(new Library.Utility.FilterExpression(Library.Utility.Utility.ExpandEnvironmentVariables(value), true));
- return false;
+ if (!string.IsNullOrEmpty(value))
+ {
+ m_filters.Add(new Library.Utility.FilterExpression(Library.Utility.Utility.ExpandEnvironmentVariables(value), true));
+ return false;
+ }
+ }
+ else if (key.Equals("exclude", StringComparison.OrdinalIgnoreCase))
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ m_filters.Add(new Library.Utility.FilterExpression(Library.Utility.Utility.ExpandEnvironmentVariables(value), false));
+ return false;
+ }
}
- else if (key.Equals("exclude", StringComparison.InvariantCultureIgnoreCase))
+ else if (key.Equals("default-filters", StringComparison.OrdinalIgnoreCase) || key.Equals("default-filter", StringComparison.OrdinalIgnoreCase))
{
- m_filters.Add(new Library.Utility.FilterExpression(Library.Utility.Utility.ExpandEnvironmentVariables(value), false));
+ m_filters.AddRange(DefaultFilters.GetFilters(Library.Utility.Utility.ExpandEnvironmentVariables(value ?? string.Empty)));
return false;
}
@@ -56,12 +67,12 @@ namespace Duplicati.Library.Utility
return true;
});
}
-
+
public static Tuple<Dictionary<string, string>, Library.Utility.IFilter> ExtractOptions(List<string> args, Func<string, string, bool> callbackHandler = null)
{
var fc = new FilterCollector();
var opts = fc.DoExtractOptions(args, callbackHandler);
return new Tuple<Dictionary<string, string>, Library.Utility.IFilter>(opts, fc.Filter);
}
- }}
-
+ }
+}
diff --git a/Duplicati/Library/Utility/FilterExpression.cs b/Duplicati/Library/Utility/FilterExpression.cs
index 07789fe65..7064dc21d 100644
--- a/Duplicati/Library/Utility/FilterExpression.cs
+++ b/Duplicati/Library/Utility/FilterExpression.cs
@@ -65,7 +65,10 @@ namespace Duplicati.Library.Utility
private const char MULTIPLE_WILDCARD = '*';
- private static readonly System.Text.RegularExpressions.RegexOptions REGEXP_OPTIONS = Library.Utility.Utility.IsFSCaseSensitive ? System.Text.RegularExpressions.RegexOptions.Compiled : System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.IgnoreCase;
+ private static readonly System.Text.RegularExpressions.RegexOptions REGEXP_OPTIONS =
+ System.Text.RegularExpressions.RegexOptions.Compiled |
+ System.Text.RegularExpressions.RegexOptions.ExplicitCapture |
+ (Library.Utility.Utility.IsFSCaseSensitive ? System.Text.RegularExpressions.RegexOptions.None : System.Text.RegularExpressions.RegexOptions.IgnoreCase);
public FilterEntry(string filter)
{
@@ -379,15 +382,16 @@ namespace Duplicati.Library.Utility
includes = false;
excludes = false;
- Tuple<bool, bool> cacheLookup;
+ Tuple<bool, bool> cacheLookup = null;
// Check for cached results
- lock(_matchLock)
- if (_matchFallbackLookup.TryGetValue(filter, out cacheLookup))
- {
- includes = cacheLookup.Item1;
- excludes = cacheLookup.Item2;
- }
+ if (filter != null)
+ lock(_matchLock)
+ if (_matchFallbackLookup.TryGetValue(filter, out cacheLookup))
+ {
+ includes = cacheLookup.Item1;
+ excludes = cacheLookup.Item2;
+ }
// Figure out what components are in the filter
if (cacheLookup == null)
diff --git a/Duplicati/Library/Utility/HashAlgorithmHelper.cs b/Duplicati/Library/Utility/HashAlgorithmHelper.cs
new file mode 100644
index 000000000..62bf0e7c0
--- /dev/null
+++ b/Duplicati/Library/Utility/HashAlgorithmHelper.cs
@@ -0,0 +1,39 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+
+namespace Duplicati.Library.Utility
+{
+ /// <summary>
+ /// This class helps picking the fastest hash algorithm implementation,
+ /// which is what <seealso cref="System.Security.Cryptography.HashAlgorithm.Create()"/> should do, but does not.
+ /// </summary>
+ public static class HashAlgorithmHelper
+ {
+ /// <summary>
+ /// Create the hash algorithm with the specified name.
+ /// </summary>
+ /// <returns>The hash algorithm.</returns>
+ /// <param name="name">The name of the algorithm to create.</param>
+ public static HashAlgorithm Create(string name)
+ {
+ return FasterHashing.FasterHash.Create(name);
+ }
+ }
+}
diff --git a/Duplicati/Library/Utility/HashCalculatingStream.cs b/Duplicati/Library/Utility/HashCalculatingStream.cs
index 68ea4ab92..6ff39e23d 100644
--- a/Duplicati/Library/Utility/HashCalculatingStream.cs
+++ b/Duplicati/Library/Utility/HashCalculatingStream.cs
@@ -49,7 +49,7 @@ namespace Duplicati.Library.Utility
private int m_hashbufferLength = 0;
public HashCalculatingStream(System.IO.Stream basestream, string hashalgorithm)
- : this(basestream, System.Security.Cryptography.HashAlgorithm.Create(hashalgorithm))
+ : this(basestream, HashAlgorithmHelper.Create(hashalgorithm))
{
}
diff --git a/Duplicati/Library/Utility/JoinedFilterExpression.cs b/Duplicati/Library/Utility/JoinedFilterExpression.cs
index ff4cc5c34..9ffaf8b4b 100644
--- a/Duplicati/Library/Utility/JoinedFilterExpression.cs
+++ b/Duplicati/Library/Utility/JoinedFilterExpression.cs
@@ -39,9 +39,15 @@ namespace Duplicati.Library.Utility
public static IFilter Join(IFilter first, IFilter second)
{
- if (first == null || first.Empty)
+ if (first == null && second == null)
+ return null;
+ else if (first == null)
return second;
- else if (second == null || second.Empty)
+ else if (second == null)
+ return first;
+ else if (first.Empty)
+ return second;
+ else if (second.Empty)
return first;
else
{
diff --git a/Duplicati/Library/Utility/Power/DefaultPowerSupplyState.cs b/Duplicati/Library/Utility/Power/DefaultPowerSupplyState.cs
new file mode 100644
index 000000000..c8014974e
--- /dev/null
+++ b/Duplicati/Library/Utility/Power/DefaultPowerSupplyState.cs
@@ -0,0 +1,27 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+namespace Duplicati.Library.Utility.Power
+{
+ public class DefaultPowerSupplyState : IPowerSupplyState
+ {
+ public PowerSupply.Source GetSource()
+ {
+ return PowerSupply.Source.Unknown;
+ }
+ }
+}
diff --git a/Duplicati/Library/Utility/Power/IPowerSupplyState.cs b/Duplicati/Library/Utility/Power/IPowerSupplyState.cs
new file mode 100644
index 000000000..f824c64a8
--- /dev/null
+++ b/Duplicati/Library/Utility/Power/IPowerSupplyState.cs
@@ -0,0 +1,24 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+namespace Duplicati.Library.Utility.Power
+{
+ public interface IPowerSupplyState
+ {
+ PowerSupply.Source GetSource();
+ }
+}
diff --git a/Duplicati/Library/Utility/Power/LinuxPowerSupplyState.cs b/Duplicati/Library/Utility/Power/LinuxPowerSupplyState.cs
new file mode 100644
index 000000000..282a27bc5
--- /dev/null
+++ b/Duplicati/Library/Utility/Power/LinuxPowerSupplyState.cs
@@ -0,0 +1,107 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+using System;
+using System.IO;
+using System.Linq;
+
+namespace Duplicati.Library.Utility.Power
+{
+ public class LinuxPowerSupplyState : IPowerSupplyState
+ {
+ private readonly string sysfsPath = Path.Combine("/", "sys", "class", "power_supply");
+
+ public PowerSupply.Source GetSource()
+ {
+ if (this.IsAC())
+ {
+ return PowerSupply.Source.AC;
+ }
+ if (this.IsBattery())
+ {
+ return PowerSupply.Source.Battery;
+ }
+
+ return PowerSupply.Source.Unknown;
+ }
+
+ private bool IsAC()
+ {
+ // If any of the power supply devices of type "Mains" are online, then we are on
+ // AC power. If none of the power supply devices are of type "Mains", then we
+ // are also on AC power. See https://bugzilla.redhat.com/show_bug.cgi?id=644629.
+ bool reply = false;
+ bool haveMains = false;
+
+ try
+ {
+ foreach (string source in Directory.GetDirectories(this.sysfsPath))
+ {
+ if (!reply)
+ {
+ string sourceType = File.ReadLines(Path.Combine(source, "type")).FirstOrDefault();
+ if (String.Equals(sourceType, "Mains", StringComparison.Ordinal))
+ {
+ haveMains = true;
+
+ string isOnline = File.ReadLines(Path.Combine(source, "online")).FirstOrDefault();
+ reply = String.Equals(isOnline, "1", StringComparison.Ordinal);
+ }
+ }
+ }
+ }
+ catch
+ {
+ return false;
+ }
+
+ return reply |= !haveMains;
+ }
+
+ private bool IsBattery()
+ {
+ // If there is at least one power supply device of type "Mains", and all "Mains"
+ // devices are offline, then we are on battery power.
+ bool allOffline = true;
+ bool haveMains = false;
+
+ try
+ {
+ foreach (string source in Directory.GetDirectories(this.sysfsPath))
+ {
+ if (allOffline)
+ {
+ string sourceType = File.ReadLines(Path.Combine(source, "type")).FirstOrDefault();
+ if (String.Equals(sourceType, "Mains", StringComparison.Ordinal))
+ {
+ haveMains = true;
+
+ string isOnline = File.ReadLines(Path.Combine(source, "online")).FirstOrDefault();
+ allOffline &= String.Equals(isOnline, "0", StringComparison.Ordinal);
+ }
+ }
+ }
+ }
+ catch
+ {
+ return false;
+ }
+
+ return haveMains && allOffline;
+ }
+ }
+}
diff --git a/Duplicati/Library/Utility/Power/PowerSupply.cs b/Duplicati/Library/Utility/Power/PowerSupply.cs
new file mode 100644
index 000000000..ff5deadb6
--- /dev/null
+++ b/Duplicati/Library/Utility/Power/PowerSupply.cs
@@ -0,0 +1,54 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+namespace Duplicati.Library.Utility.Power
+{
+ public static class PowerSupply
+ {
+ public enum Source
+ {
+ AC,
+ Battery,
+ Unknown
+ }
+
+ public static Source GetSource()
+ {
+ IPowerSupplyState state;
+
+ // Since IsClientLinux returns true when on Mac OS X, we need to check IsClientOSX first.
+ if (Utility.IsClientOSX)
+ {
+ state = new DefaultPowerSupplyState();
+ }
+ else if (Utility.IsClientLinux)
+ {
+ state = new LinuxPowerSupplyState();
+ }
+ else if (Utility.IsClientWindows)
+ {
+ state = new WindowsPowerSupplyState();
+ }
+ else
+ {
+ state = new DefaultPowerSupplyState();
+ }
+
+ return state.GetSource();
+ }
+ }
+}
diff --git a/Duplicati/Library/Utility/Power/WindowsPowerSupplyState.cs b/Duplicati/Library/Utility/Power/WindowsPowerSupplyState.cs
new file mode 100644
index 000000000..c1ffa620a
--- /dev/null
+++ b/Duplicati/Library/Utility/Power/WindowsPowerSupplyState.cs
@@ -0,0 +1,46 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+using System.Windows.Forms;
+
+namespace Duplicati.Library.Utility.Power
+{
+ public class WindowsPowerSupplyState : IPowerSupplyState
+ {
+ public PowerSupply.Source GetSource()
+ {
+ try
+ {
+ PowerLineStatus status = System.Windows.Forms.SystemInformation.PowerStatus.PowerLineStatus;
+ if (status == PowerLineStatus.Online)
+ {
+ return PowerSupply.Source.AC;
+ }
+ if (status == PowerLineStatus.Offline)
+ {
+ return PowerSupply.Source.Battery;
+ }
+
+ return PowerSupply.Source.Unknown;
+ }
+ catch
+ {
+ return PowerSupply.Source.Unknown;
+ }
+ }
+ }
+}
diff --git a/Duplicati/Library/Utility/SslCertificateValidator.cs b/Duplicati/Library/Utility/SslCertificateValidator.cs
index acade5a35..9b579adee 100644
--- a/Duplicati/Library/Utility/SslCertificateValidator.cs
+++ b/Duplicati/Library/Utility/SslCertificateValidator.cs
@@ -25,7 +25,7 @@ using System.Net.Security;
namespace Duplicati.Library.Utility
{
- public class SslCertificateValidator : IDisposable
+ public class SslCertificateValidator
{
[Serializable]
public class InvalidCertificateException : Exception
@@ -48,35 +48,13 @@ namespace Duplicati.Library.Utility
{
m_acceptAll = acceptAll;
m_validHashes = validHashes;
- m_oldCallback = System.Net.ServicePointManager.ServerCertificateValidationCallback;
-
- System.Net.ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertficate);
- m_isAttached = true;
}
private bool m_acceptAll = false;
private string[] m_validHashes = null;
- private bool m_isAttached = false;
private Exception m_uncastException = null;
- private RemoteCertificateValidationCallback m_oldCallback = null;
-
- private void Deactivate()
- {
- if (!m_isAttached)
- throw new InvalidOperationException(Strings.SslCertificateValidator.InvalidCallSequence);
- System.Net.ServicePointManager.ServerCertificateValidationCallback = m_oldCallback;
- m_oldCallback = null;
- m_isAttached = false;
- if (m_uncastException != null)
- {
- Exception tmp = m_uncastException;
- m_uncastException = null;
- throw tmp;
- }
- }
-
- private bool ValidateServerCertficate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ public bool ValidateServerCertficate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
@@ -92,7 +70,7 @@ namespace Duplicati.Library.Utility
if (certHash != null && m_validHashes != null)
foreach(var hash in m_validHashes)
{
- if (!string.IsNullOrEmpty(hash) && certHash.Equals(hash, StringComparison.InvariantCultureIgnoreCase))
+ if (!string.IsNullOrEmpty(hash) && certHash.Equals(hash, StringComparison.OrdinalIgnoreCase))
return true;
}
}
@@ -104,16 +82,5 @@ namespace Duplicati.Library.Utility
m_uncastException = new InvalidCertificateException(certHash, sslPolicyErrors);
return false;
}
-
-
- #region IDisposable Members
-
- public void Dispose()
- {
- if (m_isAttached)
- Deactivate();
- }
-
- #endregion
}
}
diff --git a/Duplicati/Library/Utility/Strings.cs b/Duplicati/Library/Utility/Strings.cs
index b91bd38ab..3a4ceb643 100644
--- a/Duplicati/Library/Utility/Strings.cs
+++ b/Duplicati/Library/Utility/Strings.cs
@@ -8,9 +8,9 @@ namespace Duplicati.Library.Utility.Strings {
}
internal static class SslCertificateValidator {
public static string InvalidCallSequence { get { return LC.L(@"The SSL certificate validator was called in an incorrect order"); } }
- public static string MonoHelpSSL { get { return LC.L(@"{0}You may want to import a set of trusted certificates into the Mono certificate store.{0}Use the command:{0} mozroots --import --sync{0}Read more: {1}", Environment.NewLine, "http://manpages.ubuntu.com/manpages/natty/man1/mozroots.1.html"); } }
+ public static string MonoHelpSSL { get { return LC.L(@"{0}You may want to import a set of trusted certificates into the Mono certificate store.{0}Use the command:{0} cert-sync /etc/ssl/certs/ca-certificates.crt #for Debian based systems{0} cert-sync /etc/pki/tls/certs/ca-bundle.crt #for RedHat derivatives{0}Read more: {1}", Environment.NewLine, "http://www.mono-project.com/docs/about-mono/releases/3.12.0/#cert-sync"); } }
public static string VerifyCertificateException(System.Net.Security.SslPolicyErrors error, string hash) { return LC.L(@"The server certificate had the error {0} and the hash {1}{2}If you trust this certificate, use the commandline option --accept-specified-ssl-hash={1} to accept the server certificate anyway.{2}You can also attempt to import the server certificate into your operating systems trust pool.", error, hash, Environment.NewLine); }
- public static string VerifyCertificateHashError(System.Exception exception, System.Net.Security.SslPolicyErrors error) { return LC.L(@"Failed while validating certificate hash, error message: {0}, Ssl error name: {1}", exception, error); }
+ public static string VerifyCertificateHashError(System.Exception exception, System.Net.Security.SslPolicyErrors error) { return LC.L(@"Failed while validating certificate hash, error message: {0}, SSL error name: {1}", exception, error); }
}
internal static class TempFolder {
public static string TempFolderDoesNotExistError(string path) { return LC.L(@"Temporary folder does not exist: {0}", path); }
@@ -35,4 +35,7 @@ namespace Duplicati.Library.Utility.Strings {
internal static class MD5CalculatingStream {
public static string IncorrectUsageError { get { return LC.L(@"Cannot read and write on the same stream"); } }
}
+ internal static class Filters {
+ public static string UnknownDefaultFilterSet(string filterSet) { return LC.L(@"Unknown default filter set: {0}", filterSet); }
+ }
}
diff --git a/Duplicati/Library/Utility/TempFolder.cs b/Duplicati/Library/Utility/TempFolder.cs
index 26ce2a39e..97d40352a 100644
--- a/Duplicati/Library/Utility/TempFolder.cs
+++ b/Duplicati/Library/Utility/TempFolder.cs
@@ -80,20 +80,18 @@ namespace Duplicati.Library.Utility
#endregion
- private static string m_system_temp_dir = null;
-
/// <summary>
/// Gets or sets the global temporary path used to store temporary files.
/// Set to null to use the system default.
/// </summary>
public static string SystemTempPath
{
- get { return m_system_temp_dir == null ? System.IO.Path.GetTempPath() : m_system_temp_dir; }
+ get { return SystemContextSettings.Tempdir; }
set
{
if (!System.IO.Directory.Exists(value))
throw new Exception(Strings.TempFolder.TempFolderDoesNotExistError(value));
- m_system_temp_dir = value;
+ SystemContextSettings.Tempdir = value;
}
}
diff --git a/Duplicati/Library/Utility/ThrottledStream.cs b/Duplicati/Library/Utility/ThrottledStream.cs
index c0a7afe14..7da95e996 100644
--- a/Duplicati/Library/Utility/ThrottledStream.cs
+++ b/Duplicati/Library/Utility/ThrottledStream.cs
@@ -34,16 +34,6 @@ namespace Duplicati.Library.Utility
public class ThrottledStream : OverrideableStream
{
/// <summary>
- /// The delegate type for the callback
- /// </summary>
- public delegate void ThrottledStreamCallback(ThrottledStream sender);
-
- /// <summary>
- /// An event that is raised while the stream is active
- /// </summary>
- public event ThrottledStreamCallback Callback;
-
- /// <summary>
/// The max number of bytes pr. second to write
/// </summary>
private long m_writespeed;
@@ -52,45 +42,64 @@ namespace Duplicati.Library.Utility
/// </summary>
private long m_readspeed;
- /// <summary>
- /// This is a list of the most recent reads. The key is the tick at the time, and the value is the number of bytes.
- /// </summary>
- List<KeyValuePair<long, long>> m_dataread;
- /// <summary>
- /// This is a list of the most recent writes. The key is the tick at the time, and the value is the number of bytes.
- /// </summary>
- List<KeyValuePair<long, long>> m_datawritten;
- /// <summary>
- /// This is the sum of all bytes in the m_dataread table, summed for fast access.
- /// </summary>
- private long m_bytesread;
- /// <summary>
- /// This is the sum of all bytes in the m_datawritten table, summed for fast access.
- /// </summary>
- private long m_byteswritten;
-
- /// <summary>
- /// The number of bytes transfered without raising an event
- /// </summary>
- private long m_progresscounter = 0;
-
- /// <summary>
- /// The number of reads or writes to keep track of
- /// </summary>
- private const long STATISTICS_SIZE = 500;
- /// <summary>
- /// The number of ticks to have passed before the throttle begins
- /// </summary>
- private const long MIN_DURATION = TimeSpan.TicksPerSecond / 4;
- /// <summary>
- /// The number of sub chunks to perform when throttling
- /// </summary>
- private const int DELAY_CHUNK_SIZE = 1024;
-
- /// <summary>
- /// The number of bytes to process without raising an event
- /// </summary>
- private const int REPORT_DISTANCE_SIZE = 1024 * 50;
+ /// <summary>
+ /// The time the last read was sampled
+ /// </summary>
+ private DateTime m_last_read_sample;
+ /// <summary>
+ /// The bytes-read counter for this period
+ /// </summary>
+ private long m_current_read_counter;
+ /// <summary>
+ /// The current measured read speed
+ /// </summary>
+ private double m_current_read_speed;
+
+ /// <summary>
+ /// The time the last read was sampled
+ /// </summary>
+ private DateTime m_last_write_sample;
+ /// <summary>
+ /// The bytes-written counter for this period
+ /// </summary>
+ private long m_current_write_counter;
+ /// <summary>
+ /// The current measured read speed
+ /// </summary>
+ private double m_current_write_speed;
+
+ /// <summary>
+ /// The time the last read was sampled
+ /// </summary>
+ private DateTime m_last_limit_update;
+
+ /// <summary>
+ /// The number of ticks to have passed before a sample is taken
+ /// </summary>
+ private const long SAMPLE_PERIOD = TimeSpan.TicksPerSecond / 4;
+
+ /// <summary>
+ /// The number of ticks to have passed before the limits updater is called
+ /// </summary>
+ private const long UPDATE_PERIOD = TimeSpan.TicksPerSecond;
+
+ /// <summary>
+ /// Callback method used to update limits
+ /// </summary>
+ private readonly Action<ThrottledStream> m_updateLimits;
+
+ /// <summary>
+ /// Creates a throttle around a stream.
+ /// </summary>
+ /// <param name="basestream">The stream to throttle</param>
+ /// <param name="readspeed">The maximum number of bytes pr. second to read. Specify a number less than 1 to allow unlimited speed.</param>
+ /// <param name="writespeed">The maximum number of bytes pr. second to write. Specify a number less than 1 to allow unlimited speed.</param>
+ public ThrottledStream(Stream basestream, Action<ThrottledStream> updateLimits)
+ : base(basestream)
+ {
+ m_last_read_sample = m_last_write_sample = m_last_limit_update = new DateTime(0);
+ m_updateLimits = updateLimits;
+ }
/// <summary>
/// Creates a throttle around a stream.
@@ -104,44 +113,62 @@ namespace Duplicati.Library.Utility
m_readspeed = readspeed;
m_writespeed = writespeed;
- if (m_basestream.CanRead && m_readspeed > 0)
- m_dataread = new List<KeyValuePair<long, long>>();
- if (m_basestream.CanWrite && m_writespeed > 0)
- m_datawritten = new List<KeyValuePair<long, long>>();
+ m_last_read_sample = m_last_write_sample = m_last_limit_update = new DateTime(0);
+ m_updateLimits = null;
}
+ /// <summary>
+ /// Read the specified buffer, offset and count.
+ /// </summary>
+ /// <param name="buffer">The buffer to read from.</param>
+ /// <param name="offset">The offset into the buffer.</param>
+ /// <param name="count">The number of bytes to read.</param>
public override int Read(byte[] buffer, int offset, int count)
{
- int bytesRead = DelayIfRequired(true, buffer, ref offset, ref count);
- if (count != 0)
- bytesRead += m_basestream.Read(buffer, offset, count);
+ var remaining = count;
- m_progresscounter += bytesRead;
+ while (remaining > 0)
+ {
+ // To avoid excessive waiting, the delay will wait at most 2 seconds,
+ // so we split the blocks to limit the number of seconds we can wait
+ UpdateLimits();
+ var chunksize = (int)Math.Min(remaining, m_readspeed <= 0 ? remaining : m_readspeed * 2);
+ DelayIfRequired(ref m_readspeed, chunksize, ref m_last_read_sample, ref m_current_read_counter, ref m_current_read_speed);
- if (m_progresscounter > REPORT_DISTANCE_SIZE)
- {
- m_progresscounter %= REPORT_DISTANCE_SIZE;
- if (Callback != null)
- Callback(this);
- }
+ var actual = m_basestream.Read(buffer, offset, chunksize);
- return bytesRead;
+ if (actual <= 0)
+ break;
+
+ m_current_read_counter += actual;
+
+ remaining -= actual;
+ }
+
+ return count - remaining;
}
+ /// <summary>
+ /// Write the specified buffer, offset and count.
+ /// </summary>
+ /// <param name="buffer">The buffer to write to.</param>
+ /// <param name="offset">The offset into the buffer.</param>
+ /// <param name="count">The number of bytes to write.</param>
public override void Write(byte[] buffer, int offset, int count)
{
- m_progresscounter += count;
-
- DelayIfRequired(false, buffer, ref offset, ref count);
- if (count > 0)
- m_basestream.Write(buffer, offset, count);
-
- if (m_progresscounter > REPORT_DISTANCE_SIZE)
- {
- m_progresscounter %= REPORT_DISTANCE_SIZE;
- if (Callback != null)
- Callback(this);
- }
+ while (count > 0)
+ {
+ // To avoid excessive waiting, the delay will wait at most 2 seconds,
+ // so we split the blocks to limit the number of seconds we can wait
+ UpdateLimits();
+ var chunksize = (int)Math.Min(count, m_writespeed <= 0 ? count : m_writespeed * 2);
+ DelayIfRequired(ref m_writespeed, chunksize, ref m_last_write_sample, ref m_current_write_counter, ref m_current_write_speed);
+ m_basestream.Write(buffer, offset, chunksize);
+
+ m_current_write_counter += chunksize;
+
+ count -= chunksize;
+ }
}
/// <summary>
@@ -164,100 +191,79 @@ namespace Duplicati.Library.Utility
set { m_writespeed = value; }
}
+ /// <summary>
+ /// Gets the actual measured read speed.
+ /// </summary>
+ public double MeasuredReadSpeed { get { return m_current_read_speed; } }
+
+ /// <summary>
+ /// Gets the actual measured write speed.
+ /// </summary>
+ public double MeasuredWriteSpeed { get { return m_current_write_speed; } }
+
/// <summary>
- /// Calculates the speed, and inserts appropriate delays
+ /// Helper method called to update the limits
/// </summary>
- /// <param name="read">True if the operation is read, false otherwise</param>
- /// <param name="buffer">The data buffer</param>
- /// <param name="offset">The offset into the buffer</param>
- /// <param name="count">The number of bytes to read or write</param>
- /// <returns>The number of bytes processed while delaying</returns>
- private int DelayIfRequired(bool read, byte[] buffer, ref int offset, ref int count)
+ private void UpdateLimits()
{
- if (count <= 0)
- return 0;
-
- List<KeyValuePair<long, long>> table = read ? m_dataread : m_datawritten;
- int bytesprocessed = 0;
-
- if (table != null)
+ var now = DateTime.Now;
+ if (m_updateLimits != null && now.Ticks - m_last_limit_update.Ticks > UPDATE_PERIOD)
{
- long maxspeed = read ? m_readspeed : m_writespeed;
- Stream stream = m_basestream;
- long bytecount = read ? m_bytesread : m_byteswritten;
-
- //Add this access
- table.Add(new KeyValuePair<long,long>(DateTime.Now.Ticks, count));
- bytecount += count;
-
- //Prevent too large tables
- while (table.Count > STATISTICS_SIZE)
- {
- bytecount -= table[0].Value;
- table.RemoveAt(0);
- }
-
- if (table.Count != 0 && bytecount != 0)
- {
- TimeSpan duration = new TimeSpan(table[table.Count - 1].Key - table[0].Key);
-
- //Bail if we are too slow
- if (duration.Ticks < MIN_DURATION || bytecount <= 0)
- return 0;
-
- //TODO: The resolution is too low in "TotalSeconds", so the speed is a little higher
- double speed = bytecount / duration.TotalSeconds;
- if (speed > maxspeed)
- {
- //We are too fast, delay the access. Calculating how much wait we need.
- double secondsNeeded = (bytecount / (double)maxspeed) - duration.TotalSeconds;
- long delayTicks = (long)(secondsNeeded * TimeSpan.TicksPerSecond);
-
- //Calculate the time we should finish, to obey the limit
- long targetTime = DateTime.Now.Ticks + delayTicks;
-
- if (delayTicks > 0)
- {
- while (count > DELAY_CHUNK_SIZE && delayTicks > 0)
- {
- int bytes = read ? stream.Read(buffer, offset, DELAY_CHUNK_SIZE) : DELAY_CHUNK_SIZE;
- if (!read)
- stream.Write(buffer, offset, DELAY_CHUNK_SIZE);
-
- delayTicks = targetTime - DateTime.Now.Ticks;
- long ticksToDelay = (delayTicks / count) * bytes;
-
- if (ticksToDelay > 0)
- System.Threading.Thread.Sleep(new TimeSpan(ticksToDelay));
-
- //Reset to include the waited time
- delayTicks = targetTime - DateTime.Now.Ticks;
-
- offset += bytes;
- count -= bytes;
- bytesprocessed += bytes;
-
- if (bytes == 0)
- break;
- }
-
- if (delayTicks > 0)
- System.Threading.Thread.Sleep(new TimeSpan(delayTicks));
-
- //Add a marker, indicating that we already slowed down
- table.Add(new KeyValuePair<long, long>(DateTime.Now.Ticks, 0));
- }
-
- }
- }
-
- if (read)
- m_bytesread = bytecount;
- else
- m_byteswritten = bytecount;
+ m_updateLimits(this);
+ m_last_limit_update = now;
}
+ }
- return bytesprocessed;
+ /// <summary>
+ /// Calculates the speed, and inserts appropriate delays
+ /// </summary>
+ /// <param name="read">True if the operation is read, false otherwise</param>
+ /// <param name="buffer">The data buffer</param>
+ /// <param name="offset">The offset into the buffer</param>
+ /// <param name="count">The number of bytes to read or write</param>
+ /// <returns>The number of bytes processed while delaying</returns>
+ private void DelayIfRequired(ref long limit, int count, ref DateTime last_sample, ref long last_count, ref double current_speed)
+ {
+ var now = DateTime.Now;
+
+ if (count <= 0 || limit <= 0)
+ return;
+
+ // If we are just starting, set the timer and counter
+ if (last_sample.Ticks == 0)
+ {
+ last_count = 0;
+ last_sample = now;
+ current_speed = limit;
+ return;
+ }
+
+ // Compute the current duration
+ var duration = now - last_sample;
+
+ // Update speed in intervals
+ if (duration.Ticks > SAMPLE_PERIOD || last_count > limit)
+ {
+ // After a sample period, measure how far ahead we are
+ var target_delay = TimeSpan.FromSeconds(last_count / (double)limit) - duration;
+
+ // If we are actually ahead, delay for a little while
+ if (target_delay.Ticks > 1000)
+ {
+ // With large changes, we avoid sleeping for several minutes
+ // This makes the throttling more resposive when increasing the
+ // throughput, even with large changes
+ var ms = (int)Math.Min(target_delay.TotalMilliseconds, 2 * 1000);
+ System.Threading.Thread.Sleep(ms);
+
+ // When we compute how fast this sample was, we include the delay
+ now = DateTime.Now;
+ }
+
+ current_speed = last_count / (now - last_sample).TotalSeconds;
+ last_sample = now;
+ last_count = 0;
+ }
}
}
}
diff --git a/Duplicati/Library/Utility/Uri.cs b/Duplicati/Library/Utility/Uri.cs
index e655ffd3b..5f39e5db1 100644
--- a/Duplicati/Library/Utility/Uri.cs
+++ b/Duplicati/Library/Utility/Uri.cs
@@ -33,7 +33,7 @@ namespace Duplicati.Library.Utility
/// <summary>
/// A very lax version of a URL parser
/// </summary>
- private static System.Text.RegularExpressions.Regex URL_PARSER = new System.Text.RegularExpressions.Regex(@"(?<scheme>[^:]+)://(((?<username>[^\:]+)(\:(?<password>[^@]*))?\@))?((?<hostname>[^/\?\:]+)(\:(?<port>\d+))?)?((?<path>[^\?]*))?(\?(?<query>.+))?");
+ private static System.Text.RegularExpressions.Regex URL_PARSER = new System.Text.RegularExpressions.Regex(@"(?<scheme>[^:]+)://(((?<username>[^\:\?/]+)(\:(?<password>[^@\:\?/]*))?\@))?((?<hostname>[^/\?\:]+)(\:(?<port>\d+))?)?((?<path>[^\?]*))?(\?(?<query>.+))?");
/// <summary>
/// The URL scheme, e.g. http
@@ -139,7 +139,7 @@ namespace Duplicati.Library.Utility
if (!m.Success || m.Length != url.Length)
{
var path = url;
- if (path.StartsWith("file://", StringComparison.InvariantCultureIgnoreCase))
+ if (path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
path = path.Substring("file://".Length);
if (path.IndexOfAny(System.IO.Path.GetInvalidPathChars()) < 0)
@@ -158,7 +158,7 @@ namespace Duplicati.Library.Utility
catch
{
}
- throw new ArgumentException(Strings.Uri.UriParseError(url), "url");
+ throw new ArgumentException(Strings.Uri.UriParseError(url), nameof(url));
}
this.Scheme = m.Groups["scheme"].Value;
@@ -391,10 +391,10 @@ namespace Duplicati.Library.Utility
private static System.Text.RegularExpressions.Regex RE_NUMBER = new System.Text.RegularExpressions.Regex(@"(\%(?<number>([0-9]|[a-f]|[A-F]){2}))|(\+)|(\%u(?<number>([0-9]|[a-f]|[A-F]){2,4,6,8}))", System.Text.RegularExpressions.RegexOptions.Compiled);
/// <summary>
- /// Encodes a URL, like System.Web.HttpUtility.UrlEncode
+ /// Decodes a URL, like System.Web.HttpUtility.UrlDecode
/// </summary>
/// <returns>The decoded URL</returns>
- /// <param name="url">The URL fragment to decode</param>
+ /// <param name="value">The URL fragment to decode</param>
/// <param name="encoding">The encoding to use</param>
public static string UrlDecode(string value, System.Text.Encoding encoding = null)
{
@@ -447,9 +447,9 @@ namespace Duplicati.Library.Utility
if (query.StartsWith("?"))
query = query.Substring(1);
if (string.IsNullOrEmpty(query))
- return new NameValueCollection(StringComparer.InvariantCultureIgnoreCase);
+ return new NameValueCollection(StringComparer.OrdinalIgnoreCase);
- var result = new NameValueCollection(StringComparer.InvariantCultureIgnoreCase);
+ var result = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
foreach(System.Text.RegularExpressions.Match m in RE_URLPARAM.Matches(query))
result.Add(UrlDecode(m.Groups["key"].Value), UrlDecode(m.Groups["value"].Success ? m.Groups["value"].Value : ""));
diff --git a/Duplicati/Library/Utility/Utility.cs b/Duplicati/Library/Utility/Utility.cs
index 66ad85ca6..3a2443488 100644
--- a/Duplicati/Library/Utility/Utility.cs
+++ b/Duplicati/Library/Utility/Utility.cs
@@ -32,7 +32,7 @@ namespace Duplicati.Library.Utility
/// <summary>
/// Size of buffers for copying stream
/// </summary>
- public static long DEFAULT_BUFFER_SIZE = 64 * 1024;
+ public static long DEFAULT_BUFFER_SIZE => SystemContextSettings.Buffersize;
/// <summary>
/// A value indicating if the current process is running in 64bit mode
@@ -220,11 +220,18 @@ namespace Duplicati.Library.Utility
public delegate System.IO.FileAttributes ExtractFileAttributes(string path);
/// <summary>
+ /// A callback delegate used for extracting attributes from a file or folder
+ /// </summary>
+ /// <param name="rootpath">The root folder where the path was found</param>
+ /// <param name="path">The path that produced the error</param>
+ /// <param name="ex">The exception for the error</param>
+ public delegate void ReportAccessError(string rootpath, string path, Exception ex);
+
+ /// <summary>
/// Returns a list of all files found in the given folder.
/// The search is recursive.
/// </summary>
/// <param name="rootpath">The folder to look in</param>
- /// <param name="filter">An optional filter to apply to the filenames</param>
/// <param name="callback">The function to call with the filenames</param>
/// <returns>A list of the full filenames</returns>
public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback)
@@ -243,7 +250,7 @@ namespace Duplicati.Library.Utility
/// <returns>A list of the full filenames</returns>
public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback, FileSystemInteraction folderList, FileSystemInteraction fileList)
{
- return EnumerateFileSystemEntries(rootpath, callback, folderList, fileList, null);
+ return EnumerateFileSystemEntries(rootpath, callback, folderList, fileList, null, null);
}
/// <summary>
@@ -255,8 +262,9 @@ namespace Duplicati.Library.Utility
/// <param name="folderList">A function to call that lists all folders in the supplied folder</param>
/// <param name="fileList">A function to call that lists all files in the supplied folder</param>
/// <param name="attributeReader">A function to call that obtains the attributes for an element, set to null to avoid reading attributes</param>
+ /// <param name="errorCallback">An optional function to call with error messages.</param>
/// <returns>A list of the full filenames</returns>
- public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback, FileSystemInteraction folderList, FileSystemInteraction fileList, ExtractFileAttributes attributeReader)
+ public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback, FileSystemInteraction folderList, FileSystemInteraction fileList, ExtractFileAttributes attributeReader, ReportAccessError errorCallback = null)
{
Stack<string> lst = new Stack<string>();
@@ -269,7 +277,7 @@ namespace Duplicati.Library.Utility
isFolder = (attributeReader(rootpath) & System.IO.FileAttributes.Directory) == System.IO.FileAttributes.Directory;
}
catch
- {
+ {
}
if (isFolder)
@@ -286,9 +294,11 @@ namespace Duplicati.Library.Utility
{
throw;
}
- catch (Exception)
+ catch (Exception ex)
{
- callback(rootpath, rootpath, ATTRIBUTE_ERROR | System.IO.FileAttributes.Directory);
+ if (errorCallback != null)
+ errorCallback(rootpath, rootpath, ex);
+ callback(rootpath, rootpath, System.IO.FileAttributes.Directory | ATTRIBUTE_ERROR);
}
while (lst.Count > 0)
@@ -302,18 +312,33 @@ namespace Duplicati.Library.Utility
foreach(string s in folderList(f))
{
var sf = AppendDirSeparator(s);
- System.IO.FileAttributes attr = attributeReader == null ? System.IO.FileAttributes.Directory : attributeReader(sf);
- if (callback(rootpath, sf, attr))
- lst.Push(sf);
+ try
+ {
+ System.IO.FileAttributes attr = attributeReader == null ? System.IO.FileAttributes.Directory : attributeReader(sf);
+ if (callback(rootpath, sf, attr))
+ lst.Push(sf);
+ }
+ catch (System.Threading.ThreadAbortException)
+ {
+ throw;
+ }
+ catch (Exception ex)
+ {
+ if (errorCallback != null)
+ errorCallback(rootpath, sf, ex);
+ callback(rootpath, sf, System.IO.FileAttributes.Directory | ATTRIBUTE_ERROR);
+ }
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
- catch (Exception)
+ catch (Exception ex)
{
- callback(rootpath, f, ATTRIBUTE_ERROR | System.IO.FileAttributes.Directory);
+ if (errorCallback != null)
+ errorCallback(rootpath, f, ex);
+ callback(rootpath, f, System.IO.FileAttributes.Directory | ATTRIBUTE_ERROR);
}
string[] files = null;
@@ -326,9 +351,11 @@ namespace Duplicati.Library.Utility
{
throw;
}
- catch (Exception)
+ catch (Exception ex)
{
- callback(rootpath, f, ATTRIBUTE_ERROR);
+ if (errorCallback != null)
+ errorCallback(rootpath, f, ex);
+ callback(rootpath, f, System.IO.FileAttributes.Directory | ATTRIBUTE_ERROR);
}
if (files != null)
@@ -344,8 +371,10 @@ namespace Duplicati.Library.Utility
{
throw;
}
- catch (Exception)
+ catch (Exception ex)
{
+ if (errorCallback != null)
+ errorCallback(rootpath, s, ex);
callback(rootpath, s, ATTRIBUTE_ERROR);
continue;
}
@@ -365,8 +394,10 @@ namespace Duplicati.Library.Utility
{
throw;
}
- catch (Exception)
+ catch (Exception ex)
{
+ if (errorCallback != null)
+ errorCallback(rootpath, rootpath, ex);
callback(rootpath, rootpath, ATTRIBUTE_ERROR);
yield break;
}
@@ -399,13 +430,38 @@ namespace Duplicati.Library.Utility
/// <returns>The path with the directory separator appended</returns>
public static string AppendDirSeparator(string path)
{
- if (!path.EndsWith(DirectorySeparatorString))
+ if (!path.EndsWith(DirectorySeparatorString, StringComparison.Ordinal))
return path += DirectorySeparatorString;
else
return path;
}
/// <summary>
+ /// Appends the appropriate directory separator to paths, depending on OS.
+ /// Does not append the separator if the path already ends with it.
+ /// </summary>
+ /// <param name="path">The path to append to</param>
+ /// <param name="separator">The directory separator to use</param>
+ /// <returns>The path with the directory separator appended</returns>
+ public static string AppendDirSeparator(string path, string separator)
+ {
+ if (!path.EndsWith(separator, StringComparison.Ordinal))
+ return path += separator;
+ else
+ return path;
+ }
+
+ /// <summary>
+ /// Guesses the directory separator from the path
+ /// </summary>
+ /// <param name="path">The path to guess the separator from</param>
+ /// <returns>The guessed directory separator</returns>
+ public static string GuessDirSeparator(string path)
+ {
+ return string.IsNullOrWhiteSpace(path) || path.StartsWith("/", StringComparison.Ordinal) ? "/" : "\\";
+ }
+
+ /// <summary>
/// Some streams can return a number that is less than the requested number of bytes.
/// This is usually due to fragmentation, and is solved by issuing a new read.
/// This function wraps that functionality.
@@ -495,7 +551,7 @@ namespace Duplicati.Library.Utility
/// <returns>The base64 encoded hash</returns>
public static string CalculateHash(System.IO.Stream stream)
{
- return Convert.ToBase64String(System.Security.Cryptography.HashAlgorithm.Create(HashAlgorithm).ComputeHash(stream));
+ return Convert.ToBase64String(HashAlgorithmHelper.Create(HashAlgorithm).ComputeHash(stream));
}
/// <summary>
@@ -769,6 +825,17 @@ namespace Duplicati.Library.Utility
{
get
{
+ var str = Environment.GetEnvironmentVariable("FILESYSTEM_CASE_SENSITIVE");
+
+ if (!string.IsNullOrWhiteSpace(str))
+ {
+ str = str.Trim();
+ if (new[] { "yes", "1", "on", "true" }.Contains(str, StringComparer.OrdinalIgnoreCase))
+ return true;
+ if (new[] { "no", "0", "off", "false" }.Contains(str, StringComparer.OrdinalIgnoreCase))
+ return false;
+ }
+
//TODO: This should probably be determined by filesystem rather than OS,
// OSX can actually have the disks formated as Case Sensitive, but insensitive is default
return IsClientLinux && !IsClientOSX;
@@ -1008,6 +1075,38 @@ namespace Duplicati.Library.Utility
}
/// <summary>
+ /// Gets the unique items from a collection.
+ /// </summary>
+ /// <typeparam name="T">The type of the elements in <paramref name="collection"/>.</typeparam>
+ /// <param name="collection">The collection to remove duplicate items from.</param>
+ /// <param name="duplicateItems">The duplicate items in <paramref name="collection"/>.</param>
+ /// <returns>The unique items from <paramref name="collection"/>.</returns>
+ public static ISet<T> GetUniqueItems<T>(IEnumerable<T> collection, out ISet<T> duplicateItems)
+ {
+ return Utility.GetUniqueItems(collection, EqualityComparer<T>.Default, out duplicateItems);
+ }
+
+ /// <summary>
+ /// Gets the unique items from a collection.
+ /// </summary>
+ /// <typeparam name="T">The type of the elements in <paramref name="collection"/>.</typeparam>
+ /// <param name="collection">The collection to remove duplicate items from.</param>
+ /// <param name="comparer">The <see cref="System.Collections.Generic.IEqualityComparer{T}"/> implementation to use when comparing values in the collection.</param>
+ /// <param name="duplicateItems">The duplicate items in <paramref name="collection"/>.</param>
+ /// <returns>The unique items from <paramref name="collection"/>.</returns>
+ public static ISet<T> GetUniqueItems<T>(IEnumerable<T> collection, IEqualityComparer<T> comparer, out ISet<T> duplicateItems)
+ {
+ HashSet<T> uniqueItems = new HashSet<T>(comparer);
+ duplicateItems = new HashSet<T>(comparer);
+
+ foreach (T item in collection)
+ if (!uniqueItems.Add(item))
+ duplicateItems.Add(item);
+
+ return uniqueItems;
+ }
+
+ /// <summary>
/// Helper method that replaces one file with another
/// </summary>
/// <param name="target">The file to replace</param>
@@ -1091,6 +1190,39 @@ namespace Duplicati.Library.Utility
}
/// <summary>
+ /// Returns a value indicating if the given type should be treated as a primitive
+ /// </summary>
+ /// <returns><c>true</c>, if type is primitive for serialization, <c>false</c> otherwise.</returns>
+ /// <param name="t">The type to check.</param>
+ private static bool IsPrimitiveTypeForSerialization(Type t)
+ {
+ return t.IsPrimitive || t.IsEnum || t == typeof(string) || t == typeof(DateTime) || t == typeof(TimeSpan);
+ }
+
+ /// <summary>
+ /// Writes a primitive to the output, or returns false if the input is not primitive
+ /// </summary>
+ /// <returns><c>true</c>, the item was printed, <c>false</c> otherwise.</returns>
+ /// <param name="item">The item to write.</param>
+ /// <param name="writer">The target writer.</param>
+ private static bool PrintSerializeIfPrimitive(object item, System.IO.TextWriter writer)
+ {
+ if (item == null)
+ {
+ writer.Write("null");
+ return true;
+ }
+
+ if (IsPrimitiveTypeForSerialization(item.GetType()))
+ {
+ writer.Write(item);
+ return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
/// Prints the object to a stream, which can be used for display or logging
/// </summary>
/// <returns>The serialized object</returns>
@@ -1101,23 +1233,40 @@ namespace Duplicati.Library.Utility
/// <param name="indentation">The string indentation</param>
/// <param name="visited">A lookup table with visited objects, used to avoid inifinite recursion</param>
/// <param name="collectionlimit">The maximum number of items to report from an IEnumerable instance</param>
- public static void PrintSerializeObject(object item, System.IO.TextWriter writer, Func<System.Reflection.PropertyInfo, bool> filter = null, bool recurseobjects = false, int indentation = 0, int collectionlimit = 0, Dictionary<object, object> visited = null)
- {
+ public static void PrintSerializeObject(object item, System.IO.TextWriter writer, Func<System.Reflection.PropertyInfo, object, bool> filter = null, bool recurseobjects = false, int indentation = 0, int collectionlimit = 0, Dictionary<object, object> visited = null)
+ {
visited = visited ?? new Dictionary<object, object>();
var indentstring = new string(' ', indentation);
+ var first = true;
+
+
+ if (item == null || IsPrimitiveTypeForSerialization(item.GetType()))
+ {
+ writer.Write(indentstring);
+ if (PrintSerializeIfPrimitive(item, writer))
+ return;
+ }
+
foreach (var p in item.GetType().GetProperties())
{
- if (filter != null && !filter(p))
+ if (filter != null && !filter(p, item))
continue;
-
- if (p.PropertyType.IsPrimitive || p.PropertyType.IsEnum || p.PropertyType == typeof(string) || p.PropertyType == typeof(DateTime) || p.PropertyType == typeof(TimeSpan))
+
+ if (IsPrimitiveTypeForSerialization(p.PropertyType))
{
- writer.WriteLine("{0}{1}: {2}", indentstring, p.Name, p.GetValue(item, null));
+ if (first)
+ first = false;
+ else
+ writer.WriteLine();
+
+ writer.Write("{0}{1}: ", indentstring, p.Name);
+ PrintSerializeIfPrimitive(p.GetValue(item, null), writer);
}
else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(p.PropertyType))
{
var enumerable = (System.Collections.IEnumerable)p.GetValue(item, null);
+ var any = false;
if (enumerable != null)
{
var enumerator = enumerable.GetEnumerator();
@@ -1125,41 +1274,43 @@ namespace Duplicati.Library.Utility
{
var remain = collectionlimit;
+ if (first)
+ first = false;
+ else
+ writer.WriteLine();
+
writer.Write("{0}{1}: [", indentstring, p.Name);
if (enumerator.MoveNext())
{
+ any = true;
writer.WriteLine();
-
- var extraindent = new string(' ', indentation + 4);
-
- writer.Write(indentstring);
- writer.Write(extraindent);
- writer.Write(enumerator.Current);
+ PrintSerializeObject(enumerator.Current, writer, filter, recurseobjects, indentation + 4, collectionlimit, visited);
remain--;
while (enumerator.MoveNext())
{
writer.WriteLine(",");
- writer.Write(indentstring);
- writer.Write(extraindent);
if (remain == 0)
{
writer.Write("...");
break;
}
- writer.Write(enumerator.Current);
+
+ PrintSerializeObject(enumerator.Current, writer, filter, recurseobjects, indentation + 4, collectionlimit, visited);
remain--;
}
- writer.WriteLine();
+ }
+ if (any)
+ {
+ writer.WriteLine();
writer.Write(indentstring);
}
-
- writer.WriteLine("]");
+ writer.Write("]");
}
}
}
@@ -1167,9 +1318,19 @@ namespace Duplicati.Library.Utility
{
var value = p.GetValue(item, null);
if (value == null)
- writer.WriteLine("{0}{1}: null", indentstring, p.Name);
+ {
+ if (first)
+ first = false;
+ else
+ writer.WriteLine();
+ writer.Write("{0}{1}: null", indentstring, p.Name);
+ }
else if (!visited.ContainsKey(value))
{
+ if (first)
+ first = false;
+ else
+ writer.WriteLine();
writer.WriteLine("{0}{1}:", indentstring, p.Name);
visited[value] = null;
PrintSerializeObject(value, writer, filter, recurseobjects, indentation + 4, collectionlimit, visited);
@@ -1188,7 +1349,7 @@ namespace Duplicati.Library.Utility
/// <param name="recurseobjects">A value indicating if non-primitive values are recursed</param>
/// <param name="indentation">The string indentation</param>
/// <param name="collectionlimit">The maximum number of items to report from an IEnumerable instance, set to zero or less for reporting all</param>
- public static StringBuilder PrintSerializeObject(object item, StringBuilder sb = null, Func<System.Reflection.PropertyInfo, bool> filter = null, bool recurseobjects = false, int indentation = 0, int collectionlimit = 10)
+ public static StringBuilder PrintSerializeObject(object item, StringBuilder sb = null, Func<System.Reflection.PropertyInfo, object, bool> filter = null, bool recurseobjects = false, int indentation = 0, int collectionlimit = 10)
{
sb = sb ?? new StringBuilder();
using(var sw = new System.IO.StringWriter(sb))
@@ -1243,5 +1404,67 @@ namespace Duplicati.Library.Utility
return buf;
}
}
+
+ /// <summary>
+ /// Gets the drive letter from the given volume guid.
+ /// This method cannot be inlined since the System.Management types are not implemented in Mono
+ /// </summary>
+ /// <param name="volumeGuid">Volume guid</param>
+ /// <returns>Drive letter, as a single character, or null if the volume wasn't found</returns>
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public static string GetDriveLetterFromVolumeGuid(Guid volumeGuid)
+ {
+ // Based on this answer:
+ // https://stackoverflow.com/questions/10186277/how-to-get-drive-information-by-volume-id
+ using (System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher("Select * from Win32_Volume"))
+ {
+ string targetId = string.Format(@"\\?\Volume{{{0}}}\", volumeGuid);
+ foreach (System.Management.ManagementObject obj in searcher.Get())
+ {
+ if (string.Equals(obj["DeviceID"].ToString(), targetId, StringComparison.OrdinalIgnoreCase))
+ {
+ object driveLetter = obj["DriveLetter"];
+ if (driveLetter != null)
+ {
+ return obj["DriveLetter"].ToString();
+ }
+ else
+ {
+ // The volume was found, but doesn't have a drive letter associated with it.
+ break;
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Gets all volume guids and their associated drive letters.
+ /// This method cannot be inlined since the System.Management types are not implemented in Mono
+ /// </summary>
+ /// <returns>Pairs of drive letter to volume guids</returns>
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public static IEnumerable<KeyValuePair<string, string>> GetVolumeGuidsAndDriveLetters()
+ {
+ using (System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher("Select * from Win32_Volume"))
+ {
+ foreach (System.Management.ManagementObject obj in searcher.Get())
+ {
+ object deviceIdObj = obj["DeviceID"];
+ object driveLetterObj = obj["DriveLetter"];
+ if (deviceIdObj != null && driveLetterObj != null)
+ {
+ string deviceId = deviceIdObj.ToString();
+ string driveLetter = driveLetterObj.ToString();
+ if (!string.IsNullOrEmpty(deviceId) && !string.IsNullOrEmpty(driveLetter))
+ {
+ yield return new KeyValuePair<string, string>(driveLetter + @"\", deviceId);
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/Duplicati/Library/Utility/Win32.cs b/Duplicati/Library/Utility/Win32.cs
index 617318b89..d830a09ed 100644
--- a/Duplicati/Library/Utility/Win32.cs
+++ b/Duplicati/Library/Utility/Win32.cs
@@ -32,6 +32,12 @@ namespace Duplicati.Library.Utility
public static class Win32
{
+ #region Consts
+
+ public const int ATTACH_PARENT_PROCESS = -1;
+
+ #endregion
+
#region Enums
[FlagsAttribute]
@@ -52,6 +58,16 @@ namespace Duplicati.Library.Utility
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
+ /// <summary>
+ /// Attaches the calling process to the console of the specified process.
+ /// </summary>
+ /// <param name="dwProcessId">[in] Identifier of the process, usually will be ATTACH_PARENT_PROCESS</param>
+ /// <returns>If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero.
+ /// To get extended error information, call Marshal.GetLastWin32Error.</returns>
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern bool AttachConsole(int dwProcessId);
+
#endregion
}
}
diff --git a/Duplicati/Library/Utility/app.config b/Duplicati/Library/Utility/app.config
index b4ca687d2..469464a22 100644
--- a/Duplicati/Library/Utility/app.config
+++ b/Duplicati/Library/Utility/app.config
@@ -1,3 +1,4 @@
<?xml version="1.0"?>
<configuration>
- <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
+ <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup>
+</configuration>
diff --git a/Duplicati/Library/Utility/packages.config b/Duplicati/Library/Utility/packages.config
new file mode 100644
index 000000000..9dfbfdc8d
--- /dev/null
+++ b/Duplicati/Library/Utility/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="FasterHashing" version="1.2.3" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Duplicati/License/Duplicati.License.csproj b/Duplicati/License/Duplicati.License.csproj
index 43cf50942..9c347a076 100644
--- a/Duplicati/License/Duplicati.License.csproj
+++ b/Duplicati/License/Duplicati.License.csproj
@@ -17,6 +17,7 @@
<UpgradeBackupLocation />
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -356,6 +357,42 @@
<Link>licenses\AngularGettext\licensedata.json</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="..\..\thirdparty\mozroots\Homepage.txt">
+ <Link>licenses\mozroots\Homepage.txt</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\thirdparty\mozroots\License.txt">
+ <Link>licenses\mozroots\License.txt</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\thirdparty\mozroots\licensedata.json">
+ <Link>licenses\mozroots\licensedata.json</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\thirdparty\TlsTest\Homepage.txt">
+ <Link>licenses\TlsTest\Homepage.txt</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\thirdparty\TlsTest\License.txt">
+ <Link>licenses\TlsTest\License.txt</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\thirdparty\TlsTest\licensedata.json">
+ <Link>licenses\TlsTest\licensedata.json</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\thirdparty\FasterHashing\download.txt">
+ <Link>licenses\FasterHashing\download.txt</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\thirdparty\FasterHashing\license.txt">
+ <Link>licenses\FasterHashing\license.txt</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\thirdparty\FasterHashing\licensedata.json">
+ <Link>licenses\FasterHashing\licensedata.json</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
@@ -387,5 +424,7 @@
<Folder Include="licenses\MimeKit\" />
<Folder Include="licenses\BouncyCastle\" />
<Folder Include="licenses\AngularGettext\" />
+ <Folder Include="licenses\mozroots\" />
+ <Folder Include="licenses\TlsTest\" />
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/Duplicati/License/acknowledgements.txt b/Duplicati/License/acknowledgements.txt
index 154b201c2..35d9059c8 100644
--- a/Duplicati/License/acknowledgements.txt
+++ b/Duplicati/License/acknowledgements.txt
@@ -11,3 +11,4 @@ Due to their recent contributions to Duplicati 2.0 we would like to thank some p
Stefan Lück (@footstark) for providing great performance optimizations to Duplicati 2.0
Tobias Käs (@weltkante) for his C# library that implements LZMA2 and 7z
Alexander Franzelin (@AlexFRAN) for the design of the Duplicati UI and the website
+ @agrajaghh for building localization support and improving the user interface
diff --git a/Duplicati/Server/Database/Connection.cs b/Duplicati/Server/Database/Connection.cs
index 0a1f5a5b5..4e4de0c8a 100644
--- a/Duplicati/Server/Database/Connection.cs
+++ b/Duplicati/Server/Database/Connection.cs
@@ -354,16 +354,104 @@ namespace Duplicati.Server.Database
}
}
- internal void AddOrUpdateBackup(IBackup item)
- {
- AddOrUpdateBackup(item, false, null);
- }
-
internal void AddOrUpdateBackupAndSchedule(IBackup item, ISchedule schedule)
{
AddOrUpdateBackup(item, true, schedule);
}
+ internal string ValidateBackup(IBackup item, ISchedule schedule)
+ {
+ if (string.IsNullOrWhiteSpace(item.Name))
+ return "Missing a name";
+
+ if (string.IsNullOrWhiteSpace(item.TargetURL))
+ return "Missing a target";
+
+ if (item.Sources == null || item.Sources.Any(x => string.IsNullOrWhiteSpace(x)) || item.Sources.Length == 0)
+ return "Invalid source list";
+
+ var disabled_encryption = false;
+ var passphrase = string.Empty;
+ if (item.Settings != null)
+ {
+ foreach (var s in item.Settings)
+ if (string.Equals(s.Name, "--no-encryption", StringComparison.OrdinalIgnoreCase))
+ disabled_encryption = string.IsNullOrWhiteSpace(s.Value) ? true : Library.Utility.Utility.ParseBool(s.Value, false);
+ else if (string.Equals(s.Name, "passphrase", StringComparison.OrdinalIgnoreCase))
+ passphrase = s.Value;
+ else if (string.Equals(s.Name, "keep-versions", StringComparison.OrdinalIgnoreCase))
+ {
+ int i;
+ if (!int.TryParse(s.Value, out i) || i <= 0)
+ return "Retention value must be a positive integer";
+ }
+ else if (string.Equals(s.Name, "keep-time", StringComparison.OrdinalIgnoreCase))
+ {
+ try
+ {
+ var ts = Library.Utility.Timeparser.ParseTimeSpan(s.Value);
+ if (ts <= TimeSpan.FromMinutes(5))
+ return "Retention value must be more than 5 minutes";
+ }
+ catch
+ {
+ return "Retention value must be a valid timespan";
+ }
+ }
+ else if (string.Equals(s.Name, "dblock-size", StringComparison.OrdinalIgnoreCase))
+ {
+ try
+ {
+ var ds = Library.Utility.Sizeparser.ParseSize(s.Value);
+ if (ds < 1024 * 1024)
+ return "DBlock size must be at least 1MB";
+ }
+ catch
+ {
+ return "DBlock value must be a valid size string";
+ }
+ }
+ else if (string.Equals(s.Name, "--blocksize", StringComparison.OrdinalIgnoreCase))
+ {
+ try
+ {
+ var ds = Library.Utility.Sizeparser.ParseSize(s.Value);
+ if (ds < 1024 || ds > int.MaxValue)
+ return "The blocksize must be at least 1KB";
+ }
+ catch
+ {
+ return "The blocksize value must be a valid size string";
+ }
+ }
+ else if (string.Equals(s.Name, "--prefix", StringComparison.OrdinalIgnoreCase))
+ {
+ if (!string.IsNullOrWhiteSpace(s.Value) && s.Value.Contains("-"))
+ return "The prefix cannot contain hyphens (-)";
+ }
+ }
+
+ if (!disabled_encryption && string.IsNullOrWhiteSpace(passphrase))
+ return "Missing passphrase";
+
+ if (schedule != null)
+ {
+ try
+ {
+ var ts = Library.Utility.Timeparser.ParseTimeSpan(schedule.Repeat);
+ if (ts <= TimeSpan.FromMinutes(5))
+ return "Schedule repetition time must be more than 5 minutes";
+ }
+ catch
+ {
+ return "Schedule repetition value must be a valid timespan";
+ }
+
+ }
+
+ return null;
+ }
+
internal void UpdateBackupDBPath(IBackup item, string path)
{
lock(m_lock)
@@ -392,7 +480,7 @@ namespace Duplicati.Server.Database
bool update = item.ID != null;
if (!update && item.DBPath == null)
{
- var folder = Program.DATAFOLDER;
+ var folder = Program.DataFolder;
if (!System.IO.Directory.Exists(folder))
System.IO.Directory.CreateDirectory(folder);
@@ -747,7 +835,8 @@ namespace Duplicati.Server.Database
),
@"SELECT ""Key"", ""Value"" FROM ""UIStorage"" WHERE ""Scheme"" = ?",
scheme)
- .ToDictionary(x => x.Key, x => x.Value);
+ .GroupBy(x => x.Key)
+ .ToDictionary(x => x.Key, x => x.Last().Value);
}
public void SetUISettings(string scheme, IDictionary<string, string> values, System.Data.IDbTransaction transaction = null)
@@ -770,6 +859,27 @@ namespace Duplicati.Server.Database
}
}
+ public void UpdateUISettings(string scheme, IDictionary<string, string> values, System.Data.IDbTransaction transaction = null)
+ {
+ lock (m_lock)
+ using (var tr = transaction == null ? m_connection.BeginTransaction() : null)
+ {
+ OverwriteAndUpdateDb(
+ tr,
+ @"DELETE FROM ""UIStorage"" WHERE ""Scheme"" = ? AND ""Key"" IN (?)", new object[] { scheme, values.Keys },
+ values.Where(x => x.Value != null),
+ @"INSERT INTO ""UIStorage"" (""Scheme"", ""Key"", ""Value"") VALUES (?, ?, ?)",
+ (f) =>
+ {
+ return new object[] { scheme, f.Key ?? "", f.Value ?? "" };
+ }
+ );
+
+ if (tr != null)
+ tr.Commit();
+ }
+ }
+
public TempFile[] GetTempFiles()
{
lock(m_lock)
@@ -823,13 +933,6 @@ namespace Duplicati.Server.Database
tr.Commit();
}
-
- using(var cmd = m_connection.CreateCommand())
- {
- cmd.CommandText = "VACUUM";
- cmd.ExecuteNonQuery();
- }
-
}
private static long NormalizeDateTimeToEpochSeconds(DateTime input)
diff --git a/Duplicati/Server/Database/Database schema/Schema.sql b/Duplicati/Server/Database/Database schema/Schema.sql
index 957844cbd..6cc17ae73 100644
--- a/Duplicati/Server/Database/Database schema/Schema.sql
+++ b/Duplicati/Server/Database/Database schema/Schema.sql
@@ -2,7 +2,7 @@
* The primary table that stores all backups.
*
* The name and tag are free form user strings.
- * The tags are comma seperated
+ * The tags are comma separated
* the TargetURL is the url to remote storage,
* and the DBPath is the path to the local database
*/
diff --git a/Duplicati/Server/Database/Schedule.cs b/Duplicati/Server/Database/Schedule.cs
index 806abc2e1..417b0668f 100644
--- a/Duplicati/Server/Database/Schedule.cs
+++ b/Duplicati/Server/Database/Schedule.cs
@@ -38,7 +38,7 @@ namespace Duplicati.Server.Database
return null;
var days = (from n in this.Rule.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
- where n.StartsWith("AllowedWeekDays=", StringComparison.InvariantCultureIgnoreCase)
+ where n.StartsWith("AllowedWeekDays=", StringComparison.OrdinalIgnoreCase)
select n.Substring("AllowedWeekDays=".Length).Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries))
.FirstOrDefault();
@@ -59,7 +59,7 @@ namespace Duplicati.Server.Database
string.IsNullOrEmpty(this.Rule) ?
new string[0] :
(from n in this.Rule.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
- where !n.StartsWith("AllowedWeekDays=", StringComparison.InvariantCultureIgnoreCase)
+ where !n.StartsWith("AllowedWeekDays=", StringComparison.OrdinalIgnoreCase)
select n);
if (value != null && value.Length != 0)
diff --git a/Duplicati/Server/Database/ServerSettings.cs b/Duplicati/Server/Database/ServerSettings.cs
index 7b2e4d08d..8104bb175 100644
--- a/Duplicati/Server/Database/ServerSettings.cs
+++ b/Duplicati/Server/Database/ServerSettings.cs
@@ -18,7 +18,11 @@
using System;
using System.Linq;
using System.Collections.Generic;
+using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Pkcs;
+using Org.BouncyCastle.Security;
namespace Duplicati.Server.Database
{
@@ -35,6 +39,8 @@ namespace Duplicati.Server.Database
public const string SERVER_PORT_CHANGED = "server-port-changed";
public const string SERVER_PASSPHRASE = "server-passphrase";
public const string SERVER_PASSPHRASE_SALT = "server-passphrase-salt";
+ public const string SERVER_PASSPHRASETRAYICON = "server-passphrase-trayicon";
+ public const string SERVER_PASSPHRASETRAYICONHASH = "server-passphrase-trayicon-hash";
public const string UPDATE_CHECK_LAST = "last-update-check";
public const string UPDATE_CHECK_INTERVAL = "update-check-interval";
public const string UPDATE_CHECK_NEW_VERSION = "update-check-latest";
@@ -44,8 +50,9 @@ namespace Duplicati.Server.Database
public const string SERVER_SSL_CERTIFICATE = "server-ssl-certificate";
public const string HAS_FIXED_INVALID_BACKUPID = "has-fixed-invalid-backup-id";
public const string UPDATE_CHANNEL = "update-channel";
- public const string USAGE_REPORTER_LEVEL = "usage-reporter-level";
- }
+ public const string USAGE_REPORTER_LEVEL = "usage-reporter-level";
+ public const string HAS_ASKED_FOR_PASSWORD_PROTECTION = "has-asked-for-password-protection";
+ }
private Dictionary<string, string> m_values;
private Database.Connection m_connection;
@@ -58,7 +65,7 @@ namespace Duplicati.Server.Database
ReloadSettings();
}
- private void ReloadSettings()
+ public void ReloadSettings()
{
lock(m_connection.m_lock)
{
@@ -87,11 +94,12 @@ namespace Duplicati.Server.Database
else
m_values[k.Key] = newsettings[k.Key];
- SaveSettings();
}
- System.Threading.Interlocked.Increment(ref Program.LastDataUpdateID);
- Program.StatusEventNotifyer.SignalNewEvent();
+ SaveSettings();
+
+ if (newsettings.Keys.Contains(CONST.SERVER_PASSPHRASE))
+ GenerateWebserverPasswordTrayIcon();
}
private void SaveSettings()
@@ -104,8 +112,13 @@ namespace Duplicati.Server.Database
Value = n.Value
}, Database.Connection.SERVER_SETTINGS_ID);
- // In case the usage reporter is enabled or disabled, refresh now
- Program.StartOrStopUsageReporter();
+ System.Threading.Interlocked.Increment(ref Program.LastDataUpdateID);
+ Program.StatusEventNotifyer.SignalNewEvent();
+
+ // In case the usage reporter is enabled or disabled, refresh now
+ Program.StartOrStopUsageReporter();
+ // If throttle options were changed, update now
+ Program.UpdateThrottleSpeeds();
}
public string StartupDelayDuration
@@ -187,9 +200,27 @@ namespace Duplicati.Server.Database
m_values[CONST.IS_FIRST_RUN] = value.ToString();
SaveSettings();
}
- }
-
- public bool UnackedError
+ }
+
+ public bool HasAskedForPasswordProtection
+ {
+ get
+ {
+ var tp = m_values[CONST.HAS_ASKED_FOR_PASSWORD_PROTECTION];
+ if (string.IsNullOrEmpty(tp))
+ return true;
+
+ return Duplicati.Library.Utility.Utility.ParseBoolOption(m_values, CONST.HAS_ASKED_FOR_PASSWORD_PROTECTION);
+ }
+ set
+ {
+ lock (m_connection.m_lock)
+ m_values[CONST.HAS_ASKED_FOR_PASSWORD_PROTECTION] = value.ToString();
+ SaveSettings();
+ }
+ }
+
+ public bool UnackedError
{
get
{
@@ -274,7 +305,6 @@ namespace Duplicati.Server.Database
m_values[CONST.SERVER_PASSPHRASE] = "";
m_values[CONST.SERVER_PASSPHRASE_SALT] = "";
}
- SaveSettings();
}
else
{
@@ -295,9 +325,41 @@ namespace Duplicati.Server.Database
m_values[CONST.SERVER_PASSPHRASE] = pwd;
m_values[CONST.SERVER_PASSPHRASE_SALT] = salt;
}
+ }
- SaveSettings();
+ SaveSettings();
+ GenerateWebserverPasswordTrayIcon();
+ }
+
+ public string WebserverPasswordTrayIcon => m_values[CONST.SERVER_PASSPHRASETRAYICON];
+
+ public string WebserverPasswordTrayIconHash => m_values[CONST.SERVER_PASSPHRASETRAYICONHASH];
+
+ public void GenerateWebserverPasswordTrayIcon()
+ {
+ var password = "";
+ var pwd = "";
+
+ if (!string.IsNullOrEmpty(m_values[CONST.SERVER_PASSPHRASE]))
+ {
+ password = Guid.NewGuid().ToString();
+ var buf = Convert.FromBase64String(m_values[CONST.SERVER_PASSPHRASE_SALT]);
+
+ var sha256 = System.Security.Cryptography.SHA256.Create();
+ var str = System.Text.Encoding.UTF8.GetBytes(password);
+
+ sha256.TransformBlock(str, 0, str.Length, str, 0);
+ sha256.TransformFinalBlock(buf, 0, buf.Length);
+ pwd = Convert.ToBase64String(sha256.Hash);
}
+
+ lock (m_connection.m_lock)
+ {
+ m_values[CONST.SERVER_PASSPHRASETRAYICON] = password;
+ m_values[CONST.SERVER_PASSPHRASETRAYICONHASH] = pwd;
+ }
+
+ SaveSettings();
}
public DateTime LastUpdateCheck
@@ -411,20 +473,31 @@ namespace Duplicati.Server.Database
{
get
{
- try
+ if (String.IsNullOrEmpty(m_values[CONST.SERVER_SSL_CERTIFICATE]))
+ return null;
+
+ if (Library.Utility.Utility.IsClientWindows)
+ return new X509Certificate2(Convert.FromBase64String(m_values[CONST.SERVER_SSL_CERTIFICATE]));
+ else
{
- if(String.IsNullOrEmpty(m_values[CONST.SERVER_SSL_CERTIFICATE]))
+ var store = new Pkcs12Store();
+
+ using (var stream = new System.IO.MemoryStream(Convert.FromBase64String(m_values[CONST.SERVER_SSL_CERTIFICATE])))
+ store.Load(stream, null);
+
+ if (store.Count != 1)
return null;
- var cert = new X509Certificate2();
-
- cert.Import(Convert.FromBase64String(m_values[CONST.SERVER_SSL_CERTIFICATE]));
+ var certAlias = store.Aliases.Cast<string>().FirstOrDefault(n => store.IsKeyEntry(n));
+ var cert = new X509Certificate2(DotNetUtilities.ToX509Certificate(store.GetCertificate(certAlias).Certificate).GetRawCertData());
+ var rsaPriv = DotNetUtilities.ToRSA(store.GetKey(certAlias).Key as RsaPrivateCrtKeyParameters);
+ var rsaPrivate = new RSACryptoServiceProvider(new CspParameters { KeyContainerName = "KeyContainer" });
+
+ rsaPrivate.ImportParameters(rsaPriv.ExportParameters(true));
+ cert.PrivateKey = rsaPrivate;
+
return cert;
}
- catch
- {
- return null;
- }
}
set
{
@@ -434,9 +507,25 @@ namespace Duplicati.Server.Database
m_values[CONST.SERVER_SSL_CERTIFICATE] = String.Empty;
}
else
- {
- lock (m_connection.m_lock)
- m_values[CONST.SERVER_SSL_CERTIFICATE] = Convert.ToBase64String(value.Export(X509ContentType.Pkcs12));
+ {
+ if (Library.Utility.Utility.IsClientWindows)
+ lock (m_connection.m_lock)
+ m_values[CONST.SERVER_SSL_CERTIFICATE] = Convert.ToBase64String(value.Export(X509ContentType.Pkcs12));
+ else
+ {
+ var store = new Pkcs12Store();
+
+ store.SetKeyEntry(value.FriendlyName,
+ new AsymmetricKeyEntry(DotNetUtilities.GetKeyPair(value.PrivateKey).Private),
+ new[] { new X509CertificateEntry(DotNetUtilities.FromX509Certificate(value)) });
+
+ using (var stream = new System.IO.MemoryStream())
+ {
+ store.Save(stream, null, new SecureRandom());
+ lock (m_connection.m_lock)
+ m_values[CONST.SERVER_SSL_CERTIFICATE] = Convert.ToBase64String(stream.ToArray());
+ }
+ }
}
SaveSettings();
}
diff --git a/Duplicati/Server/Duplicati.Server.Serialization/Duplicati.Server.Serialization.csproj b/Duplicati/Server/Duplicati.Server.Serialization/Duplicati.Server.Serialization.csproj
index 6b5bcca4a..eade340a0 100644
--- a/Duplicati/Server/Duplicati.Server.Serialization/Duplicati.Server.Serialization.csproj
+++ b/Duplicati/Server/Duplicati.Server.Serialization/Duplicati.Server.Serialization.csproj
@@ -11,6 +11,7 @@
<FileAlignment>512</FileAlignment>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -41,7 +42,7 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/Duplicati/Server/Duplicati.Server.Serialization/Enums.cs b/Duplicati/Server/Duplicati.Server.Serialization/Enums.cs
index 50abf5dd6..463fc79f9 100755
--- a/Duplicati/Server/Duplicati.Server.Serialization/Enums.cs
+++ b/Duplicati/Server/Duplicati.Server.Serialization/Enums.cs
@@ -47,7 +47,11 @@ namespace Duplicati.Server.Serialization
RepairUpdate,
Verify,
Compact,
- CreateReport
+ CreateReport,
+ ListRemote,
+ Delete,
+ Vacuum,
+ CustomRunner,
}
public enum SuggestedStatusIcon
diff --git a/Duplicati/Server/Duplicati.Server.Serialization/Interface/IProgressEventData.cs b/Duplicati/Server/Duplicati.Server.Serialization/Interface/IProgressEventData.cs
index 8dc4f0b2e..813ab1776 100644
--- a/Duplicati/Server/Duplicati.Server.Serialization/Interface/IProgressEventData.cs
+++ b/Duplicati/Server/Duplicati.Server.Serialization/Interface/IProgressEventData.cs
@@ -15,6 +15,7 @@ namespace Duplicati.Server.Serialization.Interface
long BackendFileSize { get; }
long BackendFileProgress { get; }
long BackendSpeed { get; }
+ bool BackendIsBlocking { get; }
string CurrentFilename { get; }
long CurrentFilesize { get; }
diff --git a/Duplicati/Server/Duplicati.Server.Serialization/Properties/AssemblyInfo.cs b/Duplicati/Server/Duplicati.Server.Serialization/Properties/AssemblyInfo.cs
index bf7024b16..f29219237 100644
--- a/Duplicati/Server/Duplicati.Server.Serialization/Properties/AssemblyInfo.cs
+++ b/Duplicati/Server/Duplicati.Server.Serialization/Properties/AssemblyInfo.cs
@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("Duplicati.GUI.Serialization")]
+[assembly: AssemblyTitle("Duplicati.Server.Serialization")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Duplicati Team")]
-[assembly: AssemblyProduct("Duplicati.GUI.Serialization")]
+[assembly: AssemblyProduct("Duplicati.Server.Serialization")]
[assembly: AssemblyCopyright("LGPL, Copyright © Duplicati Team 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
diff --git a/Duplicati/Server/Duplicati.Server.Serialization/packages.config b/Duplicati/Server/Duplicati.Server.Serialization/packages.config
index e1fae9c6a..ee51c2373 100644
--- a/Duplicati/Server/Duplicati.Server.Serialization/packages.config
+++ b/Duplicati/Server/Duplicati.Server.Serialization/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Server/Duplicati.Server.csproj b/Duplicati/Server/Duplicati.Server.csproj
index a28020f32..d8f9221b1 100644
--- a/Duplicati/Server/Duplicati.Server.csproj
+++ b/Duplicati/Server/Duplicati.Server.csproj
@@ -5,6 +5,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{19E661D2-C5DA-4F35-B3EE-7586E5734B5F}</ProjectGuid>
<OutputType>Exe</OutputType>
+ <Prefer32Bit>False</Prefer32Bit>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.Server</RootNamespace>
<AssemblyName>Duplicati.Server</AssemblyName>
@@ -12,6 +13,7 @@
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<SignAssembly>false</SignAssembly>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
@@ -45,6 +47,9 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
+ <Reference Include="BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
+ <HintPath>..\..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll</HintPath>
+ </Reference>
<Reference Include="UnixSupport">
<HintPath>..\..\thirdparty\UnixSupport\UnixSupport.dll</HintPath>
</Reference>
@@ -52,8 +57,9 @@
<HintPath>..\..\thirdparty\HttpServer\HttpServer.dll</HintPath>
</Reference>
<Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
<Reference Include="Newtonsoft.Json">
- <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -75,11 +81,11 @@
<Compile Include="Database\Schedule.cs" />
<Compile Include="SpecialFolders.cs" />
<Compile Include="WebServer\AuthenticationHandler.cs" />
+ <Compile Include="WebServer\RESTMethods\MSSQL.cs" />
<Compile Include="WebServer\RESTMethods\HyperV.cs" />
<Compile Include="WebServer\Server.cs" />
<Compile Include="WebServer\BodyWriter.cs" />
<Compile Include="WebServer\IndexHtmlHandler.cs" />
- <Compile Include="WebServer\ControlHandler.cs" />
<Compile Include="UpdatePollThread.cs" />
<Compile Include="LogWriteHandler.cs" />
<Compile Include="Database\Notification.cs" />
@@ -115,6 +121,10 @@
<Compile Include="WebServer\RESTMethods\WebModule.cs" />
<Compile Include="WebServer\RESTMethods\WebModules.cs" />
<Compile Include="WebServer\RESTMethods\Licenses.cs" />
+ <Compile Include="WebServer\CaptchaUtil.cs" />
+ <Compile Include="WebServer\RESTMethods\Captcha.cs" />
+ <Compile Include="WebServer\RESTMethods\CommandLine.cs" />
+ <Compile Include="WebServer\SynologyAuthenticationHandler.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
@@ -156,6 +166,10 @@
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
+ <ProjectReference Include="..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
+ <Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
+ <Name>Duplicati.Library.Backend.Jottacloud</Name>
+ </ProjectReference>
<ProjectReference Include="..\Library\Backend\OAuthHelper\Duplicati.Library.OAuthHelper.csproj">
<Project>{d4c37c33-5e73-4b56-b2c3-dc4a6baa36bb}</Project>
<Name>Duplicati.Library.OAuthHelper</Name>
@@ -168,6 +182,10 @@
<Project>{59C8BBC5-6E42-46FB-AB3E-6C183A82459A}</Project>
<Name>Duplicati.Library.Backend.SharePoint</Name>
</ProjectReference>
+ <ProjectReference Include="..\Library\Backend\Sia\Duplicati.Library.Backend.Sia.csproj">
+ <Project>{32a74526-3e5f-413a-8cb4-1efdad4c8b91}</Project>
+ <Name>Duplicati.Library.Backend.Sia</Name>
+ </ProjectReference>
<ProjectReference Include="..\Library\Backend\SSHv2\Duplicati.Library.Backend.SSHv2.csproj">
<Project>{FF2BF37C-E502-4C98-BEA0-701671DDFA08}</Project>
<Name>Duplicati.Library.Backend.SSHv2</Name>
diff --git a/Duplicati/Server/LogWriteHandler.cs b/Duplicati/Server/LogWriteHandler.cs
index 95b6a22b0..48a122fab 100644
--- a/Duplicati/Server/LogWriteHandler.cs
+++ b/Duplicati/Server/LogWriteHandler.cs
@@ -187,9 +187,6 @@ namespace Duplicati.Server
private volatile bool m_anytimeouts = false;
private RingBuffer<LogEntry> m_buffer;
- private ILog m_operationfile;
- private LogMessageType m_operationloglevel;
-
private ILog m_serverfile;
private LogMessageType m_serverloglevel;
@@ -223,31 +220,6 @@ namespace Duplicati.Server
UpdateLogLevel();
}
- public void SetOperationFile(string path, LogMessageType level)
- {
- var dir = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(path));
- if (!System.IO.Directory.Exists(dir))
- System.IO.Directory.CreateDirectory(dir);
-
- lock(m_lock)
- {
- m_operationfile = new StreamLog(path);
- m_operationloglevel = level;
- }
- }
-
- public void RemoveOperationFile()
- {
- lock(m_lock)
- {
- if (m_operationfile != null && m_operationfile is IDisposable)
- ((IDisposable)m_operationfile).Dispose();
- m_operationfile = null;
- m_operationloglevel = LogMessageType.Error;
- }
- UpdateLogLevel();
- }
-
public LogEntry[] AfterTime(DateTime offset, LogMessageType level)
{
RenewTimeout(level);
@@ -289,7 +261,7 @@ namespace Duplicati.Server
private void UpdateLogLevel()
{
Duplicati.Library.Logging.Log.LogLevel =
- (LogMessageType)(GetActiveTimeouts().Union(new int[] {(int)m_serverloglevel, (int)m_operationloglevel}).Min());
+ (LogMessageType)(GetActiveTimeouts().Union(new int[] { (int)m_serverloglevel }).Min());
}
@@ -297,16 +269,6 @@ namespace Duplicati.Server
public void WriteMessage(string message, LogMessageType type, Exception exception)
{
- var lg = m_operationfile;
- if (lg != null && type >= m_operationloglevel)
- try
- {
- lg.WriteMessage(message, type, exception);
- }
- catch
- {
- }
-
if (m_serverfile != null && type >= m_serverloglevel)
try
{
diff --git a/Duplicati/Server/Program.cs b/Duplicati/Server/Program.cs
index 77366f03b..28d116882 100644
--- a/Duplicati/Server/Program.cs
+++ b/Duplicati/Server/Program.cs
@@ -25,18 +25,13 @@ namespace Duplicati.Server
/// <summary>
/// Gets the folder where Duplicati data is stored
/// </summary>
- public static string DATAFOLDER { get { return Library.Utility.Utility.AppendDirSeparator(Library.Utility.Utility.ExpandEnvironmentVariables("%" + DATAFOLDER_ENV_NAME + "%").TrimStart('"').TrimEnd('"')); } }
+ public static string DataFolder { get; private set; }
/// <summary>
/// The single instance
/// </summary>
public static SingleInstance Instance = null;
-
- /// <summary>
- /// A flag indicating if database encryption is in use
- /// </summary>
- public static bool UseDatabaseEncryption;
-
+
/// <summary>
/// This is the only access to the database
/// </summary>
@@ -158,11 +153,11 @@ namespace Duplicati.Server
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args, Duplicati.Library.AutoUpdater.AutoUpdateStrategy.Never);
}
- public static void RealMain(string[] args)
+ public static int RealMain(string[] args)
{
//If we are on Windows, append the bundled "win-tools" programs to the search path
//We add it last, to allow the user to override with other versions
- if (!Library.Utility.Utility.IsClientLinux)
+ if (Library.Utility.Utility.IsClientWindows)
{
Environment.SetEnvironmentVariable("PATH",
Environment.GetEnvironmentVariable("PATH") +
@@ -174,41 +169,17 @@ namespace Duplicati.Server
}
//If this executable is invoked directly, write to console, otherwise throw exceptions
- bool writeConsole = System.Reflection.Assembly.GetEntryAssembly() == System.Reflection.Assembly.GetExecutingAssembly();
-
- //If we are on windows we encrypt the database by default
- //We do not encrypt on Linux as most distros use a SQLite library without encryption support,
- //Linux users can use an encrypted home folder, or install a SQLite library with encryption support
- if (!Library.Utility.Utility.IsClientLinux && string.IsNullOrEmpty(Environment.GetEnvironmentVariable(DB_KEY_ENV_NAME)))
- {
- //Note that the password here is a default password and public knowledge
- //
- //The purpose of this is to prevent casual read of the database, as well
- // as protect from harddisk string scans, not to protect from determined
- // attacks.
- //
- //If you desire better security, start Duplicati once with the commandline option
- // --unencrypted-database to decrypt the database.
- //Then set the environment variable DUPLICATI_DB_KEY to the desired key,
- // and run Duplicati again without the --unencrypted-database option
- // to re-encrypt it with the new key
- //
- //If you change the key, please note that you need to supply the same
- // key when restoring the setup, as the setup being backed up will
- // be encrypted as well.
- Environment.SetEnvironmentVariable(DB_KEY_ENV_NAME, Library.AutoUpdater.AutoUpdateSettings.AppName + "_Key_42");
- }
-
-
+ var writeConsole = System.Reflection.Assembly.GetEntryAssembly() == System.Reflection.Assembly.GetExecutingAssembly();
+
//Find commandline options here for handling special startup cases
- Dictionary<string, string> commandlineOptions = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(new List<string>(args));
+ var commandlineOptions = Duplicati.Library.Utility.CommandLineParser.ExtractOptions(new List<string>(args));
- foreach(string s in args)
+ foreach(var s in args)
if (
- s.Equals("help", StringComparison.InvariantCultureIgnoreCase) ||
- s.Equals("/help", StringComparison.InvariantCultureIgnoreCase) ||
- s.Equals("usage", StringComparison.InvariantCultureIgnoreCase) ||
- s.Equals("/usage", StringComparison.InvariantCultureIgnoreCase))
+ s.Equals("help", StringComparison.OrdinalIgnoreCase) ||
+ s.Equals("/help", StringComparison.OrdinalIgnoreCase) ||
+ s.Equals("usage", StringComparison.OrdinalIgnoreCase) ||
+ s.Equals("/usage", StringComparison.OrdinalIgnoreCase))
commandlineOptions["help"] = "";
//If the commandline issues --help, just stop here
@@ -221,7 +192,7 @@ namespace Duplicati.Server
foreach(Library.Interface.ICommandLineArgument arg in SupportedCommands)
Console.WriteLine(Strings.Program.HelpDisplayFormat(arg.Name, arg.LongDescription));
- return;
+ return 0;
}
else
{
@@ -238,155 +209,74 @@ namespace Duplicati.Server
commandlineOptions["log-level"] = Duplicati.Library.Logging.LogMessageType.Profiling.ToString();
}
#endif
- // Allow override of the environment variables from the commandline
- if (commandlineOptions.ContainsKey("server-datafolder"))
- Environment.SetEnvironmentVariable(DATAFOLDER_ENV_NAME, commandlineOptions["server-datafolder"]);
- if (commandlineOptions.ContainsKey("server-encryption-key"))
- Environment.SetEnvironmentVariable(DB_KEY_ENV_NAME, commandlineOptions["server-encryption-key"]);
-
- //Set the %DUPLICATI_HOME% env variable, if it is not already set
- if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable(DATAFOLDER_ENV_NAME)))
- {
-#if DEBUG
- //debug mode uses a lock file located in the app folder
- Environment.SetEnvironmentVariable(DATAFOLDER_ENV_NAME, StartupPath);
-#else
- bool portableMode = commandlineOptions.ContainsKey("portable-mode") ? Library.Utility.Utility.ParseBool(commandlineOptions["portable-mode"], true) : false;
-
- if (portableMode)
- {
- //Portable mode uses a data folder in the application home dir
- Environment.SetEnvironmentVariable(DATAFOLDER_ENV_NAME, System.IO.Path.Combine(StartupPath, "data"));
- }
- else
- {
- //Normal release mode uses the systems "Application Data" folder
- Environment.SetEnvironmentVariable(DATAFOLDER_ENV_NAME, System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Library.AutoUpdater.AutoUpdateSettings.AppName));
- }
-#endif
- }
-
+
try
{
- try
- {
- //This will also create Program.DATAFOLDER if it does not exist
- Instance = new SingleInstance(Duplicati.Library.AutoUpdater.AutoUpdateSettings.AppName, Program.DATAFOLDER);
- }
- catch (Exception ex)
- {
- if (writeConsole)
- {
- Console.WriteLine(Strings.Program.StartupFailure(ex));
- return;
- }
- else
- {
- throw new Exception(Strings.Program.StartupFailure(ex));
- }
- }
-
- if (!Instance.IsFirstInstance)
- {
- if (writeConsole)
- {
- Console.WriteLine(Strings.Program.AnotherInstanceDetected);
- return;
- }
- else
- {
- throw new SingleInstance.MultipleInstanceException(Strings.Program.AnotherInstanceDetected);
- }
- }
-
// Setup the log redirect
Duplicati.Library.Logging.Log.CurrentLog = Program.LogHandler;
if (commandlineOptions.ContainsKey("log-file"))
{
+#if DEBUG
+ // Only delete the --log-file when in DEBUG mode. Otherwise, don't delete and just append logs.
if (System.IO.File.Exists(commandlineOptions["log-file"]))
System.IO.File.Delete(commandlineOptions["log-file"]);
+#endif
var loglevel = Duplicati.Library.Logging.LogMessageType.Error;
if (commandlineOptions.ContainsKey("log-level"))
Enum.TryParse<Duplicati.Library.Logging.LogMessageType>(commandlineOptions["log-level"], true, out loglevel);
- Program.LogHandler.SetServerFile(commandlineOptions["log-file"], loglevel);
+ Program.LogHandler.SetServerFile(commandlineOptions["log-file"], loglevel);
}
- Version sqliteVersion = new Version((string)Duplicati.Library.SQLiteHelper.SQLiteLoader.SQLiteConnectionType.GetProperty("SQLiteVersion").GetValue(null, null));
- if (sqliteVersion < new Version(3, 6, 3))
- {
- if (writeConsole)
- {
- //The official Mono SQLite provider is also broken with less than 3.6.3
- Console.WriteLine(Strings.Program.WrongSQLiteVersion(sqliteVersion, "3.6.3"));
- return;
- }
- else
- {
- throw new Exception(Strings.Program.WrongSQLiteVersion(sqliteVersion, "3.6.3"));
- }
- }
+ DataConnection = GetDatabaseConnection(commandlineOptions);
- //Create the connection instance
- System.Data.IDbConnection con = (System.Data.IDbConnection)Activator.CreateInstance(Duplicati.Library.SQLiteHelper.SQLiteLoader.SQLiteConnectionType);
+ if (!DataConnection.ApplicationSettings.FixedInvalidBackupId)
+ DataConnection.FixInvalidBackupId();
try
{
- DatabasePath = System.IO.Path.Combine(Program.DATAFOLDER, "Duplicati-server.sqlite");
- if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(DatabasePath)))
- System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(DatabasePath));
-
-#if DEBUG
- //Default is to not use encryption for debugging
- Program.UseDatabaseEncryption = commandlineOptions.ContainsKey("unencrypted-database") ? !Library.Utility.Utility.ParseBool(commandlineOptions["unencrypted-database"], true) : false;
-#else
- Program.UseDatabaseEncryption = commandlineOptions.ContainsKey("unencrypted-database") ? !Library.Utility.Utility.ParseBool(commandlineOptions["unencrypted-database"], true) : true;
-#endif
- con.ConnectionString = "Data Source=" + DatabasePath;
-
- //Attempt to open the database, handling any encryption present
- OpenDatabase(con);
-
- Duplicati.Library.SQLiteHelper.DatabaseUpgrader.UpgradeDatabase(con, DatabasePath, typeof(Duplicati.Server.Database.Connection));
+ //This will also create DATAFOLDER if it does not exist
+ Instance = new SingleInstance(Duplicati.Library.AutoUpdater.AutoUpdateSettings.AppName, DataFolder);
}
catch (Exception ex)
{
- //Unwrap the reflection exceptions
- if (ex is System.Reflection.TargetInvocationException && ex.InnerException != null)
- ex = ex.InnerException;
-
if (writeConsole)
{
- Console.WriteLine(Strings.Program.DatabaseOpenError(ex.Message));
- return;
- }
- else
- {
- throw new Exception(Strings.Program.DatabaseOpenError(ex.Message), ex);
+ Console.WriteLine(Strings.Program.StartupFailure(ex));
+ return 200;
}
+
+ throw new Exception(Strings.Program.StartupFailure(ex));
}
- DataConnection = new Duplicati.Server.Database.Connection(con);
+ if (!Instance.IsFirstInstance)
+ {
+ if (writeConsole)
+ {
+ Console.WriteLine(Strings.Program.AnotherInstanceDetected);
+ return 200;
+ }
- if (!DataConnection.ApplicationSettings.FixedInvalidBackupId)
- DataConnection.FixInvalidBackupId();
+ throw new SingleInstance.MultipleInstanceException(Strings.Program.AnotherInstanceDetected);
+ }
StartOrStopUsageReporter();
if (commandlineOptions.ContainsKey("webservice-password"))
Program.DataConnection.ApplicationSettings.SetWebserverPassword(commandlineOptions["webservice-password"]);
+ Program.DataConnection.ApplicationSettings.GenerateWebserverPasswordTrayIcon();
+
ApplicationExitEvent = new System.Threading.ManualResetEvent(false);
Duplicati.Library.AutoUpdater.UpdaterManager.OnError += (Exception obj) =>
{
Program.DataConnection.LogError(null, "Error in updater", obj);
};
-
-
+
UpdatePoller = new UpdatePollThread();
DateTime lastPurge = new DateTime(0);
@@ -433,7 +323,7 @@ namespace Duplicati.Server
try
{
PurgeTempFilesTimer = new System.Threading.Timer(purgeTempFilesCallback, null, TimeSpan.FromHours(1), TimeSpan.FromDays(1));
- }
+ }
catch (ArgumentOutOfRangeException)
{
//Bugfix for older Mono, slightly more resources used to avoid large values in the period field
@@ -457,6 +347,16 @@ namespace Duplicati.Server
Program.Scheduler.NewSchedule += new EventHandler(SignalNewEvent);
Program.WorkThread.OnError += (worker, task, exception) => { Program.DataConnection.LogError(task == null ? null : task.BackupID, "Error in worker", exception); };
+ var lastscheduleid = LastDataUpdateID;
+ Program.StatusEventNotifyer.NewEvent += (sender, e) =>
+ {
+ if (lastscheduleid != LastDataUpdateID)
+ {
+ lastscheduleid = LastDataUpdateID;
+ Program.Scheduler.Reschedule();
+ }
+ };
+
Action<long, Exception> registerTaskResult = (id, ex) => {
lock(Program.MainLock) {
@@ -499,7 +399,10 @@ namespace Duplicati.Server
{
System.Diagnostics.Trace.WriteLine(Strings.Program.SeriousError(mex.ToString()));
if (writeConsole)
+ {
Console.WriteLine(Strings.Program.SeriousError(mex.ToString()));
+ return 100;
+ }
else
throw mex;
}
@@ -507,7 +410,10 @@ namespace Duplicati.Server
{
System.Diagnostics.Trace.WriteLine(Strings.Program.SeriousError(ex.ToString()));
if (writeConsole)
+ {
Console.WriteLine(Strings.Program.SeriousError(ex.ToString()));
+ return 100;
+ }
else
throw new Exception(Strings.Program.SeriousError(ex.ToString()), ex);
}
@@ -526,22 +432,153 @@ namespace Duplicati.Server
if (PurgeTempFilesTimer != null)
PurgeTempFilesTimer.Dispose();
+ Library.UsageReporter.Reporter.ShutDown();
+
if (PingPongThread != null)
try { PingPongThread.Abort(); }
catch { }
if (LogHandler != null)
LogHandler.Dispose();
+ }
+
+ if (UpdatePoller != null && UpdatePoller.IsUpdateRequested)
+ return Library.AutoUpdater.UpdaterManager.MAGIC_EXIT_CODE;
+
+ return 0;
+ }
+
+ public static Database.Connection GetDatabaseConnection(Dictionary<string, string> commandlineOptions)
+ {
+ var dbPassword = Environment.GetEnvironmentVariable(DB_KEY_ENV_NAME);
+
+ //If we are on windows we encrypt the database by default
+ //We do not encrypt on Linux as most distros use a SQLite library without encryption support,
+ //Linux users can use an encrypted home folder, or install a SQLite library with encryption support
+
+ //Note that the password here is a default password and public knowledge
+ //
+ //The purpose of this is to prevent casual read of the database, as well
+ // as protect from harddisk string scans, not to protect from determined
+ // attacks.
+ //
+ //If you desire better security, start Duplicati once with the commandline option
+ // --unencrypted-database to decrypt the database.
+ //Then set the environment variable DUPLICATI_DB_KEY to the desired key,
+ // and run Duplicati again without the --unencrypted-database option
+ // to re-encrypt it with the new key
+ //
+ //If you change the key, please note that you need to supply the same
+ // key when restoring the setup, as the setup being backed up will
+ // be encrypted as well.
+ if (!Library.Utility.Utility.IsClientLinux && string.IsNullOrEmpty(dbPassword))
+ dbPassword = Library.AutoUpdater.AutoUpdateSettings.AppName + "_Key_42";
+
+ // Allow override of the environment variables from the commandline
+ if (commandlineOptions.ContainsKey("server-encryption-key"))
+ dbPassword = commandlineOptions["server-encryption-key"];
+
+ var serverDataFolder = Environment.GetEnvironmentVariable(DATAFOLDER_ENV_NAME);
+ if (commandlineOptions.ContainsKey("server-datafolder"))
+ serverDataFolder = commandlineOptions["server-datafolder"];
+
+ if (string.IsNullOrEmpty(serverDataFolder))
+ {
+#if DEBUG
+ //debug mode uses a lock file located in the app folder
+ DataFolder = StartupPath;
+#else
+ bool portableMode = commandlineOptions.ContainsKey("portable-mode") ? Library.Utility.Utility.ParseBool(commandlineOptions["portable-mode"], true) : false;
+
+ if (portableMode)
+ {
+ //Portable mode uses a data folder in the application home dir
+ DataFolder = System.IO.Path.Combine(StartupPath, "data");
+ System.IO.Directory.SetCurrentDirectory(StartupPath);
+ }
+ else
+ {
+ //Normal release mode uses the systems "(Local) Application Data" folder
+ // %LOCALAPPDATA% on Windows, ~/.config on Linux
+
+ // Special handling for Windows:
+ // - Older versions use %APPDATA%
+ // - but new versions use %LOCALAPPDATA%
+ //
+ // If we find a new version, lets use that
+ // otherwise use the older location
+ //
+
+ serverDataFolder = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Library.AutoUpdater.AutoUpdateSettings.AppName);
+ if (Duplicati.Library.Utility.Utility.IsClientWindows)
+ {
+ var localappdata = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Library.AutoUpdater.AutoUpdateSettings.AppName);
+
+ var prefile = System.IO.Path.Combine(serverDataFolder, "Duplicati-server.sqlite");
+ var curfile = System.IO.Path.Combine(localappdata, "Duplicati-server.sqlite");
+
+ // If the new file exists, we use that
+ // If the new file does not exist, and the old file exists we use the old
+ // Otherwise we use the new location
+ if (System.IO.File.Exists(curfile) || !System.IO.File.Exists(prefile))
+ serverDataFolder = localappdata;
+ }
+
+ DataFolder = serverDataFolder;
+ }
+#endif
+ }
+ else
+ DataFolder = Library.Utility.Utility.AppendDirSeparator(Library.Utility.Utility.ExpandEnvironmentVariables(serverDataFolder).Trim('"'));
+
+ var sqliteVersion = new Version((string)Duplicati.Library.SQLiteHelper.SQLiteLoader.SQLiteConnectionType.GetProperty("SQLiteVersion").GetValue(null, null));
+
+ if (sqliteVersion < new Version(3, 6, 3))
+ {
+ //The official Mono SQLite provider is also broken with less than 3.6.3
+ throw new Exception(Strings.Program.WrongSQLiteVersion(sqliteVersion, "3.6.3"));
+ }
+
+ //Create the connection instance
+ var con = Library.SQLiteHelper.SQLiteLoader.LoadConnection();
+
+ try
+ {
+ DatabasePath = System.IO.Path.Combine(DataFolder, "Duplicati-server.sqlite");
+
+ if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(DatabasePath)))
+ System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(DatabasePath));
+#if DEBUG
+ //Default is to not use encryption for debugging
+ var useDatabaseEncryption = commandlineOptions.ContainsKey("unencrypted-database") && !Library.Utility.Utility.ParseBool(commandlineOptions["unencrypted-database"], true);
+#else
+ var useDatabaseEncryption = !commandlineOptions.ContainsKey("unencrypted-database") || !Library.Utility.Utility.ParseBool(commandlineOptions["unencrypted-database"], true);
+#endif
+ con.ConnectionString = "Data Source=" + DatabasePath;
+ //Attempt to open the database, handling any encryption present
+ OpenDatabase(con, useDatabaseEncryption, dbPassword);
+
+ Duplicati.Library.SQLiteHelper.DatabaseUpgrader.UpgradeDatabase(con, DatabasePath, typeof(Database.Connection));
+ }
+ catch (Exception ex)
+ {
+ //Unwrap the reflection exceptions
+ if (ex is System.Reflection.TargetInvocationException && ex.InnerException != null)
+ ex = ex.InnerException;
+
+ throw new Exception(Strings.Program.DatabaseOpenError(ex.Message));
}
+
+ return new Database.Connection(con);
}
public static void StartOrStopUsageReporter()
{
var disableUsageReporter =
- string.Equals(DataConnection.ApplicationSettings.UsageReporterLevel, "none", StringComparison.InvariantCultureIgnoreCase)
+ string.Equals(DataConnection.ApplicationSettings.UsageReporterLevel, "none", StringComparison.OrdinalIgnoreCase)
||
- string.Equals(DataConnection.ApplicationSettings.UsageReporterLevel, "disabled", StringComparison.InvariantCultureIgnoreCase);
+ string.Equals(DataConnection.ApplicationSettings.UsageReporterLevel, "disabled", StringComparison.OrdinalIgnoreCase);
Library.UsageReporter.ReportType reportLevel;
if (!Enum.TryParse<Library.UsageReporter.ReportType>(DataConnection.ApplicationSettings.UsageReporterLevel, true, out reportLevel))
@@ -550,6 +587,16 @@ namespace Duplicati.Server
Library.UsageReporter.Reporter.SetReportLevel(reportLevel, disableUsageReporter);
}
+ public static void UpdateThrottleSpeeds()
+ {
+ if (Program.WorkThread == null)
+ return;
+
+ var cur = Program.WorkThread.CurrentTask;
+ if (cur != null)
+ cur.UpdateThrottleSpeed();
+ }
+
private static void SignalNewEvent(object sender, EventArgs e)
{
StatusEventNotifyer.SignalNewEvent();
@@ -608,15 +655,14 @@ namespace Duplicati.Server
/// Helper method with logic to handle opening a database in possibly encrypted format
/// </summary>
/// <param name="con">The SQLite connection object</param>
- internal static void OpenDatabase(System.Data.IDbConnection con)
+ /// <param name="useDatabaseEncryption">Specify if database is encrypted</param>
+ /// <param name="password">Encryption password</param>
+ public static void OpenDatabase(System.Data.IDbConnection con, bool useDatabaseEncryption, string password)
{
- bool noEncryption = !Program.UseDatabaseEncryption;
- string password = Environment.GetEnvironmentVariable(DB_KEY_ENV_NAME);
-
System.Reflection.MethodInfo setPwdMethod = con.GetType().GetMethod("SetPassword", new Type[] { typeof(string) });
string attemptedPassword;
- if (noEncryption || string.IsNullOrEmpty(password))
+ if (!useDatabaseEncryption || string.IsNullOrEmpty(password))
attemptedPassword = null; //No encryption specified, attempt to open without
else
attemptedPassword = password; //Encryption specified, attempt to open with
@@ -645,13 +691,11 @@ namespace Duplicati.Server
throw;
//Open failed, now try the reverse
- if (attemptedPassword == null)
- attemptedPassword = password;
- else
- attemptedPassword = null;
+ attemptedPassword = attemptedPassword == null ? password : null;
con.Close();
- setPwdMethod.Invoke(con, new object[] { attemptedPassword });
+ if (setPwdMethod != null)
+ setPwdMethod.Invoke(con, new object[] { attemptedPassword });
con.Open();
// Do a dummy query to make sure we have a working db
@@ -673,7 +717,7 @@ namespace Duplicati.Server
//The open method succeeded with the non-default method, now change the password
System.Reflection.MethodInfo changePwdMethod = con.GetType().GetMethod("ChangePassword", new Type[] { typeof(string) });
- changePwdMethod.Invoke(con, new object[] { noEncryption ? null : password });
+ changePwdMethod.Invoke(con, new object[] { useDatabaseEncryption ? password : null });
}
}
@@ -721,8 +765,8 @@ namespace Duplicati.Server
new Duplicati.Library.Interface.CommandLineArgument("log-level", Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Enumeration, Strings.Program.LoglevelCommandDescription, Strings.Program.LoglevelCommandDescription, "Warning", null, Enum.GetNames(typeof(Duplicati.Library.Logging.LogMessageType))),
new Duplicati.Library.Interface.CommandLineArgument(Duplicati.Server.WebServer.Server.OPTION_WEBROOT, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Path, Strings.Program.WebserverWebrootDescription, Strings.Program.WebserverWebrootDescription, Duplicati.Server.WebServer.Server.DEFAULT_OPTION_WEBROOT),
new Duplicati.Library.Interface.CommandLineArgument(Duplicati.Server.WebServer.Server.OPTION_PORT, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.String, Strings.Program.WebserverPortDescription, Strings.Program.WebserverPortDescription, Duplicati.Server.WebServer.Server.DEFAULT_OPTION_PORT.ToString()),
- new Duplicati.Library.Interface.CommandLineArgument(Duplicati.Server.WebServer.Server.OPTION_SSLCERTIFICATEFILE, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.String, Strings.Program.WebserverPortDescription, Strings.Program.WebserverPortDescription, Duplicati.Server.WebServer.Server.OPTION_SSLCERTIFICATEFILE.ToString()),
- new Duplicati.Library.Interface.CommandLineArgument(Duplicati.Server.WebServer.Server.OPTION_SSLCERTIFICATEFILEPASSWORD, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.String, Strings.Program.WebserverPortDescription, Strings.Program.WebserverPortDescription, Duplicati.Server.WebServer.Server.OPTION_SSLCERTIFICATEFILEPASSWORD.ToString()),
+ new Duplicati.Library.Interface.CommandLineArgument(Duplicati.Server.WebServer.Server.OPTION_SSLCERTIFICATEFILE, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.String, Strings.Program.WebserverCertificateFileDescription, Strings.Program.WebserverCertificateFileDescription, Duplicati.Server.WebServer.Server.OPTION_SSLCERTIFICATEFILE.ToString()),
+ new Duplicati.Library.Interface.CommandLineArgument(Duplicati.Server.WebServer.Server.OPTION_SSLCERTIFICATEFILEPASSWORD, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.String, Strings.Program.WebserverCertificatePasswordDescription, Strings.Program.WebserverCertificatePasswordDescription, Duplicati.Server.WebServer.Server.OPTION_SSLCERTIFICATEFILEPASSWORD.ToString()),
new Duplicati.Library.Interface.CommandLineArgument(Duplicati.Server.WebServer.Server.OPTION_INTERFACE, Duplicati.Library.Interface.CommandLineArgument.ArgumentType.String, Strings.Program.WebserverInterfaceDescription, Strings.Program.WebserverInterfaceDescription, Duplicati.Server.WebServer.Server.DEFAULT_OPTION_INTERFACE),
new Duplicati.Library.Interface.CommandLineArgument("webservice-password", Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Password, Strings.Program.WebserverPasswordDescription, Strings.Program.WebserverPasswordDescription),
new Duplicati.Library.Interface.CommandLineArgument("ping-pong-keepalive", Duplicati.Library.Interface.CommandLineArgument.ArgumentType.Boolean, Strings.Program.PingpongkeepaliveShort, Strings.Program.PingpongkeepaliveLong),
diff --git a/Duplicati/Server/Runner.cs b/Duplicati/Server/Runner.cs
index 363644c3f..fd09be390 100644
--- a/Duplicati/Server/Runner.cs
+++ b/Duplicati/Server/Runner.cs
@@ -33,6 +33,8 @@ namespace Duplicati.Server
void Abort();
void Pause();
void Resume();
+ void UpdateThrottleSpeed();
+ void SetController(Duplicati.Library.Main.Controller controller);
}
private class RunnerData : IRunnerData
@@ -48,7 +50,12 @@ namespace Duplicati.Server
public long TaskID { get { return m_taskID; } }
internal Duplicati.Library.Main.Controller Controller { get; set; }
-
+
+ public void SetController(Duplicati.Library.Main.Controller controller)
+ {
+ Controller = controller;
+ }
+
public void Stop()
{
var c = Controller;
@@ -76,7 +83,49 @@ namespace Duplicati.Server
if (c != null)
c.Resume();
}
-
+
+ public long OriginalUploadSpeed { get; set; }
+ public long OriginalDownloadSpeed { get; set; }
+
+ public void UpdateThrottleSpeed()
+ {
+ var controller = this.Controller;
+ if (controller == null)
+ return;
+
+ var job_upload_throttle = this.OriginalUploadSpeed <= 0 ? long.MaxValue : this.OriginalUploadSpeed;
+ var job_download_throttle = this.OriginalDownloadSpeed <= 0 ? long.MaxValue : this.OriginalDownloadSpeed;
+
+ var server_upload_throttle = long.MaxValue;
+ var server_download_throttle = long.MaxValue;
+
+ try
+ {
+ if (!string.IsNullOrWhiteSpace(Program.DataConnection.ApplicationSettings.UploadSpeedLimit))
+ server_upload_throttle = Duplicati.Library.Utility.Sizeparser.ParseSize(Program.DataConnection.ApplicationSettings.UploadSpeedLimit, "kb");
+ }
+ catch { }
+
+ try
+ {
+ if (!string.IsNullOrWhiteSpace(Program.DataConnection.ApplicationSettings.DownloadSpeedLimit))
+ server_download_throttle = Duplicati.Library.Utility.Sizeparser.ParseSize(Program.DataConnection.ApplicationSettings.DownloadSpeedLimit, "kb");
+ }
+ catch { }
+
+ var upload_throttle = Math.Min(job_upload_throttle, server_upload_throttle);
+ var download_throttle = Math.Min(job_download_throttle, server_download_throttle);
+
+ if (upload_throttle <= 0 || upload_throttle == long.MaxValue)
+ upload_throttle = 0;
+
+ if (download_throttle <= 0 || download_throttle == long.MaxValue)
+ download_throttle = 0;
+
+ controller.MaxUploadSpeed = upload_throttle;
+ controller.MaxDownloadSpeed = download_throttle;
+ }
+
private readonly long m_taskID;
public RunnerData()
@@ -84,6 +133,26 @@ namespace Duplicati.Server
m_taskID = System.Threading.Interlocked.Increment(ref RunnerTaskID);
}
}
+
+ private class CustomRunnerTask : RunnerData
+ {
+ public readonly Action<Library.Main.IMessageSink> Run;
+
+ public CustomRunnerTask(Action<Library.Main.IMessageSink> runner)
+ : base()
+ {
+ if (runner == null)
+ throw new ArgumentNullException("runner");
+ Run = runner;
+ Operation = DuplicatiOperation.CustomRunner;
+ Backup = new Database.Backup();
+ }
+ }
+
+ public static IRunnerData CreateCustomTask(Action<Library.Main.IMessageSink> runner)
+ {
+ return new CustomRunnerTask(runner);
+ }
public static IRunnerData CreateTask(Duplicati.Server.Serialization.DuplicatiOperation operation, Duplicati.Server.Serialization.Interface.IBackup backup, IDictionary<string, string> extraOptions = null, string[] filterStrings = null)
{
@@ -145,6 +214,7 @@ namespace Duplicati.Server
internal long m_backendFileSize;
internal long m_backendFileProgress;
internal long m_backendSpeed;
+ internal bool m_backendIsBlocking;
internal string m_currentFilename;
internal long m_currentFilesize;
@@ -177,6 +247,7 @@ namespace Duplicati.Server
public long BackendFileSize { get { return m_backendFileSize; } }
public long BackendFileProgress { get { return m_backendFileProgress; } }
public long BackendSpeed { get { return m_backendSpeed; } }
+ public bool BackendIsBlocking { get { return m_backendIsBlocking; } }
public string CurrentFilename { get { return m_currentFilename; } }
public long CurrentFilesize { get { return m_currentFilesize; } }
public long CurrentFileoffset { get { return m_currentFileoffset; } }
@@ -205,7 +276,7 @@ namespace Duplicati.Server
lock(m_lock)
{
if (m_backendProgress != null)
- m_backendProgress.Update(out m_state.m_backendAction, out m_state.m_backendPath, out m_state.m_backendFileSize, out m_state.m_backendFileProgress, out m_state.m_backendSpeed);
+ m_backendProgress.Update(out m_state.m_backendAction, out m_state.m_backendPath, out m_state.m_backendFileSize, out m_state.m_backendFileProgress, out m_state.m_backendSpeed, out m_state.m_backendIsBlocking);
if (m_operationProgress != null)
{
m_operationProgress.UpdateFile(out m_state.m_currentFilename, out m_state.m_currentFilesize, out m_state.m_currentFileoffset);
@@ -300,8 +371,20 @@ namespace Duplicati.Server
)
);
- Func<string, string> appendBackslash = x => x.EndsWith("\\") ? x + "\\" : x;
- exe = "\"" + appendBackslash(exe) + "\"";
+ Func<string, string> commandLineEscapeValue = x =>
+ {
+ if (string.IsNullOrWhiteSpace(x))
+ return x;
+
+ if (x.EndsWith("\\", StringComparison.Ordinal))
+ x += "\\";
+
+ x = x.Replace("\"", Library.Utility.Utility.IsClientWindows ? "\"\"" : "\\\"");
+
+ return "\"" + x + "\"";
+ };
+
+ exe = commandLineEscapeValue(exe);
if (Library.Utility.Utility.IsMono)
exe = "mono " + exe;
@@ -309,25 +392,83 @@ namespace Duplicati.Server
cmd.Append(exe);
cmd.Append(" backup");
- cmd.AppendFormat(" \"{0}\"", appendBackslash(backup.TargetURL));
- cmd.Append(" \"" + string.Join("\" \"", sources.Select(x => appendBackslash(x))) + "\"");
+ cmd.Append(" ");
+ cmd.Append(commandLineEscapeValue(backup.TargetURL));
+ cmd.Append(" ");
+ cmd.Append(string.Join(" ", sources.Select(x => commandLineEscapeValue(x))));
foreach(var opt in options)
- cmd.AppendFormat(" --{0}={1}", opt.Key, string.IsNullOrWhiteSpace(opt.Value) ? "" : "\"" + appendBackslash(opt.Value) + "\"");
+ cmd.AppendFormat(" --{0}={1}", opt.Key, commandLineEscapeValue(opt.Value));
if (cf != null)
foreach(var f in cf)
- cmd.AppendFormat(" --{0}=\"{1}\"", f.Include ? "include" : "exclude", appendBackslash(f.Expression));
+ cmd.AppendFormat(" --{0}={1}", f.Include ? "include" : "exclude", commandLineEscapeValue(f.Expression));
if (bf != null)
foreach(var f in bf)
- cmd.AppendFormat(" --{0}=\"{1}\"", f.Include ? "include" : "exclude", appendBackslash(f.Expression));
+ cmd.AppendFormat(" --{0}={1}", f.Include ? "include" : "exclude", commandLineEscapeValue(f.Expression));
return cmd.ToString();
}
+
+ public static string[] GetCommandLineParts(IRunnerData data)
+ {
+ var backup = data.Backup;
+
+ var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation));
+ if (data.ExtraOptions != null)
+ foreach (var k in data.ExtraOptions)
+ options[k.Key] = k.Value;
+
+ var cf = Program.DataConnection.Filters;
+ var bf = backup.Filters;
+
+ var sources =
+ (from n in backup.Sources
+ let p = SpecialFolders.ExpandEnvironmentVariables(n)
+ where !string.IsNullOrWhiteSpace(p)
+ select p).ToArray();
+
+ var parts = new List<string>();
+
+ parts.Add(backup.TargetURL);
+ parts.AddRange(sources);
+
+ foreach (var opt in options)
+ parts.Add(string.Format("--{0}={1}", opt.Key, opt.Value));
+
+ if (cf != null)
+ foreach (var f in cf)
+ parts.Add(string.Format("--{0}={1}", f.Include ? "include" : "exclude", f.Expression));
+
+ if (bf != null)
+ foreach (var f in bf)
+ parts.Add(string.Format("--{0}={1}", f.Include ? "include" : "exclude", f.Expression));
+
+ return parts.ToArray();
+ }
public static Duplicati.Library.Interface.IBasicResults Run(IRunnerData data, bool fromQueue)
{
+ if (data is CustomRunnerTask)
+ {
+ try
+ {
+ var sink = new MessageSink(data.TaskID, null);
+ Program.GenerateProgressState = () => sink.Copy();
+ Program.StatusEventNotifyer.SignalNewEvent();
+
+ ((CustomRunnerTask)data).Run(sink);
+ }
+ catch(Exception ex)
+ {
+ Program.DataConnection.LogError(string.Empty, "Failed while executing custom task", ex);
+ }
+
+ return null;
+ }
+
+
var backup = data.Backup;
Duplicati.Library.Utility.TempFolder tempfolder = null;
@@ -336,40 +477,22 @@ namespace Duplicati.Server
try
{
- var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation));
var sink = new MessageSink(data.TaskID, backup.ID);
if (fromQueue)
{
Program.GenerateProgressState = () => sink.Copy();
Program.StatusEventNotifyer.SignalNewEvent();
}
-
+
+ var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation));
if (data.ExtraOptions != null)
foreach(var k in data.ExtraOptions)
- options[k.Key] = k.Value;
-
- // Log file is using the internal log-handler
- // so we can display output in the GUI as well as log
- // into the given file
- if (options.ContainsKey("log-file"))
- {
- var file = options["log-file"];
-
- string o;
- Library.Logging.LogMessageType level;
- options.TryGetValue("log-level", out o);
- Enum.TryParse<Library.Logging.LogMessageType>(o, true, out level);
-
- options.Remove("log-file");
- options.Remove("log-level");
-
- Program.LogHandler.SetOperationFile(file, level);
- }
+ options[k.Key] = k.Value;
// Pack in the system or task config for easy restore
if (data.Operation == DuplicatiOperation.Backup && options.ContainsKey("store-task-config"))
{
- var all_tasks = string.Equals(options["store-task-config"], "all", StringComparison.InvariantCultureIgnoreCase) || string.Equals(options["store-task-config"], "*", StringComparison.InvariantCultureIgnoreCase);
+ var all_tasks = string.Equals(options["store-task-config"], "all", StringComparison.OrdinalIgnoreCase) || string.Equals(options["store-task-config"], "*", StringComparison.OrdinalIgnoreCase);
var this_task = Duplicati.Library.Utility.Utility.ParseBool(options["store-task-config"], false);
options.Remove("store-task-config");
@@ -410,8 +533,23 @@ namespace Duplicati.Server
using(tempfolder)
using(var controller = new Duplicati.Library.Main.Controller(backup.TargetURL, options, sink))
{
+ try
+ {
+ if (options.ContainsKey("throttle-upload"))
+ ((RunnerData)data).OriginalUploadSpeed = Duplicati.Library.Utility.Sizeparser.ParseSize(options["throttle-upload"], "kb");
+ }
+ catch { }
+
+ try
+ {
+ if (options.ContainsKey("throttle-download"))
+ ((RunnerData)data).OriginalDownloadSpeed = Duplicati.Library.Utility.Sizeparser.ParseSize(options["throttle-download"], "kb");
+ }
+ catch { }
+
((RunnerData)data).Controller = controller;
-
+ data.UpdateThrottleSpeed();
+
switch (data.Operation)
{
case DuplicatiOperation.Backup:
@@ -494,6 +632,37 @@ namespace Duplicati.Server
return r;
}
}
+
+ case DuplicatiOperation.ListRemote:
+ {
+ var r = controller.ListRemote();
+ UpdateMetadata(backup, r);
+ return r;
+ }
+
+ case DuplicatiOperation.Delete:
+ {
+ if (Library.Utility.Utility.ParseBoolOption(data.ExtraOptions, "delete-remote-files"))
+ controller.DeleteAllRemoteFiles();
+
+ if (Library.Utility.Utility.ParseBoolOption(data.ExtraOptions, "delete-local-db"))
+ {
+ string dbpath;
+ options.TryGetValue("db-path", out dbpath);
+
+ if (!string.IsNullOrWhiteSpace(dbpath) && System.IO.File.Exists(dbpath))
+ System.IO.File.Delete(dbpath);
+ }
+ Program.DataConnection.DeleteBackup(backup);
+ Program.Scheduler.Reschedule();
+ return null;
+ }
+ case DuplicatiOperation.Vacuum:
+ {
+ var r = controller.Vacuum();
+ UpdateMetadata(backup, r);
+ return r;
+ }
default:
//TODO: Log this
return null;
@@ -514,7 +683,6 @@ namespace Duplicati.Server
finally
{
((RunnerData)data).Controller = null;
- Program.LogHandler.RemoveOperationFile();
}
}
@@ -572,7 +740,14 @@ namespace Duplicati.Server
var r = (Duplicati.Library.Interface.IParsedBackendStatistics)o;
UpdateMetadata(backup, r);
}
-
+
+ if (o is Duplicati.Library.Interface.IBackendStatsticsReporter)
+ {
+ var r = (Duplicati.Library.Interface.IBackendStatsticsReporter)o;
+ if (r.BackendStatistics is Duplicati.Library.Interface.IParsedBackendStatistics)
+ UpdateMetadata(backup, (Duplicati.Library.Interface.IParsedBackendStatistics)r.BackendStatistics);
+ }
+
if (o is Duplicati.Library.Interface.IBackupResults)
{
var r = (Duplicati.Library.Interface.IBackupResults)o;
@@ -581,24 +756,22 @@ namespace Duplicati.Server
backup.Metadata["SourceSizeString"] = Duplicati.Library.Utility.Utility.FormatSizeString(r.SizeOfExaminedFiles);
backup.Metadata["LastBackupStarted"] = Library.Utility.Utility.SerializeDateTime(((Duplicati.Library.Interface.IBasicResults)o).BeginTime.ToUniversalTime());
backup.Metadata["LastBackupFinished"] = Library.Utility.Utility.SerializeDateTime(((Duplicati.Library.Interface.IBasicResults)o).EndTime.ToUniversalTime());
-
- if (r.BackendStatistics is Duplicati.Library.Interface.IParsedBackendStatistics)
- UpdateMetadata(backup, (Duplicati.Library.Interface.IParsedBackendStatistics)r.BackendStatistics);
- if (r.FilesWithError > 0 || r.Warnings.Any())
+ if (r.FilesWithError > 0 || r.Warnings.Any() || r.Errors.Any())
{
Program.DataConnection.RegisterNotification(
- NotificationType.Error,
- backup.IsTemporary ?
+ NotificationType.Error,
+ backup.IsTemporary ?
"Warning" : string.Format("Warning while running {0}", backup.Name),
- r.FilesWithError > 0 ?
+ r.FilesWithError > 0 ?
string.Format("Errors affected {0} file(s) ", r.FilesWithError) :
string.Format("Got {0} warning(s) ", r.Warnings.Count())
,
null,
backup.ID,
"backup:show-log",
- (n, a) => {
+ (n, a) =>
+ {
var existing = (a.Where(x => x.BackupID == backup.ID)).FirstOrDefault();
if (existing == null)
return n;
@@ -611,6 +784,36 @@ namespace Duplicati.Server
);
}
}
+ else if (o is Duplicati.Library.Interface.IBasicResults)
+ {
+ var r = (Duplicati.Library.Interface.IBasicResults)o;
+ if (r.ParsedResult != Library.Interface.ParsedResultType.Success)
+ {
+ var type = r.ParsedResult == Library.Interface.ParsedResultType.Warning
+ ? NotificationType.Warning
+ : NotificationType.Error;
+
+ var title = r.ParsedResult == Library.Interface.ParsedResultType.Warning
+ ? (backup.IsTemporary ?
+ "Warning" : string.Format("Warning while running {0}", backup.Name))
+ : (backup.IsTemporary ?
+ "Error" : string.Format("Error while running {0}", backup.Name));
+
+ var message = r.ParsedResult == Library.Interface.ParsedResultType.Warning
+ ? string.Format("Got {0} warning(s) ", r.Warnings.Count())
+ : string.Format("Got {0} error(s) ", r.Errors.Count());
+
+ Program.DataConnection.RegisterNotification(
+ type,
+ title,
+ message,
+ null,
+ backup.ID,
+ "backup:show-log",
+ (n, a) => n
+ );
+ }
+ }
if (!backup.IsTemporary)
Program.DataConnection.SetMetadata(backup.Metadata, long.Parse(backup.ID), null);
@@ -633,12 +836,12 @@ namespace Duplicati.Server
if (options.TryGetValue("enable-module", out enabledModules))
{
var emods = (enabledModules ?? "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- options["enable-module"] = string.Join(",", emods.Where(x => module.Equals(x, StringComparison.InvariantCultureIgnoreCase)));
+ options["enable-module"] = string.Join(",", emods.Where(x => module.Equals(x, StringComparison.OrdinalIgnoreCase)));
}
options.TryGetValue("disable-module", out disabledModules);
var mods = (disabledModules ?? "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- options["disable-module"] = string.Join(",", mods.Union(new string[] { module }).Distinct(StringComparer.InvariantCultureIgnoreCase));
+ options["disable-module"] = string.Join(",", mods.Union(new string[] { module }).Distinct(StringComparer.OrdinalIgnoreCase));
}
private static Dictionary<string, string> ApplyOptions(Duplicati.Server.Serialization.Interface.IBackup backup, DuplicatiOperation mode, Dictionary<string, string> options)
@@ -705,6 +908,8 @@ namespace Duplicati.Server
select (Duplicati.Library.Utility.IFilter)(new Duplicati.Library.Utility.FilterExpression(exp, n.Include)))
.Aggregate((a, b) => Duplicati.Library.Utility.FilterExpression.Combine(a, b));
}
+
+
}
}
diff --git a/Duplicati/Server/Scheduler.cs b/Duplicati/Server/Scheduler.cs
index 9871ff34f..5db794ba7 100644
--- a/Duplicati/Server/Scheduler.cs
+++ b/Duplicati/Server/Scheduler.cs
@@ -217,10 +217,9 @@ namespace Duplicati.Server
/// </summary>
private void Runner()
{
- var scheduled = new Dictionary<long, DateTime>();
+ var scheduled = new Dictionary<long, KeyValuePair<long, DateTime>>();
while (!m_terminate)
{
-
//TODO: As this is executed repeatedly we should cache it
// to avoid frequent db lookups
@@ -230,13 +229,21 @@ namespace Duplicati.Server
{
if (!string.IsNullOrEmpty(sc.Repeat))
{
- DateTime start;
+ KeyValuePair<long, DateTime> startkey;
+
DateTime last = new DateTime(0, DateTimeKind.Utc);
- if (!scheduled.TryGetValue(sc.ID, out start))
+ DateTime start;
+ var scticks = sc.Time.Ticks;
+
+ if (!scheduled.TryGetValue(sc.ID, out startkey) || startkey.Key != scticks)
{
- start = new DateTime(sc.Time.Ticks, DateTimeKind.Utc);
+ start = new DateTime(scticks, DateTimeKind.Utc);
last = sc.LastRun;
}
+ else
+ {
+ start = startkey.Value;
+ }
try
{
@@ -274,7 +281,7 @@ namespace Duplicati.Server
//Caluclate next time, by finding the first entry later than now
try
{
- start = GetNextValidTime(start, new DateTime(Math.Max(DateTime.Now.AddSeconds(1).Ticks, start.AddSeconds(1).Ticks), DateTimeKind.Utc), sc.Repeat, sc.AllowedDays);
+ start = GetNextValidTime(start, new DateTime(Math.Max(DateTime.UtcNow.AddSeconds(1).Ticks, start.AddSeconds(1).Ticks), DateTimeKind.Utc), sc.Repeat, sc.AllowedDays);
}
catch(Exception ex)
{
@@ -297,7 +304,7 @@ namespace Duplicati.Server
}
}
- scheduled[sc.ID] = start;
+ scheduled[sc.ID] = new KeyValuePair<long,DateTime>(scticks, start);
}
}
@@ -306,8 +313,8 @@ namespace Duplicati.Server
lock(m_lock)
m_schedule = (from n in scheduled
where existing.ContainsKey(n.Key)
- orderby n.Value
- select new KeyValuePair<DateTime, ISchedule>(n.Value, existing[n.Key])).ToArray();
+ orderby n.Value.Value
+ select new KeyValuePair<DateTime, ISchedule>(n.Value.Value, existing[n.Key])).ToArray();
// Remove unused entries
foreach(var c in (from n in scheduled where !existing.ContainsKey(n.Key) select n.Key).ToArray())
@@ -323,7 +330,7 @@ namespace Duplicati.Server
if (scheduled.Count > 0)
{
//When is the next run scheduled?
- TimeSpan nextrun = scheduled.Min((x) => x.Value) - DateTime.UtcNow;
+ TimeSpan nextrun = scheduled.Values.Min((x) => x.Value) - DateTime.UtcNow;
if (nextrun.TotalMilliseconds < 0)
continue;
diff --git a/Duplicati/Server/Serializable/ServerSettings.cs b/Duplicati/Server/Serializable/ServerSettings.cs
index 184222111..7571ce820 100644
--- a/Duplicati/Server/Serializable/ServerSettings.cs
+++ b/Duplicati/Server/Serializable/ServerSettings.cs
@@ -202,7 +202,22 @@ namespace Duplicati.Server.Serializable
select new DynamicModule(n))
.ToArray();
}
- }
+ }
+
+ /// <summary>
+ /// The server modules known by the server
+ /// </summary>
+ public static object[] ServerModules
+ {
+ get
+ {
+ return
+ (from n in Library.DynamicLoader.GenericLoader.Modules
+ where n is Library.Interface.IGenericServerModule
+ select n)
+ .ToArray();
+ }
+ }
/// <summary>
/// The filters that are applied to all backups
diff --git a/Duplicati/Server/Serializable/ServerStatus.cs b/Duplicati/Server/Serializable/ServerStatus.cs
index 3ea0dfc17..1804dc87f 100644
--- a/Duplicati/Server/Serializable/ServerStatus.cs
+++ b/Duplicati/Server/Serializable/ServerStatus.cs
@@ -65,10 +65,10 @@ namespace Duplicati.Server.Serializable
get
{
var t = Program.WorkThread.CurrentTask;
- if (t == null || t.Backup == null)
+ if (t == null)
return null;
else
- return new Tuple<long, string>(t.TaskID, t.Backup.ID);
+ return new Tuple<long, string>(t.TaskID, t.Backup == null ? null : t.Backup.ID);
}
}
diff --git a/Duplicati/Server/SpecialFolders.cs b/Duplicati/Server/SpecialFolders.cs
index 802897e79..fc7b31c9f 100644
--- a/Duplicati/Server/SpecialFolders.cs
+++ b/Duplicati/Server/SpecialFolders.cs
@@ -24,13 +24,14 @@ namespace Duplicati.Server
public static class SpecialFolders
{
public static readonly Serializable.TreeNode[] Nodes;
- private static readonly Dictionary<string, string> PathMap = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
- private static readonly Dictionary<string, string> DisplayMap = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
+ private static readonly Dictionary<string, string> PathMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+ private static readonly Dictionary<string, string> DisplayMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
public static string ExpandEnvironmentVariables(string path)
{
foreach(var n in Nodes)
- path = path.Replace(n.id, n.resolvedpath);
+ if (path.StartsWith(n.id))
+ path = path.Replace(n.id, n.resolvedpath);
return Library.Utility.Utility.ExpandEnvironmentVariables(path);
}
@@ -84,18 +85,22 @@ namespace Duplicati.Server
{
try
{
- if (System.IO.Path.IsPathRooted(folder) && System.IO.Directory.Exists(folder))
+ if (!string.IsNullOrWhiteSpace(folder) && System.IO.Path.IsPathRooted(folder) && System.IO.Directory.Exists(folder))
{
- lst.Add(new Serializable.TreeNode() {
- id = id,
- text = display,
- leaf = false,
- iconCls = "x-tree-icon-special",
- resolvedpath = folder
- });
-
- PathMap[id] = folder;
- DisplayMap[id] = display;
+ if (!PathMap.ContainsKey(id))
+ {
+ lst.Add(new Serializable.TreeNode()
+ {
+ id = id,
+ text = display,
+ leaf = false,
+ iconCls = "x-tree-icon-special",
+ resolvedpath = folder
+ });
+
+ PathMap[id] = folder;
+ DisplayMap[id] = display;
+ }
}
}
catch
@@ -107,7 +112,7 @@ namespace Duplicati.Server
{
var lst = new List<Serializable.TreeNode>();
- if (!Library.Utility.Utility.IsClientLinux)
+ if (Library.Utility.Utility.IsClientWindows)
{
TryAdd(lst, Environment.SpecialFolder.MyDocuments, "%MY_DOCUMENTS%", "My Documents");
TryAdd(lst, Environment.SpecialFolder.MyMusic, "%MY_MUSIC%", "My Music");
@@ -116,6 +121,16 @@ namespace Duplicati.Server
TryAdd(lst, Environment.SpecialFolder.DesktopDirectory, "%DESKTOP%", "Desktop");
TryAdd(lst, Environment.SpecialFolder.ApplicationData, "%APPDATA%", "Application Data");
TryAdd(lst, Environment.SpecialFolder.UserProfile, "%HOME%", "Home");
+
+ try
+ {
+ // In case the UserProfile member points to junk
+ TryAdd(lst, System.IO.Path.Combine(Environment.GetEnvironmentVariable("HOMEDRIVE"), Environment.GetEnvironmentVariable("HOMEPATH")), "%HOME%", "Home");
+ }
+ catch
+ {
+ }
+
}
else
{
@@ -123,6 +138,7 @@ namespace Duplicati.Server
TryAdd(lst, Environment.SpecialFolder.MyMusic, "%MY_MUSIC%", "My Music");
TryAdd(lst, Environment.SpecialFolder.MyPictures, "%MY_PICTURES%", "My Pictures");
TryAdd(lst, Environment.SpecialFolder.DesktopDirectory, "%DESKTOP%", "Desktop");
+ TryAdd(lst, Environment.GetEnvironmentVariable("HOME"), "%HOME%", "Home");
TryAdd(lst, Environment.SpecialFolder.Personal, "%HOME%", "Home");
}
diff --git a/Duplicati/Server/Strings.cs b/Duplicati/Server/Strings.cs
index def138fdf..355a6d121 100644
--- a/Duplicati/Server/Strings.cs
+++ b/Duplicati/Server/Strings.cs
@@ -15,14 +15,14 @@ Error message: {0}", message); }
public static string LogfileCommandDescription { get { return LC.L(@"Outputs log information to the file given"); } }
public static string LoglevelCommandDescription { get { return LC.L(@"Determines the amount of information written in the log file"); } }
public static string PortablemodeCommandDescription { get { return LC.L(@"Activates portable mode where the database is placed below the program executable"); } }
- public static string SeriousError(string message) { return LC.L(@"A serious error occured in Duplicati: {0}", message); }
+ public static string SeriousError(string message) { return LC.L(@"A serious error occurred in Duplicati: {0}", message); }
public static string StartupFailure(System.Exception error) { return LC.L(@"Unable to start up, perhaps another process is already running?
Error message: {0}", error); }
public static string UnencrypteddatabaseCommandDescription { get { return LC.L(@"Disables database encryption"); } }
public static string WrongSQLiteVersion(System.Version actualversion, string expectedversion) { return LC.L(@"Unsupported version of SQLite detected ({0}), must be {1} or higher", actualversion, expectedversion); }
public static string WebserverWebrootDescription { get { return LC.L(@"The path to the folder where the static files for the webserver is present. The folder must be located beneath the installation folder"); } }
public static string WebserverPortDescription { get { return LC.L(@"The port the webserver listens on. Multiple values may be supplied with a comma in between."); } }
- public static string WebserverCertificateFileDescription { get { return LC.L(@"The certificate and key file in PKCS #12 format the webserver use for SSL."); } }
+ public static string WebserverCertificateFileDescription { get { return LC.L(@"The certificate and key file in PKCS #12 format the webserver use for SSL. Only RSA/DSA keys are supported."); } }
public static string WebserverCertificatePasswordDescription { get { return LC.L(@"The password for decryption of certificate PKCS #12 file."); } }
public static string WebserverInterfaceDescription { get { return LC.L(@"The interface the webserver listens on. The special values ""*"" and ""any"" means any interface. The special value ""loopback"" means the loopback adapter."); } }
public static string WebserverPasswordDescription { get { return LC.L(@"The password required to access the webserver. This option is saved so you do not need to set it on each run. Setting an empty value disables the password."); } }
diff --git a/Duplicati/Server/UpdatePollThread.cs b/Duplicati/Server/UpdatePollThread.cs
index 56d96bd6c..0c741aff5 100644
--- a/Duplicati/Server/UpdatePollThread.cs
+++ b/Duplicati/Server/UpdatePollThread.cs
@@ -35,6 +35,8 @@ namespace Duplicati.Server
private AutoResetEvent m_waitSignal;
private double m_downloadProgress;
+ public bool IsUpdateRequested { get; private set; } = false;
+
public UpdatePollerStates ThreadState { get; private set; }
public double DownloadProgess
{
@@ -81,7 +83,10 @@ namespace Duplicati.Server
public void ActivateUpdate()
{
if (Duplicati.Library.AutoUpdater.UpdaterManager.SetRunUpdate())
+ {
+ IsUpdateRequested = true;
Program.ApplicationExitEvent.Set();
+ }
}
public void Terminate()
@@ -106,6 +111,20 @@ namespace Duplicati.Server
while (!m_terminated)
{
var nextCheck = Program.DataConnection.ApplicationSettings.NextUpdateCheck;
+
+ var maxcheck = TimeSpan.FromDays(7);
+ try
+ {
+ maxcheck = Library.Utility.Timeparser.ParseTimeSpan(Program.DataConnection.ApplicationSettings.UpdateCheckInterval);
+ }
+ catch
+ {
+ }
+
+ // If we have some weirdness, just check now
+ if (nextCheck - DateTime.UtcNow > maxcheck)
+ nextCheck = DateTime.UtcNow - TimeSpan.FromSeconds(1);
+
if (nextCheck < DateTime.UtcNow || m_forceCheck)
{
lock(m_lock)
@@ -196,8 +215,16 @@ namespace Duplicati.Server
}
var waitTime = nextCheck - DateTime.UtcNow;
+
+ // Guard against spin-loop
if (waitTime.TotalSeconds < 5)
waitTime = TimeSpan.FromSeconds(5);
+
+ // Guard against year-long waits
+ // A re-check does not cause an update check
+ if (waitTime.TotalDays > 1)
+ waitTime = TimeSpan.FromDays(1);
+
m_waitSignal.WaitOne(waitTime, true);
}
}
diff --git a/Duplicati/Server/WebServer/AuthenticationHandler.cs b/Duplicati/Server/WebServer/AuthenticationHandler.cs
index 7f3c0a5ee..bd8339e4d 100644
--- a/Duplicati/Server/WebServer/AuthenticationHandler.cs
+++ b/Duplicati/Server/WebServer/AuthenticationHandler.cs
@@ -32,8 +32,11 @@ namespace Duplicati.Server.WebServer
private const string XSRF_COOKIE_NAME = "xsrf-token";
private const string XSRF_HEADER_NAME = "X-XSRF-Token";
+ private const string TRAYICONPASSWORDSOURCE_HEADER = "X-TrayIcon-PasswordSource";
+
public const string LOGIN_SCRIPT_URI = "/login.cgi";
public const string LOGOUT_SCRIPT_URI = "/logout.cgi";
+ public const string CAPTCHA_IMAGE_URI = RESTHandler.API_URI_PATH + "/captcha/";
private const int XSRF_TIMEOUT_MINUTES = 10;
private const int AUTH_TIMEOUT_MINUTES = 10;
@@ -93,11 +96,11 @@ namespace Duplicati.Server.WebServer
var authform = request.Form["auth-token"] ?? request.Form[Library.Utility.Uri.UrlEncode("auth-token")];
var authquery = request.QueryString["auth-token"] ?? request.QueryString[Library.Utility.Uri.UrlEncode("auth-token")];
- var auth_token = authcookie == null || string.IsNullOrWhiteSpace(authcookie.Value) ? null : authcookie.Value;
- if (authquery != null && !string.IsNullOrWhiteSpace(authquery.Value))
- auth_token = authquery["auth-token"].Value;
- if (authform != null && !string.IsNullOrWhiteSpace(authform.Value))
- auth_token = authform["auth-token"].Value;
+ var auth_token = string.IsNullOrWhiteSpace(authcookie?.Value) ? null : authcookie.Value;
+ if (!string.IsNullOrWhiteSpace(authquery?.Value))
+ auth_token = authquery.Value;
+ if (!string.IsNullOrWhiteSpace(authform?.Value))
+ auth_token = authform.Value;
return auth_token;
}
@@ -150,7 +153,7 @@ namespace Duplicati.Server.WebServer
Tuple<DateTime, string> tmpTuple;
DateTime tmpDateTime;
- if (LOGOUT_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
+ if (LOGOUT_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.OrdinalIgnoreCase))
{
if (!string.IsNullOrWhiteSpace(auth_token))
{
@@ -163,7 +166,7 @@ namespace Duplicati.Server.WebServer
return true;
}
- else if (LOGIN_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
+ else if (LOGIN_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.OrdinalIgnoreCase))
{
// Remove expired nonces
foreach(var k in (from n in m_activeNonces where DateTime.UtcNow > n.Value.Item1 select n.Key))
@@ -178,6 +181,11 @@ namespace Duplicati.Server.WebServer
return true;
}
+ var password = Program.DataConnection.ApplicationSettings.WebserverPassword;
+
+ if (request.Headers[TRAYICONPASSWORDSOURCE_HEADER] == "database")
+ password = Program.DataConnection.ApplicationSettings.WebserverPasswordTrayIconHash;
+
var buf = new byte[32];
var expires = DateTime.UtcNow.AddMinutes(AUTH_TIMEOUT_MINUTES);
m_prng.GetBytes(buf);
@@ -185,7 +193,7 @@ namespace Duplicati.Server.WebServer
var sha256 = System.Security.Cryptography.SHA256.Create();
sha256.TransformBlock(buf, 0, buf.Length, buf, 0);
- buf = Convert.FromBase64String(Program.DataConnection.ApplicationSettings.WebserverPassword);
+ buf = Convert.FromBase64String(password);
sha256.TransformFinalBlock(buf, 0, buf.Length);
var pwd = Convert.ToBase64String(sha256.Hash);
@@ -263,11 +271,13 @@ namespace Duplicati.Server.WebServer
}
var limitedAccess =
- ControlHandler.CONTROL_HANDLER_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase)
- ||
- request.Uri.AbsolutePath.StartsWith(RESTHandler.API_URI_PATH, StringComparison.InvariantCultureIgnoreCase)
+ request.Uri.AbsolutePath.StartsWith(RESTHandler.API_URI_PATH, StringComparison.OrdinalIgnoreCase)
;
+ // Override to allow the CAPTCHA call to go through
+ if (request.Uri.AbsolutePath.StartsWith(CAPTCHA_IMAGE_URI, StringComparison.OrdinalIgnoreCase) && request.Method == "GET")
+ limitedAccess = false;
+
if (limitedAccess)
{
if (xsrf_token != null && m_activexsrf.ContainsKey(xsrf_token))
@@ -313,7 +323,7 @@ namespace Duplicati.Server.WebServer
}
}
- if ("/".Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase) || "/index.html".Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
+ if ("/".Equals(request.Uri.AbsolutePath, StringComparison.OrdinalIgnoreCase) || "/index.html".Equals(request.Uri.AbsolutePath, StringComparison.OrdinalIgnoreCase))
{
response.Redirect("/login.html");
return true;
diff --git a/Duplicati/Server/WebServer/CaptchaUtil.cs b/Duplicati/Server/WebServer/CaptchaUtil.cs
new file mode 100644
index 000000000..a7a56b5db
--- /dev/null
+++ b/Duplicati/Server/WebServer/CaptchaUtil.cs
@@ -0,0 +1,115 @@
+// Copyright (C) 2016, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Linq;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Text;
+
+namespace Duplicati.Server.WebServer
+{
+ /// <summary>
+ /// Helper class for creating Captcha images
+ /// </summary>
+ public static class CaptchaUtil
+ {
+ /// <summary>
+ /// A lookup string with characters to use
+ /// </summary>
+ private static readonly string DEFAULT_CHARS = "ACDEFGHJKLMNPQRTUVWXY34679";
+
+ /// <summary>
+ /// A range of possible brush colors
+ /// </summary>
+ private static readonly Brush[] BRUSH_COLORS =
+ typeof(Brushes)
+ .GetProperties(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)
+ .Where(x => x.PropertyType == typeof(Brush))
+ .Select(x => x.GetValue(null, null) as Brush)
+ .Where(x => x != null)
+ .ToArray();
+
+ /// <summary>
+ /// Creates a random answer.
+ /// </summary>
+ /// <returns>The random answer.</returns>
+ /// <param name="allowedchars">The list of allowed chars, supply a character multiple times to change frequency.</param>
+ /// <param name="minlength">The minimum answer length.</param>
+ /// <param name="maxlength">The maximum answer length.</param>
+ public static string CreateRandomAnswer(string allowedchars = null, int minlength = 10, int maxlength = 12)
+ {
+ allowedchars = allowedchars ?? DEFAULT_CHARS;
+ var rnd = new Random();
+ var len = rnd.Next(Math.Min(minlength, maxlength), Math.Max(minlength, maxlength) + 1);
+ if (len <= 0)
+ throw new ArgumentException($"The values ${minlength} and ${maxlength} gave a final length of {len} and it must be greater than 0");
+
+ return new string(Enumerable.Range(0, len).Select(x => allowedchars[rnd.Next(0, allowedchars.Length)]).ToArray());
+ }
+
+ /// <summary>
+ /// Creates a captcha image.
+ /// </summary>
+ /// <returns>The captcha image.</returns>
+ /// <param name="answer">The captcha solution string.</param>
+ /// <param name="size">The size of the image, omit to get a size based on the string.</param>
+ /// <param name="fontsize">The size of the font used to create the captcha.</param>
+ public static Bitmap CreateCaptcha(string answer, Size size = default(Size), int fontsize = 24)
+ {
+ if (size.Width == 0 || size.Height == 0)
+ size = new Size((answer.Length + 1) * fontsize, fontsize * 2);
+
+ var bmp = new Bitmap(size.Width, size.Height);
+ var rnd = new Random();
+ var stray_x = fontsize / 4;
+ var stray_y = size.Height / 4;
+
+ using (var graphics = Graphics.FromImage(bmp))
+ using (var font1 = new Font("Ariel", fontsize))
+ using (var font2 = new Font("Ariel", fontsize))
+ using (var font3 = new HatchBrush(HatchStyle.Shingle, Color.GhostWhite, Color.DarkBlue))
+ {
+ graphics.Clear(Color.White);
+ graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
+
+ // Apply a some background string to make it hard to do OCR
+ foreach (var color in new[] { Color.Yellow, Color.LightGreen, Color.GreenYellow })
+ using (var brush = new SolidBrush(color))
+ graphics.DrawString(CreateRandomAnswer(minlength: answer.Length, maxlength: answer.Length), font2, brush, rnd.Next(-stray_x, stray_x), rnd.Next(-stray_y, stray_y));
+
+
+ var spacing = (size.Width / fontsize) + rnd.Next(0, stray_x);
+
+ // Create a vertical background lines
+ for (var i = rnd.Next(0, stray_x); i < size.Width; i += spacing)
+ using (var pen = new Pen(BRUSH_COLORS[rnd.Next(0, BRUSH_COLORS.Length)]))
+ graphics.DrawLine(pen, i + rnd.Next(-stray_x, stray_x), rnd.Next(0, stray_y), i + rnd.Next(-stray_x, stray_x), size.Height - rnd.Next(0, stray_y));
+
+ spacing = (size.Height / fontsize) + rnd.Next(0, stray_y);
+ // Create a horizontal background lines
+ for (var i = rnd.Next(0, stray_y); i < size.Height; i += spacing)
+ using (var pen = new Pen(BRUSH_COLORS[rnd.Next(0, BRUSH_COLORS.Length)]))
+ graphics.DrawLine(pen, rnd.Next(0, stray_x), i + rnd.Next(-stray_y, stray_y), size.Width - rnd.Next(0, stray_x), i + rnd.Next(-stray_y, stray_y));
+
+ // Draw the actual answer
+ graphics.DrawString(answer, font1, font3, ((size.Width - (fontsize * answer.Length)) / 2) + rnd.Next(-stray_x, stray_x), ((size.Height - (fontsize * 2)) / 2) + rnd.Next(-stray_y, stray_y));
+
+ return bmp;
+ }
+ }
+ }
+}
diff --git a/Duplicati/Server/WebServer/ControlHandler.cs b/Duplicati/Server/WebServer/ControlHandler.cs
deleted file mode 100644
index 5a0516705..000000000
--- a/Duplicati/Server/WebServer/ControlHandler.cs
+++ /dev/null
@@ -1,488 +0,0 @@
-// Copyright (C) 2015, The Duplicati Team
-
-// http://www.duplicati.com, info@duplicati.com
-//
-// This library is free software; you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as
-// published by the Free Software Foundation; either version 2.1 of the
-// License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-using System;
-using System.Linq;
-using HttpServer;
-using HttpServer.HttpModules;
-using System.Collections.Generic;
-using Duplicati.Server.Serialization;
-using System.IO;
-
-namespace Duplicati.Server.WebServer
-{
- internal partial class ControlHandler : HttpModule
- {
- private delegate void ProcessSub(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter writer);
- private readonly Dictionary<string, ProcessSub> SUPPORTED_METHODS;
-
- public const string CONTROL_HANDLER_URI = "/control.cgi";
-
- public ControlHandler()
- {
- SUPPORTED_METHODS = new Dictionary<string, ProcessSub>(System.StringComparer.InvariantCultureIgnoreCase);
-
- //Make a list of all supported actions
- SUPPORTED_METHODS.Add("supported-actions", ListSupportedActions);
- SUPPORTED_METHODS.Add("system-info", ListSystemInfo);
- SUPPORTED_METHODS.Add("list-backups", ListBackups);
- SUPPORTED_METHODS.Add("get-current-state", GetCurrentState);
- SUPPORTED_METHODS.Add("get-progress-state", GetProgressState);
- SUPPORTED_METHODS.Add("list-application-settings", ListApplicationSettings);
- SUPPORTED_METHODS.Add("send-command", SendCommand);
- SUPPORTED_METHODS.Add("get-backup-defaults", GetBackupDefaults);
- SUPPORTED_METHODS.Add("get-folder-contents", GetFolderContents);
- SUPPORTED_METHODS.Add("get-backup", GetBackup);
- SUPPORTED_METHODS.Add("add-backup", AddBackup);
- SUPPORTED_METHODS.Add("update-backup", UpdateBackup);
- SUPPORTED_METHODS.Add("delete-backup", DeleteBackup);
- SUPPORTED_METHODS.Add("copy-backup-to-temp", CopyBackupToTemporary);
- SUPPORTED_METHODS.Add("validate-path", ValidatePath);
- SUPPORTED_METHODS.Add("list-tags", ListTags);
- SUPPORTED_METHODS.Add("test-backend", TestBackend);
- SUPPORTED_METHODS.Add("create-remote-folder", CreateRemoteFolder);
- SUPPORTED_METHODS.Add("list-remote-folder", ListRemoteFolder);
- SUPPORTED_METHODS.Add("list-backup-sets", ListBackupSets);
- SUPPORTED_METHODS.Add("search-backup-files", SearchBackupFiles);
- SUPPORTED_METHODS.Add("restore-files", RestoreFiles);
- SUPPORTED_METHODS.Add("read-log", ReadLogData);
- SUPPORTED_METHODS.Add("get-license-data", GetLicenseData);
- SUPPORTED_METHODS.Add("get-changelog", GetChangelog);
- SUPPORTED_METHODS.Add("get-acknowledgements", GetAcknowledgements);
- SUPPORTED_METHODS.Add("locate-uri-db", LocateUriDb);
- SUPPORTED_METHODS.Add("poll-log-messages", PollLogMessages);
- SUPPORTED_METHODS.Add("export-backup", ExportBackup);
- SUPPORTED_METHODS.Add("import-backup", ImportBackup);
- SUPPORTED_METHODS.Add("get-ui-settings", GetUISettings);
- SUPPORTED_METHODS.Add("set-ui-settings", SetUISettings);
- SUPPORTED_METHODS.Add("get-ui-schemes", GetUISettingSchemes);
- SUPPORTED_METHODS.Add("get-notifications", GetNotifications);
- SUPPORTED_METHODS.Add("dismiss-notification", DismissNotification);
- SUPPORTED_METHODS.Add("download-bug-report", DownloadBugReport);
- SUPPORTED_METHODS.Add("delete-local-data", DeleteLocalData);
- SUPPORTED_METHODS.Add("get-server-options", GetServerOptions);
- SUPPORTED_METHODS.Add("set-server-options", SetServerOptions);
- SUPPORTED_METHODS.Add("get-hyperv-guests", GetHyperVGuests);
- }
-
- public override bool Process (HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
- {
- //We use the fake entry point /control.cgi to listen for requests
- //This ensures that the rest of the webserver can just serve plain files
- if (!request.Uri.AbsolutePath.Equals(CONTROL_HANDLER_URI, StringComparison.InvariantCultureIgnoreCase))
- return false;
-
- HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
-
- string action = input["action"].Value ?? "";
-
- //Lookup the actual handler method
- ProcessSub method;
- SUPPORTED_METHODS.TryGetValue(action, out method);
-
- if (method == null) {
- response.Status = System.Net.HttpStatusCode.NotImplemented;
- response.Reason = "Unsupported action: " + (action == null ? "<null>" : "");
- response.Send();
- } else {
- //Default setup
- response.Status = System.Net.HttpStatusCode.OK;
- response.Reason = "OK";
- #if DEBUG
- response.ContentType = "text/plain";
- #else
- response.ContentType = "text/json";
- #endif
- using (BodyWriter bw = new BodyWriter(response, request))
- {
- try
- {
- method(request, response, session, bw);
- }
- catch (Exception ex)
- {
- Program.DataConnection.LogError("", string.Format("Request for {0} gave error", action), ex);
- Console.WriteLine(ex.ToString());
-
- try
- {
- if (!response.HeadersSent)
- {
- response.Status = System.Net.HttpStatusCode.InternalServerError;
- response.Reason = "Error";
- response.ContentType = "text/plain";
-
- bw.WriteJsonObject(new
- {
- Message = ex.Message,
- Type = ex.GetType().Name,
- #if DEBUG
- Stacktrace = ex.ToString()
- #endif
- });
- bw.Flush();
- }
- }
- catch (Exception flex)
- {
- Program.DataConnection.LogError("", "Reporting error gave error", flex);
- }
- }
- }
- }
-
- return true;
- }
-
- private void ReportError(HttpServer.IHttpResponse response, BodyWriter bw, string message)
- {
- response.Status = System.Net.HttpStatusCode.InternalServerError;
- response.Reason = message;
-
- bw.WriteJsonObject(new { Error = message });
- }
-
- private void ReadLogData(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
-
- if (string.IsNullOrEmpty(input["id"].Value))
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.LogData));
- else
- {
- var key = string.Format("{0}/{1}", input["id"].Value, Duplicati.Library.Utility.Utility.ParseBool(input["remotelog"].Value, false) ? "remotelog" : "log");
- RESTHandler.DoProcess(request, response, session, request.Method, typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
-
- }
-
- private void LocateUriDb(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/dbpath", Library.Utility.Uri.UrlPathEncode(input["uri"].Value));
- RESTHandler.DoProcess(request, response, session, "GET", typeof(RESTMethods.RemoteOperation).Name.ToLowerInvariant(), key);
- }
-
- private void SearchBackupFiles(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase) ? request.Form : request.QueryString;
- var key = string.Format("{0}/files/{1}", input["id"].Value, input["filter"].Value);
-
- RESTHandler.DoProcess(request, response, session, request.Method, typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
-
- }
-
- private void GetFolderContents(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.DoProcess(request, response, session, request.Method, typeof(RESTMethods.Filesystem).Name.ToLowerInvariant(), Library.Utility.Uri.UrlPathEncode(request.QueryString["path"].Value));
- }
-
-
- private void GetBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Backup));
- }
-
- private void DeleteBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- request.Method = HttpServer.Method.Delete;
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Backup));
- }
-
- private class AddOrUpdateBackupData
- {
- public Database.Schedule Schedule {get; set;}
- public Database.Backup Backup {get; set;}
- }
-
- private void UpdateBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- request.Method = HttpServer.Method.Put;
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Backup));
- }
-
- private void AddBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Backups));
- }
-
- private void GetAcknowledgements(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Acknowledgements));
- }
-
- private void GetChangelog(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Changelog));
- }
-
- private void GetLicenseData(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Licenses));
- }
- private void GetHyperVGuests(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.HyperV));
- }
-
- private void RestoreFiles(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/restore", input["id"].Value);
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
-
- private void ListBackupSets(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/filesets", input["id"].Value);
- RESTHandler.DoProcess(request, response, session, request.Method, typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
-
- private void ListRemoteFolder(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/list", Library.Utility.Uri.UrlPathEncode(input["url"].Value));
- RESTHandler.DoProcess(request, response, session, request.Method, typeof(RESTMethods.RemoteOperation).Name.ToLowerInvariant(), key);
- }
-
- private void CreateRemoteFolder(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/create", Library.Utility.Uri.UrlPathEncode(input["url"].Value));
- RESTHandler.DoProcess(request, response, session, request.Method, typeof(RESTMethods.RemoteOperation).Name.ToLowerInvariant(), key);
- }
-
- private void TestBackend(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/test", Library.Utility.Uri.UrlPathEncode(input["url"].Value));
- RESTHandler.DoProcess(request, response, session, request.Method, typeof(RESTMethods.RemoteOperation).Name.ToLowerInvariant(), key);
- }
-
- private void ListSystemInfo(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.SystemInfo));
- }
-
- private void ListSupportedActions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- bw.OutputOK(new { Version = 1, Methods = SUPPORTED_METHODS.Keys });
- }
-
- private void ListBackups (HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Backups));
- }
-
- private void ListTags(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Tags));
- }
-
- private void ValidatePath(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/validate", Library.Utility.Uri.UrlPathEncode(input["path"].Value));
- RESTHandler.DoProcess(request, response, session, "GET", typeof(RESTMethods.Filesystem).Name.ToLowerInvariant(), key);
- }
-
- private void GetProgressState(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.ProgressState));
- }
-
- private void GetCurrentState (HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.ServerState));
- }
-
- private void ListApplicationSettings(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.SystemWideSettings));
- }
-
- private void DownloadBugReport(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.BugReport));
- }
-
- private void DeleteLocalData(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/deletedb", Library.Utility.Uri.UrlPathEncode(input["id"].Value));
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
-
- private void GetServerOptions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.ServerSettings));
- }
-
- private void SetServerOptions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- request.Method = "PATCH";
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.ServerSettings));
- }
-
- private void CopyBackupToTemporary(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/copytotemp", Library.Utility.Uri.UrlPathEncode(input["id"].Value));
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
-
- private void ExportBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- var input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
- var key = string.Format("{0}/export", Library.Utility.Uri.UrlPathEncode(input["id"].Value));
- RESTHandler.DoProcess(request, response, session, request.Method, typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
-
- private void ImportBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Backups).Name.ToLowerInvariant(), "import");
- }
-
- private void GetNotifications(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Notifications));
- }
-
- private void DismissNotification(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- request.Method = "DELETE";
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.Notification));
- }
-
- private void GetUISettings(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- request.Method = "GET";
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.UISettings));
- }
-
- private void SetUISettings(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- request.Method = "POST";
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.UISettings));
- }
-
- private void GetUISettingSchemes(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.UISettings));
- }
-
- private void GetBackupDefaults(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.HandleControlCGI(request, response, session, bw, typeof(RESTMethods.BackupDefaults));
- }
-
- private void PollLogMessages(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- RESTHandler.DoProcess(request, response, session, "GET", typeof(RESTMethods.LogData).Name.ToLowerInvariant(), "poll");
- }
-
- private void SendCommand(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
- {
- HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
-
- string command = input["command"].Value ?? "";
-
- switch (command.ToLowerInvariant())
- {
- case "check-update":
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Updates).Name.ToLowerInvariant(), "check");
- return;
-
- case "install-update":
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Updates).Name.ToLowerInvariant(), "install");
- return;
-
- case "activate-update":
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Updates).Name.ToLowerInvariant(), "activate");
- return;
-
- case "pause":
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.ServerState).Name.ToLowerInvariant(), "pause");
- return;
-
- case "resume":
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.ServerState).Name.ToLowerInvariant(), "resume");
- return;
-
- case "stop":
- case "abort":
- {
- var key = string.Format("{0}/{1}", input["taskid"].Value, command);
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Task).Name.ToLowerInvariant(), key);
- }
- return;
-
- case "is-backup-active":
- {
- var key = string.Format("{0}/isactive", Library.Utility.Uri.UrlPathEncode(input["id"].Value));
- RESTHandler.DoProcess(request, response, session, "GET", typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
- return;
-
- case "run":
- case "run-backup":
- {
- var key = string.Format("{0}/start", Library.Utility.Uri.UrlPathEncode(input["id"].Value));
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
- return;
-
- case "run-verify":
- {
- var key = string.Format("{0}/verify", Library.Utility.Uri.UrlPathEncode(input["id"].Value));
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
- return;
-
- case "run-repair-update":
- {
- var key = string.Format("{0}/repairupdate", Library.Utility.Uri.UrlPathEncode(input["id"].Value));
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
- return;
-
- case "run-repair":
- {
- var key = string.Format("{0}/repair", Library.Utility.Uri.UrlPathEncode(input["id"].Value));
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
- return;
- case "create-report":
- {
- var key = string.Format("{0}/createreport", Library.Utility.Uri.UrlPathEncode(input["id"].Value));
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.Backup).Name.ToLowerInvariant(), key);
- }
- return;
-
- default:
- {
- var key = string.Format("{0}", Library.Utility.Uri.UrlPathEncode(input["command"].Value));
- RESTHandler.DoProcess(request, response, session, "POST", typeof(RESTMethods.WebModule).Name.ToLowerInvariant(), key);
- return;
- }
- }
- }
-
- }
-}
-
diff --git a/Duplicati/Server/WebServer/RESTHandler.cs b/Duplicati/Server/WebServer/RESTHandler.cs
index ca630160f..f006a2711 100644
--- a/Duplicati/Server/WebServer/RESTHandler.cs
+++ b/Duplicati/Server/WebServer/RESTHandler.cs
@@ -27,7 +27,7 @@ namespace Duplicati.Server.WebServer
public const string API_URI_PATH = "/api/v1";
public static readonly int API_URI_SEGMENTS = API_URI_PATH.Split(new char[] {'/'}).Length;
- private static readonly Dictionary<string, IRESTMethod> _modules = new Dictionary<string, IRESTMethod>(StringComparer.InvariantCultureIgnoreCase);
+ private static readonly Dictionary<string, IRESTMethod> _modules = new Dictionary<string, IRESTMethod>(StringComparer.OrdinalIgnoreCase);
public static IDictionary<string, IRESTMethod> Modules { get { return _modules; } }
@@ -81,6 +81,8 @@ namespace Duplicati.Server.WebServer
private static System.Globalization.CultureInfo ParseRequestCulture(string acceptheader)
{
+ acceptheader = acceptheader ?? string.Empty;
+
// Lock-free read
System.Globalization.CultureInfo ci;
if (_cultureCache.TryGetValue(acceptheader, out ci))
@@ -96,7 +98,7 @@ namespace Duplicati.Server.WebServer
var opts = x.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
var lang = opts.FirstOrDefault();
var weight =
- opts.Where(y => y.StartsWith("q=", StringComparison.InvariantCultureIgnoreCase))
+ opts.Where(y => y.StartsWith("q=", StringComparison.OrdinalIgnoreCase))
.Select(y =>
{
float f;
@@ -227,7 +229,7 @@ namespace Duplicati.Server.WebServer
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
{
- if (!request.Uri.AbsolutePath.StartsWith(API_URI_PATH, StringComparison.InvariantCultureIgnoreCase))
+ if (!request.Uri.AbsolutePath.StartsWith(API_URI_PATH, StringComparison.OrdinalIgnoreCase))
return false;
var module = request.Uri.Segments.Skip(API_URI_SEGMENTS).FirstOrDefault();
diff --git a/Duplicati/Server/WebServer/RESTMethods/Backup.cs b/Duplicati/Server/WebServer/RESTMethods/Backup.cs
index be760656d..9015c7753 100644
--- a/Duplicati/Server/WebServer/RESTMethods/Backup.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/Backup.cs
@@ -41,7 +41,7 @@ namespace Duplicati.Server.WebServer.RESTMethods
private void SearchFiles(IBackup backup, string filterstring, RequestInfo info)
{
- var filter = filterstring.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries);
+ var filter = filterstring;
var timestring = info.Request.QueryString["time"].Value;
var allversion = Duplicati.Library.Utility.Utility.ParseBool(info.Request.QueryString["all-versions"].Value, false);
@@ -57,7 +57,7 @@ namespace Duplicati.Server.WebServer.RESTMethods
if (!allversion)
time = Duplicati.Library.Utility.Timeparser.ParseTimeInterval(timestring, DateTime.Now);
- var r = Runner.Run(Runner.CreateListTask(backup, filter, prefixonly, allversion, foldercontents, time), false) as Duplicati.Library.Interface.IListResults;
+ var r = Runner.Run(Runner.CreateListTask(backup, new string[] { filter }, prefixonly, allversion, foldercontents, time), false) as Duplicati.Library.Interface.IListResults;
var result = new Dictionary<string, object>();
@@ -83,7 +83,7 @@ namespace Duplicati.Server.WebServer.RESTMethods
var r = Runner.Run(Runner.CreateTask(DuplicatiOperation.List, backup, extra), false) as Duplicati.Library.Interface.IListResults;
- if (r.EncryptedFiles && backup.Settings.Any(x => string.Equals("--no-encryption", x.Name, StringComparison.InvariantCultureIgnoreCase)))
+ if (r.EncryptedFiles && backup.Settings.Any(x => string.Equals("--no-encryption", x.Name, StringComparison.OrdinalIgnoreCase)))
info.ReportServerError("encrypted-storage");
else
info.OutputOK(r.Filesets);
@@ -91,23 +91,14 @@ namespace Duplicati.Server.WebServer.RESTMethods
private void FetchLogData(IBackup backup, RequestInfo info)
{
- using(var con = (System.Data.IDbConnection)Activator.CreateInstance(Duplicati.Library.SQLiteHelper.SQLiteLoader.SQLiteConnectionType))
- {
- con.ConnectionString = "Data Source=" + backup.DBPath;
- con.Open();
-
+ using(var con = Duplicati.Library.SQLiteHelper.SQLiteLoader.LoadConnection(backup.DBPath))
using(var cmd = con.CreateCommand())
info.OutputOK(LogData.DumpTable(cmd, "LogData", "ID", info.Request.QueryString["offset"].Value, info.Request.QueryString["pagesize"].Value));
- }
}
private void FetchRemoteLogData(IBackup backup, RequestInfo info)
{
- using(var con = (System.Data.IDbConnection)Activator.CreateInstance(Duplicati.Library.SQLiteHelper.SQLiteLoader.SQLiteConnectionType))
- {
- con.ConnectionString = "Data Source=" + backup.DBPath;
- con.Open();
-
+ using(var con = Duplicati.Library.SQLiteHelper.SQLiteLoader.LoadConnection(backup.DBPath))
using(var cmd = con.CreateCommand())
{
var dt = LogData.DumpTable(cmd, "RemoteOperation", "ID", info.Request.QueryString["offset"].Value, info.Request.QueryString["pagesize"].Value);
@@ -119,16 +110,30 @@ namespace Duplicati.Server.WebServer.RESTMethods
info.OutputOK(dt);
}
- }
+ }
+ private void IsDBUsedElseWhere(IBackup backup, RequestInfo info)
+ {
+ info.OutputOK(new { inuse = Library.Main.DatabaseLocator.IsDatabasePathInUse(backup.DBPath) });
}
private void Export(IBackup backup, RequestInfo info)
{
var cmdline = Library.Utility.Utility.ParseBool(info.Request.QueryString["cmdline"].Value, false);
+ var argsonly = Library.Utility.Utility.ParseBool(info.Request.QueryString["argsonly"].Value, false);
if (cmdline)
{
info.OutputOK(new { Command = Runner.GetCommandLine(Runner.CreateTask(DuplicatiOperation.Backup, backup)) });
}
+ else if (argsonly)
+ {
+ var parts = Runner.GetCommandLineParts(Runner.CreateTask(DuplicatiOperation.Backup, backup));
+
+ info.OutputOK(new {
+ Backend = parts.First(),
+ Arguments = parts.Skip(1).Where(x => !x.StartsWith("--", StringComparison.Ordinal)),
+ Options = parts.Skip(1).Where(x => x.StartsWith("--", StringComparison.Ordinal))
+ });
+ }
else
{
var passphrase = info.Request.QueryString["passphrase"].Value;
@@ -197,6 +202,15 @@ namespace Duplicati.Server.WebServer.RESTMethods
info.OutputOK(new { Status = "OK", ID = task.TaskID });
}
+ private void ReportRemoteSize(IBackup backup, RequestInfo info)
+ {
+ var task = Runner.CreateTask(DuplicatiOperation.ListRemote, backup);
+ Program.WorkThread.AddTask(task);
+ Program.StatusEventNotifyer.SignalNewEvent();
+
+ info.OutputOK(new { Status = "OK", ID = task.TaskID });
+ }
+
private void Repair(IBackup backup, RequestInfo info)
{
DoRepair(backup, info, false);
@@ -230,7 +244,7 @@ namespace Duplicati.Server.WebServer.RESTMethods
string[] filters;
var rawpaths = (paths ?? string.Empty).Trim();
- // We send the file list as a JSON array to avoid encoding issues with the path seperator
+ // We send the file list as a JSON array to avoid encoding issues with the path separator
// as it is an allowed character in file and path names.
// We also accept the old way, for compatibility with the greeno theme
if (!string.IsNullOrWhiteSpace(rawpaths) && rawpaths.StartsWith("[", StringComparison.Ordinal) && rawpaths.EndsWith("]", StringComparison.Ordinal))
@@ -366,6 +380,9 @@ namespace Duplicati.Server.WebServer.RESTMethods
case "export":
Export(bk, info);
return;
+ case "isdbusedelsewhere":
+ IsDBUsedElseWhere(bk, info);
+ return;
case "isactive":
IsActive(bk, info);
return;
@@ -450,6 +467,9 @@ namespace Duplicati.Server.WebServer.RESTMethods
RunBackup(bk, info);
return;
+ case "report-remote-size":
+ ReportRemoteSize(bk, info);
+ return;
case "copytotemp":
var ipx = Serializer.Deserialize<Database.Backup>(new StringReader(Newtonsoft.Json.JsonConvert.SerializeObject(bk)));
@@ -519,12 +539,19 @@ namespace Duplicati.Server.WebServer.RESTMethods
return;
}
- if (Program.DataConnection.Backups.Where(x => x.Name.Equals(data.Backup.Name, StringComparison.InvariantCultureIgnoreCase) && x.ID != data.Backup.ID).Any())
+ if (Program.DataConnection.Backups.Where(x => x.Name.Equals(data.Backup.Name, StringComparison.OrdinalIgnoreCase) && x.ID != data.Backup.ID).Any())
{
info.ReportClientError("There already exists a backup with the name: " + data.Backup.Name);
return;
}
+ var err = Program.DataConnection.ValidateBackup(data.Backup, data.Schedule);
+ if (!string.IsNullOrWhiteSpace(err))
+ {
+ info.ReportClientError(err);
+ return;
+ }
+
//TODO: Merge in real passwords where the placeholder is found
Program.DataConnection.AddOrUpdateBackupAndSchedule(data.Backup, data.Schedule);
@@ -539,7 +566,6 @@ namespace Duplicati.Server.WebServer.RESTMethods
info.ReportClientError(string.Format("Unable to parse backup or schedule object: {0}", ex.Message));
else
info.ReportClientError(string.Format("Unable to save backup or schedule: {0}", ex.Message));
-
}
}
@@ -552,6 +578,25 @@ namespace Duplicati.Server.WebServer.RESTMethods
return;
}
+ var delete_remote_files = Library.Utility.Utility.ParseBool(info.Request.Param["delete-remote-files"].Value, false);
+
+ if (delete_remote_files)
+ {
+ var captcha_token = info.Request.Param["captcha-token"].Value;
+ var captcha_answer = info.Request.Param["captcha-answer"].Value;
+ if (string.IsNullOrWhiteSpace(captcha_token) || string.IsNullOrWhiteSpace(captcha_answer))
+ {
+ info.ReportClientError("Missing captcha");
+ return;
+ }
+
+ if (!Captcha.SolvedCaptcha(captcha_token, "DELETE /backup/" + backup.ID, captcha_answer))
+ {
+ info.ReportClientError("Invalid captcha", System.Net.HttpStatusCode.Forbidden);
+ return;
+ }
+ }
+
if (Program.WorkThread.Active)
{
try
@@ -615,28 +660,17 @@ namespace Duplicati.Server.WebServer.RESTMethods
}
}
+ var extra = new Dictionary<string, string>();
+ if (!string.IsNullOrWhiteSpace(info.Request.Param["delete-local-db"].Value))
+ extra["delete-local-db"] = info.Request.Param["delete-local-db"].Value;
+ if (delete_remote_files)
+ extra["delete-remote-files"] = "true";
- //var dbpath = backup.DBPath;
- Program.DataConnection.DeleteBackup(backup);
-
- // TODO: Before we activate this,
- // we need some strategy to figure out
- // if the db is shared with something else
- // like the commandline or another backup
- /*try
- {
- if (System.IO.File.Exists(dbpath))
- System.IO.File.Delete(dbpath);
- }
- catch (Exception ex)
- {
- Program.DataConnection.LogError(null, string.Format("Failed to delete database: {0}", dbpath), ex);
- }*/
-
- //We have fiddled with the schedules
- Program.Scheduler.Reschedule();
+ var task = Runner.CreateTask(DuplicatiOperation.Delete, backup, extra);
+ Program.WorkThread.AddTask(task);
+ Program.StatusEventNotifyer.SignalNewEvent();
- info.OutputOK();
+ info.OutputOK(new { Status = "OK", ID = task.TaskID });
}
public string Description { get { return "Retrieves, updates or deletes an existing backup and schedule"; } }
diff --git a/Duplicati/Server/WebServer/RESTMethods/Backups.cs b/Duplicati/Server/WebServer/RESTMethods/Backups.cs
index d5fe6b3de..bc9c107e8 100644
--- a/Duplicati/Server/WebServer/RESTMethods/Backups.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/Backups.cs
@@ -49,12 +49,13 @@ namespace Duplicati.Server.WebServer.RESTMethods
private void ImportBackup(RequestInfo info)
{
- var output_template = "<html><body><script type=\"text/javascript\">var rp = null; try { rp = parent['CBM']; } catch (e) {}; rp = rp || alert; rp('MSG');</script></body></html>";
+ var output_template = "<html><body><script type=\"text/javascript\">var jso = 'JSO'; var rp = null; try { rp = parent['CBM']; } catch (e) {}; if (rp) { rp('MSG', jso); } else { alert; rp('MSG'); };</script></body></html>";
//output_template = "<html><body><script type=\"text/javascript\">alert('MSG');</script></body></html>";
try
{
var input = info.Request.Form;
var cmdline = Library.Utility.Utility.ParseBool(input["cmdline"].Value, false);
+ var direct = Library.Utility.Utility.ParseBool(input["direct"].Value, false);
output_template = output_template.Replace("CBM", input["callback"].Value);
if (cmdline)
{
@@ -96,27 +97,45 @@ namespace Duplicati.Server.WebServer.RESTMethods
if (ipx.Schedule != null)
ipx.Schedule.ID = -1;
- lock(Program.DataConnection.m_lock)
+ if (direct)
{
- var basename = ipx.Backup.Name;
- var c = 0;
- while (c++ < 100 && Program.DataConnection.Backups.Where(x => x.Name.Equals(ipx.Backup.Name, StringComparison.InvariantCultureIgnoreCase)).Any())
- ipx.Backup.Name = basename + " (" + c.ToString() + ")";
-
- if (Program.DataConnection.Backups.Where(x => x.Name.Equals(ipx.Backup.Name, StringComparison.InvariantCultureIgnoreCase)).Any())
+ lock (Program.DataConnection.m_lock)
{
- info.BodyWriter.SetOK();
- info.Response.ContentType = "text/html";
- info.BodyWriter.Write(output_template.Replace("MSG", "There already exists a backup with the name: " + basename.Replace("\'", "\\'")));
+ var basename = ipx.Backup.Name;
+ var c = 0;
+ while (c++ < 100 && Program.DataConnection.Backups.Where(x => x.Name.Equals(ipx.Backup.Name, StringComparison.OrdinalIgnoreCase)).Any())
+ ipx.Backup.Name = basename + " (" + c.ToString() + ")";
+
+ if (Program.DataConnection.Backups.Where(x => x.Name.Equals(ipx.Backup.Name, StringComparison.OrdinalIgnoreCase)).Any())
+ {
+ info.BodyWriter.SetOK();
+ info.Response.ContentType = "text/html";
+ info.BodyWriter.Write(output_template.Replace("MSG", "There already exists a backup with the name: " + basename.Replace("\'", "\\'")));
+ }
+
+ var err = Program.DataConnection.ValidateBackup(ipx.Backup, ipx.Schedule);
+ if (!string.IsNullOrWhiteSpace(err))
+ {
+ info.ReportClientError(err);
+ return;
+ }
+
+ Program.DataConnection.AddOrUpdateBackupAndSchedule(ipx.Backup, ipx.Schedule);
}
- Program.DataConnection.AddOrUpdateBackupAndSchedule(ipx.Backup, ipx.Schedule);
- }
+ info.Response.ContentType = "text/html";
+ info.BodyWriter.Write(output_template.Replace("MSG", "OK"));
- info.Response.ContentType = "text/html";
- info.BodyWriter.Write(output_template.Replace("MSG", "OK"));
-
- //bw.OutputOK(new { status = "OK", ID = ipx.Backup.ID });
+ }
+ else
+ {
+ using (var sw = new StringWriter())
+ {
+ Serializer.SerializeJson(sw, ipx, true);
+ output_template = output_template.Replace("'JSO'", sw.ToString());
+ }
+ info.BodyWriter.Write(output_template.Replace("MSG", "Import completed, but a browser issue prevents loading the contents. Try using the direct import method instead."));
+ }
}
}
catch (Exception ex)
@@ -129,7 +148,7 @@ namespace Duplicati.Server.WebServer.RESTMethods
public void POST(string key, RequestInfo info)
{
- if ("import".Equals(key, StringComparison.InvariantCultureIgnoreCase))
+ if ("import".Equals(key, StringComparison.OrdinalIgnoreCase))
{
ImportBackup(info);
return;
@@ -175,12 +194,19 @@ namespace Duplicati.Server.WebServer.RESTMethods
lock(Program.DataConnection.m_lock)
{
- if (Program.DataConnection.Backups.Where(x => x.Name.Equals(data.Backup.Name, StringComparison.InvariantCultureIgnoreCase)).Any())
+ if (Program.DataConnection.Backups.Where(x => x.Name.Equals(data.Backup.Name, StringComparison.OrdinalIgnoreCase)).Any())
{
info.ReportClientError("There already exists a backup with the name: " + data.Backup.Name);
return;
}
+ var err = Program.DataConnection.ValidateBackup(data.Backup, data.Schedule);
+ if (!string.IsNullOrWhiteSpace(err))
+ {
+ info.ReportClientError(err);
+ return;
+ }
+
Program.DataConnection.AddOrUpdateBackupAndSchedule(data.Backup, data.Schedule);
}
diff --git a/Duplicati/Server/WebServer/RESTMethods/Captcha.cs b/Duplicati/Server/WebServer/RESTMethods/Captcha.cs
new file mode 100644
index 000000000..4bf51fb2c
--- /dev/null
+++ b/Duplicati/Server/WebServer/RESTMethods/Captcha.cs
@@ -0,0 +1,166 @@
+// Copyright (C) 2016, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Linq;
+using System.Collections.Generic;
+
+namespace Duplicati.Server.WebServer.RESTMethods
+{
+ public class Captcha : IRESTMethodGET, IRESTMethodPOST
+ {
+ private class CaptchaEntry
+ {
+ public readonly string Answer;
+ public readonly string Target;
+ public int Attempts;
+ public readonly DateTime Expires;
+
+ public CaptchaEntry(string answer, string target)
+ {
+ Answer = answer;
+ Target = target;
+ Attempts = 4;
+ Expires = DateTime.Now.AddMinutes(2);
+ }
+ }
+
+ private static object m_lock = new object();
+ private static Dictionary<string, CaptchaEntry> m_captchas = new Dictionary<string, CaptchaEntry>();
+
+ public static bool SolvedCaptcha(string token, string target, string answer)
+ {
+ lock(m_lock)
+ {
+ CaptchaEntry tp;
+ m_captchas.TryGetValue(token ?? string.Empty, out tp);
+ if (tp == null)
+ return false;
+
+ if (tp.Attempts > 0)
+ tp.Attempts--;
+
+ return tp.Attempts >= 0 && string.Equals(tp.Answer, answer, StringComparison.OrdinalIgnoreCase) && tp.Target == target && tp.Expires >= DateTime.Now;
+ }
+ }
+
+ public void GET(string key, RequestInfo info)
+ {
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ info.ReportClientError("Missing token value");
+ return;
+ }
+ else
+ {
+ string answer = null;
+ lock (m_lock)
+ {
+ CaptchaEntry tp;
+ m_captchas.TryGetValue(key, out tp);
+ if (tp != null && tp.Expires > DateTime.Now)
+ answer = tp.Answer;
+ }
+
+ if (string.IsNullOrWhiteSpace(answer))
+ {
+ info.ReportClientError("No such entry", System.Net.HttpStatusCode.NotFound);
+ return;
+ }
+
+ using (var bmp = CaptchaUtil.CreateCaptcha(answer))
+ using (var ms = new System.IO.MemoryStream())
+ {
+ info.Response.ContentType = "image/jpeg";
+ info.Response.ContentLength = ms.Length;
+ bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
+ ms.Position = 0;
+
+ info.Response.ContentType = "image/jpeg";
+ info.Response.ContentLength = ms.Length;
+ info.Response.SendHeaders();
+ ms.CopyTo(info.Response.Body);
+ info.Response.Send();
+ }
+ }
+ }
+
+ public void POST(string key, RequestInfo info)
+ {
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ var target = info.Request.Param["target"].Value;
+ if (string.IsNullOrWhiteSpace(target))
+ {
+ info.ReportClientError("Missing target parameter");
+ return;
+ }
+
+ var answer = CaptchaUtil.CreateRandomAnswer(minlength: 6, maxlength: 6);
+ var nonce = Guid.NewGuid().ToString();
+
+ string token;
+ using (var ms = new System.IO.MemoryStream())
+ {
+ var bytes = System.Text.Encoding.UTF8.GetBytes(answer + nonce);
+ ms.Write(bytes, 0, bytes.Length);
+ ms.Position = 0;
+ token = Library.Utility.Utility.Base64PlainToBase64Url(Library.Utility.Utility.CalculateHash(ms));
+ }
+
+ lock (m_lock)
+ {
+ var expired = m_captchas.Where(x => x.Value.Expires < DateTime.Now).Select(x => x.Key).ToArray();
+ foreach (var x in expired)
+ m_captchas.Remove(x);
+
+ if (m_captchas.Count > 3)
+ {
+ info.ReportClientError("Too many captchas, wait 2 minutes and try again", System.Net.HttpStatusCode.ServiceUnavailable);
+ return;
+ }
+
+ m_captchas[token] = new CaptchaEntry(answer, target);
+ }
+
+ info.OutputOK(new
+ {
+ token = token
+ });
+ }
+ else
+ {
+ var answer = info.Request.Param["answer"].Value;
+ var target = info.Request.Param["target"].Value;
+ if (string.IsNullOrWhiteSpace(answer))
+ {
+ info.ReportClientError("Missing answer parameter");
+ return;
+ }
+ if (string.IsNullOrWhiteSpace(target))
+ {
+ info.ReportClientError("Missing target parameter");
+ return;
+ }
+
+ if (SolvedCaptcha(key, target, answer))
+ info.OutputOK();
+ else
+ info.ReportClientError("Incorrect");
+ }
+ }
+ }
+}
diff --git a/Duplicati/Server/WebServer/RESTMethods/CommandLine.cs b/Duplicati/Server/WebServer/RESTMethods/CommandLine.cs
new file mode 100644
index 000000000..72ccc6bd0
--- /dev/null
+++ b/Duplicati/Server/WebServer/RESTMethods/CommandLine.cs
@@ -0,0 +1,256 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Duplicati.Server.WebServer.RESTMethods
+{
+ public class CommandLine : IRESTMethodGET, IRESTMethodPOST
+ {
+ private class LogWriter : System.IO.TextWriter
+ {
+ private readonly ActiveRun m_target;
+ private readonly StringBuilder m_sb = new StringBuilder();
+ private int m_newlinechars = 0;
+
+ public LogWriter(ActiveRun target)
+ {
+ m_target = target;
+ }
+
+ public override Encoding Encoding { get { return System.Text.Encoding.UTF8; } }
+
+ public override void Write(char value)
+ {
+ lock(m_target.Lock)
+ {
+ m_sb.Append(value);
+ if (NewLine[m_newlinechars] == value)
+ {
+ m_newlinechars++;
+ if (m_newlinechars == NewLine.Length)
+ WriteLine(string.Empty);
+ }
+ else
+ m_newlinechars = 0;
+ }
+ }
+
+ public override void WriteLine(string value)
+ {
+ value = value ?? string.Empty;
+ lock(m_target.Lock)
+ {
+ m_target.LastAccess = DateTime.Now;
+
+ if (m_sb.Length != 0)
+ {
+ m_target.Log.Add(m_sb.ToString() + value);
+ m_sb.Length = 0;
+ m_newlinechars = 0;
+ }
+ else
+ {
+ m_target.Log.Add(value);
+ }
+ }
+ }
+ }
+
+ private class ActiveRun
+ {
+ public readonly string ID = Guid.NewGuid().ToString();
+ public DateTime LastAccess = DateTime.Now;
+ public Library.Utility.FileBackedStringList Log = new Library.Utility.FileBackedStringList();
+ public Runner.IRunnerData Task;
+ public LogWriter Writer;
+ public readonly object Lock = new object();
+ public bool Finished = false;
+ public bool Started = false;
+ public System.Threading.Thread Thread;
+ }
+
+ private readonly Dictionary<string, ActiveRun> m_activeItems = new Dictionary<string, ActiveRun>();
+ private System.Threading.Tasks.Task m_cleanupTask;
+
+ public void POST(string key, RequestInfo info)
+ {
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ string[] args;
+ using (var sr = new StreamReader(info.Request.Body, System.Text.Encoding.UTF8, true))
+ args = Newtonsoft.Json.JsonConvert.DeserializeObject<string[]>(sr.ReadToEnd());
+
+ var k = new ActiveRun();
+ k.Writer = new LogWriter(k);
+
+ m_activeItems[k.ID] = k;
+ StartCleanupTask();
+
+ k.Task = Runner.CreateCustomTask((sink) =>
+ {
+ try
+ {
+ k.Thread = System.Threading.Thread.CurrentThread;
+ k.Started = true;
+
+ var code = Duplicati.CommandLine.Program.RunCommandLine(k.Writer, k.Writer, c => {
+ k.Task.SetController(c);
+ c.AppendSink(sink);
+ }, args);
+ k.Writer.WriteLine(string.Format("Return code: {0}", code));
+ }
+ catch (Exception ex)
+ {
+ var rx = ex;
+ if (rx is System.Reflection.TargetInvocationException)
+ rx = rx.InnerException;
+
+ if (rx is Library.Interface.UserInformationException)
+ k.Log.Add(rx.Message);
+ else
+ k.Log.Add(rx.ToString());
+
+ throw rx;
+ }
+ finally
+ {
+ k.Finished = true;
+ k.Thread = null;
+ }
+ });
+
+ Program.WorkThread.AddTask(k.Task);
+
+ info.OutputOK(new
+ {
+ ID = k.ID
+ });
+ }
+ else
+ {
+ if (!key.EndsWith("/abort", StringComparison.OrdinalIgnoreCase))
+ {
+ info.ReportClientError("Only abort commands are allowed");
+ return;
+ }
+
+ key = key.Substring(0, key.Length - "/abort".Length);
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ info.ReportClientError("No task key found");
+ return;
+ }
+
+ ActiveRun t;
+ if (!m_activeItems.TryGetValue(key, out t))
+ {
+ info.OutputError(code: System.Net.HttpStatusCode.NotFound);
+ return;
+ }
+
+ var tt = t.Task;
+ if (tt != null)
+ tt.Abort();
+
+ var tr = t.Thread;
+ if (tr != null)
+ tr.Abort();
+
+ info.OutputOK();
+ }
+ }
+
+ private void StartCleanupTask()
+ {
+ if (m_cleanupTask == null || m_cleanupTask.IsCompleted || m_cleanupTask.IsFaulted || m_cleanupTask.IsCanceled)
+ m_cleanupTask = RunCleanupAsync();
+ }
+
+ private async System.Threading.Tasks.Task RunCleanupAsync()
+ {
+ while (m_activeItems.Count > 0)
+ {
+ var oldest = m_activeItems.Values.OrderBy(x => x.LastAccess).FirstOrDefault();
+ if (oldest != null && DateTime.Now - oldest.LastAccess > TimeSpan.FromMinutes(5))
+ {
+ m_activeItems.Remove(oldest.ID);
+ oldest.Log.Dispose();
+
+ // Fix all expired, or stop running
+ continue;
+ }
+
+ await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(60));
+ }
+ }
+
+ public void GET(string key, RequestInfo info)
+ {
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ info.OutputOK(
+ Duplicati.CommandLine.Program.SupportedCommands
+ );
+ }
+ else
+ {
+ ActiveRun t;
+ if (!m_activeItems.TryGetValue(key, out t))
+ {
+ info.OutputError(code: System.Net.HttpStatusCode.NotFound);
+ return;
+ }
+
+ int pagesize;
+ int offset;
+
+ int.TryParse(info.Request.QueryString["pagesize"].Value, out pagesize);
+ int.TryParse(info.Request.QueryString["offset"].Value, out offset);
+ pagesize = Math.Max(10, Math.Min(500, pagesize));
+ offset = Math.Max(0, offset);
+ var items = new List<string>();
+ long count;
+ bool started;
+ bool finished;
+
+ lock(t.Lock)
+ {
+ t.LastAccess = DateTime.Now;
+ count = t.Log.Count;
+ offset = Math.Min((int)count, offset);
+ items.AddRange(t.Log.Skip(offset).Take(pagesize));
+ finished = t.Finished;
+ started = t.Started;
+ }
+
+ info.OutputOK(new
+ {
+ Pagesize = pagesize,
+ Offset = offset,
+ Count = count,
+ Items = items,
+ Finished = finished,
+ Started = started
+ });
+ }
+ }
+ }
+}
diff --git a/Duplicati/Server/WebServer/RESTMethods/Filesystem.cs b/Duplicati/Server/WebServer/RESTMethods/Filesystem.cs
index e0fdda807..dd44dfe3a 100644
--- a/Duplicati/Server/WebServer/RESTMethods/Filesystem.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/Filesystem.cs
@@ -54,7 +54,7 @@ namespace Duplicati.Server.WebServer.RESTMethods
if (ix > 0)
{
var tk = path.Substring(0, ix + 1);
- var node = SpecialFolders.Nodes.Where(x => x.id.Equals(tk, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
+ var node = SpecialFolders.Nodes.Where(x => x.id.Equals(tk, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (node != null)
{
specialpath = node.resolvedpath;
@@ -73,7 +73,7 @@ namespace Duplicati.Server.WebServer.RESTMethods
if (!string.IsNullOrWhiteSpace(command))
{
- if ("validate".Equals(command, StringComparison.InvariantCultureIgnoreCase))
+ if ("validate".Equals(command, StringComparison.OrdinalIgnoreCase))
{
try
{
diff --git a/Duplicati/Server/WebServer/RESTMethods/HyperV.cs b/Duplicati/Server/WebServer/RESTMethods/HyperV.cs
index 989208d5c..497ee99fb 100644
--- a/Duplicati/Server/WebServer/RESTMethods/HyperV.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/HyperV.cs
@@ -14,22 +14,75 @@
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-using System; using System.Collections.Generic; using Duplicati.Library.Interface;
+using System;
+using System.Collections.Generic;
+using Duplicati.Library.Interface;
using System.Linq;
+using System.Security.Principal;
using Duplicati.Library.Snapshots;
namespace Duplicati.Server.WebServer.RESTMethods
{
public class HyperV : IRESTMethodGET, IRESTMethodDocumented
{
- public void GET(string key, RequestInfo info) {
+ public void GET(string key, RequestInfo info)
+ {
+ // Early exit in case we are non-windows to prevent attempting to load Windows-only components
+ if (Library.Utility.Utility.IsClientWindows)
+ RealGET(key, info);
+ else
+ info.OutputOK(new string[0]);
+ }
+
+ // Make sure the JIT does not attempt to inline this call and thus load
+ // referenced types from System.Management here
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ private void RealGET(string key, RequestInfo info)
+ {
+ var hypervUtility = new HyperVUtility();
+
+ if (!hypervUtility.IsHyperVInstalled || !new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
+ {
+ info.OutputOK(new string[0]);
+ return;
+ }
+
try
{
- info.OutputOK(new HyperVUtility().GetHyperVGuests().Select(x => new { id = x.ID, name = x.Name }).ToList());
+ if (string.IsNullOrEmpty(key))
+ {
+ hypervUtility.QueryHyperVGuestsInfo();
+ info.OutputOK(hypervUtility.Guests.Select(x => new { id = x.ID, name = x.Name }).ToList());
+ }
+ else
+ {
+ hypervUtility.QueryHyperVGuestsInfo(true);
+ var foundVMs = hypervUtility.Guests.FindAll(x => x.ID.Equals(new Guid(key)));
+
+ if (foundVMs.Count == 1)
+ info.OutputOK(foundVMs[0].DataPaths.Select(x => new { text = x, id = x, cls = "folder", iconCls = "x-tree-icon-leaf", check = "false", leaf = "true" }).ToList());
+ else
+ info.ReportClientError(string.Format("Cannot find VM with ID {0}.", key));
+ }
}
catch (Exception ex)
{
- info.ReportClientError("Failed to enumerate Hyper-V virtual machines: " + ex.Message);
- } } public string Description { get { return "Return a list of Hyper-V virtual machines"; } } public IEnumerable<KeyValuePair<string, Type>> Types { get { return new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>(HttpServer.Method.Get, typeof(ICommandLineArgument[])) }; } } }
+ info.ReportServerError("Failed to enumerate Hyper-V virtual machines: " + ex.Message);
+ }
+ }
+
+ public string Description { get { return "Return a list of Hyper-V virtual machines"; } }
+
+ public IEnumerable<KeyValuePair<string, Type>> Types
+ {
+ get
+ {
+ return new KeyValuePair<string, Type>[] {
+ new KeyValuePair<string, Type>(HttpServer.Method.Get, typeof(ICommandLineArgument[]))
+ };
+ }
+ }
+
+ }
}
diff --git a/Duplicati/Server/WebServer/RESTMethods/LogData.cs b/Duplicati/Server/WebServer/RESTMethods/LogData.cs
index 177330575..552cc2a7c 100644
--- a/Duplicati/Server/WebServer/RESTMethods/LogData.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/LogData.cs
@@ -14,12 +14,98 @@
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-using System; using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
namespace Duplicati.Server.WebServer.RESTMethods
{
public class LogData : IRESTMethodGET, IRESTMethodDocumented
- { public void GET(string key, RequestInfo info) { if ("poll".Equals(key, StringComparison.InvariantCultureIgnoreCase)) { var input = info.Request.QueryString; var level_str = input["level"].Value ?? ""; var id_str = input["id"].Value ?? ""; Library.Logging.LogMessageType level; long id; long.TryParse(id_str, out id); Enum.TryParse(level_str, true, out level); info.OutputOK(Program.LogHandler.AfterID(id, level)); } else { List<Dictionary<string, object>> res = null; Program.DataConnection.ExecuteWithCommand(x => { res = DumpTable(x, "ErrorLog", "Timestamp", info.Request.QueryString["offset"].Value, info.Request.QueryString["pagesize"].Value); }); info.OutputOK(res); } } public static List<Dictionary<string, object>> DumpTable(System.Data.IDbCommand cmd, string tablename, string pagingfield, string offset_str, string pagesize_str) { var result = new List<Dictionary<string, object>>(); long pagesize; if (!long.TryParse(pagesize_str, out pagesize)) pagesize = 100; pagesize = Math.Max(10, Math.Min(500, pagesize)); cmd.CommandText = "SELECT * FROM \"" + tablename + "\""; long offset = 0; if (!string.IsNullOrWhiteSpace(offset_str) && long.TryParse(offset_str, out offset) && !string.IsNullOrEmpty(pagingfield)) { var p = cmd.CreateParameter(); p.Value = offset; cmd.Parameters.Add(p); cmd.CommandText += " WHERE \"" + pagingfield + "\" < ?"; } if (!string.IsNullOrEmpty(pagingfield)) cmd.CommandText += " ORDER BY \"" + pagingfield + "\" DESC"; cmd.CommandText += " LIMIT " + pagesize.ToString(); using(var rd = cmd.ExecuteReader()) { var names = new List<string>(); for(var i = 0; i < rd.FieldCount; i++) names.Add(rd.GetName(i)); while (rd.Read()) { var dict = new Dictionary<string, object>(); for(int i = 0; i < names.Count; i++) dict[names[i]] = rd.GetValue(i); result.Add(dict); } } return result; } public string Description { get { return "Retrieves system log data"; } } public IEnumerable<KeyValuePair<string, Type>> Types { get { return new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>(HttpServer.Method.Get, typeof(Dictionary<string, string>[])), }; } }
+ {
+ public void GET(string key, RequestInfo info)
+ {
+ if ("poll".Equals(key, StringComparison.OrdinalIgnoreCase))
+ {
+ var input = info.Request.QueryString;
+ var level_str = input["level"].Value ?? "";
+ var id_str = input["id"].Value ?? "";
+
+ Library.Logging.LogMessageType level;
+ long id;
+
+ long.TryParse(id_str, out id);
+ Enum.TryParse(level_str, true, out level);
+
+ info.OutputOK(Program.LogHandler.AfterID(id, level));
+ }
+ else
+ {
+
+ List<Dictionary<string, object>> res = null;
+ Program.DataConnection.ExecuteWithCommand(x =>
+ {
+ res = DumpTable(x, "ErrorLog", "Timestamp", info.Request.QueryString["offset"].Value, info.Request.QueryString["pagesize"].Value);
+ });
+
+ info.OutputOK(res);
+ }
+ }
+
+
+ public static List<Dictionary<string, object>> DumpTable(System.Data.IDbCommand cmd, string tablename, string pagingfield, string offset_str, string pagesize_str)
+ {
+ var result = new List<Dictionary<string, object>>();
+
+ long pagesize;
+ if (!long.TryParse(pagesize_str, out pagesize))
+ pagesize = 100;
+
+ pagesize = Math.Max(10, Math.Min(500, pagesize));
+
+ cmd.CommandText = "SELECT * FROM \"" + tablename + "\"";
+ long offset = 0;
+ if (!string.IsNullOrWhiteSpace(offset_str) && long.TryParse(offset_str, out offset) && !string.IsNullOrEmpty(pagingfield))
+ {
+ var p = cmd.CreateParameter();
+ p.Value = offset;
+ cmd.Parameters.Add(p);
+
+ cmd.CommandText += " WHERE \"" + pagingfield + "\" < ?";
+ }
+
+ if (!string.IsNullOrEmpty(pagingfield))
+ cmd.CommandText += " ORDER BY \"" + pagingfield + "\" DESC";
+ cmd.CommandText += " LIMIT " + pagesize.ToString();
+
+ using(var rd = cmd.ExecuteReader())
+ {
+ var names = new List<string>();
+ for(var i = 0; i < rd.FieldCount; i++)
+ names.Add(rd.GetName(i));
+
+ while (rd.Read())
+ {
+ var dict = new Dictionary<string, object>();
+ for(int i = 0; i < names.Count; i++)
+ dict[names[i]] = rd.GetValue(i);
+
+ result.Add(dict);
+ }
+ }
+
+ return result;
+ }
+
+ public string Description { get { return "Retrieves system log data"; } }
+
+ public IEnumerable<KeyValuePair<string, Type>> Types
+ {
+ get
+ {
+ return new KeyValuePair<string, Type>[] {
+ new KeyValuePair<string, Type>(HttpServer.Method.Get, typeof(Dictionary<string, string>[])),
+ };
+ }
+ }
}
}
diff --git a/Duplicati/Server/WebServer/RESTMethods/MSSQL.cs b/Duplicati/Server/WebServer/RESTMethods/MSSQL.cs
new file mode 100644
index 000000000..15ddf1923
--- /dev/null
+++ b/Duplicati/Server/WebServer/RESTMethods/MSSQL.cs
@@ -0,0 +1,86 @@
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using Duplicati.Library.Interface;
+using System.Linq;
+using System.Security.Principal;
+using Duplicati.Library.Snapshots;
+
+namespace Duplicati.Server.WebServer.RESTMethods
+{
+ public class MSSQL : IRESTMethodGET, IRESTMethodDocumented
+ {
+ public void GET(string key, RequestInfo info)
+ {
+ // Early exit in case we are non-windows to prevent attempting to load Windows-only components
+ if (Library.Utility.Utility.IsClientWindows)
+ RealGET(key, info);
+ else
+ info.OutputOK(new string[0]);
+ }
+
+ // Make sure the JIT does not attempt to inline this call and thus load
+ // referenced types from System.Management here
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ private void RealGET(string key, RequestInfo info)
+ {
+ var mssqlUtility = new MSSQLUtility();
+
+ if (!mssqlUtility.IsMSSQLInstalled || !new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
+ {
+ info.OutputOK(new string[0]);
+ return;
+ }
+
+ try
+ {
+ mssqlUtility.QueryDBsInfo();
+
+ if (string.IsNullOrEmpty(key))
+ info.OutputOK(mssqlUtility.DBs.Select(x => new { id = x.ID, name = x.Name }).ToList());
+ else
+ {
+ var foundDBs = mssqlUtility.DBs.FindAll(x => x.ID.Equals(key, StringComparison.OrdinalIgnoreCase));
+
+ if (foundDBs.Count == 1)
+ info.OutputOK(foundDBs[0].DataPaths.Select(x => new { text = x, id = x, cls = "folder", iconCls = "x-tree-icon-leaf", check = "false", leaf = "true" }).ToList());
+ else
+ info.ReportClientError(string.Format("Cannot find DB with ID {0}.", key));
+ }
+ }
+ catch (Exception ex)
+ {
+ info.ReportServerError("Failed to enumerate Microsoft SQL Server databases: " + ex.Message);
+ }
+ }
+
+ public string Description { get { return "Return a list of Microsoft SQL Server databases"; } }
+
+ public IEnumerable<KeyValuePair<string, Type>> Types
+ {
+ get
+ {
+ return new KeyValuePair<string, Type>[] {
+ new KeyValuePair<string, Type>(HttpServer.Method.Get, typeof(ICommandLineArgument[]))
+ };
+ }
+ }
+
+ }
+}
+
diff --git a/Duplicati/Server/WebServer/RESTMethods/ServerSetting.cs b/Duplicati/Server/WebServer/RESTMethods/ServerSetting.cs
index fec295237..d0adad452 100644
--- a/Duplicati/Server/WebServer/RESTMethods/ServerSetting.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/ServerSetting.cs
@@ -30,9 +30,15 @@ namespace Duplicati.Server.WebServer.RESTMethods
return;
}
+ if (key.Equals("server-ssl-certificate", StringComparison.OrdinalIgnoreCase) || key.Equals("ServerSSLCertificate", StringComparison.OrdinalIgnoreCase))
+ {
+ info.OutputOK(Program.DataConnection.ApplicationSettings.ServerSSLCertificate == null ? "False" : "True");
+ return;
+ }
+
if (key.StartsWith("--", StringComparison.Ordinal))
{
- var prop = Program.DataConnection.Settings.FirstOrDefault(x => string.Equals(key, x.Name, StringComparison.InvariantCultureIgnoreCase));
+ var prop = Program.DataConnection.Settings.FirstOrDefault(x => string.Equals(key, x.Name, StringComparison.OrdinalIgnoreCase));
info.OutputOK(prop == null ? null : prop.Value);
}
else
@@ -53,15 +59,23 @@ namespace Duplicati.Server.WebServer.RESTMethods
return;
}
+ if (key.Equals("server-ssl-certificate", StringComparison.OrdinalIgnoreCase) || key.Equals("ServerSSLCertificate", StringComparison.OrdinalIgnoreCase))
+ {
+ info.OutputError(null, System.Net.HttpStatusCode.BadRequest, "Can only update SSL certificate from commandline");
+ return;
+ }
+
if (key.StartsWith("--", StringComparison.Ordinal))
{
var settings = Program.DataConnection.Settings.ToList();
- var prop = settings.Where(x => string.Equals(key, x.Name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
+ var prop = settings.Where(x => string.Equals(key, x.Name, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (prop == null)
settings.Add(prop = new Database.Setting() { Name = key, Value = info.Request.Form["data"].Value });
else
prop.Value = info.Request.Form["data"].Value;
+
+ Program.DataConnection.Settings = settings.ToArray();
info.OutputOK(prop == null ? null : prop.Value);
}
diff --git a/Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs b/Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs
index 12cc925d9..222f0e5e9 100644
--- a/Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs
@@ -40,6 +40,10 @@ namespace Duplicati.Server.WebServer.RESTMethods
foreach (var n in adv_props)
dict[n.Name] = n.Value;
+ string sslcert;
+ dict.TryGetValue("server-ssl-certificate", out sslcert);
+ dict["server-ssl-certificate"] = (!string.IsNullOrWhiteSpace(sslcert)).ToString();
+
info.OutputOK(dict);
}
@@ -71,22 +75,29 @@ namespace Duplicati.Server.WebServer.RESTMethods
var serversettings = data.Where(x => !string.IsNullOrWhiteSpace(x.Key)).ToDictionary(x => x.Key, x => x.Key.StartsWith("--", StringComparison.Ordinal) ? null : x.Value);
var globalsettings = data.Where(x => !string.IsNullOrWhiteSpace(x.Key) && x.Key.StartsWith("--", StringComparison.Ordinal));
- Program.DataConnection.ApplicationSettings.UpdateSettings(serversettings, false);
-
- // Update based on inputs
- var existing = Program.DataConnection.Settings.ToDictionary(x => x.Name, x => x);
- foreach (var g in globalsettings)
- if (g.Value == null)
- existing.Remove(g.Key);
- else
- {
- if (existing.ContainsKey(g.Key))
- existing[g.Key].Value = g.Value;
- else
- existing[g.Key] = new Setting() { Name = g.Key, Value = g.Value };
- }
+ serversettings.Remove("server-ssl-certificate");
+ serversettings.Remove("ServerSSLCertificate");
+
+ if (serversettings.Any())
+ Program.DataConnection.ApplicationSettings.UpdateSettings(serversettings, false);
- Program.DataConnection.Settings = existing.Select(x => x.Value).ToArray();
+ if (globalsettings.Any())
+ {
+ // Update based on inputs
+ var existing = Program.DataConnection.Settings.ToDictionary(x => x.Name, x => x);
+ foreach (var g in globalsettings)
+ if (g.Value == null)
+ existing.Remove(g.Key);
+ else
+ {
+ if (existing.ContainsKey(g.Key))
+ existing[g.Key].Value = g.Value;
+ else
+ existing[g.Key] = new Setting() { Name = g.Key, Value = g.Value };
+ }
+
+ Program.DataConnection.Settings = existing.Select(x => x.Value).ToArray();
+ }
info.OutputOK();
}
diff --git a/Duplicati/Server/WebServer/RESTMethods/SystemInfo.cs b/Duplicati/Server/WebServer/RESTMethods/SystemInfo.cs
index b1ca474d6..07eb83339 100644
--- a/Duplicati/Server/WebServer/RESTMethods/SystemInfo.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/SystemInfo.cs
@@ -97,9 +97,11 @@ namespace Duplicati.Server.WebServer.RESTMethods
GenericModules = Serializable.ServerSettings.GenericModules,
WebModules = Serializable.ServerSettings.WebModules,
ConnectionModules = Serializable.ServerSettings.ConnectionModules,
+ ServerModules = Serializable.ServerSettings.ServerModules,
UsingAlternateUpdateURLs = Duplicati.Library.AutoUpdater.AutoUpdateSettings.UsesAlternateURLs,
LogLevels = Enum.GetNames(typeof(Duplicati.Library.Logging.LogMessageType)),
SuppressDonationMessages = Duplicati.Library.Main.Utility.SuppressDonationMessages,
+ SpecialFolders = from n in SpecialFolders.Nodes select new { ID = n.id, Path = n.resolvedpath },
BrowserLocale = new
{
Code = browserlanguage.Name,
diff --git a/Duplicati/Server/WebServer/RESTMethods/UISettings.cs b/Duplicati/Server/WebServer/RESTMethods/UISettings.cs
index 0cadb8451..ff8e300f5 100644
--- a/Duplicati/Server/WebServer/RESTMethods/UISettings.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/UISettings.cs
@@ -18,8 +18,45 @@ using System; using System.Collections.Generic; using Duplicati.Server.Serializa
namespace Duplicati.Server.WebServer.RESTMethods
{
- public class UISettings : IRESTMethodGET, IRESTMethodPOST
- { public void GET(string key, RequestInfo info) { if (string.IsNullOrWhiteSpace(key)) { info.OutputOK(Program.DataConnection.GetUISettingsSchemes()); } else { info.OutputOK(Program.DataConnection.GetUISettings(key)); } } public void POST(string key, RequestInfo info) { if (string.IsNullOrWhiteSpace(key)) { info.ReportClientError("Scheme is missing"); return; } IDictionary<string, string> data; try { data = Serializer.Deserialize<Dictionary<string, string>>(new StreamReader(info.Request.Body)); } catch (Exception ex) { info.ReportClientError(string.Format("Unable to parse settings object: {0}", ex.Message)); return; } if (data == null) { info.ReportClientError(string.Format("Unable to parse settings object")); return; } Program.DataConnection.SetUISettings(key, data); info.OutputOK(); }
- }
+ public class UISettings : IRESTMethodGET, IRESTMethodPOST, IRESTMethodPATCH
+ { public void GET(string key, RequestInfo info) { if (string.IsNullOrWhiteSpace(key)) { info.OutputOK(Program.DataConnection.GetUISettingsSchemes()); } else { info.OutputOK(Program.DataConnection.GetUISettings(key)); } }
+
+ public void POST(string key, RequestInfo info)
+ {
+ PATCH(key, info);
+ }
+
+ public void PATCH(string key, RequestInfo info)
+ {
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ info.ReportClientError("Scheme is missing");
+ return;
+ }
+
+ IDictionary<string, string> data;
+ try
+ {
+ data = Serializer.Deserialize<Dictionary<string, string>>(new StreamReader(info.Request.Body));
+ }
+ catch (Exception ex)
+ {
+ info.ReportClientError(string.Format("Unable to parse settings object: {0}", ex.Message));
+ return;
+ }
+
+ if (data == null)
+ {
+ info.ReportClientError(string.Format("Unable to parse settings object"));
+ return;
+ }
+
+ if (info.Request.Method == "POST")
+ Program.DataConnection.SetUISettings(key, data);
+ else
+ Program.DataConnection.UpdateUISettings(key, data);
+ info.OutputOK();
+ }
+ }
}
diff --git a/Duplicati/Server/WebServer/RESTMethods/WebModule.cs b/Duplicati/Server/WebServer/RESTMethods/WebModule.cs
index 108353938..5145653af 100644
--- a/Duplicati/Server/WebServer/RESTMethods/WebModule.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/WebModule.cs
@@ -14,14 +14,27 @@
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-using System; using System.Linq;
+using System;
+using System.Linq;
namespace Duplicati.Server.WebServer.RESTMethods
{
public class WebModule : IRESTMethodPOST
{
public void POST(string key, RequestInfo info)
- { var m = Duplicati.Library.DynamicLoader.WebLoader.Modules.Where(x => x.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); if (m == null) { info.ReportClientError(string.Format("No such command {0}", key), System.Net.HttpStatusCode.NotFound); return; } info.OutputOK(new { Status = "OK", Result = m.Execute(info.Request.Form.Where(x => !x.Name.Equals("command", StringComparison.InvariantCultureIgnoreCase) ).ToDictionary(x => x.Name, x => x.Value)) });
+ {
+ var m = Duplicati.Library.DynamicLoader.WebLoader.Modules.Where(x => x.Key.Equals(key, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
+ if (m == null)
+ {
+ info.ReportClientError(string.Format("No such command {0}", key), System.Net.HttpStatusCode.NotFound);
+ return;
+ }
+
+ info.OutputOK(new {
+ Status = "OK",
+ Result = m.Execute(info.Request.Form.Where(x => !x.Name.Equals("command", StringComparison.OrdinalIgnoreCase)
+ ).ToDictionary(x => x.Name, x => x.Value))
+ });
}
}
}
diff --git a/Duplicati/Server/WebServer/Server.cs b/Duplicati/Server/WebServer/Server.cs
index 56465a6b5..7b4016879 100644
--- a/Duplicati/Server/WebServer/Server.cs
+++ b/Duplicati/Server/WebServer/Server.cs
@@ -107,7 +107,7 @@ namespace Duplicati.Server.WebServer
if (string.IsNullOrWhiteSpace(interfacestring))
interfacestring = DEFAULT_OPTION_INTERFACE;
- if (interfacestring.Trim() == "*" || interfacestring.Trim().Equals("any", StringComparison.InvariantCultureIgnoreCase))
+ if (interfacestring.Trim() == "*" || interfacestring.Trim().Equals("any", StringComparison.OrdinalIgnoreCase) || interfacestring.Trim().Equals("all", StringComparison.OrdinalIgnoreCase))
listenInterface = System.Net.IPAddress.Any;
else if (interfacestring.Trim() == "loopback")
listenInterface = System.Net.IPAddress.Loopback;
@@ -172,7 +172,7 @@ namespace Duplicati.Server.WebServer
if (!certValid)
server.Start(listenInterface, p);
else
- server.Start(listenInterface, p, cert, System.Security.Authentication.SslProtocols.Tls | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12, null, false);
+ server.Start(listenInterface, p, cert, System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12, null, false);
m_server = server;
m_server.ServerName = string.Format("{0} v{1}", Library.AutoUpdater.AutoUpdateSettings.AppName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
@@ -212,9 +212,10 @@ namespace Duplicati.Server.WebServer
{
HttpServer.HttpServer server = new HttpServer.HttpServer();
- server.Add(new AuthenticationHandler());
+ if (string.Equals(Environment.GetEnvironmentVariable("SYNO_DSM_AUTH") ?? string.Empty, "1"))
+ server.Add(new SynologyAuthenticationHandler());
- server.Add(new ControlHandler());
+ server.Add(new AuthenticationHandler());
server.Add(new RESTHandler());
@@ -289,7 +290,7 @@ namespace Duplicati.Server.WebServer
server.Add(proxy_files);
}
- var fh = new FileModule("/", webroot);
+ var fh = new FileModule("/", webroot, true);
AddMimeTypes(fh);
server.Add(fh);
diff --git a/Duplicati/Server/WebServer/SynologyAuthenticationHandler.cs b/Duplicati/Server/WebServer/SynologyAuthenticationHandler.cs
new file mode 100644
index 000000000..37c49f084
--- /dev/null
+++ b/Duplicati/Server/WebServer/SynologyAuthenticationHandler.cs
@@ -0,0 +1,288 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using HttpServer.HttpModules;
+
+namespace Duplicati.Server.WebServer
+{
+ /// <summary>
+ /// Helper class for enforcing the built-in authentication on Synology DSM
+ /// </summary>
+ public class SynologyAuthenticationHandler : HttpModule
+ {
+ /// <summary>
+ /// The path to the login.cgi script
+ /// </summary>
+ private readonly string LOGIN_CGI = GetEnvArg("SYNO_LOGIN_CGI", "/usr/syno/synoman/webman/login.cgi");
+ /// <summary>
+ /// The path to the authenticate.cgi script
+ /// </summary>
+ private readonly string AUTH_CGI = GetEnvArg("SYNO_AUTHENTICATE_CGI", "/usr/syno/synoman/webman/modules/authenticate.cgi");
+ /// <summary>
+ /// A flag indicating if only admins are allowed
+ /// </summary>
+ private readonly bool ADMIN_ONLY = !(GetEnvArg("SYNO_ALL_USERS", "0") == "1");
+ /// <summary>
+ /// A flag indicating if the XSRF token should be fetched automatically
+ /// </summary>
+ private readonly bool AUTO_XSRF = GetEnvArg("SYNO_AUTO_XSRF", "1") == "1";
+
+ /// <summary>
+ /// A flag indicating that the auth-module is fully disabled
+ /// </summary>
+ private readonly bool FULLY_DISABLED;
+
+ /// <summary>
+ /// Re-evealuate the logins periodically to ensure it is still valid
+ /// </summary>
+ private readonly TimeSpan CACHE_TIMEOUT = TimeSpan.FromMinutes(3);
+
+ /// <summary>
+ /// A cache of previously authenticated logins
+ /// </summary>
+ private readonly Dictionary<string, DateTime> m_logincache = new Dictionary<string, DateTime>();
+
+ /// <summary>
+ /// The loca guarding the login cache
+ /// </summary>
+ private object m_lock = new object();
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:Duplicati.Server.WebServer.SynologyAuthenticationHandler"/> class.
+ /// </summary>
+ public SynologyAuthenticationHandler()
+ {
+ Console.WriteLine("Enabling Synology integrated authentication handler");
+ var disable = false;
+ if (!File.Exists(LOGIN_CGI))
+ {
+ Console.WriteLine("Disabling webserver as the login script is not found: {0}", LOGIN_CGI);
+ disable = true;
+ }
+ if (!File.Exists(AUTH_CGI))
+ {
+ Console.WriteLine("Disabling webserver as the auth script is not found: {0}", AUTH_CGI);
+ disable = true;
+ }
+
+ FULLY_DISABLED = disable;
+ }
+
+ /// <summary>
+ /// Processes the request
+ /// </summary>
+ /// <returns><c>true</c> if the request is handled <c>false</c> otherwise.</returns>
+ /// <param name="request">The request.</param>
+ /// <param name="response">The response.</param>
+ /// <param name="session">The session.</param>
+ public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
+ {
+ if (FULLY_DISABLED)
+ {
+ response.Status = System.Net.HttpStatusCode.ServiceUnavailable;
+ response.Reason = "The system is incorrectly configured";
+ return true;
+ }
+
+ var limitedAccess =
+ request.Uri.AbsolutePath.StartsWith(RESTHandler.API_URI_PATH, StringComparison.OrdinalIgnoreCase)
+ ||
+ request.Uri.AbsolutePath.StartsWith(AuthenticationHandler.LOGIN_SCRIPT_URI, StringComparison.OrdinalIgnoreCase)
+ ||
+ request.Uri.AbsolutePath.StartsWith(AuthenticationHandler.LOGOUT_SCRIPT_URI, StringComparison.OrdinalIgnoreCase);
+
+ if (!limitedAccess)
+ return false;
+
+ var tmpenv = new Dictionary<string, string>();
+
+ tmpenv["REMOTE_ADDR"] = request.RemoteEndPoint.Address.ToString();
+ tmpenv["REMOTE_PORT"] = request.RemoteEndPoint.Port.ToString();
+
+ if (!string.IsNullOrWhiteSpace(request.Headers["X-Real-IP"]))
+ tmpenv["REMOTE_ADDR"] = request.Headers["X-Real-IP"];
+ if (!string.IsNullOrWhiteSpace(request.Headers["X-Real-IP"]))
+ tmpenv["REMOTE_PORT"] = request.Headers["X-Real-Port"];
+
+ var loginid = request.Cookies["id"]?.Value;
+ if (!string.IsNullOrWhiteSpace(loginid))
+ tmpenv["HTTP_COOKIE"] = "id=" + loginid;
+
+ var xsrftoken = request.Headers["X-Syno-Token"];
+ if (string.IsNullOrWhiteSpace(xsrftoken))
+ xsrftoken = request.QueryString["SynoToken"]?.Value;
+
+ var cachestring = BuildCacheKey(tmpenv, xsrftoken);
+
+ DateTime cacheExpires;
+ if (m_logincache.TryGetValue(cachestring, out cacheExpires) && cacheExpires > DateTime.Now)
+ {
+ // We do not refresh the cache, as we need to ask the synology auth system periodically
+ return false;
+ }
+
+ if (string.IsNullOrWhiteSpace(xsrftoken) && AUTO_XSRF)
+ {
+ var authre = new Regex(@"""SynoToken""\s?\:\s?""(?<token>[^""]+)""");
+ try
+ {
+ var resp = ShellExec(LOGIN_CGI, env: tmpenv).Result;
+
+ var m = authre.Match(resp);
+ if (m.Success)
+ xsrftoken = m.Groups["token"].Value;
+ else
+ throw new Exception("Unable to get XSRF token");
+ }
+ catch (Exception ex)
+ {
+ response.Status = System.Net.HttpStatusCode.InternalServerError;
+ response.Reason = "The system is incorrectly configured";
+ return true;
+
+ }
+ }
+
+ if (!string.IsNullOrWhiteSpace(xsrftoken))
+ tmpenv["HTTP_X_SYNO_TOKEN"] = xsrftoken;
+
+ cachestring = BuildCacheKey(tmpenv, xsrftoken);
+
+ var username = GetEnvArg("SYNO_USERNAME");
+ if (string.IsNullOrWhiteSpace(username))
+ {
+ try
+ {
+ username = ShellExec(AUTH_CGI, shell: false, exitcode: 0, env: tmpenv).Result;
+ }
+ catch (Exception ex)
+ {
+ response.Status = System.Net.HttpStatusCode.InternalServerError;
+ response.Reason = "The system is incorrectly configured";
+ return true;
+ }
+ }
+
+ if (string.IsNullOrWhiteSpace(username))
+ {
+ response.Status = System.Net.HttpStatusCode.Forbidden;
+ response.Reason = "Permission denied, not logged in";
+ return true;
+ }
+
+ username = username.Trim();
+
+ if (ADMIN_ONLY)
+ {
+ var groups = GetEnvArg("SYNO_GROUP_IDS");
+
+ if (string.IsNullOrWhiteSpace(groups))
+ groups = ShellExec("id", "-G '" + username.Trim().Replace("'", "\\'") + "'", exitcode: 0).Result ?? string.Empty;
+ if (!groups.Split(new char[] { ' ' }).Contains("101"))
+ {
+ response.Status = System.Net.HttpStatusCode.Forbidden;
+ response.Reason = "Administrator login required";
+ return true;
+ }
+ }
+
+ // We are now authenticated, add to cache
+ m_logincache[cachestring] = DateTime.Now + CACHE_TIMEOUT;
+ return false;
+ }
+
+ /// <summary>
+ /// Builds a cache key from the environment data
+ /// </summary>
+ /// <returns>The cache key.</returns>
+ /// <param name="values">The environment.</param>
+ /// <param name="xsrftoken">The XSRF token.</param>
+ private static string BuildCacheKey(Dictionary<string, string> values, string xsrftoken)
+ {
+ if (!values.ContainsKey("REMOTE_ADDR") || !values.ContainsKey("REMOTE_PORT") || !values.ContainsKey("HTTP_COOKIE"))
+ return null;
+
+ return string.Format("{0}:{1}/{2}?{3}", values["REMOTE_ADDR"], values["REMOTE_PORT"], values["HTTP_COOKIE"], xsrftoken);
+ }
+
+ /// <summary>
+ /// Runs an external command
+ /// </summary>
+ /// <returns>The stdout data.</returns>
+ /// <param name="command">The executable</param>
+ /// <param name="args">The executable and the arguments.</param>
+ /// <param name="shell">If set to <c>true</c> use the shell context for execution.</param>
+ /// <param name="exitcode">Set the value to check for a particular exitcode.</param>
+ private static async Task<string> ShellExec(string command, string args = null, bool shell = false, int exitcode = -1, Dictionary<string, string> env = null)
+ {
+ var psi = new ProcessStartInfo()
+ {
+ FileName = command,
+ Arguments = shell ? null : args,
+ UseShellExecute = false,
+ RedirectStandardInput = shell,
+ RedirectStandardOutput = true
+ };
+
+ if (env != null)
+ foreach (var pk in env)
+ psi.EnvironmentVariables[pk.Key] = pk.Value;
+
+ using (var p = System.Diagnostics.Process.Start(psi))
+ {
+ if (shell && args != null)
+ await p.StandardInput.WriteLineAsync(args);
+
+ var res = p.StandardOutput.ReadToEndAsync();
+
+ var tries = 10;
+ var ms = (int)TimeSpan.FromSeconds(0.5).TotalMilliseconds;
+ while (tries > 0 && !p.HasExited)
+ {
+ tries--;
+ p.WaitForExit(ms);
+ }
+
+ if (!p.HasExited)
+ try { p.Kill(); }
+ catch { }
+
+ if (!p.HasExited || (p.ExitCode != exitcode && exitcode != -1))
+ throw new Exception(string.Format("Exit code was: {0}, stdout: {1}", p.ExitCode, res));
+ return await res;
+ }
+ }
+
+ /// <summary>
+ /// Gets the environment variable argument.
+ /// </summary>
+ /// <returns>The environment variable.</returns>
+ /// <param name="key">The name of the environment variable.</param>
+ /// <param name="default">The default value.</param>
+ private static string GetEnvArg(string key, string @default = null)
+ {
+ var res = Environment.GetEnvironmentVariable(key);
+ return string.IsNullOrWhiteSpace(res) ? @default : res.Trim();
+ }
+ }
+}
diff --git a/Duplicati/Server/packages.config b/Duplicati/Server/packages.config
index e1fae9c6a..efc598b08 100644
--- a/Duplicati/Server/packages.config
+++ b/Duplicati/Server/packages.config
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+ <package id="BouncyCastle" version="1.8.1" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/Server/webroot/greeno/images/ajax-loader-16.gif b/Duplicati/Server/webroot/greeno/images/ajax-loader-16.gif
deleted file mode 100755
index 1b5b2fde4..000000000
--- a/Duplicati/Server/webroot/greeno/images/ajax-loader-16.gif
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/ajax-loader-32.gif b/Duplicati/Server/webroot/greeno/images/ajax-loader-32.gif
deleted file mode 100644
index 3288d1035..000000000
--- a/Duplicati/Server/webroot/greeno/images/ajax-loader-32.gif
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/ajax-loader-66.gif b/Duplicati/Server/webroot/greeno/images/ajax-loader-66.gif
deleted file mode 100644
index 0ca7ada96..000000000
--- a/Duplicati/Server/webroot/greeno/images/ajax-loader-66.gif
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/clock.png b/Duplicati/Server/webroot/greeno/images/clock.png
deleted file mode 100644
index 31fe66f30..000000000
--- a/Duplicati/Server/webroot/greeno/images/clock.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/donate.png b/Duplicati/Server/webroot/greeno/images/donate.png
deleted file mode 100644
index c8fd3ad3b..000000000
--- a/Duplicati/Server/webroot/greeno/images/donate.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/generic-file.png b/Duplicati/Server/webroot/greeno/images/generic-file.png
deleted file mode 100644
index d2894e886..000000000
--- a/Duplicati/Server/webroot/greeno/images/generic-file.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/hourglass.png b/Duplicati/Server/webroot/greeno/images/hourglass.png
deleted file mode 100644
index f47a214de..000000000
--- a/Duplicati/Server/webroot/greeno/images/hourglass.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/menu-grey-small.png b/Duplicati/Server/webroot/greeno/images/menu-grey-small.png
deleted file mode 100644
index 0ab4ea03c..000000000
--- a/Duplicati/Server/webroot/greeno/images/menu-grey-small.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/menu-grey.png b/Duplicati/Server/webroot/greeno/images/menu-grey.png
deleted file mode 100644
index 1f58713a9..000000000
--- a/Duplicati/Server/webroot/greeno/images/menu-grey.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/menu-white.png b/Duplicati/Server/webroot/greeno/images/menu-white.png
deleted file mode 100644
index 076bb800e..000000000
--- a/Duplicati/Server/webroot/greeno/images/menu-white.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/pause.png b/Duplicati/Server/webroot/greeno/images/pause.png
deleted file mode 100644
index b9d3e450f..000000000
--- a/Duplicati/Server/webroot/greeno/images/pause.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/play.png b/Duplicati/Server/webroot/greeno/images/play.png
deleted file mode 100644
index 65119fdf7..000000000
--- a/Duplicati/Server/webroot/greeno/images/play.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/plus.png b/Duplicati/Server/webroot/greeno/images/plus.png
deleted file mode 100644
index c10846aea..000000000
--- a/Duplicati/Server/webroot/greeno/images/plus.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/restore.png b/Duplicati/Server/webroot/greeno/images/restore.png
deleted file mode 100644
index 0f2ba9a57..000000000
--- a/Duplicati/Server/webroot/greeno/images/restore.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/settings.png b/Duplicati/Server/webroot/greeno/images/settings.png
deleted file mode 100644
index 363eef0f6..000000000
--- a/Duplicati/Server/webroot/greeno/images/settings.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/images/small-close.png b/Duplicati/Server/webroot/greeno/images/small-close.png
deleted file mode 100644
index 949915e78..000000000
--- a/Duplicati/Server/webroot/greeno/images/small-close.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/index.html b/Duplicati/Server/webroot/greeno/index.html
deleted file mode 100644
index 97f615b6e..000000000
--- a/Duplicati/Server/webroot/greeno/index.html
+++ /dev/null
@@ -1,713 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=9" />
-<title>Backup</title>
-
- <link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
-
- <link rel="stylesheet" type="text/css" href="stylesheets/green-theme/jquery-ui-1.10.3.min.css" />
- <link rel="stylesheet" type="text/css" href="stylesheets/common.css" />
- <link rel="stylesheet" type="text/css" href="stylesheets/jstree/style.css" />
- <link rel="stylesheet" type="text/css" href="stylesheets/main.css" />
- <link rel="stylesheet" type="text/css" href="stylesheets/editdialog.css" />
- <link rel="stylesheet" type="text/css" href="stylesheets/restoredialog.css" />
- <link rel="stylesheet" type="text/css" href="stylesheets/logwindow.css" />
- <link rel="stylesheet" type="text/css" href="../oem/greeno/stylesheets/oem.css" />
- <link rel="stylesheet" type="text/css" href="../customized/customized.css" />
-
-
-<!--[if lt IE 9]>
- <script type="text/javascript" src="scripts/jquery-1.11.0.min.js"></script>
-<![endif]-->
- <script type="text/javascript" src="scripts/jquery-2.0.3.min.js"></script>
- <script type="text/javascript" src="scripts/jquery-ui-1.10.3.min.js"></script>
- <script type="text/javascript" src="scripts/jquery.tmpl.min.js"></script>
- <script type="text/javascript" src="scripts/jquery.watermark.min.js"></script>
- <script type="text/javascript" src="scripts/jstree.min.js"></script>
- <script type="text/javascript" src="scripts/json2.js"></script>
- <script type="text/javascript" src="scripts/oldbrowsersupport.js"></script>
- <script type="text/javascript" src="scripts/config.js"></script>
- <script type="text/javascript" src="scripts/app.js"></script>
- <script type="text/javascript" src="scripts/editdialog.js"></script>
- <script type="text/javascript" src="scripts/edituri.js"></script>
- <script type="text/javascript" src="scripts/restoredialog.js"></script>
- <script type="text/javascript" src="scripts/folderbrowser.js"></script>
- <script type="text/javascript" src="scripts/logwindow.js"></script>
- <script type="text/javascript" src="scripts/plugins.js"></script>
- <script type="text/javascript" src="scripts/hideShowPassword.min.js"></script>
- <script type="text/javascript" src="scripts/jquery.timeago.js"></script>
- <script type="text/javascript" src="scripts/jquery.noty.packaged.min.js"></script>
- <script type="text/javascript" src="scripts/zxcvbn.js"></script>
- <script type="text/javascript" src="scripts/cryptojs.js"></script>
- <script type="text/javascript" src="../oem/greeno/scripts/oem.js"></script>
- <script type="text/javascript" src="../customized/customized.js"></script>
-
-
- <script id="backup-item-template" type="text/x-jquery-tmpl">
- <div id="backup-${Backup.ID}" class="main-backup-entry">
-
- <div id="backup-control-${Backup.ID}" class="main-backup-control">
- </div>
-
- <div class="caption-text">${Backup.Name}</div>
- <ul class="hint-text last-run-time" style="display: none" >
- <li class="hint-text-caption">Last successful run:</li>
- <li class="backup-last-run" alt="${Backup.Metadata.LastBackupStarted}">${$.timeago($.parseDate(Backup.Metadata.LastBackupStarted))}</li>
- </ul>
- <ul class="hint-text next-run-time" style="display: none">
- <li class="hint-text-caption">Next run:</li>
- <li class="backup-next-run"></li>
- </ul>
-
- <ul class="hint-text last-run-source-size">
- <li class="hint-text-caption">Source:</li>
- <li class="source-size">${Backup.Metadata.SourceSizeString || 'No data'}</li>
- </ul>
- <ul class="hint-text last-run-target-size">
- <li class="hint-text-caption">Backup:</li>
- <li class="target-size">${Backup.Metadata.TargetSizeString || 'No data'}</li>
- </ul>
- </div>
- </script>
- <script id="backup-option-template" type="text/x-jquery-tmpl">
- <div class="backup-option ${Deprecated}">
- <div>
- <a id="${Name}" class="action-link backup-option-name backup-option-link">${Name}</a> : <div class="backup-option-short">${ShortDescription}</div>
- </div>
- <div class="backup-option-summary">
- <div class="backup-option-type">Type: ${Type}</div>,
- <div class="backup-option-default">Default value: ${DefaultValue}</div>
- </div>
- <div class="backup-option-long">${LongDescription}</div>
- </div>
- </script>
-
- <script id="log-data-template" type="text/x-jquery-tmpl">
- <div class="log-entry">
- <div class="log-backupid">${BackupID}</div>
- <div class="log-timestamp" title="${Timestamp*1000}">${Timestamp*1000}</div>
- <div class="log-message">${Message}</div>
- <div class="log-exception">${Exception}</div>
- </div>
- </script>
-
- <script id="live-log-data-template" type="text/x-jquery-tmpl">
- <div class="log-entry">
- <div class="log-id">${BackupID}</div>
- <div class="log-timestamp" title="${When}">${When}</div>
- <div class="log-message">${Message}</div>
- <div class="log-exception">${Exception}</div>
- </div>
- </script>
-
- <script id="log-backup-general-template" type="text/x-jquery-tmpl">
- <div class="log-entry">
- <div class="log-operationid">${BackupID}</div>
- <div class="log-timestamp" title="${Timestamp*1000}">${Timestamp*1000}</div>
- <div class="log-type">${Type}</div>
- <div class="log-message">${Message}</div>
- <div class="log-exception">${Exception}</div>
- </div>
- </script>
-
- <script id="log-backup-remote-template" type="text/x-jquery-tmpl">
- <div class="log-entry">
- <div class="log-operationid">${OperationID}</div>
- <div class="log-timestamp" title="${Timestamp*1000}">${Timestamp*1000}</div>
- <div class="log-type">${Operation}</div>
- <div class="log-path">${Path}</div>
- <div class="log-data">${Data}</div>
- </div>
- </script>
-
- <script id="about-dialog-template" type="text/x-jquery-tmpl">
- <li class="about-library-entry">
- <div class="about-library-name"><a href="${link}" target="blank">${name}</a></div>
- <div class="about-library-description">${description}.</div>
- <div class="about-library-license"> <a href="${licenselink}">${license} licensed.</a></div>
- <div class="about-library-notes"></div>
- </li>
- </script>
-
-</head>
-<body>
- <header>
- <div id="click-intercept"></div>
- <div id="main-topbar">
- <div class="content-wrap padded">
- <div id="main-appname">Duplicati</div>
-
- <ul class="main-shortcuts">
- <li id="main-donate" class="main-icon-donate" style="display: none"></li>
- <li id="main-control" class="main-icon-pause"></li>
- <li id="main-settings" class="main-icon-settings"></li>
- </ul>
-
- <ul id="main-control-menu" class="menu">
- <li id="main-control-menu-settings"><a>Settings...</a></li>
- <li>-</li>
- <li><a>Pause</a>
- <ul id="main-control-menu-pause-submenu" class="menu">
- <li id="main-control-menu-pause-submenu-5m"><a>5 minutes</a></li>
- <li id="main-control-menu-pause-submenu-10m"><a>10 minutes</a></li>
- <li id="main-control-menu-pause-submenu-15m"><a>15 minutes</a></li>
- <li id="main-control-menu-pause-submenu-30m"><a>30 minutes</a></li>
- <li id="main-control-menu-pause-submenu-1h"><a>1 hour</a></li>
- </ul>
- </li>
- <li id="main-control-menu-throttle"><a>Throttle ...</a></li>
- <li>-</li>
- <li id="main-control-menu-import"><a>Import backup job...</a></li>
- <li id="main-control-menu-restore-direct"><a>Restore from target ...</a></li>
- <li>-</li>
- <li id="main-control-menu-updates"><a>Check for updates</a></li>
- <li id="main-control-menu-check-updates"><a>Check for updates</a></li>
- <li id="main-control-menu-log"><a>Show log ...</a></li>
- <li id="main-control-menu-options"><a>Options ...</a></li>
- <li id="main-control-menu-about"><a>About ...</a></li>
- </ul>
- </div>
- </div>
-
- <div class="main-status-area-outer">
- <div class="content-wrap padded">
- <div id="main-status-area">
- <div id="main-status-area-text">
- My Important Backup
- </div>
- <div id="main-status-area-cancel-button"></div>
- <div id="main-status-area-progress-outer">
- <div id="main-status-area-progress-bar" class="">
- </div>
- <div id="main-status-area-progress-text">
- Processing 123456 files ...
- </div>
- </div>
- </div>
- </div>
- </div>
- </header>
- <section>
- <ul id="backup-context-menu" class="context-popup-menu menu" style="display: none">
- <li><u><b>Operations</b></u></li>
- <li id="backup-details-run"><a>Run backup now!</a></li>
- <li id="backup-details-restore"><a>Restore files ...</a></li>
- <li>-</li>
- <li><u><b>Configuration</b></u></li>
- <li id="backup-details-edit"><a>Edit ...</a></li>
- <!-- <li id="backup-details-copy"><a>Copy</a></li> -->
- <li id="backup-details-export"><a>Export ...</a></li>
- <li id="backup-details-delete"><a>Delete</a></li>
- <li>-</li>
- <li><u><b>Advanced</b></u></li>
- <li id="backup-details-delete-local"><a>Delete local database</a></li>
- <!-- <li id="backup-details-delete-remote"><a>Delete remote data</a></li> -->
- <li id="backup-details-repair"><a>Repair local database</a></li>
- <li id="backup-details-verify"><a>Verify backup files</a></li>
- <li>-</li>
- <li><u><b>Reporting</b></u></li>
- <li id="backup-details-show-log"><a>Show log ...</a></li>
- <li id="backup-details-send-report"><a>Create bug report ...</a></li>
- </ul>
-
- <div id="main-list">
- <div id="main-list-container" class="content-wrap padded">
- <div id="main-newbackup" class="main-backup-action-buttons">
- <div class="main-backup-control main-icon-plus"></div>
- <div class="caption-text">Add new backup</div>
- </div>
- <div id="main-restorebackup" class="main-backup-action-buttons">
- <div class="main-backup-control main-icon-restore"></div>
- <div class="caption-text">Restore from target</div>
- </div>
- </div>
- </div>
-
- <div id="loading-dialog" class="modal-dialog" title="Loading...">
- <div id="main-list-loader-icon" class="large-loader-icon"></div>
- </div>
-
- <div id="connection-lost-dialog" class="modal-dialog" title="Server connection lost">
- <div id="connection-lost-dialog-text"></div>
- <div id="connection-lost-dialog-error"></div>
- </div>
-
- <div id="edit-dialog" class="modal-dialog tabs edit-dialog" title="Edit backup">
- <ul>
- <li><a href="#edit-tab-general">General</a></li>
- <li><a href="#edit-tab-sourcedata">Source Data</a></li>
- <li><a href="#edit-tab-schedule">Schedule</a></li>
- <li><a href="#edit-tab-options">Options</a></li>
- </ul>
-
- <form id="edit-dialog-form">
- <div id="edit-tab-general">
- <div class="input-block">
- <div class="edit-dialog-label" title="Choose a descriptive name for your backup job">Name</div>
- <input type="text" name="backup-name" id="backup-name" class="ui-corner-all" />
- </div>
- <!--
- <div class="input-block">
- <div class="edit-dialog-label">Backup labels</div>
- <input type="text" name="backup-labels" id="backup-labels" class="ui-corner-all" />
- </div>
- -->
- <div class="input-block">
- <div class="edit-dialog-label action-link" id="backup-uri-label" title="The destination where the backup data is stored is supplied in the form of a URI. Click the link here to edit the individual parts of the connection URI.">Backup to…</div>
- <div class="field-group">
- <textarea type="text" name="backup-uri" id="backup-uri" value="" class="ui-corner-all" rows="3"></textarea>
- </div>
- </div>
-
- <div id="encryption-area">
- <div class="input-block">
- <div class="edit-dialog-label" title="It is recommended to encrypt all backups stored on remote servers">Encryption</div>
- <div class="field-group">
- <select type="text" name="encryption-method" id="encryption-method" class="ui-corner-all">
- <option>AES 256 bit</option>
- <option>GNU Privacy Guard</option>
- </select>
- </div>
- </div>
-
- <div id="encryption-password-area">
- <div class="input-block">
- <div class="edit-dialog-label">Passphrase</div>
- <div class="field-group">
- <input type="password" name="encryption-password" id="encryption-password" value="" class="ui-corner-all" />
- </div>
- </div>
-
- <div class="input-block">
- <div class="edit-dialog-label" id="repeat-password-label">Repeat passphrase</div>
- <div class="field-group">
- <input type="password" name="repeat-password" id="repeat-password" value="" class="ui-corner-all" />
- <ul class="inline-links">
- <li><div id="toggle-show-password" class="action-link">Show</div></li>
- <li><div id="generate-password" class="action-link">Generate</div></li>
- <li><div id="backup-password-strength" class="" title="Time it takes to break this password">Strength: unknown</div></li>
- </ul>
- </div>
- </div>
- </div>
- </div>
-
- </div>
-
- <div id="edit-tab-sourcedata">
-
- <!-- <div class="input-wrapper">
- <div class="edit-dialog-label" title="Choose if the backup configuration should be stored">Store configuration</div>
- <select id="store-task-config" name="store-task-config">
- <option value="false">Don't store setup</option>
- <option value="true">Store this backup job setup</option>
- <option value="all">Store all backup job setups</option>
- </select>
- </div>
-
- <div class="clearfix"></div> -->
-
- <div id="source-folder-paths" class="empty">
- <div id="source-folder-droptarget"></div>
- <div id="source-folder-paths-hint" class="hint-text">Click the &quot;Add&quot; button to add folders</div>
- </div>
-
- <div class="clearfix"></div>
-
- <input id="source-folder-list" name="source-folder-list" type="hidden" />
- <div id="source-folder-entry">
- <input id="source-folder-path-text" type="text" />
- <div id="source-folder-path-add" class="button">Browse</div>
- </div>
-
- <div id="source-folder-filter-area">
- <div id="source-folder-filter-label" title="Enter filters, one per line. Lines starting with a plus are inclusions, lines starting with a minus are exclusions. Regular expression are entered inside hard brackets."><a href="https://github.com/duplicati/duplicati/wiki/How-do-filters-work%3F" target="_blank">Source data filters<div class="ui-icon ui-icon-info ui-icon-inline"></div></a></div>
- <textarea type="text" name="source-filters" id="source-filters" value="" class="ui-corner-all pre-style-text" rows="3"></textarea>
- </div>
-
-
- </div>
-
- <div id="edit-tab-schedule">
- <input id="use-scheduled-run" type="checkbox" />
- <div>Run regularly at the specified times</div>
-
- <div id="use-scheduled-run-details">
- <div class="hint-line-last">If a date was missed, the job will run as soon as possible.</div>
-
- <div class="clearfix"></div>
-
- <div class="edit-dialog-label" title="The next time the backup is started">Next time</div>
- <div class="input-wrapper">
- <input type="time" id="next-run-time" name="next-run-time"/>
- <input type="date" id="next-run-date" name="next-run-date" />
- </div>
-
- <div class="clearfix"></div>
-
- <div class="edit-dialog-label" title="How often the backup is repeated">Run again every</div>
- <div class="input-wrapper">
- <input type="number" id="repeat-run-number" name="repeat-run-number"/>
- <select id="repeat-run-multiplier" name="repeat-run-multiplier">
- <option value="h">hours</option>
- <option value="D">days</option>
- <option value="W">weeks</option>
- <option value="M">months</option>
- <option value="Y">years</option>
- <option value="">custom</option>
- </select>
- </div>
-
- <div class="clearfix"></div>
-
- <div class="edit-dialog-label">Allowed days</div>
- <div class="input-wrapper">
- <input type="checkbox" class="simple-checkbox" id="allow-day-mon" name="allow-day-mon" />
- <div class="days-label">Mon</div>
- <input type="checkbox" class="simple-checkbox" id="allow-day-tue" name="allow-day-tue" />
- <div class="days-label">Tue</div>
- <input type="checkbox" class="simple-checkbox" id="allow-day-wed" name="allow-day-wed" />
- <div class="days-label">Wed</div>
- <input type="checkbox" class="simple-checkbox" id="allow-day-thu" name="allow-day-thu" />
- <div class="days-label">Thu</div>
- <input type="checkbox" class="simple-checkbox" id="allow-day-fri" name="allow-day-fri" />
- <div class="days-label">Fri</div>
- <input type="checkbox" class="simple-checkbox" id="allow-day-sat" name="allow-day-sat" />
- <div class="days-label">Sat</div>
- <input type="checkbox" class="simple-checkbox" id="allow-day-sun" name="allow-day-sun" />
- <div class="days-label">Sun</div>
- </div>
- </div>
- </div>
-
- <div id="edit-tab-options">
-
- <div class="input-block">
- <div class="edit-dialog-label" title="Duplicati splits backups into smaller files. A smaller size (e.g. 10MB) is recommended for slow and unstable connections. A larger size (e.g. 200MB) is recommended in LAN environments.">Max backup file size<div class="ui-icon ui-icon-info ui-icon-inline"></div></div>
- <div class="input-wrapper">
- <input type="number" id="dblock-size-number" name="dblock-size-number" />
- <select id="dblock-size-multiplier" name="dblock-size-multiplier">
- <option value="kb">KByte</option>
- <option value="mb">MByte</option>
- <option value="gb">GByte</option>
- <option value="tb">TByte</option>
- </select>
- </div>
- </div>
-
- <div class="clearfix"></div>
-
- <div class="input-block">
-
- <div class="edit-dialog-label" title="Define how many backups you want to keep stored. Old backups are removed if Duplicati can free a significant amount of space. This is done during compacting.">Keep backups<div class="ui-icon ui-icon-info ui-icon-inline"></div></div>
- <div class="input-wrapper">
- <select id="keep-time-type" name="keep-time-type">
- <option value="">forever</option>
- <option value="keep-time">for a specific time</option>
- <option value="keep-versions">a specific number</option>
- </select>
- <input type="number" id="keep-time-number" name="keep-time-number" />
- <select id="keep-time-multiplier" name="keep-time-multiplier">
- <option value="D">Days</option>
- <option value="W">Weeks</option>
- <option value="M">Months</option>
- <option value="Y">Years</option>
- </select>
- </div>
- </div>
-
- <div class="clearfix"></div>
-
- <div class="edit-dialog-label" id="backup-options-link" title="Advanced options can be specified command-line style. One option per line like --option=value. Click here to see a list of options"><a class="action-link">Options<div class="ui-icon ui-icon-info ui-icon-inline"></div></a></div>
-
- <textarea id="backup-options" rows="4" class="pre-style-text" name="backup-options"></textarea>
-
- </div>
- </form>
- </div>
-
- <div id="connection-uri-dialog" class="modal-dialog edit-dialog" style="display: none" title="Connection URI">
- <form id="edit-uri-form">
- <div class="edit-dialog-label">Target Type</div>
- <div class="field-group">
- <select id="backend-type" name="backend-type"></select>
- <input type="checkbox" id="server-use-ssl" name="server-use-ssl" value="use-ssl"/><div class="checkbox-label" id="server-use-ssl-label" >Use SSL</div>
- </div>
-
- <div class="clearfix"></div>
-
- <div class="edit-dialog-label" id="server-name-and-port-label">Server &amp; Port</div>
- <div class="field-group" id="server-name-and-port">
- <input type="text" name="server-name" id="server-name" value="" class="text ui-widget-content ui-corner-all" />
- <input type="text" name="server-port" id="server-port" value="" class="text ui-widget-content ui-corner-all" />
- </div>
-
- <div class="clearfix"></div>
-
- <div class="edit-dialog-label" id="server-path-label">Path on server</div>
- <input type="text" name="server-path" id="server-path" class="text ui-widget-content ui-corner-all" />
-
- <div class="clearfix"></div>
-
- <div id="server-username-and-password">
- <div id="server-username-label" class="edit-dialog-label">Username</div>
- <input type="text" name="server-username" id="server-username" class="text ui-widget-content ui-corner-all" />
-
- <div class="clearfix"></div>
-
- <div id="server-password-label" class="edit-dialog-label">Password</div>
- <input type="password" name="server-password" id="server-password" class="text ui-widget-content ui-corner-all" />
- </div>
-
- <div class="clearfix"></div>
-
- <div class="edit-dialog-label" id="server-options-label" title="Advanced options can be specified command-line style. One option per line like --option=value. Click here to see a list of options"><a class="action-link">Options<div class="ui-icon ui-icon-info"></div></a></div>
- <textarea id="server-options" class="pre-style-text" name="server-options"></textarea>
-
- <div id="edit-dialog-extensions"></div>
- </form>
- </div>
-
- <div id="restore-dialog" class="modal-dialog restore-dialog" title="Restore files &amp; folders">
- <form id="restore-form">
- <div id="restore-files-page">
- <div id="restore-search-section">
- <input type="search" id="restore-search" /><div id="restore-search-loader" class="small-loader-icon"></div>
-
- <select id="restore-version">
- <option value="0">Latest</option>
- </select>
- </div>
-
- <div id="restore-files-tree"></div>
- </div>
-
- <div id="restore-path-page">
- <div id="restore-hint-target" class="hint-text">Where do you want to restore the files to?</div>
- <div><input id="restore-overwrite-target-original" type="radio" name="restore-target" value="original" />Original location</div>
- <div><input id="restore-overwrite-target-other" type="radio" name="restore-target" value="other" />Pick a new location</div>
-
- <div id="restore-target-path-area">
- <input type="text" id="restore-target-path" /><input type="button" id="restore-target-path-browse" class="browse-button" value="..." />
- </div>
-
- <div class="clearfix"></div>
-
- <div id="restore-hint-overwrite" class="hint-text">How do you want to handle existing files?</div>
- <div><input id="restore-overwrite-overwrite" type="radio" name="restore-overwrite" value="overwrite" />Overwrite</div>
- <div><input id="restore-overwrite-keep" type="radio" name="restore-overwrite" value="keep" />Save different versions with timestamp in file name</div>
-
- <div class="clearfix"></div>
-
- <div id="restore-hint-metadata" class="hint-text">Permissions</div>
-
- <div><input id="restore-metadata-permissions" type="checkbox" name="restore-metadata" value="permissions" />Restore read/write permissions</div>
- </div>
-
- <div id="restore-complete-page">
- <div class="hint-text">Your files and folders have been restored successfully.</div>
- <div id="restore-hint-donate" class="hint-text">Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest 10€ for private use and 100€ for commercial use.</div>
- <div id="restore-hint-paypal" class="hint-text"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal%40hexad%2edk&item_name=Duplicati%20Donation&no_shipping=2&no_note=1&tax=0&currency_code=EUR&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=US" target="blank">VISA, Mastercard, ... via Paypal</div>
- <div id="restore-hint-bitcoin" class="hint-text"><a href="bitcoin:1L74qa1n5SFKwwyHhECTHBJgcf6WT2rJKf" target="blank">Bitcoin: 1L74qa1n5SFKwwyHhECTHBJgcf6WT2rJKf</a></div>
-
- </div>
- </form>
- </div>
-
-
- <div id="backup-options-dialog" class="modal-dialog" title="Available options"></div>
-
- <div id="folder-browse-dialog" class="modal-dialog" title="Choose folder"></div>
-
- <div id="log-dialog" class="modal-dialog" title="Log data">
- <ul>
- <li><a href="#log-tab-stored">Stored</a></li>
- <li><a href="#log-tab-live">Live</a></li>
- </ul>
-
- <div id="log-tab-stored">
- </div>
-
- <div id="log-tab-live">
- <div>Select a log level and see the live message while a backup is running.</div>
- <select id="log-tab-live-level"></select>
- </div>
-
- </div>
-
- <div id="backup-log-dialog" class="modal-dialog" title="Log data">
- <ul>
- <li><a href="#backup-log-tab-general">General</a></li>
- <li><a href="#backup-log-tab-remote">Remote</a></li>
- </ul>
-
- <div id="backup-log-tab-general">
- </div>
-
- <div id="backup-log-tab-remote">
- </div>
- </div>
-
- <div id="about-dialog" class="modal-dialog" title="About">
- <ul>
- <li><a href="#about-dialog-tab-general">General</a></li>
- <li><a href="#about-dialog-tab-changelog">Changelog</a></li>
- <li><a href="#about-dialog-tab-libraries">Libraries</a></li>
- </ul>
-
- <div id="about-dialog-tab-general">
- Duplicati was primarily developed by <a href="mailto:kenneth@duplicati.com">Kenneth Skovhede</a> and <a href="mailto:rene@duplicati.com">Rene Stach</a>. Duplicati can be downloaded from <a href="http://www.duplicati.com" target="blank">duplicati.com</a>. Duplicati is licensed under the <a href="https://www.gnu.org/licenses/lgpl.html">GNU Lesser General Public License</a>.
-
- <div id="about-dialog-current">You are currently running Duplicati <p id="about-dialog-current-version">unknown</p></div>
-
- <div id="about-dialog-tab-general-acknowledgements">
- Loading ...
- </div>
- </div>
-
- <div id="about-dialog-tab-changelog">
- Loading ...
- </div>
-
- <div id="about-dialog-tab-libraries">
- Duplicati is using the following third party libraries:
- <ul id="about-dialog-tab-thirdparty-list">
- <li>Loading ...</li>
- </ul>
- </div>
-
- </div>
-
- <div id="export-dialog" class="modal-dialog" title="Export ...">
- <form>
- <input type="radio" name="export-type" id="export-type-commandline" value="commandline" /><div class="export-dialog-label">As Command-line</div><br/>
- <input type="radio" name="export-type" id="export-type-file" value="file" /><div class="export-dialog-label">To File</div><br/>
- <input type="checkbox" name="use-encryption" id="export-use-encryption" /><div class="export-dialog-label">Encrypt with</div>
- <input type="password" name="encryption-password" id="export-encryption-password">
- </form>
- </div>
-
- <div id="import-dialog" class="modal-dialog" title="Import ...">
- <form id="import-dialog-form" enctype="multipart/form-data" method="POST">
- <div class="import-dialog-label">Configuration file:&nbsp;</div>
- <input type="file" name="config" id="import-dialog-file"></br></br>
-
- <div class="import-dialog-label">Passphrase (if encrypted):</div>
- <input type="password" name="passphrase" id="import-encryption-password">
-
- <input type="hidden" name="action" value="import-backup">
- <input type="hidden" name="callback" id="import-dialog-callback" value="">
- </form>
- </div>
-
- <div id="global-advanced-options-dialog" class="modal-dialog" title="Available options"></div>
-
- <div id="options-dialog" class="modal-dialog" title="Options">
- <div>
- <div class="options-header options-header-first">Access to user interface</div>
- <div>
- <div class="options-items">
- <input type="checkbox" id="webservice-password-enabled"/>
- <div id="webservice-password-label">Password</div>
- <input type="password" id="webservice-password" name="webservice-password"/>
- </div>
- </div>
-
- <div class="clearfix"></div>
-
- <div class="options-items">
- <input type="checkbox" id="webservice-remote-access-enabled"/>
- <div>Allow remote access (requires restart)</div>
- </div>
-
- </div>
-
- <div>
- <div class="options-header" title="To grant all processes and the network some time to recover after a startup or hibernation, you can delay backup jobs a little">Pause after startup or hibernation<div class="ui-icon ui-icon-info ui-icon-inline"></div></div>
- <div class="options-items">
- <div class="edit-dialog-label">Pause</div>
- <select id="global-delay-startup-value">
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="10">10</option>
- <option value="15">15</option>
- <option value="30">30</option>
- <option value="45">45</option>
- </select>
- <select id="global-delay-startup-multiplier">
- <option value="s">Seconds</option>
- <option value="m">Minutes</option>
- <option value="h">Hours</option>
- </select>
- </div>
-
- <div class="clearfix"></div>
-
- <div class="options-header">Advanced options</div>
- <div class="options-items">
- <div class="edit-dialog-label" id="global-options-link" title="Advanced options can be specified command-line style. One option per line like --option=value. Click here to see a list of options"><a class="action-link">Options<div class="ui-icon ui-icon-info ui-icon-inline"></div></a></div>
-
- <textarea id="global-advanced-options" rows="4" class="pre-style-text" name="global-advanced-options"></textarea>
- </div>
-
- </div>
-
- </div>
-
- <div id="restore-direct-options-dialog" class="modal-dialog" title="Available options"></div>
-
-
-
- <div id="restore-direct-dialog" class="modal-dialog tabs edit-dialog" title="Restore files">
-
- <form id="restore-direct-dialog-form">
- <div class="input-block">
- <div class="edit-dialog-label action-link" id="restore-direct-uri-label" title="The destination where the backup data is stored is supplied in the form of a URI. Click the link here to edit the individual parts of the connection URI.">Restore from…</div>
- <div class="field-group">
- <textarea type="text" name="restore-direct-uri" id="restore-direct-uri" value="" class="ui-corner-all" rows="3"></textarea>
- </div>
- </div>
-
- <div class="input-block">
- <div class="edit-dialog-label">Passphrase</div>
- <div class="field-group">
- <input type="password" name="restore-direct-encryption-password" id="restore-direct-encryption-password" value="" class="ui-corner-all" />
- </div>
- </div>
-
- <div class="options-items">
- <div class="edit-dialog-label" id="restore-direct-options-link" title="Advanced options can be specified command-line style. One option per line like --option=value. Click here to see a list of options"><a class="action-link">Advanced Options<div class="ui-icon ui-icon-info ui-icon-inline"></div></a></div>
-
- <textarea id="restore-direct-advanced-options" rows="4" class="pre-style-text" name="restore-direct-advanced-options"></textarea>
- </div>
-
- </form>
-
- </div>
- </section>
- <footer>
- <div class="box-duplicati-copy">
- &copy; 2015 | <a class="link_extern" href="http://www.duplicati.com/" target="_blank">Duplicati</a>
- </div>
- <div class="box-duplicati-copy">
- <a class="link_extern" href="../theme.html" target="_self">Change theme</a>
- </div>
- <div class="box-visit-us">
- <div>
- Visit <a class="link_extern" href="https://github.com/duplicati/duplicati" target="_blank">GitHub</a> for reporting bugs or feature request!
- </div>
- <div>
- Visit us on <a class="link_extern" href="http://www.facebook.com/pages/Duplicati/105118456272281" target="_blank">Facebook</a> or on <a class="link_extern" href="https://plus.google.com/105271984558189185842" target="_blank">Google+</a>!
- </div>
- <div>
- We accept donations via <a class="link_extern" href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal%40hexad%2edk&item_name=Duplicati%20Donation&no_shipping=2&no_note=1&tax=0&currency_code=EUR&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=US" target="_blank">PayPal</a> and <a class="link_extern" href="bitcoin:1HnWb5wLhwa9UREZCxKyNfzkKiR3b6RCPX?amount=0.1&message=Duplicati">Bitcoin</a>.
- </div>
- </div>
- </footer>
-</body>
-</html>
diff --git a/Duplicati/Server/webroot/greeno/scripts/app.js b/Duplicati/Server/webroot/greeno/scripts/app.js
deleted file mode 100644
index 4b0cc1fed..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/app.js
+++ /dev/null
@@ -1,2239 +0,0 @@
-/*
- * Primary app code
- */
-
-// Global app settings
-
-APP_DATA = null;
-APP_EVENTS= {};
-APP_UTIL = {
- parseBoolOption: function(val, def) {
- if (val == null) {
- if (def === undefined)
- return true;
- else
- return def == true;
- }
-
- var str = (val + '').toLowerCase();
- return str == '' || str == 'true' || str == '1' || str == 'yes' || str == 'on';
- },
-
- isValidBoolOption: function(val) {
- if (val == null)
- return true;
-
- var t = (val + '').toLowerCase();
- return val == '' || t == '1' || t == 'true' || t == 'on' || t == 'yes' || t == '0' || t == 'false' || t == 'off' || t == 'no';
- },
-
- parseOptionStrings: function(val, dict, validateCallback) {
- dict = dict || {};
- var lines = replace_all(val || '', '\r', '\n').split('\n');
- for(var i in lines) {
- var line = lines[i].trim();
- if (line != '' && line[0] != '#') {
- if (line.indexOf('--') == 0) {
- line = line.substr(2);
- }
-
- var eqpos = line.indexOf('=');
- var key = line;
- var value = true;
- if (eqpos > 0) {
- key = line.substr(0, eqpos).trim();
- value = line.substr(eqpos + 1).trim();
- if (value == '')
- value = true;
- }
-
- if (validateCallback)
- if (!validateCallback(dict, key, value))
- return null;
-
- dict['--' + key] = value;
- }
- }
-
- return dict;
- },
-
- fill_form: function(form, data, map, extra) {
- map = map || {};
- data = data || {};
-
- for(var k in data) {
- var key = k;
- var m = map[key];
- var v = data[k];
-
- if (m !== false) {
- if (m && typeof(m) == typeof(''))
- key = m;
-
- if (m && typeof(m) == typeof(function() {})) {
- m(data, key, v, extra);
- } else {
- var n = form.find('#' + key);
- if (n.attr('type') == 'checkbox') {
- n.attr('checked', APP_UTIL.parseBoolOption(v));
- } else {
- n.val(v);
- }
-
- n.change();
- }
- }
- }
- },
-
- read_form: function(form, map, values, extra) {
- values = values || {};
- map = map || {};
-
- form.find('select').each(function(i, e) {
- var key = e.id;
- var m = map[e.id];
-
- if (m !== false) {
- if (m && typeof(m) == typeof(function() {})) {
- m(values, key, e, extra);
- } else {
- if (m && typeof(m) == typeof(''))
- key = m;
-
- values[key] = $(e).val();
- }
- }
- });
-
- form.find('textarea').each(function(i, e) {
- var key = e.id;
- var m = map[e.id];
-
- if (m !== false) {
- if (m && typeof(m) == typeof(function() {})) {
- m(values, key, e, extra);
- } else {
- if (m && typeof(m) == typeof(''))
- key = m;
-
- values[key] = $(e).val();
- }
- }
- });
-
- form.find('input').each(function(i, e) {
- var key = e.id;
- var m = map[e.id];
-
- if (m !== false) {
- if (m && typeof(m) == typeof(function() {})) {
- m(values, key, e, extra);
- } else {
- if (m && typeof(m) == typeof(''))
- key = m;
-
- if (e.type == 'checkbox')
- values[key] = $(e).is(':checked');
- else
- values[key] = $(e).val();
- }
- }
- });
-
- return values;
- },
-
- create_modal_wait: function(title, text, cancel_callback) {
- var dlg = $('<div></div>').attr('title', title);
-
- dlg.dialog({
- autoOpen: true,
- modal: true,
- closeOnEscape: false,
- buttons: [
- { text: 'Cancel', click: function(event, ui) {
- if (!cancel_callback || cancel_callback())
- {
- dlg.dialog('close');
- dlg.remove();
- }
- }}
- ]
- });
-
- dlg.parent().find('.ui-dialog-titlebar-close').remove().first().remove();
-
- var pgtxt = $('<div></div>');
- pgtxt.text(text);
-
- dlg.append(pgtxt);
- dlg.pgtxt = pgtxt;
-
- return dlg;
- },
-
- create_modal_task_wait: function(title, text, complete_callback) {
- var handler_for_event = null;
- var handler_for_progress = null;
- var cancelled = false;
- var taskid = null;
-
- var pg = $('<div></div>');
- pg.progressbar({ value: false });
-
- var dlg = APP_UTIL.create_modal_wait(title, text, function() {
- if (confirm('Stop the process ?')) {
- APP_DATA.stopTask(taskid, true);
- $(document).off('server-state-updated', handler_for_event);
- $(document).off('server-progress-updated', handler_for_progress);
- cancelled = true;
- return true;
- } else {
- return false;
- }
- });
-
- pg.insertAfter(dlg.pgtxt);
-
- handler_for_progress = function(ev, data) {
- if (taskid == null)
- return;
-
- if (data.TaskID == taskid) {
- pg.progressbar('option', 'value', parseInt(data.OverallProgress * 100));
- } else {
- pg.progressbar('option', 'value', false);
- }
- };
-
- handler_for_event = function(ev, data) {
- if (taskid == null)
- return;
-
- var active = data.ActiveTask != null && data.ActiveTask.Item1 == taskid;
-
- if (!active && data.SchedulerQueueIds)
- for(var n in data.SchedulerQueueIds)
- active = active || (data.SchedulerQueueIds[n].Item1 == taskid);
-
- if (!active) {
- handler_for_progress(null, {OverallProgress: 1, TaskID: taskid});
-
- $(document).off('server-state-updated', handler_for_event);
- $(document).off('server-progress-updated', handler_for_progress);
-
- dlg.dialog('close');
- dlg.remove();
- complete_callback(cancelled, taskid);
- }
- };
-
- dlg.register_updates = function(id) {
- taskid = id;
- $(document).on('server-state-updated', handler_for_event);
- $(document).on('server-progress-updated', handler_for_progress);
- }
-
- return dlg;
- }
-};
-
-$(document).ready(function() {
-
- // Flag as loaded in case we have plugins
- APP_DATA = {
- plugins: {
- backend: {},
- compression: {},
- encryption: {},
- primary: {}
-
- }
- };
-
- var PRIVATE_DATA = {};
-
- $(document).tooltip();
-
- $('#main-appname').text(APP_CONFIG.branded_name);
-
- window.document.title = APP_CONFIG.branded_name;
-
- if ((APP_CONFIG.branded_subtitle || '').length > 0) {
- var subdiv = $('<div id="main-appname-subtitle">');
- subdiv.text(APP_CONFIG.branded_subtitle);
- $('#main-appname').append(subdiv);
- $('#main-appname').addClass('has-subtitle');
- }
-
- $('.button').button();
-
- $('textarea.pre-style-text').each(function(i, e) { e.wrap = "off"; });
-
- $('#main-list-container > div.main-backup-entry').remove();
- $('#loading-dialog').dialog({modal: true}).show();
-
- jQuery.timeago.settings.allowFuture = true;
- jQuery.timeago.settings.allowPast = true;
-
- $.noty.defaults.layout = 'bottomCenter';
-
- // Register a global function for password strength
- $.passwordStrength = function(password, callback) {
- if (callback == null)
- return;
-
- var onUpdate = function(res) {
- try { callback(res); }
- catch (e) { }
- };
-
- try { onUpdate(zxcvbn(password)); }
- catch (e) { onUpdate(null); }
- };
-
- var formatSizes = ['TB', 'GB', 'MB', 'KB'];
- $.formatSizeString = function(val) {
- val = parseInt(val || 0);
- var max = formatSizes.length;
- for(var i = 0; i < formatSizes.length; i++) {
- var m = Math.pow(1024, max - i);
- if (val > m)
- return (val / m).toFixed(2) + ' ' + formatSizes[i];
- }
-
- return val + ' ' + bytes;
- };
-
- pwz = function(i, c) {
- i += '';
- while(i.length < c)
- i = '0' + i;
- return i;
- }
-
- $.toDisplayDateAndTime = function(dt) {
- return pwz(dt.getFullYear(), 4) + '-' + pwz(dt.getMonth() + 1, 2) + '-' + pwz(dt.getDate(), 2) + ' ' + pwz(dt.getHours(), 2) + ':' + pwz(dt.getMinutes(), 2);
- };
-
- $.parseDate = function(dt) {
- if (typeof(dt) == typeof('')) {
- var msec = Date.parse(dt);
- if (isNaN(msec)) {
- if (dt.length == 16 && dt[8] == 'T' && dt[15] == 'Z') {
- dt = dt.substr(0, 4) + '-' + dt.substr(4, 2) + '-' + dt.substr(6, 2) + 'T' +
- dt.substr(9, 2) + ':' + dt.substr(11, 2) + ':' + dt.substr(13, 2) + 'Z';
- }
- return new Date(dt);
- } else {
- return new Date(msec);
- }
- }
- else
- return new Date(dt);
- };
-
- var serverWithCallback = function(data, callback, errorhandler, refreshMethod) {
- if (typeof(data) == typeof(''))
- data = { action: data };
-
- var method = 'GET';
- if (data.HTTP_METHOD) {
- method = data.HTTP_METHOD;
- delete data.HTTP_METHOD;
- }
-
- $.ajax({
- url: APP_CONFIG.server_url,
- headers: {'X-XSRF-Token': APP_DATA.xsrf_token},
- type: method,
- dataType: 'json',
- data: data
- })
- .done(function(data) {
- if (refreshMethod)
- refreshMethod(data, true, null);
-
- if (callback != null)
- callback(data, true, null);
- })
- .fail(function(data, status) {
- var msg = data.statusText;
- if (data && data.responseJSON && data.responseJSON.Message)
- msg = data.responseJSON.Message;
-
- if (refreshMethod)
- refreshMethod(data, false, msg);
-
- if (errorhandler)
- errorhandler(data, false, msg);
- });
- };
-
- PRIVATE_DATA.server_state = {
- polling: false,
- eventId: -1,
- state: null,
- failed: false,
- dataEventId: -1,
- notificationId: -1,
- xsrf_error: false,
-
- retryTimer: null,
- pauseUpdateTimer: null,
- activeTask: null,
- scheduled: []
- };
-
- PRIVATE_DATA.progress_state_text = {
- 'Backup_Begin': 'Starting ...',
- 'Backup_PreBackupVerify': 'Verifying backend data ...',
- 'Backup_PostBackupTest': 'Verifying remote data ...',
- 'Backup_PreviousBackupFinalize': 'Completing previous backup ...',
- 'Backup_ProcessingFiles': null,
- 'Backup_Finalize': 'Completing backup ...',
- 'Backup_WaitForUpload': 'Waiting for upload ...',
- 'Backup_Delete': 'Deleting unwanted files ...',
- 'Backup_Compact': 'Compacting remote data ...',
- 'Backup_VerificationUpload': 'Uploading verification file ...',
- 'Backup_PostBackupVerify': 'Verifying backend data ...',
- 'Backup_Complete': 'Finished!',
- 'Restore_Begin': 'Starting ...',
- 'Restore_RecreateDatabase': 'Rebuilding local database ...',
- 'Restore_PreRestoreVerify': 'Verifying remote data ...',
- 'Restore_CreateFileList': 'Building list of files to restore ...',
- 'Restore_CreateTargetFolders': 'Creating target folders ...',
- 'Restore_ScanForExistingFiles': 'Scanning existing files ...',
- 'Restore_ScanForLocalBlocks': 'Scanning for local blocks ...',
- 'Restore_PatchWithLocalBlocks': 'Patching files with local blocks ...',
- 'Restore_DownloadingRemoteFiles': 'Downloading files ...',
- 'Restore_PostRestoreVerify': 'Verifying restored files ...',
- 'Restore_Complete': 'Finished!',
- 'Recreate_Running': 'Recreating database ...',
- 'Repair_Running': 'Reparing ...',
- 'Verify_Running': 'Verifying ...',
- 'Error': 'Error!'
- };
-
- PRIVATE_DATA.update_progress_and_schedules = function() {
- var scheduledMap = {};
- var backupMap = {};
- var state = PRIVATE_DATA.server_state;
- var current = state.activeTask == null ? false : 'backup-' + state.activeTask.Item2;
-
- if (state.activeTask == null) {
- $('#main-status-area-cancel-button').hide();
- $('#main-status-area-progress-outer').hide();
-
- //TODO: state.scheduled is just the current queue, we need to find the next based on "Time"
-
-
- if (PRIVATE_DATA.backup_list == null || PRIVATE_DATA.backup_list.length == 0) {
- $('#main-status-area-text').text('No scheduled backups waiting');
- } else {
- var bk = null;
- var mindate = null;
- for(var n in PRIVATE_DATA.backup_list) {
- if (PRIVATE_DATA.backup_list[n].Schedule == null || PRIVATE_DATA.backup_list[n].Schedule.Time == null)
- continue;
-
- var selfdate = new Date(PRIVATE_DATA.backup_list[n].Schedule.Time);
- if (mindate == null || selfdate < mindate) {
- bk = PRIVATE_DATA.backup_list[n].Backup;
- mindate = selfdate;
- }
- }
-
- if (bk == null) {
- $('#main-status-area-text').text('No scheduled backups waiting');
- } else {
- $('#main-status-area-text').text('Waiting to start "' + bk.Name + '" at ' + $.toDisplayDateAndTime(mindate));
- }
- }
- } else {
- $('#main-status-area-cancel-button').show();
- $('#main-status-area-progress-outer').show();
-
- var id = state.activeTask.Item2;
- var bk = null;
-
- for(var n in PRIVATE_DATA.backup_list)
- if (PRIVATE_DATA.backup_list[n].Backup.ID == id) {
- bk = PRIVATE_DATA.backup_list[n].Backup;
- break;
- }
-
- if (bk == null)
- $('#main-status-area-text').text('Unknown backup');
- else
- $('#main-status-area-text').text(bk.Name);
-
- var txt = 'Running ...';
- var pg = -1;
- if (PRIVATE_DATA.server_progress.lastEvent != null) {
-
- if (PRIVATE_DATA.server_progress.lastEvent.Phase == 'Backup_ProcessingFiles') {
-
- if (PRIVATE_DATA.server_progress.lastEvent.StillCounting) {
- txt = 'Counting (' + PRIVATE_DATA.server_progress.lastEvent.TotalFileCount + ' files found, ' + $.formatSizeString(PRIVATE_DATA.server_progress.lastEvent.TotalFileSize) + ')';
- pg = 0;
- } else {
- var filesleft = PRIVATE_DATA.server_progress.lastEvent.TotalFileCount - PRIVATE_DATA.server_progress.lastEvent. ProcessedFileCount;
- var sizeleft = PRIVATE_DATA.server_progress.lastEvent.TotalFileSize - PRIVATE_DATA.server_progress.lastEvent.ProcessedFileSize;
- pg = PRIVATE_DATA.server_progress.lastEvent.ProcessedFileSize / PRIVATE_DATA.server_progress.lastEvent.TotalFileSize;
-
- if (PRIVATE_DATA.server_progress.lastEvent.ProcessedFileCount == 0)
- pg = 0;
- else if (pg == 1)
- pg = 0.95;
-
- txt = filesleft + ' files (' + $.formatSizeString(sizeleft) + ') to go';
- }
- } else {
- txt = PRIVATE_DATA.progress_state_text[PRIVATE_DATA.server_progress.lastEvent.Phase] || txt;
- if (PRIVATE_DATA.server_progress.lastEvent.Phase == 'Backup_WaitForUpload')
- pg = 1;
- else if (PRIVATE_DATA.server_progress.lastEvent.OverallProgress > 0)
- pg = PRIVATE_DATA.server_progress.lastEvent.OverallProgress;
- }
-
- if (pg == -1) {
- $('#main-status-area-progress-outer').addClass('backup-progress-indeterminate');
- $('#main-status-area-progress-bar').css('width', '0%');
- } else {
- $('#main-status-area-progress-outer').removeClass('backup-progress-indeterminate');
- $('#main-status-area-progress-bar').css('width', parseInt(pg*100) + '%');
- }
- $('#main-status-area-progress-text').text(txt);
-
- }
- }
-
- if (state.scheduled != null)
- for(var n in state.scheduled)
- if (scheduledMap['backup-' + state.scheduled[n].Item2] == null)
- scheduledMap['backup-' + state.scheduled[n].Item2] = parseInt(n) + 1;
-
- for(var n in PRIVATE_DATA.backup_list)
- backupMap['backup-' + PRIVATE_DATA.backup_list[n].Backup.ID] = PRIVATE_DATA.backup_list[n];
-
- $('#main-list').find('.main-backup-entry').each(function(i, e) {
- var el = $(e);
-
- var lastStarted = $.parseDate(backupMap[e.id].Backup.Metadata.LastBackupStarted);
- var lastError = $.parseDate(backupMap[e.id].Backup.Metadata.LastErrorDate);
-
- if (isNaN(lastStarted)) {
- el.find('.last-run-time').hide();
- } else {
- el.find('.last-run-time').show();
- }
-
- if (!isNaN(lastStarted) && !isNaN(lastError) && lastError > lastStarted) {
- //var msg = backupMap[e.id].Backup.Metadata.LastErrorMessage;
- el.find('.last-run-time').addClass('last-run-failed');
- } else {
- el.find('.last-run-time').removeClass('last-run-failed');
- }
-
-
- // Scheduled items
- if (scheduledMap[e.id]) {
- el.find('.backup-next-run').text('#' + parseInt(scheduledMap[e.id]) + ' in queue');
- el.find('.next-run-time').show();
- } else if (e.id == current) {
- el.find('.backup-next-run').text('Running now');
- el.find('.next-run-time').show();
- } else if (backupMap[e.id] && backupMap[e.id].Schedule) {
- var targetDate = $.parseDate(backupMap[e.id].Schedule.Time);
- el.find('.backup-next-run').text($.toDisplayDateAndTime(targetDate));
- el.find('.next-run-time').show();
- } else {
- el.find('.next-run-time').hide();
- }
- });
- };
-
- PRIVATE_DATA.long_poll_for_status = function() {
- var state = PRIVATE_DATA.server_state;
- if (state.polling)
- return;
-
- if (state.retryTimer != null) {
- $(document).trigger('server-state-connecting');
- clearInterval(state.retryTimer);
- state.retryTimer = null;
- }
-
- if (APP_DATA.xsrf_token == null) {
- var cookies = document.cookie.split(';');
- for(var c in cookies) {
- if (cookies[c].trim().toLowerCase().indexOf('xsrf-token=') == 0) {
- APP_DATA.xsrf_token = decodeURIComponent(cookies[c].trim().substr('xsrf-token='.length));
- break;
- }
- }
- }
-
- state.polling = true;
-
- var req = { action: 'get-current-state', longpoll: true, lastEventId: state.eventId };
- var timeout = 240000;
- if (state.failed || state.eventId == -1) {
- req.longpoll = false;
- timeout = 5000
- }
-
- req.duration = parseInt((timeout-1000) / 1000) + 's';
-
- $.ajax({
- url: APP_CONFIG.server_url,
- type: 'GET',
- timeout: timeout,
- headers: {'X-XSRF-Token': APP_DATA.xsrf_token},
- dataType: 'json',
- data: req
- })
- .done(function(data) {
- state.polling = false;
- state.state = data;
- var oldDataId = state.dataEventId;
- var oldState = state.programState;
- var oldEventId = state.eventId;
- var oldNotificationId = state.notificationId;
-
- state.eventId = data.LastEventID;
- state.dataEventId = data.LastDataUpdateID;
- state.notificationId = data.LastNotificationUpdateID;
- state.programState = data.ProgramState;
- state.scheduled = data.SchedulerQueueIds || [];
-
- if (state.failed) {
- state.failed = false;
-
- // If the server was restarted, we refresh
- if (oldEventId > state.eventId)
- location.reload(true);
-
- $(document).trigger('server-state-restored');
- }
-
- //If there is an active backup, (re)start the progress monitor
- if (data.ActiveTask != null) {
- state.activeTask = data.ActiveTask;
- PRIVATE_DATA.poll_for_progress();
- } else {
- state.activeTask = null;
- }
-
- $(document).trigger('server-state-updated', data);
- if (oldDataId != state.dataEventId)
- $(document).trigger('server-state-data-updated', data);
-
- if (oldNotificationId != state.notificationId)
- PRIVATE_DATA.refresh_notifications();
-
- if (oldState != state.programState) {
- if (state.pauseUpdateTimer != null) {
- clearInterval(state.pauseUpdateTimer);
- state.pauseUpdateTimer = null;
- }
-
- $(document).trigger('server-state-changed', state.programState);
-
- if (state.programState == 'Running') {
- $(document).trigger('server-state-running');
- } else if (state.programState == 'Paused') {
- $(document).trigger('server-state-paused');
-
- var estimatedEnd = Date.parse(data.EstimatedPauseEnd);
- if (estimatedEnd > 0) {
- estimatedEnd = new Date(estimatedEnd);
- var updateTimer = function() {
- var left = Math.max(0, estimatedEnd - new Date());
- $(document).trigger('server-state-pause-countdown', {millisecondsLeft: left});
- if (left == 0) {
- clearInterval(state.pauseUpdateTimer);
- state.pauseUpdateTimer = null;
- }
-
- }
-
- state.pauseUpdateTimer = setInterval(updateTimer, 500);
- updateTimer();
- }
- }
- }
-
- PRIVATE_DATA.update_progress_and_schedules();
- PRIVATE_DATA.long_poll_for_status();
- })
- .fail(function(data) {
- if (data.status == 401)
- window.location = APP_CONFIG.login_url;
-
- // XSRF token expired
- if (data.status == 400 && data.statusText.toUpperCase().indexOf('XSRF') >= 0)
- {
- PRIVATE_DATA.xsrf_error = true;
- $('#connection-lost-dialog-error').text('Invalid or expired XSRF token, try reloading the page');
- }
- else
- {
- PRIVATE_DATA.xsrf_error = false;
- $('#connection-lost-dialog-error').text('');
- }
-
- state.polling = false;
- if (!state.failed) {
- state.failed = true;
- $(document).trigger('server-state-lost');
- }
-
- state.retryStartTime = new Date();
- var updateTimer = function() {
- var n = new Date() - state.retryStartTime;
- var left = Math.max(0, (PRIVATE_DATA.xsrf_error ? 5000 : 15000) - n);
- $(document).trigger('server-state-countdown', {millisecondsLeft: left});
- if (left <= 0)
- {
- PRIVATE_DATA.long_poll_for_status();
-
- if (PRIVATE_DATA.xsrf_error)
- location.reload();
- }
- }
-
- state.retryTimer = setInterval(updateTimer, 500);
- });
- };
-
- PRIVATE_DATA.notifications = {
- lastId: -1,
- pending: []
- };
-
- PRIVATE_DATA.refresh_notifications = function() {
- serverWithCallback({'action': 'get-notifications'},
- function(data) {
- // Append new notifications to pending
- var pendingmap = {};
- for(var n in data)
- pendingmap[data[n].ID] = data[n];
-
- var toremove = [];
- for(var n in PRIVATE_DATA.notifications.pending)
- if (pendingmap[PRIVATE_DATA.notifications.pending[n].ID] == null) {
- toremove.push(PRIVATE_DATA.notifications.pending[n]);
- } else {
- delete pendingmap[PRIVATE_DATA.notifications.pending[n].ID];
- }
-
- // Remove missing notifications, and dismiss any shown noty's
- for(var n in toremove) {
- if (toremove[n].noty)
- toremove[n].noty.close();
-
- for(var n in PRIVATE_DATA.notifications.pending)
- if (PRIVATE_DATA.notifications.pending[n] == toremove[n]) {
- PRIVATE_DATA.notifications.pending.splice(n, 1);
- break;
- }
- }
-
- // Append new pending notifications
- for(var n in pendingmap) {
- PRIVATE_DATA.notifications.pending.push(pendingmap[n]);
- }
-
- // Setup noty's for new notifications
- for(var n in PRIVATE_DATA.notifications.pending) {
- if (!PRIVATE_DATA.notifications.pending[n].noty) {
- var self = PRIVATE_DATA.notifications.pending[n];
-
- var buttons = [{
- text: 'Dismiss',
- onClick: function($noty) { $noty.close(); }
- }];
-
- if (self.Action == 'backup:show-log') {
- buttons.push({
- text: 'Show',
- onClick: function($noty) { $.showBackupLog(this.notification.BackupID); }
- });
- } else if (self.Action == 'update:new') {
- buttons.push({
- text: 'Show',
- onClick: function($noty) { APP_DATA.showChangelog(true); }
- });
-
- buttons.push({
- text: 'Install',
- onClick: function($noty) { APP_DATA.installUpdate(); $noty.close(); }
- });
- } else if (self.Action != null && self.Action.indexOf('bug-report:created:') == 0) {
- self.bugreportid = self.Action.substr('bug-report:created:'.length);
- buttons.push({
- text: 'Download',
- onClick: function($noty) { APP_DATA.downloadBugReport(this.notification.bugreportid); $noty.close(); }
- });
- }
-
-
- self.noty = noty({
- text: self.Title + ': ' + self.Message,
- type: self.Type.toLowerCase(),
- callback: {
- afterClose: function() {
- APP_DATA.callServer({'action': 'dismiss-notification', 'id': this.notification.ID});
- }
- },
- buttons: buttons
- });
-
- self.noty.notification = self;
- }
- }
-
- },
- function(a,b,message) {
-
- }
- );
- };
-
- PRIVATE_DATA.server_progress = {
- polling: false,
- eventId: -1,
- throttleTimer: null,
- lastEvent: null,
- updateFreq: 2000
- };
-
- PRIVATE_DATA.poll_for_progress = function() {
- var state = PRIVATE_DATA.server_progress;
- if (state.polling)
- return;
-
- if (state.throttleTimer != null) {
- clearTimeout(state.throttleTimer);
- state.throttleTimer = null;
- }
-
- state.polling = true;
-
- var req = { action: 'get-progress-state', longpoll: false };
- state.requestStart = new Date();
-
- var restart_poll = function() {
- if (state.throttleTimer != null) {
- clearTimeout(state.throttleTimer);
- state.throttleTimer = null;
- }
-
- var timeSinceLast = new Date() - state.requestStart;
- if (timeSinceLast < state.updateFreq) {
- state.throttleTimer = setTimeout(function(){
- if (PRIVATE_DATA.server_state.activeTask != null)
- PRIVATE_DATA.poll_for_progress();
-
- }, Math.max(500, state.updateFreq - timeSinceLast));
- } else {
- if (PRIVATE_DATA.server_state.activeTask != null)
- PRIVATE_DATA.poll_for_progress();
- }
- };
-
- $.ajax({
- url: APP_CONFIG.server_url,
- type: 'GET',
- headers: {'X-XSRF-Token': APP_DATA.xsrf_token},
- timeout: 5000,
- dataType: 'json',
- data: req
- })
- .done(function(data) {
- state.polling = false;
- state.eventId = data.LastEventID;
- state.lastEvent = data;
- PRIVATE_DATA.update_progress_and_schedules();
-
- $(document).trigger('server-progress-updated', data);
-
- restart_poll();
- })
- .fail(function(data, a, b, c, d) {
- state.polling = false;
- if (PRIVATE_DATA.server_state.failed) {
- // We will be restarted on re-connect
- } else {
- // Bad poll request, just retry
- restart_poll();
- }
- });
- };
-
- PRIVATE_DATA.refresh_server_settings = function(callback, errorhandler) {
- serverWithCallback(
- 'system-info',
- callback,
- errorhandler,
- function(data, success) {
- if (success && data != null) {
- PRIVATE_DATA.server_config = data;
- window.document.title = APP_CONFIG.branded_name + ' - ' + data.MachineName;
- }
- }
- );
- };
-
- PRIVATE_DATA.refresh_backup_list = function(callback, errorhandler) {
- serverWithCallback(
- 'list-backups',
- callback,
- errorhandler,
- function(data, success) {
- if (success && data != null) {
- PRIVATE_DATA.backup_list = data;
-
- // Clear existing stuff
- $('#main-list-container > div.main-backup-entry').remove();
-
- if ($('#backup-item-template').length > 0 && data.length > 0) {
-
- // Pre-processing of data
- for(var n in data)
- data[n].Backup.Metadata = data[n].Backup.Metadata || {};
-
- if (APP_DATA.plugins.primary['backup-list-preprocess'])
- APP_DATA.plugins.primary['backup-list-preprocess'](data);
-
- //Fill with jQuery template
- $.tmpl($('#backup-item-template'), data).prependTo($('#main-list-container'));
-
- var decodeid = function(e) {
- var p = e.delegateTarget.id.split('-');
- return parseInt(p[p.length - 1]);
- };
-
- // Post processing of data
- for(var n in data) {
- var id = data[n].Backup.ID;
-
- // Setup context menu trigger
- $('#backup-control-' + id).click(function(e) {
- var id = decodeid(e);
- APP_DATA.showContextMenu(id, $('#backup-control-' + id));
- });
- }
-
- if (APP_DATA.plugins.primary['backup-list-postrocess'])
- APP_DATA.plugins.primary['backup-list-postrocess']($('#main-list-container'), $('#main-list-container > div.main-backup-entry'), data);
- }
- }
-
- PRIVATE_DATA.update_progress_and_schedules();
- }
- );
- };
-
- APP_DATA.getBackupName = function(id) {
- if (PRIVATE_DATA.backup_list)
- for(var n in PRIVATE_DATA.backup_list)
- if (PRIVATE_DATA.backup_list[n].Backup.ID == id)
- return PRIVATE_DATA.backup_list[n].Backup.Name;
- return null;
- };
-
- APP_DATA.getServerConfig = function(callback, errorhandler) {
- if (PRIVATE_DATA.server_config == null) {
- PRIVATE_DATA.refresh_server_settings(callback, errorhandler);
- } else {
- callback(PRIVATE_DATA.server_config);
- }
- };
-
- APP_DATA.validatePath = function(path, callback) {
- serverWithCallback({ action: 'validate-path', path: path }, callback, callback);
- };
- APP_DATA.getLabels = function(callback) {
- serverWithCallback('list-tags', callback, callback);
- };
-
- APP_DATA.getBackupDefaults = function(callback, errorhandler) {
- serverWithCallback('get-backup-defaults', callback, errorhandler);
- };
- APP_DATA.getBackupData = function(id, callback, errorhandler) {
- serverWithCallback({ action: 'get-backup', id: id}, callback, errorhandler);
- };
-
- APP_DATA.addBackup = function(cfg, callback, errorhandler, extra_options) {
- serverWithCallback(
- $.extend(
- {},
- extra_options,
- { action: 'add-backup', HTTP_METHOD: 'POST', data: JSON.stringify(cfg), contentType : "application/x-www-form-urlencoded; charset=utf-8"}
- ),
- callback,
- errorhandler
- );
- };
-
- APP_DATA.updateBackup = function(cfg, callback, errorhandler) {
- serverWithCallback(
- { action: 'update-backup', HTTP_METHOD: 'POST', data: JSON.stringify(cfg), contentType : "application/x-www-form-urlencoded; charset=utf-8"},
- callback,
- errorhandler
- );
- };
-
- APP_DATA.locateUriDb = function(targeturl, callback, errorhandler) {
- serverWithCallback(
- { action: 'locate-uri-db', HTTP_METHOD: 'POST', uri: targeturl},
- callback,
- errorhandler
- );
- };
-
- APP_DATA.editNewBackup = function() {
- APP_DATA.editBackup();
- };
-
- APP_DATA.deleteBackup = function(id, callback, errorhandler) {
- serverWithCallback(
- { action: 'delete-backup', id: id },
- callback,
- errorhandler
- );
- };
-
- APP_DATA.editBackup = function(id) {
- APP_DATA.getServerConfig(function(data) {
-
- var callback = function(data) {
- $("#edit-dialog").dialog('open');
-
- // Bug-fix, this will remove style="width: auto", which breaks Chrome a bit
- $("#edit-dialog").css('width', '');
-
- // Send data to the dialog
- $("#edit-dialog").trigger('setup-dialog', data.data);
- };
-
- var errorhandler = function() {
- alert('Failed to get server setup...')
- };
-
- if (id == undefined || parseInt(id) < 0)
- APP_DATA.getBackupDefaults(callback, errorhandler);
- else
- APP_DATA.getBackupData(id, callback, errorhandler);
- },
- function() {
- alert('Failed to get server setup...')
- });
-
- };
-
- APP_DATA.runBackup = function(id) {
- serverWithCallback(
- { action: 'send-command', command: 'run-backup', id: id },
- function() {},
- function(d,s,m) { alert('Failed to start backup: ' + m); }
- );
- };
-
- APP_DATA.isBackupActive = function(id, callback) {
- serverWithCallback(
- { action: 'send-command', command: 'is-backup-active', id: id },
- function(data) { callback(data.Active); },
- function(d,s,m) { alert('Failed to query backup: ' + m); }
- );
- };
-
- APP_DATA.restoreBackup = function(id, isFromDirect) {
- APP_DATA.isBackupActive(id, function(active) {
- if (active) {
- alert('Cannot start restore while the backup is active.');
- } else {
- $('#restore-dialog').dialog('open');
- $('#restore-dialog').trigger('setup-dialog', {id: id, isDirectRestore: isFromDirect});
- }
- });
-
- };
-
- APP_DATA.pauseServer = function(duration) {
- serverWithCallback({action: 'send-command', command: 'pause', duration: duration});
- };
-
- APP_DATA.resumeServer = function() {
- serverWithCallback({action: 'send-command', command: 'resume'});
- };
-
- APP_DATA.stopTask = function(taskId, force) {
- serverWithCallback(
- { action: 'send-command', command: force ? 'abort' : 'stop', taskid: taskId },
- function() {},
- function(d,s,m) { alert('Failed to send stop command: ' + m); }
- );
- }
-
- APP_DATA.runVerify = function(id) {
- serverWithCallback(
- { action: 'send-command', command: 'run-verify', id: id },
- function() {},
- function(d,s,m) { alert('Failed to start verification: ' + m); }
- );
- };
-
- APP_DATA.runRepair = function(id, callback, errorhandler) {
- serverWithCallback(
- { action: 'send-command', command: 'run-repair', id: id },
- callback,
- errorhandler || function(d,s,m) { alert('Failed to start repair: ' + m); }
- );
- };
-
- APP_DATA.createReport = function(id) {
- serverWithCallback(
- { action: 'send-command', command: 'create-report', id: id },
- function() {},
- function(d,s,m) { alert('Failed to create bug report: ' + m); }
- );
- };
-
- APP_DATA.deleteLocalData = function(id) {
- serverWithCallback(
- { action: 'delete-local-data', id: id },
- function() {},
- function(d,s,m) { alert('Failed to delete local data: ' + m); }
- );
- };
-
- APP_DATA.restoreDirect = function() {
- $('#restore-direct-dialog').dialog('open');
- }
-
- APP_DATA.testConnection = function (uri, callback, errorhandler) {
- serverWithCallback(
- {action: 'test-backend', url: uri},
- callback,
- errorhandler
- );
- }
-
- APP_DATA.hasLoadedAbout = false;
- APP_DATA.hasLoadedChangelog = false;
- APP_DATA.hasLoadedAcknowledgements = false;
-
- APP_DATA.showAbout = function() {
-
- var licenses = {
- 'MIT': 'http://www.linfo.org/mitlicense.html',
- 'Apache': 'https://www.apache.org/licenses/LICENSE-2.0.html',
- 'Apache 2': 'https://www.apache.org/licenses/LICENSE-2.0.html',
- 'Apache 2.0': 'https://www.apache.org/licenses/LICENSE-2.0.html',
- 'Public Domain': 'https://creativecommons.org/licenses/publicdomain/',
- 'GPL': 'https://www.gnu.org/copyleft/gpl.html',
- 'LGPL': 'https://www.gnu.org/copyleft/lgpl.html',
- 'MS-PL': 'http://opensource.org/licenses/MS-PL',
- 'Microsoft Public': 'http://opensource.org/licenses/MS-PL',
- 'New BSD': 'http://opensource.org/licenses/BSD-3-Clause'
- };
-
- if (!APP_DATA.hasLoadedAcknowledgements) {
- serverWithCallback(
- { action: 'get-acknowledgements' },
- function(data) {
- $('#about-dialog-tab-general-acknowledgements').empty();
- $('#about-dialog-tab-general-acknowledgements').html(nl2br(replace_all(data.Acknowledgements, ' ', '&nbsp;&nbsp;')));
- APP_DATA.hasLoadedAcknowledgements = true;
- }, function(a,b,message) {
- alert('Failed to load acknowledgements: ' + message);
- }
- );
-
-
- }
-
- if (!APP_DATA.hasLoadedChangelog) {
- serverWithCallback(
- { action: 'get-changelog', 'from-update': 'false' },
- function(data) {
- $('#about-dialog-tab-changelog').empty();
- $('#about-dialog-tab-changelog').html(nl2br(replace_all(data.Changelog, ' ', '&nbsp;&nbsp;')));
- APP_DATA.hasLoadedChangelog = true;
- }, function(a,b,message) {
- alert('Failed to load changelog: ' + message);
- }
- );
- }
-
- if (!APP_DATA.hasLoadedAbout) {
- serverWithCallback('get-license-data',
- function(data) {
- var d = [];
- for(var n in data) {
- try {
- var r = JSON.parse(data[n].Jsondata);
- if (r != null) {
- r.licenselink = r.licenselink || licenses[r.license] || '#';
- d.push(r);
- }
- } catch (e) {}
- }
-
- $('#about-dialog-current-version').text(PRIVATE_DATA.server_config.ServerVersionName);
-
- $('#about-dialog-tab-thirdparty-list').empty();
- $('#about-dialog-tab-thirdparty-list').append($.tmpl($('#about-dialog-template'), d));
- APP_DATA.hasLoadedAbout = true;
- APP_DATA.showAbout();
- }, function(msg) {
- alert('Failed to load data: ' + msg);
- });
- } else {
- $('#about-dialog').dialog('open');
- }
- };
-
- APP_DATA.checkForUpdates = function() {
- serverWithCallback(
- { action: 'send-command', command: 'check-update' },
- function() {},
- function(d,s,m) { alert('Failed to check for updates: ' + m); }
- );
- };
-
- APP_DATA.installUpdate = function() {
- serverWithCallback(
- { action: 'send-command', command: 'install-update' },
- function() {
- // Remove notifications for updates when we install
- for(var n in PRIVATE_DATA.notifications.pending)
- if (PRIVATE_DATA.notifications.pending[n].Action == 'backup:new' && PRIVATE_DATA.notifications.pending[n].noty)
- PRIVATE_DATA.notifications.pending[n].noty.close();
- },
- function(d,s,m) { alert('Failed to install for update: ' + m); }
- );
- };
-
- APP_DATA.activateUpdate = function() {
- serverWithCallback(
- { action: 'send-command', command: 'activate-update' },
- function() {},
- function(d,s,m) { alert('Failed to activate update: ' + m); }
- );
- };
-
- APP_DATA.showChangelog = function(from_update) {
- serverWithCallback(
- { action: 'get-changelog', 'from-update': from_update ? 'true' : '' },
- function(data) {
- var dlg = $('<div></div>').attr('title', 'Changelog');
-
- var pgtxt = $('<div class="change-log-data"></div>');
- pgtxt.html(nl2br(replace_all(data.Changelog, ' ', '&nbsp;&nbsp;')));
- dlg.append(pgtxt);
-
- dlg.dialog({
- autoOpen: true,
- width: $('body').width > 450 ? 430 : 600,
- height: 500,
- modal: true,
- closeOnEscape: true,
- buttons: [
- { text: 'Close', click: function(event, ui) {
- dlg.dialog('close');
- dlg.remove();
- }}
- ]
- });
-
- },
- function(d,s,m) { alert('Failed to get changelog: ' + m); }
- );
- };
-
- APP_DATA.downloadBugReport = function(id) {
- var sendobj = {
- 'action': 'download-bug-report',
- 'id': id,
- 'x-xsrf-token': APP_DATA.xsrf_token
- };
-
- var completed = false;
- var url = APP_CONFIG.server_url;
- url += (url.indexOf('?') > -1) ? '&' : '?';
- url += $.param(sendobj);
-
- var iframe = $('<iframe>')
- .hide()
- .prop('src', url)
- .appendTo('body');
-
- setTimeout(function() { iframe.remove(); }, 5000);
- };
-
- APP_DATA.callServer = serverWithCallback;
-
- $.showPopupMenu = function(menu, anchor, offset) {
- var pos = anchor.offset();
- var menuwidth = menu.outerWidth();
- var menuheight = menu.outerHeight();
-
- offset = offset || {};
- offset.x = offset.x || 0;
- offset.y = offset.y || 0;
-
- menu.toggle();
-
- var left = pos.left + offset.x;
- var top = pos.top + offset.y;
- if (left + menuwidth > $(document).outerWidth())
- left -= menuwidth;
- if (top + menuheight > $(document).outerHeight())
- top -= menuheight;
-
- if (top < 0)
- top = 0;
-
- if (menu.is(':visible')) {
- menu.css({
- position: 'absolute',
- top: top + 'px',
- left: left + 'px'
- });
- $('#click-intercept').show();
- }
- };
-
- $('#main-settings').click(function() {
- var pos = $('#main-settings').offset();
- var buttonwidth = $('#main-settings').outerWidth();
- $.showPopupMenu($('#main-control-menu'), $('#main-settings'), {y: $('#main-topbar').outerHeight() - pos.top });
-
- $('#main-control-menu').css({ left: "", right: ($(document).outerWidth() - (pos.left + buttonwidth)) + 'px' });
- });
-
- $('#click-intercept').click(function() {
- $('#click-intercept').hide();
- $('.menu').hide();
- });
-
- $('#main-donate').click(function() {
-
- });
-
- $('#main-control').click(function() {
- });
-
- $('#main-newbackup').click(function() {
- APP_DATA.editNewBackup();
- });
-
- $('#main-restorebackup').click(function() {
- APP_DATA.restoreDirect();
- });
-
- $('#edit-dialog').tabs({ active: 0 });
- $('#edit-dialog').dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- { text: '< Previous', disabled: true, click: function(event, ui) {
- var cur = parseInt($('#edit-dialog').tabs( "option", "active"));
- cur = Math.max(cur-1, 0);
- $('#edit-dialog').tabs( "option", "active", cur);
- }},
- { text: 'Next >', click: function(event, ui) {
- var cur = parseInt($('#edit-dialog').tabs( "option", "active"));
- var max = $('#edit-dialog').parent().find('[role=tablist] > li').size() - 1;
-
- if (!EDIT_BACKUP.validate_tab(cur))
- return;
-
- event.curPage = cur;
- event.currentTarget.curPage = cur;
- cur = Math.min(cur+1, max);
- $('#edit-dialog').tabs( "option", "active", cur);
- }}
- ]
- });
-
- $(document).on('server-state-updated', function() {
- $('#loading-dialog').dialog("close");
- });
-
- $(document).on('server-state-lost', function() {
- $('#connection-lost-dialog').dialog('open');
- $('#connection-lost-dialog-text').text('Server connection lost...');
- var button = $('#connection-lost-dialog').parent().find('.ui-dialog-buttonpane').find('.ui-button').first();
- button.attr("disabled",false).removeClass( 'ui-button-disabled ui-state-disabled' );
-
- });
-
- $(document).on('server-state-restored', function() {
- $('#connection-lost-dialog').dialog('close');
- });
-
- $(document).on('server-state-countdown', function(e, f) {
- var s = parseInt(f.millisecondsLeft / 1000) + 1;
- $('#connection-lost-dialog-text').html('Server connection lost, <br/>retry in ' + s + ' seconds');
- var button = $('#connection-lost-dialog').parent().find('.ui-dialog-buttonpane').find('.ui-button').first();
- button.attr("disabled",false).removeClass( 'ui-button-disabled ui-state-disabled' );
- });
-
- $(document).on('server-state-connecting', function(e) {
- $('#connection-lost-dialog-text').text('Retrying...');
- var button = $('#connection-lost-dialog').parent().find('.ui-dialog-buttonpane').find('.ui-button').first();
- button.attr("disabled",true).addClass( 'ui-button-disabled ui-state-disabled' );
- });
-
- $(document).on('server-state-running', function() {
- $('#main-control').removeClass('main-icon-run').addClass('main-icon-pause');
- });
-
- $(document).on('server-state-paused', function() {
- $('#main-control').removeClass('main-icon-pause').addClass('main-icon-run');
- });
-
- $(document).on('server-state-pause-countdown', function(e, f) {
- var s = parseInt(f.millisecondsLeft / 1000) + 1;
- });
-
- $('#main-control').click(function() {
- if ($('#main-control').hasClass('main-icon-run'))
- APP_DATA.resumeServer();
- else
- APP_DATA.pauseServer();
- });
-
- $('#connection-lost-dialog').dialog({
- modal: true,
- autoOpen: false,
- closeOnEscape: false,
- buttons: [
- {
- text: 'Retry now',
- disabled: true,
- click: function(event, ui) {
- PRIVATE_DATA.long_poll_for_status();
- }
- }
- ]
- });
-
- $('#connection-lost-dialog').parent().find('.ui-dialog-titlebar-close').remove().first().remove();
-
- $('#connection-lost-dialog').on('dialogbeforeclose', function( event, ui ) {
- return !PRIVATE_DATA.server_state.failed;
- });
-
-
- $(document).on('server-state-data-updated', function() {
- PRIVATE_DATA.refresh_backup_list();
- });
-
- PRIVATE_DATA.long_poll_for_status();
- PRIVATE_DATA.refresh_server_settings();
- PRIVATE_DATA.refresh_backup_list();
-
- $('#main-control-menu').menu();
- $('#main-control-menu').removeClass('ui-widget-content');
- $('#main-control-menu-pause-submenu').removeClass('ui-widget-content');
- $('#main-control-menu-settings').hide().next().hide();
- $('#main-control-menu-throttle').hide();
-
- $('#main-control-menu-about').click(function() { APP_DATA.showAbout(); })
-
- $('#main-control-menu-pause-submenu-5m').click(function() { APP_DATA.pauseServer('5m'); });
- $('#main-control-menu-pause-submenu-10m').click(function() { APP_DATA.pauseServer('10m'); });
- $('#main-control-menu-pause-submenu-15m').click(function() { APP_DATA.pauseServer('15m'); });
- $('#main-control-menu-pause-submenu-30m').click(function() { APP_DATA.pauseServer('30m'); });
- $('#main-control-menu-pause-submenu-1h').click(function() { APP_DATA.pauseServer('1h'); });
-
- $('#main-control-menu-import').click(function() { $('#import-dialog').dialog('open'); });
- $('#main-control-menu-restore-direct').click(function() { APP_DATA.restoreDirect(); });
- $('#main-control-menu-add-backup').click(function() { APP_DATA.editNewBackup(); });
-
- var updaterState = {
- state: 'Waiting',
- version: null,
- installed: false,
- restarted: false,
- simplestate: null,
- noty: null,
- noty_type: null,
-
- closeNoty: function() {
- if (this.noty != null) {
- this.noty.close();
- this.noty = null;
- this.noty_type = null;
- }
- },
- checkingNoty: function() {
- this.closeNoty();
- this.noty = noty({
- text: 'Checking for updates ...',
- });
- this.noty_type = 'checking';
- },
- downloadingNoty: function() {
- this.closeNoty();
- var self = this;
- this.noty = noty({
- text: 'Downloading update ' + self.version,
- });
- this.noty_type = 'downloading';
- },
- setDownloadProgress: function(pg) {
- if (this.noty_type == 'downloading' && this.noty != null)
- this.noty.setText('Downloading update ' + this.version + ' (' + parseInt(pg*100) + '%)');
-
- },
- foundupdateNoty: function() {
- this.closeNoty();
- },
- updateinstalledNoty: function() {
- this.closeNoty();
- var self = this;
- this.noty = noty({
- text: 'Update <div class="noty-update-changelog-link">' + self.version + '</div> installed',
- type: 'information',
- buttons: [{
- text: 'Not now',
- onClick: function() {
- self.closeNoty();
- }
- },{
- text: 'Restart',
- onClick: function() {
- self.activateUpdate();
- self.closeNoty();
- }
- }]
- });
- this.noty_type = 'installed';
- $('.noty-update-changelog-link').click(function() { APP_DATA.showChangelog(true); });
- },
- activateUpdate: function() {
- if (confirm('Restart ' + APP_CONFIG.branded_name + ' and activate update?'))
- {
- APP_DATA.activateUpdate();
- updaterState.restarted = true;
- }
- },
- noUpdatesNoty: function() {
- noty({
- text: 'No updates found',
- timeout: 5000
- });
- }
- };
-
- $(document).on('server-state-updated', function(eventargs, data) {
- var prevstate = updaterState.simplestate;
-
- updaterState.state = data.UpdaterState;
- updaterState.version = data.UpdatedVersion;
- updaterState.installed = data.UpdateReady;
-
- if (updaterState.restarted && updaterState.version == null)
- location.reload(true);
-
- if (updaterState.state == 'Waiting') {
- if (updaterState.version == null)
- updaterState.simplestate = null;
- else if (!updaterState.installed)
- updaterState.simplestate = 'found';
- else if (updaterState.installed)
- updaterState.simplestate = 'installed';
- else
- updaterState.simplestate = null;
-
- } else if (updaterState.state == 'Checking') {
- updaterState.simplestate = 'check';
- } else if (updaterState.state == 'Downloading') {
- updaterState.simplestate = 'download';
- } else {
- updaterState.simplestate = null;
- }
-
- if (updaterState.simplestate == null) {
- $('#main-control-menu-updates > a').text('Check for updates');
- $('#main-control-menu-updates').removeClass('ui-state-disabled');
- $('#main-control-menu-check-updates').hide();
- } else if (updaterState.simplestate == 'found') {
- $('#main-control-menu-updates > a').text('Install update');
- $('#main-control-menu-updates').removeClass('ui-state-disabled');
- $('#main-control-menu-check-updates').show();
- } else if (updaterState.simplestate == 'installed') {
- $('#main-control-menu-updates > a').text('Restart with update');
- $('#main-control-menu-updates').removeClass('ui-state-disabled');
- $('#main-control-menu-check-updates').hide();
- } else if (updaterState.simplestate == 'check') {
- $('#main-control-menu-updates > a').text('Checking for update ...');
- $('#main-control-menu-updates').addClass('ui-state-disabled');
- $('#main-control-menu-check-updates').hide();
- } else if (updaterState.simplestate == 'download') {
- $('#main-control-menu-updates > a').text('Downloading update ...');
- $('#main-control-menu-updates').addClass('ui-state-disabled');
- $('#main-control-menu-check-updates').hide();
- } else {
- $('#main-control-menu-updates > a').text('Unknown state ...');
- $('#main-control-menu-updates').addClass('ui-state-disabled');
- $('#main-control-menu-check-updates').show();
- }
-
- if (updaterState.simplestate != prevstate) {
- if (updaterState.simplestate == 'found')
- updaterState.foundupdateNoty();
- else if (updaterState.simplestate == 'installed')
- updaterState.updateinstalledNoty();
- else if (updaterState.simplestate == 'check')
- updaterState.checkingNoty();
- else if (updaterState.simplestate == 'download')
- updaterState.downloadingNoty();
- else
- {
- updaterState.closeNoty();
- if (prevstate == 'check')
- updaterState.noUpdatesNoty();
- }
- } else if (updaterState.simplestate == 'download') {
- updaterState.setDownloadProgress(data.UpdateDownloadProgress);
- }
-
- });
-
- $('#main-control-menu-check-updates').click(function() {
- if (updaterState.state != 'Waiting')
- return;
-
- APP_DATA.checkForUpdates();
- });
-
- $('#main-control-menu-updates').click(function() {
- if (updaterState.state != 'Waiting')
- return;
-
- if (updaterState.version == null) {
- APP_DATA.checkForUpdates();
- } else if (!updaterState.installed) {
- APP_DATA.checkForUpdates();
- APP_DATA.installUpdate();
- } else if (updaterState.installed) {
- updaterState.activateUpdate();
- }
- });
-
- $('#main-control-menu-log').click(function() { $.showAppLog(); });
- $('#main-control-menu-options').click( function() { APP_DATA.showAppSettings(); });
-
- $('#main-control-menu').find('li').click(function() { $('#click-intercept').trigger('click'); });
-
- var pausenoty = {
- n: null,
- prevstate: null
- };
-
- $(document).on('server-state-changed', function(e, state) {
- if (pausenoty.prevstate != state && pausenoty.prevstate != null) {
- if (pausenoty.n != null)
- pausenoty.n.close();
-
- if (state == 'Running') {
- pausenoty.n = noty({
- text: 'Server is now resumed',
- timeout: 5000
- });
- } else {
- pausenoty.n = noty({
- text: 'Server is paused',
- buttons: [{
- text: 'Resume',
- onClick: function() {
- APP_DATA.resumeServer();
- }
- }]
- });
- }
- }
-
- pausenoty.prevstate = state;
- });
-
- $(document).on('server-state-pause-countdown', function(e, data) {
- if (pausenoty.prevstate != 'Paused' || pausenoty.n == null) {
- if (pausenoty.n != null)
- pausenoty.n.close();
- pausenoty.n = noty({
- text: 'Server is paused',
- buttons: [{
- text: 'Resume',
- onClick: function() {
- APP_DATA.resumeServer();
- }
- }]
- });
- }
- var seconds = parseInt(data.millisecondsLeft / 1000);
- var hours = parseInt(seconds / 3600);
- seconds -= (hours * 3600);
- var minutes = parseInt(seconds / 60)
- seconds -= (minutes * 60);
- seconds = seconds + '';
- if (seconds.length == 1)
- seconds = '0' + seconds;
-
- var timestr = '';
- if (hours > 0)
- timestr += hours + 'h ';
-
- timestr += minutes + ':' + seconds;
-
- pausenoty.n.setText('Server is paused, resuming in ' + timestr);
- });
-
- $('#about-dialog').tabs({ active: 0 });
- $("#about-dialog").dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- { text: 'Close', disabled: false, click: function(event, ui) {
- $('#about-dialog').dialog('close');
- }}
- ]
- });
-
- setInterval(function() {
- $('#main-list').find('.backup-last-run').each(function(i, e) {
- $(e).text($.timeago($.parseDate($(e).attr('alt'))));
- })
- }, 60*1000);
-
- APP_DATA.getCurrentBackupId = function() {
- return PRIVATE_DATA.server_state.activeTask == null ? null : PRIVATE_DATA.server_state.activeTask.Item2;
- };
-
- APP_DATA.getCurrentTaskId = function() {
- return PRIVATE_DATA.server_state.activeTask == null ? null : PRIVATE_DATA.server_state.activeTask.Item1;
- };
-
- APP_DATA.contextMenuId = null;
- APP_DATA.showContextMenu = function(id, anchor) {
- APP_DATA.contextMenuId = id;
- $.showPopupMenu($('#backup-context-menu'), anchor, {x: $(anchor).outerWidth() + 10});
- };
-
- APP_DATA.showAppSettings = function() {
- serverWithCallback(
- {'action': 'get-server-options'},
- function(data) {
- $('#options-dialog').trigger('setup-dialog', data);
- $('#options-dialog').dialog('open');
- },
- function(a,b,msg) {
- alert('Failed to load server options: ' + msg);
- }
- );
- };
-
- $('#backup-details-run').click(function(e) {
- APP_DATA.runBackup(APP_DATA.contextMenuId);
- });
-
- $('#backup-details-restore').click(function(e) {
- APP_DATA.restoreBackup(APP_DATA.contextMenuId);
- });
-
- $('#backup-details-edit').click(function(e) {
- APP_DATA.editBackup(APP_DATA.contextMenuId);
- });
-
- $('#backup-details-delete').click(function(e) {
- var name = APP_DATA.getBackupName(APP_DATA.contextMenuId);
-
- if (name && confirm('Really delete ' + name + '?'))
- APP_DATA.deleteBackup(APP_DATA.contextMenuId);
- });
-
- $('#backup-details-show-log').click(function(e) {
- $.showBackupLog(APP_DATA.contextMenuId);
- });
-
- $('#backup-details-verify').click(function(e) {
- APP_DATA.runVerify(APP_DATA.contextMenuId);
- });
-
- $('#backup-details-send-report').click(function(e) {
- APP_DATA.createReport(APP_DATA.contextMenuId);
- });
-
- $('#backup-details-repair').click(function(e) {
- APP_DATA.runRepair(APP_DATA.contextMenuId);
- });
-
- $('#backup-details-export').click(function(e) {
- $('#export-dialog').dialog('open');
- $('#export-dialog').data('backupid', APP_DATA.contextMenuId);
- });
-
- $('#backup-details-copy').click(function(e) {
- alert('Function is not implemented yet');
- });
-
- $('#backup-details-delete-local').click(function(e) {
- if (confirm('Do you really want to delete the local database?'))
- APP_DATA.deleteLocalData(APP_DATA.contextMenuId);
- });
-
- $('#backup-details-delete-remote').click(function(e) {
- alert('Function is not implemented yet');
- });
-
- $('#backup-context-menu').menu().removeClass('ui-widget-content');
- $('#backup-context-menu').find('li').click(function() { $('#click-intercept').trigger('click'); });
-
-
- var cancelnoty = {
- n: null,
- taskId: null,
- onRequest: function() {
- var current = APP_DATA.getCurrentTaskId();
-
- if (current == null)
- return;
-
- // Seems too harsh to use the double-stop = force logic
- /*if (this.cancel_task_id == current) {
- APP_DATA.stopTask(current, true);
- } else*/ {
- APP_DATA.stopTask(current, false);
- if (this.cancel_task_id != current) {
- this.cancel_task_id = current;
-
- if (this.n != null) {
- this.n.close();
- this.n = null;
- }
-
- this.n = noty({
- text: 'Task stopped, waiting for task to clean up',
- buttons: [{
- text: 'Force stop',
- onClick: function() {
- APP_DATA.stopTask(current, true);
- }
- }]
- });
- }
- }
- },
- onUpdate: function() {
- if (this.n == null)
- return;
-
- var current = APP_DATA.getCurrentTaskId();
- if (current != this.cancel_task_id) {
- this.n.close();
- this.n = null;
- this.cancel_task_id = null;
- }
-
- }
- };
-
-
- $(document).on('server-state-updated', function(e, data) {
- cancelnoty.onUpdate();
- });
-
- $(document).on('server-progress-updated', function(e, data) {
- cancelnoty.onUpdate();
- });
-
- $('#main-status-area-cancel-button').click(function() {
- var dlg = $('<div></div>').attr('title', 'Warning');
- dlg.dialog({
- autoOpen: true,
- width: $('body').width > 450 ? 430 : 600,
- modal: true,
- closeOnEscape: true,
- buttons: [
- { text: 'Stop now', click: function(event, ui) {
- var current = APP_DATA.getCurrentTaskId();
- if (current != null)
- APP_DATA.stopTask(current, true);
-
- dlg.dialog('close');
- dlg.remove();
- }},
- { text: 'Stop after upload', click: function(event, ui) {
- cancelnoty.onRequest();
- dlg.dialog('close');
- dlg.remove();
- }},
- { text: 'Cancel', click: function(event, ui) {
- dlg.dialog('close');
- dlg.remove();
- }}
- ]
- });
-
- var pgtxt = $('<div></div>');
- pgtxt.text('Stop the current task?');
- dlg.append(pgtxt);
-
- });
-
- $('#import-dialog').dialog({
- autoOpen: false,
- width: $('body').width > 320 ? 320 : 600,
- height: 250,
- modal: true,
- closeOnEscape: true,
- buttons: [
- { text: 'Cancel', click: function(event, ui) {
- $(this).dialog('close');
- }},
- { text: 'Import', click: function(event, ui) {
- var uid = 'submit-frm-' + Math.random();
- var callback = 'callback-' + Math.random();
- var completed = false;
-
- var iframe = $('<iframe>')
- .hide()
- .prop('id', uid)
- .prop('name', uid)
- .appendTo('body');
-
- window[callback] = function(message) {
- completed = true;
- if (message == 'OK')
- $('#import-dialog').dialog('close');
- else
- alert(message);
- };
-
- var url = APP_CONFIG.server_url;
- url += (url.indexOf('?') > -1) ? '&' : '?';
- url += $.param({'x-xsrf-token': APP_DATA.xsrf_token});
-
- $('#import-dialog-form')
- .attr('action', url)
- .attr('target', uid);
-
- $('#import-dialog-callback').val(callback);
-
- $('#import-dialog-form').submit();
-
- setTimeout(function() {
- if (!completed)
- alert('Import failed, see the log for details');
- delete window[callback];
- iframe.remove();
- }, 5000);
- }}
- ]
- });
- $('#import-dialog').on('dialogopen', function() {
- $('#import-dialog-form').each(function(i,e) {
- e.reset();
- });
- });
-
-
- $('#export-dialog').dialog({
- autoOpen: false,
- width: $('body').width > 320 ? 320 : 600,
- height: 250,
- modal: true,
- closeOnEscape: true,
- buttons: [
- { text: 'Cancel', click: function(event, ui) {
- $(this).dialog('close');
- }},
- { text: 'Export', click: function(event, ui) {
-
- var dlgself = this;
- if ($('#export-use-encryption').is(':checked') && $('#export-encryption-password').val().trim() == '') {
- alert('Empty passphrase not allowed, de-select encryption or enter a passphrase');
- return;
- }
-
- var sendobj = {
- 'action': 'export-backup',
- 'id': $('#export-dialog').data('backupid'),
- 'cmdline': $('#export-type-commandline').is(':checked'),
- 'passphrase': $('#export-encryption-password').val(),
- 'x-xsrf-token': APP_DATA.xsrf_token
- };
-
- if ($('#export-type-file').is(':checked')) {
-
- var completed = false;
- var url = APP_CONFIG.server_url;
- url += (url.indexOf('?') > -1) ? '&' : '?';
- url += $.param(sendobj);
-
- var iframe = $('<iframe>')
- .hide()
- .prop('src', url)
- .appendTo('body');
-
- setTimeout(function() { iframe.remove(); }, 5000);
-
- $(dlgself).dialog('close');
-
- } else {
- APP_DATA.callServer(sendobj,
- function(data) {
- var dlg = $('<div></div>').attr('title', 'Commandline');
- dlg.dialog({
- autoOpen: true,
- width: $('body').width > 450 ? 430 : 600,
- modal: true,
- closeOnEscape: true,
- buttons: [
- { text: 'Close', click: function(event, ui) {
- dlg.dialog('close');
- dlg.remove();
- }}
- ]
- });
-
- var pgtxt = $('<div></div>');
- pgtxt.text(data.Command);
- dlg.append(pgtxt);
-
- $(dlgself).dialog('close');
- },
- function(data, succes, status) {
- alert('Could not export: ' + status);
- });
- }
-
-
- }}
- ]
- });
-
- var option_dialog_data = null;
-
- $('#options-dialog').dialog({
- autoOpen: false,
- width: $('body').width > 320 ? 320 : 600,
- minWidth: 320,
- height: 500,
- modal: true,
- closeOnEscape: true,
- buttons: [{
- text: 'Cancel', click: function(event, ui) {
- option_dialog_data = null;
- $(this).dialog('close');
- }
- }, {
- text: 'OK', click: function(event, ui) {
- if ($('#webservice-password-enabled').is(':checked') && $('#webservice-password').val() == '') {
- EDIT_URI.validation_error($('#webservice-password'), 'Cannot use empty password');
- return;
- }
-
- var data = $.extend({}, option_dialog_data);
-
- for(var k in data)
- if (k.indexOf('--') == 0)
- delete data[k];
-
- if (!EDIT_URI.parse_extra_options($('#global-advanced-options'), data))
- return;
-
- if (!$('#webservice-remote-access-enabled').is(':checked'))
- data['server-listen-interface'] = 'loopback';
- else if (data['server-listen-interface'] == 'loopback')
- data['server-listen-interface'] = 'any';
-
- if ($('#webservice-password-enabled').is(':checked')) {
- if (data['server-passphrase'] != $('#webservice-password').val()) {
- data['server-passphrase-salt'] = CryptoJS.lib.WordArray.random(256/8).toString(CryptoJS.enc.Base64);
- data['server-passphrase'] = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Utf8.parse($('#webservice-password').val()) + CryptoJS.enc.Base64.parse(data['server-passphrase-salt']))).toString(CryptoJS.enc.Base64);
- }
- } else {
- data['server-passphrase-salt'] = '';
- data['server-passphrase'] = '';
- }
-
- data['startup-delay'] = $('#global-delay-startup-value').val() + $('#global-delay-startup-multiplier').val();
-
- var dlg = $(this);
- APP_DATA.callServer(
- {'action': 'set-server-options', 'data': JSON.stringify(data), 'HTTP_METHOD': 'POST'},
- function() {
- dlg.dialog('close');
- },
- function(a,b,msg) {
- alert('Failed to save: ' + msg);
- }
- );
-
- }
- }]
- });
-
- $('#webservice-password-enabled').change(function() {
- $('#webservice-password').attr('disabled', !$('#webservice-password-enabled').is(':checked'));
- });
-
- $('#options-dialog').on('setup-dialog', function(e, data) {
- option_dialog_data = data;
-
- $('#webservice-remote-access-enabled').attr('checked', data['server-listen-interface'] != 'loopback');
- $('#webservice-password-enabled').attr('checked', (data['server-passphrase'] || '') != '');
- $('#webservice-password-enabled').change();
-
- if ($('#webservice-password-enabled').is(':checked'))
- $('#webservice-password').val(data['server-passphrase']);
- else
- $('#webservice-password').val('');
-
- var advopts = '';
- for(var n in data)
- if (n.indexOf('--') == 0)
- advopts += n + '=' + data[n] + '\n';
-
- if ((data['startup-delay'] || '') == '') {
- $('#global-delay-startup-value').val('1');
- $('#global-delay-startup-multiplier').val('s');
- } else {
- var v = data['startup-delay'].substr(0, data['startup-delay'].length - 1);
- var m = data['startup-delay'].substr(data['startup-delay'].length - 1, 1);
- $('#global-delay-startup-value').val(v);
- $('#global-delay-startup-multiplier').val(m);
- }
-
-
- $('#global-advanced-options').val('').val(advopts);
- });
-
-
- $('#global-advanced-options-dialog').dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- { text: 'Close', disabled: false, click: function(event, ui) {
- $(this).dialog('close');
- }}
- ]
- });
-
-
- $('#global-options-link').click(function() {
- APP_DATA.getServerConfig(function(data) {
- $('#global-advanced-options-dialog').dialog('open');
-
- var baseOpts = data.Options;
-
- for(var n in data.BackendModules)
- baseOpts = baseOpts.concat(data.BackendModules[n].Options);
-
- for(var n in data.CompressionModules)
- baseOpts = baseOpts.concat(data.CompressionModules[n].Options);
-
- for(var n in data.EncryptionModules)
- baseOpts = baseOpts.concat(data.EncryptionModules[n].Options);
-
- for(var n in data.GenericModules)
- baseOpts = baseOpts.concat(data.GenericModules[n].Options);
-
-
- $('#global-advanced-options-dialog').trigger('configure', { Options: baseOpts, callback: function(id) {
- $('#global-advanced-options-dialog').dialog('close');
-
- var txt = $('#global-advanced-options').val().trim();
- if (txt.length > 0)
- txt += '\n';
-
- var defaultvalue = '';
- for(var o in data.Options)
- if (data.Options[o].Name == id) {
- defaultvalue = data.Options[o].DefaultValue;
- break;
- }
-
-
- txt += '--' + id + '=' + defaultvalue;
- $('#global-advanced-options').val('').val(txt);
- $('#global-advanced-options').focus();
-
- }});
- }, function() {
- });
- });
-
- $('#global-advanced-options-dialog').on('configure', function(e, data) {
- $('#global-advanced-options-dialog').empty();
-
- var s = data.Options.sort(function(a, b){
- if (a == null)
- return -1;
- if (b == null)
- return 1;
- if (a == null && b == null)
- return 0;
-
- if(a.Name < b.Name) return -1;
- if(a.Name > b.Name) return 1;
- return 0;
- });
-
- //Fill with jQuery template
- $.tmpl($('#backup-option-template'), s).prependTo($('#global-advanced-options-dialog'));
- $('#global-advanced-options-dialog').find('.backup-option-link').click(function(e) {
- data.callback(e.target.id);
- });
-
- $('#global-advanced-options-dialog').find('.backup-option-long').each(function(i, e) {
- $(e).html(nl2br($(e).html()));
- });
- });
-
- var exportTypeChange = function() {
- $('#export-use-encryption').attr('disabled', !$('#export-type-file').is(':checked'));
- $('#export-use-encryption').change();
- };
-
- $('#export-dialog').on('dialogopen', function() {
- $('#export-type-commandline').attr('checked', true);
- $('#export-use-encryption').attr('checked', false);
- $('#export-encryption-password').val('');
- exportTypeChange();
- });
-
- $('#export-type-commandline').change(exportTypeChange);
- $('#export-type-file').change(exportTypeChange);
- $('#export-use-encryption').change(function() {
- $('#export-encryption-password').attr('disabled', !($('#export-use-encryption').is(':checked') && $('#export-type-file').is(':checked')));
- });
-
-});
diff --git a/Duplicati/Server/webroot/greeno/scripts/config.js b/Duplicati/Server/webroot/greeno/scripts/config.js
deleted file mode 100644
index fd2e004c0..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/config.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * The basic client config
- */
-
-APP_CONFIG = {
- server_url: '/control.cgi',
- login_url: '/login.html',
- branded_name: 'Duplicati',
- branded_subtitle: ''
-};
diff --git a/Duplicati/Server/webroot/greeno/scripts/editdialog.js b/Duplicati/Server/webroot/greeno/scripts/editdialog.js
deleted file mode 100644
index f931fa5e4..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/editdialog.js
+++ /dev/null
@@ -1,1121 +0,0 @@
-/*
- * Edit dialog app code
- */
-
- EDIT_STATE = null;
- EDIT_BACKUP = null;
-
-$(document).ready(function() {
-
- var dirSep = '/';
-
- EDIT_BACKUP = {
- validate_tab: function(tab) {
- var tabs = $('#edit-dialog').parent().find('[role=tablist] > li');
- tab += '';
-
- if (tab.length > 0 && tab[0] == '#')
- tab = tab.substr(1);
-
- if (parseInt(tab) + '' == tab) {
- tab = tabs[parseInt(tab)]
- } else {
- var tt = tab;
- tab = null;
- for(var n in tabs) {
- var href = $(n).find('a').attr('href');
- if (href && href[0] == '#') {
- href = href.substr(1);
- }
-
- if (tabs[n] == tt || href == tab) {
- tab = tabs[n];
- break;
- }
- }
- }
-
- if (tab) {
- var href = $(tab).find('a').attr('href');
- if (href && href[0] == '#')
- href = href.substr(1);
-
- var index;
- for(index in tabs)
- if (tab == tabs[index])
- break;
-
- if (EDIT_BACKUP.validate_form_map[href]) {
- if (!EDIT_BACKUP.validate_form_map[href](index)) {
- return false;
- }
- }
-
- return true;
- } else {
- return false;
- }
-
- },
-
- validate_form_map: {
- 'edit-tab-general': function(tabindex) {
- if ($('#backup-name').val().trim() == '') {
- $('#edit-dialog').tabs( "option", "active", tabindex);
- $('#backup-name').focus();
- alert('You must enter a name for the backup');
- return false;
- }
-
- if ($('#backup-uri').val().trim() == '') {
- $('#edit-dialog').tabs( "option", "active", tabindex);
- $('#backup-uri').focus();
- alert('You must enter a connection url for the backup');
- return false;
- }
-
- if ($('#encryption-method').val() != '') {
- if ($('#encryption-password').val().trim() == '') {
- $('#edit-dialog').tabs( "option", "active", tabindex);
- $('#encryption-password').focus();
- alert('You must enter a passphrase');
- return false;
- }
-
- if (!EDIT_STATE.passwordShown && $('#repeat-password').hasClass('password-mismatch')) {
- $('#edit-dialog').tabs( "option", "active", tabindex);
- $('#repeat-password').focus();
- alert('The passwords do not match');
- return false;
- }
- }
-
- return true;
- },
-
- 'edit-tab-sourcedata': function(tabindex) {
-
- if ($('#source-folder-paths').find('.source-folder').length == 0) {
- $('#edit-dialog').tabs( "option", "active", tabindex);
- $('#source-folder-paths').focus();
- alert('You must select at least one source folder to back up');
- return false;
- }
-
- return true;
- },
-
- 'edit-tab-schedule': function(tabindex) {
- if ($('#use-scheduled-run').is(':checked')) {
- var t = Date.parse($('#next-run-date').val() + 'T' + $('#next-run-time').val());
- if (isNaN(t)) {
- $('#edit-dialog').tabs( "option", "active", tabindex);
- $('#next-run-time').focus();
- alert('You must enter a valid time');
- return false;
- }
- }
-
- return true;
- },
-
- 'edit-tab-options': function(tabindex) {
- var kt = ($('#keep-time-number').val() || '').trim();
- if ($('#keep-time-type').val() != '' && (parseInt(kt) <= 0 || (parseInt(kt) + '') != kt)) {
- $('#edit-dialog').tabs( "option", "active", tabindex);
- $('keep-time-number').focus();
- alert('You must enter a positive integer for the backup retention');
- return false;
- }
-
- return true;
- }
- },
-
- fill_form_map: {
- 'encryption-module': 'encryption-method',
- 'Name': 'backup-name',
- 'TargetURL': 'backup-uri',
- 'passphrase': function(dict, key, val, cfgel) {
- $('#encryption-password').val(val);
- $('#repeat-password').val(val);
- },
- 'Sources': function(dict, key, val, cfgel) {
- var sources = val || [];
-
- var lookup = {};
- if (EDIT_STATE.orig_config && EDIT_STATE.orig_config.DisplayNames)
- lookup = EDIT_STATE.orig_config.DisplayNames;
-
- $('#source-folder-paths').find('.source-folder').remove();
- for(var n in sources) {
- var p = sources[n];
- var rp = p;
- addSourceFolder(rp, lookup[p] || p);
- }
- },
- 'Tags': function(dict, key, val, cfgel) {
- var tags = val || [];
- //$('#backup-labels').val(tags.join(', '));
- },
- 'Schedule': function(dict, key, val, cfgel) {
- $('#use-scheduled-run').attr('checked', val != null)
- $('#use-scheduled-run').trigger('change');
- },
- 'Repeat': function(dict, key, val, cfgel) {
- $('#use-scheduled-run').attr('checked', val != '');
- $('#use-scheduled-run').change();
-
- if (!$('#use-scheduled-run').is(':checked'))
- return;
-
- var m = (/(\d*)(\w)/mg).exec(val);
- var mul = null;
- if (m) {
- switch(m[2]) {
- case 'D':
- mul = 'days';
- break;
- case 'h':
- mul = 'hours';
- break;
- case 'M':
- mul = 'months';
- break;
- case 'Y':
- mul = 'years';
- break;
- case 'W':
- mul = 'weeks';
- break;
- }
- }
-
- if (!mul) {
- // Strange stuff, just use it as-is
- $('#repeat-run-number').val(val + '');
- $('#repeat-run-multiplier').val('custom');
- } else {
- $('#repeat-run-number').val(m[1]);
- $('#repeat-run-multiplier').val(m[2]);
- }
- },
- 'Time': function(dict, key, val, cfgel) {
- var parts = val.split(':');
- var now = new Date();
- var msec = Date.parse(val);
- if (isNaN(msec))
- msec = Date.parse("1970-01-01T" + val);
-
- var d = null;
- if (isNaN(msec)) {
- d = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 13, 0, 0);
-
- $('#next-run-time').val('13:00');
- $('#next-run-date').val(now);
- } else {
- d = new Date(msec);
- if (d.getFullYear() <= 1970) {
- msec += new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0).getTime();
- d = new Date(msec);
- }
- }
-
- var y = d.getFullYear() + '';
- var m = (d.getMonth() + 1) + '';
- var n = d.getDate() + '';
-
- var h = d.getHours() + '';
- var l = d.getMinutes() + '';
- var s = d.getSeconds() + '';
-
- if (m.length == 1)
- m = '0' + m;
- if (n.length == 1)
- n = '0' + n;
- if (h.length == 1)
- h = '0' + h;
- if (l.length == 1)
- l = '0' + l;
- if (s.length == 1)
- s = '0' + s;
-
- $('#next-run-date').val(y + '-' + m + '-' + n);
- $('#next-run-time').val(h + ':' + l + ':' + s);
-
- },
- 'AllowedDays': function(dict, key, val, cfgel) {
-
- var d = false;
- if (val == null || val.length == 0)
- d = true;
-
- var n = {
- 'mon': d,
- 'tue': d,
- 'wed': d,
- 'thu': d,
- 'fri': d,
- 'sat': d,
- 'sun': d
- };
-
- for(var i in val)
- if (n[val[i]] !== undefined)
- n[val[i]] = true;
-
- for(var k in n) {
- $('#allow-day-' + k).attr('checked', n[k]);
- }
- },
- 'dblock-size': function(dict, key, val, cfgel) {
- var m = (/(\d*)(\w*)/mg).exec(val);
- var mul = null;
- if (m) {
- $('#dblock-size-number').val(m[1]);
- $('#dblock-size-multiplier').val(m[2]);
- }
- },
- 'keep-time': function(dict, key, val, cfgel) {
- if (val == null || val.length == 0) {
- $('#keep-time-type').val('');
- } else {
- var m = (/(\d*)(\w)/mg).exec(val);
- if (m) {
- $('#keep-time-type').val('keep-time');
- $('#keep-time-number').val(parseInt(m[1]));
- $('#keep-time-multiplier').val(m[2]);
- } else {
- $('#keep-time-type').val('');
- }
- }
-
- $('#keep-time-type').change();
- },
- 'keep-versions': function(dict, key, val, cfgel) {
- if (val == null || val.length == 0) {
- $('#keep-time-type').val('');
- } else {
- $('#keep-time-type').val('keep-versions');
- $('#keep-time-number').val(parseInt(val));
- }
- $('#keep-time-type').change();
- }
- },
-
- fill_dict_map: {
- 'source-folder-path-text': false,
- 'repeat-password': false,
- 'dblock-size-multiplier': false,
- 'repeat-run-multiplier': false,
- 'next-run-date': false,
- 'allow-day-mon': false,
- 'allow-day-tue': false,
- 'allow-day-wed': false,
- 'allow-day-thu': false,
- 'allow-day-fri': false,
- 'allow-day-sat': false,
- 'keep-time-number': false,
- 'keep-time-multiplier': false,
-
- 'allow-day-sun': function(dict, key, el, cfgel) {
- if (!$('#use-scheduled-run').is(':checked'))
- return;
-
- if (!dict['Schedule'])
- dict['Schedule'] = {};
-
-
- // Collect all days
- var days = [];
- var r = ['mon', 'tue', 'wed', 'thu','fri', 'sat', 'sun'];
- for(var k in r)
- if ($('#allow-day-' + r[k]).is(':checked'))
- days.push(r[k]);
-
- dict['Schedule']['AllowedDays']= days;
- },
- 'encryption-password': function(dict, key, el, cfgel) {
- dict['Backup']['Settings']['passphrase'] = $(el).val();
- },
- 'source-folder-list': function(dict, key, el, cfgel) {
- var sources = [];
- $('#source-folder-paths').find('.source-folder').each(function(i,el) {
- var p = $(el).data('id');
- sources.push(p);
- });
-
- dict['Backup']['Sources'] = sources;
- },
- 'use-scheduled-run': function(dict, key, el, cfgel) {
- if (!$(el).is(':checked')) {
- dict['Schedule'] = null;
- } else if(!dict['Schedule']) {
- dict['Schedule'] = {};
- }
- },
- 'backup-uri': function(dict, key, el, cfgel) {
- dict['Backup']['TargetURL'] = $(el).val();
- },
- 'backup-name': function(dict, key, el, cfgel) {
- dict['Backup']['Name'] = $(el).val();
- },
- 'backup-labels': function(dict, key, el, cfgel) {
-// dict['Backup']['Tags'] = $(el).val().split(',');
- },
- 'encryption-method': function(dict, key, el, cfgel) {
- dict['Backup']['Settings']['encryption-module'] = $(el).val();
- if ($(el).val().trim() == '')
- dict['Backup']['Settings']['--no-encryption'] = true;
- else
- delete dict['Backup']['Settings']['--no-encryption'];
- },
- 'next-run-time': function(dict, key, el, cfgel) {
- if (!$('#use-scheduled-run').is(':checked'))
- return;
-
- if (!dict['Schedule'])
- dict['Schedule'] = {};
-
- var t = Date.parse($('#next-run-date').val());
- if (t != NaN) {
- var tp = $('#next-run-time').val().split(':');
- while(tp.length < 3)
- tp.push('00');
-
- var d = new Date(t);
- d = new Date(d.getFullYear(), d.getMonth(), d.getDate(), parseInt(tp[0]), parseInt(tp[1]), parseInt(tp[2]))
-
- dict['Schedule']['Time'] = d.toISOString();
- }
- },
- 'dblock-size-number': function(dict, key, el, cfgel) {
- dict['Backup']['Settings']['dblock-size'] = $(el).val() + $('#dblock-size-multiplier').val();
- },
- 'repeat-run-number': function(dict, key, el, cfgel) {
- if (!$('#use-scheduled-run').is(':checked'))
- return;
-
- if (!dict['Schedule'])
- dict['Schedule'] = {};
-
- var m = $('#repeat-run-multiplier').val();
- if (m == 'custom')
- dict['Schedule']['Repeat'] = $(el).val();
- else
- dict['Schedule']['Repeat'] = $(el).val() + m;
- },
- 'keep-time-type': function(dict, key, el, cfgel) {
- var t = $('#keep-time-type').val();
- if (t == 'keep-time') {
- delete dict['Backup']['Settings']['keep-versions'];
- dict['Backup']['Settings']['keep-time'] = parseInt($('#keep-time-number').val()) + $('#keep-time-multiplier').val();
- } else if (t == 'keep-versions') {
- delete dict['Backup']['Settings']['keep-time'];
- dict['Backup']['Settings']['keep-versions'] = parseInt($('#keep-time-number').val());
- } else {
- delete dict['Backup']['Settings']['keep-versions'];
- delete dict['Backup']['Settings']['keep-time'];
- }
- },
- 'store-task-config': function(dict, key, el, cfgel) {
- dict['Backup']['Settings']['store-task-config'] = $(el).val();
- }
- }
- };
-
- $('#backup-name').watermark('Photos 2015');
-// $('#backup-labels').watermark('work, docs, s3, movies, other');
- $('#backup-uri').watermark('webdavs://user:pass@example.com:995/backup?option=true');
- $('#encryption-password').watermark('Long and secret passphrase');
- $('#repeat-password').watermark('Long and secret passphrase');
- $('#backup-options').watermark('Enter one option per line in command-line format, eg. --dblock-size=100MB');
- $('#source-folder-path-text').watermark('Enter a path to back up');
- $('#source-filters').watermark('One filter per line, e.g. "+*.txt" or "-[.*\\.txt]"');
-
- var updateState = function() { if (EDIT_STATE != null) EDIT_STATE.dataModified = true; };
-
- $('#backup-name').change(updateState);
-// $('#backup-labels').change(updateState);
- $('#backup-uri').change(updateState);
- $('#encryption-password').change(updateState);
- $('#repeat-password').change(updateState);
- $('#backup-options').change(updateState);
- $('#source-filters').change(updateState);
-
- function split(val) {
- return val.split(/,\s*/);
- }
- function extractLast(val) {
- return split(val).pop();
- }
-
- // $('#backup-labels').autocomplete({
- // minLength: 0,
-
- // source: function(request, response) {
- // if (EDIT_STATE != null && EDIT_STATE.tags != null)
- // response( $.ui.autocomplete.filter(EDIT_STATE.tags, extractLast(request.term)));
- // },
-
- // focus: function() {
- // return false;
- // },
-
- // select: function( event, ui ) {
- // var terms = split( this.value );
- // terms.pop(); //remove current
- // terms.push(ui.item.value);
- // terms.push(''); //prepare for new
- // this.value = terms.join(', ');
- // return false;
- // }
- // });
-
- var updatePasswordIndicator = function() {
-
- var strengthMap = {
- 0: "Useless",
- 1: "Very weak",
- 2: "Weak",
- 3: "Strong",
- 4: "Very strong"
- };
-
- $.passwordStrength($('#encryption-password')[0].value, function(r) {
- var f = $('#backup-password-strength');
- if (r == null) {
- f.text('Strength: Unknown');
- r = {score: -1}
- } else {
- console.log(r)
- f.text('Strength: ' + strengthMap[r.score]);
- }
-
- f.removeClass('password-strength-0');
- f.removeClass('password-strength-1');
- f.removeClass('password-strength-2');
- f.removeClass('password-strength-3');
- f.removeClass('password-strength-4');
- f.removeClass('password-strength-unknown');
-
- if (r.score == 0)
- f.addClass('password-strength-0');
- else if (r.score == 1)
- f.addClass('password-strength-1');
- else if (r.score == 2)
- f.addClass('password-strength-2');
- else if (r.score == 3)
- f.addClass('password-strength-3');
- else if (r.score == 4)
- f.addClass('password-strength-4');
- else
- f.addClass('password-strength-unknown');
-
- });
-
- if ($('#encryption-password').val() != $('#repeat-password').val()) {
- $('#repeat-password').addClass('password-mismatch');
- //$('#encryption-password').addClass('password-mismatch');
- } else {
- $('#repeat-password').removeClass('password-mismatch');
- //$('#encryption-password').removeClass('password-mismatch');
- }
- }
-
- $('#encryption-password').change(updatePasswordIndicator);
- $('#repeat-password').change(updatePasswordIndicator);
- $('#encryption-password').keyup(updatePasswordIndicator);
- $('#repeat-password').keyup(updatePasswordIndicator);
-
- $('#toggle-show-password').click(function() {
- $('#encryption-password').togglePassword();
- });
-
- $('#encryption-password').on('passwordShown', function () {
- $('#toggle-show-password').text('Hide')
- $('#repeat-password').showPassword();
- EDIT_STATE.passwordShown = true;
- //$('#repeat-password').hide();
- //$('#repeat-password-label').hide();
- }).on('passwordHidden', function () {
- $('#toggle-show-password').text('Show')
- $('#repeat-password').hidePassword();
- EDIT_STATE.passwordShown = false;
- //$('#repeat-password').show();
- //$('#repeat-password-label').show();
- });
-
- $('#generate-password').click(function() {
- var specials = '!@#$%^&*()_+{}:"<>?[];\',./';
- var lowercase = 'abcdefghijklmnopqrstuvwxyz';
- var uppercase = lowercase.toUpperCase();
- var numbers = '0123456789';
- var all = specials + lowercase + uppercase + numbers;
-
- function choose(str, n) {
- var res = '';
- for (var i = 0; i < n; i++) {
- res += str.charAt(Math.floor(Math.random() * str.length));
- }
-
- return res;
- };
-
- var pwd = (
- choose(specials, 2) +
- choose(lowercase, 2) +
- choose(uppercase, 2) +
- choose(numbers, 2) +
- choose(all, (Math.random()*5) + 5)
- ).split('');
-
- for(var i = 0; i < pwd.length; i++) {
- var pos = parseInt(Math.random() * pwd.length);
- var t = pwd[i]
- pwd[i] = pwd[pos];
- pwd[pos] = t;
- }
-
- pwd = pwd.join('');
-
- $('#encryption-password')[0].value = pwd;
- $('#repeat-password')[0].value = pwd;
-
- $('#encryption-password').showPassword();
- updatePasswordIndicator();
- });
-
- $('#backup-uri-label').click(function() {
- $('#connection-uri-dialog').dialog('open');
- $('#connection-uri-dialog').trigger('setup-dialog', $('#backup-uri'));
- });
-
- var dlg_buttons = $('#edit-dialog').parent().find('.ui-dialog-buttonpane').find('.ui-button');
-
- $('#edit-dialog').on( "tabsactivate", function( event, ui ) {
-
- var tabs = $('#edit-dialog').parent().find('[role=tablist] > li');
-
- if (ui.newPanel.attr('id') == tabs.first().attr('aria-controls'))
- dlg_buttons.first().button('option', 'disabled', true);
- else if (ui.oldPanel.attr('id') == tabs.first().attr('aria-controls'))
- dlg_buttons.first().button('option', 'disabled', false);
-
- if (ui.newPanel.attr('id') == tabs.last().attr('aria-controls'))
- dlg_buttons.last().button('option', 'label', 'Save');
- else if (ui.oldPanel.attr('id') == tabs.last().attr('aria-controls'))
- dlg_buttons.last().button('option', 'label', 'Next >');
-
- });
-
- $('#edit-dialog').on( "dialogopen", function( event, ui ) {
- $('#edit-dialog-form').each(function(i, e) { e.reset(); });
- $('#edit-dialog-form select').each(function(i, e) { $(e).change(); });
- $('#edit-dialog-form input').each(function(i, e) { $(e).change(); });
- $('#source-folder-paths').find('.source-folder').remove();
- removeSourceFolder();
-
- EDIT_STATE = {
- passwordShown: false,
- dataModified: false,
- passwordModified: false,
- newBackup: true
- };
-
- APP_DATA.getServerConfig(function(serverdata) {
- dirSep = serverdata.DirectorySeparator;
-
- if (serverdata['EncryptionModules'] == null || serverdata['EncryptionModules'].length == 0) {
- $('#encryption-area').hide();
- } else {
- $('#encryption-area').show();
-
- var drop = $('#encryption-method');
- drop.empty();
-
- drop.append($("<option></option>").attr("value", '').text('No encryption'));
-
- var encmodules = serverdata['EncryptionModules'];
-
- for (var i = 0; i < encmodules.length; i++)
- drop.append($("<option></option>").attr("value", encmodules[i].Key).text(encmodules[i].DisplayName));
- }
-
- $('#encryption-method').change();
- });
-
- APP_DATA.getLabels(function(labels) {
- EDIT_STATE.tags = labels;
- });
-
- $('#edit-dialog').tabs('option', 'active', 0);
- });
-
- $('#encryption-method').change(function() {
- if ($('#encryption-method').val() == '')
- $('#encryption-password-area').hide();
- else
- $('#encryption-password-area').show();
- });
-
-
- $('#edit-dialog').on( "dialogbeforeclose", function( event, ui ) {
- //TODO: Actually set this flag
- if (EDIT_STATE.dataModified) {
- if (!confirm('Close without saving?'))
- return false;
- }
- });
-
- var readFormData = function(validateOptions) {
-
- var obj = {
- 'Schedule': {},
- 'Backup': {
- 'Settings': {},
- 'Filters': [],
- 'Sources': [],
- 'Tags': []
- }
- };
-
- // To protect against data loss, we use the orig config and update it
- if (EDIT_STATE.orig_config != null)
- $.extend(true, obj, EDIT_STATE.orig_config);
-
- for(var k in obj.Backup.Settings)
- if (k.indexOf('--') == 0)
- delete obj.Backup.Settings[k];
-
- APP_UTIL.read_form($('#edit-dialog-form'), EDIT_BACKUP.fill_dict_map, obj);
-
- if (!APP_UTIL.parseOptionStrings($('#backup-options').val(), obj.Backup.Settings, function() {
- //TODO: Add validation
- return true;
- })) {
- return null;
- }
-
- var filters = $('#source-filters').val();
- var filterlist = [];
- if (filters != '') {
- var lines = filters.split('\n');
-
- for(var i in lines) {
- var ld = lines[i].trim();
- if (ld == '')
- continue;
-
- if (ld[0] != '-' && ld[0] != '+') {
- EDIT_URI.validation_error($('#source-filters'), 'Each filter line must start with either a "+" or a "-" character');
- return null;
- }
-
- filterlist.push({'Expression': ld.substr(1), 'Include': ld[0] == '+', 'Order': i});
- }
- }
-
- obj.Backup.Filters = filterlist;
-
- return obj
- };
-
- dlg_buttons.last().click(function(event, ui) {
- var tabs = $('#edit-dialog').parent().find('[role=tablist] > li');
- if (event.curPage == tabs.size() - 1) {
- // Saving, validate first
-
- for(var n in tabs) {
- if (!EDIT_BACKUP.validate_tab(n)) {
- return;
- }
- }
-
- var obj = readFormData(true);
- if (obj == null)
- return;
- //Fixup, change settings dict into array
-
- var set = obj.Backup.Settings;
- obj.Backup.Settings = [];
- for(var k in set)
- obj.Backup.Settings.push({Name: k, Value: set[k]});
-
- if (EDIT_STATE.newBackup) {
-
- APP_DATA.locateUriDb(obj.Backup.TargetURL, function(res) {
- var existing_db = (res.Exists && confirm("An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?")) ? true : false;
-
- APP_DATA.addBackup(obj, function() {
- EDIT_STATE.dataModified = false;
- $('#edit-dialog').dialog('close');
- },
- function(data, succes, status) {
- alert('Could not save: ' + status);
- },
- {
- existing_db: existing_db
- });
- },
- function(data, succes, status) {
- alert('Could not save: ' + status);
- });
-
- } else {
- APP_DATA.updateBackup(obj, function() {
- EDIT_STATE.dataModified = false;
- $('#edit-dialog').dialog('close');
- },
- function(data, succes, status) {
- alert('Could not save: ' + status);
- });
- }
-
- }
- });
-
- var removeSourceFolder = function(el) {
- var container = $('#source-folder-paths');
- if (el)
- container.each(function(i, e) { e.removeChild(el) });
-
- if (container.find('.source-folder').length == 0) {
- container.addClass('empty');
- $('#source-folder-paths-hint').show();
- }
- };
-
- var addSourceFolder = function(path, display) {
- var container = $('#source-folder-paths');
- container.removeClass('empty');
- $('#source-folder-paths-hint').hide();
-
- if (path == null || path.trim() == '')
- return false;
-
- var exists = false;
- container.find('.source-folder').each(function(i,el) {
- exists |= $(el).data('id') == path;
- });
-
- if (exists)
- return false;
-
- var div = $('<div>').addClass('source-folder').text(display).each(function(i, e) { if (path[0] != '%') { e.title = path; }});
- var closer = $('<div></div>').addClass('source-folder-close-icon');
- div.append(closer);
-
- closer.click(function() {
- removeSourceFolder(div[0]);
- });
-
- container.append(div);
-
- $(div).data('id', path);
-
- APP_DATA.validatePath(path, function(path, success) {
- if (success)
- div.addClass('path-valid');
- else
- div.addClass('path-invalid');
- });
-
- return true;
- };
-
- var browsePath = function() {
- $.browseForFolder({
- title: 'Select folder to back up',
- multiSelect: true,
- callback: function(path, disp) {
- disp = (disp || path).split(dirSep);
- addSourceFolder(path, disp[disp.length - 1]);
- }
- });
- };
-
- $('#source-folder-path-browse').click(browsePath);
-
- $('#source-folder-path-add').click(function() {
- if ($('#source-folder-path-text').val() == '') {
- browsePath();
- } else {
- var path = $('#source-folder-path-text').val();
- var disp = path.split(dirSep);
- if (addSourceFolder(path, disp[disp.length - 1])) {
- $('#source-folder-path-text').val('');
- $('#source-folder-path-text').trigger('change');
- $('#source-folder-path-text').focus();
- }
- }
-
- });
-
- $('#source-folder-path-text').keypress(function(e) {
- if (e.which == 13)
- $('#source-folder-path-add').click();
- else
- $('#source-folder-path-text').trigger('change');
-
- });
-
- $('#source-folder-path-text').keyup(function(e) {
- $('#source-folder-path-text').trigger('change');
-
- });
-
- $('#source-folder-path-text').change(function(e, data) {
- if ($('#source-folder-path-text').val().trim() == '')
- $('#source-folder-path-add').button('option', 'label', 'Browse');
- else
- $('#source-folder-path-add').button('option', 'label', 'Add');
- });
-
- // Register a drop target for folder nodes
- var inActualMove = false;
- $('#source-folder-droptarget').jstree({
- 'core': {
- 'check_callback': function(method, item, parent, position) {
- if (inActualMove)
- addSourceFolder(item.data('id'), item.data('display'));
-
- return !inActualMove;
- },
- },
- 'dnd': { copy: false }
- });
-
- // We need to know if the check callback happens on drop or on drag
- // but jstree only sends "move_node"
- var tree = $('#source-folder-droptarget').data('jstree');
- tree.tree_move_orig = tree.move_node;
- tree.move_node = function(obj, par, pos, callback, is_loaded) {
- try {
- inActualMove = true;
- this.tree_move_orig(obj, par, pos, callback, is_loaded);
- } finally {
- inActualMove = false;
- }
- }
-
- $("#edit-dialog").on('setup-dialog', function(e, data) {
- if (data.Backup && data.Backup.ID && parseInt(data.Backup.ID) > 0) {
- EDIT_STATE.orig_config = data;
- EDIT_STATE.newBackup = false;
- } else {
- EDIT_STATE.orig_config = null;
- EDIT_STATE.newBackup = true;
- }
-
- if (data['Schedule'] == null || data['Schedule']['Repeat'] == null || data['Schedule']['Repeat'] == '')
- APP_UTIL.fill_form($('#edit-dialog-form'), { 'Schedule': null }, EDIT_BACKUP.fill_form_map, 'Schedule');
- else
- APP_UTIL.fill_form($('#edit-dialog-form'), data['Schedule'], EDIT_BACKUP.fill_form_map, 'Schedule');
-
- // Convert from list-form to key/value map
- var orig = data['Backup'].Settings;
- var settings = {};
- data['Backup'].Settings = settings;
- for(var n in orig)
- settings[orig[n].Name] = orig[n].Value;
-
- APP_UTIL.fill_form($('#edit-dialog-form'), data['Backup'], EDIT_BACKUP.fill_form_map, d);
-
- for(var d in data['Backup'])
- if (typeof(data['Backup'][d]) == typeof({}))
- APP_UTIL.fill_form($('#edit-dialog-form'), data['Backup'][d], EDIT_BACKUP.fill_form_map, d);
-
- var opttext = '';
- for(var k in data['Backup']['Settings'])
- if (EDIT_BACKUP.fill_form_map[k] === undefined && k.indexOf('--') == 0)
- opttext += k + '=' + (data['Backup']['Settings'][k] || '') + '\n';
-
- $('#backup-options').val(opttext);
-
- var filtertext = '';
- for(var k in data['Backup']['Filters'])
- filtertext += (data['Backup']['Filters'][k].Include ? '+' : '-') + data['Backup']['Filters'][k].Expression + '\n';
-
- $('#source-filters').val(filtertext);
-
-
- EDIT_STATE.dataModified = false;
- });
-
- $('#backup-options-dialog').dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- { text: 'Close', disabled: false, click: function(event, ui) {
- $(this).dialog('close');
- }}
- ]
- });
-
- $('#backup-options-link').click(function() {
- APP_DATA.getServerConfig(function(data) {
- $('#backup-options-dialog').dialog('open');
-
- var baseOpts = data.Options;
-
- var obj = readFormData(false);
- var compressionModule = '';
- var encryptionModule = '';
-
- for (var i in data.Options)
- if (data.Options[i].Name == 'compression-module')
- compressionModule = data.Options[i].DefaultValue;
- else if (data.Options[i].Name == 'encryption-module')
- encryptionModule = data.Options[i].DefaultValue;
-
- if (obj != null && obj.Backup != null && obj.Backup.Settings != null) {
- if (obj.Backup.Settings['compression-module'] != null && obj.Backup.Settings['compression-module'] != '')
- compressionModule = obj.Backup.Settings['compression-module'];
- if (obj.Backup.Settings['encryption-module'] != null && obj.Backup.Settings['encryption-module'] != '')
- encryptionModule = obj.Backup.Settings['encryption-module'];
- }
-
- for(var n in data.CompressionModules)
- if (data.CompressionModules[n].Key == compressionModule) {
- baseOpts = baseOpts.concat(data.CompressionModules[n].Options);
- break;
- }
-
- for(var n in data.EncryptionModules)
- if (data.EncryptionModules[n].Key == encryptionModule) {
- baseOpts = baseOpts.concat(data.EncryptionModules[n].Options);
- break;
- }
-
- for(var n in data.GenericModules)
- baseOpts = baseOpts.concat(data.GenericModules[n].Options);
-
-
- $('#backup-options-dialog').trigger('configure', { Options: baseOpts, callback: function(id) {
- $('#backup-options-dialog').dialog('close');
-
- var txt = $('#backup-options').val().trim();
- if (txt.length > 0)
- txt += '\n';
-
- var defaultvalue = '';
- for(var o in data.Options)
- if (data.Options[o].Name == id) {
- defaultvalue = data.Options[o].DefaultValue;
- break;
- }
-
-
- txt += '--' + id + '=' + defaultvalue;
- $('#backup-options').val('').val(txt);
- $('#backup-options').focus();
-
- }});
- }, function() {
- });
- });
-
- $('#backup-options-dialog').on('configure', function(e, data) {
- $('#backup-options-dialog').empty();
-
- var s = data.Options.sort(function(a, b){
- if (a == null)
- return -1;
- if (b == null)
- return 1;
- if (a == null && b == null)
- return 0;
-
- if(a.Name < b.Name) return -1;
- if(a.Name > b.Name) return 1;
- return 0;
- });
-
- //Fill with jQuery template
- $.tmpl($('#backup-option-template'), s).prependTo($('#backup-options-dialog'));
- $('#backup-options-dialog').find('.backup-option-link').click(function(e) {
- data.callback(e.target.id);
- });
-
- $('#backup-options-dialog').find('.backup-option-long').each(function(i, e) {
- $(e).html(nl2br($(e).html()));
- });
- });
-
- var setStateModified = function() {
- if (EDIT_STATE != null)
- EDIT_STATE.dataModified = true;
- };
-
- $('#edit-dialog-form').find('input').change(setStateModified);
- $('#edit-dialog-form').find('select').change(setStateModified);
- $('#edit-dialog-form').find('textarea').change(setStateModified);
-
- $('#use-scheduled-run').change(function() {
- if ($('#use-scheduled-run').is(':checked')) {
- $('#use-scheduled-run-details').show();
-
- var dt = new Date();
- dt.setHours(dt.getHours() + 1);
- dt.setMinutes(0);
- dt.setSeconds(0);
-
- if ($('#next-run-time').val() == '') {
- var h = dt.getHours() + '';
- var m = dt.getMinutes() + '';
- if (h.length == 1)
- h = '0' + h;
- if (m.length == 1)
- m = '0' + m;
- $('#next-run-time').val(h + ':' + m);
- }
-
- if ($('#next-run-date').val() == '') {
- var y = dt.getFullYear();
- var d = dt.getDate() + '';
- var m = (dt.getMonth() + 1) + '';
- if (d.length == 1)
- d = '0' + d;
- if (m.length == 1)
- m = '0' + m;
- $('#next-run-date').val(y + '-' + m + '-' + d);
- }
-
- if ($('#repeat-run-number').val() == '' || $('#repeat-run-number').val() == undefined) {
- $('#repeat-run-number').val('1');
- $('#repeat-run-multiplier').val('D');
-
- $('#allow-day-mon').attr('checked', true);
- $('#allow-day-tue').attr('checked', true);
- $('#allow-day-wed').attr('checked', true);
- $('#allow-day-thu').attr('checked', true);
- $('#allow-day-fri').attr('checked', true);
- $('#allow-day-sat').attr('checked', true);
- $('#allow-day-sun').attr('checked', true);
- }
-
- } else {
- $('#use-scheduled-run-details').hide();
- }
- });
-
- $('#keep-time-type').change(function() {
- var v = $('#keep-time-type').val();
- if (v == 'keep-time') {
- $('#keep-time-number').show();
- $('#keep-time-multiplier').show();
- } else if (v == 'keep-versions') {
- $('#keep-time-number').show();
- $('#keep-time-multiplier').hide();
- } else {
- $('#keep-time-number').hide();
- $('#keep-time-multiplier').hide();
- }
- });
-});
diff --git a/Duplicati/Server/webroot/greeno/scripts/edituri.js b/Duplicati/Server/webroot/greeno/scripts/edituri.js
deleted file mode 100644
index 2892d06dc..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/edituri.js
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Edituri app code
- */
-
-BACKEND_STATE = null;
-EDIT_URI = null;
-
-
-$(document).ready(function() {
-
- EDIT_URI = {
- URL_REGEXP_FIELDS: ['source_uri', 'backend-type', '--auth-username', '--auth-password', 'server-name', 'server-port', 'server-path', 'querystring'],
- URL_REGEXP: /([^:]+)\:\/\/(?:(?:([^\:]+)(?:\:?:([^@]*))?\@))?(?:([^\/\?\:]*)(?:\:(\d+))?)(?:\/([^\?]*))?(?:\?(.+))?/,
- QUERY_REGEXP: /(?:^|&)([^&=]*)=?([^&]*)/g,
-
- createFieldset: function(config) {
- var outer = $('<div></div>');
- var label = config.label ? $('<div></div>').addClass('edit-dialog-label ' + (config.labelclass || '')).html(config.label) : null;
- var field;
- if (config.type == 'link') {
- field = config.field === false ? null :
- $('<a />').text(config.title)
- .attr('id', (config.name || ''))
- .addClass('action-link ' + (config.fieldclass || ''))
- .attr('href', config.href || '#')
- .attr('target', config.target || '_blank');
-
- } else {
- field = config.field === false ? null :
- $('<input type="' + (config.type || 'text') + '" name="' + (config.name || '') + '" />')
- .attr('id', (config.name || ''))
- .addClass('text ui-widget-content ui-corner-all ' + (config.fieldclass || ''));
-
- if (field && config.value !== undefined)
- config.attr('value', config.value);
- }
-
- var checklabel = config.checklabel ? $('<div></div>').addClass('checkbox-label ' + (config.labelclass || '')).html(config.checklabel) : null;
-
- outer.append(label, field, checklabel);
-
- var r = {
- outer: outer,
- label: label,
- field: field,
- checklabel: checklabel
- };
-
- if (config.title)
- for(var k in r)
- if (r[k])
- r[k].attr('title', config.title);
-
- if (config.watermark && field != null)
- field.watermark(config.watermark);
-
- BACKEND_STATE.fieldset_cleanup.push(outer);
-
- if (config.after)
- outer.insertAfter(config.after);
- else if (config.before)
- outer.insertBefore(config.before);
- else if (config.append)
- config.append(outer);
- else
- $('#edit-dialog-extensions').append(outer);
-
- return r;
- },
-
- validate_input: function(values, validateOptions) {
- if (!BACKEND_STATE.current_state.hideserverandport) {
- if (values['server-name'] == '')
- return EDIT_URI.validation_error($('server-name'), 'You must fill in the server name');
- } else {
- values['server-name'] = '';
- }
-
- if (!BACKEND_STATE.current_state.optionalauth) {
- if (values['--auth-username'] == '')
- return EDIT_URI.validation_error($('server-username'), 'You must fill in a username');
- if (!BACKEND_STATE.current_state.optionalpassword)
- if (values['--auth-password'] == '')
- return EDIT_URI.validation_error($('server-password'), 'You must fill in a password');
- }
-
- if (validateOptions) {
- var validOptions = BACKEND_STATE.module_lookup[values['backend-type']].Options.concat(BACKEND_STATE.extra_options);
- var validOptionsDict = {};
- var names = [];
- for (var n in validOptions) {
- validOptionsDict[validOptions[n].Name] = validOptions[n];
- names.push(n.Name);
- if (n.Aliases != null)
- for (var i in n.Aliases) {
- validOptionsDict[i] = n;
- names.push(i);
- }
- }
-
- for(var k in values) {
- if (k.length > 2 && k.substr(0, 2) == '--') {
- var opt = validOptionsDict[k.substr(2)];
-
- if (!opt) {
- return EDIT_URI.validation_error($('#server-options'), 'Invalid option: ' + k.substr(2));
- }
-
- if (opt.Deprecated) {
- alert('Warning', 'The option ' + opt.Name + ' is deprecated :' + opt.DeprecationMessage);
- }
-
- var val = values[k];
-
- if (opt.Typename == 'Boolean') {
- if (!APP_UTIL.isValidBoolOption(val))
- return EDIT_URI.validation_error($('#server-options'), 'Invalid value for ' + k.substr(2) + ': ' + val + ' is not a valid boolean value');
-
- } else if (opt.Typename == 'Password') {
-
- } else if (opt.Typename == 'Integer') {
- if ((parseInt(val) + '') != val) {
- return EDIT_URI.validation_error($('#server-options'), 'Invalid value for ' + k.substr(2) + ': ' + val + ' is not an integer');
- }
- } else if (opt.Typename == 'Size') {
- //TODO
- } else if (opt.Typename == 'Timespan') {
- //TODO
- }
-
- }
- }
- }
-
- return true;
- },
-
- validation_error: function(el, message) {
- alert(message);
- window.setTimeout( function() { el.focus(); }, 500);
- return false;
- },
-
- parse_extra_options: function(el, dict) {
- return APP_UTIL.parseOptionStrings(el.val(), dict, function(d, k, v) {
- if (d['--' + k] !== undefined)
- return EDIT_URI.validation_error(el, 'Duplicate option ' + k);
-
- return true;
- }) != null;
- },
- build_uri: function(cfg) {
- var url = cfg['backend-type'];
- if (APP_UTIL.parseBoolOption(cfg['--use-ssl'], false))
- url += 's';
-
- url += '://';
- url += cfg['server-name'];
- if (cfg['server-port'])
- url += ':' + cfg['server-port'];
-
- if (cfg['server-path'] != '')
- {
- if(url[url.length - 1] != '/')
- url += '/';
-
- url += cfg['server-path'];
- }
-
- var opts = [];
-
- if (cfg['--auth-username'] && cfg['--auth-username'] != '')
- opts.push('auth-username=' + encodeURIComponent(cfg['--auth-username']));
-
- if (cfg['--auth-password'] && cfg['--auth-password'] != '')
- opts.push('auth-password=' + encodeURIComponent(cfg['--auth-password']));
-
- for(var k in cfg)
- if (k.substr(0, 2) == '--' && k != '--auth-password' && k != '--auth-username' && k != '--use-ssl' && cfg[k] !== false && cfg[k] != '')
- opts.push(encodeURIComponent(k.substr(2)) + '=' + encodeURIComponent(cfg[k]));
-
- if (opts.length > 0) {
- url += '?';
- url += opts.join('&');
- }
-
- return url;
- },
-
- decode_uri: function(uri) {
-
- var i = EDIT_URI.URL_REGEXP_FIELDS.length + 1;
- var res = {};
-
- var m = EDIT_URI.URL_REGEXP.exec(uri);
-
- // Invalid URI
- if (!m)
- return res;
-
- while (i--) {
- res[EDIT_URI.URL_REGEXP_FIELDS[i]] = m[i] || "";
- }
-
- res.querystring.replace(EDIT_URI.QUERY_REGEXP, function(str, key, val) {
- if (key)
- res['--' + key] = decodeURIComponent(val);
- });
-
- var scheme = res['backend-type'];
-
- if (scheme && scheme[scheme.length - 1] == 's' && !APP_DATA.plugins.backend[scheme] && APP_DATA.plugins.backend[scheme.substr(0, scheme.length-1)]) {
- res['backend-type'] = scheme.substr(0, scheme.length-1);
- res['--use-ssl'] = true;
- }
-
- return res;
- },
-
- find_scheme: function(uri) {
- if (!uri || uri.length == 0)
- return null;
-
- uri = uri.trim().toLowerCase();
- var ix = uri.indexOf('://');
- if (ix <= 0) {
- if (BACKEND_STATE.module_lookup['file'])
- return 'file';
- return BACKEND_STATE.modules[0];
- }
-
- return (EDIT_URI.decode_uri(uri)['backend-type'] || '').toLowerCase()
- },
-
- read_form: function(form) {
- var map = EDIT_URI.fill_dict_map;
-
- var values = APP_UTIL.read_form(form, map);
- if (BACKEND_STATE.current_state.fill_dict_map)
- values = APP_UTIL.read_form(form, BACKEND_STATE.current_state.fill_dict_map, values);
-
- return values;
- },
-
- fill_form_map: {
- '--auth-username': 'server-username',
- '--auth-password': 'server-password',
- '--use-ssl': 'server-use-ssl',
- 'backend-type': function() {},
- },
-
- fill_dict_map: {
- 'server-username': '--auth-username',
- 'server-password': '--auth-password',
- 'server-use-ssl': '--use-ssl'
- },
-
- fill_form: function(form, values) {
- var found = {};
-
- var map = EDIT_URI.fill_form_map;
- APP_UTIL.fill_form($('#edit-uri-form'), values, map);
- if (BACKEND_STATE.current_state.fill_form_map) {
- map = $.extend(true, {}, map);
- for(var k in map)
- map[k] = false;
-
- $.extend(true, map, BACKEND_STATE.current_state.fill_form_map);
-
- APP_UTIL.fill_form($('#edit-uri-form'), values, map);
- }
-
- var opttext = '';
- for(var k in values) {
- if (map[k] === undefined && k.indexOf('--') == 0) {
- opttext += k + '=' + decodeURIComponent(values[k] || '') + '\n';
- }
- }
-
- form.find('#server-options').val(opttext);
- }
- };
-
- var resetform = function() {
- $('#server-name').watermark('example.com');
- $('#server-port').watermark('8801');
- $('#server-path').watermark('mybackup');
- $('#server-username').watermark('Username for authentication');
- $('#server-password').watermark('Password for authentication');
- $('#server-options').watermark('Enter connection options here');
- $('#server-username-label').text('Username');
- $('#server-password-label').text('Password');
-
- if (BACKEND_STATE != null) {
- if (BACKEND_STATE.fieldset_cleanup != null)
- for(var i in BACKEND_STATE.fieldset_cleanup)
- BACKEND_STATE.fieldset_cleanup[i].remove();
-
- if (BACKEND_STATE && BACKEND_STATE.current_state && BACKEND_STATE.current_state.cleanup )
- BACKEND_STATE.current_state.cleanup($('#connection-uri-dialog'), $('#edit-dialog-extensions'));
- BACKEND_STATE.current_state = null;
- BACKEND_STATE.fieldset_cleanup = [];
- }
- $('#edit-dialog-extensions').empty();
- };
-
- var uriel = null;
-
- $('#connection-uri-dialog').on( "dialogclose", function( event, ui ) {
- uriel = null;
- resetform();
- });
-
-
-
- $('#connection-uri-dialog').on( "setup-dialog", function( event, el ) {
- uriel = $(el);
-
- BACKEND_STATE = {};
- $('#edit-uri-form').each(function(i, e) { e.reset(); });
-
- APP_DATA.getServerConfig(function(serverdata) {
- var drop = $('#backend-type');
- drop.empty();
-
- BACKEND_STATE.modules = serverdata['BackendModules'];
- BACKEND_STATE.module_lookup = {};
- BACKEND_STATE.extra_options = [];
- for(var i in serverdata['ConnectionModules'])
- BACKEND_STATE.extra_options = BACKEND_STATE.extra_options.concat(serverdata['ConnectionModules'][i].Options);
-
- var group_basic = $('<optgroup label="Standard protocols"></optgroup>');
- var group_local = $('<optgroup label="Local storage"></optgroup>');
- var group_prop = $('<optgroup label="Proprietary"></optgroup>');
- var group_others = $('<optgroup label="Others"></optgroup>');
-
- for (var i = 0; i < BACKEND_STATE.modules.length; i++) {
- BACKEND_STATE.module_lookup[BACKEND_STATE.modules[i].Key] = BACKEND_STATE.modules[i];
- }
-
- var used = {};
-
- for(var i in {'ftp':0, 'ssh':0, 'webdav':0, 'aftp':0}) {
- if (BACKEND_STATE.module_lookup[i]) {
- used[i] = true;
- group_basic.append($("<option></option>").attr("value", i).text(BACKEND_STATE.module_lookup[i].DisplayName));
- }
- }
-
- if (BACKEND_STATE.module_lookup['s3']) {
- used['s3'] = true;
- group_basic.append($("<option></option>").attr("value", 's3').text('S3 compatible'));
- }
-
- if (BACKEND_STATE.module_lookup['openstack']) {
- used['openstack'] = true;
- group_basic.append($("<option></option>").attr("value", 'openstack').text('OpenStack Object Storage/ Swift'));
- }
-
- for(var i in {'file':0}) {
- if (BACKEND_STATE.module_lookup[i]) {
- used[i] = true;
- group_local.append($("<option></option>").attr("value", i).text(BACKEND_STATE.module_lookup[i].DisplayName));
- }
- }
-
- for (var i in { 's3': 0, 'azure': 0, 'googledrive': 0, 'onedrive': 0, 'cloudfiles': 0, 'gcs': 0, 'openstack': 0, 'hubic': 0, 'amzcd': 0, 'b2': 0, 'mega': 0, 'od4b': 0, 'mssp': 0 }) {
- if (BACKEND_STATE.module_lookup[i]) {
- used[i] = true;
- group_prop.append($("<option></option>").attr("value", i).text(BACKEND_STATE.module_lookup[i].DisplayName));
- }
- }
-
- for (var i = 0; i < BACKEND_STATE.modules.length; i++) {
- var k = BACKEND_STATE.modules[i].Key;
- if (!used[k]) {
- group_others.append($("<option></option>").attr("value", k).text(BACKEND_STATE.module_lookup[k].DisplayName));
- }
- }
-
- if (group_basic.children().length > 0)
- drop.append(group_basic);
- if (group_local.children().length > 0)
- drop.append(group_local);
- if (group_prop.children().length > 0)
- drop.append(group_prop);
- if (group_others.children().length > 0)
- drop.append(group_others);
-
-
- BACKEND_STATE.orig_uri = uriel.val();
- BACKEND_STATE.orig_cfg = EDIT_URI.decode_uri(BACKEND_STATE.orig_uri);
- var scheme = BACKEND_STATE.orig_cfg['backend-type'];
-
- if (scheme == null && (BACKEND_STATE.orig_uri.indexOf('://') < 0 || BACKEND_STATE.orig_uri.indexOf('file://') == 0))
- scheme = 'file';
-
- if (scheme && APP_DATA.plugins.backend[scheme] && APP_DATA.plugins.backend[scheme].decode_uri) {
- BACKEND_STATE.orig_cfg = APP_DATA.plugins.backend[scheme].decode_uri(BACKEND_STATE.orig_uri);
- }
-
- BACKEND_STATE.first_setup = true;
- if (scheme && BACKEND_STATE.module_lookup[scheme])
- drop.val(scheme);
-
- drop.change();
- },
- function() {
- alert('Failed to get server setup...')
- });
- });
-
- $('#server-use-ssl').change(function() {
- if (BACKEND_STATE.current_state.defaultportssl) {
- if ($('#server-use-ssl').is(':checked')) {
- $('#server-port').watermark(BACKEND_STATE.current_state.defaultportssl + '');
- } else {
- $('#server-port').watermark(BACKEND_STATE.current_state.defaultport + '');
- }
- }
- });
-
- $('#backend-type').change(function() {
- var k = $('#backend-type').val();
- var m = null;
- var hasssl = false;
-
- var cfg = APP_DATA.plugins.backend[k] || {};
-
- // Auto-detect for SSL
- if (cfg.hasssl === undefined) {
- var m = BACKEND_STATE.module_lookup[k];
-
- if (m && m.Options)
- for(var i in m.Options)
- if (m.Options[i].Name == 'use-ssl')
- cfg.hasssl = true;
- }
-
- resetform();
-
- // Simple config changes through properties
- $('#server-use-ssl').toggle(cfg.hasssl == true);
- $('#server-use-ssl-label').toggle(cfg.hasssl == true);
-
- $('#server-name-and-port-label').toggle(cfg.hideserverandport != true);
- $('#server-name-and-port').toggle(cfg.hideserverandport != true);
-
- $('#server-port').toggle(cfg.hideport != true);
- $('#server-username-and-password').toggle(cfg.hideusernameandpassword != true);
-
- if (cfg.usernamelabel)
- $('#server-username-label').text(cfg.usernamelabel + '');
- if (cfg.passwordlabel)
- $('#server-password-label').text(cfg.passwordlabel + '');
- if (cfg.serverandportlabel)
- $('#server-name-and-port-label').text(cfg.serverandportlabel + '');
- if (cfg.serverpathlabel)
- $('#server-path').text(cfg.serverpathlabel + '');
- if (cfg.usernamewatermark)
- $('#server-username-label').watermark(cfg.usernamewatermark + '');
- if (cfg.passwordwatermark)
- $('#server-password-label').watermark(cfg.passwordwatermark + '');
- if (cfg.defaultport)
- $('#server-port').watermark(cfg.defaultport + '');
-
-
- BACKEND_STATE.current_state = cfg;
-
- // Specialized setup
- if (cfg.setup != null)
- cfg.setup($('#connection-uri-dialog'), $('#edit-dialog-extensions'));
-
- if (!cfg.hasssl)
- $('#server-use-ssl').attr('checked', false);
- $('#server-use-ssl').change();
-
- if (BACKEND_STATE.first_setup) {
-
- if (cfg.hideserverandport) {
- var hostname = BACKEND_STATE.orig_cfg['server-name'];
- if (hostname != '' && hostname != null) {
- if (hostname[hostname.length - 1] != '/' && BACKEND_STATE.orig_cfg['server-path'] != '')
- hostname += '/';
- BACKEND_STATE.orig_cfg['server-name'] = '';
- BACKEND_STATE.orig_cfg['server-path'] = hostname + BACKEND_STATE.orig_cfg['server-path'];
- }
- }
-
- BACKEND_STATE.first_setup = false;
- if (cfg.fill_form)
- cfg.fill_form($('#edit-uri-form'), BACKEND_STATE.orig_cfg);
- else
- EDIT_URI.fill_form($('#edit-uri-form'), BACKEND_STATE.orig_cfg);
- }
- });
-
- var validate_and_return_uri = function() {
- var values = EDIT_URI.read_form($('#edit-uri-form'));
-
- if (!EDIT_URI.parse_extra_options($('#server-options'), values))
- return null;
-
- if (!BACKEND_STATE.current_state.hasssl && values['--use-ssl'] !== undefined)
- delete values['--use-ssl'];
-
-
- if (BACKEND_STATE.current_state.validate)
- {
- if (!BACKEND_STATE.current_state.validate($('#connection-uri-dialog'), values))
- return null;
- } else {
- if (!EDIT_URI.validate_input(values, true))
- return null;
- }
-
- var uri = null;
- if (BACKEND_STATE.current_state.build_uri) {
- uri = BACKEND_STATE.current_state.build_uri($('#connection-uri-dialog'), values);
- } else {
- uri = EDIT_URI.build_uri(values);
- }
-
- return uri;
- };
-
- $('#connection-uri-dialog').dialog({
- modal: true,
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- {text: 'Cancel', click: function() { $( this ).dialog( "close" ); } },
- {text: 'Test connection', click: function() {
- var selfbtn = $(this).parent().find('.ui-dialog-buttonpane').find('.ui-button').first().next();
-
- var hasTriedCreate = false;
- var hasTriedCert = false;
-
- var testConnection = null;
-
- var handleError = function(data, success, message) {
- selfbtn.button('option', 'disabled', false);
- selfbtn.button('option', 'label', 'Test connection');
-
- if (!hasTriedCreate && message == 'missing-folder')
- {
- if (confirm('The folder ' + $('#server-path').val() + ' does not exist\nCreate it now?')) {
- createFolder();
- }
- }
- else if (!hasTriedCert && message.indexOf('incorrect-cert:') == 0)
- {
- var hash = message.substr('incorrect-cert:'.length);
- if (confirm('The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: ' + hash + '?' )) {
-
- hasTriedCert = true;
- $('#server-options').val($('#server-options').val() + '--accept-specified-ssl-hash=' + hash);
-
- testConnection();
- }
- }
- else
- alert('Failed to connect: ' + message);
- }
-
- testConnection = function() {
- selfbtn.button('option', 'disabled', true);
- selfbtn.button('option', 'label', 'Testing ...');
-
- APP_DATA.callServer({action: 'test-backend', url: uri}, function(data) {
- selfbtn.button('option', 'disabled', false);
- selfbtn.button('option', 'label', 'Test connection');
- alert('Connection worked!');
- }, handleError);
- };
-
- var createFolder = function() {
- hasTriedCreate = true;
- selfbtn.button('option', 'disabled', true);
- selfbtn.button('option', 'label', 'Creating folder ...');
-
- APP_DATA.callServer(
- {action: 'create-remote-folder', url: uri},
- testConnection,
- handleError
- );
- };
-
- var uri = validate_and_return_uri();
- if (uri != null) {
- testConnection();
- }
- } },
- {text: 'Create URI', click: function() {
-
- var uri = validate_and_return_uri();
- if (uri != null) {
- uriel.val(uri);
- $( this ).dialog( "close" );
- }
- } }
- ]
- });
-
- $('#server-options-label').click(function() {
- $('#backup-options-dialog').dialog('open');
-
- var k = $('#backend-type').val();
- var m = BACKEND_STATE.module_lookup[k];
-
- if (m && m.Options) {
- $('#backup-options-dialog').trigger('configure', { Options: m.Options.concat(BACKEND_STATE.extra_options), callback: function(id) {
- $('#backup-options-dialog').dialog('close');
-
- var txt = $('#server-options').val().trim();
- if (txt.length > 0)
- txt += '\n';
-
- var defaultvalue = '';
- for(var o in m.Options)
- if (m.Options[o].Name == id) {
- defaultvalue = m.Options[o].DefaultValue;
- break;
- }
-
-
- txt += '--' + id + '=' + defaultvalue;
- $('#server-options').val('').val(txt);
- $('#server-options').focus();
-
- }});
- }
- });
-});
diff --git a/Duplicati/Server/webroot/greeno/scripts/folderbrowser.js b/Duplicati/Server/webroot/greeno/scripts/folderbrowser.js
deleted file mode 100644
index f1b632d3e..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/folderbrowser.js
+++ /dev/null
@@ -1,139 +0,0 @@
-$(document).ready(function() {
- $.browseForFolder = function(config) {
- var self = {};
-
- var select_node = function(node) {
- if (node != null && node.original != null && node.original.filepath != null) {
- var path = node.original.filepath;
- if (self.resolvePath && node.original.resolvedpath)
- path = node.original.resolvedpath;
-
- config.callback(path, node.text);
- self.rootel.dialog('close');
- }
- }
-
- self.rootel = $('<div class="modal-dialog folder-browser-dialog"></div>')
- self.treeel = $('<div></div>');
-
- self.rootel.append(self.treeel);
-
- self.rootel.attr('title', config.title);
- self.resolvePath = config.resolvePath;
- self.multiSelect = config.multiSelect;
-
- self.loadData = function(path, callback) {
- $.ajax({
- 'url': APP_CONFIG.server_url,
- 'data': {
- 'action': 'get-folder-contents',
- 'onlyfolders': true,
- 'path': path
- },
- headers: {'X-XSRF-Token': APP_DATA.xsrf_token},
- 'dataType': 'json'
- }).done(function(data, status, xhr) {
- for(var i = 0; i < data.length; i++) {
- var o = data[i];
- o.children = !o.leaf;
- o.filepath = o.id;
-
- //o.icon = o.iconCls;
- delete o.id;
- delete o.iconCls;
- delete o.leaf;
- }
-
- if (path == "/") {
- var usernode = {
- text: 'User data',
- leaf: false,
- state: {opened: true},
- children: []
- };
-
- var systemnode = {
- text: 'Computer',
- leaf: false,
- state: {opened: true},
- children: []
- };
-
- var roots = [
- usernode,
- systemnode
- ];
-
- for(var i = 0; i < data.length; i++) {
- if (data[i].filepath.indexOf('%') == 0)
- usernode.children.push(data[i]);
- else
- systemnode.children.push(data[i]);
- }
-
- data = roots;
- }
-
-
- callback(data)
- }).fail(function() {
- callback(null);
- });
- };
-
- self.treeel.jstree({
- 'core': {
- 'data': function(node, callback){
- if (node.id === '#') {
- self.loadData('/', callback);
- } else {
- self.loadData(node.original.filepath, callback);
- }
- },
- 'multiple' : self.multiSelect
- },
- 'dnd': { copy: false },
- 'checkbox' : { visible: self.multiSelect, three_state: self.multiSelect },
- 'plugins': ["checkbox"]
- });
-
- self.rootel.dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: true,
- closeOnEscape: true,
- buttons: [
- { text: 'Close', disabled: false, click: function(event, ui) {
- self.rootel.dialog('close');
- }},
- { text: 'OK', disabled: true, click: function(event, ui) {
- select_node(self.selected_node);
- }}
- ]
- });
-
- self.dlg_buttons = self.rootel.parent().find('.ui-dialog-buttonpane').find('.ui-button');
-
- self.rootel.on('dialogclose', function() {
- self.rootel.remove();
- });
-
- self.treeel.bind("dblclick.jstree", function (event) {
- var node = self.treeel.jstree().get_node($(event.target).closest("li"));
- select_node(node);
- });
-
- self.treeel.bind('select_node.jstree', function (event, data) {
- if (data.node.original.filepath)
- self.selected_node = data.node;
- else
- self.selected_node = null;
- self.dlg_buttons.last().button('option', 'disabled', self.selected_node == null);
- });
-
-
- };
-});
diff --git a/Duplicati/Server/webroot/greeno/scripts/hideShowPassword.min.js b/Duplicati/Server/webroot/greeno/scripts/hideShowPassword.min.js
deleted file mode 100644
index d4b5f3490..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/hideShowPassword.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(factory,global){if(typeof define==="function"&&define.amd){define(["jquery"],factory)}else{factory(global.jQuery||global.Zepto)}}(function($,undef){var dataKey="plugin_hideShowPassword",defaults={show:"infer",innerToggle:false,hideToggleUntil:false,touchSupport:false,toggleEvent:"click",toggleTouchEvent:"touchstart mousedown",wrapperClass:"hideShowPassword-wrapper",wrapperWidth:true,toggleClass:"hideShowPassword-toggle",states:{shown:{inputClass:"hideShowPassword-shown",eventName:"passwordShown",toggleClass:"hideShowPassword-toggle-hide",toggleText:"Hide",attr:{type:"text",autocapitalize:"off",autocomplete:"off",autocorrect:"off",spellcheck:"false"}},hidden:{inputClass:"hideShowPassword-hidden",eventName:"passwordHidden",toggleClass:"hideShowPassword-toggle-show",toggleText:"Show",attr:{type:"password"}}},widthMethod:$.fn.outerWidth===undef?"width":"outerWidth",heightMethod:$.fn.outerHeight===undef?"height":"outerHeight"};function HideShowPassword(element,options){this.element=$(element);this.init(options)}HideShowPassword.prototype={init:function(options){this.update(options,defaults,this.element.prop("type")==="password");if(this.options.innerToggle){this.initInnerToggle(this.element,this.options)}},update:function(options,base,toggleFallback){base=base||this.options;toggleFallback=toggleFallback||!this.options.show;if(typeof options!=="object"){options={show:options}}this.options=$.extend(true,{},base,options);if(this.options.show==="toggle"){this.options.show=toggleFallback}if(this.options.show==="infer"){this.options.show=this.element.prop("type")!=="password"}this.ifCurrentOrNot($.proxy(function(state){$.each(state.attr,$.proxy(function(key,value){this.element.prop(key,value)},this));this.element.addClass(state.inputClass).trigger(state.eventName)},this),$.proxy(function(state){this.element.removeClass(state.inputClass)},this))},toggle:function(){this.update("toggle")},currentStateKey:function(){return this.options.show?"shown":"hidden"},ifCurrentOrNot:function(ifCurrent,ifNot){var currentKey=this.currentStateKey();$.each(this.options.states,function(thisKey,state){(currentKey===thisKey?ifCurrent:ifNot)(state)})},initInnerToggle:function(el,options){var attachment=el.css("direction")==="rtl"?"left":"right",elWidth=el[options.widthMethod](),wrapperCSS={position:"relative",display:el.css("display"),verticalAlign:el.css("verticalAlign"),marginTop:el.css("marginTop"),marginRight:el.css("marginRight"),marginBottom:el.css("marginBottom"),marginLeft:el.css("marginLeft")},toggleCSS={position:"absolute",top:"50%",mozUserSelect:"none",webkitUserSelect:"none",msUserSelect:"none",userSelect:"none"},elCSS={marginTop:0,marginRight:0,marginBottom:0,marginLeft:0},eventName="",wrapper,toggle;el.wrap($("<div />").addClass(options.wrapperClass).css(wrapperCSS));wrapper=el.parent();if(options.wrapperWidth===true&&wrapper[options.widthMethod]()!==elWidth){wrapper.css("width",elWidth)}else if(options.wrapperWidth!==false&&options.wrapperWidth!==null){wrapper.css("width",options.wrapperWidth)}toggle=$("<div />").addClass(options.toggleClass);this.updateInnerToggle(toggle,this.currentStateKey(),options.states);toggleCSS[attachment]=0;toggle.css(toggleCSS);toggle.appendTo(wrapper);toggle.css("marginTop",toggle[options.heightMethod]()/-2);elCSS["padding"+attachment.replace(/./,function(m){return m[0].toUpperCase()})]=toggle[options.widthMethod]();el.css(elCSS);if(options.touchSupport){toggle.css("pointerEvents","none");el.on(options.toggleTouchEvent,$.proxy(function(event){var toggleX=toggle.offset().left,eventX,lesser,greater;if(toggleX){eventX=event.pageX||event.originalEvent.pageX;if(attachment==="left"){toggleX+=toggle[options.widthMethod]();lesser=eventX;greater=toggleX}else{lesser=toggleX;greater=eventX}if(greater>=lesser){event.preventDefault();this.toggle()}}},this))}else{toggle.on(options.toggleEvent,$.proxy(function(){this.toggle()},this))}$.each(options.states,function(key,state){eventName+=state.eventName+" "});el.on(eventName,$.proxy(function(){this.updateInnerToggle(toggle,this.currentStateKey(),options.states)},this));if(options.hideToggleUntil){toggle.hide();el.one(options.hideToggleUntil,function(){toggle.show()})}},updateInnerToggle:function(el,currentKey,states){this.ifCurrentOrNot(function(state){el.addClass(state.toggleClass).text(state.toggleText)},function(state){el.removeClass(state.toggleClass)})}};$.fn.hideShowPassword=function(options){return this.each(function(){var $this=$(this),data=$this.data(dataKey);if(data){data.update(options)}else{$this.data(dataKey,new HideShowPassword(this,options))}})};$.each({show:true,hide:false,toggle:"toggle"},function(verb,showVal){$.fn[verb+"Password"]=function(options){return this.hideShowPassword($.extend({},options,{show:showVal}))}})},this);
diff --git a/Duplicati/Server/webroot/greeno/scripts/jquery-1.11.0.min.js b/Duplicati/Server/webroot/greeno/scripts/jquery-1.11.0.min.js
deleted file mode 100644
index 73f33fb3a..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jquery-1.11.0.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
-!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f
-}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},W=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a>",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=$.test(e)?this.mouseHooks:Z.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||z),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||z,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==db()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===db()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=z.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===L&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&(a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault())?bb:cb):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:cb,isPropagationStopped:cb,isImmediatePropagationStopped:cb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=bb,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=bb,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submitBubbles||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?b.form:void 0;c&&!n._data(c,"submitBubbles")&&(n.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),n._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.changeBubbles||(n.event.special.change={setup:function(){return Y.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),n.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),n.event.simulate("change",this,a,!0)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;Y.test(b.nodeName)&&!n._data(b,"changeBubbles")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a,!0)}),n._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!Y.test(this.nodeName)}}),l.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=cb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return n().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=cb),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});function eb(a){var b=fb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var fb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gb=/ jQuery\d+="(?:null|\d+)"/g,hb=new RegExp("<(?:"+fb+")[\\s/>]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/<tbody/i,mb=/<|&#?\w+;/,nb=/<(?:script|style|link)/i,ob=/checked\s*(?:[^=]|=\s*.checked.)/i,pb=/^$|\/(?:java|ecma)script/i,qb=/^true\/(.*)/,rb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,sb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1></$2>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?"<table>"!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Db[0].contentWindow||Db[0].contentDocument).document,b.write(),b.close(),c=Fb(a,b),Db.detach()),Eb[a]=c),c}!function(){var a,b,c=z.createElement("div"),d="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],a.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(a.style.opacity),l.cssFloat=!!a.style.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===c.style.backgroundClip,a=c=null,l.shrinkWrapBlocks=function(){var a,c,e,f;if(null==b){if(a=z.getElementsByTagName("body")[0],!a)return;f="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",c=z.createElement("div"),e=z.createElement("div"),a.appendChild(c).appendChild(e),b=!1,typeof e.style.zoom!==L&&(e.style.cssText=d+";width:1px;padding:1px;zoom:1",e.innerHTML="<div></div>",e.firstChild.style.width="5px",b=3!==e.offsetWidth),a.removeChild(c),a=c=e=null}return b}}();var Hb=/^margin/,Ib=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Jb,Kb,Lb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Jb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),Ib.test(g)&&Hb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):z.documentElement.currentStyle&&(Jb=function(a){return a.currentStyle},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ib.test(g)&&!Lb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Mb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h=z.createElement("div"),i="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",j="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";h.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",b=h.getElementsByTagName("a")[0],b.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(b.style.opacity),l.cssFloat=!!b.style.cssFloat,h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,b=h=null,n.extend(l,{reliableHiddenOffsets:function(){if(null!=c)return c;var a,b,d,e=z.createElement("div"),f=z.getElementsByTagName("body")[0];if(f)return e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=z.createElement("div"),a.style.cssText=i,f.appendChild(a).appendChild(e),e.innerHTML="<table><tr><td></td><td>t</td></tr></table>",b=e.getElementsByTagName("td"),b[0].style.cssText="padding:0;margin:0;border:0;display:none",d=0===b[0].offsetHeight,b[0].style.display="",b[1].style.display="none",c=d&&0===b[0].offsetHeight,f.removeChild(a),e=f=null,c},boxSizing:function(){return null==d&&k(),d},boxSizingReliable:function(){return null==e&&k(),e},pixelPosition:function(){return null==f&&k(),f},reliableMarginRight:function(){var b,c,d,e;if(null==g&&a.getComputedStyle){if(b=z.getElementsByTagName("body")[0],!b)return;c=z.createElement("div"),d=z.createElement("div"),c.style.cssText=i,b.appendChild(c).appendChild(d),e=d.appendChild(z.createElement("div")),e.style.cssText=d.style.cssText=j,e.style.marginRight=e.style.width="0",d.style.width="1px",g=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight),b.removeChild(c)}return g}});function k(){var b,c,h=z.getElementsByTagName("body")[0];h&&(b=z.createElement("div"),c=z.createElement("div"),b.style.cssText=i,h.appendChild(b).appendChild(c),c.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%",n.swap(h,null!=h.style.zoom?{zoom:1}:{},function(){d=4===c.offsetWidth}),e=!0,f=!1,g=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(c,null)||{}).top,e="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width),h.removeChild(b),c=h=null)}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Nb=/alpha\([^)]*\)/i,Ob=/opacity\s*=\s*([^)]*)/,Pb=/^(none|table(?!-c[ea]).+)/,Qb=new RegExp("^("+T+")(.*)$","i"),Rb=new RegExp("^([+-])=("+T+")","i"),Sb={position:"absolute",visibility:"hidden",display:"block"},Tb={letterSpacing:0,fontWeight:400},Ub=["Webkit","O","Moz","ms"];function Vb(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ub.length;while(e--)if(b=Ub[e]+c,b in a)return b;return d}function Wb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=n._data(d,"olddisplay",Gb(d.nodeName)))):f[g]||(e=V(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Xb(a,b,c){var d=Qb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Yb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Zb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Jb(a),g=l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Kb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ib.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Yb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Kb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=Vb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Rb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]="",i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Vb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Kb(a,b,d)),"normal"===f&&b in Tb&&(f=Tb[b]),""===c||c?(e=parseFloat(f),c===!0||n.isNumeric(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Pb.test(n.css(a,"display"))?n.swap(a,Sb,function(){return Zb(a,b,d)}):Zb(a,b,d):void 0},set:function(a,c,d){var e=d&&Jb(a);return Xb(a,c,d?Yb(a,b,d,l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Ob.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Nb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Nb.test(f)?f.replace(Nb,e):f+" "+e)}}),n.cssHooks.marginRight=Mb(l.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},Kb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Hb.test(a)||(n.cssHooks[a+b].set=Xb)}),n.fn.extend({css:function(a,b){return W(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Jb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)
-},a,b,arguments.length>1)},show:function(){return Wb(this,!0)},hide:function(){return Wb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function $b(a,b,c,d,e){return new $b.prototype.init(a,b,c,d,e)}n.Tween=$b,$b.prototype={constructor:$b,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=$b.propHooks[this.prop];return a&&a.get?a.get(this):$b.propHooks._default.get(this)},run:function(a){var b,c=$b.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):$b.propHooks._default.set(this),this}},$b.prototype.init.prototype=$b.prototype,$b.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},$b.propHooks.scrollTop=$b.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=$b.prototype.init,n.fx.step={};var _b,ac,bc=/^(?:toggle|show|hide)$/,cc=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),dc=/queueHooks$/,ec=[jc],fc={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=cc.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&cc.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function gc(){return setTimeout(function(){_b=void 0}),_b=n.now()}function hc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=U[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function ic(a,b,c){for(var d,e=(fc[b]||[]).concat(fc["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function jc(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&V(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k=Gb(a.nodeName),"none"===j&&(j=k),"inline"===j&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==k?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],bc.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}if(!n.isEmptyObject(o)){r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=ic(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function kc(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function lc(a,b,c){var d,e,f=0,g=ec.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=_b||gc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:_b||gc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(kc(k,j.opts.specialEasing);g>f;f++)if(d=ec[f].call(j,a,k,j.opts))return d;return n.map(k,ic,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(lc,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],fc[c]=fc[c]||[],fc[c].unshift(b)},prefilter:function(a,b){b?ec.unshift(a):ec.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=lc(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&dc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(hc(b,!0),a,d,e)}}),n.each({slideDown:hc("show"),slideUp:hc("hide"),slideToggle:hc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(_b=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),_b=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ac||(ac=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(ac),ac=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e=z.createElement("div");e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=e.getElementsByTagName("a")[0],c=z.createElement("select"),d=c.appendChild(z.createElement("option")),b=e.getElementsByTagName("input")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==e.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=d.selected,l.enctype=!!z.createElement("form").enctype,c.disabled=!0,l.optDisabled=!d.disabled,b=z.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value,a=b=c=d=e=null}();var mc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(mc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.text(a)}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var nc,oc,pc=n.expr.attrHandle,qc=/^(?:checked|selected)$/i,rc=l.getSetAttribute,sc=l.input;n.fn.extend({attr:function(a,b){return W(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===L?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?oc:nc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(F);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?sc&&rc||!qc.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(rc?c:d)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),oc={set:function(a,b,c){return b===!1?n.removeAttr(a,c):sc&&rc||!qc.test(c)?a.setAttribute(!rc&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=pc[b]||n.find.attr;pc[b]=sc&&rc||!qc.test(b)?function(a,b,d){var e,f;return d||(f=pc[b],pc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,pc[b]=f),e}:function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),sc&&rc||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):nc&&nc.set(a,b,c)}}),rc||(nc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},pc.id=pc.name=pc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:nc.set},n.attrHooks.contenteditable={set:function(a,b,c){nc.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var tc=/^(?:input|select|textarea|button|object)$/i,uc=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return W(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):tc.test(a.nodeName)||uc.test(a.nodeName)&&a.href?0:-1}}}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var vc=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(F)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===L||"boolean"===c)&&(this.className&&n._data(this,"__className__",this.className),this.className=this.className||a===!1?"":n._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(vc," ").indexOf(b)>=0)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var wc=n.now(),xc=/\?/,yc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(yc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var zc,Ac,Bc=/#.*$/,Cc=/([?&])_=[^&]*/,Dc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ec=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Fc=/^(?:GET|HEAD)$/,Gc=/^\/\//,Hc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ic={},Jc={},Kc="*/".concat("*");try{Ac=location.href}catch(Lc){Ac=z.createElement("a"),Ac.href="",Ac=Ac.href}zc=Hc.exec(Ac.toLowerCase())||[];function Mc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(F)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nc(a,b,c,d){var e={},f=a===Jc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Oc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Pc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Qc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ac,type:"GET",isLocal:Ec.test(zc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Oc(Oc(a,n.ajaxSettings),b):Oc(n.ajaxSettings,a)},ajaxPrefilter:Mc(Ic),ajaxTransport:Mc(Jc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Dc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||Ac)+"").replace(Bc,"").replace(Gc,zc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(F)||[""],null==k.crossDomain&&(c=Hc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===zc[1]&&c[2]===zc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(zc[3]||("http:"===zc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),Nc(Ic,k,b,v),2===t)return v;h=k.global,h&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Fc.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(xc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Cc.test(e)?e.replace(Cc,"$1_="+wc++):e+(xc.test(e)?"&":"?")+"_="+wc++)),k.ifModified&&(n.lastModified[e]&&v.setRequestHeader("If-Modified-Since",n.lastModified[e]),n.etag[e]&&v.setRequestHeader("If-None-Match",n.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Kc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Nc(Jc,k,b,v)){v.readyState=1,h&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Pc(k,v,c)),u=Qc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(n.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!l.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||n.css(a,"display"))},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Rc=/%20/g,Sc=/\[\]$/,Tc=/\r?\n/g,Uc=/^(?:submit|button|image|reset|file)$/i,Vc=/^(?:input|select|textarea|keygen)/i;function Wc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Sc.test(a)?d(a,e):Wc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Wc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Wc(c,a[c],b,e);return d.join("&").replace(Rc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Vc.test(this.nodeName)&&!Uc.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Tc,"\r\n")}}):{name:b.name,value:c.replace(Tc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$c()||_c()}:$c;var Xc=0,Yc={},Zc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Yc)Yc[a](void 0,!0)}),l.cors=!!Zc&&"withCredentials"in Zc,Zc=l.ajax=!!Zc,Zc&&n.ajaxTransport(function(a){if(!a.crossDomain||l.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Xc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Yc[g],b=void 0,f.onreadystatechange=n.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Yc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function $c(){try{return new a.XMLHttpRequest}catch(b){}}function _c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||n("head")[0]||z.documentElement;return{send:function(d,e){b=z.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ad=[],bd=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ad.pop()||n.expando+"_"+wc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bd.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bd.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(bd,"$1"+e):b.jsonp!==!1&&(b.url+=(xc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ad.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||z;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var cd=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&cd)return cd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h,a.length),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&n.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return W(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n});
diff --git a/Duplicati/Server/webroot/greeno/scripts/jquery-1.11.0.min.map b/Duplicati/Server/webroot/greeno/scripts/jquery-1.11.0.min.map
deleted file mode 100644
index 2775c548f..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jquery-1.11.0.min.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"jquery-1.11.0.min.js","sources":["jquery-1.11.0.js"],"names":["global","factory","module","exports","document","w","Error","window","this","noGlobal","deletedIds","slice","concat","push","indexOf","class2type","toString","hasOwn","hasOwnProperty","trim","support","version","jQuery","selector","context","fn","init","rtrim","rmsPrefix","rdashAlpha","fcamelCase","all","letter","toUpperCase","prototype","jquery","constructor","length","toArray","call","get","num","pushStack","elems","ret","merge","prevObject","each","callback","args","map","elem","i","apply","arguments","first","eq","last","len","j","end","sort","splice","extend","src","copyIsArray","copy","name","options","clone","target","deep","isFunction","isPlainObject","isArray","undefined","expando","Math","random","replace","isReady","error","msg","noop","obj","type","Array","isWindow","isNumeric","parseFloat","isEmptyObject","key","nodeType","e","ownLast","globalEval","data","execScript","camelCase","string","nodeName","toLowerCase","value","isArraylike","text","makeArray","arr","results","Object","inArray","max","second","grep","invert","callbackInverse","matches","callbackExpect","arg","guid","proxy","tmp","now","Date","split","Sizzle","Expr","getText","isXML","compile","outermostContext","sortInput","hasDuplicate","setDocument","docElem","documentIsHTML","rbuggyQSA","rbuggyMatches","contains","preferredDoc","dirruns","done","classCache","createCache","tokenCache","compilerCache","sortOrder","a","b","strundefined","MAX_NEGATIVE","pop","push_native","booleans","whitespace","characterEncoding","identifier","attributes","pseudos","RegExp","rcomma","rcombinators","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rinputs","rheader","rnative","rquickExpr","rsibling","rescape","runescape","funescape","_","escaped","escapedWhitespace","high","String","fromCharCode","childNodes","els","seed","match","m","groups","old","nid","newContext","newSelector","ownerDocument","exec","getElementById","parentNode","id","getElementsByTagName","getElementsByClassName","qsa","test","tokenize","getAttribute","setAttribute","toSelector","testContext","join","querySelectorAll","qsaError","removeAttribute","select","keys","cache","cacheLength","shift","markFunction","assert","div","createElement","removeChild","addHandle","attrs","handler","attrHandle","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","createButtonPseudo","createPositionalPseudo","argument","matchIndexes","documentElement","node","hasCompare","doc","parent","defaultView","top","addEventListener","attachEvent","className","appendChild","createComment","innerHTML","firstChild","getById","getElementsByName","find","filter","attrId","getAttributeNode","tag","input","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","attr","val","specified","uniqueSort","duplicates","detectDuplicates","sortStable","textContent","nodeValue","selectors","createPseudo","relative",">","dir"," ","+","~","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","check","result","what","simple","forward","ofType","xml","outerCache","nodeIndex","start","useCache","lastChild","pseudo","setFilters","idx","matched","not","matcher","unmatched","has","innerText","lang","elemLang","hash","location","root","focus","activeElement","hasFocus","href","tabIndex","enabled","disabled","checked","selected","selectedIndex","empty","header","button","even","odd","lt","gt","radio","checkbox","file","password","image","submit","reset","filters","parseOnly","tokens","soFar","preFilters","cached","addCombinator","combinator","base","checkNonElements","doneName","oldCache","newCache","elementMatcher","matchers","condense","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","multipleContexts","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","matcherFromGroupMatchers","elementMatchers","setMatchers","bySet","byElement","superMatcher","outermost","matchedCount","setMatched","contextBackup","dirrunsUnique","group","contexts","token","div1","defaultValue","unique","isXMLDoc","rneedsContext","rsingleTag","risSimple","winnow","qualifier","self","is","rootjQuery","charAt","parseHTML","ready","rparentsprev","guaranteedUnique","children","contents","next","prev","until","sibling","n","r","targets","closest","l","pos","index","prevAll","add","addBack","parents","parentsUntil","nextAll","nextUntil","prevUntil","siblings","contentDocument","contentWindow","reverse","rnotwhite","optionsCache","createOptions","object","flag","Callbacks","firing","memory","fired","firingLength","firingIndex","firingStart","list","stack","once","fire","stopOnFalse","disable","remove","lock","locked","fireWith","Deferred","func","tuples","state","promise","always","deferred","fail","then","fns","newDefer","tuple","returned","resolve","reject","progress","notify","pipe","stateString","when","subordinate","resolveValues","remaining","updateFunc","values","progressValues","notifyWith","resolveWith","progressContexts","resolveContexts","readyList","readyWait","holdReady","hold","wait","body","setTimeout","trigger","off","detach","removeEventListener","completed","detachEvent","event","readyState","frameElement","doScroll","doScrollCheck","inlineBlockNeedsLayout","container","style","cssText","zoom","offsetWidth","deleteExpando","acceptData","noData","rbrace","rmultiDash","dataAttr","parseJSON","isEmptyDataObject","internalData","pvt","thisCache","internalKey","isNode","toJSON","internalRemoveData","cleanData","applet ","embed ","object ","hasData","removeData","_data","_removeData","queue","dequeue","startLength","hooks","_queueHooks","stop","setter","clearQueue","count","defer","pnum","source","cssExpand","isHidden","el","css","access","chainable","emptyGet","raw","bulk","rcheckableType","fragment","createDocumentFragment","leadingWhitespace","tbody","htmlSerialize","html5Clone","cloneNode","outerHTML","appendChecked","noCloneChecked","checkClone","noCloneEvent","click","eventName","change","focusin","rformElems","rkeyEvent","rmouseEvent","rfocusMorph","rtypenamespace","returnTrue","returnFalse","safeActiveElement","err","types","events","t","handleObjIn","special","eventHandle","handleObj","handlers","namespaces","origType","elemData","handle","triggered","dispatch","delegateType","bindType","namespace","delegateCount","setup","mappedTypes","origCount","teardown","removeEvent","onlyHandlers","ontype","bubbleType","eventPath","Event","isTrigger","namespace_re","noBubble","parentWindow","isPropagationStopped","preventDefault","isDefaultPrevented","_default","fix","handlerQueue","delegateTarget","preDispatch","currentTarget","isImmediatePropagationStopped","stopPropagation","postDispatch","sel","prop","originalEvent","fixHook","fixHooks","mouseHooks","keyHooks","props","srcElement","metaKey","original","which","charCode","keyCode","eventDoc","fromElement","pageX","clientX","scrollLeft","clientLeft","pageY","clientY","scrollTop","clientTop","relatedTarget","toElement","load","blur","beforeunload","returnValue","simulate","bubble","isSimulated","defaultPrevented","getPreventDefault","timeStamp","cancelBubble","stopImmediatePropagation","mouseenter","mouseleave","orig","related","submitBubbles","form","_submit_bubble","changeBubbles","propertyName","_just_changed","focusinBubbles","attaches","on","one","origFn","triggerHandler","createSafeFragment","nodeNames","safeFrag","rinlinejQuery","rnoshimcache","rleadingWhitespace","rxhtmlTag","rtagName","rtbody","rhtml","rnoInnerhtml","rchecked","rscriptType","rscriptTypeMasked","rcleanScript","wrapMap","option","legend","area","param","thead","tr","col","td","safeFragment","fragmentDiv","optgroup","tfoot","colgroup","caption","th","getAll","found","fixDefaultChecked","defaultChecked","manipulationTarget","content","disableScript","restoreScript","setGlobalEval","refElements","cloneCopyEvent","dest","oldData","curData","fixCloneNodeIssues","defaultSelected","dataAndEvents","deepDataAndEvents","destElements","srcElements","inPage","buildFragment","scripts","selection","wrap","safe","nodes","createTextNode","append","domManip","prepend","insertBefore","before","after","keepData","html","replaceWith","replaceChild","hasScripts","set","iNoClone","_evalUrl","appendTo","prependTo","insertAfter","replaceAll","insert","iframe","elemdisplay","actualDisplay","display","getDefaultComputedStyle","defaultDisplay","write","close","shrinkWrapBlocksVal","divReset","opacity","cssFloat","backgroundClip","clearCloneStyle","shrinkWrapBlocks","containerStyles","width","rmargin","rnumnonpx","getStyles","curCSS","rposition","getComputedStyle","computed","minWidth","maxWidth","getPropertyValue","currentStyle","left","rs","rsLeft","runtimeStyle","pixelLeft","addGetHookIf","conditionFn","hookFn","condition","reliableHiddenOffsetsVal","boxSizingVal","boxSizingReliableVal","pixelPositionVal","reliableMarginRightVal","reliableHiddenOffsets","tds","isSupported","offsetHeight","boxSizing","computeStyleTests","boxSizingReliable","pixelPosition","reliableMarginRight","marginDiv","marginRight","swap","ralpha","ropacity","rdisplayswap","rnumsplit","rrelNum","cssShow","position","visibility","cssNormalTransform","letterSpacing","fontWeight","cssPrefixes","vendorPropName","capName","origName","showHide","show","hidden","setPositiveNumber","subtract","augmentWidthOrHeight","extra","isBorderBox","styles","getWidthOrHeight","valueIsBorderBox","cssHooks","cssNumber","columnCount","fillOpacity","lineHeight","order","orphans","widows","zIndex","cssProps","float","$1","margin","padding","border","prefix","suffix","expand","expanded","parts","hide","toggle","Tween","easing","unit","propHooks","run","percent","eased","duration","step","tween","fx","linear","p","swing","cos","PI","fxNow","timerId","rfxtypes","rfxnum","rrun","animationPrefilters","defaultPrefilter","tweeners","*","createTween","scale","maxIterations","createFxNow","genFx","includeWidth","height","animation","collection","opts","oldfire","dDisplay","anim","dataShow","unqueued","overflow","overflowX","overflowY","propFilter","specialEasing","Animation","properties","stopped","tick","currentTime","startTime","tweens","originalProperties","originalOptions","gotoEnd","rejectWith","timer","complete","tweener","prefilter","speed","opt","speeds","fadeTo","to","animate","optall","doAnimation","finish","stopQueue","timers","cssFn","slideDown","slideUp","slideToggle","fadeIn","fadeOut","fadeToggle","interval","setInterval","clearInterval","slow","fast","delay","time","timeout","clearTimeout","getSetAttribute","hrefNormalized","checkOn","optSelected","enctype","optDisabled","radioValue","rreturn","valHooks","optionSet","scrollHeight","nodeHook","boolHook","ruseDefault","getSetInput","removeAttr","nType","attrHooks","propName","attrNames","propFix","getter","setAttributeNode","createAttribute","coords","contenteditable","rfocusable","rclickable","removeProp","for","class","notxml","tabindex","parseInt","rclass","addClass","classes","clazz","finalValue","proceed","removeClass","toggleClass","stateVal","classNames","hasClass","hover","fnOver","fnOut","bind","unbind","delegate","undelegate","nonce","rquery","rvalidtokens","JSON","parse","requireNonComma","depth","str","comma","open","Function","parseXML","DOMParser","parseFromString","ActiveXObject","async","loadXML","ajaxLocParts","ajaxLocation","rhash","rts","rheaders","rlocalProtocol","rnoContent","rprotocol","rurl","prefilters","transports","allTypes","addToPrefiltersOrTransports","structure","dataTypeExpression","dataType","dataTypes","inspectPrefiltersOrTransports","jqXHR","inspected","seekingTransport","inspect","prefilterOrFactory","dataTypeOrTransport","ajaxExtend","flatOptions","ajaxSettings","ajaxHandleResponses","s","responses","firstDataType","ct","finalDataType","mimeType","getResponseHeader","converters","ajaxConvert","response","isSuccess","conv2","current","conv","responseFields","dataFilter","active","lastModified","etag","url","isLocal","processData","contentType","accepts","json","* text","text html","text json","text xml","ajaxSetup","settings","ajaxPrefilter","ajaxTransport","ajax","cacheURL","responseHeadersString","timeoutTimer","fireGlobals","transport","responseHeaders","callbackContext","globalEventContext","completeDeferred","statusCode","requestHeaders","requestHeadersNames","strAbort","getAllResponseHeaders","setRequestHeader","lname","overrideMimeType","code","status","abort","statusText","finalText","success","method","crossDomain","traditional","hasContent","ifModified","headers","beforeSend","send","nativeStatusText","modified","getJSON","getScript","throws","wrapAll","wrapInner","unwrap","visible","r20","rbracket","rCRLF","rsubmitterTypes","rsubmittable","buildParams","v","encodeURIComponent","serialize","serializeArray","xhr","createStandardXHR","createActiveXHR","xhrId","xhrCallbacks","xhrSupported","cors","username","xhrFields","isAbort","onreadystatechange","responseText","XMLHttpRequest","script","text script","head","scriptCharset","charset","onload","oldCallbacks","rjsonp","jsonp","jsonpCallback","originalSettings","callbackName","overwritten","responseContainer","jsonProp","keepScripts","parsed","_load","params","animated","getWindow","offset","setOffset","curPosition","curLeft","curCSSTop","curTop","curOffset","curCSSLeft","calculatePosition","curElem","using","win","box","getBoundingClientRect","pageYOffset","pageXOffset","offsetParent","parentOffset","scrollTo","Height","Width","defaultExtra","funcName","size","andSelf","define","amd","_jQuery","_$","$","noConflict"],"mappings":"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"} \ No newline at end of file
diff --git a/Duplicati/Server/webroot/greeno/scripts/jquery-2.0.3.min.map b/Duplicati/Server/webroot/greeno/scripts/jquery-2.0.3.min.map
deleted file mode 100644
index 472d71bb0..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jquery-2.0.3.min.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"jquery-2.0.3.min.js","sources":["jquery-2.0.3.js"],"names":["window","undefined","rootjQuery","readyList","core_strundefined","location","document","docElem","documentElement","_jQuery","jQuery","_$","$","class2type","core_deletedIds","core_version","core_concat","concat","core_push","push","core_slice","slice","core_indexOf","indexOf","core_toString","toString","core_hasOwn","hasOwnProperty","core_trim","trim","selector","context","fn","init","core_pnum","source","core_rnotwhite","rquickExpr","rsingleTag","rmsPrefix","rdashAlpha","fcamelCase","all","letter","toUpperCase","completed","removeEventListener","ready","prototype","jquery","constructor","match","elem","this","charAt","length","exec","find","merge","parseHTML","nodeType","ownerDocument","test","isPlainObject","isFunction","attr","getElementById","parentNode","makeArray","toArray","call","get","num","pushStack","elems","ret","prevObject","each","callback","args","promise","done","apply","arguments","first","eq","last","i","len","j","map","end","sort","splice","extend","options","name","src","copy","copyIsArray","clone","target","deep","isArray","expando","Math","random","replace","noConflict","isReady","readyWait","holdReady","hold","wait","resolveWith","trigger","off","obj","type","Array","isWindow","isNumeric","isNaN","parseFloat","isFinite","String","e","isEmptyObject","error","msg","Error","data","keepScripts","parsed","scripts","createElement","buildFragment","remove","childNodes","parseJSON","JSON","parse","parseXML","xml","tmp","DOMParser","parseFromString","getElementsByTagName","noop","globalEval","code","script","indirect","eval","text","head","appendChild","removeChild","camelCase","string","nodeName","toLowerCase","value","isArraylike","arr","results","Object","inArray","second","l","grep","inv","retVal","arg","guid","proxy","access","key","chainable","emptyGet","raw","bulk","now","Date","swap","old","style","Deferred","readyState","setTimeout","addEventListener","split","support","cachedruns","Expr","getText","isXML","compile","outermostContext","sortInput","setDocument","documentIsHTML","rbuggyQSA","rbuggyMatches","matches","contains","preferredDoc","dirruns","classCache","createCache","tokenCache","compilerCache","hasDuplicate","sortOrder","a","b","strundefined","MAX_NEGATIVE","hasOwn","pop","push_native","booleans","whitespace","characterEncoding","identifier","attributes","pseudos","rtrim","RegExp","rcomma","rcombinators","rsibling","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rnative","rinputs","rheader","rescape","runescape","funescape","_","escaped","escapedWhitespace","high","fromCharCode","els","Sizzle","seed","m","groups","nid","newContext","newSelector","id","getElementsByClassName","qsa","tokenize","getAttribute","setAttribute","toSelector","join","querySelectorAll","qsaError","removeAttribute","select","keys","cache","cacheLength","shift","markFunction","assert","div","addHandle","attrs","handler","attrHandle","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","createButtonPseudo","createPositionalPseudo","argument","matchIndexes","node","doc","parent","defaultView","attachEvent","top","className","createComment","innerHTML","firstChild","getById","getElementsByName","filter","attrId","getAttributeNode","tag","input","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","val","specified","uniqueSort","duplicates","detectDuplicates","sortStable","textContent","nodeValue","selectors","createPseudo","relative",">","dir"," ","+","~","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","check","result","what","simple","forward","ofType","outerCache","nodeIndex","start","useCache","lastChild","pseudo","setFilters","idx","matched","not","matcher","unmatched","has","innerText","lang","elemLang","hash","root","focus","activeElement","hasFocus","href","tabIndex","enabled","disabled","checked","selected","selectedIndex","empty","header","button","even","odd","lt","gt","radio","checkbox","file","password","image","submit","reset","filters","parseOnly","tokens","soFar","preFilters","cached","addCombinator","combinator","base","checkNonElements","doneName","dirkey","elementMatcher","matchers","condense","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","multipleContexts","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","matcherFromGroupMatchers","elementMatchers","setMatchers","matcherCachedRuns","bySet","byElement","superMatcher","expandContext","setMatched","matchedCount","outermost","contextBackup","dirrunsUnique","group","contexts","token","div1","defaultValue","unique","isXMLDoc","optionsCache","createOptions","object","flag","Callbacks","memory","fired","firing","firingStart","firingLength","firingIndex","list","stack","once","fire","stopOnFalse","self","disable","add","index","lock","locked","fireWith","func","tuples","state","always","deferred","fail","then","fns","newDefer","tuple","action","returned","resolve","reject","progress","notify","pipe","stateString","when","subordinate","resolveValues","remaining","updateFunc","values","progressValues","notifyWith","progressContexts","resolveContexts","fragment","createDocumentFragment","opt","checkOn","optSelected","reliableMarginRight","boxSizingReliable","pixelPosition","noCloneChecked","cloneNode","optDisabled","radioValue","checkClone","focusinBubbles","backgroundClip","clearCloneStyle","container","marginDiv","divReset","body","cssText","zoom","boxSizing","offsetWidth","getComputedStyle","width","marginRight","data_user","data_priv","rbrace","rmultiDash","Data","defineProperty","uid","accepts","owner","descriptor","unlock","defineProperties","set","prop","stored","camel","hasData","discard","acceptData","removeData","_data","_removeData","dataAttr","camelKey","queue","dequeue","startLength","hooks","_queueHooks","next","stop","setter","delay","time","fx","speeds","timeout","clearTimeout","clearQueue","count","defer","nodeHook","boolHook","rclass","rreturn","rfocusable","removeAttr","removeProp","propFix","addClass","classes","clazz","proceed","removeClass","toggleClass","stateVal","classNames","hasClass","valHooks","option","one","max","optionSet","nType","attrHooks","propName","attrNames","for","class","notxml","propHooks","hasAttribute","getter","rkeyEvent","rmouseEvent","rfocusMorph","rtypenamespace","returnTrue","returnFalse","safeActiveElement","err","event","global","types","handleObjIn","eventHandle","events","t","handleObj","special","handlers","namespaces","origType","elemData","handle","triggered","dispatch","delegateType","bindType","namespace","delegateCount","setup","mappedTypes","origCount","teardown","removeEvent","onlyHandlers","bubbleType","ontype","eventPath","Event","isTrigger","namespace_re","noBubble","parentWindow","isPropagationStopped","preventDefault","isDefaultPrevented","_default","fix","handlerQueue","delegateTarget","preDispatch","currentTarget","isImmediatePropagationStopped","stopPropagation","postDispatch","sel","props","fixHooks","keyHooks","original","which","charCode","keyCode","mouseHooks","eventDoc","pageX","clientX","scrollLeft","clientLeft","pageY","clientY","scrollTop","clientTop","originalEvent","fixHook","load","blur","click","beforeunload","returnValue","simulate","bubble","isSimulated","defaultPrevented","getPreventDefault","timeStamp","stopImmediatePropagation","mouseenter","mouseleave","orig","related","relatedTarget","attaches","on","origFn","triggerHandler","isSimple","rparentsprev","rneedsContext","guaranteedUnique","children","contents","prev","targets","winnow","is","closest","pos","prevAll","addBack","sibling","parents","parentsUntil","until","nextAll","nextUntil","prevUntil","siblings","contentDocument","reverse","truncate","n","qualifier","rxhtmlTag","rtagName","rhtml","rnoInnerhtml","manipulation_rcheckableType","rchecked","rscriptType","rscriptTypeMasked","rcleanScript","wrapMap","thead","col","tr","td","optgroup","tbody","tfoot","colgroup","caption","th","append","createTextNode","domManip","manipulationTarget","prepend","insertBefore","before","after","keepData","cleanData","getAll","setGlobalEval","dataAndEvents","deepDataAndEvents","html","replaceWith","detach","allowIntersection","hasScripts","iNoClone","disableScript","restoreScript","_evalUrl","appendTo","prependTo","insertAfter","replaceAll","insert","srcElements","destElements","inPage","fixInput","cloneCopyEvent","selection","wrap","nodes","url","ajax","dataType","async","throws","content","refElements","dest","pdataOld","pdataCur","udataOld","udataCur","wrapAll","firstElementChild","wrapInner","unwrap","curCSS","iframe","rdisplayswap","rmargin","rnumsplit","rnumnonpx","rrelNum","elemdisplay","BODY","cssShow","position","visibility","display","cssNormalTransform","letterSpacing","fontWeight","cssExpand","cssPrefixes","vendorPropName","capName","origName","isHidden","el","css","getStyles","showHide","show","hidden","css_defaultDisplay","styles","hide","toggle","cssHooks","opacity","computed","cssNumber","columnCount","fillOpacity","lineHeight","order","orphans","widows","zIndex","cssProps","float","extra","_computed","minWidth","maxWidth","getPropertyValue","setPositiveNumber","subtract","augmentWidthOrHeight","isBorderBox","getWidthOrHeight","valueIsBorderBox","offsetHeight","actualDisplay","contentWindow","write","close","visible","margin","padding","border","prefix","suffix","expand","expanded","parts","r20","rbracket","rCRLF","rsubmitterTypes","rsubmittable","serialize","param","serializeArray","traditional","s","encodeURIComponent","ajaxSettings","buildParams","v","hover","fnOver","fnOut","bind","unbind","delegate","undelegate","ajaxLocParts","ajaxLocation","ajax_nonce","ajax_rquery","rhash","rts","rheaders","rlocalProtocol","rnoContent","rprotocol","rurl","_load","prefilters","transports","allTypes","addToPrefiltersOrTransports","structure","dataTypeExpression","dataTypes","inspectPrefiltersOrTransports","originalOptions","jqXHR","inspected","seekingTransport","inspect","prefilterOrFactory","dataTypeOrTransport","ajaxExtend","flatOptions","params","response","responseText","complete","status","active","lastModified","etag","isLocal","processData","contentType","*","json","responseFields","converters","* text","text html","text json","text xml","ajaxSetup","settings","ajaxPrefilter","ajaxTransport","transport","cacheURL","responseHeadersString","responseHeaders","timeoutTimer","fireGlobals","callbackContext","globalEventContext","completeDeferred","statusCode","requestHeaders","requestHeadersNames","strAbort","getResponseHeader","getAllResponseHeaders","setRequestHeader","lname","overrideMimeType","mimeType","abort","statusText","finalText","success","method","crossDomain","hasContent","ifModified","headers","beforeSend","send","nativeStatusText","responses","isSuccess","modified","ajaxHandleResponses","ajaxConvert","rejectWith","getJSON","getScript","ct","finalDataType","firstDataType","conv2","current","conv","dataFilter","text script","charset","scriptCharset","evt","oldCallbacks","rjsonp","jsonp","jsonpCallback","originalSettings","callbackName","overwritten","responseContainer","jsonProp","xhr","XMLHttpRequest","xhrSupported","xhrSuccessStatus",1223,"xhrId","xhrCallbacks","ActiveXObject","cors","open","username","xhrFields","onload","onerror","fxNow","timerId","rfxtypes","rfxnum","rrun","animationPrefilters","defaultPrefilter","tweeners","tween","createTween","unit","scale","maxIterations","createFxNow","animation","collection","Animation","properties","stopped","tick","currentTime","startTime","duration","percent","tweens","run","opts","specialEasing","originalProperties","Tween","easing","gotoEnd","propFilter","timer","anim","tweener","prefilter","oldfire","dataShow","unqueued","overflow","overflowX","overflowY","eased","step","cssFn","speed","animate","genFx","fadeTo","to","optall","doAnimation","finish","stopQueue","timers","includeWidth","height","slideDown","slideUp","slideToggle","fadeIn","fadeOut","fadeToggle","linear","p","swing","cos","PI","interval","setInterval","clearInterval","slow","fast","animated","offset","setOffset","win","box","left","getBoundingClientRect","getWindow","pageYOffset","pageXOffset","curPosition","curLeft","curCSSTop","curTop","curOffset","curCSSLeft","calculatePosition","curElem","using","offsetParent","parentOffset","scrollTo","Height","Width","defaultExtra","funcName","size","andSelf","module","exports","define","amd"],"mappings":"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"} \ No newline at end of file
diff --git a/Duplicati/Server/webroot/greeno/scripts/jquery-ui-1.10.3.min.js b/Duplicati/Server/webroot/greeno/scripts/jquery-ui-1.10.3.min.js
deleted file mode 100755
index e6a288feb..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jquery-ui-1.10.3.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*! jQuery UI - v1.10.3 - 2013-10-20
-* http://jqueryui.com
-* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
-* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
-
-(function(e,t){function i(t,i){var s,n,r,o=t.nodeName.toLowerCase();return"area"===o?(s=t.parentNode,n=s.name,t.href&&n&&"map"===s.nodeName.toLowerCase()?(r=e("img[usemap=#"+n+"]")[0],!!r&&a(r)):!1):(/input|select|textarea|button|object/.test(o)?!t.disabled:"a"===o?t.href||i:i)&&a(t)}function a(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var s=0,n=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,a){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),a&&a.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var a,s,n=e(this[0]);n.length&&n[0]!==document;){if(a=n.css("position"),("absolute"===a||"relative"===a||"fixed"===a)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++s)})},removeUniqueId:function(){return this.each(function(){n.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,a){return!!e.data(t,a[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var a=e.attr(t,"tabindex"),s=isNaN(a);return(s||a>=0)&&i(t,!s)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(i,a){function s(t,i,a,s){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,a&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===a?["Left","Right"]:["Top","Bottom"],r=a.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+a]=function(i){return i===t?o["inner"+a].call(this):this.each(function(){e(this).css(r,s(this,i)+"px")})},e.fn["outer"+a]=function(t,i){return"number"!=typeof t?o["outer"+a].call(this,t):this.each(function(){e(this).css(r,s(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,a){var s,n=e.ui[t].prototype;for(s in a)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([i,a[s]])},call:function(e,t,i){var a,s=e.plugins[t];if(s&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(a=0;s.length>a;a++)e.options[s[a][0]]&&s[a][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var a=i&&"left"===i?"scrollLeft":"scrollTop",s=!1;return t[a]>0?!0:(t[a]=1,s=t[a]>0,t[a]=0,s)}})})(jQuery);(function(e,t){var i=0,s=Array.prototype.slice,a=e.cleanData;e.cleanData=function(t){for(var i,s=0;null!=(i=t[s]);s++)try{e(i).triggerHandler("remove")}catch(n){}a(t)},e.widget=function(i,s,a){var n,r,o,h,l={},u=i.split(".")[0];i=i.split(".")[1],n=u+"-"+i,a||(a=s,s=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[u]=e[u]||{},r=e[u][i],o=e[u][i]=function(e,i){return this._createWidget?(arguments.length&&this._createWidget(e,i),t):new o(e,i)},e.extend(o,r,{version:a.version,_proto:e.extend({},a),_childConstructors:[]}),h=new s,h.options=e.widget.extend({},h.options),e.each(a,function(i,a){return e.isFunction(a)?(l[i]=function(){var e=function(){return s.prototype[i].apply(this,arguments)},t=function(e){return s.prototype[i].apply(this,e)};return function(){var i,s=this._super,n=this._superApply;return this._super=e,this._superApply=t,i=a.apply(this,arguments),this._super=s,this._superApply=n,i}}(),t):(l[i]=a,t)}),o.prototype=e.widget.extend(h,{widgetEventPrefix:r?h.widgetEventPrefix:i},l,{constructor:o,namespace:u,widgetName:i,widgetFullName:n}),r?(e.each(r._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete r._childConstructors):s._childConstructors.push(o),e.widget.bridge(i,o)},e.widget.extend=function(i){for(var a,n,r=s.call(arguments,1),o=0,h=r.length;h>o;o++)for(a in r[o])n=r[o][a],r[o].hasOwnProperty(a)&&n!==t&&(i[a]=e.isPlainObject(n)?e.isPlainObject(i[a])?e.widget.extend({},i[a],n):e.widget.extend({},n):n);return i},e.widget.bridge=function(i,a){var n=a.prototype.widgetFullName||i;e.fn[i]=function(r){var o="string"==typeof r,h=s.call(arguments,1),l=this;return r=!o&&h.length?e.widget.extend.apply(null,[r].concat(h)):r,o?this.each(function(){var s,a=e.data(this,n);return a?e.isFunction(a[r])&&"_"!==r.charAt(0)?(s=a[r].apply(a,h),s!==a&&s!==t?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):t):e.error("no such method '"+r+"' for "+i+" widget instance"):e.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+r+"'")}):this.each(function(){var t=e.data(this,n);t?t.option(r||{})._init():e.data(this,n,new a(r,this))}),l}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(i,s){var a,n,r,o=i;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof i)if(o={},a=i.split("."),i=a.shift(),a.length){for(n=o[i]=e.widget.extend({},this.options[i]),r=0;a.length-1>r;r++)n[a[r]]=n[a[r]]||{},n=n[a[r]];if(i=a.pop(),s===t)return n[i]===t?null:n[i];n[i]=s}else{if(s===t)return this.options[i]===t?null:this.options[i];o[i]=s}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,a){var n,r=this;"boolean"!=typeof i&&(a=s,s=i,i=!1),a?(s=n=e(s),this.bindings=this.bindings.add(s)):(a=s,s=this.element,n=this.widget()),e.each(a,function(a,o){function h(){return i||r.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?r[o]:o).apply(r,arguments):t}"string"!=typeof o&&(h.guid=o.guid=o.guid||h.guid||e.guid++);var l=a.match(/^(\w+)\s*(.*)$/),u=l[1]+r.eventNamespace,c=l[2];c?n.delegate(c,u,h):s.bind(u,h)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var a,n,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],n=i.originalEvent)for(a in n)a in i||(i[a]=n[a]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,a,n){"string"==typeof a&&(a={effect:a});var r,o=a?a===!0||"number"==typeof a?i:a.effect||i:t;a=a||{},"number"==typeof a&&(a={duration:a}),r=!e.isEmptyObject(a),a.complete=n,a.delay&&s.delay(a.delay),r&&e.effects&&e.effects.effect[o]?s[t](a):o!==t&&s[o]?s[o](a.duration,a.easing,n):s.queue(function(i){e(this)[t](),n&&n.call(s[0]),i()})}})})(jQuery);(function(e){var t=!1;e(document).mouseup(function(){t=!1}),e.widget("ui.mouse",{version:"1.10.3",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!t){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,a=1===i.which,n="string"==typeof this.options.cancel&&i.target.nodeName?e(i.target).closest(this.options.cancel).length:!1;return a&&!n&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===e.data(i.target,this.widgetName+".preventClickEvent")&&e.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return s._mouseMove(e)},this._mouseUpDelegate=function(e){return s._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),t=!0,!0)):!0}},_mouseMove:function(t){return e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button?this._mouseUp(t):this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(e,t){function i(e,t,i){return[parseFloat(e[0])*(p.test(e[0])?t/100:1),parseFloat(e[1])*(p.test(e[1])?i/100:1)]}function s(t,i){return parseInt(e.css(t,i),10)||0}function a(t){var i=t[0];return 9===i.nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:e.isWindow(i)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var n,r=Math.max,o=Math.abs,h=Math.round,l=/left|center|right/,u=/top|center|bottom/,c=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=e.fn.position;e.position={scrollbarWidth:function(){if(n!==t)return n;var i,s,a=e("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),r=a.children()[0];return e("body").append(a),i=r.offsetWidth,a.css("overflow","scroll"),s=r.offsetWidth,i===s&&(s=a[0].clientWidth),a.remove(),n=i-s},getScrollInfo:function(t){var i=t.isWindow?"":t.element.css("overflow-x"),s=t.isWindow?"":t.element.css("overflow-y"),a="scroll"===i||"auto"===i&&t.width<t.element[0].scrollWidth,n="scroll"===s||"auto"===s&&t.height<t.element[0].scrollHeight;return{width:n?e.position.scrollbarWidth():0,height:a?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var i=e(t||window),s=e.isWindow(i[0]);return{element:i,isWindow:s,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s?i.width():i.outerWidth(),height:s?i.height():i.outerHeight()}}},e.fn.position=function(t){if(!t||!t.of)return f.apply(this,arguments);t=e.extend({},t);var n,p,m,g,v,y,b=e(t.of),_=e.position.getWithinInfo(t.within),x=e.position.getScrollInfo(_),k=(t.collision||"flip").split(" "),w={};return y=a(b),b[0].preventDefault&&(t.at="left top"),p=y.width,m=y.height,g=y.offset,v=e.extend({},g),e.each(["my","at"],function(){var e,i,s=(t[this]||"").split(" ");1===s.length&&(s=l.test(s[0])?s.concat(["center"]):u.test(s[0])?["center"].concat(s):["center","center"]),s[0]=l.test(s[0])?s[0]:"center",s[1]=u.test(s[1])?s[1]:"center",e=c.exec(s[0]),i=c.exec(s[1]),w[this]=[e?e[0]:0,i?i[0]:0],t[this]=[d.exec(s[0])[0],d.exec(s[1])[0]]}),1===k.length&&(k[1]=k[0]),"right"===t.at[0]?v.left+=p:"center"===t.at[0]&&(v.left+=p/2),"bottom"===t.at[1]?v.top+=m:"center"===t.at[1]&&(v.top+=m/2),n=i(w.at,p,m),v.left+=n[0],v.top+=n[1],this.each(function(){var a,l,u=e(this),c=u.outerWidth(),d=u.outerHeight(),f=s(this,"marginLeft"),y=s(this,"marginTop"),D=c+f+s(this,"marginRight")+x.width,T=d+y+s(this,"marginBottom")+x.height,M=e.extend({},v),S=i(w.my,u.outerWidth(),u.outerHeight());"right"===t.my[0]?M.left-=c:"center"===t.my[0]&&(M.left-=c/2),"bottom"===t.my[1]?M.top-=d:"center"===t.my[1]&&(M.top-=d/2),M.left+=S[0],M.top+=S[1],e.support.offsetFractions||(M.left=h(M.left),M.top=h(M.top)),a={marginLeft:f,marginTop:y},e.each(["left","top"],function(i,s){e.ui.position[k[i]]&&e.ui.position[k[i]][s](M,{targetWidth:p,targetHeight:m,elemWidth:c,elemHeight:d,collisionPosition:a,collisionWidth:D,collisionHeight:T,offset:[n[0]+S[0],n[1]+S[1]],my:t.my,at:t.at,within:_,elem:u})}),t.using&&(l=function(e){var i=g.left-M.left,s=i+p-c,a=g.top-M.top,n=a+m-d,h={target:{element:b,left:g.left,top:g.top,width:p,height:m},element:{element:u,left:M.left,top:M.top,width:c,height:d},horizontal:0>s?"left":i>0?"right":"center",vertical:0>n?"top":a>0?"bottom":"middle"};c>p&&p>o(i+s)&&(h.horizontal="center"),d>m&&m>o(a+n)&&(h.vertical="middle"),h.important=r(o(i),o(s))>r(o(a),o(n))?"horizontal":"vertical",t.using.call(this,e,h)}),u.offset(e.extend(M,{using:l}))})},e.ui.position={fit:{left:function(e,t){var i,s=t.within,a=s.isWindow?s.scrollLeft:s.offset.left,n=s.width,o=e.left-t.collisionPosition.marginLeft,h=a-o,l=o+t.collisionWidth-n-a;t.collisionWidth>n?h>0&&0>=l?(i=e.left+h+t.collisionWidth-n-a,e.left+=h-i):e.left=l>0&&0>=h?a:h>l?a+n-t.collisionWidth:a:h>0?e.left+=h:l>0?e.left-=l:e.left=r(e.left-o,e.left)},top:function(e,t){var i,s=t.within,a=s.isWindow?s.scrollTop:s.offset.top,n=t.within.height,o=e.top-t.collisionPosition.marginTop,h=a-o,l=o+t.collisionHeight-n-a;t.collisionHeight>n?h>0&&0>=l?(i=e.top+h+t.collisionHeight-n-a,e.top+=h-i):e.top=l>0&&0>=h?a:h>l?a+n-t.collisionHeight:a:h>0?e.top+=h:l>0?e.top-=l:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var i,s,a=t.within,n=a.offset.left+a.scrollLeft,r=a.width,h=a.isWindow?a.scrollLeft:a.offset.left,l=e.left-t.collisionPosition.marginLeft,u=l-h,c=l+t.collisionWidth-r-h,d="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,p="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,f=-2*t.offset[0];0>u?(i=e.left+d+p+f+t.collisionWidth-r-n,(0>i||o(u)>i)&&(e.left+=d+p+f)):c>0&&(s=e.left-t.collisionPosition.marginLeft+d+p+f-h,(s>0||c>o(s))&&(e.left+=d+p+f))},top:function(e,t){var i,s,a=t.within,n=a.offset.top+a.scrollTop,r=a.height,h=a.isWindow?a.scrollTop:a.offset.top,l=e.top-t.collisionPosition.marginTop,u=l-h,c=l+t.collisionHeight-r-h,d="top"===t.my[1],p=d?-t.elemHeight:"bottom"===t.my[1]?t.elemHeight:0,f="top"===t.at[1]?t.targetHeight:"bottom"===t.at[1]?-t.targetHeight:0,m=-2*t.offset[1];0>u?(s=e.top+p+f+m+t.collisionHeight-r-n,e.top+p+f+m>u&&(0>s||o(u)>s)&&(e.top+=p+f+m)):c>0&&(i=e.top-t.collisionPosition.marginTop+p+f+m-h,e.top+p+f+m>c&&(i>0||c>o(i))&&(e.top+=p+f+m))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,i,s,a,n,r=document.getElementsByTagName("body")[0],o=document.createElement("div");t=document.createElement(r?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},r&&e.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(n in s)t.style[n]=s[n];t.appendChild(o),i=r||document.documentElement,i.insertBefore(t,i.firstChild),o.style.cssText="position: absolute; left: 10.7432222px;",a=e(o).offset().left,e.support.offsetFractions=a>10&&11>a,t.innerHTML="",i.removeChild(t)}()})(jQuery);(function(e){e.widget("ui.draggable",e.ui.mouse,{version:"1.10.3",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var i=this.options;return this.helper||i.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(e(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){e("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var i=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,i){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),!i){var a=this._uiHash();if(this._trigger("drag",t,a)===!1)return this._mouseUp({}),!1;this.position=a.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var i=this,a=!1;return e.ui.ddmanager&&!this.options.dropBehaviour&&(a=e.ui.ddmanager.drop(this,t)),this.dropped&&(a=this.dropped,this.dropped=!1),"original"!==this.options.helper||e.contains(this.element[0].ownerDocument,this.element[0])?("invalid"===this.options.revert&&!a||"valid"===this.options.revert&&a||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,a)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",t)!==!1&&i._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1):!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(t){var i=this.options,a=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return a.parents("body").length||a.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),a[0]===this.element[0]||/(fixed|absolute)/.test(a.css("position"))||a.css("position","absolute"),a},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,a,s=this.options;return s.containment?"window"===s.containment?(this.containment=[e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,e(window).scrollLeft()+e(window).width()-this.helperProportions.width-this.margins.left,e(window).scrollTop()+(e(window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):"document"===s.containment?(this.containment=[0,0,e(document).width()-this.helperProportions.width-this.margins.left,(e(document).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):s.containment.constructor===Array?(this.containment=s.containment,undefined):("parent"===s.containment&&(s.containment=this.helper[0].parentNode),i=e(s.containment),a=i[0],a&&(t="hidden"!==i.css("overflow"),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(t?Math.max(a.scrollWidth,a.offsetWidth):a.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(a.scrollHeight,a.offsetHeight):a.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i),undefined):(this.containment=null,undefined)},_convertPositionTo:function(t,i){i||(i=this.position);var a="absolute"===t?1:-1,s="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent;return this.offset.scroll||(this.offset.scroll={top:s.scrollTop(),left:s.scrollLeft()}),{top:i.top+this.offset.relative.top*a+this.offset.parent.top*a-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top)*a,left:i.left+this.offset.relative.left*a+this.offset.parent.left*a-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)*a}},_generatePosition:function(t){var i,a,s,n,r=this.options,o="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,l=t.pageX,h=t.pageY;return this.offset.scroll||(this.offset.scroll={top:o.scrollTop(),left:o.scrollLeft()}),this.originalPosition&&(this.containment&&(this.relative_container?(a=this.relative_container.offset(),i=[this.containment[0]+a.left,this.containment[1]+a.top,this.containment[2]+a.left,this.containment[3]+a.top]):i=this.containment,t.pageX-this.offset.click.left<i[0]&&(l=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(h=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(l=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(h=i[3]+this.offset.click.top)),r.grid&&(s=r.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/r.grid[1])*r.grid[1]:this.originalPageY,h=i?s-this.offset.click.top>=i[1]||s-this.offset.click.top>i[3]?s:s-this.offset.click.top>=i[1]?s-r.grid[1]:s+r.grid[1]:s,n=r.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/r.grid[0])*r.grid[0]:this.originalPageX,l=i?n-this.offset.click.left>=i[0]||n-this.offset.click.left>i[2]?n:n-this.offset.click.left>=i[0]?n-r.grid[0]:n+r.grid[0]:n)),{top:h-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,i,a){return a=a||this._uiHash(),e.ui.plugin.call(this,t,[i,a]),"drag"===t&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,i,a)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,i){var a=e(this).data("ui-draggable"),s=a.options,n=e.extend({},i,{item:a.element});a.sortables=[],e(s.connectToSortable).each(function(){var i=e.data(this,"ui-sortable");i&&!i.options.disabled&&(a.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",t,n))})},stop:function(t,i){var a=e(this).data("ui-draggable"),s=e.extend({},i,{item:a.element});e.each(a.sortables,function(){this.instance.isOver?(this.instance.isOver=0,a.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,"original"===a.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,s))})},drag:function(t,i){var a=e(this).data("ui-draggable"),s=this;e.each(a.sortables,function(){var n=!1,r=this;this.instance.positionAbs=a.positionAbs,this.instance.helperProportions=a.helperProportions,this.instance.offset.click=a.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(n=!0,e.each(a.sortables,function(){return this.instance.positionAbs=a.positionAbs,this.instance.helperProportions=a.helperProportions,this.instance.offset.click=a.offset.click,this!==r&&this.instance._intersectsWith(this.instance.containerCache)&&e.contains(r.instance.element[0],this.instance.element[0])&&(n=!1),n})),n?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(s).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=a.offset.click.top,this.instance.offset.click.left=a.offset.click.left,this.instance.offset.parent.left-=a.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=a.offset.parent.top-this.instance.offset.parent.top,a._trigger("toSortable",t),a.dropped=this.instance.element,a.currentItem=a.element,this.instance.fromOutside=a),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),a._trigger("fromSortable",t),a.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(){var t=e("body"),i=e(this).data("ui-draggable").options;t.css("cursor")&&(i._cursor=t.css("cursor")),t.css("cursor",i.cursor)},stop:function(){var t=e(this).data("ui-draggable").options;t._cursor&&e("body").css("cursor",t._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,i){var a=e(i.helper),s=e(this).data("ui-draggable").options;a.css("opacity")&&(s._opacity=a.css("opacity")),a.css("opacity",s.opacity)},stop:function(t,i){var a=e(this).data("ui-draggable").options;a._opacity&&e(i.helper).css("opacity",a._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(){var t=e(this).data("ui-draggable");t.scrollParent[0]!==document&&"HTML"!==t.scrollParent[0].tagName&&(t.overflowOffset=t.scrollParent.offset())},drag:function(t){var i=e(this).data("ui-draggable"),a=i.options,s=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(a.axis&&"x"===a.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-t.pageY<a.scrollSensitivity?i.scrollParent[0].scrollTop=s=i.scrollParent[0].scrollTop+a.scrollSpeed:t.pageY-i.overflowOffset.top<a.scrollSensitivity&&(i.scrollParent[0].scrollTop=s=i.scrollParent[0].scrollTop-a.scrollSpeed)),a.axis&&"y"===a.axis||(i.overflowOffset.left+i.scrollParent[0].offsetWidth-t.pageX<a.scrollSensitivity?i.scrollParent[0].scrollLeft=s=i.scrollParent[0].scrollLeft+a.scrollSpeed:t.pageX-i.overflowOffset.left<a.scrollSensitivity&&(i.scrollParent[0].scrollLeft=s=i.scrollParent[0].scrollLeft-a.scrollSpeed))):(a.axis&&"x"===a.axis||(t.pageY-e(document).scrollTop()<a.scrollSensitivity?s=e(document).scrollTop(e(document).scrollTop()-a.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<a.scrollSensitivity&&(s=e(document).scrollTop(e(document).scrollTop()+a.scrollSpeed))),a.axis&&"y"===a.axis||(t.pageX-e(document).scrollLeft()<a.scrollSensitivity?s=e(document).scrollLeft(e(document).scrollLeft()-a.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<a.scrollSensitivity&&(s=e(document).scrollLeft(e(document).scrollLeft()+a.scrollSpeed)))),s!==!1&&e.ui.ddmanager&&!a.dropBehaviour&&e.ui.ddmanager.prepareOffsets(i,t)}}),e.ui.plugin.add("draggable","snap",{start:function(){var t=e(this).data("ui-draggable"),i=t.options;t.snapElements=[],e(i.snap.constructor!==String?i.snap.items||":data(ui-draggable)":i.snap).each(function(){var i=e(this),a=i.offset();this!==t.element[0]&&t.snapElements.push({item:this,width:i.outerWidth(),height:i.outerHeight(),top:a.top,left:a.left})})},drag:function(t,i){var a,s,n,r,o,l,h,u,d,c,p=e(this).data("ui-draggable"),f=p.options,m=f.snapTolerance,g=i.offset.left,v=g+p.helperProportions.width,y=i.offset.top,b=y+p.helperProportions.height;for(d=p.snapElements.length-1;d>=0;d--)o=p.snapElements[d].left,l=o+p.snapElements[d].width,h=p.snapElements[d].top,u=h+p.snapElements[d].height,o-m>v||g>l+m||h-m>b||y>u+m||!e.contains(p.snapElements[d].item.ownerDocument,p.snapElements[d].item)?(p.snapElements[d].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,t,e.extend(p._uiHash(),{snapItem:p.snapElements[d].item})),p.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(a=m>=Math.abs(h-b),s=m>=Math.abs(u-y),n=m>=Math.abs(o-v),r=m>=Math.abs(l-g),a&&(i.position.top=p._convertPositionTo("relative",{top:h-p.helperProportions.height,left:0}).top-p.margins.top),s&&(i.position.top=p._convertPositionTo("relative",{top:u,left:0}).top-p.margins.top),n&&(i.position.left=p._convertPositionTo("relative",{top:0,left:o-p.helperProportions.width}).left-p.margins.left),r&&(i.position.left=p._convertPositionTo("relative",{top:0,left:l}).left-p.margins.left)),c=a||s||n||r,"outer"!==f.snapMode&&(a=m>=Math.abs(h-y),s=m>=Math.abs(u-b),n=m>=Math.abs(o-g),r=m>=Math.abs(l-v),a&&(i.position.top=p._convertPositionTo("relative",{top:h,left:0}).top-p.margins.top),s&&(i.position.top=p._convertPositionTo("relative",{top:u-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.left=p._convertPositionTo("relative",{top:0,left:o}).left-p.margins.left),r&&(i.position.left=p._convertPositionTo("relative",{top:0,left:l-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[d].snapping&&(a||s||n||r||c)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,t,e.extend(p._uiHash(),{snapItem:p.snapElements[d].item})),p.snapElements[d].snapping=a||s||n||r||c)}}),e.ui.plugin.add("draggable","stack",{start:function(){var t,i=this.data("ui-draggable").options,a=e.makeArray(e(i.stack)).sort(function(t,i){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(i).css("zIndex"),10)||0)});a.length&&(t=parseInt(e(a[0]).css("zIndex"),10)||0,e(a).each(function(i){e(this).css("zIndex",t+i)}),this.css("zIndex",t+a.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,i){var a=e(i.helper),s=e(this).data("ui-draggable").options;a.css("zIndex")&&(s._zIndex=a.css("zIndex")),a.css("zIndex",s.zIndex)},stop:function(t,i){var a=e(this).data("ui-draggable").options;a._zIndex&&e(i.helper).css("zIndex",a._zIndex)}})})(jQuery);(function(e){function t(e,t,i){return e>t&&t+i>e}e.widget("ui.droppable",{version:"1.10.3",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t=this.options,i=t.accept;this.isover=!1,this.isout=!0,this.accept=e.isFunction(i)?i:function(e){return e.is(i)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},e.ui.ddmanager.droppables[t.scope]=e.ui.ddmanager.droppables[t.scope]||[],e.ui.ddmanager.droppables[t.scope].push(this),t.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){for(var t=0,i=e.ui.ddmanager.droppables[this.options.scope];i.length>t;t++)i[t]===this&&i.splice(t,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,i){"accept"===t&&(this.accept=e.isFunction(i)?i:function(e){return e.is(i)}),e.Widget.prototype._setOption.apply(this,arguments)},_activate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",t,this.ui(i))},_deactivate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",t,this.ui(i))},_over:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(i)))},_out:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(i)))},_drop:function(t,i){var a=i||e.ui.ddmanager.current,s=!1;return a&&(a.currentItem||a.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var t=e.data(this,"ui-droppable");return t.options.greedy&&!t.options.disabled&&t.options.scope===a.options.scope&&t.accept.call(t.element[0],a.currentItem||a.element)&&e.ui.intersect(a,e.extend(t,{offset:t.element.offset()}),t.options.tolerance)?(s=!0,!1):undefined}),s?!1:this.accept.call(this.element[0],a.currentItem||a.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(a)),this.element):!1):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(e,i,a){if(!i.offset)return!1;var s,n,r=(e.positionAbs||e.position.absolute).left,o=r+e.helperProportions.width,l=(e.positionAbs||e.position.absolute).top,h=l+e.helperProportions.height,u=i.offset.left,d=u+i.proportions.width,c=i.offset.top,p=c+i.proportions.height;switch(a){case"fit":return r>=u&&d>=o&&l>=c&&p>=h;case"intersect":return r+e.helperProportions.width/2>u&&d>o-e.helperProportions.width/2&&l+e.helperProportions.height/2>c&&p>h-e.helperProportions.height/2;case"pointer":return s=(e.positionAbs||e.position.absolute).left+(e.clickOffset||e.offset.click).left,n=(e.positionAbs||e.position.absolute).top+(e.clickOffset||e.offset.click).top,t(n,c,i.proportions.height)&&t(s,u,i.proportions.width);case"touch":return(l>=c&&p>=l||h>=c&&p>=h||c>l&&h>p)&&(r>=u&&d>=r||o>=u&&d>=o||u>r&&o>d);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,i){var a,s,n=e.ui.ddmanager.droppables[t.options.scope]||[],r=i?i.type:null,o=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();e:for(a=0;n.length>a;a++)if(!(n[a].options.disabled||t&&!n[a].accept.call(n[a].element[0],t.currentItem||t.element))){for(s=0;o.length>s;s++)if(o[s]===n[a].element[0]){n[a].proportions.height=0;continue e}n[a].visible="none"!==n[a].element.css("display"),n[a].visible&&("mousedown"===r&&n[a]._activate.call(n[a],i),n[a].offset=n[a].element.offset(),n[a].proportions={width:n[a].element[0].offsetWidth,height:n[a].element[0].offsetHeight})}},drop:function(t,i){var a=!1;return e.each((e.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance)&&(a=this._drop.call(this,i)||a),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),a},dragStart:function(t,i){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)})},drag:function(t,i){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,i),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var a,s,n,r=e.ui.intersect(t,this,this.options.tolerance),o=!r&&this.isover?"isout":r&&!this.isover?"isover":null;o&&(this.options.greedy&&(s=this.options.scope,n=this.element.parents(":data(ui-droppable)").filter(function(){return e.data(this,"ui-droppable").options.scope===s}),n.length&&(a=e.data(n[0],"ui-droppable"),a.greedyChild="isover"===o)),a&&"isover"===o&&(a.isover=!1,a.isout=!0,a._out.call(a,i)),this[o]=!0,this["isout"===o?"isover":"isout"]=!1,this["isover"===o?"_over":"_out"].call(this,i),a&&"isout"===o&&(a.isout=!1,a.isover=!0,a._over.call(a,i)))}})},dragStop:function(t,i){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)}}})(jQuery);(function(e){function t(e){return parseInt(e,10)||0}function i(e){return!isNaN(parseInt(e,10))}e.widget("ui.resizable",e.ui.mouse,{version:"1.10.3",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var t,i,s,a,n,r=this,o=this.options;if(this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!o.aspectRatio,aspectRatio:o.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:o.helper||o.ghost||o.animate?o.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=o.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={},i=0;t.length>i;i++)s=e.trim(t[i]),n="ui-resizable-"+s,a=e("<div class='ui-resizable-handle "+n+"'></div>"),a.css({zIndex:o.zIndex}),"se"===s&&a.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(a);this._renderAxis=function(t){var i,s,a,n;t=t||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=e(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=e(this.handles[i],this.element),n=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),a=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),t.css(a,n),this._proportionallyResize()),e(this.handles[i]).length},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){r.resizing||(this.className&&(a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=a&&a[1]?a[1]:"se")}),o.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){o.disabled||(e(this).removeClass("ui-resizable-autohide"),r._handles.show())}).mouseleave(function(){o.disabled||r.resizing||(e(this).addClass("ui-resizable-autohide"),r._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,i=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(t){var i,s,a=!1;for(i in this.handles)s=e(this.handles[i])[0],(s===t.target||e.contains(s,t.target))&&(a=!0);return!this.options.disabled&&a},_mouseStart:function(i){var s,a,n,r=this.options,o=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:o.top,left:o.left}),this._renderProxy(),s=t(this.helper.css("left")),a=t(this.helper.css("top")),r.containment&&(s+=e(r.containment).scrollLeft()||0,a+=e(r.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:a},this.size=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:a},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof r.aspectRatio?r.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor","auto"===n?this.axis+"-resize":n),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(t){var i,s=this.helper,a={},n=this.originalMousePosition,r=this.axis,o=this.position.top,h=this.position.left,l=this.size.width,u=this.size.height,c=t.pageX-n.left||0,d=t.pageY-n.top||0,p=this._change[r];return p?(i=p.apply(this,[t,c,d]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(i=this._updateRatio(i,t)),i=this._respectSize(i,t),this._updateCache(i),this._propagate("resize",t),this.position.top!==o&&(a.top=this.position.top+"px"),this.position.left!==h&&(a.left=this.position.left+"px"),this.size.width!==l&&(a.width=this.size.width+"px"),this.size.height!==u&&(a.height=this.size.height+"px"),s.css(a),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(a)||this._trigger("resize",t,this.ui()),!1):!1},_mouseStop:function(t){this.resizing=!1;var i,s,a,n,r,o,h,l=this.options,u=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),a=s&&e.ui.hasScroll(i[0],"left")?0:u.sizeDiff.height,n=s?0:u.sizeDiff.width,r={width:u.helper.width()-n,height:u.helper.height()-a},o=parseInt(u.element.css("left"),10)+(u.position.left-u.originalPosition.left)||null,h=parseInt(u.element.css("top"),10)+(u.position.top-u.originalPosition.top)||null,l.animate||this.element.css(e.extend(r,{top:h,left:o})),u.helper.height(u.size.height),u.helper.width(u.size.width),this._helper&&!l.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t,s,a,n,r,o=this.options;r={minWidth:i(o.minWidth)?o.minWidth:0,maxWidth:i(o.maxWidth)?o.maxWidth:1/0,minHeight:i(o.minHeight)?o.minHeight:0,maxHeight:i(o.maxHeight)?o.maxHeight:1/0},(this._aspectRatio||e)&&(t=r.minHeight*this.aspectRatio,a=r.minWidth/this.aspectRatio,s=r.maxHeight*this.aspectRatio,n=r.maxWidth/this.aspectRatio,t>r.minWidth&&(r.minWidth=t),a>r.minHeight&&(r.minHeight=a),r.maxWidth>s&&(r.maxWidth=s),r.maxHeight>n&&(r.maxHeight=n)),this._vBoundaries=r},_updateCache:function(e){this.offset=this.helper.offset(),i(e.left)&&(this.position.left=e.left),i(e.top)&&(this.position.top=e.top),i(e.height)&&(this.size.height=e.height),i(e.width)&&(this.size.width=e.width)},_updateRatio:function(e){var t=this.position,s=this.size,a=this.axis;return i(e.height)?e.width=e.height*this.aspectRatio:i(e.width)&&(e.height=e.width/this.aspectRatio),"sw"===a&&(e.left=t.left+(s.width-e.width),e.top=null),"nw"===a&&(e.top=t.top+(s.height-e.height),e.left=t.left+(s.width-e.width)),e},_respectSize:function(e){var t=this._vBoundaries,s=this.axis,a=i(e.width)&&t.maxWidth&&t.maxWidth<e.width,n=i(e.height)&&t.maxHeight&&t.maxHeight<e.height,r=i(e.width)&&t.minWidth&&t.minWidth>e.width,o=i(e.height)&&t.minHeight&&t.minHeight>e.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,u=/sw|nw|w/.test(s),c=/nw|ne|n/.test(s);return r&&(e.width=t.minWidth),o&&(e.height=t.minHeight),a&&(e.width=t.maxWidth),n&&(e.height=t.maxHeight),r&&u&&(e.left=h-t.minWidth),a&&u&&(e.left=h-t.maxWidth),o&&c&&(e.top=l-t.minHeight),n&&c&&(e.top=l-t.maxHeight),e.width||e.height||e.left||!e.top?e.width||e.height||e.top||!e.left||(e.left=null):e.top=null,e},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var e,t,i,s,a,n=this.helper||this.element;for(e=0;this._proportionallyResizeElements.length>e;e++){if(a=this._proportionallyResizeElements[e],!this.borderDif)for(this.borderDif=[],i=[a.css("borderTopWidth"),a.css("borderRightWidth"),a.css("borderBottomWidth"),a.css("borderLeftWidth")],s=[a.css("paddingTop"),a.css("paddingRight"),a.css("paddingBottom"),a.css("paddingLeft")],t=0;i.length>t;t++)this.borderDif[t]=(parseInt(i[t],10)||0)+(parseInt(s[t],10)||0);a.css({height:n.height()-this.borderDif[0]-this.borderDif[2]||0,width:n.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var t=this.element,i=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||e("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,i){var s=this.originalSize,a=this.originalPosition;return{top:a.top+i,height:s.height-i}},s:function(e,t,i){return{height:this.originalSize.height+i}},se:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},sw:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,i,s]))},ne:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},nw:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,i,s]))}},_propagate:function(t,i){e.ui.plugin.call(this,t,[i,this.ui()]),"resize"!==t&&this._trigger(t,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var i=e(this).data("ui-resizable"),s=i.options,a=i._proportionallyResizeElements,n=a.length&&/textarea/i.test(a[0].nodeName),r=n&&e.ui.hasScroll(a[0],"left")?0:i.sizeDiff.height,o=n?0:i.sizeDiff.width,h={width:i.size.width-o,height:i.size.height-r},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,u=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(e.extend(h,u&&l?{top:u,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};a&&a.length&&e(a[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var i,s,a,n,r,o,h,l=e(this).data("ui-resizable"),u=l.options,c=l.element,d=u.containment,p=d instanceof e?d.get(0):/parent/.test(d)?c.parent().get(0):d;p&&(l.containerElement=e(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(i=e(p),s=[],e(["Top","Right","Left","Bottom"]).each(function(e,a){s[e]=t(i.css("padding"+a))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},a=l.containerOffset,n=l.containerSize.height,r=l.containerSize.width,o=e.ui.hasScroll(p,"left")?p.scrollWidth:r,h=e.ui.hasScroll(p)?p.scrollHeight:n,l.parentData={element:p,left:a.left,top:a.top,width:o,height:h}))},resize:function(t){var i,s,a,n,r=e(this).data("ui-resizable"),o=r.options,h=r.containerOffset,l=r.position,u=r._aspectRatio||t.shiftKey,c={top:0,left:0},d=r.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(c=h),l.left<(r._helper?h.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-h.left:r.position.left-c.left),u&&(r.size.height=r.size.width/r.aspectRatio),r.position.left=o.helper?h.left:0),l.top<(r._helper?h.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-h.top:r.position.top),u&&(r.size.width=r.size.height*r.aspectRatio),r.position.top=r._helper?h.top:0),r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top,i=Math.abs((r._helper?r.offset.left-c.left:r.offset.left-c.left)+r.sizeDiff.width),s=Math.abs((r._helper?r.offset.top-c.top:r.offset.top-h.top)+r.sizeDiff.height),a=r.containerElement.get(0)===r.element.parent().get(0),n=/relative|absolute/.test(r.containerElement.css("position")),a&&n&&(i-=r.parentData.left),i+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-i,u&&(r.size.height=r.size.width/r.aspectRatio)),s+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-s,u&&(r.size.width=r.size.height*r.aspectRatio))},stop:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.containerOffset,a=t.containerPosition,n=t.containerElement,r=e(t.helper),o=r.offset(),h=r.outerWidth()-t.sizeDiff.width,l=r.outerHeight()-t.sizeDiff.height;t._helper&&!i.animate&&/relative/.test(n.css("position"))&&e(this).css({left:o.left-a.left-s.left,width:h,height:l}),t._helper&&!i.animate&&/static/.test(n.css("position"))&&e(this).css({left:o.left-a.left-s.left,width:h,height:l})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).data("ui-resizable"),i=t.options,s=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)})},resize:function(t,i){var s=e(this).data("ui-resizable"),a=s.options,n=s.originalSize,r=s.originalPosition,o={height:s.size.height-n.height||0,width:s.size.width-n.width||0,top:s.position.top-r.top||0,left:s.position.left-r.left||0},h=function(t,s){e(t).each(function(){var t=e(this),a=e(this).data("ui-resizable-alsoresize"),n={},r=s&&s.length?s:t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(e,t){var i=(a[t]||0)+(o[t]||0);i&&i>=0&&(n[t]=i||null)}),t.css(n)})};"object"!=typeof a.alsoResize||a.alsoResize.nodeType?h(a.alsoResize):e.each(a.alsoResize,function(e,t){h(e,t)})},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).data("ui-resizable");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).data("ui-resizable");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.size,a=t.originalSize,n=t.originalPosition,r=t.axis,o="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=o[0]||1,l=o[1]||1,u=Math.round((s.width-a.width)/h)*h,c=Math.round((s.height-a.height)/l)*l,d=a.width+u,p=a.height+c,f=i.maxWidth&&d>i.maxWidth,m=i.maxHeight&&p>i.maxHeight,g=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=o,g&&(d+=h),v&&(p+=l),f&&(d-=h),m&&(p-=l),/^(se|s|e)$/.test(r)?(t.size.width=d,t.size.height=p):/^(ne)$/.test(r)?(t.size.width=d,t.size.height=p,t.position.top=n.top-c):/^(sw)$/.test(r)?(t.size.width=d,t.size.height=p,t.position.left=n.left-u):(t.size.width=d,t.size.height=p,t.position.top=n.top-c,t.position.left=n.left-u)}})})(jQuery);(function(e){e.widget("ui.selectable",e.ui.mouse,{version:"1.10.3",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var t,i=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){t=e(i.options.filter,i.element[0]),t.addClass("ui-selectee"),t.each(function(){var t=e(this),i=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:i.left,top:i.top,right:i.left+t.outerWidth(),bottom:i.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=t.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var i=this,s=this.options;this.opos=[t.pageX,t.pageY],this.options.disabled||(this.selectees=e(s.filter,this.element[0]),this._trigger("start",t),e(s.appendTo).append(this.helper),this.helper.css({left:t.pageX,top:t.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=e.data(this,"selectable-item");s.startselected=!0,t.metaKey||t.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",t,{unselecting:s.element}))}),e(t.target).parents().addBack().each(function(){var s,a=e.data(this,"selectable-item");return a?(s=!t.metaKey&&!t.ctrlKey||!a.$element.hasClass("ui-selected"),a.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),a.unselecting=!s,a.selecting=s,a.selected=s,s?i._trigger("selecting",t,{selecting:a.element}):i._trigger("unselecting",t,{unselecting:a.element}),!1):undefined}))},_mouseDrag:function(t){if(this.dragged=!0,!this.options.disabled){var i,s=this,a=this.options,n=this.opos[0],r=this.opos[1],o=t.pageX,h=t.pageY;return n>o&&(i=o,o=n,n=i),r>h&&(i=h,h=r,r=i),this.helper.css({left:n,top:r,width:o-n,height:h-r}),this.selectees.each(function(){var i=e.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===a.tolerance?l=!(i.left>o||n>i.right||i.top>h||r>i.bottom):"fit"===a.tolerance&&(l=i.left>n&&o>i.right&&i.top>r&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",t,{selecting:i.element}))):(i.selecting&&((t.metaKey||t.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",t,{unselecting:i.element}))),i.selected&&(t.metaKey||t.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",t,{unselecting:i.element})))))}),!1}},_mouseStop:function(t){var i=this;return this.dragged=!1,e(".ui-unselecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",t,{unselected:s.element})}),e(".ui-selecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",t,{selected:s.element})}),this._trigger("stop",t),this.helper.remove(),!1}})})(jQuery);(function(e){function t(e,t,i){return e>t&&t+i>e}function i(e){return/left|right/.test(e.css("float"))||/inline|table-cell/.test(e.css("display"))}e.widget("ui.sortable",e.ui.mouse,{version:"1.10.3",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===e.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,i){"disabled"===t?(this.options[t]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,i){var s=null,a=!1,n=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(t),e(t.target).parents().each(function(){return e.data(this,n.widgetName+"-item")===n?(s=e(this),!1):undefined}),e.data(t.target,n.widgetName+"-item")===n&&(s=e(t.target)),s?!this.options.handle||i||(e(this.options.handle,s).find("*").addBack().each(function(){this===t.target&&(a=!0)}),a)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(t,i,s){var a,n,r=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,r.cursorAt&&this._adjustOffsetFromHelper(r.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),r.containment&&this._setContainment(),r.cursor&&"auto"!==r.cursor&&(n=this.document.find("body"),this.storedCursor=n.css("cursor"),n.css("cursor",r.cursor),this.storedStylesheet=e("<style>*{ cursor: "+r.cursor+" !important; }</style>").appendTo(n)),r.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",r.opacity)),r.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",r.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(a=this.containers.length-1;a>=0;a--)this.containers[a]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!r.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var i,s,a,n,r=this.options,o=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<r.scrollSensitivity?this.scrollParent[0].scrollTop=o=this.scrollParent[0].scrollTop+r.scrollSpeed:t.pageY-this.overflowOffset.top<r.scrollSensitivity&&(this.scrollParent[0].scrollTop=o=this.scrollParent[0].scrollTop-r.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<r.scrollSensitivity?this.scrollParent[0].scrollLeft=o=this.scrollParent[0].scrollLeft+r.scrollSpeed:t.pageX-this.overflowOffset.left<r.scrollSensitivity&&(this.scrollParent[0].scrollLeft=o=this.scrollParent[0].scrollLeft-r.scrollSpeed)):(t.pageY-e(document).scrollTop()<r.scrollSensitivity?o=e(document).scrollTop(e(document).scrollTop()-r.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<r.scrollSensitivity&&(o=e(document).scrollTop(e(document).scrollTop()+r.scrollSpeed)),t.pageX-e(document).scrollLeft()<r.scrollSensitivity?o=e(document).scrollLeft(e(document).scrollLeft()-r.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<r.scrollSensitivity&&(o=e(document).scrollLeft(e(document).scrollLeft()+r.scrollSpeed))),o!==!1&&e.ui.ddmanager&&!r.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],a=s.item[0],n=this._intersectsWithPointer(s),n&&s.instance===this.currentContainer&&a!==this.currentItem[0]&&this.placeholder[1===n?"next":"prev"]()[0]!==a&&!e.contains(this.placeholder[0],a)&&("semi-dynamic"===this.options.type?!e.contains(this.element[0],a):!0)){if(this.direction=1===n?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,i){if(t){if(e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t),this.options.revert){var s=this,a=this.placeholder.offset(),n=this.options.axis,r={};n&&"x"!==n||(r.left=a.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),n&&"y"!==n||(r.top=a.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,e(this.helper).animate(r,parseInt(this.options.revert,10)||500,function(){s._clear(t)})}else this._clear(t,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},e(i).each(function(){var i=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);i&&s.push((t.key||i[1]+"[]")+"="+(t.key&&t.expression?i[1]:i[2]))}),!s.length&&t.key&&s.push(t.key+"="),s.join("&")},toArray:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},i.each(function(){s.push(e(t.item||this).attr(t.attribute||"id")||"")}),s},_intersectsWith:function(e){var t=this.positionAbs.left,i=t+this.helperProportions.width,s=this.positionAbs.top,a=s+this.helperProportions.height,n=e.left,r=n+e.width,o=e.top,h=o+e.height,l=this.offset.click.top,u=this.offset.click.left,c="x"===this.options.axis||s+l>o&&h>s+l,d="y"===this.options.axis||t+u>n&&r>t+u,p=c&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?p:t+this.helperProportions.width/2>n&&r>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>o&&h>a-this.helperProportions.height/2},_intersectsWithPointer:function(e){var i="x"===this.options.axis||t(this.positionAbs.top+this.offset.click.top,e.top,e.height),s="y"===this.options.axis||t(this.positionAbs.left+this.offset.click.left,e.left,e.width),a=i&&s,n=this._getDragVerticalDirection(),r=this._getDragHorizontalDirection();return a?this.floating?r&&"right"===r||"down"===n?2:1:n&&("down"===n?2:1):!1},_intersectsWithSides:function(e){var i=t(this.positionAbs.top+this.offset.click.top,e.top+e.height/2,e.height),s=t(this.positionAbs.left+this.offset.click.left,e.left+e.width/2,e.width),a=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&s||"left"===n&&!s:a&&("down"===a&&i||"up"===a&&!i)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return 0!==e&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return 0!==e&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var i,s,a,n,r=[],o=[],h=this._connectWith();if(h&&t)for(i=h.length-1;i>=0;i--)for(a=e(h[i]),s=a.length-1;s>=0;s--)n=e.data(a[s],this.widgetFullName),n&&n!==this&&!n.options.disabled&&o.push([e.isFunction(n.options.items)?n.options.items.call(n.element):e(n.options.items,n.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),n]);for(o.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),i=o.length-1;i>=0;i--)o[i][0].each(function(){r.push(this)});return e(r)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var i=0;t.length>i;i++)if(t[i]===e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var i,s,a,n,r,o,h,l,u=this.items,c=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(a=e(d[i]),s=a.length-1;s>=0;s--)n=e.data(a[s],this.widgetFullName),n&&n!==this&&!n.options.disabled&&(c.push([e.isFunction(n.options.items)?n.options.items.call(n.element[0],t,{item:this.currentItem}):e(n.options.items,n.element),n]),this.containers.push(n));for(i=c.length-1;i>=0;i--)for(r=c[i][1],o=c[i][0],s=0,l=o.length;l>s;s++)h=e(o[s]),h.data(this.widgetName+"-item",r),u.push({item:h,instance:r,width:0,height:0,left:0,top:0})},refreshPositions:function(t){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,a,n;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(a=this.options.toleranceElement?e(this.options.toleranceElement,s.item):s.item,t||(s.width=a.outerWidth(),s.height=a.outerHeight()),n=a.offset(),s.left=n.left,s.top=n.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)n=this.containers[i].element.offset(),this.containers[i].containerCache.left=n.left,this.containers[i].containerCache.top=n.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var i,s=t.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=t.currentItem[0].nodeName.toLowerCase(),a=e("<"+s+">",t.document[0]).addClass(i||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?t.currentItem.children().each(function(){e("<td>&#160;</td>",t.document[0]).attr("colspan",e(this).attr("colspan")||1).appendTo(a)}):"img"===s&&a.attr("src",t.currentItem.attr("src")),i||a.css("visibility","hidden"),a},update:function(e,a){(!i||s.forcePlaceholderSize)&&(a.height()||a.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),a.width()||a.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10)))}}),t.placeholder=e(s.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),s.placeholder.update(t,t.placeholder)},_contactContainers:function(s){var a,n,r,o,h,l,u,c,d,p,f=null,m=null;for(a=this.containers.length-1;a>=0;a--)if(!e.contains(this.currentItem[0],this.containers[a].element[0]))if(this._intersectsWith(this.containers[a].containerCache)){if(f&&e.contains(this.containers[a].element[0],f.element[0]))continue;f=this.containers[a],m=a}else this.containers[a].containerCache.over&&(this.containers[a]._trigger("out",s,this._uiHash(this)),this.containers[a].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[m].containerCache.over||(this.containers[m]._trigger("over",s,this._uiHash(this)),this.containers[m].containerCache.over=1);else{for(r=1e4,o=null,p=f.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",u=this.positionAbs[h]+this.offset.click[h],n=this.items.length-1;n>=0;n--)e.contains(this.containers[m].element[0],this.items[n].item[0])&&this.items[n].item[0]!==this.currentItem[0]&&(!p||t(this.positionAbs.top+this.offset.click.top,this.items[n].top,this.items[n].height))&&(c=this.items[n].item.offset()[h],d=!1,Math.abs(c-u)>Math.abs(c+this.items[n][l]-u)&&(d=!0,c+=this.items[n][l]),r>Math.abs(c-u)&&(r=Math.abs(c-u),o=this.items[n],this.direction=d?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[m])return;o?this._rearrange(s,o,null,!0):this._rearrange(s,null,this.containers[m].element,!0),this._trigger("change",s,this._uiHash()),this.containers[m]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[m],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[m]._trigger("over",s,this._uiHash(this)),this.containers[m].containerCache.over=1}},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||e("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,a=this.options;"parent"===a.containment&&(a.containment=this.helper[0].parentNode),("document"===a.containment||"window"===a.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,e("document"===a.containment?document:window).width()-this.helperProportions.width-this.margins.left,(e("document"===a.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(a.containment)||(t=e(a.containment)[0],i=e(a.containment).offset(),s="hidden"!==e(t).css("overflow"),this.containment=[i.left+(parseInt(e(t).css("borderLeftWidth"),10)||0)+(parseInt(e(t).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(e(t).css("borderTopWidth"),10)||0)+(parseInt(e(t).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(e(t).css("borderLeftWidth"),10)||0)-(parseInt(e(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(e(t).css("borderTopWidth"),10)||0)-(parseInt(e(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,a="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,n=/(html|body)/i.test(a[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():n?0:a.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():n?0:a.scrollLeft())*s}},_generatePosition:function(t){var i,s,a=this.options,n=t.pageX,r=t.pageY,o="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(o[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(n=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(r=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(n=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(r=this.containment[3]+this.offset.click.top)),a.grid&&(i=this.originalPageY+Math.round((r-this.originalPageY)/a.grid[1])*a.grid[1],r=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-a.grid[1]:i+a.grid[1]:i,s=this.originalPageX+Math.round((n-this.originalPageX)/a.grid[0])*a.grid[0],n=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-a.grid[0]:s+a.grid[0]:s)),{top:r-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:o.scrollTop()),left:n-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:o.scrollLeft())}},_rearrange:function(e,t,i,s){i?i[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var a=this.counter;this._delay(function(){a===this.counter&&this.refreshPositions(!s)})},_clear:function(e,t){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)("auto"===this._storedCSS[i]||"static"===this._storedCSS[i])&&(this._storedCSS[i]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!t&&s.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||t||s.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(t||(s.push(function(e){this._trigger("remove",e,this._uiHash())}),s.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;i>=0;i--)t||s.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!t){for(this._trigger("beforeStop",e,this._uiHash()),i=0;s.length>i;i++)s[i].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!1}if(t||this._trigger("beforeStop",e,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!t){for(i=0;s.length>i;i++)s[i].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var i=t||this;return{helper:i.helper,placeholder:i.placeholder||e([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:t?t.element:null}}})})(jQuery);(function(e){var t=0,i={},a={};i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="hide",a.height=a.paddingTop=a.paddingBottom=a.borderTopWidth=a.borderBottomWidth="show",e.widget("ui.accordion",{version:"1.10.3",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var t=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),t.collapsible||t.active!==!1&&null!=t.active||(t.active=0),this._processPanels(),0>t.active&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():e(),content:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("<span>").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),"content"!==this.options.heightStyle&&e.css("height","")},_setOption:function(e,t){return"active"===e?(this._activate(t),undefined):("event"===e&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),"collapsible"!==e||t||this.options.active!==!1||this._activate(0),"icons"===e&&(this._destroyIcons(),t&&this._createIcons()),"disabled"===e&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t),undefined)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var i=e.ui.keyCode,a=this.headers.length,s=this.headers.index(t.target),n=!1;switch(t.keyCode){case i.RIGHT:case i.DOWN:n=this.headers[(s+1)%a];break;case i.LEFT:case i.UP:n=this.headers[(s-1+a)%a];break;case i.SPACE:case i.ENTER:this._eventHandler(t);break;case i.HOME:n=this.headers[0];break;case i.END:n=this.headers[a-1]}n&&(e(t.target).attr("tabIndex",-1),e(n).attr("tabIndex",0),n.focus(),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t=this.options;this._processPanels(),t.active===!1&&t.collapsible===!0||!this.headers.length?(t.active=!1,this.active=e()):t.active===!1?this._activate(0):this.active.length&&!e.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=e()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var i,a=this.options,s=a.heightStyle,n=this.element.parent(),r=this.accordionId="ui-accordion-"+(this.element.attr("id")||++t);this.active=this._findActive(a.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(t){var i=e(this),a=i.attr("id"),s=i.next(),n=s.attr("id");a||(a=r+"-header-"+t,i.attr("id",a)),n||(n=r+"-panel-"+t,s.attr("id",n)),i.attr("aria-controls",n),s.attr("aria-labelledby",a)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(a.event),"fill"===s?(i=n.height(),this.element.siblings(":visible").each(function(){var t=e(this),a=t.css("position");"absolute"!==a&&"fixed"!==a&&(i-=t.outerHeight(!0))}),this.headers.each(function(){i-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===s&&(i=0,this.headers.next().each(function(){i=Math.max(i,e(this).css("height","").height())}).height(i))},_activate:function(t){var i=this._findActive(t)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):e()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var i=this.options,a=this.active,s=e(t.currentTarget),n=s[0]===a[0],r=n&&i.collapsible,o=r?e():s.next(),h=a.next(),l={oldHeader:a,oldPanel:h,newHeader:r?e():s,newPanel:o};t.preventDefault(),n&&!i.collapsible||this._trigger("beforeActivate",t,l)===!1||(i.active=r?!1:this.headers.index(s),this.active=n?e():s,this._toggle(l),a.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&a.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),n||(s.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),s.next().addClass("ui-accordion-content-active")))},_toggle:function(t){var i=t.newPanel,a=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=a,this.options.animate?this._animate(i,a,t):(a.hide(),i.show(),this._toggleComplete(t)),a.attr({"aria-expanded":"false","aria-hidden":"true"}),a.prev().attr("aria-selected","false"),i.length&&a.length?a.prev().attr("tabIndex",-1):i.length&&this.headers.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(e,t,s){var n,r,o,h=this,l=0,u=e.length&&(!t.length||e.index()<t.index()),d=this.options.animate||{},c=u&&d.down||d,p=function(){h._toggleComplete(s)};return"number"==typeof c&&(o=c),"string"==typeof c&&(r=c),r=r||c.easing||d.easing,o=o||c.duration||d.duration,t.length?e.length?(n=e.show().outerHeight(),t.animate(i,{duration:o,easing:r,step:function(e,t){t.now=Math.round(e)}}),e.hide().animate(a,{duration:o,easing:r,complete:p,step:function(e,i){i.now=Math.round(e),"height"!==i.prop?l+=i.now:"content"!==h.options.heightStyle&&(i.now=Math.round(n-t.outerHeight()-l),l=0)}}),undefined):t.animate(i,o,r,p):e.animate(a,o,r,p)},_toggleComplete:function(e){var t=e.oldPanel;t.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),t.length&&(t.parent()[0].className=t.parent()[0].className),this._trigger("activate",null,e)}})})(jQuery);(function(e){var t=0;e.widget("ui.autocomplete",{version:"1.10.3",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var t,i,a,s=this.element[0].nodeName.toLowerCase(),n="textarea"===s,r="input"===s;this.isMultiLine=n?!0:r?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[n||r?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(s){if(this.element.prop("readOnly"))return t=!0,a=!0,i=!0,undefined;t=!1,a=!1,i=!1;var n=e.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:t=!0,this._move("previousPage",s);break;case n.PAGE_DOWN:t=!0,this._move("nextPage",s);break;case n.UP:t=!0,this._keyEvent("previous",s);break;case n.DOWN:t=!0,this._keyEvent("next",s);break;case n.ENTER:case n.NUMPAD_ENTER:this.menu.active&&(t=!0,s.preventDefault(),this.menu.select(s));break;case n.TAB:this.menu.active&&this.menu.select(s);break;case n.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(s),s.preventDefault());break;default:i=!0,this._searchTimeout(s)}},keypress:function(a){if(t)return t=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&a.preventDefault(),undefined;if(!i){var s=e.ui.keyCode;switch(a.keyCode){case s.PAGE_UP:this._move("previousPage",a);break;case s.PAGE_DOWN:this._move("nextPage",a);break;case s.UP:this._keyEvent("previous",a);break;case s.DOWN:this._keyEvent("next",a)}}},input:function(e){return a?(a=!1,e.preventDefault(),undefined):(this._searchTimeout(e),undefined)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,undefined):(clearTimeout(this.searching),this.close(e),this._change(e),undefined)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().data("ui-menu"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(a){a.target===t.element[0]||a.target===i||e.contains(i,a.target)||t.close()})})},menufocus:function(t,i){if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)}),undefined;var a=i.item.data("ui-autocomplete-item");!1!==this._trigger("focus",t,{item:a})?t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(a.value):this.liveRegion.text(a.value)},menuselect:function(e,t){var i=t.item.data("ui-autocomplete-item"),a=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=a,this._delay(function(){this.previous=a,this.selectedItem=i})),!1!==this._trigger("select",e,{item:i})&&this._value(i.value),this.term=this._value(),this.close(e),this.selectedItem=i}}),this.liveRegion=e("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertBefore(this.element),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),"source"===e&&this._initSource(),"appendTo"===e&&this.menu.element.appendTo(this._appendTo()),"disabled"===e&&t&&this.xhr&&this.xhr.abort()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_initSource:function(){var t,i,a=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(i,a){a(e.ui.autocomplete.filter(t,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(t,s){a.xhr&&a.xhr.abort(),a.xhr=e.ajax({url:i,data:t,dataType:"json",success:function(e){s(e)},error:function(){s([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){return e=null!=e?e:this._value(),this.term=this._value(),e.length<this.options.minLength?this.close(t):this._trigger("search",t)!==!1?this._search(e):undefined},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var e=this,i=++t;return function(a){i===t&&e.__response(a),e.pending--,e.pending||e.element.removeClass("ui-autocomplete-loading")}},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return"string"==typeof t?{label:t,value:t}:e.extend({label:t.label||t.value,value:t.value||t.label},t)})},_suggest:function(t){var i=this.menu.element.empty();this._renderMenu(i,t),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,i){var a=this;e.each(i,function(e,i){a._renderItemData(t,i)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,i){return e("<li>").append(e("<a>").text(i.label)).appendTo(t)},_move:function(e,t){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)?(this._value(this.term),this.menu.blur(),undefined):(this.menu[e](t),undefined):(this.search(null,t),undefined)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(e,t),t.preventDefault())}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,i){var a=RegExp(e.ui.autocomplete.escapeRegex(i),"i");return e.grep(t,function(e){return a.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var t;this._superApply(arguments),this.options.disabled||this.cancelSearch||(t=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.text(t))}})})(jQuery);(function(e){var t,i,a,s,n="ui-button ui-widget ui-state-default ui-corner-all",r="ui-state-hover ui-state-active ",o="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",h=function(){var t=e(this);setTimeout(function(){t.find(":ui-button").button("refresh")},1)},l=function(t){var i=t.name,a=t.form,s=e([]);return i&&(i=i.replace(/'/g,"\\'"),s=a?e(a).find("[name='"+i+"']"):e("[name='"+i+"']",t.ownerDocument).filter(function(){return!this.form})),s};e.widget("ui.button",{version:"1.10.3",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,h),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var r=this,o=this.options,u="checkbox"===this.type||"radio"===this.type,d=u?"":"ui-state-active",c="ui-state-focus";null===o.label&&(o.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(n).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){o.disabled||this===t&&e(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){o.disabled||e(this).removeClass(d)}).bind("click"+this.eventNamespace,function(e){o.disabled&&(e.preventDefault(),e.stopImmediatePropagation())}),this.element.bind("focus"+this.eventNamespace,function(){r.buttonElement.addClass(c)}).bind("blur"+this.eventNamespace,function(){r.buttonElement.removeClass(c)}),u&&(this.element.bind("change"+this.eventNamespace,function(){s||r.refresh()}),this.buttonElement.bind("mousedown"+this.eventNamespace,function(e){o.disabled||(s=!1,i=e.pageX,a=e.pageY)}).bind("mouseup"+this.eventNamespace,function(e){o.disabled||(i!==e.pageX||a!==e.pageY)&&(s=!0)})),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return o.disabled||s?!1:undefined}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(o.disabled||s)return!1;e(this).addClass("ui-state-active"),r.buttonElement.attr("aria-pressed","true");var t=r.element[0];l(t).not(t).map(function(){return e(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return o.disabled?!1:(e(this).addClass("ui-state-active"),t=this,r.document.one("mouseup",function(){t=null}),undefined)}).bind("mouseup"+this.eventNamespace,function(){return o.disabled?!1:(e(this).removeClass("ui-state-active"),undefined)}).bind("keydown"+this.eventNamespace,function(t){return o.disabled?!1:((t.keyCode===e.ui.keyCode.SPACE||t.keyCode===e.ui.keyCode.ENTER)&&e(this).addClass("ui-state-active"),undefined)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){e(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(t){t.keyCode===e.ui.keyCode.SPACE&&e(this).click()})),this._setOption("disabled",o.disabled),this._resetButton()},_determineButtonType:function(){var e,t,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(e=this.element.parents().last(),t="label[for='"+this.element.attr("id")+"']",this.buttonElement=e.find(t),this.buttonElement.length||(e=e.length?e.siblings():this.element.siblings(),this.buttonElement=e.filter(t),this.buttonElement.length||(this.buttonElement=e.find(t))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(n+" "+r+" "+o).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(e,t){return this._super(e,t),"disabled"===e?(t?this.element.prop("disabled",!0):this.element.prop("disabled",!1),undefined):(this._resetButton(),undefined)},refresh:function(){var t=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOption("disabled",t),"radio"===this.type?l(this.element[0]).each(function(){e(this).is(":checked")?e(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):e(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),undefined;var t=this.buttonElement.removeClass(o),i=e("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(t.empty()).text(),a=this.options.icons,s=a.primary&&a.secondary,n=[];a.primary||a.secondary?(this.options.text&&n.push("ui-button-text-icon"+(s?"s":a.primary?"-primary":"-secondary")),a.primary&&t.prepend("<span class='ui-button-icon-primary ui-icon "+a.primary+"'></span>"),a.secondary&&t.append("<span class='ui-button-icon-secondary ui-icon "+a.secondary+"'></span>"),this.options.text||(n.push(s?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||t.attr("title",e.trim(i)))):n.push("ui-button-text-only"),t.addClass(n.join(" "))}}),e.widget("ui.buttonset",{version:"1.10.3",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(e,t){"disabled"===e&&this.buttons.button("option",e,t),this._super(e,t)},refresh:function(){var t="rtl"===this.element.css("direction");this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(t?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(t?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})})(jQuery);(function(e,t){function i(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},e.extend(this._defaults,this.regional[""]),this.dpDiv=a(e("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function a(t){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return t.delegate(i,"mouseout",function(){e(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",function(){e.datepicker._isDisabledDatepicker(n.inline?t.parent()[0]:n.input[0])||(e(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),e(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).addClass("ui-datepicker-next-hover"))})}function s(t,i){e.extend(t,i);for(var a in i)null==i[a]&&(t[a]=i[a]);return t}e.extend(e.ui,{datepicker:{version:"1.10.3"}});var n,r="datepicker";e.extend(i.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return s(this._defaults,e||{}),this},_attachDatepicker:function(t,i){var a,s,n;a=t.nodeName.toLowerCase(),s="div"===a||"span"===a,t.id||(this.uuid+=1,t.id="dp"+this.uuid),n=this._newInst(e(t),s),n.settings=e.extend({},i||{}),"input"===a?this._connectDatepicker(t,n):s&&this._inlineDatepicker(t,n)},_newInst:function(t,i){var s=t[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:t,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?a(e("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(t,i){var a=e(t);i.append=e([]),i.trigger=e([]),a.hasClass(this.markerClassName)||(this._attachments(a,i),a.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),e.data(t,r,i),i.settings.disabled&&this._disableDatepicker(t))},_attachments:function(t,i){var a,s,n,r=this._get(i,"appendText"),o=this._get(i,"isRTL");i.append&&i.append.remove(),r&&(i.append=e("<span class='"+this._appendClass+"'>"+r+"</span>"),t[o?"before":"after"](i.append)),t.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),a=this._get(i,"showOn"),("focus"===a||"both"===a)&&t.focus(this._showDatepicker),("button"===a||"both"===a)&&(s=this._get(i,"buttonText"),n=this._get(i,"buttonImage"),i.trigger=e(this._get(i,"buttonImageOnly")?e("<img/>").addClass(this._triggerClass).attr({src:n,alt:s,title:s}):e("<button type='button'></button>").addClass(this._triggerClass).html(n?e("<img/>").attr({src:n,alt:s,title:s}):s)),t[o?"before":"after"](i.trigger),i.trigger.click(function(){return e.datepicker._datepickerShowing&&e.datepicker._lastInput===t[0]?e.datepicker._hideDatepicker():e.datepicker._datepickerShowing&&e.datepicker._lastInput!==t[0]?(e.datepicker._hideDatepicker(),e.datepicker._showDatepicker(t[0])):e.datepicker._showDatepicker(t[0]),!1}))},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t,i,a,s,n=new Date(2009,11,20),r=this._get(e,"dateFormat");r.match(/[DM]/)&&(t=function(e){for(i=0,a=0,s=0;e.length>s;s++)e[s].length>i&&(i=e[s].length,a=s);return a},n.setMonth(t(this._get(e,r.match(/MM/)?"monthNames":"monthNamesShort"))),n.setDate(t(this._get(e,r.match(/DD/)?"dayNames":"dayNamesShort"))+20-n.getDay())),e.input.attr("size",this._formatDate(e,n).length)}},_inlineDatepicker:function(t,i){var a=e(t);a.hasClass(this.markerClassName)||(a.addClass(this.markerClassName).append(i.dpDiv),e.data(t,r,i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(t),i.dpDiv.css("display","block"))},_dialogDatepicker:function(t,i,a,n,o){var h,l,u,d,c,p=this._dialogInst;return p||(this.uuid+=1,h="dp"+this.uuid,this._dialogInput=e("<input type='text' id='"+h+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),e("body").append(this._dialogInput),p=this._dialogInst=this._newInst(this._dialogInput,!1),p.settings={},e.data(this._dialogInput[0],r,p)),s(p.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(p,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(l=document.documentElement.clientWidth,u=document.documentElement.clientHeight,d=document.documentElement.scrollLeft||document.body.scrollLeft,c=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[l/2-100+d,u/2-150+c]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),p.settings.onSelect=a,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),e.blockUI&&e.blockUI(this.dpDiv),e.data(this._dialogInput[0],r,p),this},_destroyDatepicker:function(t){var i,a=e(t),s=e.data(t,r);a.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),e.removeData(t,r),"input"===i?(s.append.remove(),s.trigger.remove(),a.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&a.removeClass(this.markerClassName).empty())},_enableDatepicker:function(t){var i,a,s=e(t),n=e.data(t,r);s.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!1,n.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(a=s.children("."+this._inlineClass),a.children().removeClass("ui-state-disabled"),a.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}))},_disableDatepicker:function(t){var i,a,s=e(t),n=e.data(t,r);s.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!0,n.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(a=s.children("."+this._inlineClass),a.children().addClass("ui-state-disabled"),a.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}),this._disabledInputs[this._disabledInputs.length]=t)},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;this._disabledInputs.length>t;t++)if(this._disabledInputs[t]===e)return!0;return!1},_getInst:function(t){try{return e.data(t,r)}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(i,a,n){var r,o,h,l,u=this._getInst(i);return 2===arguments.length&&"string"==typeof a?"defaults"===a?e.extend({},e.datepicker._defaults):u?"all"===a?e.extend({},u.settings):this._get(u,a):null:(r=a||{},"string"==typeof a&&(r={},r[a]=n),u&&(this._curInst===u&&this._hideDatepicker(),o=this._getDateDatepicker(i,!0),h=this._getMinMaxDate(u,"min"),l=this._getMinMaxDate(u,"max"),s(u.settings,r),null!==h&&r.dateFormat!==t&&r.minDate===t&&(u.settings.minDate=this._formatDate(u,h)),null!==l&&r.dateFormat!==t&&r.maxDate===t&&(u.settings.maxDate=this._formatDate(u,l)),"disabled"in r&&(r.disabled?this._disableDatepicker(i):this._enableDatepicker(i)),this._attachments(e(i),u),this._autoSize(u),this._setDate(u,o),this._updateAlternate(u),this._updateDatepicker(u)),t)},_changeDatepicker:function(e,t,i){this._optionDatepicker(e,t,i)},_refreshDatepicker:function(e){var t=this._getInst(e);t&&this._updateDatepicker(t)},_setDateDatepicker:function(e,t){var i=this._getInst(e);i&&(this._setDate(i,t),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(e,t){var i=this._getInst(e);return i&&!i.inline&&this._setDateFromField(i,t),i?this._getDate(i):null},_doKeyDown:function(t){var i,a,s,n=e.datepicker._getInst(t.target),r=!0,o=n.dpDiv.is(".ui-datepicker-rtl");if(n._keyEvent=!0,e.datepicker._datepickerShowing)switch(t.keyCode){case 9:e.datepicker._hideDatepicker(),r=!1;break;case 13:return s=e("td."+e.datepicker._dayOverClass+":not(."+e.datepicker._currentClass+")",n.dpDiv),s[0]&&e.datepicker._selectDay(t.target,n.selectedMonth,n.selectedYear,s[0]),i=e.datepicker._get(n,"onSelect"),i?(a=e.datepicker._formatDate(n),i.apply(n.input?n.input[0]:null,[a,n])):e.datepicker._hideDatepicker(),!1;case 27:e.datepicker._hideDatepicker();break;case 33:e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(n,"stepBigMonths"):-e.datepicker._get(n,"stepMonths"),"M");break;case 34:e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(n,"stepBigMonths"):+e.datepicker._get(n,"stepMonths"),"M");break;case 35:(t.ctrlKey||t.metaKey)&&e.datepicker._clearDate(t.target),r=t.ctrlKey||t.metaKey;break;case 36:(t.ctrlKey||t.metaKey)&&e.datepicker._gotoToday(t.target),r=t.ctrlKey||t.metaKey;break;case 37:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,o?1:-1,"D"),r=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(n,"stepBigMonths"):-e.datepicker._get(n,"stepMonths"),"M");break;case 38:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,-7,"D"),r=t.ctrlKey||t.metaKey;break;case 39:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,o?-1:1,"D"),r=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(n,"stepBigMonths"):+e.datepicker._get(n,"stepMonths"),"M");break;case 40:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,7,"D"),r=t.ctrlKey||t.metaKey;break;default:r=!1}else 36===t.keyCode&&t.ctrlKey?e.datepicker._showDatepicker(this):r=!1;r&&(t.preventDefault(),t.stopPropagation())},_doKeyPress:function(i){var a,s,n=e.datepicker._getInst(i.target);return e.datepicker._get(n,"constrainInput")?(a=e.datepicker._possibleChars(e.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==i.charCode?i.keyCode:i.charCode),i.ctrlKey||i.metaKey||" ">s||!a||a.indexOf(s)>-1):t},_doKeyUp:function(t){var i,a=e.datepicker._getInst(t.target);if(a.input.val()!==a.lastVal)try{i=e.datepicker.parseDate(e.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,e.datepicker._getFormatConfig(a)),i&&(e.datepicker._setDateFromField(a),e.datepicker._updateAlternate(a),e.datepicker._updateDatepicker(a))}catch(s){}return!0},_showDatepicker:function(t){if(t=t.target||t,"input"!==t.nodeName.toLowerCase()&&(t=e("input",t.parentNode)[0]),!e.datepicker._isDisabledDatepicker(t)&&e.datepicker._lastInput!==t){var i,a,n,r,o,h,l;i=e.datepicker._getInst(t),e.datepicker._curInst&&e.datepicker._curInst!==i&&(e.datepicker._curInst.dpDiv.stop(!0,!0),i&&e.datepicker._datepickerShowing&&e.datepicker._hideDatepicker(e.datepicker._curInst.input[0])),a=e.datepicker._get(i,"beforeShow"),n=a?a.apply(t,[t,i]):{},n!==!1&&(s(i.settings,n),i.lastVal=null,e.datepicker._lastInput=t,e.datepicker._setDateFromField(i),e.datepicker._inDialog&&(t.value=""),e.datepicker._pos||(e.datepicker._pos=e.datepicker._findPos(t),e.datepicker._pos[1]+=t.offsetHeight),r=!1,e(t).parents().each(function(){return r|="fixed"===e(this).css("position"),!r}),o={left:e.datepicker._pos[0],top:e.datepicker._pos[1]},e.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),e.datepicker._updateDatepicker(i),o=e.datepicker._checkOffset(i,o,r),i.dpDiv.css({position:e.datepicker._inDialog&&e.blockUI?"static":r?"fixed":"absolute",display:"none",left:o.left+"px",top:o.top+"px"}),i.inline||(h=e.datepicker._get(i,"showAnim"),l=e.datepicker._get(i,"duration"),i.dpDiv.zIndex(e(t).zIndex()+1),e.datepicker._datepickerShowing=!0,e.effects&&e.effects.effect[h]?i.dpDiv.show(h,e.datepicker._get(i,"showOptions"),l):i.dpDiv[h||"show"](h?l:null),e.datepicker._shouldFocusInput(i)&&i.input.focus(),e.datepicker._curInst=i))}},_updateDatepicker:function(t){this.maxRows=4,n=t,t.dpDiv.empty().append(this._generateHTML(t)),this._attachHandlers(t),t.dpDiv.find("."+this._dayOverClass+" a").mouseover();var i,a=this._getNumberOfMonths(t),s=a[1],r=17;t.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),s>1&&t.dpDiv.addClass("ui-datepicker-multi-"+s).css("width",r*s+"em"),t.dpDiv[(1!==a[0]||1!==a[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),t.dpDiv[(this._get(t,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),t===e.datepicker._curInst&&e.datepicker._datepickerShowing&&e.datepicker._shouldFocusInput(t)&&t.input.focus(),t.yearshtml&&(i=t.yearshtml,setTimeout(function(){i===t.yearshtml&&t.yearshtml&&t.dpDiv.find("select.ui-datepicker-year:first").replaceWith(t.yearshtml),i=t.yearshtml=null},0))},_shouldFocusInput:function(e){return e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&!e.input.is(":focus")},_checkOffset:function(t,i,a){var s=t.dpDiv.outerWidth(),n=t.dpDiv.outerHeight(),r=t.input?t.input.outerWidth():0,o=t.input?t.input.outerHeight():0,h=document.documentElement.clientWidth+(a?0:e(document).scrollLeft()),l=document.documentElement.clientHeight+(a?0:e(document).scrollTop());return i.left-=this._get(t,"isRTL")?s-r:0,i.left-=a&&i.left===t.input.offset().left?e(document).scrollLeft():0,i.top-=a&&i.top===t.input.offset().top+o?e(document).scrollTop():0,i.left-=Math.min(i.left,i.left+s>h&&h>s?Math.abs(i.left+s-h):0),i.top-=Math.min(i.top,i.top+n>l&&l>n?Math.abs(n+o):0),i},_findPos:function(t){for(var i,a=this._getInst(t),s=this._get(a,"isRTL");t&&("hidden"===t.type||1!==t.nodeType||e.expr.filters.hidden(t));)t=t[s?"previousSibling":"nextSibling"];return i=e(t).offset(),[i.left,i.top]},_hideDatepicker:function(t){var i,a,s,n,o=this._curInst;!o||t&&o!==e.data(t,r)||this._datepickerShowing&&(i=this._get(o,"showAnim"),a=this._get(o,"duration"),s=function(){e.datepicker._tidyDialog(o)},e.effects&&(e.effects.effect[i]||e.effects[i])?o.dpDiv.hide(i,e.datepicker._get(o,"showOptions"),a,s):o.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?a:null,s),i||s(),this._datepickerShowing=!1,n=this._get(o,"onClose"),n&&n.apply(o.input?o.input[0]:null,[o.input?o.input.val():"",o]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),e.blockUI&&(e.unblockUI(),e("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(t){if(e.datepicker._curInst){var i=e(t.target),a=e.datepicker._getInst(i[0]);(i[0].id!==e.datepicker._mainDivId&&0===i.parents("#"+e.datepicker._mainDivId).length&&!i.hasClass(e.datepicker.markerClassName)&&!i.closest("."+e.datepicker._triggerClass).length&&e.datepicker._datepickerShowing&&(!e.datepicker._inDialog||!e.blockUI)||i.hasClass(e.datepicker.markerClassName)&&e.datepicker._curInst!==a)&&e.datepicker._hideDatepicker()}},_adjustDate:function(t,i,a){var s=e(t),n=this._getInst(s[0]);this._isDisabledDatepicker(s[0])||(this._adjustInstDate(n,i+("M"===a?this._get(n,"showCurrentAtPos"):0),a),this._updateDatepicker(n))},_gotoToday:function(t){var i,a=e(t),s=this._getInst(a[0]);this._get(s,"gotoCurrent")&&s.currentDay?(s.selectedDay=s.currentDay,s.drawMonth=s.selectedMonth=s.currentMonth,s.drawYear=s.selectedYear=s.currentYear):(i=new Date,s.selectedDay=i.getDate(),s.drawMonth=s.selectedMonth=i.getMonth(),s.drawYear=s.selectedYear=i.getFullYear()),this._notifyChange(s),this._adjustDate(a)},_selectMonthYear:function(t,i,a){var s=e(t),n=this._getInst(s[0]);n["selected"+("M"===a?"Month":"Year")]=n["draw"+("M"===a?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(n),this._adjustDate(s)},_selectDay:function(t,i,a,s){var n,r=e(t);e(s).hasClass(this._unselectableClass)||this._isDisabledDatepicker(r[0])||(n=this._getInst(r[0]),n.selectedDay=n.currentDay=e("a",s).html(),n.selectedMonth=n.currentMonth=i,n.selectedYear=n.currentYear=a,this._selectDate(t,this._formatDate(n,n.currentDay,n.currentMonth,n.currentYear)))},_clearDate:function(t){var i=e(t);this._selectDate(i,"")},_selectDate:function(t,i){var a,s=e(t),n=this._getInst(s[0]);i=null!=i?i:this._formatDate(n),n.input&&n.input.val(i),this._updateAlternate(n),a=this._get(n,"onSelect"),a?a.apply(n.input?n.input[0]:null,[i,n]):n.input&&n.input.trigger("change"),n.inline?this._updateDatepicker(n):(this._hideDatepicker(),this._lastInput=n.input[0],"object"!=typeof n.input[0]&&n.input.focus(),this._lastInput=null)},_updateAlternate:function(t){var i,a,s,n=this._get(t,"altField");n&&(i=this._get(t,"altFormat")||this._get(t,"dateFormat"),a=this._getDate(t),s=this.formatDate(i,a,this._getFormatConfig(t)),e(n).each(function(){e(this).val(s)}))},noWeekends:function(e){var t=e.getDay();return[t>0&&6>t,""]},iso8601Week:function(e){var t,i=new Date(e.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),t=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((t-i)/864e5)/7)+1},parseDate:function(i,a,s){if(null==i||null==a)throw"Invalid arguments";if(a="object"==typeof a?""+a:a+"",""===a)return null;var n,r,o,h,l=0,u=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,d="string"!=typeof u?u:(new Date).getFullYear()%100+parseInt(u,10),c=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,p=(s?s.dayNames:null)||this._defaults.dayNames,m=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,g=-1,v=-1,y=-1,b=-1,_=!1,k=function(e){var t=i.length>n+1&&i.charAt(n+1)===e;return t&&n++,t},x=function(e){var t=k(e),i="@"===e?14:"!"===e?20:"y"===e&&t?4:"o"===e?3:2,s=RegExp("^\\d{1,"+i+"}"),n=a.substring(l).match(s);if(!n)throw"Missing number at position "+l;return l+=n[0].length,parseInt(n[0],10)},D=function(i,s,n){var r=-1,o=e.map(k(i)?n:s,function(e,t){return[[t,e]]}).sort(function(e,t){return-(e[1].length-t[1].length)});if(e.each(o,function(e,i){var s=i[1];return a.substr(l,s.length).toLowerCase()===s.toLowerCase()?(r=i[0],l+=s.length,!1):t}),-1!==r)return r+1;throw"Unknown name at position "+l},w=function(){if(a.charAt(l)!==i.charAt(n))throw"Unexpected literal at position "+l;l++};for(n=0;i.length>n;n++)if(_)"'"!==i.charAt(n)||k("'")?w():_=!1;else switch(i.charAt(n)){case"d":y=x("d");break;case"D":D("D",c,p);break;case"o":b=x("o");break;case"m":v=x("m");break;case"M":v=D("M",m,f);break;case"y":g=x("y");break;case"@":h=new Date(x("@")),g=h.getFullYear(),v=h.getMonth()+1,y=h.getDate();break;case"!":h=new Date((x("!")-this._ticksTo1970)/1e4),g=h.getFullYear(),v=h.getMonth()+1,y=h.getDate();break;case"'":k("'")?w():_=!0;break;default:w()}if(a.length>l&&(o=a.substr(l),!/^\s+/.test(o)))throw"Extra/unparsed characters found in date: "+o;if(-1===g?g=(new Date).getFullYear():100>g&&(g+=(new Date).getFullYear()-(new Date).getFullYear()%100+(d>=g?0:-100)),b>-1)for(v=1,y=b;;){if(r=this._getDaysInMonth(g,v-1),r>=y)break;v++,y-=r}if(h=this._daylightSavingAdjust(new Date(g,v-1,y)),h.getFullYear()!==g||h.getMonth()+1!==v||h.getDate()!==y)throw"Invalid date";return h},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(e,t,i){if(!t)return"";var a,s=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,n=(i?i.dayNames:null)||this._defaults.dayNames,r=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,o=(i?i.monthNames:null)||this._defaults.monthNames,h=function(t){var i=e.length>a+1&&e.charAt(a+1)===t;return i&&a++,i},l=function(e,t,i){var a=""+t;if(h(e))for(;i>a.length;)a="0"+a;return a},u=function(e,t,i,a){return h(e)?a[t]:i[t]},d="",c=!1;if(t)for(a=0;e.length>a;a++)if(c)"'"!==e.charAt(a)||h("'")?d+=e.charAt(a):c=!1;else switch(e.charAt(a)){case"d":d+=l("d",t.getDate(),2);break;case"D":d+=u("D",t.getDay(),s,n);break;case"o":d+=l("o",Math.round((new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()-new Date(t.getFullYear(),0,0).getTime())/864e5),3);break;case"m":d+=l("m",t.getMonth()+1,2);break;case"M":d+=u("M",t.getMonth(),r,o);break;case"y":d+=h("y")?t.getFullYear():(10>t.getYear()%100?"0":"")+t.getYear()%100;break;case"@":d+=t.getTime();break;case"!":d+=1e4*t.getTime()+this._ticksTo1970;break;case"'":h("'")?d+="'":c=!0;break;default:d+=e.charAt(a)}return d},_possibleChars:function(e){var t,i="",a=!1,s=function(i){var a=e.length>t+1&&e.charAt(t+1)===i;return a&&t++,a};for(t=0;e.length>t;t++)if(a)"'"!==e.charAt(t)||s("'")?i+=e.charAt(t):a=!1;else switch(e.charAt(t)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":s("'")?i+="'":a=!0;break;default:i+=e.charAt(t)}return i},_get:function(e,i){return e.settings[i]!==t?e.settings[i]:this._defaults[i]},_setDateFromField:function(e,t){if(e.input.val()!==e.lastVal){var i=this._get(e,"dateFormat"),a=e.lastVal=e.input?e.input.val():null,s=this._getDefaultDate(e),n=s,r=this._getFormatConfig(e);try{n=this.parseDate(i,a,r)||s}catch(o){a=t?"":a}e.selectedDay=n.getDate(),e.drawMonth=e.selectedMonth=n.getMonth(),e.drawYear=e.selectedYear=n.getFullYear(),e.currentDay=a?n.getDate():0,e.currentMonth=a?n.getMonth():0,e.currentYear=a?n.getFullYear():0,this._adjustInstDate(e)}},_getDefaultDate:function(e){return this._restrictMinMax(e,this._determineDate(e,this._get(e,"defaultDate"),new Date))},_determineDate:function(t,i,a){var s=function(e){var t=new Date;return t.setDate(t.getDate()+e),t},n=function(i){try{return e.datepicker.parseDate(e.datepicker._get(t,"dateFormat"),i,e.datepicker._getFormatConfig(t))}catch(a){}for(var s=(i.toLowerCase().match(/^c/)?e.datepicker._getDate(t):null)||new Date,n=s.getFullYear(),r=s.getMonth(),o=s.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":o+=parseInt(l[1],10);break;case"w":case"W":o+=7*parseInt(l[1],10);break;case"m":case"M":r+=parseInt(l[1],10),o=Math.min(o,e.datepicker._getDaysInMonth(n,r));break;case"y":case"Y":n+=parseInt(l[1],10),o=Math.min(o,e.datepicker._getDaysInMonth(n,r))}l=h.exec(i)}return new Date(n,r,o)},r=null==i||""===i?a:"string"==typeof i?n(i):"number"==typeof i?isNaN(i)?a:s(i):new Date(i.getTime());return r=r&&"Invalid Date"==""+r?a:r,r&&(r.setHours(0),r.setMinutes(0),r.setSeconds(0),r.setMilliseconds(0)),this._daylightSavingAdjust(r)},_daylightSavingAdjust:function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},_setDate:function(e,t,i){var a=!t,s=e.selectedMonth,n=e.selectedYear,r=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=r.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=r.getMonth(),e.drawYear=e.selectedYear=e.currentYear=r.getFullYear(),s===e.selectedMonth&&n===e.selectedYear||i||this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(a?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&""===e.input.val()?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(t){var i=this._get(t,"stepMonths"),a="#"+t.id.replace(/\\\\/g,"\\");t.dpDiv.find("[data-handler]").map(function(){var t={prev:function(){e.datepicker._adjustDate(a,-i,"M")},next:function(){e.datepicker._adjustDate(a,+i,"M")},hide:function(){e.datepicker._hideDatepicker()},today:function(){e.datepicker._gotoToday(a)},selectDay:function(){return e.datepicker._selectDay(a,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return e.datepicker._selectMonthYear(a,this,"M"),!1},selectYear:function(){return e.datepicker._selectMonthYear(a,this,"Y"),!1}};e(this).bind(this.getAttribute("data-event"),t[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t,i,a,s,n,r,o,h,l,u,d,c,p,m,f,g,v,y,b,_,k,x,D,w,T,M,S,N,C,A,P,I,F,j,H,E,z,L,O,R=new Date,W=this._daylightSavingAdjust(new Date(R.getFullYear(),R.getMonth(),R.getDate())),Y=this._get(e,"isRTL"),J=this._get(e,"showButtonPanel"),$=this._get(e,"hideIfNoPrevNext"),Q=this._get(e,"navigationAsDateFormat"),B=this._getNumberOfMonths(e),K=this._get(e,"showCurrentAtPos"),V=this._get(e,"stepMonths"),U=1!==B[0]||1!==B[1],G=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),q=this._getMinMaxDate(e,"min"),X=this._getMinMaxDate(e,"max"),Z=e.drawMonth-K,et=e.drawYear;if(0>Z&&(Z+=12,et--),X)for(t=this._daylightSavingAdjust(new Date(X.getFullYear(),X.getMonth()-B[0]*B[1]+1,X.getDate())),t=q&&q>t?q:t;this._daylightSavingAdjust(new Date(et,Z,1))>t;)Z--,0>Z&&(Z=11,et--);for(e.drawMonth=Z,e.drawYear=et,i=this._get(e,"prevText"),i=Q?this.formatDate(i,this._daylightSavingAdjust(new Date(et,Z-V,1)),this._getFormatConfig(e)):i,a=this._canAdjustMonth(e,-1,et,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":$?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",s=this._get(e,"nextText"),s=Q?this.formatDate(s,this._daylightSavingAdjust(new Date(et,Z+V,1)),this._getFormatConfig(e)):s,n=this._canAdjustMonth(e,1,et,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+s+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+s+"</span></a>":$?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+s+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+s+"</span></a>",r=this._get(e,"currentText"),o=this._get(e,"gotoCurrent")&&e.currentDay?G:W,r=Q?this.formatDate(r,o,this._getFormatConfig(e)):r,h=e.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(e,"closeText")+"</button>",l=J?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(e,o)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+r+"</button>":"")+(Y?"":h)+"</div>":"",u=parseInt(this._get(e,"firstDay"),10),u=isNaN(u)?0:u,d=this._get(e,"showWeek"),c=this._get(e,"dayNames"),p=this._get(e,"dayNamesMin"),m=this._get(e,"monthNames"),f=this._get(e,"monthNamesShort"),g=this._get(e,"beforeShowDay"),v=this._get(e,"showOtherMonths"),y=this._get(e,"selectOtherMonths"),b=this._getDefaultDate(e),_="",x=0;B[0]>x;x++){for(D="",this.maxRows=4,w=0;B[1]>w;w++){if(T=this._daylightSavingAdjust(new Date(et,Z,e.selectedDay)),M=" ui-corner-all",S="",U){if(S+="<div class='ui-datepicker-group",B[1]>1)switch(w){case 0:S+=" ui-datepicker-group-first",M=" ui-corner-"+(Y?"right":"left");break;case B[1]-1:S+=" ui-datepicker-group-last",M=" ui-corner-"+(Y?"left":"right");break;default:S+=" ui-datepicker-group-middle",M=""}S+="'>"}for(S+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+M+"'>"+(/all|left/.test(M)&&0===x?Y?n:a:"")+(/all|right/.test(M)&&0===x?Y?a:n:"")+this._generateMonthYearHeader(e,Z,et,q,X,x>0||w>0,m,f)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",N=d?"<th class='ui-datepicker-week-col'>"+this._get(e,"weekHeader")+"</th>":"",k=0;7>k;k++)C=(k+u)%7,N+="<th"+((k+u+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+c[C]+"'>"+p[C]+"</span></th>";for(S+=N+"</tr></thead><tbody>",A=this._getDaysInMonth(et,Z),et===e.selectedYear&&Z===e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,A)),P=(this._getFirstDayOfMonth(et,Z)-u+7)%7,I=Math.ceil((P+A)/7),F=U?this.maxRows>I?this.maxRows:I:I,this.maxRows=F,j=this._daylightSavingAdjust(new Date(et,Z,1-P)),H=0;F>H;H++){for(S+="<tr>",E=d?"<td class='ui-datepicker-week-col'>"+this._get(e,"calculateWeek")(j)+"</td>":"",k=0;7>k;k++)z=g?g.apply(e.input?e.input[0]:null,[j]):[!0,""],L=j.getMonth()!==Z,O=L&&!y||!z[0]||q&&q>j||X&&j>X,E+="<td class='"+((k+u+6)%7>=5?" ui-datepicker-week-end":"")+(L?" ui-datepicker-other-month":"")+(j.getTime()===T.getTime()&&Z===e.selectedMonth&&e._keyEvent||b.getTime()===j.getTime()&&b.getTime()===T.getTime()?" "+this._dayOverClass:"")+(O?" "+this._unselectableClass+" ui-state-disabled":"")+(L&&!v?"":" "+z[1]+(j.getTime()===G.getTime()?" "+this._currentClass:"")+(j.getTime()===W.getTime()?" ui-datepicker-today":""))+"'"+(L&&!v||!z[2]?"":" title='"+z[2].replace(/'/g,"&#39;")+"'")+(O?"":" data-handler='selectDay' data-event='click' data-month='"+j.getMonth()+"' data-year='"+j.getFullYear()+"'")+">"+(L&&!v?"&#xa0;":O?"<span class='ui-state-default'>"+j.getDate()+"</span>":"<a class='ui-state-default"+(j.getTime()===W.getTime()?" ui-state-highlight":"")+(j.getTime()===G.getTime()?" ui-state-active":"")+(L?" ui-priority-secondary":"")+"' href='#'>"+j.getDate()+"</a>")+"</td>",j.setDate(j.getDate()+1),j=this._daylightSavingAdjust(j);S+=E+"</tr>"}Z++,Z>11&&(Z=0,et++),S+="</tbody></table>"+(U?"</div>"+(B[0]>0&&w===B[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),D+=S}_+=D}return _+=l,e._keyEvent=!1,_},_generateMonthYearHeader:function(e,t,i,a,s,n,r,o){var h,l,u,d,c,p,m,f,g=this._get(e,"changeMonth"),v=this._get(e,"changeYear"),y=this._get(e,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",_="";if(n||!g)_+="<span class='ui-datepicker-month'>"+r[t]+"</span>";else{for(h=a&&a.getFullYear()===i,l=s&&s.getFullYear()===i,_+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",u=0;12>u;u++)(!h||u>=a.getMonth())&&(!l||s.getMonth()>=u)&&(_+="<option value='"+u+"'"+(u===t?" selected='selected'":"")+">"+o[u]+"</option>");_+="</select>"}if(y||(b+=_+(!n&&g&&v?"":"&#xa0;")),!e.yearshtml)if(e.yearshtml="",n||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(d=this._get(e,"yearRange").split(":"),c=(new Date).getFullYear(),p=function(e){var t=e.match(/c[+\-].*/)?i+parseInt(e.substring(1),10):e.match(/[+\-].*/)?c+parseInt(e,10):parseInt(e,10);
-return isNaN(t)?c:t},m=p(d[0]),f=Math.max(m,p(d[1]||"")),m=a?Math.max(m,a.getFullYear()):m,f=s?Math.min(f,s.getFullYear()):f,e.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";f>=m;m++)e.yearshtml+="<option value='"+m+"'"+(m===i?" selected='selected'":"")+">"+m+"</option>";e.yearshtml+="</select>",b+=e.yearshtml,e.yearshtml=null}return b+=this._get(e,"yearSuffix"),y&&(b+=(!n&&g&&v?"":"&#xa0;")+_),b+="</div>"},_adjustInstDate:function(e,t,i){var a=e.drawYear+("Y"===i?t:0),s=e.drawMonth+("M"===i?t:0),n=Math.min(e.selectedDay,this._getDaysInMonth(a,s))+("D"===i?t:0),r=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(a,s,n)));e.selectedDay=r.getDate(),e.drawMonth=e.selectedMonth=r.getMonth(),e.drawYear=e.selectedYear=r.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(e)},_restrictMinMax:function(e,t){var i=this._getMinMaxDate(e,"min"),a=this._getMinMaxDate(e,"max"),s=i&&i>t?i:t;return a&&s>a?a:s},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return null==t?[1,1]:"number"==typeof t?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return new Date(e,t,1).getDay()},_canAdjustMonth:function(e,t,i,a){var s=this._getNumberOfMonths(e),n=this._daylightSavingAdjust(new Date(i,a+(0>t?t:s[0]*s[1]),1));return 0>t&&n.setDate(this._getDaysInMonth(n.getFullYear(),n.getMonth())),this._isInRange(e,n)},_isInRange:function(e,t){var i,a,s=this._getMinMaxDate(e,"min"),n=this._getMinMaxDate(e,"max"),r=null,o=null,h=this._get(e,"yearRange");return h&&(i=h.split(":"),a=(new Date).getFullYear(),r=parseInt(i[0],10),o=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(r+=a),i[1].match(/[+\-].*/)&&(o+=a)),(!s||t.getTime()>=s.getTime())&&(!n||t.getTime()<=n.getTime())&&(!r||t.getFullYear()>=r)&&(!o||o>=t.getFullYear())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t="string"!=typeof t?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,i,a){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var s=t?"object"==typeof t?t:this._daylightSavingAdjust(new Date(a,i,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),s,this._getFormatConfig(e))}}),e.fn.datepicker=function(t){if(!this.length)return this;e.datepicker.initialized||(e(document).mousedown(e.datepicker._checkExternalClick),e.datepicker.initialized=!0),0===e("#"+e.datepicker._mainDivId).length&&e("body").append(e.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof t||"isDisabled"!==t&&"getDate"!==t&&"widget"!==t?"option"===t&&2===arguments.length&&"string"==typeof arguments[1]?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof t?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this].concat(i)):e.datepicker._attachDatepicker(this,t)}):e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i))},e.datepicker=new i,e.datepicker.initialized=!1,e.datepicker.uuid=(new Date).getTime(),e.datepicker.version="1.10.3"})(jQuery);(function(e){var t={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.10.3",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var i=e(this).css(t).offset().top;0>i&&e(this).css("top",t.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&e.fn.draggable&&this._makeDraggable(),this.options.resizable&&e.fn.resizable&&this._makeResizable(),this._isOpen=!1},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var t=this.options.appendTo;return t&&(t.jquery||t.nodeType)?e(t):this.document.find(t||"body").eq(0)},_destroy:function(){var e,t=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},disable:e.noop,enable:e.noop,close:function(t){var i=this;this._isOpen&&this._trigger("beforeClose",t)!==!1&&(this._isOpen=!1,this._destroyOverlay(),this.opener.filter(":focusable").focus().length||e(this.document[0].activeElement).blur(),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",t)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,t){var i=!!this.uiDialog.nextAll(":visible").insertBefore(this.uiDialog).length;return i&&!t&&this._trigger("focus",e),i},open:function(){var t=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),undefined):(this._isOpen=!0,this.opener=e(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")}),this._trigger("open"),undefined)},_focusTabbable:function(){var e=this.element.find("[autofocus]");e.length||(e=this.element.find(":tabbable")),e.length||(e=this.uiDialogButtonPane.find(":tabbable")),e.length||(e=this.uiDialogTitlebarClose.filter(":tabbable")),e.length||(e=this.uiDialog),e.eq(0).focus()},_keepFocus:function(t){function i(){var t=this.document[0].activeElement,i=this.uiDialog[0]===t||e.contains(this.uiDialog[0],t);i||this._focusTabbable()}t.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=e("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(t){if(this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===e.ui.keyCode.ESCAPE)return t.preventDefault(),this.close(t),undefined;if(t.keyCode===e.ui.keyCode.TAB){var i=this.uiDialog.find(":tabbable"),a=i.filter(":first"),s=i.filter(":last");t.target!==s[0]&&t.target!==this.uiDialog[0]||t.shiftKey?t.target!==a[0]&&t.target!==this.uiDialog[0]||!t.shiftKey||(s.focus(1),t.preventDefault()):(a.focus(1),t.preventDefault())}},mousedown:function(e){this._moveToTop(e)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var t;this.uiDialogTitlebar=e("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(t){e(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=e("<button></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(e){e.preventDefault(),this.close(e)}}),t=e("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(t),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(e){this.options.title||e.html("&#160;"),e.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=e("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=e("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var t=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),e.isEmptyObject(i)||e.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),undefined):(e.each(i,function(i,a){var s,n;a=e.isFunction(a)?{click:a,text:i}:a,a=e.extend({type:"button"},a),s=a.click,a.click=function(){s.apply(t.element[0],arguments)},n={icons:a.icons,text:a.showText},delete a.icons,delete a.showText,e("<button></button>",a).button(n).appendTo(t.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),undefined)},_makeDraggable:function(){function t(e){return{position:e.position,offset:e.offset}}var i=this,a=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(a,s){e(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",a,t(s))},drag:function(e,a){i._trigger("drag",e,t(a))},stop:function(s,n){a.position=[n.position.left-i.document.scrollLeft(),n.position.top-i.document.scrollTop()],e(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",s,t(n))}})},_makeResizable:function(){function t(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}var i=this,a=this.options,s=a.resizable,n=this.uiDialog.css("position"),r="string"==typeof s?s:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:a.maxWidth,maxHeight:a.maxHeight,minWidth:a.minWidth,minHeight:this._minHeight(),handles:r,start:function(a,s){e(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",a,t(s))},resize:function(e,a){i._trigger("resize",e,t(a))},stop:function(s,n){a.height=e(this).height(),a.width=e(this).width(),e(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",s,t(n))}}).css("position",n)},_minHeight:function(){var e=this.options;return"auto"===e.height?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(){var e=this.uiDialog.is(":visible");e||this.uiDialog.show(),this.uiDialog.position(this.options.position),e||this.uiDialog.hide()},_setOptions:function(a){var s=this,n=!1,r={};e.each(a,function(e,a){s._setOption(e,a),e in t&&(n=!0),e in i&&(r[e]=a)}),n&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",r)},_setOption:function(e,t){var i,a,s=this.uiDialog;"dialogClass"===e&&s.removeClass(this.options.dialogClass).addClass(t),"disabled"!==e&&(this._super(e,t),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:""+t}),"draggable"===e&&(i=s.is(":data(ui-draggable)"),i&&!t&&s.draggable("destroy"),!i&&t&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(a=s.is(":data(ui-resizable)"),a&&!t&&s.resizable("destroy"),a&&"string"==typeof t&&s.resizable("option","handles",t),a||t===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var e,t,i,a=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),a.minWidth>a.width&&(a.width=a.minWidth),e=this.uiDialog.css({height:"auto",width:a.width}).outerHeight(),t=Math.max(0,a.minHeight-e),i="number"==typeof a.maxHeight?Math.max(0,a.maxHeight-e):"none","auto"===a.height?this.element.css({minHeight:t,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,a.height-e)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=e(this);return e("<div>").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return e(t.target).closest(".ui-dialog").length?!0:!!e(t.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var t=this,i=this.widgetFullName;e.ui.dialog.overlayInstances||this._delay(function(){e.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(a){t._allowInteraction(a)||(a.preventDefault(),e(".ui-dialog:visible:last .ui-dialog-content").data(i)._focusTabbable())})}),this.overlay=e("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),e.ui.dialog.overlayInstances++}},_destroyOverlay:function(){this.options.modal&&this.overlay&&(e.ui.dialog.overlayInstances--,e.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),e.ui.dialog.overlayInstances=0,e.uiBackCompat!==!1&&e.widget("ui.dialog",e.ui.dialog,{_position:function(){var t,i=this.options.position,a=[],s=[0,0];i?(("string"==typeof i||"object"==typeof i&&"0"in i)&&(a=i.split?i.split(" "):[i[0],i[1]],1===a.length&&(a[1]=a[0]),e.each(["left","top"],function(e,t){+a[e]===a[e]&&(s[e]=a[e],a[e]=t)}),i={my:a[0]+(0>s[0]?s[0]:"+"+s[0])+" "+a[1]+(0>s[1]?s[1]:"+"+s[1]),at:a.join(" ")}),i=e.extend({},e.ui.dialog.prototype.options.position,i)):i=e.ui.dialog.prototype.options.position,t=this.uiDialog.is(":visible"),t||this.uiDialog.show(),this.uiDialog.position(i),t||this.uiDialog.hide()}})})(jQuery);(function(e){e.widget("ui.menu",{version:"1.10.3",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,e.proxy(function(e){this.options.disabled&&e.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(e){e.preventDefault()},"click .ui-state-disabled > a":function(e){e.preventDefault()},"click .ui-menu-item:has(a)":function(t){var i=e(t.target).closest(".ui-menu-item");!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.mouseHandled=!0,this.select(t),i.has(".ui-menu").length?this.expand(t):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var i=e(t.currentTarget);i.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(t,i)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var i=this.active||this.element.children(".ui-menu-item").eq(0);t||this.focus(e,i)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){e(t.target).closest(".ui-menu").length||this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){function i(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var s,a,n,r,o,h=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:h=!1,a=this.previousFilter||"",n=String.fromCharCode(t.keyCode),r=!1,clearTimeout(this.filterTimer),n===a?r=!0:n=a+n,o=RegExp("^"+i(n),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())}),s=r&&-1!==s.index(this.active.next())?this.active.nextAll(".ui-menu-item"):s,s.length||(n=String.fromCharCode(t.keyCode),o=RegExp("^"+i(n),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())})),s.length?(this.focus(t,s),s.length>1?(this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}h&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(e):this.select(e))},refresh:function(){var t,i=this.options.icons.submenu,s=this.element.find(this.options.menus);s.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),s=t.prev("a"),a=e("<span>").addClass("ui-menu-icon ui-icon "+i).data("ui-menu-submenu-carat",!0);s.attr("aria-haspopup","true").prepend(a),t.attr("aria-labelledby",s.attr("id"))}),t=s.add(this.element),t.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),t.children(":not(.ui-menu-item)").each(function(){var t=e(this);/[^\-\u2014\u2013\s]/.test(t.text())||t.addClass("ui-widget-content ui-menu-divider")}),t.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(e,t){"icons"===e&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(t.submenu),this._super(e,t)},focus:function(e,t){var i,s;this.blur(e,e&&"focus"===e.type),this._scrollIntoView(t),this.active=t.first(),s=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),e&&"keydown"===e.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=t.children(".ui-menu"),i.length&&/^mouse/.test(e.type)&&this._startOpening(i),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var i,s,a,n,r,o;this._hasScroll()&&(i=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,a=t.offset().top-this.activeMenu.offset().top-i-s,n=this.activeMenu.scrollTop(),r=this.activeMenu.height(),o=t.height(),0>a?this.activeMenu.scrollTop(n+a):a+o>r&&this.activeMenu.scrollTop(n+a-r+o))},blur:function(e,t){t||clearTimeout(this.timer),this.active&&(this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active}))},_startOpening:function(e){clearTimeout(this.timer),"true"===e.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(e)},this.delay))},_open:function(t){var i=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(t,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(t),this.activeMenu=s},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,i){var s;this.active&&(s="first"===e||"last"===e?this.active["first"===e?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[e+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.children(".ui-menu-item")[t]()),this.focus(i,s)},nextPage:function(t){var i,s,a;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,a=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=e(this),0>i.offset().top-s-a}),this.focus(t,i)):this.focus(t,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())),undefined):(this.next(t),undefined)},previousPage:function(t){var i,s,a;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,a=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=e(this),i.offset().top-s+a>0}),this.focus(t,i)):this.focus(t,this.activeMenu.children(".ui-menu-item").first())),undefined):(this.next(t),undefined)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||e(t.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,i)}})})(jQuery);(function(e,t){e.widget("ui.progressbar",{version:"1.10.3",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=e("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return e===t?this.options.value:(this.options.value=this._constrainedValue(e),this._refreshValue(),t)},_constrainedValue:function(e){return e===t&&(e=this.options.value),this.indeterminate=e===!1,"number"!=typeof e&&(e=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,e))},_setOptions:function(e){var t=e.value;delete e.value,this._super(e),this.options.value=this._constrainedValue(t),this._refreshValue()},_setOption:function(e,t){"max"===e&&(t=Math.max(this.min,t)),this._super(e,t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var t=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||t>this.min).toggleClass("ui-corner-right",t===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=e("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":t}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==t&&(this.oldValue=t,this._trigger("change")),t===this.options.max&&this._trigger("complete")}})})(jQuery);(function(e){var t=5;e.widget("ui.slider",e.ui.mouse,{version:"1.10.3",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var t,i,s=this.options,a=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),n="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",r=[];for(i=s.values&&s.values.length||1,a.length>i&&(a.slice(i).remove(),a=a.slice(0,i)),t=a.length;i>t;t++)r.push(n);this.handles=a.add(e(r.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(t){e(this).data("ui-slider-handle-index",t)})},_createRange:function(){var t=this.options,i="";t.range?(t.range===!0&&(t.values?t.values.length&&2!==t.values.length?t.values=[t.values[0],t.values[0]]:e.isArray(t.values)&&(t.values=t.values.slice(0)):t.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=e("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===t.range||"max"===t.range?" ui-slider-range-"+t.range:""))):this.range=e([])},_setupEvents:function(){var e=this.handles.add(this.range).filter("a");this._off(e),this._on(e,this._handleEvents),this._hoverable(e),this._focusable(e)},_destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(t){var i,s,a,n,r,o,h,l,u=this,c=this.options;return c.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:t.pageX,y:t.pageY},s=this._normValueFromMouse(i),a=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var i=Math.abs(s-u.values(t));(a>i||a===i&&(t===u._lastChangedValue||u.values(t)===c.min))&&(a=i,n=e(this),r=t)}),o=this._start(t,r),o===!1?!1:(this._mouseSliding=!0,this._handleIndex=r,n.addClass("ui-state-active").focus(),h=n.offset(),l=!e(t.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:t.pageX-h.left-n.width()/2,top:t.pageY-h.top-n.height()/2-(parseInt(n.css("borderTopWidth"),10)||0)-(parseInt(n.css("borderBottomWidth"),10)||0)+(parseInt(n.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,r,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},i=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,i),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,i,s,a,n;return"horizontal"===this.orientation?(t=this.elementSize.width,i=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,i=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/t,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),a=this._valueMax()-this._valueMin(),n=this._valueMin()+s*a,this._trimAlignValue(n)},_start:function(e,t){var i={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("start",e,i)},_slide:function(e,t,i){var s,a,n;this.options.values&&this.options.values.length?(s=this.values(t?0:1),2===this.options.values.length&&this.options.range===!0&&(0===t&&i>s||1===t&&s>i)&&(i=s),i!==this.values(t)&&(a=this.values(),a[t]=i,n=this._trigger("slide",e,{handle:this.handles[t],value:i,values:a}),s=this.values(t?0:1),n!==!1&&this.values(t,i,!0))):i!==this.value()&&(n=this._trigger("slide",e,{handle:this.handles[t],value:i}),n!==!1&&this.value(i))},_stop:function(e,t){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("stop",e,i)},_change:function(e,t){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._lastChangedValue=t,this._trigger("change",e,i)}},value:function(e){return arguments.length?(this.options.value=this._trimAlignValue(e),this._refreshValue(),this._change(null,0),undefined):this._value()},values:function(t,i){var s,a,n;if(arguments.length>1)return this.options.values[t]=this._trimAlignValue(i),this._refreshValue(),this._change(null,t),undefined;if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();for(s=this.options.values,a=arguments[0],n=0;s.length>n;n+=1)s[n]=this._trimAlignValue(a[n]),this._change(null,n);this._refreshValue()},_setOption:function(t,i){var s,a=0;switch("range"===t&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),e.isArray(this.options.values)&&(a=this.options.values.length),e.Widget.prototype._setOption.apply(this,arguments),t){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;a>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var e=this.options.value;return e=this._trimAlignValue(e)},_values:function(e){var t,i,s;if(arguments.length)return t=this.options.values[e],t=this._trimAlignValue(t);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(e){if(this._valueMin()>=e)return this._valueMin();if(e>=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,i=(e-this._valueMin())%t,s=e-i;return 2*Math.abs(i)>=t&&(s+=i>0?t:-t),parseFloat(s.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,i,s,a,n,r=this.options.range,o=this.options,h=this,l=this._animateOff?!1:o.animate,u={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),u["horizontal"===h.orientation?"left":"bottom"]=i+"%",e(this).stop(1,1)[l?"animate":"css"](u,o.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},o.animate),1===s&&h.range[l?"animate":"css"]({width:i-t+"%"},{queue:!1,duration:o.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},o.animate),1===s&&h.range[l?"animate":"css"]({height:i-t+"%"},{queue:!1,duration:o.animate}))),t=i}):(s=this.value(),a=this._valueMin(),n=this._valueMax(),i=n!==a?100*((s-a)/(n-a)):0,u["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](u,o.animate),"min"===r&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},o.animate),"max"===r&&"horizontal"===this.orientation&&this.range[l?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:o.animate}),"min"===r&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},o.animate),"max"===r&&"vertical"===this.orientation&&this.range[l?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:o.animate}))},_handleEvents:{keydown:function(i){var s,a,n,r,o=e(i.target).data("ui-slider-handle-index");switch(i.keyCode){case e.ui.keyCode.HOME:case e.ui.keyCode.END:case e.ui.keyCode.PAGE_UP:case e.ui.keyCode.PAGE_DOWN:case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(i.preventDefault(),!this._keySliding&&(this._keySliding=!0,e(i.target).addClass("ui-state-active"),s=this._start(i,o),s===!1))return}switch(r=this.options.step,a=n=this.options.values&&this.options.values.length?this.values(o):this.value(),i.keyCode){case e.ui.keyCode.HOME:n=this._valueMin();break;case e.ui.keyCode.END:n=this._valueMax();break;case e.ui.keyCode.PAGE_UP:n=this._trimAlignValue(a+(this._valueMax()-this._valueMin())/t);break;case e.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(a-(this._valueMax()-this._valueMin())/t);break;case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:if(a===this._valueMax())return;n=this._trimAlignValue(a+r);break;case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(a===this._valueMin())return;n=this._trimAlignValue(a-r)}this._slide(i,o,n)},click:function(e){e.preventDefault()},keyup:function(t){var i=e(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,i),this._change(t,i),e(t.target).removeClass("ui-state-active"))}}})})(jQuery);(function(e){function t(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.widget("ui.spinner",{version:"1.10.3",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},i=this.element;return e.each(["min","max","step"],function(e,s){var a=i.attr(s);void 0!==a&&a.length&&(t[s]=a)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e),void 0)},mousewheel:function(e,t){if(t){if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()}},"mousedown .ui-spinner-button":function(t){function i(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(t)!==!1&&this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){return e(t.currentTarget).hasClass("ui-state-active")?this._start(t)===!1?!1:(this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*e.height())&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var i=this.options,s=e.ui.keyCode;switch(t.keyCode){case s.UP:return this._repeat(null,1,t),!0;case s.DOWN:return this._repeat(null,-1,t),!0;case s.PAGE_UP:return this._repeat(null,i.page,t),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,t),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(e){return this.spinning||this._trigger("start",e)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(e,t,i){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,i)},e),this._spin(t*this.options.step,i)},_spin:function(e,t){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+e*this._increment(this.counter)),this.spinning&&this._trigger("spin",t,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(t){var i=this.options.incremental;return i?e.isFunction(i)?i(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return null!==this.options.min&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=""+e,i=t.indexOf(".");return-1===i?0:t.length-i-1},_adjustValue:function(e){var t,i,s=this.options;return t=null!==s.min?s.min:0,i=e-t,i=Math.round(i/s.step)*s.step,e=t+i,e=parseFloat(e.toFixed(this._precision())),null!==s.max&&e>s.max?s.max:null!==s.min&&s.min>e?s.min:e},_stop:function(e){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",e))},_setOption:function(e,t){if("culture"===e||"numberFormat"===e){var i=this._parse(this.element.val());return this.options[e]=t,this.element.val(this._format(i)),void 0}("max"===e||"min"===e||"step"===e)&&"string"==typeof t&&(t=this._parse(t)),"icons"===e&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(t.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(t.down)),this._super(e,t),"disabled"===e&&(t?(this.element.prop("disabled",!0),this.buttons.button("disable")):(this.element.prop("disabled",!1),this.buttons.button("enable")))},_setOptions:t(function(e){this._super(e),this._value(this.element.val())}),_parse:function(e){return"string"==typeof e&&""!==e&&(e=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(e,10,this.options.culture):+e),""===e||isNaN(e)?null:e},_format:function(e){return""===e?"":window.Globalize&&this.options.numberFormat?Globalize.format(e,this.options.numberFormat,this.options.culture):e},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},_value:function(e,t){var i;""!==e&&(i=this._parse(e),null!==i&&(t||(i=this._adjustValue(i)),e=this._format(i))),this.element.val(e),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:t(function(e){this._stepUp(e)}),_stepUp:function(e){this._start()&&(this._spin((e||1)*this.options.step),this._stop())},stepDown:t(function(e){this._stepDown(e)}),_stepDown:function(e){this._start()&&(this._spin((e||1)*-this.options.step),this._stop())},pageUp:t(function(e){this._stepUp((e||1)*this.options.page)}),pageDown:t(function(e){this._stepDown((e||1)*this.options.page)}),value:function(e){return arguments.length?(t(this._value).call(this,e),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}})})(jQuery);(function(e,t){function i(){return++a}function s(e){return e.hash.length>1&&decodeURIComponent(e.href.replace(n,""))===decodeURIComponent(location.href.replace(n,""))}var a=0,n=/#.*$/;e.widget("ui.tabs",{version:"1.10.3",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),e.isArray(i.disabled)&&(i.disabled=e.unique(i.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):e(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var i=this.options.active,s=this.options.collapsible,a=location.hash.substring(1);return null===i&&(a&&this.tabs.each(function(s,n){return e(n).attr("aria-controls")===a?(i=s,!1):t}),null===i&&(i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===i||-1===i)&&(i=this.tabs.length?0:!1)),i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),-1===i&&(i=s?!1:0)),!s&&i===!1&&this.anchors.length&&(i=0),i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(i){var s=e(this.document[0].activeElement).closest("li"),a=this.tabs.index(s),n=!0;if(!this._handlePageNav(i)){switch(i.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:a++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:n=!1,a--;break;case e.ui.keyCode.END:a=this.anchors.length-1;break;case e.ui.keyCode.HOME:a=0;break;case e.ui.keyCode.SPACE:return i.preventDefault(),clearTimeout(this.activating),this._activate(a),t;case e.ui.keyCode.ENTER:return i.preventDefault(),clearTimeout(this.activating),this._activate(a===this.options.active?!1:a),t;default:return}i.preventDefault(),clearTimeout(this.activating),a=this._focusNextTab(a,n),i.ctrlKey||(s.attr("aria-selected","false"),this.tabs.eq(a).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",a)},this.delay))}},_panelKeydown:function(t){this._handlePageNav(t)||t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(i){return i.altKey&&i.keyCode===e.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):i.altKey&&i.keyCode===e.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):t},_findNextTab:function(t,i){function s(){return t>a&&(t=0),0>t&&(t=a),t}for(var a=this.tabs.length-1;-1!==e.inArray(s(),this.options.disabled);)t=i?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,i){return"active"===e?(this._activate(i),t):"disabled"===e?(this._setupDisabled(i),t):(this._super(e,i),"collapsible"===e&&(this.element.toggleClass("ui-tabs-collapsible",i),i||this.options.active!==!1||this._activate(0)),"event"===e&&this._setupEvents(i),"heightStyle"===e&&this._setupHeightStyle(i),t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,i=this.tablist.children(":has(a[href])");t.disabled=e.map(i.filter(".ui-state-disabled"),function(e){return i.index(e)}),this._processTabs(),t.active!==!1&&this.anchors.length?this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=e()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(i,a){var n,r,o,h=e(a).uniqueId().attr("id"),l=e(a).closest("li"),u=l.attr("aria-controls");s(a)?(n=a.hash,r=t.element.find(t._sanitizeSelector(n))):(o=t._tabId(l),n="#"+o,r=t.element.find(n),r.length||(r=t._createPanel(o),r.insertAfter(t.panels[i-1]||t.tablist)),r.attr("aria-live","polite")),r.length&&(t.panels=t.panels.add(r)),u&&l.data("ui-tabs-aria-controls",u),l.attr({"aria-controls":n.substring(1),"aria-labelledby":h}),r.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("<div>").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var i,s=0;i=this.tabs[s];s++)t===!0||-1!==e.inArray(s,t)?e(i).addClass("ui-state-disabled").attr("aria-disabled","true"):e(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var i={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,s=this.element.parent();"fill"===t?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=e(this),s=t.css("position");"absolute"!==s&&"fixed"!==s&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,e(this).height("").height())}).height(i))},_eventHandler:function(t){var i=this.options,s=this.active,a=e(t.currentTarget),n=a.closest("li"),r=n[0]===s[0],o=r&&i.collapsible,h=o?e():this._getPanelForTab(n),l=s.length?this._getPanelForTab(s):e(),u={oldTab:s,oldPanel:l,newTab:o?e():n,newPanel:h};t.preventDefault(),n.hasClass("ui-state-disabled")||n.hasClass("ui-tabs-loading")||this.running||r&&!i.collapsible||this._trigger("beforeActivate",t,u)===!1||(i.active=o?!1:this.tabs.index(n),this.active=r?e():n,this.xhr&&this.xhr.abort(),l.length||h.length||e.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(n),t),this._toggle(t,u))},_toggle:function(t,i){function s(){n.running=!1,n._trigger("activate",t,i)}function a(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&n.options.show?n._show(r,n.options.show,s):(r.show(),s())}var n=this,r=i.newPanel,o=i.oldPanel;this.running=!0,o.length&&this.options.hide?this._hide(o,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),a()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),o.hide(),a()),o.attr({"aria-expanded":"false","aria-hidden":"true"}),i.oldTab.attr("aria-selected","false"),r.length&&o.length?i.oldTab.attr("tabIndex",-1):r.length&&this.tabs.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),r.attr({"aria-expanded":"true","aria-hidden":"false"}),i.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var i,s=this._findActive(t);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),i=t.data("ui-tabs-aria-controls");i?t.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var s=this.options.disabled;s!==!1&&(i===t?s=!1:(i=this._getIndex(i),s=e.isArray(s)?e.map(s,function(e){return e!==i?e:null}):e.map(this.tabs,function(e,t){return t!==i?t:null})),this._setupDisabled(s))},disable:function(i){var s=this.options.disabled;if(s!==!0){if(i===t)s=!0;else{if(i=this._getIndex(i),-1!==e.inArray(i,s))return;s=e.isArray(s)?e.merge([i],s).sort():[i]}this._setupDisabled(s)}},load:function(t,i){t=this._getIndex(t);var a=this,n=this.tabs.eq(t),r=n.find(".ui-tabs-anchor"),o=this._getPanelForTab(n),h={tab:n,panel:o};s(r[0])||(this.xhr=e.ajax(this._ajaxSettings(r,i,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(n.addClass("ui-tabs-loading"),o.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){o.html(e),a._trigger("load",i,h)},1)}).complete(function(e,t){setTimeout(function(){"abort"===t&&a.panels.stop(!1,!0),n.removeClass("ui-tabs-loading"),o.removeAttr("aria-busy"),e===a.xhr&&delete a.xhr},1)})))},_ajaxSettings:function(t,i,s){var a=this;return{url:t.attr("href"),beforeSend:function(t,n){return a._trigger("beforeLoad",i,e.extend({jqXHR:t,ajaxSettings:n},s))}}},_getPanelForTab:function(t){var i=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})})(jQuery);(function(e){function t(t,i){var s=(t.attr("aria-describedby")||"").split(/\s+/);s.push(i),t.data("ui-tooltip-id",i).attr("aria-describedby",e.trim(s.join(" ")))}function i(t){var i=t.data("ui-tooltip-id"),s=(t.attr("aria-describedby")||"").split(/\s+/),a=e.inArray(i,s);-1!==a&&s.splice(a,1),t.removeData("ui-tooltip-id"),s=e.trim(s.join(" ")),s?t.attr("aria-describedby",s):t.removeAttr("aria-describedby")}var s=0;e.widget("ui.tooltip",{version:"1.10.3",options:{content:function(){var t=e(this).attr("title")||"";return e("<a>").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(t,i){var s=this;return"disabled"===t?(this[i?"_disable":"_enable"](),this.options[t]=i,void 0):(this._super(t,i),"content"===t&&e.each(this.tooltips,function(e,t){s._updateContent(t)}),void 0)},_disable:function(){var t=this;e.each(this.tooltips,function(i,s){var a=e.Event("blur");a.target=a.currentTarget=s[0],t.close(a,!0)}),this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var i=this,s=e(t?t.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),t&&"mouseover"===t.type&&s.parents().each(function(){var t,s=e(this);s.data("ui-tooltip-open")&&(t=e.Event("blur"),t.target=t.currentTarget=this,i.close(t,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,t))},_updateContent:function(e,t){var i,s=this.options.content,a=this,n=t?t.type:null;return"string"==typeof s?this._open(t,e,s):(i=s.call(e[0],function(i){e.data("ui-tooltip-open")&&a._delay(function(){t&&(t.type=n),this._open(t,e,i)})}),i&&this._open(t,e,i),void 0)},_open:function(i,s,a){function n(e){l.of=e,r.is(":hidden")||r.position(l)}var r,o,h,l=e.extend({},this.options.position);if(a){if(r=this._find(s),r.length)return r.find(".ui-tooltip-content").html(a),void 0;s.is("[title]")&&(i&&"mouseover"===i.type?s.attr("title",""):s.removeAttr("title")),r=this._tooltip(s),t(s,r.attr("id")),r.find(".ui-tooltip-content").html(a),this.options.track&&i&&/^mouse/.test(i.type)?(this._on(this.document,{mousemove:n}),n(i)):r.position(e.extend({of:s},this.options.position)),r.hide(),this._show(r,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){r.is(":visible")&&(n(l.of),clearInterval(h))},e.fx.interval)),this._trigger("open",i,{tooltip:r}),o={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var i=e.Event(t);i.currentTarget=s[0],this.close(i,!0)}},remove:function(){this._removeTooltip(r)}},i&&"mouseover"!==i.type||(o.mouseleave="close"),i&&"focusin"!==i.type||(o.focusout="close"),this._on(!0,s,o)}},close:function(t){var s=this,a=e(t?t.currentTarget:this.element),n=this._find(a);this.closing||(clearInterval(this.delayedShow),a.data("ui-tooltip-title")&&a.attr("title",a.data("ui-tooltip-title")),i(a),n.stop(!0),this._hide(n,this.options.hide,function(){s._removeTooltip(e(this))}),a.removeData("ui-tooltip-open"),this._off(a,"mouseleave focusout keyup"),a[0]!==this.element[0]&&this._off(a,"remove"),this._off(this.document,"mousemove"),t&&"mouseleave"===t.type&&e.each(this.parents,function(t,i){e(i.element).attr("title",i.title),delete s.parents[t]}),this.closing=!0,this._trigger("close",t,{tooltip:n}),this.closing=!1)},_tooltip:function(t){var i="ui-tooltip-"+s++,a=e("<div>").attr({id:i,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("<div>").addClass("ui-tooltip-content").appendTo(a),a.appendTo(this.document[0].body),this.tooltips[i]=t,a},_find:function(t){var i=t.data("ui-tooltip-id");return i?e("#"+i):e()},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(i,s){var a=e.Event("blur");a.target=a.currentTarget=s[0],t.close(a,!0),e("#"+i).remove(),s.data("ui-tooltip-title")&&(s.attr("title",s.data("ui-tooltip-title")),s.removeData("ui-tooltip-title"))})}})})(jQuery);(function(e,t){var i="ui-effects-";e.effects={effect:{}},function(e,t){function i(e,t,i){var s=c[t.type]||{};return null==e?i||!t.def?null:t.def:(e=s.floor?~~e:parseFloat(e),isNaN(e)?t.def:s.mod?(e+s.mod)%s.mod:0>e?0:e>s.max?s.max:e)}function s(i){var s=l(),a=s._rgba=[];return i=i.toLowerCase(),f(h,function(e,n){var r,o=n.re.exec(i),h=o&&n.parse(o),l=n.space||"rgba";return h?(r=s[l](h),s[u[l].cache]=r[u[l].cache],a=s._rgba=r._rgba,!1):t}),a.length?("0,0,0,0"===a.join()&&e.extend(a,n.transparent),s):n[i]}function a(e,t,i){return i=(i+1)%1,1>6*i?e+6*(t-e)*i:1>2*i?t:2>3*i?e+6*(t-e)*(2/3-i):e}var n,r="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",o=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1],e[2],e[3],e[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[2.55*e[1],2.55*e[2],2.55*e[3],e[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(e){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(e){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(e){return[e[1],e[2]/100,e[3]/100,e[4]]}}],l=e.Color=function(t,i,s,a){return new e.Color.fn.parse(t,i,s,a)},u={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},c={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=e("<p>")[0],f=e.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),l.fn=e.extend(l.prototype,{parse:function(a,r,o,h){if(a===t)return this._rgba=[null,null,null,null],this;(a.jquery||a.nodeType)&&(a=e(a).css(r),r=t);var c=this,d=e.type(a),p=this._rgba=[];return r!==t&&(a=[a,r,o,h],d="array"),"string"===d?this.parse(s(a)||n._default):"array"===d?(f(u.rgba.props,function(e,t){p[t.idx]=i(a[t.idx],t)}),this):"object"===d?(a instanceof l?f(u,function(e,t){a[t.cache]&&(c[t.cache]=a[t.cache].slice())}):f(u,function(t,s){var n=s.cache;f(s.props,function(e,t){if(!c[n]&&s.to){if("alpha"===e||null==a[e])return;c[n]=s.to(c._rgba)}c[n][t.idx]=i(a[e],t,!0)}),c[n]&&0>e.inArray(null,c[n].slice(0,3))&&(c[n][3]=1,s.from&&(c._rgba=s.from(c[n])))}),this):t},is:function(e){var i=l(e),s=!0,a=this;return f(u,function(e,n){var r,o=i[n.cache];return o&&(r=a[n.cache]||n.to&&n.to(a._rgba)||[],f(n.props,function(e,i){return null!=o[i.idx]?s=o[i.idx]===r[i.idx]:t})),s}),s},_space:function(){var e=[],t=this;return f(u,function(i,s){t[s.cache]&&e.push(i)}),e.pop()},transition:function(e,t){var s=l(e),a=s._space(),n=u[a],r=0===this.alpha()?l("transparent"):this,o=r[n.cache]||n.to(r._rgba),h=o.slice();return s=s[n.cache],f(n.props,function(e,a){var n=a.idx,r=o[n],l=s[n],u=c[a.type]||{};null!==l&&(null===r?h[n]=l:(u.mod&&(l-r>u.mod/2?r+=u.mod:r-l>u.mod/2&&(r-=u.mod)),h[n]=i((l-r)*t+r,a)))}),this[a](h)},blend:function(t){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),a=l(t)._rgba;return l(e.map(i,function(e,t){return(1-s)*a[t]+s*e}))},toRgbaString:function(){var t="rgba(",i=e.map(this._rgba,function(e,t){return null==e?t>2?1:0:e});return 1===i[3]&&(i.pop(),t="rgb("),t+i.join()+")"},toHslaString:function(){var t="hsla(",i=e.map(this.hsla(),function(e,t){return null==e&&(e=t>2?1:0),t&&3>t&&(e=Math.round(100*e)+"%"),e});return 1===i[3]&&(i.pop(),t="hsl("),t+i.join()+")"},toHexString:function(t){var i=this._rgba.slice(),s=i.pop();return t&&i.push(~~(255*s)),"#"+e.map(i,function(e){return e=(e||0).toString(16),1===e.length?"0"+e:e}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,u.hsla.to=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t,i,s=e[0]/255,a=e[1]/255,n=e[2]/255,r=e[3],o=Math.max(s,a,n),h=Math.min(s,a,n),l=o-h,u=o+h,c=.5*u;return t=h===o?0:s===o?60*(a-n)/l+360:a===o?60*(n-s)/l+120:60*(s-a)/l+240,i=0===l?0:.5>=c?l/u:l/(2-u),[Math.round(t)%360,i,c,null==r?1:r]},u.hsla.from=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t=e[0]/360,i=e[1],s=e[2],n=e[3],r=.5>=s?s*(1+i):s+i-s*i,o=2*s-r;return[Math.round(255*a(o,r,t+1/3)),Math.round(255*a(o,r,t)),Math.round(255*a(o,r,t-1/3)),n]},f(u,function(s,a){var n=a.props,r=a.cache,h=a.to,u=a.from;l.fn[s]=function(s){if(h&&!this[r]&&(this[r]=h(this._rgba)),s===t)return this[r].slice();var a,o=e.type(s),c="array"===o||"object"===o?s:arguments,d=this[r].slice();return f(n,function(e,t){var s=c["object"===o?e:t.idx];null==s&&(s=d[t.idx]),d[t.idx]=i(s,t)}),u?(a=l(u(d)),a[r]=d,a):l(d)},f(n,function(t,i){l.fn[t]||(l.fn[t]=function(a){var n,r=e.type(a),h="alpha"===t?this._hsla?"hsla":"rgba":s,l=this[h](),u=l[i.idx];return"undefined"===r?u:("function"===r&&(a=a.call(this,u),r=e.type(a)),null==a&&i.empty?this:("string"===r&&(n=o.exec(a),n&&(a=u+parseFloat(n[2])*("+"===n[1]?1:-1))),l[i.idx]=a,this[h](l)))})})}),l.hook=function(t){var i=t.split(" ");f(i,function(t,i){e.cssHooks[i]={set:function(t,a){var n,r,o="";if("transparent"!==a&&("string"!==e.type(a)||(n=s(a)))){if(a=l(n||a),!d.rgba&&1!==a._rgba[3]){for(r="backgroundColor"===i?t.parentNode:t;(""===o||"transparent"===o)&&r&&r.style;)try{o=e.css(r,"backgroundColor"),r=r.parentNode}catch(h){}a=a.blend(o&&"transparent"!==o?o:"_default")}a=a.toRgbaString()}try{t.style[i]=a}catch(h){}}},e.fx.step[i]=function(t){t.colorInit||(t.start=l(t.elem,i),t.end=l(t.end),t.colorInit=!0),e.cssHooks[i].set(t.elem,t.start.transition(t.end,t.pos))}})},l.hook(r),e.cssHooks.borderColor={expand:function(e){var t={};return f(["Top","Right","Bottom","Left"],function(i,s){t["border"+s+"Color"]=e}),t}},n=e.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(t){var i,s,a=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,n={};if(a&&a.length&&a[0]&&a[a[0]])for(s=a.length;s--;)i=a[s],"string"==typeof a[i]&&(n[e.camelCase(i)]=a[i]);else for(i in a)"string"==typeof a[i]&&(n[i]=a[i]);return n}function s(t,i){var s,a,r={};for(s in i)a=i[s],t[s]!==a&&(n[s]||(e.fx.step[s]||!isNaN(parseFloat(a)))&&(r[s]=a));return r}var a=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,i){e.fx.step[i]=function(e){("none"!==e.end&&!e.setAttr||1===e.pos&&!e.setAttr)&&(jQuery.style(e.elem,i,e.end),e.setAttr=!0)}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e.effects.animateClass=function(t,n,r,o){var h=e.speed(n,r,o);return this.queue(function(){var n,r=e(this),o=r.attr("class")||"",l=h.children?r.find("*").addBack():r;l=l.map(function(){var t=e(this);return{el:t,start:i(this)}}),n=function(){e.each(a,function(e,i){t[i]&&r[i+"Class"](t[i])})},n(),l=l.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),l=l.map(function(){var t=this,i=e.Deferred(),s=e.extend({},h,{queue:!1,complete:function(){i.resolve(t)}});return this.el.animate(this.diff,s),i.promise()}),e.when.apply(e,l.get()).done(function(){n(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),h.complete.call(r[0])})})},e.fn.extend({addClass:function(t){return function(i,s,a,n){return s?e.effects.animateClass.call(this,{add:i},s,a,n):t.apply(this,arguments)}}(e.fn.addClass),removeClass:function(t){return function(i,s,a,n){return arguments.length>1?e.effects.animateClass.call(this,{remove:i},s,a,n):t.apply(this,arguments)}}(e.fn.removeClass),toggleClass:function(i){return function(s,a,n,r,o){return"boolean"==typeof a||a===t?n?e.effects.animateClass.call(this,a?{add:s}:{remove:s},n,r,o):i.apply(this,arguments):e.effects.animateClass.call(this,{toggle:s},a,n,r)}}(e.fn.toggleClass),switchClass:function(t,i,s,a,n){return e.effects.animateClass.call(this,{add:i,remove:t},s,a,n)}})}(),function(){function s(t,i,s,a){return e.isPlainObject(t)&&(i=t,t=t.effect),t={effect:t},null==i&&(i={}),e.isFunction(i)&&(a=i,s=null,i={}),("number"==typeof i||e.fx.speeds[i])&&(a=s,s=i,i={}),e.isFunction(s)&&(a=s,s=null),i&&e.extend(t,i),s=s||i.duration,t.duration=e.fx.off?0:"number"==typeof s?s:s in e.fx.speeds?e.fx.speeds[s]:e.fx.speeds._default,t.complete=a||i.complete,t}function a(t){return!t||"number"==typeof t||e.fx.speeds[t]?!0:"string"!=typeof t||e.effects.effect[t]?e.isFunction(t)?!0:"object"!=typeof t||t.effect?!1:!0:!0}e.extend(e.effects,{version:"1.10.3",save:function(e,t){for(var s=0;t.length>s;s++)null!==t[s]&&e.data(i+t[s],e[0].style[t[s]])},restore:function(e,s){var a,n;for(n=0;s.length>n;n++)null!==s[n]&&(a=e.data(i+s[n]),a===t&&(a=""),e.css(s[n],a))},setMode:function(e,t){return"toggle"===t&&(t=e.is(":hidden")?"show":"hide"),t},getBaseline:function(e,t){var i,s;switch(e[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=e[0]/t.height}switch(e[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=e[1]/t.width}return{x:s,y:i}},createWrapper:function(t){if(t.parent().is(".ui-effects-wrapper"))return t.parent();var i={width:t.outerWidth(!0),height:t.outerHeight(!0),"float":t.css("float")},s=e("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),a={width:t.width(),height:t.height()},n=document.activeElement;try{n.id}catch(r){n=document.body}return t.wrap(s),(t[0]===n||e.contains(t[0],n))&&e(n).focus(),s=t.parent(),"static"===t.css("position")?(s.css({position:"relative"}),t.css({position:"relative"})):(e.extend(i,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,s){i[s]=t.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(a),s.css(i).show()},removeWrapper:function(t){var i=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===i||e.contains(t[0],i))&&e(i).focus()),t},setTransition:function(t,i,s,a){return a=a||{},e.each(i,function(e,i){var n=t.cssUnit(i);n[0]>0&&(a[i]=n[0]*s+n[1])}),a}}),e.fn.extend({effect:function(){function t(t){function s(){e.isFunction(n)&&n.call(a[0]),e.isFunction(t)&&t()}var a=e(this),n=i.complete,o=i.mode;(a.is(":hidden")?"hide"===o:"show"===o)?(a[o](),s()):r.call(a[0],i,s)}var i=s.apply(this,arguments),a=i.mode,n=i.queue,r=e.effects.effect[i.effect];return e.fx.off||!r?a?this[a](i.duration,i.complete):this.each(function(){i.complete&&i.complete.call(this)}):n===!1?this.each(t):this.queue(n||"fx",t)},show:function(e){return function(t){if(a(t))return e.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="show",this.effect.call(this,i)}}(e.fn.show),hide:function(e){return function(t){if(a(t))return e.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="hide",this.effect.call(this,i)}}(e.fn.hide),toggle:function(e){return function(t){if(a(t)||"boolean"==typeof t)return e.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="toggle",this.effect.call(this,i)}}(e.fn.toggle),cssUnit:function(t){var i=this.css(t),s=[];return e.each(["em","px","%","pt"],function(e,t){i.indexOf(t)>0&&(s=[parseFloat(i),t])}),s}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,i){t[i]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return 0===e||1===e?e:-Math.pow(2,8*(e-1))*Math.sin((80*(e-1)-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){for(var t,i=4;((t=Math.pow(2,--i))-1)/11>e;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*t-2)/22-e,2)}}),e.each(t,function(t,i){e.easing["easeIn"+t]=i,e.easing["easeOut"+t]=function(e){return 1-i(1-e)},e.easing["easeInOut"+t]=function(e){return.5>e?i(2*e)/2:1-i(-2*e+2)/2}})}()})(jQuery);(function(e){var t=/up|down|vertical/,i=/up|left|vertical|horizontal/;e.effects.effect.blind=function(a,s){var n,r,o,l=e(this),h=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(l,a.mode||"hide"),d=a.direction||"up",c=t.test(d),p=c?"height":"width",f=c?"top":"left",m=i.test(d),g={},v="show"===u;l.parent().is(".ui-effects-wrapper")?e.effects.save(l.parent(),h):e.effects.save(l,h),l.show(),n=e.effects.createWrapper(l).css({overflow:"hidden"}),r=n[p](),o=parseFloat(n.css(f))||0,g[p]=v?r:0,m||(l.css(c?"bottom":"right",0).css(c?"top":"left","auto").css({position:"absolute"}),g[f]=v?o:r+o),v&&(n.css(p,0),m||n.css(f,o+r)),n.animate(g,{duration:a.duration,easing:a.easing,queue:!1,complete:function(){"hide"===u&&l.hide(),e.effects.restore(l,h),e.effects.removeWrapper(l),s()}})}})(jQuery);(function(e){e.effects.effect.bounce=function(t,i){var a,s,n,r=e(this),o=["position","top","bottom","left","right","height","width"],l=e.effects.setMode(r,t.mode||"effect"),h="hide"===l,u="show"===l,d=t.direction||"up",c=t.distance,p=t.times||5,f=2*p+(u||h?1:0),m=t.duration/f,g=t.easing,v="up"===d||"down"===d?"top":"left",y="up"===d||"left"===d,b=r.queue(),_=b.length;for((u||h)&&o.push("opacity"),e.effects.save(r,o),r.show(),e.effects.createWrapper(r),c||(c=r["top"===v?"outerHeight":"outerWidth"]()/3),u&&(n={opacity:1},n[v]=0,r.css("opacity",0).css(v,y?2*-c:2*c).animate(n,m,g)),h&&(c/=Math.pow(2,p-1)),n={},n[v]=0,a=0;p>a;a++)s={},s[v]=(y?"-=":"+=")+c,r.animate(s,m,g).animate(n,m,g),c=h?2*c:c/2;h&&(s={opacity:0},s[v]=(y?"-=":"+=")+c,r.animate(s,m,g)),r.queue(function(){h&&r.hide(),e.effects.restore(r,o),e.effects.removeWrapper(r),i()}),_>1&&b.splice.apply(b,[1,0].concat(b.splice(_,f+1))),r.dequeue()}})(jQuery);(function(e){e.effects.effect.clip=function(t,i){var a,s,n,r=e(this),o=["position","top","bottom","left","right","height","width"],l=e.effects.setMode(r,t.mode||"hide"),h="show"===l,u=t.direction||"vertical",d="vertical"===u,c=d?"height":"width",p=d?"top":"left",f={};e.effects.save(r,o),r.show(),a=e.effects.createWrapper(r).css({overflow:"hidden"}),s="IMG"===r[0].tagName?a:r,n=s[c](),h&&(s.css(c,0),s.css(p,n/2)),f[c]=h?n:0,f[p]=h?0:n/2,s.animate(f,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){h||r.hide(),e.effects.restore(r,o),e.effects.removeWrapper(r),i()}})}})(jQuery);(function(e){e.effects.effect.drop=function(t,i){var a,s=e(this),n=["position","top","bottom","left","right","opacity","height","width"],r=e.effects.setMode(s,t.mode||"hide"),o="show"===r,l=t.direction||"left",h="up"===l||"down"===l?"top":"left",u="up"===l||"left"===l?"pos":"neg",d={opacity:o?1:0};e.effects.save(s,n),s.show(),e.effects.createWrapper(s),a=t.distance||s["top"===h?"outerHeight":"outerWidth"](!0)/2,o&&s.css("opacity",0).css(h,"pos"===u?-a:a),d[h]=(o?"pos"===u?"+=":"-=":"pos"===u?"-=":"+=")+a,s.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===r&&s.hide(),e.effects.restore(s,n),e.effects.removeWrapper(s),i()}})}})(jQuery);(function(e){e.effects.effect.explode=function(t,i){function s(){b.push(this),b.length===d*c&&a()}function a(){p.css({visibility:"visible"}),e(b).remove(),m||p.hide(),i()}var n,r,o,l,h,u,d=t.pieces?Math.round(Math.sqrt(t.pieces)):3,c=d,p=e(this),f=e.effects.setMode(p,t.mode||"hide"),m="show"===f,g=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/c),y=Math.ceil(p.outerHeight()/d),b=[];for(n=0;d>n;n++)for(l=g.top+n*y,u=n-(d-1)/2,r=0;c>r;r++)o=g.left+r*v,h=r-(c-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-r*v,top:-n*y}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:y,left:o+(m?h*v:0),top:l+(m?u*y:0),opacity:m?0:1}).animate({left:o+(m?0:h*v),top:l+(m?0:u*y),opacity:m?1:0},t.duration||500,t.easing,s)}})(jQuery);(function(e){e.effects.effect.fade=function(t,i){var s=e(this),a=e.effects.setMode(s,t.mode||"toggle");s.animate({opacity:a},{queue:!1,duration:t.duration,easing:t.easing,complete:i})}})(jQuery);(function(e){e.effects.effect.fold=function(t,i){var s,a,n=e(this),r=["position","top","bottom","left","right","height","width"],o=e.effects.setMode(n,t.mode||"hide"),l="show"===o,h="hide"===o,u=t.size||15,d=/([0-9]+)%/.exec(u),c=!!t.horizFirst,p=l!==c,f=p?["width","height"]:["height","width"],m=t.duration/2,g={},v={};e.effects.save(n,r),n.show(),s=e.effects.createWrapper(n).css({overflow:"hidden"}),a=p?[s.width(),s.height()]:[s.height(),s.width()],d&&(u=parseInt(d[1],10)/100*a[h?0:1]),l&&s.css(c?{height:0,width:u}:{height:u,width:0}),g[f[0]]=l?a[0]:u,v[f[1]]=l?a[1]:0,s.animate(g,m,t.easing).animate(v,m,t.easing,function(){h&&n.hide(),e.effects.restore(n,r),e.effects.removeWrapper(n),i()})}})(jQuery);(function(e){e.effects.effect.highlight=function(t,i){var s=e(this),a=["backgroundImage","backgroundColor","opacity"],n=e.effects.setMode(s,t.mode||"show"),r={backgroundColor:s.css("backgroundColor")};"hide"===n&&(r.opacity=0),e.effects.save(s,a),s.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(r,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===n&&s.hide(),e.effects.restore(s,a),i()}})}})(jQuery);(function(e){e.effects.effect.pulsate=function(t,i){var s,a=e(this),n=e.effects.setMode(a,t.mode||"show"),r="show"===n,o="hide"===n,l=r||"hide"===n,h=2*(t.times||5)+(l?1:0),u=t.duration/h,d=0,c=a.queue(),p=c.length;for((r||!a.is(":visible"))&&(a.css("opacity",0).show(),d=1),s=1;h>s;s++)a.animate({opacity:d},u,t.easing),d=1-d;a.animate({opacity:d},u,t.easing),a.queue(function(){o&&a.hide(),i()}),p>1&&c.splice.apply(c,[1,0].concat(c.splice(p,h+1))),a.dequeue()}})(jQuery);(function(e){e.effects.effect.puff=function(t,i){var s=e(this),a=e.effects.setMode(s,t.mode||"hide"),n="hide"===a,r=parseInt(t.percent,10)||150,o=r/100,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:a,complete:i,percent:n?r:100,from:n?h:{height:h.height*o,width:h.width*o,outerHeight:h.outerHeight*o,outerWidth:h.outerWidth*o}}),s.effect(t)},e.effects.effect.scale=function(t,i){var s=e(this),a=e.extend(!0,{},t),n=e.effects.setMode(s,t.mode||"effect"),r=parseInt(t.percent,10)||(0===parseInt(t.percent,10)?0:"hide"===n?0:100),o=t.direction||"both",h=t.origin,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},u={y:"horizontal"!==o?r/100:1,x:"vertical"!==o?r/100:1};a.effect="size",a.queue=!1,a.complete=i,"effect"!==n&&(a.origin=h||["middle","center"],a.restore=!0),a.from=t.from||("show"===n?{height:0,width:0,outerHeight:0,outerWidth:0}:l),a.to={height:l.height*u.y,width:l.width*u.x,outerHeight:l.outerHeight*u.y,outerWidth:l.outerWidth*u.x},a.fade&&("show"===n&&(a.from.opacity=0,a.to.opacity=1),"hide"===n&&(a.from.opacity=1,a.to.opacity=0)),s.effect(a)},e.effects.effect.size=function(t,i){var s,a,n,r=e(this),o=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],l=["width","height","overflow"],u=["fontSize"],d=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],c=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(r,t.mode||"effect"),f=t.restore||"effect"!==p,m=t.scale||"both",g=t.origin||["middle","center"],v=r.css("position"),y=f?o:h,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&r.show(),s={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},"toggle"===t.mode&&"show"===p?(r.from=t.to||b,r.to=t.from||s):(r.from=t.from||("show"===p?b:s),r.to=t.to||("hide"===p?b:s)),n={from:{y:r.from.height/s.height,x:r.from.width/s.width},to:{y:r.to.height/s.height,x:r.to.width/s.width}},("box"===m||"both"===m)&&(n.from.y!==n.to.y&&(y=y.concat(d),r.from=e.effects.setTransition(r,d,n.from.y,r.from),r.to=e.effects.setTransition(r,d,n.to.y,r.to)),n.from.x!==n.to.x&&(y=y.concat(c),r.from=e.effects.setTransition(r,c,n.from.x,r.from),r.to=e.effects.setTransition(r,c,n.to.x,r.to))),("content"===m||"both"===m)&&n.from.y!==n.to.y&&(y=y.concat(u).concat(l),r.from=e.effects.setTransition(r,u,n.from.y,r.from),r.to=e.effects.setTransition(r,u,n.to.y,r.to)),e.effects.save(r,y),r.show(),e.effects.createWrapper(r),r.css("overflow","hidden").css(r.from),g&&(a=e.effects.getBaseline(g,s),r.from.top=(s.outerHeight-r.outerHeight())*a.y,r.from.left=(s.outerWidth-r.outerWidth())*a.x,r.to.top=(s.outerHeight-r.to.outerHeight)*a.y,r.to.left=(s.outerWidth-r.to.outerWidth)*a.x),r.css(r.from),("content"===m||"both"===m)&&(d=d.concat(["marginTop","marginBottom"]).concat(u),c=c.concat(["marginLeft","marginRight"]),l=o.concat(d).concat(c),r.find("*[width]").each(function(){var i=e(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&e.effects.save(i,l),i.from={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},i.to={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x},n.from.y!==n.to.y&&(i.from=e.effects.setTransition(i,d,n.from.y,i.from),i.to=e.effects.setTransition(i,d,n.to.y,i.to)),n.from.x!==n.to.x&&(i.from=e.effects.setTransition(i,c,n.from.x,i.from),i.to=e.effects.setTransition(i,c,n.to.x,i.to)),i.css(i.from),i.animate(i.to,t.duration,t.easing,function(){f&&e.effects.restore(i,l)})})),r.animate(r.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){0===r.to.opacity&&r.css("opacity",r.from.opacity),"hide"===p&&r.hide(),e.effects.restore(r,y),f||("static"===v?r.css({position:"relative",top:r.to.top,left:r.to.left}):e.each(["top","left"],function(e,t){r.css(t,function(t,i){var s=parseInt(i,10),a=e?r.to.left:r.to.top;return"auto"===i?a+"px":s+a+"px"})})),e.effects.removeWrapper(r),i()}})}})(jQuery);(function(e){e.effects.effect.shake=function(t,i){var s,a=e(this),n=["position","top","bottom","left","right","height","width"],r=e.effects.setMode(a,t.mode||"effect"),o=t.direction||"left",h=t.distance||20,l=t.times||3,u=2*l+1,d=Math.round(t.duration/u),c="up"===o||"down"===o?"top":"left",p="up"===o||"left"===o,f={},m={},g={},v=a.queue(),y=v.length;for(e.effects.save(a,n),a.show(),e.effects.createWrapper(a),f[c]=(p?"-=":"+=")+h,m[c]=(p?"+=":"-=")+2*h,g[c]=(p?"-=":"+=")+2*h,a.animate(f,d,t.easing),s=1;l>s;s++)a.animate(m,d,t.easing).animate(g,d,t.easing);a.animate(m,d,t.easing).animate(f,d/2,t.easing).queue(function(){"hide"===r&&a.hide(),e.effects.restore(a,n),e.effects.removeWrapper(a),i()}),y>1&&v.splice.apply(v,[1,0].concat(v.splice(y,u+1))),a.dequeue()}})(jQuery);(function(e){e.effects.effect.slide=function(t,i){var s,a=e(this),n=["position","top","bottom","left","right","width","height"],r=e.effects.setMode(a,t.mode||"show"),o="show"===r,h=t.direction||"left",l="up"===h||"down"===h?"top":"left",u="up"===h||"left"===h,d={};e.effects.save(a,n),a.show(),s=t.distance||a["top"===l?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(a).css({overflow:"hidden"}),o&&a.css(l,u?isNaN(s)?"-"+s:-s:s),d[l]=(o?u?"+=":"-=":u?"-=":"+=")+s,a.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===r&&a.hide(),e.effects.restore(a,n),e.effects.removeWrapper(a),i()}})}})(jQuery);(function(e){e.effects.effect.transfer=function(t,i){var s=e(this),a=e(t.to),n="fixed"===a.css("position"),r=e("body"),o=n?r.scrollTop():0,h=n?r.scrollLeft():0,l=a.offset(),u={top:l.top-o,left:l.left-h,height:a.innerHeight(),width:a.innerWidth()},d=s.offset(),c=e("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(t.className).css({top:d.top-o,left:d.left-h,height:s.innerHeight(),width:s.innerWidth(),position:n?"fixed":"absolute"}).animate(u,t.duration,t.easing,function(){c.remove(),i()})}})(jQuery);
diff --git a/Duplicati/Server/webroot/greeno/scripts/jquery.noty.packaged.min.js b/Duplicati/Server/webroot/greeno/scripts/jquery.noty.packaged.min.js
deleted file mode 100755
index 459f48e18..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jquery.noty.packaged.min.js
+++ /dev/null
@@ -1 +0,0 @@
-"function"!=typeof Object.create&&(Object.create=function(a){function b(){}return b.prototype=a,new b}),function(a){var b={init:function(b){return this.options=a.extend({},a.noty.defaults,b),this.options.layout=this.options.custom?a.noty.layouts.inline:a.noty.layouts[this.options.layout],a.noty.themes[this.options.theme]?this.options.theme=a.noty.themes[this.options.theme]:b.themeClassName=this.options.theme,delete b.layout,delete b.theme,this.options=a.extend({},this.options,this.options.layout.options),this.options.id="noty_"+(new Date).getTime()*Math.floor(1e6*Math.random()),this.options=a.extend({},this.options,b),this._build(),this},_build:function(){var b=a('<div class="noty_bar noty_type_'+this.options.type+'"></div>').attr("id",this.options.id);if(b.append(this.options.template).find(".noty_text").html(this.options.text),this.$bar=null!==this.options.layout.parent.object?a(this.options.layout.parent.object).css(this.options.layout.parent.css).append(b):b,this.options.themeClassName&&this.$bar.addClass(this.options.themeClassName).addClass("noty_container_type_"+this.options.type),this.options.buttons){this.options.closeWith=[],this.options.timeout=!1;var c=a("<div/>").addClass("noty_buttons");null!==this.options.layout.parent.object?this.$bar.find(".noty_bar").append(c):this.$bar.append(c);var d=this;a.each(this.options.buttons,function(b,c){var e=a("<button/>").addClass(c.addClass?c.addClass:"gray").html(c.text).attr("id",c.id?c.id:"button-"+b).appendTo(d.$bar.find(".noty_buttons")).bind("click",function(){a.isFunction(c.onClick)&&c.onClick.call(e,d)})})}this.$message=this.$bar.find(".noty_message"),this.$closeButton=this.$bar.find(".noty_close"),this.$buttons=this.$bar.find(".noty_buttons"),a.noty.store[this.options.id]=this},show:function(){var b=this;return b.options.custom?b.options.custom.find(b.options.layout.container.selector).append(b.$bar):a(b.options.layout.container.selector).append(b.$bar),b.options.theme&&b.options.theme.style&&b.options.theme.style.apply(b),"function"===a.type(b.options.layout.css)?this.options.layout.css.apply(b.$bar):b.$bar.css(this.options.layout.css||{}),b.$bar.addClass(b.options.layout.addClass),b.options.layout.container.style.apply(a(b.options.layout.container.selector)),b.showing=!0,b.options.theme&&b.options.theme.style&&b.options.theme.callback.onShow.apply(this),a.inArray("click",b.options.closeWith)>-1&&b.$bar.css("cursor","pointer").one("click",function(a){b.stopPropagation(a),b.options.callback.onCloseClick&&b.options.callback.onCloseClick.apply(b),b.close()}),a.inArray("hover",b.options.closeWith)>-1&&b.$bar.one("mouseenter",function(){b.close()}),a.inArray("button",b.options.closeWith)>-1&&b.$closeButton.one("click",function(a){b.stopPropagation(a),b.close()}),-1==a.inArray("button",b.options.closeWith)&&b.$closeButton.remove(),b.options.callback.onShow&&b.options.callback.onShow.apply(b),b.$bar.animate(b.options.animation.open,b.options.animation.speed,b.options.animation.easing,function(){b.options.callback.afterShow&&b.options.callback.afterShow.apply(b),b.showing=!1,b.shown=!0}),b.options.timeout&&b.$bar.delay(b.options.timeout).promise().done(function(){b.close()}),this},close:function(){if(!(this.closed||this.$bar&&this.$bar.hasClass("i-am-closing-now"))){var b=this;if(this.showing)return b.$bar.queue(function(){b.close.apply(b)}),void 0;if(!this.shown&&!this.showing){var c=[];return a.each(a.noty.queue,function(a,d){d.options.id!=b.options.id&&c.push(d)}),a.noty.queue=c,void 0}b.$bar.addClass("i-am-closing-now"),b.options.callback.onClose&&b.options.callback.onClose.apply(b),b.$bar.clearQueue().stop().animate(b.options.animation.close,b.options.animation.speed,b.options.animation.easing,function(){b.options.callback.afterClose&&b.options.callback.afterClose.apply(b)}).promise().done(function(){b.options.modal&&(a.notyRenderer.setModalCount(-1),0==a.notyRenderer.getModalCount()&&a(".noty_modal").fadeOut("fast",function(){a(this).remove()})),a.notyRenderer.setLayoutCountFor(b,-1),0==a.notyRenderer.getLayoutCountFor(b)&&a(b.options.layout.container.selector).remove(),"undefined"!=typeof b.$bar&&null!==b.$bar&&(b.$bar.remove(),b.$bar=null,b.closed=!0),delete a.noty.store[b.options.id],b.options.theme.callback&&b.options.theme.callback.onClose&&b.options.theme.callback.onClose.apply(b),b.options.dismissQueue||(a.noty.ontap=!0,a.notyRenderer.render()),b.options.maxVisible>0&&b.options.dismissQueue&&a.notyRenderer.render()})}},setText:function(a){return this.closed||(this.options.text=a,this.$bar.find(".noty_text").html(a)),this},setType:function(a){return this.closed||(this.options.type=a,this.options.theme.style.apply(this),this.options.theme.callback.onShow.apply(this)),this},setTimeout:function(a){if(!this.closed){var b=this;this.options.timeout=a,b.$bar.delay(b.options.timeout).promise().done(function(){b.close()})}return this},stopPropagation:function(a){a=a||window.event,"undefined"!=typeof a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},closed:!1,showing:!1,shown:!1};a.notyRenderer={},a.notyRenderer.init=function(c){var d=Object.create(b).init(c);return d.options.killer&&a.noty.closeAll(),d.options.force?a.noty.queue.unshift(d):a.noty.queue.push(d),a.notyRenderer.render(),"object"==a.noty.returns?d:d.options.id},a.notyRenderer.render=function(){var b=a.noty.queue[0];"object"===a.type(b)?b.options.dismissQueue?b.options.maxVisible>0?a(b.options.layout.container.selector+" li").length<b.options.maxVisible&&a.notyRenderer.show(a.noty.queue.shift()):a.notyRenderer.show(a.noty.queue.shift()):a.noty.ontap&&(a.notyRenderer.show(a.noty.queue.shift()),a.noty.ontap=!1):a.noty.ontap=!0},a.notyRenderer.show=function(b){b.options.modal&&(a.notyRenderer.createModalFor(b),a.notyRenderer.setModalCount(1)),b.options.custom?0==b.options.custom.find(b.options.layout.container.selector).length?b.options.custom.append(a(b.options.layout.container.object).addClass("i-am-new")):b.options.custom.find(b.options.layout.container.selector).removeClass("i-am-new"):0==a(b.options.layout.container.selector).length?a("body").append(a(b.options.layout.container.object).addClass("i-am-new")):a(b.options.layout.container.selector).removeClass("i-am-new"),a.notyRenderer.setLayoutCountFor(b,1),b.show()},a.notyRenderer.createModalFor=function(b){if(0==a(".noty_modal").length){var c=a("<div/>").addClass("noty_modal").addClass(b.options.theme).data("noty_modal_count",0);b.options.theme.modal&&b.options.theme.modal.css&&c.css(b.options.theme.modal.css),c.prependTo(a("body")).fadeIn("fast")}},a.notyRenderer.getLayoutCountFor=function(b){return a(b.options.layout.container.selector).data("noty_layout_count")||0},a.notyRenderer.setLayoutCountFor=function(b,c){return a(b.options.layout.container.selector).data("noty_layout_count",a.notyRenderer.getLayoutCountFor(b)+c)},a.notyRenderer.getModalCount=function(){return a(".noty_modal").data("noty_modal_count")||0},a.notyRenderer.setModalCount=function(b){return a(".noty_modal").data("noty_modal_count",a.notyRenderer.getModalCount()+b)},a.fn.noty=function(b){return b.custom=a(this),a.notyRenderer.init(b)},a.noty={},a.noty.queue=[],a.noty.ontap=!0,a.noty.layouts={},a.noty.themes={},a.noty.returns="object",a.noty.store={},a.noty.get=function(b){return a.noty.store.hasOwnProperty(b)?a.noty.store[b]:!1},a.noty.close=function(b){return a.noty.get(b)?a.noty.get(b).close():!1},a.noty.setText=function(b,c){return a.noty.get(b)?a.noty.get(b).setText(c):!1},a.noty.setType=function(b,c){return a.noty.get(b)?a.noty.get(b).setType(c):!1},a.noty.clearQueue=function(){a.noty.queue=[]},a.noty.closeAll=function(){a.noty.clearQueue(),a.each(a.noty.store,function(a,b){b.close()})};var c=window.alert;a.noty.consumeAlert=function(b){window.alert=function(c){b?b.text=c:b={text:c},a.notyRenderer.init(b)}},a.noty.stopConsumeAlert=function(){window.alert=c},a.noty.defaults={layout:"top",theme:"defaultTheme",type:"alert",text:"",dismissQueue:!0,template:'<div class="noty_message"><span class="noty_text"></span><div class="noty_close"></div></div>',animation:{open:{height:"toggle"},close:{height:"toggle"},easing:"swing",speed:500},timeout:!1,force:!1,modal:!1,maxVisible:5,killer:!1,closeWith:["click"],callback:{onShow:function(){},afterShow:function(){},onClose:function(){},afterClose:function(){},onCloseClick:function(){}},buttons:!1},a(window).resize(function(){a.each(a.noty.layouts,function(b,c){c.container.style.apply(a(c.container.selector))})})}(jQuery),window.noty=function(a){return jQuery.notyRenderer.init(a)},function(a){a.noty.layouts.bottom={name:"bottom",options:{},container:{object:'<ul id="noty_bottom_layout_container" />',selector:"ul#noty_bottom_layout_container",style:function(){a(this).css({bottom:0,left:"5%",position:"fixed",width:"90%",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:9999999})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none"},addClass:""}}(jQuery),function(a){a.noty.layouts.bottomCenter={name:"bottomCenter",options:{},container:{object:'<ul id="noty_bottomCenter_layout_container" />',selector:"ul#noty_bottomCenter_layout_container",style:function(){a(this).css({bottom:20,left:0,position:"fixed",width:"310px",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:1e7}),a(this).css({left:(a(window).width()-a(this).outerWidth(!1))/2+"px"})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none",width:"310px"},addClass:""}}(jQuery),function(a){a.noty.layouts.bottomLeft={name:"bottomLeft",options:{},container:{object:'<ul id="noty_bottomLeft_layout_container" />',selector:"ul#noty_bottomLeft_layout_container",style:function(){a(this).css({bottom:20,left:20,position:"fixed",width:"310px",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:1e7}),window.innerWidth<600&&a(this).css({left:5})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none",width:"310px"},addClass:""}}(jQuery),function(a){a.noty.layouts.bottomRight={name:"bottomRight",options:{},container:{object:'<ul id="noty_bottomRight_layout_container" />',selector:"ul#noty_bottomRight_layout_container",style:function(){a(this).css({bottom:20,right:20,position:"fixed",width:"310px",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:1e7}),window.innerWidth<600&&a(this).css({right:5})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none",width:"310px"},addClass:""}}(jQuery),function(a){a.noty.layouts.center={name:"center",options:{},container:{object:'<ul id="noty_center_layout_container" />',selector:"ul#noty_center_layout_container",style:function(){a(this).css({position:"fixed",width:"310px",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:1e7});var b=a(this).clone().css({visibility:"hidden",display:"block",position:"absolute",top:0,left:0}).attr("id","dupe");a("body").append(b),b.find(".i-am-closing-now").remove(),b.find("li").css("display","block");var c=b.height();b.remove(),a(this).hasClass("i-am-new")?a(this).css({left:(a(window).width()-a(this).outerWidth(!1))/2+"px",top:(a(window).height()-c)/2+"px"}):a(this).animate({left:(a(window).width()-a(this).outerWidth(!1))/2+"px",top:(a(window).height()-c)/2+"px"},500)}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none",width:"310px"},addClass:""}}(jQuery),function(a){a.noty.layouts.centerLeft={name:"centerLeft",options:{},container:{object:'<ul id="noty_centerLeft_layout_container" />',selector:"ul#noty_centerLeft_layout_container",style:function(){a(this).css({left:20,position:"fixed",width:"310px",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:1e7});var b=a(this).clone().css({visibility:"hidden",display:"block",position:"absolute",top:0,left:0}).attr("id","dupe");a("body").append(b),b.find(".i-am-closing-now").remove(),b.find("li").css("display","block");var c=b.height();b.remove(),a(this).hasClass("i-am-new")?a(this).css({top:(a(window).height()-c)/2+"px"}):a(this).animate({top:(a(window).height()-c)/2+"px"},500),window.innerWidth<600&&a(this).css({left:5})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none",width:"310px"},addClass:""}}(jQuery),function(a){a.noty.layouts.centerRight={name:"centerRight",options:{},container:{object:'<ul id="noty_centerRight_layout_container" />',selector:"ul#noty_centerRight_layout_container",style:function(){a(this).css({right:20,position:"fixed",width:"310px",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:1e7});var b=a(this).clone().css({visibility:"hidden",display:"block",position:"absolute",top:0,left:0}).attr("id","dupe");a("body").append(b),b.find(".i-am-closing-now").remove(),b.find("li").css("display","block");var c=b.height();b.remove(),a(this).hasClass("i-am-new")?a(this).css({top:(a(window).height()-c)/2+"px"}):a(this).animate({top:(a(window).height()-c)/2+"px"},500),window.innerWidth<600&&a(this).css({right:5})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none",width:"310px"},addClass:""}}(jQuery),function(a){a.noty.layouts.inline={name:"inline",options:{},container:{object:'<ul class="noty_inline_layout_container" />',selector:"ul.noty_inline_layout_container",style:function(){a(this).css({width:"100%",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:9999999})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none"},addClass:""}}(jQuery),function(a){a.noty.layouts.top={name:"top",options:{},container:{object:'<ul id="noty_top_layout_container" />',selector:"ul#noty_top_layout_container",style:function(){a(this).css({top:0,left:"5%",position:"fixed",width:"90%",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:9999999})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none"},addClass:""}}(jQuery),function(a){a.noty.layouts.topCenter={name:"topCenter",options:{},container:{object:'<ul id="noty_topCenter_layout_container" />',selector:"ul#noty_topCenter_layout_container",style:function(){a(this).css({top:20,left:0,position:"fixed",width:"310px",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:1e7}),a(this).css({left:(a(window).width()-a(this).outerWidth(!1))/2+"px"})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none",width:"310px"},addClass:""}}(jQuery),function(a){a.noty.layouts.topLeft={name:"topLeft",options:{},container:{object:'<ul id="noty_topLeft_layout_container" />',selector:"ul#noty_topLeft_layout_container",style:function(){a(this).css({top:20,left:20,position:"fixed",width:"310px",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:1e7}),window.innerWidth<600&&a(this).css({left:5})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none",width:"310px"},addClass:""}}(jQuery),function(a){a.noty.layouts.topRight={name:"topRight",options:{},container:{object:'<ul id="noty_topRight_layout_container" />',selector:"ul#noty_topRight_layout_container",style:function(){a(this).css({top:20,right:20,position:"fixed",width:"310px",height:"auto",margin:0,padding:0,listStyleType:"none",zIndex:1e7}),window.innerWidth<600&&a(this).css({right:5})}},parent:{object:"<li />",selector:"li",css:{}},css:{display:"none",width:"310px"},addClass:""}}(jQuery),function(a){a.noty.themes.defaultTheme={name:"defaultTheme",helpers:{borderFix:function(){if(this.options.dismissQueue){var b=this.options.layout.container.selector+" "+this.options.layout.parent.selector;switch(this.options.layout.name){case"top":a(b).css({borderRadius:"0px 0px 0px 0px"}),a(b).last().css({borderRadius:"0px 0px 5px 5px"});break;case"topCenter":case"topLeft":case"topRight":case"bottomCenter":case"bottomLeft":case"bottomRight":case"center":case"centerLeft":case"centerRight":case"inline":a(b).css({borderRadius:"0px 0px 0px 0px"}),a(b).first().css({"border-top-left-radius":"5px","border-top-right-radius":"5px"}),a(b).last().css({"border-bottom-left-radius":"5px","border-bottom-right-radius":"5px"});break;case"bottom":a(b).css({borderRadius:"0px 0px 0px 0px"}),a(b).first().css({borderRadius:"5px 5px 0px 0px"})}}}},modal:{css:{position:"fixed",width:"100%",height:"100%",backgroundColor:"#000",zIndex:1e4,opacity:.6,display:"none",left:0,top:0}},style:function(){switch(this.$bar.css({overflow:"hidden",background:"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAoCAYAAAAPOoFWAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPZJREFUeNq81tsOgjAMANB2ov7/7ypaN7IlIwi9rGuT8QSc9EIDAsAznxvY4pXPKr05RUE5MEVB+TyWfCEl9LZApYopCmo9C4FKSMtYoI8Bwv79aQJU4l6hXXCZrQbokJEksxHo9KMOgc6w1atHXM8K9DVC7FQnJ0i8iK3QooGgbnyKgMDygBWyYFZoqx4qS27KqLZJjA1D0jK6QJcYEQEiWv9PGkTsbqxQ8oT+ZtZB6AkdsJnQDnMoHXHLGKOgDYuCWmYhEERCI5gaamW0bnHdA3k2ltlIN+2qKRyCND0bhqSYCyTB3CAOc4WusBEIpkeBuPgJMAAX8Hs1NfqHRgAAAABJRU5ErkJggg==') repeat-x scroll left top #fff"}),this.$message.css({fontSize:"13px",lineHeight:"16px",textAlign:"center",padding:"8px 10px 9px",width:"auto",position:"relative"}),this.$closeButton.css({position:"absolute",top:4,right:4,width:10,height:10,background:"url(data:image/png;base64,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)",display:"none",cursor:"pointer"}),this.$buttons.css({padding:5,textAlign:"right",borderTop:"1px solid #ccc",backgroundColor:"#fff"}),this.$buttons.find("button").css({marginLeft:5}),this.$buttons.find("button:first").css({marginLeft:0}),this.$bar.bind({mouseenter:function(){a(this).find(".noty_close").stop().fadeTo("normal",1)},mouseleave:function(){a(this).find(".noty_close").stop().fadeTo("normal",0)}}),this.options.layout.name){case"top":this.$bar.css({borderRadius:"0px 0px 5px 5px",borderBottom:"2px solid #eee",borderLeft:"2px solid #eee",borderRight:"2px solid #eee",boxShadow:"0 2px 4px rgba(0, 0, 0, 0.1)"});break;case"topCenter":case"center":case"bottomCenter":case"inline":this.$bar.css({borderRadius:"5px",border:"1px solid #eee",boxShadow:"0 2px 4px rgba(0, 0, 0, 0.1)"}),this.$message.css({fontSize:"13px",textAlign:"center"});break;case"topLeft":case"topRight":case"bottomLeft":case"bottomRight":case"centerLeft":case"centerRight":this.$bar.css({borderRadius:"5px",border:"1px solid #eee",boxShadow:"0 2px 4px rgba(0, 0, 0, 0.1)"}),this.$message.css({fontSize:"13px",textAlign:"left"});break;case"bottom":this.$bar.css({borderRadius:"5px 5px 0px 0px",borderTop:"2px solid #eee",borderLeft:"2px solid #eee",borderRight:"2px solid #eee",boxShadow:"0 -2px 4px rgba(0, 0, 0, 0.1)"});break;default:this.$bar.css({border:"2px solid #eee",boxShadow:"0 2px 4px rgba(0, 0, 0, 0.1)"})}switch(this.options.type){case"alert":case"notification":this.$bar.css({backgroundColor:"#FFF",borderColor:"#CCC",color:"#444"});break;case"warning":this.$bar.css({backgroundColor:"#FFEAA8",borderColor:"#FFC237",color:"#826200"}),this.$buttons.css({borderTop:"1px solid #FFC237"});break;case"error":this.$bar.css({backgroundColor:"red",borderColor:"darkred",color:"#FFF"}),this.$message.css({fontWeight:"bold"}),this.$buttons.css({borderTop:"1px solid darkred"});break;case"information":this.$bar.css({backgroundColor:"#57B7E2",borderColor:"#0B90C4",color:"#FFF"}),this.$buttons.css({borderTop:"1px solid #0B90C4"});break;case"success":this.$bar.css({backgroundColor:"lightgreen",borderColor:"#50C24E",color:"darkgreen"}),this.$buttons.css({borderTop:"1px solid #50C24E"});break;default:this.$bar.css({backgroundColor:"#FFF",borderColor:"#CCC",color:"#444"})}},callback:{onShow:function(){a.noty.themes.defaultTheme.helpers.borderFix.apply(this)},onClose:function(){a.noty.themes.defaultTheme.helpers.borderFix.apply(this)}}}}(jQuery);
diff --git a/Duplicati/Server/webroot/greeno/scripts/jquery.timeago.js b/Duplicati/Server/webroot/greeno/scripts/jquery.timeago.js
deleted file mode 100644
index 44539a49a..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jquery.timeago.js
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
- * Timeago is a jQuery plugin that makes it easy to support automatically
- * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
- *
- * @name timeago
- * @version 1.4.0
- * @requires jQuery v1.2.3+
- * @author Ryan McGeary
- * @license MIT License - http://www.opensource.org/licenses/mit-license.php
- *
- * For usage and examples, visit:
- * http://timeago.yarp.com/
- *
- * Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
- */
-
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else {
- // Browser globals
- factory(jQuery);
- }
-}(function ($) {
- $.timeago = function(timestamp) {
- if (timestamp instanceof Date) {
- return inWords(timestamp);
- } else if (typeof timestamp === "string") {
- return inWords($.timeago.parse(timestamp));
- } else if (typeof timestamp === "number") {
- return inWords(new Date(timestamp));
- } else {
- return inWords($.timeago.datetime(timestamp));
- }
- };
- var $t = $.timeago;
-
- $.extend($.timeago, {
- settings: {
- refreshMillis: 60000,
- allowPast: true,
- allowFuture: false,
- localeTitle: false,
- cutoff: 0,
- strings: {
- prefixAgo: null,
- prefixFromNow: null,
- suffixAgo: "ago",
- suffixFromNow: "from now",
- inPast: 'any moment now',
- seconds: "less than a minute",
- minute: "about a minute",
- minutes: "%d minutes",
- hour: "about an hour",
- hours: "about %d hours",
- day: "a day",
- days: "%d days",
- month: "about a month",
- months: "%d months",
- year: "about a year",
- years: "%d years",
- wordSeparator: " ",
- numbers: []
- }
- },
-
- inWords: function(distanceMillis) {
- if(!this.settings.allowPast && ! this.settings.allowFuture) {
- throw 'timeago allowPast and allowFuture settings can not both be set to false.';
- }
-
- var $l = this.settings.strings;
- var prefix = $l.prefixAgo;
- var suffix = $l.suffixAgo;
- if (this.settings.allowFuture) {
- if (distanceMillis < 0) {
- prefix = $l.prefixFromNow;
- suffix = $l.suffixFromNow;
- }
- }
-
- if(!this.settings.allowPast && distanceMillis >= 0) {
- return this.settings.strings.inPast;
- }
-
- var seconds = Math.abs(distanceMillis) / 1000;
- var minutes = seconds / 60;
- var hours = minutes / 60;
- var days = hours / 24;
- var years = days / 365;
-
- function substitute(stringOrFunction, number) {
- var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
- var value = ($l.numbers && $l.numbers[number]) || number;
- return string.replace(/%d/i, value);
- }
-
- var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
- seconds < 90 && substitute($l.minute, 1) ||
- minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
- minutes < 90 && substitute($l.hour, 1) ||
- hours < 24 && substitute($l.hours, Math.round(hours)) ||
- hours < 42 && substitute($l.day, 1) ||
- days < 30 && substitute($l.days, Math.round(days)) ||
- days < 45 && substitute($l.month, 1) ||
- days < 365 && substitute($l.months, Math.round(days / 30)) ||
- years < 1.5 && substitute($l.year, 1) ||
- substitute($l.years, Math.round(years));
-
- var separator = $l.wordSeparator || "";
- if ($l.wordSeparator === undefined) { separator = " "; }
- return $.trim([prefix, words, suffix].join(separator));
- },
-
- parse: function(iso8601) {
- var s = $.trim(iso8601);
- s = s.replace(/\.\d+/,""); // remove milliseconds
- s = s.replace(/-/,"/").replace(/-/,"/");
- s = s.replace(/T/," ").replace(/Z/," UTC");
- s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
- s = s.replace(/([\+\-]\d\d)$/," $100"); // +09 -> +0900
- return new Date(s);
- },
- datetime: function(elem) {
- var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
- return $t.parse(iso8601);
- },
- isTime: function(elem) {
- // jQuery's `is()` doesn't play well with HTML5 in IE
- return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
- }
- });
-
- // functions that can be called via $(el).timeago('action')
- // init is default when no action is given
- // functions are called with context of a single element
- var functions = {
- init: function(){
- var refresh_el = $.proxy(refresh, this);
- refresh_el();
- var $s = $t.settings;
- if ($s.refreshMillis > 0) {
- this._timeagoInterval = setInterval(refresh_el, $s.refreshMillis);
- }
- },
- update: function(time){
- var parsedTime = $t.parse(time);
- $(this).data('timeago', { datetime: parsedTime });
- if($t.settings.localeTitle) $(this).attr("title", parsedTime.toLocaleString());
- refresh.apply(this);
- },
- updateFromDOM: function(){
- $(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) });
- refresh.apply(this);
- },
- dispose: function () {
- if (this._timeagoInterval) {
- window.clearInterval(this._timeagoInterval);
- this._timeagoInterval = null;
- }
- }
- };
-
- $.fn.timeago = function(action, options) {
- var fn = action ? functions[action] : functions.init;
- if(!fn){
- throw new Error("Unknown function name '"+ action +"' for timeago");
- }
- // each over objects here and call the requested function
- this.each(function(){
- fn.call(this, options);
- });
- return this;
- };
-
- function refresh() {
- var data = prepareData(this);
- var $s = $t.settings;
-
- if (!isNaN(data.datetime)) {
- if ( $s.cutoff == 0 || distance(data.datetime) < $s.cutoff) {
- $(this).text(inWords(data.datetime));
- }
- }
- return this;
- }
-
- function prepareData(element) {
- element = $(element);
- if (!element.data("timeago")) {
- element.data("timeago", { datetime: $t.datetime(element) });
- var text = $.trim(element.text());
- if ($t.settings.localeTitle) {
- element.attr("title", element.data('timeago').datetime.toLocaleString());
- } else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
- element.attr("title", text);
- }
- }
- return element.data("timeago");
- }
-
- function inWords(date) {
- return $t.inWords(distance(date));
- }
-
- function distance(date) {
- return (new Date().getTime() - date.getTime());
- }
-
- // fix for IE6 suckage
- document.createElement("abbr");
- document.createElement("time");
-}));
diff --git a/Duplicati/Server/webroot/greeno/scripts/jquery.tmpl.min.js b/Duplicati/Server/webroot/greeno/scripts/jquery.tmpl.min.js
deleted file mode 100644
index 1b3b878aa..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jquery.tmpl.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * jQuery Templates Plugin 1.0.0pre
- * http://github.com/jquery/jquery-tmpl
- * Requires jQuery 1.4.2
- *
- * Copyright 2011, Software Freedom Conservancy, Inc.
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- */
-(function(a){var r=a.fn.domManip,d="_tmplitem",q=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,b={},f={},e,p={key:0,data:{}},i=0,c=0,l=[];function g(g,d,h,e){var c={data:e||(e===0||e===false)?e:d?d.data:{},_wrap:d?d._wrap:null,tmpl:null,parent:d||null,nodes:[],calls:u,nest:w,wrap:x,html:v,update:t};g&&a.extend(c,g,{nodes:[],parent:d});if(h){c.tmpl=h;c._ctnt=c._ctnt||c.tmpl(a,c);c.key=++i;(l.length?f:b)[i]=c}return c}a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(f,d){a.fn[f]=function(n){var g=[],i=a(n),k,h,m,l,j=this.length===1&&this[0].parentNode;e=b||{};if(j&&j.nodeType===11&&j.childNodes.length===1&&i.length===1){i[d](this[0]);g=this}else{for(h=0,m=i.length;h<m;h++){c=h;k=(h>0?this.clone(true):this).get();a(i[h])[d](k);g=g.concat(k)}c=0;g=this.pushStack(g,f,i.selector)}l=e;e=null;a.tmpl.complete(l);return g}});a.fn.extend({tmpl:function(d,c,b){return a.tmpl(this[0],d,c,b)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(d,m,k){if(d[0]&&a.isArray(d[0])){var g=a.makeArray(arguments),h=d[0],j=h.length,i=0,f;while(i<j&&!(f=a.data(h[i++],"tmplItem")));if(f&&c)g[2]=function(b){a.tmpl.afterManip(this,b,k)};r.apply(this,g)}else r.apply(this,arguments);c=0;!e&&a.tmpl.complete(b);return this}});a.extend({tmpl:function(d,h,e,c){var i,k=!c;if(k){c=p;d=a.template[d]||a.template(null,d);f={}}else if(!d){d=c.tmpl;b[c.key]=c;c.nodes=[];c.wrapped&&n(c,c.wrapped);return a(j(c,null,c.tmpl(a,c)))}if(!d)return[];if(typeof h==="function")h=h.call(c||{});e&&e.wrapped&&n(e,e.wrapped);i=a.isArray(h)?a.map(h,function(a){return a?g(e,c,d,a):null}):[g(e,c,d,h)];return k?a(j(c,null,i)):i},tmplItem:function(b){var c;if(b instanceof a)b=b[0];while(b&&b.nodeType===1&&!(c=a.data(b,"tmplItem"))&&(b=b.parentNode));return c||p},template:function(c,b){if(b){if(typeof b==="string")b=o(b);else if(b instanceof a)b=b[0]||{};if(b.nodeType)b=a.data(b,"tmpl")||a.data(b,"tmpl",o(b.innerHTML));return typeof c==="string"?(a.template[c]=b):b}return c?typeof c!=="string"?a.template(null,c):a.template[c]||a.template(null,q.test(c)?c:a(c)):null},encode:function(a){return(""+a).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;")}});a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if($notnull_1){__=__.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(__,$1,$2);__=[];",close:"call=$item.calls();__=call._.concat($item.wrap(call,__));"},each:{_default:{$2:"$index, $value"},open:"if($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if(($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if(($notnull_1) && $1a){"},html:{open:"if($notnull_1){__.push($1a);}"},"=":{_default:{$1:"$data"},open:"if($notnull_1){__.push($.encode($1a));}"},"!":{open:""}},complete:function(){b={}},afterManip:function(f,b,d){var e=b.nodeType===11?a.makeArray(b.childNodes):b.nodeType===1?[b]:[];d.call(f,b);m(e);c++}});function j(e,g,f){var b,c=f?a.map(f,function(a){return typeof a==="string"?e.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+e.key+'" $2'):a:j(a,e,a._ctnt)}):e;if(g)return c;c=c.join("");c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(f,c,e,d){b=a(e).get();m(b);if(c)b=k(c).concat(b);if(d)b=b.concat(k(d))});return b?b:k(c)}function k(c){var b=document.createElement("div");b.innerHTML=c;return a.makeArray(b.childNodes)}function o(b){return new Function("jQuery","$item","var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(m,l,k,g,b,c,d){var j=a.tmpl.tag[k],i,e,f;if(!j)throw"Unknown template tag: "+k;i=j._default||[];if(c&&!/\w$/.test(b)){b+=c;c=""}if(b){b=h(b);d=d?","+h(d)+")":c?")":"";e=c?b.indexOf(".")>-1?b+h(c):"("+b+").call($item"+d:b;f=c?e:"(typeof("+b+")==='function'?("+b+").call($item):("+b+"))"}else f=e=i.$1||"null";g=h(g);return"');"+j[l?"close":"open"].split("$notnull_1").join(b?"typeof("+b+")!=='undefined' && ("+b+")!=null":"true").split("$1a").join(f).split("$1").join(e).split("$2").join(g||i.$2||"")+"__.push('"})+"');}return __;")}function n(c,b){c._wrap=j(c,true,a.isArray(b)?b:[q.test(b)?b:a(b).html()]).join("")}function h(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(b){var a=document.createElement("div");a.appendChild(b.cloneNode(true));return a.innerHTML}function m(o){var n="_"+c,k,j,l={},e,p,h;for(e=0,p=o.length;e<p;e++){if((k=o[e]).nodeType!==1)continue;j=k.getElementsByTagName("*");for(h=j.length-1;h>=0;h--)m(j[h]);m(k)}function m(j){var p,h=j,k,e,m;if(m=j.getAttribute(d)){while(h.parentNode&&(h=h.parentNode).nodeType===1&&!(p=h.getAttribute(d)));if(p!==m){h=h.parentNode?h.nodeType===11?0:h.getAttribute(d)||0:0;if(!(e=b[m])){e=f[m];e=g(e,b[h]||f[h]);e.key=++i;b[i]=e}c&&o(m)}j.removeAttribute(d)}else if(c&&(e=a.data(j,"tmplItem"))){o(e.key);b[e.key]=e;h=a.data(j.parentNode,"tmplItem");h=h?h.key:0}if(e){k=e;while(k&&k.key!=h){k.nodes.push(j);k=k.parent}delete e._ctnt;delete e._wrap;a.data(j,"tmplItem",e)}function o(a){a=a+n;e=l[a]=l[a]||g(e,b[e.parent.key+n]||e.parent)}}}function u(a,d,c,b){if(!a)return l.pop();l.push({_:a,tmpl:d,item:this,data:c,options:b})}function w(d,c,b){return a.tmpl(a.template(d),c,b,this)}function x(b,d){var c=b.options||{};c.wrapped=d;return a.tmpl(a.template(b.tmpl),b.data,c,b.item)}function v(d,c){var b=this._wrap;return a.map(a(a.isArray(b)?b.join(""):b).filter(d||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function t(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]);a(b).remove()}})(jQuery);
diff --git a/Duplicati/Server/webroot/greeno/scripts/jquery.watermark.min.js b/Duplicati/Server/webroot/greeno/scripts/jquery.watermark.min.js
deleted file mode 100755
index 892920868..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jquery.watermark.min.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- Watermark v3.1.4 (August 13, 2012) plugin for jQuery
- http://jquery-watermark.googlecode.com/
- Copyright (c) 2009-2012 Todd Northrop
- http://www.speednet.biz/
- Dual licensed under the MIT or GPL Version 2 licenses.
-*/
-(function(n,t,i){var g="TEXTAREA",d="function",nt="password",c="maxLength",v="type",r="",u=!0,rt="placeholder",h=!1,tt="watermark",s=tt,o="watermarkClass",w="watermarkFocus",a="watermarkSubmit",b="watermarkMaxLength",e="watermarkPassword",f="watermarkText",l=/\r/g,ft=/^(button|checkbox|hidden|image|radio|range|reset|submit)$/i,it="input:data("+s+"),textarea:data("+s+")",p=":watermarkable",k=["Page_ClientValidate"],y=h,ut=rt in document.createElement("input");n.watermark=n.watermark||{version:"3.1.4",runOnce:u,options:{className:tt,useNative:u,hideBeforeUnload:u},hide:function(t){n(t).filter(it).each(function(){n.watermark._hide(n(this))})},_hide:function(n,i){var a=n[0],w=(a.value||r).replace(l,r),h=n.data(f)||r,p=n.data(b)||0,y=n.data(o),s,u;h.length&&w==h&&(a.value=r,n.data(e)&&(n.attr(v)||r)==="text"&&(s=n.data(e)||[],u=n.parent()||[],s.length&&u.length&&(u[0].removeChild(n[0]),u[0].appendChild(s[0]),n=s)),p&&(n.attr(c,p),n.removeData(b)),i&&(n.attr("autocomplete","off"),t.setTimeout(function(){n.select()},1))),y&&n.removeClass(y)},show:function(t){n(t).filter(it).each(function(){n.watermark._show(n(this))})},_show:function(t){var p=t[0],g=(p.value||r).replace(l,r),i=t.data(f)||r,k=t.attr(v)||r,d=t.data(o),h,s,a;g.length!=0&&g!=i||t.data(w)?n.watermark._hide(t):(y=u,t.data(e)&&k===nt&&(h=t.data(e)||[],s=t.parent()||[],h.length&&s.length&&(s[0].removeChild(t[0]),s[0].appendChild(h[0]),t=h,t.attr(c,i.length),p=t[0])),(k==="text"||k==="search")&&(a=t.attr(c)||0,a>0&&i.length>a&&(t.data(b,a),t.attr(c,i.length))),d&&t.addClass(d),p.value=i)},hideAll:function(){y&&(n.watermark.hide(p),y=h)},showAll:function(){n.watermark.show(p)}},n.fn.watermark=n.fn.watermark||function(i,y){var tt="string";if(!this.length)return this;var k=h,b=typeof i==tt;return b&&(i=i.replace(l,r)),typeof y=="object"?(k=typeof y.className==tt,y=n.extend({},n.watermark.options,y)):typeof y==tt?(k=u,y=n.extend({},n.watermark.options,{className:y})):y=n.watermark.options,typeof y.useNative!=d&&(y.useNative=y.useNative?function(){return u}:function(){return h}),this.each(function(){var et="dragleave",ot="dragenter",ft=this,h=n(ft),st,d,tt,it;if(h.is(p)){if(h.data(s))(b||k)&&(n.watermark._hide(h),b&&h.data(f,i),k&&h.data(o,y.className));else{if(ut&&y.useNative.call(ft,h)&&(h.attr("tagName")||r)!==g){b&&h.attr(rt,i);return}h.data(f,b?i:r),h.data(o,y.className),h.data(s,1),(h.attr(v)||r)===nt?(st=h.wrap("<span>").parent(),d=n(st.html().replace(/type=["']?password["']?/i,'type="text"')),d.data(f,h.data(f)),d.data(o,h.data(o)),d.data(s,1),d.attr(c,i.length),d.focus(function(){n.watermark._hide(d,u)}).bind(ot,function(){n.watermark._hide(d)}).bind("dragend",function(){t.setTimeout(function(){d.blur()},1)}),h.blur(function(){n.watermark._show(h)}).bind(et,function(){n.watermark._show(h)}),d.data(e,h),h.data(e,d)):h.focus(function(){h.data(w,1),n.watermark._hide(h,u)}).blur(function(){h.data(w,0),n.watermark._show(h)}).bind(ot,function(){n.watermark._hide(h)}).bind(et,function(){n.watermark._show(h)}).bind("dragend",function(){t.setTimeout(function(){n.watermark._show(h)},1)}).bind("drop",function(n){var i=h[0],t=n.originalEvent.dataTransfer.getData("Text");(i.value||r).replace(l,r).replace(t,r)===h.data(f)&&(i.value=t),h.focus()}),ft.form&&(tt=ft.form,it=n(tt),it.data(a)||(it.submit(n.watermark.hideAll),tt.submit?(it.data(a,tt.submit),tt.submit=function(t,i){return function(){var r=i.data(a);n.watermark.hideAll(),r.apply?r.apply(t,Array.prototype.slice.call(arguments)):r()}}(tt,it)):(it.data(a,1),tt.submit=function(t){return function(){n.watermark.hideAll(),delete t.submit,t.submit()}}(tt))))}n.watermark._show(h)}})},n.watermark.runOnce&&(n.watermark.runOnce=h,n.extend(n.expr[":"],{data:n.expr.createPseudo?n.expr.createPseudo(function(t){return function(i){return!!n.data(i,t)}}):function(t,i,r){return!!n.data(t,r[3])},watermarkable:function(n){var t,i=n.nodeName;return i===g?u:i!=="INPUT"?h:(t=n.getAttribute(v),!t||!ft.test(t))}}),function(t){n.fn.val=function(){var u=this,e=Array.prototype.slice.call(arguments),o;return u.length?e.length?(t.apply(u,e),n.watermark.show(u),u):u.data(s)?(o=(u[0].value||r).replace(l,r),o===(u.data(f)||r)?r:o):t.apply(u):e.length?u:i}}(n.fn.val),k.length&&n(function(){for(var u,r,i=k.length-1;i>=0;i--)u=k[i],r=t[u],typeof r==d&&(t[u]=function(t){return function(){return n.watermark.hideAll(),t.apply(null,Array.prototype.slice.call(arguments))}}(r))}),n(t).bind("beforeunload",function(){n.watermark.options.hideBeforeUnload&&n.watermark.hideAll()}))})(jQuery,window);
diff --git a/Duplicati/Server/webroot/greeno/scripts/json2.js b/Duplicati/Server/webroot/greeno/scripts/json2.js
deleted file mode 100644
index deb88ec9a..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/json2.js
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- json2.js
- 2014-02-04
-
- Public Domain.
-
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
- See http://www.JSON.org/js.html
-
-
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
-
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
-
-
- This file creates a global JSON object containing two methods: stringify
- and parse.
-
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
-
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
-
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or '&nbsp;'),
- it contains the characters used to indent at each level.
-
- This method produces a JSON text from a JavaScript value.
-
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
-
- For example, this would serialize Dates as ISO strings.
-
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
-
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
-
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
-
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
-
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
-
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
-
- Example:
-
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
-
-
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date ?
- 'Date(' + this[key] + ')' : value;
- });
- // text is '["Date(---current time---)"]'
-
-
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
-
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
-
- Example:
-
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
-
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
-
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
-
-
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
-*/
-
-/*jslint evil: true, regexp: true */
-
-/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-if (typeof JSON !== 'object') {
- JSON = {};
-}
-
-(function () {
- 'use strict';
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function () {
-
- return isFinite(this.valueOf())
- ? this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z'
- : null;
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function () {
- return this.valueOf();
- };
- }
-
- var cx,
- escapable,
- gap,
- indent,
- meta,
- rep;
-
-
- function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string'
- ? c
- : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' : '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
-// Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
-// What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
- return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
- case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
-// Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
-// Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
- v = partial.length === 0
- ? '[]'
- : gap
- ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
- : '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === 'string') {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
- v = partial.length === 0
- ? '{}'
- : gap
- ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
- : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- };
- JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
-// If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
- JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/
- .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
- .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function'
- ? walk({'': j}, '')
- : j;
- }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
diff --git a/Duplicati/Server/webroot/greeno/scripts/jstree.js b/Duplicati/Server/webroot/greeno/scripts/jstree.js
deleted file mode 100755
index c0ababf5d..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jstree.js
+++ /dev/null
@@ -1,5799 +0,0 @@
-/*globals jQuery, define, exports, require, window, document */
-(function (factory) {
- "use strict";
- if (typeof define === 'function' && define.amd) {
- define(['jquery'], factory);
- }
- else if(typeof exports === 'object') {
- factory(require('jquery'));
- }
- else {
- factory(jQuery);
- }
-}(function ($, undefined) {
- "use strict";
-/*!
- * jsTree 3.0.0
- * http://jstree.com/
- *
- * Copyright (c) 2013 Ivan Bozhanov (http://vakata.com)
- *
- * Licensed same as jquery - under the terms of the MIT License
- * http://www.opensource.org/licenses/mit-license.php
- */
-/*!
- * if using jslint please allow for the jQuery global and use following options:
- * jslint: browser: true, ass: true, bitwise: true, continue: true, nomen: true, plusplus: true, regexp: true, unparam: true, todo: true, white: true
- */
-
- // prevent another load? maybe there is a better way?
- if($.jstree) {
- return;
- }
-
- /**
- * ### jsTree core functionality
- */
-
- // internal variables
- var instance_counter = 0,
- ccp_node = false,
- ccp_mode = false,
- ccp_inst = false,
- themes_loaded = [],
- src = $('script:last').attr('src'),
- _d = document, _node = _d.createElement('LI'), _temp1, _temp2;
-
- _node.setAttribute('role', 'treeitem');
- _temp1 = _d.createElement('I');
- _temp1.className = 'jstree-icon jstree-ocl';
- _node.appendChild(_temp1);
- _temp1 = _d.createElement('A');
- _temp1.className = 'jstree-anchor';
- _temp1.setAttribute('href','#');
- _temp2 = _d.createElement('I');
- _temp2.className = 'jstree-icon jstree-themeicon';
- _temp1.appendChild(_temp2);
- _node.appendChild(_temp1);
- _temp1 = _temp2 = null;
-
-
- /**
- * holds all jstree related functions and variables, including the actual class and methods to create, access and manipulate instances.
- * @name $.jstree
- */
- $.jstree = {
- /**
- * specifies the jstree version in use
- * @name $.jstree.version
- */
- version : '3.0.0-beta9',
- /**
- * holds all the default options used when creating new instances
- * @name $.jstree.defaults
- */
- defaults : {
- /**
- * configure which plugins will be active on an instance. Should be an array of strings, where each element is a plugin name. The default is `[]`
- * @name $.jstree.defaults.plugins
- */
- plugins : []
- },
- /**
- * stores all loaded jstree plugins (used internally)
- * @name $.jstree.plugins
- */
- plugins : {},
- path : src && src.indexOf('/') !== -1 ? src.replace(/\/[^\/]+$/,'') : ''
- };
- /**
- * creates a jstree instance
- * @name $.jstree.create(el [, options])
- * @param {DOMElement|jQuery|String} el the element to create the instance on, can be jQuery extended or a selector
- * @param {Object} options options for this instance (extends `$.jstree.defaults`)
- * @return {jsTree} the new instance
- */
- $.jstree.create = function (el, options) {
- var tmp = new $.jstree.core(++instance_counter),
- opt = options;
- options = $.extend(true, {}, $.jstree.defaults, options);
- if(opt && opt.plugins) {
- options.plugins = opt.plugins;
- }
- $.each(options.plugins, function (i, k) {
- if(i !== 'core') {
- tmp = tmp.plugin(k, options[k]);
- }
- });
- tmp.init(el, options);
- return tmp;
- };
- /**
- * the jstree class constructor, used only internally
- * @private
- * @name $.jstree.core(id)
- * @param {Number} id this instance's index
- */
- $.jstree.core = function (id) {
- this._id = id;
- this._cnt = 0;
- this._data = {
- core : {
- themes : {
- name : false,
- dots : false,
- icons : false
- },
- selected : [],
- last_error : {}
- }
- };
- };
- /**
- * get a reference to an existing instance
- *
- * __Examples__
- *
- * // provided a container with an ID of "tree", and a nested node with an ID of "branch"
- * // all of there will return the same instance
- * $.jstree.reference('tree');
- * $.jstree.reference('#tree');
- * $.jstree.reference($('#tree'));
- * $.jstree.reference(document.getElementByID('tree'));
- * $.jstree.reference('branch');
- * $.jstree.reference('#branch');
- * $.jstree.reference($('#branch'));
- * $.jstree.reference(document.getElementByID('branch'));
- *
- * @name $.jstree.reference(needle)
- * @param {DOMElement|jQuery|String} needle
- * @return {jsTree|null} the instance or `null` if not found
- */
- $.jstree.reference = function (needle) {
- if(needle && !$(needle).length) {
- if(needle.id) {
- needle = needle.id;
- }
- var tmp = null;
- $('.jstree').each(function () {
- var inst = $(this).data('jstree');
- if(inst && inst._model.data[needle]) {
- tmp = inst;
- return false;
- }
- });
- return tmp;
- }
- return $(needle).closest('.jstree').data('jstree');
- };
- /**
- * Create an instance, get an instance or invoke a command on a instance.
- *
- * If there is no instance associated with the current node a new one is created and `arg` is used to extend `$.jstree.defaults` for this new instance. There would be no return value (chaining is not broken).
- *
- * If there is an existing instance and `arg` is a string the command specified by `arg` is executed on the instance, with any additional arguments passed to the function. If the function returns a value it will be returned (chaining could break depending on function).
- *
- * If there is an existing instance and `arg` is not a string the instance itself is returned (similar to `$.jstree.reference`).
- *
- * In any other case - nothing is returned and chaining is not broken.
- *
- * __Examples__
- *
- * $('#tree1').jstree(); // creates an instance
- * $('#tree2').jstree({ plugins : [] }); // create an instance with some options
- * $('#tree1').jstree('open_node', '#branch_1'); // call a method on an existing instance, passing additional arguments
- * $('#tree2').jstree(); // get an existing instance (or create an instance)
- * $('#tree2').jstree(true); // get an existing instance (will not create new instance)
- * $('#branch_1').jstree().select_node('#branch_1'); // get an instance (using a nested element and call a method)
- *
- * @name $().jstree([arg])
- * @param {String|Object} arg
- * @return {Mixed}
- */
- $.fn.jstree = function (arg) {
- // check for string argument
- var is_method = (typeof arg === 'string'),
- args = Array.prototype.slice.call(arguments, 1),
- result = null;
- this.each(function () {
- // get the instance (if there is one) and method (if it exists)
- var instance = $.jstree.reference(this),
- method = is_method && instance ? instance[arg] : null;
- // if calling a method, and method is available - execute on the instance
- result = is_method && method ?
- method.apply(instance, args) :
- null;
- // if there is no instance and no method is being called - create one
- if(!instance && !is_method && (arg === undefined || $.isPlainObject(arg))) {
- $(this).data('jstree', new $.jstree.create(this, arg));
- }
- // if there is an instance and no method is called - return the instance
- if(instance && !is_method) {
- result = instance;
- }
- // if there was a method call which returned a result - break and return the value
- if(result !== null && result !== undefined) {
- return false;
- }
- });
- // if there was a method call with a valid return value - return that, otherwise continue the chain
- return result !== null && result !== undefined ?
- result : this;
- };
- /**
- * used to find elements containing an instance
- *
- * __Examples__
- *
- * $('div:jstree').each(function () {
- * $(this).jstree('destroy');
- * });
- *
- * @name $(':jstree')
- * @return {jQuery}
- */
- $.expr[':'].jstree = $.expr.createPseudo(function(search) {
- return function(a) {
- return $(a).hasClass('jstree') &&
- $(a).data('jstree') !== undefined;
- };
- });
-
- /**
- * stores all defaults for the core
- * @name $.jstree.defaults.core
- */
- $.jstree.defaults.core = {
- /**
- * data configuration
- *
- * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items).
- *
- * You can also pass in a HTML string or a JSON array here.
- *
- * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree.
- * In addition to the standard jQuery ajax options here you can suppy functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used.
- *
- * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result.
- *
- * __Examples__
- *
- * // AJAX
- * $('#tree').jstree({
- * 'core' : {
- * 'data' : {
- * 'url' : '/get/children/',
- * 'data' : function (node) {
- * return { 'id' : node.id };
- * }
- * }
- * });
- *
- * // direct data
- * $('#tree').jstree({
- * 'core' : {
- * 'data' : [
- * 'Simple root node',
- * {
- * 'id' : 'node_2',
- * 'text' : 'Root node with options',
- * 'state' : { 'opened' : true, 'selected' : true },
- * 'children' : [ { 'text' : 'Child 1' }, 'Child 2']
- * }
- * ]
- * });
- *
- * // function
- * $('#tree').jstree({
- * 'core' : {
- * 'data' : function (obj, callback) {
- * callback.call(this, ['Root 1', 'Root 2']);
- * }
- * });
- *
- * @name $.jstree.defaults.core.data
- */
- data : false,
- /**
- * configure the various strings used throughout the tree
- *
- * You can use an object where the key is the string you need to replace and the value is your replacement.
- * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement.
- * If left as `false` no replacement is made.
- *
- * __Examples__
- *
- * $('#tree').jstree({
- * 'core' : {
- * 'strings' : {
- * 'Loading...' : 'Please wait ...'
- * }
- * }
- * });
- *
- * @name $.jstree.defaults.core.strings
- */
- strings : false,
- /**
- * determines what happens when a user tries to modify the structure of the tree
- * If left as `false` all operations like create, rename, delete, move or copy are prevented.
- * You can set this to `true` to allow all interactions or use a function to have better control.
- *
- * __Examples__
- *
- * $('#tree').jstree({
- * 'core' : {
- * 'check_callback' : function (operation, node, node_parent, node_position) {
- * // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node' or 'copy_node'
- * // in case of 'rename_node' node_position is filled with the new node name
- * return operation === 'rename_node' ? true : false;
- * }
- * }
- * });
- *
- * @name $.jstree.defaults.core.check_callback
- */
- check_callback : false,
- /**
- * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc)
- * @name $.jstree.defaults.core.error
- */
- error : $.noop,
- /**
- * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`)
- * @name $.jstree.defaults.core.animation
- */
- animation : 200,
- /**
- * a boolean indicating if multiple nodes can be selected
- * @name $.jstree.defaults.core.multiple
- */
- multiple : true,
- /**
- * theme configuration object
- * @name $.jstree.defaults.core.themes
- */
- themes : {
- /**
- * the name of the theme to use (if left as `false` the default theme is used)
- * @name $.jstree.defaults.core.themes.name
- */
- name : false,
- /**
- * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme.
- * @name $.jstree.defaults.core.themes.url
- */
- url : false,
- /**
- * the location of all jstree themes - only used if `url` is set to `true`
- * @name $.jstree.defaults.core.themes.dir
- */
- dir : false,
- /**
- * a boolean indicating if connecting dots are shown
- * @name $.jstree.defaults.core.themes.dots
- */
- dots : true,
- /**
- * a boolean indicating if node icons are shown
- * @name $.jstree.defaults.core.themes.icons
- */
- icons : true,
- /**
- * a boolean indicating if the tree background is striped
- * @name $.jstree.defaults.core.themes.stripes
- */
- stripes : false,
- /**
- * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants)
- * @name $.jstree.defaults.core.themes.variant
- */
- variant : false,
- /**
- * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `true`.
- * @name $.jstree.defaults.core.themes.responsive
- */
- responsive : true
- },
- /**
- * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user)
- * @name $.jstree.defaults.core.expand_selected_onload
- */
- expand_selected_onload : true
- };
- $.jstree.core.prototype = {
- /**
- * used to decorate an instance with a plugin. Used internally.
- * @private
- * @name plugin(deco [, opts])
- * @param {String} deco the plugin to decorate with
- * @param {Object} opts options for the plugin
- * @return {jsTree}
- */
- plugin : function (deco, opts) {
- var Child = $.jstree.plugins[deco];
- if(Child) {
- this._data[deco] = {};
- Child.prototype = this;
- return new Child(opts, this);
- }
- return this;
- },
- /**
- * used to decorate an instance with a plugin. Used internally.
- * @private
- * @name init(el, optons)
- * @param {DOMElement|jQuery|String} el the element we are transforming
- * @param {Object} options options for this instance
- * @trigger init.jstree, loading.jstree, loaded.jstree, ready.jstree, changed.jstree
- */
- init : function (el, options) {
- this._model = {
- data : {
- '#' : {
- id : '#',
- parent : null,
- parents : [],
- children : [],
- children_d : [],
- state : { loaded : false }
- }
- },
- changed : [],
- force_full_redraw : false,
- redraw_timeout : false,
- default_state : {
- loaded : true,
- opened : false,
- selected : false,
- disabled : false
- }
- };
-
- this.element = $(el).addClass('jstree jstree-' + this._id);
- this.settings = options;
- this.element.bind("destroyed", $.proxy(this.teardown, this));
-
- this._data.core.ready = false;
- this._data.core.loaded = false;
- this._data.core.rtl = (this.element.css("direction") === "rtl");
- this.element[this._data.core.rtl ? 'addClass' : 'removeClass']("jstree-rtl");
- this.element.attr('role','tree');
-
- this.bind();
- /**
- * triggered after all events are bound
- * @event
- * @name init.jstree
- */
- this.trigger("init");
-
- this._data.core.original_container_html = this.element.find(" > ul > li").clone(true);
- this._data.core.original_container_html
- .find("li").addBack()
- .contents().filter(function() {
- return this.nodeType === 3 && (!this.nodeValue || /^\s+$/.test(this.nodeValue));
- })
- .remove();
- this.element.html("<"+"ul class='jstree-container-ul'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>");
- this._data.core.li_height = this.get_container_ul().children("li:eq(0)").height() || 18;
- /**
- * triggered after the loading text is shown and before loading starts
- * @event
- * @name loading.jstree
- */
- this.trigger("loading");
- this.load_node('#');
- },
- /**
- * destroy an instance
- * @name destroy()
- */
- destroy : function () {
- this.element.unbind("destroyed", this.teardown);
- this.teardown();
- },
- /**
- * part of the destroying of an instance. Used internally.
- * @private
- * @name teardown()
- */
- teardown : function () {
- this.unbind();
- this.element
- .removeClass('jstree')
- .removeData('jstree')
- .find("[class^='jstree']")
- .addBack()
- .attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); });
- this.element = null;
- },
- /**
- * bind all events. Used internally.
- * @private
- * @name bind()
- */
- bind : function () {
- this.element
- .on("dblclick.jstree", function () {
- if(document.selection && document.selection.empty) {
- document.selection.empty();
- }
- else {
- if(window.getSelection) {
- var sel = window.getSelection();
- try {
- sel.removeAllRanges();
- sel.collapse();
- } catch (ignore) { }
- }
- }
- })
- .on("click.jstree", ".jstree-ocl", $.proxy(function (e) {
- this.toggle_node(e.target);
- }, this))
- .on("click.jstree", ".jstree-anchor", $.proxy(function (e) {
- e.preventDefault();
- $(e.currentTarget).focus();
- this.activate_node(e.currentTarget, e);
- }, this))
- .on('keydown.jstree', '.jstree-anchor', $.proxy(function (e) {
- var o = null;
- switch(e.which) {
- case 13:
- case 32:
- e.type = "click";
- $(e.currentTarget).trigger(e);
- break;
- case 37:
- e.preventDefault();
- if(this.is_open(e.currentTarget)) {
- this.close_node(e.currentTarget);
- }
- else {
- o = this.get_prev_dom(e.currentTarget);
- if(o && o.length) { o.children('.jstree-anchor').focus(); }
- }
- break;
- case 38:
- e.preventDefault();
- o = this.get_prev_dom(e.currentTarget);
- if(o && o.length) { o.children('.jstree-anchor').focus(); }
- break;
- case 39:
- e.preventDefault();
- if(this.is_closed(e.currentTarget)) {
- this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').focus(); });
- }
- else {
- o = this.get_next_dom(e.currentTarget);
- if(o && o.length) { o.children('.jstree-anchor').focus(); }
- }
- break;
- case 40:
- e.preventDefault();
- o = this.get_next_dom(e.currentTarget);
- if(o && o.length) { o.children('.jstree-anchor').focus(); }
- break;
- // delete
- case 46:
- e.preventDefault();
- o = this.get_node(e.currentTarget);
- if(o && o.id && o.id !== '#') {
- o = this.is_selected(o) ? this.get_selected() : o;
- // this.delete_node(o);
- }
- break;
- // f2
- case 113:
- e.preventDefault();
- o = this.get_node(e.currentTarget);
- /*!
- if(o && o.id && o.id !== '#') {
- // this.edit(o);
- }
- */
- break;
- default:
- // console.log(e.which);
- break;
- }
- }, this))
- .on("load_node.jstree", $.proxy(function (e, data) {
- if(data.status) {
- if(data.node.id === '#' && !this._data.core.loaded) {
- this._data.core.loaded = true;
- /**
- * triggered after the root node is loaded for the first time
- * @event
- * @name loaded.jstree
- */
- this.trigger("loaded");
- }
- if(!this._data.core.ready && !this.get_container_ul().find('.jstree-loading:eq(0)').length) {
- this._data.core.ready = true;
- if(this._data.core.selected.length) {
- if(this.settings.core.expand_selected_onload) {
- var tmp = [], i, j;
- for(i = 0, j = this._data.core.selected.length; i < j; i++) {
- tmp = tmp.concat(this._model.data[this._data.core.selected[i]].parents);
- }
- tmp = $.vakata.array_unique(tmp);
- for(i = 0, j = tmp.length; i < j; i++) {
- this.open_node(tmp[i], false, 0);
- }
- }
- this.trigger('changed', { 'action' : 'ready', 'selected' : this._data.core.selected });
- }
- /**
- * triggered after all nodes are finished loading
- * @event
- * @name ready.jstree
- */
- setTimeout($.proxy(function () { this.trigger("ready"); }, this), 0);
- }
- }
- }, this))
- // THEME RELATED
- .on("init.jstree", $.proxy(function () {
- var s = this.settings.core.themes;
- this._data.core.themes.dots = s.dots;
- this._data.core.themes.stripes = s.stripes;
- this._data.core.themes.icons = s.icons;
- this.set_theme(s.name || "default", s.url);
- this.set_theme_variant(s.variant);
- }, this))
- .on("loading.jstree", $.proxy(function () {
- this[ this._data.core.themes.dots ? "show_dots" : "hide_dots" ]();
- this[ this._data.core.themes.icons ? "show_icons" : "hide_icons" ]();
- this[ this._data.core.themes.stripes ? "show_stripes" : "hide_stripes" ]();
- }, this))
- .on('focus.jstree', '.jstree-anchor', $.proxy(function (e) {
- this.element.find('.jstree-hovered').not(e.currentTarget).mouseleave();
- $(e.currentTarget).mouseenter();
- }, this))
- .on('mouseenter.jstree', '.jstree-anchor', $.proxy(function (e) {
- this.hover_node(e.currentTarget);
- }, this))
- .on('mouseleave.jstree', '.jstree-anchor', $.proxy(function (e) {
- this.dehover_node(e.currentTarget);
- }, this));
- },
- /**
- * part of the destroying of an instance. Used internally.
- * @private
- * @name unbind()
- */
- unbind : function () {
- this.element.off('.jstree');
- $(document).off('.jstree-' + this._id);
- },
- /**
- * trigger an event. Used internally.
- * @private
- * @name trigger(ev [, data])
- * @param {String} ev the name of the event to trigger
- * @param {Object} data additional data to pass with the event
- */
- trigger : function (ev, data) {
- if(!data) {
- data = {};
- }
- data.instance = this;
- this.element.triggerHandler(ev.replace('.jstree','') + '.jstree', data);
- },
- /**
- * returns the jQuery extended instance container
- * @name get_container()
- * @return {jQuery}
- */
- get_container : function () {
- return this.element;
- },
- /**
- * returns the jQuery extended main UL node inside the instance container. Used internally.
- * @private
- * @name get_container_ul()
- * @return {jQuery}
- */
- get_container_ul : function () {
- return this.element.children("ul:eq(0)");
- },
- /**
- * gets string replacements (localization). Used internally.
- * @private
- * @name get_string(key)
- * @param {String} key
- * @return {String}
- */
- get_string : function (key) {
- var a = this.settings.core.strings;
- if($.isFunction(a)) { return a.call(this, key); }
- if(a && a[key]) { return a[key]; }
- return key;
- },
- /**
- * gets the first child of a DOM node. Used internally.
- * @private
- * @name _firstChild(dom)
- * @param {DOMElement} dom
- * @return {DOMElement}
- */
- _firstChild : function (dom) {
- dom = dom ? dom.firstChild : null;
- while(dom !== null && dom.nodeType !== 1) {
- dom = dom.nextSibling;
- }
- return dom;
- },
- /**
- * gets the next sibling of a DOM node. Used internally.
- * @private
- * @name _nextSibling(dom)
- * @param {DOMElement} dom
- * @return {DOMElement}
- */
- _nextSibling : function (dom) {
- dom = dom ? dom.nextSibling : null;
- while(dom !== null && dom.nodeType !== 1) {
- dom = dom.nextSibling;
- }
- return dom;
- },
- /**
- * gets the previous sibling of a DOM node. Used internally.
- * @private
- * @name _previousSibling(dom)
- * @param {DOMElement} dom
- * @return {DOMElement}
- */
- _previousSibling : function (dom) {
- dom = dom ? dom.previousSibling : null;
- while(dom !== null && dom.nodeType !== 1) {
- dom = dom.previousSibling;
- }
- return dom;
- },
- /**
- * get the JSON representation of a node (or the actual jQuery extended DOM node) by using any input (child DOM element, ID string, selector, etc)
- * @name get_node(obj [, as_dom])
- * @param {mixed} obj
- * @param {Boolean} as_dom
- * @return {Object|jQuery}
- */
- get_node : function (obj, as_dom) {
- if(obj && obj.id) {
- obj = obj.id;
- }
- var dom;
- try {
- if(this._model.data[obj]) {
- obj = this._model.data[obj];
- }
- else if(((dom = $(obj, this.element)).length || (dom = $('#' + obj, this.element)).length) && this._model.data[dom.closest('li').attr('id')]) {
- obj = this._model.data[dom.closest('li').attr('id')];
- }
- else if((dom = $(obj, this.element)).length && dom.hasClass('jstree')) {
- obj = this._model.data['#'];
- }
- else {
- return false;
- }
-
- if(as_dom) {
- obj = obj.id === '#' ? this.element : $(document.getElementById(obj.id));
- }
- return obj;
- } catch (ex) { return false; }
- },
- /**
- * get the path to a node, either consisting of node texts, or of node IDs, optionally glued together (otherwise an array)
- * @name get_path(obj [, glue, ids])
- * @param {mixed} obj the node
- * @param {String} glue if you want the path as a string - pass the glue here (for example '/'), if a falsy value is supplied here, an array is returned
- * @param {Boolean} ids if set to true build the path using ID, otherwise node text is used
- * @return {mixed}
- */
- get_path : function (obj, glue, ids) {
- obj = obj.parents ? obj : this.get_node(obj);
- if(!obj || obj.id === '#' || !obj.parents) {
- return false;
- }
- var i, j, p = [];
- p.push(ids ? obj.id : obj.text);
- for(i = 0, j = obj.parents.length; i < j; i++) {
- p.push(ids ? obj.parents[i] : this.get_text(obj.parents[i]));
- }
- p = p.reverse().slice(1);
- return glue ? p.join(glue) : p;
- },
- /**
- * get the next visible node that is below the `obj` node. If `strict` is set to `true` only sibling nodes are returned.
- * @name get_next_dom(obj [, strict])
- * @param {mixed} obj
- * @param {Boolean} strict
- * @return {jQuery}
- */
- get_next_dom : function (obj, strict) {
- var tmp;
- obj = this.get_node(obj, true);
- if(obj[0] === this.element[0]) {
- tmp = this._firstChild(this.get_container_ul()[0]);
- return tmp ? $(tmp) : false;
- }
- if(!obj || !obj.length) {
- return false;
- }
- if(strict) {
- tmp = this._nextSibling(obj[0]);
- return tmp ? $(tmp) : false;
- }
- if(obj.hasClass("jstree-open")) {
- tmp = this._firstChild(obj.children('ul')[0]);
- return tmp ? $(tmp) : false;
- }
- if((tmp = this._nextSibling(obj[0])) !== null) {
- return $(tmp);
- }
- return obj.parentsUntil(".jstree","li").next("li").eq(0);
- },
- /**
- * get the previous visible node that is above the `obj` node. If `strict` is set to `true` only sibling nodes are returned.
- * @name get_prev_dom(obj [, strict])
- * @param {mixed} obj
- * @param {Boolean} strict
- * @return {jQuery}
- */
- get_prev_dom : function (obj, strict) {
- var tmp;
- obj = this.get_node(obj, true);
- if(obj[0] === this.element[0]) {
- tmp = this.get_container_ul()[0].lastChild;
- return tmp ? $(tmp) : false;
- }
- if(!obj || !obj.length) {
- return false;
- }
- if(strict) {
- tmp = this._previousSibling(obj[0]);
- return tmp ? $(tmp) : false;
- }
- if((tmp = this._previousSibling(obj[0])) !== null) {
- obj = $(tmp);
- while(obj.hasClass("jstree-open")) {
- obj = obj.children("ul:eq(0)").children("li:last");
- }
- return obj;
- }
- tmp = obj[0].parentNode.parentNode;
- return tmp && tmp.tagName === 'LI' ? $(tmp) : false;
- },
- /**
- * get the parent ID of a node
- * @name get_parent(obj)
- * @param {mixed} obj
- * @return {String}
- */
- get_parent : function (obj) {
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') {
- return false;
- }
- return obj.parent;
- },
- /**
- * get a jQuery collection of all the children of a node (node must be rendered)
- * @name get_children_dom(obj)
- * @param {mixed} obj
- * @return {jQuery}
- */
- get_children_dom : function (obj) {
- obj = this.get_node(obj, true);
- if(obj[0] === this.element[0]) {
- return this.get_container_ul().children("li");
- }
- if(!obj || !obj.length) {
- return false;
- }
- return obj.children("ul").children("li");
- },
- /**
- * checks if a node has children
- * @name is_parent(obj)
- * @param {mixed} obj
- * @return {Boolean}
- */
- is_parent : function (obj) {
- obj = this.get_node(obj);
- return obj && (obj.state.loaded === false || obj.children.length > 0);
- },
- /**
- * checks if a node is loaded (its children are available)
- * @name is_loaded(obj)
- * @param {mixed} obj
- * @return {Boolean}
- */
- is_loaded : function (obj) {
- obj = this.get_node(obj);
- return obj && obj.state.loaded;
- },
- /**
- * check if a node is currently loading (fetching children)
- * @name is_loading(obj)
- * @param {mixed} obj
- * @return {Boolean}
- */
- is_loading : function (obj) {
- obj = this.get_node(obj, true);
- return obj && obj.hasClass("jstree-loading");
- },
- /**
- * check if a node is opened
- * @name is_open(obj)
- * @param {mixed} obj
- * @return {Boolean}
- */
- is_open : function (obj) {
- obj = this.get_node(obj);
- return obj && obj.state.opened;
- },
- /**
- * check if a node is in a closed state
- * @name is_closed(obj)
- * @param {mixed} obj
- * @return {Boolean}
- */
- is_closed : function (obj) {
- obj = this.get_node(obj);
- return obj && this.is_parent(obj) && !obj.state.opened;
- },
- /**
- * check if a node has no children
- * @name is_leaf(obj)
- * @param {mixed} obj
- * @return {Boolean}
- */
- is_leaf : function (obj) {
- return !this.is_parent(obj);
- },
- /**
- * loads a node (fetches its children using the `core.data` setting). Multiple nodes can be passed to by using an array.
- * @name load_node(obj [, callback])
- * @param {mixed} obj
- * @param {function} callback a function to be executed once loading is conplete, the function is executed in the instance's scope and receives two arguments - the node and a boolean status
- * @return {Boolean}
- * @trigger load_node.jstree
- */
- load_node : function (obj, callback) {
- var t1, t2;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.load_node(obj[t1], callback);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj) {
- callback.call(this, obj, false);
- return false;
- }
- this.get_node(obj, true).addClass("jstree-loading");
- this._load_node(obj, $.proxy(function (status) {
- obj.state.loaded = status;
- this.get_node(obj, true).removeClass("jstree-loading");
- /**
- * triggered after a node is loaded
- * @event
- * @name load_node.jstree
- * @param {Object} node the node that was loading
- * @param {Boolean} status was the node loaded successfully
- */
- this.trigger('load_node', { "node" : obj, "status" : status });
- if(callback) {
- callback.call(this, obj, status);
- }
- }, this));
- return true;
- },
- /**
- * handles the actual loading of a node. Used only internally.
- * @private
- * @name _load_node(obj [, callback])
- * @param {mixed} obj
- * @param {function} callback a function to be executed once loading is conplete, the function is executed in the instance's scope and receives one argument - a boolean status
- * @return {Boolean}
- */
- _load_node : function (obj, callback) {
- var s = this.settings.core.data, t;
- // use original HTML
- if(!s) {
- return callback.call(this, obj.id === '#' ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false);
- }
- if($.isFunction(s)) {
- return s.call(this, obj, $.proxy(function (d) {
- return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d));
- }, this));
- }
- if(typeof s === 'object') {
- if(s.url) {
- s = $.extend(true, {}, s);
- if($.isFunction(s.url)) {
- s.url = s.url.call(this, obj);
- }
- if($.isFunction(s.data)) {
- s.data = s.data.call(this, obj);
- }
- return $.ajax(s)
- .done($.proxy(function (d,t,x) {
- var type = x.getResponseHeader('Content-Type');
- if(type.indexOf('json') !== -1) {
- return callback.call(this, this._append_json_data(obj, d));
- }
- if(type.indexOf('html') !== -1) {
- return callback.call(this, this._append_html_data(obj, $(d)));
- }
- }, this))
- .fail($.proxy(function () {
- callback.call(this, false);
- this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify(s) };
- this.settings.core.error.call(this, this._data.core.last_error);
- }, this));
- }
- t = ($.isArray(s) || $.isPlainObject(s)) ? JSON.parse(JSON.stringify(s)) : s;
- return callback.call(this, this._append_json_data(obj, t));
- }
- if(typeof s === 'string') {
- return callback.call(this, this._append_html_data(obj, s));
- }
- return callback.call(this, false);
- },
- /**
- * adds a node to the list of nodes to redraw. Used only internally.
- * @private
- * @name _node_changed(obj [, callback])
- * @param {mixed} obj
- */
- _node_changed : function (obj) {
- obj = this.get_node(obj);
- if(obj) {
- this._model.changed.push(obj.id);
- }
- },
- /**
- * appends HTML content to the tree. Used internally.
- * @private
- * @name _append_html_data(obj, data)
- * @param {mixed} obj the node to append to
- * @param {String} data the HTML string to parse and append
- * @return {Boolean}
- * @trigger model.jstree, changed.jstree
- */
- _append_html_data : function (dom, data) {
- dom = this.get_node(dom);
- dom.children = [];
- dom.children_d = [];
- var dat = data.is('ul') ? data.children() : data,
- par = dom.id,
- chd = [],
- dpc = [],
- m = this._model.data,
- p = m[par],
- s = this._data.core.selected.length,
- tmp, i, j;
- dat.each($.proxy(function (i, v) {
- tmp = this._parse_model_from_html($(v), par, p.parents.concat());
- if(tmp) {
- chd.push(tmp);
- dpc.push(tmp);
- if(m[tmp].children_d.length) {
- dpc = dpc.concat(m[tmp].children_d);
- }
- }
- }, this));
- p.children = chd;
- p.children_d = dpc;
- for(i = 0, j = p.parents.length; i < j; i++) {
- m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);
- }
- /**
- * triggered when new data is inserted to the tree model
- * @event
- * @name model.jstree
- * @param {Array} nodes an array of node IDs
- * @param {String} parent the parent ID of the nodes
- */
- this.trigger('model', { "nodes" : dpc, 'parent' : par });
- if(par !== '#') {
- this._node_changed(par);
- this.redraw();
- }
- else {
- this.get_container_ul().children('.jstree-initial-node').remove();
- this.redraw(true);
- }
- if(this._data.core.selected.length !== s) {
- this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected });
- }
- return true;
- },
- /**
- * appends JSON content to the tree. Used internally.
- * @private
- * @name _append_json_data(obj, data)
- * @param {mixed} obj the node to append to
- * @param {String} data the JSON object to parse and append
- * @return {Boolean}
- */
- _append_json_data : function (dom, data) {
- dom = this.get_node(dom);
- dom.children = [];
- dom.children_d = [];
- var dat = data,
- par = dom.id,
- chd = [],
- dpc = [],
- m = this._model.data,
- p = m[par],
- s = this._data.core.selected.length,
- tmp, i, j;
- // *%$@!!!
- if(dat.d) {
- dat = dat.d;
- if(typeof dat === "string") {
- dat = JSON.parse(dat);
- }
- }
- if(!$.isArray(dat)) { dat = [dat]; }
- if(dat.length && dat[0].id !== undefined && dat[0].parent !== undefined) {
- // Flat JSON support (for easy import from DB):
- // 1) convert to object (foreach)
- for(i = 0, j = dat.length; i < j; i++) {
- if(!dat[i].children) {
- dat[i].children = [];
- }
- m[dat[i].id] = dat[i];
- }
- // 2) populate children (foreach)
- for(i = 0, j = dat.length; i < j; i++) {
- m[dat[i].parent].children.push(dat[i].id);
- // populate parent.children_d
- p.children_d.push(dat[i].id);
- }
- // 3) normalize && populate parents and children_d with recursion
- for(i = 0, j = p.children.length; i < j; i++) {
- tmp = this._parse_model_from_flat_json(m[p.children[i]], par, p.parents.concat());
- dpc.push(tmp);
- if(m[tmp].children_d.length) {
- dpc = dpc.concat(m[tmp].children_d);
- }
- }
- // ?) three_state selection - p.state.selected && t - (if three_state foreach(dat => ch) -> foreach(parents) if(parent.selected) child.selected = true;
- }
- else {
- for(i = 0, j = dat.length; i < j; i++) {
- tmp = this._parse_model_from_json(dat[i], par, p.parents.concat());
- if(tmp) {
- chd.push(tmp);
- dpc.push(tmp);
- if(m[tmp].children_d.length) {
- dpc = dpc.concat(m[tmp].children_d);
- }
- }
- }
- p.children = chd;
- p.children_d = dpc;
- for(i = 0, j = p.parents.length; i < j; i++) {
- m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);
- }
- }
- this.trigger('model', { "nodes" : dpc, 'parent' : par });
-
- if(par !== '#') {
- this._node_changed(par);
- this.redraw();
- }
- else {
- // this.get_container_ul().children('.jstree-initial-node').remove();
- this.redraw(true);
- }
- if(this._data.core.selected.length !== s) {
- this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected });
- }
- return true;
- },
- /**
- * parses a node from a jQuery object and appends them to the in memory tree model. Used internally.
- * @private
- * @name _parse_model_from_html(d [, p, ps])
- * @param {jQuery} d the jQuery object to parse
- * @param {String} p the parent ID
- * @param {Array} ps list of all parents
- * @return {String} the ID of the object added to the model
- */
- _parse_model_from_html : function (d, p, ps) {
- if(!ps) { ps = []; }
- else { ps = [].concat(ps); }
- if(p) { ps.unshift(p); }
- var c, e, m = this._model.data,
- data = {
- id : false,
- text : false,
- icon : true,
- parent : p,
- parents : ps,
- children : [],
- children_d : [],
- data : null,
- state : { },
- li_attr : { id : false },
- a_attr : { href : '#' },
- original : false
- }, i, tmp, tid;
- for(i in this._model.default_state) {
- if(this._model.default_state.hasOwnProperty(i)) {
- data.state[i] = this._model.default_state[i];
- }
- }
- tmp = $.vakata.attributes(d, true);
- $.each(tmp, function (i, v) {
- v = $.trim(v);
- if(!v.length) { return true; }
- data.li_attr[i] = v;
- if(i === 'id') {
- data.id = v;
- }
- });
- tmp = d.children('a').eq(0);
- if(tmp.length) {
- tmp = $.vakata.attributes(tmp, true);
- $.each(tmp, function (i, v) {
- v = $.trim(v);
- if(v.length) {
- data.a_attr[i] = v;
- }
- });
- }
- tmp = d.children("a:eq(0)").length ? d.children("a:eq(0)").clone() : d.clone();
- tmp.children("ins, i, ul").remove();
- tmp = tmp.html();
- tmp = $('<div />').html(tmp);
- data.text = tmp.html();
- tmp = d.data();
- data.data = tmp ? $.extend(true, {}, tmp) : null;
- data.state.opened = d.hasClass('jstree-open');
- data.state.selected = d.children('a').hasClass('jstree-clicked');
- data.state.disabled = d.children('a').hasClass('jstree-disabled');
- if(data.data && data.data.jstree) {
- for(i in data.data.jstree) {
- if(data.data.jstree.hasOwnProperty(i)) {
- data.state[i] = data.data.jstree[i];
- }
- }
- }
- tmp = d.children("a").children(".jstree-themeicon");
- if(tmp.length) {
- data.icon = tmp.hasClass('jstree-themeicon-hidden') ? false : tmp.attr('rel');
- }
- if(data.state.icon) {
- data.icon = data.state.icon;
- }
- tmp = d.children("ul").children("li");
- do {
- tid = 'j' + this._id + '_' + (++this._cnt);
- } while(m[tid]);
- data.id = data.li_attr.id || tid;
- if(tmp.length) {
- tmp.each($.proxy(function (i, v) {
- c = this._parse_model_from_html($(v), data.id, ps);
- e = this._model.data[c];
- data.children.push(c);
- if(e.children_d.length) {
- data.children_d = data.children_d.concat(e.children_d);
- }
- }, this));
- data.children_d = data.children_d.concat(data.children);
- }
- else {
- if(d.hasClass('jstree-closed')) {
- data.state.loaded = false;
- }
- }
- if(data.li_attr['class']) {
- data.li_attr['class'] = data.li_attr['class'].replace('jstree-closed','').replace('jstree-open','');
- }
- if(data.a_attr['class']) {
- data.a_attr['class'] = data.a_attr['class'].replace('jstree-clicked','').replace('jstree-disabled','');
- }
- m[data.id] = data;
- if(data.state.selected) {
- this._data.core.selected.push(data.id);
- }
- return data.id;
- },
- /**
- * parses a node from a JSON object (used when dealing with flat data, which has no nesting of children, but has id and parent properties) and appends it to the in memory tree model. Used internally.
- * @private
- * @name _parse_model_from_flat_json(d [, p, ps])
- * @param {Object} d the JSON object to parse
- * @param {String} p the parent ID
- * @param {Array} ps list of all parents
- * @return {String} the ID of the object added to the model
- */
- _parse_model_from_flat_json : function (d, p, ps) {
- if(!ps) { ps = []; }
- else { ps = ps.concat(); }
- if(p) { ps.unshift(p); }
- var tid = d.id,
- m = this._model.data,
- df = this._model.default_state,
- i, j, c, e,
- tmp = {
- id : tid,
- text : d.text || '',
- icon : d.icon !== undefined ? d.icon : true,
- parent : p,
- parents : ps,
- children : d.children || [],
- children_d : d.children_d || [],
- data : d.data,
- state : { },
- li_attr : { id : false },
- a_attr : { href : '#' },
- original : false
- };
- for(i in df) {
- if(df.hasOwnProperty(i)) {
- tmp.state[i] = df[i];
- }
- }
- if(d && d.data && d.data.jstree && d.data.jstree.icon) {
- tmp.icon = d.data.jstree.icon;
- }
- if(d && d.data) {
- tmp.data = d.data;
- if(d.data.jstree) {
- for(i in d.data.jstree) {
- if(d.data.jstree.hasOwnProperty(i)) {
- tmp.state[i] = d.data.jstree[i];
- }
- }
- }
- }
- if(d && typeof d.state === 'object') {
- for (i in d.state) {
- if(d.state.hasOwnProperty(i)) {
- tmp.state[i] = d.state[i];
- }
- }
- }
- if(d && typeof d.li_attr === 'object') {
- for (i in d.li_attr) {
- if(d.li_attr.hasOwnProperty(i)) {
- tmp.li_attr[i] = d.li_attr[i];
- }
- }
- }
- if(!tmp.li_attr.id) {
- tmp.li_attr.id = tid;
- }
- if(d && typeof d.a_attr === 'object') {
- for (i in d.a_attr) {
- if(d.a_attr.hasOwnProperty(i)) {
- tmp.a_attr[i] = d.a_attr[i];
- }
- }
- }
- if(d && d.children && d.children === true) {
- tmp.state.loaded = false;
- tmp.children = [];
- tmp.children_d = [];
- }
- m[tmp.id] = tmp;
- for(i = 0, j = tmp.children.length; i < j; i++) {
- c = this._parse_model_from_flat_json(m[tmp.children[i]], tmp.id, ps);
- e = m[c];
- tmp.children_d.push(c);
- if(e.children_d.length) {
- tmp.children_d = tmp.children_d.concat(e.children_d);
- }
- }
- delete d.data;
- delete d.children;
- m[tmp.id].original = d;
- if(tmp.state.selected) {
- this._data.core.selected.push(tmp.id);
- }
- return tmp.id;
- },
- /**
- * parses a node from a JSON object and appends it to the in memory tree model. Used internally.
- * @private
- * @name _parse_model_from_json(d [, p, ps])
- * @param {Object} d the JSON object to parse
- * @param {String} p the parent ID
- * @param {Array} ps list of all parents
- * @return {String} the ID of the object added to the model
- */
- _parse_model_from_json : function (d, p, ps) {
- if(!ps) { ps = []; }
- else { ps = ps.concat(); }
- if(p) { ps.unshift(p); }
- var tid = false, i, j, c, e, m = this._model.data, df = this._model.default_state, tmp;
- do {
- tid = 'j' + this._id + '_' + (++this._cnt);
- } while(m[tid]);
-
- tmp = {
- id : false,
- text : typeof d === 'string' ? d : '',
- icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true,
- parent : p,
- parents : ps,
- children : [],
- children_d : [],
- data : null,
- state : { },
- li_attr : { id : false },
- a_attr : { href : '#' },
- original : false
- };
- for(i in df) {
- if(df.hasOwnProperty(i)) {
- tmp.state[i] = df[i];
- }
- }
- if(d && d.id) { tmp.id = d.id; }
- if(d && d.text) { tmp.text = d.text; }
- if(d && d.data && d.data.jstree && d.data.jstree.icon) {
- tmp.icon = d.data.jstree.icon;
- }
- if(d && d.data) {
- tmp.data = d.data;
- if(d.data.jstree) {
- for(i in d.data.jstree) {
- if(d.data.jstree.hasOwnProperty(i)) {
- tmp.state[i] = d.data.jstree[i];
- }
- }
- }
- }
- if(d && typeof d.state === 'object') {
- for (i in d.state) {
- if(d.state.hasOwnProperty(i)) {
- tmp.state[i] = d.state[i];
- }
- }
- }
- if(d && typeof d.li_attr === 'object') {
- for (i in d.li_attr) {
- if(d.li_attr.hasOwnProperty(i)) {
- tmp.li_attr[i] = d.li_attr[i];
- }
- }
- }
- if(tmp.li_attr.id && !tmp.id) {
- tmp.id = tmp.li_attr.id;
- }
- if(!tmp.id) {
- tmp.id = tid;
- }
- if(!tmp.li_attr.id) {
- tmp.li_attr.id = tmp.id;
- }
- if(d && typeof d.a_attr === 'object') {
- for (i in d.a_attr) {
- if(d.a_attr.hasOwnProperty(i)) {
- tmp.a_attr[i] = d.a_attr[i];
- }
- }
- }
- if(d && d.children && d.children.length) {
- for(i = 0, j = d.children.length; i < j; i++) {
- c = this._parse_model_from_json(d.children[i], tmp.id, ps);
- e = m[c];
- tmp.children.push(c);
- if(e.children_d.length) {
- tmp.children_d = tmp.children_d.concat(e.children_d);
- }
- }
- tmp.children_d = tmp.children_d.concat(tmp.children);
- }
- if(d && d.children && d.children === true) {
- tmp.state.loaded = false;
- tmp.children = [];
- tmp.children_d = [];
- }
- delete d.data;
- delete d.children;
- tmp.original = d;
- m[tmp.id] = tmp;
- if(tmp.state.selected) {
- this._data.core.selected.push(tmp.id);
- }
- return tmp.id;
- },
- /**
- * redraws all nodes that need to be redrawn. Used internally.
- * @private
- * @name _redraw()
- * @trigger redraw.jstree
- */
- _redraw : function () {
- var nodes = this._model.force_full_redraw ? this._model.data['#'].children.concat([]) : this._model.changed.concat([]),
- f = document.createElement('UL'), tmp, i, j;
- for(i = 0, j = nodes.length; i < j; i++) {
- tmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw);
- if(tmp && this._model.force_full_redraw) {
- f.appendChild(tmp);
- }
- }
- if(this._model.force_full_redraw) {
- f.className = this.get_container_ul()[0].className;
- this.element.empty().append(f);
- //this.get_container_ul()[0].appendChild(f);
- }
- this._model.force_full_redraw = false;
- this._model.changed = [];
- /**
- * triggered after nodes are redrawn
- * @event
- * @name redraw.jstree
- * @param {array} nodes the redrawn nodes
- */
- this.trigger('redraw', { "nodes" : nodes });
- },
- /**
- * redraws all nodes that need to be redrawn or optionally - the whole tree
- * @name redraw([full])
- * @param {Boolean} full if set to `true` all nodes are redrawn.
- */
- redraw : function (full) {
- if(full) {
- this._model.force_full_redraw = true;
- }
- //if(this._model.redraw_timeout) {
- // clearTimeout(this._model.redraw_timeout);
- //}
- //this._model.redraw_timeout = setTimeout($.proxy(this._redraw, this),0);
- this._redraw();
- },
- /**
- * redraws a single node. Used internally.
- * @private
- * @name redraw_node(node, deep, is_callback)
- * @param {mixed} node the node to redraw
- * @param {Boolean} deep should child nodes be redrawn too
- * @param {Boolean} is_callback is this a recursion call
- */
- redraw_node : function (node, deep, is_callback) {
- var obj = this.get_node(node),
- par = false,
- ind = false,
- old = false,
- i = false,
- j = false,
- k = false,
- c = '',
- d = document,
- m = this._model.data,
- f = false,
- s = false;
- if(!obj) { return false; }
- if(obj.id === '#') { return this.redraw(true); }
- deep = deep || obj.children.length === 0;
- node = d.getElementById(obj.id); //, this.element);
- if(!node) {
- deep = true;
- //node = d.createElement('LI');
- if(!is_callback) {
- par = obj.parent !== '#' ? $('#' + obj.parent, this.element)[0] : null;
- if(par !== null && (!par || !m[obj.parent].state.opened)) {
- return false;
- }
- ind = $.inArray(obj.id, par === null ? m['#'].children : m[obj.parent].children);
- }
- }
- else {
- node = $(node);
- if(!is_callback) {
- par = node.parent().parent()[0];
- if(par === this.element[0]) {
- par = null;
- }
- ind = node.index();
- }
- // m[obj.id].data = node.data(); // use only node's data, no need to touch jquery storage
- if(!deep && obj.children.length && !node.children('ul').length) {
- deep = true;
- }
- if(!deep) {
- old = node.children('UL')[0];
- }
- s = node.attr('aria-selected');
- f = node.children('.jstree-anchor')[0] === document.activeElement;
- node.remove();
- //node = d.createElement('LI');
- //node = node[0];
- }
- node = _node.cloneNode(true);
- // node is DOM, deep is boolean
-
- c = 'jstree-node ';
- for(i in obj.li_attr) {
- if(obj.li_attr.hasOwnProperty(i)) {
- if(i === 'id') { continue; }
- if(i !== 'class') {
- node.setAttribute(i, obj.li_attr[i]);
- }
- else {
- c += obj.li_attr[i];
- }
- }
- }
- if(s && s !== "false") {
- node.setAttribute('aria-selected', true);
- }
- if(!obj.children.length && obj.state.loaded) {
- c += ' jstree-leaf';
- }
- else {
- c += obj.state.opened ? ' jstree-open' : ' jstree-closed';
- node.setAttribute('aria-expanded', obj.state.opened);
- }
- if(obj.parent !== null && m[obj.parent].children[m[obj.parent].children.length - 1] === obj.id) {
- c += ' jstree-last';
- }
- node.id = obj.id;
- node.className = c;
- c = ( obj.state.selected ? ' jstree-clicked' : '') + ( obj.state.disabled ? ' jstree-disabled' : '');
- for(j in obj.a_attr) {
- if(obj.a_attr.hasOwnProperty(j)) {
- if(j === 'href' && obj.a_attr[j] === '#') { continue; }
- if(j !== 'class') {
- node.childNodes[1].setAttribute(j, obj.a_attr[j]);
- }
- else {
- c += ' ' + obj.a_attr[j];
- }
- }
- }
- if(c.length) {
- node.childNodes[1].className = 'jstree-anchor ' + c;
- }
- if((obj.icon && obj.icon !== true) || obj.icon === false) {
- if(obj.icon === false) {
- node.childNodes[1].childNodes[0].className += ' jstree-themeicon-hidden';
- }
- else if(obj.icon.indexOf('/') === -1 && obj.icon.indexOf('.') === -1) {
- node.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom';
- }
- else {
- node.childNodes[1].childNodes[0].style.backgroundImage = 'url('+obj.icon+')';
- node.childNodes[1].childNodes[0].style.backgroundPosition = 'center center';
- node.childNodes[1].childNodes[0].style.backgroundSize = 'auto';
- node.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom';
- }
- }
- //node.childNodes[1].appendChild(d.createTextNode(obj.text));
- node.childNodes[1].innerHTML += obj.text;
- // if(obj.data) { $.data(node, obj.data); } // always work with node's data, no need to touch jquery store
-
- if(deep && obj.children.length && obj.state.opened) {
- k = d.createElement('UL');
- k.setAttribute('role', 'group');
- k.className = 'jstree-children';
- for(i = 0, j = obj.children.length; i < j; i++) {
- k.appendChild(this.redraw_node(obj.children[i], deep, true));
- }
- node.appendChild(k);
- }
- if(old) {
- node.appendChild(old);
- }
- if(!is_callback) {
- // append back using par / ind
- if(!par) {
- par = this.element[0];
- }
- if(!par.getElementsByTagName('UL').length) {
- i = d.createElement('UL');
- i.setAttribute('role', 'group');
- i.className = 'jstree-children';
- par.appendChild(i);
- par = i;
- }
- else {
- par = par.getElementsByTagName('UL')[0];
- }
-
- if(ind < par.childNodes.length) {
- par.insertBefore(node, par.childNodes[ind]);
- }
- else {
- par.appendChild(node);
- }
- if(f) {
- node.childNodes[1].focus();
- }
- }
- return node;
- },
- /**
- * opens a node, revaling its children. If the node is not loaded it will be loaded and opened once ready.
- * @name open_node(obj [, callback, animation])
- * @param {mixed} obj the node to open
- * @param {Function} callback a function to execute once the node is opened
- * @param {Number} animation the animation duration in milliseconds when opening the node (overrides the `core.animation` setting). Use `false` for no animation.
- * @trigger open_node.jstree, after_open.jstree
- */
- open_node : function (obj, callback, animation) {
- var t1, t2, d, t;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.open_node(obj[t1], callback, animation);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') {
- return false;
- }
- animation = animation === undefined ? this.settings.core.animation : animation;
- if(!this.is_closed(obj)) {
- if(callback) {
- callback.call(this, obj, false);
- }
- return false;
- }
- if(!this.is_loaded(obj)) {
- if(this.is_loading(obj)) {
- return setTimeout($.proxy(function () {
- this.open_node(obj, callback, animation);
- }, this), 500);
- }
- this.load_node(obj, function (o, ok) {
- return ok ? this.open_node(o, callback, animation) : (callback ? callback.call(this, o, false) : false);
- });
- }
- else {
- d = this.get_node(obj, true);
- t = this;
- if(d.length) {
- if(obj.children.length && !this._firstChild(d.children('ul')[0])) {
- obj.state.opened = true;
- this.redraw_node(obj, true);
- d = this.get_node(obj, true);
- }
- if(!animation) {
- d[0].className = d[0].className.replace('jstree-closed', 'jstree-open');
- d[0].setAttribute("aria-expanded", true);
- }
- else {
- d
- .children("ul").css("display","none").end()
- .removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded", true)
- .children("ul").stop(true, true)
- .slideDown(animation, function () {
- this.style.display = "";
- t.trigger("after_open", { "node" : obj });
- });
- }
- }
- obj.state.opened = true;
- if(callback) {
- callback.call(this, obj, true);
- }
- /**
- * triggered when a node is opened (if there is an animation it will not be completed yet)
- * @event
- * @name open_node.jstree
- * @param {Object} node the opened node
- */
- this.trigger('open_node', { "node" : obj });
- if(!animation || !d.length) {
- /**
- * triggered when a node is opened and the animation is complete
- * @event
- * @name after_open.jstree
- * @param {Object} node the opened node
- */
- this.trigger("after_open", { "node" : obj });
- }
- }
- },
- /**
- * opens every parent of a node (node should be loaded)
- * @name _open_to(obj)
- * @param {mixed} obj the node to reveal
- * @private
- */
- _open_to : function (obj) {
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') {
- return false;
- }
- var i, j, p = obj.parents;
- for(i = 0, j = p.length; i < j; i+=1) {
- if(i !== '#') {
- this.open_node(p[i], false, 0);
- }
- }
- return $(document.getElementById(obj.id));
- },
- /**
- * closes a node, hiding its children
- * @name close_node(obj [, animation])
- * @param {mixed} obj the node to close
- * @param {Number} animation the animation duration in milliseconds when closing the node (overrides the `core.animation` setting). Use `false` for no animation.
- * @trigger close_node.jstree, after_close.jstree
- */
- close_node : function (obj, animation) {
- var t1, t2, t, d;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.close_node(obj[t1], animation);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') {
- return false;
- }
- animation = animation === undefined ? this.settings.core.animation : animation;
- t = this;
- d = this.get_node(obj, true);
- if(d.length) {
- if(!animation) {
- d[0].className = d[0].className.replace('jstree-open', 'jstree-closed');
- d.attr("aria-expanded", false).children('ul').remove();
- }
- else {
- d
- .children("ul").attr("style","display:block !important").end()
- .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false)
- .children("ul").stop(true, true).slideUp(animation, function () {
- this.style.display = "";
- d.children('ul').remove();
- t.trigger("after_close", { "node" : obj });
- });
- }
- }
- obj.state.opened = false;
- /**
- * triggered when a node is closed (if there is an animation it will not be complete yet)
- * @event
- * @name close_node.jstree
- * @param {Object} node the closed node
- */
- this.trigger('close_node',{ "node" : obj });
- if(!animation || !d.length) {
- /**
- * triggered when a node is closed and the animation is complete
- * @event
- * @name after_close.jstree
- * @param {Object} node the closed node
- */
- this.trigger("after_close", { "node" : obj });
- }
- },
- /**
- * toggles a node - closing it if it is open, opening it if it is closed
- * @name toggle_node(obj)
- * @param {mixed} obj the node to toggle
- */
- toggle_node : function (obj) {
- var t1, t2;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.toggle_node(obj[t1]);
- }
- return true;
- }
- if(this.is_closed(obj)) {
- return this.open_node(obj);
- }
- if(this.is_open(obj)) {
- return this.close_node(obj);
- }
- },
- /**
- * opens all nodes within a node (or the tree), revaling their children. If the node is not loaded it will be loaded and opened once ready.
- * @name open_all([obj, animation, original_obj])
- * @param {mixed} obj the node to open recursively, omit to open all nodes in the tree
- * @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation
- * @param {jQuery} reference to the node that started the process (internal use)
- * @trigger open_all.jstree
- */
- open_all : function (obj, animation, original_obj) {
- if(!obj) { obj = '#'; }
- obj = this.get_node(obj);
- if(!obj) { return false; }
- var dom = obj.id === '#' ? this.get_container_ul() : this.get_node(obj, true), i, j, _this;
- if(!dom.length) {
- for(i = 0, j = obj.children_d.length; i < j; i++) {
- if(this.is_closed(this._model.data[obj.children_d[i]])) {
- this._model.data[obj.children_d[i]].state.opened = true;
- }
- }
- return this.trigger('open_all', { "node" : obj });
- }
- original_obj = original_obj || dom;
- _this = this;
- dom = this.is_closed(obj) ? dom.find('li.jstree-closed').addBack() : dom.find('li.jstree-closed');
- dom.each(function () {
- _this.open_node(
- this,
- function(node, status) { if(status && this.is_parent(node)) { this.open_all(node, animation, original_obj); } },
- animation || 0
- );
- });
- if(original_obj.find('li.jstree-closed').length === 0) {
- /**
- * triggered when an `open_all` call completes
- * @event
- * @name open_all.jstree
- * @param {Object} node the opened node
- */
- this.trigger('open_all', { "node" : this.get_node(original_obj) });
- }
- },
- /**
- * closes all nodes within a node (or the tree), revaling their children
- * @name close_all([obj, animation])
- * @param {mixed} obj the node to close recursively, omit to close all nodes in the tree
- * @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation
- * @trigger close_all.jstree
- */
- close_all : function (obj, animation) {
- if(!obj) { obj = '#'; }
- obj = this.get_node(obj);
- if(!obj) { return false; }
- var dom = obj.id === '#' ? this.get_container_ul() : this.get_node(obj, true),
- _this = this, i, j;
- if(!dom.length) {
- for(i = 0, j = obj.children_d.length; i < j; i++) {
- this._model.data[obj.children_d[i]].state.opened = false;
- }
- return this.trigger('close_all', { "node" : obj });
- }
- dom = this.is_open(obj) ? dom.find('li.jstree-open').addBack() : dom.find('li.jstree-open');
- dom.vakata_reverse().each(function () { _this.close_node(this, animation || 0); });
- /**
- * triggered when an `close_all` call completes
- * @event
- * @name close_all.jstree
- * @param {Object} node the closed node
- */
- this.trigger('close_all', { "node" : obj });
- },
- /**
- * checks if a node is disabled (not selectable)
- * @name is_disabled(obj)
- * @param {mixed} obj
- * @return {Boolean}
- */
- is_disabled : function (obj) {
- obj = this.get_node(obj);
- return obj && obj.state && obj.state.disabled;
- },
- /**
- * enables a node - so that it can be selected
- * @name enable_node(obj)
- * @param {mixed} obj the node to enable
- * @trigger enable_node.jstree
- */
- enable_node : function (obj) {
- var t1, t2;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.enable_node(obj[t1]);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') {
- return false;
- }
- obj.state.disabled = false;
- this.get_node(obj,true).children('.jstree-anchor').removeClass('jstree-disabled');
- /**
- * triggered when an node is enabled
- * @event
- * @name enable_node.jstree
- * @param {Object} node the enabled node
- */
- this.trigger('enable_node', { 'node' : obj });
- },
- /**
- * disables a node - so that it can not be selected
- * @name disable_node(obj)
- * @param {mixed} obj the node to disable
- * @trigger disable_node.jstree
- */
- disable_node : function (obj) {
- var t1, t2;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.disable_node(obj[t1]);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') {
- return false;
- }
- obj.state.disabled = true;
- this.get_node(obj,true).children('.jstree-anchor').addClass('jstree-disabled');
- /**
- * triggered when an node is disabled
- * @event
- * @name disable_node.jstree
- * @param {Object} node the disabled node
- */
- this.trigger('disable_node', { 'node' : obj });
- },
- /**
- * called when a node is selected by the user. Used internally.
- * @private
- * @name activate_node(obj, e)
- * @param {mixed} obj the node
- * @param {Object} e the related event
- * @trigger activate_node.jstree
- */
- activate_node : function (obj, e) {
- if(this.is_disabled(obj)) {
- return false;
- }
- if(!this.settings.core.multiple || (!e.metaKey && !e.ctrlKey && !e.shiftKey) || (e.shiftKey && (!this._data.core.last_clicked || !this.get_parent(obj) || this.get_parent(obj) !== this._data.core.last_clicked.parent ) )) {
- if(!this.settings.core.multiple && (e.metaKey || e.ctrlKey || e.shiftKey) && this.is_selected(obj)) {
- this.deselect_node(obj, false, false, e);
- }
- else {
- this.deselect_all(true);
- this.select_node(obj, false, false, e);
- this._data.core.last_clicked = this.get_node(obj);
- }
- }
- else {
- if(e.shiftKey) {
- var o = this.get_node(obj).id,
- l = this._data.core.last_clicked.id,
- p = this.get_node(this._data.core.last_clicked.parent).children,
- c = false,
- i, j;
- for(i = 0, j = p.length; i < j; i += 1) {
- // separate IFs work whem o and l are the same
- if(p[i] === o) {
- c = !c;
- }
- if(p[i] === l) {
- c = !c;
- }
- if(c || p[i] === o || p[i] === l) {
- this.select_node(p[i], false, false, e);
- }
- else {
- this.deselect_node(p[i], false, false, e);
- }
- }
- }
- else {
- if(!this.is_selected(obj)) {
- this.select_node(obj, false, false, e);
- }
- else {
- this.deselect_node(obj, false, false, e);
- }
- }
- }
- /**
- * triggered when an node is clicked or intercated with by the user
- * @event
- * @name activate_node.jstree
- * @param {Object} node
- */
- this.trigger('activate_node', { 'node' : this.get_node(obj) });
- },
- /**
- * applies the hover state on a node, called when a node is hovered by the user. Used internally.
- * @private
- * @name hover_node(obj)
- * @param {mixed} obj
- * @trigger hover_node.jstree
- */
- hover_node : function (obj) {
- obj = this.get_node(obj, true);
- if(!obj || !obj.length || obj.children('.jstree-hovered').length) {
- return false;
- }
- var o = this.element.find('.jstree-hovered'), t = this.element;
- if(o && o.length) { this.dehover_node(o); }
-
- obj.children('.jstree-anchor').addClass('jstree-hovered');
- /**
- * triggered when an node is hovered
- * @event
- * @name hover_node.jstree
- * @param {Object} node
- */
- this.trigger('hover_node', { 'node' : this.get_node(obj) });
- setTimeout(function () { t.attr('aria-activedescendant', obj[0].id); obj.attr('aria-selected', true); }, 0);
- },
- /**
- * removes the hover state from a nodecalled when a node is no longer hovered by the user. Used internally.
- * @private
- * @name dehover_node(obj)
- * @param {mixed} obj
- * @trigger dehover_node.jstree
- */
- dehover_node : function (obj) {
- obj = this.get_node(obj, true);
- if(!obj || !obj.length || !obj.children('.jstree-hovered').length) {
- return false;
- }
- obj.attr('aria-selected', false).children('.jstree-anchor').removeClass('jstree-hovered');
- /**
- * triggered when an node is no longer hovered
- * @event
- * @name dehover_node.jstree
- * @param {Object} node
- */
- this.trigger('dehover_node', { 'node' : this.get_node(obj) });
- },
- /**
- * select a node
- * @name select_node(obj [, supress_event, prevent_open])
- * @param {mixed} obj an array can be used to select multiple nodes
- * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
- * @param {Boolean} prevent_open if set to `true` parents of the selected node won't be opened
- * @trigger select_node.jstree, changed.jstree
- */
- select_node : function (obj, supress_event, prevent_open, e) {
- var dom, t1, t2, th;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.select_node(obj[t1], supress_event, prevent_open, e);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') {
- return false;
- }
- dom = this.get_node(obj, true);
- if(!obj.state.selected) {
- obj.state.selected = true;
- this._data.core.selected.push(obj.id);
- if(!prevent_open) {
- dom = this._open_to(obj);
- }
- if(dom && dom.length) {
- dom.children('.jstree-anchor').addClass('jstree-clicked');
- }
- /**
- * triggered when an node is selected
- * @event
- * @name select_node.jstree
- * @param {Object} node
- * @param {Array} selected the current selection
- * @param {Object} event the event (if any) that triggered this select_node
- */
- this.trigger('select_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
- if(!supress_event) {
- /**
- * triggered when selection changes
- * @event
- * @name changed.jstree
- * @param {Object} node
- * @param {Object} action the action that caused the selection to change
- * @param {Array} selected the current selection
- * @param {Object} event the event (if any) that triggered this changed event
- */
- this.trigger('changed', { 'action' : 'select_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
- }
- }
- },
- /**
- * deselect a node
- * @name deselect_node(obj [, supress_event])
- * @param {mixed} obj an array can be used to deselect multiple nodes
- * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
- * @trigger deselect_node.jstree, changed.jstree
- */
- deselect_node : function (obj, supress_event, e) {
- var t1, t2, dom;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.deselect_node(obj[t1], supress_event, e);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') {
- return false;
- }
- dom = this.get_node(obj, true);
- if(obj.state.selected) {
- obj.state.selected = false;
- this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.id);
- if(dom.length) {
- dom.children('.jstree-anchor').removeClass('jstree-clicked');
- }
- /**
- * triggered when an node is deselected
- * @event
- * @name deselect_node.jstree
- * @param {Object} node
- * @param {Array} selected the current selection
- * @param {Object} event the event (if any) that triggered this deselect_node
- */
- this.trigger('deselect_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
- if(!supress_event) {
- this.trigger('changed', { 'action' : 'deselect_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
- }
- }
- },
- /**
- * select all nodes in the tree
- * @name select_all([supress_event])
- * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
- * @trigger select_all.jstree, changed.jstree
- */
- select_all : function (supress_event) {
- var tmp = this._data.core.selected.concat([]), i, j;
- this._data.core.selected = this._model.data['#'].children_d.concat();
- for(i = 0, j = this._data.core.selected.length; i < j; i++) {
- if(this._model.data[this._data.core.selected[i]]) {
- this._model.data[this._data.core.selected[i]].state.selected = true;
- }
- }
- this.redraw(true);
- /**
- * triggered when all nodes are selected
- * @event
- * @name select_all.jstree
- * @param {Array} selected the current selection
- */
- this.trigger('select_all', { 'selected' : this._data.core.selected });
- if(!supress_event) {
- this.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp });
- }
- },
- /**
- * deselect all selected nodes
- * @name deselect_all([supress_event])
- * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
- * @trigger deselect_all.jstree, changed.jstree
- */
- deselect_all : function (supress_event) {
- var tmp = this._data.core.selected.concat([]), i, j;
- for(i = 0, j = this._data.core.selected.length; i < j; i++) {
- if(this._model.data[this._data.core.selected[i]]) {
- this._model.data[this._data.core.selected[i]].state.selected = false;
- }
- }
- this._data.core.selected = [];
- this.element.find('.jstree-clicked').removeClass('jstree-clicked');
- /**
- * triggered when all nodes are deselected
- * @event
- * @name deselect_all.jstree
- * @param {Object} node the previous selection
- * @param {Array} selected the current selection
- */
- this.trigger('deselect_all', { 'selected' : this._data.core.selected, 'node' : tmp });
- if(!supress_event) {
- this.trigger('changed', { 'action' : 'deselect_all', 'selected' : this._data.core.selected, 'old_selection' : tmp });
- }
- },
- /**
- * checks if a node is selected
- * @name is_selected(obj)
- * @param {mixed} obj
- * @return {Boolean}
- */
- is_selected : function (obj) {
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') {
- return false;
- }
- return obj.state.selected;
- },
- /**
- * get an array of all selected node IDs
- * @name get_selected([full])
- * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
- * @return {Array}
- */
- get_selected : function (full) {
- return full ? $.map(this._data.core.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.core.selected;
- },
- /**
- * gets the current state of the tree so that it can be restored later with `set_state(state)`. Used internally.
- * @name get_state()
- * @private
- * @return {Object}
- */
- get_state : function () {
- var state = {
- 'core' : {
- 'open' : [],
- 'scroll' : {
- 'left' : this.element.scrollLeft(),
- 'top' : this.element.scrollTop()
- },
- /*!
- 'themes' : {
- 'name' : this.get_theme(),
- 'icons' : this._data.core.themes.icons,
- 'dots' : this._data.core.themes.dots
- },
- */
- 'selected' : []
- }
- }, i;
- for(i in this._model.data) {
- if(this._model.data.hasOwnProperty(i)) {
- if(i !== '#') {
- if(this._model.data[i].state.opened) {
- state.core.open.push(i);
- }
- if(this._model.data[i].state.selected) {
- state.core.selected.push(i);
- }
- }
- }
- }
- return state;
- },
- /**
- * sets the state of the tree. Used internally.
- * @name set_state(state [, callback])
- * @private
- * @param {Object} state the state to restore
- * @param {Function} callback an optional function to execute once the state is restored.
- * @trigger set_state.jstree
- */
- set_state : function (state, callback) {
- if(state) {
- if(state.core) {
- var res, n, t, _this;
- if(state.core.open) {
- if(!$.isArray(state.core.open)) {
- delete state.core.open;
- this.set_state(state, callback);
- return false;
- }
- res = true;
- n = false;
- t = this;
- $.each(state.core.open.concat([]), function (i, v) {
- n = t.get_node(v);
- if(n) {
- if(t.is_loaded(v)) {
- if(t.is_closed(v)) {
- t.open_node(v, false, 0);
- }
- if(state && state.core && state.core.open) {
- $.vakata.array_remove_item(state.core.open, v);
- }
- }
- else {
- if(!t.is_loading(v)) {
- t.open_node(v, $.proxy(function () { this.set_state(state, callback); }, t), 0);
- }
- // there will be some async activity - so wait for it
- res = false;
- }
- }
- });
- if(res) {
- delete state.core.open;
- this.set_state(state, callback);
- }
- return false;
- }
- if(state.core.scroll) {
- if(state.core.scroll && state.core.scroll.left !== undefined) {
- this.element.scrollLeft(state.core.scroll.left);
- }
- if(state.core.scroll && state.core.scroll.top !== undefined) {
- this.element.scrollTop(state.core.scroll.top);
- }
- delete state.core.scroll;
- this.set_state(state, callback);
- return false;
- }
- /*!
- if(state.core.themes) {
- if(state.core.themes.name) {
- this.set_theme(state.core.themes.name);
- }
- if(typeof state.core.themes.dots !== 'undefined') {
- this[ state.core.themes.dots ? "show_dots" : "hide_dots" ]();
- }
- if(typeof state.core.themes.icons !== 'undefined') {
- this[ state.core.themes.icons ? "show_icons" : "hide_icons" ]();
- }
- delete state.core.themes;
- delete state.core.open;
- this.set_state(state, callback);
- return false;
- }
- */
- if(state.core.selected) {
- _this = this;
- this.deselect_all();
- $.each(state.core.selected, function (i, v) {
- _this.select_node(v);
- });
- delete state.core.selected;
- this.set_state(state, callback);
- return false;
- }
- if($.isEmptyObject(state.core)) {
- delete state.core;
- this.set_state(state, callback);
- return false;
- }
- }
- if($.isEmptyObject(state)) {
- state = null;
- if(callback) { callback.call(this); }
- /**
- * triggered when a `set_state` call completes
- * @event
- * @name set_state.jstree
- */
- this.trigger('set_state');
- return false;
- }
- return true;
- }
- return false;
- },
- /**
- * refreshes the tree - all nodes are reloaded with calls to `load_node`.
- * @name refresh()
- * @param {Boolean} skip_loading an option to skip showing the loading indicator
- * @trigger refresh.jstree
- */
- refresh : function (skip_loading) {
- this._data.core.state = this.get_state();
- this._cnt = 0;
- this._model.data = {
- '#' : {
- id : '#',
- parent : null,
- parents : [],
- children : [],
- children_d : [],
- state : { loaded : false }
- }
- };
- var c = this.get_container_ul()[0].className;
- if(!skip_loading) {
- this.element.html("<"+"ul class='jstree-container-ul'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>");
- }
- this.load_node('#', function (o, s) {
- if(s) {
- this.get_container_ul()[0].className = c;
- this.set_state($.extend(true, {}, this._data.core.state), function () {
- /**
- * triggered when a `refresh` call completes
- * @event
- * @name refresh.jstree
- */
- this.trigger('refresh');
- });
- }
- this._data.core.state = null;
- });
- },
- /**
- * set (change) the ID of a node
- * @name set_id(obj, id)
- * @param {mixed} obj the node
- * @param {String} id the new ID
- * @return {Boolean}
- */
- set_id : function (obj, id) {
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') { return false; }
- var i, j, m = this._model.data;
- // update parents (replace current ID with new one in children and children_d)
- m[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id;
- for(i = 0, j = obj.parents.length; i < j; i++) {
- m[obj.parents[i]].children_d[$.inArray(obj.id, m[obj.parents[i]].children_d)] = id;
- }
- // update children (replace current ID with new one in parent and parents)
- for(i = 0, j = obj.children.length; i < j; i++) {
- m[obj.children[i]].parent = id;
- }
- for(i = 0, j = obj.children_d.length; i < j; i++) {
- m[obj.children_d[i]].parents[$.inArray(obj.id, m[obj.children_d[i]].parents)] = id;
- }
- i = $.inArray(obj.id, this._data.core.selected);
- if(i !== -1) { this._data.core.selected[i] = id; }
- // update model and obj itself (obj.id, this._model.data[KEY])
- i = this.get_node(obj.id, true);
- if(i) {
- i.attr('id', id);
- }
- delete m[obj.id];
- obj.id = id;
- m[id] = obj;
- return true;
- },
- /**
- * get the text value of a node
- * @name get_text(obj)
- * @param {mixed} obj the node
- * @return {String}
- */
- get_text : function (obj) {
- obj = this.get_node(obj);
- return (!obj || obj.id === '#') ? false : obj.text;
- },
- /**
- * set the text value of a node. Used internally, please use `rename_node(obj, val)`.
- * @private
- * @name set_text(obj, val)
- * @param {mixed} obj the node, you can pass an array to set the text on multiple nodes
- * @param {String} val the new text value
- * @return {Boolean}
- * @trigger set_text.jstree
- */
- set_text : function (obj, val) {
- var t1, t2, dom, tmp;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.set_text(obj[t1], val);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') { return false; }
- obj.text = val;
- dom = this.get_node(obj, true);
- if(dom.length) {
- dom = dom.children(".jstree-anchor:eq(0)");
- tmp = dom.children("I").clone();
- dom.html(val).prepend(tmp);
- /**
- * triggered when a node text value is changed
- * @event
- * @name set_text.jstree
- * @param {Object} obj
- * @param {String} text the new value
- */
- this.trigger('set_text',{ "obj" : obj, "text" : val });
- }
- return true;
- },
- /**
- * gets a JSON representation of a node (or the whole tree)
- * @name get_json([obj, options])
- * @param {mixed} obj
- * @param {Object} options
- * @param {Boolean} options.no_state do not return state information
- * @param {Boolean} options.no_id do not return ID
- * @param {Boolean} options.no_children do not include children
- * @param {Boolean} options.no_data do not include node data
- * @param {Boolean} options.flat return flat JSON instead of nested
- * @return {Object}
- */
- get_json : function (obj, options, flat) {
- obj = this.get_node(obj || '#');
- if(!obj) { return false; }
- if(options && options.flat && !flat) { flat = []; }
- var tmp = {
- 'id' : obj.id,
- 'text' : obj.text,
- 'icon' : this.get_icon(obj),
- 'li_attr' : obj.li_attr,
- 'a_attr' : obj.a_attr,
- 'state' : {},
- 'data' : options && options.no_data ? false : obj.data
- //( this.get_node(obj, true).length ? this.get_node(obj, true).data() : obj.data ),
- }, i, j;
- if(options && options.flat) {
- tmp.parent = obj.parent;
- }
- else {
- tmp.children = [];
- }
- if(!options || !options.no_state) {
- for(i in obj.state) {
- if(obj.state.hasOwnProperty(i)) {
- tmp.state[i] = obj.state[i];
- }
- }
- }
- if(options && options.no_id) {
- delete tmp.id;
- if(tmp.li_attr && tmp.li_attr.id) {
- delete tmp.li_attr.id;
- }
- }
- if(options && options.flat && obj.id !== '#') {
- flat.push(tmp);
- }
- if(!options || !options.no_children) {
- for(i = 0, j = obj.children.length; i < j; i++) {
- if(options && options.flat) {
- this.get_json(obj.children[i], options, flat);
- }
- else {
- tmp.children.push(this.get_json(obj.children[i], options));
- }
- }
- }
- return options && options.flat ? flat : (obj.id === '#' ? tmp.children : tmp);
- },
- /**
- * create a new node (do not confuse with load_node)
- * @name create_node([obj, node, pos, callback, is_loaded])
- * @param {mixed} par the parent node
- * @param {mixed} node the data for the new node (a valid JSON object, or a simple string with the name)
- * @param {mixed} pos the index at which to insert the node, "first" and "last" are also supported, default is "last"
- * @param {Function} callback a function to be called once the node is created
- * @param {Boolean} is_loaded internal argument indicating if the parent node was succesfully loaded
- * @return {String} the ID of the newly create node
- * @trigger model.jstree, create_node.jstree
- */
- create_node : function (par, node, pos, callback, is_loaded) {
- par = this.get_node(par);
- if(!par) { return false; }
- pos = pos === undefined ? "last" : pos;
- if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
- return this.load_node(par, function () { this.create_node(par, node, pos, callback, true); });
- }
- if(!node) { node = { "text" : this.get_string('New node') }; }
- if(node.text === undefined) { node.text = this.get_string('New node'); }
- var tmp, dpc, i, j;
-
- if(par.id === '#') {
- if(pos === "before") { pos = "first"; }
- if(pos === "after") { pos = "last"; }
- }
- switch(pos) {
- case "before":
- tmp = this.get_node(par.parent);
- pos = $.inArray(par.id, tmp.children);
- par = tmp;
- break;
- case "after" :
- tmp = this.get_node(par.parent);
- pos = $.inArray(par.id, tmp.children) + 1;
- par = tmp;
- break;
- case "inside":
- case "first":
- pos = 0;
- break;
- case "last":
- pos = par.children.length;
- break;
- default:
- if(!pos) { pos = 0; }
- break;
- }
- if(pos > par.children.length) { pos = par.children.length; }
- if(!node.id) { node.id = true; }
- if(!this.check("create_node", node, par, pos)) {
- this.settings.core.error.call(this, this._data.core.last_error);
- return false;
- }
- if(node.id === true) { delete node.id; }
- node = this._parse_model_from_json(node, par.id, par.parents.concat());
- if(!node) { return false; }
- tmp = this.get_node(node);
- dpc = [];
- dpc.push(node);
- dpc = dpc.concat(tmp.children_d);
- this.trigger('model', { "nodes" : dpc, "parent" : par.id });
-
- par.children_d = par.children_d.concat(dpc);
- for(i = 0, j = par.parents.length; i < j; i++) {
- this._model.data[par.parents[i]].children_d = this._model.data[par.parents[i]].children_d.concat(dpc);
- }
- node = tmp;
- tmp = [];
- for(i = 0, j = par.children.length; i < j; i++) {
- tmp[i >= pos ? i+1 : i] = par.children[i];
- }
- tmp[pos] = node.id;
- par.children = tmp;
-
- this.redraw_node(par, true);
- if(callback) { callback.call(this, this.get_node(node)); }
- /**
- * triggered when a node is created
- * @event
- * @name create_node.jstree
- * @param {Object} node
- * @param {String} parent the parent's ID
- * @param {Number} position the position of the new node among the parent's children
- */
- this.trigger('create_node', { "node" : this.get_node(node), "parent" : par.id, "position" : pos });
- return node.id;
- },
- /**
- * set the text value of a node
- * @name rename_node(obj, val)
- * @param {mixed} obj the node, you can pass an array to rename multiple nodes to the same name
- * @param {String} val the new text value
- * @return {Boolean}
- * @trigger rename_node.jstree
- */
- rename_node : function (obj, val) {
- var t1, t2, old;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.rename_node(obj[t1], val);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') { return false; }
- old = obj.text;
- if(!this.check("rename_node", obj, this.get_parent(obj), val)) {
- this.settings.core.error.call(this, this._data.core.last_error);
- return false;
- }
- this.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments))
- /**
- * triggered when a node is renamed
- * @event
- * @name rename_node.jstree
- * @param {Object} node
- * @param {String} text the new value
- * @param {String} old the old value
- */
- this.trigger('rename_node', { "node" : obj, "text" : val, "old" : old });
- return true;
- },
- /**
- * remove a node
- * @name delete_node(obj)
- * @param {mixed} obj the node, you can pass an array to delete multiple nodes
- * @return {Boolean}
- * @trigger delete_node.jstree, changed.jstree
- */
- delete_node : function (obj) {
- var t1, t2, par, pos, tmp, i, j, k, l, c;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.delete_node(obj[t1]);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') { return false; }
- par = this.get_node(obj.parent);
- pos = $.inArray(obj.id, par.children);
- c = false;
- if(!this.check("delete_node", obj, par, pos)) {
- this.settings.core.error.call(this, this._data.core.last_error);
- return false;
- }
- if(pos !== -1) {
- par.children = $.vakata.array_remove(par.children, pos);
- }
- tmp = obj.children_d.concat([]);
- tmp.push(obj.id);
- for(k = 0, l = tmp.length; k < l; k++) {
- for(i = 0, j = obj.parents.length; i < j; i++) {
- pos = $.inArray(tmp[k], this._model.data[obj.parents[i]].children_d);
- if(pos !== -1) {
- this._model.data[obj.parents[i]].children_d = $.vakata.array_remove(this._model.data[obj.parents[i]].children_d, pos);
- }
- }
- if(this._model.data[tmp[k]].state.selected) {
- c = true;
- pos = $.inArray(tmp[k], this._data.core.selected);
- if(pos !== -1) {
- this._data.core.selected = $.vakata.array_remove(this._data.core.selected, pos);
- }
- }
- }
- /**
- * triggered when a node is deleted
- * @event
- * @name delete_node.jstree
- * @param {Object} node
- * @param {String} parent the parent's ID
- */
- this.trigger('delete_node', { "node" : obj, "parent" : par.id });
- if(c) {
- this.trigger('changed', { 'action' : 'delete_node', 'node' : obj, 'selected' : this._data.core.selected, 'parent' : par.id });
- }
- for(k = 0, l = tmp.length; k < l; k++) {
- delete this._model.data[tmp[k]];
- }
- this.redraw_node(par, true);
- return true;
- },
- /**
- * check if an operation is premitted on the tree. Used internally.
- * @private
- * @name check(chk, obj, par, pos)
- * @param {String} chk the operation to check, can be "create_node", "rename_node", "delete_node", "copy_node" or "move_node"
- * @param {mixed} obj the node
- * @param {mixed} par the parent
- * @param {mixed} pos the position to insert at, or if "rename_node" - the new name
- * @return {Boolean}
- */
- check : function (chk, obj, par, pos) {
- obj = obj && obj.id ? obj : this.get_node(obj);
- par = par && par.id ? par : this.get_node(par);
- var tmp = chk.match(/^move_node|copy_node|create_node$/i) ? par : obj,
- chc = this.settings.core.check_callback;
- if(chk === "move_node") {
- if(obj.id === par.id || $.inArray(obj.id, par.children) === pos || $.inArray(par.id, obj.children_d) !== -1) {
- this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
- return false;
- }
- }
- tmp = this.get_node(tmp, true);
- if(tmp.length) { tmp = tmp.data('jstree'); }
- if(tmp && tmp.functions && (tmp.functions[chk] === false || tmp.functions[chk] === true)) {
- if(tmp.functions[chk] === false) {
- this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_02', 'reason' : 'Node data prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
- }
- return tmp.functions[chk];
- }
- if(chc === false || ($.isFunction(chc) && chc.call(this, chk, obj, par, pos) === false) || (chc && chc[chk] === false)) {
- this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_03', 'reason' : 'User config for core.check_callback prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
- return false;
- }
- return true;
- },
- /**
- * get the last error
- * @name last_error()
- * @return {Object}
- */
- last_error : function () {
- return this._data.core.last_error;
- },
- /**
- * move a node to a new parent
- * @name move_node(obj, par [, pos, callback, is_loaded])
- * @param {mixed} obj the node to move, pass an array to move multiple nodes
- * @param {mixed} par the new parent
- * @param {mixed} pos the position to insert at ("first" and "last" are supported, as well as "before" and "after"), defaults to `0`
- * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position
- * @param {Boolean} internal parameter indicating if the parent node has been loaded
- * @trigger move_node.jstree
- */
- move_node : function (obj, par, pos, callback, is_loaded) {
- var t1, t2, old_par, new_par, old_ins, is_multi, dpc, tmp, i, j, k, l, p;
- if($.isArray(obj)) {
- obj = obj.reverse().slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.move_node(obj[t1], par, pos, callback, is_loaded);
- }
- return true;
- }
- obj = obj && obj.id ? obj : this.get_node(obj);
- par = this.get_node(par);
- pos = pos === undefined ? 0 : pos;
-
- if(!par || !obj || obj.id === '#') { return false; }
- if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
- return this.load_node(par, function () { this.move_node(obj, par, pos, callback, true); });
- }
-
- old_par = (obj.parent || '#').toString();
- new_par = (!pos.toString().match(/^(before|after)$/) || par.id === '#') ? par : this.get_node(par.parent);
- old_ins = this._model.data[obj.id] ? this : $.jstree.reference(obj.id);
- is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);
- if(is_multi) {
- if(this.copy_node(obj, par, pos, callback, is_loaded)) {
- if(old_ins) { old_ins.delete_node(obj); }
- return true;
- }
- return false;
- }
- //var m = this._model.data;
- if(new_par.id === '#') {
- if(pos === "before") { pos = "first"; }
- if(pos === "after") { pos = "last"; }
- }
- switch(pos) {
- case "before":
- pos = $.inArray(par.id, new_par.children);
- break;
- case "after" :
- pos = $.inArray(par.id, new_par.children) + 1;
- break;
- case "inside":
- case "first":
- pos = 0;
- break;
- case "last":
- pos = new_par.children.length;
- break;
- default:
- if(!pos) { pos = 0; }
- break;
- }
- if(pos > new_par.children.length) { pos = new_par.children.length; }
- if(!this.check("move_node", obj, new_par, pos)) {
- this.settings.core.error.call(this, this._data.core.last_error);
- return false;
- }
- if(obj.parent === new_par.id) {
- dpc = new_par.children.concat();
- tmp = $.inArray(obj.id, dpc);
- if(tmp !== -1) {
- dpc = $.vakata.array_remove(dpc, tmp);
- if(pos > tmp) { pos--; }
- }
- tmp = [];
- for(i = 0, j = dpc.length; i < j; i++) {
- tmp[i >= pos ? i+1 : i] = dpc[i];
- }
- tmp[pos] = obj.id;
- new_par.children = tmp;
- this._node_changed(new_par.id);
- this.redraw(new_par.id === '#');
- }
- else {
- // clean old parent and up
- tmp = obj.children_d.concat();
- tmp.push(obj.id);
- for(i = 0, j = obj.parents.length; i < j; i++) {
- dpc = [];
- p = old_ins._model.data[obj.parents[i]].children_d;
- for(k = 0, l = p.length; k < l; k++) {
- if($.inArray(p[k], tmp) === -1) {
- dpc.push(p[k]);
- }
- }
- old_ins._model.data[obj.parents[i]].children_d = dpc;
- }
- old_ins._model.data[old_par].children = $.vakata.array_remove_item(old_ins._model.data[old_par].children, obj.id);
-
- // insert into new parent and up
- for(i = 0, j = new_par.parents.length; i < j; i++) {
- this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(tmp);
- }
- dpc = [];
- for(i = 0, j = new_par.children.length; i < j; i++) {
- dpc[i >= pos ? i+1 : i] = new_par.children[i];
- }
- dpc[pos] = obj.id;
- new_par.children = dpc;
- new_par.children_d.push(obj.id);
- new_par.children_d = new_par.children_d.concat(obj.children_d);
-
- // update object
- obj.parent = new_par.id;
- tmp = new_par.parents.concat();
- tmp.unshift(new_par.id);
- p = obj.parents.length;
- obj.parents = tmp;
-
- // update object children
- tmp = tmp.concat();
- for(i = 0, j = obj.children_d.length; i < j; i++) {
- this._model.data[obj.children_d[i]].parents = this._model.data[obj.children_d[i]].parents.slice(0,p*-1);
- Array.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp);
- }
-
- this._node_changed(old_par);
- this._node_changed(new_par.id);
- this.redraw(old_par === '#' || new_par.id === '#');
- }
- if(callback) { callback.call(this, obj, new_par, pos); }
- /**
- * triggered when a node is moved
- * @event
- * @name move_node.jstree
- * @param {Object} node
- * @param {String} parent the parent's ID
- * @param {Number} position the position of the node among the parent's children
- * @param {String} old_parent the old parent of the node
- * @param {Boolean} is_multi do the node and new parent belong to different instances
- * @param {jsTree} old_instance the instance the node came from
- * @param {jsTree} new_instance the instance of the new parent
- */
- this.trigger('move_node', { "node" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "is_multi" : is_multi, 'old_instance' : old_ins, 'new_instance' : this });
- return true;
- },
- /**
- * copy a node to a new parent
- * @name copy_node(obj, par [, pos, callback, is_loaded])
- * @param {mixed} obj the node to copy, pass an array to copy multiple nodes
- * @param {mixed} par the new parent
- * @param {mixed} pos the position to insert at ("first" and "last" are supported, as well as "before" and "after"), defaults to `0`
- * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position
- * @param {Boolean} internal parameter indicating if the parent node has been loaded
- * @trigger model.jstree copy_node.jstree
- */
- copy_node : function (obj, par, pos, callback, is_loaded) {
- var t1, t2, dpc, tmp, i, j, node, old_par, new_par, old_ins, is_multi;
- if($.isArray(obj)) {
- obj = obj.reverse().slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.copy_node(obj[t1], par, pos, callback, is_loaded);
- }
- return true;
- }
- obj = obj && obj.id ? obj : this.get_node(obj);
- par = this.get_node(par);
- pos = pos === undefined ? 0 : pos;
-
- if(!par || !obj || obj.id === '#') { return false; }
- if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
- return this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true); });
- }
-
- old_par = (obj.parent || '#').toString();
- new_par = (!pos.toString().match(/^(before|after)$/) || par.id === '#') ? par : this.get_node(par.parent);
- old_ins = this._model.data[obj.id] ? this : $.jstree.reference(obj.id);
- is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);
- if(new_par.id === '#') {
- if(pos === "before") { pos = "first"; }
- if(pos === "after") { pos = "last"; }
- }
- switch(pos) {
- case "before":
- pos = $.inArray(par.id, new_par.children);
- break;
- case "after" :
- pos = $.inArray(par.id, new_par.children) + 1;
- break;
- case "inside":
- case "first":
- pos = 0;
- break;
- case "last":
- pos = new_par.children.length;
- break;
- default:
- if(!pos) { pos = 0; }
- break;
- }
- if(pos > new_par.children.length) { pos = new_par.children.length; }
- if(!this.check("copy_node", obj, new_par, pos)) {
- this.settings.core.error.call(this, this._data.core.last_error);
- return false;
- }
- node = old_ins ? old_ins.get_json(obj, { no_id : true, no_data : true, no_state : true }) : obj;
- if(!node) { return false; }
- if(node.id === true) { delete node.id; }
- node = this._parse_model_from_json(node, new_par.id, new_par.parents.concat());
- if(!node) { return false; }
- tmp = this.get_node(node);
- dpc = [];
- dpc.push(node);
- dpc = dpc.concat(tmp.children_d);
- this.trigger('model', { "nodes" : dpc, "parent" : new_par.id });
-
- // insert into new parent and up
- for(i = 0, j = new_par.parents.length; i < j; i++) {
- this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(dpc);
- }
- dpc = [];
- for(i = 0, j = new_par.children.length; i < j; i++) {
- dpc[i >= pos ? i+1 : i] = new_par.children[i];
- }
- dpc[pos] = tmp.id;
- new_par.children = dpc;
- new_par.children_d.push(tmp.id);
- new_par.children_d = new_par.children_d.concat(tmp.children_d);
-
- this._node_changed(new_par.id);
- this.redraw(new_par.id === '#');
- if(callback) { callback.call(this, tmp, new_par, pos); }
- /**
- * triggered when a node is copied
- * @event
- * @name copy_node.jstree
- * @param {Object} node the copied node
- * @param {Object} original the original node
- * @param {String} parent the parent's ID
- * @param {Number} position the position of the node among the parent's children
- * @param {String} old_parent the old parent of the node
- * @param {Boolean} is_multi do the node and new parent belong to different instances
- * @param {jsTree} old_instance the instance the node came from
- * @param {jsTree} new_instance the instance of the new parent
- */
- this.trigger('copy_node', { "node" : tmp, "original" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "is_multi" : is_multi, 'old_instance' : old_ins, 'new_instance' : this });
- return tmp.id;
- },
- /**
- * cut a node (a later call to `paste(obj)` would move the node)
- * @name cut(obj)
- * @param {mixed} obj multiple objects can be passed using an array
- * @trigger cut.jstree
- */
- cut : function (obj) {
- if(!obj) { obj = this._data.core.selected.concat(); }
- if(!$.isArray(obj)) { obj = [obj]; }
- if(!obj.length) { return false; }
- var tmp = [], o, t1, t2;
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- o = this.get_node(obj[t1]);
- if(o && o.id && o.id !== '#') { tmp.push(o); }
- }
- if(!tmp.length) { return false; }
- ccp_node = tmp;
- ccp_inst = this;
- ccp_mode = 'move_node';
- /**
- * triggered when nodes are added to the buffer for moving
- * @event
- * @name cut.jstree
- * @param {Array} node
- */
- this.trigger('cut', { "node" : obj });
- },
- /**
- * copy a node (a later call to `paste(obj)` would copy the node)
- * @name copy(obj)
- * @param {mixed} obj multiple objects can be passed using an array
- * @trigger copy.jstre
- */
- copy : function (obj) {
- if(!obj) { obj = this._data.core.selected.concat(); }
- if(!$.isArray(obj)) { obj = [obj]; }
- if(!obj.length) { return false; }
- var tmp = [], o, t1, t2;
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- o = this.get_node(obj[t1]);
- if(o && o.id && o.id !== '#') { tmp.push(o); }
- }
- if(!tmp.length) { return false; }
- ccp_node = tmp;
- ccp_inst = this;
- ccp_mode = 'copy_node';
- /**
- * triggered when nodes are added to the buffer for copying
- * @event
- * @name copy.jstree
- * @param {Array} node
- */
- this.trigger('copy', { "node" : obj });
- },
- /**
- * get the current buffer (any nodes that are waiting for a paste operation)
- * @name get_buffer()
- * @return {Object} an object consisting of `mode` ("copy_node" or "move_node"), `node` (an array of objects) and `inst` (the instance)
- */
- get_buffer : function () {
- return { 'mode' : ccp_mode, 'node' : ccp_node, 'inst' : ccp_inst };
- },
- /**
- * check if there is something in the buffer to paste
- * @name can_paste()
- * @return {Boolean}
- */
- can_paste : function () {
- return ccp_mode !== false && ccp_node !== false; // && ccp_inst._model.data[ccp_node];
- },
- /**
- * copy or move the previously cut or copied nodes to a new parent
- * @name paste(obj)
- * @param {mixed} obj the new parent
- * @trigger paste.jstree
- */
- paste : function (obj) {
- obj = this.get_node(obj);
- if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; }
- if(this[ccp_mode](ccp_node, obj)) {
- /**
- * triggered when paste is invoked
- * @event
- * @name paste.jstree
- * @param {String} parent the ID of the receiving node
- * @param {Array} node the nodes in the buffer
- * @param {String} mode the performed operation - "copy_node" or "move_node"
- */
- this.trigger('paste', { "parent" : obj.id, "node" : ccp_node, "mode" : ccp_mode });
- }
- ccp_node = false;
- ccp_mode = false;
- ccp_inst = false;
- },
- /**
- * put a node in edit mode (input field to rename the node)
- * @name edit(obj [, default_text])
- * @param {mixed} obj
- * @param {String} default_text the text to populate the input with (if omitted the node text value is used)
- */
- edit : function (obj, default_text) {
- obj = this._open_to(obj);
- if(!obj || !obj.length) { return false; }
- var rtl = this._data.core.rtl,
- w = this.element.width(),
- a = obj.children('.jstree-anchor'),
- s = $('<span>'),
- /*!
- oi = obj.children("i:visible"),
- ai = a.children("i:visible"),
- w1 = oi.width() * oi.length,
- w2 = ai.width() * ai.length,
- */
- t = typeof default_text === 'string' ? default_text : this.get_text(obj),
- h1 = $("<"+"div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"),
- h2 = $("<"+"input />", {
- "value" : t,
- "class" : "jstree-rename-input",
- // "size" : t.length,
- "css" : {
- "padding" : "0",
- "border" : "1px solid silver",
- "box-sizing" : "border-box",
- "display" : "inline-block",
- "height" : (this._data.core.li_height) + "px",
- "lineHeight" : (this._data.core.li_height) + "px",
- "width" : "150px" // will be set a bit further down
- },
- "blur" : $.proxy(function () {
- var i = s.children(".jstree-rename-input"),
- v = i.val();
- if(v === "") { v = t; }
- h1.remove();
- s.replaceWith(a);
- s.remove();
- this.set_text(obj, t);
- if(this.rename_node(obj, v) === false) {
- this.set_text(obj, t); // move this up? and fix #483
- }
- }, this),
- "keydown" : function (event) {
- var key = event.which;
- if(key === 27) {
- this.value = t;
- }
- if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) {
- event.stopImmediatePropagation();
- }
- if(key === 27 || key === 13) {
- event.preventDefault();
- this.blur();
- }
- },
- "click" : function (e) { e.stopImmediatePropagation(); },
- "mousedown" : function (e) { e.stopImmediatePropagation(); },
- "keyup" : function (event) {
- h2.width(Math.min(h1.text("pW" + this.value).width(),w));
- },
- "keypress" : function(event) {
- if(event.which === 13) { return false; }
- }
- }),
- fn = {
- fontFamily : a.css('fontFamily') || '',
- fontSize : a.css('fontSize') || '',
- fontWeight : a.css('fontWeight') || '',
- fontStyle : a.css('fontStyle') || '',
- fontStretch : a.css('fontStretch') || '',
- fontVariant : a.css('fontVariant') || '',
- letterSpacing : a.css('letterSpacing') || '',
- wordSpacing : a.css('wordSpacing') || ''
- };
- this.set_text(obj, "");
- s.attr('class', a.attr('class')).append(a.contents().clone()).append(h2);
- a.replaceWith(s);
- h1.css(fn);
- h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select();
- },
-
-
- /**
- * changes the theme
- * @name set_theme(theme_name [, theme_url])
- * @param {String} theme_name the name of the new theme to apply
- * @param {mixed} theme_url the location of the CSS file for this theme. Omit or set to `false` if you manually included the file. Set to `true` to autoload from the `core.themes.dir` directory.
- * @trigger set_theme.jstree
- */
- set_theme : function (theme_name, theme_url) {
- if(!theme_name) { return false; }
- if(theme_url === true) {
- var dir = this.settings.core.themes.dir;
- if(!dir) { dir = $.jstree.path + '/themes'; }
- theme_url = dir + '/' + theme_name + '/style.css';
- }
- if(theme_url && $.inArray(theme_url, themes_loaded) === -1) {
- $('head').append('<'+'link rel="stylesheet" href="' + theme_url + '" type="text/css" />');
- themes_loaded.push(theme_url);
- }
- if(this._data.core.themes.name) {
- this.element.removeClass('jstree-' + this._data.core.themes.name);
- }
- this._data.core.themes.name = theme_name;
- this.element.addClass('jstree-' + theme_name);
- this.element[this.settings.core.themes.responsive ? 'addClass' : 'removeClass' ]('jstree-' + theme_name + '-responsive');
- /**
- * triggered when a theme is set
- * @event
- * @name set_theme.jstree
- * @param {String} theme the new theme
- */
- this.trigger('set_theme', { 'theme' : theme_name });
- },
- /**
- * gets the name of the currently applied theme name
- * @name get_theme()
- * @return {String}
- */
- get_theme : function () { return this._data.core.themes.name; },
- /**
- * changes the theme variant (if the theme has variants)
- * @name set_theme_variant(variant_name)
- * @param {String|Boolean} variant_name the variant to apply (if `false` is used the current variant is removed)
- */
- set_theme_variant : function (variant_name) {
- if(this._data.core.themes.variant) {
- this.element.removeClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant);
- }
- this._data.core.themes.variant = variant_name;
- if(variant_name) {
- this.element.addClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant);
- }
- },
- /**
- * gets the name of the currently applied theme variant
- * @name get_theme()
- * @return {String}
- */
- get_theme_variant : function () { return this._data.core.themes.variant; },
- /**
- * shows a striped background on the container (if the theme supports it)
- * @name show_stripes()
- */
- show_stripes : function () { this._data.core.themes.stripes = true; this.get_container_ul().addClass("jstree-striped"); },
- /**
- * hides the striped background on the container
- * @name hide_stripes()
- */
- hide_stripes : function () { this._data.core.themes.stripes = false; this.get_container_ul().removeClass("jstree-striped"); },
- /**
- * toggles the striped background on the container
- * @name toggle_stripes()
- */
- toggle_stripes : function () { if(this._data.core.themes.stripes) { this.hide_stripes(); } else { this.show_stripes(); } },
- /**
- * shows the connecting dots (if the theme supports it)
- * @name show_dots()
- */
- show_dots : function () { this._data.core.themes.dots = true; this.get_container_ul().removeClass("jstree-no-dots"); },
- /**
- * hides the connecting dots
- * @name hide_dots()
- */
- hide_dots : function () { this._data.core.themes.dots = false; this.get_container_ul().addClass("jstree-no-dots"); },
- /**
- * toggles the connecting dots
- * @name toggle_dots()
- */
- toggle_dots : function () { if(this._data.core.themes.dots) { this.hide_dots(); } else { this.show_dots(); } },
- /**
- * show the node icons
- * @name show_icons()
- */
- show_icons : function () { this._data.core.themes.icons = true; this.get_container_ul().removeClass("jstree-no-icons"); },
- /**
- * hide the node icons
- * @name hide_icons()
- */
- hide_icons : function () { this._data.core.themes.icons = false; this.get_container_ul().addClass("jstree-no-icons"); },
- /**
- * toggle the node icons
- * @name toggle_icons()
- */
- toggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } },
- /**
- * set the node icon for a node
- * @name set_icon(obj, icon)
- * @param {mixed} obj
- * @param {String} icon the new icon - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class
- */
- set_icon : function (obj, icon) {
- var t1, t2, dom, old;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.set_icon(obj[t1], icon);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') { return false; }
- old = obj.icon;
- obj.icon = icon;
- dom = this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon");
- if(icon === false) {
- this.hide_icon(obj);
- }
- else if(icon === true) {
- dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel");
- }
- else if(icon.indexOf("/") === -1 && icon.indexOf(".") === -1) {
- dom.removeClass(old).css("background","");
- dom.addClass(icon + ' jstree-themeicon-custom').attr("rel",icon);
- }
- else {
- dom.removeClass(old).css("background","");
- dom.addClass('jstree-themeicon-custom').css("background", "url('" + icon + "') center center no-repeat").attr("rel",icon);
- }
- return true;
- },
- /**
- * get the node icon for a node
- * @name get_icon(obj)
- * @param {mixed} obj
- * @return {String}
- */
- get_icon : function (obj) {
- obj = this.get_node(obj);
- return (!obj || obj.id === '#') ? false : obj.icon;
- },
- /**
- * hide the icon on an individual node
- * @name hide_icon(obj)
- * @param {mixed} obj
- */
- hide_icon : function (obj) {
- var t1, t2;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.hide_icon(obj[t1]);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj === '#') { return false; }
- obj.icon = false;
- this.get_node(obj, true).children("a").children(".jstree-themeicon").addClass('jstree-themeicon-hidden');
- return true;
- },
- /**
- * show the icon on an individual node
- * @name show_icon(obj)
- * @param {mixed} obj
- */
- show_icon : function (obj) {
- var t1, t2, dom;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.show_icon(obj[t1]);
- }
- return true;
- }
- obj = this.get_node(obj);
- if(!obj || obj === '#') { return false; }
- dom = this.get_node(obj, true);
- obj.icon = dom.length ? dom.children("a").children(".jstree-themeicon").attr('rel') : true;
- if(!obj.icon) { obj.icon = true; }
- dom.children("a").children(".jstree-themeicon").removeClass('jstree-themeicon-hidden');
- return true;
- }
- };
-
- // helpers
- $.vakata = {};
- // reverse
- $.fn.vakata_reverse = [].reverse;
- // collect attributes
- $.vakata.attributes = function(node, with_values) {
- node = $(node)[0];
- var attr = with_values ? {} : [];
- if(node && node.attributes) {
- $.each(node.attributes, function (i, v) {
- if($.inArray(v.nodeName.toLowerCase(),['style','contenteditable','hasfocus','tabindex']) !== -1) { return; }
- if(v.nodeValue !== null && $.trim(v.nodeValue) !== '') {
- if(with_values) { attr[v.nodeName] = v.nodeValue; }
- else { attr.push(v.nodeName); }
- }
- });
- }
- return attr;
- };
- $.vakata.array_unique = function(array) {
- var a = [], i, j, l;
- for(i = 0, l = array.length; i < l; i++) {
- for(j = 0; j <= i; j++) {
- if(array[i] === array[j]) {
- break;
- }
- }
- if(j === i) { a.push(array[i]); }
- }
- return a;
- };
- // remove item from array
- $.vakata.array_remove = function(array, from, to) {
- var rest = array.slice((to || from) + 1 || array.length);
- array.length = from < 0 ? array.length + from : from;
- array.push.apply(array, rest);
- return array;
- };
- // remove item from array
- $.vakata.array_remove_item = function(array, item) {
- var tmp = $.inArray(item, array);
- return tmp !== -1 ? $.vakata.array_remove(array, tmp) : array;
- };
- // browser sniffing
- (function () {
- var browser = {},
- b_match = function(ua) {
- ua = ua.toLowerCase();
-
- var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
- /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
- /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
- /(msie) ([\w.]+)/.exec( ua ) ||
- (ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua )) ||
- [];
- return {
- browser: match[1] || "",
- version: match[2] || "0"
- };
- },
- matched = b_match(window.navigator.userAgent);
- if(matched.browser) {
- browser[ matched.browser ] = true;
- browser.version = matched.version;
- }
- if(browser.chrome) {
- browser.webkit = true;
- }
- else if(browser.webkit) {
- browser.safari = true;
- }
- $.vakata.browser = browser;
- }());
- if($.vakata.browser.msie && $.vakata.browser.version < 8) {
- $.jstree.defaults.core.animation = 0;
- }
-
-/**
- * ### Checkbox plugin
- *
- * This plugin renders checkbox icons in front of each node, making multiple selection much easier.
- * It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up.
- */
-
- var _i = document.createElement('I');
- _i.className = 'jstree-icon jstree-checkbox';
- /**
- * stores all defaults for the checkbox plugin
- * @name $.jstree.defaults.checkbox
- * @plugin checkbox
- */
- $.jstree.defaults.checkbox = {
- /**
- * a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`.
- * @name $.jstree.defaults.checkbox.visible
- * @plugin checkbox
- */
- visible : true,
- /**
- * a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`.
- * @name $.jstree.defaults.checkbox.three_state
- * @plugin checkbox
- */
- three_state : true,
- /**
- * a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`.
- * @name $.jstree.defaults.checkbox.whole_node
- * @plugin checkbox
- */
- whole_node : true,
- /**
- * a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`.
- * @name $.jstree.defaults.checkbox.keep_selected_style
- * @plugin checkbox
- */
- keep_selected_style : true
- };
- $.jstree.plugins.checkbox = function (options, parent) {
- this.bind = function () {
- parent.bind.call(this);
- this._data.checkbox.uto = false;
- this.element
- .on("init.jstree", $.proxy(function () {
- this._data.checkbox.visible = this.settings.checkbox.visible;
- if(!this.settings.checkbox.keep_selected_style) {
- this.element.addClass('jstree-checkbox-no-clicked');
- }
- }, this))
- .on("loading.jstree", $.proxy(function () {
- this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ]();
- }, this));
- if(this.settings.checkbox.three_state) {
- this.element
- .on('changed.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', $.proxy(function () {
- if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
- this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
- }, this))
- .on('model.jstree', $.proxy(function (e, data) {
- var m = this._model.data,
- p = m[data.parent],
- dpc = data.nodes,
- chd = [],
- c, i, j, k, l, tmp;
-
- // apply down
- if(p.state.selected) {
- for(i = 0, j = dpc.length; i < j; i++) {
- m[dpc[i]].state.selected = true;
- }
- this._data.core.selected = this._data.core.selected.concat(dpc);
- }
- else {
- for(i = 0, j = dpc.length; i < j; i++) {
- if(m[dpc[i]].state.selected) {
- for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) {
- m[m[dpc[i]].children_d[k]].state.selected = true;
- }
- this._data.core.selected = this._data.core.selected.concat(m[dpc[i]].children_d);
- }
- }
- }
-
- // apply up
- for(i = 0, j = p.children_d.length; i < j; i++) {
- if(!m[p.children_d[i]].children.length) {
- chd.push(m[p.children_d[i]].parent);
- }
- }
- chd = $.vakata.array_unique(chd);
- for(k = 0, l = chd.length; k < l; k++) {
- p = m[chd[k]];
- while(p && p.id !== '#') {
- c = 0;
- for(i = 0, j = p.children.length; i < j; i++) {
- c += m[p.children[i]].state.selected;
- }
- if(c === j) {
- p.state.selected = true;
- this._data.core.selected.push(p.id);
- tmp = this.get_node(p, true);
- if(tmp && tmp.length) {
- tmp.children('.jstree-anchor').addClass('jstree-clicked');
- }
- }
- else {
- break;
- }
- p = this.get_node(p.parent);
- }
- }
- this._data.core.selected = $.vakata.array_unique(this._data.core.selected);
- }, this))
- .on('select_node.jstree', $.proxy(function (e, data) {
- var obj = data.node,
- m = this._model.data,
- par = this.get_node(obj.parent),
- dom = this.get_node(obj, true),
- i, j, c, tmp;
- this._data.core.selected = $.vakata.array_unique(this._data.core.selected.concat(obj.children_d));
- for(i = 0, j = obj.children_d.length; i < j; i++) {
- m[obj.children_d[i]].state.selected = true;
- }
- while(par && par.id !== '#') {
- c = 0;
- for(i = 0, j = par.children.length; i < j; i++) {
- c += m[par.children[i]].state.selected;
- }
- if(c === j) {
- par.state.selected = true;
- this._data.core.selected.push(par.id);
- tmp = this.get_node(par, true);
- if(tmp && tmp.length) {
- tmp.children('.jstree-anchor').addClass('jstree-clicked');
- }
- }
- else {
- break;
- }
- par = this.get_node(par.parent);
- }
- if(dom.length) {
- dom.find('.jstree-anchor').addClass('jstree-clicked');
- }
- }, this))
- .on('deselect_node.jstree', $.proxy(function (e, data) {
- var obj = data.node,
- dom = this.get_node(obj, true),
- i, j, tmp;
- for(i = 0, j = obj.children_d.length; i < j; i++) {
- this._model.data[obj.children_d[i]].state.selected = false;
- }
- for(i = 0, j = obj.parents.length; i < j; i++) {
- this._model.data[obj.parents[i]].state.selected = false;
- tmp = this.get_node(obj.parents[i], true);
- if(tmp && tmp.length) {
- tmp.children('.jstree-anchor').removeClass('jstree-clicked');
- }
- }
- tmp = [];
- for(i = 0, j = this._data.core.selected.length; i < j; i++) {
- if($.inArray(this._data.core.selected[i], obj.children_d) === -1 && $.inArray(this._data.core.selected[i], obj.parents) === -1) {
- tmp.push(this._data.core.selected[i]);
- }
- }
- this._data.core.selected = $.vakata.array_unique(tmp);
- if(dom.length) {
- dom.find('.jstree-anchor').removeClass('jstree-clicked');
- }
- }, this))
- .on('delete_node.jstree', $.proxy(function (e, data) {
- var p = this.get_node(data.parent),
- m = this._model.data,
- i, j, c, tmp;
- while(p && p.id !== '#') {
- c = 0;
- for(i = 0, j = p.children.length; i < j; i++) {
- c += m[p.children[i]].state.selected;
- }
- if(c === j) {
- p.state.selected = true;
- this._data.core.selected.push(p.id);
- tmp = this.get_node(p, true);
- if(tmp && tmp.length) {
- tmp.children('.jstree-anchor').addClass('jstree-clicked');
- }
- }
- else {
- break;
- }
- p = this.get_node(p.parent);
- }
- }, this))
- .on('move_node.jstree', $.proxy(function (e, data) {
- var is_multi = data.is_multi,
- old_par = data.old_parent,
- new_par = this.get_node(data.parent),
- m = this._model.data,
- p, c, i, j, tmp;
- if(!is_multi) {
- p = this.get_node(old_par);
- while(p && p.id !== '#') {
- c = 0;
- for(i = 0, j = p.children.length; i < j; i++) {
- c += m[p.children[i]].state.selected;
- }
- if(c === j) {
- p.state.selected = true;
- this._data.core.selected.push(p.id);
- tmp = this.get_node(p, true);
- if(tmp && tmp.length) {
- tmp.children('.jstree-anchor').addClass('jstree-clicked');
- }
- }
- else {
- break;
- }
- p = this.get_node(p.parent);
- }
- }
- p = new_par;
- while(p && p.id !== '#') {
- c = 0;
- for(i = 0, j = p.children.length; i < j; i++) {
- c += m[p.children[i]].state.selected;
- }
- if(c === j) {
- if(!p.state.selected) {
- p.state.selected = true;
- this._data.core.selected.push(p.id);
- tmp = this.get_node(p, true);
- if(tmp && tmp.length) {
- tmp.children('.jstree-anchor').addClass('jstree-clicked');
- }
- }
- }
- else {
- if(p.state.selected) {
- p.state.selected = false;
- this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, p.id);
- tmp = this.get_node(p, true);
- if(tmp && tmp.length) {
- tmp.children('.jstree-anchor').removeClass('jstree-clicked');
- }
- }
- else {
- break;
- }
- }
- p = this.get_node(p.parent);
- }
- }, this));
- }
- };
- /**
- * set the undetermined state where and if necessary. Used internally.
- * @private
- * @name _undetermined()
- * @plugin checkbox
- */
- this._undetermined = function () {
- var i, j, m = this._model.data, s = this._data.core.selected, p = [], t = this;
- for(i = 0, j = s.length; i < j; i++) {
- if(m[s[i]] && m[s[i]].parents) {
- p = p.concat(m[s[i]].parents);
- }
- }
- // attempt for server side undetermined state
- this.element.find('.jstree-closed').not(':has(ul)')
- .each(function () {
- var tmp = t.get_node(this);
- if(!tmp.state.loaded && tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) {
- p.push(tmp.id);
- p = p.concat(tmp.parents);
- }
- });
- p = $.vakata.array_unique(p);
- i = $.inArray('#', p);
- if(i !== -1) {
- p = $.vakata.array_remove(p, i);
- }
-
- this.element.find('.jstree-undetermined').removeClass('jstree-undetermined');
- for(i = 0, j = p.length; i < j; i++) {
- if(!m[p[i]].state.selected) {
- s = this.get_node(p[i], true);
- if(s && s.length) {
- s.children('a').children('.jstree-checkbox').addClass('jstree-undetermined');
- }
- }
- }
- };
- this.redraw_node = function(obj, deep, is_callback) {
- obj = parent.redraw_node.call(this, obj, deep, is_callback);
- if(obj) {
- var tmp = obj.getElementsByTagName('A')[0];
- tmp.insertBefore(_i.cloneNode(), tmp.childNodes[0]);
- }
- if(!is_callback && this.settings.checkbox.three_state) {
- if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
- this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
- }
- return obj;
- };
- this.activate_node = function (obj, e) {
- if(this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox')) {
- e.ctrlKey = true;
- }
- return parent.activate_node.call(this, obj, e);
- };
- /**
- * show the node checkbox icons
- * @name show_checkboxes()
- * @plugin checkbox
- */
- this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.element.children("ul").removeClass("jstree-no-checkboxes"); };
- /**
- * hide the node checkbox icons
- * @name hide_checkboxes()
- * @plugin checkbox
- */
- this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.element.children("ul").addClass("jstree-no-checkboxes"); };
- /**
- * toggle the node icons
- * @name toggle_checkboxes()
- * @plugin checkbox
- */
- this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } };
- };
-
- // include the checkbox plugin by default
- // $.jstree.defaults.plugins.push("checkbox");
-
-/**
- * ### Contextmenu plugin
- *
- * Shows a context menu when a node is right-clicked.
- */
-// TODO: move logic outside of function + check multiple move
-
- /**
- * stores all defaults for the contextmenu plugin
- * @name $.jstree.defaults.contextmenu
- * @plugin contextmenu
- */
- $.jstree.defaults.contextmenu = {
- /**
- * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`.
- * @name $.jstree.defaults.contextmenu.select_node
- * @plugin contextmenu
- */
- select_node : true,
- /**
- * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used.
- * @name $.jstree.defaults.contextmenu.show_at_node
- * @plugin contextmenu
- */
- show_at_node : true,
- /**
- * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too).
- *
- * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required):
- *
- * * `separator_before` - a boolean indicating if there should be a separator before this item
- * * `separator_after` - a boolean indicating if there should be a separator after this item
- * * `_disabled` - a boolean indicating if this action should be disabled
- * * `label` - a string - the name of the action
- * * `action` - a function to be executed if this item is chosen
- * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class
- * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2)
- * * `shortcut_label` - shortcut label (like for example `F2` for rename)
- *
- * @name $.jstree.defaults.contextmenu.items
- * @plugin contextmenu
- */
- items : function (o, cb) { // Could be an object directly
- return {
- "create" : {
- "separator_before" : false,
- "separator_after" : true,
- "_disabled" : false, //(this.check("create_node", data.reference, {}, "last")),
- "label" : "Create",
- "action" : function (data) {
- var inst = $.jstree.reference(data.reference),
- obj = inst.get_node(data.reference);
- inst.create_node(obj, {}, "last", function (new_node) {
- setTimeout(function () { inst.edit(new_node); },0);
- });
- }
- },
- "rename" : {
- "separator_before" : false,
- "separator_after" : false,
- "_disabled" : false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")),
- "label" : "Rename",
- /*
- "shortcut" : 113,
- "shortcut_label" : 'F2',
- "icon" : "glyphicon glyphicon-leaf",
- */
- "action" : function (data) {
- var inst = $.jstree.reference(data.reference),
- obj = inst.get_node(data.reference);
- inst.edit(obj);
- }
- },
- "remove" : {
- "separator_before" : false,
- "icon" : false,
- "separator_after" : false,
- "_disabled" : false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")),
- "label" : "Delete",
- "action" : function (data) {
- var inst = $.jstree.reference(data.reference),
- obj = inst.get_node(data.reference);
- if(inst.is_selected(obj)) {
- inst.delete_node(inst.get_selected());
- }
- else {
- inst.delete_node(obj);
- }
- }
- },
- "ccp" : {
- "separator_before" : true,
- "icon" : false,
- "separator_after" : false,
- "label" : "Edit",
- "action" : false,
- "submenu" : {
- "cut" : {
- "separator_before" : false,
- "separator_after" : false,
- "label" : "Cut",
- "action" : function (data) {
- var inst = $.jstree.reference(data.reference),
- obj = inst.get_node(data.reference);
- if(inst.is_selected(obj)) {
- inst.cut(inst.get_selected());
- }
- else {
- inst.cut(obj);
- }
- }
- },
- "copy" : {
- "separator_before" : false,
- "icon" : false,
- "separator_after" : false,
- "label" : "Copy",
- "action" : function (data) {
- var inst = $.jstree.reference(data.reference),
- obj = inst.get_node(data.reference);
- if(inst.is_selected(obj)) {
- inst.copy(inst.get_selected());
- }
- else {
- inst.copy(obj);
- }
- }
- },
- "paste" : {
- "separator_before" : false,
- "icon" : false,
- "_disabled" : function (data) {
- return !$.jstree.reference(data.reference).can_paste();
- },
- "separator_after" : false,
- "label" : "Paste",
- "action" : function (data) {
- var inst = $.jstree.reference(data.reference),
- obj = inst.get_node(data.reference);
- inst.paste(obj);
- }
- }
- }
- }
- };
- }
- };
-
- $.jstree.plugins.contextmenu = function (options, parent) {
- this.bind = function () {
- parent.bind.call(this);
-
- this.element
- .on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e) {
- e.preventDefault();
- if(!this.is_loading(e.currentTarget)) {
- this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e);
- }
- }, this))
- .on("click.jstree", ".jstree-anchor", $.proxy(function (e) {
- if(this._data.contextmenu.visible) {
- $.vakata.context.hide();
- }
- }, this));
- /*
- if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) {
- var el = null, tm = null;
- this.element
- .on("touchstart", ".jstree-anchor", function (e) {
- el = e.currentTarget;
- tm = +new Date();
- $(document).one("touchend", function (e) {
- e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset);
- e.currentTarget = e.target;
- tm = ((+(new Date())) - tm);
- if(e.target === el && tm > 600 && tm < 1000) {
- e.preventDefault();
- $(el).trigger('contextmenu', e);
- }
- el = null;
- tm = null;
- });
- });
- }
- */
- $(document).on("context_hide.vakata", $.proxy(function () { this._data.contextmenu.visible = false; }, this));
- };
- this.teardown = function () {
- if(this._data.contextmenu.visible) {
- $.vakata.context.hide();
- }
- parent.teardown.call(this);
- };
-
- /**
- * prepare and show the context menu for a node
- * @name show_contextmenu(obj [, x, y])
- * @param {mixed} obj the node
- * @param {Number} x the x-coordinate relative to the document to show the menu at
- * @param {Number} y the y-coordinate relative to the document to show the menu at
- * @param {Object} e the event if available that triggered the contextmenu
- * @plugin contextmenu
- * @trigger show_contextmenu.jstree
- */
- this.show_contextmenu = function (obj, x, y, e) {
- obj = this.get_node(obj);
- if(!obj || obj.id === '#') { return false; }
- var s = this.settings.contextmenu,
- d = this.get_node(obj, true),
- a = d.children(".jstree-anchor"),
- o = false,
- i = false;
- if(s.show_at_node || x === undefined || y === undefined) {
- o = a.offset();
- x = o.left;
- y = o.top + this._data.core.li_height;
- }
- if(this.settings.contextmenu.select_node && !this.is_selected(obj)) {
- this.deselect_all();
- this.select_node(obj, false, false, e);
- }
-
- i = s.items;
- if($.isFunction(i)) {
- i = i.call(this, obj, $.proxy(function (i) {
- this._show_contextmenu(obj, x, y, i);
- }, this));
- }
- if($.isPlainObject(i)) {
- this._show_contextmenu(obj, x, y, i);
- }
- };
- /**
- * show the prepared context menu for a node
- * @name _show_contextmenu(obj, x, y, i)
- * @param {mixed} obj the node
- * @param {Number} x the x-coordinate relative to the document to show the menu at
- * @param {Number} y the y-coordinate relative to the document to show the menu at
- * @param {Number} i the object of items to show
- * @plugin contextmenu
- * @trigger show_contextmenu.jstree
- * @private
- */
- this._show_contextmenu = function (obj, x, y, i) {
- var d = this.get_node(obj, true),
- a = d.children(".jstree-anchor");
- $(document).one("context_show.vakata", $.proxy(function (e, data) {
- var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu';
- $(data.element).addClass(cls);
- }, this));
- this._data.contextmenu.visible = true;
- $.vakata.context.show(a, { 'x' : x, 'y' : y }, i);
- /**
- * triggered when the contextmenu is shown for a node
- * @event
- * @name show_contextmenu.jstree
- * @param {Object} node the node
- * @param {Number} x the x-coordinate of the menu relative to the document
- * @param {Number} y the y-coordinate of the menu relative to the document
- * @plugin contextmenu
- */
- this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y });
- };
- };
-
- // contextmenu helper
- (function ($) {
- var right_to_left = false,
- vakata_context = {
- element : false,
- reference : false,
- position_x : 0,
- position_y : 0,
- items : [],
- html : "",
- is_visible : false
- };
-
- $.vakata.context = {
- settings : {
- hide_onmouseleave : 0,
- icons : true
- },
- _trigger : function (event_name) {
- $(document).triggerHandler("context_" + event_name + ".vakata", {
- "reference" : vakata_context.reference,
- "element" : vakata_context.element,
- "position" : {
- "x" : vakata_context.position_x,
- "y" : vakata_context.position_y
- }
- });
- },
- _execute : function (i) {
- i = vakata_context.items[i];
- return i && (!i._disabled || ($.isFunction(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, {
- "item" : i,
- "reference" : vakata_context.reference,
- "element" : vakata_context.element,
- "position" : {
- "x" : vakata_context.position_x,
- "y" : vakata_context.position_y
- }
- }) : false;
- },
- _parse : function (o, is_callback) {
- if(!o) { return false; }
- if(!is_callback) {
- vakata_context.html = "";
- vakata_context.items = [];
- }
- var str = "",
- sep = false,
- tmp;
-
- if(is_callback) { str += "<"+"ul>"; }
- $.each(o, function (i, val) {
- if(!val) { return true; }
- vakata_context.items.push(val);
- if(!sep && val.separator_before) {
- str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + ">&#160;<"+"/a><"+"/li>";
- }
- sep = false;
- str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.isFunction(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">";
- str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "'>";
- if($.vakata.context.settings.icons) {
- str += "<"+"i ";
- if(val.icon) {
- if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; }
- else { str += " class='" + val.icon + "' "; }
- }
- str += "><"+"/i><"+"span class='vakata-contextmenu-sep'>&#160;<"+"/span>";
- }
- str += val.label + (val.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+val.shortcut+'">'+ (val.shortcut_label || '') +'</span>':'') + "<"+"/a>";
- if(val.submenu) {
- tmp = $.vakata.context._parse(val.submenu, true);
- if(tmp) { str += tmp; }
- }
- str += "<"+"/li>";
- if(val.separator_after) {
- str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + ">&#160;<"+"/a><"+"/li>";
- sep = true;
- }
- });
- str = str.replace(/<li class\='vakata-context-separator'\><\/li\>$/,"");
- if(is_callback) { str += "</ul>"; }
- /**
- * triggered on the document when the contextmenu is parsed (HTML is built)
- * @event
- * @plugin contextmenu
- * @name context_parse.vakata
- * @param {jQuery} reference the element that was right clicked
- * @param {jQuery} element the DOM element of the menu itself
- * @param {Object} position the x & y coordinates of the menu
- */
- if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); }
- return str.length > 10 ? str : false;
- },
- _show_submenu : function (o) {
- o = $(o);
- if(!o.length || !o.children("ul").length) { return; }
- var e = o.children("ul"),
- x = o.offset().left + o.outerWidth(),
- y = o.offset().top,
- w = e.width(),
- h = e.height(),
- dw = $(window).width() + $(window).scrollLeft(),
- dh = $(window).height() + $(window).scrollTop();
- // може да се спести е една проверка - дали няма някой от класовете вече нагоре
- if(right_to_left) {
- o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left");
- }
- else {
- o[x + w + 10 > dw ? "addClass" : "removeClass"]("vakata-context-right");
- }
- if(y + h + 10 > dh) {
- e.css("bottom","-1px");
- }
- e.show();
- },
- show : function (reference, position, data) {
- var o, e, x, y, w, h, dw, dh, cond = true;
- if(vakata_context.element && vakata_context.element.length) {
- vakata_context.element.width('');
- }
- switch(cond) {
- case (!position && !reference):
- return false;
- case (!!position && !!reference):
- vakata_context.reference = reference;
- vakata_context.position_x = position.x;
- vakata_context.position_y = position.y;
- break;
- case (!position && !!reference):
- vakata_context.reference = reference;
- o = reference.offset();
- vakata_context.position_x = o.left + reference.outerHeight();
- vakata_context.position_y = o.top;
- break;
- case (!!position && !reference):
- vakata_context.position_x = position.x;
- vakata_context.position_y = position.y;
- break;
- }
- if(!!reference && !data && $(reference).data('vakata_contextmenu')) {
- data = $(reference).data('vakata_contextmenu');
- }
- if($.vakata.context._parse(data)) {
- vakata_context.element.html(vakata_context.html);
- }
- if(vakata_context.items.length) {
- e = vakata_context.element;
- x = vakata_context.position_x;
- y = vakata_context.position_y;
- w = e.width();
- h = e.height();
- dw = $(window).width() + $(window).scrollLeft();
- dh = $(window).height() + $(window).scrollTop();
- if(right_to_left) {
- x -= e.outerWidth();
- if(x < $(window).scrollLeft() + 20) {
- x = $(window).scrollLeft() + 20;
- }
- }
- if(x + w + 20 > dw) {
- x = dw - (w + 20);
- }
- if(y + h + 20 > dh) {
- y = dh - (h + 20);
- }
-
- vakata_context.element
- .css({ "left" : x, "top" : y })
- .show()
- .find('a:eq(0)').focus().parent().addClass("vakata-context-hover");
- vakata_context.is_visible = true;
- /**
- * triggered on the document when the contextmenu is shown
- * @event
- * @plugin contextmenu
- * @name context_show.vakata
- * @param {jQuery} reference the element that was right clicked
- * @param {jQuery} element the DOM element of the menu itself
- * @param {Object} position the x & y coordinates of the menu
- */
- $.vakata.context._trigger("show");
- }
- },
- hide : function () {
- if(vakata_context.is_visible) {
- vakata_context.element.hide().find("ul").hide().end().find(':focus').blur();
- vakata_context.is_visible = false;
- /**
- * triggered on the document when the contextmenu is hidden
- * @event
- * @plugin contextmenu
- * @name context_hide.vakata
- * @param {jQuery} reference the element that was right clicked
- * @param {jQuery} element the DOM element of the menu itself
- * @param {Object} position the x & y coordinates of the menu
- */
- $.vakata.context._trigger("hide");
- }
- }
- };
- $(function () {
- right_to_left = $("body").css("direction") === "rtl";
- var to = false;
-
- vakata_context.element = $("<ul class='vakata-context'></ul>");
- vakata_context.element
- .on("mouseenter", "li", function (e) {
- e.stopImmediatePropagation();
-
- if($.contains(this, e.relatedTarget)) {
- // премахнато заради delegate mouseleave по-долу
- // $(this).find(".vakata-context-hover").removeClass("vakata-context-hover");
- return;
- }
-
- if(to) { clearTimeout(to); }
- vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end();
-
- $(this)
- .siblings().find("ul").hide().end().end()
- .parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover");
- $.vakata.context._show_submenu(this);
- })
- // тестово - дали не натоварва?
- .on("mouseleave", "li", function (e) {
- if($.contains(this, e.relatedTarget)) { return; }
- $(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover");
- })
- .on("mouseleave", function (e) {
- $(this).find(".vakata-context-hover").removeClass("vakata-context-hover");
- if($.vakata.context.settings.hide_onmouseleave) {
- to = setTimeout(
- (function (t) {
- return function () { $.vakata.context.hide(); };
- }(this)), $.vakata.context.settings.hide_onmouseleave);
- }
- })
- .on("click", "a", function (e) {
- e.preventDefault();
- })
- .on("mouseup", "a", function (e) {
- if(!$(this).blur().parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) {
- $.vakata.context.hide();
- }
- })
- .on('keydown', 'a', function (e) {
- var o = null;
- switch(e.which) {
- case 13:
- case 32:
- e.type = "mouseup";
- e.preventDefault();
- $(e.currentTarget).trigger(e);
- break;
- case 37:
- if(vakata_context.is_visible) {
- vakata_context.element.find(".vakata-context-hover").last().parents("li:eq(0)").find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').focus();
- e.stopImmediatePropagation();
- e.preventDefault();
- }
- break;
- case 38:
- if(vakata_context.is_visible) {
- o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first();
- if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); }
- o.addClass("vakata-context-hover").children('a').focus();
- e.stopImmediatePropagation();
- e.preventDefault();
- }
- break;
- case 39:
- if(vakata_context.is_visible) {
- vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').focus();
- e.stopImmediatePropagation();
- e.preventDefault();
- }
- break;
- case 40:
- if(vakata_context.is_visible) {
- o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first();
- if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); }
- o.addClass("vakata-context-hover").children('a').focus();
- e.stopImmediatePropagation();
- e.preventDefault();
- }
- break;
- case 27:
- $.vakata.context.hide();
- e.preventDefault();
- break;
- default:
- //console.log(e.which);
- break;
- }
- })
- .on('keydown', function (e) {
- e.preventDefault();
- var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent();
- if(a.parent().not('.vakata-context-disabled')) {
- a.mouseup();
- }
- })
- .appendTo("body");
-
- $(document)
- .on("mousedown", function (e) {
- if(vakata_context.is_visible && !$.contains(vakata_context.element[0], e.target)) { $.vakata.context.hide(); }
- })
- .on("context_show.vakata", function (e, data) {
- vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent");
- if(right_to_left) {
- vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl");
- }
- // also apply a RTL class?
- vakata_context.element.find("ul").hide().end();
- });
- });
- }($));
- // $.jstree.defaults.plugins.push("contextmenu");
-
-/**
- * ### Drag'n'drop plugin
- *
- * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations.
- */
-
- /**
- * stores all defaults for the drag'n'drop plugin
- * @name $.jstree.defaults.dnd
- * @plugin dnd
- */
- $.jstree.defaults.dnd = {
- /**
- * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`.
- * @name $.jstree.defaults.dnd.copy
- * @plugin dnd
- */
- copy : true,
- /**
- * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`.
- * @name $.jstree.defaults.dnd.open_timeout
- * @plugin dnd
- */
- open_timeout : 500,
- /**
- * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the node as an argument - return `false` to prevent dragging
- * @name $.jstree.defaults.dnd.is_draggable
- * @plugin dnd
- */
- is_draggable : true,
- /**
- * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true`
- * @name $.jstree.defaults.dnd.check_while_dragging
- * @plugin dnd
- */
- check_while_dragging : true
- };
- // TODO: now check works by checking for each node individually, how about max_children, unique, etc?
- // TODO: drop somewhere else - maybe demo only?
- $.jstree.plugins.dnd = function (options, parent) {
- this.bind = function () {
- parent.bind.call(this);
-
- this.element
- .on('mousedown touchstart', '.jstree-anchor', $.proxy(function (e) {
- var obj = this.get_node(e.target),
- mlt = this.is_selected(obj) ? this.get_selected().length : 1;
- if(obj && obj.id && obj.id !== "#" && (e.which === 1 || e.type === "touchstart") &&
- (this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, obj)))
- ) {
- this.element.trigger('mousedown.jstree');
- return $.vakata.dnd.start(e, { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_selected() : [obj.id] }, '<div id="jstree-dnd" class="jstree-' + this.get_theme() + '"><i class="jstree-icon jstree-er"></i>' + (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget, true)) + '<ins class="jstree-copy" style="display:none;">+</ins></div>');
- }
- }, this));
- };
- };
-
- $(function() {
- // bind only once for all instances
- var lastmv = false,
- laster = false,
- opento = false,
- marker = $('<div id="jstree-marker">&#160;</div>').hide().appendTo('body');
-
- $(document)
- .bind('dnd_start.vakata', function (e, data) {
- lastmv = false;
- })
- .bind('dnd_move.vakata', function (e, data) {
- if(opento) { clearTimeout(opento); }
- if(!data.data.jstree) { return; }
-
- // if we are hovering the marker image do nothing (can happen on "inside" drags)
- if(data.event.target.id && data.event.target.id === 'jstree-marker') {
- return;
- }
-
- var ins = $.jstree.reference(data.event.target),
- ref = false,
- off = false,
- rel = false,
- l, t, h, p, i, o, ok, t1, t2, op, ps, pr;
- // if we are over an instance
- if(ins && ins._data && ins._data.dnd) {
- marker.attr('class', 'jstree-' + ins.get_theme());
- data.helper
- .children().attr('class', 'jstree-' + ins.get_theme())
- .find('.jstree-copy:eq(0)')[ data.data.origin && data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey) ? 'show' : 'hide' ]();
-
-
- // if are hovering the container itself add a new root node
- if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) {
- ok = true;
- for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
- ok = ok && ins.check( (data.data.origin && data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), '#', 'last');
- if(!ok) { break; }
- }
- if(ok) {
- lastmv = { 'ins' : ins, 'par' : '#', 'pos' : 'last' };
- marker.hide();
- data.helper.find('.jstree-icon:eq(0)').removeClass('jstree-er').addClass('jstree-ok');
- return;
- }
- }
- else {
- // if we are hovering a tree node
- ref = $(data.event.target).closest('a');
- if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) {
- off = ref.offset();
- rel = data.event.pageY - off.top;
- h = ref.height();
- if(rel < h / 3) {
- o = ['b', 'i', 'a'];
- }
- else if(rel > h - h / 3) {
- o = ['a', 'i', 'b'];
- }
- else {
- o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a'];
- }
- $.each(o, function (j, v) {
- switch(v) {
- case 'b':
- l = off.left - 6;
- t = off.top - 5;
- p = ins.get_parent(ref);
- i = ref.parent().index();
- break;
- case 'i':
- l = off.left - 2;
- t = off.top - 5 + h / 2 + 1;
- p = ref.parent();
- i = 0;
- break;
- case 'a':
- l = off.left - 6;
- t = off.top - 5 + h;
- p = ins.get_parent(ref);
- i = ref.parent().index() + 1;
- break;
- }
- /*!
- // TODO: moving inside, but the node is not yet loaded?
- // the check will work anyway, as when moving the node will be loaded first and checked again
- if(v === 'i' && !ins.is_loaded(p)) { }
- */
- ok = true;
- for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
- op = data.data.origin && data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey) ? "copy_node" : "move_node";
- ps = i;
- if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) {
- pr = ins.get_node(p);
- if(ps > $.inArray(data.data.nodes[t1], pr.children)) {
- ps -= 1;
- }
- }
- ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps) );
- if(!ok) {
- if(ins && ins.last_error) { laster = ins.last_error(); }
- break;
- }
- }
- if(ok) {
- if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) {
- opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout);
- }
- lastmv = { 'ins' : ins, 'par' : p, 'pos' : i };
- marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show();
- data.helper.find('.jstree-icon:eq(0)').removeClass('jstree-er').addClass('jstree-ok');
- laster = {};
- o = true;
- return false;
- }
- });
- if(o === true) { return; }
- }
- }
- }
- lastmv = false;
- data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');
- marker.hide();
- })
- .bind('dnd_scroll.vakata', function (e, data) {
- if(!data.data.jstree) { return; }
- marker.hide();
- lastmv = false;
- data.helper.find('.jstree-icon:eq(0)').removeClass('jstree-ok').addClass('jstree-er');
- })
- .bind('dnd_stop.vakata', function (e, data) {
- if(opento) { clearTimeout(opento); }
- if(!data.data.jstree) { return; }
- marker.hide();
- var i, j, nodes = [];
- if(lastmv) {
- for(i = 0, j = data.data.nodes.length; i < j; i++) {
- nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i];
- }
- lastmv.ins[ data.data.origin && data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos);
- }
- else {
- i = $(data.event.target).closest('.jstree');
- if(i.length && laster && laster.error && laster.error === 'check') {
- i = i.jstree(true);
- if(i) {
- i.settings.core.error.call(this, laster);
- }
- }
- }
- })
- .bind('keyup keydown', function (e, data) {
- data = $.vakata.dnd._get();
- if(data.data && data.data.jstree) {
- data.helper.find('.jstree-copy:eq(0)')[ data.data.origin && data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey) ? 'show' : 'hide' ]();
- }
- });
- });
-
- // helpers
- (function ($) {
- $.fn.vakata_reverse = [].reverse;
- // private variable
- var vakata_dnd = {
- element : false,
- is_down : false,
- is_drag : false,
- helper : false,
- helper_w: 0,
- data : false,
- init_x : 0,
- init_y : 0,
- scroll_l: 0,
- scroll_t: 0,
- scroll_e: false,
- scroll_i: false
- };
- $.vakata.dnd = {
- settings : {
- scroll_speed : 10,
- scroll_proximity : 20,
- helper_left : 5,
- helper_top : 10,
- threshold : 5
- },
- _trigger : function (event_name, e) {
- var data = $.vakata.dnd._get();
- data.event = e;
- $(document).triggerHandler("dnd_" + event_name + ".vakata", data);
- },
- _get : function () {
- return {
- "data" : vakata_dnd.data,
- "element" : vakata_dnd.element,
- "helper" : vakata_dnd.helper
- };
- },
- _clean : function () {
- if(vakata_dnd.helper) { vakata_dnd.helper.remove(); }
- if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }
- vakata_dnd = {
- element : false,
- is_down : false,
- is_drag : false,
- helper : false,
- helper_w: 0,
- data : false,
- init_x : 0,
- init_y : 0,
- scroll_l: 0,
- scroll_t: 0,
- scroll_e: false,
- scroll_i: false
- };
- $(document).off("mousemove touchmove", $.vakata.dnd.drag);
- $(document).off("mouseup touchend", $.vakata.dnd.stop);
- },
- _scroll : function (init_only) {
- if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) {
- if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }
- return false;
- }
- if(!vakata_dnd.scroll_i) {
- vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100);
- return false;
- }
- if(init_only === true) { return false; }
-
- var i = vakata_dnd.scroll_e.scrollTop(),
- j = vakata_dnd.scroll_e.scrollLeft();
- vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed);
- vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed);
- if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) {
- /**
- * triggered on the document when a drag causes an element to scroll
- * @event
- * @plugin dnd
- * @name dnd_scroll.vakata
- * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
- * @param {DOM} element the DOM element being dragged
- * @param {jQuery} helper the helper shown next to the mouse
- * @param {jQuery} event the element that is scrolling
- */
- $.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e);
- }
- },
- start : function (e, data, html) {
- if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
- e.pageX = e.originalEvent.changedTouches[0].pageX;
- e.pageY = e.originalEvent.changedTouches[0].pageY;
- e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
- }
- if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); }
- try {
- e.currentTarget.unselectable = "on";
- e.currentTarget.onselectstart = function() { return false; };
- if(e.currentTarget.style) { e.currentTarget.style.MozUserSelect = "none"; }
- } catch(ignore) { }
- vakata_dnd.init_x = e.pageX;
- vakata_dnd.init_y = e.pageY;
- vakata_dnd.data = data;
- vakata_dnd.is_down = true;
- vakata_dnd.element = e.currentTarget;
- if(html !== false) {
- vakata_dnd.helper = $("<div id='vakata-dnd'></div>").html(html).css({
- "display" : "block",
- "margin" : "0",
- "padding" : "0",
- "position" : "absolute",
- "top" : "-2000px",
- "lineHeight" : "16px",
- "zIndex" : "10000"
- });
- }
- $(document).bind("mousemove touchmove", $.vakata.dnd.drag);
- $(document).bind("mouseup touchend", $.vakata.dnd.stop);
- return false;
- },
- drag : function (e) {
- if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
- e.pageX = e.originalEvent.changedTouches[0].pageX;
- e.pageY = e.originalEvent.changedTouches[0].pageY;
- e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
- }
- if(!vakata_dnd.is_down) { return; }
- if(!vakata_dnd.is_drag) {
- if(
- Math.abs(e.pageX - vakata_dnd.init_x) > $.vakata.dnd.settings.threshold ||
- Math.abs(e.pageY - vakata_dnd.init_y) > $.vakata.dnd.settings.threshold
- ) {
- if(vakata_dnd.helper) {
- vakata_dnd.helper.appendTo("body");
- vakata_dnd.helper_w = vakata_dnd.helper.outerWidth();
- }
- vakata_dnd.is_drag = true;
- /**
- * triggered on the document when a drag starts
- * @event
- * @plugin dnd
- * @name dnd_start.vakata
- * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
- * @param {DOM} element the DOM element being dragged
- * @param {jQuery} helper the helper shown next to the mouse
- * @param {Object} event the event that caused the start (probably mousemove)
- */
- $.vakata.dnd._trigger("start", e);
- }
- else { return; }
- }
-
- var d = false, w = false,
- dh = false, wh = false,
- dw = false, ww = false,
- dt = false, dl = false,
- ht = false, hl = false;
-
- vakata_dnd.scroll_t = 0;
- vakata_dnd.scroll_l = 0;
- vakata_dnd.scroll_e = false;
- $(e.target)
- .parentsUntil("body").addBack().vakata_reverse()
- .filter(function () {
- return (/^auto|scroll$/).test($(this).css("overflow")) &&
- (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth);
- })
- .each(function () {
- var t = $(this), o = t.offset();
- if(this.scrollHeight > this.offsetHeight) {
- if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; }
- if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; }
- }
- if(this.scrollWidth > this.offsetWidth) {
- if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; }
- if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; }
- }
- if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {
- vakata_dnd.scroll_e = $(this);
- return false;
- }
- });
-
- if(!vakata_dnd.scroll_e) {
- d = $(document); w = $(window);
- dh = d.height(); wh = w.height();
- dw = d.width(); ww = w.width();
- dt = d.scrollTop(); dl = d.scrollLeft();
- if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; }
- if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; }
- if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; }
- if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; }
- if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {
- vakata_dnd.scroll_e = d;
- }
- }
- if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); }
-
- if(vakata_dnd.helper) {
- ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10);
- hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10);
- if(dh && ht + 25 > dh) { ht = dh - 50; }
- if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); }
- vakata_dnd.helper.css({
- left : hl + "px",
- top : ht + "px"
- });
- }
- /**
- * triggered on the document when a drag is in progress
- * @event
- * @plugin dnd
- * @name dnd_move.vakata
- * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
- * @param {DOM} element the DOM element being dragged
- * @param {jQuery} helper the helper shown next to the mouse
- * @param {Object} event the event that caused this to trigger (most likely mousemove)
- */
- $.vakata.dnd._trigger("move", e);
- },
- stop : function (e) {
- if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
- e.pageX = e.originalEvent.changedTouches[0].pageX;
- e.pageY = e.originalEvent.changedTouches[0].pageY;
- e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
- }
- if(vakata_dnd.is_drag) {
- /**
- * triggered on the document when a drag stops (the dragged element is dropped)
- * @event
- * @plugin dnd
- * @name dnd_stop.vakata
- * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
- * @param {DOM} element the DOM element being dragged
- * @param {jQuery} helper the helper shown next to the mouse
- * @param {Object} event the event that caused the stop
- */
- $.vakata.dnd._trigger("stop", e);
- }
- $.vakata.dnd._clean();
- }
- };
- }(jQuery));
-
- // include the dnd plugin by default
- // $.jstree.defaults.plugins.push("dnd");
-
-
-/**
- * ### Search plugin
- *
- * Adds search functionality to jsTree.
- */
-
- /**
- * stores all defaults for the search plugin
- * @name $.jstree.defaults.search
- * @plugin search
- */
- $.jstree.defaults.search = {
- /**
- * a jQuery-like AJAX config, which jstree uses if a server should be queried for results.
- *
- * A `str` (which is the search string) parameter will be added with the request. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed.
- * Leave this setting as `false` to not query the server.
- * @name $.jstree.defaults.search.ajax
- * @plugin search
- */
- ajax : false,
- /**
- * Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `true`.
- * @name $.jstree.defaults.search.fuzzy
- * @plugin search
- */
- fuzzy : true,
- /**
- * Indicates if the search should be case sensitive. Default is `false`.
- * @name $.jstree.defaults.search.case_sensitive
- * @plugin search
- */
- case_sensitive : false,
- /**
- * Indicates if the tree should be filtered to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers). Default is `false`.
- * @name $.jstree.defaults.search.show_only_matches
- * @plugin search
- */
- show_only_matches : false,
- /**
- * Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`.
- * @name $.jstree.defaults.search.close_opened_onclear
- * @plugin search
- */
- close_opened_onclear : true
- };
-
- $.jstree.plugins.search = function (options, parent) {
- this.bind = function () {
- parent.bind.call(this);
-
- this._data.search.str = "";
- this._data.search.dom = $();
- this._data.search.res = [];
- this._data.search.opn = [];
- this._data.search.sln = null;
-
- if(this.settings.search.show_only_matches) {
- this.element
- .on("search.jstree", function (e, data) {
- if(data.nodes.length) {
- $(this).find("li").hide().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
- data.nodes.parentsUntil(".jstree").addBack().show()
- .filter("ul").each(function () { $(this).children("li:visible").eq(-1).addClass("jstree-last"); });
- }
- })
- .on("clear_search.jstree", function (e, data) {
- if(data.nodes.length) {
- $(this).find("li").css("display","").filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
- }
- });
- }
- };
- /**
- * used to search the tree nodes for a given string
- * @name search(str [, skip_async])
- * @param {String} str the search string
- * @param {Boolean} skip_async if set to true server will not be queried even if configured
- * @plugin search
- * @trigger search.jstree
- */
- this.search = function (str, skip_async) {
- if(str === false || $.trim(str) === "") {
- return this.clear_search();
- }
- var s = this.settings.search,
- a = s.ajax ? $.extend({}, s.ajax) : false,
- f = null,
- r = [],
- p = [], i, j;
- if(this._data.search.res.length) {
- this.clear_search();
- }
- if(!skip_async && a !== false) {
- if(!a.data) { a.data = {}; }
- a.data.str = str;
- return $.ajax(a)
- .fail($.proxy(function () {
- this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) };
- this.settings.core.error.call(this, this._data.core.last_error);
- }, this))
- .done($.proxy(function (d) {
- if(d && d.d) { d = d.d; }
- this._data.search.sln = !$.isArray(d) ? [] : d;
- this._search_load(str);
- }, this));
- }
- this._data.search.str = str;
- this._data.search.dom = $();
- this._data.search.res = [];
- this._data.search.opn = [];
-
- f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy });
-
- $.each(this._model.data, function (i, v) {
- if(v.text && f.search(v.text).isMatch) {
- r.push(i);
- p = p.concat(v.parents);
- }
- });
- if(r.length) {
- p = $.vakata.array_unique(p);
- this._search_open(p);
- for(i = 0, j = r.length; i < j; i++) {
- f = this.get_node(r[i], true);
- if(f) {
- this._data.search.dom = this._data.search.dom.add(f);
- }
- }
- this._data.search.res = r;
- this._data.search.dom.children(".jstree-anchor").addClass('jstree-search');
- }
- /**
- * triggered after search is complete
- * @event
- * @name search.jstree
- * @param {jQuery} nodes a jQuery collection of matching nodes
- * @param {String} str the search string
- * @param {Array} res a collection of objects represeing the matching nodes
- * @plugin search
- */
- this.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res });
- };
- /**
- * used to clear the last search (removes classes and shows all nodes if filtering is on)
- * @name clear_search()
- * @plugin search
- * @trigger clear_search.jstree
- */
- this.clear_search = function () {
- this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search");
- if(this.settings.search.close_opened_onclear) {
- this.close_node(this._data.search.opn, 0);
- }
- /**
- * triggered after search is complete
- * @event
- * @name clear_search.jstree
- * @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search)
- * @param {String} str the search string (the last search string)
- * @param {Array} res a collection of objects represeing the matching nodes (the result from the last search)
- * @plugin search
- */
- this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res });
- this._data.search.str = "";
- this._data.search.res = [];
- this._data.search.opn = [];
- this._data.search.dom = $();
- };
- /**
- * opens nodes that need to be opened to reveal the search results. Used only internally.
- * @private
- * @name _search_open(d)
- * @param {Array} d an array of node IDs
- * @plugin search
- */
- this._search_open = function (d) {
- var t = this;
- $.each(d.concat([]), function (i, v) {
- v = document.getElementById(v);
- if(v) {
- if(t.is_closed(v)) {
- t._data.search.opn.push(v.id);
- t.open_node(v, function () { t._search_open(d); }, 0);
- }
- }
- });
- };
- /**
- * loads nodes that need to be opened to reveal the search results. Used only internally.
- * @private
- * @name _search_load(d, str)
- * @param {String} str the search string
- * @plugin search
- */
- this._search_load = function (str) {
- var res = true,
- t = this,
- m = t._model.data;
- if($.isArray(this._data.search.sln)) {
- if(!this._data.search.sln.length) {
- this._data.search.sln = null;
- this.search(str, true);
- }
- else {
- $.each(this._data.search.sln, function (i, v) {
- if(m[v]) {
- $.vakata.array_remove_item(t._data.search.sln, v);
- if(!m[v].state.loaded) {
- t.load_node(v, function (o, s) { if(s) { t._search_load(str); } });
- res = false;
- }
- }
- });
- if(res) {
- this._data.search.sln = [];
- this._search_load(str);
- }
- }
- }
- };
- };
-
- // helpers
- (function ($) {
- // from http://kiro.me/projects/fuse.html
- $.vakata.search = function(pattern, txt, options) {
- options = options || {};
- if(options.fuzzy !== false) {
- options.fuzzy = true;
- }
- pattern = options.caseSensitive ? pattern : pattern.toLowerCase();
- var MATCH_LOCATION = options.location || 0,
- MATCH_DISTANCE = options.distance || 100,
- MATCH_THRESHOLD = options.threshold || 0.6,
- patternLen = pattern.length,
- matchmask, pattern_alphabet, match_bitapScore, search;
- if(patternLen > 32) {
- options.fuzzy = false;
- }
- if(options.fuzzy) {
- matchmask = 1 << (patternLen - 1);
- pattern_alphabet = (function () {
- var mask = {},
- i = 0;
- for (i = 0; i < patternLen; i++) {
- mask[pattern.charAt(i)] = 0;
- }
- for (i = 0; i < patternLen; i++) {
- mask[pattern.charAt(i)] |= 1 << (patternLen - i - 1);
- }
- return mask;
- }());
- match_bitapScore = function (e, x) {
- var accuracy = e / patternLen,
- proximity = Math.abs(MATCH_LOCATION - x);
- if(!MATCH_DISTANCE) {
- return proximity ? 1.0 : accuracy;
- }
- return accuracy + (proximity / MATCH_DISTANCE);
- };
- }
- search = function (text) {
- text = options.caseSensitive ? text : text.toLowerCase();
- if(pattern === text || text.indexOf(pattern) !== -1) {
- return {
- isMatch: true,
- score: 0
- };
- }
- if(!options.fuzzy) {
- return {
- isMatch: false,
- score: 1
- };
- }
- var i, j,
- textLen = text.length,
- scoreThreshold = MATCH_THRESHOLD,
- bestLoc = text.indexOf(pattern, MATCH_LOCATION),
- binMin, binMid,
- binMax = patternLen + textLen,
- lastRd, start, finish, rd, charMatch,
- score = 1,
- locations = [];
- if (bestLoc !== -1) {
- scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);
- bestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen);
- if (bestLoc !== -1) {
- scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);
- }
- }
- bestLoc = -1;
- for (i = 0; i < patternLen; i++) {
- binMin = 0;
- binMid = binMax;
- while (binMin < binMid) {
- if (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) {
- binMin = binMid;
- } else {
- binMax = binMid;
- }
- binMid = Math.floor((binMax - binMin) / 2 + binMin);
- }
- binMax = binMid;
- start = Math.max(1, MATCH_LOCATION - binMid + 1);
- finish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen;
- rd = new Array(finish + 2);
- rd[finish + 1] = (1 << i) - 1;
- for (j = finish; j >= start; j--) {
- charMatch = pattern_alphabet[text.charAt(j - 1)];
- if (i === 0) {
- rd[j] = ((rd[j + 1] << 1) | 1) & charMatch;
- } else {
- rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1];
- }
- if (rd[j] & matchmask) {
- score = match_bitapScore(i, j - 1);
- if (score <= scoreThreshold) {
- scoreThreshold = score;
- bestLoc = j - 1;
- locations.push(bestLoc);
- if (bestLoc > MATCH_LOCATION) {
- start = Math.max(1, 2 * MATCH_LOCATION - bestLoc);
- } else {
- break;
- }
- }
- }
- }
- if (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) {
- break;
- }
- lastRd = rd;
- }
- return {
- isMatch: bestLoc >= 0,
- score: score
- };
- };
- return txt === true ? { 'search' : search } : search(txt);
- };
- }(jQuery));
-
- // include the search plugin by default
- // $.jstree.defaults.plugins.push("search");
-
-/**
- * ### Sort plugin
- *
- * Autmatically sorts all siblings in the tree according to a sorting function.
- */
-
- /**
- * the settings function used to sort the nodes.
- * It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`.
- * @name $.jstree.defaults.sort
- * @plugin sort
- */
- $.jstree.defaults.sort = function (a, b) {
- //return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b);
- return this.get_text(a) > this.get_text(b) ? 1 : -1;
- };
- $.jstree.plugins.sort = function (options, parent) {
- this.bind = function () {
- parent.bind.call(this);
- this.element
- .on("model.jstree", $.proxy(function (e, data) {
- this.sort(data.parent, true);
- }, this))
- .on("rename_node.jstree create_node.jstree", $.proxy(function (e, data) {
- this.sort(data.parent || data.node.parent, false);
- this.redraw_node(data.parent || data.node.parent, true);
- }, this))
- .on("move_node.jstree copy_node.jstree", $.proxy(function (e, data) {
- this.sort(data.parent, false);
- this.redraw_node(data.parent, true);
- }, this));
- };
- /**
- * used to sort a node's children
- * @private
- * @name sort(obj [, deep])
- * @param {mixed} obj the node
- * @param {Boolean} deep if set to `true` nodes are sorted recursively.
- * @plugin sort
- * @trigger search.jstree
- */
- this.sort = function (obj, deep) {
- var i, j;
- obj = this.get_node(obj);
- if(obj && obj.children && obj.children.length) {
- obj.children.sort($.proxy(this.settings.sort, this));
- if(deep) {
- for(i = 0, j = obj.children_d.length; i < j; i++) {
- this.sort(obj.children_d[i], false);
- }
- }
- }
- };
- };
-
- // include the sort plugin by default
- // $.jstree.defaults.plugins.push("sort");
-
-/**
- * ### State plugin
- *
- * Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc)
- */
-
- var to = false;
- /**
- * stores all defaults for the state plugin
- * @name $.jstree.defaults.state
- * @plugin state
- */
- $.jstree.defaults.state = {
- /**
- * A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`.
- * @name $.jstree.defaults.state.key
- * @plugin state
- */
- key : 'jstree',
- /**
- * A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`.
- * @name $.jstree.defaults.state.events
- * @plugin state
- */
- events : 'changed.jstree open_node.jstree close_node.jstree',
- /**
- * Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire.
- * @name $.jstree.defaults.state.ttl
- * @plugin state
- */
- ttl : false,
- /**
- * A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state.
- * @name $.jstree.defaults.state.filter
- * @plugin state
- */
- filter : false
- };
- $.jstree.plugins.state = function (options, parent) {
- this.bind = function () {
- parent.bind.call(this);
- var bind = $.proxy(function () {
- this.element.on(this.settings.state.events, $.proxy(function () {
- if(to) { clearTimeout(to); }
- to = setTimeout($.proxy(function () { this.save_state(); }, this), 100);
- }, this));
- }, this);
- this.element
- .on("ready.jstree", $.proxy(function (e, data) {
- this.element.one("restore_state.jstree", bind);
- if(!this.restore_state()) { bind(); }
- }, this));
- };
- /**
- * save the state
- * @name save_state()
- * @plugin state
- */
- this.save_state = function () {
- var st = { 'state' : this.get_state(), 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) };
- $.vakata.storage.set(this.settings.state.key, JSON.stringify(st));
- };
- /**
- * restore the state from the user's computer
- * @name restore_state()
- * @plugin state
- */
- this.restore_state = function () {
- var k = $.vakata.storage.get(this.settings.state.key);
- if(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } }
- if(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; }
- if(!!k && k.state) { k = k.state; }
- if(!!k && $.isFunction(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); }
- if(!!k) {
- this.element.one("set_state.jstree", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); });
- this.set_state(k);
- return true;
- }
- return false;
- };
- /**
- * clear the state on the user's computer
- * @name clear_state()
- * @plugin state
- */
- this.clear_state = function () {
- return $.vakata.storage.del(this.settings.state.key);
- };
- };
-
- (function ($, undefined) {
- $.vakata.storage = {
- // simply specifying the functions in FF throws an error
- set : function (key, val) { return window.localStorage.setItem(key, val); },
- get : function (key) { return window.localStorage.getItem(key); },
- del : function (key) { return window.localStorage.removeItem(key); }
- };
- }(jQuery));
-
- // include the state plugin by default
- // $.jstree.defaults.plugins.push("state");
-
-/**
- * ### Types plugin
- *
- * Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group.
- */
-
- /**
- * An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional).
- *
- * * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited.
- * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited.
- * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits.
- * * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme.
- *
- * There are two predefined types:
- *
- * * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes.
- * * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified.
- *
- * @name $.jstree.defaults.types
- * @plugin types
- */
- $.jstree.defaults.types = {
- '#' : {},
- 'default' : {}
- };
-
- $.jstree.plugins.types = function (options, parent) {
- this.init = function (el, options) {
- var i, j;
- if(options && options.types && options.types['default']) {
- for(i in options.types) {
- if(i !== "default" && i !== "#" && options.types.hasOwnProperty(i)) {
- for(j in options.types['default']) {
- if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) {
- options.types[i][j] = options.types['default'][j];
- }
- }
- }
- }
- }
- parent.init.call(this, el, options);
- this._model.data['#'].type = '#';
- };
- this.bind = function () {
- parent.bind.call(this);
- this.element
- .on('model.jstree', $.proxy(function (e, data) {
- var m = this._model.data,
- dpc = data.nodes,
- t = this.settings.types,
- i, j, c = 'default';
- for(i = 0, j = dpc.length; i < j; i++) {
- c = 'default';
- if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) {
- c = m[dpc[i]].original.type;
- }
- if(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) {
- c = m[dpc[i]].data.jstree.type;
- }
- m[dpc[i]].type = c;
- if(m[dpc[i]].icon === true && t[c].icon !== undefined) {
- m[dpc[i]].icon = t[c].icon;
- }
- }
- }, this));
- };
- this.get_json = function (obj, options, flat) {
- var i, j,
- m = this._model.data,
- opt = options ? $.extend(true, {}, options, {no_id:false}) : {},
- tmp = parent.get_json.call(this, obj, opt, flat);
- if(tmp === false) { return false; }
- if($.isArray(tmp)) {
- for(i = 0, j = tmp.length; i < j; i++) {
- tmp[i].type = tmp[i].id && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : "default";
- if(options && options.no_id) {
- delete tmp[i].id;
- if(tmp[i].li_attr && tmp[i].li_attr.id) {
- delete tmp[i].li_attr.id;
- }
- }
- }
- }
- else {
- tmp.type = tmp.id && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : "default";
- if(options && options.no_id) {
- tmp = this._delete_ids(tmp);
- }
- }
- return tmp;
- };
- this._delete_ids = function (tmp) {
- if($.isArray(tmp)) {
- for(var i = 0, j = tmp.length; i < j; i++) {
- tmp[i] = this._delete_ids(tmp[i]);
- }
- return tmp;
- }
- delete tmp.id;
- if(tmp.li_attr && tmp.li_attr.id) {
- delete tmp.li_attr.id;
- }
- if(tmp.children && $.isArray(tmp.children)) {
- tmp.children = this._delete_ids(tmp.children);
- }
- return tmp;
- };
- this.check = function (chk, obj, par, pos) {
- if(parent.check.call(this, chk, obj, par, pos) === false) { return false; }
- obj = obj && obj.id ? obj : this.get_node(obj);
- par = par && par.id ? par : this.get_node(par);
- var m = obj && obj.id ? $.jstree.reference(obj.id) : null, tmp, d, i, j;
- m = m && m._model && m._model.data ? m._model.data : null;
- switch(chk) {
- case "create_node":
- case "move_node":
- case "copy_node":
- if(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) {
- tmp = this.get_rules(par);
- if(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) {
- this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
- return false;
- }
- if(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray(obj.type, tmp.valid_children) === -1) {
- this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
- return false;
- }
- if(m && obj.children_d && obj.parents) {
- d = 0;
- for(i = 0, j = obj.children_d.length; i < j; i++) {
- d = Math.max(d, m[obj.children_d[i]].parents.length);
- }
- d = d - obj.parents.length + 1;
- }
- if(d <= 0 || d === undefined) { d = 1; }
- do {
- if(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) {
- this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
- return false;
- }
- par = this.get_node(par.parent);
- tmp = this.get_rules(par);
- d++;
- } while(par);
- }
- break;
- }
- return true;
- };
- /**
- * used to retrieve the type settings object for a node
- * @name get_rules(obj)
- * @param {mixed} obj the node to find the rules for
- * @return {Object}
- * @plugin types
- */
- this.get_rules = function (obj) {
- obj = this.get_node(obj);
- if(!obj) { return false; }
- var tmp = this.get_type(obj, true);
- if(tmp.max_depth === undefined) { tmp.max_depth = -1; }
- if(tmp.max_children === undefined) { tmp.max_children = -1; }
- if(tmp.valid_children === undefined) { tmp.valid_children = -1; }
- return tmp;
- };
- /**
- * used to retrieve the type string or settings object for a node
- * @name get_type(obj [, rules])
- * @param {mixed} obj the node to find the rules for
- * @param {Boolean} rules if set to `true` instead of a string the settings object will be returned
- * @return {String|Object}
- * @plugin types
- */
- this.get_type = function (obj, rules) {
- obj = this.get_node(obj);
- return (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type);
- };
- /**
- * used to change a node's type
- * @name set_type(obj, type)
- * @param {mixed} obj the node to change
- * @param {String} type the new type
- * @plugin types
- */
- this.set_type = function (obj, type) {
- var t, t1, t2, old_type, old_icon;
- if($.isArray(obj)) {
- obj = obj.slice();
- for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
- this.set_type(obj[t1], type);
- }
- return true;
- }
- t = this.settings.types;
- obj = this.get_node(obj);
- if(!t[type] || !obj) { return false; }
- old_type = obj.type;
- old_icon = this.get_icon(obj);
- obj.type = type;
- if(old_icon === true || (t[old_type] && t[old_type].icon && old_icon === t[old_type].icon)) {
- this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true);
- }
- return true;
- };
- };
- // include the types plugin by default
- // $.jstree.defaults.plugins.push("types");
-
-/**
- * ### Unique plugin
- *
- * Enforces that no nodes with the same name can coexist as siblings.
- */
-
- $.jstree.plugins.unique = function (options, parent) {
- this.check = function (chk, obj, par, pos) {
- if(parent.check.call(this, chk, obj, par, pos) === false) { return false; }
- obj = obj && obj.id ? obj : this.get_node(obj);
- par = par && par.id ? par : this.get_node(par);
- if(!par || !par.children) { return true; }
- var n = chk === "rename_node" ? pos : obj.text,
- c = [],
- m = this._model.data, i, j;
- for(i = 0, j = par.children.length; i < j; i++) {
- c.push(m[par.children[i]].text);
- }
- switch(chk) {
- case "delete_node":
- return true;
- case "rename_node":
- case "copy_node":
- i = ($.inArray(n, c) === -1);
- if(!i) {
- this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
- }
- return i;
- case "move_node":
- i = (obj.parent === par.id || $.inArray(n, c) === -1);
- if(!i) {
- this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
- }
- return i;
- }
- return true;
- };
- };
-
- // include the unique plugin by default
- // $.jstree.defaults.plugins.push("unique");
-
-
-/**
- * ### Wholerow plugin
- *
- * Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers.
- */
-
- var div = document.createElement('DIV');
- div.setAttribute('unselectable','on');
- div.className = 'jstree-wholerow';
- div.innerHTML = '&#160;';
- $.jstree.plugins.wholerow = function (options, parent) {
- this.bind = function () {
- parent.bind.call(this);
-
- this.element
- .on('loading', $.proxy(function () {
- div.style.height = this._data.core.li_height + 'px';
- }, this))
- .on('ready.jstree set_state.jstree', $.proxy(function () {
- this.hide_dots();
- }, this))
- .on("ready.jstree", $.proxy(function () {
- this.get_container_ul().addClass('jstree-wholerow-ul');
- }, this))
- .on("deselect_all.jstree", $.proxy(function (e, data) {
- this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');
- }, this))
- .on("changed.jstree", $.proxy(function (e, data) {
- this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');
- var tmp = false, i, j;
- for(i = 0, j = data.selected.length; i < j; i++) {
- tmp = this.get_node(data.selected[i], true);
- if(tmp && tmp.length) {
- tmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked');
- }
- }
- }, this))
- .on("open_node.jstree", $.proxy(function (e, data) {
- this.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked');
- }, this))
- .on("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) {
- this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered');
- }, this))
- .on("contextmenu.jstree", ".jstree-wholerow", $.proxy(function (e) {
- e.preventDefault();
- $(e.currentTarget).closest("li").children("a:eq(0)").trigger('contextmenu',e);
- }, this))
- .on("click.jstree", ".jstree-wholerow", function (e) {
- e.stopImmediatePropagation();
- var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
- $(e.currentTarget).closest("li").children("a:eq(0)").trigger(tmp).focus();
- })
- .on("click.jstree", ".jstree-leaf > .jstree-ocl", $.proxy(function (e) {
- e.stopImmediatePropagation();
- var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
- $(e.currentTarget).closest("li").children("a:eq(0)").trigger(tmp).focus();
- }, this))
- .on("mouseover.jstree", ".jstree-wholerow, .jstree-icon", $.proxy(function (e) {
- e.stopImmediatePropagation();
- this.hover_node(e.currentTarget);
- return false;
- }, this))
- .on("mouseleave.jstree", ".jstree-node", $.proxy(function (e) {
- this.dehover_node(e.currentTarget);
- }, this));
- };
- this.teardown = function () {
- if(this.settings.wholerow) {
- this.element.find(".jstree-wholerow").remove();
- }
- parent.teardown.call(this);
- };
- this.redraw_node = function(obj, deep, callback) {
- obj = parent.redraw_node.call(this, obj, deep, callback);
- if(obj) {
- var tmp = div.cloneNode(true);
- //tmp.style.height = this._data.core.li_height + 'px';
- if($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; }
- obj.insertBefore(tmp, obj.childNodes[0]);
- }
- return obj;
- };
- };
- // include the wholerow plugin by default
- // $.jstree.defaults.plugins.push("wholerow");
-
-}));
diff --git a/Duplicati/Server/webroot/greeno/scripts/jstree.min.js b/Duplicati/Server/webroot/greeno/scripts/jstree.min.js
deleted file mode 100755
index 485634937..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/jstree.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jsTree - v3.0.0-beta9 - 2014-02-27 - (MIT) */
-(function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?e(require("jquery")):e(jQuery)})(function(e,t){"use strict";if(!e.jstree){var n=0,i=!1,r=!1,s=!1,a=[],o=e("script:last").attr("src"),d=document,l=d.createElement("LI"),c,h;l.setAttribute("role","treeitem"),c=d.createElement("I"),c.className="jstree-icon jstree-ocl",l.appendChild(c),c=d.createElement("A"),c.className="jstree-anchor",c.setAttribute("href","#"),h=d.createElement("I"),h.className="jstree-icon jstree-themeicon",c.appendChild(h),l.appendChild(c),c=h=null,e.jstree={version:"3.0.0-beta9",defaults:{plugins:[]},plugins:{},path:o&&-1!==o.indexOf("/")?o.replace(/\/[^\/]+$/,""):""},e.jstree.create=function(t,i){var r=new e.jstree.core(++n),s=i;return i=e.extend(!0,{},e.jstree.defaults,i),s&&s.plugins&&(i.plugins=s.plugins),e.each(i.plugins,function(e,t){"core"!==e&&(r=r.plugin(t,i[t]))}),r.init(t,i),r},e.jstree.core=function(e){this._id=e,this._cnt=0,this._data={core:{themes:{name:!1,dots:!1,icons:!1},selected:[],last_error:{}}}},e.jstree.reference=function(n){if(n&&!e(n).length){n.id&&(n=n.id);var i=null;return e(".jstree").each(function(){var r=e(this).data("jstree");return r&&r._model.data[n]?(i=r,!1):t}),i}return e(n).closest(".jstree").data("jstree")},e.fn.jstree=function(n){var i="string"==typeof n,r=Array.prototype.slice.call(arguments,1),s=null;return this.each(function(){var a=e.jstree.reference(this),o=i&&a?a[n]:null;return s=i&&o?o.apply(a,r):null,a||i||n!==t&&!e.isPlainObject(n)||e(this).data("jstree",new e.jstree.create(this,n)),a&&!i&&(s=a),null!==s&&s!==t?!1:t}),null!==s&&s!==t?s:this},e.expr[":"].jstree=e.expr.createPseudo(function(n){return function(n){return e(n).hasClass("jstree")&&e(n).data("jstree")!==t}}),e.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:e.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,stripes:!1,variant:!1,responsive:!0},expand_selected_onload:!0},e.jstree.core.prototype={plugin:function(t,n){var i=e.jstree.plugins[t];return i?(this._data[t]={},i.prototype=this,new i(n,this)):this},init:function(t,n){this._model={data:{"#":{id:"#",parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}}},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this.element=e(t).addClass("jstree jstree-"+this._id),this.settings=n,this.element.bind("destroyed",e.proxy(this.teardown,this)),this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html("<ul class='jstree-container-ul'><li class='jstree-initial-node jstree-loading jstree-leaf jstree-last'><i class='jstree-icon jstree-ocl'></i><a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>"+this.get_string("Loading ...")+"</a></li></ul>"),this._data.core.li_height=this.get_container_ul().children("li:eq(0)").height()||18,this.trigger("loading"),this.load_node("#")},destroy:function(){this.element.unbind("destroyed",this.teardown),this.teardown()},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){this.element.on("dblclick.jstree",function(){if(document.selection&&document.selection.empty)document.selection.empty();else if(window.getSelection){var e=window.getSelection();try{e.removeAllRanges(),e.collapse()}catch(t){}}}).on("click.jstree",".jstree-ocl",e.proxy(function(e){this.toggle_node(e.target)},this)).on("click.jstree",".jstree-anchor",e.proxy(function(t){t.preventDefault(),e(t.currentTarget).focus(),this.activate_node(t.currentTarget,t)},this)).on("keydown.jstree",".jstree-anchor",e.proxy(function(t){var n=null;switch(t.which){case 13:case 32:t.type="click",e(t.currentTarget).trigger(t);break;case 37:t.preventDefault(),this.is_open(t.currentTarget)?this.close_node(t.currentTarget):(n=this.get_prev_dom(t.currentTarget),n&&n.length&&n.children(".jstree-anchor").focus());break;case 38:t.preventDefault(),n=this.get_prev_dom(t.currentTarget),n&&n.length&&n.children(".jstree-anchor").focus();break;case 39:t.preventDefault(),this.is_closed(t.currentTarget)?this.open_node(t.currentTarget,function(e){this.get_node(e,!0).children(".jstree-anchor").focus()}):(n=this.get_next_dom(t.currentTarget),n&&n.length&&n.children(".jstree-anchor").focus());break;case 40:t.preventDefault(),n=this.get_next_dom(t.currentTarget),n&&n.length&&n.children(".jstree-anchor").focus();break;case 46:t.preventDefault(),n=this.get_node(t.currentTarget),n&&n.id&&"#"!==n.id&&(n=this.is_selected(n)?this.get_selected():n);break;case 113:t.preventDefault(),n=this.get_node(t.currentTarget);break;default:}},this)).on("load_node.jstree",e.proxy(function(t,n){if(n.status&&("#"!==n.node.id||this._data.core.loaded||(this._data.core.loaded=!0,this.trigger("loaded")),!this._data.core.ready&&!this.get_container_ul().find(".jstree-loading:eq(0)").length)){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){var i=[],r,s;for(r=0,s=this._data.core.selected.length;s>r;r++)i=i.concat(this._model.data[this._data.core.selected[r]].parents);for(i=e.vakata.array_unique(i),r=0,s=i.length;s>r;r++)this.open_node(i[r],!1,0)}this.trigger("changed",{action:"ready",selected:this._data.core.selected})}setTimeout(e.proxy(function(){this.trigger("ready")},this),0)}},this)).on("init.jstree",e.proxy(function(){var e=this.settings.core.themes;this._data.core.themes.dots=e.dots,this._data.core.themes.stripes=e.stripes,this._data.core.themes.icons=e.icons,this.set_theme(e.name||"default",e.url),this.set_theme_variant(e.variant)},this)).on("loading.jstree",e.proxy(function(){this[this._data.core.themes.dots?"show_dots":"hide_dots"](),this[this._data.core.themes.icons?"show_icons":"hide_icons"](),this[this._data.core.themes.stripes?"show_stripes":"hide_stripes"]()},this)).on("focus.jstree",".jstree-anchor",e.proxy(function(t){this.element.find(".jstree-hovered").not(t.currentTarget).mouseleave(),e(t.currentTarget).mouseenter()},this)).on("mouseenter.jstree",".jstree-anchor",e.proxy(function(e){this.hover_node(e.currentTarget)},this)).on("mouseleave.jstree",".jstree-anchor",e.proxy(function(e){this.dehover_node(e.currentTarget)},this))},unbind:function(){this.element.off(".jstree"),e(document).off(".jstree-"+this._id)},trigger:function(e,t){t||(t={}),t.instance=this,this.element.triggerHandler(e.replace(".jstree","")+".jstree",t)},get_container:function(){return this.element},get_container_ul:function(){return this.element.children("ul:eq(0)")},get_string:function(t){var n=this.settings.core.strings;return e.isFunction(n)?n.call(this,t):n&&n[t]?n[t]:t},_firstChild:function(e){e=e?e.firstChild:null;while(null!==e&&1!==e.nodeType)e=e.nextSibling;return e},_nextSibling:function(e){e=e?e.nextSibling:null;while(null!==e&&1!==e.nodeType)e=e.nextSibling;return e},_previousSibling:function(e){e=e?e.previousSibling:null;while(null!==e&&1!==e.nodeType)e=e.previousSibling;return e},get_node:function(t,n){t&&t.id&&(t=t.id);var i;try{if(this._model.data[t])t=this._model.data[t];else if(((i=e(t,this.element)).length||(i=e("#"+t,this.element)).length)&&this._model.data[i.closest("li").attr("id")])t=this._model.data[i.closest("li").attr("id")];else{if(!(i=e(t,this.element)).length||!i.hasClass("jstree"))return!1;t=this._model.data["#"]}return n&&(t="#"===t.id?this.element:e(document.getElementById(t.id))),t}catch(r){return!1}},get_path:function(e,t,n){if(e=e.parents?e:this.get_node(e),!e||"#"===e.id||!e.parents)return!1;var i,r,s=[];for(s.push(n?e.id:e.text),i=0,r=e.parents.length;r>i;i++)s.push(n?e.parents[i]:this.get_text(e.parents[i]));return s=s.reverse().slice(1),t?s.join(t):s},get_next_dom:function(t,n){var i;return t=this.get_node(t,!0),t[0]===this.element[0]?(i=this._firstChild(this.get_container_ul()[0]),i?e(i):!1):t&&t.length?n?(i=this._nextSibling(t[0]),i?e(i):!1):t.hasClass("jstree-open")?(i=this._firstChild(t.children("ul")[0]),i?e(i):!1):null!==(i=this._nextSibling(t[0]))?e(i):t.parentsUntil(".jstree","li").next("li").eq(0):!1},get_prev_dom:function(t,n){var i;if(t=this.get_node(t,!0),t[0]===this.element[0])return i=this.get_container_ul()[0].lastChild,i?e(i):!1;if(!t||!t.length)return!1;if(n)return i=this._previousSibling(t[0]),i?e(i):!1;if(null!==(i=this._previousSibling(t[0]))){t=e(i);while(t.hasClass("jstree-open"))t=t.children("ul:eq(0)").children("li:last");return t}return i=t[0].parentNode.parentNode,i&&"LI"===i.tagName?e(i):!1},get_parent:function(e){return e=this.get_node(e),e&&"#"!==e.id?e.parent:!1},get_children_dom:function(e){return e=this.get_node(e,!0),e[0]===this.element[0]?this.get_container_ul().children("li"):e&&e.length?e.children("ul").children("li"):!1},is_parent:function(e){return e=this.get_node(e),e&&(e.state.loaded===!1||e.children.length>0)},is_loaded:function(e){return e=this.get_node(e),e&&e.state.loaded},is_loading:function(e){return e=this.get_node(e,!0),e&&e.hasClass("jstree-loading")},is_open:function(e){return e=this.get_node(e),e&&e.state.opened},is_closed:function(e){return e=this.get_node(e),e&&this.is_parent(e)&&!e.state.opened},is_leaf:function(e){return!this.is_parent(e)},load_node:function(t,n){var i,r;if(e.isArray(t)){for(t=t.slice(),i=0,r=t.length;r>i;i++)this.load_node(t[i],n);return!0}return(t=this.get_node(t))?(this.get_node(t,!0).addClass("jstree-loading"),this._load_node(t,e.proxy(function(e){t.state.loaded=e,this.get_node(t,!0).removeClass("jstree-loading"),this.trigger("load_node",{node:t,status:e}),n&&n.call(this,t,e)},this)),!0):(n.call(this,t,!1),!1)},_load_node:function(n,i){var r=this.settings.core.data,s;return r?e.isFunction(r)?r.call(this,n,e.proxy(function(t){return t===!1?i.call(this,!1):i.call(this,this["string"==typeof t?"_append_html_data":"_append_json_data"](n,"string"==typeof t?e(t):t))},this)):"object"==typeof r?r.url?(r=e.extend(!0,{},r),e.isFunction(r.url)&&(r.url=r.url.call(this,n)),e.isFunction(r.data)&&(r.data=r.data.call(this,n)),e.ajax(r).done(e.proxy(function(r,s,a){var o=a.getResponseHeader("Content-Type");return-1!==o.indexOf("json")?i.call(this,this._append_json_data(n,r)):-1!==o.indexOf("html")?i.call(this,this._append_html_data(n,e(r))):t},this)).fail(e.proxy(function(){i.call(this,!1),this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify(r)},this.settings.core.error.call(this,this._data.core.last_error)},this))):(s=e.isArray(r)||e.isPlainObject(r)?JSON.parse(JSON.stringify(r)):r,i.call(this,this._append_json_data(n,s))):"string"==typeof r?i.call(this,this._append_html_data(n,r)):i.call(this,!1):i.call(this,"#"===n.id?this._append_html_data(n,this._data.core.original_container_html.clone(!0)):!1)},_node_changed:function(e){e=this.get_node(e),e&&this._model.changed.push(e.id)},_append_html_data:function(t,n){t=this.get_node(t),t.children=[],t.children_d=[];var i=n.is("ul")?n.children():n,r=t.id,s=[],a=[],o=this._model.data,d=o[r],l=this._data.core.selected.length,c,h,_;for(i.each(e.proxy(function(t,n){c=this._parse_model_from_html(e(n),r,d.parents.concat()),c&&(s.push(c),a.push(c),o[c].children_d.length&&(a=a.concat(o[c].children_d)))},this)),d.children=s,d.children_d=a,h=0,_=d.parents.length;_>h;h++)o[d.parents[h]].children_d=o[d.parents[h]].children_d.concat(a);return this.trigger("model",{nodes:a,parent:r}),"#"!==r?(this._node_changed(r),this.redraw()):(this.get_container_ul().children(".jstree-initial-node").remove(),this.redraw(!0)),this._data.core.selected.length!==l&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),!0},_append_json_data:function(n,i){n=this.get_node(n),n.children=[],n.children_d=[];var r=i,s=n.id,a=[],o=[],d=this._model.data,l=d[s],c=this._data.core.selected.length,h,_,u;if(r.d&&(r=r.d,"string"==typeof r&&(r=JSON.parse(r))),e.isArray(r)||(r=[r]),r.length&&r[0].id!==t&&r[0].parent!==t){for(_=0,u=r.length;u>_;_++)r[_].children||(r[_].children=[]),d[r[_].id]=r[_];for(_=0,u=r.length;u>_;_++)d[r[_].parent].children.push(r[_].id),l.children_d.push(r[_].id);for(_=0,u=l.children.length;u>_;_++)h=this._parse_model_from_flat_json(d[l.children[_]],s,l.parents.concat()),o.push(h),d[h].children_d.length&&(o=o.concat(d[h].children_d))}else{for(_=0,u=r.length;u>_;_++)h=this._parse_model_from_json(r[_],s,l.parents.concat()),h&&(a.push(h),o.push(h),d[h].children_d.length&&(o=o.concat(d[h].children_d)));for(l.children=a,l.children_d=o,_=0,u=l.parents.length;u>_;_++)d[l.parents[_]].children_d=d[l.parents[_]].children_d.concat(o)}return this.trigger("model",{nodes:o,parent:s}),"#"!==s?(this._node_changed(s),this.redraw()):this.redraw(!0),this._data.core.selected.length!==c&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),!0},_parse_model_from_html:function(n,i,r){r=r?[].concat(r):[],i&&r.unshift(i);var s,a,o=this._model.data,d={id:!1,text:!1,icon:!0,parent:i,parents:r,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1},l,c,h;for(l in this._model.default_state)this._model.default_state.hasOwnProperty(l)&&(d.state[l]=this._model.default_state[l]);if(c=e.vakata.attributes(n,!0),e.each(c,function(n,i){return i=e.trim(i),i.length?(d.li_attr[n]=i,"id"===n&&(d.id=i),t):!0}),c=n.children("a").eq(0),c.length&&(c=e.vakata.attributes(c,!0),e.each(c,function(t,n){n=e.trim(n),n.length&&(d.a_attr[t]=n)})),c=n.children("a:eq(0)").length?n.children("a:eq(0)").clone():n.clone(),c.children("ins, i, ul").remove(),c=c.html(),c=e("<div />").html(c),d.text=c.html(),c=n.data(),d.data=c?e.extend(!0,{},c):null,d.state.opened=n.hasClass("jstree-open"),d.state.selected=n.children("a").hasClass("jstree-clicked"),d.state.disabled=n.children("a").hasClass("jstree-disabled"),d.data&&d.data.jstree)for(l in d.data.jstree)d.data.jstree.hasOwnProperty(l)&&(d.state[l]=d.data.jstree[l]);c=n.children("a").children(".jstree-themeicon"),c.length&&(d.icon=c.hasClass("jstree-themeicon-hidden")?!1:c.attr("rel")),d.state.icon&&(d.icon=d.state.icon),c=n.children("ul").children("li");do h="j"+this._id+"_"+ ++this._cnt;while(o[h]);return d.id=d.li_attr.id||h,c.length?(c.each(e.proxy(function(t,n){s=this._parse_model_from_html(e(n),d.id,r),a=this._model.data[s],d.children.push(s),a.children_d.length&&(d.children_d=d.children_d.concat(a.children_d))},this)),d.children_d=d.children_d.concat(d.children)):n.hasClass("jstree-closed")&&(d.state.loaded=!1),d.li_attr["class"]&&(d.li_attr["class"]=d.li_attr["class"].replace("jstree-closed","").replace("jstree-open","")),d.a_attr["class"]&&(d.a_attr["class"]=d.a_attr["class"].replace("jstree-clicked","").replace("jstree-disabled","")),o[d.id]=d,d.state.selected&&this._data.core.selected.push(d.id),d.id},_parse_model_from_flat_json:function(e,n,i){i=i?i.concat():[],n&&i.unshift(n);var r=e.id,s=this._model.data,a=this._model.default_state,o,d,l,c,h={id:r,text:e.text||"",icon:e.icon!==t?e.icon:!0,parent:n,parents:i,children:e.children||[],children_d:e.children_d||[],data:e.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(o in a)a.hasOwnProperty(o)&&(h.state[o]=a[o]);if(e&&e.data&&e.data.jstree&&e.data.jstree.icon&&(h.icon=e.data.jstree.icon),e&&e.data&&(h.data=e.data,e.data.jstree))for(o in e.data.jstree)e.data.jstree.hasOwnProperty(o)&&(h.state[o]=e.data.jstree[o]);if(e&&"object"==typeof e.state)for(o in e.state)e.state.hasOwnProperty(o)&&(h.state[o]=e.state[o]);if(e&&"object"==typeof e.li_attr)for(o in e.li_attr)e.li_attr.hasOwnProperty(o)&&(h.li_attr[o]=e.li_attr[o]);if(h.li_attr.id||(h.li_attr.id=r),e&&"object"==typeof e.a_attr)for(o in e.a_attr)e.a_attr.hasOwnProperty(o)&&(h.a_attr[o]=e.a_attr[o]);for(e&&e.children&&e.children===!0&&(h.state.loaded=!1,h.children=[],h.children_d=[]),s[h.id]=h,o=0,d=h.children.length;d>o;o++)l=this._parse_model_from_flat_json(s[h.children[o]],h.id,i),c=s[l],h.children_d.push(l),c.children_d.length&&(h.children_d=h.children_d.concat(c.children_d));return delete e.data,delete e.children,s[h.id].original=e,h.state.selected&&this._data.core.selected.push(h.id),h.id},_parse_model_from_json:function(e,n,i){i=i?i.concat():[],n&&i.unshift(n);var r=!1,s,a,o,d,l=this._model.data,c=this._model.default_state,h;do r="j"+this._id+"_"+ ++this._cnt;while(l[r]);h={id:!1,text:"string"==typeof e?e:"",icon:"object"==typeof e&&e.icon!==t?e.icon:!0,parent:n,parents:i,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(s in c)c.hasOwnProperty(s)&&(h.state[s]=c[s]);if(e&&e.id&&(h.id=e.id),e&&e.text&&(h.text=e.text),e&&e.data&&e.data.jstree&&e.data.jstree.icon&&(h.icon=e.data.jstree.icon),e&&e.data&&(h.data=e.data,e.data.jstree))for(s in e.data.jstree)e.data.jstree.hasOwnProperty(s)&&(h.state[s]=e.data.jstree[s]);if(e&&"object"==typeof e.state)for(s in e.state)e.state.hasOwnProperty(s)&&(h.state[s]=e.state[s]);if(e&&"object"==typeof e.li_attr)for(s in e.li_attr)e.li_attr.hasOwnProperty(s)&&(h.li_attr[s]=e.li_attr[s]);if(h.li_attr.id&&!h.id&&(h.id=h.li_attr.id),h.id||(h.id=r),h.li_attr.id||(h.li_attr.id=h.id),e&&"object"==typeof e.a_attr)for(s in e.a_attr)e.a_attr.hasOwnProperty(s)&&(h.a_attr[s]=e.a_attr[s]);if(e&&e.children&&e.children.length){for(s=0,a=e.children.length;a>s;s++)o=this._parse_model_from_json(e.children[s],h.id,i),d=l[o],h.children.push(o),d.children_d.length&&(h.children_d=h.children_d.concat(d.children_d));h.children_d=h.children_d.concat(h.children)}return e&&e.children&&e.children===!0&&(h.state.loaded=!1,h.children=[],h.children_d=[]),delete e.data,delete e.children,h.original=e,l[h.id]=h,h.state.selected&&this._data.core.selected.push(h.id),h.id},_redraw:function(){var e=this._model.force_full_redraw?this._model.data["#"].children.concat([]):this._model.changed.concat([]),t=document.createElement("UL"),n,i,r;for(i=0,r=e.length;r>i;i++)n=this.redraw_node(e[i],!0,this._model.force_full_redraw),n&&this._model.force_full_redraw&&t.appendChild(n);this._model.force_full_redraw&&(t.className=this.get_container_ul()[0].className,this.element.empty().append(t)),this._model.force_full_redraw=!1,this._model.changed=[],this.trigger("redraw",{nodes:e})},redraw:function(e){e&&(this._model.force_full_redraw=!0),this._redraw()},redraw_node:function(t,n,i){var r=this.get_node(t),s=!1,a=!1,o=!1,d=!1,c=!1,h=!1,_="",u=document,g=this._model.data,f=!1,p=!1;if(!r)return!1;if("#"===r.id)return this.redraw(!0);if(n=n||0===r.children.length,t=u.getElementById(r.id))t=e(t),i||(s=t.parent().parent()[0],s===this.element[0]&&(s=null),a=t.index()),n||!r.children.length||t.children("ul").length||(n=!0),n||(o=t.children("UL")[0]),p=t.attr("aria-selected"),f=t.children(".jstree-anchor")[0]===document.activeElement,t.remove();else if(n=!0,!i){if(s="#"!==r.parent?e("#"+r.parent,this.element)[0]:null,!(null===s||s&&g[r.parent].state.opened))return!1;a=e.inArray(r.id,null===s?g["#"].children:g[r.parent].children)}t=l.cloneNode(!0),_="jstree-node ";for(d in r.li_attr)if(r.li_attr.hasOwnProperty(d)){if("id"===d)continue;"class"!==d?t.setAttribute(d,r.li_attr[d]):_+=r.li_attr[d]}p&&"false"!==p&&t.setAttribute("aria-selected",!0),!r.children.length&&r.state.loaded?_+=" jstree-leaf":(_+=r.state.opened?" jstree-open":" jstree-closed",t.setAttribute("aria-expanded",r.state.opened)),null!==r.parent&&g[r.parent].children[g[r.parent].children.length-1]===r.id&&(_+=" jstree-last"),t.id=r.id,t.className=_,_=(r.state.selected?" jstree-clicked":"")+(r.state.disabled?" jstree-disabled":"");for(c in r.a_attr)if(r.a_attr.hasOwnProperty(c)){if("href"===c&&"#"===r.a_attr[c])continue;"class"!==c?t.childNodes[1].setAttribute(c,r.a_attr[c]):_+=" "+r.a_attr[c]}if(_.length&&(t.childNodes[1].className="jstree-anchor "+_),(r.icon&&r.icon!==!0||r.icon===!1)&&(r.icon===!1?t.childNodes[1].childNodes[0].className+=" jstree-themeicon-hidden":-1===r.icon.indexOf("/")&&-1===r.icon.indexOf(".")?t.childNodes[1].childNodes[0].className+=" "+r.icon+" jstree-themeicon-custom":(t.childNodes[1].childNodes[0].style.backgroundImage="url("+r.icon+")",t.childNodes[1].childNodes[0].style.backgroundPosition="center center",t.childNodes[1].childNodes[0].style.backgroundSize="auto",t.childNodes[1].childNodes[0].className+=" jstree-themeicon-custom")),t.childNodes[1].innerHTML+=r.text,n&&r.children.length&&r.state.opened){for(h=u.createElement("UL"),h.setAttribute("role","group"),h.className="jstree-children",d=0,c=r.children.length;c>d;d++)h.appendChild(this.redraw_node(r.children[d],n,!0));t.appendChild(h)}return o&&t.appendChild(o),i||(s||(s=this.element[0]),s.getElementsByTagName("UL").length?s=s.getElementsByTagName("UL")[0]:(d=u.createElement("UL"),d.setAttribute("role","group"),d.className="jstree-children",s.appendChild(d),s=d),s.childNodes.length>a?s.insertBefore(t,s.childNodes[a]):s.appendChild(t),f&&t.childNodes[1].focus()),t},open_node:function(n,i,r){var s,a,o,d;if(e.isArray(n)){for(n=n.slice(),s=0,a=n.length;a>s;s++)this.open_node(n[s],i,r);return!0}if(n=this.get_node(n),!n||"#"===n.id)return!1;if(r=r===t?this.settings.core.animation:r,!this.is_closed(n))return i&&i.call(this,n,!1),!1;if(this.is_loaded(n))o=this.get_node(n,!0),d=this,o.length&&(n.children.length&&!this._firstChild(o.children("ul")[0])&&(n.state.opened=!0,this.redraw_node(n,!0),o=this.get_node(n,!0)),r?o.children("ul").css("display","none").end().removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded",!0).children("ul").stop(!0,!0).slideDown(r,function(){this.style.display="",d.trigger("after_open",{node:n})}):(o[0].className=o[0].className.replace("jstree-closed","jstree-open"),o[0].setAttribute("aria-expanded",!0))),n.state.opened=!0,i&&i.call(this,n,!0),this.trigger("open_node",{node:n}),r&&o.length||this.trigger("after_open",{node:n});else{if(this.is_loading(n))return setTimeout(e.proxy(function(){this.open_node(n,i,r)},this),500);this.load_node(n,function(e,t){return t?this.open_node(e,i,r):i?i.call(this,e,!1):!1})}},_open_to:function(t){if(t=this.get_node(t),!t||"#"===t.id)return!1;var n,i,r=t.parents;for(n=0,i=r.length;i>n;n+=1)"#"!==n&&this.open_node(r[n],!1,0);return e(document.getElementById(t.id))},close_node:function(n,i){var r,s,a,o;if(e.isArray(n)){for(n=n.slice(),r=0,s=n.length;s>r;r++)this.close_node(n[r],i);return!0}return n=this.get_node(n),n&&"#"!==n.id?(i=i===t?this.settings.core.animation:i,a=this,o=this.get_node(n,!0),o.length&&(i?o.children("ul").attr("style","display:block !important").end().removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded",!1).children("ul").stop(!0,!0).slideUp(i,function(){this.style.display="",o.children("ul").remove(),a.trigger("after_close",{node:n})}):(o[0].className=o[0].className.replace("jstree-open","jstree-closed"),o.attr("aria-expanded",!1).children("ul").remove())),n.state.opened=!1,this.trigger("close_node",{node:n}),i&&o.length||this.trigger("after_close",{node:n}),t):!1},toggle_node:function(n){var i,r;if(e.isArray(n)){for(n=n.slice(),i=0,r=n.length;r>i;i++)this.toggle_node(n[i]);return!0}return this.is_closed(n)?this.open_node(n):this.is_open(n)?this.close_node(n):t},open_all:function(e,t,n){if(e||(e="#"),e=this.get_node(e),!e)return!1;var i="#"===e.id?this.get_container_ul():this.get_node(e,!0),r,s,a;if(!i.length){for(r=0,s=e.children_d.length;s>r;r++)this.is_closed(this._model.data[e.children_d[r]])&&(this._model.data[e.children_d[r]].state.opened=!0);return this.trigger("open_all",{node:e})}n=n||i,a=this,i=this.is_closed(e)?i.find("li.jstree-closed").addBack():i.find("li.jstree-closed"),i.each(function(){a.open_node(this,function(e,i){i&&this.is_parent(e)&&this.open_all(e,t,n)},t||0)}),0===n.find("li.jstree-closed").length&&this.trigger("open_all",{node:this.get_node(n)})},close_all:function(e,t){if(e||(e="#"),e=this.get_node(e),!e)return!1;var n="#"===e.id?this.get_container_ul():this.get_node(e,!0),i=this,r,s;if(!n.length){for(r=0,s=e.children_d.length;s>r;r++)this._model.data[e.children_d[r]].state.opened=!1;return this.trigger("close_all",{node:e})}n=this.is_open(e)?n.find("li.jstree-open").addBack():n.find("li.jstree-open"),n.vakata_reverse().each(function(){i.close_node(this,t||0)}),this.trigger("close_all",{node:e})},is_disabled:function(e){return e=this.get_node(e),e&&e.state&&e.state.disabled},enable_node:function(n){var i,r;if(e.isArray(n)){for(n=n.slice(),i=0,r=n.length;r>i;i++)this.enable_node(n[i]);return!0}return n=this.get_node(n),n&&"#"!==n.id?(n.state.disabled=!1,this.get_node(n,!0).children(".jstree-anchor").removeClass("jstree-disabled"),this.trigger("enable_node",{node:n}),t):!1},disable_node:function(n){var i,r;if(e.isArray(n)){for(n=n.slice(),i=0,r=n.length;r>i;i++)this.disable_node(n[i]);return!0}return n=this.get_node(n),n&&"#"!==n.id?(n.state.disabled=!0,this.get_node(n,!0).children(".jstree-anchor").addClass("jstree-disabled"),this.trigger("disable_node",{node:n}),t):!1},activate_node:function(e,t){if(this.is_disabled(e))return!1;if(this.settings.core.multiple&&(t.metaKey||t.ctrlKey||t.shiftKey)&&(!t.shiftKey||this._data.core.last_clicked&&this.get_parent(e)&&this.get_parent(e)===this._data.core.last_clicked.parent))if(t.shiftKey){var n=this.get_node(e).id,i=this._data.core.last_clicked.id,r=this.get_node(this._data.core.last_clicked.parent).children,s=!1,a,o;for(a=0,o=r.length;o>a;a+=1)r[a]===n&&(s=!s),r[a]===i&&(s=!s),s||r[a]===n||r[a]===i?this.select_node(r[a],!1,!1,t):this.deselect_node(r[a],!1,!1,t)}else this.is_selected(e)?this.deselect_node(e,!1,!1,t):this.select_node(e,!1,!1,t);else!this.settings.core.multiple&&(t.metaKey||t.ctrlKey||t.shiftKey)&&this.is_selected(e)?this.deselect_node(e,!1,!1,t):(this.deselect_all(!0),this.select_node(e,!1,!1,t),this._data.core.last_clicked=this.get_node(e));this.trigger("activate_node",{node:this.get_node(e)})},hover_node:function(e){if(e=this.get_node(e,!0),!e||!e.length||e.children(".jstree-hovered").length)return!1;var t=this.element.find(".jstree-hovered"),n=this.element;t&&t.length&&this.dehover_node(t),e.children(".jstree-anchor").addClass("jstree-hovered"),this.trigger("hover_node",{node:this.get_node(e)}),setTimeout(function(){n.attr("aria-activedescendant",e[0].id),e.attr("aria-selected",!0)},0)},dehover_node:function(e){return e=this.get_node(e,!0),e&&e.length&&e.children(".jstree-hovered").length?(e.attr("aria-selected",!1).children(".jstree-anchor").removeClass("jstree-hovered"),this.trigger("dehover_node",{node:this.get_node(e)}),t):!1},select_node:function(n,i,r,s){var a,o,d,l;if(e.isArray(n)){for(n=n.slice(),o=0,d=n.length;d>o;o++)this.select_node(n[o],i,r,s);return!0}return n=this.get_node(n),n&&"#"!==n.id?(a=this.get_node(n,!0),n.state.selected||(n.state.selected=!0,this._data.core.selected.push(n.id),r||(a=this._open_to(n)),a&&a.length&&a.children(".jstree-anchor").addClass("jstree-clicked"),this.trigger("select_node",{node:n,selected:this._data.core.selected,event:s}),i||this.trigger("changed",{action:"select_node",node:n,selected:this._data.core.selected,event:s})),t):!1},deselect_node:function(n,i,r){var s,a,o;if(e.isArray(n)){for(n=n.slice(),s=0,a=n.length;a>s;s++)this.deselect_node(n[s],i,r);return!0}return n=this.get_node(n),n&&"#"!==n.id?(o=this.get_node(n,!0),n.state.selected&&(n.state.selected=!1,this._data.core.selected=e.vakata.array_remove_item(this._data.core.selected,n.id),o.length&&o.children(".jstree-anchor").removeClass("jstree-clicked"),this.trigger("deselect_node",{node:n,selected:this._data.core.selected,event:r}),i||this.trigger("changed",{action:"deselect_node",node:n,selected:this._data.core.selected,event:r})),t):!1},select_all:function(e){var t=this._data.core.selected.concat([]),n,i;for(this._data.core.selected=this._model.data["#"].children_d.concat(),n=0,i=this._data.core.selected.length;i>n;n++)this._model.data[this._data.core.selected[n]]&&(this._model.data[this._data.core.selected[n]].state.selected=!0);this.redraw(!0),this.trigger("select_all",{selected:this._data.core.selected}),e||this.trigger("changed",{action:"select_all",selected:this._data.core.selected,old_selection:t})},deselect_all:function(e){var t=this._data.core.selected.concat([]),n,i;for(n=0,i=this._data.core.selected.length;i>n;n++)this._model.data[this._data.core.selected[n]]&&(this._model.data[this._data.core.selected[n]].state.selected=!1);this._data.core.selected=[],this.element.find(".jstree-clicked").removeClass("jstree-clicked"),this.trigger("deselect_all",{selected:this._data.core.selected,node:t}),e||this.trigger("changed",{action:"deselect_all",selected:this._data.core.selected,old_selection:t})},is_selected:function(e){return e=this.get_node(e),e&&"#"!==e.id?e.state.selected:!1},get_selected:function(t){return t?e.map(this._data.core.selected,e.proxy(function(e){return this.get_node(e)},this)):this._data.core.selected},get_state:function(){var e={core:{open:[],scroll:{left:this.element.scrollLeft(),top:this.element.scrollTop()},selected:[]}},t;for(t in this._model.data)this._model.data.hasOwnProperty(t)&&"#"!==t&&(this._model.data[t].state.opened&&e.core.open.push(t),this._model.data[t].state.selected&&e.core.selected.push(t));return e},set_state:function(n,i){if(n){if(n.core){var r,s,a,o;if(n.core.open)return e.isArray(n.core.open)?(r=!0,s=!1,a=this,e.each(n.core.open.concat([]),function(t,o){s=a.get_node(o),s&&(a.is_loaded(o)?(a.is_closed(o)&&a.open_node(o,!1,0),n&&n.core&&n.core.open&&e.vakata.array_remove_item(n.core.open,o)):(a.is_loading(o)||a.open_node(o,e.proxy(function(){this.set_state(n,i)},a),0),r=!1))}),r&&(delete n.core.open,this.set_state(n,i)),!1):(delete n.core.open,this.set_state(n,i),!1);if(n.core.scroll)return n.core.scroll&&n.core.scroll.left!==t&&this.element.scrollLeft(n.core.scroll.left),n.core.scroll&&n.core.scroll.top!==t&&this.element.scrollTop(n.core.scroll.top),delete n.core.scroll,this.set_state(n,i),!1;if(n.core.selected)return o=this,this.deselect_all(),e.each(n.core.selected,function(e,t){o.select_node(t)}),delete n.core.selected,this.set_state(n,i),!1;if(e.isEmptyObject(n.core))return delete n.core,this.set_state(n,i),!1}return e.isEmptyObject(n)?(n=null,i&&i.call(this),this.trigger("set_state"),!1):!0}return!1},refresh:function(t){this._data.core.state=this.get_state(),this._cnt=0,this._model.data={"#":{id:"#",parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}}};var n=this.get_container_ul()[0].className;t||this.element.html("<ul class='jstree-container-ul'><li class='jstree-initial-node jstree-loading jstree-leaf jstree-last'><i class='jstree-icon jstree-ocl'></i><a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>"+this.get_string("Loading ...")+"</a></li></ul>"),this.load_node("#",function(t,i){i&&(this.get_container_ul()[0].className=n,this.set_state(e.extend(!0,{},this._data.core.state),function(){this.trigger("refresh")})),this._data.core.state=null})},set_id:function(t,n){if(t=this.get_node(t),!t||"#"===t.id)return!1;var i,r,s=this._model.data;for(s[t.parent].children[e.inArray(t.id,s[t.parent].children)]=n,i=0,r=t.parents.length;r>i;i++)s[t.parents[i]].children_d[e.inArray(t.id,s[t.parents[i]].children_d)]=n;for(i=0,r=t.children.length;r>i;i++)s[t.children[i]].parent=n;for(i=0,r=t.children_d.length;r>i;i++)s[t.children_d[i]].parents[e.inArray(t.id,s[t.children_d[i]].parents)]=n;return i=e.inArray(t.id,this._data.core.selected),-1!==i&&(this._data.core.selected[i]=n),i=this.get_node(t.id,!0),i&&i.attr("id",n),delete s[t.id],t.id=n,s[n]=t,!0},get_text:function(e){return e=this.get_node(e),e&&"#"!==e.id?e.text:!1},set_text:function(t,n){var i,r,s,a;
-if(e.isArray(t)){for(t=t.slice(),i=0,r=t.length;r>i;i++)this.set_text(t[i],n);return!0}return t=this.get_node(t),t&&"#"!==t.id?(t.text=n,s=this.get_node(t,!0),s.length&&(s=s.children(".jstree-anchor:eq(0)"),a=s.children("I").clone(),s.html(n).prepend(a),this.trigger("set_text",{obj:t,text:n})),!0):!1},get_json:function(e,t,n){if(e=this.get_node(e||"#"),!e)return!1;t&&t.flat&&!n&&(n=[]);var i={id:e.id,text:e.text,icon:this.get_icon(e),li_attr:e.li_attr,a_attr:e.a_attr,state:{},data:t&&t.no_data?!1:e.data},r,s;if(t&&t.flat?i.parent=e.parent:i.children=[],!t||!t.no_state)for(r in e.state)e.state.hasOwnProperty(r)&&(i.state[r]=e.state[r]);if(t&&t.no_id&&(delete i.id,i.li_attr&&i.li_attr.id&&delete i.li_attr.id),t&&t.flat&&"#"!==e.id&&n.push(i),!t||!t.no_children)for(r=0,s=e.children.length;s>r;r++)t&&t.flat?this.get_json(e.children[r],t,n):i.children.push(this.get_json(e.children[r],t));return t&&t.flat?n:"#"===e.id?i.children:i},create_node:function(n,i,r,s,a){if(n=this.get_node(n),!n)return!1;if(r=r===t?"last":r,!(""+r).match(/^(before|after)$/)&&!a&&!this.is_loaded(n))return this.load_node(n,function(){this.create_node(n,i,r,s,!0)});i||(i={text:this.get_string("New node")}),i.text===t&&(i.text=this.get_string("New node"));var o,d,l,c;switch("#"===n.id&&("before"===r&&(r="first"),"after"===r&&(r="last")),r){case"before":o=this.get_node(n.parent),r=e.inArray(n.id,o.children),n=o;break;case"after":o=this.get_node(n.parent),r=e.inArray(n.id,o.children)+1,n=o;break;case"inside":case"first":r=0;break;case"last":r=n.children.length;break;default:r||(r=0)}if(r>n.children.length&&(r=n.children.length),i.id||(i.id=!0),!this.check("create_node",i,n,r))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(i.id===!0&&delete i.id,i=this._parse_model_from_json(i,n.id,n.parents.concat()),!i)return!1;for(o=this.get_node(i),d=[],d.push(i),d=d.concat(o.children_d),this.trigger("model",{nodes:d,parent:n.id}),n.children_d=n.children_d.concat(d),l=0,c=n.parents.length;c>l;l++)this._model.data[n.parents[l]].children_d=this._model.data[n.parents[l]].children_d.concat(d);for(i=o,o=[],l=0,c=n.children.length;c>l;l++)o[l>=r?l+1:l]=n.children[l];return o[r]=i.id,n.children=o,this.redraw_node(n,!0),s&&s.call(this,this.get_node(i)),this.trigger("create_node",{node:this.get_node(i),parent:n.id,position:r}),i.id},rename_node:function(t,n){var i,r,s;if(e.isArray(t)){for(t=t.slice(),i=0,r=t.length;r>i;i++)this.rename_node(t[i],n);return!0}return t=this.get_node(t),t&&"#"!==t.id?(s=t.text,this.check("rename_node",t,this.get_parent(t),n)?(this.set_text(t,n),this.trigger("rename_node",{node:t,text:n,old:s}),!0):(this.settings.core.error.call(this,this._data.core.last_error),!1)):!1},delete_node:function(t){var n,i,r,s,a,o,d,l,c,h;if(e.isArray(t)){for(t=t.slice(),n=0,i=t.length;i>n;n++)this.delete_node(t[n]);return!0}if(t=this.get_node(t),!t||"#"===t.id)return!1;if(r=this.get_node(t.parent),s=e.inArray(t.id,r.children),h=!1,!this.check("delete_node",t,r,s))return this.settings.core.error.call(this,this._data.core.last_error),!1;for(-1!==s&&(r.children=e.vakata.array_remove(r.children,s)),a=t.children_d.concat([]),a.push(t.id),l=0,c=a.length;c>l;l++){for(o=0,d=t.parents.length;d>o;o++)s=e.inArray(a[l],this._model.data[t.parents[o]].children_d),-1!==s&&(this._model.data[t.parents[o]].children_d=e.vakata.array_remove(this._model.data[t.parents[o]].children_d,s));this._model.data[a[l]].state.selected&&(h=!0,s=e.inArray(a[l],this._data.core.selected),-1!==s&&(this._data.core.selected=e.vakata.array_remove(this._data.core.selected,s)))}for(this.trigger("delete_node",{node:t,parent:r.id}),h&&this.trigger("changed",{action:"delete_node",node:t,selected:this._data.core.selected,parent:r.id}),l=0,c=a.length;c>l;l++)delete this._model.data[a[l]];return this.redraw_node(r,!0),!0},check:function(t,n,i,r){n=n&&n.id?n:this.get_node(n),i=i&&i.id?i:this.get_node(i);var s=t.match(/^move_node|copy_node|create_node$/i)?i:n,a=this.settings.core.check_callback;return"move_node"!==t||n.id!==i.id&&e.inArray(n.id,i.children)!==r&&-1===e.inArray(i.id,n.children_d)?(s=this.get_node(s,!0),s.length&&(s=s.data("jstree")),s&&s.functions&&(s.functions[t]===!1||s.functions[t]===!0)?(s.functions[t]===!1&&(this._data.core.last_error={error:"check",plugin:"core",id:"core_02",reason:"Node data prevents function: "+t,data:JSON.stringify({chk:t,pos:r,obj:n&&n.id?n.id:!1,par:i&&i.id?i.id:!1})}),s.functions[t]):a===!1||e.isFunction(a)&&a.call(this,t,n,i,r)===!1||a&&a[t]===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_03",reason:"User config for core.check_callback prevents function: "+t,data:JSON.stringify({chk:t,pos:r,obj:n&&n.id?n.id:!1,par:i&&i.id?i.id:!1})},!1):!0):(this._data.core.last_error={error:"check",plugin:"core",id:"core_01",reason:"Moving parent inside child",data:JSON.stringify({chk:t,pos:r,obj:n&&n.id?n.id:!1,par:i&&i.id?i.id:!1})},!1)},last_error:function(){return this._data.core.last_error},move_node:function(n,i,r,s,a){var o,d,l,c,h,_,u,g,f,p,m,v,y;if(e.isArray(n)){for(n=n.reverse().slice(),o=0,d=n.length;d>o;o++)this.move_node(n[o],i,r,s,a);return!0}if(n=n&&n.id?n:this.get_node(n),i=this.get_node(i),r=r===t?0:r,!i||!n||"#"===n.id)return!1;if(!(""+r).match(/^(before|after)$/)&&!a&&!this.is_loaded(i))return this.load_node(i,function(){this.move_node(n,i,r,s,!0)});if(l=""+(n.parent||"#"),c=(""+r).match(/^(before|after)$/)&&"#"!==i.id?this.get_node(i.parent):i,h=this._model.data[n.id]?this:e.jstree.reference(n.id),_=!h||!h._id||this._id!==h._id)return this.copy_node(n,i,r,s,a)?(h&&h.delete_node(n),!0):!1;switch("#"===c.id&&("before"===r&&(r="first"),"after"===r&&(r="last")),r){case"before":r=e.inArray(i.id,c.children);break;case"after":r=e.inArray(i.id,c.children)+1;break;case"inside":case"first":r=0;break;case"last":r=c.children.length;break;default:r||(r=0)}if(r>c.children.length&&(r=c.children.length),!this.check("move_node",n,c,r))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(n.parent===c.id){for(u=c.children.concat(),g=e.inArray(n.id,u),-1!==g&&(u=e.vakata.array_remove(u,g),r>g&&r--),g=[],f=0,p=u.length;p>f;f++)g[f>=r?f+1:f]=u[f];g[r]=n.id,c.children=g,this._node_changed(c.id),this.redraw("#"===c.id)}else{for(g=n.children_d.concat(),g.push(n.id),f=0,p=n.parents.length;p>f;f++){for(u=[],y=h._model.data[n.parents[f]].children_d,m=0,v=y.length;v>m;m++)-1===e.inArray(y[m],g)&&u.push(y[m]);h._model.data[n.parents[f]].children_d=u}for(h._model.data[l].children=e.vakata.array_remove_item(h._model.data[l].children,n.id),f=0,p=c.parents.length;p>f;f++)this._model.data[c.parents[f]].children_d=this._model.data[c.parents[f]].children_d.concat(g);for(u=[],f=0,p=c.children.length;p>f;f++)u[f>=r?f+1:f]=c.children[f];for(u[r]=n.id,c.children=u,c.children_d.push(n.id),c.children_d=c.children_d.concat(n.children_d),n.parent=c.id,g=c.parents.concat(),g.unshift(c.id),y=n.parents.length,n.parents=g,g=g.concat(),f=0,p=n.children_d.length;p>f;f++)this._model.data[n.children_d[f]].parents=this._model.data[n.children_d[f]].parents.slice(0,-1*y),Array.prototype.push.apply(this._model.data[n.children_d[f]].parents,g);this._node_changed(l),this._node_changed(c.id),this.redraw("#"===l||"#"===c.id)}return s&&s.call(this,n,c,r),this.trigger("move_node",{node:n,parent:c.id,position:r,old_parent:l,is_multi:_,old_instance:h,new_instance:this}),!0},copy_node:function(n,i,r,s,a){var o,d,l,c,h,_,u,g,f,p,m;if(e.isArray(n)){for(n=n.reverse().slice(),o=0,d=n.length;d>o;o++)this.copy_node(n[o],i,r,s,a);return!0}if(n=n&&n.id?n:this.get_node(n),i=this.get_node(i),r=r===t?0:r,!i||!n||"#"===n.id)return!1;if(!(""+r).match(/^(before|after)$/)&&!a&&!this.is_loaded(i))return this.load_node(i,function(){this.copy_node(n,i,r,s,!0)});switch(g=""+(n.parent||"#"),f=(""+r).match(/^(before|after)$/)&&"#"!==i.id?this.get_node(i.parent):i,p=this._model.data[n.id]?this:e.jstree.reference(n.id),m=!p||!p._id||this._id!==p._id,"#"===f.id&&("before"===r&&(r="first"),"after"===r&&(r="last")),r){case"before":r=e.inArray(i.id,f.children);break;case"after":r=e.inArray(i.id,f.children)+1;break;case"inside":case"first":r=0;break;case"last":r=f.children.length;break;default:r||(r=0)}if(r>f.children.length&&(r=f.children.length),!this.check("copy_node",n,f,r))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(u=p?p.get_json(n,{no_id:!0,no_data:!0,no_state:!0}):n,!u)return!1;if(u.id===!0&&delete u.id,u=this._parse_model_from_json(u,f.id,f.parents.concat()),!u)return!1;for(c=this.get_node(u),l=[],l.push(u),l=l.concat(c.children_d),this.trigger("model",{nodes:l,parent:f.id}),h=0,_=f.parents.length;_>h;h++)this._model.data[f.parents[h]].children_d=this._model.data[f.parents[h]].children_d.concat(l);for(l=[],h=0,_=f.children.length;_>h;h++)l[h>=r?h+1:h]=f.children[h];return l[r]=c.id,f.children=l,f.children_d.push(c.id),f.children_d=f.children_d.concat(c.children_d),this._node_changed(f.id),this.redraw("#"===f.id),s&&s.call(this,c,f,r),this.trigger("copy_node",{node:c,original:n,parent:f.id,position:r,old_parent:g,is_multi:m,old_instance:p,new_instance:this}),c.id},cut:function(n){if(n||(n=this._data.core.selected.concat()),e.isArray(n)||(n=[n]),!n.length)return!1;var a=[],o,d,l;for(d=0,l=n.length;l>d;d++)o=this.get_node(n[d]),o&&o.id&&"#"!==o.id&&a.push(o);return a.length?(i=a,s=this,r="move_node",this.trigger("cut",{node:n}),t):!1},copy:function(n){if(n||(n=this._data.core.selected.concat()),e.isArray(n)||(n=[n]),!n.length)return!1;var a=[],o,d,l;for(d=0,l=n.length;l>d;d++)o=this.get_node(n[d]),o&&o.id&&"#"!==o.id&&a.push(o);return a.length?(i=a,s=this,r="copy_node",this.trigger("copy",{node:n}),t):!1},get_buffer:function(){return{mode:r,node:i,inst:s}},can_paste:function(){return r!==!1&&i!==!1},paste:function(e){return e=this.get_node(e),e&&r&&r.match(/^(copy_node|move_node)$/)&&i?(this[r](i,e)&&this.trigger("paste",{parent:e.id,node:i,mode:r}),i=!1,r=!1,s=!1,t):!1},edit:function(n,i){if(n=this._open_to(n),!n||!n.length)return!1;var r=this._data.core.rtl,s=this.element.width(),a=n.children(".jstree-anchor"),o=e("<span>"),d="string"==typeof i?i:this.get_text(n),l=e("<div />",{css:{position:"absolute",top:"-200px",left:r?"0px":"-1000px",visibility:"hidden"}}).appendTo("body"),c=e("<input />",{value:d,"class":"jstree-rename-input",css:{padding:"0",border:"1px solid silver","box-sizing":"border-box",display:"inline-block",height:this._data.core.li_height+"px",lineHeight:this._data.core.li_height+"px",width:"150px"},blur:e.proxy(function(){var e=o.children(".jstree-rename-input"),t=e.val();""===t&&(t=d),l.remove(),o.replaceWith(a),o.remove(),this.set_text(n,d),this.rename_node(n,t)===!1&&this.set_text(n,d)},this),keydown:function(e){var t=e.which;27===t&&(this.value=d),(27===t||13===t||37===t||38===t||39===t||40===t||32===t)&&e.stopImmediatePropagation(),(27===t||13===t)&&(e.preventDefault(),this.blur())},click:function(e){e.stopImmediatePropagation()},mousedown:function(e){e.stopImmediatePropagation()},keyup:function(e){c.width(Math.min(l.text("pW"+this.value).width(),s))},keypress:function(e){return 13===e.which?!1:t}}),h={fontFamily:a.css("fontFamily")||"",fontSize:a.css("fontSize")||"",fontWeight:a.css("fontWeight")||"",fontStyle:a.css("fontStyle")||"",fontStretch:a.css("fontStretch")||"",fontVariant:a.css("fontVariant")||"",letterSpacing:a.css("letterSpacing")||"",wordSpacing:a.css("wordSpacing")||""};this.set_text(n,""),o.attr("class",a.attr("class")).append(a.contents().clone()).append(c),a.replaceWith(o),l.css(h),c.css(h).width(Math.min(l.text("pW"+c[0].value).width(),s))[0].select()},set_theme:function(t,n){if(!t)return!1;if(n===!0){var i=this.settings.core.themes.dir;i||(i=e.jstree.path+"/themes"),n=i+"/"+t+"/style.css"}n&&-1===e.inArray(n,a)&&(e("head").append('<link rel="stylesheet" href="'+n+'" type="text/css" />'),a.push(n)),this._data.core.themes.name&&this.element.removeClass("jstree-"+this._data.core.themes.name),this._data.core.themes.name=t,this.element.addClass("jstree-"+t),this.element[this.settings.core.themes.responsive?"addClass":"removeClass"]("jstree-"+t+"-responsive"),this.trigger("set_theme",{theme:t})},get_theme:function(){return this._data.core.themes.name},set_theme_variant:function(e){this._data.core.themes.variant&&this.element.removeClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant),this._data.core.themes.variant=e,e&&this.element.addClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant)},get_theme_variant:function(){return this._data.core.themes.variant},show_stripes:function(){this._data.core.themes.stripes=!0,this.get_container_ul().addClass("jstree-striped")},hide_stripes:function(){this._data.core.themes.stripes=!1,this.get_container_ul().removeClass("jstree-striped")},toggle_stripes:function(){this._data.core.themes.stripes?this.hide_stripes():this.show_stripes()},show_dots:function(){this._data.core.themes.dots=!0,this.get_container_ul().removeClass("jstree-no-dots")},hide_dots:function(){this._data.core.themes.dots=!1,this.get_container_ul().addClass("jstree-no-dots")},toggle_dots:function(){this._data.core.themes.dots?this.hide_dots():this.show_dots()},show_icons:function(){this._data.core.themes.icons=!0,this.get_container_ul().removeClass("jstree-no-icons")},hide_icons:function(){this._data.core.themes.icons=!1,this.get_container_ul().addClass("jstree-no-icons")},toggle_icons:function(){this._data.core.themes.icons?this.hide_icons():this.show_icons()},set_icon:function(t,n){var i,r,s,a;if(e.isArray(t)){for(t=t.slice(),i=0,r=t.length;r>i;i++)this.set_icon(t[i],n);return!0}return t=this.get_node(t),t&&"#"!==t.id?(a=t.icon,t.icon=n,s=this.get_node(t,!0).children(".jstree-anchor").children(".jstree-themeicon"),n===!1?this.hide_icon(t):n===!0?s.removeClass("jstree-themeicon-custom "+a).css("background","").removeAttr("rel"):-1===n.indexOf("/")&&-1===n.indexOf(".")?(s.removeClass(a).css("background",""),s.addClass(n+" jstree-themeicon-custom").attr("rel",n)):(s.removeClass(a).css("background",""),s.addClass("jstree-themeicon-custom").css("background","url('"+n+"') center center no-repeat").attr("rel",n)),!0):!1},get_icon:function(e){return e=this.get_node(e),e&&"#"!==e.id?e.icon:!1},hide_icon:function(t){var n,i;if(e.isArray(t)){for(t=t.slice(),n=0,i=t.length;i>n;n++)this.hide_icon(t[n]);return!0}return t=this.get_node(t),t&&"#"!==t?(t.icon=!1,this.get_node(t,!0).children("a").children(".jstree-themeicon").addClass("jstree-themeicon-hidden"),!0):!1},show_icon:function(t){var n,i,r;if(e.isArray(t)){for(t=t.slice(),n=0,i=t.length;i>n;n++)this.show_icon(t[n]);return!0}return t=this.get_node(t),t&&"#"!==t?(r=this.get_node(t,!0),t.icon=r.length?r.children("a").children(".jstree-themeicon").attr("rel"):!0,t.icon||(t.icon=!0),r.children("a").children(".jstree-themeicon").removeClass("jstree-themeicon-hidden"),!0):!1}},e.vakata={},e.fn.vakata_reverse=[].reverse,e.vakata.attributes=function(t,n){t=e(t)[0];var i=n?{}:[];return t&&t.attributes&&e.each(t.attributes,function(t,r){-1===e.inArray(r.nodeName.toLowerCase(),["style","contenteditable","hasfocus","tabindex"])&&null!==r.nodeValue&&""!==e.trim(r.nodeValue)&&(n?i[r.nodeName]=r.nodeValue:i.push(r.nodeName))}),i},e.vakata.array_unique=function(e){var t=[],n,i,r;for(n=0,r=e.length;r>n;n++){for(i=0;n>=i;i++)if(e[n]===e[i])break;i===n&&t.push(e[n])}return t},e.vakata.array_remove=function(e,t,n){var i=e.slice((n||t)+1||e.length);return e.length=0>t?e.length+t:t,e.push.apply(e,i),e},e.vakata.array_remove_item=function(t,n){var i=e.inArray(n,t);return-1!==i?e.vakata.array_remove(t,i):t},function(){var t={},n=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||0>e.indexOf("compatible")&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},i=n(window.navigator.userAgent);i.browser&&(t[i.browser]=!0,t.version=i.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),e.vakata.browser=t}(),e.vakata.browser.msie&&8>e.vakata.browser.version&&(e.jstree.defaults.core.animation=0);var _=document.createElement("I");_.className="jstree-icon jstree-checkbox",e.jstree.defaults.checkbox={visible:!0,three_state:!0,whole_node:!0,keep_selected_style:!0},e.jstree.plugins.checkbox=function(t,n){this.bind=function(){n.bind.call(this),this._data.checkbox.uto=!1,this.element.on("init.jstree",e.proxy(function(){this._data.checkbox.visible=this.settings.checkbox.visible,this.settings.checkbox.keep_selected_style||this.element.addClass("jstree-checkbox-no-clicked")},this)).on("loading.jstree",e.proxy(function(){this[this._data.checkbox.visible?"show_checkboxes":"hide_checkboxes"]()},this)),this.settings.checkbox.three_state&&this.element.on("changed.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree",e.proxy(function(){this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(e.proxy(this._undetermined,this),50)},this)).on("model.jstree",e.proxy(function(t,n){var i=this._model.data,r=i[n.parent],s=n.nodes,a=[],o,d,l,c,h,_;if(r.state.selected){for(d=0,l=s.length;l>d;d++)i[s[d]].state.selected=!0;this._data.core.selected=this._data.core.selected.concat(s)}else for(d=0,l=s.length;l>d;d++)if(i[s[d]].state.selected){for(c=0,h=i[s[d]].children_d.length;h>c;c++)i[i[s[d]].children_d[c]].state.selected=!0;this._data.core.selected=this._data.core.selected.concat(i[s[d]].children_d)}for(d=0,l=r.children_d.length;l>d;d++)i[r.children_d[d]].children.length||a.push(i[r.children_d[d]].parent);for(a=e.vakata.array_unique(a),c=0,h=a.length;h>c;c++){r=i[a[c]];while(r&&"#"!==r.id){for(o=0,d=0,l=r.children.length;l>d;d++)o+=i[r.children[d]].state.selected;if(o!==l)break;r.state.selected=!0,this._data.core.selected.push(r.id),_=this.get_node(r,!0),_&&_.length&&_.children(".jstree-anchor").addClass("jstree-clicked"),r=this.get_node(r.parent)}}this._data.core.selected=e.vakata.array_unique(this._data.core.selected)},this)).on("select_node.jstree",e.proxy(function(t,n){var i=n.node,r=this._model.data,s=this.get_node(i.parent),a=this.get_node(i,!0),o,d,l,c;for(this._data.core.selected=e.vakata.array_unique(this._data.core.selected.concat(i.children_d)),o=0,d=i.children_d.length;d>o;o++)r[i.children_d[o]].state.selected=!0;while(s&&"#"!==s.id){for(l=0,o=0,d=s.children.length;d>o;o++)l+=r[s.children[o]].state.selected;if(l!==d)break;s.state.selected=!0,this._data.core.selected.push(s.id),c=this.get_node(s,!0),c&&c.length&&c.children(".jstree-anchor").addClass("jstree-clicked"),s=this.get_node(s.parent)}a.length&&a.find(".jstree-anchor").addClass("jstree-clicked")},this)).on("deselect_node.jstree",e.proxy(function(t,n){var i=n.node,r=this.get_node(i,!0),s,a,o;for(s=0,a=i.children_d.length;a>s;s++)this._model.data[i.children_d[s]].state.selected=!1;for(s=0,a=i.parents.length;a>s;s++)this._model.data[i.parents[s]].state.selected=!1,o=this.get_node(i.parents[s],!0),o&&o.length&&o.children(".jstree-anchor").removeClass("jstree-clicked");for(o=[],s=0,a=this._data.core.selected.length;a>s;s++)-1===e.inArray(this._data.core.selected[s],i.children_d)&&-1===e.inArray(this._data.core.selected[s],i.parents)&&o.push(this._data.core.selected[s]);this._data.core.selected=e.vakata.array_unique(o),r.length&&r.find(".jstree-anchor").removeClass("jstree-clicked")},this)).on("delete_node.jstree",e.proxy(function(e,t){var n=this.get_node(t.parent),i=this._model.data,r,s,a,o;while(n&&"#"!==n.id){for(a=0,r=0,s=n.children.length;s>r;r++)a+=i[n.children[r]].state.selected;if(a!==s)break;n.state.selected=!0,this._data.core.selected.push(n.id),o=this.get_node(n,!0),o&&o.length&&o.children(".jstree-anchor").addClass("jstree-clicked"),n=this.get_node(n.parent)}},this)).on("move_node.jstree",e.proxy(function(t,n){var i=n.is_multi,r=n.old_parent,s=this.get_node(n.parent),a=this._model.data,o,d,l,c,h;if(!i){o=this.get_node(r);while(o&&"#"!==o.id){for(d=0,l=0,c=o.children.length;c>l;l++)d+=a[o.children[l]].state.selected;if(d!==c)break;o.state.selected=!0,this._data.core.selected.push(o.id),h=this.get_node(o,!0),h&&h.length&&h.children(".jstree-anchor").addClass("jstree-clicked"),o=this.get_node(o.parent)}}o=s;while(o&&"#"!==o.id){for(d=0,l=0,c=o.children.length;c>l;l++)d+=a[o.children[l]].state.selected;if(d===c)o.state.selected||(o.state.selected=!0,this._data.core.selected.push(o.id),h=this.get_node(o,!0),h&&h.length&&h.children(".jstree-anchor").addClass("jstree-clicked"));else{if(!o.state.selected)break;o.state.selected=!1,this._data.core.selected=e.vakata.array_remove_item(this._data.core.selected,o.id),h=this.get_node(o,!0),h&&h.length&&h.children(".jstree-anchor").removeClass("jstree-clicked")}o=this.get_node(o.parent)}},this))},this._undetermined=function(){var t,n,i=this._model.data,r=this._data.core.selected,s=[],a=this;for(t=0,n=r.length;n>t;t++)i[r[t]]&&i[r[t]].parents&&(s=s.concat(i[r[t]].parents));for(this.element.find(".jstree-closed").not(":has(ul)").each(function(){var e=a.get_node(this);!e.state.loaded&&e.original&&e.original.state&&e.original.state.undetermined&&e.original.state.undetermined===!0&&(s.push(e.id),s=s.concat(e.parents))}),s=e.vakata.array_unique(s),t=e.inArray("#",s),-1!==t&&(s=e.vakata.array_remove(s,t)),this.element.find(".jstree-undetermined").removeClass("jstree-undetermined"),t=0,n=s.length;n>t;t++)i[s[t]].state.selected||(r=this.get_node(s[t],!0),r&&r.length&&r.children("a").children(".jstree-checkbox").addClass("jstree-undetermined"))},this.redraw_node=function(t,i,r){if(t=n.redraw_node.call(this,t,i,r)){var s=t.getElementsByTagName("A")[0];s.insertBefore(_.cloneNode(),s.childNodes[0])}return!r&&this.settings.checkbox.three_state&&(this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(e.proxy(this._undetermined,this),50)),t},this.activate_node=function(t,i){return(this.settings.checkbox.whole_node||e(i.target).hasClass("jstree-checkbox"))&&(i.ctrlKey=!0),n.activate_node.call(this,t,i)},this.show_checkboxes=function(){this._data.core.themes.checkboxes=!0,this.element.children("ul").removeClass("jstree-no-checkboxes")},this.hide_checkboxes=function(){this._data.core.themes.checkboxes=!1,this.element.children("ul").addClass("jstree-no-checkboxes")},this.toggle_checkboxes=function(){this._data.core.themes.checkboxes?this.hide_checkboxes():this.show_checkboxes()}},e.jstree.defaults.contextmenu={select_node:!0,show_at_node:!0,items:function(t,n){return{create:{separator_before:!1,separator_after:!0,_disabled:!1,label:"Create",action:function(t){var n=e.jstree.reference(t.reference),i=n.get_node(t.reference);n.create_node(i,{},"last",function(e){setTimeout(function(){n.edit(e)},0)})}},rename:{separator_before:!1,separator_after:!1,_disabled:!1,label:"Rename",action:function(t){var n=e.jstree.reference(t.reference),i=n.get_node(t.reference);n.edit(i)}},remove:{separator_before:!1,icon:!1,separator_after:!1,_disabled:!1,label:"Delete",action:function(t){var n=e.jstree.reference(t.reference),i=n.get_node(t.reference);n.is_selected(i)?n.delete_node(n.get_selected()):n.delete_node(i)}},ccp:{separator_before:!0,icon:!1,separator_after:!1,label:"Edit",action:!1,submenu:{cut:{separator_before:!1,separator_after:!1,label:"Cut",action:function(t){var n=e.jstree.reference(t.reference),i=n.get_node(t.reference);n.is_selected(i)?n.cut(n.get_selected()):n.cut(i)}},copy:{separator_before:!1,icon:!1,separator_after:!1,label:"Copy",action:function(t){var n=e.jstree.reference(t.reference),i=n.get_node(t.reference);n.is_selected(i)?n.copy(n.get_selected()):n.copy(i)}},paste:{separator_before:!1,icon:!1,_disabled:function(t){return!e.jstree.reference(t.reference).can_paste()},separator_after:!1,label:"Paste",action:function(t){var n=e.jstree.reference(t.reference),i=n.get_node(t.reference);n.paste(i)}}}}}}},e.jstree.plugins.contextmenu=function(n,i){this.bind=function(){i.bind.call(this),this.element.on("contextmenu.jstree",".jstree-anchor",e.proxy(function(e){e.preventDefault(),this.is_loading(e.currentTarget)||this.show_contextmenu(e.currentTarget,e.pageX,e.pageY,e)},this)).on("click.jstree",".jstree-anchor",e.proxy(function(t){this._data.contextmenu.visible&&e.vakata.context.hide()},this)),e(document).on("context_hide.vakata",e.proxy(function(){this._data.contextmenu.visible=!1},this))},this.teardown=function(){this._data.contextmenu.visible&&e.vakata.context.hide(),i.teardown.call(this)},this.show_contextmenu=function(n,i,r,s){if(n=this.get_node(n),!n||"#"===n.id)return!1;var a=this.settings.contextmenu,o=this.get_node(n,!0),d=o.children(".jstree-anchor"),l=!1,c=!1;(a.show_at_node||i===t||r===t)&&(l=d.offset(),i=l.left,r=l.top+this._data.core.li_height),this.settings.contextmenu.select_node&&!this.is_selected(n)&&(this.deselect_all(),this.select_node(n,!1,!1,s)),c=a.items,e.isFunction(c)&&(c=c.call(this,n,e.proxy(function(e){this._show_contextmenu(n,i,r,e)},this))),e.isPlainObject(c)&&this._show_contextmenu(n,i,r,c)},this._show_contextmenu=function(t,n,i,r){var s=this.get_node(t,!0),a=s.children(".jstree-anchor");e(document).one("context_show.vakata",e.proxy(function(t,n){var i="jstree-contextmenu jstree-"+this.get_theme()+"-contextmenu";e(n.element).addClass(i)},this)),this._data.contextmenu.visible=!0,e.vakata.context.show(a,{x:n,y:i},r),this.trigger("show_contextmenu",{node:t,x:n,y:i})}},function(e){var n=!1,i={element:!1,reference:!1,position_x:0,position_y:0,items:[],html:"",is_visible:!1};e.vakata.context={settings:{hide_onmouseleave:0,icons:!0},_trigger:function(t){e(document).triggerHandler("context_"+t+".vakata",{reference:i.reference,element:i.element,position:{x:i.position_x,y:i.position_y}})},_execute:function(t){return t=i.items[t],t&&(!t._disabled||e.isFunction(t._disabled)&&!t._disabled({item:t,reference:i.reference,element:i.element}))&&t.action?t.action.call(null,{item:t,reference:i.reference,element:i.element,position:{x:i.position_x,y:i.position_y}}):!1},_parse:function(n,r){if(!n)return!1;r||(i.html="",i.items=[]);var s="",a=!1,o;return r&&(s+="<ul>"),e.each(n,function(n,r){return r?(i.items.push(r),!a&&r.separator_before&&(s+="<li class='vakata-context-separator'><a href='#' "+(e.vakata.context.settings.icons?"":'style="margin-left:0px;"')+">&#160;<"+"/a><"+"/li>"),a=!1,s+="<li class='"+(r._class||"")+(r._disabled===!0||e.isFunction(r._disabled)&&r._disabled({item:r,reference:i.reference,element:i.element})?" vakata-contextmenu-disabled ":"")+"' "+(r.shortcut?" data-shortcut='"+r.shortcut+"' ":"")+">",s+="<a href='#' rel='"+(i.items.length-1)+"'>",e.vakata.context.settings.icons&&(s+="<i ",r.icon&&(s+=-1!==r.icon.indexOf("/")||-1!==r.icon.indexOf(".")?" style='background:url(\""+r.icon+"\") center center no-repeat' ":" class='"+r.icon+"' "),s+="></i><span class='vakata-contextmenu-sep'>&#160;</span>"),s+=r.label+(r.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+r.shortcut+'">'+(r.shortcut_label||"")+"</span>":"")+"<"+"/a>",r.submenu&&(o=e.vakata.context._parse(r.submenu,!0),o&&(s+=o)),s+="</li>",r.separator_after&&(s+="<li class='vakata-context-separator'><a href='#' "+(e.vakata.context.settings.icons?"":'style="margin-left:0px;"')+">&#160;<"+"/a><"+"/li>",a=!0),t):!0}),s=s.replace(/<li class\='vakata-context-separator'\><\/li\>$/,""),r&&(s+="</ul>"),r||(i.html=s,e.vakata.context._trigger("parse")),s.length>10?s:!1},_show_submenu:function(t){if(t=e(t),t.length&&t.children("ul").length){var i=t.children("ul"),r=t.offset().left+t.outerWidth(),s=t.offset().top,a=i.width(),o=i.height(),d=e(window).width()+e(window).scrollLeft(),l=e(window).height()+e(window).scrollTop();n?t[0>r-(a+10+t.outerWidth())?"addClass":"removeClass"]("vakata-context-left"):t[r+a+10>d?"addClass":"removeClass"]("vakata-context-right"),s+o+10>l&&i.css("bottom","-1px"),i.show()}},show:function(t,r,s){var a,o,d,l,c,h,_,u,g=!0;switch(i.element&&i.element.length&&i.element.width(""),g){case!r&&!t:return!1;case!!r&&!!t:i.reference=t,i.position_x=r.x,i.position_y=r.y;break;case!r&&!!t:i.reference=t,a=t.offset(),i.position_x=a.left+t.outerHeight(),i.position_y=a.top;break;case!!r&&!t:i.position_x=r.x,i.position_y=r.y}t&&!s&&e(t).data("vakata_contextmenu")&&(s=e(t).data("vakata_contextmenu")),e.vakata.context._parse(s)&&i.element.html(i.html),i.items.length&&(o=i.element,d=i.position_x,l=i.position_y,c=o.width(),h=o.height(),_=e(window).width()+e(window).scrollLeft(),u=e(window).height()+e(window).scrollTop(),n&&(d-=o.outerWidth(),e(window).scrollLeft()+20>d&&(d=e(window).scrollLeft()+20)),d+c+20>_&&(d=_-(c+20)),l+h+20>u&&(l=u-(h+20)),i.element.css({left:d,top:l}).show().find("a:eq(0)").focus().parent().addClass("vakata-context-hover"),i.is_visible=!0,e.vakata.context._trigger("show"))},hide:function(){i.is_visible&&(i.element.hide().find("ul").hide().end().find(":focus").blur(),i.is_visible=!1,e.vakata.context._trigger("hide"))}},e(function(){n="rtl"===e("body").css("direction");var t=!1;i.element=e("<ul class='vakata-context'></ul>"),i.element.on("mouseenter","li",function(n){n.stopImmediatePropagation(),e.contains(this,n.relatedTarget)||(t&&clearTimeout(t),i.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(),e(this).siblings().find("ul").hide().end().end().parentsUntil(".vakata-context","li").addBack().addClass("vakata-context-hover"),e.vakata.context._show_submenu(this))}).on("mouseleave","li",function(t){e.contains(this,t.relatedTarget)||e(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover")}).on("mouseleave",function(n){e(this).find(".vakata-context-hover").removeClass("vakata-context-hover"),e.vakata.context.settings.hide_onmouseleave&&(t=setTimeout(function(t){return function(){e.vakata.context.hide()}}(this),e.vakata.context.settings.hide_onmouseleave))}).on("click","a",function(e){e.preventDefault()}).on("mouseup","a",function(t){e(this).blur().parent().hasClass("vakata-context-disabled")||e.vakata.context._execute(e(this).attr("rel"))===!1||e.vakata.context.hide()}).on("keydown","a",function(t){var n=null;switch(t.which){case 13:case 32:t.type="mouseup",t.preventDefault(),e(t.currentTarget).trigger(t);break;case 37:i.is_visible&&(i.element.find(".vakata-context-hover").last().parents("li:eq(0)").find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children("a").focus(),t.stopImmediatePropagation(),t.preventDefault());break;case 38:i.is_visible&&(n=i.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(),n.length||(n=i.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last()),n.addClass("vakata-context-hover").children("a").focus(),t.stopImmediatePropagation(),t.preventDefault());break;case 39:i.is_visible&&(i.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children("a").focus(),t.stopImmediatePropagation(),t.preventDefault());break;case 40:i.is_visible&&(n=i.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(),n.length||(n=i.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first()),n.addClass("vakata-context-hover").children("a").focus(),t.stopImmediatePropagation(),t.preventDefault());break;case 27:e.vakata.context.hide(),t.preventDefault();break;default:}}).on("keydown",function(e){e.preventDefault();var t=i.element.find(".vakata-contextmenu-shortcut-"+e.which).parent();t.parent().not(".vakata-context-disabled")&&t.mouseup()}).appendTo("body"),e(document).on("mousedown",function(t){i.is_visible&&!e.contains(i.element[0],t.target)&&e.vakata.context.hide()}).on("context_show.vakata",function(e,t){i.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"),n&&i.element.addClass("vakata-context-rtl").css("direction","rtl"),i.element.find("ul").hide().end()
-})})}(e),e.jstree.defaults.dnd={copy:!0,open_timeout:500,is_draggable:!0,check_while_dragging:!0},e.jstree.plugins.dnd=function(n,i){this.bind=function(){i.bind.call(this),this.element.on("mousedown touchstart",".jstree-anchor",e.proxy(function(n){var i=this.get_node(n.target),r=this.is_selected(i)?this.get_selected().length:1;return i&&i.id&&"#"!==i.id&&(1===n.which||"touchstart"===n.type)&&(this.settings.dnd.is_draggable===!0||e.isFunction(this.settings.dnd.is_draggable)&&this.settings.dnd.is_draggable.call(this,i))?(this.element.trigger("mousedown.jstree"),e.vakata.dnd.start(n,{jstree:!0,origin:this,obj:this.get_node(i,!0),nodes:r>1?this.get_selected():[i.id]},'<div id="jstree-dnd" class="jstree-'+this.get_theme()+'"><i class="jstree-icon jstree-er"></i>'+(r>1?r+" "+this.get_string("nodes"):this.get_text(n.currentTarget,!0))+'<ins class="jstree-copy" style="display:none;">+</ins></div>')):t},this))}},e(function(){var n=!1,i=!1,r=!1,s=e('<div id="jstree-marker">&#160;</div>').hide().appendTo("body");e(document).bind("dnd_start.vakata",function(e,t){n=!1}).bind("dnd_move.vakata",function(a,o){if(r&&clearTimeout(r),o.data.jstree&&(!o.event.target.id||"jstree-marker"!==o.event.target.id)){var d=e.jstree.reference(o.event.target),l=!1,c=!1,h=!1,_,u,g,f,p,m,v,y,j,x,k,b;if(d&&d._data&&d._data.dnd)if(s.attr("class","jstree-"+d.get_theme()),o.helper.children().attr("class","jstree-"+d.get_theme()).find(".jstree-copy:eq(0)")[o.data.origin&&o.data.origin.settings.dnd.copy&&(o.event.metaKey||o.event.ctrlKey)?"show":"hide"](),o.event.target!==d.element[0]&&o.event.target!==d.get_container_ul()[0]||0!==d.get_container_ul().children().length){if(l=e(o.event.target).closest("a"),l&&l.length&&l.parent().is(".jstree-closed, .jstree-open, .jstree-leaf")&&(c=l.offset(),h=o.event.pageY-c.top,g=l.height(),m=g/3>h?["b","i","a"]:h>g-g/3?["a","i","b"]:h>g/2?["i","a","b"]:["i","b","a"],e.each(m,function(a,h){switch(h){case"b":_=c.left-6,u=c.top-5,f=d.get_parent(l),p=l.parent().index();break;case"i":_=c.left-2,u=c.top-5+g/2+1,f=l.parent(),p=0;break;case"a":_=c.left-6,u=c.top-5+g,f=d.get_parent(l),p=l.parent().index()+1}for(v=!0,y=0,j=o.data.nodes.length;j>y;y++)if(x=o.data.origin&&o.data.origin.settings.dnd.copy&&(o.event.metaKey||o.event.ctrlKey)?"copy_node":"move_node",k=p,"move_node"===x&&"a"===h&&o.data.origin&&o.data.origin===d&&f===d.get_parent(o.data.nodes[y])&&(b=d.get_node(f),k>e.inArray(o.data.nodes[y],b.children)&&(k-=1)),v=v&&(d&&d.settings&&d.settings.dnd&&d.settings.dnd.check_while_dragging===!1||d.check(x,o.data.origin&&o.data.origin!==d?o.data.origin.get_node(o.data.nodes[y]):o.data.nodes[y],f,k)),!v){d&&d.last_error&&(i=d.last_error());break}return v?("i"===h&&l.parent().is(".jstree-closed")&&d.settings.dnd.open_timeout&&(r=setTimeout(function(e,t){return function(){e.open_node(t)}}(d,l),d.settings.dnd.open_timeout)),n={ins:d,par:f,pos:p},s.css({left:_+"px",top:u+"px"}).show(),o.helper.find(".jstree-icon:eq(0)").removeClass("jstree-er").addClass("jstree-ok"),i={},m=!0,!1):t}),m===!0))return}else{for(v=!0,y=0,j=o.data.nodes.length;j>y;y++)if(v=v&&d.check(o.data.origin&&o.data.origin.settings.dnd.copy&&(o.event.metaKey||o.event.ctrlKey)?"copy_node":"move_node",o.data.origin&&o.data.origin!==d?o.data.origin.get_node(o.data.nodes[y]):o.data.nodes[y],"#","last"),!v)break;if(v)return n={ins:d,par:"#",pos:"last"},s.hide(),o.helper.find(".jstree-icon:eq(0)").removeClass("jstree-er").addClass("jstree-ok"),t}n=!1,o.helper.find(".jstree-icon").removeClass("jstree-ok").addClass("jstree-er"),s.hide()}}).bind("dnd_scroll.vakata",function(e,t){t.data.jstree&&(s.hide(),n=!1,t.helper.find(".jstree-icon:eq(0)").removeClass("jstree-ok").addClass("jstree-er"))}).bind("dnd_stop.vakata",function(t,a){if(r&&clearTimeout(r),a.data.jstree){s.hide();var o,d,l=[];if(n){for(o=0,d=a.data.nodes.length;d>o;o++)l[o]=a.data.origin?a.data.origin.get_node(a.data.nodes[o]):a.data.nodes[o];n.ins[a.data.origin&&a.data.origin.settings.dnd.copy&&(a.event.metaKey||a.event.ctrlKey)?"copy_node":"move_node"](l,n.par,n.pos)}else o=e(a.event.target).closest(".jstree"),o.length&&i&&i.error&&"check"===i.error&&(o=o.jstree(!0),o&&o.settings.core.error.call(this,i))}}).bind("keyup keydown",function(t,n){n=e.vakata.dnd._get(),n.data&&n.data.jstree&&n.helper.find(".jstree-copy:eq(0)")[n.data.origin&&n.data.origin.settings.dnd.copy&&(t.metaKey||t.ctrlKey)?"show":"hide"]()})}),function(e){e.fn.vakata_reverse=[].reverse;var n={element:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1};e.vakata.dnd={settings:{scroll_speed:10,scroll_proximity:20,helper_left:5,helper_top:10,threshold:5},_trigger:function(t,n){var i=e.vakata.dnd._get();i.event=n,e(document).triggerHandler("dnd_"+t+".vakata",i)},_get:function(){return{data:n.data,element:n.element,helper:n.helper}},_clean:function(){n.helper&&n.helper.remove(),n.scroll_i&&(clearInterval(n.scroll_i),n.scroll_i=!1),n={element:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1},e(document).off("mousemove touchmove",e.vakata.dnd.drag),e(document).off("mouseup touchend",e.vakata.dnd.stop)},_scroll:function(t){if(!n.scroll_e||!n.scroll_l&&!n.scroll_t)return n.scroll_i&&(clearInterval(n.scroll_i),n.scroll_i=!1),!1;if(!n.scroll_i)return n.scroll_i=setInterval(e.vakata.dnd._scroll,100),!1;if(t===!0)return!1;var i=n.scroll_e.scrollTop(),r=n.scroll_e.scrollLeft();n.scroll_e.scrollTop(i+n.scroll_t*e.vakata.dnd.settings.scroll_speed),n.scroll_e.scrollLeft(r+n.scroll_l*e.vakata.dnd.settings.scroll_speed),(i!==n.scroll_e.scrollTop()||r!==n.scroll_e.scrollLeft())&&e.vakata.dnd._trigger("scroll",n.scroll_e)},start:function(t,i,r){"touchstart"===t.type&&t.originalEvent&&t.originalEvent.changedTouches&&t.originalEvent.changedTouches[0]&&(t.pageX=t.originalEvent.changedTouches[0].pageX,t.pageY=t.originalEvent.changedTouches[0].pageY,t.target=document.elementFromPoint(t.originalEvent.changedTouches[0].pageX-window.pageXOffset,t.originalEvent.changedTouches[0].pageY-window.pageYOffset)),n.is_drag&&e.vakata.dnd.stop({});try{t.currentTarget.unselectable="on",t.currentTarget.onselectstart=function(){return!1},t.currentTarget.style&&(t.currentTarget.style.MozUserSelect="none")}catch(s){}return n.init_x=t.pageX,n.init_y=t.pageY,n.data=i,n.is_down=!0,n.element=t.currentTarget,r!==!1&&(n.helper=e("<div id='vakata-dnd'></div>").html(r).css({display:"block",margin:"0",padding:"0",position:"absolute",top:"-2000px",lineHeight:"16px",zIndex:"10000"})),e(document).bind("mousemove touchmove",e.vakata.dnd.drag),e(document).bind("mouseup touchend",e.vakata.dnd.stop),!1},drag:function(i){if("touchmove"===i.type&&i.originalEvent&&i.originalEvent.changedTouches&&i.originalEvent.changedTouches[0]&&(i.pageX=i.originalEvent.changedTouches[0].pageX,i.pageY=i.originalEvent.changedTouches[0].pageY,i.target=document.elementFromPoint(i.originalEvent.changedTouches[0].pageX-window.pageXOffset,i.originalEvent.changedTouches[0].pageY-window.pageYOffset)),n.is_down){if(!n.is_drag){if(!(Math.abs(i.pageX-n.init_x)>e.vakata.dnd.settings.threshold||Math.abs(i.pageY-n.init_y)>e.vakata.dnd.settings.threshold))return;n.helper&&(n.helper.appendTo("body"),n.helper_w=n.helper.outerWidth()),n.is_drag=!0,e.vakata.dnd._trigger("start",i)}var r=!1,s=!1,a=!1,o=!1,d=!1,l=!1,c=!1,h=!1,_=!1,u=!1;n.scroll_t=0,n.scroll_l=0,n.scroll_e=!1,e(i.target).parentsUntil("body").addBack().vakata_reverse().filter(function(){return/^auto|scroll$/.test(e(this).css("overflow"))&&(this.scrollHeight>this.offsetHeight||this.scrollWidth>this.offsetWidth)}).each(function(){var r=e(this),s=r.offset();return this.scrollHeight>this.offsetHeight&&(s.top+r.height()-i.pageY<e.vakata.dnd.settings.scroll_proximity&&(n.scroll_t=1),i.pageY-s.top<e.vakata.dnd.settings.scroll_proximity&&(n.scroll_t=-1)),this.scrollWidth>this.offsetWidth&&(s.left+r.width()-i.pageX<e.vakata.dnd.settings.scroll_proximity&&(n.scroll_l=1),i.pageX-s.left<e.vakata.dnd.settings.scroll_proximity&&(n.scroll_l=-1)),n.scroll_t||n.scroll_l?(n.scroll_e=e(this),!1):t}),n.scroll_e||(r=e(document),s=e(window),a=r.height(),o=s.height(),d=r.width(),l=s.width(),c=r.scrollTop(),h=r.scrollLeft(),a>o&&i.pageY-c<e.vakata.dnd.settings.scroll_proximity&&(n.scroll_t=-1),a>o&&o-(i.pageY-c)<e.vakata.dnd.settings.scroll_proximity&&(n.scroll_t=1),d>l&&i.pageX-h<e.vakata.dnd.settings.scroll_proximity&&(n.scroll_l=-1),d>l&&l-(i.pageX-h)<e.vakata.dnd.settings.scroll_proximity&&(n.scroll_l=1),(n.scroll_t||n.scroll_l)&&(n.scroll_e=r)),n.scroll_e&&e.vakata.dnd._scroll(!0),n.helper&&(_=parseInt(i.pageY+e.vakata.dnd.settings.helper_top,10),u=parseInt(i.pageX+e.vakata.dnd.settings.helper_left,10),a&&_+25>a&&(_=a-50),d&&u+n.helper_w>d&&(u=d-(n.helper_w+2)),n.helper.css({left:u+"px",top:_+"px"})),e.vakata.dnd._trigger("move",i)}},stop:function(t){"touchend"===t.type&&t.originalEvent&&t.originalEvent.changedTouches&&t.originalEvent.changedTouches[0]&&(t.pageX=t.originalEvent.changedTouches[0].pageX,t.pageY=t.originalEvent.changedTouches[0].pageY,t.target=document.elementFromPoint(t.originalEvent.changedTouches[0].pageX-window.pageXOffset,t.originalEvent.changedTouches[0].pageY-window.pageYOffset)),n.is_drag&&e.vakata.dnd._trigger("stop",t),e.vakata.dnd._clean()}}}(jQuery),e.jstree.defaults.search={ajax:!1,fuzzy:!0,case_sensitive:!1,show_only_matches:!1,close_opened_onclear:!0},e.jstree.plugins.search=function(t,n){this.bind=function(){n.bind.call(this),this._data.search.str="",this._data.search.dom=e(),this._data.search.res=[],this._data.search.opn=[],this._data.search.sln=null,this.settings.search.show_only_matches&&this.element.on("search.jstree",function(t,n){n.nodes.length&&(e(this).find("li").hide().filter(".jstree-last").filter(function(){return this.nextSibling}).removeClass("jstree-last"),n.nodes.parentsUntil(".jstree").addBack().show().filter("ul").each(function(){e(this).children("li:visible").eq(-1).addClass("jstree-last")}))}).on("clear_search.jstree",function(t,n){n.nodes.length&&e(this).find("li").css("display","").filter(".jstree-last").filter(function(){return this.nextSibling}).removeClass("jstree-last")})},this.search=function(t,n){if(t===!1||""===e.trim(t))return this.clear_search();var i=this.settings.search,r=i.ajax?e.extend({},i.ajax):!1,s=null,a=[],o=[],d,l;if(this._data.search.res.length&&this.clear_search(),!n&&r!==!1)return r.data||(r.data={}),r.data.str=t,e.ajax(r).fail(e.proxy(function(){this._data.core.last_error={error:"ajax",plugin:"search",id:"search_01",reason:"Could not load search parents",data:JSON.stringify(r)},this.settings.core.error.call(this,this._data.core.last_error)},this)).done(e.proxy(function(n){n&&n.d&&(n=n.d),this._data.search.sln=e.isArray(n)?n:[],this._search_load(t)},this));if(this._data.search.str=t,this._data.search.dom=e(),this._data.search.res=[],this._data.search.opn=[],s=new e.vakata.search(t,!0,{caseSensitive:i.case_sensitive,fuzzy:i.fuzzy}),e.each(this._model.data,function(e,t){t.text&&s.search(t.text).isMatch&&(a.push(e),o=o.concat(t.parents))}),a.length){for(o=e.vakata.array_unique(o),this._search_open(o),d=0,l=a.length;l>d;d++)s=this.get_node(a[d],!0),s&&(this._data.search.dom=this._data.search.dom.add(s));this._data.search.res=a,this._data.search.dom.children(".jstree-anchor").addClass("jstree-search")}this.trigger("search",{nodes:this._data.search.dom,str:t,res:this._data.search.res})},this.clear_search=function(){this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search"),this.settings.search.close_opened_onclear&&this.close_node(this._data.search.opn,0),this.trigger("clear_search",{nodes:this._data.search.dom,str:this._data.search.str,res:this._data.search.res}),this._data.search.str="",this._data.search.res=[],this._data.search.opn=[],this._data.search.dom=e()},this._search_open=function(t){var n=this;e.each(t.concat([]),function(e,i){i=document.getElementById(i),i&&n.is_closed(i)&&(n._data.search.opn.push(i.id),n.open_node(i,function(){n._search_open(t)},0))})},this._search_load=function(t){var n=!0,i=this,r=i._model.data;e.isArray(this._data.search.sln)&&(this._data.search.sln.length?(e.each(this._data.search.sln,function(s,a){r[a]&&(e.vakata.array_remove_item(i._data.search.sln,a),r[a].state.loaded||(i.load_node(a,function(e,n){n&&i._search_load(t)}),n=!1))}),n&&(this._data.search.sln=[],this._search_load(t))):(this._data.search.sln=null,this.search(t,!0)))}},function(e){e.vakata.search=function(e,t,n){n=n||{},n.fuzzy!==!1&&(n.fuzzy=!0),e=n.caseSensitive?e:e.toLowerCase();var i=n.location||0,r=n.distance||100,s=n.threshold||.6,a=e.length,o,d,l,c;return a>32&&(n.fuzzy=!1),n.fuzzy&&(o=1<<a-1,d=function(){var t={},n=0;for(n=0;a>n;n++)t[e.charAt(n)]=0;for(n=0;a>n;n++)t[e.charAt(n)]|=1<<a-n-1;return t}(),l=function(e,t){var n=e/a,s=Math.abs(i-t);return r?n+s/r:s?1:n}),c=function(t){if(t=n.caseSensitive?t:t.toLowerCase(),e===t||-1!==t.indexOf(e))return{isMatch:!0,score:0};if(!n.fuzzy)return{isMatch:!1,score:1};var r,c,h=t.length,_=s,u=t.indexOf(e,i),g,f,p=a+h,m,v,y,j,x,k=1,b=[];for(-1!==u&&(_=Math.min(l(0,u),_),u=t.lastIndexOf(e,i+a),-1!==u&&(_=Math.min(l(0,u),_))),u=-1,r=0;a>r;r++){g=0,f=p;while(f>g)_>=l(r,i+f)?g=f:p=f,f=Math.floor((p-g)/2+g);for(p=f,v=Math.max(1,i-f+1),y=Math.min(i+f,h)+a,j=Array(y+2),j[y+1]=(1<<r)-1,c=y;c>=v;c--)if(x=d[t.charAt(c-1)],j[c]=0===r?(1|j[c+1]<<1)&x:(1|j[c+1]<<1)&x|(1|(m[c+1]|m[c])<<1)|m[c+1],j[c]&o&&(k=l(r,c-1),_>=k)){if(_=k,u=c-1,b.push(u),!(u>i))break;v=Math.max(1,2*i-u)}if(l(r+1,i)>_)break;m=j}return{isMatch:u>=0,score:k}},t===!0?{search:c}:c(t)}}(jQuery),e.jstree.defaults.sort=function(e,t){return this.get_text(e)>this.get_text(t)?1:-1},e.jstree.plugins.sort=function(t,n){this.bind=function(){n.bind.call(this),this.element.on("model.jstree",e.proxy(function(e,t){this.sort(t.parent,!0)},this)).on("rename_node.jstree create_node.jstree",e.proxy(function(e,t){this.sort(t.parent||t.node.parent,!1),this.redraw_node(t.parent||t.node.parent,!0)},this)).on("move_node.jstree copy_node.jstree",e.proxy(function(e,t){this.sort(t.parent,!1),this.redraw_node(t.parent,!0)},this))},this.sort=function(t,n){var i,r;if(t=this.get_node(t),t&&t.children&&t.children.length&&(t.children.sort(e.proxy(this.settings.sort,this)),n))for(i=0,r=t.children_d.length;r>i;i++)this.sort(t.children_d[i],!1)}};var u=!1;e.jstree.defaults.state={key:"jstree",events:"changed.jstree open_node.jstree close_node.jstree",ttl:!1,filter:!1},e.jstree.plugins.state=function(t,n){this.bind=function(){n.bind.call(this);var t=e.proxy(function(){this.element.on(this.settings.state.events,e.proxy(function(){u&&clearTimeout(u),u=setTimeout(e.proxy(function(){this.save_state()},this),100)},this))},this);this.element.on("ready.jstree",e.proxy(function(e,n){this.element.one("restore_state.jstree",t),this.restore_state()||t()},this))},this.save_state=function(){var t={state:this.get_state(),ttl:this.settings.state.ttl,sec:+new Date};e.vakata.storage.set(this.settings.state.key,JSON.stringify(t))},this.restore_state=function(){var t=e.vakata.storage.get(this.settings.state.key);if(t)try{t=JSON.parse(t)}catch(n){return!1}return t&&t.ttl&&t.sec&&+new Date-t.sec>t.ttl?!1:(t&&t.state&&(t=t.state),t&&e.isFunction(this.settings.state.filter)&&(t=this.settings.state.filter.call(this,t)),t?(this.element.one("set_state.jstree",function(n,i){i.instance.trigger("restore_state",{state:e.extend(!0,{},t)})}),this.set_state(t),!0):!1)},this.clear_state=function(){return e.vakata.storage.del(this.settings.state.key)}},function(e,t){e.vakata.storage={set:function(e,t){return window.localStorage.setItem(e,t)},get:function(e){return window.localStorage.getItem(e)},del:function(e){return window.localStorage.removeItem(e)}}}(jQuery),e.jstree.defaults.types={"#":{},"default":{}},e.jstree.plugins.types=function(n,i){this.init=function(e,n){var r,s;if(n&&n.types&&n.types["default"])for(r in n.types)if("default"!==r&&"#"!==r&&n.types.hasOwnProperty(r))for(s in n.types["default"])n.types["default"].hasOwnProperty(s)&&n.types[r][s]===t&&(n.types[r][s]=n.types["default"][s]);i.init.call(this,e,n),this._model.data["#"].type="#"},this.bind=function(){i.bind.call(this),this.element.on("model.jstree",e.proxy(function(e,n){var i=this._model.data,r=n.nodes,s=this.settings.types,a,o,d="default";for(a=0,o=r.length;o>a;a++)d="default",i[r[a]].original&&i[r[a]].original.type&&s[i[r[a]].original.type]&&(d=i[r[a]].original.type),i[r[a]].data&&i[r[a]].data.jstree&&i[r[a]].data.jstree.type&&s[i[r[a]].data.jstree.type]&&(d=i[r[a]].data.jstree.type),i[r[a]].type=d,i[r[a]].icon===!0&&s[d].icon!==t&&(i[r[a]].icon=s[d].icon)},this))},this.get_json=function(t,n,r){var s,a,o=this._model.data,d=n?e.extend(!0,{},n,{no_id:!1}):{},l=i.get_json.call(this,t,d,r);if(l===!1)return!1;if(e.isArray(l))for(s=0,a=l.length;a>s;s++)l[s].type=l[s].id&&o[l[s].id]&&o[l[s].id].type?o[l[s].id].type:"default",n&&n.no_id&&(delete l[s].id,l[s].li_attr&&l[s].li_attr.id&&delete l[s].li_attr.id);else l.type=l.id&&o[l.id]&&o[l.id].type?o[l.id].type:"default",n&&n.no_id&&(l=this._delete_ids(l));return l},this._delete_ids=function(t){if(e.isArray(t)){for(var n=0,i=t.length;i>n;n++)t[n]=this._delete_ids(t[n]);return t}return delete t.id,t.li_attr&&t.li_attr.id&&delete t.li_attr.id,t.children&&e.isArray(t.children)&&(t.children=this._delete_ids(t.children)),t},this.check=function(n,r,s,a){if(i.check.call(this,n,r,s,a)===!1)return!1;r=r&&r.id?r:this.get_node(r),s=s&&s.id?s:this.get_node(s);var o=r&&r.id?e.jstree.reference(r.id):null,d,l,c,h;switch(o=o&&o._model&&o._model.data?o._model.data:null,n){case"create_node":case"move_node":case"copy_node":if("move_node"!==n||-1===e.inArray(r.id,s.children)){if(d=this.get_rules(s),d.max_children!==t&&-1!==d.max_children&&d.max_children===s.children.length)return this._data.core.last_error={error:"check",plugin:"types",id:"types_01",reason:"max_children prevents function: "+n,data:JSON.stringify({chk:n,pos:a,obj:r&&r.id?r.id:!1,par:s&&s.id?s.id:!1})},!1;if(d.valid_children!==t&&-1!==d.valid_children&&-1===e.inArray(r.type,d.valid_children))return this._data.core.last_error={error:"check",plugin:"types",id:"types_02",reason:"valid_children prevents function: "+n,data:JSON.stringify({chk:n,pos:a,obj:r&&r.id?r.id:!1,par:s&&s.id?s.id:!1})},!1;if(o&&r.children_d&&r.parents){for(l=0,c=0,h=r.children_d.length;h>c;c++)l=Math.max(l,o[r.children_d[c]].parents.length);l=l-r.parents.length+1}(0>=l||l===t)&&(l=1);do{if(d.max_depth!==t&&-1!==d.max_depth&&l>d.max_depth)return this._data.core.last_error={error:"check",plugin:"types",id:"types_03",reason:"max_depth prevents function: "+n,data:JSON.stringify({chk:n,pos:a,obj:r&&r.id?r.id:!1,par:s&&s.id?s.id:!1})},!1;s=this.get_node(s.parent),d=this.get_rules(s),l++}while(s)}}return!0},this.get_rules=function(e){if(e=this.get_node(e),!e)return!1;var n=this.get_type(e,!0);return n.max_depth===t&&(n.max_depth=-1),n.max_children===t&&(n.max_children=-1),n.valid_children===t&&(n.valid_children=-1),n},this.get_type=function(t,n){return t=this.get_node(t),t?n?e.extend({type:t.type},this.settings.types[t.type]):t.type:!1},this.set_type=function(n,i){var r,s,a,o,d;if(e.isArray(n)){for(n=n.slice(),s=0,a=n.length;a>s;s++)this.set_type(n[s],i);return!0}return r=this.settings.types,n=this.get_node(n),r[i]&&n?(o=n.type,d=this.get_icon(n),n.type=i,(d===!0||r[o]&&r[o].icon&&d===r[o].icon)&&this.set_icon(n,r[i].icon!==t?r[i].icon:!0),!0):!1}},e.jstree.plugins.unique=function(t,n){this.check=function(t,i,r,s){if(n.check.call(this,t,i,r,s)===!1)return!1;if(i=i&&i.id?i:this.get_node(i),r=r&&r.id?r:this.get_node(r),!r||!r.children)return!0;var a="rename_node"===t?s:i.text,o=[],d=this._model.data,l,c;for(l=0,c=r.children.length;c>l;l++)o.push(d[r.children[l]].text);switch(t){case"delete_node":return!0;case"rename_node":case"copy_node":return l=-1===e.inArray(a,o),l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_01",reason:"Child with name "+a+" already exists. Preventing: "+t,data:JSON.stringify({chk:t,pos:s,obj:i&&i.id?i.id:!1,par:r&&r.id?r.id:!1})}),l;case"move_node":return l=i.parent===r.id||-1===e.inArray(a,o),l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_01",reason:"Child with name "+a+" already exists. Preventing: "+t,data:JSON.stringify({chk:t,pos:s,obj:i&&i.id?i.id:!1,par:r&&r.id?r.id:!1})}),l}return!0}};var g=document.createElement("DIV");g.setAttribute("unselectable","on"),g.className="jstree-wholerow",g.innerHTML="&#160;",e.jstree.plugins.wholerow=function(t,n){this.bind=function(){n.bind.call(this),this.element.on("loading",e.proxy(function(){g.style.height=this._data.core.li_height+"px"},this)).on("ready.jstree set_state.jstree",e.proxy(function(){this.hide_dots()},this)).on("ready.jstree",e.proxy(function(){this.get_container_ul().addClass("jstree-wholerow-ul")},this)).on("deselect_all.jstree",e.proxy(function(e,t){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked")},this)).on("changed.jstree",e.proxy(function(e,t){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked");var n=!1,i,r;for(i=0,r=t.selected.length;r>i;i++)n=this.get_node(t.selected[i],!0),n&&n.length&&n.children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("open_node.jstree",e.proxy(function(e,t){this.get_node(t.node,!0).find(".jstree-clicked").parent().children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("hover_node.jstree dehover_node.jstree",e.proxy(function(e,t){this.get_node(t.node,!0).children(".jstree-wholerow")["hover_node"===e.type?"addClass":"removeClass"]("jstree-wholerow-hovered")},this)).on("contextmenu.jstree",".jstree-wholerow",e.proxy(function(t){t.preventDefault(),e(t.currentTarget).closest("li").children("a:eq(0)").trigger("contextmenu",t)},this)).on("click.jstree",".jstree-wholerow",function(t){t.stopImmediatePropagation();var n=e.Event("click",{metaKey:t.metaKey,ctrlKey:t.ctrlKey,altKey:t.altKey,shiftKey:t.shiftKey});e(t.currentTarget).closest("li").children("a:eq(0)").trigger(n).focus()}).on("click.jstree",".jstree-leaf > .jstree-ocl",e.proxy(function(t){t.stopImmediatePropagation();var n=e.Event("click",{metaKey:t.metaKey,ctrlKey:t.ctrlKey,altKey:t.altKey,shiftKey:t.shiftKey});e(t.currentTarget).closest("li").children("a:eq(0)").trigger(n).focus()},this)).on("mouseover.jstree",".jstree-wholerow, .jstree-icon",e.proxy(function(e){return e.stopImmediatePropagation(),this.hover_node(e.currentTarget),!1},this)).on("mouseleave.jstree",".jstree-node",e.proxy(function(e){this.dehover_node(e.currentTarget)},this))},this.teardown=function(){this.settings.wholerow&&this.element.find(".jstree-wholerow").remove(),n.teardown.call(this)},this.redraw_node=function(t,i,r){if(t=n.redraw_node.call(this,t,i,r)){var s=g.cloneNode(!0);-1!==e.inArray(t.id,this._data.core.selected)&&(s.className+=" jstree-wholerow-clicked"),t.insertBefore(s,t.childNodes[0])}return t}}}});
diff --git a/Duplicati/Server/webroot/greeno/scripts/logwindow.js b/Duplicati/Server/webroot/greeno/scripts/logwindow.js
deleted file mode 100644
index 9770b7e05..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/logwindow.js
+++ /dev/null
@@ -1,237 +0,0 @@
-$(document).ready(function() {
- var appdatacallback = function(data, tag) {
- var td = $.tmpl($('#log-data-template'), data);
- td.appendTo(tag);
-
- td.find('.log-exception').each(function(i, e) {
- $(e).html(nl2br($(e).html()));
- });
-
- td.find('.log-exception').click(function(e) {
- e.bubbles = false;
- return false;
- });
- td.find('.log-timestamp').each(function(i, e) {
- $(e).text((new Date(parseInt($(e).attr('title')))).toLocaleString());
- });
- td.click(function(e) {
- $(this).toggleClass('expanded');
- });
- };
-
- var livedatacallback = function(data, tag) {
- var scrolledToEnd = tag.parent().scrollTop() > tag.height() - (tag.parent().height()*2);
-
- var td = $.tmpl($('#live-log-data-template'), data)
- td.appendTo(tag);
-
- td.find('.log-exception').each(function(i, e) {
- $(e).html(nl2br($(e).html()));
- });
-
- td.find('.log-exception').click(function(e) {
- e.bubbles = false;
- return false;
- });
- td.find('.log-timestamp').each(function(i, e) {
- $(e).text(new Date($(e).attr('title')).toLocaleString());
- });
- td.click(function(e) {
- $(this).toggleClass('expanded');
- });
-
- if (data != null && data.length > 0 && scrolledToEnd)
- tag.parent().scrollTop(tag.height());
- };
-
- var generaldatacallback = function(data, tag) {
- var td = $.tmpl($('#log-backup-general-template'), data)
- td.appendTo(tag);
-
- td.find('.log-exception').each(function(i, e) {
- $(e).html(nl2br($(e).html()));
- });
- td.find('.log-message').each(function(i, e) {
- $(e).html(nl2br($(e).html()));
- });
-
- td.find('.log-exception').click(function(e) {
- return e.bubbles = false;
- });
- td.find('.log-message').click(function(e) {
- return e.bubbles = false;
- });
-
- td.find('.log-timestamp').each(function(i, e) {
- $(e).text((new Date(parseInt($(e).attr('title')))).toLocaleString());
- });
-
- td.click(function(e) {
- $(this).toggleClass('expanded');
- });
- };
-
- var remotedatacallback = function(data, tag) {
- var td = $.tmpl($('#log-backup-remote-template'), data);
- td.appendTo(tag);
-
- td.find('.log-data').each(function(i, e) {
- $(e).html(nl2br($(e).html()));
- });
- td.find('.log-data').click(function(e) {
- return e.bubbles = false;
- });
-
- td.find('.log-timestamp').each(function(i, e) {
- $(e).text((new Date(parseInt($(e).attr('title')))).toLocaleString());
- });
-
- td.click(function(e) {
- $(e.target).closest('.log-entry').toggleClass('expanded');
- });
- };
-
- var refreshRunning = false;
- var refreshId = 0;
-
- var refreshLiveData = function() {
- if (refreshRunning)
- return;
-
- var v = $('#log-tab-live-level').val();
- if (v == '' || v == 'disabled')
- return;
-
- if (!$('#log-dialog').dialog('isOpen'))
- return;
-
- refreshRunning = true;
-
- APP_DATA.callServer({'action': 'poll-log-messages', 'level': v, 'id': refreshId},
- function(data) {
- for(var n in data)
- refreshId = Math.max(refreshId, data[n].ID);
-
- refreshRunning = false;
- livedatacallback(data, $('#log-tab-live'));
- setTimeout(refreshLiveData, 3000);
- },
- function() {
- refreshRunning = false;
- setTimeout(refreshLiveData, 1000);
- });
- };
-
- $.showAppLog = function() {
- var dlg_buttons = $('#log-dialog').parent().find('.ui-dialog-buttonpane').find('.ui-button');
-
- $('#log-dialog').dialog('open');
-
- var data = $('#log-tab-stored').data('log');
- if (!data) {
- data = {
- first: null,
- last: null
- };
- $('#log-tab-stored').data('log', data);
- }
-
- if (data.first == null) {
- $('#log-tab-stored').empty();
- APP_DATA.callServer({'action': 'read-log', 'pagesize': 100}, function(data) {
- appdatacallback(data, $('#log-tab-stored'));
- });
- };
-
- var loglevel = $('#log-tab-live-level');
- loglevel.empty();
-
- $('#log-tab-live').find('.log-entry').remove();
-
- loglevel.change(function() {
- refreshId = 0;
-
- var v = $('#log-tab-live-level').val();
- if (v == '' || v == 'disabled')
- return;
-
- $('#log-tab-live').find('.log-entry').remove();
- refreshLiveData();
- });
-
- APP_DATA.getServerConfig(function(server_config) {
-
- loglevel.append($('<option></option>')
- .attr('value', 'disabled')
- .text('Disabled'));
-
- for(var n in server_config.LogLevels)
- loglevel.append($('<option></option>')
- .attr('value',server_config.LogLevels[n])
- .text(server_config.LogLevels[n]));
-
- }, function() { alert('Failed to read server data'); });
-
- };
-
- $.showBackupLog = function(id) {
-
- $('#backup-log-tab-general').empty();
- $('#backup-log-tab-remote').empty();
-
- $('<div id="restore-search-loader" class="small-loader-icon">').appendTo($('#backup-log-tab-general'));
- $('<div id="restore-search-loader" class="small-loader-icon">').appendTo($('#backup-log-tab-remote'));
-
- var loglevel = $('#backup-log-live-level');
- loglevel.empty();
-
- loglevel.change(refreshLiveData);
-
- $('#backup-log-dialog').dialog('open');
-
-
- APP_DATA.callServer({'action': 'read-log', 'pagesize': 100, 'id': id, 'remotelog': false}, function(generaldata) {
- APP_DATA.callServer({'action': 'read-log', 'pagesize': 100, 'id': id, 'remotelog': true}, function(remotedata) {
- $('#backup-log-tab-general').empty();
- $('#backup-log-tab-remote').empty();
-
- generaldatacallback(generaldata, $('#backup-log-tab-general'));
- remotedatacallback(remotedata, $('#backup-log-tab-remote'));
-
- }, function() { alert('Failed to read log data'); });
- }, function() { alert('Failed to read log data'); });
- };
-
-
- $('#log-dialog').tabs({ active: 0 });
- $('#log-dialog').dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- { text: 'Close', disabled: false, click: function(event, ui) {
- $(this).dialog('close');
- }}
- ]
- });
-
- $('#backup-log-dialog').tabs({ active: 0 });
- $('#backup-log-dialog').dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- { text: 'Close', disabled: false, click: function(event, ui) {
- $(this).dialog('close');
- }}
- ]
- });
-});
diff --git a/Duplicati/Server/webroot/greeno/scripts/oldbrowsersupport.js b/Duplicati/Server/webroot/greeno/scripts/oldbrowsersupport.js
deleted file mode 100644
index e257be3fb..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/oldbrowsersupport.js
+++ /dev/null
@@ -1,52 +0,0 @@
-if ( !Date.prototype.toISOString ) {
- ( function() {
-
- function pad(number) {
- if ( number < 10 ) {
- return '0' + number;
- }
- return number;
- }
-
- Date.prototype.toISOString = function() {
- return this.getUTCFullYear() +
- '-' + pad( this.getUTCMonth() + 1 ) +
- '-' + pad( this.getUTCDate() ) +
- 'T' + pad( this.getUTCHours() ) +
- ':' + pad( this.getUTCMinutes() ) +
- ':' + pad( this.getUTCSeconds() ) +
- '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice( 2, 5 ) +
- 'Z';
- };
-
- }() );
-}
-
-function nl2br (str, is_xhtml) {
- var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';
- return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
-}
-
-function preg_quote( str ) {
- // http://kevin.vanzonneveld.net
- // + original by: booeyOH
- // + improved by: Ates Goral (http://magnetiq.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // * example 1: preg_quote("$40");
- // * returns 1: '\$40'
- // * example 2: preg_quote("*RRRING* Hello?");
- // * returns 2: '\*RRRING\* Hello\?'
- // * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
- // * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:'
-
- return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
-}
-
-function replace_all_insensitive(str, pattern, replacement) {
- return str.replace( new RegExp( "(" + preg_quote(pattern) + ")" , 'gi' ), replacement );
-};
-
-function replace_all(str, pattern, replacement) {
- return str.replace( new RegExp( "(" + preg_quote(pattern) + ")" , 'g' ), replacement );
-}
diff --git a/Duplicati/Server/webroot/greeno/scripts/plugins.js b/Duplicati/Server/webroot/greeno/scripts/plugins.js
deleted file mode 100644
index da7266105..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/plugins.js
+++ /dev/null
@@ -1,837 +0,0 @@
-$(document).ready(function() {
-
- APP_DATA.plugins.backend['file'] = {
- hasssl: false,
- hideserverandport: true,
- optionalauth: true,
-
- btnel: null,
-
- fill_form_map: {
- 'server-path': function(dict, key, el, cfgel) {
- var p = [];
- if (dict['server-name'] && dict['server-name'] != '')
- p.push(dict['server-name']);
- if (dict['server-path'] && dict['server-path'] != '')
- p.push(dict['server-path']);
-
- var sep = '/';
- if (this.serverconfig)
- sep = this.serverconfig.DirectorySeparator;
-
- p = p.join(sep);
- if (p.indexOf('file://') == 0)
- p = p.substr('file://'.length);
-
- $('#server-path').val(p);
- }
- },
-
- fill_dict_map: {
- 'server-path': function(dict, key, el, cfgel) {
- var p = $(el).val();
- if (p.indexOf('file://') == 0)
- p = p.substr('file://'.length);
- dict['server-path'] = p;
- dict['server-name'] = '';
- }
- },
-
- decode_uri: function(url) {
- var dict = EDIT_URI.decode_uri(url);
- if (dict == null || dict['backend-type'] == null) {
-
- dict = dict || {};
-
- var p = url;
- if (p.indexOf('file://') == 0)
- p = p.substr('file://'.length);
-
- if (p.indexOf('?') > 0) {
- var q = p.substr(p.indexOf('?') + 1);
- p = p.substr(0, p.length - q.length - 1);
- q.replace(EDIT_URI.QUERY_REGEXP, function(str, key, val) {
- if (key)
- dict['--' + key] = decodeURIComponent(val);
- });
- }
-
- $.extend(true, dict, {
- 'source_uri': url,
- 'backend-type': 'file',
- 'server-path': p
- });
- }
-
- return dict;
- },
-
- setup: function(dlg, div) {
- $('#server-path').addClass('server-path-file');
- $('#server-path').watermark('mybackup');
-
- this.btnel = $('<input type="button" value="..." class="browse-button" />').css('width', 'auto');
- this.btnel.insertAfter($('#server-path'));
- this.btnel.click(function() {
- $.browseForFolder({
- title: 'Select target folder',
- multiSelect: false,
- resolvePath: true,
- callback: function(path, display) {
- $('#server-path').val(path);
- }
- });
- });
-
- if (this.serverconfig == null) {
- APP_DATA.getServerConfig(function(data) {
- this.serverconfig = data;
- });
- }
- },
- cleanup: function(dlg, div) {
- $('#server-path').removeClass('server-path-file');
- if (this.btnel != null) {
- this.btnel.remove();
- this.btnel = null;
- }
-
- }
- }
-
- APP_DATA.plugins.backend['webdav'] = {
- defaultport: 80,
- defaultportssl: 443
- }
-
- APP_DATA.plugins.backend['cloudfiles'] = {
- defaultport: 80,
- defaultportssl: 443
- }
-
- APP_DATA.plugins.backend['ftp'] = {
- defaultport: 21,
- defaultportssl: 443,
- optionalpassword: true
- }
-
- APP_DATA.plugins.backend['aftp'] = {
- defaultport: 21,
- defaultportssl: 443,
- optionalpassword: true
- }
-
- APP_DATA.plugins.backend['ssh'] = {
- defaultport: 22,
- optionalauth: true,
- hasssl: false
- }
-
- APP_DATA.plugins.backend['onedrive'] = {
- PLUGIN_LOGIN_LINK: 'https://duplicati-oauth-handler.appspot.com/',
-
- hideserverandport: true,
- hideusernameandpassword: true,
- optionalauth: true,
- hasssl: false,
- fetchtoken: null,
-
- passwordlabel: 'AuthID',
-
- fill_form_map: {
- '--authid': 'authid'
- },
-
- fill_dict_map: {
- 'authid': '--authid'
- },
-
- validate: function(form, values) {
- delete values['auth-username'];
- delete values['auth-password'];
- delete values['--auth-username'];
- delete values['--auth-password'];
-
- if (values['--authid'] == '')
- return EDIT_URI.validation_error($('#server-password'), 'You must fill in an AuthID');
-
-
- return EDIT_URI.validate_input(values, true);
- },
-
- setup: function(dlg, div) {
-
-
- var authid = EDIT_URI.createFieldset({label: 'AuthID', name: 'authid', after: $('#server-path'), watermark: 'Enter the AuthID value'});
-
- authid.label.addClass('action-link');
-
-
- var self = this;
- authid.label.click(function() {
-
- self.fetchtoken = Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2);
- var ft = self.fetchtoken;
-
- var countDown = 100;
- var url = self.PLUGIN_LOGIN_LINK + '?token=' + self.fetchtoken;
- var real_link = $('<a />').text(authid.label.text())
- .addClass('edit-dialog-label')
- .addClass('action-link')
- .attr('href', url)
- .attr('target', '_blank');
-
- authid.label.attr('href', url).addClass('action-link');
- real_link.insertAfter(authid.label);
-
- setTimeout(function() { authid.label.hide(); }, 500);
-
- var w = 400;
- var h = 550;
-
- var left = (screen.width/2)-(w/2);
- var top = (screen.height/2)-(h/2);
- var wnd = window.open(url, '_blank', 'height=' + h +',width=' + w + ',menubar=0,status=0,titlebar=0,toolbar=0,left=' + left + ',top=' + top)
-
- var recheck = function() {
- countDown--;
- if (countDown > 0 && ft == self.fetchtoken) {
- $.ajax({
- url: self.PLUGIN_LOGIN_LINK + 'fetch',
- dataType: 'jsonp',
- data: {'token': ft}
- })
- .done(function(data) {
- if (data.authid) {
- authid.field.val(data.authid);
- wnd.close();
- } else {
- setTimeout(recheck, 3000);
- }
- })
- .fail(function() {
- setTimeout(recheck, 3000);
- });
- } else {
- if (wnd != null)
- wnd.close();
- }
- };
-
- setTimeout(recheck, 6000);
-
- return false;
- });
- },
-
- cleanup: function(dlg, div) {
- this.fetchtoken = null;
- }
- }
-
- APP_DATA.plugins.backend['googledrive'] = APP_DATA.plugins.backend['onedrive'];
- APP_DATA.plugins.backend['hubic'] = APP_DATA.plugins.backend['onedrive'];
- APP_DATA.plugins.backend['amzcd'] = APP_DATA.plugins.backend['onedrive'];
- APP_DATA.plugins.backend['box'] = APP_DATA.plugins.backend['onedrive'];
-
- APP_DATA.plugins.backend['s3'] = {
-
- PLUGIN_S3_LINK: 'https://portal.aws.amazon.com/gp/aws/developer/registration/index.html',
-
- hasssl: true,
- hideserverandport: true,
- usernamelabel: 'AWS Access ID',
- passwordlabel: 'AWS Secret Key',
- usernamewatermark: 'AWS Access ID',
- passwordwatermark: 'AWS Secret Key',
- serverdrop_field: null,
- regiondrop_field: null,
- storageclassdrop_field: null,
- bucket_field: null,
-
- known_hosts: null,
- known_regions: null,
- known_storage_classes: null,
-
- setup_hosts_after_config: function() {
- if (this.known_hosts != null && this.serverdrop_field != null)
- {
- var servers = [];
- for (var k in this.known_hosts)
- servers.push({label: k + ' (' + this.known_hosts[k] + ')', value: this.known_hosts[k]});
-
- this.serverdrop_field.autocomplete({
- minLength: 0,
- source: servers,
- });
- var self = this;
- this.serverdrop_field.click(function() {
- self.serverdrop_field.autocomplete('search', '');
- });
- }
- },
-
- setup_regions_after_config: function() {
- if (this.known_regions != null && this.regiondrop_field != null) {
- var buckets = [];
- for (var k in this.known_regions)
- buckets.push({label: k + ' (' + this.known_regions[k] + ')', value: this.known_regions[k]});
-
- this.regiondrop_field.autocomplete({
- minLength: 0,
- source: buckets,
- });
- var self = this;
- this.regiondrop_field.click(function() {
- self.regiondrop_field.autocomplete('search', '');
- });
- }
- },
-
- setup_storage_classes_after_config: function() {
- if (this.known_storage_classes != null && this.storageclassdrop_field != null) {
- var buckets = [];
- for (var k in this.known_storage_classes)
- buckets.push({label: k + ' (' + this.known_storage_classes[k] + ')', value: this.known_storage_classes[k]});
-
- this.storageclassdrop_field.autocomplete({
- minLength: 0,
- source: buckets,
- });
- var self = this;
- this.storageclassdrop_field.click(function() {
- self.storageclassdrop_field.autocomplete('search', '');
- });
- }
- },
-
- setup: function(dlg, div) {
- var self = this;
-
- $('#server-path-label').hide();
- $('#server-path').hide();
-
- var serverdrop = EDIT_URI.createFieldset({label: 'S3 servername', name: 's3-server', after: $('#server-path'), watermark: 'Click for a list of providers'});
- var bucketfield = EDIT_URI.createFieldset({label: 'S3 Bucket name', name: 's3-bucket', after: $('#server-username-and-password'), title: 'Use / to access subfolders in the bucket', watermark: 'Enter bucket name'});
- var regiondrop = EDIT_URI.createFieldset({label: 'Bucket create region', name: 's3-region', before: $('#server-options-label'), watermark: 'Click for a list of regions', title: 'Note that region is only used when creating buckets'});
- var storageclassdrop = EDIT_URI.createFieldset({label: 'Storage class', name: 's3-storage-class', after: regiondrop.outer, watermark: 'Click for a list of storage classes'});
- var signuplink = EDIT_URI.createFieldset({'label': '&nbsp;', href: this.PLUGIN_S3_LINK, type: 'link', before: bucketfield.outer, 'title': 'Click here for the sign up page'});
-
- signuplink.outer.css('margin-bottom', '10px');
-
- this.serverdrop_field = serverdrop.field;
- this.regiondrop_field = regiondrop.field;
- this.bucket_field = bucketfield.field;
- this.storageclassdrop_field = storageclassdrop.field;
-
-
- if (self.known_hosts == null) {
- APP_DATA.callServer({action: 'send-command', command: 's3-getconfig', 's3-config': 'Providers'}, function(data) {
- self.known_hosts = data.Result;
- self.setup_hosts_after_config();
- },
- function(data, success, message) {
- alert('Failed to get S3 config: ' + message);
- });
- } else {
- this.setup_hosts_after_config();
- }
-
- if (self.known_regions == null) {
- APP_DATA.callServer({action: 'send-command', command: 's3-getconfig', 's3-config': 'Regions'}, function(data) {
- self.known_regions = data.Result;
- self.setup_regions_after_config();
- },
- function(data, success, message) {
- alert('Failed to get S3 config: ' + message);
- });
- } else {
- this.setup_regions_after_config();
- }
-
- if (self.known_storage_classes == null) {
- APP_DATA.callServer({action: 'send-command', command: 's3-getconfig', 's3-config': 'StorageClasses'}, function(data) {
- self.known_storage_classes = data.Result;
- self.setup_storage_classes_after_config();
- },
- function(data, success, message) {
- alert('Failed to get S3 config: ' + message);
- });
- } else {
- this.setup_storage_classes_after_config();
- }
-
- },
-
- cleanup: function(dlg, div) {
- $('#server-path-label').show();
- $('#server-path').show();
- this.serverdrop_field = null;
- this.regiondrop_field = null;
- this.storageclassdrop_field = null;
- this.bucket_field = null;
- },
-
- fill_form: function(el, cfg) {
- // Upgrade from checkbox to string
- if (APP_UTIL.parseBoolOption(cfg['--s3-use-rrs']) && !cfg['--s3-location-constraint']) {
- delete cfg['--s3-use-rrs'];
- cfg['--s3-location-constraint'] = 'REDUCED_REDUNDANCY';
- }
-
- EDIT_URI.fill_form(el, cfg);
- },
-
- validate: function(dlg, values) {
- if (!EDIT_URI.validate_input(values, true))
- return;
- if (values['--s3-server-name'] == '')
- return EDIT_URI.validation_error(this.serverdrop_field, 'You must fill in or select the S3 server to use');
-
- if (values['server-path'] == '')
- return EDIT_URI.validation_error(this.bucket_field, 'You must enter a S3 bucket name');
- if (values['server-path'].toLowerCase() != values['server-path']) {
- if (!confirm('The bucket name must be all lower case, convert automatically?')) {
- this.bucket_field.focus();
- return false;
- }
- values['server-path'] = values['server-path'].toLowerCase();
- this.bucket_field.val(values['server-path']);
- }
- if (values['server-path'].indexOf(values['--auth-username'].toLowerCase()) != 0) {
- if (confirm('The bucket name should start with your username, append automatically?')) {
- values['server-path'] = values['--auth-username'].toLowerCase() + '-' + values['server-path'];
- this.bucket_field.val(values['server-path']);
- }
- }
-
- return true;
- },
-
- fill_form_map: {
- 'server-path': 's3-bucket',
- '--s3-server-name': 's3-server',
- '--s3-storage-class': 's3-storage-class',
- '--s3-location-constraint': 's3-region'
- },
-
- fill_dict_map: {
- 's3-bucket': 'server-path',
- 's3-server': '--s3-server-name',
- 's3-storage-class': '--s3-storage-class',
- 's3-region': '--s3-location-constraint'
- }
- }
-
- APP_DATA.plugins.backend['azure'] = {
-
- PLUGIN_AZURE_LINK: 'https://account.windowsazure.com/Home/Index',
-
- hasssl: false,
- hideserverandport: true,
- usernamelabel: 'Account Name',
- passwordlabel: 'Access Key',
- usernamewatermark: 'Account Name',
- passwordwatermark: 'Access Key',
- container_field: null,
-
- setup: function (dlg, div) {
- $('#server-path-label').hide();
- $('#server-path').hide();
-
- $('#server-username').attr('placeholder', this.usernamewatermark);
- $('#server-password').attr('placeholder', this.passwordwatermark);
-
- var containerfield = EDIT_URI.createFieldset({ label: 'Container Name', name: 'azure-container', after: $('#server-username-and-password'), title: 'Container name', watermark: 'Enter container name' });
- this.container_field = containerfield.field;
-
- var signuplink = EDIT_URI.createFieldset({ 'label': '&nbsp;', href: this.PLUGIN_AZURE_LINK, type: 'link', before: $('#server-options-label'), 'title': 'Click here to sign in or register' });
- signuplink.outer.css('margin-bottom', '10px');
-
- },
-
- cleanup: function (dlg, div) {
- $('#server-path-label').show();
- $('#server-path').show();
- this.container_field = null;
- },
-
- validate: function (dlg, values) {
- if (!EDIT_URI.validate_input(values, true))
- return false;
- if (values['azure-container'] == '')
- return EDIT_URI.validation_error(this.container_field, 'You must enter an Azure container name');
-
- values['server-name'] = values["azure-container"].toLowerCase();
- this.container_field.val(values['server-name']);
-
- return true;
- },
-
- fill_form_map: {
- 'server-name': 'azure-container'
- },
-
- fill_dict_map: {
- 'azure-container': 'server-name'
- }
- }
-
- var tmp_gcs = $.extend(true, {
- locationdrop_field: null,
- known_locations: null,
- storage_class_field: null,
- known_storage_classes: null,
-
- setup_locations_after_config: function() {
- if (this.known_locations != null && this.locationdrop_field != null)
- {
- var servers = [];
- for (var k in this.known_locations)
- servers.push({label: k + ' (' + this.known_locations[k] + ')', value: this.known_locations[k]});
-
- this.locationdrop_field.autocomplete({
- minLength: 0,
- source: servers,
- });
- var self = this;
- this.locationdrop_field.click(function() {
- self.locationdrop_field.autocomplete('search', '');
- });
- }
- },
-
- setup_storage_classes_after_config: function() {
- if (this.known_storage_classes != null && this.storage_class_field != null)
- {
- var servers = [];
- for (var k in this.known_storage_classes)
- servers.push({label: k + ' (' + this.known_storage_classes[k] + ')', value: this.known_storage_classes[k]});
-
- this.storage_class_field.autocomplete({
- minLength: 0,
- source: servers,
- });
- var self = this;
- this.storage_class_field.click(function() {
- self.storage_class_field.autocomplete('search', '');
- });
- }
- },
-
- setup_gcs: function()
- {
- var locationdrop = EDIT_URI.createFieldset({label: 'Bucket create location', name: 'gcs-location', before: $('#server-options-label'), watermark: 'Click for a list of locations', title: 'Note that location is only used when creating buckets'});
- var storageclassdrop = EDIT_URI.createFieldset({label: 'Bucket storage class', name: 'gcs-storage-class', before: $('#server-options-label'), watermark: 'Click for a list of storage classes', title: 'Note that storage class is only used when creating buckets'});
- var projectidfield = EDIT_URI.createFieldset({label: 'GCS Project ID', name: 'gcs-project', before: $('#server-options-label'), title: 'Supply the project ID', watermark: 'Enter project ID'});
-
- this.locationdrop_field = locationdrop.field;
- this.storage_class_field = storageclassdrop.field;
- this.projectid_field = projectidfield.field;
-
- this.prevsettings = {
- placeholder: $('#server-path').attr('placeholder'),
- text: $('#server-path-label').text()
- };
-
- $('#server-path').attr('placeholder', 'bucket/folder/subfolder');
- $('#server-path-label').text('Bucket name');
-
-
- var self = this;
-
- if (self.known_locations == null) {
- APP_DATA.callServer({action: 'send-command', command: 'gcs-getconfig', 'gcs-config': 'Locations'}, function(data) {
- self.known_locations = data.Result;
- self.setup_locations_after_config();
- },
- function(data, success, message) {
- alert('Failed to get GCS config: ' + message);
- });
- } else {
- this.setup_locations_after_config();
- }
-
- if (self.known_storage_classes == null) {
- APP_DATA.callServer({action: 'send-command', command: 'gcs-getconfig', 'gcs-config': 'StorageClasses'}, function(data) {
- self.known_storage_classes = data.Result;
- self.setup_storage_classes_after_config();
- },
- function(data, success, message) {
- alert('Failed to get GCS config: ' + message);
- });
- } else {
- this.setup_storage_classes_after_config();
- }
- },
-
- cleanup_gcs: function() {
- this.locationdrop_field = null;
- this.regiondrop_field = null;
- this.projectid_field = null;
-
- if (this.prevsettings != null) {
- $('#server-path').attr('placeholder', this.prevsettings.placeholder);
- $('#server-path-label').text(this.prevsettings.text);
- this.prevsettings = null;
- }
-
- },
-
- fill_form_map: {
- '--gcs-location': 'gcs-location',
- '--gcs-storage-class': 'gcs-storage-class',
- '--gcs-project': 'gcs-project'
- },
-
- fill_dict_map: {
- 'gcs-location': '--gcs-location',
- 'gcs-storage-class': '--gcs-storage-class',
- 'gcs-project': '--gcs-project'
- }
-
- }, APP_DATA.plugins.backend['onedrive']);
-
- tmp_gcs.setup_auth = tmp_gcs.setup;
- tmp_gcs.cleanup_auth = tmp_gcs.cleanup;
-
- tmp_gcs.setup = function() {
- this.setup_auth();
- this.setup_gcs();
- };
-
- tmp_gcs.cleanup = function() {
- this.cleanup_auth();
- this.cleanup_gcs();
- };
-
- APP_DATA.plugins.backend['gcs'] = tmp_gcs;
- delete tmp_gcs;
-
- APP_DATA.plugins.backend['openstack'] = {
-
- hasssl: false,
- hideserverandport: true,
-
- serverdrop_field: null,
- known_hosts: null,
- optionalauth: true,
-
- setup_hosts_after_config: function() {
- if (this.known_hosts != null && this.serverdrop_field != null)
- {
- var servers = [];
- for (var k in this.known_hosts)
- servers.push({label: k + ' (' + this.known_hosts[k] + ')', value: this.known_hosts[k]});
-
- this.serverdrop_field.autocomplete({
- minLength: 0,
- source: servers,
- });
- var self = this;
- this.serverdrop_field.click(function() {
- self.serverdrop_field.autocomplete('search', '');
- });
- }
- },
-
- setup: function(dlg, div) {
- var self = this;
-
- var projectidfield = EDIT_URI.createFieldset({label: 'Tenant Name', name: 'openstack-tenant-name', before: $('#server-options-label'), title: 'Enter the Tenant Name if you are not using API Key', watermark: 'Optional Tenant Name'});
- var projectidfield = EDIT_URI.createFieldset({label: 'API Key', name: 'openstack-apikey', before: $('#server-options-label'), title: 'If you supply the API key, the Password, Tenant Name fields are not required', watermark: 'Optional API Key'});
- var projectidfield = EDIT_URI.createFieldset({label: 'Container region', name: 'openstack-region', before: $('#server-options-label'), title: 'If your provider supports regions, you can supply the region value here.', watermark: 'Optional region'});
-
- var serverdrop = EDIT_URI.createFieldset({label: 'OpenStack Authuri', name: 'openstack-authuri', after: $('#server-path'), watermark: 'Click for a list of providers'});
- this.serverdrop_field = serverdrop.field;
-
- this.prevsettings = {
- placeholder: $('#server-path').attr('placeholder'),
- text: $('#server-path-label').text()
- };
-
- $('#server-path').attr('placeholder', 'bucket/folder/subfolder');
- $('#server-path-label').text('Bucket name');
-
- if (self.known_hosts == null) {
- APP_DATA.callServer({action: 'send-command', command: 'openstack-getconfig', 'openstack-config': 'Providers'}, function(data) {
- self.known_hosts = data.Result;
- self.setup_hosts_after_config();
- },
- function(data, success, message) {
- alert('Failed to get OpenStack config: ' + message);
- });
- } else {
- this.setup_hosts_after_config();
- }
- },
-
- cleanup: function(dlg, div) {
- this.serverdrop_field = null;
- if (this.prevsettings != null) {
- $('#server-path').attr('placeholder', this.prevsettings.placeholder);
- $('#server-path-label').text(this.prevsettings.text);
- this.prevsettings = null;
- }
- },
-
- validate: function(dlg, values) {
- if (!EDIT_URI.validate_input(values, true))
- return;
- if (values['--openstack-authuri'] == '')
- return EDIT_URI.validation_error(this.serverdrop_field, 'You must fill in or select the Authentication URI');
-
- if (values['server-path'] == '')
- return EDIT_URI.validation_error($('#server-path'), 'You must enter a path');
-
- if (values['server-username'] == '')
- return EDIT_URI.validation_error($('#server-username'), 'You must enter a username');
-
- if (values['--openstack-apikey'] == '')
- {
- if (values['server-password'] == '')
- return EDIT_URI.validation_error($('#server-username'), 'You must enter a password or API key');
-
- if (values['openstack-tenantname'] == '')
- return EDIT_URI.validation_error($('#server-username'), 'You must enter a Tenant Name if you do not supply the API key');
- }
- else
- {
- if (values['server-password'] != '')
- return EDIT_URI.validation_error($('#server-username'), 'You should not enter a password if you are using API key authentication');
- }
-
- return true;
- },
-
- fill_form_map: {
- '--openstack-authuri': 'openstack-authuri',
- '--openstack-tenant-name': 'openstack-tenant-name',
- '--openstack-apikey': 'openstack-apikey',
- '--openstack-region': 'openstack-region'
- },
-
- fill_dict_map: {
- 'openstack-authuri': '--openstack-authuri',
- 'openstack-tenant-name': '--openstack-tenant-name',
- 'openstack-apikey': '--openstack-apikey',
- 'openstack-region': '--openstack-region'
- }
- }
-
- APP_DATA.plugins.backend['b2'] = {
-
- PLUGIN_B2_LINK: 'https://www.backblaze.com/b2/cloud-storage.html',
-
- hasssl: false,
- hideserverandport: true,
- usernamelabel: 'B2 Account ID',
- passwordlabel: 'B2 Application Key',
- usernamewatermark: 'B2 Cloud Storage Account ID',
- passwordwatermark: 'B2 Cloud Storage Application Key',
-
- setup: function(dlg, div) {
- var self = this;
-
- $('#server-path-label').hide();
- $('#server-path').hide();
-
- var bucketfield = EDIT_URI.createFieldset({label: 'B2 Bucket name', name: 'b2-bucket', after: $('#server-username-and-password'), title: 'Use / to access subfolders in the bucket', watermark: 'Enter bucket name'});
- var signuplink = EDIT_URI.createFieldset({'label': '&nbsp;', href: this.PLUGIN_B2_LINK, type: 'link', before: bucketfield.outer, 'title': 'Click here for the sign up page'});
-
- signuplink.outer.css('margin-bottom', '10px');
-
- this.bucket_field = bucketfield.field;
- },
-
- cleanup: function(dlg, div) {
- $('#server-path-label').show();
- $('#server-path').show();
- this.bucket_field = null;
- },
-
- validate: function(dlg, values) {
- if (!EDIT_URI.validate_input(values, true))
- return;
-
- if (values['server-path'] == '')
- return EDIT_URI.validation_error(this.bucket_field, 'You must enter a B2 bucket name');
-
- return true;
- },
-
- fill_form_map: {
- 'server-path': 'b2-bucket'
- },
-
- fill_dict_map: {
- 'b2-bucket': 'server-path'
- }
- }
-
- APP_DATA.plugins.backend['mega'] = {
-
- PLUGIN_MEGA_LINK: 'https://mega.co.nz',
-
- hasssl: false,
- hideserverandport: true,
- usernamelabel: 'Username',
- passwordlabel: 'Password',
- usernamewatermark: 'Username',
- passwordwatermark: 'Password',
- path_field: null,
-
- setup: function (dlg, div) {
- $('#server-path-label').hide();
- $('#server-path').hide();
-
- $('#server-username').attr('placeholder', this.usernamewatermark);
- $('#server-password').attr('placeholder', this.passwordwatermark);
-
- var pathfield = EDIT_URI.createFieldset({ label: 'Path', name: 'mega-path', after: $('#server-username-and-password'), title: 'Path', watermark: 'Enter path' });
- this.path_field = pathfield.field;
-
- var signuplink = EDIT_URI.createFieldset({ 'label': '&nbsp;', href: this.PLUGIN_MEGA_LINK, type: 'link', before: $('#server-options-label'), 'title': 'Click here to sign in or register' });
- signuplink.outer.css('margin-bottom', '10px');
-
- },
-
- cleanup: function (dlg, div) {
- $('#server-path-label').show();
- $('#server-path').show();
- this.path_field = null;
- },
-
- validate: function (dlg, values) {
- if (!EDIT_URI.validate_input(values, true))
- return false;
-
- values['server-path'] = values["mega-path"].toLowerCase();
- this.path_field.val(values['server-path']);
-
- return true;
- },
-
- fill_form_map: {
- 'server-path': function(dict, key, el, cfgel) {
- var p = [];
- if (dict['server-name'] && dict['server-name'] != '')
- p.push(dict['server-name']);
- if (dict['server-path'] && dict['server-path'] != '')
- p.push(dict['server-path']);
-
- p = p.join('/');
-
- $('#mega-path').val(p);
- }
- },
-
- fill_dict_map: {
- 'mega-path': function(dict, key, el, cfgel) {
- var p = $(el).val();
- dict['server-path'] = p;
- dict['server-name'] = '';
- }
- }
- }
-});
diff --git a/Duplicati/Server/webroot/greeno/scripts/restoredialog.js b/Duplicati/Server/webroot/greeno/scripts/restoredialog.js
deleted file mode 100644
index f0561b1fe..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/restoredialog.js
+++ /dev/null
@@ -1,972 +0,0 @@
-$(document).ready(function() {
-
- var curpage = 0;
- var backupId = 0;
- var dirSep = '/';
- var pathSep = ':';
- var trees = {};
- var searchdata = {};
- var nodedata = {};
-
- var manualIncludes = {};
- var searchTrees = {};
- var commonPrefix = [];
-
- var dbversions = {};
- var isDirectRestore = false;
-
- var includeMap = null;
-
- var performRestore = function(tasks) {
- var dlg = $('<div></div>').attr('title', 'Restoring files ...');
- var cancelling = false;
- var currentProgressTask = null;
- var remainingTasks = tasks.length;
-
- dlg.dialog({
- autoOpen: true,
- modal: true,
- closeOnEscape: false,
- buttons: [
- { text: 'Cancel', click: function(event, ui) {
- if (confirm('Stop the restore?')) {
- cancelling = true;
- if (currentProgressTask != null)
- APP_DATA.stopTask(currentProgressTask.taskId, true);
-
- updatePageNav();
- dlg.dialog('close');
- dlg.remove();
- }
- }}
- ]
- });
-
- dlg.parent().find('.ui-dialog-titlebar-close').remove().first().remove();
-
- var pg = $('<div></div>');
- pg.progressbar({ value: false });
- var pgtxt = $('<div></div>');
- pgtxt.text('Sending jobs to server ...');
-
- dlg.append(pg);
- dlg.append(pgtxt);
-
- var onAllRestoresCompleted = function() {
- $(document).off('server-progress-updated', serverProgressUpdateMethod);
- $(document).off('server-state-updated', serverStateUpdateMethod);
-
- curpage = Math.min(2, curpage+1);
- updatePageNav();
- dlg.dialog('close');
- dlg.remove();
- };
-
- var serverProgressUpdateMethod = function(e, data) {
- if (currentProgressTask == null)
- pgtxt.text('Waiting for restore to begin ...');
- else {
- if (tasks.length == 1)
- pgtxt.text('Restoring files ...');
- else
- pgtxt.text('Restoring files (' + (tasks.length - remainingTasks) + ' of ' + tasks.length + ')');
- }
-
- };
-
- var serverStateUpdateMethod = function(e, data) {
- var activeTaskId = -1;
- var queuedTasks = [];
-
- if (cancelling)
- return;
-
- if (data.ActiveTask != null)
- activeTaskId = data.ActiveTask.Item1;
-
- if (data.SchedulerQueueIds != null)
- for(var n in data.SchedulerQueueIds)
- queuedTasks.push(data.SchedulerQueueIds[n].Item1);
-
- var remaining = 0;
- for(var n in tasks) {
-
- if (tasks[n].taskId == activeTaskId) {
- currentProgressTask = tasks[n];
- remaining++;
- continue;
- }
-
- for(var i in queuedTasks)
- if (queuedTasks[i] == tasks[n].taskId) {
- remaining++;
- continue;
- }
- }
-
- if (remaining == 0)
- onAllRestoresCompleted();
- };
-
- var curTask = 0;
- var registerTasks = function() {
- if (curTask == tasks.length) {
- pgtxt.text('Waiting for restore to begin ...');
- $(document).on('server-progress-updated', serverProgressUpdateMethod);
- $(document).on('server-state-updated', serverStateUpdateMethod);
- return;
- }
-
- var task = tasks[curTask];
- curTask++;
-
- APP_DATA.callServer(task, function(data) {
- task['taskId'] = data.TaskID;
- registerTasks();
- },
- function(d, s, m) {
- alert('Error: ' + m);
- dlg.dialog('close');
- dlg.remove();
- });
-
- }
-
- registerTasks();
- };
-
- $('#restore-dialog').dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- { text: '< Previous', disabled: true, click: function(event, ui) {
- curpage = Math.max(0, curpage-1);
- updatePageNav();
-
- }},
- { text: 'Next >', click: function(event, ui) {
- if (curpage == 2) {
- $('#restore-dialog').dialog('close');
- } else if (curpage == 1) {
-
- var restorePath = null;
-
- var overwrite = $('#restore-overwrite-overwrite').is(':checked');
-
- var restore_permissions = $('#restore-metadata-permissions').is(':checked');
- var skip_metadata = $('#restore-metadata-none').is(':checked');
-
- if ($('#restore-overwrite-target-other').is(':checked'))
- restorePath = $('#restore-target-path').val();
-
- var tasks = [];
- for(var n in includeMap) {
- var t = {
- 'action': 'restore-files',
- time: $('#restore-version').val(),
- 'HTTP_METHOD': 'POST',
- id: backupId,
- 'restore-path': restorePath,
- 'overwrite': overwrite,
- 'permissions': restore_permissions,
- 'skip-metadata': skip_metadata,
- paths: []
- };
- for(var p in includeMap[n]) {
- if (p.lastIndexOf(dirSep) == p.length -1)
- t.paths.push(p + '*');
- else
- t.paths.push(p);
- }
-
- if (t.paths.length > 0)
- {
- t.paths = t.paths.join(pathSep);
- tasks.push(t);
- }
- }
-
- if (isDirectRestore) {
-
- var backupid = null;
-
- var dlg = APP_UTIL.create_modal_task_wait('Creating database', 'Building local database ... ', function(cancelled, taskid) {
- if (!cancelled)
- performRestore(tasks);
- });
-
- APP_DATA.callServer({ action: 'copy-backup-to-temp', 'id': backupId }, function(data) {
- var bkid = data.ID;
- for(var n in tasks)
- tasks[n].id = bkid;
-
- APP_DATA.callServer({ action: 'send-command', command: 'run-repair', 'id': bkid, 'time': $('#restore-version').val(), 'paths': tasks[0].paths, 'HTTP_METHOD': 'POST' }, function(data) {
- dlg.register_updates(data.ID);
- }, function(a,b,msg) {
- alert('Failed to connect: ' + msg);
- dlg.dialog('close');
- dlg.remove();
- });
- }, function(a,b,msg) {
- alert('Failed to connect: ' + msg);
- dlg.dialog('close');
- dlg.remove();
- });
-
-
- } else {
- performRestore(tasks);
- }
- } else {
- var els = 0;
- includeMap = buildIncludeMap();
-
- for(var t in includeMap)
- for(var i in includeMap[t])
- els++;
-
- if (els == 0) {
- alert('You must select at least one path to restore');
- return;
- }
-
- curpage = Math.min(2, curpage+1);
- updatePageNav();
-
- }
- }}
- ]
- });
-
- var dlg_buttons = $('#restore-dialog').parent().find('.ui-dialog-buttonpane').find('.ui-button');
- var updatePageNav = function() {
- if (curpage == 0) {
- $('#restore-files-page').show();
- $('#restore-path-page').hide();
- $('#restore-complete-page').hide();
- dlg_buttons.first().show();
- dlg_buttons.last().button('option', 'label', 'Next >');
- } else if (curpage == 1) {
- $('#restore-files-page').hide();
- $('#restore-path-page').show();
- $('#restore-complete-page').hide();
- dlg_buttons.first().show();
- dlg_buttons.last().button('option', 'label', 'Restore');
- } else {
- $('#restore-files-page').hide();
- $('#restore-path-page').hide();
- $('#restore-complete-page').show();
-
- dlg_buttons.first().hide();
- dlg_buttons.last().button('option', 'label', 'OK');
- }
-
- dlg_buttons.first().button('option', 'disabled', curpage == 0);
- };
-
- $('#restore-search').watermark('Search for files & folders');
-
- $('#restore-files-page').show();
- $('#restore-path-page').hide();
- $('#restore-complete-page').hide();
-
- var colorize = function(tree, term, entry) {
- var tr = tree.jstree();
- $(entry || tree).find('a.jstree-anchor').each(function(i, e) {
- var s = $(e);
- var node = tr.get_node(s);
- if (node.text) {
- s.children('.search-match').remove();
- var o = s.children();
- s.html(replace_all_insensitive(node.text, term, '<div class="search-match">$1</div>'));
- s.prepend(o);
- }
- });
- };
-
- var buildSearchNodes = function(time, data, search) {
- var rootpath = commonPrefix[time];
- if (rootpath != '' && rootpath[rootpath.length - 1] != dirSep)
- rootpath += dirSep;
- var rootnode = createNodeFromData(commonPrefix[time], commonPrefix[time], time, true);
- rootnode.state = rootnode.state || {};
- rootnode.state.opened = true;
-
-
- for(var i = 0; i < data.Files.length; i++) {
- var n = rootnode;
- var p = rootpath;
- var sp = data.Files[i].Path;
-
- if (search && sp.toLowerCase().indexOf(search.toLowerCase()) < 0)
- continue;
-
- var isDir = sp.substr(sp.length - 1) == dirSep;
- if (isDir)
- sp = sp.substr(0, sp.length - 1);
-
- var items = sp.substr(rootpath.length).split(dirSep);
-
- for(var j = 0; j < items.length; j++) {
- p += items[j] + (!isDir && j == items.length - 1 ? '' : dirSep);
-
- var e = null;
- for(var x in n.children)
- if (n.children[x].filepath == p) {
- e = n.children[x];
- break;
- }
-
- if (e == null) {
- e = createNodeFromData(p, commonPrefix[time], time, false);
-
- if (j != items.length - 1) {
- e.state = e.state || {};
- e.state.opened = true;
- }
-
- if (n.children === false || n.children === true)
- n.children = [];
- n.children.push(e);
-
- }
- n = e;
- }
- }
-
- return [rootnode];
- }
-
- var inSearch = false;
- var doSearch = function(time, search) {
- if (inSearch)
- return;
-
- $('#restore-search-loader').show();
- inSearch = true;
-
- var stree = searchTrees[time];
- var tree = trees[time];
-
- var buildSearchTree = function(nodes) {
- var streeel = $('<div></div>');
- searchTrees[time] = streeel;
- $('#restore-files-tree').append(streeel);
-
- var te = streeel.jstree({
- 'plugins' : [ 'checkbox' ],
- 'core': { 'data' : nodes }
- });
-
- colorize(streeel, search);
- streeel.show();
- };
-
- if (searchdata[time]) {
- var t = searchdata[time];
- for(var p in t) {
- if (search.indexOf(p) == 0) {
- colorize(tree, search);
-
- if (t[p].Files.length == 0) {
- alert('No results matched the query');
- tree.show();
- } else if (stree) {
- colorize(stree, search);
- tree.hide();
- stree.show();
- } else {
- buildSearchTree(buildSearchNodes(time, t[p], search));
- tree.hide();
- }
- $('#restore-search-loader').hide();
- inSearch = false;
- return;
- }
- }
- }
-
- if (tree) {
- colorize(tree, search);
- tree.hide();
- }
- if (stree)
- colorize(stree, search);
-
-
- if (stree) {
- stree.remove();
- delete searchTrees[time];
- }
-
- $.ajax({
- 'url': APP_CONFIG.server_url,
- headers: {'X-XSRF-Token': APP_DATA.xsrf_token},
- 'data': {
- 'action': 'search-backup-files',
- 'id': backupId,
- 'time': time,
- 'prefix-only': 'false',
- 'filter': '*' + search + '*'
- },
- 'dataType': 'json'
- })
- .done(function(data, status, xhr) {
-
- if (!searchdata[time])
- searchdata[time] = {};
-
- if (!manualIncludes[time])
- manualIncludes[time] = [];
-
- searchdata[time][search] = data;
-
- $('#restore-search-loader').hide();
- inSearch = false;
-
- if (data.Files.length == 0) {
- alert('No results matched the query');
- tree.show();
- return;
- }
-
- buildSearchTree(buildSearchNodes(time, data));
-
- })
- .fail(function() {
- $('#restore-search-loader').hide();
- inSearch = false;
- alert('Search failed ...');
- tree.show();
- });
- };
-
- var createNodeFromData = function(path, prefix, time, rootnode) {
- var disp = path.substr(prefix.length);
- var isFolder = disp.lastIndexOf(dirSep) == disp.length - 1;
- var icon = null;
- var state = null;
- if (isFolder)
- disp = disp.substr(0, disp.length - 1);
- else
- icon = 'icon-file icon-file-' + disp.substr(disp.lastIndexOf('.')+1);
-
- if (rootnode) {
- disp = APP_DATA.getBackupName(backupId) || disp;
- //state = {opened: true};
- }
-
- return {
- text: disp,
- filepath: path,
- time: time,
- children: isFolder,
- state: state,
- icon: icon
- };
- };
-
- var loadNodes = function(node, callback, time) {
- $.ajax({
- 'url': APP_CONFIG.server_url,
- 'data': {
- 'action': 'search-backup-files',
- 'id': backupId,
- 'time': time,
- 'prefix-only': node.id === '#',
- 'folder-contents': node.id !== '#',
- 'filter': node.id === '#' ? '*' : node.original.filepath,
- 'Prefix': node.id === '#' ? '' : node.original.filepath
- },
- headers: {'X-XSRF-Token': APP_DATA.xsrf_token},
- 'dataType': 'json'
- })
- .done(function(data, status, xhr) {
- var nodes = [];
- data.Files = data.Files || [];
- for(var i = 0; i < data.Files.length; i++)
- nodes.push(createNodeFromData(data.Files[i].Path, data.Prefix, time, node.id === '#'));
-
- callback(nodes, data);
-
- if (node.id === '#')
- commonPrefix[time] = data.Files[0].Path;
- });
- };
-
- var setupTree = function(time) {
- var treeel = trees[time];
-
- if (!trees[time]) {
- var treeel = $('<div></div>');
- trees[time] = treeel;
- $('#restore-files-tree').append(treeel);
-
- treeel.jstree({
- 'core': {
- 'data': function(node, callback) {
- if (nodedata[node.id]) {
- callback(nodedata[node.id]);
- colorize(treeel, $('#restore-search').val());
- } else {
- loadNodes(node, function(nodes, data) {
- callback(nodes);
- if (data.Prefix == '')
- treeel.jstree("open_node", treeel.find('li').first());
- colorize(treeel, $('#restore-search').val());
- },
- time);
- }
- }
- },
- 'plugins' : [ 'checkbox' ]
- });
- }
-
- for(var t in trees)
- if (t != time)
- trees[t].hide();
- else {
- trees[t].show();
- }
- };
-
- var buildIncludeMap = function() {
- var time = $('#restore-version').val();
- var m = {};
- //strees = strees || trees;
- var strees = [ trees[time] ];
- var partialfolders = false;
- if (searchTrees[time] && searchTrees[time].is(':visible')) {
- partialfolders = true;
- strees = [ searchTrees[time] ];
- }
-
- for(var t in strees) {
- m[t] = {};
- var tr = strees[t].jstree();
-
- var roots = strees[t].children('ul').children('li');
- var follow = [];
-
- roots.each(function(i,e) {
- follow.push(tr.get_node(e));
- });
-
- while(follow.length > 0) {
- var n = follow.pop();
- if (n.state.selected && n.original.filepath) {
- // If we have partial folder matches,
- // we only include the leaves
- if (partialfolders) {
- if (!n.children || n.children.length == 0) {
- m[t][n.original.filepath] = 1;
- } else {
- // Non-leaf node, recurse it
- for(var c in n.children)
- follow.push(tr.get_node(n.children[c]));
- }
-
- } else {
- m[t][n.original.filepath] = 1;
- }
- } else {
- //TODO: This traverses the entire tree,
- // we could choose only those with indeterminate,
- // but that state only exists in the DOM which is
- // removed when collapsed
- for(var c in n.children)
- follow.push(tr.get_node(n.children[c]));
- }
- }
- }
-
- return m;
- };
-
- $('#restore-dialog').on('setup-dialog', function(e, data) {
- backupId = data.id;
- isDirectRestore = data.isDirectRestore;
- trees = { };
- searchdata = { };
- dbversions = { };
-
- $('#restore-files-tree').empty();
- $('#restore-search-loader').hide();
- $('#restore-form').each(function(i, e) { e.reset(); });
- $('#restore-overwrite-overwrite').each(function(i, e) { e.checked = true; });
- $('#restore-overwrite-target-original').each(function(i, e) { e.checked = true; });
- $('#restore-metadata-timestamps').each(function(i, e) { e.checked = true; });
-
- curpage = 0;
- updatePageNav();
-
- APP_DATA.getServerConfig(function(serverdata) {
-
- // TODO: Should be the backup data versions, not the host OS
- dirSep = serverdata.DirectorySeparator;
- pathSep = serverdata.PathSeparator;
-
- APP_DATA.callServer({ 'action': 'list-backup-sets', id: backupId, 'from-remote-only': isDirectRestore }, function(data, success, message) {
- $('#restore-version').empty();
-
- if (data == null || data.length == 0) {
- alert('Failed to get list of backup times');
- $('#restore-dialog').dialog('close');
- }
-
- for(var n in data)
- dbversions[data[n].Time] = isDirectRestore ? n : true;
- dbversions[data[0].Time] = true;
-
- var latest_group = $('<optgroup></optgroup>').attr('label', 'Newest - ' + $.timeago(data[0].Time));
- latest_group.append($("<option></option>").attr("value", data[0].Time).text($.toDisplayDateAndTime($.parseDate(data[0].Time))));
- $('#restore-version').append(latest_group);
-
- var dateStamp = function(a) { return a.getFullYear() * 10000 + a.getMonth() * 100 + a.getDate(); }
- var now = new Date();
- var today = dateStamp(now);
- var yesterday = dateStamp(new Date(new Date().setDate(now.getDate() - 1)));
- var week = dateStamp(new Date(new Date().setDate(now.getDate() - 7)));
- var thismonth = dateStamp(new Date(new Date().setMonth(now.getMonth() - 1)));
- var lastmonth = dateStamp(new Date(new Date().setMonth(now.getMonth() - 2)));
-
- var dateBuckets = [
- {text:'Today', stamp: today, items: []},
- {text: 'Yesterday', stamp: yesterday, items: []},
- {text: 'This week', stamp: week, items: []},
- {text: 'This month', stamp: thismonth, items: []},
- {text: 'Last month', stamp: lastmonth, items: []}
- ];
-
- var yearBuckets = { };
-
- for(var i in data) {
- if (i == '0')
- continue;
- var dt = $.parseDate(data[i].Time);
- var stamp = dateStamp(dt);
- var inserted = false;
-
- for(var t in dateBuckets) {
- if (stamp >= dateBuckets[t].stamp) {
- dateBuckets[t].items.push(data[i])
- inserted = true;
- break;
- }
- }
-
- if (!inserted) {
- var y = dt.getFullYear() + '';
- if (yearBuckets[y] == null) {
- yearBuckets[y] = {text: y, stamp: dateStamp(new Date(dt.getFullYear(), 0, 1)), items: []};
- dateBuckets.push(yearBuckets[y]);
- }
- yearBuckets[y].items.push(data[i]);
- }
- }
-
-
- for(var n in dateBuckets) {
- var e = dateBuckets[n];
- if (e.items.length == 0)
- continue;
-
- var group = $('<optgroup></optgroup>').attr('label', e.text);
- for(var d in e.items)
- group.append($("<option></option>").attr("value", e.items[d].Time).text($.toDisplayDateAndTime($.parseDate(e.items[d].Time))));
-
- $('#restore-version').append(group);
-
- }
-
- $('#restore-version').trigger('change');
-
- }, function(data, success, message) {
- alert('Failed to get list of backup times:\n' + message);
- $('#restore-dialog').dialog('close');
- });
- }, function() {
- alert('Failed to get server config');
- $('#restore-dialog').dialog('close');
- });
- });
-
- var doQuickSearch = function(search) {
- var search = $('#restore-search').val();
- var time = $('#restore-version').val();
- if (searchdata[time]) {
- for(var k in searchdata[time]) {
- if (search.indexOf(k) == 0) {
- colorize(trees[time], search);
- return true;
- }
- }
- }
-
- return false;
- };
-
- $('#restore-search').keypress(function(e) {
- var time = $('#restore-version').val();
- if (e.which == 13 && $('#restore-search').val().trim() != '')
- doSearch(time, $('#restore-search').val());
- else if ($('#restore-search').val().trim() != '') {
- colorize(trees[time], $('#restore-search').val());
- if (searchTrees[time])
- colorize(searchTrees[time], $('#restore-search').val());
-
- }
- });
-
- $('#restore-search').keyup(function(e) {
- var time = $('#restore-version').val();
- colorize(trees[time], $('#restore-search').val());
- if (searchTrees[time])
- colorize(searchTrees[time], $('#restore-search').val());
- });
-
- $('#restore-search').change(function(e) {
- var time = $('#restore-version').val();
- colorize(trees[time], $('#restore-search').val());
- if (searchTrees[time])
- colorize(searchTrees[time], $('#restore-search').val());
- });
-
- $('#restore-search').on('search', function(e) {
- var time = $('#restore-version').val();
- if ($('#restore-search').val() == '') {
- trees[time].show();
- if (searchTrees[time]) {
- searchTrees[time].remove();
- delete searchTrees[time];
- }
- colorize(trees[time], $('#restore-search').val());
- } else
- doSearch(time, $('#restore-search').val());
- });
-
- $('#restore-version').change(function() {
- $('#restore-search').val('');
-
- var selectedversion = $('#restore-version').val();
-
- if (dbversions[selectedversion] !== true) {
- // Need to patch the db with data
-
- var dlg = APP_UTIL.create_modal_task_wait('Updating database', 'Updating local database ... ', function(cancelled, taskid) {
- if (!cancelled) {
- dbversions[selectedversion] = true;
- setupTree(selectedversion);
- }
- });
-
- APP_DATA.callServer({ action: 'send-command', command: 'run-repair-update', 'only-paths': true, 'id': backupId, 'time': selectedversion }, function(data) {
- dlg.register_updates(data.ID);
- }, function(a,b,msg) {
- alert('Failed to connect: ' + msg);
- dlg.dialog('close');
- dlg.remove();
- });
- } else {
- setupTree(selectedversion);
- }
- });
-
- $('#restore-target-path').keypress(function() { $('#restore-overwrite-target-other').each(function(i,e) { e.checked = true; }); });
- $('#restore-target-path').change(function() { $('#restore-overwrite-target-other').each(function(i,e) { e.checked = true; }); });
-
- $('#restore-overwrite-target-other').click(function() { $('#restore-target-path-browse').trigger('click'); } );
-
- $('#restore-target-path-browse').click(function(e) {
- $.browseForFolder({
- title: 'Select restore folder',
- resolvePath: true,
- multiSelect: false,
- callback: function(path, display) {
- $('#restore-target-path').val(path);
- $('#restore-overwrite-target-other').each(function(i, e) { e.checked = true; });
- }
- });
- });
-
- $('#restore-direct-uri').watermark('webdavs://user:pass@example.com:995/backup?option=true');
- $('#restore-direct-encryption-password').watermark('Enter backup passphrase, if any');
- $('#restore-direct-advanced-options').watermark('Enter one option per line in command-line format, eg. --prefix=backup');
-
- $('#restore-direct-uri-label').click(function() {
- $('#connection-uri-dialog').dialog('open');
- $('#connection-uri-dialog').trigger('setup-dialog', $('#restore-direct-uri'));
- });
-
- $('#restore-direct-dialog').dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- { text: 'Cancel', click: function(event, ui) {
- $(this).dialog('close');
- }},
- { text: 'Connect', click: function(event, ui) {
- var uri = $('#restore-direct-uri').val();
- var passphrase = $('#restore-direct-encryption-password').val();
-
- if (uri == null || uri.trim().length == 1) {
- alert('You must supply a connection URI');
- return;
- }
-
- var options = {};
- if (passphrase != null && passphrase.trim().length > 0)
- options['--passphrase'] = passphrase;
- else
- options['--no-encryption'] = 'true';
-
- if (!EDIT_URI.parse_extra_options($('#restore-direct-advanced-options'), options))
- return;
-
- var settings = [];
- for(var k in options)
- settings.push({'Name': k, 'Value': options[k]});
-
- var item = {
- 'Schedule': null,
- 'Backup': {
- 'TargetURL': uri,
- 'Settings': settings
- }
- };
-
- var self = this;
- var backupid = null;
-
- var dlg = APP_UTIL.create_modal_task_wait('Creating database', 'Building local database ... ', function(cancelled, taskid) {
- if (!cancelled) {
- APP_DATA.restoreBackup(backupid, true);
- $(self).dialog('close');
- }
- });
-
- APP_DATA.testConnection(uri, function() {
- APP_DATA.addBackup(item, function(data) {
- backupid = data.ID;
-
- APP_DATA.callServer({ action: 'send-command', command: 'run-repair', 'only-paths': true, 'id': backupid, 'version': 0 }, function(data) {
- dlg.register_updates(data.ID);
-
- }, function(a,b,msg) {
- alert('Failed to connect: ' + msg);
- dlg.dialog('close');
- dlg.remove();
- });
- }, function(a,b,msg) {
- alert('Failed to create a backup set: ' + msg);
- dlg.dialog('close');
- dlg.remove();
- }, {'temporary': true});
- }, function(a,b,msg) {
- alert('Failed to connect: ' + msg);
- dlg.dialog('close');
- dlg.remove();
- });
-
- }}
- ]
- });
-
- $('#restore-direct-options-dialog').dialog({
- minWidth: 320,
- width: $('body').width > 600 ? 320 : 600,
- minHeight: 480,
- height: 500,
- modal: true,
- autoOpen: false,
- closeOnEscape: true,
- buttons: [
- { text: 'Close', disabled: false, click: function(event, ui) {
- $(this).dialog('close');
- }}
- ]
- });
-
- $('#restore-direct-options-link').click(function() {
- APP_DATA.getServerConfig(function(data) {
- $('#restore-direct-options-dialog').dialog('open');
-
- var baseOpts = data.Options;
-
- for(var n in data.BackendModules)
- baseOpts = baseOpts.concat(data.BackendModules[n].Options);
-
- for(var n in data.CompressionModules)
- baseOpts = baseOpts.concat(data.CompressionModules[n].Options);
-
- for(var n in data.EncryptionModules)
- baseOpts = baseOpts.concat(data.EncryptionModules[n].Options);
-
- for(var n in data.GenericModules)
- baseOpts = baseOpts.concat(data.GenericModules[n].Options);
-
-
- $('#restore-direct-options-dialog').trigger('configure', { Options: baseOpts, callback: function(id) {
- $('#restore-direct-options-dialog').dialog('close');
-
- var txt = $('#restore-direct-advanced-options').val().trim();
- if (txt.length > 0)
- txt += '\n';
-
- var defaultvalue = '';
- for(var o in data.Options)
- if (data.Options[o].Name == id) {
- defaultvalue = data.Options[o].DefaultValue;
- break;
- }
-
-
- txt += '--' + id + '=' + defaultvalue;
- $('#restore-direct-advanced-options').val('').val(txt);
- $('#restore-direct-advanced-options').focus();
-
- }});
- }, function() {
- });
- });
-
- $('#restore-direct-options-dialog').on('configure', function(e, data) {
- $('#restore-direct-options-dialog').empty();
-
- var s = data.Options.sort(function(a, b){
- if (a == null)
- return -1;
- if (b == null)
- return 1;
- if (a == null && b == null)
- return 0;
-
- if(a.Name < b.Name) return -1;
- if(a.Name > b.Name) return 1;
- return 0;
- });
-
- //Fill with jQuery template
- $.tmpl($('#backup-option-template'), s).prependTo($('#restore-direct-options-dialog'));
- $('#restore-direct-options-dialog').find('.backup-option-link').click(function(e) {
- data.callback(e.target.id);
- });
-
- $('#restore-direct-options-dialog').find('.backup-option-long').each(function(i, e) {
- $(e).html(nl2br($(e).html()));
- });
- });
-
-
-});
diff --git a/Duplicati/Server/webroot/greeno/scripts/zxcvbn.js b/Duplicati/Server/webroot/greeno/scripts/zxcvbn.js
deleted file mode 100644
index 12128b50c..000000000
--- a/Duplicati/Server/webroot/greeno/scripts/zxcvbn.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// This is the zxcvbn password strength estimator, from: https://github.com/dropbox/zxcvbn
-
-(function(){var w,o,r,x,J,K,L,M,N,O,P,Q,y,q,z,R,S,T,U,V,W;P=function(b){var a,d;d=[];for(a in b)d.push(a);return 0===d.length};y=function(b,a){return b.push.apply(b,a)};V=function(b,a){var d,c,e,f,g;f=b.split("");g=[];c=0;for(e=f.length;c<e;c++)d=f[c],g.push(a[d]||d);return g.join("")};R=function(b){var a,d,c,e;d=[];c=0;for(e=A.length;c<e;c++)a=A[c],y(d,a(b));return d.sort(function(b,a){return b.i-a.i||b.j-a.j})};N=function(b,a){var d,c,e,f,g,h,i,j,k;h=[];e=b.length;f=b.toLowerCase();for(d=j=0;0<=
-e?j<e:j>e;d=0<=e?++j:--j)for(c=k=d;d<=e?k<e:k>e;c=d<=e?++k:--k)if(f.slice(d,+c+1||9E9)in a)i=f.slice(d,+c+1||9E9),g=a[i],h.push({pattern:"dictionary",i:d,j:c,token:b.slice(d,+c+1||9E9),matched_word:i,rank:g});return h};r=function(b){var a,d,c,e,f;d={};a=1;e=0;for(f=b.length;e<f;e++)c=b[e],d[c]=a,a+=1;return d};o=function(b,a){return function(d){var c,e,f;c=N(d,a);e=0;for(f=c.length;e<f;e++)d=c[e],d.dictionary_name=b;return c}};z={a:["4","@"],b:["8"],c:["(","{","[","<"],e:["3"],g:["6","9"],i:["1",
-"!","|"],l:["1","|","7"],o:["0"],s:["$","5"],t:["+","7"],x:["%"],z:["2"]};S=function(b){var a,d,c,e,f;d={};f=b.split("");c=0;for(e=f.length;c<e;c++)b=f[c],d[b]=!0;b={};for(a in z){e=z[a];var g=f=void 0,h=void 0,h=[];f=0;for(g=e.length;f<g;f++)c=e[f],c in d&&h.push(c);c=h;0<c.length&&(b[a]=c)}return b};Q=function(b){var a,d,c,e,f,g,h,i,j,k,l,m,p;f=function(){var a;a=[];for(e in b)a.push(e);return a}();j=[[]];d=function(a){var b,c,d,f,g,i,h,j;c=[];f={};h=0;for(j=a.length;h<j;h++)g=a[h],b=function(){var b,
-a,c;c=[];i=b=0;for(a=g.length;b<a;i=++b)e=g[i],c.push([e,i]);return c}(),b.sort(),d=function(){var a,c,d;d=[];i=a=0;for(c=b.length;a<c;i=++a)e=b[i],d.push(e+","+i);return d}().join("-"),d in f||(f[d]=!0,c.push(g));return c};c=function(a){var f,e,g,i,h,k,l,p,m,n,o,r,q;if(a.length){e=a[0];h=a.slice(1);i=[];r=b[e];l=0;for(n=r.length;l<n;l++){a=r[l];p=0;for(o=j.length;p<o;p++){k=j[p];f=-1;g=m=0;for(q=k.length;0<=q?m<q:m>q;g=0<=q?++m:--m)if(k[g][0]===a){f=g;break}-1===f?(f=k.concat([[a,e]]),i.push(f)):
-(g=k.slice(0),g.splice(f,1),g.push([a,e]),i.push(k),i.push(g))}}j=d(i);return c(h)}};c(f);i=[];k=0;for(m=j.length;k<m;k++){g=j[k];h={};l=0;for(p=g.length;l<p;l++)a=g[l],f=a[0],a=a[1],h[f]=a;i.push(h)}return i};U=function(b,a,d){var c,e,f,g,h,i,j,k,l,m,p,s,n;l=[];for(i=0;i<b.length-1;){j=i+1;k=null;for(m=p=0;;){c=b.charAt(j-1);h=!1;g=-1;e=a[c]||[];if(j<b.length){f=b.charAt(j);s=0;for(n=e.length;s<n;s++)if(c=e[s],g+=1,c&&-1!==c.indexOf(f)){h=!0;1===c.indexOf(f)&&(m+=1);k!==g&&(p+=1,k=g);break}}if(h)j+=
-1;else{2<j-i&&l.push({pattern:"spatial",i:i,j:j-1,token:b.slice(i,j),graph:d,turns:p,shifted_count:m});i=j;break}}}return l};w={lower:"abcdefghijklmnopqrstuvwxyz",upper:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",digits:"01234567890"};T=function(b,a){var d,c;c=[];for(d=1;1<=a?d<=a:d>=a;1<=a?++d:--d)c.push(b);return c.join("")};q=function(b,a){var d,c;for(c=[];;){d=b.match(a);if(!d)break;d.i=d.index;d.j=d.index+d[0].length-1;c.push(d);b=b.replace(d[0],T(" ",d[0].length))}return c};O=/\d{3,}/;W=/19\d\d|200\d|201\d/;
-M=function(b){var a,d,c,e,f,g,h,i,j,k,l,m,p,s;e=[];s=q(b,/\d{4,8}/);k=0;for(m=s.length;k<m;k++){g=s[k];h=[g.i,g.j];g=h[0];h=h[1];c=b.slice(g,+h+1||9E9);a=c.length;d=[];6>=c.length&&(d.push({daymonth:c.slice(2),year:c.slice(0,2),i:g,j:h}),d.push({daymonth:c.slice(0,a-2),year:c.slice(a-2),i:g,j:h}));6<=c.length&&(d.push({daymonth:c.slice(4),year:c.slice(0,4),i:g,j:h}),d.push({daymonth:c.slice(0,a-4),year:c.slice(a-4),i:g,j:h}));c=[];l=0;for(p=d.length;l<p;l++)switch(a=d[l],a.daymonth.length){case 2:c.push({day:a.daymonth[0],
-month:a.daymonth[1],year:a.year,i:a.i,j:a.j});break;case 3:c.push({day:a.daymonth.slice(0,2),month:a.daymonth[2],year:a.year,i:a.i,j:a.j});c.push({day:a.daymonth[0],month:a.daymonth.slice(1,3),year:a.year,i:a.i,j:a.j});break;case 4:c.push({day:a.daymonth.slice(0,2),month:a.daymonth.slice(2,4),year:a.year,i:a.i,j:a.j})}l=0;for(p=c.length;l<p;l++)a=c[l],f=parseInt(a.day),i=parseInt(a.month),j=parseInt(a.year),f=x(f,i,j),d=f[0],j=f[1],f=j[0],i=j[1],j=j[2],d&&e.push({pattern:"date",i:a.i,j:a.j,token:b.slice(g,
-+h+1||9E9),separator:"",day:f,month:i,year:j})}return e};K=/(\d{1,2})(\s|-|\/|\\|_|\.)(\d{1,2})\2(19\d{2}|200\d|201\d|\d{2})/;J=/(19\d{2}|200\d|201\d|\d{2})(\s|-|\/|\\|_|\.)(\d{1,2})\2(\d{1,2})/;L=function(b){var a,d,c,e,f,g,h,i,j,k;e=[];j=q(b,K);g=0;for(i=j.length;g<i;g++)c=j[g],k=function(){var a,b,f,e;f=[1,3,4];e=[];a=0;for(b=f.length;a<b;a++)d=f[a],e.push(parseInt(c[d]));return e}(),c.day=k[0],c.month=k[1],c.year=k[2],c.sep=c[2],e.push(c);j=q(b,J);g=0;for(i=j.length;g<i;g++)c=j[g],k=function(){var a,
-b,f,e;f=[4,3,1];e=[];a=0;for(b=f.length;a<b;a++)d=f[a],e.push(parseInt(c[d]));return e}(),c.day=k[0],c.month=k[1],c.year=k[2],c.sep=c[2],e.push(c);k=[];i=0;for(j=e.length;i<j;i++)c=e[i],a=x(c.day,c.month,c.year),g=a[0],h=a[1],a=h[0],f=h[1],h=h[2],g&&k.push({pattern:"date",i:c.i,j:c.j,token:b.slice(c.i,+c.j+1||9E9),separator:c.sep,day:a,month:f,year:h});return k};x=function(b,a,d){12<=a&&31>=a&&12>=b&&(a=[a,b],b=a[0],a=a[1]);return 31<b||12<a||!(1900<=d&&2019>=d)?[!1,[]]:[!0,[b,a,d]]};var X,Y,Z,$,
-C,aa,ba,ca,da,ea,fa,ga,ha,ia,n,ja,t,ka,D,la,ma,na;t=function(b,a){var d,c,e;if(a>b)return 0;if(0===a)return 1;for(d=e=c=1;1<=a?e<=a:e>=a;d=1<=a?++e:--e)c*=b,c/=d,b-=1;return c};n=function(b){return Math.log(b)/Math.log(2)};ja=function(b,a){var d,c,e,f,g,h,i,j,k,l,m;c=C(b);k=[];d=[];f=i=0;for(m=b.length;0<=m?i<m:i>m;f=0<=m?++i:--i){k[f]=(k[f-1]||0)+n(c);d[f]=null;j=0;for(l=a.length;j<l;j++)h=a[j],h.j===f&&(g=[h.i,h.j],e=g[0],g=g[1],e=(k[e-1]||0)+aa(h),e<k[g]&&(k[g]=e,d[g]=h))}i=[];for(f=b.length-1;0<=
-f;)(h=d[f])?(i.push(h),f=h.i-1):f-=1;i.reverse();d=function(a,d){return{pattern:"bruteforce",i:a,j:d,token:b.slice(a,+d+1||9E9),entropy:n(Math.pow(c,d-a+1)),cardinality:c}};f=0;j=[];l=0;for(m=i.length;l<m;l++)h=i[l],g=[h.i,h.j],e=g[0],g=g[1],0<e-f&&j.push(d(f,e-1)),f=g+1,j.push(h);f<b.length&&j.push(d(f,b.length-1));i=j;h=k[b.length-1]||0;f=ga(h);return{password:b,entropy:D(h,3),match_sequence:i,crack_time:D(f,3),crack_time_display:fa(f),score:ba(f)}};D=function(b,a){return Math.round(b*Math.pow(10,
-a))/Math.pow(10,a)};ga=function(b){return 5.0E-5*Math.pow(2,b)};ba=function(b){return b<Math.pow(10,2)?0:b<Math.pow(10,4)?1:b<Math.pow(10,6)?2:b<Math.pow(10,8)?3:4};aa=function(b){var a;if(null!=b.entropy)return b.entropy;a=function(){switch(b.pattern){case "repeat":return ka;case "sequence":return la;case "digits":return ea;case "year":return na;case "date":return ca;case "spatial":return ma;case "dictionary":return da}}();return b.entropy=a(b)};ka=function(b){var a;a=C(b.token);return n(a*b.token.length)};
-la=function(b){var a;a=b.token.charAt(0);a="a"===a||"1"===a?1:a.match(/\d/)?n(10):a.match(/[a-z]/)?n(26):n(26)+1;b.ascending||(a+=1);return a+n(b.token.length)};ea=function(b){return n(Math.pow(10,b.token.length))};na=function(){return n(119)};ca=function(b){var a;a=100>b.year?n(37200):n(44268);b.separator&&(a+=2);return a};ma=function(b){var a,d,c,e,f,g,h,i,j,k;"qwerty"===(c=b.graph)||"dvorak"===c?(h=oa,d=pa):(h=qa,d=ra);f=0;a=b.token.length;i=b.turns;for(c=j=2;2<=a?j<=a:j>=a;c=2<=a?++j:--j){g=Math.min(i,
-c-1);for(e=k=1;1<=g?k<=g:k>=g;e=1<=g?++k:--k)f+=t(c-1,e-1)*h*Math.pow(d,e)}d=n(f);if(b.shifted_count){a=b.shifted_count;b=b.token.length-b.shifted_count;c=e=f=0;for(g=Math.min(a,b);0<=g?e<=g:e>=g;c=0<=g?++e:--e)f+=t(a+b,c);d+=n(f)}return d};da=function(b){b.base_entropy=n(b.rank);b.uppercase_entropy=ia(b);b.l33t_entropy=ha(b);return b.base_entropy+b.uppercase_entropy+b.l33t_entropy};$=/^[A-Z][^A-Z]+$/;Z=/^[^A-Z]+[A-Z]$/;Y=/^[^a-z]+$/;X=/^[^A-Z]+$/;ia=function(b){var a,d,c,e,f,g,h;f=b.token;if(f.match(X))return 0;
-e=[$,Z,Y];a=0;for(c=e.length;a<c;a++)if(b=e[a],f.match(b))return 1;a=function(){var a,b,c,e;c=f.split("");e=[];a=0;for(b=c.length;a<b;a++)d=c[a],d.match(/[A-Z]/)&&e.push(d);return e}().length;b=function(){var a,b,c,e;c=f.split("");e=[];a=0;for(b=c.length;a<b;a++)d=c[a],d.match(/[a-z]/)&&e.push(d);return e}().length;c=g=e=0;for(h=Math.min(a,b);0<=h?g<=h:g>=h;c=0<=h?++g:--g)e+=t(a+b,c);return n(e)};ha=function(b){var a,d,c,e,f,g,h,i,j,k;if(!b.l33t)return 0;f=0;j=b.sub;for(g in j){h=j[g];a=function(){var a,
-d,e,f;e=b.token.split("");f=[];a=0;for(d=e.length;a<d;a++)c=e[a],c===g&&f.push(c);return f}().length;d=function(){var a,d,e,f;e=b.token.split("");f=[];a=0;for(d=e.length;a<d;a++)c=e[a],c===h&&f.push(c);return f}().length;e=i=0;for(k=Math.min(d,a);0<=k?i<=k:i>=k;e=0<=k?++i:--i)f+=t(d+a,e)}return n(f)||1};C=function(b){var a,d,c,e,f,g,h,i;f=[!1,!1,!1,!1,!1];c=f[0];g=f[1];d=f[2];e=f[3];f=f[4];i=b.split("");b=0;for(h=i.length;b<h;b++)a=i[b],a=a.charCodeAt(0),48<=a&&57>=a?d=!0:65<=a&&90>=a?g=!0:97<=a&&
-122>=a?c=!0:127>=a?e=!0:f=!0;b=0;d&&(b+=10);g&&(b+=26);c&&(b+=26);e&&(b+=33);f&&(b+=100);return b};fa=function(b){return 60>b?"instant":3600>b?""+(1+Math.ceil(b/60))+" minutes":86400>b?""+(1+Math.ceil(b/3600))+" hours":2678400>b?""+(1+Math.ceil(b/86400))+" days":32140800>b?""+(1+Math.ceil(b/2678400))+" months":321408E4>b?""+(1+Math.ceil(b/32140800))+" years":"centuries"};var E={"!":["`~",null,null,"2@","qQ",null],'"':[";:","[{","]}",null,null,"/?"],"#":["2@",null,null,"4$","eE","wW"],$:["3#",null,
-null,"5%","rR","eE"],"%":["4$",null,null,"6^","tT","rR"],"&":["6^",null,null,"8*","uU","yY"],"'":[";:","[{","]}",null,null,"/?"],"(":["8*",null,null,"0)","oO","iI"],")":["9(",null,null,"-_","pP","oO"],"*":["7&",null,null,"9(","iI","uU"],"+":["-_",null,null,null,"]}","[{"],",":["mM","kK","lL",".>",null,null],"-":["0)",null,null,"=+","[{","pP"],".":[",<","lL",";:","/?",null,null],"/":[".>",";:","'\"",null,null,null],"0":["9(",null,null,"-_","pP","oO"],1:["`~",null,null,"2@","qQ",null],2:["1!",null,
-null,"3#","wW","qQ"],3:["2@",null,null,"4$","eE","wW"],4:["3#",null,null,"5%","rR","eE"],5:["4$",null,null,"6^","tT","rR"],6:["5%",null,null,"7&","yY","tT"],7:["6^",null,null,"8*","uU","yY"],8:["7&",null,null,"9(","iI","uU"],9:["8*",null,null,"0)","oO","iI"],":":"lL,pP,[{,'\",/?,.>".split(","),";":"lL,pP,[{,'\",/?,.>".split(","),"<":["mM","kK","lL",".>",null,null],"=":["-_",null,null,null,"]}","[{"],">":[",<","lL",";:","/?",null,null],"?":[".>",";:","'\"",null,null,null],"@":["1!",null,null,"3#",
-"wW","qQ"],A:[null,"qQ","wW","sS","zZ",null],B:["vV","gG","hH","nN",null,null],C:["xX","dD","fF","vV",null,null],D:"sS,eE,rR,fF,cC,xX".split(","),E:"wW,3#,4$,rR,dD,sS".split(","),F:"dD,rR,tT,gG,vV,cC".split(","),G:"fF,tT,yY,hH,bB,vV".split(","),H:"gG,yY,uU,jJ,nN,bB".split(","),I:"uU,8*,9(,oO,kK,jJ".split(","),J:"hH,uU,iI,kK,mM,nN".split(","),K:"jJ iI oO lL ,< mM".split(" "),L:"kK oO pP ;: .> ,<".split(" "),M:["nN","jJ","kK",",<",null,null],N:["bB","hH","jJ","mM",null,null],O:"iI,9(,0),pP,lL,kK".split(","),
-P:"oO,0),-_,[{,;:,lL".split(","),Q:[null,"1!","2@","wW","aA",null],R:"eE,4$,5%,tT,fF,dD".split(","),S:"aA,wW,eE,dD,xX,zZ".split(","),T:"rR,5%,6^,yY,gG,fF".split(","),U:"yY,7&,8*,iI,jJ,hH".split(","),V:["cC","fF","gG","bB",null,null],W:"qQ,2@,3#,eE,sS,aA".split(","),X:["zZ","sS","dD","cC",null,null],Y:"tT,6^,7&,uU,hH,gG".split(","),Z:[null,"aA","sS","xX",null,null],"[":"pP,-_,=+,]},'\",;:".split(","),"\\":["]}",null,null,null,null,null],"]":["[{","=+",null,"\\|",null,"'\""],"^":["5%",null,null,"7&",
-"yY","tT"],_:["0)",null,null,"=+","[{","pP"],"`":[null,null,null,"1!",null,null],a:[null,"qQ","wW","sS","zZ",null],b:["vV","gG","hH","nN",null,null],c:["xX","dD","fF","vV",null,null],d:"sS,eE,rR,fF,cC,xX".split(","),e:"wW,3#,4$,rR,dD,sS".split(","),f:"dD,rR,tT,gG,vV,cC".split(","),g:"fF,tT,yY,hH,bB,vV".split(","),h:"gG,yY,uU,jJ,nN,bB".split(","),i:"uU,8*,9(,oO,kK,jJ".split(","),j:"hH,uU,iI,kK,mM,nN".split(","),k:"jJ iI oO lL ,< mM".split(" "),l:"kK oO pP ;: .> ,<".split(" "),m:["nN","jJ","kK",",<",
-null,null],n:["bB","hH","jJ","mM",null,null],o:"iI,9(,0),pP,lL,kK".split(","),p:"oO,0),-_,[{,;:,lL".split(","),q:[null,"1!","2@","wW","aA",null],r:"eE,4$,5%,tT,fF,dD".split(","),s:"aA,wW,eE,dD,xX,zZ".split(","),t:"rR,5%,6^,yY,gG,fF".split(","),u:"yY,7&,8*,iI,jJ,hH".split(","),v:["cC","fF","gG","bB",null,null],w:"qQ,2@,3#,eE,sS,aA".split(","),x:["zZ","sS","dD","cC",null,null],y:"tT,6^,7&,uU,hH,gG".split(","),z:[null,"aA","sS","xX",null,null],"{":"pP,-_,=+,]},'\",;:".split(","),"|":["]}",null,null,
-null,null,null],"}":["[{","=+",null,"\\|",null,"'\""],"~":[null,null,null,"1!",null,null]},F={"*":["/",null,null,null,"-","+","9","8"],"+":["9","*","-",null,null,null,null,"6"],"-":["*",null,null,null,null,null,"+","9"],".":["0","2","3",null,null,null,null,null],"/":[null,null,null,null,"*","9","8","7"],"0":[null,"1","2","3",".",null,null,null],1:[null,null,"4","5","2","0",null,null],2:["1","4","5","6","3",".","0",null],3:["2","5","6",null,null,null,".","0"],4:[null,null,"7","8","5","2","1",null],
-5:"4,7,8,9,6,3,2,1".split(","),6:["5","8","9","+",null,null,"3","2"],7:[null,null,null,"/","8","5","4",null],8:["7",null,"/","*","9","6","5","4"],9:["8","/","*","-","+",null,"6","5"]},u,G,pa,oa,ra,qa,A,v,H,I;H={};u=[o("passwords",r("password,123456,12345678,1234,qwerty,12345,dragon,pussy,baseball,football,letmein,monkey,696969,abc123,mustang,shadow,master,111111,2000,jordan,superman,harley,1234567,fuckme,hunter,fuckyou,trustno1,ranger,buster,tigger,soccer,fuck,batman,test,pass,killer,hockey,charlie,love,sunshine,asshole,6969,pepper,access,123456789,654321,maggie,starwars,silver,dallas,yankees,123123,666666,hello,orange,biteme,freedom,computer,sexy,thunder,ginger,hammer,summer,corvette,fucker,austin,1111,merlin,121212,golfer,cheese,princess,chelsea,diamond,yellow,bigdog,secret,asdfgh,sparky,cowboy,camaro,matrix,falcon,iloveyou,guitar,purple,scooter,phoenix,aaaaaa,tigers,porsche,mickey,maverick,cookie,nascar,peanut,131313,money,horny,samantha,panties,steelers,snoopy,boomer,whatever,iceman,smokey,gateway,dakota,cowboys,eagles,chicken,dick,black,zxcvbn,ferrari,knight,hardcore,compaq,coffee,booboo,bitch,bulldog,xxxxxx,welcome,player,ncc1701,wizard,scooby,junior,internet,bigdick,brandy,tennis,blowjob,banana,monster,spider,lakers,rabbit,enter,mercedes,fender,yamaha,diablo,boston,tiger,marine,chicago,rangers,gandalf,winter,bigtits,barney,raiders,porn,badboy,blowme,spanky,bigdaddy,chester,london,midnight,blue,fishing,000000,hannah,slayer,11111111,sexsex,redsox,thx1138,asdf,marlboro,panther,zxcvbnm,arsenal,qazwsx,mother,7777777,jasper,winner,golden,butthead,viking,iwantu,angels,prince,cameron,girls,madison,hooters,startrek,captain,maddog,jasmine,butter,booger,golf,rocket,theman,liverpoo,flower,forever,muffin,turtle,sophie,redskins,toyota,sierra,winston,giants,packers,newyork,casper,bubba,112233,lovers,mountain,united,driver,helpme,fucking,pookie,lucky,maxwell,8675309,bear,suckit,gators,5150,222222,shithead,fuckoff,jaguar,hotdog,tits,gemini,lover,xxxxxxxx,777777,canada,florida,88888888,rosebud,metallic,doctor,trouble,success,stupid,tomcat,warrior,peaches,apples,fish,qwertyui,magic,buddy,dolphins,rainbow,gunner,987654,freddy,alexis,braves,cock,2112,1212,cocacola,xavier,dolphin,testing,bond007,member,voodoo,7777,samson,apollo,fire,tester,beavis,voyager,porno,rush2112,beer,apple,scorpio,skippy,sydney,red123,power,beaver,star,jackass,flyers,boobs,232323,zzzzzz,scorpion,doggie,legend,ou812,yankee,blazer,runner,birdie,bitches,555555,topgun,asdfasdf,heaven,viper,animal,2222,bigboy,4444,private,godzilla,lifehack,phantom,rock,august,sammy,cool,platinum,jake,bronco,heka6w2,copper,cumshot,garfield,willow,cunt,slut,69696969,kitten,super,jordan23,eagle1,shelby,america,11111,free,123321,chevy,bullshit,broncos,horney,surfer,nissan,999999,saturn,airborne,elephant,shit,action,adidas,qwert,1313,explorer,police,christin,december,wolf,sweet,therock,online,dickhead,brooklyn,cricket,racing,penis,0000,teens,redwings,dreams,michigan,hentai,magnum,87654321,donkey,trinity,digital,333333,cartman,guinness,123abc,speedy,buffalo,kitty,pimpin,eagle,einstein,nirvana,vampire,xxxx,playboy,pumpkin,snowball,test123,sucker,mexico,beatles,fantasy,celtic,cherry,cassie,888888,sniper,genesis,hotrod,reddog,alexande,college,jester,passw0rd,bigcock,lasvegas,slipknot,3333,death,1q2w3e,eclipse,1q2w3e4r,drummer,montana,music,aaaa,carolina,colorado,creative,hello1,goober,friday,bollocks,scotty,abcdef,bubbles,hawaii,fluffy,horses,thumper,5555,pussies,darkness,asdfghjk,boobies,buddha,sandman,naughty,honda,azerty,6666,shorty,money1,beach,loveme,4321,simple,poohbear,444444,badass,destiny,vikings,lizard,assman,nintendo,123qwe,november,xxxxx,october,leather,bastard,101010,extreme,password1,pussy1,lacrosse,hotmail,spooky,amateur,alaska,badger,paradise,maryjane,poop,mozart,video,vagina,spitfire,cherokee,cougar,420420,horse,enigma,raider,brazil,blonde,55555,dude,drowssap,lovely,1qaz2wsx,booty,snickers,nipples,diesel,rocks,eminem,westside,suzuki,passion,hummer,ladies,alpha,suckme,147147,pirate,semperfi,jupiter,redrum,freeuser,wanker,stinky,ducati,paris,babygirl,windows,spirit,pantera,monday,patches,brutus,smooth,penguin,marley,forest,cream,212121,flash,maximus,nipple,vision,pokemon,champion,fireman,indian,softball,picard,system,cobra,enjoy,lucky1,boogie,marines,security,dirty,admin,wildcats,pimp,dancer,hardon,fucked,abcd1234,abcdefg,ironman,wolverin,freepass,bigred,squirt,justice,hobbes,pearljam,mercury,domino,9999,rascal,hitman,mistress,bbbbbb,peekaboo,naked,budlight,electric,sluts,stargate,saints,bondage,bigman,zombie,swimming,duke,qwerty1,babes,scotland,disney,rooster,mookie,swordfis,hunting,blink182,8888,samsung,bubba1,whore,general,passport,aaaaaaaa,erotic,liberty,arizona,abcd,newport,skipper,rolltide,balls,happy1,galore,christ,weasel,242424,wombat,digger,classic,bulldogs,poopoo,accord,popcorn,turkey,bunny,mouse,007007,titanic,liverpool,dreamer,everton,chevelle,psycho,nemesis,pontiac,connor,eatme,lickme,cumming,ireland,spiderma,patriots,goblue,devils,empire,asdfg,cardinal,shaggy,froggy,qwer,kawasaki,kodiak,phpbb,54321,chopper,hooker,whynot,lesbian,snake,teen,ncc1701d,qqqqqq,airplane,britney,avalon,sugar,sublime,wildcat,raven,scarface,elizabet,123654,trucks,wolfpack,pervert,redhead,american,bambam,woody,shaved,snowman,tiger1,chicks,raptor,1969,stingray,shooter,france,stars,madmax,sports,789456,simpsons,lights,chronic,hahaha,packard,hendrix,service,spring,srinivas,spike,252525,bigmac,suck,single,popeye,tattoo,texas,bullet,taurus,sailor,wolves,panthers,japan,strike,pussycat,chris1,loverboy,berlin,sticky,tarheels,russia,wolfgang,testtest,mature,catch22,juice,michael1,nigger,159753,alpha1,trooper,hawkeye,freaky,dodgers,pakistan,machine,pyramid,vegeta,katana,moose,tinker,coyote,infinity,pepsi,letmein1,bang,hercules,james1,tickle,outlaw,browns,billybob,pickle,test1,sucks,pavilion,changeme,caesar,prelude,darkside,bowling,wutang,sunset,alabama,danger,zeppelin,pppppp,2001,ping,darkstar,madonna,qwe123,bigone,casino,charlie1,mmmmmm,integra,wrangler,apache,tweety,qwerty12,bobafett,transam,2323,seattle,ssssss,openup,pandora,pussys,trucker,indigo,storm,malibu,weed,review,babydoll,doggy,dilbert,pegasus,joker,catfish,flipper,fuckit,detroit,cheyenne,bruins,smoke,marino,fetish,xfiles,stinger,pizza,babe,stealth,manutd,gundam,cessna,longhorn,presario,mnbvcxz,wicked,mustang1,victory,21122112,awesome,athena,q1w2e3r4,holiday,knicks,redneck,12341234,gizmo,scully,dragon1,devildog,triumph,bluebird,shotgun,peewee,angel1,metallica,madman,impala,lennon,omega,access14,enterpri,search,smitty,blizzard,unicorn,tight,asdf1234,trigger,truck,beauty,thailand,1234567890,cadillac,castle,bobcat,buddy1,sunny,stones,asian,butt,loveyou,hellfire,hotsex,indiana,panzer,lonewolf,trumpet,colors,blaster,12121212,fireball,precious,jungle,atlanta,gold,corona,polaris,timber,theone,baller,chipper,skyline,dragons,dogs,licker,engineer,kong,pencil,basketba,hornet,barbie,wetpussy,indians,redman,foobar,travel,morpheus,target,141414,hotstuff,photos,rocky1,fuck_inside,dollar,turbo,design,hottie,202020,blondes,4128,lestat,avatar,goforit,random,abgrtyu,jjjjjj,cancer,q1w2e3,smiley,express,virgin,zipper,wrinkle1,babylon,consumer,monkey1,serenity,samurai,99999999,bigboobs,skeeter,joejoe,master1,aaaaa,chocolat,christia,stephani,tang,1234qwer,98765432,sexual,maxima,77777777,buckeye,highland,seminole,reaper,bassman,nugget,lucifer,airforce,nasty,warlock,2121,dodge,chrissy,burger,snatch,pink,gang,maddie,huskers,piglet,photo,dodger,paladin,chubby,buckeyes,hamlet,abcdefgh,bigfoot,sunday,manson,goldfish,garden,deftones,icecream,blondie,spartan,charger,stormy,juventus,galaxy,escort,zxcvb,planet,blues,david1,ncc1701e,1966,51505150,cavalier,gambit,ripper,oicu812,nylons,aardvark,whiskey,bing,plastic,anal,babylon5,loser,racecar,insane,yankees1,mememe,hansolo,chiefs,fredfred,freak,frog,salmon,concrete,zxcv,shamrock,atlantis,wordpass,rommel,1010,predator,massive,cats,sammy1,mister,stud,marathon,rubber,ding,trunks,desire,montreal,justme,faster,irish,1999,jessica1,alpine,diamonds,00000,swinger,shan,stallion,pitbull,letmein2,ming,shadow1,clitoris,fuckers,jackoff,bluesky,sundance,renegade,hollywoo,151515,wolfman,soldier,ling,goddess,manager,sweety,titans,fang,ficken,niners,bubble,hello123,ibanez,sweetpea,stocking,323232,tornado,content,aragorn,trojan,christop,rockstar,geronimo,pascal,crimson,google,fatcat,lovelove,cunts,stimpy,finger,wheels,viper1,latin,greenday,987654321,creampie,hiphop,snapper,funtime,duck,trombone,adult,cookies,mulder,westham,latino,jeep,ravens,drizzt,madness,energy,kinky,314159,slick,rocker,55555555,mongoose,speed,dddddd,catdog,cheng,ghost,gogogo,tottenha,curious,butterfl,mission,january,shark,techno,lancer,lalala,chichi,orion,trixie,delta,bobbob,bomber,kang,1968,spunky,liquid,beagle,granny,network,kkkkkk,1973,biggie,beetle,teacher,toronto,anakin,genius,cocks,dang,karate,snakes,bangkok,fuckyou2,pacific,daytona,infantry,skywalke,sailing,raistlin,vanhalen,huang,blackie,tarzan,strider,sherlock,gong,dietcoke,ultimate,shai,sprite,ting,artist,chai,chao,devil,python,ninja,ytrewq,superfly,456789,tian,jing,jesus1,freedom1,drpepper,chou,hobbit,shen,nolimit,mylove,biscuit,yahoo,shasta,sex4me,smoker,pebbles,pics,philly,tong,tintin,lesbians,cactus,frank1,tttttt,chun,danni,emerald,showme,pirates,lian,dogg,xiao,xian,tazman,tanker,toshiba,gotcha,rang,keng,jazz,bigguy,yuan,tomtom,chaos,fossil,racerx,creamy,bobo,musicman,warcraft,blade,shuang,shun,lick,jian,microsoft,rong,feng,getsome,quality,1977,beng,wwwwww,yoyoyo,zhang,seng,harder,qazxsw,qian,cong,chuan,deng,nang,boeing,keeper,western,1963,subaru,sheng,thuglife,teng,jiong,miao,mang,maniac,pussie,a1b2c3,zhou,zhuang,xing,stonecol,spyder,liang,jiang,memphis,ceng,magic1,logitech,chuang,sesame,shao,poison,titty,kuan,kuai,mian,guan,hamster,guai,ferret,geng,duan,pang,maiden,quan,velvet,nong,neng,nookie,buttons,bian,bingo,biao,zhong,zeng,zhun,ying,zong,xuan,zang,0.0.000,suan,shei,shui,sharks,shang,shua,peng,pian,piao,liao,meng,miami,reng,guang,cang,ruan,diao,luan,qing,chui,chuo,cuan,nuan,ning,heng,huan,kansas,muscle,weng,1passwor,bluemoon,zhui,zhua,xiang,zheng,zhen,zhei,zhao,zhan,yomama,zhai,zhuo,zuan,tarheel,shou,shuo,tiao,leng,kuang,jiao,13579,basket,qiao,qiong,qiang,chuai,nian,niao,niang,huai,22222222,zhuan,zhuai,shuan,shuai,stardust,jumper,66666666,charlott,qwertz,bones,waterloo,2002,11223344,oldman,trains,vertigo,246810,black1,swallow,smiles,standard,alexandr,parrot,user,1976,surfing,pioneer,apple1,asdasd,auburn,hannibal,frontier,panama,welcome1,vette,blue22,shemale,111222,baggins,groovy,global,181818,1979,blades,spanking,byteme,lobster,dawg,japanese,1970,1964,2424,polo,coco,deedee,mikey,1972,171717,1701,strip,jersey,green1,capital,putter,vader,seven7,banshee,grendel,dicks,hidden,iloveu,1980,ledzep,147258,female,bugger,buffett,molson,2020,wookie,sprint,jericho,102030,ranger1,trebor,deepthroat,bonehead,molly1,mirage,models,1984,2468,showtime,squirrel,pentium,anime,gator,powder,twister,connect,neptune,engine,eatshit,mustangs,woody1,shogun,septembe,pooh,jimbo,russian,sabine,voyeur,2525,363636,camel,germany,giant,qqqq,nudist,bone,sleepy,tequila,fighter,obiwan,makaveli,vacation,walnut,1974,ladybug,cantona,ccbill,satan,rusty1,passwor1,columbia,kissme,motorola,william1,1967,zzzz,skater,smut,matthew1,valley,coolio,dagger,boner,bull,horndog,jason1,penguins,rescue,griffey,8j4ye3uz,californ,champs,qwertyuiop,portland,colt45,xxxxxxx,xanadu,tacoma,carpet,gggggg,safety,palace,italia,picturs,picasso,thongs,tempest,asd123,hairy,foxtrot,nimrod,hotboy,343434,1111111,asdfghjkl,goose,overlord,stranger,454545,shaolin,sooners,socrates,spiderman,peanuts,13131313,andrew1,filthy,ohyeah,africa,intrepid,pickles,assass,fright,potato,hhhhhh,kingdom,weezer,424242,pepsi1,throat,looker,puppy,butch,sweets,megadeth,analsex,nymets,ddddddd,bigballs,oakland,oooooo,qweasd,chucky,carrot,chargers,discover,dookie,condor,horny1,sunrise,sinner,jojo,megapass,martini,assfuck,ffffff,mushroom,jamaica,7654321,77777,cccccc,gizmodo,tractor,mypass,hongkong,1975,blue123,pissing,thomas1,redred,basketball,satan666,dublin,bollox,kingkong,1971,22222,272727,sexx,bbbb,grizzly,passat,defiant,bowler,knickers,monitor,wisdom,slappy,thor,letsgo,robert1,brownie,098765,playtime,lightnin,atomic,goku,llllll,qwaszx,cosmos,bosco,knights,beast,slapshot,assword,frosty,dumbass,mallard,dddd,159357,titleist,aussie,golfing,doobie,loveit,werewolf,vipers,1965,blabla,surf,sucking,tardis,thegame,legion,rebels,sarah1,onelove,loulou,toto,blackcat,0007,tacobell,soccer1,jedi,method,poopie,boob,breast,kittycat,belly,pikachu,thunder1,thankyou,celtics,frogger,scoobydo,sabbath,coltrane,budman,jackal,zzzzz,licking,gopher,geheim,lonestar,primus,pooper,newpass,brasil,heather1,husker,element,moomoo,beefcake,zzzzzzzz,shitty,smokin,jjjj,anthony1,anubis,backup,gorilla,fuckface,lowrider,punkrock,traffic,delta1,amazon,fatass,dodgeram,dingdong,qqqqqqqq,breasts,boots,honda1,spidey,poker,temp,johnjohn,147852,asshole1,dogdog,tricky,crusader,syracuse,spankme,speaker,meridian,amadeus,harley1,falcons,turkey50,kenwood,keyboard,ilovesex,1978,shazam,shalom,lickit,jimbob,roller,fatman,sandiego,magnus,cooldude,clover,mobile,plumber,texas1,tool,topper,mariners,rebel,caliente,celica,oxford,osiris,orgasm,punkin,porsche9,tuesday,breeze,bossman,kangaroo,latinas,astros,scruffy,qwertyu,hearts,jammer,java,1122,goodtime,chelsea1,freckles,flyboy,doodle,nebraska,bootie,kicker,webmaster,vulcan,191919,blueeyes,321321,farside,rugby,director,pussy69,power1,hershey,hermes,monopoly,birdman,blessed,blackjac,southern,peterpan,thumbs,fuckyou1,rrrrrr,a1b2c3d4,coke,bohica,elvis1,blacky,sentinel,snake1,richard1,1234abcd,guardian,candyman,fisting,scarlet,dildo,pancho,mandingo,lucky7,condom,munchkin,billyboy,summer1,sword,skiing,site,sony,thong,rootbeer,assassin,fffff,fitness,durango,postal,achilles,kisses,warriors,plymouth,topdog,asterix,hallo,cameltoe,fuckfuck,eeeeee,sithlord,theking,avenger,backdoor,chevrole,trance,cosworth,houses,homers,eternity,kingpin,verbatim,incubus,1961,blond,zaphod,shiloh,spurs,mighty,aliens,charly,dogman,omega1,printer,aggies,deadhead,bitch1,stone55,pineappl,thekid,rockets,camels,formula,oracle,pussey,porkchop,abcde,clancy,mystic,inferno,blackdog,steve1,alfa,grumpy,flames,puffy,proxy,valhalla,unreal,herbie,engage,yyyyyy,010101,pistol,celeb,gggg,portugal,a12345,newbie,mmmm,1qazxsw2,zorro,writer,stripper,sebastia,spread,links,metal,1221,565656,funfun,trojans,cyber,hurrican,moneys,1x2zkg8w,zeus,tomato,lion,atlantic,usa123,trans,aaaaaaa,homerun,hyperion,kevin1,blacks,44444444,skittles,fart,gangbang,fubar,sailboat,oilers,buster1,hithere,immortal,sticks,pilot,lexmark,jerkoff,maryland,cheers,possum,cutter,muppet,swordfish,sport,sonic,peter1,jethro,rockon,asdfghj,pass123,pornos,ncc1701a,bootys,buttman,bonjour,1960,bears,362436,spartans,tinman,threesom,maxmax,1414,bbbbb,camelot,chewie,gogo,fusion,saint,dilligaf,nopass,hustler,hunter1,whitey,beast1,yesyes,spank,smudge,pinkfloy,patriot,lespaul,hammers,formula1,sausage,scooter1,orioles,oscar1,colombia,cramps,exotic,iguana,suckers,slave,topcat,lancelot,magelan,racer,crunch,british,steph,456123,skinny,seeking,rockhard,filter,freaks,sakura,pacman,poontang,newlife,homer1,klingon,watcher,walleye,tasty,sinatra,starship,steel,starbuck,poncho,amber1,gonzo,catherin,candle,firefly,goblin,scotch,diver,usmc,huskies,kentucky,kitkat,beckham,bicycle,yourmom,studio,33333333,splash,jimmy1,12344321,sapphire,mailman,raiders1,ddddd,excalibu,illini,imperial,lansing,maxx,gothic,golfball,facial,front242,macdaddy,qwer1234,vectra,cowboys1,crazy1,dannyboy,aquarius,franky,ffff,sassy,pppp,pppppppp,prodigy,noodle,eatpussy,vortex,wanking,billy1,siemens,phillies,groups,chevy1,cccc,gggggggg,doughboy,dracula,nurses,loco,lollipop,utopia,chrono,cooler,nevada,wibble,summit,1225,capone,fugazi,panda,qazwsxed,puppies,triton,9876,nnnnnn,momoney,iforgot,wolfie,studly,hamburg,81fukkc,741852,catman,china,gagging,scott1,oregon,qweqwe,crazybab,daniel1,cutlass,holes,mothers,music1,walrus,1957,bigtime,xtreme,simba,ssss,rookie,bathing,rotten,maestro,turbo1,99999,butthole,hhhh,yoda,shania,phish,thecat,rightnow,baddog,greatone,gateway1,abstr,napster,brian1,bogart,hitler,wildfire,jackson1,1981,beaner,yoyo,0.0.0.000,super1,select,snuggles,slutty,phoenix1,technics,toon,raven1,rayray,123789,1066,albion,greens,gesperrt,brucelee,hehehe,kelly1,mojo,1998,bikini,woofwoof,yyyy,strap,sites,central,f**k,nyjets,punisher,username,vanilla,twisted,bunghole,viagra,veritas,pony,titts,labtec,jenny1,masterbate,mayhem,redbull,govols,gremlin,505050,gmoney,rovers,diamond1,trident,abnormal,deskjet,cuddles,bristol,milano,vh5150,jarhead,1982,bigbird,bizkit,sixers,slider,star69,starfish,penetration,tommy1,john316,caligula,flicks,films,railroad,cosmo,cthulhu,br0d3r,bearbear,swedish,spawn,patrick1,reds,anarchy,groove,fuckher,oooo,airbus,cobra1,clips,delete,duster,kitty1,mouse1,monkeys,jazzman,1919,262626,swinging,stroke,stocks,sting,pippen,labrador,jordan1,justdoit,meatball,females,vector,cooter,defender,nike,bubbas,bonkers,kahuna,wildman,4121,sirius,static,piercing,terror,teenage,leelee,microsof,mechanic,robotech,rated,chaser,salsero,macross,quantum,tsunami,daddy1,cruise,newpass6,nudes,hellyeah,1959,zaq12wsx,striker,spice,spectrum,smegma,thumb,jjjjjjjj,mellow,cancun,cartoon,sabres,samiam,oranges,oklahoma,lust,denali,nude,noodles,brest,hooter,mmmmmmmm,warthog,blueblue,zappa,wolverine,sniffing,jjjjj,calico,freee,rover,pooter,closeup,bonsai,emily1,keystone,iiii,1955,yzerman,theboss,tolkien,megaman,rasta,bbbbbbbb,hal9000,goofy,gringo,gofish,gizmo1,samsam,scuba,onlyme,tttttttt,corrado,clown,clapton,bulls,jayhawk,wwww,sharky,seeker,ssssssss,pillow,thesims,lighter,lkjhgf,melissa1,marcius2,guiness,gymnast,casey1,goalie,godsmack,lolo,rangers1,poppy,clemson,clipper,deeznuts,holly1,eeee,kingston,yosemite,sucked,sex123,sexy69,pic\\'s,tommyboy,masterbating,gretzky,happyday,frisco,orchid,orange1,manchest,aberdeen,ne1469,boxing,korn,intercourse,161616,1985,ziggy,supersta,stoney,amature,babyboy,bcfields,goliath,hack,hardrock,frodo,scout,scrappy,qazqaz,tracker,active,craving,commando,cohiba,cyclone,bubba69,katie1,mpegs,vsegda,irish1,sexy1,smelly,squerting,lions,jokers,jojojo,meathead,ashley1,groucho,cheetah,champ,firefox,gandalf1,packer,love69,tyler1,typhoon,tundra,bobby1,kenworth,village,volley,wolf359,0420,000007,swimmer,skydive,smokes,peugeot,pompey,legolas,redhot,rodman,redalert,grapes,4runner,carrera,floppy,ou8122,quattro,cloud9,davids,nofear,busty,homemade,mmmmm,whisper,vermont,webmaste,wives,insertion,jayjay,philips,topher,temptress,midget,ripken,havefun,canon,celebrity,ghetto,ragnarok,usnavy,conover,cruiser,dalshe,nicole1,buzzard,hottest,kingfish,misfit,milfnew,warlord,wassup,bigsexy,blackhaw,zippy,tights,kungfu,labia,meatloaf,area51,batman1,bananas,636363,ggggg,paradox,queens,adults,aikido,cigars,hoosier,eeyore,moose1,warez,interacial,streaming,313131,pertinant,pool6123,mayday,animated,banker,baddest,gordon24,ccccc,fantasies,aisan,deadman,homepage,ejaculation,whocares,iscool,jamesbon,1956,1pussy,womam,sweden,skidoo,spock,sssss,pepper1,pinhead,micron,allsop,amsterda,gunnar,666999,february,fletch,george1,sapper,sasha1,luckydog,lover1,magick,popopo,ultima,cypress,businessbabe,brandon1,vulva,vvvv,jabroni,bigbear,yummy,010203,searay,secret1,sinbad,sexxxx,soleil,software,piccolo,thirteen,leopard,legacy,memorex,redwing,rasputin,134679,anfield,greenbay,catcat,feather,scanner,pa55word,contortionist,danzig,daisy1,hores,exodus,iiiiii,1001,subway,snapple,sneakers,sonyfuck,picks,poodle,test1234,llll,junebug,marker,mellon,ronaldo,roadkill,amanda1,asdfjkl,beaches,great1,cheerleaers,doitnow,ozzy,boxster,brighton,housewifes,kkkk,mnbvcx,moocow,vides,1717,bigmoney,blonds,1000,storys,stereo,4545,420247,seductive,sexygirl,lesbean,justin1,124578,cabbage,canadian,gangbanged,dodge1,dimas,malaka,puss,probes,coolman,nacked,hotpussy,erotica,kool,implants,intruder,bigass,zenith,woohoo,womans,tango,pisces,laguna,maxell,andyod22,barcelon,chainsaw,chickens,flash1,orgasms,magicman,profit,pusyy,pothead,coconut,chuckie,clevelan,builder,budweise,hotshot,horizon,experienced,mondeo,wifes,1962,stumpy,smiths,slacker,pitchers,passwords,laptop,allmine,alliance,bbbbbbb,asscock,halflife,88888,chacha,saratoga,sandy1,doogie,qwert40,transexual,close-up,ib6ub9,volvo,jacob1,iiiii,beastie,sunnyday,stoned,sonics,starfire,snapon,pictuers,pepe,testing1,tiberius,lisalisa,lesbain,litle,retard,ripple,austin1,badgirl,golfgolf,flounder,royals,dragoon,dickie,passwor,majestic,poppop,trailers,nokia,bobobo,br549,minime,mikemike,whitesox,1954,3232,353535,seamus,solo,sluttey,pictere,titten,lback,1024,goodluck,fingerig,gallaries,goat,passme,oasis,lockerroom,logan1,rainman,treasure,custom,cyclops,nipper,bucket,homepage-,hhhhh,momsuck,indain,2345,beerbeer,bimmer,stunner,456456,tootsie,testerer,reefer,1012,harcore,gollum,545454,chico,caveman,fordf150,fishes,gaymen,saleen,doodoo,pa55w0rd,presto,qqqqq,cigar,bogey,helloo,dutch,kamikaze,wasser,vietnam,visa,japanees,0123,swords,slapper,peach,masterbaiting,redwood,1005,ametuer,chiks,fucing,sadie1,panasoni,mamas,rambo,unknown,absolut,dallas1,housewife,keywest,kipper,18436572,1515,zxczxc,303030,shaman,terrapin,masturbation,mick,redfish,1492,angus,goirish,hardcock,forfun,galary,freeporn,duchess,olivier,lotus,pornographic,ramses,purdue,traveler,crave,brando,enter1,killme,moneyman,welder,windsor,wifey,indon,yyyyy,taylor1,4417,picher,pickup,thumbnils,johnboy,jets,ameteur,amateurs,apollo13,hambone,goldwing,5050,sally1,doghouse,padres,pounding,quest,truelove,underdog,trader,climber,bolitas,hohoho,beanie,beretta,wrestlin,stroker,sexyman,jewels,johannes,mets,rhino,bdsm,balloons,grils,happy123,flamingo,route66,devo,outkast,paintbal,magpie,llllllll,twilight,critter,cupcake,nickel,bullseye,knickerless,videoes,binladen,xerxes,slim,slinky,pinky,thanatos,meister,menace,retired,albatros,balloon,goten,5551212,getsdown,donuts,nwo4life,tttt,comet,deer,dddddddd,deeznutz,nasty1,nonono,enterprise,eeeee,misfit99,milkman,vvvvvv,1818,blueboy,bigbutt,tech,toolman,juggalo,jetski,barefoot,50spanks,gobears,scandinavian,cubbies,nitram,kings,bilbo,yumyum,zzzzzzz,stylus,321654,shannon1,server,squash,starman,steeler,phrases,techniques,laser,135790,athens,cbr600,chemical,fester,gangsta,fucku2,droopy,objects,passwd,lllll,manchester,vedder,clit,chunky,darkman,buckshot,buddah,boobed,henti,winter1,bigmike,beta,zidane,talon,slave1,pissoff,thegreat,lexus,matador,readers,armani,goldstar,5656,fmale,fuking,fucku,ggggggg,sauron,diggler,pacers,looser,pounded,premier,triangle,cosmic,depeche,norway,helmet,mustard,misty1,jagger,3x7pxr,silver1,snowboar,penetrating,photoes,lesbens,lindros,roadking,rockford,1357,143143,asasas,goodboy,898989,chicago1,ferrari1,galeries,godfathe,gawker,gargoyle,gangster,rubble,rrrr,onetime,pussyman,pooppoop,trapper,cinder,newcastl,boricua,bunny1,boxer,hotred,hockey1,edward1,moscow,mortgage,bigtit,snoopdog,joshua1,july,1230,assholes,frisky,sanity,divine,dharma,lucky13,akira,butterfly,hotbox,hootie,howdy,earthlink,kiteboy,westwood,1988,blackbir,biggles,wrench,wrestle,slippery,pheonix,penny1,pianoman,thedude,jenn,jonjon,jones1,roadrunn,arrow,azzer,seahawks,diehard,dotcom,tunafish,chivas,cinnamon,clouds,deluxe,northern,boobie,momomo,modles,volume,23232323,bluedog,wwwwwww,zerocool,yousuck,pluto,limewire,joung,awnyce,gonavy,haha,films+pic+galeries,girsl,fuckthis,girfriend,uncencored,a123456,chrisbln,combat,cygnus,cupoi,netscape,hhhhhhhh,eagles1,elite,knockers,1958,tazmania,shonuf,pharmacy,thedog,midway,arsenal1,anaconda,australi,gromit,gotohell,787878,66666,carmex2,camber,gator1,ginger1,fuzzy,seadoo,lovesex,rancid,uuuuuu,911911,bulldog1,heater,monalisa,mmmmmmm,whiteout,virtual,jamie1,japanes,james007,2727,2469,blam,bitchass,zephyr,stiffy,sweet1,southpar,spectre,tigger1,tekken,lakota,lionking,jjjjjjj,megatron,1369,hawaiian,gymnastic,golfer1,gunners,7779311,515151,sanfran,optimus,panther1,love1,maggie1,pudding,aaron1,delphi,niceass,bounce,house1,killer1,momo,musashi,jammin,2003,234567,wp2003wp,submit,sssssss,spikes,sleeper,passwort,kume,meme,medusa,mantis,reebok,1017,artemis,harry1,cafc91,fettish,oceans,oooooooo,mango,ppppp,trainer,uuuu,909090,death1,bullfrog,hokies,holyshit,eeeeeee,jasmine1,&amp,&amp;,spinner,jockey,babyblue,gooner,474747,cheeks,pass1234,parola,okokok,poseidon,989898,crusher,cubswin,nnnn,kotaku,mittens,whatsup,vvvvv,iomega,insertions,bengals,biit,yellow1,012345,spike1,sowhat,pitures,pecker,theend,hayabusa,hawkeyes,florian,qaz123,usarmy,twinkle,chuckles,hounddog,hover,hothot,europa,kenshin,kojak,mikey1,water1,196969,wraith,zebra,wwwww,33333,simon1,spider1,snuffy,philippe,thunderb,teddy1,marino13,maria1,redline,renault,aloha,handyman,cerberus,gamecock,gobucks,freesex,duffman,ooooo,nuggets,magician,longbow,preacher,porno1,chrysler,contains,dalejr,navy,buffy1,hedgehog,hoosiers,honey1,hott,heyhey,dutchess,everest,wareagle,ihateyou,sunflowe,3434,senators,shag,spoon,sonoma,stalker,poochie,terminal,terefon,maradona,1007,142536,alibaba,america1,bartman,astro,goth,chicken1,cheater,ghost1,passpass,oral,r2d2c3po,civic,cicero,myxworld,kkkkk,missouri,wishbone,infiniti,1a2b3c,1qwerty,wonderboy,shojou,sparky1,smeghead,poiuy,titanium,lantern,jelly,1213,bayern,basset,gsxr750,cattle,fishing1,fullmoon,gilles,dima,obelix,popo,prissy,ramrod,bummer,hotone,dynasty,entry,konyor,missy1,282828,xyz123,426hemi,404040,seinfeld,pingpong,lazarus,marine1,12345a,beamer,babyface,greece,gustav,7007,ccccccc,faggot,foxy,gladiato,duckie,dogfood,packers1,longjohn,radical,tuna,clarinet,danny1,novell,bonbon,kashmir,kiki,mortimer,modelsne,moondog,vladimir,insert,1953,zxc123,supreme,3131,sexxx,softail,poipoi,pong,mars,martin1,rogue,avalanch,audia4,55bgates,cccccccc,came11,figaro,dogboy,dnsadm,dipshit,paradigm,othello,operator,tripod,chopin,coucou,cocksuck,borussia,heritage,hiziad,homerj,mullet,whisky,4242,speedo,starcraf,skylar,spaceman,piggy,tiger2,legos,jezebel,joker1,mazda,727272,chester1,rrrrrrrr,dundee,lumber,ppppppp,tranny,aaliyah,admiral,comics,delight,buttfuck,homeboy,eternal,kilroy,violin,wingman,walmart,bigblue,blaze,beemer,beowulf,bigfish,yyyyyyy,woodie,yeahbaby,0123456,tbone,syzygy,starter,linda1,merlot,mexican,11235813,banner,bangbang,badman,barfly,grease,charles1,ffffffff,doberman,dogshit,overkill,coolguy,claymore,demo,nomore,hhhhhhh,hondas,iamgod,enterme,electron,eastside,minimoni,mybaby,wildbill,wildcard,ipswich,200000,bearcat,zigzag,yyyyyyyy,sweetnes,369369,skyler,skywalker,pigeon,tipper,asdf123,alphabet,asdzxc,babybaby,banane,guyver,graphics,chinook,florida1,flexible,fuckinside,ursitesux,tototo,adam12,christma,chrome,buddie,bombers,hippie,misfits,292929,woofer,wwwwwwww,stubby,sheep,sparta,stang,spud,sporty,pinball,just4fun,maxxxx,rebecca1,fffffff,freeway,garion,rrrrr,sancho,outback,maggot,puddin,987456,hoops,mydick,19691969,bigcat,shiner,silverad,templar,lamer,juicy,mike1,maximum,1223,10101010,arrows,alucard,haggis,cheech,safari,dog123,orion1,paloma,qwerasdf,presiden,vegitto,969696,adonis,cookie1,newyork1,buddyboy,hellos,heineken,eraser,moritz,millwall,visual,jaybird,1983,beautifu,zodiac,steven1,sinister,slammer,smashing,slick1,sponge,teddybea,ticklish,jonny,1211,aptiva,applepie,bailey1,guitar1,canyon,gagged,fuckme1,digital1,dinosaur,98765,90210,clowns,cubs,deejay,nigga,naruto,boxcar,icehouse,hotties,electra,widget,1986,2004,bluefish,bingo1,*****,stratus,sultan,storm1,44444,4200,sentnece,sexyboy,sigma,smokie,spam,pippo,temppass,manman,1022,bacchus,aztnm,axio,bamboo,hakr,gregor,hahahaha,5678,camero1,dolphin1,paddle,magnet,qwert1,pyon,porsche1,tripper,noway,burrito,bozo,highheel,hookem,eddie1,entropy,kkkkkkkk,kkkkkkk,illinois,1945,1951,24680,21212121,100000,stonecold,taco,subzero,sexxxy,skolko,skyhawk,spurs1,sputnik,testpass,jiggaman,1224,hannah1,525252,4ever,carbon,scorpio1,rt6ytere,madison1,loki,coolness,coldbeer,citadel,monarch,morgan1,washingt,1997,bella1,yaya,superb,taxman,studman,3636,pizzas,tiffany1,lassie,larry1,joseph1,mephisto,reptile,razor,1013,hammer1,gypsy,grande,camper,chippy,cat123,chimera,fiesta,glock,domain,dieter,dragonba,onetwo,nygiants,password2,quartz,prowler,prophet,towers,ultra,cocker,corleone,dakota1,cumm,nnnnnnn,boxers,heynow,iceberg,kittykat,wasabi,vikings1,beerman,splinter,snoopy1,pipeline,mickey1,mermaid,micro,meowmeow,redbird,baura,chevys,caravan,frogman,diving,dogger,draven,drifter,oatmeal,paris1,longdong,quant4307s,rachel1,vegitta,cobras,corsair,dadada,mylife,bowwow,hotrats,eastwood,moonligh,modena,illusion,iiiiiii,jayhawks,swingers,shocker,shrimp,sexgod,squall,poiu,tigers1,toejam,tickler,julie1,jimbo1,jefferso,michael2,rodeo,robot,1023,annie1,bball,happy2,charter,flasher,falcon1,fiction,fastball,gadget,scrabble,diaper,dirtbike,oliver1,paco,macman,poopy,popper,postman,ttttttt,acura,cowboy1,conan,daewoo,nemrac58,nnnnn,nextel,bobdylan,eureka,kimmie,kcj9wx5n,killbill,musica,volkswag,wage,windmill,wert,vintage,iloveyou1,itsme,zippo,311311,starligh,smokey1,snappy,soulmate,plasma,krusty,just4me,marius,rebel1,1123,audi,fick,goaway,rusty2,dogbone,doofus,ooooooo,oblivion,mankind,mahler,lllllll,pumper,puck,pulsar,valkyrie,tupac,compass,concorde,cougars,delaware,niceguy,nocturne,bob123,boating,bronze,herewego,hewlett,houhou,earnhard,eeeeeeee,mingus,mobydick,venture,verizon,imation,1950,1948,1949,223344,bigbig,wowwow,sissy,spiker,snooker,sluggo,player1,jsbach,jumbo,medic,reddevil,reckless,123456a,1125,1031,astra,gumby,757575,585858,chillin,fuck1,radiohea,upyours,trek,coolcool,classics,choochoo,nikki1,nitro,boytoy,excite,kirsty,wingnut,wireless,icu812,1master,beatle,bigblock,wolfen,summer99,sugar1,tartar,sexysexy,senna,sexman,soprano,platypus,pixies,telephon,laura1,laurent,rimmer,1020,12qwaszx,hamish,halifax,fishhead,forum,dododo,doit,paramedi,lonesome,mandy1,uuuuu,uranus,ttttt,bruce1,helper,hopeful,eduard,dusty1,kathy1,moonbeam,muscles,monster1,monkeybo,windsurf,vvvvvvv,vivid,install,1947,187187,1941,1952,susan1,31415926,sinned,sexxy,smoothie,snowflak,playstat,playa,playboy1,toaster,jerry1,marie1,mason1,merlin1,roger1,roadster,112358,1121,andrea1,bacardi,hardware,789789,5555555,captain1,fergus,sascha,rrrrrrr,dome,onion,lololo,qqqqqqq,undertak,uuuuuuuu,uuuuuuu,cobain,cindy1,coors,descent,nimbus,nomad,nanook,norwich,bombay,broker,hookup,kiwi,winners,jackpot,1a2b3c4d,1776,beardog,bighead,bird33,0987,spooge,pelican,peepee,titan,thedoors,jeremy1,altima,baba,hardone,5454,catwoman,finance,farmboy,farscape,genesis1,salomon,loser1,r2d2,pumpkins,chriss,cumcum,ninjas,ninja1,killers,miller1,islander,jamesbond,intel,19841984,2626,bizzare,blue12,biker,yoyoma,sushi,shitface,spanker,steffi,sphinx,please1,paulie,pistons,tiburon,maxwell1,mdogg,rockies,armstron,alejandr,arctic,banger,audio,asimov,753951,4you,chilly,care1839,flyfish,fantasia,freefall,sandrine,oreo,ohshit,macbeth,madcat,loveya,qwerqwer,colnago,chocha,cobalt,crystal1,dabears,nevets,nineinch,broncos1,epsilon,kestrel,winston1,warrior1,iiiiiiii,iloveyou2,1616,woowoo,sloppy,specialk,tinkerbe,jellybea,reader,redsox1,1215,1112,arcadia,baggio,555666,cayman,cbr900rr,gabriell,glennwei,sausages,disco,pass1,lovebug,macmac,puffin,vanguard,trinitro,airwolf,aaa111,cocaine,cisco,datsun,bricks,bumper,eldorado,kidrock,wizard1,whiskers,wildwood,istheman,25802580,bigones,woodland,wolfpac,strawber,3030,sheba1,sixpack,peace1,physics,tigger2,toad,megan1,meow,ringo,amsterdam,717171,686868,5424,canuck,football1,footjob,fulham,seagull,orgy,lobo,mancity,vancouve,vauxhall,acidburn,derf,myspace1,boozer,buttercu,hola,minemine,munch,1dragon,biology,bestbuy,bigpoppa,blackout,blowfish,bmw325,bigbob,stream,talisman,tazz,sundevil,3333333,skate,shutup,shanghai,spencer1,slowhand,pinky1,tootie,thecrow,jubilee,jingle,matrix1,manowar,messiah,resident,redbaron,romans,andromed,athlon,beach1,badgers,guitars,harald,harddick,gotribe,6996,7grout,5wr2i7h8,635241,chase1,fallout,fiddle,fenris,francesc,fortuna,fairlane,felix1,gasman,fucks,sahara,sassy1,dogpound,dogbert,divx1,manila,pornporn,quasar,venom,987987,access1,clippers,daman,crusty,nathan1,nnnnnnnn,bruno1,budapest,kittens,kerouac,mother1,waldo1,whistler,whatwhat,wanderer,idontkno,1942,1946,bigdawg,bigpimp,zaqwsx,414141,3000gt,434343,serpent,smurf,pasword,thisisit,john1,robotics,redeye,rebelz,1011,alatam,asians,bama,banzai,harvest,575757,5329,fatty,fender1,flower2,funky,sambo,drummer1,dogcat,oedipus,osama,prozac,private1,rampage,concord,cinema,cornwall,cleaner,ciccio,clutch,corvet07,daemon,bruiser,boiler,hjkl,egghead,mordor,jamess,iverson3,bluesman,zouzou,090909,1002,stone1,4040,sexo,smith1,sperma,sneaky,polska,thewho,terminat,krypton,lekker,johnson1,johann,rockie,aspire,goodie,cheese1,fenway,fishon,fishin,fuckoff1,girls1,doomsday,pornking,ramones,rabbits,transit,aaaaa1,boyz,bookworm,bongo,bunnies,buceta,highbury,henry1,eastern,mischief,mopar,ministry,vienna,wildone,bigbooty,beavis1,xxxxxx1,yogibear,000001,0815,zulu,420000,sigmar,sprout,stalin,lkjhgfds,lagnaf,rolex,redfox,referee,123123123,1231,angus1,ballin,attila,greedy,grunt,747474,carpedie,caramel,foxylady,gatorade,futbol,frosch,saiyan,drums,donner,doggy1,drum,doudou,nutmeg,quebec,valdepen,tosser,tuscl,comein,cola,deadpool,bremen,hotass,hotmail1,eskimo,eggman,koko,kieran,katrin,kordell1,komodo,mone,munich,vvvvvvvv,jackson5,2222222,bergkamp,bigben,zanzibar,xxx123,sunny1,373737,slayer1,snoop,peachy,thecure,little1,jennaj,rasta69,1114,aries,havana,gratis,calgary,checkers,flanker,salope,dirty1,draco,dogface,luv2epus,rainbow6,qwerty123,umpire,turnip,vbnm,tucson,troll,codered,commande,neon,nico,nightwin,boomer1,bushido,hotmail0,enternow,keepout,karen1,mnbv,viewsoni,volcom,wizards,1995,berkeley,woodstoc,tarpon,shinobi,starstar,phat,toolbox,julien,johnny1,joebob,riders,reflex,120676,1235,angelus,anthrax,atlas,grandam,harlem,hawaii50,655321,cabron,challeng,callisto,firewall,firefire,flyer,flower1,gambler,frodo1,sam123,scania,dingo,papito,passmast,ou8123,randy1,twiggy,travis1,treetop,addict,admin1,963852,aceace,cirrus,bobdole,bonjovi,bootsy,boater,elway7,kenny1,moonshin,montag,wayne1,white1,jazzy,jakejake,1994,1991,2828,bluejays,belmont,sensei,southpark,peeper,pharao,pigpen,tomahawk,teensex,leedsutd,jeepster,jimjim,josephin,melons,matthias,robocop,1003,1027,antelope,azsxdc,gordo,hazard,granada,8989,7894,ceasar,cabernet,cheshire,chelle,candy1,fergie,fidelio,giorgio,fuckhead,dominion,qawsed,trucking,chloe1,daddyo,nostromo,boyboy,booster,bucky,honolulu,esquire,dynamite,mollydog,windows1,waffle,wealth,vincent1,jabber,jaguars,javelin,irishman,idefix,bigdog1,blue42,blanked,blue32,biteme1,bearcats,yessir,sylveste,sunfire,tbird,stryker,3ip76k2,sevens,pilgrim,tenchi,titman,leeds,lithium,linkin,marijuan,mariner,markie,midnite,reddwarf,1129,123asd,12312312,allstar,albany,asdf12,aspen,hardball,goldfing,7734,49ers,carnage,callum,carlos1,fitter,fandango,gofast,gamma,fucmy69,scrapper,dogwood,django,magneto,premium,9999999,abc1234,newyear,bookie,bounty,brown1,bologna,elway,killjoy,klondike,mouser,wayer,impreza,insomnia,24682468,2580,24242424,billbill,bellaco,blues1,blunts,teaser,sf49ers,shovel,solitude,spikey,pimpdadd,timeout,toffee,lefty,johndoe,johndeer,mega,manolo,ratman,robin1,1124,1210,1028,1226,babylove,barbados,gramma,646464,carpente,chaos1,fishbone,fireblad,frogs,screamer,scuba1,ducks,doggies,dicky,obsidian,rams,tottenham,aikman,comanche,corolla,cumslut,cyborg,boston1,houdini,helmut,elvisp,keksa12,monty1,wetter,watford,wiseguy,1989,1987,20202020,biatch,beezer,bigguns,blueball,bitchy,wyoming,yankees2,wrestler,stupid1,sealteam,sidekick,simple1,smackdow,sporting,spiral,smeller,plato,tophat,test2,toomuch,jello,junkie,maxim,maxime,meadow,remingto,roofer,124038,1018,1269,1227,123457,arkansas,aramis,beaker,barcelona,baltimor,googoo,goochi,852456,4711,catcher,champ1,fortress,fishfish,firefigh,geezer,rsalinas,samuel1,saigon,scooby1,dick1,doom,dontknow,magpies,manfred,vader1,universa,tulips,mygirl,bowtie,holycow,honeys,enforcer,waterboy,1992,23skidoo,bimbo,blue11,birddog,zildjian,030303,stinker,stoppedby,sexybabe,speakers,slugger,spotty,smoke1,polopolo,perfect1,torpedo,lakeside,jimmys,junior1,masamune,1214,april1,grinch,767676,5252,cherries,chipmunk,cezer121,carnival,capecod,finder,fearless,goats,funstuff,gideon,savior,seabee,sandro,schalke,salasana,disney1,duckman,pancake,pantera1,malice,love123,qwert123,tracer,creation,cwoui,nascar24,hookers,erection,ericsson,edthom,kokoko,kokomo,mooses,inter,1michael,1993,19781978,25252525,shibby,shamus,skibum,sheepdog,sex69,spliff,slipper,spoons,spanner,snowbird,toriamos,temp123,tennesse,lakers1,jomama,mazdarx7,recon,revolver,1025,1101,barney1,babycake,gotham,gravity,hallowee,616161,515000,caca,cannabis,chilli,fdsa,getout,fuck69,gators1,sable,rumble,dolemite,dork,duffer,dodgers1,onions,logger,lookout,magic32,poon,twat,coventry,citroen,civicsi,cocksucker,coochie,compaq1,nancy1,buzzer,boulder,butkus,bungle,hogtied,hotgirls,heidi1,eggplant,mustang6,monkey12,wapapapa,wendy1,volleyba,vibrate,blink,birthday4,xxxxx1,stephen1,suburban,sheeba,start1,soccer10,starcraft,soccer12,peanut1,plastics,penthous,peterbil,tetsuo,torino,tennis1,termite,lemmein,lakewood,jughead,melrose,megane,redone,angela1,goodgirl,gonzo1,golden1,gotyoass,656565,626262,capricor,chains,calvin1,getmoney,gabber,runaway,salami,dungeon,dudedude,opus,paragon,panhead,pasadena,opendoor,odyssey,magellan,printing,prince1,trustme,nono,buffet,hound,kajak,killkill,moto,winner1,vixen,whiteboy,versace,voyager1,indy,jackjack,bigal,beech,biggun,blake1,blue99,big1,synergy,success1,336699,sixty9,shark1,simba1,sebring,spongebo,spunk,springs,sliver,phialpha,password9,pizza1,pookey,tickling,lexingky,lawman,joe123,mike123,romeo1,redheads,apple123,backbone,aviation,green123,carlitos,byebye,cartman1,camden,chewy,camaross,favorite6,forumwp,ginscoot,fruity,sabrina1,devil666,doughnut,pantie,oldone,paintball,lumina,rainbow1,prosper,umbrella,ajax,951753,achtung,abc12345,compact,corndog,deerhunt,darklord,dank,nimitz,brandy1,hetfield,holein1,hillbill,hugetits,evolutio,kenobi,whiplash,wg8e3wjf,istanbul,invis,1996,bigjohn,bluebell,beater,benji,bluejay,xyzzy,suckdick,taichi,stellar,shaker,semper,splurge,squeak,pearls,playball,pooky,titfuck,joemama,johnny5,marcello,maxi,rhubarb,ratboy,reload,1029,1030,1220,bbking,baritone,gryphon,57chevy,494949,celeron,fishy,gladiator,fucker1,roswell,dougie,dicker,diva,donjuan,nympho,racers,truck1,trample,acer,cricket1,climax,denmark,cuervo,notnow,nittany,neutron,bosco1,buffa,breaker,hello2,hydro,kisskiss,kittys,montecar,modem,mississi,20012001,bigdick1,benfica,yahoo1,striper,tabasco,supra,383838,456654,seneca,shuttle,penguin1,pathfind,testibil,thethe,jeter2,marma,mark1,metoo,republic,rollin,redleg,redbone,redskin,1245,anthony7,altoids,barley,asswipe,bauhaus,bbbbbb1,gohome,harrier,golfpro,goldeney,818181,6666666,5000,5rxypn,cameron1,checker,calibra,freefree,faith1,fdm7ed,giraffe,giggles,fringe,scamper,rrpass1,screwyou,dimples,pacino,ontario,passthie,oberon,quest1,postov1000,puppydog,puffer,qwerty7,tribal,adam25,a1234567,collie,cleopatr,davide,namaste,buffalo1,bonovox,bukkake,burner,bordeaux,burly,hun999,enters,mohawk,vgirl,jayden,1812,1943,222333,bigjim,bigd,zoom,wordup,ziggy1,yahooo,workout,young1,xmas,zzzzzz1,surfer1,strife,sunlight,tasha1,skunk,sprinter,peaches1,pinetree,plum,pimping,theforce,thedon,toocool,laddie,lkjh,jupiter1,matty,redrose,1200,102938,antares,austin31,goose1,737373,78945612,789987,6464,calimero,caster,casper1,cement,chevrolet,chessie,caddy,canucks,fellatio,f00tball,gateway2,gamecube,rugby1,scheisse,dshade,dixie1,offshore,lucas1,macaroni,manga,pringles,puff,trouble1,ussy,coolhand,colonial,colt,darthvad,cygnusx1,natalie1,newark,hiking,errors,elcamino,koolaid,knight1,murphy1,volcano,idunno,2005,2233,blueberr,biguns,yamahar1,zapper,zorro1,0911,3006,sixsix,shopper,sextoy,snowboard,speedway,pokey,playboy2,titi,toonarmy,lambda,joecool,juniper,max123,mariposa,met2002,reggae,ricky1,1236,1228,1016,all4one,baberuth,asgard,484848,5683,6669,catnip,charisma,capslock,cashmone,galant,frenchy,gizmodo1,girlies,screwy,doubled,divers,dte4uw,dragonfl,treble,twinkie,tropical,crescent,cococo,dabomb,daffy,dandfa,cyrano,nathanie,boners,helium,hellas,espresso,killa,kikimora,w4g8at,ilikeit,iforget,1944,20002000,birthday1,beatles1,blue1,bigdicks,beethove,blacklab,blazers,benny1,woodwork,0069,0101,taffy,4567,shodan,pavlov,pinnacle,petunia,tito,teenie,lemonade,lalakers,lebowski,lalalala,ladyboy,jeeper,joyjoy,mercury1,mantle,mannn,rocknrol,riversid,123aaa,11112222,121314,1021,1004,1120,allen1,ambers,amstel,alice1,alleycat,allegro,ambrosia,gspot,goodsex,hattrick,harpoon,878787,8inches,4wwvte,cassandr,charlie123,gatsby,generic,gareth,fuckme2,samm,seadog,satchmo,scxakv,santafe,dipper,outoutout,madmad,london1,qbg26i,pussy123,tzpvaw,vamp,comp,cowgirl,coldplay,dawgs,nt5d27,novifarm,notredam,newness,mykids,bryan1,bouncer,hihihi,honeybee,iceman1,hotlips,dynamo,kappa,kahlua,muffy,mizzou,wannabe,wednesda,whatup,waterfal,willy1,bear1,billabon,youknow,yyyyyy1,zachary1,01234567,070462,zurich,superstar,stiletto,strat,427900,sigmachi,shells,sexy123,smile1,sophie1,stayout,somerset,playmate,pinkfloyd,phish1,payday,thebear,telefon,laetitia,kswbdu,jerky,metro,revoluti,1216,1201,1204,1222,1115,archange,barry1,handball,676767,chewbacc,furball,gocubs,fullback,gman,dewalt,dominiqu,diver1,dhip6a,olemiss,mandrake,mangos,pretzel,pusssy,tripleh,vagabond,clovis,dandan,csfbr5yy,deadspin,ninguna,ncc74656,bootsie,bp2002,bourbon,bumble,heyyou,houston1,hemlock,hippo,hornets,horseman,excess,extensa,muffin1,virginie,werdna,idontknow,jack1,1bitch,151nxjmt,bendover,bmwbmw,zaq123,wxcvbn,supernov,tahoe,shakur,sexyone,seviyi,smart1,speed1,pepito,phantom1,playoffs,terry1,terrier,laser1,lite,lancia,johngalt,jenjen,midori,maserati,matteo,miami1,riffraff,ronald1,1218,1026,123987,1015,1103,armada,architec,austria,gotmilk,cambridg,camero,flex,foreplay,getoff,glacier,glotest,froggie,gerbil,rugger,sanity72,donna1,orchard,oyster,palmtree,pajero,m5wkqf,magenta,luckyone,treefrog,vantage,usmarine,tyvugq,uptown,abacab,aaaaaa1,chuck1,darkange,cyclones,navajo,bubba123,iawgk2,hrfzlz,dylan1,enrico,encore,eclipse1,mutant,mizuno,mustang2,video1,viewer,weed420,whales,jaguar1,1990,159159,1love,bears1,bigtruck,bigboss,blitz,xqgann,yeahyeah,zeke,zardoz,stickman,3825,sentra,shiva,skipper1,singapor,southpaw,sonora,squid,slamdunk,slimjim,placid,photon,placebo,pearl1,test12,therock1,tiger123,leinad,legman,jeepers,joeblow,mike23,redcar,rhinos,rjw7x4,1102,13576479,112211,gwju3g,greywolf,7bgiqk,7878,535353,4snz9g,candyass,cccccc1,catfight,cali,fister,fosters,finland,frankie1,gizzmo,royalty,rugrat,dodo,oemdlg,out3xf,paddy,opennow,puppy1,qazwsxedc,ramjet,abraxas,cn42qj,dancer1,death666,nudity,nimda2k,buick,bobb,braves1,henrik,hooligan,everlast,karachi,mortis,monies,motocros,wally1,willie1,inspiron,1test,2929,bigblack,xytfu7,yackwin,zaq1xsw2,yy5rbfsc,100100,0660,tahiti,takehana,332211,3535,sedona,seawolf,skydiver,spleen,slash,spjfet,special1,slimshad,sopranos,spock1,penis1,patches1,thierry,thething,toohot,limpone,mash4077,matchbox,masterp,maxdog,ribbit,rockin,redhat,1113,14789632,1331,allday,aladin,andrey,amethyst,baseball1,athome,goofy1,greenman,goofball,ha8fyp,goodday,778899,charon,chappy,caracas,cardiff,capitals,canada1,cajun,catter,freddy1,favorite2,forme,forsaken,feelgood,gfxqx686,saskia,sanjose,salsa,dilbert1,dukeduke,downhill,longhair,locutus,lockdown,malachi,mamacita,lolipop,rainyday,pumpkin1,punker,prospect,rambo1,rainbows,quake,trinity1,trooper1,citation,coolcat,default,deniro,d9ungl,daddys,nautica,nermal,bukowski,bubbles1,bogota,buds,hulk,hitachi,ender,export,kikiki,kcchiefs,kram,morticia,montrose,mongo,waqw3p,wizzard,whdbtp,whkzyc,154ugeiu,1fuck,binky,bigred1,blubber,becky1,year2005,wonderfu,xrated,0001,tampabay,survey,tammy1,stuffer,3mpz4r,3000,3some,sierra1,shampoo,shyshy,slapnuts,standby,spartan1,sprocket,stanley1,poker1,theshit,lavalamp,light1,laserjet,jediknig,jjjjj1,mazda626,menthol,margaux,medic1,rhino1,1209,1234321,amigos,apricot,asdfgh1,hairball,hatter,grimace,7xm5rq,6789,cartoons,capcom,cashflow,carrots,fanatic,format,girlie,safeway,dogfart,dondon,outsider,odin,opiate,lollol,love12,mallrats,prague,primetime21,pugsley,r29hqq,valleywa,airman,abcdefg1,darkone,cummer,natedogg,nineball,ndeyl5,natchez,newone,normandy,nicetits,buddy123,buddys,homely,husky,iceland,hr3ytm,highlife,holla,earthlin,exeter,eatmenow,kimkim,k2trix,kernel,money123,moonman,miles1,mufasa,mousey,whites,warhamme,jackass1,2277,20spanks,blobby,blinky,bikers,blackjack,becca,blue23,xman,wyvern,085tzzqi,zxzxzx,zsmj2v,suede,t26gn4,sugars,tantra,swoosh,4226,4271,321123,383pdjvl,shane1,shelby1,spades,smother,sparhawk,pisser,photo1,pebble,peavey,pavement,thistle,kronos,lilbit,linux,melanie1,marbles,redlight,1208,1138,1008,alchemy,aolsucks,alexalex,atticus,auditt,b929ezzh,goodyear,gubber,863abgsg,7474,797979,464646,543210,4zqauf,4949,ch5nmk,carlito,chewey,carebear,checkmat,cheddar,chachi,forgetit,forlife,giants1,getit,gerhard,galileo,g3ujwg,ganja,rufus1,rushmore,discus,dudeman,olympus,oscars,osprey,madcow,locust,loyola,mammoth,proton,rabbit1,ptfe3xxp,pwxd5x,purple1,punkass,prophecy,uyxnyd,tyson1,aircraft,access99,abcabc,colts,civilwar,claudia1,contour,dddddd1,cypher,dapzu455,daisydog,noles,hoochie,hoser,eldiablo,kingrich,mudvayne,motown,mp8o6d,vipergts,italiano,2055,2211,bloke,blade1,yamato,zooropa,yqlgr667,050505,zxcvbnm1,zw6syj,suckcock,tango1,swampy,445566,333666,380zliki,sexpot,sexylady,sixtynin,sickboy,spiffy,skylark,sparkles,pintail,phreak,teller,timtim,thighs,latex,letsdoit,lkjhg,landmark,lizzard,marlins,marauder,metal1,manu,righton,1127,alain,alcat,amigo,basebal1,azertyui,azrael,hamper,gotenks,golfgti,hawkwind,h2slca,grace1,6chid8,789654,canine,casio,cazzo,cbr900,cabrio,calypso,capetown,feline,flathead,fisherma,flipmode,fungus,g9zns4,giggle,gabriel1,fuck123,saffron,dogmeat,dreamcas,dirtydog,douche,dresden,dickdick,destiny1,pappy,oaktree,luft4,puta,ramada,trumpet1,vcradq,tulip,tracy71,tycoon,aaaaaaa1,conquest,chitown,creepers,cornhole,danman,dada,density,d9ebk7,darth,nirvana1,nestle,brenda1,bonanza,hotspur,hufmqw,electro,erasure,elisabet,etvww4,ewyuza,eric1,kenken,kismet,klaatu,milamber,willi,isacs155,igor,1million,1letmein,x35v8l,yogi,ywvxpz,xngwoj,zippy1,020202,****,stonewal,sentry,sexsexsex,sonysony,smirnoff,star12,solace,star1,pkxe62,pilot1,pommes,paulpaul,tical,tictac,lighthou,lemans,kubrick,letmein22,letmesee,jys6wz,jonesy,jjjjjj1,jigga,redstorm,riley1,14141414,1126,allison1,badboy1,asthma,auggie,hardwood,gumbo,616913,57np39,56qhxs,4mnveh,fatluvr69,fqkw5m,fidelity,feathers,fresno,godiva,gecko,gibson1,gogators,general1,saxman,rowing,sammys,scotts,scout1,sasasa,samoht,dragon69,ducky,dragonball,driller,p3wqaw,papillon,oneone,openit,optimist,longshot,rapier,pussy2,ralphie,tuxedo,undertow,copenhag,delldell,culinary,deltas,mytime,noname,noles1,bucker,bopper,burnout,ibilltes,hihje863,hitter,ekim,espana,eatme69,elpaso,express1,eeeeee1,eatme1,karaoke,mustang5,wellingt,willem,waterski,webcam,jasons,infinite,iloveyou!,jakarta,belair,bigdad,beerme,yoshi,yinyang,x24ik3,063dyjuy,0000007,ztmfcq,stopit,stooges,symow8,strato,2hot4u,skins,shakes,sex1,snacks,softtail,slimed123,pizzaman,tigercat,tonton,lager,lizzy,juju,john123,jesse1,jingles,martian,mario1,rootedit,rochard,redwine,requiem,riverrat,1117,1014,1205,amor,amiga,alpina,atreides,banana1,bahamut,golfman,happines,7uftyx,5432,5353,5151,4747,foxfire,ffvdj474,foreskin,gayboy,gggggg1,gameover,glitter,funny1,scoobydoo,saxophon,dingbat,digimon,omicron,panda1,loloxx,macintos,lululu,lollypop,racer1,queen1,qwertzui,upnfmc,tyrant,trout1,9skw5g,aceman,acls2h,aaabbb,acapulco,aggie,comcast,cloudy,cq2kph,d6o8pm,cybersex,davecole,darian,crumbs,davedave,dasani,mzepab,myporn,narnia,booger1,bravo1,budgie,btnjey,highlander,hotel6,humbug,ewtosi,kristin1,kobe,knuckles,keith1,katarina,muff,muschi,montana1,wingchun,wiggle,whatthe,vette1,vols,virago,intj3a,ishmael,jachin,illmatic,199999,2010,blender,bigpenis,bengal,blue1234,zaqxsw,xray,xxxxxxx1,zebras,yanks,tadpole,stripes,3737,4343,3728,4444444,368ejhih,solar,sonne,sniffer,sonata,squirts,playstation,pktmxr,pescator,texaco,lesbos,l8v53x,jo9k2jw2,jimbeam,jimi,jupiter2,jurassic,marines1,rocket1,14725836,12345679,1219,123098,1233,alessand,althor,arch,alpha123,basher,barefeet,balboa,bbbbb1,badabing,gopack,golfnut,gsxr1000,gregory1,766rglqy,8520,753159,8dihc6,69camaro,666777,cheeba,chino,cheeky,camel1,fishcake,flubber,gianni,gnasher23,frisbee,fuzzy1,fuzzball,save13tx,russell1,sandra1,scrotum,scumbag,sabre,samdog,dripping,dragon12,dragster,orwell,mainland,maine,qn632o,poophead,rapper,porn4life,rapunzel,velocity,vanessa1,trueblue,vampire1,abacus,902100,crispy,chooch,d6wnro,dabulls,dehpye,navyseal,njqcw4,nownow,nigger1,nightowl,nonenone,nightmar,bustle,buddy2,boingo,bugman,bosshog,hybrid,hillside,hilltop,hotlegs,hzze929b,hhhhh1,hellohel,evilone,edgewise,e5pftu,eded,embalmer,excalibur,elefant,kenzie,killah,kleenex,mouses,mounta1n,motors,mutley,muffdive,vivitron,w00t88,iloveit,jarjar,incest,indycar,17171717,1664,17011701,222777,2663,beelch,benben,yitbos,yyyyy1,zzzzz1,stooge,tangerin,taztaz,stewart1,summer69,system1,surveyor,stirling,3qvqod,3way,456321,sizzle,simhrq,sparty,ssptx452,sphere,persian,ploppy,pn5jvw,poobear,pianos,plaster,testme,tiff,thriller,master12,rockey,1229,1217,1478,1009,anastasi,amonra,argentin,albino,azazel,grinder,6uldv8,83y6pv,8888888,4tlved,515051,carsten,flyers88,ffffff1,firehawk,firedog,flashman,ggggg1,godspeed,galway,giveitup,funtimes,gohan,giveme,geryfe,frenchie,sayang,rudeboy,sandals,dougal,drag0n,dga9la,desktop,onlyone,otter,pandas,mafia,luckys,lovelife,manders,qqh92r,qcmfd454,radar1,punani,ptbdhw,turtles,undertaker,trs8f7,ugejvp,abba,911turbo,acdc,abcd123,crash1,colony,delboy,davinci,notebook,nitrox,borabora,bonzai,brisbane,heeled,hooyah,hotgirl,i62gbq,horse1,hpk2qc,epvjb6,mnbvc,mommy1,munster,wiccan,2369,bettyboo,blondy,bismark,beanbag,bjhgfi,blackice,yvtte545,ynot,yess,zlzfrh,wolvie,007bond,******,tailgate,tanya1,sxhq65,stinky1,3234412,3ki42x,seville,shimmer,sienna,shitshit,skillet,sooners1,solaris,smartass,pedros,pennywis,pfloyd,tobydog,thetruth,letme1n,mario66,micky,rocky2,rewq,reindeer,1128,1207,1104,1432,aprilia,allstate,bagels,baggies,barrage,guru,72d5tn,606060,4wcqjn,chance1,flange,fartman,geil,gbhcf2,fussball,fuaqz4,gameboy,geneviev,rotary,seahawk,saab,samadams,devlt4,ditto,drevil,drinker,deuce,dipstick,octopus,ottawa,losangel,loverman,porky,q9umoz,rapture,pussy4me,triplex,ue8fpw,turbos,aaa340,churchil,crazyman,cutiepie,ddddd1,dejavu,cuxldv,nbvibt,nikon,niko,nascar1,bubba2,boobear,boogers,bullwink,bulldawg,horsemen,escalade,eagle2,dynamic,efyreg,minnesot,mogwai,msnxbi,mwq6qlzo,werder,verygood,voodoo1,iiiiii1,159951,1624,1911a1,2244,bellagio,bedlam,belkin,bill1,xirt2k,??????,susieq,sundown,sukebe,swifty,2fast4u,sexe,shroom,seaweed,skeeter1,snicker,spanky1,spook,phaedrus,pilots,peddler,thumper1,tiger7,tmjxn151,thematri,l2g7k3,letmeinn,jeffjeff,johnmish,mantra,mike69,mazda6,riptide,robots,1107,1130,142857,11001001,1134,armored,allnight,amatuers,bartok,astral,baboon,balls1,bassoon,hcleeb,happyman,granite,graywolf,golf1,gomets,8vjzus,7890,789123,8uiazp,5757,474jdvff,551scasi,50cent,camaro1,cherry1,chemist,firenze,fishtank,freewill,glendale,frogfrog,ganesh,scirocco,devilman,doodles,okinawa,olympic,orpheus,ohmygod,paisley,pallmall,lunchbox,manhatta,mahalo,mandarin,qwqwqw,qguvyt,pxx3eftp,rambler,poppy1,turk182,vdlxuc,tugboat,valiant,uwrl7c,chris123,cmfnpu,decimal,debbie1,dandy,daedalus,natasha1,nissan1,nancy123,nevermin,napalm,newcastle,bonghit,ibxnsm,hhhhhh1,holger,edmonton,equinox,dvader,kimmy,knulla,mustafa,monsoon,mistral,morgana,monica1,mojave,monterey,mrbill,vkaxcs,victor1,violator,vfdhif,wilson1,wavpzt,wildstar,winter99,iqzzt580,imback,1914,19741974,1monkey,1q2w3e4r5t,2500,2255,bigshow,bigbucks,blackcoc,zoomer,wtcacq,wobble,xmen,xjznq5,yesterda,yhwnqc,zzzxxx,393939,2fchbg,skinhead,skilled,shadow12,seaside,sinful,silicon,smk7366,snapshot,sniper1,soccer11,smutty,peepers,plokij,pdiddy,pimpdaddy,thrust,terran,topaz,today1,lionhear,littlema,lauren1,lincoln1,lgnu9d,juneau,methos,rogue1,romulus,redshift,1202,1469,12locked,arizona1,alfarome,al9agd,aol123,altec,apollo1,arse,baker1,bbb747,axeman,astro1,hawthorn,goodfell,hawks1,gstring,hannes,8543852,868686,4ng62t,554uzpad,5401,567890,5232,catfood,fire1,flipflop,fffff1,fozzie,fluff,fzappa,rustydog,scarab,satin,ruger,samsung1,destin,diablo2,dreamer1,detectiv,doqvq3,drywall,paladin1,papabear,offroad,panasonic,nyyankee,luetdi,qcfmtz,pyf8ah,puddles,pussyeat,ralph1,princeto,trivia,trewq,tri5a3,advent,9898,agyvorc,clarkie,coach1,courier,christo,chowder,cyzkhw,davidb,dad2ownu,daredevi,de7mdf,nazgul,booboo1,bonzo,butch1,huskers1,hgfdsa,hornyman,elektra,england1,elodie,kermit1,kaboom,morten,mocha,monday1,morgoth,weewee,weenie,vorlon,wahoo,ilovegod,insider,jayman,1911,1dallas,1900,1ranger,201jedlz,2501,1qaz,bignuts,bigbad,beebee,billows,belize,wvj5np,wu4etd,yamaha1,wrinkle5,zebra1,yankee1,zoomzoom,09876543,0311,?????,stjabn,tainted,3tmnej,skooter,skelter,starlite,spice1,stacey1,smithy,pollux,peternorth,pixie,piston,poets,toons,topspin,kugm7b,legends,jeepjeep,joystick,junkmail,jojojojo,jonboy,midland,mayfair,riches,reznor,rockrock,reboot,renee1,roadway,rasta220,1411,1478963,1019,archery,andyandy,barks,bagpuss,auckland,gooseman,hazmat,gucci,grammy,happydog,7kbe9d,7676,6bjvpe,5lyedn,5858,5291,charlie2,c7lrwu,candys,chateau,ccccc1,cardinals,fihdfv,fortune12,gocats,gaelic,fwsadn,godboy,gldmeo,fx3tuo,fubar1,generals,gforce,rxmtkp,rulz,sairam,dunhill,dogggg,ozlq6qwm,ov3ajy,lockout,makayla,macgyver,mallorca,prima,pvjegu,qhxbij,prelude1,totoro,tusymo,trousers,tulane,turtle1,tracy1,aerosmit,abbey1,clticic,cooper1,comets,delpiero,cyprus,dante1,dave1,nounours,nexus6,nogard,norfolk,brent1,booyah,bootleg,bulls23,bulls1,booper,heretic,icecube,hellno,hounds,honeydew,hooters1,hoes,hevnm4,hugohugo,epson,evangeli,eeeee1,eyphed".split(","))),
-o("english",r("you,i,to,the,a,and,that,it,of,me,what,is,in,this,know,i'm,for,no,have,my,don't,just,not,do,be,on,your,was,we,it's,with,so,but,all,well,are,he,oh,about,right,you're,get,here,out,going,like,yeah,if,her,she,can,up,want,think,that's,now,go,him,at,how,got,there,one,did,why,see,come,good,they,really,as,would,look,when,time,will,okay,back,can't,mean,tell,i'll,from,hey,were,he's,could,didn't,yes,his,been,or,something,who,because,some,had,then,say,ok,take,an,way,us,little,make,need,gonna,never,we're,too,she's,i've,sure,them,more,over,our,sorry,where,what's,let,thing,am,maybe,down,man,has,uh,very,by,there's,should,anything,said,much,any,life,even,off,doing,thank,give,only,thought,help,two,talk,people,god,still,wait,into,find,nothing,again,things,let's,doesn't,call,told,great,before,better,ever,night,than,away,first,believe,other,feel,everything,work,you've,fine,home,after,last,these,day,keep,does,put,around,stop,they're,i'd,guy,isn't,always,listen,wanted,mr,guys,huh,those,big,lot,happened,thanks,won't,trying,kind,wrong,through,talking,made,new,being,guess,hi,care,bad,mom,remember,getting,we'll,together,dad,leave,place,understand,wouldn't,actually,hear,baby,nice,father,else,stay,done,wasn't,their,course,might,mind,every,enough,try,hell,came,someone,you'll,own,family,whole,another,house,yourself,idea,ask,best,must,coming,old,looking,woman,which,years,room,left,knew,tonight,real,son,hope,name,same,went,um,hmm,happy,pretty,saw,girl,sir,show,friend,already,saying,next,three,job,problem,minute,found,world,thinking,haven't,heard,honey,matter,myself,couldn't,exactly,having,ah,probably,happen,we've,hurt,boy,both,while,dead,gotta,alone,since,excuse,start,kill,hard,you'd,today,car,ready,until,without,wants,hold,wanna,yet,seen,deal,took,once,gone,called,morning,supposed,friends,head,stuff,most,used,worry,second,part,live,truth,school,face,forget,true,business,each,cause,soon,knows,few,telling,wife,who's,use,chance,run,move,anyone,person,bye,somebody,dr,heart,such,miss,married,point,later,making,meet,anyway,many,phone,reason,damn,lost,looks,bring,case,turn,wish,tomorrow,kids,trust,check,change,end,late,anymore,five,least,town,aren't,ha,working,year,makes,taking,means,brother,play,hate,ago,says,beautiful,gave,fact,crazy,party,sit,open,afraid,between,important,rest,fun,kid,word,watch,glad,everyone,days,sister,minutes,everybody,bit,couple,whoa,either,mrs,feeling,daughter,wow,gets,asked,under,break,promise,door,set,close,hand,easy,question,tried,far,walk,needs,mine,though,times,different,killed,hospital,anybody,alright,wedding,shut,able,die,perfect,stand,comes,hit,story,ya,mm,waiting,dinner,against,funny,husband,almost,pay,answer,four,office,eyes,news,child,shouldn't,half,side,yours,moment,sleep,read,where's,started,men,sounds,sonny,pick,sometimes,em,bed,also,date,line,plan,hours,lose,hands,serious,behind,inside,high,ahead,week,wonderful,fight,past,cut,quite,number,he'll,sick,it'll,game,eat,nobody,goes,along,save,seems,finally,lives,worried,upset,carly,met,book,brought,seem,sort,safe,living,children,weren't,leaving,front,shot,loved,asking,running,clear,figure,hot,felt,six,parents,drink,absolutely,how's,daddy,alive,sense,meant,happens,special,bet,blood,ain't,kidding,lie,full,meeting,dear,seeing,sound,fault,water,ten,women,buy,months,hour,speak,lady,jen,thinks,christmas,body,order,outside,hang,possible,worse,company,mistake,ooh,handle,spend,totally,giving,control,here's,marriage,realize,president,unless,sex,send,needed,taken,died,scared,picture,talked,ass,hundred,changed,completely,explain,playing,certainly,sign,boys,relationship,loves,hair,lying,choice,anywhere,future,weird,luck,she'll,turned,known,touch,kiss,crane,questions,obviously,wonder,pain,calling,somewhere,throw,straight,cold,fast,words,food,none,drive,feelings,they'll,worked,marry,light,drop,cannot,sent,city,dream,protect,twenty,class,surprise,its,sweetheart,poor,looked,mad,except,gun,y'know,dance,takes,appreciate,especially,situation,besides,pull,himself,hasn't,act,worth,sheridan,amazing,top,given,expect,rather,involved,swear,piece,busy,law,decided,happening,movie,we'd,catch,country,less,perhaps,step,fall,watching,kept,darling,dog,win,air,honor,personal,moving,till,admit,problems,murder,he'd,evil,definitely,feels,information,honest,eye,broke,missed,longer,dollars,tired,evening,human,starting,red,entire,trip,club,niles,suppose,calm,imagine,fair,caught,blame,street,sitting,favor,apartment,court,terrible,clean,learn,works,frasier,relax,million,accident,wake,prove,smart,message,missing,forgot,interested,table,nbsp,become,mouth,pregnant,middle,ring,careful,shall,team,ride,figured,wear,shoot,stick,follow,angry,instead,write,stopped,early,ran,war,standing,forgive,jail,wearing,kinda,lunch,cristian,eight,greenlee,gotten,hoping,phoebe,thousand,ridge,paper,tough,tape,state,count,boyfriend,proud,agree,birthday,seven,they've,history,share,offer,hurry,feet,wondering,decision,building,ones,finish,voice,herself,would've,list,mess,deserve,evidence,cute,dress,interesting,hotel,quiet,concerned,road,staying,beat,sweetie,mention,clothes,finished,fell,neither,mmm,fix,respect,spent,prison,attention,holding,calls,near,surprised,bar,keeping,gift,hadn't,putting,dark,self,owe,using,ice,helping,normal,aunt,lawyer,apart,certain,plans,jax,girlfriend,floor,whether,everything's,present,earth,box,cover,judge,upstairs,sake,mommy,possibly,worst,station,acting,accept,blow,strange,saved,conversation,plane,mama,yesterday,lied,quick,lately,stuck,report,difference,rid,store,she'd,bag,bought,doubt,listening,walking,cops,deep,dangerous,buffy,sleeping,chloe,rafe,shh,record,lord,moved,join,card,crime,gentlemen,willing,window,return,walked,guilty,likes,fighting,difficult,soul,joke,favorite,uncle,promised,public,bother,island,seriously,cell,lead,knowing,broken,advice,somehow,paid,losing,push,helped,killing,usually,earlier,boss,beginning,liked,innocent,doc,rules,cop,learned,thirty,risk,letting,speaking,officer,ridiculous,support,afternoon,born,apologize,seat,nervous,across,song,charge,patient,boat,how'd,hide,detective,planning,nine,huge,breakfast,horrible,age,awful,pleasure,driving,hanging,picked,sell,quit,apparently,dying,notice,congratulations,chief,one's,month,visit,could've,c'mon,letter,decide,double,sad,press,forward,fool,showed,smell,seemed,spell,memory,pictures,slow,seconds,hungry,board,position,hearing,roz,kitchen,ma'am,force,fly,during,space,should've,realized,experience,kick,others,grab,mother's,discuss,third,cat,fifty,responsible,fat,reading,idiot,yep,suddenly,agent,destroy,bucks,track,shoes,scene,peace,arms,demon,low,livvie,consider,papers,medical,incredible,witch,drunk,attorney,tells,knock,ways,gives,department,nose,skye,turns,keeps,jealous,drug,sooner,cares,plenty,extra,tea,won,attack,ground,whose,outta,weekend,matters,wrote,type,father's,gosh,opportunity,impossible,books,waste,pretend,named,jump,eating,proof,complete,slept,career,arrest,breathe,perfectly,warm,pulled,twice,easier,goin,dating,suit,romantic,drugs,comfortable,finds,checked,fit,divorce,begin,ourselves,closer,ruin,although,smile,laugh,treat,god's,fear,what'd,guy's,otherwise,excited,mail,hiding,cost,stole,pacey,noticed,fired,excellent,lived,bringing,pop,bottom,note,sudden,bathroom,flight,honestly,sing,foot,games,remind,bank,charges,witness,finding,places,tree,dare,hardly,that'll,interest,steal,silly,contact,teach,shop,plus,colonel,fresh,trial,invited,roll,radio,reach,heh,choose,emergency,dropped,credit,obvious,cry,locked,loving,positive,nuts,agreed,prue,goodbye,condition,guard,fuckin,grow,cake,mood,dad's,total,crap,crying,belong,lay,partner,trick,pressure,ohh,arm,dressed,cup,lies,bus,taste,neck,south,something's,nurse,raise,lots,carry,group,whoever,drinking,they'd,breaking,file,lock,wine,closed,writing,spot,paying,study,assume,asleep,man's,turning,legal,viki,bedroom,shower,nikolas,camera,fill,reasons,forty,bigger,nope,breath,doctors,pants,level,movies,gee,area,folks,ugh,continue,focus,wild,truly,desk,convince,client,threw,band,hurts,spending,allow,grand,answers,shirt,chair,allowed,rough,doin,sees,government,ought,empty,round,hat,wind,shows,aware,dealing,pack,meaning,hurting,ship,subject,guest,mom's,pal,match,arrested,salem,confused,surgery,expecting,deacon,unfortunately,goddamn,lab,passed,bottle,beyond,whenever,pool,opinion,held,common,starts,jerk,secrets,falling,played,necessary,barely,dancing,health,tests,copy,cousin,planned,dry,ahem,twelve,simply,tess,skin,often,fifteen,speech,names,issue,orders,nah,final,results,code,believed,complicated,umm,research,nowhere,escape,biggest,restaurant,grateful,usual,burn,address,within,someplace,screw,everywhere,train,film,regret,goodness,mistakes,details,responsibility,suspect,corner,hero,dumb,terrific,further,gas,whoo,hole,memories,o'clock,following,ended,nobody's,teeth,ruined,split,airport,bite,stenbeck,older,liar,showing,project,cards,desperate,themselves,pathetic,damage,spoke,quickly,scare,marah,afford,vote,settle,mentioned,due,stayed,rule,checking,tie,hired,upon,heads,concern,blew,natural,alcazar,champagne,connection,tickets,happiness,form,saving,kissing,hated,personally,suggest,prepared,build,leg,onto,leaves,downstairs,ticket,it'd,taught,loose,holy,staff,sea,duty,convinced,throwing,defense,kissed,legs,according,loud,practice,saturday,babies,army,where'd,warning,miracle,carrying,flying,blind,ugly,shopping,hates,someone's,sight,bride,coat,account,states,clearly,celebrate,brilliant,wanting,add,forrester,lips,custody,center,screwed,buying,size,toast,thoughts,student,stories,however,professional,reality,birth,lexie,attitude,advantage,grandfather,sami,sold,opened,grandma,beg,changes,someday,grade,roof,brothers,signed,ahh,marrying,powerful,grown,grandmother,fake,opening,expected,eventually,must've,ideas,exciting,covered,familiar,bomb,bout,television,harmony,color,heavy,schedule,records,capable,practically,including,correct,clue,forgotten,immediately,appointment,social,nature,deserves,threat,bloody,lonely,ordered,shame,local,jacket,hook,destroyed,scary,investigation,above,invite,shooting,port,lesson,criminal,growing,caused,victim,professor,followed,funeral,nothing's,considering,burning,strength,loss,view,gia,sisters,everybody's,several,pushed,written,somebody's,shock,pushing,heat,chocolate,greatest,miserable,corinthos,nightmare,brings,zander,character,became,famous,enemy,crash,chances,sending,recognize,healthy,boring,feed,engaged,percent,headed,lines,treated,purpose,knife,rights,drag,san,fan,badly,hire,paint,pardon,built,behavior,closet,warn,gorgeous,milk,survive,forced,operation,offered,ends,dump,rent,remembered,lieutenant,trade,thanksgiving,rain,revenge,physical,available,program,prefer,baby's,spare,pray,disappeared,aside,statement,sometime,meat,fantastic,breathing,laughing,itself,tip,stood,market,affair,ours,depends,main,protecting,jury,national,brave,large,jack's,interview,fingers,murdered,explanation,process,picking,based,style,pieces,blah,assistant,stronger,aah,pie,handsome,unbelievable,anytime,nearly,shake,everyone's,oakdale,cars,wherever,serve,pulling,points,medicine,facts,waited,lousy,circumstances,stage,disappointed,weak,trusted,license,nothin,community,trash,understanding,slip,cab,sounded,awake,friendship,stomach,weapon,threatened,mystery,official,regular,river,vegas,understood,contract,race,basically,switch,frankly,issues,cheap,lifetime,deny,painting,ear,clock,weight,garbage,why'd,tear,ears,dig,selling,setting,indeed,changing,singing,tiny,particular,draw,decent,avoid,messed,filled,touched,score,people's,disappear,exact,pills,kicked,harm,recently,fortune,pretending,raised,insurance,fancy,drove,cared,belongs,nights,shape,lorelai,base,lift,stock,sonny's,fashion,timing,guarantee,chest,bridge,woke,source,patients,theory,original,burned,watched,heading,selfish,oil,drinks,failed,period,doll,committed,elevator,freeze,noise,exist,science,pair,edge,wasting,sat,ceremony,pig,uncomfortable,peg,guns,staring,files,bike,weather,name's,mostly,stress,permission,arrived,thrown,possibility,example,borrow,release,ate,notes,hoo,library,property,negative,fabulous,event,doors,screaming,xander,term,what're,meal,fellow,apology,anger,honeymoon,wet,bail,parking,non,protection,fixed,families,chinese,campaign,map,wash,stolen,sensitive,stealing,chose,lets,comfort,worrying,whom,pocket,mateo,bleeding,students,shoulder,ignore,fourth,neighborhood,fbi,talent,tied,garage,dies,demons,dumped,witches,training,rude,crack,model,bothering,radar,grew,remain,soft,meantime,gimme,connected,kinds,cast,sky,likely,fate,buried,hug,brother's,concentrate,prom,messages,east,unit,intend,crew,ashamed,somethin,manage,guilt,weapons,terms,interrupt,guts,tongue,distance,conference,treatment,shoe,basement,sentence,purse,glasses,cabin,universe,towards,repeat,mirror,wound,travers,tall,reaction,odd,engagement,therapy,letters,emotional,runs,magazine,jeez,decisions,soup,daughter's,thrilled,society,managed,stake,chef,moves,extremely,entirely,moments,expensive,counting,shots,kidnapped,square,son's,cleaning,shift,plate,impressed,smells,trapped,male,tour,aidan,knocked,charming,attractive,argue,puts,whip,language,embarrassed,settled,package,laid,animals,hitting,disease,bust,stairs,alarm,pure,nail,nerve,incredibly,walks,dirt,stamp,sister's,becoming,terribly,friendly,easily,damned,jobs,suffering,disgusting,stopping,deliver,riding,helps,federal,disaster,bars,dna,crossed,rate,create,trap,claim,california,talks,eggs,effect,chick,threatening,spoken,introduce,confession,embarrassing,bags,impression,gate,year's,reputation,attacked,among,knowledge,presents,inn,europe,chat,suffer,argument,talkin,crowd,homework,fought,coincidence,cancel,accepted,rip,pride,solve,hopefully,pounds,pine,mate,illegal,generous,streets,con,separate,outfit,maid,bath,punch,mayor,freaked,begging,recall,enjoying,bug,woman's,prepare,parts,wheel,signal,direction,defend,signs,painful,yourselves,rat,maris,amount,that'd,suspicious,flat,cooking,button,warned,sixty,pity,parties,crisis,coach,row,yelling,leads,awhile,pen,confidence,offering,falls,image,farm,pleased,panic,hers,gettin,role,refuse,determined,hell's,grandpa,progress,testify,passing,military,choices,uhh,gym,cruel,wings,bodies,mental,gentleman,coma,cutting,proteus,guests,girl's,expert,benefit,faces,cases,led,jumped,toilet,secretary,sneak,mix,firm,halloween,agreement,privacy,dates,anniversary,smoking,reminds,pot,created,twins,swing,successful,season,scream,considered,solid,options,commitment,senior,ill,else's,crush,ambulance,wallet,discovered,officially,til,rise,reached,eleven,option,laundry,former,assure,stays,skip,fail,accused,wide,challenge,popular,learning,discussion,clinic,plant,exchange,betrayed,bro,sticking,university,members,lower,bored,mansion,soda,sheriff,suite,handled,busted,senator,load,happier,younger,studying,romance,procedure,ocean,section,sec,commit,assignment,suicide,minds,swim,ending,bat,yell,llanview,league,chasing,seats,proper,command,believes,humor,hopes,fifth,winning,solution,leader,theresa's,sale,lawyers,nor,material,latest,highly,escaped,audience,parent,tricks,insist,dropping,cheer,medication,higher,flesh,district,routine,century,shared,sandwich,handed,false,beating,appear,warrant,family's,awfully,odds,article,treating,thin,suggesting,fever,sweat,silent,specific,clever,sweater,request,prize,mall,tries,mile,fully,estate,union,sharing,assuming,judgment,goodnight,divorced,despite,surely,steps,jet,confess,math,listened,comin,answered,vulnerable,bless,dreaming,rooms,chip,zero,potential,pissed,nate,kills,tears,knees,chill,carly's,brains,agency,harvard,degree,unusual,wife's,joint,packed,dreamed,cure,covering,newspaper,lookin,coast,grave,egg,direct,cheating,breaks,quarter,mixed,locker,husband's,gifts,awkward,toy,thursday,rare,policy,kid's,joking,competition,classes,assumed,reasonable,dozen,curse,quartermaine,millions,dessert,rolling,detail,alien,served,delicious,closing,vampires,released,ancient,wore,value,tail,secure,salad,murderer,hits,toward,spit,screen,offense,dust,conscience,bread,answering,admitted,lame,invitation,grief,smiling,path,stands,bowl,pregnancy,hollywood,prisoner,delivery,guards,virus,shrink,influence,freezing,concert,wreck,partners,massimo,chain,birds,life's,wire,technically,presence,blown,anxious,cave,version,holidays,cleared,wishes,survived,caring,candles,bound,related,charm,yup,pulse,jumping,jokes,frame,boom,vice,performance,occasion,silence,opera,nonsense,frightened,downtown,americans,slipped,dimera,blowing,world's,session,relationships,kidnapping,actual,spin,civil,roxy,packing,education,blaming,wrap,obsessed,fruit,torture,personality,location,effort,daddy's,commander,trees,there'll,owner,fairy,per,other's,necessarily,county,contest,seventy,print,motel,fallen,directly,underwear,grams,exhausted,believing,particularly,freaking,carefully,trace,touching,messing,committee,recovery,intention,consequences,belt,sacrifice,courage,officers,enjoyed,lack,attracted,appears,bay,yard,returned,remove,nut,carried,today's,testimony,intense,granted,violence,heal,defending,attempt,unfair,relieved,political,loyal,approach,slowly,plays,normally,buzz,alcohol,actor,surprises,psychiatrist,pre,plain,attic,who'd,uniform,terrified,sons,pet,cleaned,zach,threaten,teaching,mum,motion,fella,enemies,desert,collection,incident,failure,satisfied,imagination,hooked,headache,forgetting,counselor,andie,acted,opposite,highest,equipment,badge,italian,visiting,naturally,frozen,commissioner,sakes,labor,appropriate,trunk,armed,thousands,received,dunno,costume,temporary,sixteen,impressive,zone,kicking,junk,hon,grabbed,unlike,understands,describe,clients,owns,affect,witnesses,starving,instincts,happily,discussing,deserved,strangers,leading,intelligence,host,authority,surveillance,cow,commercial,admire,questioning,fund,dragged,barn,object,deeply,amp,wrapped,wasted,tense,route,reports,hoped,fellas,election,roommate,mortal,fascinating,chosen,stops,shown,arranged,abandoned,sides,delivered,becomes,arrangements,agenda,began,theater,series,literally,propose,honesty,underneath,forces,services,sauce,promises,lecture,eighty,torn,shocked,relief,explained,counter,circle,victims,transfer,response,channel,identity,differently,campus,spy,ninety,interests,guide,deck,biological,pheebs,ease,creep,will's,waitress,skills,telephone,ripped,raising,scratch,rings,prints,wave,thee,arguing,figures,ephram,asks,reception,pin,oops,diner,annoying,agents,taggert,goal,mass,ability,sergeant,julian's,international,gig,blast,basic,tradition,towel,earned,rub,president's,habit,customers,creature,bermuda,actions,snap,react,prime,paranoid,wha,handling,eaten,therapist,comment,charged,tax,sink,reporter,beats,priority,interrupting,gain,fed,warehouse,shy,pattern,loyalty,inspector,events,pleasant,media,excuses,threats,permanent,guessing,financial,demand,assault,tend,praying,motive,los,unconscious,trained,museum,tracks,range,nap,mysterious,unhappy,tone,switched,rappaport,award,sookie,neighbor,loaded,gut,childhood,causing,swore,piss,hundreds,balance,background,toss,mob,misery,valentine's,thief,squeeze,lobby,hah,goa'uld,geez,exercise,ego,drama,al's,forth,facing,booked,boo,songs,sandburg,eighteen,d'you,bury,perform,everyday,digging,creepy,compared,wondered,trail,liver,hmmm,drawn,device,magical,journey,fits,discussed,supply,moral,helpful,attached,timmy's,searching,flew,depressed,aisle,underground,pro,daughters,cris,amen,vows,proposal,pit,neighbors,darn,cents,arrange,annulment,uses,useless,squad,represent,product,joined,afterwards,adventure,resist,protected,net,fourteen,celebrating,piano,inch,flag,debt,violent,tag,sand,gum,dammit,teal'c,hip,celebration,below,reminded,claims,tonight's,replace,phones,paperwork,emotions,typical,stubborn,stable,sheridan's,pound,papa,lap,designed,current,bum,tension,tank,suffered,steady,provide,overnight,meanwhile,chips,beef,wins,suits,boxes,salt,cassadine,collect,boy's,tragedy,therefore,spoil,realm,profile,degrees,wipe,surgeon,stretch,stepped,nephew,neat,limo,confident,anti,perspective,designer,climb,title,suggested,punishment,finest,ethan's,springfield,occurred,hint,furniture,blanket,twist,surrounded,surface,proceed,lip,fries,worries,refused,niece,gloves,soap,signature,disappoint,crawl,convicted,zoo,result,pages,lit,flip,counsel,doubts,crimes,accusing,when's,shaking,remembering,phase,hallway,halfway,bothered,useful,makeup,madam,gather,concerns,cia,cameras,blackmail,symptoms,rope,ordinary,imagined,concept,cigarette,supportive,memorial,explosion,yay,woo,trauma,ouch,leo's,furious,cheat,avoiding,whew,thick,oooh,boarding,approve,urgent,shhh,misunderstanding,minister,drawer,sin,phony,joining,jam,interfere,governor,chapter,catching,bargain,tragic,schools,respond,punish,penthouse,hop,thou,remains,rach,ohhh,insult,doctor's,bugs,beside,begged,absolute,strictly,stefano,socks,senses,ups,sneaking,yah,serving,reward,polite,checks,tale,physically,instructions,fooled,blows,tabby,internal,bitter,adorable,y'all,tested,suggestion,string,jewelry,debate,com,alike,pitch,fax,distracted,shelter,lessons,foreign,average,twin,friend's,damnit,constable,circus,audition,tune,shoulders,mud,mask,helpless,feeding,explains,dated,robbery,objection,behave,valuable,shadows,courtroom,confusing,tub,talented,struck,smarter,mistaken,italy,customer,bizarre,scaring,punk,motherfucker,holds,focused,alert,activity,vecchio,reverend,highway,foolish,compliment,bastards,attend,scheme,aid,worker,wheelchair,protective,poetry,gentle,script,reverse,picnic,knee,intended,construction,cage,wednesday,voices,toes,stink,scares,pour,effects,cheated,tower,time's,slide,ruining,recent,jewish,filling,exit,cottage,corporate,upside,supplies,proves,parked,instance,grounds,diary,complaining,basis,wounded,thing's,politics,confessed,pipe,merely,massage,data,chop,budget,brief,spill,prayer,costs,betray,begins,arrangement,waiter,scam,rats,fraud,flu,brush,anyone's,adopted,tables,sympathy,pill,pee,web,seventeen,landed,expression,entrance,employee,drawing,cap,bracelet,principal,pays,jen's,fairly,facility,dru,deeper,arrive,unique,tracking,spite,shed,recommend,oughta,nanny,naive,menu,grades,diet,corn,authorities,separated,roses,patch,dime,devastated,description,tap,subtle,include,citizen,bullets,beans,ric,pile,las,executive,confirm,toe,strings,parade,harbor,charity's,bow,borrowed,toys,straighten,steak,status,remote,premonition,poem,planted,honored,youth,specifically,meetings,exam,convenient,traveling,matches,laying,insisted,apply,units,technology,dish,aitoro,sis,kindly,grandson,donor,temper,teenager,strategy,richard's,proven,iron,denial,couples,backwards,tent,swell,noon,happiest,episode,drives,thinkin,spirits,potion,fence,affairs,acts,whatsoever,rehearsal,proved,overheard,nuclear,lemme,hostage,faced,constant,bench,tryin,taxi,shove,sets,moron,limits,impress,entitled,needle,limit,lad,intelligent,instant,forms,disagree,stinks,rianna,recover,paul's,losers,groom,gesture,developed,constantly,blocks,bartender,tunnel,suspects,sealed,removed,legally,illness,hears,dresses,aye,vehicle,thy,teachers,sheet,receive,psychic,night's,denied,knocking,judging,bible,behalf,accidentally,waking,ton,superior,seek,rumor,natalie's,manners,homeless,hollow,desperately,critical,theme,tapes,referring,personnel,item,genoa,gear,majesty,fans,exposed,cried,tons,spells,producer,launch,instinct,belief,quote,motorcycle,convincing,appeal,advance,greater,fashioned,aids,accomplished,mommy's,grip,bump,upsetting,soldiers,scheduled,production,needing,invisible,forgiveness,feds,complex,compare,bothers,tooth,territory,sacred,mon,jessica's,inviting,inner,earn,compromise,cocktail,tramp,temperature,signing,landing,jabot,intimate,dignity,dealt,souls,informed,gods,entertainment,dressing,cigarettes,blessing,billion,alistair,upper,manner,lightning,leak,heaven's,fond,corky,alternative,seduce,players,operate,modern,liquor,fingerprints,enchantment,butters,stuffed,stavros,rome,filed,emotionally,division,conditions,uhm,transplant,tips,passes,oxygen,nicely,lunatic,hid,drill,designs,complain,announcement,visitors,unfortunate,slap,prayers,plug,organization,opens,oath,o'neill,mutual,graduate,confirmed,broad,yacht,spa,remembers,fried,extraordinary,bait,appearance,abuse,warton,sworn,stare,safely,reunion,plot,burst,aha,might've,experiment,dive,commission,cells,aboard,returning,independent,expose,environment,buddies,trusting,smaller,mountains,booze,sweep,sore,scudder,properly,parole,manhattan,effective,ditch,decides,canceled,bra,antonio's,speaks,spanish,reaching,glow,foundation,women's,wears,thirsty,skull,ringing,dorm,dining,bend,unexpected,systems,sob,pancakes,michael's,harsh,flattered,existence,ahhh,troubles,proposed,fights,favourite,eats,driven,computers,rage,luke's,causes,border,undercover,spoiled,sloane,shine,rug,identify,destroying,deputy,deliberately,conspiracy,clothing,thoughtful,similar,sandwiches,plates,nails,miracles,investment,fridge,drank,contrary,beloved,allergic,washed,stalking,solved,sack,misses,hope's,forgiven,erica's,cuz,bent,approval,practical,organized,maciver,involve,industry,fuel,dragging,cooked,possession,pointing,foul,editor,dull,beneath,ages,horror,heels,grass,faking,deaf,stunt,portrait,painted,jealousy,hopeless,fears,cuts,conclusion,volunteer,scenario,satellite,necklace,men's,crashed,chapel,accuse,restraining,jason's,humans,homicide,helicopter,formal,firing,shortly,safer,devoted,auction,videotape,tore,stores,reservations,pops,appetite,anybody's,wounds,vanquish,symbol,prevent,patrol,ironic,flow,fathers,excitement,anyhow,tearing,sends,sam's,rape,laughed,function,core,charmed,whatever's,sub,lucy's,dealer,cooperate,bachelor,accomplish,wakes,struggle,spotted,sorts,reservation,ashes,yards,votes,tastes,supposedly,loft,intentions,integrity,wished,towels,suspected,slightly,qualified,log,investigating,inappropriate,immediate,companies,backed,pan,owned,lipstick,lawn,compassion,cafeteria,belonged,affected,scarf,precisely,obsession,management,loses,lighten,jake's,infection,granddaughter,explode,chemistry,balcony,this'll,storage,spying,publicity,exists,employees,depend,cue,cracked,conscious,aww,ally,ace,accounts,absurd,vicious,tools,strongly,rap,invented,forbid,directions,defendant,bare,announce,alcazar's,screwing,salesman,robbed,leap,lakeview,insanity,injury,genetic,document,why's,reveal,religious,possibilities,kidnap,gown,entering,chairs,wishing,statue,setup,serial,punished,dramatic,dismissed,criminals,seventh,regrets,raped,quarters,produce,lamp,dentist,anyways,anonymous,added,semester,risks,regarding,owes,magazines,machines,lungs,explaining,delicate,child's,tricked,oldest,liv,eager,doomed,cafe,bureau,adoption,traditional,surrender,stab,sickness,scum,loop,independence,generation,floating,envelope,entered,combination,chamber,worn,vault,sorel,pretended,potatoes,plea,photograph,payback,misunderstood,kiddo,healing,cascade,capeside,application,stabbed,remarkable,cabinet,brat,wrestling,sixth,scale,privilege,passionate,nerves,lawsuit,kidney,disturbed,crossing,cozy,associate,tire,shirts,required,posted,oven,ordering,mill,journal,gallery,delay,clubs,risky,nest,monsters,honorable,grounded,favour,culture,closest,brenda's,breakdown,attempted,tony's,placed,conflict,bald,actress,abandon,steam,scar,pole,duh,collar,worthless,standards,resources,photographs,introduced,injured,graduation,enormous,disturbing,disturb,distract,deals,conclusions,vodka,situations,require,mid,measure,dishes,crawling,congress,children's,briefcase,wiped,whistle,sits,roast,rented,pigs,greek,flirting,existed,deposit,damaged,bottles,vanessa's,types,topic,riot,overreacting,minimum,logical,impact,hostile,embarrass,casual,beacon,amusing,altar,values,recognized,maintain,goods,covers,claus,battery,survival,skirt,shave,prisoners,porch,med,ghosts,favors,drops,dizzy,chili,begun,beaten,advise,transferred,strikes,rehab,raw,photographer,peaceful,leery,heavens,fortunately,fooling,expectations,draft,citizens,weakness,ski,ships,ranch,practicing,musical,movement,individual,homes,executed,examine,documents,cranes,column,bribe,task,species,sail,rum,resort,prescription,operating,hush,fragile,forensics,expense,drugged,differences,cows,conduct,comic,bells,avenue,attacking,assigned,visitor,suitcase,sources,sorta,scan,payment,motor,mini,manticore,inspired,insecure,imagining,hardest,clerk,yea,wrist,what'll,tube,starters,silk,pump,pale,nicer,haul,flies,demands,boot,arts,african,there'd,limited,how're,elders,connections,quietly,pulls,idiots,factor,erase,denying,attacks,ankle,amnesia,accepting,ooo,heartbeat,gal,devane,confront,backing,phrase,operations,minus,meets,legitimate,hurricane,fixing,communication,boats,auto,arrogant,supper,studies,slightest,sins,sayin,recipe,pier,paternity,humiliating,genuine,catholic,snack,rational,pointed,minded,guessed,grace's,display,dip,brooke's,advanced,weddings,unh,tumor,teams,reported,humiliated,destruction,copies,closely,bid,aspirin,academy,wig,throughout,spray,occur,logic,eyed,equal,drowning,contacts,shakespeare,ritual,perfume,kelly's,hiring,hating,generally,error,elected,docks,creatures,visions,thanking,thankful,sock,replaced,nineteen,nick's,fork,comedy,analysis,yale,throws,teenagers,studied,stressed,slice,rolls,requires,plead,ladder,kicks,detectives,assured,alison's,widow,tomorrow's,tissue,tellin,shallow,responsibilities,repay,rejected,permanently,girlfriends,deadly,comforting,ceiling,bonus,verdict,maintenance,jar,insensitive,factory,aim,triple,spilled,respected,recovered,messy,interrupted,halliwell,car's,bleed,benefits,wardrobe,takin,significant,objective,murders,doo,chart,backs,workers,waves,underestimate,ties,registered,multiple,justify,harmless,frustrated,fold,enzo,convention,communicate,bugging,attraction,arson,whack,salary,rumors,residence,party's,obligation,medium,liking,laura's,development,develop,dearest,david's,danny's,congratulate,vengeance,switzerland,severe,rack,puzzle,puerto,guidance,fires,courtesy,caller,blamed,tops,repair,quiz,prep,now's,involves,headquarters,curiosity,codes,circles,barbecue,troops,sunnydale,spinning,scores,pursue,psychotic,cough,claimed,accusations,shares,resent,money's,laughs,gathered,freshman,envy,drown,cristian's,bartlet,asses,sofa,scientist,poster,islands,highness,dock,apologies,welfare,victor's,theirs,stat,stall,spots,somewhat,ryan's,realizes,psych,fools,finishing,album,wee,understandable,unable,treats,theatre,succeed,stir,relaxed,makin,inches,gratitude,faithful,bin,accent,zip,witter,wandering,regardless,que,locate,inevitable,gretel,deed,crushed,controlling,taxes,smelled,settlement,robe,poet,opposed,marked,greenlee's,gossip,gambling,determine,cuba,cosmetics,cent,accidents,surprising,stiff,sincere,shield,rushed,resume,reporting,refrigerator,reference,preparing,nightmares,mijo,ignoring,hunch,fog,fireworks,drowned,crown,cooperation,brass,accurate,whispering,sophisticated,religion,luggage,investigate,hike,explore,emotion,creek,crashing,contacted,complications,ceo,acid,shining,rolled,righteous,reconsider,inspiration,goody,geek,frightening,festival,ethics,creeps,courthouse,camping,assistance,affection,vow,smythe,protest,lodge,haircut,forcing,essay,chairman,baked,apologized,vibe,respects,receipt,mami,includes,hats,exclusive,destructive,define,defeat,adore,adopt,voted,tracked,signals,shorts,rory's,reminding,relative,ninth,floors,dough,creations,continues,cancelled,cabot,barrel,adam's,snuck,slight,reporters,rear,pressing,novel,newspapers,magnificent,madame,lazy,glorious,fiancee,candidate,brick,bits,australia,activities,visitation,scholarship,sane,previous,kindness,ivy's,shoulda,rescued,mattress,maria's,lounge,lifted,label,importantly,glove,enterprises,driver's,disappointment,condo,cemetery,beings,admitting,yelled,waving,screech,satisfaction,requested,reads,plants,nun,nailed,described,dedicated,certificate,centuries,annual,worm,tick,resting,primary,polish,marvelous,fuss,funds,defensive,cortlandt,compete,chased,provided,pockets,luckily,lilith,filing,depression,conversations,consideration,consciousness,worlds,innocence,indicate,grandmother's,forehead,bam,appeared,aggressive,trailer,slam,retirement,quitting,pry,person's,narrow,levels,kay's,inform,encourage,dug,delighted,daylight,danced,currently,confidential,billy's,ben's,aunts,washing,vic,tossed,spectra,rick's,permit,marrow,lined,implying,hatred,grill,efforts,corpse,clues,sober,relatives,promotion,offended,morgue,larger,infected,humanity,eww,emily's,electricity,electrical,distraction,cart,broadcast,wired,violation,suspended,promising,harassment,glue,gathering,d'angelo,cursed,controlled,calendar,brutal,assets,warlocks,wagon,unpleasant,proving,priorities,observation,mustn't,lease,grows,flame,domestic,disappearance,depressing,thrill,sitter,ribs,offers,naw,flush,exception,earrings,deadline,corporal,collapsed,update,snapped,smack,orleans,offices,melt,figuring,delusional,coulda,burnt,actors,trips,tender,sperm,specialist,scientific,realise,pork,popped,planes,kev,interrogation,institution,included,esteem,communications,choosing,choir,undo,pres,prayed,plague,manipulate,lifestyle,insulting,honour,detention,delightful,coffeehouse,chess,betrayal,apologizing,adjust,wrecked,wont,whipped,rides,reminder,psychological,principle,monsieur,injuries,fame,faint,confusion,christ's,bon,bake,nearest,korea,industries,execution,distress,definition,creating,correctly,complaint,blocked,trophy,tortured,structure,rot,risking,pointless,household,heir,handing,eighth,dumping,cups,chloe's,alibi,absence,vital,tokyo,thus,struggling,shiny,risked,refer,mummy,mint,joey's,involvement,hose,hobby,fortunate,fleischman,fitting,curtain,counseling,addition,wit,transport,technical,rode,puppet,opportunities,modeling,memo,irresponsible,humiliation,hiya,freakin,fez,felony,choke,blackmailing,appreciated,tabloid,suspicion,recovering,rally,psychology,pledge,panicked,nursery,louder,jeans,investigator,identified,homecoming,helena's,height,graduated,frustrating,fabric,distant,buys,busting,buff,wax,sleeve,products,philosophy,irony,hospitals,dope,declare,autopsy,workin,torch,substitute,scandal,prick,limb,leaf,lady's,hysterical,growth,goddamnit,fetch,dimension,day's,crowded,clip,climbing,bonding,approved,yeh,woah,ultimately,trusts,returns,negotiate,millennium,majority,lethal,length,iced,deeds,bore,babysitter,questioned,outrageous,medal,kiriakis,insulted,grudge,established,driveway,deserted,definite,capture,beep,wires,suggestions,searched,owed,originally,nickname,lighting,lend,drunken,demanding,costanza,conviction,characters,bumped,weigh,touches,tempted,shout,resolve,relate,poisoned,pip,phoebe's,pete's,occasionally,molly's,meals,maker,invitations,haunted,fur,footage,depending,bogus,autograph,affects,tolerate,stepping,spontaneous,sleeps,probation,presentation,performed,manny,identical,fist,cycle,associates,aaron's,streak,spectacular,sector,lasted,isaac's,increase,hostages,heroin,havin,habits,encouraging,cult,consult,burgers,boyfriends,bailed,baggage,association,wealthy,watches,versus,troubled,torturing,teasing,sweetest,stations,sip,shawn's,rag,qualities,postpone,pad,overwhelmed,malkovich,impulse,hut,follows,classy,charging,barbara's,angel's,amazed,scenes,rising,revealed,representing,policeman,offensive,mug,hypocrite,humiliate,hideous,finals,experiences,d'ya,courts,costumes,captured,bluffing,betting,bein,bedtime,alcoholic,vegetable,tray,suspicions,spreading,splendid,shouting,roots,pressed,nooo,liza's,jew,intent,grieving,gladly,fling,eliminate,disorder,courtney's,cereal,arrives,aaah,yum,technique,statements,sonofabitch,servant,roads,republican,paralyzed,orb,lotta,locks,guaranteed,european,dummy,discipline,despise,dental,corporation,carries,briefing,bluff,batteries,atmosphere,whatta,tux,sounding,servants,rifle,presume,kevin's,handwriting,goals,gin,fainted,elements,dried,cape,allright,allowing,acknowledge,whacked,toxic,skating,reliable,quicker,penalty,panel,overwhelming,nearby,lining,importance,harassing,fatal,endless,elsewhere,dolls,convict,bold,ballet,whatcha,unlikely,spiritual,shutting,separation,recording,positively,overcome,goddam,failing,essence,dose,diagnosis,cured,claiming,bully,airline,ahold,yearbook,various,tempting,shelf,rig,pursuit,prosecution,pouring,possessed,partnership,miguel's,lindsay's,countries,wonders,tsk,thorough,spine,rath,psychiatric,meaningless,latte,jammed,ignored,fiance,exposure,exhibit,evidently,duties,contempt,compromised,capacity,cans,weekends,urge,theft,suing,shipment,scissors,responding,refuses,proposition,noises,matching,located,ink,hormones,hiv,hail,grandchildren,godfather,gently,establish,crane's,contracts,compound,buffy's,worldwide,smashed,sexually,sentimental,senor,scored,patient's,nicest,marketing,manipulated,jaw,intern,handcuffs,framed,errands,entertaining,discovery,crib,carriage,barge,awards,attending,ambassador,videos,tab,spends,slipping,seated,rubbing,rely,reject,recommendation,reckon,ratings,headaches,float,embrace,corners,whining,sweating,sole,skipped,restore,receiving,population,pep,mountie,motives,mama's,listens,korean,heroes,heart's,cristobel,controls,cheerleader,balsom,unnecessary,stunning,shipping,scent,santa's,quartermaines,praise,pose,montega,luxury,loosen,kyle's,keri's,info,hum,haunt,gracious,git,forgiving,fleet,errand,emperor,cakes,blames,abortion,worship,theories,strict,sketch,shifts,plotting,physician,perimeter,passage,pals,mere,mattered,lonigan,longest,jews,interference,eyewitness,enthusiasm,encounter,diapers,craig's,artists,strongest,shaken,serves,punched,projects,portal,outer,nazi,hal's,colleagues,catches,bearing,backyard,academic,winds,terrorists,sabotage,pea,organs,needy,mentor,measures,listed,lex,cuff,civilization,caribbean,articles,writes,woof,who'll,viki's,valid,rarely,rabbi,prank,performing,obnoxious,mates,improve,hereby,gabby,faked,cellar,whitelighter,void,substance,strangle,sour,skill,senate,purchase,native,muffins,interfering,hoh,gina's,demonic,colored,clearing,civilian,buildings,boutique,barrington,trading,terrace,smoked,seed,righty,relations,quack,published,preliminary,petey,pact,outstanding,opinions,knot,ketchup,items,examined,disappearing,cordy,coin,circuit,assist,administration,walt,uptight,ticking,terrifying,tease,tabitha's,syd,swamp,secretly,rejection,reflection,realizing,rays,pennsylvania,partly,mentally,marone,jurisdiction,frasier's,doubted,deception,crucial,congressman,cheesy,arrival,visited,supporting,stalling,scouts,scoop,ribbon,reserve,raid,notion,income,immune,grandma's,expects,edition,destined,constitution,classroom,bets,appreciation,appointed,accomplice,whitney's,wander,shoved,sewer,scroll,retire,paintings,lasts,fugitive,freezer,discount,cranky,crank,clearance,bodyguard,anxiety,accountant,abby's,whoops,volunteered,terrorist,tales,talents,stinking,resolved,remotely,protocol,livvie's,garlic,decency,cord,beds,asa's,areas,altogether,uniforms,tremendous,restaurants,rank,profession,popping,philadelphia,outa,observe,lung,largest,hangs,feelin,experts,enforcement,encouraged,economy,dudes,donation,disguise,diane's,curb,continued,competitive,businessman,bites,antique,advertising,ads,toothbrush,retreat,represents,realistic,profits,predict,nora's,lid,landlord,hourglass,hesitate,frank's,focusing,equally,consolation,boyfriend's,babbling,aged,troy's,tipped,stranded,smartest,sabrina's,rhythm,replacement,repeating,puke,psst,paycheck,overreacted,macho,leadership,kendall's,juvenile,john's,images,grocery,freshen,disposal,cuffs,consent,caffeine,arguments,agrees,abigail's,vanished,unfinished,tobacco,tin,syndrome,ripping,pinch,missiles,isolated,flattering,expenses,dinners,cos,colleague,ciao,buh,belthazor,belle's,attorneys,amber's,woulda,whereabouts,wars,waitin,visits,truce,tripped,tee,tasted,stu,steer,ruling,poisoning,nursing,manipulative,immature,husbands,heel,granddad,delivering,deaths,condoms,automatically,anchor,trashed,tournament,throne,raining,prices,pasta,needles,leaning,leaders,judges,ideal,detector,coolest,casting,batch,approximately,appointments,almighty,achieve,vegetables,sum,spark,ruled,revolution,principles,perfection,pains,momma,mole,interviews,initiative,hairs,getaway,employment,den,cracking,counted,compliments,behold,verge,tougher,timer,tapped,taped,stakes,specialty,snooping,shoots,semi,rendezvous,pentagon,passenger,leverage,jeopardize,janitor,grandparents,forbidden,examination,communist,clueless,cities,bidding,arriving,adding,ungrateful,unacceptable,tutor,soviet,shaped,serum,scuse,savings,pub,pajamas,mouths,modest,methods,lure,irrational,depth,cries,classified,bombs,beautifully,arresting,approaching,vessel,variety,traitor,sympathetic,smug,smash,rental,prostitute,premonitions,mild,jumps,inventory,ing,improved,grandfather's,developing,darlin,committing,caleb's,banging,asap,amendment,worms,violated,vent,traumatic,traced,tow,swiss,sweaty,shaft,recommended,overboard,literature,insight,healed,grasp,fluid,experiencing,crappy,crab,connecticut,chunk,chandler's,awww,applied,witnessed,traveled,stain,shack,reacted,pronounce,presented,poured,occupied,moms,marriages,jabez,invested,handful,gob,gag,flipped,fireplace,expertise,embarrassment,disappears,concussion,bruises,brakes,anything's,week's,twisting,tide,swept,summon,splitting,settling,scientists,reschedule,regard,purposes,ohio,notch,mike's,improvement,hooray,grabbing,extend,exquisite,disrespect,complaints,colin's,armor,voting,thornhart,sustained,straw,slapped,simon's,shipped,shattered,ruthless,reva's,refill,recorded,payroll,numb,mourning,marijuana,manly,jerry's,involving,hunk,entertain,earthquake,drift,dreadful,doorstep,confirmation,chops,bridget's,appreciates,announced,vague,tires,stressful,stem,stashed,stash,sensed,preoccupied,predictable,noticing,madly,halls,gunshot,embassy,dozens,dinner's,confuse,cleaners,charade,chalk,cappuccino,breed,bouquet,amulet,addiction,who've,warming,unlock,transition,satisfy,sacrificed,relaxing,lone,input,hampshire,girlfriend's,elaborate,concerning,completed,channels,category,cal,blocking,blend,blankets,america's,addicted,yuck,voters,professionals,positions,monica's,mode,initial,hunger,hamburger,greeting,greet,gravy,gram,dreamt,dice,declared,collecting,caution,brady's,backpack,agreeing,writers,whale,tribe,taller,supervisor,sacrifices,radiation,poo,phew,outcome,ounce,missile,meter,likewise,irrelevant,gran,felon,feature,favorites,farther,fade,experiments,erased,easiest,disk,convenience,conceived,compassionate,challenged,cane,blair's,backstage,agony,adores,veins,tweek,thieves,surgical,strangely,stetson,recital,proposing,productive,meaningful,marching,immunity,hassle,goddamned,frighten,directors,dearly,comments,closure,cease,ambition,wisconsin,unstable,sweetness,salvage,richer,refusing,raging,pumping,pressuring,petition,mortals,lowlife,jus,intimidated,intentionally,inspire,forgave,eric's,devotion,despicable,deciding,dash,comfy,breach,bo's,bark,alternate,aaaah,switching,swallowed,stove,slot,screamed,scars,russians,relevant,poof,pipes,persons,pawn,losses,legit,invest,generations,farewell,experimental,difficulty,curtains,civilized,championship,caviar,boost,token,tends,temporarily,superstition,supernatural,sunk,sadness,reduced,recorder,psyched,presidential,owners,motivated,microwave,lands,karen's,hallelujah,gap,fraternity,engines,dryer,cocoa,chewing,additional,acceptable,unbelievably,survivor,smiled,smelling,sized,simpler,sentenced,respectable,remarks,registration,premises,passengers,organ,occasional,khasinau,indication,gutter,grabs,goo,fulfill,flashlight,ellenor,courses,blooded,blessings,beware,beth's,bands,advised,water's,uhhh,turf,swings,slips,shocking,resistance,privately,olivia's,mirrors,lyrics,locking,instrument,historical,heartless,fras,decades,comparison,childish,cassie's,cardiac,admission,utterly,tuscany,ticked,suspension,stunned,statesville,sadly,resolution,reserved,purely,opponent,noted,lowest,kiddin,jerks,hitch,flirt,fare,extension,establishment,equals,dismiss,delayed,decade,christening,casket,c'mere,breakup,brad's,biting,antibiotics,accusation,abducted,witchcraft,whoever's,traded,thread,spelling,so's,school's,runnin,remaining,punching,protein,printed,paramedics,newest,murdering,mine's,masks,lawndale,intact,ins,initials,heights,grampa,democracy,deceased,colleen's,choking,charms,careless,bushes,buns,bummed,accounting,travels,taylor's,shred,saves,saddle,rethink,regards,references,precinct,persuade,patterns,meds,manipulating,llanfair,leash,kenny's,housing,hearted,guarantees,flown,feast,extent,educated,disgrace,determination,deposition,coverage,corridor,burial,bookstore,boil,abilities,vitals,veil,trespassing,teaches,sidewalk,sensible,punishing,overtime,optimistic,occasions,obsessing,oak,notify,mornin,jeopardy,jaffa,injection,hilarious,distinct,directed,desires,curve,confide,challenging,cautious,alter,yada,wilderness,where're,vindictive,vial,tomb,teeny,subjects,stroll,sittin,scrub,rebuild,rachel's,posters,parallel,ordeal,orbit,o'brien,nuns,max's,jennifer's,intimacy,inheritance,fails,exploded,donate,distracting,despair,democratic,defended,crackers,commercials,bryant's,ammunition,wildwind,virtue,thoroughly,tails,spicy,sketches,sights,sheer,shaving,seize,scarecrow,refreshing,prosecute,possess,platter,phillip's,napkin,misplaced,merchandise,membership,loony,jinx,heroic,frankenstein,fag,efficient,devil's,corps,clan,boundaries,attract,ambitious,virtually,syrup,solitary,resignation,resemblance,reacting,pursuing,premature,pod,liz's,lavery,journalist,honors,harvey's,genes,flashes,erm,contribution,company's,client's,cheque,charts,cargo,awright,acquainted,wrapping,untie,salute,ruins,resign,realised,priceless,partying,myth,moonlight,lightly,lifting,kasnoff,insisting,glowing,generator,flowing,explosives,employer,cutie,confronted,clause,buts,breakthrough,blouse,ballistic,antidote,analyze,allowance,adjourned,vet,unto,understatement,tucked,touchy,toll,subconscious,sequence,screws,sarge,roommates,reaches,rambaldi,programs,offend,nerd,knives,kin,irresistible,inherited,incapable,hostility,goddammit,fuse,frat,equation,curfew,centered,blackmailed,allows,alleged,walkin,transmission,text,starve,sleigh,sarcastic,recess,rebound,procedures,pinned,parlor,outfits,livin,issued,institute,industrial,heartache,head's,haired,fundraiser,doorman,documentary,discreet,dilucca,detect,cracks,cracker,considerate,climbed,catering,author,apophis,zoey,vacuum,urine,tunnels,todd's,tanks,strung,stitches,sordid,sark,referred,protector,portion,phoned,pets,paths,mat,lengths,kindergarten,hostess,flaw,flavor,discharge,deveraux,consumed,confidentiality,automatic,amongst,viktor,victim's,tactics,straightened,specials,spaghetti,soil,prettier,powerless,por,poems,playin,playground,parker's,paranoia,nsa,mainly,mac's,joe's,instantly,havoc,exaggerating,evaluation,eavesdropping,doughnuts,diversion,deepest,cutest,companion,comb,bela,behaving,avoided,anyplace,agh,accessory,zap,whereas,translate,stuffing,speeding,slime,polls,personalities,payments,musician,marital,lurking,lottery,journalism,interior,imaginary,hog,guinea,greetings,game's,fairwinds,ethical,equipped,environmental,elegant,elbow,customs,cuban,credibility,credentials,consistent,collapse,cloth,claws,chopped,challenges,bridal,boards,bedside,babysitting,authorized,assumption,ant,youngest,witty,vast,unforgivable,underworld,tempt,tabs,succeeded,sophomore,selfless,secrecy,runway,restless,programming,professionally,okey,movin,metaphor,messes,meltdown,lecter,incoming,hence,gasoline,gained,funding,episodes,diefenbaker,contain,comedian,collected,cam,buckle,assembly,ancestors,admired,adjustment,acceptance,weekly,warmth,throats,seduced,ridge's,reform,rebecca's,queer,poll,parenting,noses,luckiest,graveyard,gifted,footsteps,dimeras,cynical,assassination,wedded,voyage,volunteers,verbal,unpredictable,tuned,stoop,slides,sinking,show's,rio,rigged,regulations,region,promoted,plumbing,lingerie,layer,katie's,hankey,greed,everwood,essential,elope,dresser,departure,dat,dances,coup,chauffeur,bulletin,bugged,bouncing,website,tubes,temptation,supported,strangest,sorel's,slammed,selection,sarcasm,rib,primitive,platform,pending,partial,packages,orderly,obsessive,nevertheless,nbc,murderers,motto,meteor,inconvenience,glimpse,froze,fiber,execute,etc,ensure,drivers,dispute,damages,crop,courageous,consulate,closes,bosses,bees,amends,wuss,wolfram,wacky,unemployed,traces,town's,testifying,tendency,syringe,symphony,stew,startled,sorrow,sleazy,shaky,screams,rsquo,remark,poke,phone's,philip's,nutty,nobel,mentioning,mend,mayor's,iowa,inspiring,impulsive,housekeeper,germans,formed,foam,fingernails,economic,divide,conditioning,baking,whine,thug,starved,sedative,rose's,reversed,publishing,programmed,picket,paged,nowadays,newman's,mines,margo's,invasion,homosexual,homo,hips,forgets,flipping,flea,flatter,dwell,dumpster,consultant,choo,banking,assignments,apartments,ants,affecting,advisor,vile,unreasonable,tossing,thanked,steals,souvenir,screening,scratched,rep,psychopath,proportion,outs,operative,obstruction,obey,neutral,lump,lily's,insists,ian's,harass,gloat,flights,filth,extended,electronic,edgy,diseases,didn,coroner,confessing,cologne,cedar,bruise,betraying,bailing,attempting,appealing,adebisi,wrath,wandered,waist,vain,traps,transportation,stepfather,publicly,presidents,poking,obligated,marshal,lexie's,instructed,heavenly,halt,employed,diplomatic,dilemma,crazed,contagious,coaster,cheering,carved,bundle,approached,appearances,vomit,thingy,stadium,speeches,robbing,reflect,raft,qualify,pumped,pillows,peep,pageant,packs,neo,neglected,m'kay,loneliness,liberal,intrude,indicates,helluva,gardener,freely,forresters,err,drooling,continuing,betcha,alan's,addressed,acquired,vase,supermarket,squat,spitting,spaces,slaves,rhyme,relieve,receipts,racket,purchased,preserve,pictured,pause,overdue,officials,nod,motivation,morgendorffer,lucky's,lacking,kidnapper,introduction,insect,hunters,horns,feminine,eyeballs,dumps,disc,disappointing,difficulties,crock,convertible,context,claw,clamp,canned,cambias,bathtub,avanya,artery,weep,warmer,vendetta,tenth,suspense,summoned,stuff's,spiders,sings,reiber,raving,pushy,produced,poverty,postponed,ohhhh,noooo,mold,mice,laughter,incompetent,hugging,groceries,frequency,fastest,drip,differ,daphne's,communicating,body's,beliefs,bats,bases,auntie,adios,wraps,willingly,weirdest,voila,timmih,thinner,swelling,swat,steroids,sensitivity,scrape,rehearse,quarterback,organic,matched,ledge,justified,insults,increased,heavily,hateful,handles,feared,doorway,decorations,colour,chatting,buyer,buckaroo,bedrooms,batting,askin,ammo,tutoring,subpoena,span,scratching,requests,privileges,pager,mart,kel,intriguing,idiotic,hotels,grape,enlighten,dum,door's,dixie's,demonstrate,dairy,corrupt,combined,brunch,bridesmaid,barking,architect,applause,alongside,ale,acquaintance,yuh,wretched,superficial,sufficient,sued,soak,smoothly,sensing,restraint,quo,pow,posing,pleading,pittsburgh,peru,payoff,participate,organize,oprah,nemo,morals,loans,loaf,lists,laboratory,jumpy,intervention,ignorant,herbal,hangin,germs,generosity,flashing,country's,convent,clumsy,chocolates,captive,bianca's,behaved,apologise,vanity,trials,stumbled,republicans,represented,recognition,preview,poisonous,perjury,parental,onboard,mugged,minding,linen,learns,knots,interviewing,inmates,ingredients,humour,grind,greasy,goons,estimate,elementary,edmund's,drastic,database,coop,comparing,cocky,clearer,bruised,brag,bind,axe,asset,apparent,ann's,worthwhile,whoop,wedding's,vanquishing,tabloids,survivors,stenbeck's,sprung,spotlight,shops,sentencing,sentences,revealing,reduce,ram,racist,provoke,piper's,pining,overly,oui,ops,mop,louisiana,locket,king's,jab,imply,impatient,hovering,hotter,fest,endure,dots,doren,dim,diagnosed,debts,cultures,crawled,contained,condemned,chained,brit,breaths,adds,weirdo,warmed,wand,utah,troubling,tok'ra,stripped,strapped,soaked,skipping,sharon's,scrambled,rattle,profound,musta,mocking,mnh,misunderstand,merit,loading,linked,limousine,kacl,investors,interviewed,hustle,forensic,foods,enthusiastic,duct,drawers,devastating,democrats,conquer,concentration,comeback,clarify,chores,cheerleaders,cheaper,charlie's,callin,blushing,barging,abused,yoga,wrecking,wits,waffles,virginity,vibes,uninvited,unfaithful,underwater,tribute,strangled,state's,scheming,ropes,responded,residents,rescuing,rave,priests,postcard,overseas,orientation,ongoing,o'reily,newly,neil's,morphine,lotion,limitations,lesser,lectures,lads,kidneys,judgement,jog,itch,intellectual,installed,infant,indefinitely,grenade,glamorous,genetically,freud,faculty,engineering,doh,discretion,delusions,declaration,crate,competent,commonwealth,catalog,bakery,attempts,asylum,argh,applying,ahhhh,yesterday's,wedge,wager,unfit,tripping,treatments,torment,superhero,stirring,spinal,sorority,seminar,scenery,repairs,rabble,pneumonia,perks,owl,override,ooooh,moo,mija,manslaughter,mailed,love's,lime,lettuce,intimidate,instructor,guarded,grieve,grad,globe,frustration,extensive,exploring,exercises,eve's,doorbell,devices,deal's,dam,cultural,ctu,credits,commerce,chinatown,chemicals,baltimore,authentic,arraignment,annulled,altered,allergies,wanta,verify,vegetarian,tunes,tourist,tighter,telegram,suitable,stalk,specimen,spared,solving,shoo,satisfying,saddam,requesting,publisher,pens,overprotective,obstacles,notified,negro,nasedo,judged,jill's,identification,grandchild,genuinely,founded,flushed,fluids,floss,escaping,ditched,demon's,decorated,criticism,cramp,corny,contribute,connecting,bunk,bombing,bitten,billions,bankrupt,yikes,wrists,ultrasound,ultimatum,thirst,spelled,sniff,scope,ross's,room's,retrieve,releasing,reassuring,pumps,properties,predicted,neurotic,negotiating,needn't,multi,monitors,millionaire,microphone,mechanical,lydecker,limp,incriminating,hatchet,gracias,gordie,fills,feeds,egypt,doubting,dedication,decaf,dawson's,competing,cellular,biopsy,whiz,voluntarily,visible,ventilator,unpack,unload,universal,tomatoes,targets,suggests,strawberry,spooked,snitch,schillinger,sap,reassure,providing,prey,pressure's,persuasive,mystical,mysteries,mri,moment's,mixing,matrimony,mary's,mails,lighthouse,liability,kgb,jock,headline,frankie's,factors,explosive,explanations,dispatch,detailed,curly,cupid,condolences,comrade,cassadines,bulb,brittany's,bragging,awaits,assaulted,ambush,adolescent,adjusted,abort,yank,whit,verse,vaguely,undermine,tying,trim,swamped,stitch,stan's,stabbing,slippers,skye's,sincerely,sigh,setback,secondly,rotting,rev,retail,proceedings,preparation,precaution,pox,pcpd,nonetheless,melting,materials,mar,liaison,hots,hooking,headlines,hag,ganz,fury,felicity,fangs,expelled,encouragement,earring,dreidel,draws,dory,donut,dog's,dis,dictate,dependent,decorating,coordinates,cocktails,bumps,blueberry,believable,backfired,backfire,apron,anticipated,adjusting,activated,vous,vouch,vitamins,vista,urn,uncertain,ummm,tourists,tattoos,surrounding,sponsor,slimy,singles,sibling,shhhh,restored,representative,renting,reign,publish,planets,peculiar,parasite,paddington,noo,marries,mailbox,magically,lovebirds,listeners,knocks,kane's,informant,grain,exits,elf,drazen,distractions,disconnected,dinosaurs,designing,dashwood,crooked,conveniently,contents,argued,wink,warped,underestimated,testified,tacky,substantial,steve's,steering,staged,stability,shoving,seizure,reset,repeatedly,radius,pushes,pitching,pairs,opener,mornings,mississippi,matthew's,mash,investigations,invent,indulge,horribly,hallucinating,festive,eyebrows,expand,enjoys,dictionary,dialogue,desperation,dealers,darkest,daph,critic,consulting,cartman's,canal,boragora,belts,bagel,authorization,auditions,associated,ape,amy's,agitated,adventures,withdraw,wishful,wimp,vehicles,vanish,unbearable,tonic,tom's,tackle,suffice,suction,slaying,singapore,safest,rosanna's,rocking,relive,rates,puttin,prettiest,oval,noisy,newlyweds,nauseous,moi,misguided,mildly,midst,maps,liable,kristina's,judgmental,introducing,individuals,hunted,hen,givin,frequent,fisherman,fascinated,elephants,dislike,diploma,deluded,decorate,crummy,contractions,carve,careers,bottled,bonded,bahamas,unavailable,twenties,trustworthy,translation,traditions,surviving,surgeons,stupidity,skies,secured,salvation,remorse,rafe's,princeton,preferably,pies,photography,operational,nuh,northwest,nausea,napkins,mule,mourn,melted,mechanism,mashed,julia's,inherit,holdings,hel,greatness,golly,excused,edges,dumbo,drifting,delirious,damaging,cubicle,compelled,comm,colleges,cole's,chooses,checkup,chad's,certified,candidates,boredom,bob's,bandages,baldwin's,bah,automobile,athletic,alarms,absorbed,absent,windshield,who're,whaddya,vitamin,transparent,surprisingly,sunglasses,starring,slit,sided,schemes,roar,relatively,reade,quarry,prosecutor,prognosis,probe,potentially,pitiful,persistent,perception,percentage,peas,oww,nosy,neighbourhood,nagging,morons,molecular,meters,masterpiece,martinis,limbo,liars,jax's,irritating,inclined,hump,hoynes,haw,gauge,functions,fiasco,educational,eatin,donated,destination,dense,cubans,continent,concentrating,commanding,colorful,clam,cider,brochure,behaviour,barto,bargaining,awe,artistic,welcoming,weighing,villain,vein,vanquished,striking,stains,sooo,smear,sire,simone's,secondary,roughly,rituals,resentment,psychologist,preferred,pint,pension,passive,overhear,origin,orchestra,negotiations,mounted,morality,landingham,labs,kisser,jackson's,icy,hoot,holling,handshake,grilled,functioning,formality,elevators,edward's,depths,confirms,civilians,bypass,briefly,boathouse,binding,acres,accidental,westbridge,wacko,ulterior,transferring,tis,thugs,tangled,stirred,stefano's,sought,snag,smallest,sling,sleaze,seeds,rumour,ripe,remarried,reluctant,regularly,puddle,promote,precise,popularity,pins,perceptive,miraculous,memorable,maternal,lucinda's,longing,lockup,locals,librarian,job's,inspection,impressions,immoral,hypothetically,guarding,gourmet,gabe,fighters,fees,features,faxed,extortion,expressed,essentially,downright,digest,der,crosses,cranberry,city's,chorus,casualties,bygones,buzzing,burying,bikes,attended,allah,all's,weary,viewing,viewers,transmitter,taping,takeout,sweeping,stepmother,stating,stale,seating,seaborn,resigned,rating,prue's,pros,pepperoni,ownership,occurs,nicole's,newborn,merger,mandatory,malcolm's,ludicrous,jan's,injected,holden's,henry's,heating,geeks,forged,faults,expressing,eddie's,drue,dire,dief,desi,deceiving,centre,celebrities,caterer,calmed,businesses,budge,ashley's,applications,ankles,vending,typing,tribbiani,there're,squared,speculation,snowing,shades,sexist,scudder's,scattered,sanctuary,rewrite,regretted,regain,raises,processing,picky,orphan,mural,misjudged,miscarriage,memorize,marshall's,mark's,licensed,lens,leaking,launched,larry's,languages,judge's,jitters,invade,interruption,implied,illegally,handicapped,glitch,gittes,finer,fewer,engineered,distraught,dispose,dishonest,digs,dahlia's,dads,cruelty,conducting,clinical,circling,champions,canceling,butterflies,belongings,barbrady,amusement,allegations,alias,aging,zombies,where've,unborn,tri,swearing,stables,squeezed,spaulding's,slavery,sew,sensational,revolutionary,resisting,removing,radioactive,races,questionable,privileged,portofino,par,owning,overlook,overhead,orson,oddly,nazis,musicians,interrogate,instruments,imperative,impeccable,icu,hurtful,hors,heap,harley's,graduating,graders,glance,endangered,disgust,devious,destruct,demonstration,creates,crazier,countdown,coffee's,chump,cheeseburger,cat's,burglar,brotherhood,berries,ballroom,assumptions,ark,annoyed,allies,allergy,advantages,admirer,admirable,addresses,activate,accompany,wed,victoria's,valve,underpants,twit,triggered,teacher's,tack,strokes,stool,starr's,sham,seasons,sculpture,scrap,sailed,retarded,resourceful,remarkably,refresh,ranks,pressured,precautions,pointy,obligations,nightclub,mustache,month's,minority,mind's,maui,lace,isabella's,improving,iii,hunh,hubby,flare,fierce,farmers,dont,dokey,divided,demise,demanded,dangerously,crushing,considerable,complained,clinging,choked,chem,cheerleading,checkbook,cashmere,calmly,blush,believer,aspect,amazingly,alas,acute,a's,yak,whores,what've,tuition,trey's,tolerance,toilets,tactical,tacos,stairwell,spur,spirited,slower,sewing,separately,rubbed,restricted,punches,protects,partially,ole,nuisance,niagara,motherfuckers,mingle,mia's,kynaston,knack,kinkle,impose,hosting,harry's,gullible,grid,godmother,funniest,friggin,folding,financially,filming,fashions,eater,dysfunctional,drool,distinguished,defence,defeated,cruising,crude,criticize,corruption,contractor,conceive,clone,circulation,cedars,caliber,brighter,blinded,birthdays,bio,bill's,banquet,artificial,anticipate,annoy,achievement,whim,whichever,volatile,veto,vested,uncle's,supports,successfully,shroud,severely,rests,representation,quarantine,premiere,pleases,parent's,painless,pads,orphans,orphanage,offence,obliged,nip,niggers,negotiation,narcotics,nag,mistletoe,meddling,manifest,lookit,loo,lilah,investigated,intrigued,injustice,homicidal,hayward's,gigantic,exposing,elves,disturbance,disastrous,depended,demented,correction,cooped,colby's,cheerful,buyers,brownies,beverage,basics,attorney's,atm,arvin,arcade,weighs,upsets,unethical,tidy,swollen,sweaters,swap,stupidest,sensation,scalpel,rail,prototype,props,prescribed,pompous,poetic,ploy,paws,operates,objections,mushrooms,mulwray,monitoring,manipulation,lured,lays,lasting,kung,keg,jell,internship,insignificant,inmate,incentive,gandhi,fulfilled,flooded,expedition,evolution,discharged,disagreement,dine,dean's,crypt,coroner's,cornered,copied,confrontation,cds,catalogue,brightest,beethoven,banned,attendant,athlete,amaze,airlines,yogurt,wyndemere,wool,vocabulary,vcr,tulsa,tags,tactic,stuffy,slug,sexuality,seniors,segment,revelation,respirator,pulp,prop,producing,processed,pretends,polygraph,perp,pennies,ordinarily,opposition,olives,necks,morally,martyr,martial,lisa's,leftovers,joints,jimmy's,irs,invaded,imported,hopping,homey,hints,helicopters,heed,heated,heartbroken,gulf,greatly,forge,florist,firsthand,fiend,expanding,emma's,defenses,crippled,cousin's,corrected,conniving,conditioner,clears,chemo,bubbly,bladder,beeper,baptism,apb,answer's,anna's,angles,ache,womb,wiring,wench,weaknesses,volunteering,violating,unlocked,unemployment,tummy,tibet,threshold,surrogate,submarine,subid,stray,stated,startle,specifics,snob,slowing,sled,scoot,robbers,rightful,richest,quid,qfxmjrie,puffs,probable,pitched,pierced,pencils,paralysis,nuke,managing,makeover,luncheon,lords,linksynergy,jury's,jacuzzi,ish,interstate,hitched,historic,hangover,gasp,fracture,flock,firemen,drawings,disgusted,darned,coal,clams,chez,cables,broadcasting,brew,borrowing,banged,achieved,wildest,weirder,unauthorized,stunts,sleeves,sixties,shush,shalt,senora,rises,retro,quits,pupils,politicians,pegged,painfully,paging,outlet,omelet,observed,ned's,memorized,lawfully,jackets,interpretation,intercept,ingredient,grownup,glued,gaining,fulfilling,flee,enchanted,dvd,delusion,daring,conservative,conducted,compelling,charitable,carton,bronx,bridesmaids,bribed,boiling,bathrooms,bandage,awareness,awaiting,assign,arrogance,antiques,ainsley,turkeys,travelling,trashing,tic,takeover,sync,supervision,stockings,stalked,stabilized,spacecraft,slob,skates,sirs,sedated,robes,reviews,respecting,rat's,psyche,prominent,prizes,presumptuous,prejudice,platoon,permitted,paragraph,mush,mum's,movements,mist,missions,mints,mating,mantan,lorne,lord's,loads,listener,legendary,itinerary,hugs,hepatitis,heave,guesses,gender,flags,fading,exams,examining,elizabeth's,egyptian,dumbest,dishwasher,dimera's,describing,deceive,cunning,cripple,cove,convictions,congressional,confided,compulsive,compromising,burglary,bun,bumpy,brainwashed,benes,arnie,alvy,affirmative,adrenaline,adamant,watchin,waitresses,uncommon,treaty,transgenic,toughest,toby's,surround,stormed,spree,spilling,spectacle,soaking,significance,shreds,sewers,severed,scarce,scamming,scalp,sami's,salem's,rewind,rehearsing,pretentious,potions,possessions,planner,placing,periods,overrated,obstacle,notices,nerds,meems,medieval,mcmurphy,maturity,maternity,masses,maneuver,lyin,loathe,lawyer's,irv,investigators,hep,grin,gospel,gals,formation,fertility,facilities,exterior,epidemic,eloping,ecstatic,ecstasy,duly,divorcing,distribution,dignan,debut,costing,coaching,clubhouse,clot,clocks,classical,candid,bursting,breather,braces,bennett's,bending,australian,attendance,arsonist,applies,adored,accepts,absorb,vacant,uuh,uphold,unarmed,turd,topolsky,thrilling,thigh,terminate,tempo,sustain,spaceship,snore,sneeze,smuggling,shrine,sera,scott's,salty,salon,ramp,quaint,prostitution,prof,policies,patronize,patio,nasa,morbid,marlo's,mamma,locations,licence,kettle,joyous,invincible,interpret,insecurities,insects,inquiry,infamous,impulses,illusions,holed,glen's,fragments,forrester's,exploit,economics,drivin,des,defy,defenseless,dedicate,cradle,cpr,coupon,countless,conjure,confined,celebrated,cardboard,booking,blur,bleach,ban,backseat,austin's,alternatives,afterward,accomplishment,wordsworth,wisely,wildlife,valet,vaccine,urges,unnatural,unlucky,truths,traumatized,tit,tennessee,tasting,swears,strawberries,steaks,stats,skank,seducing,secretive,screwdriver,schedules,rooting,rightfully,rattled,qualifies,puppets,provides,prospects,pronto,prevented,powered,posse,poorly,polling,pedestal,palms,muddy,morty,miniature,microscope,merci,margin,lecturing,inject,incriminate,hygiene,hospital's,grapefruit,gazebo,funnier,freight,flooding,equivalent,eliminated,elaine's,dios,deacon's,cuter,continental,container,cons,compensation,clap,cbs,cavity,caves,capricorn,canvas,calculations,bossy,booby,bacteria,aides,zende,winthrop,wider,warrants,valentines,undressed,underage,truthfully,tampered,suffers,stored,statute,speechless,sparkling,sod,socially,sidelines,shrek,sank,roy's,raul's,railing,puberty,practices,pesky,parachute,outrage,outdoors,operated,openly,nominated,motions,moods,lunches,litter,kidnappers,itching,intuition,index,imitation,icky,humility,hassling,gallons,firmly,excessive,evolved,employ,eligible,elections,elderly,drugstore,dosage,disrupt,directing,dipping,deranged,debating,cuckoo,cremated,craziness,cooperating,compatible,circumstantial,chimney,bonnie's,blinking,biscuits,belgium,arise,analyzed,admiring,acquire,accounted,willow's,weeping,volumes,views,triad,trashy,transaction,tilt,soothing,slumber,slayers,skirts,siren,ship's,shindig,sentiment,sally's,rosco,riddance,rewarded,quaid,purity,proceeding,pretzels,practiced,politician,polar,panicking,overall,occupation,naming,minimal,mckechnie,massacre,marah's,lovin,leaked,layers,isolation,intruding,impersonating,ignorance,hoop,hamburgers,gwen's,fruits,footprints,fluke,fleas,festivities,fences,feisty,evacuate,emergencies,diabetes,detained,democrat,deceived,creeping,craziest,corpses,conned,coincidences,charleston,bums,brussels,bounced,bodyguards,blasted,bitterness,baloney,ashtray,apocalypse,advances,zillion,watergate,wallpaper,viable,tory's,tenants,telesave,sympathize,sweeter,swam,sup,startin,stages,spencer's,sodas,snowed,sleepover,signor,seein,reviewing,reunited,retainer,restroom,rested,replacing,repercussions,reliving,reef,reconciliation,reconcile,recognise,prevail,preaching,planting,overreact,oof,omen,o'neil,numerous,noose,moustache,morning's,manicure,maids,mah,lorelei's,landlady,hypothetical,hopped,homesick,hives,hesitation,herbs,hectic,heartbreak,haunting,gangs,frown,fingerprint,extract,expired,exhausting,exchanged,exceptional,everytime,encountered,disregard,daytime,cooperative,constitutional,cling,chevron,chaperone,buenos,blinding,bitty,beads,battling,badgering,anticipation,advocate,zander's,waterfront,upstanding,unprofessional,unity,unhealthy,undead,turmoil,truthful,toothpaste,tippin,thoughtless,tagataya,stretching,strategic,spun,shortage,shooters,sheriff's,shady,senseless,sailors,rewarding,refuge,rapid,rah,pun,propane,pronounced,preposterous,pottery,portable,pigeons,pastry,overhearing,ogre,obscene,novels,negotiable,mtv,morgan's,monthly,loner,leisure,leagues,jogging,jaws,itchy,insinuating,insides,induced,immigration,hospitality,hormone,hilda's,hearst,grandpa's,frequently,forthcoming,fists,fifties,etiquette,endings,elevated,editing,dunk,distinction,disabled,dibs,destroys,despises,desired,designers,deprived,dancers,dah,cuddy,crust,conductor,communists,cloak,circumstance,chewed,casserole,bora,bidder,bearer,assessment,artoo,applaud,appalling,amounts,admissions,withdrawal,weights,vowed,virgins,vigilante,vatican,undone,trench,touchdown,throttle,thaw,tha,testosterone,tailor,symptom,swoop,suited,suitcases,stomp,sticker,stakeout,spoiling,snatched,smoochy,smitten,shameless,restraints,researching,renew,relay,regional,refund,reclaim,rapids,raoul,rags,puzzles,purposely,punks,prosecuted,plaid,pineapple,picturing,pickin,pbs,parasites,offspring,nyah,mysteriously,multiply,mineral,masculine,mascara,laps,kramer's,jukebox,interruptions,hoax,gunfire,gays,furnace,exceptions,engraved,elbows,duplicate,drapes,designated,deliberate,deli,decoy,cub,cryptic,crowds,critics,coupla,convert,conventional,condemn,complicate,combine,colossal,clerks,clarity,cassadine's,byes,brushed,bride's,banished,arrests,argon,andy's,alarmed,worships,versa,uncanny,troop,treasury,transformation,terminated,telescope,technicality,sydney's,sundae,stumble,stripping,shuts,separating,schmuck,saliva,robber,retain,remained,relentless,reconnect,recipes,rearrange,ray's,rainy,psychiatrists,producers,policemen,plunge,plugged,patched,overload,ofc,obtained,obsolete,o'malley,numbered,number's,nay,moth,module,mkay,mindless,menus,lullaby,lotte,leavin,layout,knob,killin,karinsky,irregular,invalid,hides,grownups,griff,flaws,flashy,flaming,fettes,evicted,epic,encoded,dread,dil,degrassi,dealings,dangers,cushion,console,concluded,casey's,bowel,beginnings,barged,apes,announcing,amanda's,admits,abroad,abide,abandoning,workshop,wonderfully,woak,warfare,wait'll,wad,violate,turkish,tim's,ter,targeted,susan's,suicidal,stayin,sorted,slamming,sketchy,shoplifting,shapes,selected,sarah's,retiring,raiser,quizmaster,pursued,pupkin,profitable,prefers,politically,phenomenon,palmer's,olympics,needless,nature's,mutt,motherhood,momentarily,migraine,lizzie's,lilo,lifts,leukemia,leftover,law's,keepin,idol,hinks,hellhole,h'mm,gowns,goodies,gallon,futures,friction,finale,farms,extraction,entertained,electronics,eighties,earth's,dmv,darker,daniel's,cum,conspiring,consequence,cheery,caps,calf,cadet,builds,benign,barney's,aspects,artillery,apiece,allison's,aggression,adjustments,abusive,abduction,wiping,whipping,welles,unspeakable,unlimited,unidentified,trivial,transcripts,threatens,textbook,tenant,supervise,superstitious,stricken,stretched,story's,stimulating,steep,statistics,spielberg,sodium,slices,shelves,scratches,saudi,sabotaged,roxy's,retrieval,repressed,relation,rejecting,quickie,promoting,ponies,peeking,paw,paolo,outraged,observer,o'connell,moping,moaning,mausoleum,males,licked,kovich,klutz,iraq,interrogating,interfered,intensive,insulin,infested,incompetence,hyper,horrified,handedly,hacked,guiding,glamour,geoff,gekko,fraid,fractured,formerly,flour,firearms,fend,executives,examiner,evaluate,eloped,duke's,disoriented,delivers,dashing,crystals,crossroads,crashdown,court's,conclude,coffees,cockroach,climate,chipped,camps,brushing,boulevard,bombed,bolts,begs,baths,baptized,astronaut,assurance,anemia,allegiance,aiming,abuela,abiding,workplace,withholding,weave,wearin,weaker,warnings,usa,tours,thesis,terrorism,suffocating,straws,straightforward,stench,steamed,starboard,sideways,shrinks,shortcut,sean's,scram,roasted,roaming,riviera,respectfully,repulsive,recognizes,receiver,psychiatry,provoked,penitentiary,peed,pas,painkillers,oink,norm,ninotchka,muslim,montgomery's,mitzvah,milligrams,mil,midge,marshmallows,markets,macy's,looky,lapse,kubelik,knit,jeb,investments,intellect,improvise,implant,hometown,hanged,handicap,halo,governor's,goa'ulds,giddy,gia's,geniuses,fruitcake,footing,flop,findings,fightin,fib,editorial,drinkin,doork,discovering,detour,danish,cuddle,crashes,coordinate,combo,colonnade,collector,cheats,cetera,canadians,bip,bailiff,auditioning,assed,amused,alienate,algebra,alexi,aiding,aching,woe,wah,unwanted,typically,tug,topless,tongues,tiniest,them's,symbols,superiors,soy,soften,sheldrake,sensors,seller,seas,ruler,rival,rips,renowned,recruiting,reasoning,rawley,raisins,racial,presses,preservation,portfolio,oversight,organizing,obtain,observing,nessa,narrowed,minions,midwest,meth,merciful,manages,magistrate,lawsuits,labour,invention,intimidating,infirmary,indicated,inconvenient,imposter,hugged,honoring,holdin,hades,godforsaken,fumes,forgery,foremost,foolproof,folder,folded,flattery,fingertips,financing,fifteenth,exterminator,explodes,eccentric,drained,dodging,documented,disguised,developments,currency,crafts,constructive,concealed,compartment,chute,chinpokomon,captains,capitol,calculated,buses,bodily,astronauts,alimony,accustomed,accessories,abdominal,zen,zach's,wrinkle,wallow,viv,vicinity,venue,valued,valium,valerie's,upgrade,upcoming,untrue,uncover,twig,twelfth,trembling,treasures,torched,toenails,timed,termites,telly,taunting,taransky,tar,talker,succubus,statues,smarts,sliding,sizes,sighting,semen,seizures,scarred,savvy,sauna,saddest,sacrificing,rubbish,riled,ricky's,rican,revive,recruit,ratted,rationally,provenance,professors,prestigious,pms,phonse,perky,pedal,overdose,organism,nasal,nanites,mushy,movers,moot,missus,midterm,merits,melodramatic,manure,magnetic,knockout,knitting,jig,invading,interpol,incapacitated,idle,hotline,horse's,highlight,hauling,hair's,gunpoint,greenwich,grail,ganza,framing,formally,fleeing,flap,flannel,fin,fibers,faded,existing,email,eavesdrop,dwelling,dwarf,donations,detected,desserts,dar,corporations,constellation,collision,chic,calories,businessmen,buchanan's,breathtaking,bleak,blacked,batter,balanced,ante,aggravated,agencies,abu,yanked,wuh,withdrawn,wigand,whoah,wham,vocal,unwind,undoubtedly,unattractive,twitch,trimester,torrance,timetable,taxpayers,strained,stationed,stared,slapping,sincerity,signatures,siding,siblings,shit's,shenanigans,shacking,seer,satellites,sappy,samaritan,rune,regained,rebellion,proceeds,privy,power's,poorer,politely,paste,oysters,overruled,olaf,nightcap,networks,necessity,mosquito,millimeter,michelle's,merrier,massachusetts,manuscript,manufacture,manhood,lunar,lug,lucked,loaned,kilos,ignition,hurl,hauled,harmed,goodwill,freshmen,forming,fenmore,fasten,farce,failures,exploding,erratic,elm,drunks,ditching,d'artagnan,crops,cramped,contacting,coalition,closets,clientele,chimp,cavalry,casa,cabs,bled,bargained,arranging,archives,anesthesia,amuse,altering,afternoons,accountable,abetting,wrinkles,wolek,waved,unite,uneasy,unaware,ufo,toot,toddy,tens,tattooed,tad's,sway,stained,spauldings,solely,sliced,sirens,schibetta,scatter,rumours,roger's,robbie's,rinse,remo,remedy,redemption,queen's,progressive,pleasures,picture's,philosopher,pacey's,optimism,oblige,natives,muy,measuring,measured,masked,mascot,malicious,mailing,luca,lifelong,kosher,koji,kiddies,judas,isolate,intercepted,insecurity,initially,inferior,incidentally,ifs,hun,heals,headlights,guided,growl,grilling,glazed,gem,gel,gaps,fundamental,flunk,floats,fiery,fairness,exercising,excellency,evenings,ere,enrolled,disclosure,det,department's,damp,curling,cupboard,counterfeit,cooling,condescending,conclusive,clicked,cleans,cholesterol,chap,cashed,brow,broccoli,brats,blueprints,blindfold,biz,billing,barracks,attach,aquarium,appalled,altitude,alrighty,aimed,yawn,xander's,wynant,winslow's,welcomed,violations,upright,unsolved,unreliable,toots,tighten,symbolic,sweatshirt,steinbrenner,steamy,spouse,sox,sonogram,slowed,slots,sleepless,skeleton,shines,roles,retaliate,representatives,rephrase,repeated,renaissance,redeem,rapidly,rambling,quilt,quarrel,prying,proverbial,priced,presiding,presidency,prescribe,prepped,pranks,possessive,plaintiff,philosophical,pest,persuaded,perk,pediatrics,paige's,overlooked,outcast,oop,odor,notorious,nightgown,mythology,mumbo,monitored,mediocre,master's,mademoiselle,lunchtime,lifesaver,legislation,leaned,lambs,lag,killings,interns,intensity,increasing,identities,hounding,hem,hellmouth,goon,goner,ghoul,germ,gardening,frenzy,foyer,food's,extras,extinct,exhibition,exaggerate,everlasting,enlightened,drilling,doubles,digits,dialed,devote,defined,deceitful,d'oeuvres,csi,cosmetic,contaminated,conspired,conning,colonies,cerebral,cavern,cathedral,carving,butting,boiled,blurry,beams,barf,babysit,assistants,ascension,architecture,approaches,albums,albanian,aaaaah,wildly,whoopee,whiny,weiskopf,walkie,vultures,veteran,vacations,upfront,unresolved,tile,tampering,struggled,stockholders,specially,snaps,sleepwalking,shrunk,sermon,seeks,seduction,scenarios,scams,ridden,revolve,repaired,regulation,reasonably,reactor,quotes,preserved,phenomenal,patrolling,paranormal,ounces,omigod,offs,nonstop,nightfall,nat,militia,meeting's,logs,lineup,libby's,lava,lashing,labels,kilometers,kate's,invites,investigative,innocents,infierno,incision,import,implications,humming,highlights,haunts,greeks,gloss,gloating,general's,frannie,flute,fled,fitted,finishes,fiji,fetal,feeny,entrapment,edit,dyin,download,discomfort,dimensions,detonator,dependable,deke,decree,dax,cot,confiscated,concludes,concede,complication,commotion,commence,chulak,caucasian,casually,canary,brainer,bolie,ballpark,arm's,anwar,anatomy,analyzing,accommodations,yukon,youse,wring,wharf,wallowing,uranium,unclear,treason,transgenics,thrive,think's,thermal,territories,tedious,survives,stylish,strippers,sterile,squeezing,squeaky,sprained,solemn,snoring,sic,shifting,shattering,shabby,seams,scrawny,rotation,risen,revoked,residue,reeks,recite,reap,ranting,quoting,primal,pressures,predicament,precision,plugs,pits,pinpoint,petrified,petite,persona,pathological,passports,oughtta,nods,nighter,navigate,nashville,namely,museums,morale,milwaukee,meditation,mathematics,martin's,malta,logan's,latter,kippie,jackie's,intrigue,intentional,insufferable,incomplete,inability,imprisoned,hup,hunky,how've,horrifying,hearty,headmaster,hath,har,hank's,handbook,hamptons,grazie,goof,george's,funerals,fuck's,fraction,forks,finances,fetched,excruciating,enjoyable,enhanced,enhance,endanger,efficiency,dumber,drying,diabolical,destroyer,desirable,defendants,debris,darts,cuisine,cucumber,cube,crossword,contestant,considers,comprehend,club's,clipped,classmates,choppers,certificates,carmen's,canoe,candlelight,building's,brutally,brutality,boarded,bathrobe,backward,authorize,audrey's,atom,assemble,appeals,airports,aerobics,ado,abbott's,wholesome,whiff,vessels,vermin,varsity,trophies,trait,tragically,toying,titles,tissues,testy,team's,tasteful,surge,sun's,studios,strips,stocked,stephen's,staircase,squares,spinach,sow,southwest,southeast,sookie's,slayer's,sipping,singers,sidetracked,seldom,scrubbing,scraping,sanctity,russell's,ruse,robberies,rink,ridin,retribution,reinstated,refrain,rec,realities,readings,radiant,protesting,projector,posed,plutonium,plaque,pilar's,payin,parting,pans,o'reilly,nooooo,motorcycles,motherfucking,mein,measly,marv,manic,line's,lice,liam,lenses,lama,lalita,juggling,jerking,jamie's,intro,inevitably,imprisonment,hypnosis,huddle,horrendous,hobbies,heavier,heartfelt,harlin,hairdresser,grub,gramps,gonorrhea,gardens,fussing,fragment,fleeting,flawless,flashed,fetus,exclusively,eulogy,equality,enforce,distinctly,disrespectful,denies,crossbow,crest,cregg,crabs,cowardly,countess,contrast,contraction,contingency,consulted,connects,confirming,condone,coffins,cleansing,cheesecake,certainty,captain's,cages,c'est,briefed,brewing,bravest,bosom,boils,binoculars,bachelorette,aunt's,atta,assess,appetizer,ambushed,alerted,woozy,withhold,weighed,vulgar,viral,utmost,unusually,unleashed,unholy,unhappiness,underway,uncovered,unconditional,typewriter,typed,twists,sweeps,supervised,supermodel,suburbs,subpoenaed,stringing,snyder's,snot,skeptical,skateboard,shifted,secret's,scottish,schoolgirl,romantically,rocked,revoir,reviewed,respiratory,reopen,regiment,reflects,refined,puncture,pta,prone,produces,preach,pools,polished,pods,planetarium,penicillin,peacefully,partner's,nurturing,nation's,more'n,monastery,mmhmm,midgets,marklar,machinery,lodged,lifeline,joanna's,jer,jellyfish,infiltrate,implies,illegitimate,hutch,horseback,henri,heist,gents,frickin,freezes,forfeit,followers,flakes,flair,fathered,fascist,eternally,eta,epiphany,enlisted,eleventh,elect,effectively,dos,disgruntled,discrimination,discouraged,delinquent,decipher,danvers,dab,cubes,credible,coping,concession,cnn,clash,chills,cherished,catastrophe,caretaker,bulk,bras,branches,bombshell,birthright,billionaire,awol,ample,alumni,affections,admiration,abbotts,zelda's,whatnot,watering,vinegar,vietnamese,unthinkable,unseen,unprepared,unorthodox,underhanded,uncool,transmitted,traits,timeless,thump,thermometer,theoretically,theoretical,testament,tapping,tagged,tac,synthetic,syndicate,swung,surplus,supplier,stares,spiked,soviets,solves,smuggle,scheduling,scarier,saucer,reinforcements,recruited,rant,quitter,prudent,projection,previously,powdered,poked,pointers,placement,peril,penetrate,penance,patriotic,passions,opium,nudge,nostrils,nevermind,neurological,muslims,mow,momentum,mockery,mobster,mining,medically,magnitude,maggie's,loudly,listing,killer's,kar,jim's,insights,indicted,implicate,hypocritical,humanly,holiness,healthier,hammered,haldeman,gunman,graphic,gloom,geography,gary's,freshly,francs,formidable,flunked,flawed,feminist,faux,ewww,escorted,escapes,emptiness,emerge,drugging,dozer,doc's,directorate,diana's,derevko,deprive,deodorant,cryin,crusade,crocodile,creativity,controversial,commands,coloring,colder,cognac,clocked,clippings,christine's,chit,charades,chanting,certifiable,caterers,brute,brochures,briefs,bran,botched,blinders,bitchin,bauer's,banter,babu,appearing,adequate,accompanied,abrupt,abdomen,zones,wooo,woken,winding,vip,venezuela,unanimous,ulcer,tread,thirteenth,thankfully,tame,tabby's,swine,swimsuit,swans,suv,stressing,steaming,stamped,stabilize,squirm,spokesman,snooze,shuffle,shredded,seoul,seized,seafood,scratchy,savor,sadistic,roster,rica,rhetorical,revlon,realist,reactions,prosecuting,prophecies,prisons,precedent,polyester,petals,persuasion,paddles,o'leary,nuthin,neighbour,negroes,naval,mute,muster,muck,minnesota,meningitis,matron,mastered,markers,maris's,manufactured,lot's,lockers,letterman,legged,launching,lanes,journals,indictment,indicating,hypnotized,housekeeping,hopelessly,hmph,hallucinations,grader,goldilocks,girly,furthermore,frames,flask,expansion,envelopes,engaging,downside,doves,doorknob,distinctive,dissolve,discourage,disapprove,diabetic,departed,deliveries,decorator,deaq,crossfire,criminally,containment,comrades,complimentary,commitments,chum,chatter,chapters,catchy,cashier,cartel,caribou,cardiologist,bull's,buffer,brawl,bowls,booted,boat's,billboard,biblical,barbershop,awakening,aryan,angst,administer,acquitted,acquisition,aces,accommodate,zellie,yield,wreak,witch's,william's,whistles,wart,vandalism,vamps,uterus,upstate,unstoppable,unrelated,understudy,tristin,transporting,transcript,tranquilizer,trails,trafficking,toxins,tonsils,timing's,therapeutic,tex,subscription,submitted,stephanie's,stempel,spotting,spectator,spatula,soho,softer,snotty,slinging,showered,sexiest,sensual,scoring,sadder,roam,rimbaud,rim,rewards,restrain,resilient,remission,reinstate,rehash,recollection,rabies,quinn's,presenting,preference,prairie,popsicle,plausible,plantation,pharmaceutical,pediatric,patronizing,patent,participation,outdoor,ostrich,ortolani,oooooh,omelette,neighbor's,neglect,nachos,movie's,mixture,mistrial,mio,mcginty's,marseilles,mare,mandate,malt,luv,loophole,literary,liberation,laughin,lacey's,kevvy,jah,irritated,intends,initiation,initiated,initiate,influenced,infidelity,indigenous,inc,idaho,hypothermia,horrific,hive,heroine,groupie,grinding,graceful,government's,goodspeed,gestures,gah,frantic,extradition,evil's,engineers,echelon,earning,disks,discussions,demolition,definitive,dawnie,dave's,date's,dared,dan's,damsel,curled,courtyard,constitutes,combustion,collective,collateral,collage,col,chant,cassette,carol's,carl's,calculating,bumping,britain,bribes,boardwalk,blinds,blindly,bleeds,blake's,bickering,beasts,battlefield,bankruptcy,backside,avenge,apprehended,annie's,anguish,afghanistan,acknowledged,abusing,youthful,yells,yanking,whomever,when'd,waterfall,vomiting,vine,vengeful,utility,unpacking,unfamiliar,undying,tumble,trolls,treacherous,todo,tipping,tantrum,tanked,summons,strategies,straps,stomped,stinkin,stings,stance,staked,squirrels,sprinkles,speculate,specialists,sorting,skinned,sicko,sicker,shootin,shep,shatter,seeya,schnapps,s'posed,rows,rounded,ronee,rite,revolves,respectful,resource,reply,rendered,regroup,regretting,reeling,reckoned,rebuilding,randy's,ramifications,qualifications,pulitzer,puddy,projections,preschool,pots,potassium,plissken,platonic,peter's,permalash,performer,peasant,outdone,outburst,ogh,obscure,mutants,mugging,molecules,misfortune,miserably,miraculously,medications,medals,margaritas,manpower,lovemaking,long's,logo,logically,leeches,latrine,lamps,lacks,kneel,johnny's,jenny's,inflict,impostor,icon,hypocrisy,hype,hosts,hippies,heterosexual,heightened,hecuba's,hecuba,healer,habitat,gunned,grooming,groo,groin,gras,gory,gooey,gloomy,frying,friendships,fredo,foil,fishermen,firepower,fess,fathom,exhaustion,evils,epi,endeavor,ehh,eggnog,dreaded,drafted,dimensional,detached,deficit,d'arcy,crotch,coughing,coronary,cookin,contributed,consummate,congrats,concerts,companionship,caved,caspar,bulletproof,bris,brilliance,breakin,brash,blasting,beak,arabia,analyst,aluminum,aloud,alligator,airtight,advising,advertise,adultery,administered,aches,abstract,aahh,wronged,wal,voluntary,ventilation,upbeat,uncertainty,trot,trillion,tricia's,trades,tots,tol,tightly,thingies,tending,technician,tarts,surreal,summer's,strengths,specs,specialize,spat,spade,slogan,sloane's,shrew,shaping,seth's,selves,seemingly,schoolwork,roomie,requirements,redundant,redo,recuperating,recommendations,ratio,rabid,quart,pseudo,provocative,proudly,principal's,pretenses,prenatal,pillar,photographers,photographed,pharmaceuticals,patron,pacing,overworked,originals,nicotine,newsletter,neighbours,murderous,miller's,mileage,mechanics,mayonnaise,massages,maroon,lucrative,losin,lil,lending,legislative,kat,juno,iran,interrogated,instruction,injunction,impartial,homing,heartbreaker,harm's,hacks,glands,giver,fraizh,flows,flips,flaunt,excellence,estimated,espionage,englishman,electrocuted,eisenhower,dusting,ducking,drifted,donna's,donating,dom,distribute,diem,daydream,cylon,curves,crutches,crates,cowards,covenant,converted,contributions,composed,comfortably,cod,cockpit,chummy,chitchat,childbirth,charities,businesswoman,brood,brewery,bp's,blatant,bethy,barring,bagged,awakened,assumes,assembled,asbestos,arty,artwork,arc,anthony's,aka,airplanes,accelerated,worshipped,winnings,why're,whilst,wesley's,volleyball,visualize,unprotected,unleash,unexpectedly,twentieth,turnpike,trays,translated,tones,three's,thicker,therapists,takeoff,sums,stub,streisand,storm's,storeroom,stethoscope,stacked,sponsors,spiteful,solutions,sneaks,snapping,slaughtered,slashed,simplest,silverware,shits,secluded,scruples,scrubs,scraps,scholar,ruptured,rubs,roaring,relying,reflected,refers,receptionist,recap,reborn,raisin,rainforest,rae's,raditch,radiator,pushover,pout,plastered,pharmacist,petroleum,perverse,perpetrator,passages,ornament,ointment,occupy,nineties,napping,nannies,mousse,mort,morocco,moors,momentary,modified,mitch's,misunderstandings,marina's,marcy's,marched,manipulator,malfunction,loot,limbs,latitude,lapd,laced,kivar,kickin,interface,infuriating,impressionable,imposing,holdup,hires,hick,hesitated,hebrew,hearings,headphones,hammering,groundwork,grotesque,greenhouse,gradually,graces,genetics,gauze,garter,gangsters,g's,frivolous,freelance,freeing,fours,forwarding,feud,ferrars,faulty,fantasizing,extracurricular,exhaust,empathy,educate,divorces,detonate,depraved,demeaning,declaring,deadlines,dea,daria's,dalai,cursing,cufflink,crows,coupons,countryside,coo,consultation,composer,comply,comforted,clive,claustrophobic,chef's,casinos,caroline's,capsule,camped,cairo,busboy,bred,bravery,bluth,biography,berserk,bennetts,baskets,attacker,aplastic,angrier,affectionate,zit,zapped,yorker,yarn,wormhole,weaken,vat,unrealistic,unravel,unimportant,unforgettable,twain,tv's,tush,turnout,trio,towed,tofu,textbooks,territorial,suspend,supplied,superbowl,sundays,stutter,stewardess,stepson,standin,sshh,specializes,spandex,souvenirs,sociopath,snails,slope,skeletons,shivering,sexier,sequel,sensory,selfishness,scrapbook,romania,riverside,rites,ritalin,rift,ribbons,reunite,remarry,relaxation,reduction,realization,rattling,rapist,quad,pup,psychosis,promotions,presumed,prepping,posture,poses,pleasing,pisses,piling,photographic,pfft,persecuted,pear,part's,pantyhose,padded,outline,organizations,operatives,oohh,obituary,northeast,nina's,neural,negotiator,nba,natty,nathan's,minimize,merl,menopause,mennihan,marty's,martimmys,makers,loyalties,literal,lest,laynie,lando,justifies,josh's,intimately,interact,integrated,inning,inexperienced,impotent,immortality,imminent,ich,horrors,hooky,holders,hinges,heartbreaking,handcuffed,gypsies,guacamole,grovel,graziella,goggles,gestapo,fussy,functional,filmmaker,ferragamo,feeble,eyesight,explosions,experimenting,enzo's,endorsement,enchanting,eee,ed's,duration,doubtful,dizziness,dismantle,disciplinary,disability,detectors,deserving,depot,defective,decor,decline,dangling,dancin,crumble,criteria,creamed,cramping,cooled,conceal,component,competitors,clockwork,clark's,circuits,chrissakes,chrissake,chopping,cabinets,buttercup,brooding,bonfire,blurt,bluestar,bloated,blackmailer,beforehand,bathed,bathe,barcode,banjo,banish,badges,babble,await,attentive,artifacts,aroused,antibodies,animosity,administrator,accomplishments,ya'll,wrinkled,wonderland,willed,whisk,waltzing,waitressing,vis,vin,vila,vigilant,upbringing,unselfish,unpopular,unmarried,uncles,trendy,trajectory,targeting,surroundings,stun,striped,starbucks,stamina,stalled,staking,stag,spoils,snuff,snooty,snide,shrinking,senorita,securities,secretaries,scrutiny,scoundrel,saline,salads,sails,rundown,roz's,roommate's,riddles,responses,resistant,requirement,relapse,refugees,recommending,raspberry,raced,prosperity,programme,presumably,preparations,posts,pom,plight,pleaded,pilot's,peers,pecan,particles,pantry,overturned,overslept,ornaments,opposing,niner,nfl,negligent,negligence,nailing,mutually,mucho,mouthed,monstrous,monarchy,minsk,matt's,mateo's,marking,manufacturing,manager's,malpractice,maintaining,lowly,loitering,logged,lingering,light's,lettin,lattes,kim's,kamal,justification,juror,junction,julie's,joys,johnson's,jillefsky,jacked,irritate,intrusion,inscription,insatiable,infect,inadequate,impromptu,icing,hmmmm,hefty,grammar,generate,gdc,gasket,frightens,flapping,firstborn,fire's,fig,faucet,exaggerated,estranged,envious,eighteenth,edible,downward,dopey,doesn,disposition,disposable,disasters,disappointments,dipped,diminished,dignified,diaries,deported,deficiency,deceit,dealership,deadbeat,curses,coven,counselors,convey,consume,concierge,clutches,christians,cdc,casbah,carefree,callous,cahoots,caf,brotherly,britches,brides,bop,bona,bethie,beige,barrels,ballot,ave,autographed,attendants,attachment,attaboy,astonishing,ashore,appreciative,antibiotic,aneurysm,afterlife,affidavit,zuko,zoning,work's,whats,whaddaya,weakened,watermelon,vasectomy,unsuspecting,trial's,trailing,toula,topanga,tonio,toasted,tiring,thereby,terrorized,tenderness,tch,tailing,syllable,sweats,suffocated,sucky,subconsciously,starvin,staging,sprouts,spineless,sorrows,snowstorm,smirk,slicery,sledding,slander,simmer,signora,sigmund,siege,siberia,seventies,sedate,scented,sampling,sal's,rowdy,rollers,rodent,revenue,retraction,resurrection,resigning,relocate,releases,refusal,referendum,recuperate,receptive,ranking,racketeering,queasy,proximity,provoking,promptly,probability,priors,princes,prerogative,premed,pornography,porcelain,poles,podium,pinched,pig's,pendant,packet,owner's,outsiders,outpost,orbing,opportunist,olanov,observations,nurse's,nobility,neurologist,nate's,nanobot,muscular,mommies,molested,misread,melon,mediterranean,mea,mastermind,mannered,maintained,mackenzie's,liberated,lesions,lee's,laundromat,landscape,lagoon,labeled,jolt,intercom,inspect,insanely,infrared,infatuation,indulgent,indiscretion,inconsiderate,incidents,impaired,hurrah,hungarian,howling,honorary,herpes,hasta,harassed,hanukkah,guides,groveling,groosalug,geographic,gaze,gander,galactica,futile,fridays,flier,fixes,fide,fer,feedback,exploiting,exorcism,exile,evasive,ensemble,endorse,emptied,dreary,dreamy,downloaded,dodged,doctored,displayed,disobeyed,disneyland,disable,diego's,dehydrated,defect,customary,csc,criticizing,contracted,contemplating,consists,concepts,compensate,commonly,colours,coins,coconuts,cockroaches,clogged,cincinnati,churches,chronicle,chilling,chaperon,ceremonies,catalina's,cant,cameraman,bulbs,bucklands,bribing,brava,bracelets,bowels,bobby's,bmw,bluepoint,baton,barred,balm,audit,astronomy,aruba,appetizers,appendix,antics,anointed,analogy,almonds,albuquerque,abruptly,yore,yammering,winch,white's,weston's,weirdness,wangler,vibrations,vendor,unmarked,unannounced,twerp,trespass,tres,travesty,transported,transfusion,trainee,towelie,topics,tock,tiresome,thru,theatrical,terrain,suspect's,straightening,staggering,spaced,sonar,socializing,sitcom,sinus,sinners,shambles,serene,scraped,scones,scepter,sarris,saberhagen,rouge,rigid,ridiculously,ridicule,reveals,rents,reflecting,reconciled,rate's,radios,quota,quixote,publicist,pubes,prune,prude,provider,propaganda,prolonged,projecting,prestige,precrime,postponing,pluck,perpetual,permits,perish,peppermint,peeled,particle,parliament,overdo,oriented,optional,nutshell,notre,notions,nostalgic,nomination,mulan,mouthing,monkey's,mistook,mis,milhouse,mel's,meddle,maybourne,martimmy,loon,lobotomy,livelihood,litigation,lippman,likeness,laurie's,kindest,kare,kaffee,jocks,jerked,jeopardizing,jazzed,investing,insured,inquisition,inhale,ingenious,inflation,incorrect,igby,ideals,holier,highways,hereditary,helmets,heirloom,heinous,haste,harmsway,hardship,hanky,gutters,gruesome,groping,governments,goofing,godson,glare,garment,founding,fortunes,foe,finesse,figuratively,ferrie,fda,external,examples,evacuation,ethnic,est,endangerment,enclosed,emphasis,dyed,dud,dreading,dozed,dorky,dmitri,divert,dissertation,discredit,director's,dialing,describes,decks,cufflinks,crutch,creator,craps,corrupted,coronation,contemporary,consumption,considerably,comprehensive,cocoon,cleavage,chile,carriers,carcass,cannery,bystander,brushes,bruising,bribery,brainstorm,bolted,binge,bart's,barracuda,baroness,ballistics,b's,astute,arroway,arabian,ambitions,alexandra's,afar,adventurous,adoptive,addicts,addictive,accessible,yadda,wilson's,wigs,whitelighters,wematanye,weeds,wedlock,wallets,walker's,vulnerability,vroom,vibrant,vertical,vents,uuuh,urgh,upped,unsettling,unofficial,unharmed,underlying,trippin,trifle,tracing,tox,tormenting,timothy's,threads,theaters,thats,tavern,taiwan,syphilis,susceptible,summary,suites,subtext,stickin,spices,sores,smacked,slumming,sixteenth,sinks,signore,shitting,shameful,shacked,sergei,septic,seedy,security's,searches,righteousness,removal,relish,relevance,rectify,recruits,recipient,ravishing,quickest,pupil,productions,precedence,potent,pooch,pledged,phoebs,perverted,peeing,pedicure,pastrami,passionately,ozone,overlooking,outnumbered,outlook,oregano,offender,nukes,novelty,nosed,nighty,nifty,mugs,mounties,motivate,moons,misinterpreted,miners,mercenary,mentality,mas,marsellus,mapped,malls,lupus,lumbar,lovesick,longitude,lobsters,likelihood,leaky,laundering,latch,japs,jafar,instinctively,inspires,inflicted,inflammation,indoors,incarcerated,imagery,hundredth,hula,hemisphere,handkerchief,hand's,gynecologist,guittierez,groundhog,grinning,graduates,goodbyes,georgetown,geese,fullest,ftl,floral,flashback,eyelashes,eyelash,excluded,evening's,evacuated,enquirer,endlessly,encounters,elusive,disarm,detest,deluding,dangle,crabby,cotillion,corsage,copenhagen,conjugal,confessional,cones,commandment,coded,coals,chuckle,christmastime,christina's,cheeseburgers,chardonnay,ceremonial,cept,cello,celery,carter's,campfire,calming,burritos,burp,buggy,brundle,broflovski,brighten,bows,borderline,blinked,bling,beauties,bauers,battered,athletes,assisting,articulate,alot,alienated,aleksandr,ahhhhh,agreements,agamemnon,accountants,zat,y'see,wrongful,writer's,wrapper,workaholic,wok,winnebago,whispered,warts,vikki's,verified,vacate,updated,unworthy,unprecedented,unanswered,trend,transformed,transform,trademark,tote,tonane,tolerated,throwin,throbbing,thriving,thrills,thorns,thereof,there've,terminator,tendencies,tarot,tailed,swab,sunscreen,stretcher,stereotype,spike's,soggy,sobbing,slopes,skis,skim,sizable,sightings,shucks,shrapnel,sever,senile,sections,seaboard,scripts,scorned,saver,roxanne's,resemble,red's,rebellious,rained,putty,proposals,prenup,positioned,portuguese,pores,pinching,pilgrims,pertinent,peeping,pamphlet,paints,ovulating,outbreak,oppression,opposites,occult,nutcracker,nutcase,nominee,newt,newsstand,newfound,nepal,mocked,midterms,marshmallow,manufacturer,managers,majesty's,maclaren,luscious,lowered,loops,leans,laurence's,krudski,knowingly,keycard,katherine's,junkies,juilliard,judicial,jolinar,jase,irritable,invaluable,inuit,intoxicating,instruct,insolent,inexcusable,induce,incubator,illustrious,hydrogen,hunsecker,hub,houseguest,honk,homosexuals,homeroom,holly's,hindu,hernia,harming,handgun,hallways,hallucination,gunshots,gums,guineas,groupies,groggy,goiter,gingerbread,giggling,geometry,genre,funded,frontal,frigging,fledged,fedex,feat,fairies,eyeball,extending,exchanging,exaggeration,esteemed,ergo,enlist,enlightenment,encyclopedia,drags,disrupted,dispense,disloyal,disconnect,dimitri,desks,dentists,delhi,delacroix,degenerate,deemed,decay,daydreaming,cushions,cuddly,corroborate,contender,congregation,conflicts,confessions,complexion,completion,compensated,cobbler,closeness,chilled,checkmate,channing,carousel,calms,bylaws,bud's,benefactor,belonging,ballgame,baiting,backstabbing,assassins,artifact,armies,appoint,anthropology,anthropologist,alzheimer's,allegedly,alex's,airspace,adversary,adolf,actin,acre,aced,accuses,accelerant,abundantly,abstinence,abc,zsa,zissou,zandt,yom,yapping,wop,witchy,winter's,willows,whee,whadaya,want's,walter's,waah,viruses,vilandra,veiled,unwilling,undress,undivided,underestimating,ultimatums,twirl,truckload,tremble,traditionally,touring,touche,toasting,tingling,tiles,tents,tempered,sussex,sulking,stunk,stretches,sponges,spills,softly,snipers,slid,sedan,screens,scourge,rooftop,rog,rivalry,rifles,riana,revolting,revisit,resisted,rejects,refreshments,redecorating,recurring,recapture,raysy,randomly,purchases,prostitutes,proportions,proceeded,prevents,pretense,prejudiced,precogs,pouting,poppie,poofs,pimple,piles,pediatrician,patrick's,pathology,padre,packets,paces,orvelle,oblivious,objectivity,nikki's,nighttime,nervosa,navigation,moist,moan,minors,mic,mexicans,meurice,melts,mau,mats,matchmaker,markings,maeby,lugosi,lipnik,leprechaun,kissy,kafka,italians,introductions,intestines,intervene,inspirational,insightful,inseparable,injections,informal,influential,inadvertently,illustrated,hussy,huckabees,hmo,hittin,hiss,hemorrhaging,headin,hazy,haystack,hallowed,haiti,haa,grudges,grenades,granilith,grandkids,grading,gracefully,godsend,gobbles,fyi,future's,fun's,fret,frau,fragrance,fliers,firms,finchley,fbi's,farts,eyewitnesses,expendable,existential,endured,embraced,elk,ekg,dude's,dragonfly,dorms,domination,directory,depart,demonstrated,delaying,degrading,deduction,darlings,dante's,danes,cylons,counsellor,cortex,cop's,coordinator,contraire,consensus,consciously,conjuring,congratulating,compares,commentary,commandant,cokes,centimeters,cc's,caucus,casablanca,buffay,buddy's,brooch,bony,boggle,blood's,bitching,bistro,bijou,bewitched,benevolent,bends,bearings,barren,arr,aptitude,antenna,amish,amazes,alcatraz,acquisitions,abomination,worldly,woodstock,withstand,whispers,whadda,wayward,wayne's,wailing,vinyl,variables,vanishing,upscale,untouchable,unspoken,uncontrollable,unavoidable,unattended,tuning,trite,transvestite,toupee,timid,timers,themes,terrorizing,teamed,taipei,t's,swana,surrendered,suppressed,suppress,stumped,strolling,stripe,storybook,storming,stomachs,stoked,stationery,springtime,spontaneity,sponsored,spits,spins,soiree,sociology,soaps,smarty,shootout,shar,settings,sentiments,senator's,scramble,scouting,scone,runners,rooftops,retract,restrictions,residency,replay,remainder,regime,reflexes,recycling,rcmp,rawdon,ragged,quirky,quantico,psychologically,prodigal,primo,pounce,potty,portraits,pleasantries,plane's,pints,phd,petting,perceive,patrons,parameters,outright,outgoing,onstage,officer's,o'connor,notwithstanding,noah's,nibble,newmans,neutralize,mutilated,mortality,monumental,ministers,millionaires,mentions,mcdonald's,mayflower,masquerade,mangy,macreedy,lunatics,luau,lover's,lovable,louie's,locating,lizards,limping,lasagna,largely,kwang,keepers,juvie,jaded,ironing,intuitive,intensely,insure,installation,increases,incantation,identifying,hysteria,hypnotize,humping,heavyweight,happenin,gung,griet,grasping,glorified,glib,ganging,g'night,fueled,focker,flunking,flimsy,flaunting,fixated,fitzwallace,fictional,fearing,fainting,eyebrow,exonerated,ether,ers,electrician,egotistical,earthly,dusted,dues,donors,divisions,distinguish,displays,dismissal,dignify,detonation,deploy,departments,debrief,dazzling,dawn's,dan'l,damnedest,daisies,crushes,crucify,cordelia's,controversy,contraband,contestants,confronting,communion,collapsing,cocked,clock's,clicks,cliche,circular,circled,chord,characteristics,chandelier,casualty,carburetor,callers,bup,broads,breathes,boca,bobbie's,bloodshed,blindsided,blabbing,binary,bialystock,bashing,ballerina,ball's,aviva,avalanche,arteries,appliances,anthem,anomaly,anglo,airstrip,agonizing,adjourn,abandonment,zack's,you's,yearning,yams,wrecker,word's,witnessing,winged,whence,wept,warsaw,warp,warhead,wagons,visibility,usc,unsure,unions,unheard,unfreeze,unfold,unbalanced,ugliest,troublemaker,tolerant,toddler,tiptoe,threesome,thirties,thermostat,tampa,sycamore,switches,swipe,surgically,supervising,subtlety,stung,stumbling,stubs,struggles,stride,strangling,stamp's,spruce,sprayed,socket,snuggle,smuggled,skulls,simplicity,showering,shhhhh,sensor,sci,sac,sabotaging,rumson,rounding,risotto,riots,revival,responds,reserves,reps,reproduction,repairman,rematch,rehearsed,reelection,redi,recognizing,ratty,ragging,radiology,racquetball,racking,quieter,quicksand,pyramids,pulmonary,puh,publication,prowl,provisions,prompt,premeditated,prematurely,prancing,porcupine,plated,pinocchio,perceived,peeked,peddle,pasture,panting,overweight,oversee,overrun,outing,outgrown,obsess,o'donnell,nyu,nursed,northwestern,norma's,nodding,negativity,negatives,musketeers,mugger,mounting,motorcade,monument,merrily,matured,massimo's,masquerading,marvellous,marlena's,margins,maniacs,mag,lumpy,lovey,louse,linger,lilies,libido,lawful,kudos,knuckle,kitchen's,kennedy's,juices,judgments,joshua's,jars,jams,jamal's,jag,itches,intolerable,intermission,interaction,institutions,infectious,inept,incentives,incarceration,improper,implication,imaginative,ight,hussein,humanitarian,huckleberry,horatio,holster,heiress,heartburn,hayley's,hap,gunna,guitarist,groomed,greta's,granting,graciously,glee,gentleman's,fulfillment,fugitives,fronts,founder,forsaking,forgives,foreseeable,flavors,flares,fixation,figment,fickle,featuring,featured,fantasize,famished,faith's,fades,expiration,exclamation,evolve,euro,erasing,emphasize,elevator's,eiffel,eerie,earful,duped,dulles,distributor,distorted,dissing,dissect,dispenser,dilated,digit,differential,diagnostic,detergent,desdemona,debriefing,dazzle,damper,cylinder,curing,crowbar,crispina,crafty,crackpot,courting,corrections,cordial,copying,consuming,conjunction,conflicted,comprehension,commie,collects,cleanup,chiropractor,charmer,chariot,charcoal,chaplain,challenger,census,cd's,cauldron,catatonic,capabilities,calculate,bullied,buckets,brilliantly,breathed,boss's,booths,bombings,boardroom,blowout,blower,blip,blindness,blazing,birthday's,biologically,bibles,biased,beseech,barbaric,band's,balraj,auditorium,audacity,assisted,appropriations,applicants,anticipating,alcoholics,airhead,agendas,aft,admittedly,adapt,absolution,abbot,zing,youre,yippee,wittlesey,withheld,willingness,willful,whammy,webber's,weakest,washes,virtuous,violently,videotapes,vials,vee,unplugged,unpacked,unfairly,und,turbulence,tumbling,troopers,tricking,trenches,tremendously,travelled,travelers,traitors,torches,tommy's,tinga,thyroid,texture,temperatures,teased,tawdry,tat,taker,sympathies,swiped,swallows,sundaes,suave,strut,structural,stone's,stewie,stepdad,spewing,spasm,socialize,slither,sky's,simulator,sighted,shutters,shrewd,shocks,sherry's,sgc,semantics,scout's,schizophrenic,scans,savages,satisfactory,rya'c,runny,ruckus,royally,roadblocks,riff,rewriting,revoke,reversal,repent,renovation,relating,rehearsals,regal,redecorate,recovers,recourse,reconnaissance,receives,ratched,ramali,racquet,quince,quiche,puppeteer,puking,puffed,prospective,projected,problemo,preventing,praises,pouch,posting,postcards,pooped,poised,piled,phoney,phobia,performances,patty's,patching,participating,parenthood,pardner,oppose,oozing,oils,ohm,ohhhhh,nypd,numbing,novelist,nostril,nosey,nominate,noir,neatly,nato,naps,nappa,nameless,muzzle,muh,mortuary,moronic,modesty,mitz,missionary,mimi's,midwife,mercenaries,mcclane,maxie's,matuka,mano,mam,maitre,lush,lumps,lucid,loosened,loosely,loins,lawnmower,lane's,lamotta,kroehner,kristen's,juggle,jude's,joins,jinxy,jessep,jaya,jamming,jailhouse,jacking,ironically,intruders,inhuman,infections,infatuated,indoor,indigestion,improvements,implore,implanted,id's,hormonal,hoboken,hillbilly,heartwarming,headway,headless,haute,hatched,hartmans,harping,hari,grapevine,graffiti,gps,gon,gogh,gnome,ged,forties,foreigners,fool's,flyin,flirted,fingernail,fdr,exploration,expectation,exhilarating,entrusted,enjoyment,embark,earliest,dumper,duel,dubious,drell,dormant,docking,disqualified,disillusioned,dishonor,disbarred,directive,dicey,denny's,deleted,del's,declined,custodial,crunchy,crises,counterproductive,correspondent,corned,cords,cor,coot,contributing,contemplate,containers,concur,conceivable,commissioned,cobblepot,cliffs,clad,chief's,chickened,chewbacca,checkout,carpe,cap'n,campers,calcium,buyin,buttocks,bullies,brown's,brigade,brain's,braid,boxed,bouncy,blueberries,blubbering,bloodstream,bigamy,bel,beeped,bearable,bank's,awarded,autographs,attracts,attracting,asteroid,arbor,arab,apprentice,announces,andie's,ammonia,alarming,aidan's,ahoy,ahm,zan,wretch,wimps,widows,widower,whirlwind,whirl,weather's,warms,war's,wack,villagers,vie,vandelay,unveiling,uno,undoing,unbecoming,ucla,turnaround,tribunal,togetherness,tickles,ticker,tended,teensy,taunt,system's,sweethearts,superintendent,subcommittee,strengthen,stomach's,stitched,standpoint,staffers,spotless,splits,soothe,sonnet,smothered,sickening,showdown,shouted,shepherds,shelters,shawl,seriousness,separates,sen,schooled,schoolboy,scat,sats,sacramento,s'mores,roped,ritchie's,resembles,reminders,regulars,refinery,raggedy,profiles,preemptive,plucked,pheromones,particulars,pardoned,overpriced,overbearing,outrun,outlets,onward,oho,ohmigod,nosing,norwegian,nightly,nicked,neanderthal,mosquitoes,mortified,moisture,moat,mime,milky,messin,mecha,markinson,marivellas,mannequin,manderley,maid's,madder,macready,maciver's,lookie,locusts,lisbon,lifetimes,leg's,lanna,lakhi,kholi,joke's,invasive,impersonate,impending,immigrants,ick,i's,hyperdrive,horrid,hopin,hombre,hogging,hens,hearsay,haze,harpy,harboring,hairdo,hafta,hacking,gun's,guardians,grasshopper,graded,gobble,gatehouse,fourteenth,foosball,floozy,fitzgerald's,fished,firewood,finalize,fever's,fencing,felons,falsely,fad,exploited,euphemism,entourage,enlarged,ell,elitist,elegance,eldest,duo,drought,drokken,drier,dredge,dramas,dossier,doses,diseased,dictator,diarrhea,diagnose,despised,defuse,defendant's,d'amour,crowned,cooper's,continually,contesting,consistently,conserve,conscientious,conjured,completing,commune,commissioner's,collars,coaches,clogs,chenille,chatty,chartered,chamomile,casing,calculus,calculator,brittle,breached,boycott,blurted,birthing,bikinis,bankers,balancing,astounding,assaulting,aroma,arbitration,appliance,antsy,amnio,alienating,aliases,aires,adolescence,administrative,addressing,achieving,xerox,wrongs,workload,willona,whistling,werewolves,wallaby,veterans,usin,updates,unwelcome,unsuccessful,unseemly,unplug,undermining,ugliness,tyranny,tuesdays,trumpets,transference,traction,ticks,tete,tangible,tagging,swallowing,superheroes,sufficiently,studs,strep,stowed,stow,stomping,steffy,stature,stairway,sssh,sprain,spouting,sponsoring,snug,sneezing,smeared,slop,slink,slew,skid,simultaneously,simulation,sheltered,shakin,sewed,sewage,seatbelt,scariest,scammed,scab,sanctimonious,samir,rushes,rugged,routes,romanov,roasting,rightly,retinal,rethinking,resulted,resented,reruns,replica,renewed,remover,raiding,raided,racks,quantity,purest,progressing,primarily,presidente,prehistoric,preeclampsia,postponement,portals,poppa,pop's,pollution,polka,pliers,playful,pinning,pharaoh,perv,pennant,pelvic,paved,patented,paso,parted,paramedic,panels,pampered,painters,padding,overjoyed,orthodox,organizer,one'll,octavius,occupational,oakdale's,nous,nite,nicknames,neurosurgeon,narrows,mitt,misled,mislead,mishap,milltown,milking,microscopic,meticulous,mediocrity,meatballs,measurements,mandy's,malaria,machete,lydecker's,lurch,lorelai's,linda's,layin,lavish,lard,knockin,khruschev,kelso's,jurors,jumpin,jugular,journalists,jour,jeweler,jabba,intersection,intellectually,integral,installment,inquiries,indulging,indestructible,indebted,implicated,imitate,ignores,hyperventilating,hyenas,hurrying,huron,horizontal,hermano,hellish,heheh,header,hazardous,hart's,harshly,harper's,handout,handbag,grunemann,gots,glum,gland,glances,giveaway,getup,gerome,furthest,funhouse,frosting,franchise,frail,fowl,forwarded,forceful,flavored,flank,flammable,flaky,fingered,finalists,fatherly,famine,fags,facilitate,exempt,exceptionally,ethic,essays,equity,entrepreneur,enduring,empowered,employers,embezzlement,eels,dusk,duffel,downfall,dotted,doth,doke,distressed,disobey,disappearances,disadvantage,dinky,diminish,diaphragm,deuces,deployed,delia's,davidson's,curriculum,curator,creme,courteous,correspondence,conquered,comforts,coerced,coached,clots,clarification,cite,chunks,chickie,chick's,chases,chaperoning,ceramic,ceased,cartons,capri,caper,cannons,cameron's,calves,caged,bustin,bungee,bulging,bringin,brie,boomhauer,blowin,blindfolded,blab,biscotti,bird's,beneficial,bastard's,ballplayer,bagging,automated,auster,assurances,aschen,arraigned,anonymity,annex,animation,andi,anchorage,alters,alistair's,albatross,agreeable,advancement,adoring,accurately,abduct,wolfi,width,weirded,watchers,washroom,warheads,voltage,vincennes,villains,victorian,urgency,upward,understandably,uncomplicated,uhuh,uhhhh,twitching,trig,treadmill,transactions,topped,tiffany's,they's,thermos,termination,tenorman,tater,tangle,talkative,swarm,surrendering,summoning,substances,strive,stilts,stickers,stationary,squish,squashed,spraying,spew,sparring,sorrel's,soaring,snout,snort,sneezed,slaps,skanky,singin,sidle,shreck,shortness,shorthand,shepherd's,sharper,shamed,sculptures,scanning,saga,sadist,rydell,rusik,roulette,rodi's,rockefeller,revised,resumes,restoring,respiration,reiber's,reek,recycle,recount,reacts,rabbit's,purge,purgatory,purchasing,providence,prostate,princesses,presentable,poultry,ponytail,plotted,playwright,pinot,pigtails,pianist,phillippe,philippines,peddling,paroled,owww,orchestrated,orbed,opted,offends,o'hara,noticeable,nominations,nancy's,myrtle's,music's,mope,moonlit,moines,minefield,metaphors,memoirs,mecca,maureen's,manning's,malignant,mainframe,magicks,maggots,maclaine,lobe,loathing,linking,leper,leaps,leaping,lashed,larch,larceny,lapses,ladyship,juncture,jiffy,jane's,jakov,invoke,interpreted,internally,intake,infantile,increasingly,inadmissible,implement,immense,howl,horoscope,hoof,homage,histories,hinting,hideaway,hesitating,hellbent,heddy,heckles,hat's,harmony's,hairline,gunpowder,guidelines,guatemala,gripe,gratifying,grants,governess,gorge,goebbels,gigolo,generated,gears,fuzz,frigid,freddo,freddie's,foresee,filters,filmed,fertile,fellowship,feeling's,fascination,extinction,exemplary,executioner,evident,etcetera,estimates,escorts,entity,endearing,encourages,electoral,eaters,earplugs,draped,distributors,disrupting,disagrees,dimes,devastate,detain,deposits,depositions,delicacy,delays,darklighter,dana's,cynicism,cyanide,cutters,cronus,convoy,continuous,continuance,conquering,confiding,concentrated,compartments,companions,commodity,combing,cofell,clingy,cleanse,christmases,cheered,cheekbones,charismatic,cabaret,buttle,burdened,buddhist,bruenell,broomstick,brin,brained,bozos,bontecou,bluntman,blazes,blameless,bizarro,benny's,bellboy,beaucoup,barry's,barkeep,bali,bala,bacterial,axis,awaken,astray,assailant,aslan,arlington,aria,appease,aphrodisiac,announcements,alleys,albania,aitoro's,activation,acme,yesss,wrecks,woodpecker,wondrous,window's,wimpy,willpower,widowed,wheeling,weepy,waxing,waive,vulture,videotaped,veritable,vascular,variations,untouched,unlisted,unfounded,unforeseen,two's,twinge,truffles,triggers,traipsing,toxin,tombstone,titties,tidal,thumping,thor's,thirds,therein,testicles,tenure,tenor,telephones,technicians,tarmac,talby,tackled,systematically,swirling,suicides,suckered,subtitles,sturdy,strangler,stockbroker,stitching,steered,staple,standup,squeal,sprinkler,spontaneously,splendor,spiking,spender,sovereign,snipe,snip,snagged,slum,skimming,significantly,siddown,showroom,showcase,shovels,shotguns,shoelaces,shitload,shifty,shellfish,sharpest,shadowy,sewn,seizing,seekers,scrounge,scapegoat,sayonara,satan's,saddled,rung,rummaging,roomful,romp,retained,residual,requiring,reproductive,renounce,reggie's,reformed,reconsidered,recharge,realistically,radioed,quirks,quadrant,punctual,public's,presently,practising,pours,possesses,poolhouse,poltergeist,pocketbook,plural,plots,pleasure's,plainly,plagued,pity's,pillars,picnics,pesto,pawing,passageway,partied,para,owing,openings,oneself,oats,numero,nostalgia,nocturnal,nitwit,nile,nexus,neuro,negotiated,muss,moths,mono,molecule,mixer,medicines,meanest,mcbeal,matinee,margate,marce,manipulations,manhunt,manger,magicians,maddie's,loafers,litvack,lightheaded,lifeguard,lawns,laughingstock,kodak,kink,jewellery,jessie's,jacko,itty,inhibitor,ingested,informing,indignation,incorporate,inconceivable,imposition,impersonal,imbecile,ichabod,huddled,housewarming,horizons,homicides,hobo,historically,hiccups,helsinki,hehe,hearse,harmful,hardened,gushing,gushie,greased,goddamit,gigs,freelancer,forging,fonzie,fondue,flustered,flung,flinch,flicker,flak,fixin,finalized,fibre,festivus,fertilizer,fenmore's,farted,faggots,expanded,exonerate,exceeded,evict,establishing,enormously,enforced,encrypted,emdash,embracing,embedded,elliot's,elimination,dynamics,duress,dupres,dowser,doormat,dominant,districts,dissatisfied,disfigured,disciplined,discarded,dibbs,diagram,detailing,descend,depository,defining,decorative,decoration,deathbed,death's,dazzled,da's,cuttin,cures,crowding,crepe,crater,crammed,costly,cosmopolitan,cortlandt's,copycat,coordinated,conversion,contradict,containing,constructed,confidant,condemning,conceited,computer's,commute,comatose,coleman's,coherent,clinics,clapping,circumference,chuppah,chore,choksondik,chestnuts,catastrophic,capitalist,campaigning,cabins,briault,bottomless,boop,bonnet,board's,bloomingdale's,blokes,blob,bids,berluti,beret,behavioral,beggars,bar's,bankroll,bania,athos,assassinate,arsenic,apperantly,ancestor,akron,ahhhhhh,afloat,adjacent,actresses,accordingly,accents,abe's,zipped,zeros,zeroes,zamir,yuppie,youngsters,yorkers,writ,wisest,wipes,wield,whyn't,weirdos,wednesdays,villages,vicksburg,variable,upchuck,untraceable,unsupervised,unpleasantness,unpaid,unhook,unconscionable,uncalled,turks,tumors,trappings,translating,tragedies,townie,timely,tiki,thurgood,things'll,thine,tetanus,terrorize,temptations,teamwork,tanning,tampons,tact,swarming,surfaced,supporter,stuart's,stranger's,straitjacket,stint,stimulation,steroid,statistically,startling,starry,squander,speculating,source's,sollozzo,sobriety,soar,sneaked,smithsonian,slugs,slaw,skit,skedaddle,sinker,similarities,silky,shortcomings,shipments,sheila's,severity,sellin,selective,seattle's,seasoned,scrubbed,scrooge,screwup,scrapes,schooling,scarves,saturdays,satchel,sandburg's,sandbox,salesmen,rooming,romances,revolving,revere,resulting,reptiles,reproach,reprieve,recreational,rearranging,realtor,ravine,rationalize,raffle,quoted,punchy,psychobabble,provocation,profoundly,problematic,prescriptions,preferable,praised,polishing,poached,plow,pledges,planetary,plan's,pirelli,perverts,peaked,pastures,pant,oversized,overdressed,outdid,outdated,oriental,ordinance,orbs,opponents,occurrence,nuptials,nominees,nineteenth,nefarious,mutiny,mouthpiece,motels,mopping,moon's,mongrel,monetary,mommie,missin,metaphorically,merv,mertin,memos,memento,melodrama,melancholy,measles,meaner,marches,mantel,maneuvers,maneuvering,mailroom,machine's,luring,listenin,lion's,lifeless,liege,licks,libraries,liberties,levon,legwork,lanka,lacked,kneecaps,kippur,kiddie,kaput,justifiable,jigsaw,issuing,islamic,insistent,insidious,innuendo,innit,inhabitants,individually,indicator,indecent,imaginable,illicit,hymn,hurling,humane,hospitalized,horseshit,hops,hondo,hemorrhoid,hella,healthiest,haywire,hamsters,halibut,hairbrush,hackers,guam,grouchy,grisly,griffin's,gratuitous,glutton,glimmer,gibberish,ghastly,geologist,gentler,generously,generators,geeky,gaga,furs,fuhrer,fronting,forklift,foolin,fluorescent,flats,flan,financed,filmmaking,fight's,faxes,faceless,extinguisher,expressions,expel,etched,entertainer,engagements,endangering,empress,egos,educator,ducked,dual,dramatically,dodgeball,dives,diverted,dissolved,dislocated,discrepancy,discovers,dink,devour,destroyers,derail,deputies,dementia,decisive,daycare,daft,cynic,crumbling,cowardice,cow's,covet,cornwallis,corkscrew,cookbook,conditioned,commendation,commandments,columns,coincidental,cobwebs,clouded,clogging,clicking,clasp,citizenship,chopsticks,chefs,chaps,catherine's,castles,cashing,carat,calmer,burgundy,bulldog's,brightly,brazen,brainwashing,bradys,bowing,booties,bookcase,boned,bloodsucking,blending,bleachers,bleached,belgian,bedpan,bearded,barrenger,bachelors,awwww,atop,assures,assigning,asparagus,arabs,apprehend,anecdote,amoral,alterations,alli,aladdin,aggravation,afoot,acquaintances,accommodating,accelerate,yakking,wreckage,worshipping,wladek,willya,willies,wigged,whoosh,whisked,wavelength,watered,warpath,warehouses,volts,vitro,violates,viewed,vicar,valuables,users,urging,uphill,unwise,untimely,unsavory,unresponsive,unpunished,unexplained,unconventional,tubby,trolling,treasurer,transfers,toxicology,totaled,tortoise,tormented,toothache,tingly,tina's,timmiihh,tibetan,thursdays,thoreau,terrifies,temperature's,temperamental,telegrams,ted's,technologies,teaming,teal'c's,talkie,takers,table's,symbiote,swirl,suffocate,subsequently,stupider,strapping,store's,steckler,standardized,stampede,stainless,springing,spreads,spokesperson,speeds,someway,snowflake,sleepyhead,sledgehammer,slant,slams,situation's,showgirl,shoveling,shmoopy,sharkbait,shan't,seminars,scrambling,schizophrenia,schematics,schedule's,scenic,sanitary,sandeman,saloon,sabbatical,rural,runt,rummy,rotate,reykjavik,revert,retrieved,responsive,rescheduled,requisition,renovations,remake,relinquish,rejoice,rehabilitation,recreation,reckoning,recant,rebuilt,rebadow,reassurance,reassigned,rattlesnake,ramble,racism,quor,prowess,prob,primed,pricey,predictions,prance,pothole,pocus,plains,pitches,pistols,persist,perpetrated,penal,pekar,peeling,patter,pastime,parmesan,paper's,papa's,panty,pail,pacemaker,overdrive,optic,operas,ominous,offa,observant,nothings,noooooo,nonexistent,nodded,nieces,neia,neglecting,nauseating,mutton,mutated,musket,munson's,mumbling,mowing,mouthful,mooseport,monologue,momma's,moly,mistrust,meetin,maximize,masseuse,martha's,marigold,mantini,mailer,madre,lowlifes,locksmith,livid,liven,limos,licenses,liberating,lhasa,lenin,leniency,leering,learnt,laughable,lashes,lasagne,laceration,korben,katan,kalen,jordan's,jittery,jesse's,jammies,irreplaceable,intubate,intolerant,inhaler,inhaled,indifferent,indifference,impound,imposed,impolite,humbly,holocaust,heroics,heigh,gunk,guillotine,guesthouse,grounding,groundbreaking,groom's,grips,grant's,gossiping,goatee,gnomes,gellar,fusion's,fumble,frutt,frobisher,freudian,frenchman,foolishness,flagged,fixture,femme,feeder,favored,favorable,fatso,fatigue,fatherhood,farmer's,fantasized,fairest,faintest,factories,eyelids,extravagant,extraterrestrial,extraordinarily,explicit,escalator,eros,endurance,encryption,enchantment's,eliminating,elevate,editors,dysfunction,drivel,dribble,dominican,dissed,dispatched,dismal,disarray,dinnertime,devastation,dermatologist,delicately,defrost,debutante,debacle,damone,dainty,cuvee,culpa,crucified,creeped,crayons,courtship,counsel's,convene,continents,conspicuous,congresswoman,confinement,conferences,confederate,concocted,compromises,comprende,composition,communism,comma,collectors,coleslaw,clothed,clinically,chug,chickenshit,checkin,chaotic,cesspool,caskets,cancellation,calzone,brothel,boomerang,bodega,bloods,blasphemy,black's,bitsy,bink,biff,bicentennial,berlini,beatin,beards,barbas,barbarians,backpacking,audiences,artist's,arrhythmia,array,arousing,arbitrator,aqui,appropriately,antagonize,angling,anesthetic,altercation,alice's,aggressor,adversity,adopting,acne,accordance,acathla,aaahhh,wreaking,workup,workings,wonderin,wolf's,wither,wielding,whopper,what'm,what'cha,waxed,vibrating,veterinarian,versions,venting,vasey,valor,validate,urged,upholstery,upgraded,untied,unscathed,unsafe,unlawful,uninterrupted,unforgiving,undies,uncut,twinkies,tucking,tuba,truffle,truck's,triplets,treatable,treasured,transmit,tranquility,townspeople,torso,tomei,tipsy,tinsel,timeline,tidings,thirtieth,tensions,teapot,tasks,tantrums,tamper,talky,swayed,swapping,sven,sulk,suitor,subjected,stylist,stroller,storing,stirs,statistical,standoff,staffed,squadron,sprinklers,springsteen,specimens,sparkly,song's,snowy,snobby,snatcher,smoother,smith's,sleepin,shrug,shortest,shoebox,shel,sheesh,shee,shackles,setbacks,sedatives,screeching,scorched,scanned,satyr,sammy's,sahib,rosemary's,rooted,rods,roadblock,riverbank,rivals,ridiculed,resentful,repellent,relates,registry,regarded,refugee,recreate,reconvene,recalled,rebuttal,realmedia,quizzes,questionnaire,quartet,pusher,punctured,pucker,propulsion,promo,prolong,professionalism,prized,premise,predators,portions,pleasantly,planet's,pigsty,physicist,phil's,penniless,pedestrian,paychecks,patiently,paternal,parading,pa's,overactive,ovaries,orderlies,oracles,omaha,oiled,offending,nudie,neonatal,neighborly,nectar,nautical,naught,moops,moonlighting,mobilize,mite,misleading,milkshake,mickey's,metropolitan,menial,meats,mayan,maxed,marketplace,mangled,magua,lunacy,luckier,llanview's,livestock,liters,liter,licorice,libyan,legislature,lasers,lansbury,kremlin,koreans,kooky,knowin,kilt,junkyard,jiggle,jest,jeopardized,jags,intending,inkling,inhalation,influences,inflated,inflammatory,infecting,incense,inbound,impractical,impenetrable,iffy,idealistic,i'mma,hypocrites,hurtin,humbled,hosted,homosexuality,hologram,hokey,hocus,hitchhiking,hemorrhoids,headhunter,hassled,harts,hardworking,haircuts,hacksaw,guerrilla,genitals,gazillion,gatherings,ganza's,gammy,gamesphere,fugue,fuels,forests,footwear,folly,folds,flexibility,flattened,flashlights,fives,filet,field's,famously,extenuating,explored,exceed,estrogen,envisioned,entails,emerged,embezzled,eloquent,egomaniac,dummies,duds,ducts,drowsy,drones,dragon's,drafts,doree,donovon,donny's,docked,dixon's,distributed,disorders,disguises,disclose,diggin,dickie's,detachment,deserting,depriving,demographic,delegation,defying,deductible,decorum,decked,daylights,daybreak,dashboard,darien,damnation,d'angelo's,cuddling,crunching,crickets,crazies,crayon,councilman,coughed,coordination,conundrum,contractors,contend,considerations,compose,complimented,compliance,cohaagen,clutching,cluster,clued,climbs,clader,chuck's,chromosome,cheques,checkpoint,chats,channeling,ceases,catholics,cassius,carver's,carasco,capped,capisce,cantaloupe,cancelling,campsite,camouflage,cambodia,burglars,bureaucracy,breakfasts,branding,bra'tac,book's,blueprint,bleedin,blaze's,blabbed,bisexual,bile,big's,beverages,beneficiary,battery's,basing,avert,avail,autobiography,atone,army's,arlyn,ares,architectural,approves,apothecary,anus,antiseptic,analytical,amnesty,alphabetical,alignment,aligned,aleikuum,advisory,advisors,advisement,adulthood,acquiring,accessed,zombie's,zadir,wrestled,wobbly,withnail,wheeled,whattaya,whacking,wedged,wanders,walkman,visionary,virtues,vincent's,vega's,vaginal,usage,unnamed,uniquely,unimaginable,undeniable,unconditionally,uncharted,unbridled,tweezers,tvmegasite,trumped,triumphant,trimming,tribes,treading,translates,tranquilizers,towing,tout,toontown,thunk,taps,taboo,suture,suppressing,succeeding,submission,strays,stonewall,stogie,stepdaughter,stalls,stace,squint,spouses,splashed,speakin,sounder,sorrier,sorrel,sorcerer,sombrero,solemnly,softened,socialist,snobs,snippy,snare,smoothing,slump,slimeball,slaving,sips,singular,silently,sicily,shiller,shayne's,shareholders,shakedown,sensations,seagulls,scrying,scrumptious,screamin,saucy,santoses,santos's,sanctions,roundup,roughed,rosary,robechaux,roadside,riley's,retrospect,resurrected,restoration,reside,researched,rescind,reproduce,reprehensible,repel,rendering,remodeling,religions,reconsidering,reciprocate,ratchet,rambaldi's,railroaded,raccoon,quasi,psychics,psat,promos,proclamation,problem's,prob'ly,pristine,printout,priestess,prenuptial,prediction,precedes,pouty,potter's,phoning,petersburg,peppy,pariah,parched,parcel,panes,overloaded,overdoing,operators,oldies,obesity,nymphs,nother,notebooks,nook,nikolai,nearing,nearer,mutation,municipal,monstrosity,minister's,milady,mieke,mephesto,memory's,melissa's,medicated,marshals,manilow,mammogram,mainstream,madhouse,m'lady,luxurious,luck's,lucas's,lotsa,loopy,logging,liquids,lifeboat,lesion,lenient,learner,lateral,laszlo,larva,kross,kinks,jinxed,involuntary,inventor,interim,insubordination,inherent,ingrate,inflatable,independently,incarnate,inane,imaging,hypoglycemia,huntin,humorous,humongous,hoodlum,honoured,honking,hitler's,hemorrhage,helpin,hearing's,hathor,hatching,hangar,halftime,guise,guggenheim,grrr,grotto,grandson's,grandmama,gorillas,godless,girlish,ghouls,gershwin,frosted,friday's,forwards,flutter,flourish,flagpole,finely,finder's,fetching,fatter,fated,faithfully,faction,fabrics,exposition,expo,exploits,exert,exclude,eviction,everwood's,evasion,espn,escorting,escalate,enticing,enroll,enhancement,endowed,enchantress,emerging,elopement,drills,drat,downtime,downloading,dorks,doorways,doctorate,divulge,dissociative,diss,disgraceful,disconcerting,dirtbag,deteriorating,deteriorate,destinies,depressive,dented,denim,defeating,decruz,decidedly,deactivate,daydreams,czar,curls,culprit,cues,crybaby,cruelest,critique,crippling,cretin,cranberries,cous,coupled,corvis,copped,convicts,converts,contingent,contests,complement,commend,commemorate,combinations,coastguard,cloning,cirque,churning,chock,chivalry,chemotherapy,charlotte's,chancellor's,catalogues,cartwheels,carpets,carols,canister,camera's,buttered,bureaucratic,bundt,buljanoff,bubbling,brokers,broaden,brimstone,brainless,borneo,bores,boing,bodied,billie's,biceps,beijing,bead,badmouthing,bad's,avec,autopilot,attractions,attire,atoms,atheist,ascertain,artificially,archbishop,aorta,amps,ampata,amok,alloy,allied,allenby,align,albeit,aired,aint,adjoining,accosted,abyss,absolve,aborted,aaagh,aaaaaah,your's,yonder,yellin,yearly,wyndham,wrongdoing,woodsboro,wigging,whup,wasteland,warranty,waltzed,walnuts,wallace's,vividly,vibration,verses,veggie,variation,validation,unnecessarily,unloaded,unicorns,understated,undefeated,unclean,umbrellas,tyke,twirling,turpentine,turnover,tupperware,tugger,triangles,triage,treehouse,tract,toil,tidbit,tickled,thud,threes,thousandth,thingie,terminally,temporal,teething,tassel,talkies,syndication,syllables,swoon,switchboard,swerved,suspiciously,superiority,successor,subsequentlyne,subsequent,subscribe,strudel,stroking,strictest,steven's,stensland,stefan's,starsky,starin,stannart,squirming,squealing,sorely,solidarity,softie,snookums,sniveling,snail,smidge,smallpox,sloth,slab,skulking,singled,simian,silo,sightseeing,siamese,shudder,shoppers,shax,sharpen,shannen,semtex,sellout,secondhand,season's,seance,screenplay,scowl,scorn,scandals,santiago's,safekeeping,sacked,russe,rummage,rosie's,roshman,roomies,roaches,rinds,retrace,retires,resuscitate,restrained,residential,reservoir,rerun,reputations,rekall,rejoin,refreshment,reenactment,recluse,ravioli,raves,ranked,rampant,rama,rallies,raking,purses,punishable,punchline,puked,provincial,prosky,prompted,processor,previews,prepares,poughkeepsie,poppins,polluted,placenta,pissy,petulant,peterson's,perseverance,persecution,pent,peasants,pears,pawns,patrols,pastries,partake,paramount,panky,palate,overzealous,overthrow,overs,oswald's,oskar,originated,orchids,optical,onset,offenses,obstructing,objectively,obituaries,obedient,obedience,novice,nothingness,nitrate,newer,nets,mwah,musty,mung,motherly,mooning,monique's,momentous,moby,mistaking,mistakenly,minutemen,milos,microchip,meself,merciless,menelaus,mazel,mauser,masturbate,marsh's,manufacturers,mahogany,lysistrata,lillienfield,likable,lightweight,liberate,leveled,letdown,leer,leeloo,larynx,lardass,lainey,lagged,lab's,klorel,klan,kidnappings,keyed,karmic,jive,jiggy,jeebies,isabel's,irate,iraqi,iota,iodine,invulnerable,investor,intrusive,intricate,intimidation,interestingly,inserted,insemination,inquire,innate,injecting,inhabited,informative,informants,incorporation,inclination,impure,impasse,imbalance,illiterate,i'ma,i'ii,hurled,hunts,hispanic,hematoma,help's,helen's,headstrong,harmonica,hark,handmade,handiwork,gymnasium,growling,governors,govern,gorky,gook,girdle,getcha,gesundheit,gazing,gazette,garde,galley,funnel,fred's,fossils,foolishly,fondness,flushing,floris,firearm,ferocious,feathered,fateful,fancies,fakes,faker,expressway,expire,exec,ever'body,estates,essentials,eskimos,equations,eons,enlightening,energetic,enchilada,emmi,emissary,embolism,elsinore,ecklie,drenched,drazi,doped,dogging,documentation,doable,diverse,disposed,dislikes,dishonesty,disengage,discouraging,diplomat,diplomacy,deviant,descended,derailed,depleted,demi,deformed,deflect,defines,defer,defcon,deactivated,crips,creditors,counters,corridors,cordy's,conversation's,constellations,congressmen,congo,complimenting,colombian,clubbing,clog,clint's,clawing,chromium,chimes,chicken's,chews,cheatin,chaste,ceremony's,cellblock,ceilings,cece,caving,catered,catacombs,calamari,cabbie,bursts,bullying,bucking,brulee,brits,brisk,breezes,brandon's,bounces,boudoir,blockbuster,binks,better'n,beluga,bellied,behrani,behaves,bedding,battalion,barriers,banderas,balmy,bakersfield,badmouth,backers,avenging,atat,aspiring,aromatherapy,armpit,armoire,anythin,another's,anonymously,anniversaries,alonzo's,aftershave,affordable,affliction,adrift,admissible,adieu,activist,acquittal,yucky,yearn,wrongly,wino,whitter,whirlpool,wendigo,watchdog,wannabes,walkers,wakey,vomited,voicemail,verb,vans,valedictorian,vacancy,uttered,up's,unwed,unrequited,unnoticed,unnerving,unkind,unjust,uniformed,unconfirmed,unadulterated,unaccounted,uglier,tyler's,twix,turnoff,trough,trolley,trampled,tramell,traci's,tort,toads,titled,timbuktu,thwarted,throwback,thon,thinker,thimble,tasteless,tarantula,tammy's,tamale,takeovers,symposium,symmetry,swish,supposing,supporters,suns,sully,streaking,strands,statutory,starlight,stargher,starch,stanzi,stabs,squeamish,spokane,splattered,spiritually,spilt,sped,speciality,spacious,soundtrack,smacking,slain,slag,slacking,skywire,skips,skeet,skaara,simpatico,shredding,showin,shortcuts,shite,shielding,sheep's,shamelessly,serafine,sentimentality,sect,secretary's,seasick,scientifically,scholars,schemer,scandalous,saturday's,salts,saks,sainted,rustic,rugs,riedenschneider,ric's,rhyming,rhetoric,revolt,reversing,revel,retractor,retards,retaliation,resurrect,remiss,reminiscing,remanded,reluctance,relocating,relied,reiben,regions,regains,refuel,refresher,redoing,redheaded,redeemed,recycled,reassured,rearranged,rapport,qumar,prowling,promotional,promoter,preserving,prejudices,precarious,powwow,pondering,plunger,plunged,pleasantville,playpen,playback,pioneers,physicians,phlegm,perfected,pancreas,pakistani,oxide,ovary,output,outbursts,oppressed,opal's,ooohhh,omoroca,offed,o'toole,nurture,nursemaid,nosebleed,nixon's,necktie,muttering,munchies,mucking,mogul,mitosis,misdemeanor,miscarried,minx,millionth,migraines,midler,methane,metabolism,merchants,medicinal,margaret's,manifestation,manicurist,mandelbaum,manageable,mambo,malfunctioned,mais,magnesium,magnanimous,loudmouth,longed,lifestyles,liddy,lickety,leprechauns,lengthy,komako,koji's,klute,kennel,kathy's,justifying,jerusalem,israelis,isle,irreversible,inventing,invariably,intervals,intergalactic,instrumental,instability,insinuate,inquiring,ingenuity,inconclusive,incessant,improv,impersonation,impeachment,immigrant,id'd,hyena,humperdinck,humm,hubba,housework,homeland,holistic,hoffa,hither,hissy,hippy,hijacked,hero's,heparin,hellooo,heat's,hearth,hassles,handcuff,hairstyle,hadda,gymnastics,guys'll,gutted,gulp,gulls,guard's,gritty,grievous,gravitational,graft,gossamer,gooder,glory's,gere,gash,gaming,gambled,galaxies,gadgets,fundamentals,frustrations,frolicking,frock,frilly,fraser's,francais,foreseen,footloose,fondly,fluent,flirtation,flinched,flight's,flatten,fiscal,fiercely,felicia's,fashionable,farting,farthest,farming,facade,extends,exposer,exercised,evading,escrow,errr,enzymes,energies,empathize,embryos,embodiment,ellsberg,electromagnetic,ebola,earnings,dulcinea,dreamin,drawbacks,drains,doyle's,doubling,doting,doose's,doose,doofy,dominated,dividing,diversity,disturbs,disorderly,disliked,disgusts,devoid,detox,descriptions,denominator,demonstrating,demeanor,deliriously,decode,debauchery,dartmouth,d'oh,croissant,cravings,cranked,coworkers,councilor,council's,convergence,conventions,consistency,consist,conquests,conglomerate,confuses,confiscate,confines,confesses,conduit,compress,committee's,commanded,combed,colonel's,coated,clouding,clamps,circulating,circa,cinch,chinnery,celebratory,catalogs,carpenters,carnal,carla's,captures,capitan,capability,canin,canes,caitlin's,cadets,cadaver,cable's,bundys,bulldozer,buggers,bueller,bruno's,breakers,brazilian,branded,brainy,booming,bookstores,bloodbath,blister,bittersweet,biologist,billed,betty's,bellhop,beeping,beaut,beanstalk,beady,baudelaire,bartenders,bargains,ballad,backgrounds,averted,avatar's,atmospheric,assert,assassinated,armadillo,archive,appreciating,appraised,antlers,anterior,alps,aloof,allowances,alleyway,agriculture,agent's,affleck,acknowledging,achievements,accordion,accelerator,abracadabra,abject,zinc,zilch,yule,yemen,xanax,wrenching,wreath,wouldn,witted,widely,wicca,whorehouse,whooo,whips,westchester,websites,weaponry,wasn,walsh's,vouchers,vigorous,viet,victimized,vicodin,untested,unsolicited,unofficially,unfocused,unfettered,unfeeling,unexplainable,uneven,understaffed,underbelly,tutorial,tuberculosis,tryst,trois,trix,transmitting,trampoline,towering,topeka,tirade,thieving,thang,tentacles,teflon,teachings,tablets,swimmin,swiftly,swayzak,suspecting,supplying,suppliers,superstitions,superhuman,subs,stubbornness,structures,streamers,strattman,stonewalling,stimulate,stiffs,station's,stacking,squishy,spout,splice,spec,sonrisa,smarmy,slows,slicing,sisterly,sierra's,sicilian,shrill,shined,shift's,seniority,seine,seeming,sedley,seatbelts,scour,scold,schoolyard,scarring,sash,sark's,salieri,rustling,roxbury,richly,rexy,rex's,rewire,revved,retriever,respective,reputable,repulsed,repeats,rendition,remodel,relocated,reins,reincarnation,regression,reconstruction,readiness,rationale,rance,rafters,radiohead,radio's,rackets,quarterly,quadruple,pumbaa,prosperous,propeller,proclaim,probing,privates,pried,prewedding,premeditation,posturing,posterity,posh,pleasurable,pizzeria,pish,piranha,pimps,penmanship,penchant,penalties,pelvis,patriotism,pasa,papaya,packaging,overturn,overture,overstepped,overcoat,ovens,outsmart,outed,orient,ordained,ooohh,oncologist,omission,olly,offhand,odour,occurring,nyazian,notarized,nobody'll,nightie,nightclubs,newsweek,nesting,navel,nationwide,nabbed,naah,mystique,musk,mover,mortician,morose,moratorium,monster's,moderate,mockingbird,mobsters,misconduct,mingling,mikey's,methinks,metaphysical,messengered,merge,merde,medallion,mathematical,mater,mason's,masochist,martouf,martians,marinara,manray,manned,mammal,majorly,magnifying,mackerel,mabel's,lyme,lurid,lugging,lonnegan,loathsome,llantano,liszt,listings,limiting,liberace,leprosy,latinos,lanterns,lamest,laferette,ladybird,kraut,kook,kits,kipling,joyride,inward,intestine,innocencia,inhibitions,ineffectual,indisposed,incurable,incumbent,incorporated,inconvenienced,inanimate,improbable,implode,idea's,hypothesis,hydrant,hustling,hustled,huevos,how'm,horseshoe,hooey,hoods,honcho,hinge,hijack,heroism,hermit,heimlich,harvesting,hamunaptra,haladki,haiku,haggle,haaa,gutsy,grunting,grueling,grit,grifter,grievances,gribbs,greevy,greeted,green's,grandstanding,godparents,glows,glistening,glider,gimmick,genocide,gaping,fraiser,formalities,foreigner,forecast,footprint,folders,foggy,flaps,fitty,fiends,femmes,fearful,fe'nos,favours,fabio,eyeing,extort,experimentation,expedite,escalating,erect,epinephrine,entitles,entice,enriched,enable,emissions,eminence,eights,ehhh,educating,eden's,earthquakes,earthlings,eagerly,dunville,dugout,draining,doublemeat,doling,disperse,dispensing,dispatches,dispatcher,discoloration,disapproval,diners,dieu,diddly,dictates,diazepam,descendants,derogatory,deposited,delights,defies,decoder,debates,dealio,danson,cutthroat,crumbles,crud,croissants,crematorium,craftsmanship,crafted,could'a,correctional,cordless,cools,contradiction,constitute,conked,confine,concealing,composite,complicates,communique,columbian,cockamamie,coasters,clusters,clobbered,clipping,clipboard,clergy,clemenza,cleanser,circumcision,cindy's,chisel,character's,chanukah,certainaly,centerpiece,cellmate,cartoonist,cancels,cadmium,buzzed,busiest,bumstead,bucko,browsing,broth,broader,break's,braver,boundary,boggling,bobbing,blurred,birkhead,bethesda,benet,belvedere,bellies,begrudge,beckworth,bebe's,banky,baldness,bagpipes,baggy,babysitters,aversion,auxiliary,attributes,attain,astonished,asta,assorted,aspirations,arnold's,area's,appetites,apparel,apocalyptic,apartment's,announcer,angina,amiss,ambulances,allo,alleviate,alibis,algeria,alaskan,airway,affiliated,aerial,advocating,adrenalin,admires,adhesive,actively,accompanying,zeta,yoyou,yoke,yachts,wreaked,wracking,woooo,wooing,wised,winnie's,wind's,wilshire,wedgie,watson's,warden's,waging,violets,vincey,victorious,victories,velcro,vastly,valves,valley's,uplifting,untrustworthy,unmitigated,universities,uneventful,undressing,underprivileged,unburden,umbilical,twigs,tweet,tweaking,turquoise,trustees,truckers,trimmed,triggering,treachery,trapping,tourism,tosses,torching,toothpick,toga,toasty,toasts,tiamat,thickens,ther,tereza,tenacious,temperament,televised,teldar,taxis,taint,swill,sweatin,sustaining,surgery's,surgeries,succeeds,subtly,subterranean,subject's,subdural,streep,stopwatch,stockholder,stillwater,steamer,stang's,stalkers,squished,squeegee,splinters,spliced,splat,spied,specialized,spaz,spackle,sophistication,snapshots,smoky,smite,sluggish,slithered,skin's,skeeters,sidewalks,sickly,shrugs,shrubbery,shrieking,shitless,shithole,settin,servers,serge,sentinels,selfishly,segments,scarcely,sawdust,sanitation,sangria,sanctum,samantha's,sahjhan,sacrament,saber,rustle,rupture,rump,roving,rousing,rosomorf,rosario's,rodents,robust,rigs,riddled,rhythms,revelations,restart,responsibly,repression,reporter's,replied,repairing,renoir,remoray,remedial,relocation,relies,reinforcement,refundable,redirect,recheck,ravenwood,rationalizing,ramus,ramsey's,ramelle,rails,radish,quivering,pyjamas,puny,psychos,prussian,provocations,prouder,protestors,protesters,prohibited,prohibit,progression,prodded,proctologist,proclaimed,primordial,pricks,prickly,predatory,precedents,praising,pragmatic,powerhouse,posterior,postage,porthos,populated,poly,pointe,pivotal,pinata,persistence,performers,pentangeli,pele,pecs,pathetically,parka,parakeet,panicky,pandora's,pamphlets,paired,overthruster,outsmarted,ottoman,orthopedic,oncoming,oily,offing,nutritious,nuthouse,nourishment,nietzsche,nibbling,newlywed,newcomers,need's,nautilus,narcissist,myths,mythical,mutilation,mundane,mummy's,mummies,mumble,mowed,morvern,mortem,mortal's,mopes,mongolian,molasses,modification,misplace,miscommunication,miney,militant,midlife,mens,menacing,memorizing,memorabilia,membrane,massaging,masking,maritime,mapping,manually,magnets,ma's,luxuries,lows,lowering,lowdown,lounging,lothario,longtime,liposuction,lieutenant's,lidocaine,libbets,lewd,levitate,leslie's,leeway,lectured,lauren's,launcher,launcelot,latent,larek,lagos,lackeys,kumbaya,kryptonite,knapsack,keyhole,kensington,katarangura,kann,junior's,juiced,jugs,joyful,jihad,janitor's,jakey,ironclad,invoice,intertwined,interlude,interferes,insurrection,injure,initiating,infernal,india's,indeedy,incur,incorrigible,incantations,imprint,impediment,immersion,immensely,illustrate,ike's,igloo,idly,ideally,hysterectomy,hyah,house's,hour's,hounded,hooch,honeymoon's,hollering,hogs,hindsight,highs,high's,hiatus,helix,heirs,heebie,havesham,hassan's,hasenfuss,hankering,hangers,hakuna,gutless,gusto,grubbing,grrrr,greg's,grazed,gratification,grandeur,gorak,godammit,gnawing,glanced,gladiators,generating,galahad,gaius,furnished,funeral's,fundamentally,frostbite,frees,frazzled,fraulein,fraternizing,fortuneteller,formaldehyde,followup,foggiest,flunky,flickering,flashbacks,fixtures,firecrackers,fines,filly,figger,fetuses,fella's,feasible,fates,eyeliner,extremities,extradited,expires,experimented,exiting,exhibits,exhibited,exes,excursion,exceedingly,evaporate,erupt,equilibrium,epileptic,ephram's,entrails,entities,emporium,egregious,eggshells,easing,duwayne,drone,droll,dreyfuss,drastically,dovey,doubly,doozy,donkeys,donde,dominate,distrust,distributing,distressing,disintegrate,discreetly,disagreements,diff,dick's,devised,determines,descending,deprivation,delegate,dela,degradation,decision's,decapitated,dealin,deader,dashed,darkroom,dares,daddies,dabble,cycles,cushy,currents,cupcakes,cuffed,croupier,croak,criticized,crapped,coursing,cornerstone,copyright,coolers,continuum,contaminate,cont,consummated,construed,construct,condos,concoction,compulsion,committees,commish,columnist,collapses,coercion,coed,coastal,clemency,clairvoyant,circulate,chords,chesterton,checkered,charlatan,chaperones,categorically,cataracts,carano,capsules,capitalize,cache,butcher's,burdon,bullshitting,bulge,buck's,brewed,brethren,bren,breathless,breasted,brainstorming,bossing,borealis,bonsoir,bobka,boast,blimp,bleu,bleep,bleeder,blackouts,bisque,binford's,billboards,bernie's,beecher's,beatings,bayberry,bashed,bartlet's,bapu,bamboozled,ballon,balding,baklava,baffled,backfires,babak,awkwardness,attributed,attest,attachments,assembling,assaults,asphalt,arthur's,arthritis,armenian,arbitrary,apologizes,anyhoo,antiquated,alcante,agency's,advisable,advertisement,adventurer,abundance,aahhh,aaahh,zatarc,yous,york's,yeti,yellowstone,yearbooks,yakuza,wuddya,wringing,woogie,womanhood,witless,winging,whatsa,wetting,wessex,wendy's,way's,waterproof,wastin,washington's,wary,voom,volition,volcanic,vogelman,vocation,visually,violinist,vindicated,vigilance,viewpoint,vicariously,venza,vasily,validity,vacuuming,utensils,uplink,unveil,unloved,unloading,uninhibited,unattached,ukraine,typo,tweaked,twas,turnips,tunisia,tsch,trinkets,tribune,transmitters,translator,train's,toured,toughen,toting,topside,topical,toothed,tippy,tides,theology,terrors,terrify,tentative,technologically,tarnish,target's,tallest,tailored,tagliati,szpilman,swimmers,swanky,susie's,surly,supple,sunken,summation,suds,suckin,substantially,structured,stockholm,stepmom,squeaking,springfield's,spooks,splashmore,spanked,souffle,solitaire,solicitation,solarium,smooch,smokers,smog,slugged,slobbering,skylight,skimpy,situated,sinuses,simplify,silenced,sideburns,sid's,shutdown,shrinkage,shoddy,shhhhhh,shelling,shelled,shareef,shangri,shakey's,seuss,servicing,serenade,securing,scuffle,scrolls,scoff,scholarships,scanners,sauerkraut,satisfies,satanic,sars,sardines,sarcophagus,santino,sandi's,salvy,rusted,russells,ruby's,rowboat,routines,routed,rotating,rolfsky,ringside,rigging,revered,retreated,respectability,resonance,resembling,reparations,reopened,renewal,renegotiate,reminisce,reluctantly,reimburse,regimen,regaining,rectum,recommends,recognizable,realism,reactive,rawhide,rappaport's,raincoat,quibble,puzzled,pursuits,purposefully,puns,pubic,psychotherapy,prosecution's,proofs,proofing,professor's,prevention,prescribing,prelim,positioning,pore,poisons,poaching,pizza's,pertaining,personalized,personable,peroxide,performs,pentonville,penetrated,peggy's,payphone,payoffs,participated,park's,parisian,palp,paleontology,overhaul,overflowing,organised,oompa,ojai,offenders,oddest,objecting,o'hare,o'daniel,notches,noggin,nobody'd,nitrogen,nightstand,niece's,nicky's,neutralized,nervousness,nerdy,needlessly,navigational,narrative,narc,naquadah,nappy,nantucket,nambla,myriad,mussolini,mulberry,mountaineer,mound,motherfuckin,morrie,monopolizing,mohel,mistreated,misreading,misbehave,miramax,minstrel,minivan,milligram,milkshakes,milestone,middleweight,michelangelo,metamorphosis,mesh,medics,mckinnon's,mattresses,mathesar,matchbook,matata,marys,marco's,malucci,majored,magilla,magic's,lymphoma,lowers,lordy,logistics,linens,lineage,lindenmeyer,limelight,libel,leery's,leased,leapt,laxative,lather,lapel,lamppost,laguardia,labyrinth,kindling,key's,kegs,kegger,kawalsky,juries,judo,jokin,jesminder,janine's,izzy,israeli,interning,insulation,institutionalized,inspected,innings,innermost,injun,infallible,industrious,indulgence,indonesia,incinerator,impossibility,imports,impart,illuminate,iguanas,hypnotic,hyped,huns,housed,hostilities,hospitable,hoses,horton's,homemaker,history's,historian,hirschmuller,highlighted,hideout,helpers,headset,guardianship,guapo,guantanamo,grubby,greyhound,grazing,granola,granddaddy,gotham's,goren,goblet,gluttony,glucose,globes,giorno,gillian's,getter,geritol,gassed,gang's,gaggle,freighter,freebie,frederick's,fractures,foxhole,foundations,fouled,foretold,forcibly,folklore,floorboards,floods,floated,flippers,flavour,flaked,firstly,fireflies,feedings,fashionably,fascism,farragut,fallback,factions,facials,exterminate,exited,existent,exiled,exhibiting,excites,everything'll,evenin,evaluated,ethically,entree,entirety,ensue,enema,empath,embryo,eluded,eloquently,elle,eliminates,eject,edited,edema,echoes,earns,dumpling,drumming,droppings,drazen's,drab,dolled,doll's,doctrine,distasteful,disputing,disputes,displeasure,disdain,disciples,diamond's,develops,deterrent,detection,dehydration,defied,defiance,decomposing,debated,dawned,darken,daredevil,dailies,cyst,custodian,crusts,crucifix,crowning,crier,crept,credited,craze,crawls,coveted,couple's,couldn,corresponding,correcting,corkmaster,copperfield,cooties,coopers,cooperated,controller,contraption,consumes,constituents,conspire,consenting,consented,conquers,congeniality,computerized,compute,completes,complains,communicator,communal,commits,commendable,colonels,collide,coladas,colada,clout,clooney,classmate,classifieds,clammy,claire's,civility,cirrhosis,chink,chemically,characterize,censor,catskills,cath,caterpillar,catalyst,carvers,carts,carpool,carelessness,career's,cardio,carbs,captivity,capeside's,capades,butabi,busmalis,bushel,burping,buren,burdens,bunks,buncha,bulldozers,browse,brockovich,bria,breezy,breeds,breakthroughs,bravado,brandy's,bracket,boogety,bolshevik,blossoms,bloomington,blooming,bloodsucker,blockade,blight,blacksmith,betterton,betrayer,bestseller,bennigan's,belittle,beeps,bawling,barts,bartending,barbed,bankbooks,back's,babs,babish,authors,authenticity,atropine,astronomical,assertive,arterial,armbrust,armageddon,aristotle,arches,anyanka,annoyance,anemic,anck,anago,ali's,algiers,airways,airwaves,air's,aimlessly,ails,ahab,afflicted,adverse,adhere,accuracy,aaargh,aaand,zest,yoghurt,yeast,wyndham's,writings,writhing,woven,workable,winking,winded,widen,whooping,whiter,whip's,whatya,whacko,we's,wazoo,wasp,waived,vlad,virile,vino,vic's,veterinary,vests,vestibule,versed,venetian,vaughn's,vanishes,vacancies,urkel,upwards,uproot,unwarranted,unscheduled,unparalleled,undertaking,undergrad,tweedle,turtleneck,turban,trickery,travolta,transylvania,transponder,toyed,townhouse,tonto,toed,tion,tier,thyself,thunderstorm,thnk,thinning,thinkers,theatres,thawed,tether,tempus,telegraph,technicalities,tau'ri,tarp,tarnished,tara's,taggert's,taffeta,tada,tacked,systolic,symbolize,swerve,sweepstakes,swami,swabs,suspenders,surfers,superwoman,sunsets,sumo,summertime,succulent,successes,subpoenas,stumper,stosh,stomachache,stewed,steppin,stepatech,stateside,starvation,staff's,squads,spicoli,spic,sparing,soulless,soul's,sonnets,sockets,snit,sneaker,snatching,smothering,slush,sloman,slashing,sitters,simpson's,simpleton,signify,signal's,sighs,sidra,sideshow,sickens,shunned,shrunken,showbiz,shopped,shootings,shimmering,shakespeare's,shagging,seventeenth,semblance,segue,sedation,scuzzlebutt,scumbags,scribble,screwin,scoundrels,scarsdale,scamp,scabs,saucers,sanctioned,saintly,saddened,runaways,runaround,rumored,rudimentary,rubies,rsvp,rots,roman's,ripley's,rheya,revived,residing,resenting,researcher,repertoire,rehashing,rehabilitated,regrettable,regimental,refreshed,reese's,redial,reconnecting,rebirth,ravenous,raping,ralph's,railroads,rafting,rache,quandary,pylea,putrid,punitive,puffing,psychopathic,prunes,protests,protestant,prosecutors,proportional,progressed,prod,probate,prince's,primate,predicting,prayin,practitioner,possessing,pomegranate,polgara,plummeting,planners,planing,plaintiffs,plagues,pitt's,pithy,photographer's,philharmonic,petrol,perversion,personals,perpetrators,perm,peripheral,periodic,perfecto,perched,pees,peeps,pedigree,peckish,pavarotti,partnered,palette,pajama,packin,pacifier,oyez,overstepping,outpatient,optimum,okama,obstetrician,nutso,nuance,noun,noting,normalcy,normal's,nonnegotiable,nomak,nobleman,ninny,nines,nicey,newsflash,nevermore,neutered,nether,nephew's,negligee,necrosis,nebula,navigating,narcissistic,namesake,mylie,muses,munitions,motivational,momento,moisturizer,moderation,mmph,misinformed,misconception,minnifield,mikkos,methodical,mechanisms,mebbe,meager,maybes,matchmaking,masry,markovic,manifesto,malakai,madagascar,m'am,luzhin,lusting,lumberjack,louvre,loopholes,loaning,lightening,liberals,lesbo,leotard,leafs,leader's,layman's,launder,lamaze,kubla,kneeling,kilo,kibosh,kelp,keith's,jumpsuit,joy's,jovi,joliet,jogger,janover,jakovasaurs,irreparable,intervened,inspectors,innovation,innocently,inigo,infomercial,inexplicable,indispensable,indicative,incognito,impregnated,impossibly,imperfect,immaculate,imitating,illnesses,icarus,hunches,hummus,humidity,housewives,houmfort,hothead,hostiles,hooves,hoopla,hooligans,homos,homie,hisself,himalayas,hidy,hickory,heyyy,hesitant,hangout,handsomest,handouts,haitian,hairless,gwennie,guzzling,guinevere,grungy,grunge,grenada,gout,gordon's,goading,gliders,glaring,geology,gems,gavel,garments,gardino,gannon's,gangrene,gaff,gabrielle's,fundraising,fruitful,friendlier,frequencies,freckle,freakish,forthright,forearm,footnote,footer,foot's,flops,flamenco,fixer,firm's,firecracker,finito,figgered,fezzik,favourites,fastened,farfetched,fanciful,familiarize,faire,failsafe,fahrenheit,fabrication,extravaganza,extracted,expulsion,exploratory,exploitation,explanatory,exclusion,evolutionary,everglades,evenly,eunuch,estas,escapade,erasers,entries,enforcing,endorsements,enabling,emptying,emperor's,emblem,embarassing,ecosystem,ebby,ebay,dweeb,dutiful,dumplings,drilled,drafty,doug's,dolt,dollhouse,displaced,dismissing,disgraced,discrepancies,disbelief,disagreeing,disagreed,digestion,didnt,deviled,deviated,deterioration,departmental,departing,demoted,demerol,delectable,deco,decaying,decadent,dears,daze,dateless,d'algout,cultured,cultivating,cryto,crusades,crumpled,crumbled,cronies,critters,crew's,crease,craves,cozying,cortland,corduroy,cook's,consumers,congratulated,conflicting,confidante,condensed,concessions,compressor,compressions,compression,complicating,complexity,compadre,communicated,coerce,coding,coating,coarse,clown's,clockwise,clerk's,classier,clandestine,chums,chumash,christopher's,choreography,choirs,chivalrous,chinpoko,chilean,chihuahua,cheerio,charred,chafing,celibacy,casts,caste,cashier's,carted,carryin,carpeting,carp,carotid,cannibals,candor,caen,cab's,butterscotch,busts,busier,bullcrap,buggin,budding,brookside,brodski,bristow's,brig,bridesmaid's,brassiere,brainwash,brainiac,botrelle,boatload,blimey,blaring,blackness,bipolar,bipartisan,bins,bimbos,bigamist,biebe,biding,betrayals,bestow,bellerophon,beefy,bedpans,battleship,bathroom's,bassinet,basking,basin,barzini,barnyard,barfed,barbarian,bandit,balances,baker's,backups,avid,augh,audited,attribute,attitudes,at's,astor,asteroids,assortment,associations,asinine,asalaam,arouse,architects,aqua,applejack,apparatus,antiquities,annoys,angela's,anew,anchovies,anchors,analysts,ampule,alphabetically,aloe,allure,alameida,aisles,airfield,ahah,aggressively,aggravate,aftermath,affiliation,aesthetic,advertised,advancing,adept,adage,accomplices,accessing,academics,aagh,zoned,zoey's,zeal,yokel,y'ever,wynant's,wringer,witwer,withdrew,withdrawing,withdrawals,windward,wimbledon,wily,willfully,whorfin,whimsical,whimpering,welding,weddin,weathered,wealthiest,weakening,warmest,wanton,waif,volant,vivo,vive,visceral,vindication,vikram,vigorously,verification,veggies,urinate,uproar,upload,unwritten,unwrap,unsung,unsubstantiated,unspeakably,unscrupulous,unraveling,unquote,unqualified,unfulfilled,undetectable,underlined,unconstitutional,unattainable,unappreciated,ummmm,ulcers,tylenol,tweak,tutu,turnin,turk's,tucker's,tuatha,tropez,trends,trellis,traffic's,torque,toppings,tootin,toodles,toodle,tivo,tinkering,thursday's,thrives,thorne's,thespis,thereafter,theatrics,thatherton,texts,testicle,terr,tempers,teammates,taxpayer,tavington,tampon,tackling,systematic,syndicated,synagogue,swelled,sweeney's,sutures,sustenance,surfaces,superstars,sunflowers,sumatra,sublet,subjective,stubbins,strutting,strewn,streams,stowaway,stoic,sternin,stereotypes,steadily,star's,stalker's,stabilizing,sprang,spotter,spiraling,spinster,spell's,speedometer,specified,speakeasy,sparked,soooo,songwriter,soiled,sneakin,smithereens,smelt,smacks,sloan's,slaughterhouse,slang,slacks,skids,sketching,skateboards,sizzling,sixes,sirree,simplistic,sift,side's,shouts,shorted,shoelace,sheeit,shaw's,shards,shackled,sequestered,selmak,seduces,seclusion,seasonal,seamstress,seabeas,scry,scripted,scotia,scoops,scooped,schillinger's,scavenger,saturation,satch,salaries,safety's,s'more,s'il,rudeness,rostov,romanian,romancing,robo,robert's,rioja,rifkin,rieper,revise,reunions,repugnant,replicating,replacements,repaid,renewing,remembrance,relic,relaxes,rekindle,regulate,regrettably,registering,regenerate,referenced,reels,reducing,reconstruct,reciting,reared,reappear,readin,ratting,rapes,rancho,rancher,rammed,rainstorm,railroading,queers,punxsutawney,punishes,pssst,prudy,proudest,protectors,prohibits,profiling,productivity,procrastinating,procession,proactive,priss,primaries,potomac,postmortem,pompoms,polio,poise,piping,pickups,pickings,physiology,philanthropist,phenomena,pheasant,perfectionist,peretti,people'll,peninsula,pecking,peaks,pave,patrolman,participant,paralegal,paragraphs,paparazzi,pankot,pampering,pain's,overstep,overpower,ovation,outweigh,outlawed,orion's,openness,omnipotent,oleg,okra,okie,odious,nuwanda,nurtured,niles's,newsroom,netherlands,nephews,neeson,needlepoint,necklaces,neato,nationals,muggers,muffler,mousy,mourned,mosey,morn,mormon,mopey,mongolians,moldy,moderately,modelling,misinterpret,minneapolis,minion,minibar,millenium,microfilm,metals,mendola,mended,melissande,me's,mathematician,masturbating,massacred,masbath,marler's,manipulates,manifold,malp,maimed,mailboxes,magnetism,magna,m'lord,m'honey,lymph,lunge,lull,luka,lt's,lovelier,loser's,lonigan's,lode,locally,literacy,liners,linear,lefferts,leezak,ledgers,larraby,lamborghini,laloosh,kundun,kozinski,knockoff,kissin,kiosk,khasinau's,kennedys,kellman,karlo,kaleidoscope,jumble,juggernaut,joseph's,jiminy,jesuits,jeffy,jaywalking,jailbird,itsy,irregularities,inventive,introduces,interpreter,instructing,installing,inquest,inhabit,infraction,informer,infarction,incidence,impulsively,impressing,importing,impersonated,impeach,idiocy,hyperbole,hydra,hurray,hungary,humped,huhuh,hsing,hotspot,horsepower,hordes,hoodlums,honky,hitchhiker,hind,hideously,henchmen,heaving,heathrow,heather's,heathcliff,healthcare,headgear,headboard,hazing,hawking,harem,handprint,halves,hairspray,gutiurrez,greener,grandstand,goosebumps,good's,gondola,gnaw,gnat,glitches,glide,gees,gasping,gases,garrison's,frolic,fresca,freeways,frayed,fortnight,fortitude,forgetful,forefathers,foley's,foiled,focuses,foaming,flossing,flailing,fitzgeralds,firehouse,finders,filmmakers,fiftieth,fiddler,fellah,feats,fawning,farquaad,faraway,fancied,extremists,extremes,expresses,exorcist,exhale,excel,evaluations,ethros,escalated,epilepsy,entrust,enraged,ennui,energized,endowment,encephalitis,empties,embezzling,elster,ellie's,ellen's,elixir,electrolytes,elective,elastic,edged,econ,eclectic,eagle's,duplex,dryers,drexl,dredging,drawback,drafting,don'ts,docs,dobisch,divorcee,ditches,distinguishing,distances,disrespected,disprove,disobeying,disobedience,disinfectant,discs,discoveries,dips,diplomas,dingy,digress,dignitaries,digestive,dieting,dictatorship,dictating,devoured,devise,devane's,detonators,detecting,desist,deserter,derriere,deron,derive,derivative,delegates,defects,defeats,deceptive,debilitating,deathwok,dat's,darryl's,dago,daffodils,curtsy,cursory,cuppa,cumin,cultivate,cujo,cubic,cronkite,cremation,credence,cranking,coverup,courted,countin,counselling,cornball,converting,contentment,contention,contamination,consortium,consequently,consensual,consecutive,compressed,compounds,compost,components,comparative,comparable,commenting,color's,collections,coleridge,coincidentally,cluett,cleverly,cleansed,cleanliness,clea,clare's,citizen's,chopec,chomp,cholera,chins,chime,cheswick,chessler,cheapest,chatted,cauliflower,catharsis,categories,catchin,caress,cardigan,capitalism,canopy,cana,camcorder,calorie,cackling,cabot's,bystanders,buttoned,buttering,butted,buries,burgel,bullpen,buffoon,brogna,brah,bragged,boutros,boosted,bohemian,bogeyman,boar,blurting,blurb,blowup,bloodhound,blissful,birthmark,biotech,bigot,bestest,benefited,belted,belligerent,bell's,beggin,befall,beeswax,beer's,becky's,beatnik,beaming,bazaar,bashful,barricade,banners,bangers,baja,baggoli,badness,awry,awoke,autonomy,automobiles,attica,astoria,assessing,ashram,artsy,artful,aroun,armpits,arming,arithmetic,annihilate,anise,angiogram,andre's,anaesthetic,amorous,ambiguous,ambiance,alligators,afforded,adoration,admittance,administering,adama,aclu,abydos,absorption,zonked,zhivago,zealand,zazu,youngster,yorkin,wrongfully,writin,wrappers,worrywart,woops,wonderfalls,womanly,wickedness,wichita,whoopie,wholesale,wholeheartedly,whimper,which'll,wherein,wheelchairs,what'ya,west's,wellness,welcomes,wavy,warren's,warranted,wankers,waltham,wallop,wading,wade's,wacked,vogue,virginal,vill,vets,vermouth,vermeil,verger,verbs,verbally,ventriss,veneer,vecchio's,vampira,utero,ushers,urgently,untoward,unshakable,unsettled,unruly,unrest,unmanned,unlocks,unified,ungodly,undue,undermined,undergoing,undergo,uncooperative,uncontrollably,unbeatable,twitchy,tunh,tumbler,tubs,truest,troublesome,triumphs,triplicate,tribbey,trent's,transmissions,tortures,torpedoes,torah,tongaree,tommi,tightening,thunderbolt,thunderbird,thorazine,thinly,theta,theres,testifies,terre,teenaged,technological,tearful,taxing,taldor,takashi,tach,symbolizes,symbolism,syllabus,swoops,swingin,swede,sutra,suspending,supplement,sunday's,sunburn,succumbed,subtitled,substituting,subsidiary,subdued,stuttering,stupor,stumps,strummer,strides,strategize,strangulation,stooped,stipulation,stingy,stigma,stewart's,statistic,startup,starlet,stapled,squeaks,squawking,spoilsport,splicing,spiel,spencers,specifications,spawned,spasms,spaniard,sous,softener,sodding,soapbox,snow's,smoldering,smithbauer,slogans,slicker,slasher,skittish,skepticism,simulated,similarity,silvio,signifies,signaling,sifting,sickest,sicilians,shuffling,shrivel,shortstop,sensibility,sender,seminary,selecting,segretti,seeping,securely,scurrying,scrunch,scrote,screwups,schoolteacher,schibetta's,schenkman,sawing,savin,satine,saps,sapiens,salvaging,salmonella,safeguard,sacrilege,rumpus,ruffle,rube,routing,roughing,rotted,roshman's,rondall,road's,ridding,rickshaw,rialto,rhinestone,reversible,revenues,retina,restrooms,resides,reroute,requisite,repress,replicate,repetition,removes,relationship's,regent,regatta,reflective,rednecks,redeeming,rectory,recordings,reasoned,rayed,ravell,raked,rainstorm's,raincheck,raids,raffi,racked,query,quantities,pushin,prototypes,proprietor,promotes,prometheus,promenade,projectile,progeny,profess,prodding,procure,primetime,presuming,preppy,prednisone,predecessor,potted,posttraumatic,poppies,poorhouse,pool's,polaroid,podiatrist,plucky,plowed,pledging,playroom,playhouse,play's,plait,placate,pitchfork,pissant,pinback,picketing,photographing,pharoah,petrak,petal,persecuting,perchance,penny's,pellets,peeved,peerless,payable,pauses,pathways,pathologist,pat's,parchment,papi,pagliacci,owls,overwrought,overwhelmingly,overreaction,overqualified,overheated,outward,outlines,outcasts,otherworldly,originality,organisms,opinionated,oodles,oftentimes,octane,occured,obstinate,observatory,o'er,nutritionist,nutrition,numbness,nubile,notification,notary,nooooooo,nodes,nobodies,nepotism,neighborhoods,neanderthals,musicals,mushu,murphy's,multimedia,mucus,mothering,mothballs,monogrammed,monk's,molesting,misspoke,misspelled,misconstrued,miscellaneous,miscalculated,minimums,mince,mildew,mighta,middleman,metabolic,messengers,mementos,mellowed,meditate,medicare,mayol,maximilian,mauled,massaged,marmalade,mardi,mannie,mandates,mammals,malaysia,makings,major's,maim,lundegaard,lovingly,lout,louisville,loudest,lotto,loosing,loompa,looming,longs,lodging,loathes,littlest,littering,linebacker,lifelike,li'l,legalities,lavery's,laundered,lapdog,lacerations,kopalski,knobs,knitted,kittridge,kidnaps,kerosene,katya,karras,jungles,juke,joes,jockeys,jeremy's,jefe,janeiro,jacqueline's,ithaca,irrigation,iranoff,invoices,invigorating,intestinal,interactive,integration,insolence,insincere,insectopia,inhumane,inhaling,ingrates,infrastructure,infestation,infants,individuality,indianapolis,indeterminate,indefinite,inconsistent,incomprehensible,inaugural,inadequacy,impropriety,importer,imaginations,illuminating,ignited,ignite,iggy,i'da,hysterics,hypodermic,hyperventilate,hypertension,hyperactive,humoring,hotdogs,honeymooning,honed,hoist,hoarding,hitching,hinted,hill's,hiker,hijo,hightail,highlands,hemoglobin,helo,hell'd,heinie,hanoi,hags,gush,guerrillas,growin,grog,grissom's,gregory's,grasped,grandparent,granddaughters,gouged,goblins,gleam,glades,gigantor,get'em,geriatric,geared,gawk,gawd,gatekeeper,gargoyles,gardenias,garcon,garbo,gallows,gabe's,gabby's,gabbing,futon,fulla,frightful,freshener,freedoms,fountains,fortuitous,formulas,forceps,fogged,fodder,foamy,flogging,flaun,flared,fireplaces,firefighters,fins,filtered,feverish,favell,fattest,fattening,fate's,fallow,faculties,fabricated,extraordinaire,expressly,expressive,explorers,evade,evacuating,euclid,ethanol,errant,envied,enchant,enamored,enact,embarking,election's,egocentric,eeny,dussander,dunwitty,dullest,dru's,dropout,dredged,dorsia,dormitory,doot,doornail,dongs,dogged,dodgy,do's,ditty,dishonorable,discriminating,discontinue,dings,dilly,diffuse,diets,dictation,dialysis,deteriorated,delly,delightfully,definitions,decreased,declining,deadliest,daryll,dandruff,cynthia's,cush,cruddy,croquet,crocodiles,cringe,crimp,credo,cranial,crackling,coyotes,courtside,coupling,counteroffer,counterfeiting,corrupting,corrective,copter,copping,conway's,conveyor,contusions,contusion,conspirator,consoling,connoisseur,conjecture,confetti,composure,competitor,compel,commanders,coloured,collector's,colic,coldest,coincide,coddle,cocksuckers,coax,coattails,cloned,cliff's,clerical,claustrophobia,classrooms,clamoring,civics,churn,chugga,chromosomes,christened,chopper's,chirping,chasin,characterized,chapped,chalkboard,centimeter,caymans,catheter,caspian,casings,cartilage,carlton's,card's,caprica,capelli,cannolis,cannoli,canals,campaigns,camogli,camembert,butchers,butchered,busboys,bureaucrats,bungalow,buildup,budweiser,buckled,bubbe,brownstone,bravely,brackley,bouquets,botox,boozing,boosters,bodhi,blunders,blunder,blockage,blended,blackberry,bitch's,birthplace,biocyte,biking,bike's,betrays,bestowed,bested,beryllium,beheading,beginner's,beggar,begbie,beamed,bayou,bastille,bask,barstool,barricades,baron's,barbecues,barbecued,barb's,bandwagon,bandits,ballots,ballads,backfiring,bacarra,avoidance,avenged,autopsies,austrian,aunties,attache,atrium,associating,artichoke,arrowhead,arrivals,arose,armory,appendage,apostrophe,apostles,apathy,antacid,ansel,anon,annul,annihilation,andrew's,anderson's,anastasia's,amuses,amped,amicable,amendments,amberg,alluring,allotted,alfalfa,alcoholism,airs,ailing,affinity,adversaries,admirers,adlai,adjective,acupuncture,acorn,abnormality,aaaahhhh,zooming,zippity,zipping,zeroed,yuletide,yoyodyne,yengeese,yeahhh,xena,wrinkly,wracked,wording,withered,winks,windmills,widow's,whopping,wholly,wendle,weigart,weekend's,waterworks,waterford,waterbed,watchful,wantin,wally's,wail,wagging,waal,waaah,vying,voter,ville,vertebrae,versatile,ventures,ventricle,varnish,vacuumed,uugh,utilities,uptake,updating,unreachable,unprovoked,unmistakable,unky,unfriendly,unfolding,undesirable,undertake,underpaid,uncuff,unchanged,unappealing,unabomber,ufos,tyres,typhoid,tweek's,tuxedos,tushie,turret,turds,tumnus,tude,truman's,troubadour,tropic,trinium,treaters,treads,transpired,transient,transgression,tournaments,tought,touchdowns,totem,tolstoy,thready,thins,thinners,thas,terrible's,television's,techs,teary,tattaglia,tassels,tarzana,tape's,tanking,tallahassee,tablecloths,synonymous,synchronize,symptomatic,symmetrical,sycophant,swimmingly,sweatshop,surrounds,surfboard,superpowers,sunroom,sunflower,sunblock,sugarplum,sudan,subsidies,stupidly,strumpet,streetcar,strategically,strapless,straits,stooping,stools,stifler,stems,stealthy,stalks,stairmaster,staffer,sshhh,squatting,squatters,spores,spelt,spectacularly,spaniel,soulful,sorbet,socked,society's,sociable,snubbed,snub,snorting,sniffles,snazzy,snakebite,smuggler,smorgasbord,smooching,slurping,sludge,slouch,slingshot,slicer,slaved,skimmed,skier,sisterhood,silliest,sideline,sidarthur,shrink's,shipwreck,shimmy,sheraton,shebang,sharpening,shanghaied,shakers,sendoff,scurvy,scoliosis,scaredy,scaled,scagnetti,saxophone,sawchuk,saviour,saugus,saturated,sasquatch,sandbag,saltines,s'pose,royalties,routinely,roundabout,roston,rostle,riveting,ristle,righ,rifling,revulsion,reverently,retrograde,restriction,restful,resolving,resents,rescinded,reptilian,repository,reorganize,rentals,rent's,renovating,renal,remedies,reiterate,reinvent,reinmar,reibers,reechard,recuse,recorders,record's,reconciling,recognizance,recognised,reclaiming,recitation,recieved,rebate,reacquainted,rations,rascals,raptors,railly,quintuplets,quahog,pygmies,puzzling,punctuality,psychoanalysis,psalm,prosthetic,proposes,proms,proliferation,prohibition,probie,printers,preys,pretext,preserver,preppie,prag,practise,postmaster,portrayed,pollen,polled,poachers,plummet,plumbers,pled,plannin,pitying,pitfalls,piqued,pinecrest,pinches,pillage,pigheaded,pied,physique,pessimistic,persecute,perjure,perch,percentile,pentothal,pensky,penises,peking,peini,peacetime,pazzi,pastels,partisan,parlour,parkway,parallels,paperweight,pamper,palsy,palaces,pained,overwhelm,overview,overalls,ovarian,outrank,outpouring,outhouse,outage,ouija,orbital,old's,offset,offer's,occupying,obstructed,obsessions,objectives,obeying,obese,o'riley,o'neal,o'higgins,nylon,notoriously,nosebleeds,norman's,norad,noooooooo,nononono,nonchalant,nominal,nome,nitrous,nippy,neurosis,nekhorvich,necronomicon,nativity,naquada,nano,nani,n'est,mystik,mystified,mums,mumps,multinational,muddle,mothership,moped,monumentally,monogamous,mondesi,molded,mixes,misogynistic,misinterpreting,miranda's,mindlock,mimic,midtown,microphones,mending,megaphone,meeny,medicating,meanings,meanie,masseur,maru,marshal's,markstrom,marklars,mariachi,margueritas,manifesting,maintains,mail's,maharajah,lurk,lulu's,lukewarm,loveliest,loveable,lordship,looting,lizardo,liquored,lipped,lingers,limey,limestone,lieutenants,lemkin,leisurely,laureate,lathe,latched,lars,lapping,ladle,kuala,krevlorneswath,kosygin,khakis,kenaru,keats,kath,kaitlan,justin's,julliard,juliet's,journeys,jollies,jiff,jaundice,jargon,jackals,jabot's,invoked,invisibility,interacting,instituted,insipid,innovative,inflamed,infinitely,inferiority,inexperience,indirectly,indications,incompatible,incinerated,incinerate,incidental,incendiary,incan,inbred,implicitly,implicating,impersonator,impacted,ida's,ichiro,iago,hypo,hurricanes,hunks,host's,hospice,horsing,hooded,honey's,homestead,hippopotamus,hindus,hiked,hetson,hetero,hessian,henslowe,hendler,hellstrom,hecate,headstone,hayloft,hater,hast,harold's,harbucks,handguns,hallucinate,halliwell's,haldol,hailing,haggling,hadj,gynaecologist,gumball,gulag,guilder,guaranteeing,groundskeeper,ground's,grindstone,grimoir,grievance,griddle,gribbit,greystone,graceland,gooders,goeth,glossy,glam,giddyup,gentlemanly,gels,gelatin,gazelle,gawking,gaulle,gate's,ganged,fused,fukes,fromby,frenchmen,franny,foursome,forsley,foreman's,forbids,footwork,foothold,fonz,fois,foie,floater,flinging,flicking,fittest,fistfight,fireballs,filtration,fillings,fiddling,festivals,fertilization,fennyman,felonious,felonies,feces,favoritism,fatten,fanfare,fanatics,faceman,extensions,executions,executing,excusing,excepted,examiner's,ex's,evaluating,eugh,erroneous,enzyme,envoy,entwined,entrances,ensconced,enrollment,england's,enemy's,emit,emerges,embankment,em's,ellison's,electrons,eladio,ehrlichman,easterland,dylan's,dwellers,dueling,dubbed,dribbling,drape,doze,downtrodden,doused,dosed,dorleen,dopamine,domesticated,dokie,doggone,disturbances,distort,displeased,disown,dismount,disinherited,disarmed,disapproves,disabilities,diperna,dioxide,dined,diligent,dicaprio,diameter,dialect,detonated,destitute,designate,depress,demolish,demographics,degraded,deficient,decoded,debatable,dealey,darsh,dapper,damsels,damning,daisy's,dad'll,d'oeuvre,cutter's,curlers,curie,cubed,cryo,critically,crikey,crepes,crackhead,countrymen,count's,correlation,cornfield,coppers,copilot,copier,coordinating,cooing,converge,contributor,conspiracies,consolidated,consigliere,consecrated,configuration,conducts,condoning,condemnation,communities,commoner,commies,commented,comical,combust,comas,colds,clod,clique,clay's,clawed,clamped,cici,christianity,choosy,chomping,chimps,chigorin,chianti,cheval,chet's,cheep,checkups,check's,cheaters,chase's,charted,celibate,cautiously,cautionary,castell,carpentry,caroling,carjacking,caritas,caregiver,cardiology,carb,capturing,canteen,candlesticks,candies,candidacy,canasta,calendars,cain't,caboose,buster's,burro,burnin,buon,bunking,bumming,bullwinkle,budgets,brummel,brooms,broadcasts,britt's,brews,breech,breathin,braslow,bracing,bouts,botulism,bosnia,boorish,bluenote,bloodless,blayne,blatantly,blankie,birdy,bene,beetles,bedbugs,becuase,becks,bearers,bazooka,baywatch,bavarian,baseman,bartender's,barrister,barmaid,barges,bared,baracus,banal,bambino,baltic,baku,bakes,badminton,bacon's,backpacks,authorizing,aurelius,attentions,atrocious,ativan,athame,asunder,astound,assuring,aspirins,asphyxiation,ashtrays,aryans,artistry,arnon,aren,approximate,apprehension,appraisal,applauding,anya's,anvil,antiquing,antidepressants,annoyingly,amputate,altruistic,alotta,allegation,alienation,algerian,algae,alerting,airport's,aided,agricultural,afterthought,affront,affirm,adapted,actuality,acoustics,acoustic,accumulate,accountability,abysmal,absentee,zimm,yves,yoohoo,ymca,yeller,yakushova,wuzzy,wriggle,worrier,workmen,woogyman,womanizer,windpipe,windex,windbag,willy's,willin,widening,whisking,whimsy,wendall,weeny,weensy,weasels,watery,watcha,wasteful,waski,washcloth,wartime,waaay,vowel,vouched,volkswagen,viznick,visuals,visitor's,veteran's,ventriloquist,venomous,vendors,vendettas,veils,vehicular,vayhue,vary,varies,van's,vamanos,vadimus,uuhh,upstage,uppity,upheaval,unsaid,unlocking,universally,unintentionally,undisputed,undetected,undergraduate,undergone,undecided,uncaring,unbearably,twos,tween,tuscan,turkey's,tumor's,tryout,trotting,tropics,trini,trimmings,trickier,tree's,treatin,treadstone,trashcan,transports,transistor,transcendent,tramps,toxicity,townsfolk,torturous,torrid,toothpicks,tombs,tolerable,toenail,tireless,tiptoeing,tins,tinkerbell,tink,timmay,tillinghouse,tidying,tibia,thumbing,thrusters,thrashing,thompson's,these'll,testicular,terminology,teriyaki,tenors,tenacity,tellers,telemetry,teas,tea's,tarragon,taliban,switchblade,swicker,swells,sweatshirts,swatches,swatch,swapped,suzanne's,surging,supremely,suntan,sump'n,suga,succumb,subsidize,subordinate,stumbles,stuffs,stronghold,stoppin,stipulate,stewie's,stenographer,steamroll,stds,stately,stasis,stagger,squandered,splint,splendidly,splatter,splashy,splashing,spectra's,specter,sorry's,sorcerers,soot,somewheres,somber,solvent,soldier's,soir,snuggled,snowmobile,snowball's,sniffed,snake's,snags,smugglers,smudged,smirking,smearing,slings,sleet,sleepovers,sleek,slackers,skirmish,siree,siphoning,singed,sincerest,signifying,sidney's,sickened,shuffled,shriveled,shorthanded,shittin,shish,shipwrecked,shins,shingle,sheetrock,shawshank,shamu,sha're,servitude,sequins,seinfeld's,seat's,seascape,seam,sculptor,scripture,scrapings,scoured,scoreboard,scorching,sciences,sara's,sandpaper,salvaged,saluting,salud,salamander,rugrats,ruffles,ruffled,rudolph's,router,roughnecks,rougher,rosslyn,rosses,rosco's,roost,roomy,romping,romeo's,robs,roadie,ride's,riddler,rianna's,revolutionize,revisions,reuniting,retake,retaining,restitution,restaurant's,resorts,reputed,reprimanded,replies,renovate,remnants,refute,refrigerated,reforms,reeled,reefs,reed's,redundancies,rectangle,rectal,recklessly,receding,reassignment,rearing,reapers,realms,readout,ration,raring,ramblings,racetrack,raccoons,quoi,quell,quarantined,quaker,pursuant,purr,purging,punters,pulpit,publishers,publications,psychologists,psychically,provinces,proust,protocols,prose,prophets,project's,priesthood,prevailed,premarital,pregnancies,predisposed,precautionary,poppin,pollute,pollo,podunk,plums,plaything,plateau,pixilated,pivot,pitting,piranhas,pieced,piddles,pickled,picker,photogenic,phosphorous,phases,pffft,petey's,pests,pestilence,pessimist,pesos,peruvian,perspiration,perps,penticoff,pedals,payload,passageways,pardons,paprika,paperboy,panics,pancamo,pam's,paleontologist,painting's,pacifist,ozzie,overwhelms,overstating,overseeing,overpaid,overlap,overflow,overdid,outspoken,outlive,outlaws,orthodontist,orin,orgies,oreos,ordover,ordinates,ooooooh,oooohhh,omelettes,officiate,obtuse,obits,oakwood,nymph,nutritional,nuremberg,nozzle,novocaine,notable,noooooooooo,node,nipping,nilly,nikko,nightstick,nicaragua,neurology,nelson's,negate,neatness,natured,narrowly,narcotic,narcissism,napoleon's,nana's,namun,nakatomi,murky,muchacho,mouthwash,motzah,motherfucker's,mortar,morsel,morrison's,morph,morlocks,moreover,mooch,monoxide,moloch,molest,molding,mohra,modus,modicum,mockolate,mobility,missionaries,misdemeanors,miscalculation,minorities,middies,metric,mermaids,meringue,mercilessly,merchandising,ment,meditating,me'n,mayakovsky,maximillian,martinique,marlee,markovski,marissa's,marginal,mansions,manitoba,maniacal,maneuvered,mags,magnificence,maddening,lyrical,lutze,lunged,lovelies,lou's,lorry,loosening,lookee,liver's,liva,littered,lilac,lightened,lighted,licensing,lexington,lettering,legality,launches,larvae,laredo,landings,lancelot's,laker,ladyship's,laces,kurzon,kurtzweil,kobo,knowledgeable,kinship,kind've,kimono,kenji,kembu,keanu,kazuo,kayaking,juniors,jonesing,joad,jilted,jiggling,jewelers,jewbilee,jeffrey's,jamey's,jacqnoud,jacksons,jabs,ivories,isnt,irritation,iraqis,intellectuals,insurmountable,instances,installments,innocuous,innkeeper,inna,influencing,infantery,indulged,indescribable,incorrectly,incoherent,inactive,inaccurate,improperly,impervious,impertinent,imperfections,imhotep,ideology,identifies,i'il,hymns,huts,hurdles,hunnert,humpty,huffy,hourly,horsies,horseradish,hooo,honours,honduras,hollowed,hogwash,hockley,hissing,hiromitsu,hierarchy,hidin,hereafter,helpmann,haughty,happenings,hankie,handsomely,halliwells,haklar,haise,gunsights,gunn's,grossly,grossed,grope,grocer,grits,gripping,greenpeace,granddad's,grabby,glorificus,gizzard,gilardi,gibarian,geminon,gasses,garnish,galloping,galactic,gairwyn,gail's,futterman,futility,fumigated,fruitless,friendless,freon,fraternities,franc,fractions,foxes,foregone,forego,foliage,flux,floored,flighty,fleshy,flapjacks,fizzled,fittings,fisherman's,finalist,ficus,festering,ferragamo's,federation,fatalities,farbman,familial,famed,factual,fabricate,eyghon,extricate,exchanges,exalted,evolving,eventful,esophagus,eruption,envision,entre,enterprising,entail,ensuring,enrolling,endor,emphatically,eminent,embarrasses,electroshock,electronically,electrodes,efficiently,edinburgh,ecstacy,ecological,easel,dwarves,duffle,drumsticks,drake's,downstream,downed,dollface,divas,distortion,dissent,dissection,dissected,disruptive,disposing,disparaging,disorientation,disintegrated,discounts,disarming,dictated,devoting,deviation,detective's,dessaline,deprecating,deplorable,delve,deity,degenerative,deficiencies,deduct,decomposed,deceased's,debbie's,deathly,dearie,daunting,dankova,czechoslovakia,cyclotron,cyberspace,cutbacks,cusp,culpable,cuddled,crypto,crumpets,cruises,cruisers,cruelly,crowns,crouching,cristo,crip,criminology,cranium,cramming,cowering,couric,counties,cosy,corky's,cordesh,conversational,conservatory,conklin's,conducive,conclusively,competitions,compatibility,coeur,clung,cloud's,clotting,cleanest,classify,clambake,civilizations,cited,cipher,cinematic,chlorine,chipping,china's,chimpanzee,chests,checkpoints,cheapen,chainsaws,censure,censorship,cemeteries,celebrates,ceej,cavities,catapult,cassettes,cartridge,caravaggio,carats,captivating,cancers,campuses,campbell's,calrissian,calibre,calcutta,calamity,butt's,butlers,busybody,bussing,bureau's,bunion,bundy's,bulimic,bulgaria,budging,brung,browbeat,brokerage,brokenhearted,brecher,breakdowns,braun's,bracebridge,boyhood,botanical,bonuses,boning,blowhard,bloc,blisters,blackboard,blackbird,births,birdies,bigotry,biggy,bibliography,bialy,bhamra,bethlehem,bet's,bended,belgrade,begat,bayonet,bawl,battering,baste,basquiat,barrymore,barrington's,barricaded,barometer,balsom's,balled,ballast,baited,badenweiler,backhand,aztec,axle,auschwitz,astrophysics,ascenscion,argumentative,arguably,arby's,arboretum,aramaic,appendicitis,apparition,aphrodite,anxiously,antagonistic,anomalies,anne's,angora,anecdotes,anand,anacott,amniotic,amenities,ambience,alonna,aleck,albert's,akashic,airing,ageless,afro,affiliates,advertisers,adobe,adjustable,acrobat,accommodation,accelerating,absorbing,abouts,abortions,abnormalities,aawwww,aaaaarrrrrrggghhh,zuko's,zoloft,zendi,zamboni,yuppies,yodel,y'hear,wyck,wrangle,wounding,worshippers,worker's,worf,wombosi,wittle,withstanding,wisecracks,williamsburg,wilder's,wiggly,wiggling,wierd,whittlesley,whipper,whattya,whatsamatter,whatchamacallit,whassup,whad'ya,weighted,weakling,waxy,waverly,wasps,warhol,warfarin,waponis,wampum,walled,wadn't,waco,vorash,vogler's,vizzini,visas,virtucon,viridiana,veve,vetoed,vertically,veracity,ventricular,ventilated,varicose,varcon,vandalized,vampire's,vamos,vamoose,val's,vaccinated,vacationing,usted,urinal,uppers,upkeep,unwittingly,unsigned,unsealed,unplanned,unhinged,unhand,unfathomable,unequivocally,unearthed,unbreakable,unanimously,unadvisedly,udall,tynacorp,twisty,tuxes,tussle,turati,tunic,tubing,tsavo,trussed,troublemakers,trollop,trip's,trinket,trilogy,tremors,trekkie,transsexual,transitional,transfusions,tractors,toothbrushes,toned,toke,toddlers,titan's,tita,tinted,timon,timeslot,tightened,thundering,thorpey,thoracic,this'd,thespian,therapist's,theorem,thaddius,texan,tenuous,tenths,tenement,telethon,teleprompter,technicolor,teaspoon,teammate,teacup,taunted,tattle,tardiness,taraka,tappy,tapioca,tapeworm,tanith,tandem,talons,talcum,tais,tacks,synchronized,swivel,swig,swaying,swann's,suppression,supplements,superpower,summed,summarize,sumbitch,sultry,sulfur,sues,subversive,suburbia,substantive,styrofoam,stylings,struts,strolls,strobe,streaks,strategist,stockpile,stewardesses,sterilized,sterilize,stealin,starred,stakeouts,stad,squawk,squalor,squabble,sprinkled,sportsmanship,spokes,spiritus,spectators,specialties,sparklers,spareribs,sowing,sororities,sorbonne,sonovabitch,solicit,softy,softness,softening,socialite,snuggling,snatchers,snarling,snarky,snacking,smythe's,smears,slumped,slowest,slithering,sleepers,sleazebag,slayed,slaughtering,skynet,skidded,skated,sivapathasundaram,sitter's,sitcoms,sissies,sinai,silliness,silences,sidecar,sicced,siam,shylock,shtick,shrugged,shriek,shredder,shoves,should'a,shorten,shortcake,shockingly,shirking,shelly's,shedding,shaves,shatner,sharpener,shapely,shafted,sexless,sequencing,septum,semitic,selflessness,sega,sectors,seabea,scuff,screwball,screened,scoping,scooch,scolding,scholarly,schnitzel,schemed,scalper,sayings,saws,sashimi,santy,sankara,sanest,sanatorium,sampled,samoan,salzburg,saltwater,salma,salesperson,sakulos,safehouse,sabers,rwanda,ruth's,runes,rumblings,rumbling,ruijven,roxie's,round's,ringers,rigorous,righto,rhinestones,reviving,retrieving,resorted,reneging,remodelling,reliance,relentlessly,relegated,relativity,reinforced,reigning,regurgitate,regulated,refills,referencing,reeking,reduces,recreated,reclusive,recklessness,recanted,ranges,ranchers,rallied,rafer,racy,quintet,quaking,quacks,pulses,provision,prophesied,propensity,pronunciation,programmer,profusely,procedural,problema,principals,prided,prerequisite,preferences,preceded,preached,prays,postmark,popsicles,poodles,pollyanna,policing,policeman's,polecat,polaroids,polarity,pokes,poignant,poconos,pocketful,plunging,plugging,pleeease,pleaser,platters,pitied,pinetti,piercings,phyllis's,phooey,phonies,pestering,periscope,perennial,perceptions,pentagram,pelts,patronized,parliamentary,paramour,paralyze,paraguay,parachutes,pancreatic,pales,paella,paducci,oxymoron,owatta,overpass,overgrown,overdone,overcrowded,overcompensating,overcoming,ostracized,orphaned,organise,organisation,ordinate,orbiting,optometrist,oprah's,operandi,oncology,on's,omoc,omens,okayed,oedipal,occupants,obscured,oboe,nuys,nuttier,nuptial,nunheim,noxious,nourish,notepad,notation,nordic,nitroglycerin,niki's,nightmare's,nightlife,nibblet,neuroses,neighbour's,navy's,nationally,nassau,nanosecond,nabbit,mythic,murdock's,munchkins,multiplied,multimillion,mulroney,mulch,mucous,muchas,moxie,mouth's,mountaintop,mounds,morlin,mongorians,moneymaker,moneybags,monde,mom'll,molto,mixup,mitchell's,misgivings,misery's,minerals,mindset,milo's,michalchuk,mesquite,mesmerized,merman,mensa,megan's,media's,meaty,mbwun,materialize,materialistic,mastery,masterminded,mastercard,mario's,marginally,mapuhe,manuscripts,manny's,malvern,malfunctioning,mahatma,mahal,magnify,macnamara,macinerney,machinations,macarena,macadamia,lysol,luxembourg,lurks,lumpur,luminous,lube,lovelorn,lopsided,locator,lobbying,litback,litany,linea,limousines,limo's,limes,lighters,liechtenstein,liebkind,lids,libya,levity,levelheaded,letterhead,lester's,lesabre,leron,lepers,legions,lefts,leftenant,learner's,laziness,layaway,laughlan,lascivious,laryngitis,laptops,lapsed,laos,landok,landfill,laminated,laden,ladders,labelled,kyoto,kurten,kobol,koala,knucklehead,knowed,knotted,kit's,kinsa,kiln,kickboxing,karnovsky,karat,kacl's,judiciary,judaism,journalistic,jolla,joked,jimson,jettison,jet's,jeric,jeeves,jay's,jawed,jankis,janitors,janice's,jango,jamaican,jalopy,jailbreak,jackers,jackasses,j'ai,ivig,invalidate,intoxicated,interstellar,internationally,intercepting,intercede,integrate,instructors,insinuations,insignia,inn's,inflicting,infiltrated,infertile,ineffective,indies,indie,impetuous,imperialist,impaled,immerse,immaterial,imbeciles,imam,imagines,idyllic,idolized,icebox,i'd've,hypochondriac,hyphen,hydraulic,hurtling,hurried,hunchback,hums,humid,hullo,hugger,hubby's,howard's,hostel,horsting,horned,hoooo,homies,homeboys,hollywood's,hollandaise,hoity,hijinks,heya,hesitates,herrero,herndorff,hemp,helplessly,heeyy,heathen,hearin,headband,harv,harrassment,harpies,harmonious,harcourt,harbors,hannah's,hamstring,halstrom,hahahahaha,hackett's,hacer,gunmen,guff,grumbling,grimlocks,grift,greets,grandmothers,grander,granddaughter's,gran's,grafts,governing,gordievsky,gondorff,godorsky,goddesses,glscripts,gillman's,geyser,gettysburg,geological,gentlemen's,genome,gauntlet,gaudy,gastric,gardeners,gardener's,gandolf,gale's,gainful,fuses,fukienese,fucker's,frizzy,freshness,freshening,freb,fraught,frantically,fran's,foxbooks,fortieth,forked,forfeited,forbidding,footed,foibles,flunkies,fleur,fleece,flatbed,flagship,fisted,firefight,fingerpaint,fined,filibuster,fiancee's,fhloston,ferrets,fenceline,femur,fellow's,fatigues,farmhouse,fanucci,fantastically,familiars,falafel,fabulously,eyesore,extracting,extermination,expedient,expectancy,exiles,executor,excluding,ewwww,eviscerated,eventual,evac,eucalyptus,ethnicity,erogenous,equestrian,equator,epidural,enrich,endeavors,enchante,embroidered,embarassed,embarass,embalming,emails,elude,elspeth,electrocute,electrified,eigth,eheh,eggshell,eeyy,echinacea,eases,earpiece,earlobe,dwarfs,dumpsters,dumbshit,dumbasses,duloc,duisberg,drummed,drinkers,dressy,drainage,dracula's,dorma,dolittle,doily,divvy,diverting,ditz,dissuade,disrespecting,displacement,displace,disorganized,dismantled,disgustingly,discriminate,discord,disapproving,dinero,dimwit,diligence,digitally,didja,diddy,dickless,diced,devouring,devlin's,detach,destructing,desperado,desolate,designation,derek's,deposed,dependency,dentist's,demonstrates,demerits,delirium,degrade,deevak,deemesa,deductions,deduce,debriefed,deadbeats,dazs,dateline,darndest,damnable,dalliance,daiquiri,d'agosta,cuvee's,cussing,curate,cryss,cripes,cretins,creature's,crapper,crackerjack,cower,coveting,couriers,countermission,cotswolds,cornholio,copa,convinces,convertibles,conversationalist,contributes,conspirators,consorting,consoled,conservation,consarn,confronts,conformity,confides,confidentially,confederacy,concise,competence,commited,commissioners,commiserate,commencing,comme,commandos,comforter,comeuppance,combative,comanches,colosseum,colling,collaboration,coli,coexist,coaxing,cliffside,clayton's,clauses,cia's,chuy,chutes,chucked,christian's,chokes,chinaman,childlike,childhoods,chickening,chicano,chenowith,chassis,charmingly,changin,championships,chameleon,ceos,catsup,carvings,carlotta's,captioning,capsize,cappucino,capiche,cannonball,cannibal,candlewell,cams,call's,calculation,cakewalk,cagey,caesar's,caddie,buxley,bumbling,bulky,bulgarian,bugle,buggered,brussel,brunettes,brumby,brotha,bros,bronck,brisket,bridegroom,breathing's,breakout,braveheart,braided,bowled,bowed,bovary,bordering,bookkeeper,bluster,bluh,blue's,blot,bloodline,blissfully,blarney,binds,billionaires,billiard,bide,bicycles,bicker,berrisford,bereft,berating,berate,bendy,benches,bellevue,belive,believers,belated,beikoku,beens,bedspread,bed's,bear's,bawdy,barrett's,barreling,baptize,banya,balthazar,balmoral,bakshi,bails,badgered,backstreet,backdrop,awkwardly,avoids,avocado,auras,attuned,attends,atheists,astaire,assuredly,art's,arrivederci,armaments,arises,argyle,argument's,argentine,appetit,appendectomy,appealed,apologetic,antihistamine,antigua,anesthesiologist,amulets,algonquin,alexander's,ales,albie,alarmist,aiight,agility,aforementioned,adstream,adolescents,admirably,adjectives,addison's,activists,acquaint,acids,abound,abominable,abolish,abode,abfc,aaaaaaah,zorg,zoltan,zoe's,zekes,zatunica,yama,wussy,wrcw,worded,wooed,woodrell,wiretap,windowsill,windjammer,windfall,whitey's,whitaker's,whisker,whims,whatiya,whadya,westerns,welded,weirdly,weenies,webster's,waunt,washout,wanto,waning,vitality,vineyards,victimless,vicki's,verdad,veranda,vegan,veer,vandaley,vancouver,vancomycin,valise,validated,vaguest,usefulness,upshot,uprising,upgrading,unzip,unwashed,untrained,unsuitable,unstuck,unprincipled,unmentionables,unjustly,unit's,unfolds,unemployable,uneducated,unduly,undercut,uncovering,unconsciousness,unconsciously,unbeknownst,unaffected,ubiquitous,tyndareus,tutors,turncoat,turlock,tulle,tuesday's,tryouts,truth's,trouper,triplette,trepkos,tremor,treeger,treatment's,traveller,traveler's,trapeze,traipse,tradeoff,trach,torin,tommorow,tollan,toity,timpani,tilted,thumbprint,throat's,this's,theater's,thankless,terrestrial,tenney's,tell'em,telepathy,telemarketing,telekinesis,teevee,teeming,tc's,tarred,tankers,tambourine,talentless,taki,takagi,swooped,switcheroo,swirly,sweatpants,surpassed,surgeon's,supermarkets,sunstroke,suitors,suggestive,sugarcoat,succession,subways,subterfuge,subservient,submitting,subletting,stunningly,student's,strongbox,striptease,stravanavitch,stradling,stoolie,stodgy,stocky,stimuli,stigmata,stifle,stealer,statewide,stark's,stardom,stalemate,staggered,squeezes,squatter,squarely,sprouted,spool,spirit's,spindly,spellman's,speedos,specify,specializing,spacey,soups,soundly,soulmates,somethin's,somebody'll,soliciting,solenoid,sobering,snowflakes,snowballs,snores,slung,slimming,slender,skyscrapers,skulk,skivvies,skillful,skewered,skewer,skaters,sizing,sistine,sidebar,sickos,shushing,shunt,shugga,shone,shol'va,shiv,shifter,sharply,sharpened,shareholder,shapeshifter,shadowing,shadoe,serviced,selwyn,selectman,sefelt,seared,seamen,scrounging,scribbling,scotty's,scooping,scintillating,schmoozing,schenectady,scene's,scattering,scampi,scallops,sat's,sapphires,sans,sanitarium,sanded,sanction,safes,sacrificial,rudely,roust,rosebush,rosasharn,rondell,roadhouse,riveted,rile,ricochet,rhinoceros,rewrote,reverence,revamp,retaliatory,rescues,reprimand,reportedly,replicators,replaceable,repeal,reopening,renown,remo's,remedied,rembrandt,relinquishing,relieving,rejoicing,reincarnated,reimbursed,refinement,referral,reevaluate,redundancy,redid,redefine,recreating,reconnected,recession,rebelling,reassign,rearview,reappeared,readily,rayne,ravings,ravage,ratso,rambunctious,rallying,radiologist,quiver,quiero,queef,quark,qualms,pyrotechnics,pyro,puritan,punky,pulsating,publisher's,psychosomatic,provisional,proverb,protested,proprietary,promiscuous,profanity,prisoner's,prioritize,preying,predisposition,precocious,precludes,preceding,prattling,prankster,povich,potting,postpartum,portray,porter's,porridge,polluting,pogo,plowing,plating,plankton,pistachio,pissin,pinecone,pickpocket,physicists,physicals,pesticides,peruse,pertains,personified,personalize,permitting,perjured,perished,pericles,perfecting,percentages,pepys,pepperdine,pembry,peering,peels,pedophile,patties,pathogen,passkey,parrots,paratroopers,paratrooper,paraphernalia,paralyzing,panned,pandering,paltry,palpable,painkiller,pagers,pachyderm,paced,overtaken,overstay,overestimated,overbite,outwit,outskirts,outgrow,outbid,origins,ordnance,ooze,ooops,oomph,oohhh,omni,oldie,olas,oddball,observers,obscurity,obliterate,oblique,objectionable,objected,oars,o'keefe,nygma,nyet,nouveau,notting,nothin's,noches,nnno,nitty,nighters,nigger's,niche,newsstands,newfoundland,newborns,neurosurgery,networking,nellie's,nein,neighboring,negligible,necron,nauseated,nastiest,nasedo's,narrowing,narrator,narcolepsy,napa,nala,nairobi,mutilate,muscled,murmur,mulva,multitude,multiplex,mulling,mules,mukada,muffled,mueller's,motorized,motif,mortgages,morgues,moonbeams,monogamy,mondays,mollusk,molester,molestation,molars,modifications,modeled,moans,misuse,misprint,mismatched,mirth,minnow,mindful,mimosas,millander,mikhail,mescaline,mercutio,menstrual,menage,mellowing,medicaid,mediator,medevac,meddlesome,mcgarry's,matey,massively,massacres,marky,many's,manifests,manifested,manicures,malevolent,malaysian,majoring,madmen,mache,macarthur's,macaroons,lydell,lycra,lunchroom,lunching,lozenges,lorenzo's,looped,look's,lolly,lofty,lobbyist,litigious,liquidate,linoleum,lingk,lincoln's,limitless,limitation,limber,lilacs,ligature,liftoff,lifeboats,lemmiwinks,leggo,learnin,lazarre,lawyered,landmarks,lament,lambchop,lactose,kringle,knocker,knelt,kirk's,kins,kiev,keynote,kenyon's,kenosha,kemosabe,kazi,kayak,kaon,kama,jussy,junky,joyce's,journey's,jordy,jo's,jimmies,jetson,jeriko,jean's,janet's,jakovasaur,jailed,jace,issacs,isotopes,isabela,irresponsibility,ironed,intravenous,intoxication,intermittent,insufficient,insinuated,inhibitors,inherits,inherently,ingest,ingenue,informs,influenza,inflexible,inflame,inevitability,inefficient,inedible,inducement,indignant,indictments,indentured,indefensible,inconsistencies,incomparable,incommunicado,in's,improvising,impounded,illogical,ignoramus,igneous,idlewild,hydrochloric,hydrate,hungover,humorless,humiliations,humanoid,huhh,hugest,hudson's,hoverdrone,hovel,honor's,hoagie,hmmph,hitters,hitchhike,hit's,hindenburg,hibernating,hermione,herds,henchman,helloooo,heirlooms,heaviest,heartsick,headshot,headdress,hatches,hastily,hartsfield's,harrison's,harrisburg,harebrained,hardships,hapless,hanen,handsomer,hallows,habitual,habeas,guten,gus's,gummy,guiltier,guidebook,gstaad,grunts,gruff,griss,grieved,grids,grey's,greenville,grata,granny's,gorignak,goosed,goofed,goat's,gnarly,glowed,glitz,glimpses,glancing,gilmores,gilligan's,gianelli,geraniums,georgie's,genitalia,gaydar,gart,garroway,gardenia,gangbusters,gamblers,gamble's,galls,fuddy,frumpy,frowning,frothy,fro'tak,friars,frere,freddy's,fragrances,founders,forgettin,footsie,follicles,foes,flowery,flophouse,floor's,floatin,flirts,flings,flatfoot,firefighter,fingerprinting,fingerprinted,fingering,finald,film's,fillet,file's,fianc,femoral,fellini,federated,federales,faze,fawkes,fatally,fascists,fascinates,farfel,familiarity,fambly,falsified,fait,fabricating,fables,extremist,exterminators,extensively,expectant,excusez,excrement,excercises,excavation,examinations,evian,evah,etins,esther's,esque,esophageal,equivalency,equate,equalizer,environmentally,entrees,enquire,enough's,engine's,endorsed,endearment,emulate,empathetic,embodies,emailed,eggroll,edna's,economist,ecology,eased,earmuffs,eared,dyslexic,duper,dupe,dungeons,duncan's,duesouth,drunker,drummers,druggie,dreadfully,dramatics,dragnet,dragline,dowry,downplay,downers,doritos,dominatrix,doers,docket,docile,diversify,distracts,disruption,disloyalty,disinterested,disciple,discharging,disagreeable,dirtier,diplomats,dinghy,diner's,dimwitted,dimoxinil,dimmy,dietary,didi,diatribe,dialects,diagrams,diagnostics,devonshire,devising,deviate,detriment,desertion,derp,derm,dept,depressants,depravity,dependence,denounced,deniability,demolished,delinquents,defiled,defends,defamation,deepcore,deductive,decrease,declares,declarations,decimated,decimate,deb's,deadbolt,dauthuille,dastardly,darla's,dans,daiquiris,daggers,dachau,d'ah,cymbals,customized,curved,curiouser,curdled,cupid's,cults,cucamonga,cruller,cruces,crow's,crosswalk,crossover,crinkle,crescendo,cremate,creeper,craftsman,cox's,counteract,counseled,couches,coronet,cornea,cornbread,corday,copernicus,conveyed,contrition,contracting,contested,contemptible,consultants,constructing,constipated,conqueror,connor's,conjoined,congenital,confounded,condescend,concubine,concoct,conch,concerto,conceded,compounded,compensating,comparisons,commoners,committment,commencement,commandeered,comely,coined,cognitive,codex,coddled,cockfight,cluttered,clunky,clownfish,cloaked,cliches,clenched,cleft,cleanin,cleaner's,civilised,circumcised,cimmeria,cilantro,chutzpah,chutney,chucking,chucker,chronicles,chiseled,chicka,chicago's,chattering,charting,characteristic,chaise,chair's,cervix,cereals,cayenne,carrey,carpal,carnations,caricature,cappuccinos,candy's,candied,cancer's,cameo,calluses,calisthenics,cadre,buzzsaw,bushy,burners,bundled,bum's,budington,buchanans,brock's,britons,brimming,breeders,breakaway,braids,bradley's,boycotting,bouncers,botticelli,botherin,boosting,bookkeeping,booga,bogyman,bogged,bluepoint's,bloodthirsty,blintzes,blanky,blak,biosphere,binturong,billable,bigboote,bewildered,betas,bernard's,bequeath,beirut,behoove,beheaded,beginners,beginner,befriend,beet,bedpost,bedded,bay's,baudelaires,barty,barreled,barboni,barbeque,bangin,baltus,bailout,bag's,backstabber,baccarat,awning,awaited,avenues,austen,augie,auditioned,auctions,astrology,assistant's,assassinations,aspiration,armenians,aristocrat,arguillo,archway,archaeologist,arcane,arabic,apricots,applicant,apologising,antennas,annyong,angered,andretti,anchorman,anchored,amritsar,amour,amidst,amid,americana,amenable,ambassadors,ambassador's,amazement,allspice,alannis,airliner,airfare,airbags,ahhhhhhhhh,ahhhhhhhh,ahhhhhhh,agitator,afternoon's,afghan,affirmation,affiliate,aegean,adrenal,actor's,acidosis,achy,achoo,accessorizing,accentuate,academically,abuses,abrasions,abilene,abductor,aaaahhh,zuzu,zoot,zeroing,zelner,zeldy,yo's,yevgeny,yeup,yeska,yellows,yeesh,yeahh,yamuri,yaks,wyatt's,wspr,writing's,wrestlers,wouldn't've,workmanship,woodsman,winnin,winked,wildness,widespread,whoring,whitewash,whiney,when're,wheezer,wheelman,wheelbarrow,whaling,westerburg,wegener's,weekdays,weeding,weaving,watermelons,watcher's,washboard,warmly,wards,waltzes,walt's,walkway,waged,wafting,voulez,voluptuous,vitone,vision's,villa's,vigilantes,videotaping,viciously,vices,veruca,vermeer,verifying,ventured,vaya,vaults,vases,vasculitis,varieties,vapor,valets,upriver,upholstered,upholding,unwavering,unused,untold,unsympathetic,unromantic,unrecognizable,unpredictability,unmask,unleashing,unintentional,unilaterally,unglued,unequivocal,underside,underrated,underfoot,unchecked,unbutton,unbind,unbiased,unagi,uhhhhh,turnovers,tugging,trouble's,triads,trespasses,treehorn,traviata,trappers,transplants,transforming,trannie,tramping,trainers,traders,tracheotomy,tourniquet,tooty,toothless,tomarrow,toasters,tine,tilting,thruster,thoughtfulness,thornwood,therapies,thanksgiving's,tha's,terri's,tengo,tenfold,telltale,telephoto,telephoned,telemarketer,teddy's,tearin,tastic,tastefully,tasking,taser,tamed,tallow,taketh,taillight,tadpoles,tachibana,syringes,sweated,swarthy,swagger,surrey,surges,surf's,supermodels,superhighway,sunup,sun'll,summaries,sumerian,sulu,sulphur,sullivan's,sulfa,suis,sugarless,sufficed,substituted,subside,submerged,subdue,styling,strolled,stringy,strengthens,street's,straightest,straightens,storyteller,storefront,stopper,stockpiling,stimulant,stiffed,steyne,sternum,stereotypical,stepladder,stepbrother,steers,steeple,steelheads,steakhouse,statue's,stathis,stankylecartmankennymr,standoffish,stalwart,stallions,stacy's,squirted,squeaker,squad's,spuds,spritz,sprig,sprawl,spousal,sportsman,sphincter,spenders,spearmint,spatter,sparrows,spangled,southey,soured,sonuvabitch,somethng,societies,snuffed,snowfall,snowboarding,sniffs,snafu,smokescreen,smilin,slurred,slurpee,slums,slobs,sleepwalker,sleds,slays,slayage,skydiving,sketched,skateboarding,skanks,sixed,siri,sired,siphoned,siphon,singer's,simpering,silencer,sigfried,siena,sidearm,siddons,sickie,siberian,shuteye,shuk,shuffleboard,shrubberies,shrouded,showmanship,shower's,shouldn't've,shortwave,shoplift,shooter's,shiatsu,sheriffs,shak,shafts,serendipity,serena's,sentries,sentance,sensuality,semesters,seething,sedition,secular,secretions,searing,scuttlebutt,sculpt,scowling,scouring,scorecard,schwarzenegger,schoolers,schmucks,scepters,scaly,scalps,scaling,scaffolding,sauces,sartorius,santen,sampler,salivating,salinger,sainthood,said's,saget,saddens,rygalski,rusting,rumson's,ruination,rueland,rudabaga,rubles,rowr,rottweiler,rotations,roofies,romantics,rollerblading,roldy,rob's,roadshow,rike,rickets,rible,rheza,revisiting,revisited,reverted,retrospective,retentive,resurface,restores,respite,resounding,resorting,resolutions,resists,repulse,repressing,repaying,reneged,relays,relayed,reinforce,regulator,registers,refunds,reflections,rediscover,redecorated,recruitment,reconstructive,reconstructed,recommitted,recollect,recoil,recited,receptor,receptacle,receivers,reassess,reanimation,realtors,razinin,ravaged,ratios,rationalization,ratified,ratatouille,rashum,rasczak,rarer,rapping,rancheros,rampler,rain's,railway,racehorse,quotient,quizzing,quips,question's,quartered,qualification,purring,pummeling,puede,publicized,psychedelic,proximo,proteins,protege,prospectus,pronouncing,pronoun,prolonging,program's,proficient,procreation,proclamations,prio,principled,prides,pricing,presbyterian,preoccupation,prego,preferential,predicts,precog,prattle,pounced,potshots,potpourri,portsmouth,porque,poppie's,poms,pomeranian,pomegranates,polynesian,polymer,polenta,plying,plume,plumber's,pluie,plough,plesac,playoff,playmates,planter,plantains,plaintiff's,pituitary,pisano's,pillowcase,piddle,pickers,phys,photocopied,philistine,pfeiffer's,peyton's,petitioned,persuading,perpetuate,perpetually,periodically,perilous,pensacola,pawned,pausing,pauper,patterned,pats,patronage,passover,partition,parter,parlez,parlay,parkinson's,parades,paperwork's,pally,pairing,ovulation,overtake,overstate,overpowering,overpowered,overconfident,overbooked,ovaltine,ouzo,outweighs,outings,outfit's,out's,ottos,orrin,originate,orifice,orangutan,optimal,optics,opportunistic,ooww,oopsy,ooooooooh,ooohhhh,onyx,onslaught,oldsmobile,ocular,ocean's,obstruct,obscenely,o'dwyer,o'brien's,nutjob,nunur,notifying,nostrand,nonny,nonfat,noblest,nimble,nikes,nicht,newsworthy,network's,nestled,nessie,necessities,nearsighted,ne'er,nazareth,navidad,nastier,nasa's,narco,nakedness,muted,mummified,multiplying,mudda,mtv's,mozzarella,moxica,motorists,motivator,motility,mothafucka,mortmain,mortgaged,mortally,moroccan,mores,moonshine,mongers,moe's,modify,mobster's,mobilization,mobbed,mitigating,mistah,misrepresented,mishke,misfortunes,misdirection,mischievous,mirrored,mineshaft,mimosa,millers,millaney,miho,midday,microwaves,mick's,metzenbaum,metres,merc,mentoring,medicine's,mccovey,maya's,mau's,masterful,masochistic,martie,marliston,market's,marijawana,marie's,marian's,manya,manuals,mantumbi,mannheim,mania,mane,mami's,malarkey,magnifique,magics,magician's,madrona,madox,madison's,machida,m'mm,m'hm,m'hidi,lyric,luxe,luther's,lusty,lullabies,loveliness,lotions,looka,lompoc,loader,litterbug,litigator,lithe,liquorice,lins,linguistics,linds,limericks,lightbulb,lewises,letch,lemec,lecter's,leavenworth,leasing,leases,layover,layered,lavatory,laurels,launchers,laude,latvian,lateness,lasky's,laparotomy,landlord's,laboring,la's,kumquat,kuato,kroff,krispy,kree,krauts,kona,knuckleheads,knighthood,kiva,kitschy,kippers,kip's,kimbrow,kike,keypad,keepsake,kebab,keane's,kazakhstan,karloff,justices,junket,juicer,judy's,judgemental,jsut,jointed,jogs,jezzie,jetting,jekyll,jehovah's,jeff's,jeeze,jeeter,jeesus,jeebs,janeane,jalapeno,jails,jailbait,jagged,jackin,jackhammer,jacket's,ixnay,ivanovich,issue's,isotope,island's,irritates,irritability,irrevocable,irrefutable,irma's,irked,invoking,intricacies,interferon,intents,inte,insubordinate,instructive,instinctive,inspector's,inserting,inscribed,inquisitive,inlay,injuns,inhibited,infringement,information's,infer,inebriated,indignity,indecisive,incisors,incacha,inauguration,inalienable,impresses,impregnate,impregnable,implosion,immersed,ikea,idolizes,ideological,idealism,icepick,hypothyroidism,hypoglycemic,hyde's,hutz,huseni,humvee,hummingbird,hugely,huddling,housekeeper's,honing,hobnobbing,hobnob,histrionics,histamine,hirohito,hippocratic,hindquarters,hinder,himalayan,hikita,hikes,hightailed,hieroglyphics,heyy,heuh,heretofore,herbalist,her's,henryk,henceforth,hehey,hedriks,heartstrings,headmistress,headlight,harvested,hardheaded,happend,handlers,handlebars,hagitha,habla,gyroscope,guys'd,guy'd,guttersnipe,grump,growed,grovelling,grooves,groan,greenbacks,greats,gravedigger,grating,grasshoppers,grappling,graph,granger's,grandiose,grandest,gram's,grains,grafted,gradual,grabthar's,goop,gooood,goood,gooks,godsakes,goaded,gloria's,glamorama,giveth,gingham,ghostbusters,germane,georgy,geisha,gazzo,gazelles,gargle,garbled,galgenstein,galapagos,gaffe,g'day,fyarl,furnish,furies,fulfills,frowns,frowned,frommer's,frighteningly,fresco,freebies,freakshow,freakishly,fraudulent,fragrant,forewarned,foreclose,forearms,fordson,ford's,fonics,follies,foghorn,fly's,flushes,fluffy's,flitting,flintstone,flemmer,flatline,flamboyant,flabby,fishbowl,firsts,finger's,financier,figs,fidgeting,fictitious,fevers,feur,ferns,feminism,fema,feigning,faxing,fatigued,fathoms,fatherless,fares,fancier,fanatical,fairs,factored,eyelid,eyeglasses,eye's,expresso,exponentially,expletive,expectin,excruciatingly,evidentiary,ever'thing,evelyn's,eurotrash,euphoria,eugene's,eubie,ethiopian,ethiopia,estrangement,espanol,erupted,ernie's,erlich,eres,epitome,epitaph,environments,environmentalists,entrap,enthusiastically,entertainers,entangled,enclose,encased,empowering,empires,emphysema,embers,embargo,emasculating,elizabethan,elephant's,eighths,egyptians,effigy,editions,echoing,eardrum,dyslexia,duplicitous,duplicated,dumpty,dumbledore,dufus,dudley's,duddy,duck's,duchamp,drunkenness,drumlin,drowns,droid,drinky,drifts,drawbridge,dramamine,downey's,douggie,douchebag,dostoyevsky,dorian's,doodling,don'tcha,domo,domineering,doings,dogcatcher,documenting,doctoring,doctoral,dockers,divides,ditzy,dissimilar,dissecting,disparage,disliking,disintegrating,dishwalla,dishonored,dishing,disengaged,discretionary,discard,disavowed,directives,dippy,diorama,dimmed,diminishing,dilate,dijon,digitalis,diggory,dicing,diagnosing,devout,devola,developmental,deter,destiny's,desolation,descendant,derived,derevko's,deployment,dennings,denials,deliverance,deliciously,delicacies,degenerates,degas,deflector,defile,deference,defenders,deduced,decrepit,decreed,decoding,deciphered,dazed,dawdle,dauphine,daresay,dangles,dampen,damndest,customer's,curricular,cucumbers,cucaracha,cryogenically,cruella,crowd's,croaks,croaked,criticise,crit,crisper,creepiest,creep's,credit's,creams,crawford's,crackle,crackin,covertly,cover's,county's,counterintelligence,corrosive,corpsman,cordially,cops'll,convulsions,convoluted,convincingly,conversing,contradictions,conga,confucius,confrontational,confab,condolence,conditional,condition's,condiments,composing,complicit,compiled,compile,compiegne,commuter,commodus,commissions,comings,cometh,combining,colossus,collusion,collared,cockeyed,coastline,clobber,clemonds,clashes,clarithromycin,clarified,cinq,cienega,chronological,christmasy,christmassy,chloroform,chippie,childless,chested,chemistry's,cheerios,cheeco,checklist,chaz,chauvinist,char,chang's,chandlers,chamois,chambermaid,chakras,chak,censored,cemented,cellophane,celestial,celebrations,caveat,catholicism,cataloguing,cartmanland,carples,carny,carded,caramels,captors,caption,cappy,caped,canvassing,cannibalism,canada's,camille's,callback,calibrated,calamine,cal's,cabo,bypassed,buzzy,buttermilk,butterfingers,bushed,burlesque,bunsen,bung,bulimia,bukatari,buildin,budged,bronck's,brom,brobich,bringer,brine,brendell,brawling,bratty,brasi,braking,braised,brackett's,braced,boyish,boundless,botch,borough,boosh,bookies,bonbons,bois,bodes,bobunk,bluntly,blossoming,bloopers,bloomers,bloodstains,bloodhounds,blitzen,blinker,blech,blasts,blanca's,bitterly,biter,biometric,bioethics,bilk,bijan,bigoted,bicep,betrothed,bergdorf's,bereaved,bequeathed,belo,bellowing,belching,beholden,befriended,beached,bawk,battled,batmobile,batman's,baseline,baseball's,barcodes,barch,barbie's,barbecuing,bandanna,baldy,bailey's,baghdad,backwater,backtrack,backdraft,ayuh,awgh,augustino,auctioned,attaching,attaches,atrophy,atrocity,atley,athletics,atchoo,asymmetrical,asthmatic,assoc,assists,ascending,ascend,articulated,arrr,armstrong's,armchair,arisen,archeology,archeological,arachnids,aptly,applesauce,appetizing,antisocial,antagonizing,anorexia,anini,angie's,andersons,anarchist,anagram,amputation,amherst,alleluia,algorithms,albemarle,ajar,airlock,airbag,aims,aimless,ailments,agua,agonized,agitate,aggravating,affirming,aerosol,aerosmith,aeroplane,acing,accumulated,accomplishing,accolades,accidently,academia,abuser,abstain,abso,abnormally,aberration,abandons,aaww,aaaaahh,zlotys,zesty,zerzura,zapruder,zany,zantopia,yugoslavia,youo,yoru,yipe,yeow,yello,yelburton,yeess,yaah,y'knowwhati'msayin,wwhat,wussies,wrenched,would'a,worryin,wormser,wooooo,wookiee,wolfe's,wolchek,woes,wishin,wiseguys,winston's,winky,wine's,windbreaker,wiggy,wieners,wiedersehen,whoopin,whittled,whey,whet,wherefore,wharvey,welts,welt,wellstone,weee,wednesday's,wedges,wavered,watchit,wastebasket,ward's,wank,wango,wallet's,wall's,waken,waiver,waitressed,wacquiem,wabbit,vrykolaka,voula,vote's,volt,volga,volcanoes,vocals,vitally,visualizing,viscous,virgo,virg,violet's,viciousness,vewy,vespers,vertes,verily,vegetarians,vater,vaseline,varied,vaporize,vannacutt,vallens,valenti's,vacated,uterine,usta,ussher,urns,urinating,urchin,upping,upheld,unwitting,untreated,untangle,untamed,unsanitary,unraveled,unopened,unisex,uninvolved,uninteresting,unintelligible,unimaginative,undisclosed,undeserving,undermines,undergarments,unconcerned,unbroken,ukrainian,tyrants,typist,tykes,tybalt,twosome,twits,tutti,turndown,tularemia,tuberculoma,tsimshian,truffaut,truer,truant,trove,triumphed,tripe,trigonometry,trifled,trifecta,tricycle,trickle,tribulations,trevor's,tremont,tremoille,treaties,trawler,translators,transcends,trafficker,touchin,tonnage,tomfoolery,tolls,tokens,tinkered,tinfoil,tightrope,ticket's,thth,thousan,thoracotomy,theses,thesaurus,theologian,themed,thawing,thatta,thar,textiles,testimonies,tessio,terminating,temps,taxidermist,tator,tarkin,tangent,tactile,tachycardia,t'akaya,synthesize,symbolically,swelco,sweetbreads,swedes,swatting,swastika,swamps,suze,supernova,supercollider,sunbathing,summarily,suffocation,sueleen,succinct,subtitle,subsided,submissive,subjecting,subbing,subatomic,stupendous,stunted,stubble,stubbed,striving,streetwalker,strategizing,straining,straightaway,storyline,stoli,stock's,stipulated,stimulus,stiffer,stickup,stens,steamroller,steadwell,steadfast,stave,statutes,stateroom,stans,stacey's,sshhhh,squishing,squinting,squealed,sprouting,sprimp,spreadsheets,sprawled,spotlights,spooning,spoiler,spirals,spinner's,speedboat,spectacles,speakerphone,spar,spaniards,spacing,sovereignty,southglen,souse,soundproof,soothsayer,soon's,sommes,somethings,solidify,soars,snorted,snorkeling,snitches,sniping,sniper's,snifter,sniffin,snickering,sneer,snarl,smila,slinking,sleuth,slater's,slated,slanted,slanderous,slammin,skyscraper,skimp,skilosh,skeletal,skag,siteid,sirloin,singe,simulate,signaled,sighing,sidekicks,sicken,shrubs,shrub,showstopper,shot's,shostakovich,shoreline,shoppin,shoplifter,shop's,shoe's,shoal,shitter,shirt's,shimokawa,sherborne,sheds,shawna's,shavadai,sharpshooters,sharking,shane's,shakespearean,shagged,shaddup,sexism,sexes,sesterces,serotonin,sequences,sentient,sensuous,seminal,selections,seismic,seashell,seaplane,sealing,seahaven,seagrave,scuttled,scullery,scow,scots,scorcher,scorch,schotzie,schnoz,schmooze,schlep,schizo,schindler's,scents,scalping,scalped,scallop,scalding,sayeth,saybrooke,sawed,savoring,sardine,sandy's,sandstorm,sandalwood,samoa,samo,salutations,salad's,saki,sailor's,sagman,s'okay,rudy's,rsvp'd,royale,rousted,rootin,roofs,romper,romanovs,rollercoaster,rolfie,rockers,rock's,robinsons,ritzy,ritualistic,ringwald,rhymed,rheingold,rewrites,revolved,revolutionaries,revoking,reviewer,reverts,retrofit,retort,retinas,resurfaced,respirations,respectively,resolute,resin,reprobate,replaying,repayment,repaint,renquist,renege,renders,rename,remarked,relapsing,rekindled,rejuvenating,rejuvenated,reinstating,reinstatement,reigns,referendums,recriminations,recitals,rechecked,reception's,recaptured,rebounds,reassemble,rears,reamed,realty,reader's,reacquaint,rayanne,ravish,rava,rathole,raspail,rarest,rapists,rants,ramone,ragnar,radiating,radial,racketeer,quotation,quittin,quitters,quintessential,quincy's,queremos,quellek,quelle,quasimodo,quarterbacks,quarter's,pyromaniac,puttanesca,puritanical,purged,purer,puree,punishments,pungent,pummel,puedo,pudge,puce,psychotherapist,psycho's,prosecutorial,prosciutto,propositioning,propellers,pronouns,progresses,procured,procrastination,processes,probationary,primping,primates,priest's,preventative,prevails,presided,preserves,preservatives,prefix,predecessors,preachy,prancer,praetorians,practicality,powders,potus,pot's,postop,positives,poser,portolano,portokalos,poolside,poltergeists,pocketed,poach,plunder,plummeted,plucking,plop,plimpton,plethora,playthings,player's,playboys,plastique,plainclothes,pious,pinpointed,pinkus,pinks,pilgrimage,pigskin,piffle,pictionary,piccata,photocopy,phobias,persia,permissible,perils,perignon,perfumes,peon,penned,penalized,peg's,pecks,pecked,paving,patriarch,patents,patently,passable,participants,parasitic,parasailing,paramus,paramilitary,parabolic,parable,papier,paperback,paintbrush,pacer,paaiint,oxen,owen's,overtures,overthink,overstayed,overrule,overlapping,overestimate,overcooked,outlandish,outgrew,outdoorsy,outdo,outbound,ostensibly,originating,orchestrate,orally,oppress,opposable,opponent's,operation's,oooohh,oomupwah,omitted,okeydokey,okaaay,ohashi,offerings,of'em,od'd,occurrences,occupant,observable,obscenities,obligatory,oakie,o'malley's,o'gar,nyah's,nurection,nun's,nougat,nostradamus,norther,norcom,nooch,nonviolent,nonsensical,nominating,nomadic,noel's,nkay,nipped,nimbala,nigeria,nigel's,nicklaus,newscast,nervously,nell's,nehru,neckline,nebbleman,navigator,nasdaq,narwhal,nametag,n'n't,mycenae,myanmar,muzak,muumuu,murderer's,mumbled,mulvehill,multiplication,multiples,muggings,muffet,mozart's,mouthy,motorbike,motivations,motivates,motaba,mortars,mordred,mops,moocher,moniker,mongi,mondo,monday's,moley,molds,moisturize,mohair,mocky,mmkay,mistuh,missis,mission's,misdeeds,minuscule,minty,mined,mincemeat,milton's,milt,millennia,mikes,miggs,miffed,mieke's,midwestern,methadone,metaphysics,messieur,merging,mergers,menopausal,menagerie,meee,mckenna's,mcgillicuddy,mayflowers,maxim's,matrimonial,matisse,matick,masculinity,mascots,masai,marzipan,marika,maplewood,manzelle,manufactures,manticore's,mannequins,manhole,manhandle,manatee,mallory's,malfunctions,mainline,magua's,madwoman,madeline's,machiavelli,lynley,lynching,lynched,lurconis,lujack,lubricant,looove,loons,loom,loofah,longevity,lonelyhearts,lollipops,loca,llama,liquidation,lineswoman,lindsey's,lindbergh,lilith's,lila's,lifers,lichen,liberty's,lias,lexter,levee,letter's,lessen,lepner,leonard's,lemony,leggy,leafy,leaflets,leadeth,lazerus,lazare,lawford,languishing,langford's,landslide,landlords,lagoda,ladman,lad's,kuwait,kundera,krist's,krinkle,krendler,kreigel,kowolski,kosovo,knockdown,knifed,kneed,kneecap,kids'll,kevlar,kennie,keeled,kazootie,kaufman's,katzenmoyer,kasdan,karl's,karak,kapowski,kakistos,jumpers,julyan,juanito,jockstrap,jobless,jiggly,jesuit,jaunt,jarring,jabbering,israelites,irrigate,irrevocably,irrationally,ironies,ions,invitro,inventions,intrigues,intimated,interview's,intervening,interchangeable,intently,intentioned,intelligently,insulated,institutional,instill,instigator,instigated,instep,inopportune,innuendoes,inheriting,inflate,infiltration,infects,infamy,inducing,indiscretions,indiscreet,indio,indignities,indict,indecision,incurred,incubation,inconspicuous,inappropriately,impunity,impudent,improves,impotence,implicates,implausible,imperfection,impatience,immutable,immobilize,illustration,illumination,idiot's,idealized,idealist,icelandic,iambic,hysterically,hyperspace,hygienist,hydraulics,hydrated,huzzah,husks,hurricane's,hunt's,hunched,huffed,hubris,hubbub,hovercraft,houngan,hotel's,hosed,horoscopes,hoppy,hopelessness,hoodwinked,honourable,honorably,honeysuckle,homeowners,homegirl,holiest,hoisted,hoho,ho's,hippity,hildie,hikers,hieroglyphs,hexton,herein,helicopter's,heckle,heats,heartbeat's,heaping,healthilizer,headmaster's,headfirst,hawk's,haviland's,hatsue,harlot,hardwired,hanno's,hams,hamilton's,halothane,hairstyles,hails,hailed,haagen,haaaaa,gyno,gutting,gurl,gumshoe,gummi,gull,guerilla,gttk,grover's,grouping,groundless,groaning,gristle,grills,graynamore,grassy,graham's,grabbin,governmental,goodes,goggle,godlike,glittering,glint,gliding,gleaming,glassy,girth,gimbal,gilmore's,gibson's,giblets,gert,geometric,geographical,genealogy,gellers,geller's,geezers,geeze,garshaw,gargantuan,garfunkel,gardner's,garcia's,garb,gangway,gandarium,gamut,galoshes,gallivanting,galleries,gainfully,gack,gachnar,fusionlips,fusilli,furiously,fulfil,fugu,frugal,fron,friendship's,fricking,frederika,freckling,frauds,fraternal,fountainhead,forthwith,forgo,forgettable,foresight,foresaw,footnotes,fondling,fondled,fondle,folksy,fluttering,flutie,fluffing,floundering,florin,florentine,flirtatious,flexing,flatterer,flaring,fizz,fixating,five's,fishnet,firs,firestorm,finchy,figurehead,fifths,fiendish,fertilize,ferment,fending,fellahs,feeny's,feelers,feeders,fatality,fascinate,fantabulous,falsify,fallopian,faithless,fairy's,fairer,fair's,fainter,failings,facto,facets,facetious,eyepatch,exxon,extraterrestrials,extradite,extracurriculars,extinguish,expunged,exports,expenditure,expelling,exorbitant,exigent,exhilarated,exertion,exerting,exemption,excursions,excludes,excessively,excercise,exceeds,exceeding,everbody,evaporated,euthanasia,euros,europeans,escargot,escapee,erases,epizootics,epithelials,ephrum,enthusiast,entanglements,enslaved,enslave,engrossed,endeavour,enables,enabled,empowerment,employer's,emphatic,emeralds,embroiled,embraces,ember,embellished,emancipated,ello,elisa's,elevates,ejaculate,ego's,effeminate,economically,eccentricities,easygoing,earshot,durp,dunks,dunes,dullness,dulli,dulled,drumstick,dropper,driftwood,dregs,dreck,dreamboat,draggin,downsizing,dost,doofer,donowitz,dominoes,dominance,doe's,diversions,distinctions,distillery,distended,dissolving,dissipate,disraeli,disqualify,disowned,dishwashing,discusses,discontent,disclosed,disciplining,discerning,disappoints,dinged,diluted,digested,dicking,diablos,deux,detonating,destinations,despising,designer's,deserts,derelict,depressor,depose,deport,dents,demonstrations,deliberations,defused,deflection,deflecting,decryption,decoys,decoupage,decompress,decibel,decadence,dealer's,deafening,deadlock,dawning,dater,darkened,darcy's,dappy,dancing's,damon's,dallying,dagon,d'etat,czechoslovakians,cuticles,cuteness,curacao,cupboards,cumulative,culottes,culmination,culminating,csi's,cruisin,crosshairs,cronyn,croc,criminalistics,crimean,creatively,creaming,crapping,cranny,cowed,countermeasures,corsica,corinne's,corey's,cooker,convened,contradicting,continuity,constitutionally,constipation,consort,consolidate,consisted,connection's,confining,confidences,confessor,confederates,condensation,concluding,conceiving,conceivably,concealment,compulsively,complainin,complacent,compiling,compels,communing,commonplace,commode,commission's,commissary,comming,commensurate,columnists,colonoscopy,colonists,collagen,collaborate,colchicine,coddling,clump,clubbed,clowning,closet's,clones,clinton's,clinic's,cliffhanger,classification,clang,citrus,cissy,circuitry,chronology,christophe,choosers,choker,chloride,chippewa,chip's,chiffon,chesty,chesapeake,chernobyl,chants,channeled,champagne's,chalet,chaka,cervical,cellphone,cellmates,caverns,catwalk,cathartic,catcher's,cassandra's,caseload,carpenter's,carolyn's,carnivorous,carjack,carbohydrates,capt,capitalists,canvass,cantonese,canisters,candlestick,candlelit,canaries,camry,camel's,calzones,calitri,caldy,cabin's,byline,butterball,bustier,burmese,burlap,burgeoning,bureaucrat,buffoons,buenas,bryan's,brookline,bronzed,broiled,broda,briss,brioche,briar,breathable,brea,brays,brassieres,braille,brahms,braddock's,boysenberry,bowman's,bowline,boutiques,botticelli's,boooo,boonies,booklets,bookish,boogeyman,boogey,bomb's,boldly,bogs,bogas,boardinghouse,bluuch,blundering,bluffs,bluer,blowed,blotto,blotchy,blossomed,blooms,bloodwork,bloodied,blithering,blinks,blathering,blasphemous,blacking,bison,birdson,bings,bilateral,bfmid,bfast,berserker,berkshires,bequest,benjamins,benevolence,benched,benatar,belthazor's,bellybutton,belabor,bela's,behooves,beddy,beaujolais,beattle,baxworth,batted,baseless,baring,barfing,barbi,bannish,bankrolled,banek,ballsy,ballpoint,balkans,balconies,bakers,bahama,baffling,badder,badda,bada,bactine,backgammon,baako,aztreonam,aztecs,awed,avon,autobiographical,autistic,authoritah,auspicious,august's,auditing,audible,auctioning,attitude's,atrocities,athlete's,astronomer,assessed,ascot,aristocratic,arid,argues,arachtoids,arachnid,aquaman,apropos,aprons,apprised,apprehensive,apex,anythng,antivenin,antichrist,antennae,anorexic,anoint,annum,annihilated,animal's,anguished,angioplasty,angio,amply,ampicillin,amphetamines,amino,american's,ambiguity,ambient,amarillo,alyssa's,alternator,alcove,albacore,alarm's,alabaster,airlifted,ahta,agrabah,affidavits,advocacy,advises,adversely,admonished,admonish,adler's,addled,addendum,acknowledgement,accuser,accompli,acclaim,acceleration,abut,abundant,absurdity,absolved,abrusso,abreast,abrasive,aboot,abductions,abducting,abbots,aback,ababwa,aand,aaahhhh,zorin,zinthar,zinfandel,zimbabwe,zillions,zephyrs,zatarcs,zacks,youuu,youths,yokels,yech,yardstick,yammer,y'understand,wynette,wrung,wrought,wreaths,wowed,wouldn'ta,worshiped,worming,wormed,workday,wops,woolly,wooh,woodsy,woodshed,woodchuck,wojadubakowski,withering,witching,wiseass,wiretaps,winner's,wining,willoby,wiccaning,whupped,whoopi,whoomp,wholesaler,whiteness,whiner,whatchya,wharves,whah,wetlands,westward,wenus,weirdoes,weds,webs,weaver's,wearer,weaning,watusi,wastes,warlock's,warfield's,waponi,waiting's,waistband,waht,wackos,vouching,votre,voight's,voiced,vivica,viveca,vivant,vivacious,visor,visitin,visage,virgil's,violins,vinny,vinci's,villas,vigor,video's,vicrum,vibrator,vetted,versailles,vernon's,venues,ventriloquism,venison,venerable,varnsen,variant,variance,vaporized,vapid,vanstock,vandals,vader's,vaccination,uuuuh,utilize,ushering,usda,usable,urur,urologist,urination,urinary,upstart,uprooted,unsubtitled,unspoiled,unseat,unseasonably,unseal,unsatisfying,unnerve,unlikable,unleaded,university's,universe's,uninsured,uninspired,uniformity,unicycle,unhooked,ungh,unfunny,unfreezing,unflattering,unfairness,unexpressed,unending,unencumbered,unearth,undiscovered,undisciplined,undertaken,understan,undershirt,underlings,underline,undercurrent,uncontrolled,uncivilized,uncharacteristic,umpteenth,uglies,u're,tut's,turner's,turbine,tunnel's,tuney,trustee,trumps,truckasaurus,trubshaw,trouser,trippy,tringle,trifling,trickster,triangular,trespassers,trespasser,traverse,traumas,trattoria,trashes,transgressions,tranquil,trampling,trainees,tracy's,tp'ed,toxoplasmosis,tounge,tortillas,torrent,torpedoed,topsy,topple,topnotch,top's,tonsil,tippin's,tions,timmuh,timithious,tilney,tighty,tightness,tightens,tidbits,ticketed,thyme,thrones,threepio,thoughtfully,thornhart's,thorkel,thommo,thing'll,theological,thel,theh,thefts,that've,thanksgivings,tetherball,testikov,terraforming,terminus,tepid,tendonitis,tenboom,telex,teleport,telepathic,teenybopper,taxicab,taxed,taut,tattered,tattaglias,tapered,tantric,tanneke,takedown,tailspin,tacs,tacit,tablet,tablecloth,systemic,syria,syphon,synthesis,symbiotic,swooping,swizzle,swiping,swindled,swilling,swerving,sweatshops,swayzak's,swaddling,swackhammer,svetkoff,suzie's,surpass,supossed,superdad,super's,sumptuous,sula,suit's,sugary,sugar's,sugai,suey,subvert,suburb,substantiate,subsidy,submersible,sublimating,subjugation,styx,stymied,stuntman,studded,strychnine,strikingly,strenuous,streetlights,strassmans,stranglehold,strangeness,straddling,straddle,stowaways,stotch,stockbrokers,stifling,stepford,stepdad's,steerage,steena,staunch,statuary,starlets,stanza,stanley's,stagnant,staggeringly,ssshhh,squaw,spurt,spungeon,sprightly,sprays,sportswear,spoonful,splittin,splitsville,spirituality,spiny,spider's,speedily,speculative,specialise,spatial,spastic,spas,sparrin,soybean,souvlaki,southie,southampton,sourpuss,soupy,soup's,soundstage,sophie's,soothes,somebody'd,solicited,softest,sociopathic,socialized,socialism,snyders,snowmobiles,snowballed,snatches,smugness,smoothest,smashes,slurp,slur,sloshed,sleight,skyrocket,skied,skewed,sizeable,sixpence,sipowicz,singling,simulations,simulates,similarly,silvery,silverstone,siesta,siempre,sidewinder,shyness,shuvanis,showoff,shortsighted,shopkeeper,shoehorn,shithouse,shirtless,shipshape,shingles,shifu,shes,sherman's,shelve,shelbyville,sheepskin,shat,sharpens,shaquille,shaq,shanshu,shania's,set's,servings,serpico,sequined,sensibilities,seizes,seesaw,seep,seconded,sebastian's,seashells,scrapped,scrambler,scorpions,scopes,schnauzer,schmo,schizoid,scampered,scag,savagely,saudis,satire,santas,sanskrit,sandovals,sanding,sandal,salient,saleswoman,sagging,s'cuse,rutting,ruthlessly,runoff,runneth,rulers,ruffians,rubes,roughriders,rotates,rotated,roswell's,rosalita,rookies,ron's,rollerblades,rohypnol,rogues,robinson's,roasts,roadies,river's,ritten,rippling,ripples,ring's,rigor,rigoletto,richardo,ribbed,revolutions,revlon's,reverend's,retreating,retractable,rethought,retaliated,retailers,reshoot,reserving,reseda,researchers,rescuer,reread,requisitions,repute,reprogram,representations,report's,replenish,repetitive,repetitious,repentance,reorganizing,renton,renee's,remodeled,religiously,relics,reinventing,reinvented,reheat,rehabilitate,registrar,regeneration,refueling,refrigerators,refining,reenter,redress,recruiter,recliner,reciprocal,reappears,razors,rawdy,rashes,rarity,ranging,rajeski,raison,raisers,rainier,ragtime,rages,radar's,quinine,questscape,queller,quartermaine's,pyre,pygmalion,pushers,pusan,purview,purification,pumpin,puller,pubescent,psychiatrist's,prudes,provolone,protestants,prospero,propriety,propped,prom's,procrastinate,processors,processional,princely,preyed,preventive,pretrial,preside,premiums,preface,preachers,pounder,ports,portrays,portrayal,portent,populations,poorest,pooling,poofy,pontoon,pompeii,polymerization,polloi,policia,poacher,pluses,pleasuring,pleads,playgrounds,platitudes,platforms,plateaued,plate's,plantations,plaguing,pittance,pitcher's,pinky's,pinheads,pincushion,pimply,pimped,piggyback,pierce's,piecing,physiological,physician's,phosphate,phillipe,philipse,philby,phased,pharaohs,petyr,petitioner,peshtigo,pesaram,perspectives,persnickety,perpetrate,percolating,pepto,pensions,penne,penell,pemmican,peeks,pedaling,peacemaker,pawnshop,patting,pathologically,patchouli,pasts,pasties,passin,parlors,panda's,panache,paltrow,palamon,padlock,paddy's,paddling,oversleep,overheating,overdosed,overcharge,overcame,overblown,outset,outrageously,outfitted,orsini's,ornery,origami,orgasmic,orga,order's,opportune,ooow,oooooooooh,oohhhh,olympian,olfactory,okum,ohhhhhh,ogres,odysseus,odorless,occupations,occupancy,obscenity,obliterated,nyong,nymphomaniac,nutsack,numa,ntozake,novocain,nough,noth,nosh,norwegians,northstar,nonnie,nonissue,nodules,nightmarish,nightline,nighthawk,niggas,nicu,nicolae,nicknamed,niceties,newsman,neverland,negatively,needra,nedry,necking,navour,nauseam,nauls,narim,nanda,namath,nagged,nads,naboo,n'sync,mythological,mysticism,myslexia,mutator,mustafi,mussels,muskie,musketeer,murtaugh,murderess,murder's,murals,munching,mumsy,muley,mouseville,mosque,mosh,mortifying,morgendorffers,moola,montel,mongoloid,molten,molestered,moldings,mocarbies,mo'ss,mixers,misrell,misnomer,misheard,mishandled,miscreant,misconceptions,miniscule,minimalist,millie's,millgate,migrate,michelangelo's,mettle,metricconverter,methodology,meter's,meteors,mesozoic,menorah,mengele,mendy's,membranes,melding,meanness,mcneil's,mcgruff,mcarnold,matzoh,matted,mathematically,materialized,mated,masterpieces,mastectomy,massager,masons,marveling,marta's,marquee,marooned,marone's,marmaduke,marick,marcie's,manhandled,mangoes,manatees,managerial,man'll,maltin,maliciously,malfeasance,malahide,maketh,makeshift,makeovers,maiming,magazine's,machismo,maarten,lutheran,lumpectomy,lumbering,luigi's,luge,lubrication,lording,lorca,lookouts,loogie,loners,london's,loin,lodgings,locomotive,lobes,loathed,lissen,linus,lighthearted,ligament,lifetime's,lifer,lier,lido,lickin,lewen,levitation,lestercorp,lessee,lentils,lena's,lemur,lein,legislate,legalizing,lederhosen,lawmen,laundry's,lasskopf,lardner,landscapes,landfall,lambeau,lamagra,lagging,ladonn,lactic,lacquer,laborers,labatier,kwan's,krit,krabappel,kpxy,kooks,knobby,knickknacks,klutzy,kleynach,klendathu,kinross,kinko's,kinkaid,kind'a,kimberly's,kilometer,khruschev's,khaki,keyboards,kewl,ketch,kesher,ken's,karikos,karenina,kanamits,junshi,juno's,jumbled,jujitsu,judith's,jt's,joust,journeyed,jotted,jonathan's,jizz,jingling,jigalong,jerseys,jerries,jellybean,jellies,jeeps,jeannie's,javna,jamestown,james's,jamboree,jail's,islanders,irresistable,irene's,ious,investigation's,investigates,invaders,inundated,introductory,interviewer,interrupts,interpreting,interplanetary,internist,intercranial,inspections,inspecting,inseminated,inquisitor,inland,infused,infuriate,influx,inflating,infidelities,inference,inexpensive,industrialist,incessantly,inception,incensed,incase,incapacitate,inca,inasmuch,inaccuracies,imus,improvised,imploding,impeding,impediments,immaturity,ills,illegible,idols,iditarod,identifiable,id'n,icicles,ibuprofen,i'i'm,hymie,hydrolase,hybrids,hunsecker's,hunker,humps,humons,humidor,humdinger,humbling,humankind,huggin,huffing,households,housecleaning,hothouse,hotcakes,hosty,hootenanny,hootchie,hoosegow,honouring,honks,honeymooners,homophobic,homily,homeopathic,hoffman's,hnnn,hitchhikers,hissed,hispanics,hillnigger,hexavalent,hewwo,heston's,hershe,herodotus,hermey,hergott,heresy,henny,hennigans,henhouse,hemolytic,hells,helipad,heifer,hebrews,hebbing,heaved,heartland,heah,headlock,hatchback,harvard's,harrowing,harnessed,harding's,happy's,hannibal's,hangovers,handi,handbasket,handbags,halloween's,hall's,halfrek,halfback,hagrid,hacene,gyges,guys're,gut's,gundersons,gumption,guardia,gruntmaster,grubs,group's,grouch,grossie,grosser,groped,grins,grime,grigio,griff's,greaseball,gravesite,gratuity,graphite,granma,grandfathers,grandbaby,gradski,gracing,got's,gossips,goonie,gooble,goobers,goners,golitsyn,gofer,godsake,goddaughter,gnats,gluing,glub,global's,glares,gizmos,givers,ginza,gimmie,gimmee,georgia's,gennero,gazpacho,gazed,gato,gated,gassy,gargling,gandhiji,galvanized,gallery's,gallbladder,gabriel's,gaaah,furtive,furthering,fungal,fumigation,fudd,fucka,fronkonsteen,fromby's,frills,fresher,freezin,freewald,freeloader,franklin's,framework,frailty,fortified,forger,forestry,foreclosure,forbade,foray,football's,foolhardy,fondest,fomin,followin,follower,follicle,flue,flowering,flotation,flopping,floodgates,flogged,flog,flicked,flenders,fleabag,flanks,fixings,fixable,fistful,firewater,firestarter,firelight,fingerbang,finalizing,fillin,filipov,fido,fiderer,feminists,felling,feldberg,feign,favorably,fave,faunia,faun,fatale,fasting,farkus,fared,fallible,faithfulness,factoring,facilitated,fable,eyeful,extramarital,extracts,extinguished,exterminated,exposes,exporter,exponential,exhumed,exhume,exasperated,eviscerate,evidenced,evanston,estoy,estimating,esmerelda,esme,escapades,erosion,erie,equitable,epsom,epoxy,enticed,enthused,entendre,ensued,enhances,engulfed,engrossing,engraving,endorphins,enamel,emptive,empirical,emmys,emission,eminently,embody,embezzler,embarressed,embarrassingly,embalmed,emancipation,eludes,eling,elevation,electorate,elated,eirie,egotitis,effecting,eerily,eeew,eecom,editorials,edict,eczema,ecumenical,ecklie's,earthy,earlobes,eally,dyeing,dwells,dvds,duvet,duncans,dulcet,duckling,droves,droppin,drools,drey'auc,dreamers,dowser's,downriver,downgraded,doping,doodie,dominicans,dominating,domesticity,dollop,doesnt,doer,dobler,divulged,divisional,diversionary,distancing,dissolves,dissipated,displaying,dispensers,dispensation,disorienting,disneyworld,dismissive,dismantling,disingenuous,disheveled,disfiguring,discourse,discontinued,disallowed,dinning,dimming,diminutive,diligently,dilettante,dilation,diggity,diggers,dickensian,diaphragms,diagnoses,dewy,developer,devastatingly,determining,destabilize,desecrate,derives,deposing,denzel,denouncing,denominations,denominational,deniece,demony,delving,delt,delicates,deigned,degrassi's,degeneration,defraud,deflower,defibrillator,defiantly,deferred,defenceless,defacing,dedicating,deconstruction,decompose,deciphering,decibels,deceptively,deceptions,decapitation,debutantes,debonair,deadlier,dawdling,davic,databases,darwinism,darnit,darks,danke,danieljackson,dangled,daimler,cytoxan,cylinders,cutout,cutlery,cuss,cushing's,curveball,curiously,curfews,cummerbund,cuckoo's,crunches,crucifixion,crouched,croix,criterion,crisps,cripples,crilly,cribs,crewman,cretaceous,creepin,creeds,credenza,creak,crawly,crawlin,crawlers,crated,crasher,crackheads,coworker,counterpart,councillor,coun,couldn't've,cots,costanza's,cosgrove's,corwins,corset,correspondents,coriander,copiously,convenes,contraceptives,continuously,contingencies,contaminating,consul,constantinople,conniption,connie's,conk,conjugate,condiment,concurrently,concocting,conclave,concert's,con's,comprehending,compliant,complacency,compilation,competitiveness,commendatore,comedies,comedians,comebacks,combines,com'on,colonized,colonization,collided,collectively,collarbone,collaborating,collaborated,colitis,coldly,coiffure,coffers,coeds,codependent,cocksucking,cockney,cockles,clutched,cluett's,cloverleaf,closeted,cloistered,clinched,clicker,cleve,clergyman,cleats,clarifying,clapped,citations,cinnabar,cinco,chunnel,chumps,chucks,christof,cholinesterase,choirboy,chocolatey,chlamydia,chili's,chigliak,cheesie,cheeses,chechnya,chauvinistic,chasm,chartreuse,charnier,chapil,chapel's,chalked,chadway,cerveza,cerulean,certifiably,celsius,cellulite,celled,ceiling's,cavalry's,cavalcade,catty,caters,cataloging,casy,castrated,cassio,cashman's,cashews,carwash,cartouche,carnivore,carcinogens,carasco's,carano's,capulet,captives,captivated,capt'n,capsized,canoes,cannes,candidate's,cancellations,camshaft,campin,callate,callar,calendar's,calculators,cair,caffeinated,cadavers,cacophony,cackle,byproduct,bwana,buzzes,buyout,buttoning,busload,burglaries,burbs,bura,buona,bunions,bungalows,bundles,bunches,bullheaded,buffs,bucyk,buckling,bruschetta,browbeating,broomsticks,broody,bromly,brolin,brigadier,briefings,bridgeport,brewskies,breathalyzer,breakups,breadth,bratwurst,brania,branching,braiding,brags,braggin,bradywood,bozo's,bottomed,bottom's,bottling,botany,boston's,bossa,bordello,booo,bookshelf,boogida,bondsman,bolsheviks,bolder,boggles,boarder,boar's,bludgeoned,blowtorch,blotter,blips,blends,blemish,bleaching,blainetologists,blading,blabbermouth,bismarck,bishops,biscayne,birdseed,birdcage,bionic,biographies,biographical,bimmel,biloxi,biggly,bianchinni,bette's,betadine,berg's,berenson,belus,belt's,belly's,belloq,bella's,belfast,behavior's,begets,befitting,beethoven's,beepers,beelzebub,beefed,bedroom's,bedrock,bedridden,bedevere,beckons,beckett's,beauty's,beaded,baubles,bauble,battlestar,battleground,battle's,bathrobes,basketballs,basements,barroom,barnacle,barkin,barked,barium,baretta,bangles,bangler,banality,bambang,baltar,ballplayers,baio,bahrain,bagman,baffles,backstroke,backroom,bachelor's,babysat,babylonian,baboons,aviv,avez,averse,availability,augmentation,auditory,auditor,audiotape,auctioneer,atten,attained,attackers,atcha,astonishment,asshole's,assembler,arugula,arsonist's,arroz,arigato,arif,ardent,archaic,approximation,approving,appointing,apartheid,antihistamines,antarctica,annoyances,annals,annabelle's,angrily,angelou,angelo's,anesthesiology,android,anatomically,anarchists,analyse,anachronism,amiable,amex,ambivalent,amassed,amaretto,alumnus,alternating,alternates,alteration,aloft,alluding,allen's,allahu,alight,alfred's,alfie,airlift,aimin,ailment,aground,agile,ageing,afterglow,africans,affronte,affectionately,aerobic,adviser,advil,adventist,advancements,adrenals,admiral's,administrators,adjutant,adherence,adequately,additives,additions,adapting,adaptable,actualization,activating,acrost,ached,accursed,accoutrements,absconded,aboveboard,abou,abetted,abbot's,abbey's,aargh,aaaahh,zuzu's,zuwicky,zolda,zits,ziploc,zakamatak,yutz,yumm,youve,yolk,yippie,yields,yiddish,yesterdays,yella,yearns,yearnings,yearned,yawning,yalta,yahtzee,yacht's,y'mean,y'are,xand,wuthering,wreaks,woul,worsened,worrisome,workstation,workiiing,worcestershire,woop,wooooooo,wooded,wonky,womanizing,wolodarsky,wnkw,wnat,wiwith,withdraws,wishy,wisht,wipers,wiper,winos,winery,windthorne,windsurfing,windermere,wiggles,wiggled,wiggen,whys,whwhat,whuh,whos,whore's,whodunit,whoaaa,whittling,whitesnake,whirling,whereof,wheezing,wheeze,whatley's,whatd'ya,whataya,whammo,whackin,wets,westbound,wellll,wellesley,welch's,weirdo's,weightless,weevil,wedgies,webbing,weasly,weapon's,wean,wayside,waxes,wavelengths,waturi,washy,washrooms,warton's,wandell,wakeup,waitaminute,waddya,wabash,waaaah,vornac,voir,voicing,vocational,vocalist,vixens,vishnoor,viscount,virulent,virtuoso,vindictiveness,vinceres,vince's,villier,viii,vigeous,viennese,viceroy,vestigial,vernacular,venza's,ventilate,vented,venereal,vell,vegetative,veering,veered,veddy,vaslova,valosky,vailsburg,vaginas,vagas,vacation's,uuml,urethra,upstaged,uploading,upgrades,unwrapping,unwieldy,untenable,untapped,unsatisfied,unsatisfactory,unquenchable,unnerved,unmentionable,unlovable,unknowns,universes,uninformed,unimpressed,unhappily,unguarded,unexplored,underpass,undergarment,underdeveloped,undeniably,uncompromising,unclench,unclaimed,uncharacteristically,unbuttoned,unblemished,unas,umpa,ululd,uhhhm,tweeze,tutsami,tusk,tushy,tuscarora,turkle,turghan,turbulent,turbinium,tuffy,tubers,tsun,trucoat,troxa,trou,tropicana,triquetra,tripled,trimmers,triceps,tribeca,trespassed,traya,travellers,traumatizing,transvestites,transatlantic,tran's,trainors,tradin,trackers,townies,tourelles,toughness,toucha,totals,totalled,tossin,tortious,topshop,topes,tonics,tongs,tomsk,tomorrows,toiling,toddle,tobs,tizzy,tiramisu,tippers,timmi,timbre,thwap,thusly,ththe,thruway,thrusts,throwers,throwed,throughway,thrice,thomas's,thickening,thia,thermonuclear,therapy's,thelwall,thataway,th's,textile,texans,terry's,terrifically,tenets,tendons,tendon,telescopic,teleportation,telepathically,telekinetic,teetering,teaspoons,teamsters,taunts,tatoo,tarantulas,tapas,tanzania,tanned,tank's,tangling,tangerine,tamales,tallied,tailors,tai's,tahitian,tag's,tactful,tackles,tachy,tablespoon,tableau,syrah,syne,synchronicity,synch,synaptic,synapses,swooning,switchman,swimsuits,swimmer's,sweltering,swelling's,sweetly,sweeper,suvolte,suss,suslov,surname,surfed,supremacy,supposition,suppertime,supervillains,superman's,superfluous,superego,sunspots,sunnydale's,sunny's,sunning,sunless,sundress,sump,suki,suffolk,sue's,suckah,succotash,substation,subscriptions,submarines,sublevel,subbasement,styled,studious,studio's,striping,stresses,strenuously,streamlined,strains,straights,stony,stonewalled,stonehenge,stomper,stipulates,stinging,stimulated,stillness,stilettos,stewards,stevesy,steno,sten,stemmed,steenwyck,statesmen,statehood,stargates,standstill,stammering,staedert,squiggly,squiggle,squashing,squaring,spurred,sprints,spreadsheet,spramp,spotters,sporto,spooking,sponsorship,splendido,spittin,spirulina,spiky,speculations,spectral,spate,spartacus,spans,spacerun,sown,southbound,sorr,sorcery,soonest,sono,sondheim,something'll,someth,somepin,someone'll,solicitor,sofas,sodomy,sobs,soberly,sobered,soared,soapy,snowmen,snowbank,snowballing,snorkel,snivelling,sniffling,snakeskin,snagging,smush,smooter,smidgen,smackers,smackdown,slumlord,slugging,slossum,slimmer,slighted,sleepwalk,sleazeball,skokie,skirmishes,skipper's,skeptic,sitka,sitarides,sistah,sipped,sindell,simpletons,simp,simony,simba's,silkwood,silks,silken,silicone,sightless,sideboard,shuttles,shrugging,shrouds,showy,shoveled,shouldn'ta,shoplifters,shitstorm,shipyard,shielded,sheldon's,sheeny,shaven,shapetype,shankar,shaming,shallows,shale,shading,shackle,shabbily,shabbas,severus,settlements,seppuku,senility,semite,semiautomatic,semester's,selznick,secretarial,sebacio,sear,seamless,scuzzy,scummy,scud,scrutinized,scrunchie,scriptures,scribbled,scouted,scotches,scolded,scissor,schooner,schmidt's,schlub,scavenging,scarin,scarfing,scarecrow's,scant,scallions,scald,scabby,say's,savour,savored,sarcoidosis,sandbar,saluted,salted,salish,saith,sailboats,sagittarius,sagan,safeguards,sacre,saccharine,sacamano,sabe,rushdie,rumpled,rumba,rulebook,rubbers,roughage,rotterdam,roto,rotisserie,rosebuds,rootie,roosters,roosevelt's,rooney's,roofy,roofie,romanticize,roma's,rolodex,rolf's,roland's,rodney's,robotic,robin's,rittle,ristorante,rippin,rioting,rinsing,ringin,rincess,rickety,rewritten,revising,reveling,rety,retreats,retest,retaliating,resumed,restructuring,restrict,restorative,reston,restaurateur,residences,reshoots,resetting,resentments,rescuers,rerouted,reprogramming,reprisals,reprisal,repossess,repartee,renzo,renfield,remore,remitting,remeber,reliability,relaxants,rejuvenate,rejections,rehu,regularity,registrar's,regionals,regimes,regenerated,regency,refocus,referrals,reeno,reelected,redevelopment,recycles,recrimination,recombinant,reclining,recanting,recalling,reattach,reassigning,realises,reactors,reactionary,rbis,razor's,razgul,raved,rattlesnakes,rattles,rashly,raquetball,rappers,rapido,ransack,rankings,rajah,raisinettes,raheem,radisson,radishes,radically,radiance,rabbi's,raban,quoth,qumari,quints,quilts,quilting,quien,queue,quarreled,qualifying,pygmy,purty,puritans,purblind,puppy's,punctuation,punchbowl,puget,publically,psychotics,psychopaths,psychoanalyze,pruning,provasik,protruding,protracted,protons,protections,protectin,prospector,prosecutor's,propping,proportioned,prophylactic,propelled,proofed,prompting,prompter,professed,procreate,proclivities,prioritizing,prinze,princess's,pricked,press'll,presets,prescribes,preocupe,prejudicial,prefex,preconceived,precipice,preamble,pram,pralines,pragmatist,powering,powerbar,pottie,pottersville,potsie,potholes,potency,posses,posner's,posies,portkey,porterhouse,pornographers,poring,poppycock,poppet,poppers,poopsie,pomponi,pokin,poitier,poes,podiatry,plush,pleeze,pleadings,playbook,platelets,plane'arium,placebos,place'll,pj's,pixels,pitted,pistachios,pisa,pirated,pirate's,pinochle,pineapples,pinafore,pimples,piggly,piggies,pie's,piddling,picon,pickpockets,picchu,physiologically,physic,photo's,phobic,philosophies,philosophers,philly's,philandering,phenomenally,pheasants,phasing,phantoms,pewter,petticoat,petronis,petitioning,perturbed,perth,persists,persians,perpetuating,permutat,perishable,periphery,perimeters,perfumed,percocet,per'sus,pepperjack,pensioners,penalize,pelting,pellet,peignoir,pedicures,pedestrians,peckers,pecans,payback's,pay's,pawning,paulsson,pattycake,patrolmen,patrolled,patois,pathos,pasted,passer,partnerships,parp,parishioners,parishioner,parcheesi,parachuting,pappa,paperclip,papayas,paolo's,pantheon,pantaloons,panhandle,pampers,palpitations,paler,palantine,paintballing,pago,owow,overtired,overstress,oversensitive,overnights,overexcited,overanxious,overachiever,outwitted,outvoted,outnumber,outlived,outlined,outlast,outlander,outfield,out've,ortolani's,orphey,ornate,ornamental,orienteering,orchestrating,orator,oppressive,operator's,openers,opec,ooky,oliver's,olde,okies,okee,ohhhhhhhhh,ohhhhhhhh,ogling,offline,offbeat,oceanographic,obsessively,obeyed,oaths,o'leary's,o'hana,o'bannon,o'bannion,numpce,nummy,nuked,nuff,nuances,nourishing,noticeably,notably,nosedive,northeastern,norbu,nomlies,nomine,nomads,noge,nixed,niro,nihilist,nightshift,newmeat,nevis,nemo's,neighborhood's,neglectful,neediness,needin,necromancer,neck's,ncic,nathaniel's,nashua,naphthalene,nanotechnology,nanocytes,nanite,naivete,nacho,n'yeah,mystifying,myhnegon,mutating,muskrat,musing,museum's,muppets,mumbles,mulled,muggy,muerto,muckraker,muchachos,mris,move's,mourners,mountainside,moulin,mould,motherless,motherfuck,mosquitos,morphed,mopped,moodoo,montage,monsignor,moncho,monarchs,mollem,moisturiser,moil,mohicans,moderator,mocks,mobs,mizz,mites,mistresses,misspent,misinterpretation,mishka,miscarry,minuses,minotaur,minoan,mindee,mimicking,millisecond,milked,militants,migration,mightn't,mightier,mierzwiak,midwives,micronesia,microchips,microbes,michele's,mhmm,mezzanine,meyerling,meticulously,meteorite,metaphorical,mesmerizing,mershaw,meir,meg's,meecrob,medicate,medea,meddled,mckinnons,mcgewan,mcdunnough,mcats,mbien,maytag,mayors,matzah,matriarch,matic,mathematicians,masturbated,masselin,marxist,martyrs,martini's,martialed,marten's,marlboros,marksmanship,marishka,marion's,marinate,marge's,marchin,manifestations,manicured,mandela,mamma's,mame,malnourished,malk,malign,majorek,maidens,mahoney's,magnon,magnificently,maestro's,macking,machiavellian,macdougal,macchiato,macaws,macanaw,m'self,lynx,lynn's,lyman's,lydells,lusts,lures,luna's,ludwig's,lucite,lubricants,louise's,lopper,lopped,loneliest,lonelier,lomez,lojack,localized,locale,loath,lloyd's,literate,liquidated,liquefy,lippy,linguistic,limps,lillian's,likin,lightness,liesl,liebchen,licious,libris,libation,lhamo,lewis's,leveraged,leticia's,leotards,leopards,leonid,leonardo's,lemmings,leland's,legitimacy,leanin,laxatives,lavished,latka,later's,larval,lanyard,lans,lanky,landscaping,landmines,lameness,lakeshore,laddies,lackluster,lacerated,labored,laboratories,l'amour,kyrgyzstan,kreskin,krazy,kovitch,kournikova,kootchy,konoss,know's,knknow,knickety,knackety,kmart,klicks,kiwanis,kitty's,kitties,kites,kissable,kirby's,kingdoms,kindergartners,kimota,kimble's,kilter,kidnet,kidman,kid'll,kicky,kickbacks,kickback,kickass,khrushchev,kholokov,kewpie,kent's,keno,kendo,keller's,kcdm,katrina's,katra,kareoke,kaia,kafelnikov,kabob,ka's,junjun,jumba,julep,jordie,jondy,jolson,jinnah,jeweler's,jerkin,jenoff,jefferson's,jaye's,jawbone,janitorial,janiro,janie's,iron's,ipecac,invigorated,inverted,intruded,intros,intravenously,interruptus,interrogations,interracial,interpretive,internment,intermediate,intermediary,interject,interfacing,interestin,insuring,instilled,instantaneous,insistence,insensitivity,inscrutable,inroads,innards,inlaid,injector,initiatives,inhe,ingratitude,infuriates,infra,informational,infliction,infighting,induction,indonesian,indochina,indistinguishable,indicators,indian's,indelicate,incubators,incrimination,increments,inconveniencing,inconsolable,incite,incestuous,incas,incarnation,incarcerate,inbreeding,inaccessible,impudence,impressionists,implemented,impeached,impassioned,impacts,imipenem,idling,idiosyncrasies,icicle,icebreaker,icebergs,i'se,hyundai,hypotensive,hydrochloride,huuh,hushed,humus,humph,hummm,hulking,hubcaps,hubald,http,howya,howbout,how'll,houseguests,housebroken,hotwire,hotspots,hotheaded,horticulture,horrace,horde,horace's,hopsfield,honto,honkin,honeymoons,homophobia,homewrecker,hombres,hollow's,hollers,hollerin,hokkaido,hohh,hogwarts,hoedown,hoboes,hobbling,hobble,hoarse,hinky,himmler,hillcrest,hijacking,highlighters,hiccup,hibernation,hexes,heru'ur,hernias,herding,heppleman,henderson's,hell're,heine's,heighten,heheheheheh,heheheh,hedging,heckling,heckled,heavyset,heatshield,heathens,heartthrob,headpiece,headliner,he'p,hazelnut,hazards,hayseed,haveo,hauls,hattie's,hathor's,hasten,harriers,harridan,harpoons,harlin's,hardens,harcesis,harbouring,hangouts,hangman,handheld,halkein,haleh,halberstam,hairpin,hairnet,hairdressers,hacky,haah,haaaa,h'yah,gyms,gusta,gushy,gusher,gurgling,gunnery,guilted,guilt's,gruel,grudging,grrrrrr,grouse,grossing,grosses,groomsmen,griping,gretchen's,gregorian,gray's,gravest,gratified,grated,graphs,grandad,goulash,goopy,goonies,goona,goodman's,goodly,goldwater,godliness,godawful,godamn,gobs,gob's,glycerin,glutes,glowy,glop,globetrotters,glimpsed,glenville,glaucoma,girlscout,giraffes,gimp,gilbey,gil's,gigglepuss,ghora,gestating,geologists,geographically,gelato,gekko's,geishas,geek's,gearshift,gear's,gayness,gasped,gaslighting,garretts,garba,gams,gags,gablyczyck,g'head,fungi,fumigating,fumbling,fulton's,fudged,fuckwad,fuck're,fuchsia,fruition,freud's,fretting,freshest,frenchies,freezers,fredrica,fraziers,francesca's,fraidy,foxholes,fourty,fossilized,forsake,formulate,forfeits,foreword,foreclosed,foreal,foraging,footsies,focussed,focal,florists,flopped,floorshow,floorboard,flinching,flecks,flavours,flaubert,flatware,flatulence,flatlined,flashdance,flail,flagging,fizzle,fiver,fitzy,fishsticks,finster,finetti,finelli,finagle,filko,filipino,figurines,figurative,fifi,fieldstone,fibber,fiance's,feuds,feta,ferrini,female's,feedin,fedora,fect,feasting,favore,fathering,farrouhk,farmin,far's,fanny's,fajita,fairytale,fairservice,fairgrounds,fads,factoid,facet,facedown,fabled,eyeballin,extortionist,exquisitely,exporting,explicitly,expenditures,expedited,expands,exorcise,existentialist,exhaustive,execs,exculpatory,excommunicated,exacerbate,everthing,eventuality,evander,eustace,euphoric,euphemisms,eton,esto,estimation,estamos,establishes,erred,environmentalist,entrepreneurial,entitle,enquiries,enormity,engages,enfants,enen,endive,end's,encyclopedias,emulating,emts,employee's,emphasized,embossed,embittered,embassies,eliot,elicit,electrolyte,ejection,effortless,effectiveness,edvard,educators,edmonton's,ecuador,ectopic,ecirc,easely,earphones,earmarks,earmarked,earl's,dysentery,dwindling,dwight's,dweller,dusky,durslar,durned,dunois,dunking,dunked,dumdum,dullard,dudleys,duce,druthers,druggist,drug's,drossos,drosophila,drooled,driveways,drippy,dreamless,drawstring,drang,drainpipe,dragoons,dozing,down's,dour,dougie's,dotes,dorsal,dorkface,doorknobs,doohickey,donnell's,donnatella,doncha,don's,dominates,domicile,dokos,dobermans,djez,dizzying,divola,dividends,ditsy,distaste,disservice,disregarded,dispensed,dismay,dislodged,dislodge,disinherit,disinformation,discrete,discounting,disciplines,disapproved,dirtball,dinka,dimly,dilute,dilucca's,digesting,diello,diddling,dictatorships,dictators,diagonal,diagnostician,devours,devilishly,detract,detoxing,detours,detente,destructs,desecrated,descends,derris,deplore,deplete,depicts,depiction,depicted,denver's,denounce,demure,demolitions,demean,deluge,dell's,delish,deliberation,delbruck,delaford,deities,degaulle,deftly,deft,deformity,deflate,definatly,defense's,defector,deducted,decrypted,decontamination,decker's,decapitate,decanter,deadline's,dardis,danger's,dampener,damme,daddy'll,dabbling,dabbled,d'etre,d'argent,d'alene,d'agnasti,czechs,czechoslovakian,cyrillic,cymbal,cyberdyne,cutoffs,cuticle,cut's,curvaceous,curiousity,curfew's,culturally,cued,cubby,cruised,crucible,crowing,crowed,croutons,cropped,croaker,cristobel's,criminy,crested,crescentis,cred,cream's,crashers,crapola,cranwell,coverin,cousteau,courtrooms,counterattack,countenance,counselor's,cottages,cosmically,cosign,cosa,corroboration,corresponds,correspond,coroners,coro,cornflakes,corbett's,copy's,copperpot,copperhead,copacetic,coordsize,convulsing,contradicted,contract's,continuation,consults,consultations,constraints,conjures,congenial,confluence,conferring,confederation,condominium,concourse,concealer,compulsory,complexities,comparatively,compactor,commodities,commercialism,colleague's,collaborator,cokey,coiled,cognizant,cofell's,cobweb,co's,cnbc,clyde's,clunkers,clumsily,clucking,cloves,cloven,cloths,clothe,clop,clods,clocking,clings,climbers,clef,clearances,clavicle,claudia's,classless,clashing,clanking,clanging,clamping,civvies,citywide,citing,circulatory,circuited,circ,chung's,chronisters,chromic,choppy,choos,chongo,chloroformed,chilton's,chillun,chil,chicky,cheetos,cheesed,chatterbox,charlies,chaperoned,channukah,chamberlain's,chairman's,chaim,cessation,cerebellum,centred,centerpieces,centerfold,cellars,ceecee,ccedil,cavorting,cavemen,cavaliers,cauterized,caustic,cauldwell,catting,cathy's,caterine,castor's,cassiopeia,cascade's,carves,cartwheel,cartridges,carpeted,carob,carlsbad,caressing,carelessly,careening,carcinoma,capricious,capitalistic,capillaries,capes,candle's,candidly,canaan,camaraderie,calumet,callously,calligraphy,calfskin,cake's,caddies,cabinet's,buzzers,buttholes,butler's,busywork,busses,burps,burgomeister,buoy,bunny's,bunkhouse,bungchow,bulkhead,builders,bugler,buffets,buffed,buckaroo's,brutish,brusque,browser,bronchitis,bromden,brolly,brody's,broached,brewskis,brewski,brewin,brewers,brean,breadwinner,brana,brackets,bozz,bountiful,bounder,bouncin,bosoms,borgnine,bopping,bootlegs,booing,bons,boneyard,bombosity,bolting,bolivia,boilerplate,boba,bluey,blowback,blouses,bloodsuckers,bloodstained,blonde's,bloat,bleeth,blazed,blaine's,blackhawk,blackface,blackest,blackened,blacken,blackballed,blabs,blabbering,birdbrain,bipartisanship,biodegradable,binghamton,biltmore,billiards,bilked,big'uns,bidwell's,bidet,bessie's,besotted,beset,berth,bernheim,benson's,beni,benegas,bendiga,belushi,beltway,bellboys,belittling,belinda's,behinds,behemoth,begone,beeline,beehive,bedsheets,beckoning,beaute,beaudine,beastly,beachfront,be's,bauk,bathes,batak,bastion,baser,baseballs,barker's,barber's,barbella,bans,bankrolling,bangladesh,bandaged,bamba,bally's,bagpipe,bagger,baerly,backlog,backin,babying,azkaban,ayatollah,axes,awwwww,awakens,aviary,avery's,autonomic,authorizes,austero,aunty,augustine's,attics,atreus,astronomers,astounded,astonish,assertion,asserting,assailants,asha's,artemus,arses,arousal,armin,arintero,argon's,arduous,archers,archdiocese,archaeology,arbitrarily,ararat,appropriated,appraiser,applicable,apathetic,anybody'd,anxieties,anwar's,anticlimactic,antar,ankle's,anima,anglos,angleman,anesthetist,androscoggin,andromeda,andover,andolini,andale,anan,amway,amuck,amphibian,amniocentesis,amnesiac,ammonium,americano,amara,alway,alvah,alum,altruism,alternapalooza,alphabetize,alpaca,almanac,ally's,allus,alluded,allocation,alliances,allergist,alleges,alexandros,alec's,alaikum,alabam,akimbo,airy,ahab's,agoraphobia,agides,aggrhh,agatha's,aftertaste,affiliations,aegis,adoptions,adjuster,addictions,adamantium,acumen,activator,activates,acrylic,accomplishes,acclaimed,absorbs,aberrant,abbu,aarp,aaaaargh,aaaaaaaaaaaaa,a'ight,zucchini,zoos,zookeeper,zirconia,zippers,zequiel,zephyr's,zellary,zeitgeist,zanuck,zambia,zagat,ylang,yielded,yes'm,yenta,yegg,yecchh,yecch,yayo,yawp,yawns,yankin,yahdah,yaaah,y'got,xeroxed,wwooww,wristwatch,wrangled,wouldst,worthiness,wort,worshiping,worsen,wormy,wormtail,wormholes,woosh,woodworking,wonka,womens,wolverines,wollsten,wolfing,woefully,wobbling,witter's,wisp,wiry,wire's,wintry,wingding,windstorm,windowtext,wiluna,wilting,wilted,willick,willenholly,wildflowers,wildebeest,wilco,wiggum,wields,widened,whyyy,whoppers,whoaa,whizzing,whizz,whitest,whitefish,whistled,whist,whinny,whereupon,whereby,wheelies,wheaties,whazzup,whatwhatwhaaat,whato,whatdya,what'dya,whar,whacks,wexler's,wewell,wewe,wetsuit,wetland,westport,welluh,weight's,weeps,webpage,waylander,wavin,watercolors,wassail,wasnt,warships,warns,warneford,warbucks,waltons,wallbanger,waiving,waitwait,vowing,voucher,vornoff,vork,vorhees,voldemort,vivre,vittles,vishnu,vips,vindaloo,videogames,victors,vicky's,vichyssoise,vicarious,vet's,vesuvius,verve,verguenza,venturing,ventura's,venezuelan,ven't,velveteen,velour,velociraptor,vegetation,vaudeville,vastness,vasectomies,vapors,vanderhof,valmont,validates,valiantly,valerian,vacuums,vaccines,uzbekistan,usurp,usernum,us'll,urinals,unyielding,unwillingness,unvarnished,unturned,untouchables,untangled,unsecured,unscramble,unreturned,unremarkable,unregistered,unpublished,unpretentious,unopposed,unnerstand,unmade,unlicensed,unites,union's,uninhabited,unimpeachable,unilateral,unicef,unfolded,unfashionable,undisturbed,underwriting,underwrite,underlining,underling,underestimates,underappreciated,undamaged,uncouth,uncork,uncontested,uncommonly,unclog,uncircumcised,unchallenged,uncas,unbuttoning,unapproved,unamerican,unafraid,umpteen,umhmm,uhwhy,uhmm,ughuh,ughh,ufo's,typewriters,twitches,twitched,twirly,twinkling,twink,twinges,twiddling,twiddle,tutored,tutelage,turners,turnabout,ture,tunisian,tumultuous,tumour,tumblin,tryed,truckin,trubshaw's,trowel,trousseau,trivialize,trifles,tribianni,trib,triangulation,trenchcoat,trembled,traumatize,transplanted,translations,transitory,transients,transfuse,transforms,transcribing,transcend,tranq,trampy,traipsed,trainin,trail's,trafalgar,trachea,traceable,touristy,toughie,totality,totaling,toscanini,tortola,tortilla,tories,toreador,tooo,tonka,tommorrow,tollbooth,tollans,toidy,togs,togas,tofurkey,toddling,toddies,tobruk,toasties,toadstool,to've,tive,tingles,timin,timey,timetables,tightest,tide's,tibetans,thunderstorms,thuggee,thrusting,thrombus,throes,throated,thrifty,thoroughbred,thornharts,thinnest,thicket,thetas,thesulac,tethered,testimonial,testaburger,tersenadine,terrif,teresa's,terdlington,tepui,tenured,tentacle,temping,temperance,temp's,teller's,televisions,telefono,tele,teddies,tector,taxidermy,taxi's,taxation,tastebuds,tasker's,tartlets,tartabull,tard,tar'd,tantamount,tans,tangy,tangles,tamer,talmud,taiwan's,tabula,tabletops,tabithia,tabernacle,szechwan,syrian,synthedyne,synopsis,synonyms,swaps,swahili,svenjolly,svengali,suvs,sush,survivalists,surmise,surfboards,surefire,suprise,supremacists,suppositories,supervisors,superstore,supermen,supercop,supercilious,suntac,sunburned,summercliff,sullied,suite's,sugared,sufficiency,suerte,suckle,sucker's,sucka,succumbing,subtleties,substantiated,subsidiaries,subsides,subliminal,subhuman,stst,strowman,stroked,stroganoff,strikers,strengthening,streetlight,straying,strainer,straighter,straightener,storytelling,stoplight,stockade,stirrups,stink's,sting's,stimulates,stifler's,stewing,stetson's,stereotyping,ster,stepmommy,stephano,steeped,statesman,stashing,starshine,stand's,stamping,stamford,stairwells,stabilization,squatsie,squandering,squalid,squabbling,squab,sprinkling,spring's,spreader,spongy,spongebob,spokeswoman,spokesmen,splintered,spittle,spitter,spiced,spews,spendin,spect,speckled,spearchucker,spatulas,sparse,sparking,spares,spaceboy,soybeans,southtown,southside,southport,southland,soused,sotheby's,soshi,sorter,sorrowful,sorceress,sooth,songwriters,some'in,solstice,soliloquy,sods,sodomized,sode,sociologist,sobriki,soaping,snows,snowcone,snowcat,snitching,snitched,sneering,snausages,snaking,smoothed,smoochies,smolensk,smarten,smallish,slushy,slurring,sluman,slobber,slithers,slippin,sleuthing,sleeveless,slade's,skinner's,skinless,skillfully,sketchbook,skagnetti,sista,sioux,sinning,sinjin,singularly,sinewy,sinclair's,simultaneous,silverlake,silva's,siguto,signorina,signature's,signalling,sieve,sids,sidearms,shyster,shying,shunning,shtud,shrooms,shrieks,shorting,shortbread,shopkeepers,shmuck,shmancy,shizzit,shitheads,shitfaced,shitbag,shipmates,shiftless,sherpa,shelving,shelley's,sheik,shedlow,shecky,sheath,shavings,shatters,sharifa,shampoos,shallots,shafter,sha'nauc,sextant,settlers,setter,seti,serviceable,serrated,serbian,sequentially,sepsis,senores,sendin,semis,semanski,seller's,selflessly,selects,selectively,seinfelds,seers,seer's,seeps,see's,seductress,sedimentary,sediment,second's,secaucus,seater,seashore,sealant,seaborn's,scuttling,scusa,sculpting,scrunched,scrimmage,screenwriter,scotsman,scorer,sclerosis,scissorhands,schreber,scholastic,schmancy,schlong,scathing,scandinavia,scamps,scalloped,savoir,savagery,sasha's,sarong,sarnia,santangel,samool,samba,salons,sallow,salino,safecracker,sadism,saddles,sacrilegious,sabrini,sabath,s'aright,ruttheimer,russia's,rudest,rubbery,rousting,rotarian,roslin,rosey,rosa's,roomed,romari,romanticism,romanica,rolltop,rolfski,rod's,rockland,rockettes,roared,riverfront,rinpoche,ringleader,rims,riker's,riffing,ricans,ribcage,riana's,rhythmic,rhah,rewired,retroactive,retrial,reting,reticulum,resuscitated,resuming,restricting,restorations,restock,resilience,reservoirs,resembled,resale,requisitioned,reprogrammed,reproducing,repressive,replicant,repentant,repellant,repays,repainting,reorganization,renounced,renegotiating,rendez,renamed,reminiscent,remem,remade,relived,relinquishes,reliant,relearn,relaxant,rekindling,rehydrate,regulatory,regiments,regan's,refueled,refrigeration,refreshingly,reflector,refine,refilling,reexamine,reeseman,redness,redirected,redeemable,redder,redcoats,rectangles,recoup,reconstituted,reciprocated,recipients,recessed,recalls,rebounded,reassessing,realy,reality's,realisation,realer,reachin,re'kali,rawlston,ravages,rattlers,rasa,raps,rappaports,ramoray,ramming,ramadan,raindrops,rahesh,radioactivity,radials,racists,racin,rabartu,quotas,quintus,quiches,ques,queries,quench,quel,quarrels,quarreling,quaintly,quagmire,quadrants,pylon,putumayo,put'em,purifier,purified,pureed,punitis,pullout,pukin,pudgy,puddings,puckering,puccini,pterodactyl,psychodrama,pseudonym,psats,proximal,providers,protestations,protectee,prospered,prosaic,propositioned,prolific,progressively,proficiency,professions,prodigious,proclivity,probed,probabilities,pro's,prison's,printouts,principally,prig,prevision,prevailing,presumptive,pressers,preset,presentations,preposition,preparatory,preliminaries,preempt,preemie,predetermined,preconceptions,precipitate,prancan,powerpuff,powerfully,potties,potters,potpie,poseur,portraying,portico,porthole,portfolios,poops,pooping,pone,pomp,pomade,polyps,polymerized,politic,politeness,polisher,polack,pokers,pocketknife,poatia,plebeian,playgroup,platonically,plato's,platitude,platelet,plastering,plasmapheresis,plaques,plaids,placemats,place's,pizzazz,piracy,pipelines,pip's,pintauro,pinstripes,pinpoints,pinkner,pincer,pimento,pillaged,pileup,pilates,pigment,pigmen,pieter,pieeee,picturesque,piano's,phrasing,phrased,photojournalist,photocopies,phosphorus,phonograph,phoebes,phoe,philistines,philippine,philanderer,pheromone,phasers,pharaoh's,pfff,pfeffernuesse,petrov,petitions,peterman's,peso,pervs,perspire,personify,perservere,perplexed,perpetrating,perp's,perkiness,perjurer,periodontist,perfunctory,performa,perdido,percodan,penzance,pentameter,pentagon's,pentacle,pensive,pensione,pennybaker,pennbrooke,penhall,pengin,penetti,penetrates,pegs,pegnoir,peeve,peephole,pectorals,peckin,peaky,peaksville,payout,paxcow,paused,pauline's,patted,pasteur,passe,parochial,parkland,parkishoff,parkers,pardoning,paraplegic,paraphrasing,parapet,paperers,papered,panoramic,pangs,paneling,pander,pandemonium,pamela's,palooza,palmed,palmdale,palisades,palestinian,paleolithic,palatable,pakistanis,pageants,packaged,pacify,pacified,oyes,owwwww,overthrown,overt,oversexed,overriding,overrides,overpaying,overdrawn,overcompensate,overcomes,overcharged,outtakes,outmaneuver,outlying,outlining,outfoxed,ousted,oust,ouse,ould,oughtn't,ough,othe,ostentatious,oshun,oscillation,orthopedist,organizational,organization's,orca,orbits,or'derves,opting,ophthalmologist,operatic,operagirl,oozes,oooooooh,only's,onesie,omnis,omelets,oktoberfest,okeydoke,ofthe,ofher,obstetrics,obstetrical,obeys,obeah,o'rourke,o'reily's,o'henry,nyquil,nyanyanyanyah,nuttin,nutsy,nutrients,nutball,nurhachi,numbskull,nullifies,nullification,nucking,nubbin,ntnt,nourished,notoriety,northland,nonspecific,nonfiction,noing,noinch,nohoho,nobler,nitwits,nitric,nips,nibs,nibbles,newton's,newsprint,newspaperman,newspaper's,newscaster,never's,neuter,neuropathy,netherworld,nests,nerf,neee,neediest,neath,navasky,naturalization,nat's,narcissists,napped,nando,nags,nafta,myocardial,mylie's,mykonos,mutilating,mutherfucker,mutha,mutations,mutates,mutate,musn't,muskets,murray's,murchy,mulwray's,multitasking,muldoon's,mujeeb,muerte,mudslinging,muckraking,mrsa,mown,mousie,mousetrap,mourns,mournful,motivating,motherland,motherf,mostro,mosaic,morphing,morphate,mormons,moralistic,moored,moochy,mooching,monotonous,monorail,monopolize,monogram,monocle,molehill,molar,moland,mofet,modestly,mockup,moca,mobilizing,mitzvahs,mitre,mistreating,misstep,misrepresentation,misjudge,misinformation,miserables,misdirected,miscarriages,minute's,miniskirt,minimizing,mindwarped,minced,milquetoast,millimeters,miguelito,migrating,mightily,midsummer,midstream,midriff,mideast,midas,microbe,metropolis,methuselah,mesdames,mescal,mercury's,menudo,menu's,mentors,men'll,memorial's,memma,melvins,melanie's,megaton,megara,megalomaniac,meeee,medulla,medivac,mediate,meaninglessness,mcnuggets,mccarthyism,maypole,may've,mauve,maturing,matter's,mateys,mate's,mastering,masher,marxism,martimmy's,marshack,marseille,markles,marketed,marketable,mansiere,manservant,manse,manhandling,manco's,manana,maman,malnutrition,mallomars,malkovich's,malcontent,malaise,makeup's,majesties,mainsail,mailmen,mahandra,magnolias,magnified,magev,maelstrom,madcap,mack's,machu,macfarlane's,macado,ma'm,m'boy,m'appelle,lying's,lustrous,lureen,lunges,lumped,lumberyard,lulled,luego,lucks,lubricated,loveseat,loused,lounger,loski,lorre,loora,looong,loonies,lonnegan's,lola's,loire,loincloth,logistical,lofts,lodges,lodgers,lobbing,loaner,livered,lithuania,liqueur,linkage,ling's,lillienfield's,ligourin,lighter's,lifesaving,lifeguards,lifeblood,library's,liberte,liaisons,liabilities,let'em,lesbianism,lenny's,lennart,lence,lemonlyman,legz,legitimize,legalized,legalization,leadin,lazars,lazarro,layoffs,lawyering,lawson's,lawndale's,laugher,laudanum,latte's,latrines,lations,laters,lastly,lapels,lansing's,lan's,lakefront,lait,lahit,lafortunata,lachrymose,laborer,l'italien,l'il,kwaini,kuzmich,kuato's,kruczynski,kramerica,krakatoa,kowtow,kovinsky,koufax,korsekov,kopek,knoxville,knowakowski,knievel,knacks,klux,klein's,kiran,kiowas,kinshasa,kinkle's,kincaid's,killington,kidnapper's,kickoff,kickball,khan's,keyworth,keymaster,kevie,keveral,kenyons,keggers,keepsakes,kechner,keaty,kavorka,katmandu,katan's,karajan,kamerev,kamal's,kaggs,juvi,jurisdictional,jujyfruit,judeo,jostled,joni's,jonestown,jokey,joists,joint's,johnnie's,jocko,jimmied,jiggled,jig's,jests,jessy,jenzen,jensen's,jenko,jellyman,jeet,jedediah,jealitosis,jaya's,jaunty,jarmel,jankle,jagoff,jagielski,jacky,jackrabbits,jabbing,jabberjaw,izzat,iuml,isolating,irreverent,irresponsibly,irrepressible,irregularity,irredeemable,investigator's,inuvik,intuitions,intubated,introspective,intrinsically,intra,intimates,interval,intersections,interred,interned,interminable,interloper,intercostal,interchange,integer,intangible,instyle,instrumentation,instigate,instantaneously,innumerable,inns,injustices,ining,inhabits,ings,ingrown,inglewood,ingestion,ingesting,infusion,infusing,infringing,infringe,inflection,infinitum,infact,inexplicably,inequities,ineligible,industry's,induces,indubitably,indisputable,indirect,indescribably,independents,indentation,indefinable,incursion,incontrovertible,inconsequential,incompletes,incoherently,inclement,inciting,incidentals,inarticulate,inadequacies,imprudent,improvisation,improprieties,imprison,imprinted,impressively,impostors,importante,implicit,imperious,impale,immortalized,immodest,immobile,imbued,imbedded,imbecilic,illustrates,illegals,iliad,idn't,idiom,icons,hysteric,hypotenuse,hygienic,hyeah,hushpuppies,hunhh,hungarians,humpback,humored,hummed,humiliates,humidifier,huggy,huggers,huckster,html,hows,howlin,hoth,hotbed,hosing,hosers,horsehair,homegrown,homebody,homebake,holographic,holing,holies,hoisting,hogwallop,hogan's,hocks,hobbits,hoaxes,hmmmmm,hisses,hippos,hippest,hindrance,hindi,him's,hillbillies,hilarity,highball,hibiscus,heyday,heurh,hershey's,herniated,hermaphrodite,hera,hennifer,hemlines,hemline,hemery,helplessness,helmsley,hellhound,heheheheh,heey,heeey,hedda,heck's,heartbeats,heaped,healers,headstart,headsets,headlong,headlining,hawkland,havta,havana's,haulin,hastened,hasn,harvey'll,harpo,hardass,haps,hanta,hansom,hangnail,handstand,handrail,handoff,hander,han's,hamlet's,hallucinogen,hallor,halitosis,halen,hahah,hado,haberdashery,gypped,guy'll,guni,gumbel,gulch,gues,guerillas,guava,guatemalan,guardrail,guadalajara,grunther,grunick,grunemann's,growers,groppi,groomer,grodin,gris,gripes,grinds,grimaldi's,grifters,griffins,gridlock,gretch,greevey,greasing,graveyards,grandkid,grainy,graced,governed,gouging,gordie's,gooney,googly,golfers,goldmuff,goldenrod,goingo,godly,gobbledygook,gobbledegook,goa'uld's,glues,gloriously,glengarry,glassware,glamor,glaciers,ginseng,gimmicks,gimlet,gilded,giggly,gig's,giambetti,ghoulish,ghettos,ghandi,ghali,gether,get's,gestation,geriatrics,gerbils,gerace's,geosynchronous,georgio,geopolitical,genus,gente,genital,geneticist,generation's,generates,gendarme,gelbman,gazillionth,gayest,gauging,gastro,gaslight,gasbag,garters,garish,garas,garages,gantu,gangy,gangly,gangland,gamer,galling,galilee,galactica's,gaiety,gadda,gacy,futuristic,futs,furrowed,funny's,funnies,funkytown,fundraisers,fundamentalist,fulcrum,fugimotto,fuente,fueling,fudging,fuckup,fuckeen,frutt's,frustrates,froufrou,froot,frontiers,fromberge,frog's,frizzies,fritters,fringes,frightfully,frigate,friendliest,freeloading,freelancing,fredonia,freakazoid,fraternization,frankfurter,francine's,franchises,framers,fostered,fortune's,fornication,fornicating,formulating,formations,forman's,forgeries,forethought,forage,footstool,foisting,focussing,focking,foal,flutes,flurries,fluffed,flourished,florida's,floe,flintstones,fleischman's,fledgling,fledermaus,flayed,flay,flawlessly,flatters,flashbang,flapped,flanking,flamer,fission,fishies,firmer,fireproof,fireman's,firebug,firebird,fingerpainting,finessed,findin,financials,finality,fillets,fighter's,fiercest,fiefdom,fibrosis,fiberglass,fibbing,feudal,festus,fervor,fervent,fentanyl,fenelon,fenders,fedorchuk,feckless,feathering,fearsome,fauna,faucets,farmland,farewells,fantasyland,fanaticism,faltered,fallacy,fairway,faggy,faberge,extremism,extorting,extorted,exterminating,exhumation,exhilaration,exhausts,exfoliate,exemptions,excesses,excels,exasperating,exacting,evoked,evocative,everyman,everybody'd,evasions,evangelical,establishments,espressos,esoteric,esmail,errrr,erratically,eroding,erode,ernswiler,episcopalian,ephemeral,epcot,entrenched,entomology,entomologist,enthralled,ensuing,ensenada,enriching,enrage,enlisting,enhancer,enhancements,endorsing,endear,encrusted,encino,enacted,employing,emperors,empathic,embodied,embezzle,embarked,emanates,elton's,eloquence,eloi,elmwood,elliptical,ellenor's,elemental,electricians,electing,elapsed,eking,egomaniacal,eggo,egging,effected,effacing,eeww,edits,editor's,edging,ectoplasm,economical,ecch,eavesdropped,eastbound,earwig,e'er,durable,dunbar's,dummkopf,dugray,duchaisne,duality,drusilla's,drunkard,drudge,drucilla's,droop,droids,drips,dripped,dribbles,drew's,dressings,drazens,downy,downsize,downpour,dowager,dote,dosages,dorothy's,doppler,doppelganger,dopes,doorman's,doohicky,doof,dontcha,donovon's,doneghy,domi,domes,dojo,documentaries,divinity,divining,divest,diuretics,diuretic,distrustful,distortions,dissident,disrupts,disruptions,disproportionate,dispensary,disparity,dismemberment,dismember,disinfect,disillusionment,disheartening,discriminated,discourteous,discotheque,discolored,disassembled,disabling,dirtiest,diphtheria,dinks,dimpled,digg,diffusion,differs,didya,dickweed,dickwad,dickson's,diatribes,diathesis,diabetics,dewars,deviants,detrimental,detonates,detests,detestable,detaining,despondent,desecration,descriptive,derision,derailing,deputized,depressors,depo,depicting,depict,dependant,dentures,denominators,demur,demonstrators,demonology,delts,dellarte,delinquency,delacour,deflated,definitively,defib,defected,defaced,deeded,decorators,debit,deaqon,davola,datin,dasilva's,darwinian,darling's,darklighters,dandelions,dandelion,dancer's,dampened,dame's,damaskinos,dama,dalrimple,dagobah,dack,d'peshu,d'hoffryn,d'astier,cystic,cynics,cybernetic,cutoff,cutesy,cutaway,customarily,curtain's,cursive,curmudgeon,curdle,cuneiform,cultivated,culpability,culo,cuisinart,cuffing,crypts,cryptid,cryogenic,crux,crunched,crumblers,crudely,crosscheck,croon,crissake,crime's,cribbage,crevasse,creswood,creepo,creases,creased,creaky,cranks,cran,craftsmen,crafting,crabgrass,cowboy's,coveralls,couple'a,councilors,coughs,cotton's,cosmology,coslaw,corresponded,corporeal,corollary,cornucopia,cornering,corks,cordoned,coolly,coolin,cooley's,coolant,cookbooks,converging,contrived,contrite,contributors,contradictory,contra,contours,contented,contenders,contemplated,contact's,constrictor,congressman's,congestion,confrontations,confound,conform,confit,confiscating,conferred,condoned,conditioners,concussions,concentric,conceding,coms,comprised,comprise,comprendo,composers,commuted,commercially,commentator,commentaries,commemorating,commander's,comers,comedic,combustible,combusted,columbo,columbia's,colourful,colonials,collingswood,coliseum,coldness,cojones,coitus,cohesive,cohesion,cohen's,coffey's,codicil,cochran's,coasting,clydesdale,cluttering,clunker,clunk,clumsiness,clumps,clotted,clothesline,clinches,clincher,cleverness,clench,clein,cleave,cleanses,claymores,clarisse,clarissa's,clammed,civilisation,ciudad,circumvent,circulated,circuit's,cinnamon's,cind,church's,chugging,chronically,christsakes,chris's,choque,chompers,choco,chiseling,chirpy,chirp,chinks,chingachgook,chigger,chicklet,chickenpox,chickadee,chewin,chessboard,cherub,chemo's,chauffeur's,chaucer,chariots,chargin,characterizing,chanteuse,chandeliers,chamdo,chalupa,chagrined,chaff,certs,certify,certification,certainties,cerreno,cerebrum,cerebro,century's,centennial,censured,cemetary,cellist,celine's,cedar's,cayo,caterwauling,caterpillars,categorized,catchers,cataclysmic,cassidy's,casitas,casino's,cased,carvel,cartographers,carting,cartels,carriages,carrear,carr's,carolling,carolinas,carolers,carnie,carne,cardiovascular,cardiogram,carbuncle,caramba,capulets,capping,canyons,canines,candaules,canape,canadiens,campaigned,cambodian,camberwell,caldecott,calamitous,caff,cadillacs,cachet,cabeza,cabdriver,byzantium,buzzkill,buzzards,buzz's,buyer's,butai,bustling,businesswomen,bunyan,bungled,bumpkins,bummers,bulletins,bullet's,bulldoze,bulbous,bug's,buffybot,budgeted,budda,bubut,bubbies,brunei,brrrrr,brownout,brouhaha,bronzing,bronchial,broiler,broadening,briskly,briefcases,bricked,breezing,breeher,breckinridge,breakwater,breakable,breadstick,bravenet,braved,brass's,brandies,brandeis,branched,brainwaves,brainiest,braggart,bradlee,boys're,boys'll,boys'd,boyd's,boutonniere,bottle's,bossed,bosomy,bosnian,borans,boosts,boombox,bookshelves,bookmark,booklet,bookends,bontecou's,bongos,boneless,bone's,bond's,bombarding,bombarded,bollo,boinked,boink,boilers,bogart's,bobbo,bobbin,bluest,bluebells,blowjobs,bloodshot,blondie's,blockhead,blockbusters,blithely,blim,bleh,blather,blasters,blankly,bladders,blackhawks,blackbeard,bjorn,bitte,bippy,bios,biohazard,biogenetics,biochemistry,biochemist,bilingual,bilge,bigmouth,bighorn,bigglesworth,bicuspids,beususe,betaseron,besmirch,besieged,bernece,bergman's,bereavement,bentonville,benthic,benjie,benji's,benefactors,benchley,benching,bembe,bellyaching,bellhops,belie,beleaguered,being's,behrle,beginnin,begining,beenie,beefs,beechwood,bee's,bedbug,becau,beaverhausen,beakers,beacon's,bazillion,baudouin,bat's,bartlett's,barrytown,barringtons,baroque,baronet,barneys,barbs,barbers,barbatus,baptists,bankrupted,banker's,bamn,bambi's,ballon's,balinese,bakeries,bailiffs,backslide,baby'd,baaad,b'fore,awwwk,aways,awakes,averages,avengers,avatars,autonomous,automotive,automaton,automatics,autism,authoritative,authenticated,authenticate,aught,audition's,aubyn,attired,attagirl,atrophied,atonement,atherton's,asystole,astroturf,assimilated,assimilate,assertiveness,assemblies,assassin's,artiste,article's,artichokes,arsehole,arrears,arquillians,arnie's,aright,archenemy,arched,arcade's,aquatic,apps,appraise,applauded,appendages,appeased,apostle,apollo's,antwerp,antler,antiquity,antin,antidepressant,antibody,anthropologists,anthology,anthea,antagonism,ant's,anspaugh,annually,anka,angola,anesthetics,anda,ancients,anchoring,anaphylactic,anaheim,ana's,amtrak,amscray,amputated,amounted,americas,amended,ambivalence,amalio,amah,altoid,alriiight,alphabetized,alpena,alouette,allowable,allora,alliteration,allenwood,alleging,allegiances,aligning,algerians,alerts,alchemist,alcerro,alastor,airway's,airmen,ahaha,ah'm,agitators,agitation,aforethought,afis,aesthetics,aerospace,aerodynamics,advertises,advert,advantageous,admonition,administration's,adirondacks,adenoids,adebisi's,acupuncturist,acula,actuarial,activators,actionable,acme's,acknowledges,achmed,achingly,acetate,accusers,accumulation,accorded,acclimated,acclimate,absurdly,absorbent,absolvo,absolutes,absences,abraham's,aboriginal,ablaze,abdomenizer,aaaaaaaaah,aaaaaaaaaa,a'right".split(","))),
-o("male_names",r("james,john,robert,michael,william,david,richard,charles,joseph,thomas,christopher,daniel,paul,mark,donald,george,kenneth,steven,edward,brian,ronald,anthony,kevin,jason,matthew,gary,timothy,jose,larry,jeffrey,frank,scott,eric,stephen,andrew,raymond,gregory,joshua,jerry,dennis,walter,patrick,peter,harold,douglas,henry,carl,arthur,ryan,roger,joe,juan,jack,albert,jonathan,justin,terry,gerald,keith,samuel,willie,ralph,lawrence,nicholas,roy,benjamin,bruce,brandon,adam,harry,fred,wayne,billy,steve,louis,jeremy,aaron,randy,eugene,carlos,russell,bobby,victor,ernest,phillip,todd,jesse,craig,alan,shawn,clarence,sean,philip,chris,johnny,earl,jimmy,antonio,danny,bryan,tony,luis,mike,stanley,leonard,nathan,dale,manuel,rodney,curtis,norman,marvin,vincent,glenn,jeffery,travis,jeff,chad,jacob,melvin,alfred,kyle,francis,bradley,jesus,herbert,frederick,ray,joel,edwin,don,eddie,ricky,troy,randall,barry,bernard,mario,leroy,francisco,marcus,micheal,theodore,clifford,miguel,oscar,jay,jim,tom,calvin,alex,jon,ronnie,bill,lloyd,tommy,leon,derek,darrell,jerome,floyd,leo,alvin,tim,wesley,dean,greg,jorge,dustin,pedro,derrick,dan,zachary,corey,herman,maurice,vernon,roberto,clyde,glen,hector,shane,ricardo,sam,rick,lester,brent,ramon,tyler,gilbert,gene,marc,reginald,ruben,brett,angel,nathaniel,rafael,edgar,milton,raul,ben,cecil,duane,andre,elmer,brad,gabriel,ron,roland,jared,adrian,karl,cory,claude,erik,darryl,neil,christian,javier,fernando,clinton,ted,mathew,tyrone,darren,lonnie,lance,cody,julio,kurt,allan,clayton,hugh,max,dwayne,dwight,armando,felix,jimmie,everett,ian,ken,bob,jaime,casey,alfredo,alberto,dave,ivan,johnnie,sidney,byron,julian,isaac,clifton,willard,daryl,virgil,andy,salvador,kirk,sergio,seth,kent,terrance,rene,eduardo,terrence,enrique,freddie,stuart,fredrick,arturo,alejandro,joey,nick,luther,wendell,jeremiah,evan,julius,donnie,otis,trevor,luke,homer,gerard,doug,kenny,hubert,angelo,shaun,lyle,matt,alfonso,orlando,rex,carlton,ernesto,pablo,lorenzo,omar,wilbur,blake,horace,roderick,kerry,abraham,rickey,ira,andres,cesar,johnathan,malcolm,rudolph,damon,kelvin,rudy,preston,alton,archie,marco,wm,pete,randolph,garry,geoffrey,jonathon,felipe,bennie,gerardo,ed,dominic,loren,delbert,colin,guillermo,earnest,benny,noel,rodolfo,myron,edmund,salvatore,cedric,lowell,gregg,sherman,devin,sylvester,roosevelt,israel,jermaine,forrest,wilbert,leland,simon,irving,owen,rufus,woodrow,kristopher,levi,marcos,gustavo,lionel,marty,gilberto,clint,nicolas,laurence,ismael,orville,drew,ervin,dewey,al,wilfred,josh,hugo,ignacio,caleb,tomas,sheldon,erick,frankie,darrel,rogelio,terence,alonzo,elias,bert,elbert,ramiro,conrad,noah,grady,phil,cornelius,lamar,rolando,clay,percy,dexter,bradford,merle,darin,amos,terrell,moses,irvin,saul,roman,darnell,randal,tommie,timmy,darrin,brendan,toby,van,abel,dominick,emilio,elijah,cary,domingo,aubrey,emmett,marlon,emanuel,jerald,edmond,emil,dewayne,otto,teddy,reynaldo,bret,jess,trent,humberto,emmanuel,stephan,louie,vicente,lamont,garland,micah,efrain,heath,rodger,demetrius,ethan,eldon,rocky,pierre,eli,bryce,antoine,robbie,kendall,royce,sterling,grover,elton,cleveland,dylan,chuck,damian,reuben,stan,leonardo,russel,erwin,benito,hans,monte,blaine,ernie,curt,quentin,agustin,jamal,devon,adolfo,tyson,wilfredo,bart,jarrod,vance,denis,damien,joaquin,harlan,desmond,elliot,darwin,gregorio,kermit,roscoe,esteban,anton,solomon,norbert,elvin,nolan,carey,rod,quinton,hal,brain,rob,elwood,kendrick,darius,moises,marlin,fidel,thaddeus,cliff,marcel,ali,raphael,bryon,armand,alvaro,jeffry,dane,joesph,thurman,ned,sammie,rusty,michel,monty,rory,fabian,reggie,kris,isaiah,gus,avery,loyd,diego,adolph,millard,rocco,gonzalo,derick,rodrigo,gerry,rigoberto,alphonso,ty,rickie,noe,vern,elvis,bernardo,mauricio,hiram,donovan,basil,nickolas,scot,vince,quincy,eddy,sebastian,federico,ulysses,heriberto,donnell,denny,gavin,emery,romeo,jayson,dion,dante,clement,coy,odell,jarvis,bruno,issac,dudley,sanford,colby,carmelo,nestor,hollis,stefan,donny,art,linwood,beau,weldon,galen,isidro,truman,delmar,johnathon,silas,frederic,irwin,merrill,charley,marcelino,carlo,trenton,kurtis,aurelio,winfred,vito,collin,denver,leonel,emory,pasquale,mohammad,mariano,danial,landon,dirk,branden,adan,numbers,clair,buford,german,bernie,wilmer,emerson,zachery,jacques,errol,josue,edwardo,wilford,theron,raymundo,daren,tristan,robby,lincoln,jame,genaro,octavio,cornell,hung,arron,antony,herschel,alva,giovanni,garth,cyrus,cyril,ronny,stevie,lon,kennith,carmine,augustine,erich,chadwick,wilburn,russ,myles,jonas,mitchel,mervin,zane,jamel,lazaro,alphonse,randell,major,johnie,jarrett,ariel,abdul,dusty,luciano,seymour,scottie,eugenio,mohammed,valentin,arnulfo,lucien,ferdinand,thad,ezra,aldo,rubin,royal,mitch,earle,abe,marquis,lanny,kareem,jamar,boris,isiah,emile,elmo,aron,leopoldo,everette,josef,eloy,dorian,rodrick,reinaldo,lucio,jerrod,weston,hershel,lemuel,lavern,burt,jules,gil,eliseo,ahmad,nigel,efren,antwan,alden,margarito,refugio,dino,osvaldo,les,deandre,normand,kieth,ivory,trey,norberto,napoleon,jerold,fritz,rosendo,milford,sang,deon,christoper,alfonzo,lyman,josiah,brant,wilton,rico,jamaal,dewitt,brenton,yong,olin,faustino,claudio,judson,gino,edgardo,alec,jarred,donn,trinidad,tad,porfirio,odis,lenard,chauncey,tod,mel,marcelo,kory,augustus,keven,hilario,bud,sal,orval,mauro,dannie,zachariah,olen,anibal,milo,jed,thanh,amado,lenny,tory,richie,horacio,brice,mohamed,delmer,dario,mac,jonah,jerrold,robt,hank,sung,rupert,rolland,kenton,damion,chi,antone,waldo,fredric,bradly,kip,burl,tyree,jefferey,ahmed,willy,stanford,oren,moshe,mikel,enoch,brendon,quintin,jamison,florencio,darrick,tobias,minh,hassan,giuseppe,demarcus,cletus,tyrell,lyndon,keenan,werner,theo,geraldo,columbus,chet,bertram,markus,huey,hilton,dwain,donte,tyron,omer,isaias,hipolito,fermin,chung,adalberto,jamey,teodoro,mckinley,maximo,sol,raleigh,lawerence,abram,rashad,emmitt,daron,chong,samual,otha,miquel,eusebio,dong,domenic,darron,wilber,renato,hoyt,haywood,ezekiel,chas,florentino,elroy,clemente,arden,neville,edison,deshawn,carrol,shayne,nathanial,jordon,danilo,claud,val,sherwood,raymon,rayford,cristobal,ambrose,titus,hyman,felton,ezequiel,erasmo,lonny,len,ike,milan,lino,jarod,herb,andreas,rhett,jude,douglass,cordell,oswaldo,ellsworth,virgilio,toney,nathanael,del,benedict,mose,hong,isreal,garret,fausto,asa,arlen,zack,modesto,francesco,manual,jae,gaylord,gaston,filiberto,deangelo,michale,granville,wes,malik,zackary,tuan,nicky,cristopher,antione,malcom,korey,jospeh,colton,waylon,von,hosea,shad,santo,rudolf,rolf,rey,renaldo,marcellus,lucius,kristofer,harland,arnoldo,rueben,leandro,kraig,jerrell,jeromy,hobert,cedrick,arlie,winford,wally,luigi,keneth,jacinto,graig,franklyn,edmundo,sid,leif,jeramy,willian,vincenzo,shon,michal,lynwood,jere,hai,elden,darell,broderick,alonso".split(","))),
-o("female_names",r("mary,patricia,linda,barbara,elizabeth,jennifer,maria,susan,margaret,dorothy,lisa,nancy,karen,betty,helen,sandra,donna,carol,ruth,sharon,michelle,laura,sarah,kimberly,deborah,jessica,shirley,cynthia,angela,melissa,brenda,amy,anna,rebecca,virginia,kathleen,pamela,martha,debra,amanda,stephanie,carolyn,christine,marie,janet,catherine,frances,ann,joyce,diane,alice,julie,heather,teresa,doris,gloria,evelyn,jean,cheryl,mildred,katherine,joan,ashley,judith,rose,janice,kelly,nicole,judy,christina,kathy,theresa,beverly,denise,tammy,irene,jane,lori,rachel,marilyn,andrea,kathryn,louise,sara,anne,jacqueline,wanda,bonnie,julia,ruby,lois,tina,phyllis,norma,paula,diana,annie,lillian,emily,robin,peggy,crystal,gladys,rita,dawn,connie,florence,tracy,edna,tiffany,carmen,rosa,cindy,grace,wendy,victoria,edith,kim,sherry,sylvia,josephine,thelma,shannon,sheila,ethel,ellen,elaine,marjorie,carrie,charlotte,monica,esther,pauline,emma,juanita,anita,rhonda,hazel,amber,eva,debbie,april,leslie,clara,lucille,jamie,joanne,eleanor,valerie,danielle,megan,alicia,suzanne,michele,gail,bertha,darlene,veronica,jill,erin,geraldine,lauren,cathy,joann,lorraine,lynn,sally,regina,erica,beatrice,dolores,bernice,audrey,yvonne,annette,june,marion,dana,stacy,ana,renee,ida,vivian,roberta,holly,brittany,melanie,loretta,yolanda,jeanette,laurie,katie,kristen,vanessa,alma,sue,elsie,beth,jeanne,vicki,carla,tara,rosemary,eileen,terri,gertrude,lucy,tonya,ella,stacey,wilma,gina,kristin,jessie,natalie,agnes,vera,charlene,bessie,delores,melinda,pearl,arlene,maureen,colleen,allison,tamara,joy,georgia,constance,lillie,claudia,jackie,marcia,tanya,nellie,minnie,marlene,heidi,glenda,lydia,viola,courtney,marian,stella,caroline,dora,jo,vickie,mattie,maxine,irma,mabel,marsha,myrtle,lena,christy,deanna,patsy,hilda,gwendolyn,jennie,nora,margie,nina,cassandra,leah,penny,kay,priscilla,naomi,carole,olga,billie,dianne,tracey,leona,jenny,felicia,sonia,miriam,velma,becky,bobbie,violet,kristina,toni,misty,mae,shelly,daisy,ramona,sherri,erika,katrina,claire,lindsey,lindsay,geneva,guadalupe,belinda,margarita,sheryl,cora,faye,ada,natasha,sabrina,isabel,marguerite,hattie,harriet,molly,cecilia,kristi,brandi,blanche,sandy,rosie,joanna,iris,eunice,angie,inez,lynda,madeline,amelia,alberta,genevieve,monique,jodi,janie,kayla,sonya,jan,kristine,candace,fannie,maryann,opal,alison,yvette,melody,luz,susie,olivia,flora,shelley,kristy,mamie,lula,lola,verna,beulah,antoinette,candice,juana,jeannette,pam,kelli,whitney,bridget,karla,celia,latoya,patty,shelia,gayle,della,vicky,lynne,sheri,marianne,kara,jacquelyn,erma,blanca,myra,leticia,pat,krista,roxanne,angelica,robyn,adrienne,rosalie,alexandra,brooke,bethany,sadie,bernadette,traci,jody,kendra,nichole,rachael,mable,ernestine,muriel,marcella,elena,krystal,angelina,nadine,kari,estelle,dianna,paulette,lora,mona,doreen,rosemarie,desiree,antonia,janis,betsy,christie,freda,meredith,lynette,teri,cristina,eula,leigh,meghan,sophia,eloise,rochelle,gretchen,cecelia,raquel,henrietta,alyssa,jana,gwen,jenna,tricia,laverne,olive,tasha,silvia,elvira,delia,kate,patti,lorena,kellie,sonja,lila,lana,darla,mindy,essie,mandy,lorene,elsa,josefina,jeannie,miranda,dixie,lucia,marta,faith,lela,johanna,shari,camille,tami,shawna,elisa,ebony,melba,ora,nettie,tabitha,ollie,winifred,kristie,marina,alisha,aimee,rena,myrna,marla,tammie,latasha,bonita,patrice,ronda,sherrie,addie,francine,deloris,stacie,adriana,cheri,abigail,celeste,jewel,cara,adele,rebekah,lucinda,dorthy,effie,trina,reba,sallie,aurora,lenora,etta,lottie,kerri,trisha,nikki,estella,francisca,josie,tracie,marissa,karin,brittney,janelle,lourdes,laurel,helene,fern,elva,corinne,kelsey,ina,bettie,elisabeth,aida,caitlin,ingrid,iva,eugenia,christa,goldie,maude,jenifer,therese,dena,lorna,janette,latonya,candy,consuelo,tamika,rosetta,debora,cherie,polly,dina,jewell,fay,jillian,dorothea,nell,trudy,esperanza,patrica,kimberley,shanna,helena,cleo,stefanie,rosario,ola,janine,mollie,lupe,alisa,lou,maribel,susanne,bette,susana,elise,cecile,isabelle,lesley,jocelyn,paige,joni,rachelle,leola,daphne,alta,ester,petra,graciela,imogene,jolene,keisha,lacey,glenna,gabriela,keri,ursula,lizzie,kirsten,shana,adeline,mayra,jayne,jaclyn,gracie,sondra,carmela,marisa,rosalind,charity,tonia,beatriz,marisol,clarice,jeanine,sheena,angeline,frieda,lily,shauna,millie,claudette,cathleen,angelia,gabrielle,autumn,katharine,jodie,staci,lea,christi,justine,elma,luella,margret,dominique,socorro,martina,margo,mavis,callie,bobbi,maritza,lucile,leanne,jeannine,deana,aileen,lorie,ladonna,willa,manuela,gale,selma,dolly,sybil,abby,ivy,dee,winnie,marcy,luisa,jeri,magdalena,ofelia,meagan,audra,matilda,leila,cornelia,bianca,simone,bettye,randi,virgie,latisha,barbra,georgina,eliza,leann,bridgette,rhoda,haley,adela,nola,bernadine,flossie,ila,greta,ruthie,nelda,minerva,lilly,terrie,letha,hilary,estela,valarie,brianna,rosalyn,earline,catalina,ava,mia,clarissa,lidia,corrine,alexandria,concepcion,tia,sharron,rae,dona,ericka,jami,elnora,chandra,lenore,neva,marylou,melisa,tabatha,serena,avis,allie,sofia,jeanie,odessa,nannie,harriett,loraine,penelope,milagros,emilia,benita,allyson,ashlee,tania,esmeralda,karina,eve,pearlie,zelma,malinda,noreen,tameka,saundra,hillary,amie,althea,rosalinda,lilia,alana,clare,alejandra,elinor,lorrie,jerri,darcy,earnestine,carmella,noemi,marcie,liza,annabelle,louisa,earlene,mallory,carlene,nita,selena,tanisha,katy,julianne,lakisha,edwina,maricela,margery,kenya,dollie,roxie,roslyn,kathrine,nanette,charmaine,lavonne,ilene,tammi,suzette,corine,kaye,chrystal,lina,deanne,lilian,juliana,aline,luann,kasey,maryanne,evangeline,colette,melva,lawanda,yesenia,nadia,madge,kathie,ophelia,valeria,nona,mitzi,mari,georgette,claudine,fran,alissa,roseann,lakeisha,susanna,reva,deidre,chasity,sheree,elvia,alyce,deirdre,gena,briana,araceli,katelyn,rosanne,wendi,tessa,berta,marva,imelda,marietta,marci,leonor,arline,sasha,madelyn,janna,juliette,deena,aurelia,josefa,augusta,liliana,lessie,amalia,savannah,anastasia,vilma,natalia,rosella,lynnette,corina,alfreda,leanna,amparo,coleen,tamra,aisha,wilda,karyn,queen,maura,mai,evangelina,rosanna,hallie,erna,enid,mariana,lacy,juliet,jacklyn,freida,madeleine,mara,cathryn,lelia,casandra,bridgett,angelita,jannie,dionne,annmarie,katina,beryl,millicent,katheryn,diann,carissa,maryellen,liz,lauri,helga,gilda,rhea,marquita,hollie,tisha,tamera,angelique,francesca,kaitlin,lolita,florine,rowena,reyna,twila,fanny,janell,ines,concetta,bertie,alba,brigitte,alyson,vonda,pansy,elba,noelle,letitia,deann,brandie,louella,leta,felecia,sharlene,lesa,beverley,isabella,herminia,terra,celina,tori,octavia,jade,denice,germaine,michell,cortney,nelly,doretha,deidra,monika,lashonda,judi,chelsey,antionette,margot,adelaide,nan,leeann,elisha,dessie,libby,kathi,gayla,latanya,mina,mellisa,kimberlee,jasmin,renae,zelda,elda,justina,gussie,emilie,camilla,abbie,rocio,kaitlyn,edythe,ashleigh,selina,lakesha,geri,allene,pamala,michaela,dayna,caryn,rosalia,sun,jacquline,rebeca,marybeth,krystle,iola,dottie,belle,griselda,ernestina,elida,adrianne,demetria,delma,jaqueline,arleen,virgina,retha,fatima,tillie,eleanore,cari,treva,wilhelmina,rosalee,maurine,latrice,jena,taryn,elia,debby,maudie,jeanna,delilah,catrina,shonda,hortencia,theodora,teresita,robbin,danette,delphine,brianne,nilda,danna,cindi,bess,iona,winona,vida,rosita,marianna,racheal,guillermina,eloisa,celestine,caren,malissa,lona,chantel,shellie,marisela,leora,agatha,soledad,migdalia,ivette,christen,janel,veda,pattie,tessie,tera,marilynn,lucretia,karrie,dinah,daniela,alecia,adelina,vernice,shiela,portia,merry,lashawn,dara,tawana,oma,verda,alene,zella,sandi,rafaela,maya,kira,candida,alvina,suzan,shayla,lyn,lettie,samatha,oralia,matilde,larissa,vesta,renita,india,delois,shanda,phillis,lorri,erlinda,cathrine,barb,zoe,isabell,ione,gisela,roxanna,mayme,kisha,ellie,mellissa,dorris,dalia,bella,annetta,zoila,reta,reina,lauretta,kylie,christal,pilar,charla,elissa,tiffani,tana,paulina,leota,breanna,jayme,carmel,vernell,tomasa,mandi,dominga,santa,melodie,lura,alexa,tamela,mirna,kerrie,venus,felicita,cristy,carmelita,berniece,annemarie,tiara,roseanne,missy,cori,roxana,pricilla,kristal,jung,elyse,haydee,aletha,bettina,marge,gillian,filomena,zenaida,harriette,caridad,vada,una,aretha,pearline,marjory,marcela,flor,evette,elouise,alina,damaris,catharine,belva,nakia,marlena,luanne,lorine,karon,dorene,danita,brenna,tatiana,louann,julianna,andria,philomena,lucila,leonora,dovie,romona,mimi,jacquelin,gaye,tonja,misti,chastity,stacia,roxann,micaela,nikita,mei,velda,marlys,johnna,aura,ivonne,hayley,nicki,majorie,herlinda,yadira,perla,gregoria,antonette,shelli,mozelle,mariah,joelle,cordelia,josette,chiquita,trista,laquita,georgiana,candi,shanon,hildegard,valentina,stephany,magda,karol,gabriella,tiana,roma,richelle,oleta,jacque,idella,alaina,suzanna,jovita,tosha,nereida,marlyn,kyla,delfina,tena,stephenie,sabina,nathalie,marcelle,gertie,darleen,thea,sharonda,shantel,belen,venessa,rosalina,ona,genoveva,clementine,rosalba,renate,renata,georgianna,floy,dorcas,ariana,tyra,theda,mariam,juli,jesica,vikki,verla,roselyn,melvina,jannette,ginny,debrah,corrie,asia,violeta,myrtis,latricia,collette,charleen,anissa,viviana,twyla,nedra,latonia,lan,hellen,fabiola,annamarie,adell,sharyn,chantal,niki,maud,lizette,lindy,kia,kesha,jeana,danelle,charline,chanel,valorie,lia,dortha,cristal,leone,leilani,gerri,debi,andra,keshia,ima,eulalia,easter,dulce,natividad,linnie,kami,georgie,catina,brook,alda,winnifred,sharla,ruthann,meaghan,magdalene,lissette,adelaida,venita,trena,shirlene,shameka,elizebeth,dian,shanta,latosha,carlotta,windy,rosina,mariann,leisa,jonnie,dawna,cathie,astrid,laureen,janeen,holli,fawn,vickey,teressa,shante,rubye,marcelina,chanda,terese,scarlett,marnie,lulu,lisette,jeniffer,elenor,dorinda,donita,carman,bernita,altagracia,aleta,adrianna,zoraida,nicola,lyndsey,janina,ami,starla,phylis,phuong,kyra,charisse,blanch,sanjuanita,rona,nanci,marilee,maranda,brigette,sanjuana,marita,kassandra,joycelyn,felipa,chelsie,bonny,mireya,lorenza,kyong,ileana,candelaria,sherie,lucie,leatrice,lakeshia,gerda,edie,bambi,marylin,lavon,hortense,garnet,evie,tressa,shayna,lavina,kyung,jeanetta,sherrill,shara,phyliss,mittie,anabel,alesia,thuy,tawanda,joanie,tiffanie,lashanda,karissa,enriqueta,daria,daniella,corinna,alanna,abbey,roxane,roseanna,magnolia,lida,joellen,era,coral,carleen,tresa,peggie,novella,nila,maybelle,jenelle,carina,nova,melina,marquerite,margarette,josephina,evonne,cinthia,albina,toya,tawnya,sherita,myriam,lizabeth,lise,keely,jenni,giselle,cheryle,ardith,ardis,alesha,adriane,shaina,linnea,karolyn,felisha,dori,darci,artie,armida,zola,xiomara,vergie,shamika,nena,nannette,maxie,lovie,jeane,jaimie,inge,farrah,elaina,caitlyn,felicitas,cherly,caryl,yolonda,yasmin,teena,prudence,pennie,nydia,mackenzie,orpha,marvel,lizbeth,laurette,jerrie,hermelinda,carolee,tierra,mirian,meta,melony,kori,jennette,jamila,ena,anh,yoshiko,susannah,salina,rhiannon,joleen,cristine,ashton,aracely,tomeka,shalonda,marti,lacie,kala,jada,ilse,hailey,brittani,zona,syble,sherryl,nidia,marlo,kandice,kandi,deb,alycia,ronna,norene,mercy,ingeborg,giovanna,gemma,christel,audry,zora,vita,trish,stephaine,shirlee,shanika,melonie,mazie,jazmin,inga,hoa,hettie,geralyn,fonda,estrella,adella,sarita,rina,milissa,maribeth,golda,evon,ethelyn,enedina,cherise,chana,velva,tawanna,sade,mirta,karie,jacinta,elna,davina,cierra,ashlie,albertha,tanesha,nelle,mindi,lorinda,larue,florene,demetra,dedra,ciara,chantelle,ashly,suzy,rosalva,noelia,lyda,leatha,krystyna,kristan,karri,darline,darcie,cinda,cherrie,awilda,almeda,rolanda,lanette,jerilyn,gisele,evalyn,cyndi,cleta,carin,zina,zena,velia,tanika,charissa,talia,margarete,lavonda,kaylee,kathlene,jonna,irena,ilona,idalia,candis,candance,brandee,anitra,alida,sigrid,nicolette,maryjo,linette,hedwig,christiana,alexia,tressie,modesta,lupita,lita,gladis,evelia,davida,cherri,cecily,ashely,annabel,agustina,wanita,shirly,rosaura,hulda,eun,yetta,verona,thomasina,sibyl,shannan,mechelle,lue,leandra,lani,kylee,kandy,jolynn,ferne,eboni,corene,alysia,zula,nada,moira,lyndsay,lorretta,jammie,hortensia,gaynell,adria,vina,vicenta,tangela,stephine,norine,nella,liana,leslee,kimberely,iliana,glory,felica,emogene,elfriede,eden,eartha,carma,bea,ocie,lennie,kiara,jacalyn,carlota,arielle,otilia,kirstin,kacey,johnetta,joetta,jeraldine,jaunita,elana,dorthea,cami,amada,adelia,vernita,tamar,siobhan,renea,rashida,ouida,nilsa,meryl,kristyn,julieta,danica,breanne,aurea,anglea,sherron,odette,malia,lorelei,leesa,kenna,kathlyn,fiona,charlette,suzie,shantell,sabra,racquel,myong,mira,martine,lucienne,lavada,juliann,elvera,delphia,christiane,charolette,carri,asha,angella,paola,ninfa,leda,lai,eda,stefani,shanell,palma,machelle,lissa,kecia,kathryne,karlene,julissa,jettie,jenniffer,hui,corrina,carolann,alena,rosaria,myrtice,marylee,liane,kenyatta,judie,janey,elmira,eldora,denna,cristi,cathi,zaida,vonnie,viva,vernie,rosaline,mariela,luciana,lesli,karan,felice,deneen,adina,wynona,tarsha,sheron,shanita,shani,shandra,randa,pinkie,nelida,marilou,lyla,laurene,laci,joi,janene,dorotha,daniele,dani,carolynn,carlyn,berenice,ayesha,anneliese,alethea,thersa,tamiko,rufina,oliva,mozell,marylyn,kristian,kathyrn,kasandra,kandace,janae,domenica,debbra,dannielle,arcelia,aja,zenobia,sharen,sharee,lavinia,kum,kacie,jackeline,huong,felisa,emelia,eleanora,cythia,cristin,claribel,anastacia,zulma,zandra,yoko,tenisha,susann,sherilyn,shay,shawanda,romana,mathilda,linsey,keiko,joana,isela,gretta,georgetta,eugenie,desirae,delora,corazon,antonina,anika,willene,tracee,tamatha,nichelle,mickie,maegan,luana,lanita,kelsie,edelmira,bree,afton,teodora,tamie,shena,meg,linh,keli,kaci,danyelle,arlette,albertine,adelle,tiffiny,simona,nicolasa,nichol,nia,nakisha,mee,maira,loreen,kizzy,fallon,christene,bobbye,vincenza,tanja,rubie,roni,queenie,margarett,kimberli,irmgard,idell,hilma,evelina,esta,emilee,dennise,dania,carie,wai,risa,rikki,particia,mui,masako,luvenia,loree,loni,lien,gigi,florencia,denita,billye,tomika,sharita,rana,nikole,neoma,margarite,madalyn,lucina,laila,kali,jenette,gabriele,evelyne,elenora,clementina,alejandrina,zulema,violette,vannessa,thresa,retta,pia,patience,noella,nickie,jonell,chaya,camelia,bethel,anya,suzann,shu,mila,lilla,laverna,keesha,kattie,georgene,eveline,estell,elizbeth,vivienne,vallie,trudie,stephane,magaly,madie,kenyetta,karren,janetta,hermine,drucilla,debbi,celestina,candie,britni,beckie,amina,zita,yun,yolande,vivien,vernetta,trudi,sommer,pearle,patrina,ossie,nicolle,loyce,letty,larisa,katharina,joselyn,jonelle,jenell,iesha,heide,florinda,florentina,flo,elodia,dorine,brunilda,brigid,ashli,ardella,twana,thu,tarah,shavon,serina,rayna,ramonita,nga,margurite,lucrecia,kourtney,kati,jesenia,crista,ayana,alica,alia,vinnie,suellen,romelia,rachell,olympia,michiko,kathaleen,jolie,jessi,janessa,hana,elease,carletta,britany,shona,salome,rosamond,regena,raina,ngoc,nelia,louvenia,lesia,latrina,laticia,larhonda,jina,jacki,emmy,deeann,coretta,arnetta,thalia,shanice,neta,mikki,micki,lonna,leana,lashunda,kiley,joye,jacqulyn,ignacia,hyun,hiroko,henriette,elayne,delinda,dahlia,coreen,consuela,conchita,celine,babette,ayanna,anette,albertina,shawnee,shaneka,quiana,pamelia,min,merri,merlene,margit,kiesha,kiera,kaylene,jodee,jenise,erlene,emmie,dalila,daisey,casie,belia,babara,versie,vanesa,shelba,shawnda,nikia,naoma,marna,margeret,madaline,lawana,kindra,jutta,jazmine,janett,hannelore,glendora,gertrud,garnett,freeda,frederica,florance,flavia,carline,beverlee,anjanette,valda,tamala,shonna,sha,sarina,oneida,merilyn,marleen,lurline,lenna,katherin,jin,jeni,hae,gracia,glady,farah,enola,ema,dominque,devona,delana,cecila,caprice,alysha,alethia,vena,theresia,tawny,shakira,samara,sachiko,rachele,pamella,marni,mariel,maren,malisa,ligia,lera,latoria,larae,kimber,kathern,karey,jennefer,janeth,halina,fredia,delisa,debroah,ciera,angelika,andree,altha,yen,vivan,terresa,tanna,suk,sudie,soo,signe,salena,ronni,rebbecca,myrtie,malika,maida,loan,leonarda,kayleigh,ethyl,ellyn,dayle,cammie,brittni,birgit,avelina,asuncion,arianna,akiko,venice,tyesha,tonie,tiesha,takisha,steffanie,sindy,meghann,manda,macie,kellye,kellee,joslyn,inger,indira,glinda,glennis,fernanda,faustina,eneida,elicia,dot,digna,dell,arletta,willia,tammara,tabetha,sherrell,sari,rebbeca,pauletta,natosha,nakita,mammie,kenisha,kazuko,kassie,earlean,daphine,corliss,clotilde,carolyne,bernetta,augustina,audrea,annis,annabell,yan,tennille,tamica,selene,rosana,regenia,qiana,markita,macy,leeanne,laurine,kym,jessenia,janita,georgine,genie,emiko,elvie,deandra,dagmar,corie,collen,cherish,romaine,porsha,pearlene,micheline,merna,margorie,margaretta,lore,jenine,hermina,fredericka,elke,drusilla,dorathy,dione,celena,brigida,angeles,allegra,tamekia,synthia,sook,slyvia,rosann,reatha,raye,marquetta,margart,layla,kymberly,kiana,kayleen,katlyn,karmen,joella,irina,emelda,eleni,detra,clemmie,cheryll,chantell,cathey,arnita,arla,angle,angelic,alyse,zofia,thomasine,tennie,sherly,sherley,sharyl,remedios,petrina,nickole,myung,myrle,mozella,louanne,lisha,latia,krysta,julienne,jeanene,jacqualine,isaura,gwenda,earleen,cleopatra,carlie,audie,antonietta,alise,verdell,tomoko,thao,talisha,shemika,savanna,santina,rosia,raeann,odilia,nana,minna,magan,lynelle,karma,joeann,ivana,inell,ilana,hye,hee,gudrun,dreama,crissy,chante,carmelina,arvilla,annamae,alvera,aleida,yanira,vanda,tianna,tam,stefania,shira,nicol,nancie,monserrate,melynda,melany,lovella,laure,kacy,jacquelynn,hyon,gertha,eliana,christena,christeen,charise,caterina,carley,candyce,arlena,ammie,willette,vanita,tuyet,syreeta,penney,nyla,maryam,marya,magen,ludie,loma,livia,lanell,kimberlie,julee,donetta,diedra,denisha,deane,dawne,clarine,cherryl,bronwyn,alla,valery,tonda,sueann,soraya,shoshana,shela,sharleen,shanelle,nerissa,meridith,mellie,maye,maple,magaret,lili,leonila,leonie,leeanna,lavonia,lavera,kristel,kathey,kathe,jann,ilda,hildred,hildegarde,genia,fumiko,evelin,ermelinda,elly,dung,doloris,dionna,danae,berneice,annice,alix,verena,verdie,shawnna,shawana,shaunna,rozella,randee,ranae,milagro,lynell,luise,loida,lisbeth,karleen,junita,jona,isis,hyacinth,hedy,gwenn,ethelene,erline,donya,domonique,delicia,dannette,cicely,branda,blythe,bethann,ashlyn,annalee,alline,yuko,vella,trang,towanda,tesha,sherlyn,narcisa,miguelina,meri,maybell,marlana,marguerita,madlyn,lory,loriann,leonore,leighann,laurice,latesha,laronda,katrice,kasie,kaley,jadwiga,glennie,gearldine,francina,epifania,dyan,dorie,diedre,denese,demetrice,delena,cristie,cleora,catarina,carisa,barbera,almeta,trula,tereasa,solange,sheilah,shavonne,sanora,rochell,mathilde,margareta,maia,lynsey,lawanna,launa,kena,keena,katia,glynda,gaylene,elvina,elanor,danuta,danika,cristen,cordie,coletta,clarita,carmon,brynn,azucena,aundrea,angele,verlie,verlene,tamesha,silvana,sebrina,samira,reda,raylene,penni,norah,noma,mireille,melissia,maryalice,laraine,kimbery,karyl,karine,kam,jolanda,johana,jesusa,jaleesa,jacquelyne,iluminada,hilaria,hanh,gennie,francie,floretta,exie,edda,drema,delpha,bev,barbar,assunta,ardell,annalisa,alisia,yukiko,yolando,wonda,wei,waltraud,veta,temeka,tameika,shirleen,shenita,piedad,ozella,mirtha,marilu,kimiko,juliane,jenice,janay,jacquiline,hilde,fae,elois,echo,devorah,chau,brinda,betsey,arminda,aracelis,apryl,annett,alishia,veola,usha,toshiko,theola,tashia,talitha,shery,renetta,reiko,rasheeda,obdulia,mika,melaine,meggan,marlen,marget,marceline,mana,magdalen,librada,lezlie,latashia,lasandra,kelle,isidra,isa,inocencia,gwyn,francoise,erminia,erinn,dimple,devora,criselda,armanda,arie,ariane,angelena,aliza,adriene,adaline,xochitl,twanna,tomiko,tamisha,taisha,susy,siu,rutha,rhona,noriko,natashia,merrie,marinda,mariko,margert,loris,lizzette,leisha,kaila,joannie,jerrica,jene,jannet,janee,jacinda,herta,elenore,doretta,delaine,daniell,claudie,britta,apolonia,amberly,alease,yuri,yuk,wen,waneta,ute,tomi,sharri,sandie,roselle,reynalda,raguel,phylicia,patria,olimpia,odelia,mitzie,minda,mignon,mica,mendy,marivel,maile,lynetta,lavette,lauryn,latrisha,lakiesha,kiersten,kary,josphine,jolyn,jetta,janise,jacquie,ivelisse,glynis,gianna,gaynelle,danyell,danille,dacia,coralee,cher,ceola,arianne,aleshia,yung,williemae,trinh,thora,tai,svetlana,sherika,shemeka,shaunda,roseline,ricki,melda,mallie,lavonna,latina,laquanda,lala,lachelle,klara,kandis,johna,jeanmarie,jaye,grayce,gertude,emerita,ebonie,clorinda,ching,chery,carola,breann,blossom,bernardine,becki,arletha,argelia,ara,alita,yulanda,yon,yessenia,tobi,tasia,sylvie,shirl,shirely,shella,shantelle,sacha,rebecka,providencia,paulene,misha,miki,marline,marica,lorita,latoyia,lasonya,kerstin,kenda,keitha,kathrin,jaymie,gricelda,ginette,eryn,elina,elfrieda,danyel,cheree,chanelle,barrie,aurore,annamaria,alleen,ailene,aide,yasmine,vashti,treasa,tiffaney,sheryll,sharie,shanae,sau,raisa,neda,mitsuko,mirella,milda,maryanna,maragret,mabelle,luetta,lorina,letisha,latarsha,lanelle,lajuana,krissy,karly,karena,jessika,jerica,jeanelle,jalisa,jacelyn,izola,euna,etha,domitila,dominica,daina,creola,carli,camie,brittny,ashanti,anisha,aleen,adah,yasuko,valrie,tona,tinisha,thi,terisa,taneka,simonne,shalanda,serita,ressie,refugia,olene,margherita,mandie,maire,lyndia,luci,lorriane,loreta,leonia,lavona,lashawnda,lakia,kyoko,krystina,krysten,kenia,kelsi,jeanice,isobel,georgiann,genny,felicidad,eilene,deloise,conception,clora,cherilyn,calandra,armandina,anisa,ula,tiera,theressa,stephania,sima,shyla,shonta,shera,shaquita,shala,rossana,nohemi,nery,moriah,melita,melida,melani,marylynn,marisha,mariette,malorie,madelene,ludivina,loria,lorette,loralee,lianne,lavenia,laurinda,lashon,kit,kimi,keila,katelynn,kai,jone,joane,jayna,janella,hue,hertha,francene,elinore,despina,delsie,deedra,clemencia,carolin,bulah,brittanie,bok,blondell,bibi,beaulah,beata,annita,agripina,virgen,valene,twanda,tommye,toi,tarra,tari,tammera,shakia,sadye,ruthanne,rochel,rivka,pura,nenita,natisha,merrilee,melodee,marvis,lucilla,leena,laveta,larita,lanie,keren,ileen,georgeann,genna,frida,ewa,eufemia,emely,ela,edyth,deonna,deadra,darlena,chanell,cathern,cassondra,cassaundra,bernarda,berna,arlinda,anamaria,vertie,valeri,torri,tatyana,stasia,sherise,sherill,sanda,ruthe,rosy,robbi,ranee,quyen,pearly,palmira,onita,nisha,niesha,nida,nam,merlyn,mayola,marylouise,marth,margene,madelaine,londa,leontine,leoma,leia,lauralee,lanora,lakita,kiyoko,keturah,katelin,kareen,jonie,johnette,jenee,jeanett,izetta,hiedi,heike,hassie,giuseppina,georgann,fidela,fernande,elwanda,ellamae,eliz,dusti,dotty,cyndy,coralie,celesta,argentina,alverta,xenia,wava,vanetta,torrie,tashina,tandy,tambra,tama,stepanie,shila,shaunta,sharan,shaniqua,shae,setsuko,serafina,sandee,rosamaria,priscila,olinda,nadene,muoi,michelina,mercedez,maryrose,marcene,mao,magali,mafalda,lannie,kayce,karoline,kamilah,kamala,justa,joline,jennine,jacquetta,iraida,georgeanna,franchesca,emeline,elane,ehtel,earlie,dulcie,dalene,classie,chere,charis,caroyln,carmina,carita,bethanie,ayako,arica,alysa,alessandra,akilah,adrien,zetta,youlanda,yelena,yahaira,wendolyn,tijuana,terina,teresia,suzi,sherell,shavonda,shaunte,sharda,shakita,sena,ryann,rubi,riva,reginia,rachal,parthenia,pamula,monnie,monet,michaele,melia,malka,maisha,lisandra,lekisha,lean,lakendra,krystin,kortney,kizzie,kittie,kera,kendal,kemberly,kanisha,julene,jule,johanne,jamee,halley,gidget,galina,fredricka,fleta,fatimah,eusebia,elza,eleonore,dorthey,doria,donella,dinorah,delorse,claretha,christinia,charlyn,bong,belkis,azzie,andera,aiko,adena,yer,yajaira,wan,vania,ulrike,toshia,tifany,stefany,shizue,shenika,shawanna,sharolyn,sharilyn,shaquana,shantay,rozanne,roselee,remona,reanna,raelene,phung,petronila,natacha,nancey,myrl,miyoko,miesha,merideth,marvella,marquitta,marhta,marchelle,lizeth,libbie,lahoma,ladawn,kina,katheleen,katharyn,karisa,kaleigh,junie,julieann,johnsie,janean,jaimee,jackqueline,hisako,herma,helaine,gwyneth,gita,eustolia,emelina,elin,edris,donnette,donnetta,dierdre,denae,darcel,clarisa,cinderella,chia,charlesetta,charita,celsa,cassy,cassi,carlee,bruna,brittaney,brande,billi,bao,antonetta,angla,angelyn,analisa,alane,wenona,wendie,veronique,vannesa,tobie,tempie,sumiko,sulema,sparkle,somer,sheba,sharice,shanel,shalon,rosio,roselia,renay,rema,reena,ozie,oretha,oralee,oda,ngan,nakesha,milly,marybelle,margrett,maragaret,manie,lurlene,lillia,lieselotte,lavelle,lashaunda,lakeesha,kaycee,kalyn,joya,joette,jenae,janiece,illa,grisel,glayds,genevie,gala,fredda,eleonor,debera,deandrea,corrinne,cordia,contessa,colene,cleotilde,chantay,cecille,beatris,azalee,arlean,ardath,anjelica,anja,alfredia,aleisha,zada,yuonne,willodean,vennie,vanna,tyisha,tova,torie,tonisha,tilda,tien,sirena,sherril,shanti,senaida,samella,robbyn,renda,reita,phebe,paulita,nobuko,nguyet,neomi,mikaela,melania,maximina,marg,maisie,lynna,lilli,lashaun,lakenya,lael,kirstie,kathline,kasha,karlyn,karima,jovan,josefine,jennell,jacqui,jackelyn,hyo,hien,grazyna,florrie,floria,eleonora,dwana,dorla,delmy,deja,dede,dann,crysta,clelia,claris,chieko,cherlyn,cherelle,charmain,chara,cammy,bee,arnette,ardelle,annika,amiee,amee,allena,yvone,yuki,yoshie,yevette,yael,willetta,voncile,venetta,tula,tonette,timika,temika,telma,teisha,taren,stacee,shawnta,saturnina,ricarda,pok,pasty,onie,nubia,marielle,mariella,marianela,mardell,luanna,loise,lisabeth,lindsy,lilliana,lilliam,lelah,leigha,leanora,kristeen,khalilah,keeley,kandra,junko,joaquina,jerlene,jani,jamika,hsiu,hermila,genevive,evia,eugena,emmaline,elfreda,elene,donette,delcie,deeanna,darcey,cuc,clarinda,cira,chae,celinda,catheryn,casimira,carmelia,camellia,breana,bobette,bernardina,bebe,basilia,arlyne,amal,alayna,zonia,zenia,yuriko,yaeko,wynell,willena,vernia,tora,terrilyn,terica,tenesha,tawna,tajuana,taina,stephnie,sona,sina,shondra,shizuko,sherlene,sherice,sharika,rossie,rosena,rima,ria,rheba,renna,natalya,nancee,melodi,meda,matha,marketta,maricruz,marcelene,malvina,luba,louetta,leida,lecia,lauran,lashawna,laine,khadijah,katerine,kasi,kallie,julietta,jesusita,jestine,jessia,jeffie,janyce,isadora,georgianne,fidelia,evita,eura,eulah,estefana,elsy,eladia,dodie,dia,denisse,deloras,delila,daysi,crystle,concha,claretta,charlsie,charlena,carylon,bettyann,asley,ashlea,amira,agueda,agnus,yuette,vinita,victorina,tynisha,treena,toccara,tish,thomasena,tegan,soila,shenna,sharmaine,shantae,shandi,september,saran,sarai,sana,rosette,rolande,regine,otelia,olevia,nicholle,necole,naida,myrta,myesha,mitsue,minta,mertie,margy,mahalia,madalene,loura,lorean,lesha,leonida,lenita,lavone,lashell,lashandra,lamonica,kimbra,katherina,karry,kanesha,jong,jeneva,jaquelyn,hwa,gilma,ghislaine,gertrudis,fransisca,fermina,ettie,etsuko,ellan,elidia,edra,dorethea,doreatha,denyse,deetta,daine,cyrstal,corrin,cayla,carlita,camila,burma,bula,buena,barabara,avril,alaine,zana,wilhemina,wanetta,veronika,verline,vasiliki,tonita,tisa,teofila,tayna,taunya,tandra,takako,sunni,suanne,sixta,sharell,seema,rosenda,robena,raymonde,pei,pamila,ozell,neida,mistie,micha,merissa,maurita,maryln,maryetta,marcell,malena,makeda,lovetta,lourie,lorrine,lorilee,laurena,lashay,larraine,laree,lacresha,kristle,krishna,keva,keira,karole,joie,jinny,jeannetta,jama,heidy,gilberte,gema,faviola,evelynn,enda,elli,ellena,divina,dagny,collene,codi,cindie,chassidy,chasidy,catrice,catherina,cassey,caroll,carlena,candra,calista,bryanna,britteny,beula,bari,audrie,audria,ardelia,annelle,angila,alona,allyn".split(","))),
-o("surnames",r("smith,johnson,williams,jones,brown,davis,miller,wilson,moore,taylor,anderson,jackson,white,harris,martin,thompson,garcia,martinez,robinson,clark,rodriguez,lewis,lee,walker,hall,allen,young,hernandez,king,wright,lopez,hill,green,adams,baker,gonzalez,nelson,carter,mitchell,perez,roberts,turner,phillips,campbell,parker,evans,edwards,collins,stewart,sanchez,morris,rogers,reed,cook,morgan,bell,murphy,bailey,rivera,cooper,richardson,cox,howard,ward,torres,peterson,gray,ramirez,watson,brooks,sanders,price,bennett,wood,barnes,ross,henderson,coleman,jenkins,perry,powell,long,patterson,hughes,flores,washington,butler,simmons,foster,gonzales,bryant,alexander,griffin,diaz,hayes,myers,ford,hamilton,graham,sullivan,wallace,woods,cole,west,owens,reynolds,fisher,ellis,harrison,gibson,mcdonald,cruz,marshall,ortiz,gomez,murray,freeman,wells,webb,simpson,stevens,tucker,porter,hicks,crawford,boyd,mason,morales,kennedy,warren,dixon,ramos,reyes,burns,gordon,shaw,holmes,rice,robertson,hunt,daniels,palmer,mills,nichols,grant,ferguson,stone,hawkins,dunn,perkins,hudson,spencer,gardner,stephens,payne,pierce,berry,matthews,arnold,wagner,willis,watkins,olson,carroll,duncan,snyder,hart,cunningham,lane,andrews,ruiz,harper,fox,riley,armstrong,carpenter,weaver,greene,elliott,chavez,sims,peters,kelley,franklin,lawson,fields,gutierrez,schmidt,carr,vasquez,castillo,wheeler,chapman,oliver,montgomery,richards,williamson,johnston,banks,meyer,bishop,mccoy,howell,alvarez,morrison,hansen,fernandez,garza,burton,nguyen,jacobs,reid,fuller,lynch,garrett,romero,welch,larson,frazier,burke,hanson,mendoza,moreno,bowman,medina,fowler,brewer,hoffman,carlson,silva,pearson,holland,fleming,jensen,vargas,byrd,davidson,hopkins,may,herrera,wade,soto,walters,neal,caldwell,lowe,jennings,barnett,graves,jimenez,horton,shelton,barrett,obrien,castro,sutton,mckinney,lucas,miles,rodriquez,chambers,holt,lambert,fletcher,watts,bates,hale,rhodes,pena,beck,newman,haynes,mcdaniel,mendez,bush,vaughn,parks,dawson,santiago,norris,hardy,steele,curry,powers,schultz,barker,guzman,page,munoz,ball,keller,chandler,weber,walsh,lyons,ramsey,wolfe,schneider,mullins,benson,sharp,bowen,barber,cummings,hines,baldwin,griffith,valdez,hubbard,salazar,reeves,warner,stevenson,burgess,santos,tate,cross,garner,mann,mack,moss,thornton,mcgee,farmer,delgado,aguilar,vega,glover,manning,cohen,harmon,rodgers,robbins,newton,blair,higgins,ingram,reese,cannon,strickland,townsend,potter,goodwin,walton,rowe,hampton,ortega,patton,swanson,goodman,maldonado,yates,becker,erickson,hodges,rios,conner,adkins,webster,malone,hammond,flowers,cobb,moody,quinn,pope,osborne,mccarthy,guerrero,estrada,sandoval,gibbs,gross,fitzgerald,stokes,doyle,saunders,wise,colon,gill,alvarado,greer,padilla,waters,nunez,ballard,schwartz,mcbride,houston,christensen,klein,pratt,briggs,parsons,mclaughlin,zimmerman,french,buchanan,moran,copeland,pittman,brady,mccormick,holloway,brock,poole,logan,bass,marsh,drake,wong,jefferson,park,morton,abbott,sparks,norton,huff,massey,figueroa,carson,bowers,roberson,barton,tran,lamb,harrington,boone,cortez,clarke,mathis,singleton,wilkins,cain,underwood,hogan,mckenzie,collier,luna,phelps,mcguire,bridges,wilkerson,nash,summers,atkins,wilcox,pitts,conley,marquez,burnett,cochran,chase,davenport,hood,gates,ayala,sawyer,vazquez,dickerson,hodge,acosta,flynn,espinoza,nicholson,monroe,morrow,whitaker,oconnor,skinner,ware,molina,kirby,huffman,gilmore,dominguez,oneal,lang,combs,kramer,hancock,gallagher,gaines,shaffer,short,wiggins,mathews,mcclain,fischer,wall,small,melton,hensley,bond,dyer,grimes,contreras,wyatt,baxter,snow,mosley,shepherd,larsen,hoover,beasley,petersen,whitehead,meyers,garrison,shields,horn,savage,olsen,schroeder,hartman,woodard,mueller,kemp,deleon,booth,patel,calhoun,wiley,eaton,cline,navarro,harrell,humphrey,parrish,duran,hutchinson,hess,dorsey,bullock,robles,beard,dalton,avila,rich,blackwell,york,johns,blankenship,trevino,salinas,campos,pruitt,callahan,montoya,hardin,guerra,mcdowell,stafford,gallegos,henson,wilkinson,booker,merritt,atkinson,orr,decker,hobbs,tanner,knox,pacheco,stephenson,glass,rojas,serrano,marks,hickman,english,sweeney,strong,mcclure,conway,roth,maynard,farrell,lowery,hurst,nixon,weiss,trujillo,ellison,sloan,juarez,winters,mclean,boyer,villarreal,mccall,gentry,carrillo,ayers,lara,sexton,pace,hull,leblanc,browning,velasquez,leach,chang,sellers,herring,noble,foley,bartlett,mercado,landry,durham,walls,barr,mckee,bauer,rivers,bradshaw,pugh,velez,rush,estes,dodson,morse,sheppard,weeks,camacho,bean,barron,livingston,middleton,spears,branch,blevins,chen,kerr,mcconnell,hatfield,harding,solis,frost,giles,blackburn,pennington,woodward,finley,mcintosh,koch,mccullough,blanchard,rivas,brennan,mejia,kane,benton,buckley,valentine,maddox,russo,mcknight,buck,moon,mcmillan,crosby,berg,dotson,mays,roach,church,chan,richmond,meadows,faulkner,oneill,knapp,kline,ochoa,jacobson,gay,hendricks,horne,shepard,hebert,cardenas,mcintyre,waller,holman,donaldson,cantu,morin,gillespie,fuentes,tillman,bentley,peck,key,salas,rollins,gamble,dickson,battle,santana,cabrera,cervantes,howe,hinton,hurley,spence,zamora,yang,mcneil,suarez,petty,gould,mcfarland,sampson,carver,bray,macdonald,stout,hester,melendez,dillon,farley,hopper,galloway,potts,joyner,stein,aguirre,osborn,mercer,bender,franco,rowland,sykes,pickett,sears,mayo,dunlap,hayden,wilder,mckay,coffey,mccarty,ewing,cooley,vaughan,bonner,cotton,holder,stark,ferrell,cantrell,fulton,lott,calderon,pollard,hooper,burch,mullen,fry,riddle,levy,odonnell,britt,daugherty,berger,dillard,alston,frye,riggs,chaney,odom,duffy,fitzpatrick,valenzuela,mayer,alford,mcpherson,acevedo,barrera,cote,reilly,compton,mooney,mcgowan,craft,clemons,wynn,nielsen,baird,stanton,snider,rosales,bright,witt,hays,holden,rutledge,kinney,clements,castaneda,slater,hahn,burks,delaney,pate,lancaster,sharpe,whitfield,talley,macias,burris,ratliff,mccray,madden,kaufman,goff,cash,bolton,mcfadden,levine,byers,kirkland,kidd,workman,carney,mcleod,holcomb,england,finch,sosa,haney,franks,sargent,nieves,downs,rasmussen,bird,hewitt,foreman,valencia,oneil,delacruz,vinson,dejesus,hyde,forbes,gilliam,guthrie,wooten,huber,barlow,boyle,mcmahon,buckner,rocha,puckett,langley,knowles,cooke,velazquez,whitley,vang,shea,rouse,hartley,mayfield,elder,rankin,hanna,cowan,lucero,arroyo,slaughter,haas,oconnell,minor,boucher,archer,boggs,dougherty,andersen,newell,crowe,wang,friedman,bland,swain,holley,pearce,childs,yarbrough,galvan,proctor,meeks,lozano,mora,rangel,bacon,villanueva,schaefer,rosado,helms,boyce,goss,stinson,lake,ibarra,hutchins,covington,crowley,hatcher,mackey,bunch,womack,polk,dodd,childress,childers,camp,villa,dye,springer,mahoney,dailey,belcher,lockhart,griggs,costa,brandt,walden,moser,tatum,mccann,akers,lutz,pryor,orozco,mcallister,lugo,davies,shoemaker,rutherford,newsome,magee,chamberlain,blanton,simms,godfrey,flanagan,crum,cordova,escobar,downing,sinclair,donahue,krueger,mcginnis,gore,farris,webber,corbett,andrade,starr,lyon,yoder,hastings,mcgrath,spivey,krause,harden,crabtree,kirkpatrick,arrington,ritter,mcghee,bolden,maloney,gagnon,dunbar,ponce,pike,mayes,beatty,mobley,kimball,butts,montes,eldridge,braun,hamm,gibbons,moyer,manley,herron,plummer,elmore,cramer,rucker,pierson,fontenot,field,rubio,goldstein,elkins,wills,novak,hickey,worley,gorman,katz,dickinson,broussard,woodruff,crow,britton,nance,lehman,bingham,zuniga,whaley,shafer,coffman,steward,delarosa,nix,neely,mata,davila,mccabe,kessler,hinkle,welsh,pagan,goldberg,goins,crouch,cuevas,quinones,mcdermott,hendrickson,samuels,denton,bergeron,lam,ivey,locke,haines,snell,hoskins,byrne,arias,roe,corbin,beltran,chappell,downey,dooley,tuttle,couch,payton,mcelroy,crockett,groves,cartwright,dickey,mcgill,dubois,muniz,tolbert,dempsey,cisneros,sewell,latham,vigil,tapia,rainey,norwood,stroud,meade,tipton,kuhn,hilliard,bonilla,teague,gunn,greenwood,correa,reece,poe,pineda,phipps,frey,kaiser,ames,gunter,schmitt,milligan,espinosa,bowden,vickers,lowry,pritchard,costello,piper,mcclellan,lovell,sheehan,hatch,dobson,singh,jeffries,hollingsworth,sorensen,meza,fink,donnelly,burrell,tomlinson,colbert,billings,ritchie,helton,sutherland,peoples,mcqueen,thomason,givens,crocker,vogel,robison,dunham,coker,swartz,keys,ladner,richter,hargrove,edmonds,brantley,albright,murdock,boswell,muller,quintero,padgett,kenney,daly,connolly,inman,quintana,lund,barnard,villegas,simons,land,huggins,tidwell,sanderson,bullard,mcclendon,duarte,draper,marrero,dwyer,abrams,stover,goode,fraser,crews,bernal,godwin,conklin,mcneal,baca,esparza,crowder,bower,brewster,mcneill,rodrigues,leal,coates,raines,mccain,mccord,miner,holbrook,swift,dukes,carlisle,aldridge,ackerman,starks,ricks,holliday,ferris,hairston,sheffield,lange,fountain,doss,betts,kaplan,carmichael,bloom,ruffin,penn,kern,bowles,sizemore,larkin,dupree,seals,metcalf,hutchison,henley,farr,mccauley,hankins,gustafson,curran,ash,waddell,ramey,cates,pollock,cummins,messer,heller,lin,funk,cornett,palacios,galindo,cano,hathaway,singer,pham,enriquez,salgado,pelletier,painter,wiseman,blount,feliciano,temple,houser,doherty,mead,mcgraw,swan,capps,blanco,blackmon,thomson,mcmanus,burkett,post,gleason,ott,dickens,cormier,voss,rushing,rosenberg,hurd,dumas,benitez,arellano,marin,caudill,bragg,jaramillo,huerta,gipson,colvin,biggs,vela,platt,cassidy,tompkins,mccollum,dolan,daley,crump,sneed,kilgore,grove,grimm,davison,brunson,prater,marcum,devine,stratton,rosas,choi,tripp,ledbetter,hightower,feldman,epps,yeager,posey,scruggs,cope,stubbs,richey,overton,trotter,sprague,cordero,butcher,stiles,burgos,woodson,horner,bassett,purcell,haskins,akins,ziegler,spaulding,hadley,grubbs,sumner,murillo,zavala,shook,lockwood,driscoll,dahl,thorpe,redmond,putnam,mcwilliams,mcrae,romano,joiner,sadler,hedrick,hager,hagen,fitch,coulter,thacker,mansfield,langston,guidry,ferreira,corley,conn,rossi,lackey,baez,saenz,mcnamara,mcmullen,mckenna,mcdonough,link,engel,browne,roper,peacock,eubanks,drummond,stringer,pritchett,parham,mims,landers,ham,grayson,schafer,egan,timmons,ohara,keen,hamlin,finn,cortes,mcnair,nadeau,moseley,michaud,rosen,oakes,kurtz,jeffers,calloway,beal,bautista,winn,suggs,stern,stapleton,lyles,laird,montano,dawkins,hagan,goldman,bryson,barajas,lovett,segura,metz,lockett,langford,hinson,eastman,hooks,smallwood,shapiro,crowell,whalen,triplett,chatman,aldrich,cahill,youngblood,ybarra,stallings,sheets,reeder,connelly,bateman,abernathy,winkler,wilkes,masters,hackett,granger,gillis,schmitz,sapp,napier,souza,lanier,gomes,weir,otero,ledford,burroughs,babcock,ventura,siegel,dugan,bledsoe,atwood,wray,varner,spangler,anaya,staley,kraft,fournier,belanger,wolff,thorne,bynum,burnette,boykin,swenson,purvis,pina,khan,duvall,darby,xiong,kauffman,healy,engle,benoit,valle,steiner,spicer,shaver,randle,lundy,dow,chin,calvert,staton,neff,kearney,darden,oakley,medeiros,mccracken,crenshaw,block,perdue,dill,whittaker,tobin,washburn,hogue,goodrich,easley,bravo,dennison,shipley,kerns,jorgensen,crain,villalobos,maurer,longoria,keene,coon,witherspoon,staples,pettit,kincaid,eason,madrid,echols,lusk,stahl,currie,thayer,shultz,mcnally,seay,north,maher,gagne,barrow,nava,moreland,honeycutt,hearn,diggs,caron,whitten,westbrook,stovall,ragland,munson,meier,looney,kimble,jolly,hobson,goddard,culver,burr,presley,negron,connell,tovar,huddleston,ashby,salter,root,pendleton,oleary,nickerson,myrick,judd,jacobsen,bain,adair,starnes,matos,busby,herndon,hanley,bellamy,doty,bartley,yazzie,rowell,parson,gifford,cullen,christiansen,benavides,barnhart,talbot,mock,crandall,connors,bonds,whitt,gage,bergman,arredondo,addison,lujan,dowdy,jernigan,huynh,bouchard,dutton,rhoades,ouellette,kiser,herrington,hare,blackman,babb,allred,rudd,paulson,ogden,koenig,geiger,begay,parra,lassiter,hawk,esposito,cho,waldron,ransom,prather,chacon,vick,sands,roark,parr,mayberry,greenberg,coley,bruner,whitman,skaggs,shipman,leary,hutton,romo,medrano,ladd,kruse,askew,schulz,alfaro,tabor,mohr,gallo,bermudez,pereira,bliss,reaves,flint,comer,woodall,naquin,guevara,delong,carrier,pickens,brand,tilley,schaffer,lim,knutson,fenton,doran,chu,vogt,vann,prescott,mclain,landis,corcoran,zapata,hyatt,hemphill,faulk,dove,boudreaux,aragon,whitlock,trejo,tackett,shearer,saldana,hanks,mckinnon,koehler,bourgeois,keyes,goodson,foote,lunsford,goldsmith,flood,winslow,sams,reagan,mccloud,hough,esquivel,naylor,loomis,coronado,ludwig,braswell,bearden,fagan,ezell,edmondson,cyr,cronin,nunn,lemon,guillory,grier,dubose,traylor,ryder,dobbins,coyle,aponte,whitmore,smalls,rowan,malloy,cardona,braxton,borden,humphries,carrasco,ruff,metzger,huntley,hinojosa,finney,madsen,hills,ernst,dozier,burkhart,bowser,peralta,daigle,whittington,sorenson,saucedo,roche,redding,fugate,avalos,waite,lind,huston,hay,hawthorne,hamby,boyles,boles,regan,faust,crook,beam,barger,hinds,gallardo,willoughby,willingham,eckert,busch,zepeda,worthington,tinsley,hoff,hawley,carmona,varela,rector,newcomb,kinsey,dube,whatley,ragsdale,bernstein,becerra,yost,mattson,felder,cheek,handy,grossman,gauthier,escobedo,braden,beckman,mott,hillman,flaherty,dykes,doe,stockton,stearns,lofton,coats,cavazos,beavers,barrios,parish,mosher,cardwell,coles,burnham,weller,lemons,beebe,aguilera,parnell,harman,couture,alley,schumacher,redd,dobbs,blum,blalock,merchant,ennis,denson,cottrell,brannon,bagley,aviles,watt,sousa,rosenthal,rooney,dietz,blank,paquette,mcclelland,duff,velasco,lentz,grubb,burrows,barbour,ulrich,shockley,rader,beyer,mixon,layton,altman,weathers,stoner,squires,shipp,priest,lipscomb,cutler,caballero,zimmer,willett,thurston,storey,medley,epperson,shah,mcmillian,baggett,torrez,laws,hirsch,dent,poirier,peachey,farrar,creech,barth,trimble,dupre,albrecht,sample,lawler,crisp,conroy,wetzel,nesbitt,murry,jameson,wilhelm,patten,minton,matson,kimbrough,iverson,guinn,croft,toth,pulliam,nugent,newby,littlejohn,dias,canales,bernier,baron,singletary,renteria,pruett,mchugh,mabry,landrum,brower,stoddard,cagle,stjohn,scales,kohler,kellogg,hopson,gant,tharp,gann,zeigler,pringle,hammons,fairchild,deaton,chavis,carnes,rowley,matlock,kearns,irizarry,carrington,starkey,lopes,jarrell,craven,baum,spain,littlefield,linn,humphreys,etheridge,cuellar,chastain,bundy,speer,skelton,quiroz,pyle,portillo,ponder,moulton,machado,liu,killian,hutson,hitchcock,dowling,cloud,burdick,spann,pedersen,levin,leggett,hayward,hacker,dietrich,beaulieu,barksdale,wakefield,snowden,briscoe,bowie,berman,ogle,mcgregor,laughlin,helm,burden,wheatley,schreiber,pressley,parris,alaniz,agee,urban,swann,snodgrass,schuster,radford,monk,mattingly,harp,girard,cheney,yancey,wagoner,ridley,lombardo,lau,hudgins,gaskins,duckworth,coe,coburn,willey,prado,newberry,magana,hammonds,elam,whipple,slade,serna,ojeda,liles,dorman,diehl,upton,reardon,michaels,goetz,eller,bauman,baer,layne,hummel,brenner,amaya,adamson,ornelas,dowell,cloutier,castellanos,wing,wellman,saylor,orourke,moya,montalvo,kilpatrick,durbin,shell,oldham,garvin,foss,branham,bartholomew,templeton,maguire,holton,rider,monahan,mccormack,beaty,anders,streeter,nieto,nielson,moffett,lankford,keating,heck,gatlin,delatorre,callaway,adcock,worrell,unger,robinette,nowak,jeter,brunner,steen,parrott,overstreet,nobles,montanez,clevenger,brinkley,trahan,quarles,pickering,pederson,jansen,grantham,gilchrist,crespo,aiken,schell,schaeffer,lorenz,leyva,harms,dyson,wallis,pease,leavitt,cavanaugh,batts,warden,seaman,rockwell,quezada,paxton,linder,houck,fontaine,durant,caruso,adler,pimentel,mize,lytle,cleary,cason,acker,switzer,isaacs,higginbotham,han,waterman,vandyke,stamper,sisk,shuler,riddick,mcmahan,levesque,hatton,bronson,bollinger,arnett,okeefe,gerber,gannon,farnsworth,baughman,silverman,satterfield,mccrary,kowalski,grigsby,greco,cabral,trout,rinehart,mahon,linton,gooden,curley,baugh,wyman,weiner,schwab,schuler,morrissey,mahan,bunn,thrasher,spear,waggoner,qualls,purdy,mcwhorter,mauldin,gilman,perryman,newsom,menard,martino,graf,billingsley,artis,simpkins,salisbury,quintanilla,gilliland,fraley,foust,crouse,scarborough,ngo,grissom,fultz,marlow,markham,madrigal,lawton,barfield,whiting,varney,schwarz,gooch,arce,wheat,truong,poulin,hurtado,selby,gaither,fortner,culpepper,coughlin,brinson,boudreau,barkley,bales,stepp,holm,tan,schilling,morrell,kahn,heaton,gamez,causey,turpin,shanks,schrader,meek,isom,hardison,carranza,yanez,scroggins,schofield,runyon,ratcliff,murrell,moeller,irby,currier,butterfield,yee,ralston,pullen,pinson,estep,carbone,hawks,ellington,casillas,spurlock,sikes,motley,mccartney,kruger,isbell,houle,burk,tomlin,quigley,neumann,lovelace,fennell,cheatham,bustamante,skidmore,hidalgo,forman,culp,bowens,betancourt,aquino,robb,rea,milner,martel,gresham,wiles,ricketts,dowd,collazo,bostic,blakely,sherrod,kenyon,gandy,ebert,deloach,allard,sauer,robins,olivares,gillette,chestnut,bourque,paine,hite,hauser,devore,crawley,chapa,talbert,poindexter,meador,mcduffie,mattox,kraus,harkins,choate,wren,sledge,sanborn,kinder,geary,cornwell,barclay,abney,seward,rhoads,howland,fortier,benner,vines,tubbs,troutman,rapp,mccurdy,deluca,westmoreland,havens,guajardo,ely,clary,seal,meehan,herzog,guillen,ashcraft,waugh,renner,milam,elrod,churchill,breaux,bolin,asher,windham,tirado,pemberton,nolen,noland,knott,emmons,cornish,christenson,brownlee,barbee,waldrop,pitt,olvera,lombardi,gruber,gaffney,eggleston,banda,archuleta,slone,prewitt,pfeiffer,nettles,mena,mcadams,henning,gardiner,cromwell,chisholm,burleson,vest,oglesby,mccarter,lumpkin,grey,wofford,vanhorn,thorn,teel,swafford,stclair,stanfield,ocampo,herrmann,hannon,arsenault,roush,mcalister,hiatt,gunderson,forsythe,duggan,delvalle,cintron,wilks,weinstein,uribe,rizzo,noyes,mclendon,gurley,bethea,winstead,maples,guyton,giordano,alderman,valdes,polanco,pappas,lively,grogan,griffiths,arevalo,whitson,sowell,rendon,fernandes,farrow,benavidez,ayres,alicea,stump,smalley,seitz,schulte,gilley,gallant,canfield,wolford,omalley,mcnutt,mcnulty,mcgovern,hardman,harbin,cowart,chavarria,brink,beckett,bagwell,armstead,anglin,abreu,reynoso,krebs,jett,hoffmann,greenfield,forte,burney,broome,sisson,trammell,partridge,mace,lomax,lemieux,gossett,frantz,fogle,cooney,broughton,pence,paulsen,muncy,mcarthur,hollins,beauchamp,withers,osorio,mulligan,hoyle,foy,dockery,cockrell,begley,amador,roby,rains,lindquist,gentile,everhart,bohannon,wylie,sommers,purnell,fortin,dunning,breeden,vail,phelan,phan,marx,cosby,colburn,boling,biddle,ledesma,gaddis,denney,chow,bueno,berrios,wicker,tolliver,thibodeaux,nagle,lavoie,fisk,crist,barbosa,reedy,march,locklear,kolb,himes,behrens,beckwith,weems,wahl,shorter,shackelford,rees,muse,cerda,valadez,thibodeau,saavedra,ridgeway,reiter,mchenry,majors,lachance,keaton,ferrara,clemens,blocker,applegate,paz,needham,mojica,kuykendall,hamel,escamilla,doughty,burchett,ainsworth,vidal,upchurch,thigpen,strauss,spruill,sowers,riggins,ricker,mccombs,harlow,buffington,sotelo,olivas,negrete,morey,macon,logsdon,lapointe,bigelow,bello,westfall,stubblefield,peak,lindley,hein,hawes,farrington,breen,birch,wilde,steed,sepulveda,reinhardt,proffitt,minter,messina,mcnabb,maier,keeler,gamboa,donohue,basham,shinn,crooks,cota,borders,bills,bachman,tisdale,tavares,schmid,pickard,gulley,fonseca,delossantos,condon,batista,wicks,wadsworth,martell,littleton,ison,haag,folsom,brumfield,broyles,brito,mireles,mcdonnell,leclair,hamblin,gough,fanning,binder,winfield,whitworth,soriano,palumbo,newkirk,mangum,hutcherson,comstock,carlin,beall,bair,wendt,watters,walling,putman,otoole,morley,mares,lemus,keener,hundley,dial,damico,billups,strother,mcfarlane,lamm,eaves,crutcher,caraballo,canty,atwell,taft,siler,rust,rawls,rawlings,prieto,mcneely,mcafee,hulsey,hackney,galvez,escalante,delagarza,crider,charlton,bandy,wilbanks,stowe,steinberg,renfro,masterson,massie,lanham,haskell,hamrick,fort,dehart,burdette,branson,bourne,babin,aleman,worthy,tibbs,smoot,slack,paradis,mull,luce,houghton,gantt,furman,danner,christianson,burge,ashford,arndt,almeida,stallworth,shade,searcy,sager,noonan,mclemore,mcintire,maxey,lavigne,jobe,ferrer,falk,coffin,byrnes,aranda,apodaca,stamps,rounds,peek,olmstead,lewandowski,kaminski,dunaway,bruns,brackett,amato,reich,mcclung,lacroix,koontz,herrick,hardesty,flanders,cousins,cato,cade,vickery,shank,nagel,dupuis,croteau,cotter,cable,stuckey,stine,porterfield,pauley,nye,moffitt,knudsen,hardwick,goforth,dupont,blunt,barrows,barnhill,shull,rash,loftis,lemay,kitchens,horvath,grenier,fuchs,fairbanks,culbertson,calkins,burnside,beattie,ashworth,albertson,wertz,vaught,vallejo,turk,tuck,tijerina,sage,peterman,marroquin,marr,lantz,hoang,demarco,daily,cone,berube,barnette,wharton,stinnett,slocum,scanlon,sander,pinto,mancuso,lima,headley,epstein,counts,clarkson,carnahan,boren,arteaga,adame,zook,whittle,whitehurst,wenzel,saxton,reddick,puente,handley,haggerty,earley,devlin,chaffin,cady,acuna,solano,sigler,pollack,pendergrass,ostrander,janes,francois,crutchfield,chamberlin,brubaker,baptiste,willson,reis,neeley,mullin,mercier,lira,layman,keeling,higdon,espinal,chapin,warfield,toledo,pulido,peebles,nagy,montague,mello,lear,jaeger,hogg,graff,furr,soliz,poore,mendenhall,mclaurin,maestas,gable,barraza,tillery,snead,pond,neill,mcculloch,mccorkle,lightfoot,hutchings,holloman,harness,dorn,council,bock,zielinski,turley,treadwell,stpierre,starling,somers,oswald,merrick,easterling,bivens,truitt,poston,parry,ontiveros,olivarez,moreau,medlin,lenz,knowlton,fairley,cobbs,chisolm,bannister,woodworth,toler,ocasio,noriega,neuman,moye,milburn,mcclanahan,lilley,hanes,flannery,dellinger,danielson,conti,blodgett,beers,weatherford,strain,karr,hitt,denham,custer,coble,clough,casteel,bolduc,batchelor,ammons,whitlow,tierney,staten,sibley,seifert,schubert,salcedo,mattison,laney,haggard,grooms,dix,dees,cromer,cooks,colson,caswell,zarate,swisher,shin,ragan,pridgen,mcvey,matheny,lafleur,franz,ferraro,dugger,whiteside,rigsby,mcmurray,lehmann,jacoby,hildebrand,hendrick,headrick,goad,fincher,drury,borges,archibald,albers,woodcock,trapp,soares,seaton,monson,luckett,lindberg,kopp,keeton,hsu,healey,garvey,gaddy,fain,burchfield,wentworth,strand,stack,spooner,saucier,sales,ricci,plunkett,pannell,ness,leger,hoy,freitas,fong,elizondo,duval,beaudoin,urbina,rickard,partin,moe,mcgrew,mcclintock,ledoux,forsyth,faison,devries,bertrand,wasson,tilton,scarbrough,leung,irvine,garber,denning,corral,colley,castleberry,bowlin,bogan,beale,baines,trice,rayburn,parkinson,pak,nunes,mcmillen,leahy,kimmel,higgs,fulmer,carden,bedford,taggart,spearman,register,prichard,morrill,koonce,heinz,hedges,guenther,grice,findley,dover,creighton,boothe,bayer,arreola,vitale,valles,raney,osgood,hanlon,burley,bounds,worden,weatherly,vetter,tanaka,stiltner,nevarez,mosby,montero,melancon,harter,hamer,goble,gladden,gist,ginn,akin,zaragoza,towns,tarver,sammons,royster,oreilly,muir,morehead,luster,kingsley,kelso,grisham,glynn,baumann,alves,yount,tamayo,paterson,oates,menendez,longo,hargis,gillen,desantis,breedlove,sumpter,scherer,rupp,reichert,heredia,creel,cohn,clemmons,casas,bickford,belton,bach,williford,whitcomb,tennant,sutter,stull,sessions,mccallum,langlois,keel,keegan,dangelo,dancy,damron,clapp,clanton,bankston,oliveira,mintz,mcinnis,martens,mabe,laster,jolley,hildreth,hefner,glaser,duckett,demers,brockman,blais,alcorn,agnew,toliver,tice,seeley,najera,musser,mcfall,laplante,galvin,fajardo,doan,coyne,copley,clawson,cheung,barone,wynne,woodley,tremblay,stoll,sparrow,sparkman,schweitzer,sasser,samples,roney,legg,heim,farias,colwell,christman,bratcher,winchester,upshaw,southerland,sorrell,sells,mount,mccloskey,martindale,luttrell,loveless,lovejoy,linares,latimer,embry,coombs,bratton,bostick,venable,tuggle,toro,staggs,sandlin,jefferies,heckman,griffis,crayton,clem,browder,thorton,sturgill,sprouse,royer,rousseau,ridenour,pogue,perales,peeples,metzler,mesa,mccutcheon,mcbee,hornsby,heffner,corrigan,armijo,vue,plante,peyton,paredes,macklin,hussey,hodgson,granados,frias,becnel,batten,almanza,turney,teal,sturgeon,meeker,mcdaniels,limon,keeney,kee,hutto,holguin,gorham,fishman,fierro,blanchette,rodrigue,reddy,osburn,oden,lerma,kirkwood,keefer,haugen,hammett,chalmers,brinkman,baumgartner,valerio,tellez,steffen,shumate,sauls,ripley,kemper,jacks,guffey,evers,craddock,carvalho,blaylock,banuelos,balderas,wooden,wheaton,turnbull,shuman,pointer,mosier,mccue,ligon,kozlowski,johansen,ingle,herr,briones,snipes,rickman,pipkin,pantoja,orosco,moniz,lawless,kunkel,hibbard,galarza,enos,bussey,schott,salcido,perreault,mcdougal,mccool,haight,garris,ferry,easton,conyers,atherton,wimberly,utley,spellman,smithson,slagle,ritchey,rand,petit,osullivan,oaks,nutt,mcvay,mccreary,mayhew,knoll,jewett,harwood,cardoza,ashe,arriaga,zeller,wirth,whitmire,stauffer,rountree,redden,mccaffrey,martz,larose,langdon,humes,gaskin,faber,devito,cass,almond,wingfield,wingate,villareal,tyner,smothers,severson,reno,pennell,maupin,leighton,janssen,hassell,hallman,halcomb,folse,fitzsimmons,fahey,cranford,bolen,battles,battaglia,wooldridge,trask,rosser,regalado,mcewen,keefe,fuqua,echevarria,caro,boynton,andrus,viera,vanmeter,taber,spradlin,seibert,provost,prentice,oliphant,laporte,hwang,hatchett,hass,greiner,freedman,covert,chilton,byars,wiese,venegas,swank,shrader,roberge,mullis,mortensen,mccune,marlowe,kirchner,keck,isaacson,hostetler,halverson,gunther,griswold,fenner,durden,blackwood,ahrens,sawyers,savoy,nabors,mcswain,mackay,loy,lavender,lash,labbe,jessup,fullerton,cruse,crittenden,correia,centeno,caudle,canady,callender,alarcon,ahern,winfrey,tribble,styles,salley,roden,musgrove,minnick,fortenberry,carrion,bunting,batiste,whited,underhill,stillwell,rauch,pippin,perrin,messenger,mancini,lister,kinard,hartmann,fleck,broadway,wilt,treadway,thornhill,spalding,rafferty,pitre,patino,ordonez,linkous,kelleher,homan,galbraith,feeney,curtin,coward,camarillo,buss,bunnell,bolt,beeler,autry,alcala,witte,wentz,stidham,shively,nunley,meacham,martins,lemke,lefebvre,hynes,horowitz,hoppe,holcombe,dunne,derr,cochrane,brittain,bedard,beauregard,torrence,strunk,soria,simonson,shumaker,scoggins,oconner,moriarty,kuntz,ives,hutcheson,horan,hales,garmon,fitts,bohn,atchison,wisniewski,vanwinkle,sturm,sallee,prosser,moen,lundberg,kunz,kohl,keane,jorgenson,jaynes,funderburk,freed,durr,creamer,cosgrove,batson,vanhoose,thomsen,teeter,smyth,redmon,orellana,maness,heflin,goulet,frick,forney,bunker,asbury,aguiar,talbott,southard,mowery,mears,lemmon,krieger,hickson,elston,duong,delgadillo,dayton,dasilva,conaway,catron,bruton,bradbury,bordelon,bivins,bittner,bergstrom,beals,abell,whelan,tejada,pulley,pino,norfleet,nealy,maes,loper,gatewood,frierson,freund,finnegan,cupp,covey,catalano,boehm,bader,yoon,walston,tenney,sipes,rawlins,medlock,mccaskill,mccallister,marcotte,maclean,hughey,henke,harwell,gladney,gilson,dew,chism,caskey,brandenburg,baylor,villasenor,veal,thatcher,stegall,shore,petrie,nowlin,navarrete,muhammad,lombard,loftin,lemaster,kroll,kovach,kimbrell,kidwell,hershberger,fulcher,eng,cantwell,bustos,boland,bobbitt,binkley,wester,weis,verdin,tiller,sisco,sharkey,seymore,rosenbaum,rohr,quinonez,pinkston,nation,malley,logue,lessard,lerner,lebron,krauss,klinger,halstead,haller,getz,burrow,alger,shores,pfeifer,perron,nelms,munn,mcmaster,mckenney,manns,knudson,hutchens,huskey,goebel,flagg,cushman,click,castellano,carder,bumgarner,wampler,spinks,robson,neel,mcreynolds,mathias,maas,loera,kasper,jenson,florez,coons,buckingham,brogan,berryman,wilmoth,wilhite,thrash,shephard,seidel,schulze,roldan,pettis,obryan,maki,mackie,hatley,frazer,fiore,chesser,bui,bottoms,bisson,benefield,allman,wilke,trudeau,timm,shifflett,rau,mundy,milliken,mayers,leake,kohn,huntington,horsley,hermann,guerin,fryer,frizzell,foret,flemming,fife,criswell,carbajal,bozeman,boisvert,angulo,wallen,tapp,silvers,ramsay,oshea,orta,moll,mckeever,mcgehee,linville,kiefer,ketchum,howerton,groce,gass,fusco,corbitt,betz,bartels,amaral,aiello,yoo,weddle,sperry,seiler,runyan,raley,overby,osteen,olds,mckeown,matney,lauer,lattimore,hindman,hartwell,fredrickson,fredericks,espino,clegg,carswell,cambell,burkholder,woodbury,welker,totten,thornburg,theriault,stitt,stamm,stackhouse,scholl,saxon,rife,razo,quinlan,pinkerton,olivo,nesmith,nall,mattos,lafferty,justus,giron,geer,fielder,drayton,dortch,conners,conger,boatwright,billiot,barden,armenta,tibbetts,steadman,slattery,rinaldi,raynor,pinckney,pettigrew,milne,matteson,halsey,gonsalves,fellows,durand,desimone,cowley,cowles,brill,barham,barela,barba,ashmore,withrow,valenti,tejeda,spriggs,sayre,salerno,peltier,peel,merriman,matheson,lowman,lindstrom,hyland,giroux,earls,dugas,dabney,collado,briseno,baxley,whyte,wenger,vanover,vanburen,thiel,schindler,schiller,rigby,pomeroy,passmore,marble,manzo,mahaffey,lindgren,laflamme,greathouse,fite,calabrese,bayne,yamamoto,wick,townes,thames,reinhart,peeler,naranjo,montez,mcdade,mast,markley,marchand,leeper,kellum,hudgens,hennessey,hadden,gainey,coppola,borrego,bolling,beane,ault,slaton,poland,pape,null,mulkey,lightner,langer,hillard,glasgow,ethridge,enright,derosa,baskin,weinberg,turman,somerville,pardo,noll,lashley,ingraham,hiller,hendon,glaze,cothran,cooksey,conte,carrico,abner,wooley,swope,summerlin,sturgis,sturdivant,stott,spurgeon,spillman,speight,roussel,popp,nutter,mckeon,mazza,magnuson,lanning,kozak,jankowski,heyward,forster,corwin,callaghan,bays,wortham,usher,theriot,sayers,sabo,poling,loya,lieberman,laroche,labelle,howes,harr,garay,fogarty,everson,durkin,dominquez,chaves,chambliss,witcher,vieira,vandiver,terrill,stoker,schreiner,moorman,liddell,lew,lawhorn,krug,irons,hylton,hollenbeck,herrin,hembree,goolsby,goodin,gilmer,foltz,dinkins,daughtry,caban,brim,briley,bilodeau,wyant,vergara,tallent,swearingen,stroup,scribner,quillen,pitman,monaco,mccants,maxfield,martinson,holtz,flournoy,brookins,brody,baumgardner,straub,sills,roybal,roundtree,oswalt,mcgriff,mcdougall,mccleary,maggard,gragg,gooding,godinez,doolittle,donato,cowell,cassell,bracken,appel,zambrano,reuter,perea,nakamura,monaghan,mickens,mcclinton,mcclary,marler,kish,judkins,gilbreath,freese,flanigan,felts,erdmann,dodds,chew,brownell,boatright,barreto,slayton,sandberg,saldivar,pettway,odum,narvaez,moultrie,montemayor,merrell,lees,keyser,hoke,hardaway,hannan,gilbertson,fogg,dumont,deberry,coggins,buxton,bucher,broadnax,beeson,araujo,appleton,amundson,aguayo,ackley,yocum,worsham,shivers,sanches,sacco,robey,rhoden,pender,ochs,mccurry,madera,luong,knotts,jackman,heinrich,hargrave,gault,comeaux,chitwood,caraway,boettcher,bernhardt,barrientos,zink,wickham,whiteman,thorp,stillman,settles,schoonover,roque,riddell,pilcher,phifer,novotny,macleod,hardee,haase,grider,doucette,clausen,bevins,beamon,badillo,tolley,tindall,soule,snook,seale,pitcher,pinkney,pellegrino,nowell,nemeth,mondragon,mclane,lundgren,ingalls,hudspeth,hixson,gearhart,furlong,downes,dibble,deyoung,cornejo,camara,brookshire,boyette,wolcott,surratt,sellars,segal,salyer,reeve,rausch,labonte,haro,gower,freeland,fawcett,eads,driggers,donley,collett,bromley,boatman,ballinger,baldridge,volz,trombley,stonge,shanahan,rivard,rhyne,pedroza,matias,jamieson,hedgepeth,hartnett,estevez,eskridge,denman,chiu,chinn,catlett,carmack,buie,bechtel,beardsley,bard,ballou,ulmer,skeen,robledo,rincon,reitz,piazza,munger,moten,mcmichael,loftus,ledet,kersey,groff,fowlkes,folk,crumpton,clouse,bettis,villagomez,timmerman,strom,santoro,roddy,penrod,musselman,macpherson,leboeuf,harless,haddad,guido,golding,fulkerson,fannin,dulaney,dowdell,cottle,ceja,cate,bosley,benge,albritton,voigt,trowbridge,soileau,seely,rohde,pearsall,paulk,orth,nason,mota,mcmullin,marquardt,madigan,hoag,gillum,gabbard,fenwick,eck,danforth,cushing,cress,creed,cazares,casanova,bey,bettencourt,barringer,baber,stansberry,schramm,rutter,rivero,oquendo,necaise,mouton,montenegro,miley,mcgough,marra,macmillan,lamontagne,jasso,horst,hetrick,heilman,gaytan,gall,fortney,dingle,desjardins,dabbs,burbank,brigham,breland,beaman,arriola,yarborough,wallin,toscano,stowers,reiss,pichardo,orton,michels,mcnamee,mccrory,leatherman,kell,keister,horning,hargett,guay,ferro,deboer,dagostino,carper,blanks,beaudry,towle,tafoya,stricklin,strader,soper,sonnier,sigmon,schenk,saddler,pedigo,mendes,lunn,lohr,lahr,kingsbury,jarman,hume,holliman,hofmann,haworth,harrelson,hambrick,flick,edmunds,dacosta,crossman,colston,chaplin,carrell,budd,weiler,waits,valentino,trantham,tarr,solorio,roebuck,powe,plank,pettus,palm,pagano,mink,luker,leathers,joslin,hartzell,gambrell,deutsch,cepeda,carty,caputo,brewington,bedell,ballew,applewhite,warnock,walz,urena,tudor,reel,pigg,parton,mickelson,meagher,mclellan,mcculley,mandel,leech,lavallee,kraemer,kling,kipp,kehoe,hochstetler,harriman,gregoire,grabowski,gosselin,gammon,fancher,edens,desai,brannan,armendariz,woolsey,whitehouse,whetstone,ussery,towne,testa,tallman,studer,strait,steinmetz,sorrells,sauceda,rolfe,paddock,mitchem,mcginn,mccrea,lovato,hazen,gilpin,gaynor,fike,devoe,delrio,curiel,burkhardt,bode,backus,zinn,watanabe,wachter,vanpelt,turnage,shaner,schroder,sato,riordan,quimby,portis,natale,mckoy,mccown,kilmer,hotchkiss,hesse,halbert,gwinn,godsey,delisle,chrisman,canter,arbogast,angell,acree,yancy,woolley,wesson,weatherspoon,trainor,stockman,spiller,sipe,rooks,reavis,propst,porras,neilson,mullens,loucks,llewellyn,kumar,koester,klingensmith,kirsch,kester,honaker,hodson,hennessy,helmick,garrity,garibay,fee,drain,casarez,callis,botello,aycock,avant,wingard,wayman,tully,theisen,szymanski,stansbury,segovia,rainwater,preece,pirtle,padron,mincey,mckelvey,mathes,larrabee,kornegay,klug,ingersoll,hecht,germain,eggers,dykstra,deering,decoteau,deason,dearing,cofield,carrigan,bonham,bahr,aucoin,appleby,almonte,yager,womble,wimmer,weimer,vanderpool,stancil,sprinkle,romine,remington,pfaff,peckham,olivera,meraz,maze,lathrop,koehn,hazelton,halvorson,hallock,haddock,ducharme,dehaven,caruthers,brehm,bosworth,bost,bias,beeman,basile,bane,aikens,wold,walther,tabb,suber,strawn,stocker,shirey,schlosser,riedel,rembert,reimer,pyles,peele,merriweather,letourneau,latta,kidder,hixon,hillis,hight,herbst,henriquez,haygood,hamill,gabel,fritts,eubank,dawes,correll,cha,bushey,buchholz,brotherton,botts,barnwell,auger,atchley,westphal,veilleux,ulloa,stutzman,shriver,ryals,prior,pilkington,moyers,marrs,mangrum,maddux,lockard,laing,kuhl,harney,hammock,hamlett,felker,doerr,depriest,carrasquillo,carothers,bogle,bischoff,bergen,albanese,wyckoff,vermillion,vansickle,thibault,tetreault,stickney,shoemake,ruggiero,rawson,racine,philpot,paschal,mcelhaney,mathison,legrand,lapierre,kwan,kremer,jiles,hilbert,geyer,faircloth,ehlers,egbert,desrosiers,dalrymple,cotten,cashman,cadena,breeding,boardman,alcaraz,ahn,wyrick,therrien,tankersley,strickler,puryear,plourde,pattison,pardue,mcginty,mcevoy,landreth,kuhns,koon,hewett,giddens,emerick,eades,deangelis,cosme,ceballos,birdsong,benham,bemis,armour,anguiano,welborn,tsosie,storms,shoup,sessoms,samaniego,rood,rojo,rhinehart,raby,northcutt,myer,munguia,morehouse,mcdevitt,mallett,lozada,lemoine,kuehn,hallett,grim,gillard,gaylor,garman,gallaher,feaster,faris,darrow,dardar,coney,carreon,braithwaite,boylan,boyett,bixler,bigham,benford,barragan,barnum,zuber,wyche,westcott,vining,stoltzfus,simonds,shupe,sabin,ruble,rittenhouse,richman,perrone,mulholland,millan,lomeli,kite,jemison,hulett,holler,hickerson,herold,hazelwood,griffen,gause,forde,eisenberg,dilworth,charron,chaisson,brodie,bristow,breunig,brace,boutwell,bentz,belk,bayless,batchelder,baran,baeza,zimmermann,weathersby,volk,toole,theis,tedesco,searle,schenck,satterwhite,ruelas,rankins,partida,nesbit,morel,menchaca,levasseur,kaylor,johnstone,hulse,hollar,hersey,harrigan,harbison,guyer,gish,giese,gerlach,geller,geisler,falcone,elwell,doucet,deese,darr,corder,chafin,byler,bussell,burdett,brasher,bowe,bellinger,bastian,barner,alleyne,wilborn,weil,wegner,wales,tatro,spitzer,smithers,schoen,resendez,parisi,overman,obrian,mudd,moy,mclaren,maggio,lindner,lalonde,lacasse,laboy,killion,kahl,jessen,jamerson,houk,henshaw,gustin,graber,durst,duenas,davey,cundiff,conlon,colunga,coakley,chiles,capers,buell,bricker,bissonnette,birmingham,bartz,bagby,zayas,volpe,treece,toombs,thom,terrazas,swinney,skiles,silveira,shouse,senn,ramage,nez,moua,langham,kyles,holston,hoagland,herd,feller,denison,carraway,burford,bickel,ambriz,abercrombie,yamada,weidner,waddle,verduzco,thurmond,swindle,schrock,sanabria,rosenberger,probst,peabody,olinger,nazario,mccafferty,mcbroom,mcabee,mazur,matherne,mapes,leverett,killingsworth,heisler,griego,gosnell,frankel,franke,ferrante,fenn,ehrlich,christopherso,chasse,chancellor,caton,brunelle,bly,bloomfield,babbitt,azevedo,abramson,ables,abeyta,youmans,wozniak,wainwright,stowell,smitherman,samuelson,runge,rothman,rosenfeld,peake,owings,olmos,munro,moreira,leatherwood,larkins,krantz,kovacs,kizer,kindred,karnes,jaffe,hubbell,hosey,hauck,goodell,erdman,dvorak,doane,cureton,cofer,buehler,bierman,berndt,banta,abdullah,warwick,waltz,turcotte,torrey,stith,seger,sachs,quesada,pinder,peppers,pascual,paschall,parkhurst,ozuna,oster,nicholls,lheureux,lavalley,kimura,jablonski,haun,gourley,gilligan,derby,croy,cotto,cargill,burwell,burgett,buckman,booher,adorno,wrenn,whittemore,urias,szabo,sayles,saiz,rutland,rael,pharr,pelkey,ogrady,nickell,musick,moats,mather,massa,kirschner,kieffer,kellar,hendershot,gott,godoy,gadson,furtado,fiedler,erskine,dutcher,dever,daggett,chevalier,brake,ballesteros,amerson,wingo,waldon,trott,silvey,showers,schlegel,rue,ritz,pepin,pelayo,parsley,palermo,moorehead,mchale,lett,kocher,kilburn,iglesias,humble,hulbert,huckaby,hix,haven,hartford,hardiman,gurney,grigg,grasso,goings,fillmore,farber,depew,dandrea,dame,cowen,covarrubias,burrus,bracy,ardoin,thompkins,standley,radcliffe,pohl,persaud,parenteau,pabon,newson,newhouse,napolitano,mulcahy,malave,keim,hooten,hernandes,heffernan,hearne,greenleaf,glick,fuhrman,fetter,faria,dishman,dickenson,crites,criss,clapper,chenault,castor,casto,bugg,bove,bonney,ard,anderton,allgood,alderson,woodman,warrick,toomey,tooley,tarrant,summerville,stebbins,sokol,searles,schutz,schumann,scheer,remillard,raper,proulx,palmore,monroy,messier,melo,melanson,mashburn,manzano,lussier,jenks,huneycutt,hartwig,grimsley,fulk,fielding,fidler,engstrom,eldred,dantzler,crandell,calder,brumley,breton,brann,bramlett,boykins,bianco,bancroft,almaraz,alcantar,whitmer,whitener,welton,vineyard,rahn,paquin,mizell,mcmillin,mckean,marston,maciel,lundquist,liggins,lampkin,kranz,koski,kirkham,jiminez,hazzard,harrod,graziano,grammer,gendron,garrido,fordham,englert,dryden,demoss,deluna,crabb,comeau,brummett,blume,benally,wessel,vanbuskirk,thorson,stumpf,stockwell,reams,radtke,rackley,pelton,niemi,newland,nelsen,morrissette,miramontes,mcginley,mccluskey,marchant,luevano,lampe,lail,jeffcoat,infante,hinman,gaona,erb,eady,desmarais,decosta,dansby,choe,breckenridge,bostwick,borg,bianchi,alberts,wilkie,whorton,vargo,tait,soucy,schuman,ousley,mumford,lum,lippert,leath,lavergne,laliberte,kirksey,kenner,johnsen,izzo,hiles,gullett,greenwell,gaspar,galbreath,gaitan,ericson,delapaz,croom,cottingham,clift,bushnell,bice,beason,arrowood,waring,voorhees,truax,shreve,shockey,schatz,sandifer,rubino,rozier,roseberry,pieper,peden,nester,nave,murphey,malinowski,macgregor,lafrance,kunkle,kirkman,hipp,hasty,haddix,gervais,gerdes,gamache,fouts,fitzwater,dillingham,deming,deanda,cedeno,cannady,burson,bouldin,arceneaux,woodhouse,whitford,wescott,welty,weigel,torgerson,toms,surber,sunderland,sterner,setzer,riojas,pumphrey,puga,metts,mcgarry,mccandless,magill,lupo,loveland,llamas,leclerc,koons,kahler,huss,holbert,heintz,haupt,grimmett,gaskill,ellingson,dorr,dingess,deweese,desilva,crossley,cordeiro,converse,conde,caldera,cairns,burmeister,burkhalter,brawner,bott,youngs,vierra,valladares,shrum,shropshire,sevilla,rusk,rodarte,pedraza,nino,merino,mcminn,markle,mapp,lajoie,koerner,kittrell,kato,hyder,hollifield,heiser,hazlett,greenwald,fant,eldredge,dreher,delafuente,cravens,claypool,beecher,aronson,alanis,worthen,wojcik,winger,whitacre,wellington,valverde,valdivia,troupe,thrower,swindell,suttles,suh,stroman,spires,slate,shealy,sarver,sartin,sadowski,rondeau,rolon,rascon,priddy,paulino,nolte,munroe,molloy,mciver,lykins,loggins,lenoir,klotz,kempf,hupp,hollowell,hollander,haynie,harkness,harker,gottlieb,frith,eddins,driskell,doggett,densmore,charette,cassady,byrum,burcham,buggs,benn,whitted,warrington,vandusen,vaillancourt,steger,siebert,scofield,quirk,purser,plumb,orcutt,nordstrom,mosely,michalski,mcphail,mcdavid,mccraw,marchese,mannino,lefevre,largent,lanza,kress,isham,hunsaker,hoch,hildebrandt,guarino,grijalva,graybill,ewell,ewald,cusick,crumley,coston,cathcart,carruthers,bullington,bowes,blain,blackford,barboza,yingling,weiland,varga,silverstein,sievers,shuster,shumway,runnels,rumsey,renfroe,provencher,polley,mohler,middlebrooks,kutz,koster,groth,glidden,fazio,deen,chipman,chenoweth,champlin,cedillo,carrero,carmody,buckles,brien,boutin,bosch,berkowitz,altamirano,wilfong,wiegand,waites,truesdale,toussaint,tobey,tedder,steelman,sirois,schnell,robichaud,richburg,plumley,pizarro,piercy,ortego,oberg,neace,mertz,mcnew,matta,lapp,lair,kibler,howlett,hollister,hofer,hatten,hagler,falgoust,engelhardt,eberle,dombrowski,dinsmore,daye,casares,braud,balch,autrey,wendel,tyndall,strobel,stoltz,spinelli,serrato,rochester,reber,rathbone,palomino,nickels,mayle,mathers,mach,loeffler,littrell,levinson,leong,lemire,lejeune,lazo,lasley,koller,kennard,hoelscher,hintz,hagerman,greaves,fore,eudy,engler,corrales,cordes,brunet,bidwell,bennet,tyrrell,tharpe,swinton,stribling,southworth,sisneros,savoie,samons,ruvalcaba,ries,ramer,omara,mosqueda,millar,mcpeak,macomber,luckey,litton,lehr,lavin,hubbs,hoard,hibbs,hagans,futrell,exum,evenson,culler,carbaugh,callen,brashear,bloomer,blakeney,bigler,addington,woodford,unruh,tolentino,sumrall,stgermain,smock,sherer,rayner,pooler,oquinn,nero,mcglothlin,linden,kowal,kerrigan,ibrahim,harvell,hanrahan,goodall,geist,fussell,fung,ferebee,eley,eggert,dorsett,dingman,destefano,colucci,clemmer,burnell,brumbaugh,boddie,berryhill,avelar,alcantara,winder,winchell,vandenberg,trotman,thurber,thibeault,stlouis,stilwell,sperling,shattuck,sarmiento,ruppert,rumph,renaud,randazzo,rademacher,quiles,pearman,palomo,mercurio,lowrey,lindeman,lawlor,larosa,lander,labrecque,hovis,holifield,henninger,hawkes,hartfield,hann,hague,genovese,garrick,fudge,frink,eddings,dinh,cribbs,calvillo,bunton,brodeur,bolding,blanding,agosto,zahn,wiener,trussell,tew,tello,teixeira,speck,sharma,shanklin,sealy,scanlan,santamaria,roundy,robichaux,ringer,rigney,prevost,polson,nord,moxley,medford,mccaslin,mcardle,macarthur,lewin,lasher,ketcham,keiser,heine,hackworth,grose,grizzle,gillman,gartner,frazee,fleury,edson,edmonson,derry,cronk,conant,burress,burgin,broom,brockington,bolick,boger,birchfield,billington,baily,bahena,armbruster,anson,yoho,wilcher,tinney,timberlake,thoma,thielen,sutphin,stultz,sikora,serra,schulman,scheffler,santillan,rego,preciado,pinkham,mickle,luu,lomas,lizotte,lent,kellerman,keil,johanson,hernadez,hartsfield,haber,gorski,farkas,eberhardt,duquette,delano,cropper,cozart,cockerham,chamblee,cartagena,cahoon,buzzell,brister,brewton,blackshear,benfield,aston,ashburn,arruda,wetmore,weise,vaccaro,tucci,sudduth,stromberg,stoops,showalter,shears,runion,rowden,rosenblum,riffle,renfrow,peres,obryant,leftwich,lark,landeros,kistler,killough,kerley,kastner,hoggard,hartung,guertin,govan,gatling,gailey,fullmer,fulford,flatt,esquibel,endicott,edmiston,edelstein,dufresne,dressler,dickman,chee,busse,bonnett,berard,arena,yoshida,velarde,veach,vanhouten,vachon,tolson,tolman,tennyson,stites,soler,shutt,ruggles,rhone,pegues,ong,neese,muro,moncrief,mefford,mcphee,mcmorris,mceachern,mcclurg,mansour,mader,leija,lecompte,lafountain,labrie,jaquez,heald,hash,hartle,gainer,frisby,farina,eidson,edgerton,dyke,durrett,duhon,cuomo,cobos,cervantez,bybee,brockway,borowski,binion,beery,arguello,amaro,acton,yuen,winton,wigfall,weekley,vidrine,vannoy,tardiff,shoop,shilling,schick,safford,prendergast,pellerin,osuna,nissen,nalley,moller,messner,messick,merrifield,mcguinness,matherly,marcano,mahone,lemos,lebrun,jara,hoffer,herren,hecker,haws,haug,gwin,gober,gilliard,fredette,favela,echeverria,downer,donofrio,desrochers,crozier,corson,bechtold,argueta,aparicio,zamudio,westover,westerman,utter,troyer,thies,tapley,slavin,shirk,sandler,roop,raymer,radcliff,otten,moorer,millet,mckibben,mccutchen,mcavoy,mcadoo,mayorga,mastin,martineau,marek,madore,leflore,kroeger,kennon,jimerson,hostetter,hornback,hendley,hance,guardado,granado,gowen,goodale,flinn,fleetwood,fitz,durkee,duprey,dipietro,dilley,clyburn,brawley,beckley,arana,weatherby,vollmer,vestal,tunnell,trigg,tingle,takahashi,sweatt,storer,snapp,shiver,rooker,rathbun,poisson,perrine,perri,pastor,parmer,parke,pare,palmieri,nottingham,midkiff,mecham,mccomas,mcalpine,lovelady,lillard,lally,knopp,kile,kiger,haile,gupta,goldsberry,gilreath,fulks,friesen,franzen,flack,findlay,ferland,dreyer,dore,dennard,deckard,debose,crim,coulombe,cork,chancey,cantor,branton,bissell,barns,woolard,witham,wasserman,spiegel,shoffner,scholz,ruch,rossman,petry,palacio,paez,neary,mortenson,millsap,miele,menke,mckim,mcanally,martines,manor,lemley,larochelle,klaus,klatt,kaufmann,kapp,helmer,hedge,halloran,glisson,frechette,fontana,eagan,distefano,danley,creekmore,chartier,chaffee,carillo,burg,bolinger,berkley,benz,basso,bash,barrier,zelaya,woodring,witkowski,wilmot,wilkens,wieland,verdugo,urquhart,tsai,timms,swiger,swaim,sussman,pires,molnar,mcatee,lowder,loos,linker,landes,kingery,hufford,higa,hendren,hammack,hamann,gillam,gerhardt,edelman,eby,delk,deans,curl,constantine,cleaver,claar,casiano,carruth,carlyle,brophy,bolanos,bibbs,bessette,beggs,baugher,bartel,averill,andresen,amin,adames,via,valente,turnbow,tse,swink,sublett,stroh,stringfellow,ridgway,pugliese,poteat,ohare,neubauer,murchison,mingo,lemmons,kwon,kellam,kean,jarmon,hyden,hudak,hollinger,henkel,hemingway,hasson,hansel,halter,haire,ginsberg,gillispie,fogel,flory,etter,elledge,eckman,deas,currin,crafton,coomer,colter,claxton,bulter,braddock,bowyer,binns,bellows,baskerville,barros,ansley,woolf,wight,waldman,wadley,tull,trull,tesch,stouffer,stadler,slay,shubert,sedillo,santacruz,reinke,poynter,neri,neale,mowry,moralez,monger,mitchum,merryman,manion,macdougall,lux,litchfield,ley,levitt,lepage,lasalle,khoury,kavanagh,karns,ivie,huebner,hodgkins,halpin,garica,eversole,dutra,dunagan,duffey,dillman,dillion,deville,dearborn,damato,courson,coulson,burdine,bousquet,bonin,bish,atencio,westbrooks,wages,vaca,tye,toner,tillis,swett,struble,stanfill,solorzano,slusher,sipple,sim,silvas,shults,schexnayder,saez,rodas,rager,pulver,plaza,penton,paniagua,meneses,mcfarlin,mcauley,matz,maloy,magruder,lohman,landa,lacombe,jaimes,hom,holzer,holst,heil,hackler,grundy,gilkey,farnham,durfee,dunton,dunston,duda,dews,craver,corriveau,conwell,colella,chambless,bremer,boutte,bourassa,blaisdell,backman,babineaux,audette,alleman,towner,taveras,tarango,sullins,suiter,stallard,solberg,schlueter,poulos,pimental,owsley,okelley,nations,moffatt,metcalfe,meekins,medellin,mcglynn,mccowan,marriott,marable,lennox,lamoureux,koss,kerby,karp,isenberg,howze,hockenberry,highsmith,harbour,hallmark,gusman,greeley,giddings,gaudet,gallup,fleenor,eicher,edington,dimaggio,dement,demello,decastro,bushman,brundage,brooker,bourg,blackstock,bergmann,beaton,banister,argo,appling,wortman,watterson,villalpando,tillotson,tighe,sundberg,sternberg,stamey,shipe,seeger,scarberry,sattler,sain,rothstein,poteet,plowman,pettiford,penland,partain,pankey,oyler,ogletree,ogburn,moton,merkel,lucier,lakey,kratz,kinser,kershaw,josephson,imhoff,hendry,hammon,frisbie,friedrich,frawley,fraga,forester,eskew,emmert,drennan,doyon,dandridge,cawley,carvajal,bracey,belisle,batey,ahner,wysocki,weiser,veliz,tincher,sansone,sankey,sandstrom,rohrer,risner,pridemore,pfeffer,persinger,peery,oubre,nowicki,musgrave,murdoch,mullinax,mccary,mathieu,livengood,kyser,klink,kimes,kellner,kavanaugh,kasten,imes,hoey,hinshaw,hake,gurule,grube,grillo,geter,gatto,garver,garretson,farwell,eiland,dunford,decarlo,corso,colman,collard,cleghorn,chasteen,cavender,carlile,calvo,byerly,brogdon,broadwater,breault,bono,bergin,behr,ballenger,amick,tamez,stiffler,steinke,simmon,shankle,schaller,salmons,sackett,saad,rideout,ratcliffe,rao,ranson,plascencia,petterson,olszewski,olney,olguin,nilsson,nevels,morelli,montiel,monge,michaelson,mertens,mcchesney,mcalpin,mathewson,loudermilk,lineberry,liggett,kinlaw,kight,jost,hereford,hardeman,halpern,halliday,hafer,gaul,friel,freitag,forsberg,evangelista,doering,dicarlo,dendy,delp,deguzman,dameron,curtiss,cosper,cauthen,cao,bradberry,bouton,bonnell,bixby,bieber,beveridge,bedwell,barhorst,bannon,baltazar,baier,ayotte,attaway,arenas,abrego,turgeon,tunstall,thaxton,thai,tenorio,stotts,sthilaire,shedd,seabolt,scalf,salyers,ruhl,rowlett,robinett,pfister,perlman,parkman,nunnally,norvell,napper,modlin,mckellar,mcclean,mascarenas,leibowitz,ledezma,kuhlman,kobayashi,hunley,holmquist,hinkley,hartsell,gribble,gravely,fifield,eliason,doak,crossland,carleton,bridgeman,bojorquez,boggess,auten,woosley,whiteley,wexler,twomey,tullis,townley,standridge,santoyo,rueda,riendeau,revell,pless,ottinger,nigro,nickles,mulvey,menefee,mcshane,mcloughlin,mckinzie,markey,lockridge,lipsey,knisley,knepper,kitts,kiel,jinks,hathcock,godin,gallego,fikes,fecteau,estabrook,ellinger,dunlop,dudek,countryman,chauvin,chatham,bullins,brownfield,boughton,bloodworth,bibb,baucom,barbieri,aubin,armitage,alessi,absher,abbate,zito,woolery,wiggs,wacker,tynes,tolle,telles,tarter,swarey,strode,stockdale,stalnaker,spina,schiff,saari,risley,rameriz,rakes,pettaway,penner,paulus,palladino,omeara,montelongo,melnick,mehta,mcgary,mccourt,mccollough,marchetti,manzanares,lowther,leiva,lauderdale,lafontaine,kowalczyk,knighton,joubert,jaworski,ide,huth,hurdle,housley,hackman,gulick,gordy,gilstrap,gehrke,gebhart,gaudette,foxworth,essex,endres,dunkle,cimino,caddell,brauer,braley,bodine,blackmore,belden,backer,ayer,andress,wisner,vuong,valliere,twigg,tso,tavarez,strahan,steib,staub,sowder,seiber,schutt,scharf,schade,rodriques,risinger,renshaw,rahman,presnell,piatt,nieman,nevins,mcilwain,mcgaha,mccully,mccomb,massengale,macedo,lesher,kearse,jauregui,husted,hudnall,holmberg,hertel,hardie,glidewell,frausto,fassett,dalessandro,dahlgren,corum,constantino,conlin,colquitt,colombo,claycomb,cardin,buller,boney,bocanegra,biggers,benedetto,araiza,andino,albin,zorn,werth,weisman,walley,vanegas,ulibarri,towe,tedford,teasley,suttle,steffens,stcyr,squire,singley,sifuentes,shuck,schram,sass,rieger,ridenhour,rickert,richerson,rayborn,rabe,raab,pendley,pastore,ordway,moynihan,mellott,mckissick,mcgann,mccready,mauney,marrufo,lenhart,lazar,lafave,keele,kautz,jardine,jahnke,jacobo,hord,hardcastle,hageman,giglio,gehring,fortson,duque,duplessis,dicken,derosier,deitz,dalessio,cram,castleman,candelario,callison,caceres,bozarth,biles,bejarano,bashaw,avina,armentrout,alverez,acord,waterhouse,vereen,vanlandingham,uhl,strawser,shotwell,severance,seltzer,schoonmaker,schock,schaub,schaffner,roeder,rodrigez,riffe,rhine,rasberry,rancourt,railey,quade,pursley,prouty,perdomo,oxley,osterman,nickens,murphree,mounts,merida,maus,mattern,masse,martinelli,mangan,lutes,ludwick,loney,laureano,lasater,knighten,kissinger,kimsey,kessinger,honea,hollingshead,hockett,heyer,heron,gurrola,gove,glasscock,gillett,galan,featherstone,eckhardt,duron,dunson,dasher,culbreth,cowden,cowans,claypoole,churchwell,chabot,caviness,cater,caston,callan,byington,burkey,boden,beckford,atwater,archambault,alvey,alsup,whisenant,weese,voyles,verret,tsang,tessier,sweitzer,sherwin,shaughnessy,revis,remy,prine,philpott,peavy,paynter,parmenter,ovalle,offutt,nightingale,newlin,nakano,myatt,muth,mohan,mcmillon,mccarley,mccaleb,maxson,marinelli,maley,liston,letendre,kain,huntsman,hirst,hagerty,gulledge,greenway,grajeda,gorton,goines,gittens,frederickson,fanelli,embree,eichelberger,dunkin,dixson,dillow,defelice,chumley,burleigh,borkowski,binette,biggerstaff,berglund,beller,audet,arbuckle,allain,alfano,youngman,wittman,weintraub,vanzant,vaden,twitty,stollings,standifer,sines,shope,scalise,saville,posada,pisano,otte,nolasco,napoli,mier,merkle,mendiola,melcher,mejias,mcmurry,mccalla,markowitz,manis,mallette,macfarlane,lough,looper,landin,kittle,kinsella,kinnard,hobart,herald,helman,hellman,hartsock,halford,hage,gordan,glasser,gayton,gattis,gastelum,gaspard,frisch,fitzhugh,eckstein,eberly,dowden,despain,crumpler,crotty,cornelison,chouinard,chamness,catlin,cann,bumgardner,budde,branum,bradfield,braddy,borst,birdwell,bazan,banas,bade,arango,ahearn,addis,zumwalt,wurth,wilk,widener,wagstaff,urrutia,terwilliger,tart,steinman,staats,sloat,rives,riggle,revels,reichard,prickett,poff,pitzer,petro,pell,northrup,nicks,moline,mielke,maynor,mallon,magness,lingle,lindell,lieb,lesko,lebeau,lammers,lafond,kiernan,ketron,jurado,holmgren,hilburn,hayashi,hashimoto,harbaugh,guillot,gard,froehlich,feinberg,falco,dufour,drees,doney,diep,delao,daves,dail,crowson,coss,congdon,carner,camarena,butterworth,burlingame,bouffard,bloch,bilyeu,barta,bakke,baillargeon,avent,aquilar,ake,aho,zeringue,yarber,wolfson,vogler,voelker,truss,troxell,thrift,strouse,spielman,sistrunk,sevigny,schuller,schaaf,ruffner,routh,roseman,ricciardi,peraza,pegram,overturf,olander,odaniel,neu,millner,melchor,maroney,machuca,macaluso,livesay,layfield,laskowski,kwiatkowski,kilby,hovey,heywood,hayman,havard,harville,haigh,hagood,grieco,glassman,gebhardt,fleischer,fann,elson,eccles,cunha,crumb,blakley,bardwell,abshire,woodham,wines,welter,wargo,varnado,tutt,traynor,swaney,svoboda,stricker,stoffel,stambaugh,sickler,shackleford,selman,seaver,sansom,sanmiguel,royston,rourke,rockett,rioux,puleo,pitchford,nardi,mulvaney,middaugh,malek,leos,lathan,kujawa,kimbro,killebrew,houlihan,hinckley,herod,hepler,hamner,hammel,hallowell,gonsalez,gingerich,gambill,funkhouser,fricke,fewell,falkner,endsley,dulin,drennen,deaver,dambrosio,chadwell,castanon,burkes,brune,brisco,brinker,bowker,boldt,berner,beaumont,beaird,bazemore,barrick,albano,younts,wunderlich,weidman,vanness,toland,theobald,stickler,steiger,stanger,spies,spector,sollars,smedley,seibel,scoville,saito,rye,rummel,rowles,rouleau,roos,rogan,roemer,ream,raya,purkey,priester,perreira,penick,paulin,parkins,overcash,oleson,neves,muldrow,minard,midgett,michalak,melgar,mcentire,mcauliffe,marte,lydon,lindholm,leyba,langevin,lagasse,lafayette,kesler,kelton,kao,kaminsky,jaggers,humbert,huck,howarth,hinrichs,higley,gupton,guimond,gravois,giguere,fretwell,fontes,feeley,faucher,eichhorn,ecker,earp,dole,dinger,derryberry,demars,deel,copenhaver,collinsworth,colangelo,cloyd,claiborne,caulfield,carlsen,calzada,caffey,broadus,brenneman,bouie,bodnar,blaney,blanc,beltz,behling,barahona,yockey,winkle,windom,wimer,villatoro,trexler,teran,taliaferro,sydnor,swinson,snelling,smtih,simonton,simoneaux,simoneau,sherrer,seavey,scheel,rushton,rupe,ruano,rippy,reiner,reiff,rabinowitz,quach,penley,odle,nock,minnich,mckown,mccarver,mcandrew,longley,laux,lamothe,lafreniere,kropp,krick,kates,jepson,huie,howse,howie,henriques,haydon,haught,hartzog,harkey,grimaldo,goshorn,gormley,gluck,gilroy,gillenwater,giffin,fluker,feder,eyre,eshelman,eakins,detwiler,delrosario,davisson,catalan,canning,calton,brammer,botelho,blakney,bartell,averett,askins,aker,zak,worcester,witmer,wiser,winkelman,widmer,whittier,weitzel,wardell,wagers,ullman,tupper,tingley,tilghman,talton,simard,seda,scheller,sala,rundell,rost,roa,ribeiro,rabideau,primm,pinon,peart,ostrom,ober,nystrom,nussbaum,naughton,murr,moorhead,monti,monteiro,melson,meissner,mclin,mcgruder,marotta,makowski,majewski,madewell,lunt,lukens,leininger,lebel,lakin,kepler,jaques,hunnicutt,hungerford,hoopes,hertz,heins,halliburton,grosso,gravitt,glasper,gallman,gallaway,funke,fulbright,falgout,eakin,dostie,dorado,dewberry,derose,cutshall,crampton,costanzo,colletti,cloninger,claytor,chiang,canterbury,campagna,burd,brokaw,broaddus,bretz,brainard,binford,bilbrey,alpert,aitken,ahlers,zajac,woolfolk,witten,windle,wayland,tramel,tittle,talavera,suter,straley,specht,sommerville,soloman,skeens,sigman,sibert,shavers,schuck,schmit,sartain,sabol,rosenblatt,rollo,rashid,rabb,province,polston,nyberg,northrop,navarra,muldoon,mikesell,mcdougald,mcburney,mariscal,lui,lozier,lingerfelt,legere,latour,lagunas,lacour,kurth,killen,kiely,kayser,kahle,isley,huertas,hower,hinz,haugh,gumm,galicia,fortunato,flake,dunleavy,duggins,doby,digiovanni,devaney,deltoro,cribb,corpuz,coronel,coen,charbonneau,caine,burchette,blakey,blakemore,bergquist,beene,beaudette,bayles,ballance,bakker,bailes,asberry,arwood,zucker,willman,whitesell,wald,walcott,vancleave,trump,strasser,simas,shick,schleicher,schaal,saleh,rotz,resnick,rainer,partee,ollis,oller,oday,munday,mong,millican,merwin,mazzola,mansell,magallanes,llanes,lewellen,lepore,kisner,keesee,jeanlouis,ingham,hornbeck,hawn,hartz,harber,haffner,gutshall,guth,grays,gowan,finlay,finkelstein,eyler,enloe,dungan,diez,dearman,cull,crosson,chronister,cassity,campion,callihan,butz,breazeale,blumenthal,berkey,batty,batton,arvizu,alderete,aldana,albaugh,abernethy,wolter,wille,tweed,tollefson,thomasson,teter,testerman,sproul,spates,southwick,soukup,skelly,senter,sealey,sawicki,sargeant,rossiter,rosemond,repp,pifer,ormsby,nickelson,naumann,morabito,monzon,millsaps,millen,mcelrath,marcoux,mantooth,madson,macneil,mackinnon,louque,leister,lampley,kushner,krouse,kirwan,jessee,janson,jahn,jacquez,islas,hutt,holladay,hillyer,hepburn,hensel,harrold,gingrich,geis,gales,fults,finnell,ferri,featherston,epley,ebersole,eames,dunigan,drye,dismuke,devaughn,delorenzo,damiano,confer,collum,clower,clow,claussen,clack,caylor,cawthon,casias,carreno,bluhm,bingaman,bewley,belew,beckner,auld,amey,wolfenbarger,wilkey,wicklund,waltman,villalba,valero,valdovinos,ung,ullrich,tyus,twyman,trost,tardif,tanguay,stripling,steinbach,shumpert,sasaki,sappington,sandusky,reinhold,reinert,quijano,pye,placencia,pinkard,phinney,perrotta,pernell,parrett,oxendine,owensby,orman,nuno,mori,mcroberts,mcneese,mckamey,mccullum,markel,mardis,maines,lueck,lubin,lefler,leffler,larios,labarbera,kershner,josey,jeanbaptiste,izaguirre,hermosillo,haviland,hartshorn,hafner,ginter,getty,franck,fiske,dufrene,doody,davie,dangerfield,dahlberg,cuthbertson,crone,coffelt,chidester,chesson,cauley,caudell,cantara,campo,caines,bullis,bucci,brochu,bogard,bickerstaff,benning,arzola,antonelli,adkinson,zellers,wulf,worsley,woolridge,whitton,westerfield,walczak,vassar,truett,trueblood,trawick,townsley,topping,tobar,telford,steverson,stagg,sitton,sill,sergent,schoenfeld,sarabia,rutkowski,rubenstein,rigdon,prentiss,pomerleau,plumlee,philbrick,peer,patnode,oloughlin,obregon,nuss,morell,mikell,mele,mcinerney,mcguigan,mcbrayer,lor,lollar,lakes,kuehl,kinzer,kamp,joplin,jacobi,howells,holstein,hedden,hassler,harty,halle,greig,gouge,goodrum,gerhart,geier,geddes,gast,forehand,ferree,fendley,feltner,esqueda,encarnacion,eichler,egger,edmundson,eatmon,doud,donohoe,donelson,dilorenzo,digiacomo,diggins,delozier,dejong,danford,crippen,coppage,cogswell,clardy,cioffi,cabe,brunette,bresnahan,bramble,blomquist,blackstone,biller,bevis,bevan,bethune,benbow,baty,basinger,balcom,andes,aman,aguero,adkisson,yandell,wilds,whisenhunt,weigand,weeden,voight,villar,trottier,tillett,suazo,setser,scurry,schuh,schreck,schauer,samora,roane,rinker,reimers,ratchford,popovich,parkin,natal,melville,mcbryde,magdaleno,loehr,lockman,lingo,leduc,larocca,lao,lamere,laclair,krall,korte,koger,jalbert,hughs,higbee,henton,heaney,haith,gump,greeson,goodloe,gholston,gasper,gagliardi,fregoso,farthing,fabrizio,ensor,elswick,elgin,eklund,eaddy,drouin,dorton,dizon,derouen,deherrera,davy,dampier,cullum,culley,cowgill,cardoso,cardinale,brodsky,broadbent,brimmer,briceno,branscum,bolyard,boley,bennington,beadle,baur,ballentine,azure,aultman,arciniega,aguila,aceves,yepez,yap,woodrum,wethington,weissman,veloz,trusty,troup,trammel,tarpley,stivers,steck,sprayberry,spraggins,spitler,spiers,sohn,seagraves,schiffman,rudnick,rizo,riccio,rennie,quackenbush,puma,plott,pearcy,parada,paiz,munford,moskowitz,mease,mcnary,mccusker,lozoya,longmire,loesch,lasky,kuhlmann,krieg,koziol,kowalewski,konrad,kindle,jowers,jolin,jaco,hua,horgan,hine,hileman,hepner,heise,heady,hawkinson,hannigan,haberman,guilford,grimaldi,garton,gagliano,fruge,follett,fiscus,ferretti,ebner,easterday,eanes,dirks,dimarco,depalma,deforest,cruce,craighead,christner,candler,cadwell,burchell,buettner,brinton,brazier,brannen,brame,bova,bomar,blakeslee,belknap,bangs,balzer,athey,armes,alvis,alverson,alvardo,yeung,wheelock,westlund,wessels,volkman,threadgill,thelen,tague,symons,swinford,sturtevant,straka,stier,stagner,segarra,seawright,rutan,roux,ringler,riker,ramsdell,quattlebaum,purifoy,poulson,permenter,peloquin,pasley,pagel,osman,obannon,nygaard,newcomer,munos,motta,meadors,mcquiston,mcniel,mcmann,mccrae,mayne,matte,legault,lechner,kucera,krohn,kratzer,koopman,jeske,horrocks,hock,hibbler,hesson,hersh,harvin,halvorsen,griner,grindle,gladstone,garofalo,frampton,forbis,eddington,diorio,dingus,dewar,desalvo,curcio,creasy,cortese,cordoba,connally,cluff,cascio,capuano,canaday,calabro,bussard,brayton,borja,bigley,arnone,arguelles,acuff,zamarripa,wooton,widner,wideman,threatt,thiele,templin,teeters,synder,swint,swick,sturges,stogner,stedman,spratt,siegfried,shetler,scull,savino,sather,rothwell,rook,rone,rhee,quevedo,privett,pouliot,poche,pickel,petrillo,pellegrini,peaslee,partlow,otey,nunnery,morelock,morello,meunier,messinger,mckie,mccubbin,mccarron,lerch,lavine,laverty,lariviere,lamkin,kugler,krol,kissel,keeter,hubble,hickox,hetzel,hayner,hagy,hadlock,groh,gottschalk,goodsell,gassaway,garrard,galligan,fye,firth,fenderson,feinstein,etienne,engleman,emrick,ellender,drews,doiron,degraw,deegan,dart,crissman,corr,cookson,coil,cleaves,charest,chapple,chaparro,castano,carpio,byer,bufford,bridgewater,bridgers,brandes,borrero,bonanno,aube,ancheta,abarca,abad,yim,wooster,wimbush,willhite,willams,wigley,weisberg,wardlaw,vigue,vanhook,unknow,torre,tasker,tarbox,strachan,slover,shamblin,semple,schuyler,schrimsher,sayer,salzman,rubalcava,riles,reneau,reichel,rayfield,rabon,pyatt,prindle,poss,polito,plemmons,pesce,perrault,pereyra,ostrowski,nilsen,niemeyer,munsey,mundell,moncada,miceli,meader,mcmasters,mckeehan,matsumoto,marron,marden,lizarraga,lingenfelter,lewallen,langan,lamanna,kovac,kinsler,kephart,keown,kass,kammerer,jeffreys,hysell,householder,hosmer,hardnett,hanner,guyette,greening,glazer,ginder,fromm,fluellen,finkle,fey,fessler,essary,eisele,duren,dittmer,crochet,cosentino,cogan,coelho,cavin,carrizales,campuzano,brough,bopp,bookman,blouin,beesley,battista,bascom,bakken,badgett,arneson,anselmo,ahumada,woodyard,wolters,wireman,willison,warman,waldrup,vowell,vantassel,vale,twombly,toomer,tennison,teets,tedeschi,swanner,stutz,stelly,sheehy,schermerhorn,scala,sandidge,salters,salo,saechao,roseboro,rolle,ressler,renz,renn,redford,raposa,rainbolt,pelfrey,orndorff,oney,nolin,nimmons,ney,nardone,myhre,morman,menjivar,mcglone,mccammon,maxon,marciano,manus,lowrance,lorenzen,lonergan,lollis,littles,lindahl,lamas,lach,kuster,krawczyk,knuth,knecht,kirkendall,keitt,keever,kantor,jarboe,hoye,houchens,holter,holsinger,hickok,helwig,helgeson,hassett,harner,hamman,hames,hadfield,goree,goldfarb,gaughan,gaudreau,gantz,gallion,frady,foti,flesher,ferrin,faught,engram,donegan,desouza,degroot,cutright,crowl,criner,coan,clinkscales,chewning,chavira,catchings,carlock,bulger,buenrostro,bramblett,brack,boulware,bookout,bitner,birt,baranowski,baisden,augustin,allmon,acklin,yoakum,wilbourn,whisler,weinberger,washer,vasques,vanzandt,vanatta,troxler,tomes,tindle,tims,throckmorton,thach,stpeter,stlaurent,stenson,spry,spitz,songer,snavely,sly,shroyer,shortridge,shenk,sevier,seabrook,scrivner,saltzman,rosenberry,rockwood,robeson,roan,reiser,ramires,raber,posner,popham,piotrowski,pinard,peterkin,pelham,peiffer,peay,nadler,musso,millett,mestas,mcgowen,marques,marasco,manriquez,manos,mair,lipps,leiker,krumm,knorr,kinslow,kessel,kendricks,kelm,ito,irick,ickes,hurlburt,horta,hoekstra,heuer,helmuth,heatherly,hampson,hagar,haga,greenlaw,grau,godbey,gingras,gillies,gibb,gayden,gauvin,garrow,fontanez,florio,finke,fasano,ezzell,ewers,eveland,eckenrode,duclos,drumm,dimmick,delancey,defazio,dashiell,cusack,crowther,crigger,cray,coolidge,coldiron,cleland,chalfant,cassel,camire,cabrales,broomfield,brittingham,brisson,brickey,braziel,brazell,bragdon,boulanger,bos,boman,bohannan,beem,barre,baptist,azar,ashbaugh,armistead,almazan,adamski,zendejas,winburn,willaims,wilhoit,westberry,wentzel,wendling,visser,vanscoy,vankirk,vallee,tweedy,thornberry,sweeny,spradling,spano,smelser,shim,sechrist,schall,scaife,rugg,rothrock,roesler,riehl,ridings,render,ransdell,radke,pinero,petree,pendergast,peluso,pecoraro,pascoe,panek,oshiro,navarrette,murguia,moores,moberg,michaelis,mcwhirter,mcsweeney,mcquade,mccay,mauk,mariani,marceau,mandeville,maeda,lunde,ludlow,loeb,lindo,linderman,leveille,leith,larock,lambrecht,kulp,kinsley,kimberlin,kesterson,hoyos,helfrich,hanke,grisby,goyette,gouveia,glazier,gile,gerena,gelinas,gasaway,funches,fujimoto,flynt,fenske,fellers,fehr,eslinger,escalera,enciso,duley,dittman,dineen,diller,devault,dao,collings,clymer,clowers,chavers,charland,castorena,castello,camargo,bunce,bullen,boyes,borchers,borchardt,birnbaum,birdsall,billman,benites,bankhead,ange,ammerman,adkison,winegar,wickman,warr,warnke,villeneuve,veasey,vassallo,vannatta,vadnais,twilley,towery,tomblin,tippett,theiss,talkington,talamantes,swart,swanger,streit,stines,stabler,spurling,sobel,sine,simmers,shippy,shiflett,shearin,sauter,sanderlin,rusch,runkle,ruckman,rorie,roesch,richert,rehm,randel,ragin,quesenberry,puentes,plyler,plotkin,paugh,oshaughnessy,ohalloran,norsworthy,niemann,nader,moorefield,mooneyham,modica,miyamoto,mickel,mebane,mckinnie,mazurek,mancilla,lukas,lovins,loughlin,lotz,lindsley,liddle,levan,lederman,leclaire,lasseter,lapoint,lamoreaux,lafollette,kubiak,kirtley,keffer,kaczmarek,housman,hiers,hibbert,herrod,hegarty,hathorn,greenhaw,grafton,govea,futch,furst,franko,forcier,foran,flickinger,fairfield,eure,emrich,embrey,edgington,ecklund,eckard,durante,deyo,delvecchio,dade,currey,creswell,cottrill,casavant,cartier,cargile,capel,cammack,calfee,burse,burruss,brust,brousseau,bridwell,braaten,borkholder,bloomquist,bjork,bartelt,arp,amburgey,yeary,yao,whitefield,vinyard,vanvalkenburg,twitchell,timmins,tapper,stringham,starcher,spotts,slaugh,simonsen,sheffer,sequeira,rosati,rhymes,reza,quint,pollak,peirce,patillo,parkerson,paiva,nilson,nevin,narcisse,nair,mitton,merriam,merced,meiners,mckain,mcelveen,mcbeth,marsden,marez,manke,mahurin,mabrey,luper,krull,kees,iles,hunsicker,hornbuckle,holtzclaw,hirt,hinnant,heston,hering,hemenway,hegwood,hearns,halterman,guiterrez,grote,granillo,grainger,glasco,gilder,garren,garlock,garey,fryar,fredricks,fraizer,foxx,foshee,ferrel,felty,everitt,evens,esser,elkin,eberhart,durso,duguay,driskill,doster,dewall,deveau,demps,demaio,delreal,deleo,deem,darrah,cumberbatch,culberson,cranmer,cordle,colgan,chesley,cavallo,castellon,castelli,carreras,carnell,carlucci,bontrager,blumberg,blasingame,becton,ayon,artrip,andujar,alkire,alder,agan,zukowski,zuckerman,zehr,wroblewski,wrigley,woodside,wigginton,westman,westgate,werts,washam,wardlow,walser,waiters,tadlock,stringfield,stimpson,stickley,standish,spurlin,spindler,speller,spaeth,sotomayor,sok,sluder,shryock,shepardson,shatley,scannell,santistevan,rosner,rhode,resto,reinhard,rathburn,prisco,poulsen,pinney,phares,pennock,pastrana,oviedo,ostler,noto,nauman,mulford,moise,moberly,mirabal,metoyer,metheny,mentzer,meldrum,mcinturff,mcelyea,mcdougle,massaro,lumpkins,loveday,lofgren,loe,lirette,lesperance,lefkowitz,ledger,lauzon,lain,lachapelle,kurz,klassen,keough,kempton,kaelin,jeffords,huot,hsieh,hoyer,horwitz,hopp,hoeft,hennig,haskin,gourdine,golightly,girouard,fulgham,fritsch,freer,frasher,foulk,firestone,fiorentino,fedor,ensley,englehart,eells,ebel,dunphy,donahoe,dileo,dibenedetto,dabrowski,crick,coonrod,conder,coddington,chunn,choy,chaput,cerna,carreiro,calahan,braggs,bourdon,bollman,bittle,behm,bauder,batt,barreras,aubuchon,anzalone,adamo,zerbe,wirt,willcox,westberg,weikel,waymire,vroman,vinci,vallejos,truesdell,troutt,trotta,tollison,toles,tichenor,symonds,surles,strayer,stgeorge,sroka,sorrentino,solares,snelson,silvestri,sikorski,shawver,schumaker,schorr,schooley,scates,satterlee,satchell,sacks,rymer,roselli,robitaille,riegel,regis,reames,provenzano,priestley,plaisance,pettey,palomares,oman,nowakowski,nace,monette,minyard,mclamb,mchone,mccarroll,masson,magoon,maddy,lundin,loza,licata,leonhardt,lema,landwehr,kircher,kinch,karpinski,johannsen,hussain,houghtaling,hoskinson,hollaway,holeman,hobgood,hilt,hiebert,gros,goggin,geissler,gadbois,gabaldon,fleshman,flannigan,fairman,epp,eilers,dycus,dunmire,duffield,dowler,deloatch,dehaan,deemer,clayborn,christofferso,chilson,chesney,chatfield,carron,canale,brigman,branstetter,bosse,borton,bonar,blau,biron,barroso,arispe,zacharias,zabel,yaeger,woolford,whetzel,weakley,veatch,vandeusen,tufts,troxel,troche,traver,townsel,tosh,talarico,swilley,sterrett,stenger,speakman,sowards,sours,souders,souder,soles,sobers,snoddy,smither,sias,shute,shoaf,shahan,schuetz,scaggs,santini,rosson,rolen,robidoux,rentas,recio,pixley,pawlowski,pawlak,paull,overbey,orear,oliveri,oldenburg,nutting,naugle,mote,mossman,moor,misner,milazzo,michelson,mcentee,mccullar,mccree,mcaleer,mazzone,mandell,manahan,malott,maisonet,mailloux,lumley,lowrie,louviere,lipinski,lindemann,leppert,leopold,leasure,labarge,kubik,knisely,knepp,kenworthy,kennelly,kelch,karg,kanter,hyer,houchin,hosley,hosler,hollon,holleman,heitman,hebb,haggins,gwaltney,guin,goulding,gorden,geraci,georges,gathers,frison,feagin,falconer,espada,erving,erikson,eisenhauer,eder,ebeling,durgin,dowdle,dinwiddie,delcastillo,dedrick,crimmins,covell,cournoyer,coria,cohan,cataldo,carpentier,canas,campa,brode,brashears,blaser,bicknell,berk,bednar,barwick,ascencio,althoff,almodovar,alamo,zirkle,zabala,wolverton,winebrenner,wetherell,westlake,wegener,weddington,vong,tuten,trosclair,tressler,theroux,teske,swinehart,swensen,sundquist,southall,socha,sizer,silverberg,shortt,shimizu,sherrard,shaeffer,scheid,scheetz,saravia,sanner,rubinstein,rozell,romer,rheaume,reisinger,randles,pullum,petrella,payan,papp,nordin,norcross,nicoletti,nicholes,newbold,nakagawa,mraz,monteith,milstead,milliner,mellen,mccardle,luft,liptak,lipp,leitch,latimore,larrison,landau,laborde,koval,izquierdo,hymel,hoskin,holte,hoefer,hayworth,hausman,harrill,harrel,hardt,gully,groover,grinnell,greenspan,graver,grandberry,gorrell,goldenberg,goguen,gilleland,garr,fuson,foye,feldmann,everly,dyess,dyal,dunnigan,downie,dolby,deatherage,cosey,cheever,celaya,caver,cashion,caplinger,cansler,byrge,bruder,breuer,breslin,brazelton,botkin,bonneau,bondurant,bohanan,bogue,boes,bodner,boatner,blatt,bickley,belliveau,beiler,beier,beckstead,bachmann,atkin,altizer,alloway,allaire,albro,abron,zellmer,yetter,yelverton,wiltshire,wiens,whidden,viramontes,vanwormer,tarantino,tanksley,sumlin,strauch,strang,stice,spahn,sosebee,sigala,shrout,seamon,schrum,schneck,schantz,ruddy,romig,roehl,renninger,reding,pyne,polak,pohlman,pasillas,oldfield,oldaker,ohanlon,ogilvie,norberg,nolette,nies,neufeld,nellis,mummert,mulvihill,mullaney,monteleone,mendonca,meisner,mcmullan,mccluney,mattis,massengill,manfredi,luedtke,lounsbury,liberatore,leek,lamphere,laforge,kuo,koo,jourdan,ismail,iorio,iniguez,ikeda,hubler,hodgdon,hocking,heacock,haslam,haralson,hanshaw,hannum,hallam,haden,garnes,garces,gammage,gambino,finkel,faucett,fahy,ehrhardt,eggen,dusek,durrant,dubay,dones,dey,depasquale,delucia,degraff,decamp,davalos,cullins,conard,clouser,clontz,cifuentes,chappel,chaffins,celis,carwile,byram,bruggeman,bressler,brathwaite,brasfield,bradburn,boose,boon,bodie,blosser,blas,bise,bertsch,bernardi,bernabe,bengtson,barrette,astorga,alday,albee,abrahamson,yarnell,wiltse,wile,wiebe,waguespack,vasser,upham,tyre,turek,traxler,torain,tomaszewski,tinnin,tiner,tindell,teed,styron,stahlman,staab,skiba,shih,sheperd,seidl,secor,schutte,sanfilippo,ruder,rondon,rearick,procter,prochaska,pettengill,pauly,neilsen,nally,mutter,mullenax,morano,meads,mcnaughton,mcmurtry,mcmath,mckinsey,matthes,massenburg,marlar,margolis,malin,magallon,mackin,lovette,loughran,loring,longstreet,loiselle,lenihan,laub,kunze,kull,koepke,kerwin,kalinowski,kagan,innis,innes,holtzman,heinemann,harshman,haider,haack,guss,grondin,grissett,greenawalt,gravel,goudy,goodlett,goldston,gokey,gardea,galaviz,gafford,gabrielson,furlow,fritch,fordyce,folger,elizalde,ehlert,eckhoff,eccleston,ealey,dubin,diemer,deschamps,delapena,decicco,debolt,daum,cullinan,crittendon,crase,cossey,coppock,coots,colyer,cluck,chamberland,burkhead,bumpus,buchan,borman,bork,boe,birkholz,berardi,benda,behnke,barter,auer,amezquita,wotring,wirtz,wingert,wiesner,whitesides,weyant,wainscott,venezia,varnell,tussey,thurlow,tabares,stiver,stell,starke,stanhope,stanek,sisler,sinnott,siciliano,shehan,selph,seager,scurlock,scranton,santucci,santangelo,saltsman,ruel,ropp,rogge,rettig,renwick,reidy,reider,redfield,quam,premo,peet,parente,paolucci,palmquist,orme,ohler,ogg,netherton,mutchler,morita,mistretta,minnis,middendorf,menzel,mendosa,mendelson,meaux,mcspadden,mcquaid,mcnatt,manigault,maney,mager,lukes,lopresti,liriano,lipton,letson,lechuga,lazenby,lauria,larimore,kwok,kwak,krupp,krupa,krum,kopec,kinchen,kifer,kerney,kerner,kennison,kegley,kays,karcher,justis,johson,jellison,janke,huskins,holzman,hinojos,hefley,hatmaker,harte,halloway,hallenbeck,goodwyn,glaspie,geise,fullwood,fryman,frew,frakes,fraire,farrer,enlow,engen,ellzey,eckles,earles,ealy,dunkley,drinkard,dreiling,draeger,dinardo,dills,desroches,desantiago,curlee,crumbley,critchlow,coury,courtright,coffield,cleek,charpentier,cardone,caples,cantin,buntin,bugbee,brinkerhoff,brackin,bourland,bohl,bogdan,blassingame,beacham,banning,auguste,andreasen,amann,almon,alejo,adelman,abston,zeno,yerger,wymer,woodberry,windley,whiteaker,westfield,weibel,wanner,waldrep,villani,vanarsdale,utterback,updike,triggs,topete,tolar,tigner,thoms,tauber,tarvin,tally,swiney,sweatman,studebaker,stennett,starrett,stannard,stalvey,sonnenberg,smithey,sieber,sickles,shinault,segars,sanger,salmeron,rothe,rizzi,rine,ricard,restrepo,ralls,ragusa,quiroga,pero,pegg,pavlik,papenfuss,oropeza,okane,neer,nee,mudge,mozingo,molinaro,mcvicker,mcgarvey,mcfalls,mccraney,matus,magers,llanos,livermore,liss,linehan,leto,leitner,laymon,lawing,lacourse,kwong,kollar,kneeland,keo,kennett,kellett,kangas,janzen,hutter,huse,huling,hoss,hohn,hofmeister,hewes,hern,harjo,habib,gust,guice,grullon,greggs,grayer,granier,grable,gowdy,giannini,getchell,gartman,garnica,ganey,gallimore,fray,fetters,fergerson,farlow,fagundes,exley,esteves,enders,edenfield,easterwood,drakeford,dipasquale,desousa,deshields,deeter,dedmon,debord,daughtery,cutts,courtemanche,coursey,copple,coomes,collis,coll,cogburn,clopton,choquette,chaidez,castrejon,calhoon,burbach,bulloch,buchman,bruhn,bohon,blough,bien,baynes,barstow,zeman,zackery,yardley,yamashita,wulff,wilken,wiliams,wickersham,wible,whipkey,wedgeworth,walmsley,walkup,vreeland,verrill,valera,umana,traub,swingle,summey,stroupe,stockstill,steffey,stefanski,statler,stapp,speights,solari,soderberg,shunk,shorey,shewmaker,sheilds,schiffer,schank,schaff,sagers,rochon,riser,rickett,reale,raglin,polen,plata,pitcock,percival,palen,pahl,orona,oberle,nocera,navas,nault,mullings,moos,montejano,monreal,minick,middlebrook,meece,mcmillion,mccullen,mauck,marshburn,maillet,mahaney,magner,maclin,lucey,litteral,lippincott,leite,leis,leaks,lamarre,kost,jurgens,jerkins,jager,hurwitz,hughley,hotaling,horstman,hohman,hocker,hively,hipps,hile,hessler,hermanson,hepworth,henn,helland,hedlund,harkless,haigler,gutierez,grindstaff,glantz,giardina,gerken,gadsden,finnerty,feld,farnum,encinas,drakes,dennie,cutlip,curtsinger,couto,cortinas,corby,chiasson,carle,carballo,brindle,borum,bober,blagg,birk,berthiaume,beahm,batres,basnight,backes,axtell,aust,atterberry,alvares,alt,alegria,yow,yip,woodell,wojciechowski,winfree,winbush,wiest,wesner,wamsley,wakeman,verner,truex,trafton,toman,thorsen,theus,tellier,tallant,szeto,strope,stills,sorg,simkins,shuey,shaul,servin,serio,serafin,salguero,saba,ryerson,rudder,ruark,rother,rohrbaugh,rohrbach,rohan,rogerson,risher,rigg,reeser,pryce,prokop,prins,priebe,prejean,pinheiro,petrone,petri,penson,pearlman,parikh,natoli,murakami,mullikin,mullane,motes,morningstar,monks,mcveigh,mcgrady,mcgaughey,mccurley,masi,marchan,manske,maez,lusby,linde,lile,likens,licon,leroux,lemaire,legette,lax,laskey,laprade,laplant,kolar,kittredge,kinley,kerber,kanagy,jetton,janik,ippolito,inouye,hunsinger,howley,howery,horrell,holthaus,hiner,hilson,hilderbrand,hasan,hartzler,harnish,harada,hansford,halligan,hagedorn,gwynn,gudino,greenstein,greear,gracey,goudeau,gose,goodner,ginsburg,gerth,gerner,fyfe,fujii,frier,frenette,folmar,fleisher,fleischmann,fetzer,eisenman,earhart,dupuy,dunkelberger,drexler,dillinger,dilbeck,dewald,demby,deford,dake,craine,como,chesnut,casady,carstens,carrick,carino,carignan,canchola,cale,bushong,burman,buono,brownlow,broach,britten,brickhouse,boyden,boulton,borne,borland,bohrer,blubaugh,bever,berggren,benevides,arocho,arends,amezcua,almendarez,zalewski,witzel,winkfield,wilhoite,vara,vangundy,vanfleet,vanetten,vandergriff,urbanski,troiano,thibodaux,straus,stoneking,stjean,stillings,stange,speicher,speegle,sowa,smeltzer,slawson,simmonds,shuttleworth,serpa,senger,seidman,schweiger,schloss,schimmel,schechter,sayler,sabb,sabatini,ronan,rodiguez,riggleman,richins,reep,reamer,prunty,porath,plunk,piland,philbrook,pettitt,perna,peralez,pascale,padula,oboyle,nivens,nickols,murph,mundt,munden,montijo,mcmanis,mcgrane,mccrimmon,manzi,mangold,malick,mahar,maddock,losey,litten,liner,leff,leedy,leavell,ladue,krahn,kluge,junker,iversen,imler,hurtt,huizar,hubbert,howington,hollomon,holdren,hoisington,hise,heiden,hauge,hartigan,gutirrez,griffie,greenhill,gratton,granata,gottfried,gertz,gautreaux,furry,furey,funderburg,flippen,fitzgibbon,dyar,drucker,donoghue,dildy,devers,detweiler,despres,denby,degeorge,cueto,cranston,courville,clukey,cirillo,chon,chivers,caudillo,catt,butera,bulluck,buckmaster,braunstein,bracamonte,bourdeau,bonnette,bobadilla,boaz,blackledge,beshears,bernhard,bergeson,baver,barthel,balsamo,bak,aziz,awad,authement,altom,altieri,abels,zigler,zhu,younker,yeomans,yearwood,wurster,winget,whitsett,wechsler,weatherwax,wathen,warriner,wanamaker,walraven,viens,vandemark,vancamp,uchida,triana,tinoco,terpstra,tellis,tarin,taranto,takacs,studdard,struthers,strout,stiller,spataro,soderquist,sliger,silberman,shurtleff,sheetz,ritch,reif,raybon,ratzlaff,radley,putt,putney,pinette,piner,petrin,parise,osbourne,nyman,northington,noblitt,nishimura,neher,nalls,naccarato,mucha,mounce,miron,millis,meaney,mcnichols,mckinnis,mcjunkin,mcduffy,manrique,mannion,mangual,malveaux,mains,lumsden,lohmann,lipe,lightsey,lemasters,leist,laxton,laverriere,latorre,lamons,kral,kopf,knauer,kitt,kaul,karas,kamps,jusino,islam,hullinger,huges,hornung,hiser,hempel,helsel,hassinger,hargraves,hammes,hallberg,gutman,gumbs,gruver,graddy,gonsales,goncalves,glennon,gilford,geno,freshour,flippo,fifer,fason,farrish,fallin,ewert,estepp,escudero,ensminger,emberton,elms,ellerbe,eide,dysart,dougan,dierking,dicus,detrick,deroche,depue,demartino,delosreyes,dalke,culbreath,crownover,crisler,crass,corsi,chagnon,centers,cavanagh,casson,carollo,cadwallader,burnley,burciaga,burchard,broadhead,bolte,berens,bellman,bellard,baril,antonucci,wolfgram,winsor,wimbish,wier,wallach,viveros,vento,varley,vanslyke,vangorder,touchstone,tomko,tiemann,throop,tamura,talmadge,swayze,sturdevant,strauser,stolz,stenberg,stayton,spohn,spillers,spillane,sluss,slavens,simonetti,shofner,shead,senecal,seales,schueler,schley,schacht,sauve,sarno,salsbury,rothschild,rosier,rines,reveles,rein,redus,redfern,reck,ranney,raggs,prout,prill,preble,prager,plemons,pilon,piccirillo,pewitt,pesina,pecora,otani,orsini,oestreich,odea,ocallaghan,northup,niehaus,newberg,nasser,narron,monarrez,mishler,mcsherry,mcelfresh,mayon,mauer,mattice,marrone,marmolejo,marini,malm,machen,lunceford,loewen,liverman,litwin,linscott,levins,lenox,legaspi,leeman,leavy,lannon,lamson,lambdin,labarre,knouse,klemm,kleinschmidt,kirklin,keels,juliano,howser,hosier,hopwood,holyfield,hodnett,hirsh,heimann,heckel,harger,hamil,hajek,gurganus,gunning,grange,gonzalas,goggins,gerow,gaydos,garduno,ganley,galey,farner,engles,emond,emert,ellenburg,edick,duell,dorazio,dimond,diederich,depuy,dempster,demaria,dehoyos,dearth,dealba,czech,crose,crespin,cogdill,clinard,cipriano,chretien,cerny,ceniceros,celestin,caple,cacho,burrill,buhr,buckland,branam,boysen,bovee,boos,boler,blom,blasko,beyers,belz,belmonte,bednarz,beckmann,beaudin,bazile,barbeau,balentine,abrahams,zielke,yunker,yeates,wrobel,wike,whisnant,wherry,wagnon,vogan,vansant,vannest,vallo,ullery,towles,towell,thill,taormina,tannehill,taing,storrs,stickles,stetler,sparling,solt,silcox,sheard,shadle,seman,selleck,schlemmer,scher,sapien,sainz,roye,romain,rizzuto,resch,rentz,rasch,ranieri,purtell,primmer,portwood,pontius,pons,pletcher,pledger,pirkle,pillsbury,pentecost,paxson,ortez,oles,mullett,muirhead,mouzon,mork,mollett,mohn,mitcham,melillo,medders,mcmiller,mccleery,mccaughey,mak,maciejewski,macaulay,lute,lipman,lewter,larocque,langton,kriner,knipp,killeen,karn,kalish,kaczor,jonson,jerez,jarrard,janda,hymes,hollman,hollandsworth,holl,hobdy,hennen,hemmer,hagins,haddox,guitierrez,guernsey,gorsuch,gholson,genova,gazaway,gauna,gammons,freels,fonville,fetterman,fava,farquhar,farish,fabela,escoto,eisen,dossett,dority,dorfman,demmer,dehn,dawley,darbonne,damore,damm,crosley,cron,crompton,crichton,cotner,cordon,conerly,colvard,clauson,cheeseman,cavallaro,castille,cabello,burgan,buffum,bruss,brassfield,bowerman,bothwell,borgen,bonaparte,bombard,boivin,boissonneault,bogner,bodden,boan,bittinger,bickham,bedolla,bale,bainbridge,aybar,avendano,ashlock,amidon,almanzar,akridge,ackermann,zager,worrall,winans,wilsey,wightman,westrick,wenner,warne,warford,verville,utecht,upson,tuma,tseng,troncoso,trollinger,torbert,taulbee,sutterfield,stough,storch,stonebraker,stolle,stilson,stiefel,steptoe,stepney,stender,stemple,staggers,spurrier,spinney,spengler,smartt,skoog,silvis,sieg,shuford,selfridge,seguin,sedgwick,sease,scotti,schroer,schlenker,schill,savarese,sapienza,sanson,sandefur,salamone,rusnak,rudisill,rothermel,roca,resendiz,reliford,rasco,raiford,quisenberry,quijada,pullins,puccio,postell,poppe,pinter,piche,petrucci,pellegrin,pelaez,paton,pasco,parkes,paden,pabst,olmsted,newlon,mynatt,mower,morrone,moree,moffat,mixson,minner,millette,mederos,mcgahan,mcconville,maughan,massingill,marano,macri,lovern,lichtenstein,leonetti,lehner,lawley,laramie,lappin,lahti,lago,lacayo,kuester,kincade,juhl,jiron,jessop,jarosz,jain,hults,hoge,hodgins,hoban,hinkson,hillyard,herzig,hervey,henriksen,hawker,hause,hankerson,gregson,golliday,gilcrease,gessner,gerace,garwood,garst,gaillard,flinchum,fishel,fishback,filkins,fentress,fabre,ethier,eisner,ehrhart,efird,drennon,dominy,domingue,dipaolo,dinan,dimartino,deskins,dengler,defreitas,defranco,dahlin,cutshaw,cuthbert,croyle,crothers,critchfield,cowie,costner,coppedge,copes,ciccone,caufield,capo,cambron,cambridge,buser,burnes,buhl,buendia,brindley,brecht,bourgoin,blackshire,birge,benninger,bembry,beil,begaye,barrentine,banton,balmer,baity,auerbach,ambler,alexandre,ackerson,zurcher,zell,wynkoop,wallick,waid,vos,vizcaino,vester,veale,vandermark,vanderford,tuthill,trivette,thiessen,tewksbury,tao,tabron,swasey,swanigan,stoughton,stoudt,stimson,stecker,stead,spady,souther,smoak,sklar,simcox,sidwell,seybert,sesco,seeman,schwenk,schmeling,rossignol,robillard,robicheaux,riveria,rippeon,ridgley,remaley,rehkop,reddish,rauscher,quirion,pusey,pruden,pressler,potvin,pospisil,paradiso,pangburn,palmateer,ownby,otwell,osterberg,osmond,olsson,oberlander,nusbaum,novack,nokes,nicastro,nehls,naber,mulhern,motter,moretz,milian,mckeel,mcclay,mccart,matsuda,martucci,marple,marko,marciniak,manes,mancia,macrae,lybarger,lint,lineberger,levingston,lecroy,lattimer,laseter,kulick,krier,knutsen,klem,kinne,kinkade,ketterman,kerstetter,kersten,karam,joshi,jent,jefcoat,hillier,hillhouse,hettinger,henthorn,henline,helzer,heitzman,heineman,heenan,haughton,haris,harbert,haman,grinstead,gremillion,gorby,giraldo,gioia,gerardi,geraghty,gaunt,gatson,gardin,gans,gammill,friedlander,frahm,fossett,fosdick,forbush,fondren,fleckenstein,fitchett,filer,feliz,feist,ewart,esters,elsner,edgin,easterly,dussault,durazo,devereaux,deshotel,deckert,dargan,cornman,conkle,condit,claunch,clabaugh,cheesman,chea,charney,casella,carone,carbonell,canipe,campana,calles,cabezas,cabell,buttram,bustillos,buskirk,boyland,bourke,blakeley,berumen,berrier,belli,behrendt,baumbach,bartsch,baney,arambula,alldredge,allbritton,ziemba,zanders,youngquist,yoshioka,yohe,wunder,woodfin,wojtowicz,winkel,wilmore,willbanks,wesolowski,wendland,walko,votaw,vanek,uriarte,urbano,turnipseed,triche,trautman,towler,tokarz,temples,tefft,teegarden,syed,swigart,stoller,stapler,stansfield,smit,smelley,sicard,shulman,shew,shear,sheahan,sharpton,selvidge,schlesinger,savell,sandford,sabatino,rosenbloom,roepke,rish,rhames,renken,reger,quarterman,puig,prasad,poplar,pizano,pigott,phair,petrick,patt,pascua,paramore,papineau,olivieri,ogren,norden,noga,nisbet,munk,morvant,moro,moloney,merz,meltzer,mellinger,mehl,mcnealy,mckernan,mchaney,mccleskey,mcandrews,mayton,markert,maresca,maner,mandujano,malpass,macintyre,lytton,lyall,lummus,longshore,longfellow,lokey,locher,leverette,lepe,lefever,leeson,lederer,lampert,lagrone,kreider,korth,knopf,kleist,keltner,kelling,kaspar,kappler,josephs,huckins,holub,hofstetter,hoehn,higginson,hennings,heid,havel,hauer,harnden,hargreaves,hanger,guild,guidi,grate,grandy,grandstaff,goza,goodridge,goodfellow,goggans,godley,giusti,gilyard,geoghegan,galyon,gaeta,funes,font,flanary,fales,erlandson,ellett,edinger,dziedzic,duerr,draughn,donoho,dimatteo,devos,dematteo,degnan,darlington,danis,dahlstrom,dahlke,czajkowski,cumbie,culbert,crosier,croley,corry,clinger,chalker,cephas,caywood,capehart,cales,cadiz,bussiere,burriss,burkart,brundidge,bronstein,bradt,boydston,bostrom,borel,bolles,blay,blackwelder,bissett,bevers,bester,bernardino,benefiel,belote,beedle,beckles,baysinger,bassler,bartee,barlett,bargas,barefield,baptista,arterburn,armas,apperson,amoroso,amedee,zullo,zellner,yelton,willems,wilkin,wiggin,widman,welk,weingarten,walla,viers,vess,verdi,veazey,vannote,tullos,trudell,trower,trosper,trimm,trew,tousignant,topp,tocco,thoreson,terhune,tatom,suniga,sumter,steeves,stansell,soltis,sloss,slaven,shisler,shanley,servantes,selders,segrest,seese,seeber,schaible,savala,sartor,rutt,rumbaugh,ruis,roten,roessler,ritenour,riney,restivo,renard,rakestraw,rake,quiros,pullin,prudhomme,primeaux,prestridge,presswood,ponte,polzin,poarch,pittenger,piggott,pickell,phaneuf,parvin,parmley,palmeri,ozment,ormond,ordaz,ono,olea,obanion,oakman,novick,nicklas,nemec,nappi,mund,morfin,mera,melgoza,melby,mcgoldrick,mcelwain,mcchristian,mccaw,marquart,marlatt,markovich,mahr,lupton,lucus,lorusso,lerman,leddy,leaman,leachman,lavalle,laduke,kummer,koury,konopka,koh,koepp,kloss,klock,khalil,kernan,kappel,jakes,inoue,hutsell,howle,honore,hockman,hockaday,hiltz,hetherington,hesser,hershman,heffron,headen,haskett,hartline,harned,guillemette,guglielmo,guercio,greenbaum,goris,glines,gilmour,gardella,gadd,gabler,gabbert,fuselier,freudenburg,fragoso,follis,flemings,feltman,febus,farren,fallis,evert,ekstrom,eastridge,dyck,dufault,dubreuil,drapeau,domingues,dolezal,dinkel,didonato,devitt,demott,daughtrey,daubert,das,creason,crary,costilla,chipps,cheatwood,carmean,canton,caffrey,burgher,buker,brunk,brodbeck,brantner,bolivar,boerner,bodkin,biel,bencomo,bellino,beliveau,beauvais,beaupre,baylis,baskett,barcus,baltz,asay,arney,arcuri,ankney,agostini,addy,zwilling,zubia,zollinger,zeitz,yanes,winship,winningham,wickline,webre,waddington,vosburgh,verrett,varnum,vandeventer,vacca,usry,towry,touchet,tookes,tonkin,timko,tibbitts,thedford,tarleton,talty,talamantez,tafolla,sugg,strecker,steffan,spiva,slape,shatzer,seyler,seamans,schmaltz,schipper,sasso,ruppe,roudebush,riemer,richarson,revilla,reichenbach,ratley,railsback,quayle,poplin,poorman,ponton,pollitt,poitras,piscitelli,piedra,pew,perera,penwell,pelt,parkhill,paladino,ore,oram,olmo,oliveras,olivarria,ogorman,naron,muncie,mowbray,morones,moretti,monn,mitts,minks,minarik,mimms,milliron,millington,millhouse,messersmith,mcnett,mckinstry,mcgeorge,mcdill,mcateer,mazzeo,matchett,mahood,mabery,lundell,louden,losoya,lisk,lezama,leib,lebo,lanoue,lanford,lafortune,kump,krone,kreps,kott,kopecky,kolodziej,kinman,kimmons,kelty,kaster,karlson,kania,joyal,jenner,jasinski,jandreau,isenhour,hunziker,huhn,houde,houchins,holtman,hodo,heyman,hentges,hedberg,hayne,haycraft,harshbarger,harshaw,harriss,haring,hansell,hanford,handler,hamblen,gunnell,groat,gorecki,gochenour,gleeson,genest,geiser,fulghum,friese,fridley,freeborn,frailey,flaugher,fiala,ettinger,etheredge,espitia,eriksen,engelbrecht,engebretson,elie,eickhoff,edney,edelen,eberhard,eastin,eakes,driggs,doner,donaghy,disalvo,deshong,dahms,dahlquist,curren,cripe,cree,creager,corle,conatser,commons,coggin,coder,coaxum,closson,clodfelter,classen,chittenden,castilleja,casale,cartee,carriere,canup,canizales,burgoon,bunger,bugarin,buchanon,bruning,bruck,brookes,broadwell,brier,brekke,breese,bracero,bowley,bowersox,bose,bogar,blauser,blacker,bjorklund,baumer,basler,baize,baden,auman,amundsen,amore,alvarenga,adamczyk,yerkes,yerby,yamaguchi,worthey,wolk,wixom,wiersma,wieczorek,whiddon,weyer,wetherington,wein,watchman,warf,wansley,vesely,velazco,vannorman,valasquez,utz,urso,turco,turbeville,trivett,toothaker,toohey,tondreau,thaler,sylvain,swindler,swigert,swider,stiner,stever,steffes,stampley,stair,smidt,skeete,silvestre,shutts,shealey,seigler,schweizer,schuldt,schlichting,scherr,saulsberry,saner,rosin,rosato,roling,rohn,rix,rister,remley,remick,recinos,ramm,raabe,pursell,poythress,poli,pokorny,pettry,petrey,petitt,penman,payson,paquet,pappalardo,outland,orenstein,nuttall,nuckols,nott,nimmo,murtagh,mousseau,moulder,mooneyhan,moak,minch,miera,mercuri,meighan,mcnelly,mcguffin,mccreery,mcclaskey,mainor,luongo,lundstrom,loughman,lobb,linhart,lever,leu,leiter,lehoux,lehn,lares,lapan,langhorne,lamon,ladwig,ladson,kuzma,kreitzer,knop,keech,kea,kadlec,jhonson,jantz,inglis,husk,hulme,housel,hofman,hillery,heidenreich,heaps,haslett,harting,hartig,hamler,halton,hallum,gutierres,guida,guerrier,grossi,gress,greenhalgh,gravelle,gow,goslin,gonyea,gipe,gerstner,gasser,garceau,gannaway,gama,gallop,gaiser,fullilove,foutz,fossum,flannagan,farrior,faller,ericksen,entrekin,enochs,englund,ellenberger,eastland,earwood,dudash,drozd,desoto,delph,dekker,dejohn,degarmo,defeo,defalco,deblois,dacus,cudd,crossen,crooms,cronan,costin,cordray,comerford,colegrove,coldwell,claassen,chartrand,castiglione,carte,cardella,carberry,capp,capobianco,cangelosi,buch,brunell,brucker,brockett,brizendine,brinegar,brimer,brase,bosque,bonk,bolger,bohanon,bohan,blazek,berning,bergan,bennette,beauchemin,battiste,barra,balogh,avallone,aubry,ashcroft,asencio,arledge,anchondo,alvord,acheson,zaleski,yonker,wyss,wycoff,woodburn,wininger,winders,willmon,wiechmann,westley,weatherholt,warnick,wardle,warburton,volkert,villanveva,veit,vass,vanallen,tung,toribio,toothman,tiggs,thornsberry,thome,tepper,teeple,tebo,tassone,tann,stucker,stotler,stoneman,stehle,stanback,stallcup,spurr,speers,spada,solum,smolen,sinn,silvernail,sholes,shives,shain,secrest,seagle,schuette,schoch,schnieders,schild,schiavone,schiavo,scharff,santee,sandell,salvo,rollings,rivenburg,ritzman,rist,reynosa,retana,regnier,rarick,ransome,rall,propes,prall,poyner,ponds,poitra,pippins,pinion,phu,perillo,penrose,pendergraft,pelchat,patenaude,palko,odoms,oddo,novoa,noone,newburn,negri,nantz,mosser,moshier,molter,molinari,moler,millman,meurer,mendel,mcray,mcnicholas,mcnerney,mckillip,mcilvain,mcadory,marmol,marinez,manzer,mankin,makris,majeski,maffei,luoma,luman,luebke,luby,lomonaco,loar,litchford,lintz,licht,levenson,legge,lanigan,krom,kreger,koop,kober,klima,kitterman,kinkead,kimbell,kilian,kibbe,kendig,kemmer,kash,jenkin,inniss,hurlbut,hunsucker,huckabee,hoxie,hoglund,hockensmith,hoadley,hinkel,higuera,herrman,heiner,hausmann,haubrich,hassen,hanlin,hallinan,haglund,hagberg,gullo,gullion,groner,greenwalt,gobert,glowacki,glessner,gines,gildersleeve,gildea,gerke,gebhard,gatton,gately,galasso,fralick,fouse,fluharty,faucette,fairfax,evanoff,elser,ellard,egerton,ector,ebling,dunkel,duhart,drysdale,dostal,dorey,dolph,doles,dismukes,digregorio,digby,dewees,deramus,denniston,dennett,deloney,delaughter,cuneo,cumberland,crotts,crosswhite,cremeans,creasey,cottman,cothern,costales,cosner,corpus,colligan,cobble,clutter,chupp,chevez,chatmon,chaires,caplan,caffee,cabana,burrough,burditt,buckler,brunswick,brouillard,broady,bowlby,bouley,borgman,boltz,boddy,blackston,birdsell,bedgood,bate,bartos,barriga,barna,barcenas,banach,baccus,auclair,ashman,arter,arendt,ansell,allums,allender,alber,albarran,adelson,zoll,wysong,wimbley,wildes,whitis,whitehill,whicker,weymouth,weldy,wark,wareham,waddy,viveiros,vath,vandoren,vanderhoof,unrein,uecker,tsan,trepanier,tregre,torkelson,tobler,tineo,timmer,swopes,swofford,sweeten,swarts,summerfield,sumler,stucky,strozier,stigall,stickel,stennis,stelzer,steely,slayden,skillern,shurtz,shelor,shellenbarger,shand,shabazz,seo,scroggs,schwandt,schrecengost,schoenrock,schirmer,sandridge,ruzicka,rozek,rowlands,roser,rosendahl,romanowski,rolston,riggio,reichman,redondo,reay,rawlinson,raskin,raine,quandt,purpura,pruneda,prevatte,prettyman,pinedo,pierro,pidgeon,phillippi,pfeil,penix,peasley,paro,ospina,ortegon,ogata,ogara,normandin,nordman,nims,nassar,motz,morlan,mooring,moles,moir,mizrahi,mire,minaya,millwood,mikula,messmer,meikle,mctaggart,mcgonagle,mcewan,mccasland,mccane,mccaffery,mcalexander,mattocks,matranga,martone,markland,maravilla,manno,mancha,mallery,magno,lorentz,locklin,livingstone,lipford,lininger,lepley,leming,lemelin,leadbetter,lawhon,lattin,langworthy,lampman,lambeth,lamarr,lahey,krajewski,klopp,kinnison,kestner,kennell,karim,jozwiak,jakubowski,ivery,iliff,iddings,hudkins,houseman,holz,holderman,hoehne,highfill,hiett,heskett,heldt,hedman,hayslett,hatchell,hasse,hamon,hamada,hakala,haislip,haffey,hackbarth,guo,gullickson,guerrette,greenblatt,goudreau,gongora,godbout,glaude,gills,gillison,gigliotti,gargano,gallucci,galli,galante,frasure,fodor,fizer,fishburn,finkbeiner,finck,fager,estey,espiritu,eppinger,epperly,emig,eckley,dray,dorsch,dille,devita,deslauriers,demery,delorme,delbosque,dauphin,dantonio,curd,crume,cozad,cossette,comacho,climer,chadbourne,cespedes,cayton,castaldo,carpino,carls,capozzi,canela,buzard,busick,burlison,brinkmann,bridgeforth,bourbeau,bornstein,bonfiglio,boice,boese,biondi,bilski,betton,berwick,berlanga,behan,becraft,barrientez,banh,balke,balderrama,bahe,bachand,armer,arceo,aliff,alatorre,zermeno,younce,yeoman,yamasaki,wroten,woodby,winer,willits,wilcoxon,wehmeyer,waterbury,wass,wann,wachtel,vizcarra,veitch,vanderbilt,vallone,vallery,ureno,tyer,tipps,tiedeman,theberge,texeira,taub,tapscott,stutts,stults,stukes,spink,sottile,smithwick,slane,simeone,silvester,siegrist,shiffer,sheedy,sheaffer,severin,sellman,scotto,schupp,schueller,schreier,schoolcraft,schoenberger,schnabel,sangster,samford,saliba,ryles,ryans,rossetti,rodriguz,risch,riel,rezendes,rester,rencher,recker,rathjen,profitt,poteete,polizzi,perrigo,patridge,osby,orvis,opperman,oppenheim,onorato,olaughlin,ohagan,ogles,oehler,obyrne,nuzzo,nickle,nease,neagle,navarette,nagata,musto,morison,montz,mogensen,mizer,miraglia,migliore,menges,mellor,mcnear,mcnab,mcloud,mcelligott,mccollom,maynes,marquette,markowski,marcantonio,maldanado,macey,lundeen,longino,lisle,linthicum,limones,lesure,lesage,lauver,laubach,latshaw,lary,lapham,lacoste,lacher,kutcher,knickerbocker,klos,klingler,kleiman,kittleson,kimbrel,kemmerer,kelson,keese,kallas,jurgensen,junkins,juergens,jolliff,jelks,janicki,jang,ingles,huguley,huggard,howton,hone,holford,hogle,hipple,heimbach,heider,heidel,havener,hattaway,harrah,hanscom,hankinson,hamdan,gridley,goulette,goulart,goodrow,girardi,gent,gautreau,gandara,gamblin,galipeau,fyffe,furrow,fulp,fricks,frase,frandsen,fout,foulks,fouche,foskey,forgey,foor,fobbs,finklea,fincham,figueiredo,festa,ferrier,fellman,eslick,eilerman,eckart,eaglin,dunfee,dumond,drewry,douse,dimick,diener,dickert,deines,declue,daw,dattilo,danko,custodio,cuccia,crunk,crispin,corp,corea,coppin,considine,coniglio,conboy,cockrum,clute,clewis,christiano,channell,cerrato,cecere,catoe,castillon,castile,carstarphen,carmouche,caperton,buteau,bumpers,brey,brazeal,brassard,braga,bradham,bourget,borrelli,borba,boothby,bohr,bohm,boehme,bodin,bloss,blocher,bizzell,bieker,berthelot,bernardini,berends,benard,belser,baze,bartling,barrientes,barras,barcia,banfield,aurand,artman,arnott,arend,amon,almaguer,allee,albarado,alameda,abdo,zuehlke,zoeller,yokoyama,yocom,wyllie,woolum,wint,winland,wilner,wilmes,whitlatch,westervelt,walthall,walkowiak,walburn,viviano,vanderhoff,valez,ugalde,trumbull,todaro,tilford,tidd,tibbits,terranova,templeman,tannenbaum,talmage,tabarez,swearengin,swartwood,svendsen,strum,strack,storie,stockard,steinbeck,starns,stanko,stankiewicz,stacks,stach,sproles,spenser,smotherman,slusser,sinha,silber,siefert,siddiqui,shuff,sherburne,seldon,seddon,schweigert,schroeter,schmucker,saffold,rutz,rundle,rosinski,rosenow,rogalski,ridout,rhymer,replogle,raygoza,ratner,rascoe,rahm,quast,pressnell,predmore,pou,porto,pleasants,pigford,pavone,patnaude,parramore,papadopoulos,palmatier,ouzts,oshields,ortis,olmeda,olden,okamoto,norby,nitz,niebuhr,nevius,neiman,neidig,neece,murawski,mroz,moylan,moultry,mosteller,moring,morganti,mook,moffet,mettler,merlo,mengel,mendelsohn,meli,melchior,mcmeans,mcfaddin,mccullers,mccollister,mccloy,mcclaine,maury,maser,martelli,manthey,malkin,maio,magwood,maginnis,mabon,luton,lusher,lucht,lobato,levis,letellier,legendre,latson,larmon,largo,landreneau,landgraf,lamberson,kurland,kresge,korman,korando,klapper,kitson,kinyon,kincheloe,kawamoto,kawakami,jenney,jeanpierre,ivers,issa,ince,hollier,hollars,hoerner,hodgkinson,hiott,hibbitts,herlihy,henricks,heavner,hayhurst,harvill,harewood,hanselman,hanning,gustavson,grizzard,graybeal,gravley,gorney,goll,goehring,godines,gobeil,glickman,giuliano,gimbel,geib,gayhart,gatti,gains,gadberry,frei,fraise,fouch,forst,forsman,folden,fogleman,fetty,feely,fabry,eury,estill,epling,elamin,echavarria,dutil,duryea,dumais,drago,downard,douthit,doolin,dobos,dison,dinges,diebold,desilets,deshazo,depaz,degennaro,dall,cyphers,cryer,croce,crisman,credle,coriell,copp,compos,colmenero,cogar,carnevale,campanella,caley,calderone,burtch,brouwer,brehmer,brassell,brafford,bourquin,bourn,bohnert,blewett,blass,blakes,bhakta,besser,berge,bellis,balfour,avera,applin,ammon,alsop,aleshire,akbar,zoller,zapien,wymore,wyble,wolken,wix,wickstrom,whobrey,whigham,westerlund,welsch,weisser,weisner,weinstock,wehner,watlington,wakeland,wafer,victorino,veltri,veith,urich,uresti,umberger,twedt,tuohy,tschida,trumble,troia,trimmer,topps,tonn,tiernan,threet,thrall,thetford,teneyck,tartaglia,strohl,streater,strausbaugh,stradley,stonecipher,steadham,stansel,stalcup,stabile,sprenger,spradley,speier,southwood,sorrels,slezak,skow,sirmans,simental,sifford,sievert,shover,sheley,selzer,scriven,schwindt,schwan,schroth,saylors,saragosa,sant,salaam,saephan,routt,rousey,ros,rolfes,rieke,rieder,richeson,redinger,rasnick,rapoza,rambert,quist,pyron,pullman,przybylski,pridmore,pooley,pines,perkinson,perine,perham,pecor,peavler,partington,panton,oliverio,olague,ohman,ohearn,noyola,nicolai,nebel,murtha,mowrey,moroney,morgenstern,morant,monsour,moffit,mijares,meriwether,mendieta,melendrez,mejorado,mckittrick,mckey,mckenny,mckelvy,mcelvain,mccoin,mazzarella,mazon,maurin,matthies,maston,maske,marzano,marmon,marburger,mangus,mangino,mallet,luo,losada,londono,lobdell,lipson,lesniak,leighty,lei,lavallie,lareau,laperle,lape,laforce,laffey,kuehner,kravitz,kowalsky,kohr,kinsman,keppler,kennemer,keiper,kaler,jun,jelinek,jarnagin,isakson,hypes,hutzler,huls,horak,hitz,hice,herrell,henslee,heitz,heiss,heiman,hasting,hartwick,harmer,hammontree,hakes,guse,guillotte,groleau,greve,greenough,golub,golson,goldschmidt,golder,godbolt,gilmartin,gies,gibby,geren,genthner,gendreau,gemmill,gaymon,galyean,galeano,friar,folkerts,fleeman,fitzgibbons,ferranti,felan,farrand,eoff,enger,engels,ducksworth,duby,drumheller,douthitt,donis,dixion,dittrich,dials,descoteaux,depaul,denker,demuth,demelo,delacerda,deforge,danos,dalley,daigneault,cybulski,cothren,corns,corkery,copas,clubb,clore,chitty,chichester,chace,catanzaro,castonguay,cassella,carlberg,cammarata,calle,cajigas,byas,buzbee,busey,burling,bufkin,brzezinski,brun,brickner,brabham,boller,bockman,bleich,blakeman,bisbee,bier,bezanson,bevilacqua,besaw,berrian,bequette,beauford,baumgarten,baudoin,batie,basaldua,bardin,bangert,banes,backlund,avitia,artz,archey,apel,amico,alam,aden,zebrowski,yokota,wormley,wootton,womac,wiltz,wigington,whitehorn,whisman,weisgerber,weigle,weedman,watkin,wasilewski,wadlington,wadkins,viverette,vidaurri,vidales,vezina,vanleer,vanhoy,vanguilder,vanbrunt,updegraff,tylor,trinkle,touchette,tilson,tilman,tengan,tarkington,surrett,summy,streetman,straughter,steere,spruell,spadaro,solley,smathers,silvera,siems,shreffler,sholar,selden,schaper,samayoa,ruggeri,rowen,rosso,rosenbalm,roose,ronquillo,rogowski,rexford,repass,renzi,renick,rehberg,ranck,raffa,rackers,raap,puglisi,prinz,pounders,pon,pompa,plasencia,pipkins,petrosky,pelley,pauls,pauli,parkison,parisien,pangle,pancoast,palazzolo,owenby,overbay,orris,orlowski,nipp,newbern,nedd,nealon,najar,mysliwiec,myres,musson,murrieta,munsell,mumma,muldowney,moyle,mowen,morejon,moodie,monier,mikkelsen,miers,metzinger,melin,mcquay,mcpeek,mcneeley,mcglothin,mcghie,mcdonell,mccumber,mccranie,mcbean,mayhugh,marts,marenco,manges,lynam,lupien,luff,luebbert,loh,loflin,lococo,loch,lis,linke,lightle,lewellyn,leishman,lebow,lebouef,leanos,lanz,landy,landaverde,lacefield,kyler,kuebler,kropf,kroeker,kluesner,klass,kimberling,kilkenny,kiker,ketter,kelemen,keasler,kawamura,karst,kardos,igo,huseman,huseby,hurlbert,huard,hottinger,hornberger,hopps,holdsworth,hensen,heilig,heeter,harpole,haak,gutowski,gunnels,grimmer,gravatt,granderson,gotcher,gleaves,genao,garfinkel,frerichs,foushee,flanery,finnie,feldt,fagin,ewalt,ellefson,eiler,eckhart,eastep,digirolamo,didomenico,devera,delavega,defilippo,debusk,daub,damiani,cupples,crofoot,courter,coto,costigan,corning,corman,corlett,cooperman,collison,coghlan,cobbins,coady,coachman,clothier,cipolla,chmielewski,chiodo,chatterton,chappelle,chairez,ceron,casperson,casler,casados,carrow,carlino,carico,cardillo,caouette,canto,canavan,cambra,byard,buterbaugh,buse,bucy,buckwalter,bubb,bryd,brissette,brault,bradwell,boshears,borchert,blansett,biondo,biehl,bessey,belles,beeks,beekman,beaufort,bayliss,bardsley,avilla,astudillo,ardito,antunez,aderholt,abate,yowell,yin,yearby,wurst,woolverton,woolbright,wildermuth,whittenburg,whitely,wetherbee,wenz,welliver,welling,wason,warlick,voorhies,vivier,villines,verde,veiga,varghese,vanwyk,vanwingerden,vanhorne,umstead,twiggs,tusing,trego,tompson,tinkle,thoman,thole,tatman,tartt,suda,studley,strock,strawbridge,stokely,stec,stalter,speidel,spafford,sontag,sokolowski,skillman,skelley,skalski,sison,sippel,sinquefield,siegle,sher,sharrow,setliff,sellner,selig,seibold,seery,scriber,schull,schrupp,schippers,saulsbury,sao,santillo,sanor,rubalcaba,roosa,ronk,robbs,roache,riebe,reinoso,quin,preuss,pottorff,pontiff,plouffe,picou,picklesimer,pettyjohn,petti,penaloza,parmelee,pardee,palazzo,overholt,ogawa,ofarrell,nolting,noda,nickson,nevitt,neveu,navarre,murrow,munz,mulloy,monzo,milliman,metivier,merlino,mcpeters,mckissack,mckeen,mcgurk,mcfee,mcfarren,mcelwee,mceachin,mcdonagh,mccarville,mayhall,mattoon,martello,marconi,marbury,manzella,maly,malec,maitland,maheu,maclennan,lyke,luera,lowenstein,losh,lopiccolo,longacre,loman,loden,loaiza,lieber,libbey,lenhardt,lefebre,lauterbach,lauritsen,lass,larocco,larimer,lansford,lanclos,lamay,lal,kulikowski,kriebel,kosinski,kleinman,kleiner,kleckner,kistner,kissner,kissell,keisler,keeble,keaney,kale,joly,jimison,ikner,hursey,hruska,hove,hou,hosking,hoose,holle,hoeppner,hittle,hitchens,hirth,hinerman,higby,hertzog,hentz,hensler,heier,hegg,hassel,harpe,hara,hain,hagopian,grimshaw,grado,gowin,gowans,googe,goodlow,goering,gleaton,gidley,giannone,gascon,garneau,gambrel,galaz,fuentez,frisina,fresquez,fraher,feuerstein,felten,everman,ertel,erazo,ensign,endo,ellerman,eichorn,edgell,ebron,eaker,dundas,duncanson,duchene,ducan,dombroski,doman,dickison,dewoody,deloera,delahoussaye,dejean,degroat,decaro,dearmond,dashner,dales,crossett,cressey,cowger,cornette,corbo,coplin,coover,condie,cokley,ceaser,cannaday,callanan,cadle,buscher,bullion,bucklin,bruening,bruckner,brose,branan,bradway,botsford,bortz,borelli,bonetti,bolan,boerger,bloomberg,bingman,bilger,berns,beringer,beres,beets,beede,beaudet,beachum,baughn,bator,bastien,basquez,barreiro,barga,baratta,balser,baillie,axford,attebery,arakaki,annunziata,andrzejewski,ament,amendola,adcox,abril,zenon,zeitler,zambrana,ybanez,yagi,wolak,wilcoxson,whitesel,whitehair,weyand,westendorf,welke,weinmann,weesner,weekes,wedel,weatherall,warthen,vose,villalta,viator,vaz,valtierra,urbanek,tulley,trojanowski,trapani,toups,torpey,tomita,tindal,tieman,tevis,tedrow,taul,tash,tammaro,sylva,swiderski,sweeting,sund,stutler,stich,sterns,stegner,stalder,splawn,speirs,southwell,soltys,smead,slye,skipworth,sipos,simmerman,sidhu,shuffler,shingleton,shadwick,sermons,seefeldt,scipio,schwanke,schreffler,schiro,scheiber,sandoz,samsel,ruddell,royse,rouillard,rotella,rosalez,romriell,rizer,riner,rickards,rhoton,rhem,reppert,rayl,raulston,raposo,rainville,radel,quinney,purdie,pizzo,pincus,petrus,pendelton,pendarvis,peltz,peguero,peete,patricio,patchett,parrino,papke,palafox,ottley,ostby,oritz,ogan,odegaard,oatman,noell,nicoll,newhall,newbill,netzer,nettleton,neblett,murley,mungo,mulhall,mosca,morissette,morford,monsen,mitzel,miskell,minder,mehaffey,mcquillen,mclennan,mcgrail,mccreight,mayville,maysonet,maust,mathieson,mastrangelo,maskell,manz,malmberg,makela,madruga,lotts,longnecker,logston,littell,liska,lindauer,lillibridge,levron,letchworth,lesh,leffel,leday,leamon,kulas,kula,kucharski,kromer,kraatz,konieczny,konen,komar,kivett,kirts,kinnear,kersh,keithley,keifer,judah,jimenes,jeppesen,jansson,huntsberry,hund,huitt,huffine,hosford,holmstrom,hollen,hodgin,hirschman,hiltner,hilliker,hibner,hennis,helt,heidelberg,heger,heer,hartness,hardrick,halladay,gula,guillaume,guerriero,grunewald,grosse,griffeth,grenz,grassi,grandison,ginther,gimenez,gillingham,gillham,gess,gelman,gearheart,gaskell,gariepy,gamino,gallien,galentine,fuquay,froman,froelich,friedel,foos,fomby,focht,flythe,fiqueroa,filson,filip,fierros,fett,fedele,fasching,farney,fargo,everts,etzel,elzey,eichner,eger,eatman,ducker,duchesne,donati,domenech,dollard,dodrill,dinapoli,denn,delfino,delcid,delaune,delatte,deems,daluz,cusson,cullison,cuadrado,crumrine,cruickshank,crosland,croll,criddle,crepeau,coutu,couey,cort,coppinger,collman,cockburn,coca,clayborne,claflin,cissell,chowdhury,chicoine,chenier,causby,caulder,cassano,casner,cardiel,brunton,bruch,broxton,brosius,brooking,branco,bracco,bourgault,bosserman,bonet,bolds,bolander,bohman,boelter,blohm,blea,blaise,bischof,beus,bellew,bastarache,bast,bartolome,barcomb,barco,balk,balas,bakos,avey,atnip,ashbrook,arno,arbour,aquirre,appell,aldaco,alban,ahlstrom,abadie,zylstra,zick,yother,wyse,wunsch,whitty,weist,vrooman,villalon,vidrio,vavra,vasbinder,vanmatre,vandorn,ugarte,turberville,tuel,trogdon,toupin,toone,tolleson,tinkham,tinch,tiano,teston,teer,tawney,taplin,tant,tansey,swayne,sutcliffe,sunderman,strothers,stromain,stork,stoneburner,stolte,stolp,stoehr,stingley,stegman,stangl,spinella,spier,soules,sommerfield,sipp,simek,siders,shufelt,shue,shor,shires,shellenberger,sheely,sepe,seaberg,schwing,scherrer,scalzo,sasse,sarvis,santora,sansbury,salls,saleem,ryland,rybicki,ruggieri,rothenberg,rosenstein,roquemore,rollison,rodden,rivet,ridlon,riche,riccardi,reiley,regner,rech,rayo,raff,radabaugh,quon,quill,privette,prange,pickrell,perino,penning,pankratz,orlandi,nyquist,norrell,noren,naples,nale,nakashima,musselwhite,murrin,murch,mullinix,mullican,mullan,morneau,mondor,molinar,minjares,minix,minchew,milewski,mikkelson,mifflin,merkley,meis,meas,mcroy,mcphearson,mcneel,mcmunn,mcmorrow,mcdorman,mccroskey,mccoll,mcclusky,mcclaran,mccampbell,mazzariello,mauzy,mauch,mastro,martinek,marsala,marcantel,mahle,luciani,lubbers,lobel,linch,liller,legros,layden,lapine,lansberry,lage,laforest,labriola,koga,knupp,klimek,kittinger,kirchoff,kinzel,killinger,kilbourne,ketner,kepley,kemble,kells,kear,kaya,karsten,kaneshiro,kamm,joines,joachim,jacobus,iler,holgate,hoar,hisey,hird,hilyard,heslin,herzberg,hennigan,hegland,hartl,haner,handel,gualtieri,greenly,grasser,goetsch,godbold,gilland,gidney,gibney,giancola,gettinger,garzon,galle,galgano,gaier,gaertner,fuston,freel,fortes,fiorillo,figgs,fenstermacher,fedler,facer,fabiano,evins,euler,esquer,enyeart,elem,eich,edgerly,durocher,durgan,duffin,drolet,drewes,dotts,dossantos,dockins,dirksen,difiore,dierks,dickerman,dery,denault,demaree,delmonte,delcambre,daulton,darst,dahle,curnutt,cully,culligan,cueva,crosslin,croskey,cromartie,crofts,covin,coutee,coppa,coogan,condrey,concannon,coger,cloer,clatterbuck,cieslak,chumbley,choudhury,chiaramonte,charboneau,carneal,cappello,campisi,callicoat,burgoyne,bucholz,brumback,brosnan,brogden,broder,brendle,breece,bown,bou,boser,bondy,bolster,boll,bluford,blandon,biscoe,bevill,bence,battin,basel,bartram,barnaby,barmore,balbuena,badgley,backstrom,auyeung,ater,arrellano,arant,ansari,alling,alejandre,alcock,alaimo,aguinaldo,aarons,zurita,zeiger,zawacki,yutzy,yarger,wygant,wurm,wuest,witherell,wisneski,whitby,whelchel,weisz,weisinger,weishaar,wehr,waxman,waldschmidt,walck,waggener,vosburg,villela,vercher,venters,vanscyoc,vandyne,valenza,utt,urick,ungar,ulm,tumlin,tsao,tryon,trudel,treiber,tober,tipler,tillson,tiedemann,thornley,tetrault,temme,tarrance,tackitt,sykora,sweetman,swatzell,sutliff,suhr,sturtz,strub,strayhorn,stormer,steveson,stengel,steinfeldt,spiro,spieker,speth,spero,soza,souliere,soucie,snedeker,slifer,skillings,situ,siniard,simeon,signorelli,siggers,shultis,shrewsbury,shippee,shimp,shepler,sharpless,shadrick,severt,severs,semon,semmes,seiter,segers,sclafani,sciortino,schroyer,schrack,schoenberg,schober,scheidt,scheele,satter,sartori,sarratt,salvaggio,saladino,sakamoto,saine,ryman,rumley,ruggerio,rucks,roughton,robards,ricca,rexroad,resler,reny,rentschler,redrick,redick,reagle,raymo,raker,racette,pyburn,pritt,presson,pressman,pough,pisani,perz,perras,pelzer,pedrosa,palos,palmisano,paille,orem,orbison,oliveros,nourse,nordquist,newbury,nelligan,nawrocki,myler,mumaw,morphis,moldenhauer,miyashiro,mignone,mickelsen,michalec,mesta,mcree,mcqueary,mcninch,mcneilly,mclelland,mclawhorn,mcgreevy,mcconkey,mattes,maselli,marten,marcucci,manseau,manjarrez,malbrough,machin,mabie,lynde,lykes,lueras,lokken,loken,linzy,lillis,lilienthal,levey,legler,leedom,lebowitz,lazzaro,larabee,lapinski,langner,langenfeld,lampkins,lamotte,lambright,lagarde,ladouceur,labounty,lablanc,laberge,kyte,kroon,kron,kraker,kouba,kirwin,kincer,kimbler,kegler,keach,katzman,katzer,kalman,jimmerson,jenning,janus,iacovelli,hust,huson,husby,humphery,hufnagel,honig,holsey,holoman,hohl,hogge,hinderliter,hildebrant,hemby,helle,heintzelman,heidrick,hearon,hazelip,hauk,hasbrouck,harton,hartin,harpster,hansley,hanchett,haar,guthridge,gulbranson,guill,guerrera,grund,grosvenor,grist,grell,grear,granberry,gonser,giunta,giuliani,gillon,gillmore,gillan,gibbon,gettys,gelb,gano,galliher,fullen,frese,frates,foxwell,fleishman,fleener,fielden,ferrera,fells,feemster,fauntleroy,evatt,espy,eno,emmerich,edler,eastham,dunavant,duca,drinnon,dowe,dorgan,dollinger,dipalma,difranco,dietrick,denzer,demarest,delee,delariva,delany,decesare,debellis,deavers,deardorff,dawe,darosa,darley,dalzell,dahlen,curto,cupps,cunniff,cude,crivello,cripps,cresswell,cousar,cotta,compo,clyne,clayson,cearley,catania,carini,cantero,buttrey,buttler,burpee,bulkley,buitron,buda,bublitz,bryer,bryden,brouillette,brott,brookman,bronk,breshears,brennen,brannum,brandl,braman,bracewell,boyter,bomberger,bogen,boeding,blauvelt,blandford,biermann,bielecki,bibby,berthold,berkman,belvin,bellomy,beland,behne,beecham,becher,bax,bassham,barret,baley,auxier,atkison,ary,arocha,arechiga,anspach,algarin,alcott,alberty,ager,ackman,abdallah,zwick,ziemer,zastrow,zajicek,yokum,yokley,wittrock,winebarger,wilker,wilham,whitham,wetzler,westling,westbury,wendler,wellborn,weitzman,weitz,wallner,waldroup,vrabel,vowels,volker,vitiello,visconti,villicana,vibbert,vesey,vannatter,vangilder,vandervort,vandegrift,vanalstyne,vallecillo,usrey,tynan,turpen,tuller,trisler,townson,tillmon,threlkeld,thornell,terrio,taunton,tarry,tardy,swoboda,swihart,sustaita,suitt,stuber,strine,stookey,stmartin,stiger,stainbrook,solem,smail,sligh,siple,sieben,shumake,shriner,showman,sheen,sheckler,seim,secrist,scoggin,schultheis,schmalz,schendel,schacher,savard,saulter,santillanes,sandiford,sande,salzer,salvato,saltz,sakai,ryckman,ryant,ruck,rittenberry,ristau,richart,rhynes,reyer,reulet,reser,redington,reddington,rebello,reasor,raftery,rabago,raasch,quintanar,pylant,purington,provencal,prioleau,prestwood,pothier,popa,polster,politte,poffenberger,pinner,pietrzak,pettie,penaflor,pellot,pellham,paylor,payeur,papas,paik,oyola,osbourn,orzechowski,oppenheimer,olesen,oja,ohl,nuckolls,nordberg,noonkester,nold,nitta,niblett,neuhaus,nesler,nanney,myrie,mutch,mosquera,morena,montalto,montagna,mizelle,mincy,millikan,millay,miler,milbourn,mikels,migues,miesner,mershon,merrow,meigs,mealey,mcraney,mcmartin,mclachlan,mcgeehan,mcferren,mcdole,mccaulley,mcanulty,maziarz,maul,mateer,martinsen,marson,mariotti,manna,mance,malbon,magnusson,maclachlan,macek,lurie,luc,lown,loranger,lonon,lisenby,linsley,lenk,leavens,lauritzen,lathem,lashbrook,landman,lamarche,lamantia,laguerre,lagrange,kogan,klingbeil,kist,kimpel,kime,kier,kerfoot,kennamer,kellems,kammer,kamen,jepsen,jarnigan,isler,ishee,hux,hungate,hummell,hultgren,huffaker,hruby,hornick,hooser,hooley,hoggan,hirano,hilley,higham,heuser,henrickson,henegar,hellwig,hedley,hasegawa,hartt,hambright,halfacre,hafley,guion,guinan,grunwald,grothe,gries,greaney,granda,grabill,gothard,gossman,gosser,gossard,gosha,goldner,gobin,ginyard,gilkes,gilden,gerson,gephart,gengler,gautier,gassett,garon,galusha,gallager,galdamez,fulmore,fritsche,fowles,foutch,footman,fludd,ferriera,ferrero,ferreri,fenimore,fegley,fegan,fearn,farrier,fansler,fane,falzone,fairweather,etherton,elsberry,dykema,duppstadt,dunnam,dunklin,duet,dudgeon,dubuc,doxey,donmoyer,dodgen,disanto,dingler,dimattia,dilday,digennaro,diedrich,derossett,depp,demasi,degraffenreid,deakins,deady,davin,daigre,daddario,czerwinski,cullens,cubbage,cracraft,combest,coletti,coghill,claybrooks,christofferse,chiesa,chason,chamorro,celentano,cayer,carolan,carnegie,capetillo,callier,cadogan,caba,byrom,byrns,burrowes,burket,burdge,burbage,buchholtz,brunt,brungardt,brunetti,brumbelow,brugger,broadhurst,brigance,brandow,bouknight,bottorff,bottomley,bosarge,borger,bombardier,boggan,blumer,blecha,birney,birkland,betances,beran,belin,belgrave,bealer,bauch,bashir,bartow,baro,barnhouse,barile,ballweg,baisley,bains,baehr,badilla,bachus,bacher,bachelder,auzenne,aten,astle,allis,agarwal,adger,adamek,ziolkowski,zinke,zazueta,zamorano,younkin,wittig,witman,winsett,winkles,wiedman,whitner,whitcher,wetherby,westra,westhoff,wehrle,wagaman,voris,vicknair,veasley,vaugh,vanderburg,valletta,tunney,trumbo,truluck,trueman,truby,trombly,tourville,tostado,titcomb,timpson,tignor,thrush,thresher,thiede,tews,tamplin,taff,tacker,syverson,sylvestre,summerall,stumbaugh,strouth,straker,stradford,stokley,steinhoff,steinberger,spigner,soltero,snively,sletten,sinkler,sinegal,simoes,siller,sigel,shire,shinkle,shellman,sheller,sheats,sharer,selvage,sedlak,schriver,schimke,scheuerman,schanz,savory,saulters,sauers,sais,rusin,rumfelt,ruhland,rozar,rosborough,ronning,rolph,roloff,robie,rimer,riehle,ricco,rhein,retzlaff,reisman,reimann,rayes,raub,raminez,quesinberry,pua,procopio,priolo,printz,prewett,preas,prahl,poovey,ploof,platz,plaisted,pinzon,pineiro,pickney,petrovich,perl,pehrson,peets,pavon,pautz,pascarella,paras,paolini,pafford,oyer,ovellette,outten,outen,orduna,odriscoll,oberlin,nosal,niven,nisbett,nevers,nathanson,mukai,mozee,mowers,motyka,morency,montford,mollica,molden,mitten,miser,millender,midgette,messerly,melendy,meisel,meidinger,meany,mcnitt,mcnemar,mcmakin,mcgaugh,mccaa,mauriello,maudlin,matzke,mattia,matsumura,masuda,mangels,maloof,malizia,mahmoud,maglione,maddix,lucchesi,lochner,linquist,lietz,leventhal,lemanski,leiser,laury,lauber,lamberth,kuss,kulik,kuiper,krout,kotter,kort,kohlmeier,koffler,koeller,knipe,knauss,kleiber,kissee,kirst,kirch,kilgo,kerlin,kellison,kehl,kalb,jorden,jantzen,inabinet,ikard,husman,hunsberger,hundt,hucks,houtz,houseknecht,hoots,hogsett,hogans,hintze,hession,henault,hemming,helsley,heinen,heffington,heberling,heasley,hazley,hazeltine,hayton,hayse,hawke,haston,harward,harrow,hanneman,hafford,hadnot,guerro,grahm,gowins,gordillo,goosby,glatt,gibbens,ghent,gerrard,germann,gebo,gean,garling,gardenhire,garbutt,gagner,furguson,funchess,fujiwara,fujita,friley,frigo,forshee,folkes,filler,fernald,ferber,feingold,faul,farrelly,fairbank,failla,espey,eshleman,ertl,erhart,erhardt,erbe,elsea,ells,ellman,eisenhart,ehmann,earnhardt,duplantis,dulac,ducote,draves,dosch,dolce,divito,dimauro,derringer,demeo,demartini,delima,dehner,degen,defrancisco,defoor,dedeaux,debnam,cypert,cutrer,cusumano,custis,croker,courtois,costantino,cormack,corbeil,copher,conlan,conkling,cogdell,cilley,chapdelaine,cendejas,castiglia,cashin,carstensen,caprio,calcote,calaway,byfield,butner,bushway,burritt,browner,brobst,briner,bridger,brickley,brendel,bratten,bratt,brainerd,brackman,bowne,bouck,borunda,bordner,bonenfant,boer,boehmer,bodiford,bleau,blankinship,blane,blaha,bitting,bissonette,bigby,bibeau,bermudes,berke,bergevin,bergerson,bendel,belville,bechard,bearce,beadles,batz,bartlow,ayoub,avans,aumiller,arviso,arpin,arnwine,armwood,arent,arehart,arcand,antle,ambrosino,alongi,alm,allshouse,ahart,aguon,ziebarth,zeledon,zakrzewski,yuhas,yingst,yedinak,wommack,winnett,wingler,wilcoxen,whitmarsh,wayt,watley,warkentin,voll,vogelsang,voegele,vivanco,vinton,villafane,viles,ver,venne,vanwagoner,vanwagenen,vanleuven,vanauken,uselton,uren,trumbauer,tritt,treadaway,tozier,tope,tomczak,tomberlin,tomasini,tollett,toller,titsworth,tirrell,tilly,tavera,tarnowski,tanouye,swarthout,sutera,surette,styers,styer,stipe,stickland,stembridge,stearn,starkes,stanberry,stahr,spino,spicher,sperber,speece,sonntag,sneller,smalling,slowik,slocumb,sliva,slemp,slama,sitz,sisto,sisemore,sindelar,shipton,shillings,sheeley,sharber,shaddix,severns,severino,sensabaugh,seder,seawell,seamons,schrantz,schooler,scheffer,scheerer,scalia,saum,santibanez,sano,sanjuan,sampley,sailer,sabella,sabbagh,royall,rottman,rivenbark,rikard,ricketson,rickel,rethman,reily,reddin,reasoner,rast,ranallo,quintal,pung,pucci,proto,prosperie,prim,preusser,preslar,powley,postma,pinnix,pilla,pietsch,pickerel,pica,pharris,petway,petillo,perin,pereda,pennypacker,pennebaker,pedrick,patin,patchell,parodi,parman,pantano,padua,padro,osterhout,orner,olivar,ohlson,odonoghue,oceguera,oberry,novello,noguera,newquist,newcombe,neihoff,nehring,nees,nebeker,mundo,mullenix,morrisey,moronta,morillo,morefield,mongillo,molino,minto,midgley,michie,menzies,medved,mechling,mealy,mcshan,mcquaig,mcnees,mcglade,mcgarity,mcgahey,mcduff,mayweather,mastropietro,masten,maranto,maniscalco,maize,mahmood,maddocks,maday,macha,maag,luken,lopp,lolley,llanas,litz,litherland,lindenberg,lieu,letcher,lentini,lemelle,leet,lecuyer,leber,laursen,larrick,lantigua,langlinais,lalli,lafever,labat,labadie,krogman,kohut,knarr,klimas,klar,kittelson,kirschbaum,kintzel,kincannon,kimmell,killgore,kettner,kelsch,karle,kapoor,johansson,jenkinson,janney,iraheta,insley,hyslop,huckstep,holleran,hoerr,hinze,hinnenkamp,hilger,higgin,hicklin,heroux,henkle,helfer,heikkinen,heckstall,heckler,heavener,haydel,haveman,haubert,harrop,harnois,hansard,hanover,hammitt,haliburton,haefner,hadsell,haakenson,guynn,guizar,grout,grosz,gomer,golla,godby,glanz,glancy,givan,giesen,gerst,gayman,garraway,gabor,furness,frisk,fremont,frary,forand,fessenden,ferrigno,fearon,favreau,faulks,falbo,ewen,eurich,etchison,esterly,entwistle,ellingsworth,eisenbarth,edelson,eckel,earnshaw,dunneback,doyal,donnellan,dolin,dibiase,deschenes,dermody,degregorio,darnall,dant,dansereau,danaher,dammann,dames,czarnecki,cuyler,custard,cummingham,cuffie,cuffee,cudney,cuadra,crigler,creger,coughlan,corvin,cortright,corchado,connery,conforti,condron,colosimo,colclough,cohee,ciotti,chien,chacko,cevallos,cavitt,cavins,castagna,cashwell,carrozza,carrara,capra,campas,callas,caison,caggiano,bynoe,buswell,burpo,burnam,burges,buerger,buelow,bueche,bruni,brummitt,brodersen,briese,breit,brakebill,braatz,boyers,boughner,borror,borquez,bonelli,bohner,blaker,blackmer,bissette,bibbins,bhatt,bhatia,bessler,bergh,beresford,bensen,benningfield,bellantoni,behler,beehler,beazley,beauchesne,bargo,bannerman,baltes,balog,ballantyne,axelson,apgar,aoki,anstett,alejos,alcocer,albury,aichele,ackles,zerangue,zehner,zank,zacarias,youngberg,yorke,yarbro,wydra,worthley,wolbert,wittmer,witherington,wishart,winkleman,willilams,willer,wiedeman,whittingham,whitbeck,whetsel,wheless,westerberg,welcher,wegman,waterfield,wasinger,warfel,wannamaker,walborn,wada,vogl,vizcarrondo,vitela,villeda,veras,venuti,veney,ulrey,uhlig,turcios,tremper,torian,torbett,thrailkill,terrones,teitelbaum,teems,swoope,sunseri,stutes,stthomas,strohm,stroble,striegel,streicher,stodola,stinchcomb,steves,steppe,steller,staudt,starner,stamant,stam,stackpole,sprankle,speciale,spahr,sowders,sova,soluri,soderlund,slinkard,sjogren,sirianni,siewert,sickels,sica,shugart,shoults,shive,shimer,shier,shepley,sheeran,sevin,seto,segundo,sedlacek,scuderi,schurman,schuelke,scholten,schlater,schisler,schiefelbein,schalk,sanon,sabala,ruyle,ruybal,rueb,rowsey,rosol,rocheleau,rishel,rippey,ringgold,rieves,ridinger,retherford,rempe,reith,rafter,raffaele,quinto,putz,purdom,puls,pulaski,propp,principato,preiss,prada,polansky,poch,plath,pittard,pinnock,pfarr,pfannenstiel,penniman,pauling,patchen,paschke,parkey,pando,ouimet,ottman,ostlund,ormiston,occhipinti,nowacki,norred,noack,nishida,nilles,nicodemus,neth,nealey,myricks,murff,mungia,motsinger,moscato,morado,monnier,molyneux,modzelewski,miura,minich,militello,milbrandt,michalik,meserve,mendivil,melara,mcnish,mcelhannon,mccroy,mccrady,mazzella,maule,mattera,mathena,matas,mascorro,marinello,marguez,manwaring,manhart,mangano,maggi,lymon,luter,luse,lukasik,luiz,ludlum,luczak,lowenthal,lossett,lorentzen,loredo,longworth,lomanto,lisi,lish,lipsky,linck,liedtke,levering,lessman,lemond,lembo,ledonne,leatham,laufer,lanphear,langlais,lamphear,lamberton,lafon,lade,lacross,kyzer,krok,kring,krell,krehbiel,kratochvil,krach,kovar,kostka,knudtson,knaack,kliebert,klahn,kirkley,kimzey,kerrick,kennerson,keesler,karlin,janousek,imel,icenhour,hyler,hudock,houpt,holquin,holiman,holahan,hodapp,hillen,hickmon,hersom,henrich,helvey,heidt,heideman,hedstrom,hedin,hebron,hayter,harn,hardage,halsted,hahne,hagemann,guzik,guel,groesbeck,gritton,grego,graziani,grasty,graney,gouin,gossage,golston,goheen,godina,glade,giorgi,giambrone,gerrity,gerrish,gero,gerling,gaulke,garlick,galiano,gaiter,gahagan,gagnier,friddle,fredericksen,franqui,follansbee,foerster,flury,fitzmaurice,fiorini,finlayson,fiecke,fickes,fichter,ferron,farrel,fackler,eyman,escarcega,errico,erler,erby,engman,engelmann,elsass,elliston,eddleman,eadie,dummer,drost,dorrough,dorrance,doolan,donalson,domenico,ditullio,dittmar,dishon,dionisio,dike,devinney,desir,deschamp,derrickson,delamora,deitch,dechant,danek,dahmen,curci,cudjoe,croxton,creasman,craney,crader,cowling,coulston,cortina,corlew,corl,copland,convery,cohrs,clune,clausing,cipriani,cianciolo,chubb,chittum,chenard,charlesworth,charlebois,champine,chamlee,chagoya,casselman,cardello,capasso,cannella,calderwood,byford,buttars,bushee,burrage,buentello,brzozowski,bryner,brumit,brookover,bronner,bromberg,brixey,brinn,briganti,bremner,brawn,branscome,brannigan,bradsher,bozek,boulay,bormann,bongiorno,bollin,bohler,bogert,bodenhamer,blose,bivona,billips,bibler,benfer,benedetti,belue,bellanger,belford,behn,barnhardt,baltzell,balling,balducci,bainter,babineau,babich,baade,attwood,asmus,asaro,artiaga,applebaum,anding,amar,amaker,allsup,alligood,alers,agin,agar,achenbach,abramowitz,abbas,aasen,zehnder,yopp,yelle,yeldell,wynter,woodmansee,wooding,woll,winborne,willsey,willeford,widger,whiten,whitchurch,whang,weissinger,weinman,weingartner,weidler,waltrip,wagar,wafford,vitagliano,villalvazo,villacorta,vigna,vickrey,vicini,ventimiglia,vandenbosch,valvo,valazquez,utsey,urbaniak,unzueta,trombetta,trevizo,trembley,tremaine,traverso,tores,tolan,tillison,tietjen,teachout,taube,tatham,tarwater,tarbell,sydow,swims,swader,striplin,stoltenberg,steinhauer,steil,steigerwald,starkweather,stallman,squier,sparacino,spadafora,shiflet,shibata,shevlin,sherrick,sessums,servais,senters,seevers,seelye,searfoss,seabrooks,scoles,schwager,schrom,schmeltzer,scheffel,sawin,saterfiel,sardina,sanroman,sandin,salamanca,saladin,sabia,rustin,rushin,ruley,rueter,rotter,rosenzweig,rohe,roder,riter,rieth,ried,ridder,rennick,remmers,remer,relyea,reilley,reder,rasheed,rakowski,rabin,queener,pursel,prowell,pritts,presler,pouncy,porche,porcaro,pollman,pleas,planas,pinkley,pinegar,pilger,philson,petties,perrodin,pendergrast,patao,pasternak,passarelli,pasko,parshall,panos,panella,palombo,padillo,oyama,overlock,overbeck,otterson,orrell,ornellas,opitz,okelly,obando,noggle,nicosia,netto,negrin,natali,nakayama,nagao,nadel,musial,murrill,murrah,munsch,mucci,mrozek,moyes,mowrer,moris,morais,moorhouse,monico,mondy,moncayo,miltenberger,milsap,milone,millikin,milardo,micheals,micco,meyerson,mericle,mendell,meinhardt,meachum,mcleroy,mcgray,mcgonigal,maultsby,matis,matheney,matamoros,marro,marcil,marcial,mantz,mannings,maltby,malchow,maiorano,mahn,mahlum,maglio,maberry,lustig,luellen,longwell,longenecker,lofland,locascio,linney,linneman,lighty,levell,levay,lenahan,lemen,lehto,lebaron,lanctot,lamy,lainez,laffoon,labombard,kujawski,kroger,kreutzer,korhonen,kondo,kollman,kohan,kogut,knaus,kivi,kittel,kinner,kindig,kindel,kiesel,kibby,khang,kettler,ketterer,kepner,kelliher,keenum,kanode,kail,juhasz,jowett,jolicoeur,jeon,iser,ingrassia,imai,hutchcraft,humiston,hulings,hukill,huizenga,hugley,hornyak,hodder,hisle,hillenbrand,hille,higuchi,hertzler,herdon,heppner,hepp,heitmann,heckart,hazlewood,hayles,hayek,hawkin,haugland,hasler,harbuck,happel,hambly,hambleton,hagaman,guzzi,gullette,guinyard,grogg,grise,griffing,goto,gosney,goley,goldblatt,gledhill,girton,giltner,gillock,gilham,gilfillan,giblin,gentner,gehlert,gehl,garten,garney,garlow,garett,galles,galeana,futral,fuhr,friedland,franson,fransen,foulds,follmer,foland,flax,flavin,firkins,fillion,figueredo,ferrill,fenster,fenley,fauver,farfan,eustice,eppler,engelman,engelke,emmer,elzy,ellwood,ellerbee,elks,ehret,ebbert,durrah,dupras,dubuque,dragoo,donlon,dolloff,dibella,derrico,demko,demar,darrington,czapla,crooker,creagh,cranor,craner,crabill,coyer,cowman,cowherd,cottone,costillo,coster,costas,cosenza,corker,collinson,coello,clingman,clingerman,claborn,chmura,chausse,chaudhry,chapell,chancy,cerrone,caverly,caulkins,carn,campfield,campanelli,callaham,cadorette,butkovich,buske,burrier,burkley,bunyard,buckelew,buchheit,broman,brescia,brasel,boyster,booe,bonomo,bondi,bohnsack,blomberg,blanford,bilderback,biggins,bently,behrends,beegle,bedoya,bechtol,beaubien,bayerl,baumgart,baumeister,barratt,barlowe,barkman,barbagallo,baldree,baine,baggs,bacote,aylward,ashurst,arvidson,arthurs,arrieta,arrey,arreguin,arrant,arner,arizmendi,anker,amis,amend,alphin,allbright,aikin,zupan,zuchowski,zeolla,zanchez,zahradnik,zahler,younan,yeater,yearta,yarrington,yantis,woomer,wollard,wolfinger,woerner,witek,wishon,wisener,wingerter,willet,wilding,wiedemann,weisel,wedeking,waybright,wardwell,walkins,waldorf,voth,voit,virden,viloria,villagran,vasta,vashon,vaquera,vantassell,vanderlinden,vandergrift,vancuren,valenta,underdahl,tygart,twining,twiford,turlington,tullius,tubman,trowell,trieu,transue,tousant,torgersen,tooker,tome,toma,tocci,tippins,tinner,timlin,tillinghast,tidmore,teti,tedrick,tacey,swanberg,sunde,summitt,summerford,summa,stratman,strandberg,storck,stober,steitz,stayer,stauber,staiger,sponaugle,spofford,sparano,spagnola,sokoloski,snay,slough,skowronski,sieck,shimkus,sheth,sherk,shankles,shahid,sevy,senegal,seiden,seidell,searls,searight,schwalm,schug,schilke,schier,scheck,sawtelle,santore,sanks,sandquist,sanden,saling,saathoff,ryberg,rustad,ruffing,rudnicki,ruane,rozzi,rowse,rosenau,rodes,risser,riggin,riess,riese,rhoten,reinecke,reigle,reichling,redner,rebelo,raynes,raimondi,rahe,rada,querry,quellette,pulsifer,prochnow,prato,poulton,poudrier,policastro,polhemus,polasek,poissant,pohlmann,plotner,pitkin,pita,pinkett,piekarski,pichon,pfau,petroff,petermann,peplinski,peller,pecinovsky,pearse,pattillo,patague,parlier,parenti,parchman,pane,paff,ortner,oros,nolley,noakes,nigh,nicolosi,nicolay,newnam,netter,nass,napoles,nakata,nakamoto,morlock,moraga,montilla,mongeau,molitor,mohney,mitchener,meyerhoff,medel,mcniff,mcmonagle,mcglown,mcglinchey,mcgarrity,mccright,mccorvey,mcconnel,mccargo,mazzei,matula,mastroianni,massingale,maring,maricle,mans,mannon,mannix,manney,manalo,malo,malan,mahony,madril,mackowiak,macko,macintosh,lurry,luczynski,lucke,lucarelli,losee,lorence,loiacono,lohse,loder,lipari,linebarger,lindamood,limbaugh,letts,leleux,leep,leeder,leard,laxson,lawry,laverdiere,laughton,lastra,kurek,kriss,krishnan,kretschmer,krebsbach,kontos,knobel,knauf,klick,kleven,klawitter,kitchin,kirkendoll,kinkel,kingrey,kilbourn,kensinger,kennerly,kamin,justiniano,jurek,junkin,judon,jordahl,jeanes,jarrells,iwamoto,ishida,immel,iman,ihle,hyre,hurn,hunn,hultman,huffstetler,huffer,hubner,howey,hooton,holts,holscher,holen,hoggatt,hilaire,herz,henne,helstrom,hellickson,heinlein,heckathorn,heckard,headlee,hauptman,haughey,hatt,harring,harford,hammill,hamed,halperin,haig,hagwood,hagstrom,gunnells,gundlach,guardiola,greeno,greenland,gonce,goldsby,gobel,gisi,gillins,gillie,germano,geibel,gauger,garriott,garbarino,gajewski,funari,fullbright,fuell,fritzler,freshwater,freas,fortino,forbus,flohr,flemister,fisch,finks,fenstermaker,feldstein,farhat,fankhauser,fagg,fader,exline,emigh,eguia,edman,eckler,eastburn,dunmore,dubuisson,dubinsky,drayer,doverspike,doubleday,doten,dorner,dolson,dohrmann,disla,direnzo,dipaola,dines,diblasi,dewolf,desanti,dennehy,demming,delker,decola,davilla,daughtridge,darville,darland,danzy,dagenais,culotta,cruzado,crudup,croswell,coverdale,covelli,couts,corbell,coplan,coolbaugh,conyer,conlee,conigliaro,comiskey,coberly,clendening,clairmont,cienfuegos,chojnacki,chilcote,champney,cassara,casazza,casado,carew,carbin,carabajal,calcagni,cail,busbee,burts,burbridge,bunge,bundick,buhler,bucholtz,bruen,broce,brite,brignac,brierly,bridgman,braham,bradish,boyington,borjas,bonn,bonhomme,bohlen,bogardus,bockelman,blick,blackerby,bizier,biro,binney,bertolini,bertin,berti,bento,beno,belgarde,belding,beckel,becerril,bazaldua,bayes,bayard,barrus,barris,baros,bara,ballow,bakewell,baginski,badalamenti,backhaus,avilez,auvil,atteberry,ardon,anzaldua,anello,amsler,ambrosio,althouse,alles,alberti,alberson,aitchison,aguinaga,ziemann,zickefoose,zerr,zeck,zartman,zahm,zabriskie,yohn,yellowhair,yeaton,yarnall,yaple,wolski,wixon,willner,willms,whitsitt,wheelwright,weyandt,wess,wengerd,weatherholtz,wattenbarger,walrath,walpole,waldrip,voges,vinzant,viars,veres,veneziano,veillon,vawter,vaughns,vanwart,vanostrand,valiente,valderas,uhrig,tunison,tulloch,trostle,treaster,traywick,toye,tomson,tomasello,tomasek,tippit,tinajero,tift,tienda,thorington,thieme,thibeau,thakkar,tewell,telfer,sweetser,stratford,stracener,stoke,stiverson,stelling,spatz,spagnoli,sorge,slevin,slabaugh,simson,shupp,shoultz,shotts,shiroma,shetley,sherrow,sheffey,shawgo,shamburger,sester,segraves,seelig,scioneaux,schwartzkopf,schwabe,scholes,schluter,schlecht,schillaci,schildgen,schieber,schewe,schecter,scarpelli,scaglione,sautter,santelli,salmi,sabado,ryer,rydberg,ryba,rushford,runk,ruddick,rotondo,rote,rosenfield,roesner,rocchio,ritzer,rippel,rimes,riffel,richison,ribble,reynold,resh,rehn,ratti,rasor,rasnake,rappold,rando,radosevich,pulice,prichett,pribble,poynor,plowden,pitzen,pittsley,pitter,philyaw,philipps,pestana,perro,perone,pera,peil,pedone,pawlowicz,pattee,parten,parlin,pariseau,paredez,paek,pacifico,otts,ostrow,osornio,oslund,orso,ooten,onken,oniel,onan,ollison,ohlsen,ohlinger,odowd,niemiec,neubert,nembhard,neaves,neathery,nakasone,myerson,muto,muntz,munez,mumme,mumm,mujica,muise,muench,morriss,molock,mishoe,minier,metzgar,mero,meiser,meese,mcsween,mcquire,mcquinn,mcpheeters,mckeller,mcilrath,mcgown,mcdavis,mccuen,mcclenton,maxham,matsui,marriner,marlette,mansur,mancino,maland,majka,maisch,maheux,madry,madriz,mackley,macke,lydick,lutterman,luppino,lundahl,lovingood,loudon,longmore,liefer,leveque,lescarbeau,lemmer,ledgerwood,lawver,lawrie,lattea,lasko,lahman,kulpa,kukowski,kukla,kubota,kubala,krizan,kriz,krikorian,kravetz,kramp,kowaleski,knobloch,klosterman,kloster,klepper,kirven,kinnaman,kinnaird,killam,kiesling,kesner,keebler,keagle,karls,kapinos,kantner,kaba,junious,jefferys,jacquet,izzi,ishii,irion,ifill,hotard,horman,hoppes,hopkin,hokanson,hoda,hocutt,hoaglin,hites,hirai,hindle,hinch,hilty,hild,hier,hickle,hibler,henrichs,hempstead,helmers,hellard,heims,heidler,hawbaker,harkleroad,harari,hanney,hannaford,hamid,haltom,hallford,guilliams,guerette,gryder,groseclose,groen,grimley,greenidge,graffam,goucher,goodenough,goldsborough,gloster,glanton,gladson,gladding,ghee,gethers,gerstein,geesey,geddie,gayer,gaver,gauntt,gartland,garriga,garoutte,fronk,fritze,frenzel,forgione,fluitt,flinchbaugh,flach,fiorito,finan,finamore,fimbres,fillman,figeroa,ficklin,feher,feddersen,fambro,fairbairn,eves,escalona,elsey,eisenstein,ehrenberg,eargle,drane,dogan,dively,dewolfe,dettman,desiderio,desch,dennen,denk,demaris,delsignore,dejarnette,deere,dedman,daws,dauphinais,danz,dantin,dannenberg,dalby,currence,culwell,cuesta,croston,crossno,cromley,crisci,craw,coryell,condra,colpitts,colas,clink,clevinger,clermont,cistrunk,cirilo,chirico,chiarello,cephus,cecena,cavaliere,caughey,casimir,carwell,carlon,carbonaro,caraveo,cantley,callejas,cagney,cadieux,cabaniss,bushard,burlew,buras,budzinski,bucklew,bruneau,brummer,brueggemann,brotzman,bross,brittian,brimage,briles,brickman,breneman,breitenstein,brandel,brackins,boydstun,botta,bosket,boros,borgmann,bordeau,bonifacio,bolten,boehman,blundell,bloodsaw,bjerke,biffle,bickett,bickers,beville,bergren,bergey,benzing,belfiore,beirne,beckert,bebout,baumert,battey,barrs,barriere,barcelo,barbe,balliet,baham,babst,auton,asper,asbell,arzate,argento,arel,araki,arai,antley,amodeo,ammann,allensworth,aldape,akey,abeita,zweifel,zeiler,zamor,zalenski,yzaguirre,yousef,yetman,wyer,woolwine,wohlgemuth,wohlers,wittenberg,wingrove,wimsatt,willimas,wilkenson,wildey,wilderman,wilczynski,wigton,whorley,wellons,welle,weirich,weideman,weide,weast,wasmund,warshaw,walson,waldner,walch,walberg,wagener,wageman,vrieze,vossen,vorce,voorhis,vonderheide,viruet,vicari,verne,velasques,vautour,vartanian,varona,vankeuren,vandine,vandermeer,ursery,underdown,uhrich,uhlman,tworek,twine,twellman,tweedie,tutino,turmelle,tubb,trivedi,triano,trevathan,treese,treanor,treacy,traina,topham,toenjes,tippetts,tieu,thomure,thatch,tetzlaff,tetterton,teamer,tappan,talcott,tagg,szczepanski,syring,surace,sulzer,sugrue,sugarman,suess,styons,stwart,stupka,strey,straube,strate,stoddart,stockbridge,stjames,steimle,steenberg,stamand,staller,stahly,stager,spurgin,sprow,sponsler,speas,spainhour,sones,smits,smelcer,slovak,slaten,singleterry,simien,sidebottom,sibrian,shellhammer,shelburne,shambo,sepeda,seigel,scogin,scianna,schmoll,schmelzer,scheu,schachter,savant,sauseda,satcher,sandor,sampsell,rugh,rufener,rotenberry,rossow,rossbach,rollman,rodrique,rodreguez,rodkey,roda,rini,riggan,rients,riedl,rhines,ress,reinbold,raschke,rardin,racicot,quillin,pushard,primrose,pries,pressey,precourt,pratts,postel,poppell,plumer,pingree,pieroni,pflug,petre,petrarca,peterka,perkin,pergande,peranio,penna,paulhus,pasquariello,parras,parmentier,pamplin,oviatt,osterhoudt,ostendorf,osmun,ortman,orloff,orban,onofrio,olveda,oltman,okeeffe,ocana,nunemaker,novy,noffsinger,nish,niday,nethery,nemitz,neidert,nadal,nack,muszynski,munsterman,mulherin,mortimore,morter,montesino,montalvan,montalbano,momon,moman,mogan,minns,millward,milling,michelsen,mewborn,metayer,mensch,meloy,meggs,meaders,mcsorley,mcmenamin,mclead,mclauchlin,mcguffey,mcguckin,mcglaughlin,mcferron,mcentyre,mccrum,mccawley,mcbain,mayhue,matzen,matton,marsee,marrin,marland,markum,mantilla,manfre,makuch,madlock,macauley,luzier,luthy,lufkin,lucena,loudin,lothrop,lorch,loll,loadholt,lippold,lichtman,liberto,liakos,lewicki,levett,lentine,leja,legree,lawhead,lauro,lauder,lanman,lank,laning,lalor,krob,kriger,kriegel,krejci,kreisel,kozel,konkel,kolstad,koenen,kocsis,knoblock,knebel,klopfer,klee,kilday,kesten,kerbs,kempker,keathley,kazee,kaur,kamer,kamaka,kallenbach,jehle,jaycox,jardin,jahns,ivester,hyppolite,hyche,huppert,hulin,hubley,horsey,hornak,holzwarth,holmon,hollabaugh,holaway,hodes,hoak,hinesley,hillwig,hillebrand,highfield,heslop,herrada,hendryx,hellums,heit,heishman,heindel,hayslip,hayford,hastie,hartgrove,hanus,hakim,hains,hadnott,gundersen,gulino,guidroz,guebert,gressett,graydon,gramling,grahn,goupil,gorelick,goodreau,goodnough,golay,goers,glatz,gillikin,gieseke,giammarino,getman,gensler,gazda,garibaldi,gahan,funderburke,fukuda,fugitt,fuerst,fortman,forsgren,formica,flink,fitton,feltz,fekete,feit,fehrenbach,farone,farinas,faries,fagen,ewin,esquilin,esch,enderle,ellery,ellers,ekberg,egli,effinger,dymond,dulle,dula,duhe,dudney,dowless,dower,dorminey,dopp,dooling,domer,disher,dillenbeck,difilippo,dibernardo,deyoe,devillier,denley,deland,defibaugh,deeb,debow,dauer,datta,darcangelo,daoust,damelio,dahm,dahlman,curlin,cupit,culton,cuenca,cropp,croke,cremer,crace,cosio,corzine,coombe,coman,colone,coloma,collingwood,coderre,cocke,cobler,claybrook,cincotta,cimmino,christoff,chisum,chillemi,chevere,chachere,cervone,cermak,cefalu,cauble,cather,caso,carns,carcamo,carbo,capoccia,capello,capell,canino,cambareri,calvi,cabiness,bushell,burtt,burstein,burkle,bunner,bundren,buechler,bryand,bruso,brownstein,brouse,brodt,brisbin,brightman,brenes,breitenbach,brazzell,brazee,bramwell,bramhall,bradstreet,boyton,bowland,boulter,bossert,bonura,bonebrake,bonacci,boeck,blystone,birchard,bilal,biddy,bibee,bevans,bethke,bertelsen,berney,bergfeld,benware,bellon,bellah,batterton,barberio,bamber,bagdon,badeaux,averitt,augsburger,ates,arvie,aronowitz,arens,araya,angelos,andrada,amell,amante,almy,almquist,alls,aispuro,aguillon,agudelo,aceto,abalos,zdenek,zaremba,zaccaria,youssef,wrona,wrede,wotton,woolston,wolpert,wollman,wince,wimberley,willmore,willetts,wikoff,wieder,wickert,whitenack,wernick,welte,welden,weisenberger,weich,wallington,walder,vossler,vore,vigo,vierling,victorine,verdun,vencill,vazguez,vassel,vanzile,vanvliet,vantrease,vannostrand,vanderveer,vanderveen,vancil,uyeda,umphrey,uhler,uber,tutson,turrentine,tullier,tugwell,trundy,tripodi,tomer,tomasi,tomaselli,tokarski,tisher,tibbets,thweatt,tharrington,tesar,telesco,teasdale,tatem,taniguchi,suriel,sudler,stutsman,sturman,strite,strelow,streight,strawder,stransky,strahl,stours,stong,stinebaugh,stillson,steyer,stelle,steffensmeier,statham,squillante,spiess,spargo,southward,soller,soden,snuggs,snellgrove,smyers,smiddy,slonaker,skyles,skowron,sivils,siqueiros,siers,siddall,shontz,shingler,shiley,shibley,sherard,shelnutt,shedrick,shasteen,sereno,selke,scovil,scola,schuett,schuessler,schreckengost,schranz,schoepp,schneiderman,schlanger,schiele,scheuermann,schertz,scheidler,scheff,schaner,schamber,scardina,savedra,saulnier,sater,sarro,sambrano,salomone,sabourin,ruud,rutten,ruffino,ruddock,rowser,roussell,rosengarten,rominger,rollinson,rohman,roeser,rodenberg,roberds,ridgell,rhodus,reynaga,rexrode,revelle,rempel,remigio,reising,reiling,reetz,rayos,ravenscroft,ravenell,raulerson,rasmusson,rask,rase,ragon,quesnel,quashie,puzo,puterbaugh,ptak,prost,prisbrey,principe,pricer,pratte,pouncey,portman,pontious,pomerantz,planck,pilkenton,pilarski,phegley,pertuit,penta,pelc,peffer,pech,peagler,pavelka,pavao,patman,paskett,parrilla,pardini,papazian,panter,palin,paley,paetzold,packett,pacheo,ostrem,orsborn,olmedo,okamura,oiler,oglesbee,oatis,nuckles,notter,nordyke,nogueira,niswander,nibert,nesby,neloms,nading,naab,munns,mullarkey,moudy,moret,monnin,molder,modisette,moczygemba,moctezuma,mischke,miro,mings,milot,milledge,milhorn,milera,mieles,mickley,micek,metellus,mersch,merola,mercure,mencer,mellin,mell,meinke,mcquillan,mcmurtrie,mckillop,mckiernan,mckendrick,mckamie,mcilvaine,mcguffie,mcgonigle,mcgarrah,mcfetridge,mcenaney,mcdow,mccutchan,mccallie,mcadam,maycock,maybee,mattei,massi,masser,masiello,marshell,marmo,marksberry,markell,marchal,manross,manganaro,mally,mallow,mailhot,magyar,madero,madding,maddalena,macfarland,lynes,lugar,luckie,lucca,lovitt,loveridge,loux,loth,loso,lorenzana,lorance,lockley,lockamy,littler,litman,litke,liebel,lichtenberger,licea,leverich,letarte,lesesne,leno,legleiter,leffew,laurin,launius,laswell,lassen,lasala,laraway,laramore,landrith,lancon,lanahan,laiche,laford,lachermeier,kunst,kugel,kuck,kuchta,kube,korus,koppes,kolbe,koerber,kochan,knittel,kluck,kleve,kleine,kitch,kirton,kirker,kintz,kinghorn,kindell,kimrey,kilduff,kilcrease,kicklighter,kibble,kervin,keplinger,keogh,kellog,keeth,kealey,kazmierczak,karner,kamel,kalina,kaczynski,juel,jerman,jeppson,jawad,jasik,jaqua,janusz,janco,inskeep,inks,ingold,hyndman,hymer,hunte,hunkins,humber,huffstutler,huffines,hudon,hudec,hovland,houze,hout,hougland,hopf,holsapple,holness,hollenbach,hoffmeister,hitchings,hirata,hieber,hickel,hewey,herriman,hermansen,herandez,henze,heffelfinger,hedgecock,hazlitt,hazelrigg,haycock,harren,harnage,harling,harcrow,hannold,hanline,hanel,hanberry,hammersley,hamernik,hajduk,haithcock,haff,hadaway,haan,gullatt,guilbault,guidotti,gruner,grisson,grieves,granato,grabert,gover,gorka,glueck,girardin,giesler,gersten,gering,geers,gaut,gaulin,gaskamp,garbett,gallivan,galland,gaeth,fullenkamp,fullam,friedrichs,freire,freeney,fredenburg,frappier,fowkes,foree,fleurant,fleig,fleagle,fitzsimons,fischetti,fiorenza,finneran,filippi,figueras,fesler,fertig,fennel,feltmann,felps,felmlee,fannon,familia,fairall,fadden,esslinger,enfinger,elsasser,elmendorf,ellisor,einhorn,ehrman,egner,edmisten,edlund,ebinger,dyment,dykeman,durling,dunstan,dunsmore,dugal,duer,drescher,doyel,dossey,donelan,dockstader,dobyns,divis,dilks,didier,desrosier,desanto,deppe,delosh,delange,defrank,debo,dauber,dartez,daquila,dankert,dahn,cygan,cusic,curfman,croghan,croff,criger,creviston,crays,cravey,crandle,crail,crago,craghead,cousineau,couchman,cothron,corella,conine,coller,colberg,cogley,coatney,coale,clendenin,claywell,clagon,cifaldi,choiniere,chickering,chica,chennault,chavarin,chattin,chaloux,challis,cesario,cazarez,caughman,catledge,casebolt,carrel,carra,carlow,capote,canez,camillo,caliendo,calbert,bylsma,buskey,buschman,burkhard,burghardt,burgard,buonocore,bunkley,bungard,bundrick,bumbrey,buice,buffkin,brundige,brockwell,brion,briant,bredeson,bransford,brannock,brakefield,brackens,brabant,bowdoin,bouyer,bothe,boor,bonavita,bollig,blurton,blunk,blanke,blanck,birden,bierbaum,bevington,beutler,betters,bettcher,bera,benway,bengston,benesh,behar,bedsole,becenti,beachy,battersby,basta,bartmess,bartle,bartkowiak,barsky,barrio,barletta,barfoot,banegas,baldonado,azcona,avants,austell,aungst,aune,aumann,audia,atterbury,asselin,asmussen,ashline,asbill,arvizo,arnot,ariola,ardrey,angstadt,anastasio,amsden,amerman,alred,allington,alewine,alcina,alberico,ahlgren,aguas,agrawal,agosta,adolphsen,acey,aburto,abler,zwiebel,zepp,zentz,ybarbo,yarberry,yamauchi,yamashiro,wurtz,wronski,worster,wootten,wongus,woltz,wolanski,witzke,withey,wisecarver,wingham,wineinger,winegarden,windholz,wilgus,wiesen,wieck,widrick,wickliffe,whittenberg,westby,werley,wengert,wendorf,weimar,weick,weckerly,watrous,wasden,walford,wainright,wahlstrom,wadlow,vrba,voisin,vives,vivas,vitello,villescas,villavicencio,villanova,vialpando,vetrano,vensel,vassell,varano,vanriper,vankleeck,vanduyne,vanderpol,vanantwerp,valenzula,udell,turnquist,tuff,trickett,tramble,tingey,timbers,tietz,thiem,tercero,tenner,tenaglia,teaster,tarlton,taitt,tabon,sward,swaby,suydam,surita,suman,suddeth,stumbo,studivant,strobl,streich,stoodley,stoecker,stillwagon,stickle,stellmacher,stefanik,steedley,starbird,stainback,stacker,speir,spath,sommerfeld,soltani,solie,sojka,sobota,sobieski,sobczak,smullen,sleeth,slaymaker,skolnick,skoglund,sires,singler,silliman,shrock,shott,shirah,shimek,shepperd,sheffler,sheeler,sharrock,sharman,shalash,seyfried,seybold,selander,seip,seifried,sedor,sedlock,sebesta,seago,scutt,scrivens,sciacca,schultze,schoemaker,schleifer,schlagel,schlachter,schempp,scheider,scarboro,santi,sandhu,salim,saia,rylander,ryburn,rutigliano,ruocco,ruland,rudloff,rott,rosenburg,rosenbeck,romberger,romanelli,rohloff,rohlfing,rodda,rodd,ritacco,rielly,rieck,rickles,rickenbacker,respass,reisner,reineck,reighard,rehbein,rega,reddix,rawles,raver,rattler,ratledge,rathman,ramsburg,raisor,radovich,radigan,quail,puskar,purtee,priestly,prestidge,presti,pressly,pozo,pottinger,portier,porta,porcelli,poplawski,polin,poeppelman,pocock,plump,plantz,placek,piro,pinnell,pinkowski,pietz,picone,philbeck,pflum,peveto,perret,pentz,payer,patlan,paterno,papageorge,overmyer,overland,osier,orwig,orum,orosz,oquin,opie,ochsner,oathout,nygard,norville,northway,niver,nicolson,newhart,neitzel,nath,nanez,murnane,mortellaro,morreale,morino,moriarity,morgado,moorehouse,mongiello,molton,mirza,minnix,millspaugh,milby,miland,miguez,mickles,michaux,mento,melugin,melito,meinecke,mehr,meares,mcneece,mckane,mcglasson,mcgirt,mcgilvery,mcculler,mccowen,mccook,mcclintic,mccallon,mazzotta,maza,mayse,mayeda,matousek,matley,martyn,marney,marnell,marling,manuelito,maltos,malson,mahi,maffucci,macken,maass,lyttle,lynd,lyden,lukasiewicz,luebbers,lovering,loveall,longtin,lobue,loberg,lipka,lightbody,lichty,levert,lettieri,letsinger,lepak,lemmond,lembke,leitz,lasso,lasiter,lango,landsman,lamirande,lamey,laber,kuta,kulesza,krenz,kreiner,krein,kreiger,kraushaar,kottke,koser,kornreich,kopczynski,konecny,koff,koehl,kocian,knaub,kmetz,kluender,klenke,kleeman,kitzmiller,kirsh,kilman,kildow,kielbasa,ketelsen,kesinger,kehr,keef,kauzlarich,karter,kahre,jobin,jinkins,jines,jeffress,jaquith,jaillet,jablonowski,ishikawa,irey,ingerson,indelicato,huntzinger,huisman,huett,howson,houge,hosack,hora,hoobler,holtzen,holtsclaw,hollingworth,hollin,hoberg,hobaugh,hilker,hilgefort,higgenbotham,heyen,hetzler,hessel,hennessee,hendrie,hellmann,heft,heesch,haymond,haymon,haye,havlik,havis,haverland,haus,harstad,harriston,harju,hardegree,hammell,hamaker,halbrook,halberg,guptill,guntrum,gunderman,gunder,gularte,guarnieri,groll,grippo,greely,gramlich,goewey,goetzinger,goding,giraud,giefer,giberson,gennaro,gemmell,gearing,gayles,gaudin,gatz,gatts,gasca,garn,gandee,gammel,galindez,galati,gagliardo,fulop,fukushima,friedt,fretz,frenz,freeberg,fravel,fountaine,forry,forck,fonner,flippin,flewelling,flansburg,filippone,fettig,fenlon,felter,felkins,fein,favero,faulcon,farver,farless,fahnestock,facemire,faas,eyer,evett,esses,escareno,ensey,ennals,engelking,empey,ellithorpe,effler,edling,edgley,durrell,dunkerson,draheim,domina,dombrosky,doescher,dobbin,divens,dinatale,dieguez,diede,devivo,devilbiss,devaul,determan,desjardin,deshaies,delpozo,delorey,delman,delapp,delamater,deibert,degroff,debelak,dapolito,dano,dacruz,dacanay,cushenberry,cruze,crosbie,cregan,cousino,corrao,corney,cookingham,conry,collingsworth,coldren,cobian,coate,clauss,christenberry,chmiel,chauez,charters,chait,cesare,cella,caya,castenada,cashen,cantrelle,canova,campione,calixte,caicedo,byerley,buttery,burda,burchill,bulmer,bulman,buesing,buczek,buckholz,buchner,buchler,buban,bryne,brunkhorst,brumsey,brumer,brownson,brodnax,brezinski,brazile,braverman,branning,boye,boulden,bough,bossard,bosak,borth,borgmeyer,borge,blowers,blaschke,blann,blankenbaker,bisceglia,billingslea,bialek,beverlin,besecker,berquist,benigno,benavente,belizaire,beisner,behrman,beausoleil,baylon,bayley,bassi,basnett,basilio,basden,basco,banerjee,balli,bagnell,bady,averette,arzu,archambeault,arboleda,arbaugh,arata,antrim,amrhein,amerine,alpers,alfrey,alcon,albus,albertini,aguiniga,aday,acquaviva,accardi,zygmont,zych,zollner,zobel,zinck,zertuche,zaragosa,zale,zaldivar,yeadon,wykoff,woullard,wolfrum,wohlford,wison,wiseley,wisecup,winchenbach,wiltsie,whittlesey,whitelow,whiteford,wever,westrich,wertman,wensel,wenrich,weisbrod,weglarz,wedderburn,weatherhead,wease,warring,wadleigh,voltz,vise,villano,vicario,vermeulen,vazques,vasko,varughese,vangieson,vanfossen,vanepps,vanderploeg,vancleve,valerius,uyehara,unsworth,twersky,turrell,tuner,tsui,trunzo,trousdale,trentham,traughber,torgrimson,toppin,tokar,tobia,tippens,tigue,thiry,thackston,terhaar,tenny,tassin,tadeo,sweigart,sutherlin,sumrell,suen,stuhr,strzelecki,strosnider,streiff,stottlemyer,storment,storlie,stonesifer,stogsdill,stenzel,stemen,stellhorn,steidl,stecklein,statton,stangle,spratling,spoor,spight,spelman,spece,spanos,spadoni,southers,sola,sobol,smyre,slaybaugh,sizelove,sirmons,simington,silversmith,siguenza,sieren,shelman,sharples,sharif,sessler,serrata,serino,serafini,semien,selvey,seedorf,seckman,seawood,scoby,scicchitano,schorn,schommer,schnitzer,schleusner,schlabach,schiel,schepers,schaber,scally,sautner,sartwell,santerre,sandage,salvia,salvetti,salsman,sallis,salais,saeger,sabat,saar,ruther,russom,ruoff,rumery,rubottom,rozelle,rowton,routon,rotolo,rostad,roseborough,rorick,ronco,roher,roberie,robare,ritts,rison,rippe,rinke,ringwood,righter,rieser,rideaux,rickerson,renfrew,releford,reinsch,reiman,reifsteck,reidhead,redfearn,reddout,reaux,rado,radebaugh,quinby,quigg,provo,provenza,provence,pridgeon,praylow,powel,poulter,portner,pontbriand,poirrier,poirer,platero,pixler,pintor,pigman,piersall,piel,pichette,phou,pharis,phalen,petsche,perrier,penfield,pelosi,pebley,peat,pawloski,pawlik,pavlick,pavel,patz,patout,pascucci,pasch,parrinello,parekh,pantaleo,pannone,pankow,pangborn,pagani,pacelli,orsi,oriley,orduno,oommen,olivero,okada,ocon,ocheltree,oberman,nyland,noss,norling,nolton,nobile,nitti,nishimoto,nghiem,neuner,neuberger,neifert,negus,nagler,mullally,moulden,morra,morquecho,moots,mizzell,mirsky,mirabito,minardi,milholland,mikus,mijangos,michener,michalek,methvin,merrit,menter,meneely,meiers,mehring,mees,mcwhirt,mcwain,mcphatter,mcnichol,mcnaught,mclarty,mcivor,mcginness,mcgaughy,mcferrin,mcfate,mcclenny,mcclard,mccaskey,mccallion,mcamis,mathisen,marton,marsico,marchi,mani,mangione,macaraeg,lupi,lunday,lukowski,lucious,locicero,loach,littlewood,litt,lipham,linley,lindon,lightford,lieser,leyendecker,lewey,lesane,lenzi,lenart,leisinger,lehrman,lefebure,lazard,laycock,laver,launer,lastrapes,lastinger,lasker,larkey,lanser,lanphere,landey,lampton,lamark,kumm,kullman,krzeminski,krasner,koran,koning,kohls,kohen,kobel,kniffen,knick,kneip,knappenberger,klumpp,klausner,kitamura,kisling,kirshner,kinloch,kingman,kimery,kestler,kellen,keleher,keehn,kearley,kasprzak,kampf,kamerer,kalis,kahan,kaestner,kadel,kabel,junge,juckett,joynt,jorstad,jetter,jelley,jefferis,jeansonne,janecek,jaffee,izzard,istre,isherwood,ipock,iannuzzi,hypolite,humfeld,hotz,hosein,honahni,holzworth,holdridge,holdaway,holaday,hodak,hitchman,hippler,hinchey,hillin,hiler,hibdon,hevey,heth,hepfer,henneman,hemsley,hemmings,hemminger,helbert,helberg,heinze,heeren,heber,haver,hauff,haswell,harvison,hartson,harshberger,harryman,harries,hane,hamsher,haggett,hagemeier,haecker,haddon,haberkorn,guttman,guttierrez,guthmiller,guillet,guilbert,gugino,grumbles,griffy,gregerson,grana,goya,goranson,gonsoulin,goettl,goertz,godlewski,glandon,gilsdorf,gillogly,gilkison,giard,giampaolo,gheen,gettings,gesell,gershon,gaumer,gartrell,garside,garrigan,garmany,garlitz,garlington,gamet,furlough,funston,funaro,frix,frasca,francoeur,forshey,foose,flatley,flagler,fils,fillers,fickett,feth,fennelly,fencl,felch,fedrick,febres,fazekas,farnan,fairless,ewan,etsitty,enterline,elsworth,elliff,eleby,eldreth,eidem,edgecomb,edds,ebarb,dworkin,dusenberry,durrance,duropan,durfey,dungy,dundon,dumbleton,dubon,dubberly,droz,drinkwater,dressel,doughtie,doshier,dorrell,dople,doonan,donadio,dollison,doig,ditzler,dishner,discher,dimaio,digman,difalco,devino,devens,derosia,deppen,depaola,deniz,denardo,demos,demay,delgiudice,davi,danielsen,dally,dais,dahmer,cutsforth,cusimano,curington,cumbee,cryan,crusoe,crowden,crete,cressman,crapo,cowens,coupe,councill,coty,cotnoir,correira,copen,consiglio,combes,coffer,cockrill,coad,clogston,clasen,chesnutt,charrier,chadburn,cerniglia,cebula,castruita,castilla,castaldi,casebeer,casagrande,carta,carrales,carnley,cardon,capshaw,capron,cappiello,capito,canney,candela,caminiti,califano,calabria,caiazzo,cahall,buscemi,burtner,burgdorf,burdo,buffaloe,buchwald,brwon,brunke,brummond,brumm,broe,brocious,brocato,briski,brisker,brightwell,bresett,breiner,brazeau,braz,brayman,brandis,bramer,bradeen,boyko,bossi,boshart,bortle,boniello,bomgardner,bolz,bolenbaugh,bohling,bohland,bochenek,blust,bloxham,blowe,blish,blackwater,bjelland,biros,biederman,bickle,bialaszewski,bevil,beumer,bettinger,besse,bernett,bermejo,bement,belfield,beckler,baxendale,batdorf,bastin,bashore,bascombe,bartlebaugh,barsh,ballantine,bahl,badon,autin,astin,askey,ascher,arrigo,arbeiter,antes,angers,amburn,amarante,alvidrez,althaus,allmond,alfieri,aldinger,akerley,akana,aikins,ader,acebedo,accardo,abila,aberle,abele,abboud,zollars,zimmerer,zieman,zerby,zelman,zellars,yoshimura,yonts,yeats,yant,yamanaka,wyland,wuensche,worman,wordlaw,wohl,winslett,winberg,wilmeth,willcutt,wiers,wiemer,wickwire,wichman,whitting,whidbee,westergard,wemmer,wellner,weishaupt,weinert,weedon,waynick,wasielewski,waren,walworth,wallingford,walke,waechter,viviani,vitti,villagrana,vien,vicks,venema,varnes,varnadoe,varden,vanpatten,vanorden,vanderzee,vandenburg,vandehey,valls,vallarta,valderrama,valade,urman,ulery,tusa,tuft,tripoli,trimpe,trickey,tortora,torrens,torchia,toft,tjaden,tison,tindel,thurmon,thode,tardugno,tancredi,taketa,taillon,tagle,sytsma,symes,swindall,swicegood,swartout,sundstrom,sumners,sulton,studstill,stroop,stonerock,stmarie,stlawrence,stemm,steinhauser,steinert,steffensen,stefaniak,starck,stalzer,spidle,spake,sowinski,sosnowski,sorber,somma,soliday,soldner,soja,soderstrom,soder,sockwell,sobus,sloop,sinkfield,simerly,silguero,sigg,siemers,siegmund,shum,sholtis,shkreli,sheikh,shattles,sharlow,shambaugh,shaikh,serrao,serafino,selley,selle,seel,sedberry,secord,schunk,schuch,schor,scholze,schnee,schmieder,schleich,schimpf,scherf,satterthwaite,sasson,sarkisian,sarinana,sanzone,salvas,salone,salido,saiki,sahr,rusher,rusek,ruppel,rubel,rothfuss,rothenberger,rossell,rosenquist,rosebrook,romito,romines,rolan,roker,roehrig,rockhold,rocca,robuck,riss,rinaldo,riggenbach,rezentes,reuther,renolds,rench,remus,remsen,reller,relf,reitzel,reiher,rehder,redeker,ramero,rahaim,radice,quijas,qualey,purgason,prum,proudfoot,prock,probert,printup,primer,primavera,prenatt,pratico,polich,podkowka,podesta,plattner,plasse,plamondon,pittmon,pippenger,pineo,pierpont,petzold,petz,pettiway,petters,petroski,petrik,pesola,pershall,perlmutter,penepent,peevy,pechacek,peaden,pazos,pavia,pascarelli,parm,parillo,parfait,paoletti,palomba,palencia,pagaduan,oxner,overfield,overcast,oullette,ostroff,osei,omarah,olenick,olah,odem,nygren,notaro,northcott,nodine,nilges,neyman,neve,neuendorf,neisler,neault,narciso,naff,muscarella,morrisette,morphew,morein,montville,montufar,montesinos,monterroso,mongold,mojarro,moitoso,mirarchi,mirando,minogue,milici,miga,midyett,michna,meuser,messana,menzie,menz,mendicino,melone,mellish,meller,melle,meints,mechem,mealer,mcwilliam,mcwhite,mcquiggan,mcphillips,mcpartland,mcnellis,mcmackin,mclaughin,mckinny,mckeithan,mcguirk,mcgillivray,mcgarr,mcgahee,mcfaul,mcfadin,mceuen,mccullah,mcconico,mcclaren,mccaul,mccalley,mccalister,mazer,mayson,mayhan,maugeri,mauger,mattix,mattews,maslowski,masek,martir,marsch,marquess,maron,markwell,markow,marinaro,marcinek,mannella,mallen,majeed,mahnke,mahabir,magby,magallan,madere,machnik,lybrand,luque,lundholm,lueders,lucian,lubinski,lowy,loew,lippard,linson,lindblad,lightcap,levitsky,levens,leonardi,lenton,lengyel,leitzel,leicht,leaver,laubscher,lashua,larusso,larrimore,lanterman,lanni,lanasa,lamoureaux,lambros,lamborn,lamberti,lall,lafuente,laferriere,laconte,kyger,kupiec,kunzman,kuehne,kuder,kubat,krogh,kreidler,krawiec,krauth,kratky,kottwitz,korb,kono,kolman,kolesar,koeppel,knapper,klingenberg,kjos,keppel,kennan,keltz,kealoha,kasel,karney,kanne,kamrowski,kagawa,johnosn,jilek,jarvie,jarret,jansky,jacquemin,jacox,jacome,iriarte,ingwersen,imboden,iglesia,huyser,hurston,hursh,huntoon,hudman,hoying,horsman,horrigan,hornbaker,horiuchi,hopewell,hommel,homeyer,holzinger,holmer,hipsher,hinchman,hilts,higginbottom,hieb,heyne,hessling,hesler,hertlein,herford,heras,henricksen,hennemann,henery,hendershott,hemstreet,heiney,heckert,heatley,hazell,hazan,hayashida,hausler,hartsoe,harth,harriott,harriger,harpin,hardisty,hardge,hannaman,hannahs,hamp,hammersmith,hamiton,halsell,halderman,hagge,habel,gusler,gushiken,gurr,gummer,gullick,grunden,grosch,greenburg,greb,greaver,gratz,grajales,gourlay,gotto,gorley,goodpasture,godard,glorioso,gloor,glascock,gizzi,giroir,gibeault,gauldin,gauer,gartin,garrels,gamber,gallogly,gade,fusaro,fripp,freyer,freiberg,franzoni,fragale,foston,forti,forness,folts,followell,foard,flom,flett,fleitas,flamm,fino,finnen,finchum,filippelli,fickel,feucht,feiler,feenstra,feagins,faver,faulkenberry,farabaugh,fandel,faler,faivre,fairey,facey,exner,evensen,erion,erben,epting,epping,ephraim,engberg,elsen,ellingwood,eisenmann,eichman,ehle,edsall,durall,dupler,dunker,dumlao,duford,duffie,dudding,dries,doung,dorantes,donahoo,domenick,dollins,dobles,dipiazza,dimeo,diehm,dicicco,devenport,desormeaux,derrow,depaolo,demas,delpriore,delosantos,degreenia,degenhardt,defrancesco,defenbaugh,deets,debonis,deary,dazey,dargie,dambrosia,dalal,dagen,cuen,crupi,crossan,crichlow,creque,coutts,counce,coram,constante,connon,collelo,coit,cocklin,coblentz,cobey,coard,clutts,clingan,clampitt,claeys,ciulla,cimini,ciampa,christon,choat,chiou,chenail,chavous,catto,catalfamo,casterline,cassinelli,caspers,carroway,carlen,carithers,cappel,calo,callow,cagley,cafferty,byun,byam,buttner,buth,burtenshaw,burget,burfield,buresh,bunt,bultman,bulow,buchta,buchmann,brunett,bruemmer,brueggeman,britto,briney,brimhall,bribiesca,bresler,brazan,brashier,brar,brandstetter,boze,boonstra,bluitt,blomgren,blattner,blasi,bladen,bitterman,bilby,bierce,biello,bettes,bertone,berrey,bernat,berberich,benshoof,bendickson,bellefeuille,bednarski,beddingfield,beckerman,beaston,bavaro,batalla,basye,baskins,bartolotta,bartkowski,barranco,barkett,banaszak,bame,bamberger,balsley,ballas,balicki,badura,aymond,aylor,aylesworth,axley,axelrod,aubert,armond,ariza,apicella,anstine,ankrom,angevine,andreotti,alto,alspaugh,alpaugh,almada,allinder,alequin,aguillard,agron,agena,afanador,ackerley,abrev,abdalla,aaronson,zynda,zucco,zipp,zetina,zenz,zelinski,youngren,yochum,yearsley,yankey,woodfork,wohlwend,woelfel,wiste,wismer,winzer,winker,wilkison,wigger,wierenga,whipps,westray,wesch,weld,weible,wedell,weddell,wawrzyniak,wasko,washinton,wantz,walts,wallander,wain,wahlen,wachowiak,voshell,viteri,vire,villafuerte,vieyra,viau,vescio,verrier,verhey,vause,vandermolen,vanderhorst,valois,valla,valcourt,vacek,uzzle,umland,ulman,ulland,turvey,tuley,trembath,trabert,towsend,totman,toews,tisch,tisby,tierce,thivierge,tenenbaum,teagle,tacy,tabler,szewczyk,swearngin,suire,sturrock,stubbe,stronach,stoute,stoudemire,stoneberg,sterba,stejskal,steier,stehr,steckel,stearman,steakley,stanforth,stancill,srour,sprowl,spevak,sokoloff,soderman,snover,sleeman,slaubaugh,sitzman,simes,siegal,sidoti,sidler,sider,sidener,siddiqi,shireman,shima,sheroan,shadduck,seyal,sentell,sennett,senko,seligman,seipel,seekins,seabaugh,scouten,schweinsberg,schwartzberg,schurr,schult,schrick,schoening,schmitmeyer,schlicher,schlager,schack,schaar,scavuzzo,scarpa,sassano,santigo,sandavol,sampsel,samms,samet,salzano,salyards,salva,saidi,sabir,saam,runions,rundquist,rousselle,rotunno,rosch,romney,rohner,roff,rockhill,rocamora,ringle,riggie,ricklefs,rexroat,reves,reuss,repka,rentfro,reineke,recore,recalde,rease,rawling,ravencraft,ravelo,rappa,randol,ramsier,ramerez,rahimi,rahim,radney,racey,raborn,rabalais,quebedeaux,pujol,puchalski,prothro,proffit,prigge,prideaux,prevo,portales,porco,popovic,popek,popejoy,pompei,plude,platner,pizzuto,pizer,pistone,piller,pierri,piehl,pickert,piasecki,phong,philipp,peugh,pesqueira,perrett,perfetti,percell,penhollow,pelto,pellett,pavlak,paulo,pastorius,parsell,parrales,pareja,parcell,pappan,pajak,owusu,ovitt,orrick,oniell,olliff,olberding,oesterling,odwyer,ocegueda,obermiller,nylander,nulph,nottage,northam,norgard,nodal,niel,nicols,newhard,nellum,neira,nazzaro,nassif,narducci,nalbandian,musil,murga,muraoka,mumper,mulroy,mountjoy,mossey,moreton,morea,montoro,montesdeoca,montealegre,montanye,montandon,moisan,mohl,modeste,mitra,minson,minjarez,milbourne,michaelsen,metheney,mestre,mescher,mervis,mennenga,melgarejo,meisinger,meininger,mcwaters,mckern,mckendree,mchargue,mcglothlen,mcgibbon,mcgavock,mcduffee,mcclurkin,mccausland,mccardell,mccambridge,mazzoni,mayen,maxton,mawson,mauffray,mattinson,mattila,matsunaga,mascia,marse,marotz,marois,markin,markee,marcinko,marcin,manville,mantyla,manser,manry,manderscheid,mallari,malecha,malcomb,majerus,macinnis,mabey,lyford,luth,lupercio,luhman,luedke,lovick,lossing,lookabaugh,longway,loisel,logiudice,loffredo,lobaugh,lizaola,livers,littlepage,linnen,limmer,liebsch,liebman,leyden,levitan,levison,levier,leven,levalley,lettinga,lessley,lessig,lepine,leight,leick,leggio,leffingwell,leffert,lefevers,ledlow,leaton,leander,leaming,lazos,laviolette,lauffer,latz,lasorsa,lasch,larin,laporta,lanter,langstaff,landi,lamica,lambson,lambe,lamarca,laman,lamagna,lajeunesse,lafontant,lafler,labrum,laakso,kush,kuether,kuchar,kruk,kroner,kroh,kridler,kreuzer,kovats,koprowski,kohout,knicely,knell,klutts,kindrick,kiddy,khanna,ketcher,kerschner,kerfien,kensey,kenley,kenan,kemplin,kellerhouse,keesling,keas,kaplin,kanady,kampen,jutras,jungers,jeschke,janowski,janas,iskra,imperato,ikerd,igoe,hyneman,hynek,husain,hurrell,hultquist,hullett,hulen,huberty,hoyte,hossain,hornstein,hori,hopton,holms,hollmann,holdman,holdeman,holben,hoffert,himel,hillsman,herdt,hellyer,heister,heimer,heidecker,hedgpeth,hedgepath,hebel,heatwole,hayer,hausner,haskew,haselden,hartranft,harsch,harres,harps,hardimon,halm,hallee,hallahan,hackley,hackenberg,hachey,haapala,guynes,gunnerson,gunby,gulotta,gudger,groman,grignon,griebel,gregori,greenan,grauer,gourd,gorin,gorgone,gooslin,goold,goltz,goldberger,glotfelty,glassford,gladwin,giuffre,gilpatrick,gerdts,geisel,gayler,gaunce,gaulding,gateley,gassman,garson,garron,garand,gangestad,gallow,galbo,gabrielli,fullington,fucci,frum,frieden,friberg,frasco,francese,fowle,foucher,fothergill,foraker,fonder,foisy,fogal,flurry,flenniken,fitzhenry,fishbein,finton,filmore,filice,feola,felberbaum,fausnaught,fasciano,farquharson,faires,estridge,essman,enriques,emmick,ekker,ekdahl,eisman,eggleton,eddinger,eakle,eagar,durio,dunwoody,duhaime,duenes,duden,dudas,dresher,dresel,doutt,donlan,donathan,domke,dobrowolski,dingee,dimmitt,dimery,dilullo,deveaux,devalle,desper,desnoyers,desautels,derouin,derbyshire,denmon,demski,delucca,delpino,delmont,deller,dejulio,deibler,dehne,deharo,degner,defore,deerman,decuir,deckman,deasy,dease,deaner,dawdy,daughdrill,darrigo,darity,dalbey,dagenhart,daffron,curro,curnutte,curatolo,cruikshank,crosswell,croslin,croney,crofton,criado,crecelius,coscia,conniff,commodore,coltharp,colonna,collyer,collington,cobbley,coache,clonts,cloe,cliett,clemans,chrisp,chiarini,cheatam,cheadle,chand,chadd,cervera,cerulli,cerezo,cedano,cayetano,cawthorne,cavalieri,cattaneo,cartlidge,carrithers,carreira,carranco,cargle,candanoza,camburn,calender,calderin,calcagno,cahn,cadden,byham,buttry,burry,burruel,burkitt,burgio,burgener,buescher,buckalew,brymer,brumett,brugnoli,brugman,brosnahan,bronder,broeckel,broderson,brisbon,brinsfield,brinks,bresee,bregman,branner,brambila,brailsford,bouska,boster,borucki,bortner,boroughs,borgeson,bonier,bomba,bolender,boesch,boeke,bloyd,bley,binger,bilbro,biery,bichrest,bezio,bevel,berrett,bermeo,bergdoll,bercier,benzel,bentler,belnap,bellini,beitz,behrend,bednarczyk,bearse,bartolini,bartol,barretta,barbero,barbaro,banvelos,bankes,ballengee,baldon,ausmus,atilano,atienza,aschenbrenner,arora,armstong,aquilino,appleberry,applebee,apolinar,antos,andrepont,ancona,amesquita,alvino,altschuler,allin,alire,ainslie,agular,aeschliman,accetta,abdulla,abbe,zwart,zufelt,zirbel,zingaro,zilnicki,zenteno,zent,zemke,zayac,zarrella,yoshimoto,yearout,womer,woltman,wolin,wolery,woldt,witts,wittner,witherow,winward,winrow,wiemann,wichmann,whitwell,whitelaw,wheeless,whalley,wessner,wenzl,wene,weatherbee,waye,wattles,wanke,walkes,waldeck,vonruden,voisine,vogus,vittetoe,villalva,villacis,venturini,venturi,venson,vanloan,vanhooser,vanduzer,vandever,vanderwal,vanderheyden,vanbeek,vanbebber,vallance,vales,vahle,urbain,upshur,umfleet,tsuji,trybus,triolo,trimarchi,trezza,trenholm,tovey,tourigny,torry,torrain,torgeson,tomey,tischler,tinkler,tinder,ticknor,tibbles,tibbals,throneberry,thormahlen,thibert,thibeaux,theurer,templet,tegeler,tavernier,taubman,tamashiro,tallon,tallarico,taboada,sypher,sybert,swyers,switalski,swedberg,suther,surprenant,sullen,sulik,sugden,suder,suchan,strube,stroope,strittmatter,streett,straughn,strasburg,stjacques,stimage,stimac,stifter,stgelais,steinhart,stehlik,steffenson,steenbergen,stanbery,stallone,spraggs,spoto,spilman,speno,spanbauer,spalla,spagnolo,soliman,solan,sobolik,snelgrove,snedden,smale,sliter,slankard,sircy,shutter,shurtliff,shur,shirkey,shewmake,shams,shadley,shaddox,sgro,serfass,seppala,segawa,segalla,seaberry,scruton,scism,schwein,schwartzman,schwantes,schomer,schoenborn,schlottmann,schissler,scheurer,schepis,scheidegger,saunier,sauders,sassman,sannicolas,sanderfur,salser,sagar,saffer,saeed,sadberry,saban,ryce,rybak,rumore,rummell,rudasill,rozman,rota,rossin,rosell,rosel,romberg,rojero,rochin,robideau,robarge,roath,risko,ringel,ringdahl,riera,riemann,ribas,revard,renegar,reinwald,rehman,redel,raysor,rathke,rapozo,rampton,ramaker,rakow,raia,radin,raco,rackham,racca,racanelli,rabun,quaranta,purves,pundt,protsman,prezioso,presutti,presgraves,poydras,portnoy,portalatin,pontes,poehler,poblete,poat,plumadore,pleiman,pizana,piscopo,piraino,pinelli,pillai,picken,picha,piccoli,philen,petteway,petros,peskin,perugini,perrella,pernice,peper,pensinger,pembleton,passman,parrent,panetta,pallas,palka,pais,paglia,padmore,ottesen,oser,ortmann,ormand,oriol,orick,oler,okafor,ohair,obert,oberholtzer,nowland,nosek,nordeen,nolf,nogle,nobriga,nicley,niccum,newingham,neumeister,neugebauer,netherland,nerney,neiss,neis,neider,neeld,nailor,mustain,mussman,musante,murton,murden,munyon,muldrew,motton,moscoso,moschella,moroz,morelos,morace,moone,montesano,montemurro,montas,montalbo,molander,mleczko,miyake,mitschke,minger,minelli,minear,millener,mihelich,miedema,miah,metzer,mery,merrigan,merck,mennella,membreno,melecio,melder,mehling,mehler,medcalf,meche,mealing,mcqueeney,mcphaul,mcmickle,mcmeen,mcmains,mclees,mcgowin,mcfarlain,mcdivitt,mccotter,mcconn,mccaster,mcbay,mcbath,mayoral,mayeux,matsuo,masur,massman,marzette,martensen,marlett,markgraf,marcinkowski,marchbanks,mansir,mandez,mancil,malagon,magnani,madonia,madill,madia,mackiewicz,macgillivray,macdowell,mabee,lundblad,lovvorn,lovings,loreto,linz,linnell,linebaugh,lindstedt,lindbloom,limberg,liebig,lickteig,lichtenberg,licari,lewison,levario,levar,lepper,lenzen,lenderman,lemarr,leinen,leider,legrande,lefort,lebleu,leask,leacock,lazano,lawalin,laven,laplaca,lant,langsam,langone,landress,landen,lande,lamorte,lairsey,laidlaw,laffin,lackner,lacaze,labuda,labree,labella,labar,kyer,kuyper,kulinski,kulig,kuhnert,kuchera,kubicek,kruckeberg,kruchten,krider,kotch,kornfeld,koren,koogler,koll,kole,kohnke,kohli,kofoed,koelling,kluth,klump,klopfenstein,klippel,klinge,klett,klemp,kleis,klann,kitzman,kinnan,kingsberry,kilmon,killpack,kilbane,kijowski,kies,kierstead,kettering,kesselman,kennington,keniston,kehrer,kearl,keala,kassa,kasahara,kantz,kalin,kaina,jupin,juntunen,juares,joynes,jovel,joos,jiggetts,jervis,jerabek,jennison,jaso,janz,izatt,ishibashi,iannotti,hymas,huneke,hulet,hougen,horvat,horstmann,hopple,holtkamp,holsten,hohenstein,hoefle,hoback,hiney,hiemstra,herwig,herter,herriott,hermsen,herdman,herder,herbig,helling,helbig,heitkamp,heinrichs,heinecke,heileman,heffley,heavrin,heaston,haymaker,hauenstein,hartlage,harig,hardenbrook,hankin,hamiter,hagens,hagel,grizzell,griest,griese,grennan,graden,gosse,gorder,goldin,goatley,gillespi,gilbride,giel,ghoston,gershman,geisinger,gehringer,gedeon,gebert,gaxiola,gawronski,gathright,gatchell,gargiulo,garg,galang,gadison,fyock,furniss,furby,funnell,frizell,frenkel,freeburg,frankhouser,franchi,foulger,formby,forkey,fonte,folson,follette,flavell,finegan,filippini,ferencz,ference,fennessey,feggins,feehan,fazzino,fazenbaker,faunce,farraj,farnell,farler,farabee,falkowski,facio,etzler,ethington,esterline,esper,esker,erxleben,engh,emling,elridge,ellenwood,elfrink,ekhoff,eisert,eifert,eichenlaub,egnor,eggebrecht,edlin,edberg,eble,eber,easler,duwe,dutta,dutremble,dusseault,durney,dunworth,dumire,dukeman,dufner,duey,duble,dreese,dozal,douville,ditmore,distin,dimuzio,dildine,dieterich,dieckman,didonna,dhillon,dezern,devereux,devall,detty,detamore,derksen,deremer,deras,denslow,deno,denicola,denbow,demma,demille,delira,delawder,delara,delahanty,dejonge,deininger,dedios,dederick,decelles,debus,debruyn,deborde,deak,dauenhauer,darsey,dansie,dalman,dakin,dagley,czaja,cybart,cutchin,currington,curbelo,croucher,crinklaw,cremin,cratty,cranfield,crafford,cowher,couvillion,couturier,corter,coombes,contos,consolini,connaughton,conely,collom,cockett,clepper,cleavenger,claro,clarkin,ciriaco,ciesla,cichon,ciancio,cianci,chynoweth,chrzanowski,christion,cholewa,chipley,chilcott,cheyne,cheslock,chenevert,charlot,chagolla,chabolla,cesena,cerutti,cava,caul,cassone,cassin,cassese,casaus,casali,cartledge,cardamone,carcia,carbonneau,carboni,carabello,capozzoli,capella,cannata,campoverde,campeau,cambre,camberos,calvery,calnan,calmes,calley,callery,calise,cacciotti,cacciatore,butterbaugh,burgo,burgamy,burell,bunde,bumbalough,buel,buechner,buchannon,brunn,brost,broadfoot,brittan,brevard,breda,brazel,brayboy,brasier,boyea,boxx,boso,bosio,boruff,borda,bongiovanni,bolerjack,boedeker,blye,blumstein,blumenfeld,blinn,bleakley,blatter,blan,bjornson,bisignano,billick,bieniek,bhatti,bevacqua,berra,berenbaum,bensinger,bennefield,belvins,belson,bellin,beighley,beecroft,beaudreau,baynard,bautch,bausch,basch,bartleson,barthelemy,barak,balzano,balistreri,bailer,bagnall,bagg,auston,augustyn,aslinger,ashalintubbi,arjona,arebalo,appelbaum,angert,angelucci,andry,andersson,amorim,amavisca,alward,alvelo,alvear,alumbaugh,alsobrook,allgeier,allende,aldrete,akiyama,ahlquist,adolphson,addario,acoff,abelson,abasta,zulauf,zirkind,zeoli,zemlicka,zawislak,zappia,zanella,yelvington,yeatman,yanni,wragg,wissing,wischmeier,wirta,wiren,wilmouth,williard,willert,willaert,wildt,whelpley,weingart,weidenbach,weidemann,weatherman,weakland,watwood,wattley,waterson,wambach,walzer,waldow,waag,vorpahl,volkmann,vitolo,visitacion,vincelette,viggiano,vieth,vidana,vert,verges,verdejo,venzon,velardi,varian,vargus,vandermeulen,vandam,vanasse,vanaman,utzinger,uriostegui,uplinger,twiss,tumlinson,tschanz,trunnell,troung,troublefield,trojacek,treloar,tranmer,touchton,torsiello,torina,tootle,toki,toepfer,tippie,thronson,thomes,tezeno,texada,testani,tessmer,terrel,terlizzi,tempel,temblador,tayler,tawil,tasch,tames,talor,talerico,swinderman,sweetland,swager,sulser,sullens,subia,sturgell,stumpff,stufflebeam,stucki,strohmeyer,strebel,straughan,strackbein,stobaugh,stetz,stelter,steinmann,steinfeld,stecher,stanwood,stanislawski,stander,speziale,soppe,soni,sobotka,smuin,slee,skerrett,sjoberg,sittig,simonelli,simo,silverio,silveria,silsby,sillman,sienkiewicz,shomo,shoff,shoener,shiba,sherfey,shehane,sexson,setton,sergi,selvy,seiders,seegmiller,sebree,seabury,scroggin,sconyers,schwalb,schurg,schulenberg,schuld,schrage,schow,schon,schnur,schneller,schmidtke,schlatter,schieffer,schenkel,scheeler,schauwecker,schartz,schacherer,scafe,sayegh,savidge,saur,sarles,sarkissian,sarkis,sarcone,sagucio,saffell,saenger,sacher,rylee,ruvolo,ruston,ruple,rulison,ruge,ruffo,ruehl,rueckert,rudman,rudie,rubert,rozeboom,roysden,roylance,rothchild,rosse,rosecrans,rodi,rockmore,robnett,roberti,rivett,ritzel,rierson,ricotta,ricken,rezac,rendell,reitman,reindl,reeb,reddic,reddell,rebuck,reali,raso,ramthun,ramsden,rameau,ralphs,rago,racz,quinteros,quinter,quinley,quiggle,purvines,purinton,purdum,pummill,puglia,puett,ptacek,przybyla,prowse,prestwich,pracht,poutre,poucher,portera,polinsky,poage,platts,pineau,pinckard,pilson,pilling,pilkins,pili,pikes,pigram,pietila,pickron,philippi,philhower,pflueger,pfalzgraf,pettibone,pett,petrosino,persing,perrino,perotti,periera,peri,peredo,peralto,pennywell,pennel,pellegren,pella,pedroso,paulos,paulding,pates,pasek,paramo,paolino,panganiban,paneto,paluch,ozaki,ownbey,overfelt,outman,opper,onstad,oland,okuda,oertel,oelke,normandeau,nordby,nordahl,noecker,noblin,niswonger,nishioka,nett,negley,nedeau,natera,nachman,naas,musich,mungin,mourer,mounsey,mottola,mothershed,moskal,mosbey,morini,moreles,montaluo,moneypenny,monda,moench,moates,moad,missildine,misiewicz,mirabella,minott,mincks,milum,milani,mikelson,mestayer,mertes,merrihew,merlos,meritt,melnyk,medlen,meder,mcvea,mcquarrie,mcquain,mclucas,mclester,mckitrick,mckennon,mcinnes,mcgrory,mcgranahan,mcglamery,mcgivney,mcgilvray,mccuiston,mccuin,mccrystal,mccolley,mcclerkin,mcclenon,mccamey,mcaninch,mazariegos,maynez,mattioli,mastronardi,masone,marzett,marsland,margulies,margolin,malatesta,mainer,maietta,magrath,maese,madkins,madeiros,madamba,mackson,maben,lytch,lundgreen,lumb,lukach,luick,luetkemeyer,luechtefeld,ludy,ludden,luckow,lubinsky,lowes,lorenson,loran,lopinto,looby,lones,livsey,liskey,lisby,lintner,lindow,lindblom,liming,liechty,leth,lesniewski,lenig,lemonds,leisy,lehrer,lehnen,lehmkuhl,leeth,leeks,lechler,lebsock,lavere,lautenschlage,laughridge,lauderback,laudenslager,lassonde,laroque,laramee,laracuente,lapeyrouse,lampron,lamers,laino,lague,lafromboise,lafata,lacount,lachowicz,kysar,kwiecien,kuffel,kueter,kronenberg,kristensen,kristek,krings,kriesel,krey,krebbs,kreamer,krabbe,kossman,kosakowski,kosak,kopacz,konkol,koepsell,koening,koen,knerr,knapik,kluttz,klocke,klenk,klemme,klapp,kitchell,kita,kissane,kirkbride,kirchhoff,kinter,kinsel,kingsland,kimmer,kimler,killoran,kieser,khalsa,khalaf,kettel,kerekes,keplin,kentner,kennebrew,kenison,kellough,keatts,keasey,kauppi,katon,kanner,kampa,kall,kaczorowski,kaczmarski,juarbe,jordison,jobst,jezierski,jeanbart,jarquin,jagodzinski,ishak,isett,infantino,imburgia,illingworth,hysmith,hynson,hydrick,hurla,hunton,hunnell,humbertson,housand,hottle,hosch,hoos,honn,hohlt,hodel,hochmuth,hixenbaugh,hislop,hisaw,hintzen,hilgendorf,hilchey,higgens,hersman,herrara,hendrixson,hendriks,hemond,hemmingway,heminger,helgren,heisey,heilmann,hehn,hegna,heffern,hawrylak,haverty,hauger,haslem,harnett,harb,happ,hanzlik,hanway,hanby,hanan,hamric,hammaker,halas,hagenbuch,habeck,gwozdz,gunia,guadarrama,grubaugh,grivas,griffieth,grieb,grewell,gregorich,grazier,graeber,graciano,gowens,goodpaster,gondek,gohr,goffney,godbee,gitlin,gisler,gillyard,gillooly,gilchrest,gilbo,gierlach,giebler,giang,geske,gervasio,gertner,gehling,geeter,gaus,gattison,gatica,gathings,gath,gassner,gassert,garabedian,gamon,gameros,galban,gabourel,gaal,fuoco,fullenwider,fudala,friscia,franceschini,foronda,fontanilla,florey,flore,flegle,flecha,fisler,fischbach,fiorita,figura,figgins,fichera,ferra,fawley,fawbush,fausett,farnes,farago,fairclough,fahie,fabiani,evanson,eutsey,eshbaugh,ertle,eppley,englehardt,engelhard,emswiler,elling,elderkin,eland,efaw,edstrom,edgemon,ecton,echeverri,ebright,earheart,dynes,dygert,dyches,dulmage,duhn,duhamel,dubrey,dubray,dubbs,drey,drewery,dreier,dorval,dorough,dorais,donlin,donatelli,dohm,doetsch,dobek,disbrow,dinardi,dillahunty,dillahunt,diers,dier,diekmann,diangelo,deskin,deschaine,depaoli,denner,demyan,demont,demaray,delillo,deleeuw,deibel,decato,deblasio,debartolo,daubenspeck,darner,dardon,danziger,danials,damewood,dalpiaz,dallman,dallaire,cunniffe,cumpston,cumbo,cubero,cruzan,cronkhite,critelli,crimi,creegan,crean,craycraft,cranfill,coyt,courchesne,coufal,corradino,corprew,colville,cocco,coby,clinch,clickner,clavette,claggett,cirigliano,ciesielski,christain,chesbro,chavera,chard,casteneda,castanedo,casseus,caruana,carnero,cappelli,capellan,canedy,cancro,camilleri,calero,cada,burghart,burbidge,bulfer,buis,budniewski,bruney,brugh,brossard,brodmerkel,brockmann,brigmond,briere,bremmer,breck,breau,brautigam,brasch,brandenberger,bragan,bozell,bowsher,bosh,borgia,borey,boomhower,bonneville,bonam,bolland,boise,boeve,boettger,boersma,boateng,bliven,blazier,blahnik,bjornstad,bitton,biss,birkett,billingsly,biagioni,bettle,bertucci,bertolino,bermea,bergner,berber,bensley,bendixen,beltrami,bellone,belland,behringer,begum,bayona,batiz,bassin,baskette,bartolomeo,bartolo,bartholow,barkan,barish,barett,bardo,bamburg,ballerini,balla,balis,bakley,bailon,bachicha,babiarz,ayars,axton,axel,awong,awalt,auslander,ausherman,aumick,atha,atchinson,aslett,askren,arrowsmith,arras,arnhold,armagost,arey,arcos,archibeque,antunes,antilla,andras,amyx,amison,amero,alzate,alper,aller,alioto,aigner,agtarap,agbayani,adami,achorn,aceuedo,acedo,abundis,aber,abee,zuccaro,ziglar,zier,ziebell,zieba,zamzow,zahl,yurko,yurick,yonkers,yerian,yeaman,yarman,yann,yahn,yadon,yadao,woodbridge,wolske,wollenberg,wojtczak,wnuk,witherite,winther,winick,widell,wickens,whichard,wheelis,wesely,wentzell,wenthold,wemple,weisenburger,wehling,weger,weaks,wassink,walquist,wadman,wacaster,waage,voliva,vlcek,villafana,vigliotti,viger,viernes,viands,veselka,versteeg,vero,verhoeven,vendetti,velardo,vatter,vasconcellos,varn,vanwagner,vanvoorhis,vanhecke,vanduyn,vandervoort,vanderslice,valone,vallier,vails,uvalle,ursua,urenda,uphoff,tustin,turton,turnbough,turck,tullio,tuch,truehart,tropea,troester,trippe,tricarico,trevarthen,trembly,trabue,traber,tosi,toal,tinley,tingler,timoteo,tiffin,ticer,thorman,therriault,theel,tessman,tekulve,tejera,tebbs,tavernia,tarpey,tallmadge,takemoto,szot,sylvest,swindoll,swearinger,swantek,swaner,swainston,susi,surrette,sullenger,sudderth,suddarth,suckow,strege,strassburg,stoval,stotz,stoneham,stilley,stille,stierwalt,stfleur,steuck,stermer,stclaire,stano,staker,stahler,stablein,srinivasan,squillace,sprvill,sproull,sprau,sporer,spore,spittler,speelman,sparr,sparkes,spang,spagnuolo,sosinski,sorto,sorkin,sondag,sollers,socia,snarr,smrekar,smolka,slyter,slovinsky,sliwa,slavik,slatter,skiver,skeem,skala,sitzes,sitsler,sitler,sinko,simser,siegler,sideris,shrewsberry,shoopman,shoaff,shindler,shimmin,shill,shenkel,shemwell,shehorn,severa,semones,selsor,sekulski,segui,sechrest,schwer,schwebach,schur,schmiesing,schlick,schlender,schebler,schear,schapiro,sauro,saunder,sauage,satterly,saraiva,saracino,saperstein,sanmartin,sanluis,sandt,sandrock,sammet,sama,salk,sakata,saini,sackrider,russum,russi,russaw,rozzell,roza,rowlette,rothberg,rossano,rosebrock,romanski,romanik,romani,roiger,roig,roehr,rodenberger,rodela,rochford,ristow,rispoli,rigo,riesgo,riebel,ribera,ribaudo,reys,resendes,repine,reisdorf,reisch,rebman,rasmus,raske,ranum,rames,rambin,raman,rajewski,raffield,rady,radich,raatz,quinnie,pyper,puthoff,prow,proehl,pribyl,pretti,prete,presby,poyer,powelson,porteous,poquette,pooser,pollan,ploss,plewa,placide,pion,pinnick,pinales,pillot,pille,pilato,piggee,pietrowski,piermarini,pickford,piccard,phenix,pevey,petrowski,petrillose,pesek,perrotti,peppler,peppard,penfold,pellitier,pelland,pehowic,pedretti,paules,passero,pasha,panza,pallante,palau,pakele,pacetti,paavola,overy,overson,outler,osegueda,oplinger,oldenkamp,ohern,oetting,odums,nowlen,nowack,nordlund,noblett,nobbe,nierman,nichelson,niblock,newbrough,nemetz,needleman,navin,nastasi,naslund,naramore,nakken,nakanishi,najarro,mushrush,muma,mulero,morganfield,moreman,morain,moquin,monterrosa,monsivais,monroig,monje,monfort,moffa,moeckel,mobbs,misiak,mires,mirelez,mineo,mineau,milnes,mikeska,michelin,michalowski,meszaros,messineo,meshell,merten,meola,menton,mends,mende,memmott,melius,mehan,mcnickle,mcmorran,mclennon,mcleish,mclaine,mckendry,mckell,mckeighan,mcisaac,mcie,mcguinn,mcgillis,mcfatridge,mcfarling,mcelravy,mcdonalds,mcculla,mcconnaughy,mcconnaughey,mcchriston,mcbeath,mayr,matyas,matthiesen,matsuura,matinez,mathys,matarazzo,masker,masden,mascio,martis,marrinan,marinucci,margerum,marengo,manthe,mansker,manoogian,mankey,manigo,manier,mangini,maltese,malsam,mallo,maliszewski,mainolfi,maharaj,maggart,magar,maffett,macmaster,macky,macdonnell,lyvers,luzzi,lutman,lovan,lonzo,longerbeam,lofthouse,loethen,lodi,llorens,lizama,litscher,lisowski,lipski,lipsett,lipkin,linzey,lineman,limerick,limas,lige,lierman,liebold,liberti,leverton,levene,lesueur,lenser,lenker,legnon,lefrancois,ledwell,lavecchia,laurich,lauricella,lannigan,landor,lamprecht,lamountain,lamore,lammert,lamboy,lamarque,lamacchia,lalley,lagace,lacorte,lacomb,kyllonen,kyker,kuschel,kupfer,kunde,kucinski,kubacki,kroenke,krech,koziel,kovacich,kothari,koth,kotek,kostelnik,kosloski,knoles,knabe,kmiecik,klingman,kliethermes,kleffman,klees,klaiber,kittell,kissling,kisinger,kintner,kinoshita,kiener,khouri,kerman,kelii,keirn,keezer,kaup,kathan,kaser,karlsen,kapur,kandoll,kammel,kahele,justesen,jonason,johnsrud,joerling,jochim,jespersen,jeong,jenness,jedlicka,jakob,isaman,inghram,ingenito,iadarola,hynd,huxtable,huwe,hurless,humpal,hughston,hughart,huggett,hugar,huether,howdyshell,houtchens,houseworth,hoskie,holshouser,holmen,holloran,hohler,hoefler,hodsdon,hochman,hjort,hippert,hippe,hinzman,hillock,hilden,heyn,heyden,heyd,hergert,henrikson,henningsen,hendel,helget,helf,helbing,heintzman,heggie,hege,hecox,heatherington,heare,haxton,haverstock,haverly,hatler,haselton,hase,hartzfeld,harten,harken,hargrow,haran,hanton,hammar,hamamoto,halper,halko,hackathorn,haberle,haake,gunnoe,gunkel,gulyas,guiney,guilbeau,guider,guerrant,gudgel,guarisco,grossen,grossberg,gropp,groome,grobe,gremminger,greenley,grauberger,grabenstein,gowers,gostomski,gosier,goodenow,gonzoles,goliday,goettle,goens,goates,glymph,glavin,glassco,gladfelter,glackin,githens,girgis,gimpel,gilbreth,gilbeau,giffen,giannotti,gholar,gervasi,gertsch,gernatt,gephardt,genco,gehr,geddis,gase,garrott,garrette,gapinski,ganter,ganser,gangi,gangemi,gallina,galdi,gailes,gaetano,gadomski,gaccione,fuschetto,furtick,furfaro,fullman,frutos,fruchter,frogge,freytag,freudenthal,fregoe,franzone,frankum,francia,franceschi,forys,forero,folkers,flug,flitter,flemons,fitzer,firpo,finizio,filiault,figg,fichtner,fetterolf,ferringer,feil,fayne,farro,faddis,ezzo,ezelle,eynon,evitt,eutsler,euell,escovedo,erne,eriksson,enriguez,empson,elkington,eisenmenger,eidt,eichenberger,ehrmann,ediger,earlywine,eacret,duzan,dunnington,ducasse,dubiel,drovin,drager,drage,donham,donat,dolinger,dokken,doepke,dodwell,docherty,distasio,disandro,diniz,digangi,didion,dezzutti,detmer,deshon,derrigo,dentler,demoura,demeter,demeritt,demayo,demark,demario,delzell,delnero,delgrosso,dejarnett,debernardi,dearmas,dashnaw,daris,danks,danker,dangler,daignault,dafoe,dace,curet,cumberledge,culkin,crowner,crocket,crawshaw,craun,cranshaw,cragle,courser,costella,cornforth,corkill,coopersmith,conzemius,connett,connely,condict,condello,comley,cohoon,coday,clugston,clowney,clippard,clinkenbeard,clines,clelland,clapham,clancey,clabough,cichy,cicalese,chua,chittick,chisom,chisley,chinchilla,cheramie,cerritos,cercone,cena,cawood,cavness,catanzarite,casada,carvell,carmicheal,carll,cardozo,caplin,candia,canby,cammon,callister,calligan,calkin,caillouet,buzzelli,bute,bustillo,bursey,burgeson,bupp,bulson,buist,buffey,buczkowski,buckbee,bucio,brueckner,broz,brookhart,brong,brockmeyer,broberg,brittenham,brisbois,bridgmon,breyer,brede,breakfield,breakey,brauner,branigan,brandewie,branche,brager,brader,bovell,bouthot,bostock,bosma,boseman,boschee,borthwick,borneman,borer,borek,boomershine,boni,bommarito,bolman,boleware,boisse,boehlke,bodle,blash,blasco,blakesley,blacklock,blackley,bittick,birks,birdin,bircher,bilbao,bick,biby,bertoni,bertino,bertini,berson,bern,berkebile,bergstresser,benne,benevento,belzer,beltre,bellomo,bellerose,beilke,begeman,bebee,beazer,beaven,beamish,baymon,baston,bastidas,basom,basey,bartles,baroni,barocio,barnet,barclift,banville,balthazor,balleza,balkcom,baires,bailie,baik,baggott,bagen,bachner,babington,babel,asmar,arvelo,artega,arrendondo,arreaga,arrambide,arquette,aronoff,arico,argentieri,arevalos,archbold,apuzzo,antczak,ankeny,angelle,angelini,anfinson,amer,amarillas,altier,altenburg,alspach,alosa,allsbrook,alexopoulos,aleem,aldred,albertsen,akerson,agler,adley,addams,acoba,achille,abplanalp,abella,abare,zwolinski,zollicoffer,zins,ziff,zenner,zender,zelnick,zelenka,zeches,zaucha,zauala,zangari,zagorski,youtsey,yasso,yarde,yarbough,woolever,woodsmall,woodfolk,wobig,wixson,wittwer,wirtanen,winson,wingerd,wilkening,wilhelms,wierzbicki,wiechman,weyrick,wessell,wenrick,wenning,weltz,weinrich,weiand,wehunt,wareing,walth,waibel,wahlquist,vona,voelkel,vitek,vinsant,vincente,vilar,viel,vicars,vermette,verma,venner,veazie,vayda,vashaw,varon,vardeman,vandevelde,vanbrocklin,vaccarezza,urquidez,urie,urbach,uram,ungaro,umali,ulsh,tutwiler,turnbaugh,tumminello,tuite,tueller,trulove,troha,trivino,trisdale,trippett,tribbett,treptow,tremain,travelstead,trautwein,trautmann,tram,traeger,tonelli,tomsic,tomich,tomasulo,tomasino,tole,todhunter,toborg,tischer,tirpak,tircuit,tinnon,tinnel,tines,timbs,tilden,tiede,thumm,throgmorton,thorndike,thornburgh,thoren,thomann,therrell,thau,thammavong,tetrick,tessitore,tesreau,teicher,teaford,tauscher,tauer,tanabe,talamo,takeuchi,taite,tadych,sweeton,swecker,swartzentrube,swarner,surrell,surbaugh,suppa,sumbry,suchy,stuteville,studt,stromer,strome,streng,stonestreet,stockley,stmichel,stfort,sternisha,stensrud,steinhardt,steinback,steichen,stauble,stasiak,starzyk,stango,standerfer,stachowiak,springston,spratlin,spracklen,sponseller,spilker,spiegelman,spellacy,speiser,spaziani,spader,spackman,sorum,sopha,sollis,sollenberger,solivan,solheim,sokolsky,sogge,smyser,smitley,sloas,slinker,skora,skiff,skare,siverd,sivels,siska,siordia,simmering,simko,sime,silmon,silano,sieger,siebold,shukla,shreves,shoun,shortle,shonkwiler,shoals,shimmel,shiel,shieh,sherbondy,shenkman,shein,shearon,shean,shatz,shanholtz,shafran,shaff,shackett,sgroi,sewall,severy,sethi,sessa,sequra,sepulvado,seper,senteno,sendejo,semmens,seipp,segler,seegers,sedwick,sedore,sechler,sebastiano,scovel,scotton,scopel,schwend,schwarting,schutter,schrier,schons,scholtes,schnetzer,schnelle,schmutz,schlichter,schelling,schams,schamp,scarber,scallan,scalisi,scaffidi,saxby,sawrey,sauvageau,sauder,sarrett,sanzo,santizo,santella,santander,sandez,sandel,sammon,salsedo,salge,sagun,safi,sader,sacchetti,sablan,saade,runnion,runkel,rumbo,ruesch,ruegg,ruckle,ruchti,rubens,rubano,rozycki,roupe,roufs,rossel,rosmarin,rosero,rosenwald,ronca,romos,rolla,rohling,rohleder,roell,roehm,rochefort,roch,robotham,rivenburgh,riopel,riederer,ridlen,rias,rhudy,reynard,retter,respess,reppond,repko,rengifo,reinking,reichelt,reeh,redenius,rebolledo,rauh,ratajczak,rapley,ranalli,ramie,raitt,radloff,radle,rabbitt,quay,quant,pusateri,puffinberger,puerta,provencio,proano,privitera,prenger,prellwitz,pousson,potier,portz,portlock,porth,portela,portee,porchia,pollick,polinski,polfer,polanski,polachek,pluta,plourd,plauche,pitner,piontkowski,pileggi,pierotti,pico,piacente,phinisee,phaup,pfost,pettinger,pettet,petrich,peto,persley,persad,perlstein,perko,pere,penders,peifer,peco,pawley,pash,parrack,parady,papen,pangilinan,pandolfo,palone,palmertree,padin,ottey,ottem,ostroski,ornstein,ormonde,onstott,oncale,oltremari,olcott,olan,oishi,oien,odonell,odonald,obeso,obeirne,oatley,nusser,novo,novicki,nitschke,nistler,nikkel,niese,nierenberg,nield,niedzwiecki,niebla,niebel,nicklin,neyhart,newsum,nevares,nageotte,nagai,mutz,murata,muralles,munnerlyn,mumpower,muegge,muckle,muchmore,moulthrop,motl,moskos,mortland,morring,mormile,morimoto,morikawa,morgon,mordecai,montour,mont,mongan,monell,miyasato,mish,minshew,mimbs,millin,milliard,mihm,middlemiss,miano,mesick,merlan,mendonsa,mench,melonson,melling,meachem,mctighe,mcnelis,mcmurtrey,mckesson,mckenrick,mckelvie,mcjunkins,mcgory,mcgirr,mcgeever,mcfield,mcelhinney,mccrossen,mccommon,mccannon,mazyck,mawyer,maull,matute,mathies,maschino,marzan,martinie,marrotte,marmion,markarian,marinacci,margolies,margeson,marak,maraia,maracle,manygoats,manker,mank,mandich,manderson,maltz,malmquist,malacara,majette,magnan,magliocca,madina,madara,macwilliams,macqueen,maccallum,lyde,lyday,lutrick,lurz,lurvey,lumbreras,luhrs,luhr,lowrimore,lowndes,lourenco,lougee,lorona,longstreth,loht,lofquist,loewenstein,lobos,lizardi,lionberger,limoli,liljenquist,liguori,liebl,liburd,leukhardt,letizia,lesinski,lepisto,lenzini,leisenring,leipold,leier,leggitt,legare,leaphart,lazor,lazaga,lavey,laue,laudermilk,lauck,lassalle,larsson,larison,lanzo,lantzy,lanners,langtry,landford,lancour,lamour,lambertson,lalone,lairson,lainhart,lagreca,lacina,labranche,labate,kurtenbach,kuipers,kuechle,kubo,krinsky,krauser,kraeger,kracht,kozeliski,kozar,kowalik,kotler,kotecki,koslosky,kosel,koob,kolasinski,koizumi,kohlman,koffman,knutt,knore,knaff,kmiec,klamm,kittler,kitner,kirkeby,kiper,kindler,kilmartin,kilbride,kerchner,kendell,keddy,keaveney,kearsley,karlsson,karalis,kappes,kapadia,kallman,kallio,kalil,kader,jurkiewicz,jitchaku,jillson,jeune,jarratt,jarchow,janak,ivins,ivans,isenhart,inocencio,inoa,imhof,iacono,hynds,hutching,hutchin,hulsman,hulsizer,hueston,huddleson,hrbek,howry,housey,hounshell,hosick,hortman,horky,horine,hootman,honeywell,honeyestewa,holste,holien,holbrooks,hoffmeyer,hoese,hoenig,hirschfeld,hildenbrand,higson,higney,hibert,hibbetts,hewlin,hesley,herrold,hermon,hepker,henwood,helbling,heinzman,heidtbrink,hedger,havey,hatheway,hartshorne,harpel,haning,handelman,hamalainen,hamad,halasz,haigwood,haggans,hackshaw,guzzo,gundrum,guilbeault,gugliuzza,guglielmi,guderian,gruwell,grunow,grundman,gruen,grotzke,grossnickle,groomes,grode,grochowski,grob,grein,greif,greenwall,greenup,grassl,grannis,grandfield,grames,grabski,grabe,gouldsberry,gosch,goodling,goodermote,gonzale,golebiowski,goldson,godlove,glanville,gillin,gilkerson,giessler,giambalvo,giacomini,giacobbe,ghio,gergen,gentz,genrich,gelormino,gelber,geitner,geimer,gauthreaux,gaultney,garvie,gareau,garbacz,ganoe,gangwer,gandarilla,galyen,galt,galluzzo,galardo,gager,gaddie,gaber,gabehart,gaarder,fusilier,furnari,furbee,fugua,fruth,frohman,friske,frilot,fridman,frescas,freier,frayer,franzese,frankenberry,frain,fosse,foresman,forbess,flook,fletes,fleer,fleek,fleegle,fishburne,fiscalini,finnigan,fini,filipiak,figueira,fiero,ficek,fiaschetti,ferren,ferrando,ferman,fergusson,fenech,feiner,feig,faulds,fariss,falor,falke,ewings,eversley,everding,etling,essen,erskin,enstrom,engebretsen,eitel,eichberger,ehler,eekhoff,edrington,edmonston,edgmon,edes,eberlein,dwinell,dupee,dunklee,dungey,dunagin,dumoulin,duggar,duenez,dudzic,dudenhoeffer,ducey,drouillard,dreibelbis,dreger,dreesman,draughon,downen,dorminy,dombeck,dolman,doebler,dittberner,dishaw,disanti,dinicola,dinham,dimino,dilling,difrancesco,dicello,dibert,deshazer,deserio,descoteau,deruyter,dering,depinto,dente,demus,demattos,demarsico,delude,dekok,debrito,debois,deakin,dayley,dawsey,dauria,datson,darty,darsow,darragh,darensbourg,dalleva,dalbec,dadd,cutcher,cung,cuello,cuadros,crute,crutchley,crispino,crislip,crisco,crevier,creekmur,crance,cragg,crager,cozby,coyan,coxon,covalt,couillard,costley,costilow,cossairt,corvino,corigliano,cordaro,corbridge,corban,coor,conkel,conary,coltrain,collopy,colgin,colen,colbath,coiro,coffie,cochrum,cobbett,clopper,cliburn,clendenon,clemon,clementi,clausi,cirino,cina,churchman,chilcutt,cherney,cheetham,cheatom,chatelain,chalifour,cesa,cervenka,cerullo,cerreta,cerbone,cecchini,ceccarelli,cawthorn,cavalero,castner,castlen,castine,casimiro,casdorph,cartmill,cartmell,carro,carriger,carias,caravella,cappas,capen,cantey,canedo,camuso,campanaro,cambria,calzado,callejo,caligiuri,cafaro,cadotte,cacace,byrant,busbey,burtle,burres,burnworth,burggraf,burback,bunte,bunke,bulle,bugos,budlong,buckhalter,buccellato,brummet,bruff,brubeck,brouk,broten,brosky,broner,brislin,brimm,brillhart,bridgham,brideau,brennecke,breer,breeland,bredesen,brackney,brackeen,boza,boyum,bowdry,bowdish,bouwens,bouvier,bougie,bouche,bottenfield,bostian,bossie,bosler,boschert,boroff,borello,bonser,bonfield,bole,boldue,bogacz,boemer,bloxom,blickenstaff,blessinger,bleazard,blatz,blanchet,blacksher,birchler,binning,binkowski,biltz,bilotta,bilagody,bigbee,bieri,biehle,bidlack,betker,bethers,bethell,bero,bernacchi,bermingham,berkshire,benvenuto,bensman,benoff,bencivenga,beman,bellow,bellany,belflower,belch,bekker,bejar,beisel,beichner,beedy,beas,beanblossom,bawek,baus,baugus,battie,battershell,bateson,basque,basford,bartone,barritt,barko,bann,bamford,baltrip,balon,balliew,ballam,baldus,ayling,avelino,ashwell,ashland,arseneau,arroyos,armendarez,arita,argust,archuletta,arcement,antonacci,anthis,antal,annan,anderman,amster,amiri,amadon,alveraz,altomari,altmann,altenhofen,allers,allbee,allaway,aleo,alcoser,alcorta,akhtar,ahuna,agramonte,agard,adkerson,achord,abdi,abair,zurn,zoellner,zirk,zion,zarro,zarco,zambo,zaiser,zaino,zachry,youd,yonan,yniguez,yepes,yellock,yellen,yeatts,yearling,yatsko,yannone,wyler,woodridge,wolfrom,wolaver,wolanin,wojnar,wojciak,wittmann,wittich,wiswell,wisser,wintersteen,wineland,willford,wiginton,wigfield,wierman,wice,wiater,whitsel,whitbread,wheller,wettstein,werling,wente,wenig,wempe,welz,weinhold,weigelt,weichman,wedemeyer,weddel,wayment,waycaster,wauneka,watzka,watton,warnell,warnecke,warmack,warder,wands,waldvogel,waldridge,wahs,wagganer,waddill,vyas,vought,votta,voiles,virga,viner,villella,villaverde,villaneda,viele,vickroy,vicencio,vetere,vermilyea,verley,verburg,ventresca,veno,venard,venancio,velaquez,veenstra,vasil,vanzee,vanwie,vantine,vant,vanschoyck,vannice,vankampen,vanicek,vandersloot,vanderpoel,vanderlinde,vallieres,uzzell,uzelac,uranga,uptain,updyke,uong,untiedt,umbrell,umbaugh,umbarger,ulysse,ullmann,ullah,tutko,turturro,turnmire,turnley,turcott,turbyfill,turano,tuminello,tumbleson,tsou,truscott,trulson,troutner,trone,trinklein,tremmel,tredway,trease,traynham,traw,totty,torti,torregrossa,torok,tomkins,tomaino,tkach,tirey,tinsman,timpe,tiefenauer,tiedt,tidball,thwaites,thulin,throneburg,thorell,thorburn,thiemann,thieman,thesing,tham,terrien,telfair,taybron,tasson,tasso,tarro,tanenbaum,taddeo,taborn,tabios,szekely,szatkowski,sylve,swineford,swartzfager,swanton,swagerty,surrency,sunderlin,sumerlin,suero,suddith,sublette,stumpe,stueve,stuckert,strycker,struve,struss,strubbe,strough,strothmann,strahle,stoutner,stooksbury,stonebarger,stokey,stoffer,stimmel,stief,stephans,stemper,steltenpohl,stellato,steinle,stegeman,steffler,steege,steckman,stapel,stansbery,stanaland,stahley,stagnaro,stachowski,squibb,sprunger,sproule,sprehe,spreen,sprecher,sposato,spivery,souter,sopher,sommerfeldt,soffer,snowberger,snape,smylie,smyer,slaydon,slatton,slaght,skovira,skeans,sjolund,sjodin,siragusa,singelton,silis,siebenaler,shuffield,shobe,shiring,shimabukuro,shilts,sherbert,shelden,sheil,shedlock,shearn,shaub,sharbono,shapley,shands,shaheen,shaffner,servantez,sentz,seney,selin,seitzinger,seider,sehr,sego,segall,sebastien,scimeca,schwenck,schweiss,schwark,schwalbe,schucker,schronce,schrag,schouten,schoppe,schomaker,schnarr,schmied,schmader,schlicht,schlag,schield,schiano,scheve,scherbarth,schaumburg,schauman,scarpino,savinon,sassaman,saporito,sanville,santilli,santaana,salzmann,salman,sagraves,safran,saccone,rutty,russett,rupard,rumbley,ruffins,ruacho,rozema,roxas,routson,rourk,rought,rotunda,rotermund,rosman,rork,rooke,rolin,rohm,rohlman,rohl,roeske,roecker,rober,robenson,riso,rinne,riina,rigsbee,riggles,riester,rials,rhinehardt,reynaud,reyburn,rewis,revermann,reutzel,retz,rende,rendall,reistad,reinders,reichardt,rehrig,rehrer,recendez,reamy,rauls,ratz,rattray,rasband,rapone,ragle,ragins,radican,raczka,rachels,raburn,rabren,raboin,quesnell,quaintance,puccinelli,pruner,prouse,prosise,proffer,prochazka,probasco,previte,portell,porcher,popoca,pomroy,poma,polsky,polsgrove,polidore,podraza,plymale,plescia,pleau,platte,pizzi,pinchon,picot,piccione,picazo,philibert,phebus,pfohl,petell,pesso,pesante,pervis,perrins,perley,perkey,pereida,penate,peloso,pellerito,peffley,peddicord,pecina,peale,payette,paxman,pawlikowski,pavy,patry,patmon,patil,pater,patak,pasqua,pasche,partyka,parody,parmeter,pares,pardi,paonessa,panozzo,panameno,paletta,pait,oyervides,ossman,oshima,ortlieb,orsak,onley,oldroyd,okano,ohora,offley,oestreicher,odonovan,odham,odegard,obst,obriant,obrecht,nuccio,nowling,nowden,novelli,nost,norstrom,nordgren,nopper,noller,nisonger,niskanen,nienhuis,nienaber,neuwirth,neumeyer,neice,naugher,naiman,nagamine,mustin,murrietta,murdaugh,munar,muhlbauer,mroczkowski,mowdy,mouw,mousel,mountcastle,moscowitz,mosco,morro,moresi,morago,moomaw,montroy,montpas,montieth,montanaro,mongelli,mollison,mollette,moldovan,mohar,mitchelle,mishra,misenheimer,minshall,minozzi,minniefield,milhous,migliaccio,migdal,mickell,meyering,methot,mester,mesler,meriweather,mensing,mensah,menge,mendibles,meloche,melnik,mellas,meinert,mehrhoff,medas,meckler,mctague,mcspirit,mcshea,mcquown,mcquiller,mclarney,mckiney,mckearney,mcguyer,mcfarlan,mcfadyen,mcdanial,mcdanel,mccurtis,mccrohan,mccorry,mcclune,mccant,mccanna,mccandlish,mcaloon,mayall,maver,maune,matza,matsuzaki,matott,mathey,mateos,masoner,masino,marzullo,marz,marsolek,marquard,marchetta,marberry,manzione,manthei,manka,mangram,mangle,mangel,mandato,mancillas,mammen,malina,maletta,malecki,majkut,mages,maestre,macphail,maco,macneill,macadam,lysiak,lyne,luxton,luptak,lundmark,luginbill,lovallo,louthan,lousteau,loupe,lotti,lopresto,lonsdale,longsworth,lohnes,loghry,logemann,lofaro,loeber,locastro,livings,litzinger,litts,liotta,lingard,lineback,lindhorst,lill,lide,lickliter,liberman,lewinski,levandowski,leimbach,leifer,leidholt,leiby,leibel,leibee,lehrke,lehnherr,lego,leese,leen,ledo,lech,leblond,leahey,lazzari,lawrance,lawlis,lawhorne,lawes,lavigna,lavell,lauzier,lauter,laumann,latsha,latourette,latona,latney,laska,larner,larmore,larke,larence,lapier,lanzarin,lammey,lamke,laminack,lamastus,lamaster,lacewell,labarr,laabs,kutch,kuper,kuna,kubis,krzemien,krupinski,krepps,kreeger,kraner,krammer,kountz,kothe,korpela,komara,kolenda,kolek,kohnen,koelzer,koelsch,kocurek,knoke,knauff,knaggs,knab,kluver,klose,klien,klahr,kitagawa,kissler,kirstein,kinnon,kinnebrew,kinnamon,kimmins,kilgour,kilcoyne,kiester,kiehm,kesselring,kerestes,kenniston,kennamore,kenebrew,kelderman,keitel,kefauver,katzenberger,katt,kast,kassel,kamara,kalmbach,kaizer,kaiwi,kainz,jurczyk,jumonville,juliar,jourdain,johndrow,johanning,johannesen,joffrion,jobes,jerde,jentzsch,jenkens,jendro,jellerson,jefferds,jaure,jaquish,janeway,jago,iwasaki,ishman,isaza,inmon,inlow,inclan,ildefonso,iezzi,ianni,iacovetto,hyldahl,huxhold,huser,humpherys,humburg,hult,hullender,hulburt,huckabay,howeth,hovermale,hoven,houtman,hourigan,hosek,hopgood,homrich,holstine,holsclaw,hokama,hoffpauir,hoffner,hochstein,hochstatter,hochberg,hjelm,hiscox,hinsley,hineman,hineline,hinck,hilbun,hewins,herzing,hertzberg,hertenstein,herrea,herington,henrie,henman,hengst,hemmen,helmke,helgerson,heinsohn,heigl,hegstad,heggen,hegge,hefti,heathcock,haylett,haupert,haufler,hatala,haslip,hartless,hartje,hartis,harpold,harmsen,harbach,hanten,hanington,hammen,hameister,hallstrom,habersham,habegger,gussman,gundy,guitterez,guisinger,guilfoyle,groulx,grismer,griesbach,grawe,grall,graben,goulden,gornick,gori,gookin,gonzalaz,gonyer,gonder,golphin,goller,goergen,glosson,glor,gladin,girdler,gillim,gillians,gillaspie,gilhooly,gildon,gignac,gibler,gibbins,giardino,giampietro,gettman,gerringer,gerrald,gerlich,georgiou,georgi,geiselman,gehman,gangl,gamage,gallian,gallen,gallatin,galea,gainor,gahr,furbush,fulfer,fuhrmann,fritter,friis,friedly,freudenberger,freemon,fratus,frans,foulke,fosler,forquer,fontan,folwell,foeller,fodge,fobes,florek,fliss,flesner,flegel,fitzloff,fiser,firmin,firestine,finfrock,fineberg,fiegel,fickling,fesperman,fernadez,felber,feimster,feazel,favre,faughn,fatula,fasone,farron,faron,farino,falvey,falkenberg,faley,faletti,faeth,fackrell,espe,eskola,escott,esaw,erps,erker,erath,enfield,emfinger,embury,embleton,emanuele,elvers,ellwanger,ellegood,eichinger,egge,egeland,edgett,echard,eblen,eastmond,duteau,durland,dure,dunlavy,dungee,dukette,dugay,duboise,dubey,dsouza,druck,dralle,doubek,dorta,dorch,dorce,dopson,dolney,dockter,distler,dippel,dichiara,dicerbo,dewindt,dewan,deveney,devargas,deutscher,deuel,detter,dess,derrington,deroberts,dern,deponte,denogean,denardi,denard,demary,demarais,delucas,deloe,delmonico,delisi,delio,delduca,deihl,dehmer,decoste,dechick,decatur,debruce,debold,debell,deats,daunt,daquilante,dambrosi,damas,dalin,dahman,dahlem,daffin,dacquel,cutrell,cusano,curtner,currens,curnow,cuppett,cummiskey,cullers,culhane,crull,crossin,cropsey,cromie,crofford,criscuolo,crisafulli,crego,creeden,covello,covel,corse,correra,cordner,cordier,coplen,copeman,contini,conteras,consalvo,conduff,compher,colliver,colan,cohill,cohenour,cogliano,codd,cockayne,clum,clowdus,clarida,clance,clairday,clagg,citron,citino,ciriello,cicciarelli,chrostowski,christley,chrisco,chrest,chisler,chieffo,cherne,cherico,cherian,cheirs,chauhan,chamblin,cerra,cepero,cellini,celedon,cejka,cavagnaro,cauffman,catanese,castrillo,castrellon,casserly,caseres,carthen,carse,carragher,carpentieri,carmony,carmer,carlozzi,caradine,cappola,capece,capaldi,cantres,cantos,canevari,canete,calcaterra,cadigan,cabbell,byrn,bykowski,butchko,busler,bushaw,buschmann,burow,buri,burgman,bunselmeyer,bunning,buhrman,budnick,buckson,buckhannon,brunjes,brumleve,bruckman,brouhard,brougham,brostrom,broerman,brocks,brison,brining,brindisi,brereton,breon,breitling,breedon,brasseaux,branaman,bramon,brackenridge,boyan,boxley,bouman,bouillion,botting,botti,bosshart,borup,borner,bordonaro,bonsignore,bonsall,bolter,bojko,bohne,bohlmann,bogdon,boen,bodenschatz,bockoven,bobrow,blondin,blissett,bligen,blasini,blankenburg,bjorkman,bistline,bisset,birdow,biondolillo,bielski,biele,biddix,biddinger,bianchini,bevens,bevard,betancur,bernskoetter,bernet,bernardez,berliner,berland,berkheimer,berent,bensch,benesch,belleau,bedingfield,beckstrom,beckim,bechler,beachler,bazzell,basa,bartoszek,barsch,barrell,barnas,barnaba,barillas,barbier,baltodano,baltierra,balle,balint,baldi,balderson,balderama,baldauf,balcazar,balay,baiz,bairos,azim,aversa,avellaneda,ausburn,auila,augusto,atwill,artiles,arterberry,arnow,arnaud,arnall,arenz,arduini,archila,arakawa,appleman,aplin,antonini,anstey,anglen,andros,amweg,amstutz,amari,amadeo,alteri,aloi,allebach,aley,alamillo,airhart,ahrendt,aegerter,adragna,admas,adderly,adderley,addair,abelar,abbamonte,abadi,zurek,zundel,zuidema,zuelke,zuck,zogg,zody,zets,zech,zecca,zavaleta,zarr,yousif,yoes,yoast,yeagley,yaney,yanda,yackel,wyles,wyke,woolman,woollard,woodis,woodin,wonderly,wombles,woloszyn,wollam,wnek,wittie,withee,wissman,wisham,wintle,winokur,wilmarth,willhoite,wildner,wikel,wieser,wien,wicke,wiatrek,whitehall,whetstine,wheelus,weyrauch,weyers,westerling,wendelken,welner,weinreb,weinheimer,weilbacher,weihe,weider,wecker,wead,watler,watkinson,wasmer,waskiewicz,wasik,warneke,wares,wangerin,wamble,walken,waker,wakeley,wahlgren,wahlberg,wagler,wachob,vorhies,vonseggern,vittitow,vink,villarruel,villamil,villamar,villalovos,vidmar,victorero,vespa,vertrees,verissimo,veltman,vecchione,veals,varrone,varma,vanveen,vanterpool,vaneck,vandyck,vancise,vanausdal,vanalphen,valdiviezo,urton,urey,updegrove,unrue,ulbrich,tysinger,twiddy,tunson,trueheart,troyan,trier,traweek,trafford,tozzi,toulouse,tosto,toste,torez,tooke,tonini,tonge,tomerlin,tolmie,tobe,tippen,tierno,tichy,thuss,thran,thornbury,thone,theunissen,thelmon,theall,textor,teters,tesh,tench,tekautz,tehrani,teat,teare,tavenner,tartaglione,tanski,tanis,tanguma,tangeman,taney,tammen,tamburri,tamburello,talsma,tallie,takeda,taira,taheri,tademy,taddei,taaffe,szymczak,szczepaniak,szafranski,swygert,swem,swartzlander,sutley,supernaw,sundell,sullivant,suderman,sudbury,suares,stueber,stromme,streeper,streck,strebe,stonehouse,stoia,stohr,stodghill,stirewalt,sterry,stenstrom,stene,steinbrecher,stear,stdenis,stanphill,staniszewski,stanard,stahlhut,stachowicz,srivastava,spong,spomer,spinosa,spindel,spera,soward,sopp,sooter,sonnek,soland,sojourner,soeder,sobolewski,snellings,smola,smetana,smeal,smarr,sloma,sligar,skenandore,skalsky,sissom,sirko,simkin,silverthorn,silman,sikkink,signorile,siddens,shumsky,shrider,shoulta,shonk,shomaker,shippey,shimada,shillingburg,shifflet,shiels,shepheard,sheerin,shedden,sheckles,sharrieff,sharpley,shappell,shaneyfelt,shampine,shaefer,shaddock,shadd,sforza,severtson,setzler,sepich,senne,senatore,sementilli,selway,selover,sellick,seigworth,sefton,seegars,sebourn,seaquist,sealock,seabreeze,scriver,scinto,schumer,schulke,schryver,schriner,schramek,schoon,schoolfield,schonberger,schnieder,schnider,schlitz,schlather,schirtzinger,scherman,schenker,scheiner,scheible,schaus,schakel,schaad,saxe,savely,savary,sardinas,santarelli,sanschagrin,sanpedro,sandine,sandigo,sandgren,sanderford,sandahl,salzwedel,salzar,salvino,salvatierra,salminen,salierno,salberg,sahagun,saelee,sabel,rynearson,ryker,rupprecht,runquist,rumrill,ruhnke,rovira,rottenberg,rosoff,rosete,rosebrough,roppolo,roope,romas,roley,rohrback,rohlfs,rogriguez,roel,rodriguiz,rodewald,roback,rizor,ritt,rippee,riolo,rinkenberger,riggsby,rigel,rieman,riedesel,rideau,ricke,rhinebolt,rheault,revak,relford,reinsmith,reichmann,regula,redlinger,rayno,raycroft,raus,raupp,rathmann,rastorfer,rasey,raponi,rantz,ranno,ranes,ramnauth,rahal,raddatz,quattrocchi,quang,pullis,pulanco,pryde,prohaska,primiano,prez,prevatt,prechtl,pottle,potenza,portes,porowski,poppleton,pontillo,politz,politi,poggi,plonka,plaskett,placzek,pizzuti,pizzaro,pisciotta,pippens,pinkins,pinilla,pini,pingitore,piercey,piccola,piccioni,picciano,philps,philp,philo,philmon,philbin,pflieger,pezzullo,petruso,petrea,petitti,peth,peshlakai,peschel,persico,persichetti,persechino,perris,perlow,perico,pergola,penniston,pembroke,pellman,pekarek,peirson,pearcey,pealer,pavlicek,passino,pasquarello,pasion,parzych,parziale,parga,papalia,papadakis,paino,pacini,oyen,ownes,owczarzak,outley,ouelette,ottosen,otting,ostwinkle,osment,oshita,osario,orlow,oriordan,orefice,orantes,oran,orahood,opel,olpin,oliveria,okon,okerlund,okazaki,ohta,offerman,nyce,nutall,northey,norcia,noor,niehoff,niederhauser,nickolson,nguy,neylon,newstrom,nevill,netz,nesselrodt,nemes,neally,nauyen,nascimento,nardella,nanni,myren,murchinson,munter,mundschenk,mujalli,muckleroy,moussa,mouret,moulds,mottram,motte,morre,montreuil,monton,montellano,monninger,monhollen,mongeon,monestime,monegro,mondesir,monceaux,mola,moga,moening,moccia,misko,miske,mishaw,minturn,mingione,milstein,milla,milks,michl,micheletti,michals,mesia,merson,meras,menifee,meluso,mella,melick,mehlman,meffert,medoza,mecum,meaker,meahl,mczeal,mcwatters,mcomber,mcmonigle,mckiddy,mcgranor,mcgeary,mcgaw,mcenery,mcelderry,mcduffey,mccuistion,mccrudden,mccrossin,mccosh,mccolgan,mcclish,mcclenahan,mcclam,mccartt,mccarrell,mcbane,maybury,mayben,maulden,mauceri,matko,mathie,matheis,mathai,masucci,massiah,martorano,martnez,martindelcamp,marschke,marovich,markiewicz,marinaccio,marhefka,marcrum,manton,mannarino,manlove,mangham,manasco,malpica,mallernee,malinsky,malhotra,maish,maisel,mainville,maharrey,magid,maertz,mada,maclaughlin,macina,macdermott,macallister,macadangdang,maack,lynk,lydic,luyando,lutke,lupinacci,lunz,lundsten,lujano,luhn,luecke,luebbe,ludolph,luckman,lucker,luckenbill,luckenbach,lucido,lowney,lowitz,lovaglio,louro,louk,loudy,louderback,lorick,lorenzini,lorensen,lorenc,lomuscio,loguidice,lockner,lockart,lochridge,litaker,lisowe,liptrap,linnane,linhares,lindfors,lindenmuth,lincourt,liew,liebowitz,levengood,leskovec,lesch,leoni,lennard,legner,leaser,leas,leadingham,lazarski,layland,laurito,laulu,laughner,laughman,laughery,laube,latiolais,lasserre,lasser,larrow,larrea,lapsley,lantrip,lanthier,langwell,langelier,landaker,lampi,lamond,lamblin,lambie,lakins,laipple,lagrimas,lafrancois,laffitte,laday,lacko,lacava,labianca,kutsch,kuske,kunert,kubly,kuamoo,krummel,krise,krenek,kreiser,krausz,kraska,krakowski,kradel,kozik,koza,kotowski,koslow,korber,kojima,kochel,knabjian,klunder,klugh,klinkhammer,kliewer,klever,kleber,klages,klaas,kizziar,kitchel,kishimoto,kirschenman,kirschenbaum,kinnick,kinn,kiner,kindla,kindall,kincaide,kilson,killins,kightlinger,kienzle,kiah,khim,ketcherside,kerl,kelsoe,kelker,keizer,keir,kawano,kawa,kaveney,kasparek,kaplowitz,kantrowitz,kant,kanoff,kano,kamalii,kalt,kaleta,kalbach,kalauli,kalata,kalas,kaigler,kachel,juran,jubb,jonker,jonke,jolivette,joles,joas,jividen,jeffus,jeanty,jarvi,jardon,janvier,janosko,janoski,janiszewski,janish,janek,iwanski,iuliano,irle,ingmire,imber,ijames,iiams,ihrig,ichikawa,hynum,hutzel,hutts,huskin,husak,hurndon,huntsinger,hulette,huitron,huguenin,hugg,hugee,huelskamp,huch,howen,hovanec,hoston,hostettler,horsfall,horodyski,holzhauer,hollimon,hollender,hogarth,hoffelmeyer,histand,hissem,hisel,hirayama,hinegardner,hinde,hinchcliffe,hiltbrand,hilsinger,hillstrom,hiley,hickenbottom,hickam,hibley,heying,hewson,hetland,hersch,herlong,herda,henzel,henshall,helson,helfen,heinbach,heikkila,heggs,hefferon,hebard,heathcote,hearl,heaberlin,hauth,hauschild,haughney,hauch,hattori,hasley,hartpence,harroun,harelson,hardgrove,hardel,hansbrough,handshoe,handly,haluska,hally,halling,halfhill,halferty,hakanson,haist,hairgrove,hahner,hagg,hafele,haaland,guttierez,gutknecht,gunnarson,gunlock,gummersheimer,gullatte,guity,guilmette,guhl,guenette,guardino,groshong,grober,gripp,grillot,grilli,greulich,gretzinger,greenwaldt,graven,grassman,granberg,graeser,graeff,graef,grabow,grabau,gotchy,goswick,gosa,gordineer,gorczyca,goodchild,golz,gollihue,goldwire,goldbach,goffredo,glassburn,glaeser,gillilan,gigante,giere,gieger,gidcumb,giarrusso,giannelli,gettle,gesualdi,geschke,gerwig,gervase,geoffrion,gentilcore,genther,gemes,gemberling,gelles,geitz,geeslin,gedney,gebauer,gawron,gavia,gautney,gaustad,gasmen,gargus,ganske,ganger,galvis,gallinger,gallichio,galletta,gaede,gadlin,gaby,gabrielsen,gaboriault,furlan,furgerson,fujioka,fugett,fuehrer,frint,frigon,frevert,frautschi,fraker,fradette,foulkes,forslund,forni,fontenette,fones,folz,folmer,follman,folkman,flourney,flickner,flemmings,fleischacker,flander,flament,fithian,fiorello,fiorelli,fioravanti,fieck,ficke,fiallos,fiacco,feuer,ferrington,fernholz,feria,fergurson,feick,febles,favila,faulkingham,fath,farnam,falter,fakhouri,fairhurst,fahs,estrello,essick,espree,esmond,eskelson,escue,escatel,erebia,epperley,epler,enyart,engelbert,enderson,emch,elisondo,elford,ekman,eick,eichmann,ehrich,ehlen,edwardson,edley,edghill,edel,eastes,easterbrooks,eagleson,eagen,eade,dyle,dutkiewicz,dunnagan,duncil,duling,drumgoole,droney,dreyfus,dragan,dowty,doscher,dornan,doremus,doogan,donaho,donahey,dombkowski,dolton,dolen,dobratz,diveley,dittemore,ditsch,disque,dishmon,disch,dirickson,dippolito,dimuccio,dilger,diefenderfer,dicola,diblasio,dibello,devan,dettmer,deschner,desbiens,derusha,denkins,demonbreun,demchak,delucchi,delprete,deloy,deliz,deline,delap,deiter,deignan,degiacomo,degaetano,defusco,deboard,debiase,deaville,deadwyler,davanzo,daughton,darter,danser,dandrade,dando,dampeer,dalziel,dalen,dain,dague,czekanski,cutwright,cutliff,curle,cuozzo,cunnington,cunnigham,cumings,crowston,crittle,crispell,crisostomo,crear,creach,craigue,crabbs,cozzi,cozza,coxe,cowsert,coviello,couse,coull,cottier,costagliola,corra,corpening,cormany,corless,corkern,conteh,conkey,conditt,conaty,colomb,collura,colledge,colins,colgate,coleson,colemon,coffland,coccia,clougherty,clewell,cleckley,cleaveland,clarno,civils,cillo,cifelli,ciesluk,christison,chowning,chouteau,choung,childres,cherrington,chenette,cheeves,cheairs,chaddock,cernoch,cerino,cazier,castel,casselberry,caserta,carvey,carris,carmant,cariello,cardarelli,caras,caracciolo,capitano,cantoni,cantave,cancio,campillo,callens,caldero,calamia,cahee,cahan,cahalan,cabanilla,cabal,bywater,bynes,byassee,busker,bushby,busack,burtis,burrola,buroker,burnias,burlock,burham,burak,bulla,buffin,buening,budney,buchannan,buchalter,brule,brugler,broxson,broun,brosh,brissey,brisby,brinlee,brinkmeyer,brimley,brickell,breth,breger,brees,brank,braker,bozak,bowlds,bowersock,bousman,boushie,botz,bordwell,bonkowski,bonine,bonifay,bonesteel,boldin,bohringer,bohlander,boecker,bocook,bocock,boblett,bobbett,boas,boarman,bleser,blazejewski,blaustein,blausey,blancarte,blaize,blackson,blacketer,blackard,bisch,birchett,billa,bilder,bierner,bienvenu,bielinski,bialas,biagini,beynon,beyl,bettini,betcher,bessent,beshara,besch,bernd,bergemann,bergeaux,berdan,bens,benedicto,bendall,beltron,beltram,bellville,beisch,behney,beechler,beckum,batzer,batte,bastida,bassette,basley,bartosh,bartolone,barraclough,barnick,barket,barkdoll,baringer,barella,barbian,barbati,bannan,balles,baldo,balasubramani,baig,bahn,bachmeier,babyak,baas,baars,ayuso,avinger,avella,ausbrooks,aull,augello,atkeson,atkerson,atherley,athan,assad,asebedo,arrison,armon,armfield,arkin,archambeau,antonellis,angotti,amorose,amini,amborn,amano,aluarez,allgaier,allegood,alen,aldama,aird,ahsing,ahmann,aguado,agostino,agostinelli,adwell,adsit,adelstein,actis,acierno,achee,abbs,abbitt,zwagerman,zuercher,zinno,zettler,zeff,zavalza,zaugg,zarzycki,zappulla,zanotti,zachman,zacher,yundt,yslas,younes,yontz,yglesias,yeske,yeargin,yauger,yamane,xang,wylam,wrobleski,wratchford,woodlee,wolsey,wolfinbarger,wohlenhaus,wittler,wittenmyer,witkop,wishman,wintz,winkelmann,windus,winborn,wims,wiltrout,willmott,williston,wilemon,wilbourne,wiedyk,widmann,wickland,wickes,wichert,whitsell,whisenand,whidby,wetz,westmeyer,wertheim,wernert,werle,werkheiser,weldin,weissenborn,weingard,weinfeld,weihl,weightman,weichel,wehrheim,wegrzyn,wegmann,waszak,wankum,walthour,waltermire,walstad,waldren,walbert,walawender,wahlund,wahlert,wahlers,wach,vuncannon,vredenburgh,vonk,vollmar,voisinet,vlahos,viscardi,vires,vipperman,violante,vidro,vessey,vesper,veron,vergari,verbeck,venturino,velastegui,vegter,varas,vanwey,vanvranken,vanvalkenbur,vanorsdale,vanoli,vanochten,vanier,vanevery,vane,vanduser,vandersteen,vandell,vandall,vallot,vallon,vallez,vallely,vadenais,uthe,usery,unga,ultsch,ullom,tyminski,twogood,tursi,turay,tungate,truxillo,trulock,trovato,troise,tripi,trinks,trimboli,trickel,trezise,trefry,treen,trebilcock,travieso,trachtenberg,touhey,tougas,tortorella,tormey,torelli,torborg,toran,tomek,tomassi,tollerson,tolden,toda,tobon,tjelmeland,titmus,tilbury,tietje,thurner,thum,thrope,thornbrough,thibaudeau,thackeray,tesoro,territo,ternes,teich,tecson,teater,teagarden,tatsch,tarallo,tapanes,tanberg,tamm,sylvis,swenor,swedlund,sutfin,sura,sundt,sundin,summerson,sumatzkuku,sultemeier,sulivan,suggitt,suermann,sturkie,sturgess,stumph,stuemke,struckhoff,strose,stroder,stricklen,strick,streib,strei,strawther,stratis,strahm,stortz,storrer,storino,stohler,stohl,stockel,stinnette,stile,stieber,steffenhagen,stefanowicz,steever,steagall,statum,stapley,stanish,standiford,standen,stamos,stahlecker,stadtler,spratley,spraker,sposito,spickard,spehar,spees,spearing,spangle,spallone,soulard,sora,sopko,sood,sonnen,solly,solesbee,soldano,sobey,sobczyk,snedegar,sneddon,smolinski,smolik,slota,slavick,skorupski,skolnik,skirvin,skeels,skains,skahan,skaar,siwiec,siverly,siver,sivak,sirk,sinton,sinor,sincell,silberstein,sieminski,sidelinger,shurman,shunnarah,shirer,shidler,sherlin,shepperson,shemanski,sharum,shartrand,shapard,shanafelt,shamp,shader,shackelton,seyer,seroka,sernas,seright,serano,sengupta,selinger,seith,seidler,seehusen,seefried,scovell,scorzelli,sconiers,schwind,schwichtenber,schwerin,schwenke,schwaderer,schussler,schuneman,schumpert,schultheiss,schroll,schroepfer,schroeden,schrimpf,schook,schoof,schomburg,schoenfeldt,schoener,schnoor,schmick,schlereth,schindele,schildt,schildknecht,schemmel,scharfenberg,schanno,schane,schaer,schad,scearce,scardino,sawka,sawinski,savoca,savery,saults,sarpy,saris,sardinha,sarafin,sankar,sanjurjo,sanderfer,sanagustin,samudio,sammartino,samas,salz,salmen,salkeld,salamon,sakurai,sakoda,safley,sada,sachse,ryden,ryback,russow,russey,ruprecht,rumple,ruffini,rudzinski,rudel,rudden,rovero,routledge,roussin,rousse,rouser,rougeau,rosica,romey,romaniello,rolfs,rogoff,rogne,rodriquz,rodrequez,rodin,rocray,rocke,riviere,rivette,riske,risenhoover,rindfleisch,rinaudo,rimbey,riha,righi,ridner,ridling,riden,rhue,reyome,reynoldson,reusch,rensing,rensch,rennels,renderos,reininger,reiners,reigel,rehmer,regier,reff,redlin,recchia,reaume,reagor,rawe,rattigan,raska,rashed,ranta,ranft,randlett,ramiez,ramella,rallis,rajan,raisbeck,raimondo,raible,ragone,rackliffe,quirino,quiring,quero,quaife,pyke,purugganan,pursifull,purkett,purdon,pulos,puccia,provance,propper,preis,prehn,prata,prasek,pranger,pradier,portor,portley,porte,popiel,popescu,pomales,polowy,pollett,politis,polit,poley,pohler,poggio,podolak,poag,plymel,ploeger,planty,piskura,pirrone,pirro,piroso,pinsky,pilant,pickerill,piccolomini,picart,piascik,phann,petruzzelli,petosa,persson,perretta,perkowski,perilli,percifield,perault,peppel,pember,pelotte,pelcher,peixoto,pehl,peatross,pearlstein,peacher,payden,paya,pawelek,pavey,pauda,pathak,parrillo,parness,parlee,paoli,pannebaker,palomar,palo,palmberg,paganelli,paffrath,padovano,padden,pachucki,ovando,othman,osowski,osler,osika,orsburn,orlowsky,oregel,oppelt,opfer,opdyke,onell,olivos,okumura,okoro,ogas,oelschlaeger,oder,ocanas,obrion,obarr,oare,nyhus,nyenhuis,nunnelley,nunamaker,nuckels,noyd,nowlan,novakovich,noteboom,norviel,nortz,norment,norland,nolt,nolie,nixson,nitka,nissley,nishiyama,niland,niewiadomski,niemeier,nieland,nickey,nicholsen,neugent,neto,nerren,neikirk,neigh,nedrow,neave,nazaire,navaro,navalta,nasworthy,nasif,nalepa,nakao,nakai,nadolny,myklebust,mussel,murthy,muratore,murat,mundie,mulverhill,muilenburg,muetzel,mudra,mudgett,mrozinski,moura,mottinger,morson,moretto,morentin,mordan,mooreland,mooers,monts,montone,montondo,montiero,monie,monat,monares,mollo,mollet,molacek,mokry,mohrmann,mohabir,mogavero,moes,moceri,miyoshi,mitzner,misra,mirr,minish,minge,minckler,milroy,mille,mileski,milanesi,miko,mihok,mihalik,mieczkowski,messerli,meskill,mesenbrink,merton,merryweather,merkl,menser,menner,menk,menden,menapace,melbourne,mekus,meinzer,meers,mctigue,mcquitty,mcpheron,mcmurdie,mcleary,mclafferty,mckinzy,mckibbin,mckethan,mcintee,mcgurl,mceachran,mcdowall,mcdermitt,mccuaig,mccreedy,mccoskey,mcclosky,mcclintick,mccleese,mccanless,mazzucco,mazzocco,mazurkiewicz,mazariego,mayhorn,maxcy,mavity,mauzey,maulding,matuszewski,mattsson,mattke,matsushita,matsuno,matsko,matkin,mathur,masterman,massett,massart,massari,mashni,martella,marren,margotta,marder,marczak,maran,maradiaga,manwarren,manter,mantelli,manso,mangone,manfredonia,malden,malboeuf,malanga,makara,maison,maisano,mairs,mailhiot,magri,madron,madole,mackall,macduff,macartney,lynds,lusane,luffman,louth,loughmiller,lougheed,lotspeich,lorenzi,loosli,longe,longanecker,lonero,lohmeyer,loeza,lobstein,lobner,lober,littman,litalien,lippe,lints,lijewski,ligas,liebert,liebermann,liberati,lezcano,levinthal,lessor,lesieur,lenning,lengel,lempke,lemp,lemar,leitzke,leinweber,legrone,lege,leder,lawnicki,lauth,laun,laughary,lassley,lashway,larrivee,largen,lare,lanouette,lanno,langille,langen,lamonte,lalin,laible,lafratta,laforte,lacuesta,lacer,labore,laboe,labeau,kwasniewski,kunselman,kuhr,kuchler,krugman,kruckenberg,krotzer,kroemer,krist,krigbaum,kreke,kreisman,kreisler,kreft,krasnow,kras,krag,kouyate,kough,kotz,kostura,korner,kornblum,korczynski,koppa,kopczyk,konz,komorowski,kollen,kolander,koepnick,koehne,kochis,knoch,knippers,knaebel,klipp,klinedinst,klimczyk,klier,klement,klaphake,kisler,kinzie,kines,kindley,kimple,kimm,kimbel,kilker,kilborn,kibbey,khong,ketchie,kerbow,kennemore,kennebeck,kenneally,kenndy,kenmore,kemnitz,kemler,kemery,kelnhofer,kellstrom,kellis,kellams,keiter,keirstead,keeny,keelin,keefauver,keams,kautzman,kaus,katayama,kasson,kassim,kasparian,kase,karwoski,kapuscinski,kaneko,kamerling,kamada,kalka,kalar,kakacek,kaczmarczyk,jurica,junes,journell,jolliffe,johnsey,jindra,jimenz,jette,jesperson,jerido,jenrette,jencks,jech,jayroe,jayo,javens,jaskot,jaros,jaquet,janowiak,jaegers,jackel,izumi,irelan,inzunza,imoto,imme,iglehart,iannone,iannacone,huyler,hussaini,hurlock,hurlbutt,huprich,humphry,hulslander,huelsman,hudelson,hudecek,hsia,hreha,hoyland,howk,housholder,housden,houff,horkey,honan,homme,holtzberg,hollyfield,hollings,hollenbaugh,hokenson,hogrefe,hogland,hoel,hodgkin,hochhalter,hjelle,hittson,hinderman,hinchliffe,hime,hilyer,hilby,hibshman,heydt,hewell,heward,hetu,hestand,heslep,herridge,herner,hernande,hermandez,hermance,herbold,heon,henthorne,henion,henao,heming,helmkamp,hellberg,heidgerken,heichel,hehl,hegedus,heckathorne,hearron,haymer,haycook,havlicek,hausladen,haseman,hartsook,hartog,harns,harne,harmann,haren,hanserd,hanners,hanekamp,hamra,hamley,hamelin,hamblet,hakimi,hagle,hagin,haehn,haeck,hackleman,haacke,gulan,guirand,guiles,guggemos,guerrieri,guerreiro,guereca,gudiel,guccione,gubler,gruenwald,gritz,grieser,grewe,grenon,gregersen,grefe,grech,grecco,gravette,grassia,granholm,graner,grandi,grahan,gradowski,gradney,graczyk,gouthier,gottschall,goracke,gootee,goodknight,goodine,gonzalea,gonterman,gonalez,gomm,goleman,goldtooth,goldstone,goldey,golan,goen,goeller,goel,goecke,godek,goan,glunz,gloyd,glodowski,glinski,glawe,girod,girdley,gindi,gillings,gildner,giger,giesbrecht,gierke,gier,giboney,giaquinto,giannakopoulo,giaimo,giaccio,giacalone,gessel,gerould,gerlt,gerhold,geralds,genson,genereux,gellatly,geigel,gehrig,gehle,geerdes,geagan,gawel,gavina,gauss,gatwood,gathman,gaster,garske,garratt,garms,garis,gansburg,gammell,gambale,gamba,galimore,gadway,gadoury,furrer,furino,fullard,fukui,fryou,friesner,friedli,friedl,friedberg,freyermuth,fremin,fredell,fraze,franken,foth,fote,fortini,fornea,formanek,forker,forgette,folan,foister,foglesong,flinck,flewellen,flaten,flaig,fitgerald,fischels,firman,finstad,finkelman,finister,fina,fetterhoff,ferriter,ferch,fennessy,feltus,feltes,feinman,farve,farry,farrall,farag,falzarano,falck,falanga,fakhoury,fairbrother,fagley,faggins,facteau,ewer,ewbank,evola,evener,eustis,estwick,estel,essa,espinola,escutia,eschmann,erpelding,ernsberger,erling,entz,engelhart,enbody,emick,elsinger,ellinwood,ellingsen,ellicott,elkind,eisinger,eisenbeisz,eischen,eimer,eigner,eichhorst,ehmke,egleston,eggett,efurd,edgeworth,eckels,ebey,eberling,eagleton,dwiggins,dweck,dunnings,dunnavant,dumler,duman,dugue,duerksen,dudeck,dreisbach,drawdy,drawbaugh,draine,draggoo,dowse,dovel,doughton,douds,doubrava,dort,dorshorst,dornier,doolen,donavan,dominik,domingez,dolder,dold,dobies,diskin,disano,dirden,diponio,dipirro,dimock,diltz,dillabough,diley,dikes,digges,digerolamo,diel,dicharry,dicecco,dibartolomeo,diamant,dewire,devone,dessecker,dertinger,derousselle,derk,depauw,depalo,denherder,demeyer,demetro,demastus,delvillar,deloye,delosrios,delgreco,delarge,delangel,dejongh,deitsch,degiorgio,degidio,defreese,defoe,decambra,debenedetto,deaderick,daza,dauzat,daughenbaugh,dato,dass,darwish,dantuono,danton,dammeyer,daloia,daleo,dagg,dacey,curts,cuny,cunneen,culverhouse,cucinella,cubit,crumm,crudo,crowford,crout,crotteau,crossfield,crooke,crom,critz,cristaldi,crickmore,cribbin,cremeens,crayne,cradduck,couvertier,cottam,cossio,correy,cordrey,coplon,copass,coone,coody,contois,consla,connelley,connard,congleton,condry,coltey,colindres,colgrove,colfer,colasurdo,cochell,cobbin,clouthier,closs,cloonan,clizbe,clennon,clayburn,claybourn,clausell,clasby,clagett,ciskowski,cirrincione,cinque,cinelli,cimaglia,ciaburri,christiani,christeson,chladek,chizmar,chinnici,chiarella,chevrier,cheves,chernow,cheong,chelton,chanin,cham,chaligoj,celestino,cayce,cavey,cavaretta,caughron,catmull,catapano,cashaw,carullo,carualho,carthon,cartelli,carruba,carrere,carolus,carlstrom,carfora,carello,carbary,caplette,cannell,cancilla,campell,cammarota,camilo,camejo,camarata,caisse,cacioppo,cabbagestalk,cabatu,cabanas,byles,buxbaum,butland,burrington,burnsed,burningham,burlingham,burgy,buitrago,bueti,buehring,buday,bucknell,buchbinder,bucey,bruster,brunston,brouillet,brosious,broomes,brodin,broddy,brochard,britsch,britcher,brierley,brezina,bressi,bressette,breslow,brenden,breier,brei,braymer,brasuell,branscomb,branin,brandley,brahler,bracht,bracamontes,brabson,boyne,boxell,bowery,bovard,boutelle,boulette,bottini,botkins,bosen,boscia,boscarino,borich,boreman,bordoy,bordley,bordenet,boquet,boocks,bolner,boissy,boilard,bohnen,bohall,boening,boccia,boccella,bobe,blyth,biviano,bitto,bisel,binstock,bines,billiter,bigsby,bighorse,bielawski,bickmore,bettin,bettenhausen,besson,beseau,berton,berroa,berntson,bernas,berisford,berhow,bergsma,benyo,benyard,bente,bennion,benko,belsky,bellavance,belasco,belardo,beidler,behring,begnaud,bega,befort,beek,bedore,beddard,becknell,beardslee,beardall,beagan,bayly,bauza,bautz,bausman,baumler,batterson,battenfield,bassford,basse,basemore,baruch,bartholf,barman,baray,barabas,banghart,banez,balsam,ballester,ballagh,baldock,bagnoli,bagheri,bacus,bacho,baccam,axson,averhart,aver,austill,auberry,athans,atcitty,atay,astarita,ascolese,artzer,arrasmith,argenbright,aresco,aranjo,appleyard,appenzeller,apilado,antonetti,antis,annas,angwin,andris,andries,andreozzi,ando,andis,anderegg,amyot,aminov,amelung,amelio,amason,alviar,allendorf,aldredge,alcivar,alaya,alapai,airington,aina,ailor,ahrns,ahmadi,agresta,affolter,aeschlimann,adney,aderhold,adachi,ackiss,aben,abdelhamid,abar,aase,zorilla,zordan,zollman,zoch,zipfel,zimmerle,zike,ziel,zens,zelada,zaman,zahner,zadora,zachar,zaborowski,zabinski,yzquierdo,yoshizawa,yori,yielding,yerton,yehl,yeargain,yeakley,yamaoka,yagle,yablonski,wynia,wyne,wyers,wrzesinski,wrye,wriston,woolums,woolen,woodlock,woodle,wonser,wombacher,wollschlager,wollen,wolfley,wolfer,wisse,wisell,wirsing,winstanley,winsley,winiecki,winiarski,winge,winesett,windell,winberry,willyard,willemsen,wilkosz,wilensky,wikle,wiford,wienke,wieneke,wiederhold,wiebold,widick,wickenhauser,whitrock,whisner,whinery,wherley,whedbee,wheadon,whary,wessling,wessells,wenninger,wendroth,wende,wellard,weirick,weinkauf,wehrman,weech,weathersbee,warncke,wardrip,walstrom,walkowski,walcutt,waight,wagman,waggett,wadford,vowles,vormwald,vondran,vohs,vitt,vitalo,viser,vinas,villena,villaneuva,villafranca,villaflor,vilain,vicory,viana,vian,verucchi,verra,venzke,venske,veley,veile,veeder,vaske,vasconez,vargason,varble,vanwert,vantol,vanscooter,vanmetre,vanmaanen,vanhise,vaneaton,vandyk,vandriel,vandorp,vandewater,vandervelden,vanderstelt,vanderhoef,vanderbeck,vanbibber,vanalstine,vanacore,valdespino,vaill,vailes,vagliardo,ursini,urrea,urive,uriegas,umphress,ucci,uballe,tynon,twiner,tutton,tudela,tuazon,troisi,tripplett,trias,trescott,treichel,tredo,tranter,tozer,toxey,tortorici,tornow,topolski,topia,topel,topalian,tonne,tondre,tola,toepke,tisdell,tiscareno,thornborrow,thomison,thilges,theuret,therien,thagard,thacher,texter,terzo,tenpenny,tempesta,teetz,teaff,tavella,taussig,tatton,tasler,tarrence,tardie,tarazon,tantillo,tanney,tankson,tangen,tamburo,tabone,szilagyi,syphers,swistak,swiatkowski,sweigert,swayzer,swapp,svehla,sutphen,sutch,susa,surma,surls,sundermeyer,sundeen,sulek,sughrue,sudol,sturms,stupar,stum,stuckman,strole,strohman,streed,strebeck,strausser,strassel,stpaul,storts,storr,stommes,stmary,stjulien,stika,stiggers,sthill,stevick,sterman,stepanek,stemler,stelman,stelmack,steinkamp,steinbock,stcroix,stcharles,staudinger,stanly,stallsworth,stalley,srock,spritzer,spracklin,spinuzzi,spidell,speyrer,sperbeck,spendlove,speckman,spargur,spangenberg,spaid,sowle,soulier,sotolongo,sostre,sorey,sonier,somogyi,somera,soldo,soderholm,snoots,snooks,snoke,snodderly,snee,smithhart,smillie,smay,smallman,sliwinski,slentz,sledd,slager,skogen,skog,skarda,skalicky,siwek,sitterson,sisti,sissel,sinopoli,similton,simila,simenson,silvertooth,silos,siggins,sieler,siburt,sianez,shurley,shular,shuecraft,shreeves,shollenberger,shoen,shishido,shipps,shipes,shinall,sherfield,shawe,sharrett,sharrard,shankman,sessum,serviss,servello,serice,serda,semler,semenza,selmon,sellen,seley,seidner,seib,sehgal,seelbach,sedivy,sebren,sebo,seanez,seagroves,seagren,seabron,schwertner,schwegel,schwarzer,schrunk,schriefer,schreder,schrank,schopp,schonfeld,schoenwetter,schnall,schnackenberg,schnack,schmutzler,schmierer,schmidgall,schlup,schloemer,schlitt,schermann,scherff,schellenberg,schain,schaedler,schabel,scaccia,saye,saurez,sasseen,sasnett,sarti,sarra,sarber,santoy,santeramo,sansoucy,sando,sandles,sandau,samra,samaha,salizar,salam,saindon,sagaser,saeteun,sadusky,sackman,sabater,saas,ruthven,ruszkowski,rusche,rumpf,ruhter,ruhenkamp,rufo,rudge,ruddle,rowlee,rowand,routhier,rougeot,rotramel,rotan,rosten,rosillo,rookard,roode,rongstad,rollie,roider,roffe,roettger,rodick,rochez,rochat,rivkin,rivadeneira,riston,risso,rinderknecht,riis,riggsbee,rieker,riegle,riedy,richwine,richmon,ricciuti,riccardo,ricardson,rhew,revier,remsberg,remiszewski,rembold,rella,reinken,reiland,reidel,reichart,rehak,redway,rednour,redifer,redgate,redenbaugh,redburn,readus,raybuck,rauhuff,rauda,ratte,rathje,rappley,rands,ramseyer,ramseur,ramsdale,ramo,ramariz,raitz,raisch,rainone,rahr,ragasa,rafalski,radunz,quenzer,queja,queenan,pyun,putzier,puskas,purrington,puri,punt,pullar,pruse,pring,primeau,prevette,preuett,prestage,pownell,pownall,potthoff,potratz,poth,poter,posthuma,posen,porritt,popkin,poormon,polidoro,polcyn,pokora,poer,pluviose,plock,pleva,placke,pioli,pingleton,pinchback,pieretti,piccone,piatkowski,philley,phibbs,phay,phagan,pfund,peyer,pettersen,petter,petrucelli,petropoulos,petras,petix,pester,pepperman,pennick,penado,pelot,pelis,peeden,pechon,peal,pazmino,patchin,pasierb,parran,parilla,pardy,parcells,paragas,paradee,papin,panko,pangrazio,pangelinan,pandya,pancheri,panas,palmiter,pallares,palinkas,palek,pagliaro,packham,pacitti,ozier,overbaugh,oursler,ouimette,otteson,otsuka,othon,osmundson,oroz,orgill,ordeneaux,orama,oppy,opheim,onkst,oltmanns,olstad,olofson,ollivier,olejniczak,okura,okuna,ohrt,oharra,oguendo,ogier,offermann,oetzel,oechsle,odoherty,oddi,ockerman,occhiogrosso,obryon,obremski,nyreen,nylund,nylen,nyholm,nuon,nuanes,norrick,noris,nordell,norbury,nooner,nomura,nole,nolden,nofsinger,nocito,niedbala,niebergall,nicolini,nevils,neuburger,nemerofsky,nemecek,nazareno,nastri,nast,nagorski,myre,muzzey,mutschler,muther,musumeci,muranaka,muramoto,murad,murach,muns,munno,muncrief,mugrage,muecke,mozer,moyet,mowles,mottern,mosman,mosconi,morine,morge,moravec,morad,mones,moncur,monarez,molzahn,moglia,moesch,mody,modisett,mitnick,mithcell,mitchiner,mistry,misercola,mirabile,minvielle,mino,minkler,minifield,minichiello,mindell,minasian,milteer,millwee,millstein,millien,mikrut,mihaly,miggins,michard,mezo,metzner,mesquita,merriwether,merk,merfeld,mercik,mercadante,menna,mendizabal,mender,melusky,melquist,mellado,meler,melendes,mekeel,meiggs,megginson,meck,mcwherter,mcwayne,mcsparren,mcrea,mcneff,mcnease,mcmurrin,mckeag,mchughes,mcguiness,mcgilton,mcelreath,mcelhone,mcelhenney,mceldowney,mccurtain,mccure,mccosker,mccory,mccormic,mccline,mccleave,mcclatchey,mccarney,mccanse,mcallen,mazzie,mazin,mazanec,mayette,mautz,maun,mattas,mathurin,mathiesen,massmann,masri,masias,mascolo,mascetti,mascagni,marzolf,maruska,martain,marszalek,marolf,marmas,marlor,markwood,marinero,marier,marich,marcom,marciante,marchman,marchio,marbach,manzone,mantey,mannina,manhardt,manaois,malmgren,mallonee,mallin,mallary,malette,makinson,makins,makarewicz,mainwaring,maiava,magro,magouyrk,magett,maeder,madyun,maduena,maden,madeira,mackins,mackel,macinnes,macia,macgowan,lyssy,lyerly,lyalls,lutter,lunney,luksa,ludeman,lucidi,lucci,lowden,lovier,loughridge,losch,lorson,lorenzano,lorden,lorber,lopardo,loosier,loomer,longsdorf,longchamps,loncar,loker,logwood,loeffelholz,lockmiller,livoti,linford,linenberger,lindloff,lindenbaum,limoges,liley,lighthill,lightbourne,lieske,leza,levandoski,leuck,lepere,leonhart,lenon,lemma,lemler,leising,leinonen,lehtinen,lehan,leetch,leeming,ledyard,ledwith,ledingham,leclere,leck,lebert,leandry,lazzell,layo,laye,laxen,lawther,lawerance,lavoy,lavertu,laverde,latouche,latner,lathen,laskin,lashbaugh,lascala,larroque,larick,laraia,laplume,lanzilotta,lannom,landrigan,landolt,landess,lamkins,lalla,lalk,lakeman,lakatos,laib,lahay,lagrave,lagerquist,lafoy,lafleche,lader,labrada,kwiecinski,kutner,kunshier,kulakowski,kujak,kuehnle,kubisiak,krzyminski,krugh,krois,kritikos,krill,kriener,krewson,kretzschmar,kretz,kresse,kreiter,kreischer,krebel,krans,kraling,krahenbuhl,kouns,kotson,kossow,kopriva,konkle,kolter,kolk,kolich,kohner,koeppen,koenigs,kock,kochanski,kobus,knowling,knouff,knoerzer,knippel,kloberdanz,kleinert,klarich,klaassen,kisamore,kirn,kiraly,kipps,kinson,kinneman,kington,kine,kimbriel,kille,kibodeaux,khamvongsa,keylon,kever,keser,kertz,kercheval,kendrix,kendle,kempt,kemple,keesey,keatley,kazmierski,kazda,kazarian,kawashima,katsch,kasun,kassner,kassem,kasperski,kasinger,kaschak,karels,kantola,kana,kamai,kalthoff,kalla,kalani,kahrs,kahanek,kacher,jurasek,jungels,jukes,juelfs,judice,juda,josselyn,jonsson,jonak,joens,jobson,jegede,jeanjacques,jaworowski,jaspers,jannsen,janner,jankowiak,jank,janiak,jackowski,jacklin,jabbour,iyer,iveson,isner,iniquez,ingwerson,ingber,imbrogno,ille,ikehara,iannelli,hyson,huxford,huseth,hurns,hurney,hurles,hunnings,humbarger,hulan,huisinga,hughett,hughen,hudler,hubiak,hricko,hoversten,hottel,hosaka,horsch,hormann,hordge,honzell,homburg,holten,holme,hollopeter,hollinsworth,hollibaugh,holberg,hohmann,hoenstine,hodell,hodde,hiter,hirko,hinzmann,hinrichsen,hinger,hincks,hilz,hilborn,highley,higashi,hieatt,hicken,heverly,hesch,hervert,hershkowitz,herreras,hermanns,herget,henriguez,hennon,hengel,helmlinger,helmig,heldman,heizer,heinitz,heifner,heidorn,heglin,heffler,hebner,heathman,heaslip,hazlip,haymes,hayase,hawver,havermale,havas,hauber,hashim,hasenauer,harvel,hartney,hartel,harsha,harpine,harkrider,harkin,harer,harclerode,hanzely,hanni,hannagan,hampel,hammerschmidt,hamar,hallums,hallin,hainline,haid,haggart,hafen,haer,hadiaris,hadad,hackford,habeeb,guymon,guttery,gunnett,guillette,guiliano,guilbeaux,guiher,guignard,guerry,gude,gucman,guadian,grzybowski,grzelak,grussendorf,grumet,gruenhagen,grudzinski,grossmann,grof,grisso,grisanti,griffitts,griesbaum,grella,gregston,graveline,grandusky,grandinetti,gramm,goynes,gowing,goudie,gosman,gort,gorsline,goralski,goodstein,goodroe,goodlin,goodheart,goodhart,gonzelez,gonthier,goldsworthy,goldade,goettel,goerlitz,goepfert,goehner,goben,gobeille,gliem,gleich,glasson,glascoe,gladwell,giusto,girdner,gipple,giller,giesing,giammona,ghormley,germon,geringer,gergely,gerberich,gepner,gens,genier,gemme,gelsinger,geigle,gebbia,gayner,gavitt,gatrell,gastineau,gasiewski,gascoigne,garro,garin,ganong,ganga,galpin,gallus,galizia,gajda,gahm,gagen,gaffigan,furno,furnia,furgason,fronczak,frishman,friess,frierdich,freestone,franta,frankovich,fors,forres,forrer,florido,flis,flicek,flens,flegal,finkler,finkenbinder,finefrock,filpo,filion,fierman,fieldman,ferreyra,fernendez,fergeson,fera,fencil,feith,feight,federici,federer,fechtner,feagan,fausnaugh,faubert,fata,farman,farinella,fantauzzi,fanara,falso,falardeau,fagnani,fabro,excell,ewton,evey,everetts,evarts,etherington,estremera,estis,estabrooks,essig,esplin,espenschied,ernzen,eppes,eppard,entwisle,emison,elison,elguezabal,eledge,elbaz,eisler,eiden,eichorst,eichert,egle,eggler,eggimann,edey,eckerman,echelberger,ebbs,ebanks,dziak,dyche,dyce,dusch,duross,durley,durate,dunsworth,dumke,dulek,duhl,duggin,dufford,dudziak,ducrepin,dubree,dubre,dubie,dubas,droste,drisko,drewniak,doxtator,dowtin,downum,doubet,dottle,dosier,doshi,dorst,dorset,dornbusch,donze,donica,domanski,domagala,dohse,doerner,doerfler,doble,dobkins,dilts,digiulio,digaetano,dietzel,diddle,dickel,dezarn,devoy,devoss,devilla,devere,deters,desvergnes,deshay,desena,deross,depedro,densley,demorest,demore,demora,demirjian,demerchant,dematteis,demateo,delgardo,delfavero,delaurentis,delamar,delacy,deitrich,deisher,degracia,degraaf,defries,defilippis,decoursey,debruin,debiasi,debar,dearden,dealy,dayhoff,davino,darvin,darrisaw,darbyshire,daquino,daprile,danh,danahy,dalsanto,dallavalle,dagel,dadamo,dacy,dacunha,dabadie,czyz,cutsinger,curney,cuppernell,cunliffe,cumby,cullop,cullinane,cugini,cudmore,cuda,cucuzza,cuch,crumby,crouser,critton,critchley,cremona,cremar,crehan,creary,crasco,crall,crabbe,cozzolino,cozier,coyner,couvillier,counterman,coulthard,coudriet,cottom,corzo,cornutt,corkran,corda,copelin,coonan,consolo,conrow,conran,connerton,conkwright,condren,comly,comisky,colli,collet,colello,colbeck,colarusso,coiner,cohron,codere,cobia,clure,clowser,clingenpeel,clenney,clendaniel,clemenson,cleere,cleckler,claybaugh,clason,cirullo,ciraulo,ciolek,ciampi,christopherse,chovanec,chopra,chol,chiem,chestnutt,chesterman,chernoff,chermak,chelette,checketts,charpia,charo,chargois,champman,challender,chafins,cerruto,celi,cazenave,cavaluzzi,cauthon,caudy,catino,catano,cassaro,cassarino,carrano,carozza,carow,carmickle,carlyon,carlew,cardena,caputi,capley,capalbo,canseco,candella,campton,camposano,calleros,calleja,callegari,calica,calarco,calais,caillier,cahue,cadenhead,cadenas,cabera,buzzo,busto,bussmann,busenbark,burzynski,bursley,bursell,burle,burkleo,burkette,burczyk,bullett,buikema,buenaventura,buege,buechel,budreau,budhram,bucknam,brye,brushwood,brumbalow,brulotte,bruington,bruderer,brougher,bromfield,broege,brodhead,brocklesby,broadie,brizuela,britz,brisendine,brilla,briggeman,brierton,bridgeford,breyfogle,brevig,breuninger,bresse,bresette,brelsford,breitbach,brayley,braund,branscom,brandner,brahm,braboy,brabble,bozman,boyte,boynes,boyken,bowell,bowan,boutet,bouse,boulet,boule,bottcher,bosquez,borrell,boria,bordes,borchard,bonson,bonino,bonas,bonamico,bolstad,bolser,bollis,bolich,bolf,boker,boileau,bohac,bogucki,bogren,boeger,bodziony,bodo,bodley,boback,blyther,blenker,blazina,blase,blamer,blacknall,blackmond,bitz,biser,biscardi,binz,bilton,billotte,billafuerte,bigford,biegler,bibber,bhandari,beyersdorf,bevelle,bettendorf,bessard,bertsche,berne,berlinger,berish,beranek,bentson,bentsen,benskin,benoy,benoist,benitz,belongia,belmore,belka,beitzel,beiter,beitel,behrns,becka,beaudion,beary,beare,beames,beabout,beaber,bazzano,bazinet,baucum,batrez,baswell,bastos,bascomb,bartha,barstad,barrilleaux,barretto,barresi,barona,barkhurst,barke,bardales,barczak,barca,barash,banfill,balonek,balmes,balko,balestrieri,baldino,baldelli,baken,baiza,bahner,baek,badour,badley,badia,backmon,bacich,bacca,ayscue,aynes,ausiello,auringer,auiles,aspinwall,askwith,artiga,arroliga,arns,arman,arellanes,aracena,antwine,antuna,anselmi,annen,angelino,angeli,angarola,andrae,amodio,ameen,alwine,alverio,altro,altobello,altemus,alquicira,allphin,allemand,allam,alessio,akpan,akerman,aiona,agyeman,agredano,adamik,adamczak,acrey,acevado,abreo,abrahamsen,abild,zwicker,zweig,zuvich,zumpano,zuluaga,zubek,zornes,zoglmann,ziminski,zimbelman,zhanel,zenor,zechman,zauner,zamarron,zaffino,yusuf,ytuarte,yett,yerkovich,yelder,yasuda,yapp,yaden,yackley,yaccarino,wytch,wyre,wussow,worthing,wormwood,wormack,wordell,woodroof,woodington,woodhams,wooddell,wollner,wojtkowski,wojcicki,wogan,wlodarczyk,wixted,withington,withem,wisler,wirick,winterhalter,winski,winne,winemiller,wimett,wiltfong,willibrand,willes,wilkos,wilbon,wiktor,wiggers,wigg,wiegmann,wickliff,wiberg,whittler,whittenton,whitling,whitledge,whitherspoon,whiters,whitecotton,whitebird,wheary,wetherill,westmark,westaby,wertenberger,wentland,wenstrom,wenker,wellen,weier,wegleitner,wedekind,wawers,wassel,warehime,wandersee,waltmon,waltersheid,walbridge,wakely,wakeham,wajda,waithe,waidelich,wahler,wahington,wagster,wadel,vuyovich,vuolo,vulich,vukovich,volmer,vollrath,vollbrecht,vogelgesang,voeller,vlach,vivar,vitullo,vitanza,visker,visalli,viray,vinning,viniard,villapando,villaman,vier,viar,viall,verstraete,vermilya,verdon,venn,velten,velis,vanoven,vanorder,vanlue,vanheel,vanderwoude,vanderheide,vandenheuvel,vandenbos,vandeberg,vandal,vanblarcom,vanaken,vanacker,vallian,valine,valent,vaine,vaile,vadner,uttech,urioste,urbanik,unrath,unnasch,underkofler,uehara,tyrer,tyburski,twaddle,turntine,tunis,tullock,tropp,troilo,tritsch,triola,trigo,tribou,tribley,trethewey,tress,trela,treharne,trefethen,trayler,trax,traut,tranel,trager,traczyk,towsley,torrecillas,tornatore,tork,torivio,toriello,tooles,tomme,tolosa,tolen,toca,titterington,tipsword,tinklenberg,tigney,tigert,thygerson,thurn,thur,thorstad,thornberg,thoresen,thomaston,tholen,thicke,theiler,thebeau,theaux,thaker,tewani,teufel,tetley,terrebonne,terrano,terpening,tela,teig,teichert,tegethoff,teele,tatar,tashjian,tarte,tanton,tanimoto,tamimi,tamas,talman,taal,szydlowski,szostak,swoyer,swerdlow,sweeden,sweda,swanke,swander,suyama,suriano,suri,surdam,suprenant,sundet,summerton,sult,suleiman,suffridge,suby,stych,studeny,strupp,struckman,strief,strictland,stremcha,strehl,stramel,stoy,stoutamire,storozuk,stordahl,stopher,stolley,stolfi,stoeger,stockhausen,stjulian,stivanson,stinton,stinchfield,stigler,stieglitz,stgermaine,steuer,steuber,steuart,stepter,stepnowski,stepanian,steimer,stefanelli,stebner,stears,steans,stayner,staubin,statz,stasik,starn,starmer,stargel,stanzione,stankovich,stamour,staib,stadelman,stadel,stachura,squadrito,springstead,spragg,spigelmyer,spieler,spaur,sovocool,soundara,soulia,souffrant,sorce,sonkin,sodhi,soble,sniffen,smouse,smittle,smithee,smedick,slowinski,slovacek,slominski,skowronek,skokan,skanes,sivertson,sinyard,sinka,sinard,simonin,simonian,simmions,silcott,silberg,siefken,siddon,shuttlesworth,shubin,shubeck,shiro,shiraki,shipper,shina,shilt,shikles,shideler,shenton,shelvey,shellito,shelhorse,shawcroft,shatto,shanholtzer,shamonsky,shadden,seymer,seyfarth,setlock,serratos,serr,sepulueda,senay,semmel,semans,selvig,selkirk,selk,seligson,seldin,seiple,seiersen,seidling,seidensticker,secker,searson,scordo,scollard,scoggan,scobee,sciandra,scialdone,schwimmer,schwieger,schweer,schwanz,schutzenhofer,schuetze,schrodt,schriever,schriber,schremp,schrecongost,schraeder,schonberg,scholtz,scholle,schoettle,schoenemann,schoene,schnitker,schmuhl,schmith,schlotterbeck,schleppenbach,schlee,schickel,schibi,schein,scheide,scheibe,scheib,schaumberg,schardein,schaalma,scantlin,scantlebury,sayle,sausedo,saurer,sassone,sarracino,saric,sanz,santarpia,santano,santaniello,sangha,sandvik,sandoral,sandobal,sandercock,sanantonio,salviejo,salsberry,salois,salazer,sagon,saglibene,sagel,sagal,saetern,saefong,sadiq,sabori,saballos,rygiel,rushlow,runco,rulli,ruller,ruffcorn,ruess,ruebush,rudlong,rudin,rudgers,rudesill,ruderman,rucki,rucinski,rubner,rubinson,rubiano,roznowski,rozanski,rowson,rower,rounsaville,roudabush,rotundo,rothell,rotchford,rosiles,roshak,rosetti,rosenkranz,rorer,rollyson,rokosz,rojek,roitman,rohrs,rogel,roewe,rodriges,rodocker,rodgerson,rodan,rodak,rocque,rochholz,robicheau,robbinson,roady,ritchotte,ripplinger,rippetoe,ringstaff,ringenberg,rinard,rigler,rightmire,riesen,riek,ridges,richner,richberg,riback,rial,rhyner,rhees,resse,renno,rendleman,reisz,reisenauer,reinschmidt,reinholt,reinard,reifsnyder,rehfeld,reha,regester,reffitt,redler,rediske,reckner,reckart,rebolloso,rebollar,reasonover,reasner,reaser,reano,reagh,raval,ratterman,ratigan,rater,rasp,raneses,randolf,ramil,ramdas,ramberg,rajaniemi,raggio,ragel,ragain,rade,radaker,racioppi,rabinovich,quickle,quertermous,queal,quartucci,quander,quain,pynes,putzel,purl,pulizzi,pugliares,prusak,prueter,protano,propps,primack,prieur,presta,preister,prawl,pratley,pozzo,powless,povey,pottorf,pote,postley,porzio,portney,ponzi,pontoriero,ponto,pont,poncedeleon,polimeni,polhamus,polan,poetker,poellnitz,podgurski,plotts,pliego,plaugher,plantenberg,plair,plagmann,pizzitola,pittinger,pitcavage,pischke,piontek,pintar,pinnow,pinneo,pinley,pingel,pinello,pimenta,pillard,piker,pietras,piere,phillps,pfleger,pfahl,pezzuti,petruccelli,petrello,peteet,pescatore,peruzzi,perusse,perotta,perona,perini,perelman,perciful,peppin,pennix,pennino,penalosa,pemble,pelz,peltzer,pelphrey,pelote,pellum,pellecchia,pelikan,peitz,pebworth,peary,pawlicki,pavelich,paster,pasquarella,paskey,paseur,paschel,parslow,parrow,parlow,parlett,parler,pargo,parco,paprocki,panepinto,panebianco,pandy,pandey,pamphile,pamintuan,pamer,paluso,paleo,paker,pagett,paczkowski,ozburn,ovington,overmeyer,ouellet,osterlund,oslin,oseguera,osaki,orrock,ormsbee,orlikowski,organista,oregan,orebaugh,orabuena,openshaw,ontiveroz,ondo,omohundro,ollom,ollivierre,olivencia,oley,olazabal,okino,offenberger,oestmann,ocker,obar,oakeson,nuzum,nurre,nowinski,novosel,norquist,nordlie,noorani,nonnemacher,nolder,njoku,niznik,niwa,niss,ninneman,nimtz,niemczyk,nieder,nicolo,nichlos,niblack,newtown,newill,newcom,neverson,neuhart,neuenschwande,nestler,nenno,nejman,neiffer,neidlinger,neglia,nazarian,navor,nary,narayan,nangle,nakama,naish,naik,nadolski,muscato,murphrey,murdick,murchie,muratalla,munnis,mundwiller,muncey,munce,mullenbach,mulhearn,mulcahey,muhammed,muchow,mountford,moudry,mosko,morvay,morrical,morr,moros,mormann,morgen,moredock,morden,mordarski,moravek,morandi,mooradian,montejo,montegut,montan,monsanto,monford,moncus,molinas,molek,mohd,moehrle,moehring,modzeleski,modafferi,moala,moake,miyahira,mitani,mischel,minges,minella,mimes,milles,milbrett,milanes,mikolajczyk,mikami,meucci,metler,methven,metge,messmore,messerschmidt,mesrobian,meservey,merseal,menor,menon,menear,melott,melley,melfi,meinhart,megivern,megeath,meester,meeler,meegan,medoff,medler,meckley,meath,mearns,mcquigg,mcpadden,mclure,mckellips,mckeithen,mcglathery,mcginnes,mcghan,mcdonel,mccullom,mccraken,mccrackin,mcconathy,mccloe,mcclaughry,mcclaflin,mccarren,mccaig,mcaulay,mcaffee,mazzuca,maytubby,mayner,maymi,mattiello,matthis,matthees,matthai,mathiason,mastrogiovann,masteller,mashack,marucci,martorana,martiniz,marter,martellaro,marsteller,marris,marrara,maroni,marolda,marocco,maritn,maresh,maready,marchione,marbut,maranan,maragno,mapps,manrriquez,mannis,manni,mangina,manganelli,mancera,mamon,maloch,mallozzi,maller,majchrzak,majano,mainella,mahanna,maertens,madon,macumber,macioce,machuga,machlin,machala,mabra,lybbert,luvert,lutts,luttrull,lupez,lukehart,ludewig,luchsinger,lovecchio,louissaint,loughney,lostroh,lorton,lopeman,loparo,londo,lombera,lokietek,loiko,lohrenz,lohan,lofties,locklar,lockaby,lobianco,llano,livesey,litster,liske,linsky,linne,lindbeck,licudine,leyua,levie,leonelli,lenzo,lenze,lents,leitao,leidecker,leibold,lehne,legan,lefave,leehy,ledue,lecount,lecea,leadley,lazzara,lazcano,lazalde,lavi,lavancha,lavan,latu,latty,lato,larranaga,lapidus,lapenta,langridge,langeveld,langel,landowski,landgren,landfried,lamattina,lallier,lairmore,lahaie,lagazo,lagan,lafoe,lafluer,laflame,lafevers,lada,lacoss,lachney,labreck,labreche,labay,kwasnik,kuzyk,kutzner,kushnir,kusek,kurtzman,kurian,kulhanek,kuklinski,kueny,kuczynski,kubitz,kruschke,krous,krompel,kritz,krimple,kriese,krenzer,kreis,kratzke,krane,krage,kraebel,kozub,kozma,kouri,koudelka,kotcher,kotas,kostic,kosh,kosar,kopko,kopka,kooy,konigsberg,konarski,kolmer,kohlmeyer,kobbe,knoop,knoedler,knocke,knipple,knippenberg,knickrehm,kneisel,kluss,klossner,klipfel,klawiter,klasen,kittles,kissack,kirtland,kirschenmann,kirckof,kiphart,kinstler,kinion,kilton,killman,kiehl,kief,kett,kesling,keske,kerstein,kepple,keneipp,kempson,kempel,kehm,kehler,keeran,keedy,kebert,keast,kearbey,kawaguchi,kaupu,kauble,katzenbach,katcher,kartes,karpowicz,karpf,karban,kanzler,kanarek,kamper,kaman,kalsow,kalafut,kaeser,kaercher,kaeo,kaeding,jurewicz,julson,jozwick,jollie,johnigan,johll,jochum,jewkes,jestes,jeska,jereb,jaurez,jarecki,jansma,janosik,jandris,jamin,jahr,jacot,ivens,itson,isenhower,iovino,ionescu,ingrum,ingels,imrie,imlay,ihlenfeld,ihde,igou,ibach,huyett,huppe,hultberg,hullihen,hugi,hueso,huesman,hsiao,hronek,hovde,housewright,houlahan,hougham,houchen,hostler,hoster,hosang,hornik,hornes,horio,honyumptewa,honeyman,honer,hommerding,holsworth,hollobaugh,hollinshead,hollands,hollan,holecek,holdorf,hokes,hogston,hoesly,hodkinson,hodgman,hodgens,hochstedler,hochhauser,hobbie,hoare,hnat,hiskey,hirschy,hinostroza,hink,hing,hillmer,hillian,hillerman,hietala,hierro,hickling,hickingbottom,heye,heubusch,hesselschward,herriot,hernon,hermida,hermans,hentschel,henningson,henneke,henk,heninger,heltsley,helmle,helminiak,helmes,hellner,hellmuth,helke,heitmeyer,heird,heinle,heinicke,heinandez,heimsoth,heibel,hegyi,heggan,hefel,heeralall,hedrington,heacox,hazlegrove,hazelett,haymore,havenhill,hautala,hascall,harvie,hartrick,hartling,harrer,harles,hargenrader,hanshew,hanly,hankla,hanisch,hancox,hammann,hambelton,halseth,hallisey,halleck,hallas,haisley,hairr,hainey,hainer,hailstock,haertel,guzek,guyett,guster,gussler,gurwitz,gurka,gunsolus,guinane,guiden,gugliotti,guevin,guevarra,guerard,gudaitis,guadeloupe,gschwind,grupe,grumbach,gruenes,gruenberg,grom,grodski,groden,grizzel,gritten,griswald,grishaber,grinage,grimwood,grims,griffon,griffies,gribben,gressley,gren,greenstreet,grealish,gravett,grantz,granfield,granade,gowell,gossom,gorsky,goring,goodnow,goodfriend,goodemote,golob,gollnick,golladay,goldwyn,goldsboro,golds,goldrick,gohring,gohn,goettsch,goertzen,goelz,godinho,goans,glumac,gleisner,gleen,glassner,glanzer,gladue,gjelaj,givhan,girty,girone,girgenti,giorgianni,gilpatric,gillihan,gillet,gilbar,gierut,gierhart,gibert,gianotti,giannetto,giambanco,gharing,geurts,gettis,gettel,gest,germani,gerdis,gerbitz,geppert,gennings,gemmer,gelvin,gellert,gehler,geddings,gearon,geach,gazaille,gayheart,gauld,gaukel,gaudio,gathing,gasque,garstka,garsee,garringer,garofano,garo,garnsey,garigen,garcias,garbe,ganoung,ganfield,ganaway,gamero,galuska,galster,gallacher,galinski,galimi,galik,galeazzi,galdo,galdames,galas,galanis,gaglio,gaeddert,gadapee,fussner,furukawa,fuhs,fuerte,fuerstenberg,fryrear,froese,fringer,frieson,friesenhahn,frieler,friede,freymuth,freyman,freudenberg,freman,fredricksen,frech,frasch,frantum,frankin,franca,frago,fragnoli,fouquet,fossen,foskett,forner,formosa,formisano,fooks,fons,folino,flott,flesch,flener,flemmons,flanagin,flamino,flamand,fitzerald,findling,filsinger,fillyaw,fillinger,fiechter,ferre,ferdon,feldkamp,fazzio,favia,faulconer,faughnan,faubel,fassler,faso,farrey,farrare,farnworth,farland,fairrow,faille,faherty,fagnant,fabula,fabbri,eylicio,esteve,estala,espericueta,escajeda,equia,enrriquez,enomoto,enmon,engemann,emmerson,emmel,emler,elstad,ellwein,ellerson,eliott,eliassen,elchert,eisenbeis,eisel,eikenberry,eichholz,ehmer,edgerson,echenique,eberley,eans,dziuk,dykhouse,dworak,dutt,dupas,duntz,dunshee,dunovant,dunnaway,dummermuth,duerson,ducotey,duchon,duchesneau,ducci,dubord,duberry,dubach,drummonds,droege,drish,drexel,dresch,dresbach,drenner,drechsler,dowen,dotter,dosreis,doser,dorward,dorin,dorf,domeier,doler,doleman,dolbow,dolbin,dobrunz,dobransky,dobberstein,dlouhy,diosdado,dingmann,dimmer,dimarino,dimaria,dillenburg,dilaura,dieken,dickhaus,dibbles,dibben,diamante,dewilde,dewaard,devich,devenney,devaux,dettinger,desroberts,dershem,dersch,derita,derickson,depina,deorio,deoliveira,denzler,dentremont,denoble,demshar,demond,demint,demichele,demel,delzer,delval,delorbe,delli,delbridge,delanoy,delancy,delahoya,dekle,deitrick,deis,dehnert,degrate,defrance,deetz,deeg,decoster,decena,dearment,daughety,datt,darrough,danzer,danielovich,dandurand,dancause,dalo,dalgleish,daisley,dadlani,daddona,daddio,dacpano,cyprian,cutillo,curz,curvin,cuna,cumber,cullom,cudworth,cubas,crysler,cryderman,crummey,crumbly,crookshanks,croes,criscione,crespi,cresci,creaser,craton,cowin,cowdrey,coutcher,cotterman,cosselman,cosgriff,cortner,corsini,corporan,corniel,cornick,cordts,copening,connick,conlisk,conelli,comito,colten,colletta,coldivar,colclasure,colantuono,colaizzi,coggeshall,cockman,cockfield,cobourn,cobo,cobarrubias,clyatt,cloney,clonch,climes,cleckner,clearo,claybourne,clavin,claridge,claffey,ciufo,cisnero,cipollone,cieslik,ciejka,cichocki,cicchetti,cianflone,chrusciel,christesen,chmielowiec,chirino,chillis,chhoun,chevas,chehab,chaviano,chavaria,chasten,charbonnet,chanley,champoux,champa,chalifoux,cerio,cedotal,cech,cavett,cavendish,catoire,castronovo,castellucci,castellow,castaner,casso,cassels,cassatt,cassar,cashon,cartright,carros,carrisalez,carrig,carrejo,carnicelli,carnett,carlise,carhart,cardova,cardell,carchi,caram,caquias,capper,capizzi,capano,cannedy,campese,calvello,callon,callins,callies,callicutt,calix,calin,califf,calderaro,caldeira,cadriel,cadmus,cadman,caccamise,buttermore,butay,bustamente,busa,burmester,burkard,burhans,burgert,bure,burdin,bullman,bulin,buelna,buehner,budin,buco,buckhanon,bryars,brutger,brus,brumitt,brum,bruer,brucato,broyhill,broy,brownrigg,brossart,brookings,broden,brocklehurst,brockert,bristo,briskey,bringle,bries,bressman,branyan,brands,bramson,brammell,brallier,bozich,boysel,bowthorpe,bowron,bowin,boutilier,boulos,boullion,boughter,bottiglieri,borruso,borreggine,borns,borkoski,borghese,borenstein,boran,booton,bonvillain,bonini,bonello,bolls,boitnott,boike,bohnet,bohnenkamp,bohmer,boeson,boeneke,bodey,bocchino,bobrowski,bobic,bluestein,bloomingdale,blogg,blewitt,blenman,bleck,blaszak,blankenbeckle,blando,blanchfield,blancato,blalack,blakenship,blackett,bisping,birkner,birckhead,bingle,bineau,billiel,bigness,bies,bierer,bhalla,beyerlein,betesh,besler,berzins,bertalan,berntsen,bergo,berganza,bennis,benney,benkert,benjamen,benincasa,bengochia,bendle,bendana,benchoff,benbrook,belsito,belshaw,belinsky,belak,beigert,beidleman,behen,befus,beel,bedonie,beckstrand,beckerle,beato,bauguess,baughan,bauerle,battis,batis,bastone,bassetti,bashor,bary,bartunek,bartoletti,barro,barno,barnicle,barlage,barkus,barkdull,barcellos,barbarino,baranski,baranick,bankert,banchero,bambrick,bamberg,bambenek,balthrop,balmaceda,ballman,balistrieri,balcomb,balboni,balbi,bagner,bagent,badasci,bacot,bache,babione,babic,babers,babbs,avitabile,avers,avena,avance,ausley,auker,audas,aubut,athearn,atcheson,astorino,asplund,aslanian,askari,ashmead,asby,asai,arterbury,artalejo,arqueta,arquero,arostegui,arnell,armeli,arista,arender,arca,arballo,aprea,applen,applegarth,apfel,antonello,antolin,antkowiak,angis,angione,angerman,angelilli,andujo,andrick,anderberg,amigon,amalfitano,alviso,alvez,altice,altes,almarez,allton,allston,allgeyer,allegretti,aliaga,algood,alberg,albarez,albaladejo,akre,aitkin,ahles,ahlberg,agnello,adinolfi,adamis,abramek,abolt,abitong,zurawski,zufall,zubke,zizzo,zipperer,zinner,zinda,ziller,zill,zevallos,zesati,zenzen,zentner,zellmann,zelinsky,zboral,zarcone,zapalac,zaldana,zakes,zaker,zahniser,zacherl,zabawa,zabaneh,youree,younis,yorty,yonce,yero,yerkey,yeck,yeargan,yauch,yashinski,yambo,wrinn,wrightsman,worton,wortley,worland,woolworth,woolfrey,woodhead,woltjer,wolfenden,wolden,wolchesky,wojick,woessner,witters,witchard,wissler,wisnieski,wisinski,winnike,winkowski,winkels,wingenter,wineman,winegardner,wilridge,wilmont,willians,williamsen,wilhide,wilhelmsen,wilhelmi,wildrick,wilden,wiland,wiker,wigglesworth,wiebusch,widdowson,wiant,wiacek,whittet,whitelock,whiteis,whiley,westrope,westpfahl,westin,wessman,wessinger,wesemann,wesby,wertheimer,weppler,wenke,wengler,wender,welp,weitzner,weissberg,weisenborn,weipert,weiman,weidmann,wehrsig,wehrenberg,weemes,weeman,wayner,waston,wasicek,wascom,wasco,warmath,warbritton,waltner,wallenstein,waldoch,waldal,wala,waide,wadlinger,wadhams,vullo,voorheis,vonbargen,volner,vollstedt,vollman,vold,voge,vittorio,violett,viney,vinciguerra,vinal,villata,villarrvel,vilanova,vigneault,vielma,veyna,vessella,versteegh,verderber,venier,venditti,velotta,vejarano,vecchia,vecchi,vastine,vasguez,varella,vanry,vannah,vanhyning,vanhuss,vanhoff,vanhoesen,vandivort,vandevender,vanderlip,vanderkooi,vandebrink,vancott,vallien,vallas,vallandingham,valiquette,valasek,vahey,vagott,uyematsu,urbani,uran,umbach,tyon,tyma,twyford,twombley,twohig,tutterrow,turnes,turkington,turchi,tunks,tumey,tumbaga,tuinstra,tsukamoto,tschetter,trussel,trubey,trovillion,troth,trostel,tron,trinka,trine,triarsi,treto,trautz,tragesser,tooman,toolson,tonozzi,tomkiewicz,tomasso,tolin,tolfree,toelle,tisor,tiry,tinstman,timmermann,tickner,tiburcio,thunberg,thronton,thompsom,theil,thayne,thaggard,teschner,tensley,tenery,tellman,tellado,telep,teigen,teator,teall,tayag,tavis,tattersall,tassoni,tarshis,tappin,tappe,tansley,talone,talford,tainter,taha,taguchi,tacheny,tabak,szymczyk,szwaja,szopinski,syvertsen,swogger,switcher,swist,swierczek,swiech,swickard,swiatek,swezey,swepson,sweezy,swaringen,swanagan,swailes,swade,sveum,svenningsen,svec,suttie,supry,sunga,summerhill,summars,sulit,stys,stutesman,stupak,stumpo,stuller,stuekerjuerge,stuckett,stuckel,stuchlik,stuard,strutton,strop,stromski,stroebel,strehlow,strause,strano,straney,stoyle,stormo,stopyra,stoots,stonis,stoltenburg,stoiber,stoessel,stitzer,stien,stichter,stezzi,stewert,stepler,steinkraus,stegemann,steeples,steenburg,steeley,staszak,stasko,starkson,stanwick,stanke,stanifer,stangel,stai,squiers,spraglin,spragins,spraberry,spoelstra,spisak,spirko,spille,spidel,speyer,speroni,spenst,spartz,sparlin,sparacio,spaman,spainhower,souers,souchet,sosbee,sorn,sorice,sorbo,soqui,solon,soehl,sodergren,sobie,smucker,smsith,smoley,smolensky,smolenski,smolder,smethers,slusar,slowey,slonski,slemmons,slatkin,slates,slaney,slagter,slacum,skutnik,skrzypek,skibbe,sjostrom,sjoquist,sivret,sitko,sisca,sinnett,sineath,simoni,simar,simao,silvestro,silleman,silha,silfies,silberhorn,silacci,sigrist,sieczkowski,sieczka,shure,shulz,shugrue,shrode,shovlin,shortell,shonka,shiyou,shiraishi,shiplett,sheu,shermer,sherick,sheeks,shantz,shakir,shaheed,shadoan,shadid,shackford,shabot,seung,seufert,setty,setters,servis,serres,serrell,serpas,sensenig,senft,semenec,semas,semaan,selvera,sellmeyer,segar,seever,seeney,seeliger,seehafer,seebach,sebben,seaward,seary,searl,searby,scordino,scolieri,scolaro,schwiebert,schwartze,schwaner,schuur,schupbach,schumacker,schum,schudel,schubbe,schroader,schramel,schollmeyer,schoenherr,schoeffler,schoeder,schnurr,schnorr,schneeman,schnake,schnaible,schmaus,schlotter,schinke,schimming,schimek,schikora,scheulen,scherping,schermer,scherb,schember,schellhase,schedler,schanck,schaffhauser,schaffert,schadler,scarola,scarfo,scarff,scantling,scaff,sayward,sayas,saxbury,savel,savastano,sault,satre,sarkar,santellan,sandmeier,sampica,salvesen,saltis,salloum,salling,salce,salatino,salata,salamy,sadowsky,sadlier,sabbatini,sabatelli,sabal,sabados,rydzewski,rybka,rybczyk,rusconi,rupright,rufino,ruffalo,rudiger,rudig,ruda,rubyor,royea,roxberry,rouzer,roumeliotis,rossmann,rosko,rosene,rosenbluth,roseland,rosasco,rosano,rosal,rorabaugh,romie,romaro,rolstad,rollow,rohrich,roghair,rogala,roets,roen,roemmich,roelfs,roeker,roedl,roedel,rodeheaver,roddenberry,rockstad,rocchi,robirds,robben,robasciotti,robaina,rizzotto,rizzio,ritcher,rissman,riseden,ripa,rion,rintharamy,rinehimer,rinck,riling,rietschlin,riesenberg,riemenschneid,rieland,rickenbaugh,rickenbach,rhody,revells,reutter,respress,resnik,remmel,reitmeyer,reitan,reister,reinstein,reino,reinkemeyer,reifschneider,reierson,reichle,rehmeier,rehl,reeds,rede,recar,rebeiro,raybourn,rawl,rautio,raugust,raudenbush,raudales,rattan,rapuano,rapoport,rantanen,ransbottom,raner,ramkissoon,rambousek,raio,rainford,radakovich,rabenhorst,quivers,quispe,quinoes,quilici,quattrone,quates,quance,quale,purswell,purpora,pulera,pulcher,puckhaber,pryer,pruyne,pruit,prudencio,prows,protzman,prothero,prosperi,prospal,privott,pritchet,priem,prest,prell,preer,pree,preddy,preda,pravata,pradhan,potocki,postier,postema,posadas,poremba,popichak,ponti,pomrenke,pomarico,pollok,polkinghorn,polino,pock,plater,plagman,pipher,pinzone,pinkleton,pillette,pillers,pilapil,pignone,pignatelli,piersol,piepho,picton,pickrel,pichard,picchi,piatek,pharo,phanthanouvon,pettingill,pettinato,petrovits,pethtel,petersheim,pershing,perrez,perra,pergram,peretz,perego,perches,pennello,pennella,pendry,penaz,pellish,pecanty,peare,paysour,pavlovich,pavick,pavelko,paustian,patzer,patete,patadia,paszkiewicz,pase,pasculli,pascascio,parrotte,parajon,paparo,papandrea,paone,pantaleon,panning,paniccia,panarello,palmeter,pallan,palardy,pahmeier,padget,padel,oxborrow,oveson,outwater,ottaway,otake,ostermeyer,osmer,osinski,osiecki,oroak,orndoff,orms,orkin,ordiway,opatz,onsurez,onishi,oliger,okubo,okoye,ohlmann,offord,offner,offerdahl,oesterle,oesch,odonnel,odeh,odebralski,obie,obermeier,oberhausen,obenshain,obenchain,nute,nulty,norrington,norlin,nore,nordling,nordhoff,norder,nordan,norals,nogales,noboa,nitsche,niermann,nienhaus,niedringhaus,niedbalski,nicolella,nicolais,nickleberry,nicewander,newfield,neurohr,neumeier,netterville,nersesian,nern,nerio,nerby,nerbonne,neitz,neidecker,neason,nead,navratil,naves,nastase,nasir,nasca,narine,narimatsu,nard,narayanan,nappo,namm,nalbone,nakonechny,nabarro,myott,muthler,muscatello,murriel,murin,muoio,mundel,munafo,mukherjee,muffoletto,muessig,muckey,mucher,mruk,moyd,mowell,mowatt,moutray,motzer,moster,morgenroth,morga,morataya,montross,montezuma,monterroza,montemarano,montello,montbriand,montavon,montaque,monigold,monforte,molgard,moleski,mohsin,mohead,mofield,moerbe,moeder,mochizuki,miyazaki,miyasaki,mital,miskin,mischler,minniear,minero,milosevic,mildenhall,mielsch,midden,michonski,michniak,michitsch,michelotti,micheli,michelfelder,michand,metelus,merkt,merando,meranda,mentz,meneley,menaker,melino,mehaffy,meehl,meech,meczywor,mcweeney,mcumber,mcredmond,mcneer,mcnay,mcmikle,mcmaken,mclaurine,mclauglin,mclaney,mckune,mckinnies,mckague,mchattie,mcgrapth,mcglothen,mcgath,mcfolley,mcdannell,mccurty,mccort,mcclymonds,mcclimon,mcclamy,mccaughan,mccartan,mccan,mccadden,mcburnie,mcburnett,mcbryar,mcannally,mcalevy,mcaleese,maytorena,mayrant,mayland,mayeaux,mauter,matthewson,mathiew,matern,matera,maslow,mashore,masaki,maruco,martorell,martenez,marrujo,marrison,maroun,markway,markos,markoff,markman,marello,marbry,marban,maphis,manuele,mansel,manganello,mandrell,mandoza,manard,manago,maltba,mallick,mallak,maline,malikowski,majure,majcher,maise,mahl,maffit,maffeo,madueno,madlem,madariaga,macvane,mackler,macconnell,macchi,maccarone,lyng,lynchard,lunning,luneau,lunden,lumbra,lumbert,lueth,ludington,luckado,lucchini,lucatero,luallen,lozeau,lowen,lovera,lovelock,louck,lothian,lorio,lorimer,lorge,loretto,longhenry,lonas,loiseau,lohrman,logel,lockie,llerena,livington,liuzzi,liscomb,lippeatt,liou,linhardt,lindelof,lindbo,limehouse,limage,lillo,lilburn,liggons,lidster,liddick,lich,liberato,leysath,lewelling,lesney,leser,lescano,leonette,lentsch,lenius,lemmo,lemming,lemcke,leggette,legerski,legard,leever,leete,ledin,lecomte,lecocq,leakes,leab,lazarz,layous,lawrey,lawery,lauze,lautz,laughinghouse,latulippe,lattus,lattanzio,lascano,larmer,laris,larcher,laprise,lapin,lapage,lano,langseth,langman,langland,landstrom,landsberg,landsaw,landram,lamphier,lamendola,lamberty,lakhani,lajara,lagrow,lagman,ladewig,laderman,ladden,lacrue,laclaire,lachut,lachner,kwit,kvamme,kvam,kutscher,kushi,kurgan,kunsch,kundert,kulju,kukene,kudo,kubin,kubes,kuberski,krystofiak,kruppa,krul,krukowski,kruegel,kronemeyer,krock,kriston,kretzer,krenn,kralik,krafft,krabill,kozisek,koverman,kovatch,kovarik,kotlowski,kosmala,kosky,kosir,kosa,korpi,kornbluth,koppen,kooistra,kohlhepp,kofahl,koeneman,koebel,koczur,kobrin,kobashigawa,koba,knuteson,knoff,knoble,knipper,knierim,kneisley,klusman,kloc,klitzing,klinko,klinefelter,klemetson,kleinpeter,klauser,klatte,klaren,klare,kissam,kirkhart,kirchmeier,kinzinger,kindt,kincy,kincey,kimoto,killingworth,kilcullen,kilbury,kietzman,kienle,kiedrowski,kidane,khamo,khalili,ketterling,ketchem,kessenich,kessell,kepp,kenon,kenning,kennady,kendzior,kemppainen,kellermann,keirns,keilen,keiffer,kehew,keelan,keawe,keator,kealy,keady,kathman,kastler,kastanes,kassab,karpin,karau,karathanasis,kaps,kaplun,kapaun,kannenberg,kanipe,kander,kandel,kanas,kanan,kamke,kaltenbach,kallenberger,kallam,kafton,kafer,kabler,kaaihue,jundt,jovanovich,jojola,johnstad,jodon,joachin,jinright,jessick,jeronimo,jenne,jelsma,jeannotte,jeangilles,jaworsky,jaubert,jarry,jarrette,jarreau,jarett,janos,janecka,janczak,jalomo,jagoda,jagla,jacquier,jaber,iwata,ivanoff,isola,iserman,isais,isaacks,inverso,infinger,ibsen,hyser,hylan,hybarger,hwee,hutchenson,hutchcroft,husar,hurlebaus,hunsley,humberson,hulst,hulon,huhtala,hugill,hugghins,huffmaster,huckeba,hrabovsky,howden,hoverson,houts,houskeeper,housh,hosten,horras,horchler,hopke,hooke,honie,holtsoi,holsomback,holoway,holmstead,hoistion,hohnstein,hoheisel,hoguet,hoggle,hogenson,hoffstetter,hoffler,hofe,hoefling,hoague,hizer,hirschfield,hironaka,hiraldo,hinote,hingston,hinaman,hillie,hillesheim,hilderman,hiestand,heyser,heys,hews,hertler,herrandez,heppe,henle,henkensiefken,henigan,henandez,henagan,hemberger,heman,helser,helmich,hellinger,helfrick,heldenbrand,heinonen,heineck,heikes,heidkamp,heglar,heffren,heelan,hedgebeth,heckmann,heckaman,hechmer,hazelhurst,hawken,haverkamp,havatone,hausauer,hasch,harwick,hartse,harrower,harle,hargroder,hardway,hardinger,hardemon,harbeck,hant,hamre,hamberg,hallback,haisten,hailstone,hahl,hagner,hagman,hagemeyer,haeussler,hackwell,haby,haataja,gverrero,gustovich,gustave,guske,gushee,gurski,gurnett,gura,gunto,gunselman,gugler,gudmundson,gudinas,guarneri,grumbine,gruis,grotz,grosskopf,grosman,grosbier,grinter,grilley,grieger,grewal,gressler,greaser,graus,grasman,graser,grannan,granath,gramer,graboski,goyne,gowler,gottwald,gottesman,goshay,gorr,gorovitz,gores,goossens,goodier,goodhue,gonzeles,gonzalos,gonnella,golomb,golick,golembiewski,goeke,godzik,goar,glosser,glendenning,glendening,glatter,glas,gittings,gitter,gisin,giscombe,gimlin,gillitzer,gillick,gilliand,gilb,gigler,gidden,gibeau,gibble,gianunzio,giannattasio,gertelman,gerosa,gerold,gerland,gerig,gerecke,gerbino,genz,genovesi,genet,gelrud,geitgey,geiszler,gehrlein,gawrys,gavilanes,gaulden,garthwaite,garmoe,gargis,gara,gannett,galligher,galler,galleher,gallahan,galford,gahn,gacek,gabert,fuster,furuya,furse,fujihara,fuhriman,frueh,fromme,froemming,friskney,frietas,freiler,freelove,freber,frear,frankl,frankenfield,franey,francke,foxworthy,formella,foringer,forgue,fonnesbeck,fonceca,folland,fodera,fode,floresca,fleurent,fleshner,flentge,fleischhacker,fleeger,flecher,flam,flaim,fivecoat,firebaugh,fioretti,finucane,filley,figuroa,figuerda,fiddelke,feurtado,fetterly,fessel,femia,feild,fehling,fegett,fedde,fechter,fawver,faulhaber,fatchett,fassnacht,fashaw,fasel,farrugia,farran,farness,farhart,fama,falwell,falvo,falkenstein,falin,failor,faigin,fagundo,fague,fagnan,fagerstrom,faden,eytchison,eyles,everage,evangelist,estrin,estorga,esponda,espindola,escher,esche,escarsega,escandon,erven,erding,eplin,enix,englade,engdahl,enck,emmette,embery,emberson,eltzroth,elsayed,ellerby,ellens,elhard,elfers,elazegui,eisermann,eilertson,eiben,ehrhard,ehresman,egolf,egnew,eggins,efron,effland,edminster,edgeston,eckstrom,eckhard,eckford,echoles,ebsen,eatherly,eastlick,earnheart,dykhuizen,dyas,duttweiler,dutka,dusenbury,dusenbery,durre,durnil,durnell,durie,durhan,durando,dupriest,dunsmoor,dunseith,dunnum,dunman,dunlevy,duma,dulude,dulong,duignan,dugar,dufek,ducos,duchaine,duch,dubow,drowne,dross,drollinger,droke,driggars,drawhorn,drach,drabek,doyne,doukas,dorvil,dorow,doroski,dornak,dormer,donnelson,donivan,dondero,dompe,dolle,doakes,diza,divirgilio,ditore,distel,disimone,disbro,dipiero,dingson,diluzio,dillehay,digiorgio,diflorio,dietzler,dietsch,dieterle,dierolf,dierker,dicostanzo,dicesare,dexheimer,dewitte,dewing,devoti,devincentis,devary,deutschman,dettloff,detienne,destasio,dest,despard,desmet,deslatte,desfosses,derise,derenzo,deppner,depolo,denoyer,denoon,denno,denne,deniston,denike,denes,demoya,demick,demicco,demetriou,demange,delva,delorge,delley,delisio,delhoyo,delgrande,delgatto,delcour,delair,deinert,degruy,degrave,degeyter,defino,deffenbaugh,deener,decook,decant,deboe,deblanc,deatley,dearmitt,deale,deaguiar,dayan,daus,dauberman,datz,dase,dary,dartt,darocha,dari,danowski,dancel,dami,dallmann,dalere,dalba,dakan,daise,dailing,dahan,dagnan,daggs,dagan,czarkowski,czaplinski,cutten,curtice,curenton,curboy,cura,culliton,culberth,cucchiara,cubbison,csaszar,crytser,crotzer,crossgrove,crosser,croshaw,crocco,critzer,creveling,cressy,creps,creese,cratic,craigo,craigen,craib,cracchiolo,crable,coykendall,cowick,coville,couzens,coutch,cousens,cousain,counselman,coult,cotterell,cott,cotham,corsaut,corriere,corredor,cornet,corkum,coreas,cordoza,corbet,corathers,conwill,contreas,consuegra,constanza,conolly,conedy,comins,combee,colosi,colom,colmenares,collymore,colleran,colina,colaw,colatruglio,colantro,colantonio,cohea,cogill,codner,codding,cockram,cocanougher,cobine,cluckey,clucas,cloward,cloke,clisham,clinebell,cliffe,clendenen,cisowski,cirelli,ciraolo,ciocca,cintora,ciesco,cibrian,chupka,chugg,christmann,choma,chiverton,chirinos,chinen,chimenti,chima,cheuvront,chesla,chesher,chesebro,chern,chehebar,cheatum,chastine,chapnick,chapelle,chambley,cercy,celius,celano,cayea,cavicchi,cattell,catanach,catacutan,castelluccio,castellani,cassmeyer,cassetta,cassada,caspi,cashmore,casebier,casanas,carrothers,carrizal,carriveau,carretero,carradine,carosella,carnine,carloni,carkhuff,cardosi,cardo,carchidi,caravello,caranza,carandang,cantrall,canpos,canoy,cannizzaro,canion,canida,canham,cangemi,cange,cancelliere,canard,camarda,calverley,calogero,callendar,calame,cadrette,cachero,caccavale,cabreros,cabrero,cabrara,cabler,butzer,butte,butrick,butala,bustios,busser,busic,bushorn,busher,burmaster,burkland,burkins,burkert,burgueno,burgraff,burel,burck,burby,bumford,bulock,bujnowski,buggie,budine,bucciero,bubier,brzoska,brydges,brumlow,brosseau,brooksher,brokke,broeker,brittin,bristle,briano,briand,brettschneide,bresnan,brentson,brenneis,brender,brazle,brassil,brasington,branstrom,branon,branker,brandwein,brandau,bralley,brailey,brague,brade,bozzi,bownds,bowmer,bournes,bour,bouchey,botto,boteler,borroel,borra,boroski,boothroyd,boord,bonga,bonato,bonadonna,bolejack,boldman,boiser,boggio,bogacki,boerboom,boehnlein,boehle,bodah,bobst,boak,bluemel,blockmon,blitch,blincoe,bleier,blaydes,blasius,bittel,binsfeld,bindel,bilotti,billiott,bilbrew,bihm,biersner,bielat,bidrowski,bickler,biasi,bhola,bhat,bewick,betzen,bettridge,betti,betsch,besley,beshero,besa,bertoli,berstein,berrien,berrie,berrell,bermel,berenguer,benzer,bensing,benedix,bemo,belile,beilman,behunin,behrmann,bedient,becht,beaule,beaudreault,bealle,beagley,bayuk,bayot,bayliff,baugess,battistoni,batrum,basinski,basgall,bartolomei,bartnik,bartl,bartko,bartholomay,barthlow,bartgis,barsness,barski,barlette,barickman,bargen,bardon,barcliff,barbu,barakat,baracani,baraban,banos,banko,bambach,balok,balogun,bally,baldini,balck,balcer,balash,baim,bailor,bahm,bahar,bagshaw,baggerly,badie,badal,backues,babino,aydelott,awbrey,aversano,avansino,auyon,aukamp,aujla,augenstein,astacio,asplin,asato,asano,aruizu,artale,arrick,arneecher,armelin,armbrester,armacost,arkell,argrave,areizaga,apolo,anzures,anzualda,antwi,antillon,antenor,annand,anhalt,angove,anglemyer,anglada,angiano,angeloni,andaya,ancrum,anagnos,ammirati,amescua,ambrosius,amacker,amacher,amabile,alvizo,alvernaz,alvara,altobelli,altobell,althauser,alterman,altavilla,alsip,almeyda,almeter,alman,allscheid,allaman,aliotta,aliberti,alghamdi,albiston,alberding,alarie,alano,ailes,ahsan,ahrenstorff,ahler,aerni,ackland,achor,acero,acebo,abshier,abruzzo,abrom,abood,abnet,abend,abegg,abbruzzese,aaberg,zysk,zutell,zumstein,zummo,zuhlke,zuehlsdorff,zuch,zucconi,zortman,zohn,zingone,zingg,zingale,zima,zientek,zieg,zervas,zerger,zenk,zeldin,zeiss,zeiders,zediker,zavodny,zarazua,zappone,zappala,zapanta,zaniboni,zanchi,zampedri,zaller,zakrajsek,zagar,zadrozny,zablocki,zable,yust,yunk,youngkin,yosten,yockers,yochim,yerke,yerena,yanos,wysinger,wyner,wrisley,woznicki,wortz,worsell,wooters,woon,woolcock,woodke,wonnacott,wolnik,wittstock,witting,witry,witfield,witcraft,wissmann,wissink,wisehart,wiscount,wironen,wipf,winterrowd,wingett,windon,windish,windisch,windes,wiltbank,willmarth,wiler,wieseler,wiedmaier,wiederstein,wiedenheft,wieberg,wickware,wickkiser,wickell,whittmore,whitker,whitegoat,whitcraft,whisonant,whisby,whetsell,whedon,westry,westcoat,wernimont,wentling,wendlandt,wencl,weisgarber,weininger,weikle,weigold,weigl,weichbrodt,wehrli,wehe,weege,weare,watland,wassmann,warzecha,warrix,warrell,warnack,waples,wantland,wanger,wandrei,wanat,wampole,waltjen,walterscheid,waligora,walding,waldie,walczyk,wakins,waitman,wair,wainio,wahpekeche,wahlman,wagley,wagenknecht,wadle,waddoups,wadding,vuono,vuillemot,vugteveen,vosmus,vorkink,vories,vondra,voelz,vlashi,vitelli,vitali,viscarra,vinet,vimont,villega,villard,vignola,viereck,videtto,vicoy,vessell,vescovi,verros,vernier,vernaglia,vergin,verdone,verdier,verastequi,vejar,vasile,vasi,varnadore,vardaro,vanzanten,vansumeren,vanschuyver,vanleeuwen,vanhowe,vanhoozer,vaness,vandewalker,vandevoorde,vandeveer,vanderzwaag,vanderweide,vanderhyde,vandellen,vanamburg,vanalst,vallin,valk,valentini,valcarcel,valasco,valadao,vacher,urquijo,unterreiner,unsicker,unser,unrau,undercoffler,uffelman,uemura,ueda,tyszko,tyska,tymon,tyce,tyacke,twinam,tutas,tussing,turmel,turkowski,turkel,turchetta,tupick,tukes,tufte,tufo,tuey,tuell,tuckerman,tsutsumi,tsuchiya,trossbach,trivitt,trippi,trippensee,trimbach,trillo,triller,trible,tribby,trevisan,tresch,tramonte,traff,trad,tousey,totaro,torregrosa,torralba,tolly,tofil,tofani,tobiassen,tiogangco,tino,tinnes,tingstrom,tingen,tindol,tifft,tiffee,tiet,thuesen,thruston,throndson,thornsbury,thornes,thiery,thielman,thie,theilen,thede,thate,thane,thalacker,thaden,teuscher,terracina,terell,terada,tepfer,tenneson,temores,temkin,telleria,teaque,tealer,teachey,tavakoli,tauras,taucher,tartaglino,tarpy,tannery,tani,tams,tamlin,tambe,tallis,talamante,takayama,takaki,taibl,taffe,tadesse,tade,tabeling,tabag,szoke,szoc,szala,szady,sysak,sylver,syler,swonger,swiggett,swensson,sweis,sweers,sweene,sweany,sweaney,swartwout,swamy,swales,susman,surman,sundblad,summerset,summerhays,sumerall,sule,sugimoto,subramanian,sturch,stupp,stunkard,stumpp,struiksma,stropes,stromyer,stromquist,strede,strazza,strauf,storniolo,storjohann,stonum,stonier,stonecypher,stoneberger,stollar,stokke,stokan,stoetzel,stoeckel,stockner,stockinger,stockert,stockdill,stobbe,stitzel,stitely,stirgus,stigers,stettner,stettler,sterlin,sterbenz,stemp,stelluti,steinmeyer,steininger,steinauer,steigerwalt,steider,stavrou,staufenberger,stassi,stankus,stanaway,stammer,stakem,staino,stahlnecker,stagnitta,staelens,staal,srsen,sprott,sprigg,sprenkle,sprenkel,spreitzer,spraque,sprandel,sporn,spivak,spira,spiewak,spieth,spiering,sperow,speh,specking,spease,spead,sparger,spanier,spall,sower,southcott,sosna,soran,sookram,sonders,solak,sohr,sohl,sofranko,soderling,sochor,sobon,smutz,smudrick,smithj,smid,slosser,sliker,slenker,sleger,slaby,skousen,skilling,skibinski,skees,skane,skafidas,sivic,sivertsen,sivers,sitra,sito,siracusa,sinicki,simpers,simley,simbeck,silberberg,siever,siegwarth,sidman,siddle,sibbett,shumard,shubrooks,shough,shorb,shoptaw,sholty,shoffstall,shiverdecker,shininger,shimasaki,shifrin,shiffler,sheston,sherr,shere,shepeard,shelquist,sheler,shauf,sharrar,sharpnack,shamsiddeen,shambley,shallenberger,shadler,shaban,sferra,seys,sexauer,sevey,severo,setlak,seta,sesko,sersen,serratore,serdula,senechal,seldomridge,seilhamer,seifer,seidlitz,sehnert,sedam,sebron,seber,sebek,seavers,scullark,scroger,scovill,sciascia,sciarra,schweers,schwarze,schummer,schultes,schuchardt,schuchard,schrieber,schrenk,schreifels,schowalter,schoultz,scholer,schofill,schoff,schnuerer,schnettler,schmitke,schmiege,schloop,schlinger,schlessman,schlesser,schlageter,schiess,schiefer,schiavoni,scherzer,scherich,schechtman,schebel,scharpman,schaich,schaap,scappaticci,scadlock,savocchia,savini,savers,savageau,sauvage,sause,sauerwein,sary,sarwary,sarnicola,santone,santoli,santalucia,santacruce,sansoucie,sankoff,sanes,sandri,sanderman,sammartano,salmonson,salmela,salmans,sallaz,salis,sakuma,sakowski,sajdak,sahm,sagredo,safrit,sackey,sabio,sabino,rybolt,ruzzo,ruthstrom,ruta,russin,russak,rusko,ruskin,rusiecki,ruscher,rupar,rumberger,rullan,ruliffson,ruhlman,rufenacht,ruelle,rudisell,rudi,rucci,rublee,ruberto,rubeck,rowett,rottinghaus,roton,rothgeb,rothgaber,rothermich,rostek,rossini,roskelley,rosing,rosi,rosewell,rosberg,roon,ronin,romesburg,romelus,rolley,rollerson,rollefson,rolins,rolens,rois,rohrig,rohrbacher,rohland,rohen,rogness,roes,roering,roehrick,roebke,rodregez,rodabaugh,rockingham,roblee,robel,roadcap,rizzolo,riviezzo,rivest,riveron,risto,rissler,rippentrop,ripka,rinn,ringuette,ringering,rindone,rindels,rieffer,riedman,riede,riecke,riebow,riddlebarger,rhome,rhodd,rhatigan,rhame,reyers,rewitzer,revalee,retzer,rettinger,reschke,requa,reper,reopell,renzelman,renne,renker,renk,renicker,rendina,rendel,remund,remmele,remiasz,remaklus,remak,reitsma,reitmeier,reiswig,reishus,reining,reim,reidinger,reick,reiche,regans,reffett,reesor,reekie,redpath,redditt,rechtzigel,recht,rearden,raynoso,raxter,ratkowski,rasulo,rassmussen,rassel,raser,rappleye,rappe,randrup,randleman,ramson,rampey,radziewicz,quirarte,quintyne,quickel,quattrini,quakenbush,quaile,pytel,pushaw,pusch,purslow,punzo,pullam,pugmire,puello,przekop,pruss,pruiett,provow,prophete,procaccini,pritz,prillaman,priess,pretlow,prestia,presha,prescod,preast,praytor,prashad,praino,pozzi,pottenger,potash,porada,popplewell,ponzo,ponter,pommier,polland,polidori,polasky,pola,poisso,poire,pofahl,podolsky,podell,plueger,plowe,plotz,plotnik,ploch,pliska,plessner,plaut,platzer,plake,pizzino,pirog,piquette,pipho,pioche,pintos,pinkert,pinet,pilkerton,pilch,pilarz,pignataro,piermatteo,picozzi,pickler,pickette,pichler,philogene,phare,phang,pfrogner,pfisterer,pettinelli,petruzzi,petrovic,petretti,petermeier,pestone,pesterfield,pessin,pesch,persky,perruzza,perrott,perritt,perretti,perrera,peroutka,peroni,peron,peret,perdew,perazzo,peppe,peno,penberthy,penagos,peles,pelech,peiper,peight,pefferman,peddie,peckenpaugh,pean,payen,pavloski,pavlica,paullin,patteson,passon,passey,passalacqua,pasquini,paskel,partch,parriott,parrella,parraz,parmely,parizo,papelian,papasergi,pantojz,panto,panich,panchal,palys,pallone,palinski,pali,palevic,pagels,paciorek,pacho,pacella,paar,ozbun,overweg,overholser,ovalles,outcalt,otterbein,otta,ostergren,osher,osbon,orzech,orwick,orrico,oropesa,ormes,orillion,onorati,onnen,omary,olding,okonski,okimoto,ohlrich,ohayon,oguin,ogley,oftedahl,offen,ofallon,oeltjen,odam,ockmond,ockimey,obermeyer,oberdorf,obanner,oballe,oard,oakden,nyhan,nydam,numan,noyer,notte,nothstein,notestine,noser,nork,nolde,nishihara,nishi,nikolic,nihart,nietupski,niesen,niehus,nidiffer,nicoulin,nicolaysen,nicklow,nickl,nickeson,nichter,nicholl,ngyun,newsham,newmann,neveux,neuzil,neumayer,netland,nessen,nesheim,nelli,nelke,necochea,nazari,navorro,navarez,navan,natter,natt,nater,nasta,narvaiz,nardelli,napp,nakahara,nairn,nagg,nager,nagano,nafziger,naffziger,nadelson,muzzillo,murri,murrey,murgia,murcia,muno,munier,mulqueen,mulliniks,mulkins,mulik,muhs,muffley,moynahan,mounger,mottley,motil,moseman,moseby,mosakowski,mortell,morrisroe,morrero,mormino,morland,morger,morgenthaler,moren,morelle,morawski,morasca,morang,morand,moog,montney,montera,montee,montane,montagne,mons,monohan,monnett,monkhouse,moncure,momphard,molyneaux,molles,mollenkopf,molette,mohs,mohmand,mohlke,moessner,moers,mockus,moccio,mlinar,mizzelle,mittler,mitri,mitchusson,mitchen,mistrot,mistler,misch,miriello,minkin,mininger,minerich,minehart,minderman,minden,minahan,milonas,millon,millholland,milleson,millerbernd,millage,militante,milionis,milhoan,mildenberger,milbury,mikolajczak,miklos,mikkola,migneault,mifsud,mietus,mieszala,mielnicki,midy,michon,michioka,micheau,michaeli,micali,methe,metallo,messler,mesch,merow,meroney,mergenthaler,meres,menuey,menousek,menning,menn,menghini,mendia,memmer,melot,mellenthin,melland,meland,meixner,meisenheimer,meineke,meinders,mehrens,mehlig,meglio,medsker,medero,mederios,meabon,mcwright,mcright,mcreath,mcrary,mcquirter,mcquerry,mcquary,mcphie,mcnurlen,mcnelley,mcnee,mcnairy,mcmanamy,mcmahen,mckowen,mckiver,mckinlay,mckearin,mcirvin,mcintrye,mchorse,mchaffie,mcgroarty,mcgoff,mcgivern,mceniry,mcelhiney,mcdiarmid,mccullars,mccubbins,mccrimon,mccovery,mccommons,mcclour,mccarrick,mccarey,mccallen,mcbrien,mcarthy,mayone,maybin,maxam,maurais,maughn,matzek,matts,matin,mathre,mathia,mateen,matava,masso,massar,massanet,masingale,mascaro,marthaler,martes,marso,marshman,marsalis,marrano,marolt,marold,markins,margulis,mardirosian,marchiano,marchak,marandola,marana,manues,mante,mansukhani,mansi,mannan,maniccia,mangine,manery,mandigo,mancell,mamo,malstrom,malouf,malenfant,maldenado,malandruccolo,malak,malabanan,makino,maisonave,mainord,maino,mainard,maillard,mahmud,mahdi,mahapatra,mahaley,mahaffy,magouirk,maglaras,magat,maga,maffia,madrazo,madrano,maditz,mackert,mackellar,mackell,macht,macchia,maccarthy,maahs,lytal,luzar,luzader,lutjen,lunger,lunan,luma,lukins,luhmann,luers,ludvigsen,ludlam,ludemann,luchini,lucente,lubrano,lubow,luber,lubeck,lowing,loven,loup,louge,losco,lorts,lormand,lorenzetti,longford,longden,longbrake,lokhmatov,loge,loeven,loeser,locey,locatelli,litka,lista,lisonbee,lisenbee,liscano,liranzo,liquori,liptrot,lionetti,linscomb,linkovich,linington,lingefelt,lindler,lindig,lindall,lincks,linander,linan,limburg,limbrick,limbach,likos,lighthall,liford,lietzke,liebe,liddicoat,lickley,lichter,liapis,lezo,lewan,levitz,levesgue,leverson,levander,leuthauser,letbetter,lesuer,lesmeister,lesly,lerer,leppanen,lepinski,lenherr,lembrick,lelonek,leisten,leiss,leins,leingang,leinberger,leinbach,leikam,leidig,lehtonen,lehnert,lehew,legier,lefchik,lecy,leconte,lecher,lebrecht,leaper,lawter,lawrenz,lavy,laur,lauderbaugh,lauden,laudato,latting,latsko,latini,lassere,lasseigne,laspina,laso,laslie,laskowitz,laske,lasenby,lascola,lariosa,larcade,lapete,laperouse,lanuza,lanting,lantagne,lansdale,lanphier,langmaid,langella,lanese,landrus,lampros,lamens,laizure,laitinen,laigle,lahm,lagueux,lagorio,lagomarsino,lagasca,lagana,lafont,laflen,lafavor,lafarge,laducer,ladnier,ladesma,lacognata,lackland,lacerte,labuff,laborin,labine,labauve,kuzio,kusterer,kussman,kusel,kusch,kurutz,kurdyla,kupka,kunzler,kunsman,kuni,kuney,kunc,kulish,kuliga,kulaga,kuilan,kuhre,kuhnke,kuemmerle,kueker,kudla,kudelka,kubinski,kubicki,kubal,krzyzanowski,krupicka,krumwiede,krumme,kropidlowski,krokos,kroell,kritzer,kribs,kreitlow,kreisher,kraynak,krass,kranzler,kramb,kozyra,kozicki,kovalik,kovalchik,kovacevic,kotula,kotrba,koteles,kosowski,koskela,kosiba,koscinski,kosch,korab,kopple,kopper,koppelman,koppel,konwinski,kolosky,koloski,kolinsky,kolinski,kolbeck,kolasa,koepf,koda,kochevar,kochert,kobs,knust,knueppel,knoy,knieriem,knier,kneller,knappert,klitz,klintworth,klinkenberg,klinck,kleindienst,kleeb,klecker,kjellberg,kitsmiller,kisor,kisiel,kise,kirbo,kinzle,kingsford,kingry,kimpton,kimel,killmon,killick,kilgallon,kilcher,kihn,kiggins,kiecker,kher,khaleel,keziah,kettell,ketchen,keshishian,kersting,kersch,kerins,kercher,kenefick,kemph,kempa,kelsheimer,kelln,kellenberger,kekahuna,keisling,keirnan,keimig,kehn,keal,kaupp,kaufhold,kauffmann,katzenberg,katona,kaszynski,kaszuba,kassebaum,kasa,kartye,kartchner,karstens,karpinsky,karmely,karel,karasek,kapral,kaper,kanelos,kanahele,kampmann,kampe,kalp,kallus,kallevig,kallen,kaliszewski,kaleohano,kalchthaler,kalama,kalahiki,kaili,kahawai,kagey,justiss,jurkowski,jurgensmeyer,juilfs,jopling,jondahl,jomes,joice,johannessen,joeckel,jezewski,jezek,jeswald,jervey,jeppsen,jenniges,jennett,jemmott,jeffs,jaurequi,janisch,janick,jacek,jacaruso,iwanicki,ishihara,isenberger,isbister,iruegas,inzer,inyart,inscore,innocenti,inglish,infantolino,indovina,inaba,imondi,imdieke,imbert,illes,iarocci,iannucci,huver,hutley,husser,husmann,hupf,huntsberger,hunnewell,hullum,huit,huish,hughson,huft,hufstetler,hueser,hudnell,hovden,housen,houghtling,hossack,hoshaw,horsford,horry,hornbacher,hoppenstedt,hopkinson,honza,homann,holzmeister,holycross,holverson,holtzlander,holroyd,holmlund,holderness,holderfield,holck,hojnacki,hohlfeld,hohenberger,hoganson,hogancamp,hoffses,hoerauf,hoell,hoefert,hodum,hoder,hockenbury,hoage,hisserich,hislip,hirons,hippensteel,hippen,hinkston,hindes,hinchcliff,himmel,hillberry,hildring,hiester,hiefnar,hibberd,hibben,heyliger,heyl,heyes,hevia,hettrick,hert,hersha,hernandz,herkel,herber,henscheid,hennesy,henly,henegan,henebry,hench,hemsath,hemm,hemken,hemann,heltzel,hellriegel,hejny,heinl,heinke,heidinger,hegeman,hefferan,hedglin,hebdon,hearnen,heape,heagy,headings,headd,hazelbaker,havlick,hauschildt,haury,hassenfritz,hasenbeck,haseltine,hartstein,hartry,hartnell,harston,harpool,harmen,hardister,hardey,harders,harbolt,harbinson,haraway,haque,hansmann,hanser,hansch,hansberry,hankel,hanigan,haneline,hampe,hamons,hammerstone,hammerle,hamme,hammargren,hamelton,hamberger,hamasaki,halprin,halman,hallihan,haldane,haifley,hages,hagadorn,hadwin,habicht,habermehl,gyles,gutzman,gutekunst,gustason,gusewelle,gurnsey,gurnee,gunterman,gumina,gulliver,gulbrandson,guiterez,guerino,guedry,gucwa,guardarrama,guagliano,guadagno,grulke,groote,groody,groft,groeneweg,grochow,grippe,grimstead,griepentrog,greenfeld,greenaway,grebe,graziosi,graw,gravina,grassie,granzow,grandjean,granby,gramacy,gozalez,goyer,gotch,gosden,gorny,gormont,goodgion,gonya,gonnerman,gompert,golish,goligoski,goldmann,goike,goetze,godeaux,glaza,glassel,glaspy,glander,giumarro,gitelman,gisondi,gismondi,girvan,girten,gironda,giovinco,ginkel,gilster,giesy,gierman,giddins,giardini,gianino,ghea,geurin,gett,getson,gerrero,germond,gentsy,genta,gennette,genito,genis,gendler,geltz,geiss,gehret,gegenheimer,geffert,geeting,gebel,gavette,gavenda,gaumond,gaudioso,gatzke,gatza,gattshall,gaton,gatchel,gasperi,gaska,gasiorowski,garritson,garrigus,garnier,garnick,gardinier,gardenas,garcy,garate,gandolfi,gamm,gamel,gambel,gallmon,gallemore,gallati,gainous,gainforth,gahring,gaffey,gaebler,gadzinski,gadbury,gabri,gaba,fyke,furtaw,furnas,furcron,funn,funck,fulwood,fulvio,fullmore,fukumoto,fuest,fuery,frymire,frush,frohlich,froedge,frodge,fritzinger,fricker,frericks,frein,freid,freggiaro,fratto,franzi,franciscus,fralix,fowble,fotheringham,foslien,foshie,fortmann,forsey,forkner,foppiano,fontanetta,fonohema,fogler,fockler,fluty,flusche,flud,flori,flenory,fleharty,fleeks,flaxman,fiumara,fitzmorris,finnicum,finkley,fineran,fillhart,filipi,fijal,fieldson,ficarra,festerman,ferryman,ferner,fergason,ferell,fennern,femmer,feldmeier,feeser,feenan,federick,fedak,febbo,feazell,fazzone,fauth,fauset,faurote,faulker,faubion,fatzinger,fasick,fanguy,fambrough,falks,fahl,faaita,exler,ewens,estrado,esten,esteen,esquivez,espejo,esmiol,esguerra,esco,ertz,erspamer,ernstes,erisman,erhard,ereaux,ercanbrack,erbes,epple,entsminger,entriken,enslow,ennett,engquist,englebert,englander,engesser,engert,engeman,enge,enerson,emhoff,emge,elting,ellner,ellenberg,ellenbecker,elio,elfert,elawar,ekstrand,eison,eismont,eisenbrandt,eiseman,eischens,ehrgott,egley,egert,eddlemon,eckerson,eckersley,eckberg,echeverry,eberts,earthman,earnhart,eapen,eachus,dykas,dusi,durning,durdan,dunomes,duncombe,dume,dullen,dullea,dulay,duffett,dubs,dubard,drook,drenth,drahos,dragone,downin,downham,dowis,dowhower,doward,dovalina,dopazo,donson,donnan,dominski,dollarhide,dolinar,dolecki,dolbee,doege,dockus,dobkin,dobias,divoll,diviney,ditter,ditman,dissinger,dismang,dirlam,dinneen,dini,dingwall,diloreto,dilmore,dillaman,dikeman,diiorio,dighton,diffley,dieudonne,dietel,dieringer,diercks,dienhart,diekrager,diefendorf,dicke,dicamillo,dibrito,dibona,dezeeuw,dewhurst,devins,deviney,deupree,detherage,despino,desmith,desjarlais,deshner,desha,desanctis,derring,derousse,derobertis,deridder,derego,derden,deprospero,deprofio,depping,deperro,denty,denoncourt,dencklau,demler,demirchyan,demichiel,demesa,demere,demaggio,delung,deluise,delmoral,delmastro,delmas,delligatti,delle,delasbour,delarme,delargy,delagrange,delafontaine,deist,deiss,deighan,dehoff,degrazia,degman,defosses,deforrest,deeks,decoux,decarolis,debuhr,deberg,debarr,debari,dearmon,deare,deardurff,daywalt,dayer,davoren,davignon,daviau,dauteuil,dauterive,daul,darnley,darakjy,dapice,dannunzio,danison,daniello,damario,dalonzo,dallis,daleske,dalenberg,daiz,dains,daines,dagnese,dady,dadey,czyzewski,czapor,czaplewski,czajka,cyganiewicz,cuttino,cutrona,cussins,cusanelli,cuperus,cundy,cumiskey,cumins,cuizon,cuffia,cuffe,cuffari,cuccaro,cubie,cryder,cruson,crounse,cromedy,cring,creer,credeur,crea,cozort,cozine,cowee,cowdery,couser,courtway,courington,cotman,costlow,costell,corton,corsaro,corrieri,corrick,corradini,coron,coren,corbi,corado,copus,coppenger,cooperwood,coontz,coonce,contrera,connealy,conell,comtois,compere,commins,commings,comegys,colyar,colo,collister,collick,collella,coler,colborn,cohran,cogbill,coffen,cocuzzo,clynes,closter,clipp,clingingsmith,clemence,clayman,classon,clas,clarey,clague,ciubal,citrino,citarella,cirone,cipponeri,cindrich,cimo,ciliberto,cichowski,ciccarello,cicala,chura,chubbuck,chronis,christlieb,chizek,chittester,chiquito,chimento,childree,chianese,chevrette,checo,chastang,chargualaf,chapmon,chantry,chahal,chafetz,cezar,ceruantes,cerrillo,cerrano,cerecedes,cerami,cegielski,cavallero,catinella,cassata,caslin,casano,casacchia,caruth,cartrette,carten,carodine,carnrike,carnall,carmicle,carlan,carlacci,caris,cariaga,cardine,cardimino,cardani,carbonara,capua,capponi,cappellano,caporale,canupp,cantrel,cantone,canterberry,cannizzo,cannan,canelo,caneer,candill,candee,campbel,caminero,camble,caluya,callicott,calk,caito,caffie,caden,cadavid,cacy,cachu,cachola,cabreja,cabiles,cabada,caamano,byran,byon,buyck,bussman,bussie,bushner,burston,burnison,burkman,burkhammer,bures,burdeshaw,bumpass,bullinger,bullers,bulgrin,bugay,budak,buczynski,buckendorf,buccieri,bubrig,brynteson,brunz,brunmeier,brunkow,brunetto,brunelli,brumwell,bruggman,brucki,brucculeri,brozovich,browing,brotman,brocker,broadstreet,brix,britson,brinck,brimmage,brierre,bridenstine,brezenski,brezee,brevik,brentlinger,brentley,breidenbach,breckel,brech,brazzle,braughton,brauch,brattin,brattain,branhan,branford,braner,brander,braly,braegelmann,brabec,boyt,boyack,bowren,bovian,boughan,botton,botner,bosques,borzea,borre,boron,bornhorst,borgstrom,borella,bontempo,bonniwell,bonnes,bonillo,bonano,bolek,bohol,bohaty,boffa,boetcher,boesen,boepple,boehler,boedecker,boeckx,bodi,boal,bloodsworth,bloodgood,blome,blockett,blixt,blanchett,blackhurst,blackaby,bjornberg,bitzer,bittenbender,bitler,birchall,binnicker,binggeli,billett,bilberry,biglow,bierly,bielby,biegel,berzas,berte,bertagnolli,berreth,bernhart,bergum,berentson,berdy,bercegeay,bentle,bentivegna,bentham,benscoter,benns,bennick,benjamine,beneze,benett,beneke,bendure,bendix,bendick,benauides,belman,bellus,bellott,bellefleur,bellas,beljan,belgard,beith,beinlich,beierle,behme,beevers,beermann,beeching,bedward,bedrosian,bedner,bedeker,bechel,becera,beaubrun,beardmore,bealmear,bazin,bazer,baumhoer,baumgarner,bauknecht,battson,battiest,basulto,baster,basques,basista,basiliere,bashi,barzey,barz,bartus,bartucca,bartek,barrero,barreca,barnoski,barndt,barklow,baribeau,barette,bares,barentine,bareilles,barbre,barberi,barbagelata,baraw,baratto,baranoski,baptise,bankson,bankey,bankard,banik,baltzley,ballen,balkey,balius,balderston,bakula,bakalar,baffuto,baerga,badoni,backous,bachtel,bachrach,baccari,babine,babilonia,baar,azbill,azad,aycox,ayalla,avolio,austerberry,aughtry,aufderheide,auch,attanasio,athayde,atcher,asselta,aslin,aslam,ashwood,ashraf,ashbacher,asbridge,asakura,arzaga,arriaza,arrez,arrequin,arrants,armiger,armenteros,armbrister,arko,argumedo,arguijo,ardolino,arcia,arbizo,aravjo,aper,anzaldo,antu,antrikin,antonetty,antinoro,anthon,antenucci,anstead,annese,ankrum,andreason,andrado,andaverde,anastos,anable,amspoker,amrine,amrein,amorin,amel,ambrosini,alsbrook,alnutt,almasi,allessio,allateef,aldous,alderink,aldaz,akmal,akard,aiton,aites,ainscough,aikey,ahrends,ahlm,aguada,agans,adelmann,addesso,adaway,adamaitis,ackison,abud,abendroth,abdur,abdool,aamodt,zywiec,zwiefelhofer,zwahlen,zunino,zuehl,zmuda,zmolek,zizza,ziska,zinser,zinkievich,zinger,zingarelli,ziesmer,ziegenfuss,ziebol,zettlemoyer,zettel,zervos,zenke,zembower,zelechowski,zelasko,zeise,zeek,zeeb,zarlenga,zarek,zaidi,zahnow,zahnke,zaharis,zacate,zabrocki,zaborac,yurchak,yuengling,younie,youngers,youell,yott,yoshino,yorks,yordy,yochem,yerico,yerdon,yeiser,yearous,yearick,yeaney,ybarro,yasutake,yasin,yanke,yanish,yanik,yamazaki,yamat,yaggi,ximenez,wyzard,wynder,wyly,wykle,wutzke,wuori,wuertz,wuebker,wrightsel,worobel,worlie,worford,worek,woolson,woodrome,woodly,woodling,wontor,wondra,woltemath,wollmer,wolinski,wolfert,wojtanik,wojtak,wohlfarth,woeste,wobbleton,witz,wittmeyer,witchey,wisotzkey,wisnewski,wisman,wirch,wippert,wineberg,wimpee,wilusz,wiltsey,willig,williar,willers,willadsen,wildhaber,wilday,wigham,wiewel,wieting,wietbrock,wiesel,wiesehan,wiersema,wiegert,widney,widmark,wickson,wickings,wichern,whtie,whittie,whitlinger,whitfill,whitebread,whispell,whetten,wheeley,wheeles,wheelen,whatcott,weyland,weter,westrup,westphalen,westly,westland,wessler,wesolick,wesler,wesche,werry,wero,wernecke,werkhoven,wellspeak,wellings,welford,welander,weissgerber,weisheit,weins,weill,weigner,wehrmann,wehrley,wehmeier,wege,weers,weavers,watring,wassum,wassman,wassil,washabaugh,wascher,warth,warbington,wanca,wammack,wamboldt,walterman,walkington,walkenhorst,walinski,wakley,wagg,wadell,vuckovich,voogd,voller,vokes,vogle,vogelsberg,vodicka,vissering,vipond,vincik,villalona,vickerman,vettel,veteto,vesperman,vesco,vertucci,versaw,verba,ventris,venecia,vendela,venanzi,veldhuizen,vehrs,vaughen,vasilopoulos,vascocu,varvel,varno,varlas,varland,vario,vareschi,vanwyhe,vanweelden,vansciver,vannaman,vanluven,vanloo,vanlaningham,vankomen,vanhout,vanhampler,vangorp,vangorden,vanella,vandresar,vandis,vandeyacht,vandewerker,vandevsen,vanderwall,vandercook,vanderberg,vanbergen,valko,valesquez,valeriano,valen,vachula,vacha,uzee,uselman,urizar,urion,urben,upthegrove,unzicker,unsell,unick,umscheid,umin,umanzor,ullo,ulicki,uhlir,uddin,tytler,tymeson,tyger,twisdale,twedell,tweddle,turrey,tures,turell,tupa,tuitt,tuberville,tryner,trumpower,trumbore,troglen,troff,troesch,trivisonno,tritto,tritten,tritle,trippany,tringali,tretheway,treon,trejos,tregoning,treffert,traycheff,travali,trauth,trauernicht,transou,trane,trana,toves,tosta,torp,tornquist,tornes,torchio,toor,tooks,tonks,tomblinson,tomala,tollinchi,tolles,tokich,tofte,todman,titze,timpone,tillema,tienken,tiblier,thyberg,thursby,thurrell,thurm,thruman,thorsted,thorley,thomer,thoen,thissen,theimer,thayn,thanpaeng,thammavongsa,thalman,texiera,texidor,teverbaugh,teska,ternullo,teplica,tepe,teno,tenholder,tenbusch,tenbrink,temby,tejedor,teitsworth,teichmann,tehan,tegtmeyer,tees,teem,tays,taubert,tauares,taschler,tartamella,tarquinio,tarbutton,tappendorf,tapija,tansil,tannahill,tamondong,talahytewa,takashima,taecker,tabora,tabin,tabbert,szymkowski,szymanowski,syversen,syrett,synnott,sydnes,swimm,sweney,swearegene,swartzel,swanstrom,svedin,suryan,supplice,supnet,suoboda,sundby,sumaya,sumabat,sulzen,sukovaty,sukhu,sugerman,sugalski,sudweeks,sudbeck,sucharski,stutheit,stumfoll,stuffle,struyk,strutz,strumpf,strowbridge,strothman,strojny,strohschein,stroffolino,stribble,strevel,strenke,stremming,strehle,stranak,stram,stracke,stoudamire,storks,stopp,stonebreaker,stolt,stoica,stofer,stockham,stockfisch,stjuste,stiteler,stiman,stillions,stillabower,stierle,sterlace,sterk,stepps,stenquist,stenner,stellman,steines,steinbaugh,steinbacher,steiling,steidel,steffee,stavinoha,staver,stastny,stasiuk,starrick,starliper,starlin,staniford,staner,standre,standefer,standafer,stanczyk,stallsmith,stagliano,staehle,staebler,stady,stadtmiller,squyres,spurbeck,sprunk,spranger,spoonamore,spoden,spilde,spezio,speros,sperandio,specchio,spearin,spayer,spallina,spadafino,sovie,sotello,sortor,sortino,soros,sorola,sorbello,sonner,sonday,somes,soloway,soens,soellner,soderblom,sobin,sniezek,sneary,smyly,smutnick,smoots,smoldt,smitz,smitreski,smallen,smades,slunaker,sluka,slown,slovick,slocomb,slinger,slife,sleeter,slanker,skufca,skubis,skrocki,skov,skjei,skilton,skarke,skalka,skalak,skaff,sixkiller,sitze,siter,sisko,sirman,sirls,sinotte,sinon,sincock,sincebaugh,simmoms,similien,silvius,silton,silloway,sikkema,sieracki,sienko,siemon,siemer,siefker,sieberg,siebens,siebe,sicurella,sicola,sickle,shumock,shumiloff,shuffstall,shuemaker,shuart,shroff,shreeve,shostak,shortes,shorr,shivley,shintaku,shindo,shimomura,shiigi,sherow,sherburn,shepps,shenefield,shelvin,shelstad,shelp,sheild,sheaman,shaulis,sharrer,sharps,sharpes,shappy,shapero,shanor,shandy,seyller,severn,sessom,sesley,servidio,serrin,sero,septon,septer,sennott,sengstock,senff,senese,semprini,semone,sembrat,selva,sella,selbig,seiner,seif,seidt,sehrt,seemann,seelbinder,sedlay,sebert,seaholm,seacord,seaburg,scungio,scroggie,scritchfield,scrimpsher,scrabeck,scorca,scobey,scivally,schwulst,schwinn,schwieson,schwery,schweppe,schwartzenbur,schurz,schumm,schulenburg,schuff,schuerholz,schryer,schrager,schorsch,schonhardt,schoenfelder,schoeck,schoeb,schnitzler,schnick,schnautz,schmig,schmelter,schmeichel,schluneger,schlosberg,schlobohm,schlenz,schlembach,schleisman,schleining,schleiff,schleider,schink,schilz,schiffler,schiavi,scheuer,schemonia,scheman,schelb,schaul,schaufelberge,scharer,schardt,scharbach,schabacker,scee,scavone,scarth,scarfone,scalese,sayne,sayed,savitz,satterlund,sattazahn,satow,sastre,sarr,sarjeant,sarff,sardella,santoya,santoni,santai,sankowski,sanft,sandow,sandoe,sandhaus,sandefer,sampey,samperi,sammarco,samia,samek,samay,samaan,salvadore,saltness,salsgiver,saller,salaz,salano,sakal,saka,saintlouis,saile,sahota,saggese,sagastume,sadri,sadak,sachez,saalfrank,saal,saadeh,rynn,ryley,ryle,rygg,rybarczyk,ruzich,ruyter,ruvo,rupel,ruopp,rundlett,runde,rundall,runck,rukavina,ruggiano,rufi,ruef,rubright,rubbo,rowbottom,rotner,rotman,rothweiler,rothlisberger,rosseau,rossean,rossa,roso,rosiek,roshia,rosenkrans,rosener,rosencrantz,rosencrans,rosello,roques,rookstool,rondo,romasanta,romack,rokus,rohweder,roethler,roediger,rodwell,rodrigus,rodenbeck,rodefer,rodarmel,rockman,rockholt,rochow,roches,roblin,roblez,roble,robers,roat,rizza,rizvi,rizk,rixie,riveiro,rius,ritschard,ritrovato,risi,rishe,rippon,rinks,ringley,ringgenberg,ringeisen,rimando,rilley,rijos,rieks,rieken,riechman,riddley,ricord,rickabaugh,richmeier,richesin,reyolds,rexach,requena,reppucci,reposa,renzulli,renter,remondini,reither,reisig,reifsnider,reifer,reibsome,reibert,rehor,rehmann,reedus,redshaw,reczek,recupero,recor,reckard,recher,realbuto,razer,rayman,raycraft,rayas,rawle,raviscioni,ravetto,ravenelle,rauth,raup,rattliff,rattley,rathfon,rataj,rasnic,rappleyea,rapaport,ransford,rann,rampersad,ramis,ramcharan,rainha,rainforth,ragans,ragains,rafidi,raffety,raducha,radsky,radler,radatz,raczkowski,rabenold,quraishi,quinerly,quercia,quarnstrom,pusser,puppo,pullan,pulis,pugel,puca,pruna,prowant,provines,pronk,prinkleton,prindall,primas,priesmeyer,pridgett,prevento,preti,presser,presnall,preseren,presas,presa,prchal,prattis,pratillo,praska,prak,powis,powderly,postlewait,postle,posch,porteus,porraz,popwell,popoff,poplaski,poniatoski,pollina,polle,polhill,poletti,polaski,pokorney,pointdexter,poinsette,ploszaj,plitt,pletz,pletsch,plemel,pleitez,playford,plaxco,platek,plambeck,plagens,placido,pisarski,pinuelas,pinnette,pinick,pinell,pinciaro,pinal,pilz,piltz,pillion,pilkinton,pikul,piepenburg,piening,piehler,piedrahita,piechocki,picknell,pickelsimer,pich,picariello,phoeuk,phillipson,philbert,pherigo,phelka,peverini,petrash,petramale,petraglia,pery,personius,perrington,perrill,perpall,perot,perman,peragine,pentland,pennycuff,penninger,pennachio,pendexter,penalver,pelzel,pelter,pelow,pelo,peli,peinado,pedley,pecue,pecore,pechar,peairs,paynes,payano,pawelk,pavlock,pavlich,pavich,pavek,pautler,paulik,patmore,patella,patee,patalano,passini,passeri,paskell,parrigan,parmar,parayno,paparelli,pantuso,pante,panico,panduro,panagos,pama,palmo,pallotta,paling,palamino,pake,pajtas,pailthorpe,pahler,pagon,paglinawan,pagley,paget,paetz,paet,padley,pacleb,pachelo,paccione,pabey,ozley,ozimek,ozawa,owney,outram,ouillette,oudekerk,ostrosky,ostermiller,ostermann,osterloh,osterfeld,ossenfort,osoria,oshell,orsino,orscheln,orrison,ororke,orellano,orejuela,ordoyne,opsahl,opland,onofre,onaga,omahony,olszowka,olshan,ollig,oliff,olien,olexy,oldridge,oldfather,olalde,okun,okumoto,oktavec,okin,ohme,ohlemacher,ohanesian,odneal,odgers,oderkirk,odden,ocain,obradovich,oakey,nussey,nunziato,nunoz,nunnenkamp,nuncio,noviello,novacek,nothstine,northum,norsen,norlander,norkus,norgaard,norena,nored,nobrega,niziolek,ninnemann,nievas,nieratko,nieng,niedermeyer,niedermaier,nicolls,newham,newcome,newberger,nevills,nevens,nevel,neumiller,netti,nessler,neria,nemet,nelon,nellon,neller,neisen,neilly,neifer,neid,neering,neehouse,neef,needler,nebergall,nealis,naumoff,naufzinger,narum,narro,narramore,naraine,napps,nansteel,namisnak,namanny,nallie,nakhle,naito,naccari,nabb,myracle,myhand,mwakitwile,muzzy,muscolino,musco,muscente,muscat,muscara,musacchia,musa,murrish,murfin,muray,munnelly,munley,munivez,mundine,mundahl,munari,mullennex,mullendore,mulkhey,mulinix,mulders,muhl,muenchow,muellner,mudget,mudger,muckenfuss,muchler,mozena,movius,mouldin,motola,mosseri,mossa,moselle,mory,morsell,morrish,morles,morie,morguson,moresco,morck,moppin,moosman,montuori,montono,montogomery,montis,monterio,monter,monsalve,mongomery,mongar,mondello,moncivais,monard,monagan,molt,mollenhauer,moldrem,moldonado,molano,mokler,moisant,moilanen,mohrman,mohamad,moger,mogel,modine,modin,modic,modha,mlynek,miya,mittiga,mittan,mitcheltree,misfeldt,misener,mirchandani,miralles,miotke,miosky,mintey,mins,minassian,minar,mimis,milon,milloy,millison,milito,milfort,milbradt,mikulich,mikos,miklas,mihelcic,migliorisi,migliori,miesch,midura,miclette,michela,micale,mezey,mews,mewes,mettert,mesker,mesich,mesecher,merthie,mersman,mersereau,merrithew,merriott,merring,merenda,merchen,mercardo,merati,mentzel,mentis,mentel,menotti,meno,mengle,mendolia,mellick,mellett,melichar,melhorn,melendres,melchiorre,meitzler,mehtani,mehrtens,meditz,medeiras,meckes,mcteer,mctee,mcparland,mcniell,mcnealey,mcmanaway,mcleon,mclay,mclavrin,mcklveen,mckinzey,mcken,mckeand,mckale,mcilwraith,mcilroy,mcgreal,mcgougan,mcgettigan,mcgarey,mcfeeters,mcelhany,mcdaris,mccomis,mccomber,mccolm,mccollins,mccollin,mccollam,mccoach,mcclory,mcclennon,mccathern,mccarthey,mccarson,mccarrel,mccargar,mccandles,mccamish,mccally,mccage,mcbrearty,mcaneny,mcanallen,mcalarney,mcaferty,mazzo,mazy,mazurowski,mazique,mayoras,mayden,maxberry,mauller,matusiak,mattsen,matthey,matkins,mathiasen,mathe,mateus,matalka,masullo,massay,mashak,mascroft,martinex,martenson,marsiglia,marsella,maroudas,marotte,marner,markes,maret,mareno,marean,marcinkiewicz,marchel,marasigan,manzueta,manzanilla,manternach,manring,manquero,manoni,manne,mankowski,manjarres,mangen,mangat,mandonado,mandia,mancias,manbeck,mamros,maltez,mallia,mallar,malla,malen,malaspina,malahan,malagisi,malachowski,makowsky,makinen,makepeace,majkowski,majid,majercin,maisey,mainguy,mailliard,maignan,mahlman,maha,magsamen,magpusao,magnano,magley,magedanz,magarelli,magaddino,maenner,madnick,maddrey,madaffari,macnaughton,macmullen,macksey,macknight,macki,macisaac,maciejczyk,maciag,machenry,machamer,macguire,macdaniel,maccormack,maccabe,mabbott,mabb,lynott,lycan,lutwin,luscombe,lusco,lusardi,luria,lunetta,lundsford,lumas,luisi,luevanos,lueckenhoff,ludgate,ludd,lucherini,lubbs,lozado,lourens,lounsberry,loughrey,loughary,lotton,losser,loshbaugh,loseke,loscalzo,lortz,loperena,loots,loosle,looman,longstaff,longobardi,longbottom,lomay,lomasney,lohrmann,lohmiller,logalbo,loetz,loeffel,lodwick,lodrigue,lockrem,llera,llarena,littrel,littmann,lisser,lippa,lipner,linnemann,lingg,lindemuth,lindeen,lillig,likins,lieurance,liesmann,liesman,liendo,lickert,lichliter,leyvas,leyrer,lewy,leubner,lesslie,lesnick,lesmerises,lerno,lequire,lepera,lepard,lenske,leneau,lempka,lemmen,lemm,lemere,leinhart,leichner,leicher,leibman,lehmberg,leggins,lebeda,leavengood,leanard,lazaroff,laventure,lavant,lauster,laumea,latigo,lasota,lashure,lasecki,lascurain,lartigue,larouche,lappe,laplaunt,laplace,lanum,lansdell,lanpher,lanoie,lankard,laniado,langowski,langhorn,langfield,langfeldt,landt,landerman,landavazo,lampo,lampke,lamper,lamery,lambey,lamadrid,lallemand,laisure,laigo,laguer,lagerman,lageman,lagares,lacosse,lachappelle,laborn,labonne,kuzia,kutt,kutil,kurylo,kurowski,kuriger,kupcho,kulzer,kulesa,kules,kuhs,kuhne,krutz,krus,krupka,kronberg,kromka,kroese,krizek,krivanek,kringel,kreiss,kratofil,krapp,krakowsky,kracke,kozlow,kowald,kover,kovaleski,kothakota,kosten,koskinen,kositzke,korff,korbar,kopplin,koplin,koos,konyn,konczak,komp,komo,kolber,kolash,kolakowski,kohm,kogen,koestner,koegler,kodama,kocik,kochheiser,kobler,kobara,knezevich,kneifl,knapchuck,knabb,klugman,klosner,klingel,klimesh,klice,kley,kleppe,klemke,kleinmann,kleinhans,kleinberg,kleffner,kleckley,klase,kisto,kissick,kisselburg,kirschman,kirks,kirkner,kirkey,kirchman,kinville,kinnunen,kimmey,kimmerle,kimbley,kilty,kilts,killmeyer,killilea,killay,kiest,kierce,kiepert,kielman,khalid,kewal,keszler,kesson,kesich,kerwood,kerksiek,kerkhoff,kerbo,keranen,keomuangtai,kenter,kennelley,keniry,kendzierski,kempner,kemmis,kemerling,kelsay,kelchner,kela,keithly,keipe,kegg,keer,keahey,kaywood,kayes,kawahara,kasuboski,kastendieck,kassin,kasprzyk,karraker,karnofski,karman,karger,karge,karella,karbowski,kapphahn,kannel,kamrath,kaminer,kamansky,kalua,kaltz,kalpakoff,kalkbrenner,kaku,kaib,kaehler,kackley,kaber,justo,juris,jurich,jurgenson,jurez,junor,juniel,juncker,jugo,jubert,jowell,jovanovic,joosten,joncas,joma,johnso,johanns,jodoin,jockers,joans,jinwright,jinenez,jimeson,jerrett,jergens,jerden,jerdee,jepperson,jendras,jeanfrancois,jazwa,jaussi,jaster,jarzombek,jarencio,janocha,jakab,jadlowiec,jacobsma,jach,izaquirre,iwaoka,ivaska,iturbe,israelson,isles,isachsen,isaak,irland,inzerillo,insogna,ingegneri,ingalsbe,inciong,inagaki,icenogle,hyett,hyers,huyck,hutti,hutten,hutnak,hussar,hurrle,hurford,hurde,hupper,hunkin,hunkele,hunke,humann,huhtasaari,hugel,hufft,huegel,hrobsky,hren,hoyles,hovsepian,hovenga,hovatter,houdek,hotze,hossler,hossfeld,hosseini,horten,hort,horr,horgen,horen,hoopii,hoon,hoogland,hontz,honnold,homewood,holway,holtgrewe,holtan,holstrom,holstege,hollway,hollingshed,hollenback,hollard,holberton,hoines,hogeland,hofstad,hoetger,hoen,hoaglund,hirota,hintermeister,hinnen,hinders,hinderer,hinchee,himelfarb,himber,hilzer,hilling,hillers,hillegas,hildinger,hignight,highman,hierholzer,heyde,hettich,hesketh,herzfeld,herzer,hershenson,hershberg,hernando,hermenegildo,hereth,hererra,hereda,herbin,heraty,herard,hepa,henschel,henrichsen,hennes,henneberger,heningburg,henig,hendron,hendericks,hemple,hempe,hemmingsen,hemler,helvie,helmly,helmbrecht,heling,helin,helfrey,helble,helaire,heizman,heisser,heiny,heinbaugh,heidemann,heidema,heiberger,hegel,heerdt,heeg,heefner,heckerman,heckendorf,heavin,headman,haynesworth,haylock,hayakawa,hawksley,haverstick,haut,hausen,hauke,haubold,hattan,hattabaugh,hasstedt,hashem,haselhorst,harrist,harpst,haroldsen,harmison,harkema,harison,hariri,harcus,harcum,harcharik,hanzel,hanvey,hantz,hansche,hansberger,hannig,hanken,hanhardt,hanf,hanauer,hamberlin,halward,halsall,hals,hallquist,hallmon,halk,halbach,halat,hajdas,hainsworth,haik,hahm,hagger,haggar,hader,hadel,haddick,hackmann,haasch,haaf,guzzetta,guzy,gutterman,gutmann,gutkowski,gustine,gursky,gurner,gunsolley,gumpert,gulla,guilmain,guiliani,guier,guers,guerero,guerena,guebara,guadiana,grunder,grothoff,grosland,grosh,groos,grohs,grohmann,groepper,grodi,grizzaffi,grissinger,grippi,grinde,griffee,grether,greninger,greigo,gregorski,greger,grega,greenberger,graza,grattan,grasse,grano,gramby,gradilla,govin,goutremout,goulas,gotay,gosling,gorey,gordner,goossen,goodwater,gonzaga,gonyo,gonska,gongalves,gomillion,gombos,golonka,gollman,goldtrap,goldammer,golas,golab,gola,gogan,goffman,goeppinger,godkin,godette,glore,glomb,glauner,glassey,glasner,gividen,giuffrida,gishal,giovanelli,ginoza,ginns,gindlesperger,gindhart,gillem,gilger,giggey,giebner,gibbson,giacomo,giacolone,giaccone,giacchino,ghere,gherardini,gherardi,gfeller,getts,gerwitz,gervin,gerstle,gerfin,geremia,gercak,gener,gencarelli,gehron,gehrmann,geffers,geery,geater,gawlik,gaudino,garsia,garrahan,garrabrant,garofolo,garigliano,garfinkle,garelick,gardocki,garafola,gappa,gantner,ganther,gangelhoff,gamarra,galstad,gally,gallik,gallier,galimba,gali,galassi,gaige,gadsby,gabbin,gabak,fyall,furney,funez,fulwider,fulson,fukunaga,fujikawa,fugere,fuertes,fuda,fryson,frump,frothingham,froning,froncillo,frohling,froberg,froats,fritchman,frische,friedrichsen,friedmann,friddell,frid,fresch,frentzel,freno,frelow,freimuth,freidel,freehan,freeby,freeburn,fredieu,frederiksen,fredeen,frazell,frayser,fratzke,frattini,franze,franich,francescon,framer,fragman,frack,foxe,fowlston,fosberg,fortna,fornataro,forden,foots,foody,fogt,foglia,fogerty,fogelson,flygare,flowe,flinner,flem,flath,flater,flahaven,flad,fjeld,fitanides,fistler,fishbaugh,firsching,finzel,finical,fingar,filosa,filicetti,filby,fierst,fierra,ficklen,ficher,fersner,ferrufino,ferrucci,fero,ferlenda,ferko,fergerstrom,ferge,fenty,fent,fennimore,fendt,femat,felux,felman,feldhaus,feisthamel,feijoo,feiertag,fehrman,fehl,feezell,feeback,fedigan,fedder,fechner,feary,fayson,faylor,fauteux,faustini,faure,fauci,fauber,fattig,farruggio,farrens,faraci,fantini,fantin,fanno,fannings,faniel,fallaw,falker,falkenhagen,fajen,fahrner,fabel,fabacher,eytcheson,eyster,exford,exel,evetts,evenstad,evanko,euresti,euber,etcitty,estler,essner,essinger,esplain,espenshade,espaillat,escribano,escorcia,errington,errett,errera,erlanger,erenrich,erekson,erber,entinger,ensworth,ensell,enno,ennen,englin,engblom,engberson,encinias,enama,emel,elzie,elsbree,elman,ellebracht,elkan,elfstrom,elerson,eleazer,eleam,eldrige,elcock,einspahr,eike,eidschun,eickman,eichele,eiche,ehlke,eguchi,eggink,edouard,edgehill,eckes,eblin,ebberts,eavenson,earvin,eardley,eagon,eader,dzubak,dylla,dyckman,dwire,dutrow,dutile,dusza,dustman,dusing,duryee,durupan,durtschi,durtsche,durell,dunny,dunnegan,dunken,dumm,dulak,duker,dukelow,dufort,dufilho,duffee,duett,dueck,dudzinski,dudasik,duckwall,duchemin,dubrow,dubis,dubicki,duba,drust,druckman,drinnen,drewett,drewel,dreitzler,dreckman,drappo,draffen,drabant,doyen,dowding,doub,dorson,dorschner,dorrington,dorney,dormaier,dorff,dorcy,donges,donelly,donel,domangue,dols,dollahite,dolese,doldo,doiley,dohrman,dohn,doheny,doceti,dobry,dobrinski,dobey,divincenzo,dischinger,dirusso,dirocco,dipiano,diop,dinitto,dinehart,dimsdale,diminich,dimalanta,dillavou,dilello,difusco,diffey,diffenderfer,diffee,difelice,difabio,dietzman,dieteman,diepenbrock,dieckmann,dicampli,dibari,diazdeleon,diallo,dewitz,dewiel,devoll,devol,devincent,devier,devendorf,devalk,detten,detraglia,dethomas,detemple,desler,desharnais,desanty,derocco,dermer,derks,derito,derhammer,deraney,dequattro,depass,depadua,denyes,denyer,dentino,denlinger,deneal,demory,demopoulos,demontigny,demonte,demeza,delsol,delrosso,delpit,delpapa,delouise,delone,delo,delmundo,delmore,dellapaolera,delfin,delfierro,deleonardis,delenick,delcarlo,delcampo,delcamp,delawyer,delaroca,delaluz,delahunt,delaguardia,dekeyser,dekay,dejaeger,dejackome,dehay,dehass,degraffenried,degenhart,degan,deever,deedrick,deckelbaum,dechico,dececco,decasas,debrock,debona,debeaumont,debarros,debaca,dearmore,deangelus,dealmeida,dawood,davney,daudt,datri,dasgupta,darring,darracott,darcus,daoud,dansbury,dannels,danielski,danehy,dancey,damour,dambra,dalcour,dahlheimer,dadisman,dacunto,dacamara,dabe,cyrulik,cyphert,cwik,cussen,curles,curit,curby,curbo,cunas,cunard,cunanan,cumpton,culcasi,cucinotta,cucco,csubak,cruthird,crumwell,crummitt,crumedy,crouthamel,cronce,cromack,crisafi,crimin,cresto,crescenzo,cremonese,creedon,crankshaw,cozzens,coval,courtwright,courcelle,coupland,counihan,coullard,cotrell,cosgrave,cornelio,corish,cordoua,corbit,coppersmith,coonfield,conville,contrell,contento,conser,conrod,connole,congrove,conery,condray,colver,coltman,colflesh,colcord,colavito,colar,coile,coggan,coenen,codling,coda,cockroft,cockrel,cockerill,cocca,coberley,clouden,clos,clish,clinkscale,clester,clammer,cittadino,citrano,ciresi,cillis,ciccarelli,ciborowski,ciarlo,ciardullo,chritton,chopp,chirco,chilcoat,chevarie,cheslak,chernak,chay,chatterjee,chatten,chatagnier,chastin,chappuis,channey,champlain,chalupsky,chalfin,chaffer,chadek,chadderton,cestone,cestero,cestari,cerros,cermeno,centola,cedrone,cayouette,cavan,cavaliero,casuse,castricone,castoreno,casten,castanada,castagnola,casstevens,cassanova,caspari,casher,cashatt,casco,casassa,casad,carville,cartland,cartegena,carsey,carsen,carrino,carrilo,carpinteyro,carmley,carlston,carlsson,cariddi,caricofe,carel,cardy,carducci,carby,carangelo,capriotti,capria,caprario,capelo,canul,cantua,cantlow,canny,cangialosi,canepa,candland,campolo,campi,camors,camino,camfield,camelo,camarero,camaeho,calvano,calliste,caldarella,calcutt,calcano,caissie,cager,caccamo,cabotage,cabble,byman,buzby,butkowski,bussler,busico,bushovisky,busbin,busard,busalacchi,burtman,burrous,burridge,burrer,burno,burin,burgette,burdock,burdier,burckhard,bunten,bungay,bundage,bumby,bultema,bulinski,bulan,bukhari,buganski,buerkle,buen,buehl,budzynski,buckham,bryk,brydon,bruyere,brunsvold,brunnett,brunker,brunfield,brumble,brue,brozina,brossman,brosey,brookens,broersma,brodrick,brockmeier,brockhouse,brisky,brinkly,brincefield,brighenti,brigante,brieno,briede,bridenbaugh,brickett,breske,brener,brenchley,breitkreutz,breitbart,breister,breining,breighner,breidel,brehon,breheny,breard,breakell,brazill,braymiller,braum,brau,brashaw,bransom,brandolino,brancato,branagan,braff,brading,bracker,brackenbury,bracher,braasch,boylen,boyda,boyanton,bowlus,bowditch,boutot,bouthillette,boursiquot,bourjolly,bouret,boulerice,bouer,bouchillon,bouchie,bottin,boteilho,bosko,bosack,borys,bors,borla,borjon,borghi,borah,booten,boore,bonuz,bonne,bongers,boneta,bonawitz,bonanni,bomer,bollen,bollard,bolla,bolio,boisseau,boies,boiani,bohorquez,boghossian,boespflug,boeser,boehl,boegel,bodrick,bodkins,bodenstein,bodell,bockover,bocci,bobbs,boals,boahn,boadway,bluma,bluett,bloor,blomker,blevens,blethen,bleecker,blayney,blaske,blasetti,blancas,blackner,bjorkquist,bjerk,bizub,bisono,bisges,bisaillon,birr,birnie,bires,birdtail,birdine,bina,billock,billinger,billig,billet,bigwood,bigalk,bielicki,biddick,biccum,biafore,bhagat,beza,beyah,bevier,bevell,beute,betzer,betthauser,bethay,bethard,beshaw,bertholf,bertels,berridge,bernot,bernath,bernabei,berkson,berkovitz,berkich,bergsten,berget,berezny,berdin,beougher,benthin,benhaim,benenati,benejan,bemiss,beloate,bellucci,bellotti,belling,bellido,bellaire,bellafiore,bekins,bekele,beish,behnken,beerly,beddo,becket,becke,bebeau,beauchaine,beaucage,beadling,beacher,bazar,baysmore".split(","))),
-o("user_inputs",H)];A=u.concat([function(b){var a,d,c,e,f,g,h,i,j,k,l,m,p,n,o,q;f=[];o=Q(S(b));j=0;for(m=o.length;j<m;j++){g=o[j];if(P(g))break;k=0;for(p=u.length;k<p;k++){c=u[k];e=V(b,g);q=c(e);l=0;for(n=q.length;l<n;l++)if(c=q[l],i=b.slice(c.i,+c.j+1||9E9),i.toLowerCase()!==c.matched_word){e={};for(h in g)a=g[h],-1!==i.indexOf(h)&&(e[h]=a);c.l33t=!0;c.token=i;c.sub=e;i=c;var B=void 0,B=[];for(d in e)a=e[d],B.push(""+d+" -> "+a);i.sub_display=B.join(", ");f.push(c)}}}return f},function(b){var a,
-d,c,e,f,g;f=q(b,O);g=[];c=0;for(e=f.length;c<e;c++)a=f[c],d=[a.i,a.j],a=d[0],d=d[1],g.push({pattern:"digits",i:a,j:d,token:b.slice(a,+d+1||9E9)});return g},function(b){var a,d,c,e,f,g;f=q(b,W);g=[];c=0;for(e=f.length;c<e;c++)a=f[c],d=[a.i,a.j],a=d[0],d=d[1],g.push({pattern:"year",i:a,j:d,token:b.slice(a,+d+1||9E9)});return g},function(b){return M(b).concat(L(b))},function(b){var a,d,c;c=[];for(a=0;a<b.length;){for(d=a+1;;)if(b.slice(d-1,+d+1||9E9),b.charAt(d-1)===b.charAt(d))d+=1;else{2<d-a&&c.push({pattern:"repeat",
-i:a,j:d-1,token:b.slice(a,d),repeated_char:b.charAt(a)});break}a=d}return c},function(b){var a,d,c,e,f,g,h,i,j,k,l,m,n;i=[];for(f=0;f<b.length;){g=f+1;m=n=j=null;for(l in w)if(k=w[l],c=function(){var c,d,e,h;e=[b.charAt(f),b.charAt(g)];h=[];c=0;for(d=e.length;c<d;c++)a=e[c],h.push(k.indexOf(a));return h}(),e=c[0],c=c[1],-1<e&&-1<c&&(e=c-e,1===e||-1===e)){j=k;n=l;m=e;break}if(j)for(;;)if(e=b.slice(g-1,+g+1||9E9),h=e[0],d=e[1],c=function(){var b,c,e,f;e=[h,d];f=[];b=0;for(c=e.length;b<c;b++)a=e[b],
-f.push(k.indexOf(a));return f}(),e=c[0],c=c[1],c-e===m)g+=1;else{2<g-f&&i.push({pattern:"sequence",i:f,j:g-1,token:b.slice(f,g),sequence_name:n,sequence_space:j.length,ascending:1===m});break}f=g}return i},function(b){var a,d,c;c=[];for(d in G)a=G[d],y(c,U(b,a,d));return c}]);G={qwerty:E,dvorak:{"!":["`~",null,null,"2@","'\"",null],'"':[null,"1!","2@",",<","aA",null],"#":["2@",null,null,"4$",".>",",<"],$:["3#",null,null,"5%","pP",".>"],"%":["4$",null,null,"6^","yY","pP"],"&":["6^",null,null,"8*",
-"gG","fF"],"'":[null,"1!","2@",",<","aA",null],"(":["8*",null,null,"0)","rR","cC"],")":["9(",null,null,"[{","lL","rR"],"*":["7&",null,null,"9(","cC","gG"],"+":["/?","]}",null,"\\|",null,"-_"],",":"'\",2@,3#,.>,oO,aA".split(","),"-":["sS","/?","=+",null,null,"zZ"],".":",< 3# 4$ pP eE oO".split(" "),"/":"lL,[{,]},=+,-_,sS".split(","),"0":["9(",null,null,"[{","lL","rR"],1:["`~",null,null,"2@","'\"",null],2:["1!",null,null,"3#",",<","'\""],3:["2@",null,null,"4$",".>",",<"],4:["3#",null,null,"5%","pP",
-".>"],5:["4$",null,null,"6^","yY","pP"],6:["5%",null,null,"7&","fF","yY"],7:["6^",null,null,"8*","gG","fF"],8:["7&",null,null,"9(","cC","gG"],9:["8*",null,null,"0)","rR","cC"],":":[null,"aA","oO","qQ",null,null],";":[null,"aA","oO","qQ",null,null],"<":"'\",2@,3#,.>,oO,aA".split(","),"=":["/?","]}",null,"\\|",null,"-_"],">":",< 3# 4$ pP eE oO".split(" "),"?":"lL,[{,]},=+,-_,sS".split(","),"@":["1!",null,null,"3#",",<","'\""],A:[null,"'\"",",<","oO",";:",null],B:["xX","dD","hH","mM",null,null],C:"gG,8*,9(,rR,tT,hH".split(","),
-D:"iI,fF,gG,hH,bB,xX".split(","),E:"oO,.>,pP,uU,jJ,qQ".split(","),F:"yY,6^,7&,gG,dD,iI".split(","),G:"fF,7&,8*,cC,hH,dD".split(","),H:"dD,gG,cC,tT,mM,bB".split(","),I:"uU,yY,fF,dD,xX,kK".split(","),J:["qQ","eE","uU","kK",null,null],K:["jJ","uU","iI","xX",null,null],L:"rR,0),[{,/?,sS,nN".split(","),M:["bB","hH","tT","wW",null,null],N:"tT,rR,lL,sS,vV,wW".split(","),O:"aA ,< .> eE qQ ;:".split(" "),P:".>,4$,5%,yY,uU,eE".split(","),Q:[";:","oO","eE","jJ",null,null],R:"cC,9(,0),lL,nN,tT".split(","),S:"nN,lL,/?,-_,zZ,vV".split(","),
-T:"hH,cC,rR,nN,wW,mM".split(","),U:"eE,pP,yY,iI,kK,jJ".split(","),V:["wW","nN","sS","zZ",null,null],W:["mM","tT","nN","vV",null,null],X:["kK","iI","dD","bB",null,null],Y:"pP,5%,6^,fF,iI,uU".split(","),Z:["vV","sS","-_",null,null,null],"[":["0)",null,null,"]}","/?","lL"],"\\":["=+",null,null,null,null,null],"]":["[{",null,null,null,"=+","/?"],"^":["5%",null,null,"7&","fF","yY"],_:["sS","/?","=+",null,null,"zZ"],"`":[null,null,null,"1!",null,null],a:[null,"'\"",",<","oO",";:",null],b:["xX","dD","hH",
-"mM",null,null],c:"gG,8*,9(,rR,tT,hH".split(","),d:"iI,fF,gG,hH,bB,xX".split(","),e:"oO,.>,pP,uU,jJ,qQ".split(","),f:"yY,6^,7&,gG,dD,iI".split(","),g:"fF,7&,8*,cC,hH,dD".split(","),h:"dD,gG,cC,tT,mM,bB".split(","),i:"uU,yY,fF,dD,xX,kK".split(","),j:["qQ","eE","uU","kK",null,null],k:["jJ","uU","iI","xX",null,null],l:"rR,0),[{,/?,sS,nN".split(","),m:["bB","hH","tT","wW",null,null],n:"tT,rR,lL,sS,vV,wW".split(","),o:"aA ,< .> eE qQ ;:".split(" "),p:".>,4$,5%,yY,uU,eE".split(","),q:[";:","oO","eE","jJ",
-null,null],r:"cC,9(,0),lL,nN,tT".split(","),s:"nN,lL,/?,-_,zZ,vV".split(","),t:"hH,cC,rR,nN,wW,mM".split(","),u:"eE,pP,yY,iI,kK,jJ".split(","),v:["wW","nN","sS","zZ",null,null],w:["mM","tT","nN","vV",null,null],x:["kK","iI","dD","bB",null,null],y:"pP,5%,6^,fF,iI,uU".split(","),z:["vV","sS","-_",null,null,null],"{":["0)",null,null,"]}","/?","lL"],"|":["=+",null,null,null,null,null],"}":["[{",null,null,null,"=+","/?"],"~":[null,null,null,"1!",null,null]},keypad:F,mac_keypad:{"*":["/",null,null,null,
-null,null,"-","9"],"+":["6","9","-",null,null,null,null,"3"],"-":["9","/","*",null,null,null,"+","6"],".":["0","2","3",null,null,null,null,null],"/":["=",null,null,null,"*","-","9","8"],"0":[null,"1","2","3",".",null,null,null],1:[null,null,"4","5","2","0",null,null],2:["1","4","5","6","3",".","0",null],3:["2","5","6","+",null,null,".","0"],4:[null,null,"7","8","5","2","1",null],5:"4,7,8,9,6,3,2,1".split(","),6:["5","8","9","-","+",null,"3","2"],7:[null,null,null,"=","8","5","4",null],8:["7",null,
-"=","/","9","6","5","4"],9:"8,=,/,*,-,+,6,5".split(","),"=":[null,null,null,null,"/","9","8","7"]}};o=function(b){var a,d,c,e,f;a=0;for(c in b)f=b[c],a+=function(){var a,b,c;c=[];a=0;for(b=f.length;a<b;a++)(e=f[a])&&c.push(e);return c}().length;return a/=function(){var a;a=[];for(d in b)a.push(d);return a}().length};pa=o(E);ra=o(F);oa=function(){var b;b=[];for(v in E)b.push(v);return b}().length;qa=function(){var b;b=[];for(v in F)b.push(v);return b}().length;I=function(){return(new Date).getTime()};
-o=function(b,a){var d,c,e,f;c=I();if(null!=a){d=e=0;for(f=a.length;0<=f?e<f:e>f;d=0<=f?++e:--e)H[a[d].toLowerCase()]=d+1}d=R(b);d=ja(b,d);d.calc_time=I()-c;return d};"undefined"!==typeof window&&null!==window?(window.zxcvbn=o,"function"===typeof window.zxcvbn_load_hook&&window.zxcvbn_load_hook()):"undefined"!==typeof exports&&null!==exports&&(exports.zxcvbn=o)})();
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/common.css b/Duplicati/Server/webroot/greeno/stylesheets/common.css
deleted file mode 100644
index c6d5fe8f5..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/common.css
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Common style config
- */
-
-body {
- background-color: #f0f0f0;
- border: 0px none;
- margin: 0px;
- padding: 0px;
- font-family: 'Source Sans Pro', sans-serif;
- min-width: 320px;
- font-size: 75%;
-}
-
-textarea.pre-style-text, .pre-style-text {
- white-space: pre;
- overflow: auto;
- word-wrap: normal;
- font-family: "Courier New", Courier, monospace;
-}
-
-.content-wrap {
- margin: 0 auto;
- box-sizing: border-box;
- max-width: 1100px
-}
-
-.content-wrap.padded {
- padding-left: 20px;
- padding-right: 20px;
-}
-
-.ui-widget {
- font-family: 'Source Sans Pro', sans-serif;
-}
-
-.action-link, .action-links li {
- text-decoration: underline;
- color: #56acbb;
- font-size: 12pt;
- cursor: pointer;
-}
-
-.hint-text {
- color: #9b9b9b;
- font-size: 12pt;
-}
-
-.hint-text-caption {
- font-weight: bold;
- color: #9b9b9b;
- font-size: 12pt;
-}
-
-.caption-text {
- color: #68845f;
- font-weight: bold;
- font-size: 18pt;
-}
-
-.progressbar-background {
- background-color: #b1bead;
-}
-
-.menu {
- background-color: rgba(255, 255, 255, 0.9);
- position: absolute;
- display: none;
- list-style: none;
- border: 1px solid #9b9b9b;
- margin: 0px;
- padding: 0px;
- border-radius: 3px;
- white-space: nowrap;
- z-index: 10000;
-}
-
-.menu li {
- cursor: pointer;
-}
-
-.large-loader-icon {
- width: 66px;
- height: 66px;
- margin: auto;
- background: url('../images/ajax-loader-66.gif') center center no-repeat;
-}
-
-.medium-loader-icon {
- width: 32px;
- height: 32px;
- background: url("../images/ajax-loader-32.gif") center center no-repeat;
-}
-
-.small-loader-icon {
- width: 16px;
- height: 16px;
- background: url("../images/ajax-loader-16.gif") center center no-repeat;
-}
-
-.button-area {
- float: right;
- padding-bottom: 10px;
- padding-top: 10px;
-}
-
-.clearfix {
- clear: both;
-}
-
-.password-strength-0 {
- color: #ff0000
-}
-
-.password-strength-1 {
- color: #ff7700
-}
-.password-strength-2 {
- color: #aaaa00
-}
-
-.password-strength-3 {
- color: #007700
-}
-
-.password-strength-4 {
- color: #427e27;
-}
-
-.password-strength-unknown {
- color: #999999
-}
-
-.password-mismatch {
- color: #ff0000;
-}
-
-a.jstree-anchor > i.icon-file.jstree-icon {
- background-image: url('/images/generic-file.png');
- background-position: 0px 0px;
-}
-
-a.jstree-anchor > i.icon-clock.jstree-icon {
- background-image: url('/images/clock.png');
- background-position: 0px 0px;
-}
-
-a.jstree-anchor > i.icon-file.jstree-icon.icon-file-log { background-image: url('/control.cgi?action=get-system-icon&ext=log'); }
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/editdialog.css b/Duplicati/Server/webroot/greeno/stylesheets/editdialog.css
deleted file mode 100644
index a8ff0ed1e..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/editdialog.css
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * CSS config for the edit dialog
- */
-
- .edit-dialog label:before {
- clear: both;
- }
-
-.edit-dialog {
- float: left;
-}
-
- .edit-dialog label {
- min-width: 250px;
- display: inline-block;
- }
-
- .edit-dialog-label {
- min-width: 200px;
- line-height: 26px;
- clear: both;
- float: left;
- }
-
-.edit-dialog input, .edit-dialog textarea, .edit-dialog select {
- background: none;
- border-color: #c0c0c0;
-}
-
-.edit-dialog input, .edit-dialog select {
- width: 330px;
-}
-
-.edit-dialog textarea {
- max-width: 330px;
- width: 330px;
-}
-
-.input-block {
- clear: both;
- margin-top: 10px;
- overflow: hidden;
- position: relative;
-}
-
-.edit-tab-general > .input-block:first-child {
- margin-top: 0;
-}
-
-.field-group {
- display: inline-block;
-}
-
-.button-area {
- clear: both;
- position: absolute;
- bottom: 0px;
- right: 0px;
- float: right;
-}
-
-.inline-links {
- margin: 0;
- padding: 0;
-}
-
-.inline-links > li {
- border-left: 1px solid #7d7d7d;
- display: inline-block;
- margin: 0;
- padding: 0 10px;
-}
-
-.inline-links > li:first-child {
- border-left: none;
- padding-left: 5px;
-}
-
-.field-group .inline-links {
- margin-top: 5px;
-}
-
-#encryption-area {
- clear: both;
-}
-
-#backend-type {
- width: 140px;
-}
-
-#server-port {
- width: 80px;
-}
-
-#server-name {
- width: 165px;
-}
-
-#server-use-ssl {
- width: auto;
- margin-left: 10px;
-}
-
-.checkbox-label {
- display: inline-block;
- margin-top: 2px;
-}
-
-#source-folder-paths {
- margin-top: 10px;
- position: relative;
-
- padding: 10px;
- background-color: lightgray;
- margin-bottom: 10px;
- border-radius: 3px;
- overflow: hidden;
-}
-
-#source-folder-paths.empty {
- padding: 20px;
-}
-
-#source-folder-paths > div.source-folder {
- padding: 5px 25px 5px 5px;
- background-color: white;
- border-radius: 3px;
- display: inline-block;
- margin: 8px;
- position: relative;
- float: left;
-}
-
-#source-folder-paths > div.source-folder .focused, #source-folder-paths > div.source-folder:hover {
- /*background-color: grey;
- color: black;*/
-}
-
-#source-folder-paths > div.source-folder.path-valid {
-}
-
-#source-folder-paths > div.source-folder.path-invalid {
- background-color: #ffcccc;
-}
-
-
-.source-folder-close-icon {
- width: 16px;
- height: 16px;
- background-position: -80px -128px;
- background-image: url(green-theme/images/ui-icons_365724_256x240.png);
- background-repeat: no-repeat;
- position: absolute;
- top: 5px;
- right: 5px;
- cursor: pointer;
-}
-
-.source-folder-close-icon:hover {
- background-color: red;
-}
-
-#source-folder-browser {
- clear: both;
- /*height: 160px;*/
- overflow: auto;
-}
-
-#source-folder-path-text {
- /*max-width: 205px;*/
- width: 70%;
- margin-top: 6px;
-}
-
-#source-folder-path-add {
- margin-right: 0px;
- float: right;
-}
-
-#source-folder-droptarget {
- width: 100%;
- height: 100%;
- position: absolute;
- display: block;
- top: 0;
- left: 0;
-}
-
-#use-scheduled-run {
- float: left;
- width: auto;
- margin-right: 10px;
-}
-
-#next-run-time, #next-run-date, #repeat-run-number, #repeat-run-multiplier {
- width: 165px;
-}
-
-#dblock-size-number, #dblock-size-multiplier, #keep-time-type, #keep-time-number, #keep-time-multiplier {
- width: 120px;
-}
-
-#dblock-size-multiplier {
- width: 145px;
-}
-
-#keep-time-multiplier {
- width: 80px;
-}
-
-#dblock-size-number {
- width: 178px;
-}
-
-#keep-time-type {
- width: 180px;
-}
-
-#keep-time-number {
- width: 60px;
-}
-
-#dblock-size-number {
- width: 178px;
-}
-
- input.simple-checkbox {
- width: auto;
- float: none;
-}
-
-.days-label {
- display: inline-block;
-}
-
-.input-wrapper {
- float: left;
-}
-
-.hint-line-last {
- margin-bottom: 20px;
-}
-
-#edit-tab-schedule > div.clearfix, #edit-tab-options > div.clearfix {
- height: 10px;
-}
-
-#edit-dialog {
- width: 100%;
- border-top-left-radius: 0px;
- border-top-right-radius: 0px;
-}
-
-.ui-tabs-nav {
- border-top-right-radius: 0px;
- border-top-left-radius: 0px;
-}
-
-.edit-dialog-hint-text {
- width: 100%;
-}
-
-#source-folder-paths.file-drag-target {
- background-color: #00ff00;
-}
-
-#backup-options-link div.ui-icon-info, #server-options-label div.ui-icon-info {
- display: inline-block;
-}
-
-#server-options {
- max-width: none;
- width: 100%;
-}
-
-.backup-option-name {
- font-weight: bold;
- color: darkgreen;
-}
-
-.backup-option-short, .backup-option-type, .backup-option-default {
- display: inline;
-}
-
-.backup-option-summary, .backup-option-long {
- margin-left: 5px;
-}
-
-.backup-option-long {
- margin-top: 5px;
- margin-bottom: 10px;
-}
-
-input.server-path-file {
- width: 275px;
-}
-
-input.browse-button {
- padding-top: 0px;
- padding-bottom: 0px;
- width: auto;
-}
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/animated-overlay.gif b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/animated-overlay.gif
deleted file mode 100644
index 606e403b8..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/animated-overlay.gif
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_0_000000_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_0_000000_40x100.png
deleted file mode 100755
index cb192e669..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_0_000000_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_10_365724_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_10_365724_40x100.png
deleted file mode 100755
index 275758cac..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_10_365724_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_50_000000_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_50_000000_40x100.png
deleted file mode 100755
index 1f68e68f1..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_50_000000_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_55_f0f0f0_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_55_f0f0f0_40x100.png
deleted file mode 100755
index 61fa2aded..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_55_f0f0f0_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_65_f0f0f0_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_65_f0f0f0_40x100.png
deleted file mode 100755
index ae5edeb3d..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_65_f0f0f0_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_365724_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_365724_40x100.png
deleted file mode 100755
index 65b05b106..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_365724_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_4e7f33_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_4e7f33_40x100.png
deleted file mode 100755
index 81cde784d..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_4e7f33_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_f0f0f0_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_f0f0f0_40x100.png
deleted file mode 100755
index 44c547e5d..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_75_f0f0f0_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_95_f0f0f0_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_95_f0f0f0_40x100.png
deleted file mode 100755
index 14563c8be..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-bg_flat_95_f0f0f0_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_365724_256x240.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_365724_256x240.png
deleted file mode 100755
index 681c0c871..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_365724_256x240.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_da3c3c_256x240.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_da3c3c_256x240.png
deleted file mode 100755
index 4fe227417..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_da3c3c_256x240.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_e5ebe2_256x240.png b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_e5ebe2_256x240.png
deleted file mode 100755
index 77a66f2ad..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/images/ui-icons_e5ebe2_256x240.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/jquery-ui-1.10.3.css b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/jquery-ui-1.10.3.css
deleted file mode 100755
index 94653cb1f..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/jquery-ui-1.10.3.css
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*! jQuery UI - v1.10.3 - 2013-12-16
-* http://jqueryui.com
-* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
-* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CVerdana%2C%20sans-serif&fwDefault=bold&fsDefault=1.4em&cornerRadius=5px&bgColorHeader=%23365724&bgTextureHeader=flat&bgImgOpacityHeader=10&borderColorHeader=%23365724&fcHeader=%23e5ebe2&iconColorHeader=%23e5ebe2&bgColorContent=%23f0f0f0&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23f0f0f0&fcContent=%237d7d7d&iconColorContent=%23365724&bgColorDefault=%23365724&bgTextureDefault=flat&bgImgOpacityDefault=75&borderColorDefault=%234e7f33&fcDefault=%23e5ebe2&iconColorDefault=%23e5ebe2&bgColorHover=%234e7f33&bgTextureHover=flat&bgImgOpacityHover=75&borderColorHover=%234e7f33&fcHover=%23e5ebe2&iconColorHover=%23e5ebe2&bgColorActive=%23f0f0f0&bgTextureActive=flat&bgImgOpacityActive=65&borderColorActive=%23f0f0f0&fcActive=%23365724&iconColorActive=%23365724&bgColorHighlight=%23f0f0f0&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23f0f0f0&fcHighlight=%23365724&iconColorHighlight=%23365724&bgColorError=%23f0f0f0&bgTextureError=flat&bgImgOpacityError=95&borderColorError=%23f0f0f0&fcError=%23da3c3c&iconColorError=%23da3c3c&bgColorOverlay=%23000000&bgTextureOverlay=flat&bgImgOpacityOverlay=50&opacityOverlay=80&bgColorShadow=%23000000&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=40&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=8px
-* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
-
-/* Layout helpers
-----------------------------------*/
-.ui-helper-hidden {
- display: none;
-}
-.ui-helper-hidden-accessible {
- border: 0;
- clip: rect(0 0 0 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 1px;
-}
-.ui-helper-reset {
- margin: 0;
- padding: 0;
- border: 0;
- outline: 0;
- line-height: 1.3;
- text-decoration: none;
- font-size: 100%;
- list-style: none;
-}
-.ui-helper-clearfix:before,
-.ui-helper-clearfix:after {
- content: "";
- display: table;
- border-collapse: collapse;
-}
-.ui-helper-clearfix:after {
- clear: both;
-}
-.ui-helper-clearfix {
- min-height: 0; /* support: IE7 */
-}
-.ui-helper-zfix {
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
- position: absolute;
- opacity: 0;
- filter:Alpha(Opacity=0);
-}
-
-.ui-front {
- z-index: 100;
-}
-
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-disabled {
- cursor: default !important;
-}
-
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon {
- display: block;
- text-indent: -99999px;
- overflow: hidden;
- background-repeat: no-repeat;
-}
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Overlays */
-.ui-widget-overlay {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
-}
-.ui-resizable {
- position: relative;
-}
-.ui-resizable-handle {
- position: absolute;
- font-size: 0.1px;
- display: block;
-}
-.ui-resizable-disabled .ui-resizable-handle,
-.ui-resizable-autohide .ui-resizable-handle {
- display: none;
-}
-.ui-resizable-n {
- cursor: n-resize;
- height: 7px;
- width: 100%;
- top: -5px;
- left: 0;
-}
-.ui-resizable-s {
- cursor: s-resize;
- height: 7px;
- width: 100%;
- bottom: -5px;
- left: 0;
-}
-.ui-resizable-e {
- cursor: e-resize;
- width: 7px;
- right: -5px;
- top: 0;
- height: 100%;
-}
-.ui-resizable-w {
- cursor: w-resize;
- width: 7px;
- left: -5px;
- top: 0;
- height: 100%;
-}
-.ui-resizable-se {
- cursor: se-resize;
- width: 12px;
- height: 12px;
- right: 1px;
- bottom: 1px;
-}
-.ui-resizable-sw {
- cursor: sw-resize;
- width: 9px;
- height: 9px;
- left: -5px;
- bottom: -5px;
-}
-.ui-resizable-nw {
- cursor: nw-resize;
- width: 9px;
- height: 9px;
- left: -5px;
- top: -5px;
-}
-.ui-resizable-ne {
- cursor: ne-resize;
- width: 9px;
- height: 9px;
- right: -5px;
- top: -5px;
-}
-.ui-selectable-helper {
- position: absolute;
- z-index: 100;
- border: 1px dotted black;
-}
-.ui-accordion .ui-accordion-header {
- display: block;
- cursor: pointer;
- position: relative;
- margin-top: 2px;
- padding: .5em .5em .5em .7em;
- min-height: 0; /* support: IE7 */
-}
-.ui-accordion .ui-accordion-icons {
- padding-left: 2.2em;
-}
-.ui-accordion .ui-accordion-noicons {
- padding-left: .7em;
-}
-.ui-accordion .ui-accordion-icons .ui-accordion-icons {
- padding-left: 2.2em;
-}
-.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
- position: absolute;
- left: .5em;
- top: 50%;
- margin-top: -8px;
-}
-.ui-accordion .ui-accordion-content {
- padding: 1em 2.2em;
- border-top: 0;
- overflow: auto;
-}
-.ui-autocomplete {
- position: absolute;
- top: 0;
- left: 0;
- cursor: default;
-}
-.ui-button {
- display: inline-block;
- position: relative;
- padding: 0;
- line-height: normal;
- margin-right: .1em;
- cursor: pointer;
- vertical-align: middle;
- text-align: center;
- overflow: visible; /* removes extra width in IE */
-}
-.ui-button,
-.ui-button:link,
-.ui-button:visited,
-.ui-button:hover,
-.ui-button:active {
- text-decoration: none;
-}
-/* to make room for the icon, a width needs to be set here */
-.ui-button-icon-only {
- width: 2.2em;
-}
-/* button elements seem to need a little more width */
-button.ui-button-icon-only {
- width: 2.4em;
-}
-.ui-button-icons-only {
- width: 3.4em;
-}
-button.ui-button-icons-only {
- width: 3.7em;
-}
-
-/* button text element */
-.ui-button .ui-button-text {
- display: block;
- line-height: normal;
-}
-.ui-button-text-only .ui-button-text {
- padding: .4em 1em;
-}
-.ui-button-icon-only .ui-button-text,
-.ui-button-icons-only .ui-button-text {
- padding: .4em;
- text-indent: -9999999px;
-}
-.ui-button-text-icon-primary .ui-button-text,
-.ui-button-text-icons .ui-button-text {
- padding: .4em 1em .4em 2.1em;
-}
-.ui-button-text-icon-secondary .ui-button-text,
-.ui-button-text-icons .ui-button-text {
- padding: .4em 2.1em .4em 1em;
-}
-.ui-button-text-icons .ui-button-text {
- padding-left: 2.1em;
- padding-right: 2.1em;
-}
-/* no icon support for input elements, provide padding by default */
-input.ui-button {
- padding: .4em 1em;
-}
-
-/* button icon element(s) */
-.ui-button-icon-only .ui-icon,
-.ui-button-text-icon-primary .ui-icon,
-.ui-button-text-icon-secondary .ui-icon,
-.ui-button-text-icons .ui-icon,
-.ui-button-icons-only .ui-icon {
- position: absolute;
- top: 50%;
- margin-top: -8px;
-}
-.ui-button-icon-only .ui-icon {
- left: 50%;
- margin-left: -8px;
-}
-.ui-button-text-icon-primary .ui-button-icon-primary,
-.ui-button-text-icons .ui-button-icon-primary,
-.ui-button-icons-only .ui-button-icon-primary {
- left: .5em;
-}
-.ui-button-text-icon-secondary .ui-button-icon-secondary,
-.ui-button-text-icons .ui-button-icon-secondary,
-.ui-button-icons-only .ui-button-icon-secondary {
- right: .5em;
-}
-
-/* button sets */
-.ui-buttonset {
- margin-right: 7px;
-}
-.ui-buttonset .ui-button {
- margin-left: 0;
- margin-right: -.3em;
-}
-
-/* workarounds */
-/* reset extra padding in Firefox, see h5bp.com/l */
-input.ui-button::-moz-focus-inner,
-button.ui-button::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-.ui-datepicker {
- width: 17em;
- padding: .2em .2em 0;
- display: none;
-}
-.ui-datepicker .ui-datepicker-header {
- position: relative;
- padding: .2em 0;
-}
-.ui-datepicker .ui-datepicker-prev,
-.ui-datepicker .ui-datepicker-next {
- position: absolute;
- top: 2px;
- width: 1.8em;
- height: 1.8em;
-}
-.ui-datepicker .ui-datepicker-prev-hover,
-.ui-datepicker .ui-datepicker-next-hover {
- top: 1px;
-}
-.ui-datepicker .ui-datepicker-prev {
- left: 2px;
-}
-.ui-datepicker .ui-datepicker-next {
- right: 2px;
-}
-.ui-datepicker .ui-datepicker-prev-hover {
- left: 1px;
-}
-.ui-datepicker .ui-datepicker-next-hover {
- right: 1px;
-}
-.ui-datepicker .ui-datepicker-prev span,
-.ui-datepicker .ui-datepicker-next span {
- display: block;
- position: absolute;
- left: 50%;
- margin-left: -8px;
- top: 50%;
- margin-top: -8px;
-}
-.ui-datepicker .ui-datepicker-title {
- margin: 0 2.3em;
- line-height: 1.8em;
- text-align: center;
-}
-.ui-datepicker .ui-datepicker-title select {
- font-size: 1em;
- margin: 1px 0;
-}
-.ui-datepicker select.ui-datepicker-month-year {
- width: 100%;
-}
-.ui-datepicker select.ui-datepicker-month,
-.ui-datepicker select.ui-datepicker-year {
- width: 49%;
-}
-.ui-datepicker table {
- width: 100%;
- font-size: .9em;
- border-collapse: collapse;
- margin: 0 0 .4em;
-}
-.ui-datepicker th {
- padding: .7em .3em;
- text-align: center;
- font-weight: bold;
- border: 0;
-}
-.ui-datepicker td {
- border: 0;
- padding: 1px;
-}
-.ui-datepicker td span,
-.ui-datepicker td a {
- display: block;
- padding: .2em;
- text-align: right;
- text-decoration: none;
-}
-.ui-datepicker .ui-datepicker-buttonpane {
- background-image: none;
- margin: .7em 0 0 0;
- padding: 0 .2em;
- border-left: 0;
- border-right: 0;
- border-bottom: 0;
-}
-.ui-datepicker .ui-datepicker-buttonpane button {
- float: right;
- margin: .5em .2em .4em;
- cursor: pointer;
- padding: .2em .6em .3em .6em;
- width: auto;
- overflow: visible;
-}
-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
- float: left;
-}
-
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi {
- width: auto;
-}
-.ui-datepicker-multi .ui-datepicker-group {
- float: left;
-}
-.ui-datepicker-multi .ui-datepicker-group table {
- width: 95%;
- margin: 0 auto .4em;
-}
-.ui-datepicker-multi-2 .ui-datepicker-group {
- width: 50%;
-}
-.ui-datepicker-multi-3 .ui-datepicker-group {
- width: 33.3%;
-}
-.ui-datepicker-multi-4 .ui-datepicker-group {
- width: 25%;
-}
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
- border-left-width: 0;
-}
-.ui-datepicker-multi .ui-datepicker-buttonpane {
- clear: left;
-}
-.ui-datepicker-row-break {
- clear: both;
- width: 100%;
- font-size: 0;
-}
-
-/* RTL support */
-.ui-datepicker-rtl {
- direction: rtl;
-}
-.ui-datepicker-rtl .ui-datepicker-prev {
- right: 2px;
- left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next {
- left: 2px;
- right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-prev:hover {
- right: 1px;
- left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next:hover {
- left: 1px;
- right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane {
- clear: right;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button {
- float: left;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
-.ui-datepicker-rtl .ui-datepicker-group {
- float: right;
-}
-.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
- border-right-width: 0;
- border-left-width: 1px;
-}
-.ui-dialog {
- position: absolute;
- top: 0;
- left: 0;
- padding: .2em;
- outline: 0;
-}
-.ui-dialog .ui-dialog-titlebar {
- padding: .4em 1em;
- position: relative;
-}
-.ui-dialog .ui-dialog-title {
- float: left;
- margin: .1em 0;
- white-space: nowrap;
- width: 90%;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-.ui-dialog .ui-dialog-titlebar-close {
- position: absolute;
- right: .3em;
- top: 50%;
- width: 21px;
- margin: -10px 0 0 0;
- padding: 1px;
- height: 20px;
-}
-.ui-dialog .ui-dialog-content {
- position: relative;
- border: 0;
- padding: .5em 1em;
- background: none;
- overflow: auto;
-}
-.ui-dialog .ui-dialog-buttonpane {
- text-align: left;
- border-width: 1px 0 0 0;
- background-image: none;
- margin-top: .5em;
- padding: .3em 1em .5em .4em;
-}
-.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
- float: right;
-}
-.ui-dialog .ui-dialog-buttonpane button {
- margin: .5em .4em .5em 0;
- cursor: pointer;
-}
-.ui-dialog .ui-resizable-se {
- width: 12px;
- height: 12px;
- right: -5px;
- bottom: -5px;
- background-position: 16px 16px;
-}
-.ui-draggable .ui-dialog-titlebar {
- cursor: move;
-}
-.ui-menu {
- list-style: none;
- padding: 2px;
- margin: 0;
- display: block;
- outline: none;
-}
-.ui-menu .ui-menu {
- margin-top: -3px;
- position: absolute;
-}
-.ui-menu .ui-menu-item {
- margin: 0;
- padding: 0;
- width: 100%;
- /* support: IE10, see #8844 */
- list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
-}
-.ui-menu .ui-menu-divider {
- margin: 5px -2px 5px -2px;
- height: 0;
- font-size: 0;
- line-height: 0;
- border-width: 1px 0 0 0;
-}
-.ui-menu .ui-menu-item a {
- text-decoration: none;
- display: block;
- padding: 2px .4em;
- line-height: 1.5;
- min-height: 0; /* support: IE7 */
- font-weight: normal;
-}
-.ui-menu .ui-menu-item a.ui-state-focus,
-.ui-menu .ui-menu-item a.ui-state-active {
- font-weight: normal;
- margin: -1px;
-}
-
-.ui-menu .ui-state-disabled {
- font-weight: normal;
- margin: .4em 0 .2em;
- line-height: 1.5;
-}
-.ui-menu .ui-state-disabled a {
- cursor: default;
-}
-
-/* icon support */
-.ui-menu-icons {
- position: relative;
-}
-.ui-menu-icons .ui-menu-item a {
- position: relative;
- padding-left: 2em;
-}
-
-/* left-aligned */
-.ui-menu .ui-icon {
- position: absolute;
- top: .2em;
- left: .2em;
-}
-
-/* right-aligned */
-.ui-menu .ui-menu-icon {
- position: static;
- float: right;
-}
-.ui-progressbar {
- height: 2em;
- text-align: left;
- overflow: hidden;
-}
-.ui-progressbar .ui-progressbar-value {
- margin: -1px;
- height: 100%;
-}
-.ui-progressbar .ui-progressbar-overlay {
- background: url("images/animated-overlay.gif");
- height: 100%;
- filter: alpha(opacity=25);
- opacity: 0.25;
-}
-.ui-progressbar-indeterminate .ui-progressbar-value {
- background-image: none;
-}
-.ui-slider {
- position: relative;
- text-align: left;
-}
-.ui-slider .ui-slider-handle {
- position: absolute;
- z-index: 2;
- width: 1.2em;
- height: 1.2em;
- cursor: default;
-}
-.ui-slider .ui-slider-range {
- position: absolute;
- z-index: 1;
- font-size: .7em;
- display: block;
- border: 0;
- background-position: 0 0;
-}
-
-/* For IE8 - See #6727 */
-.ui-slider.ui-state-disabled .ui-slider-handle,
-.ui-slider.ui-state-disabled .ui-slider-range {
- filter: inherit;
-}
-
-.ui-slider-horizontal {
- height: .8em;
-}
-.ui-slider-horizontal .ui-slider-handle {
- top: -.3em;
- margin-left: -.6em;
-}
-.ui-slider-horizontal .ui-slider-range {
- top: 0;
- height: 100%;
-}
-.ui-slider-horizontal .ui-slider-range-min {
- left: 0;
-}
-.ui-slider-horizontal .ui-slider-range-max {
- right: 0;
-}
-
-.ui-slider-vertical {
- width: .8em;
- height: 100px;
-}
-.ui-slider-vertical .ui-slider-handle {
- left: -.3em;
- margin-left: 0;
- margin-bottom: -.6em;
-}
-.ui-slider-vertical .ui-slider-range {
- left: 0;
- width: 100%;
-}
-.ui-slider-vertical .ui-slider-range-min {
- bottom: 0;
-}
-.ui-slider-vertical .ui-slider-range-max {
- top: 0;
-}
-.ui-spinner {
- position: relative;
- display: inline-block;
- overflow: hidden;
- padding: 0;
- vertical-align: middle;
-}
-.ui-spinner-input {
- border: none;
- background: none;
- color: inherit;
- padding: 0;
- margin: .2em 0;
- vertical-align: middle;
- margin-left: .4em;
- margin-right: 22px;
-}
-.ui-spinner-button {
- width: 16px;
- height: 50%;
- font-size: .5em;
- padding: 0;
- margin: 0;
- text-align: center;
- position: absolute;
- cursor: default;
- display: block;
- overflow: hidden;
- right: 0;
-}
-/* more specificity required here to overide default borders */
-.ui-spinner a.ui-spinner-button {
- border-top: none;
- border-bottom: none;
- border-right: none;
-}
-/* vertical centre icon */
-.ui-spinner .ui-icon {
- position: absolute;
- margin-top: -8px;
- top: 50%;
- left: 0;
-}
-.ui-spinner-up {
- top: 0;
-}
-.ui-spinner-down {
- bottom: 0;
-}
-
-/* TR overrides */
-.ui-spinner .ui-icon-triangle-1-s {
- /* need to fix icons sprite */
- background-position: -65px -16px;
-}
-.ui-tabs {
- position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
- padding: .2em;
-}
-.ui-tabs .ui-tabs-nav {
- margin: 0;
- padding: .2em .2em 0;
-}
-.ui-tabs .ui-tabs-nav li {
- list-style: none;
- float: left;
- position: relative;
- top: 0;
- margin: 1px .2em 0 0;
- border-bottom-width: 0;
- padding: 0;
- white-space: nowrap;
-}
-.ui-tabs .ui-tabs-nav li a {
- float: left;
- padding: .5em 1em;
- text-decoration: none;
-}
-.ui-tabs .ui-tabs-nav li.ui-tabs-active {
- margin-bottom: -1px;
- padding-bottom: 1px;
-}
-.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
-.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
-.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
- cursor: text;
-}
-.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
-.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
- cursor: pointer;
-}
-.ui-tabs .ui-tabs-panel {
- display: block;
- border-width: 0;
- padding: 1em 1.4em;
- background: none;
-}
-.ui-tooltip {
- padding: 8px;
- position: absolute;
- z-index: 9999;
- max-width: 300px;
- -webkit-box-shadow: 0 0 5px #aaa;
- box-shadow: 0 0 5px #aaa;
-}
-body .ui-tooltip {
- border-width: 2px;
-}
-
-/* Component containers
-----------------------------------*/
-.ui-widget {
- font-family: Arial,Verdana, sans-serif;
- font-size: 1.4em;
-}
-.ui-widget .ui-widget {
- font-size: 1em;
-}
-.ui-widget input,
-.ui-widget select,
-.ui-widget textarea,
-.ui-widget button {
- font-family: Arial,Verdana, sans-serif;
- font-size: 1em;
-}
-.ui-widget-content {
- border: 1px solid #f0f0f0;
- background: #f0f0f0 url(images/ui-bg_flat_75_f0f0f0_40x100.png) 50% 50% repeat-x;
- color: #7d7d7d;
-}
-.ui-widget-content a {
- color: #7d7d7d;
-}
-.ui-widget-header {
- border: 1px solid #365724;
- background: #365724 url(images/ui-bg_flat_10_365724_40x100.png) 50% 50% repeat-x;
- color: #e5ebe2;
- font-weight: bold;
-}
-.ui-widget-header a {
- color: #e5ebe2;
-}
-
-/* Interaction states
-----------------------------------*/
-.ui-state-default,
-.ui-widget-content .ui-state-default,
-.ui-widget-header .ui-state-default {
- border: 1px solid #4e7f33;
- background: #365724 url(images/ui-bg_flat_75_365724_40x100.png) 50% 50% repeat-x;
- font-weight: bold;
- color: #e5ebe2;
-}
-.ui-state-default a,
-.ui-state-default a:link,
-.ui-state-default a:visited {
- color: #e5ebe2;
- text-decoration: none;
-}
-.ui-state-hover,
-.ui-widget-content .ui-state-hover,
-.ui-widget-header .ui-state-hover,
-.ui-state-focus,
-.ui-widget-content .ui-state-focus,
-.ui-widget-header .ui-state-focus {
- border: 1px solid #4e7f33;
- background: #4e7f33 url(images/ui-bg_flat_75_4e7f33_40x100.png) 50% 50% repeat-x;
- font-weight: bold;
- color: #e5ebe2;
-}
-.ui-state-hover a,
-.ui-state-hover a:hover,
-.ui-state-hover a:link,
-.ui-state-hover a:visited {
- color: #e5ebe2;
- text-decoration: none;
-}
-.ui-state-active,
-.ui-widget-content .ui-state-active,
-.ui-widget-header .ui-state-active {
- border: 1px solid #f0f0f0;
- background: #f0f0f0 url(images/ui-bg_flat_65_f0f0f0_40x100.png) 50% 50% repeat-x;
- font-weight: bold;
- color: #365724;
-}
-.ui-state-active a,
-.ui-state-active a:link,
-.ui-state-active a:visited {
- color: #365724;
- text-decoration: none;
-}
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-highlight,
-.ui-widget-content .ui-state-highlight,
-.ui-widget-header .ui-state-highlight {
- border: 1px solid #f0f0f0;
- background: #f0f0f0 url(images/ui-bg_flat_55_f0f0f0_40x100.png) 50% 50% repeat-x;
- color: #365724;
-}
-.ui-state-highlight a,
-.ui-widget-content .ui-state-highlight a,
-.ui-widget-header .ui-state-highlight a {
- color: #365724;
-}
-.ui-state-error,
-.ui-widget-content .ui-state-error,
-.ui-widget-header .ui-state-error {
- border: 1px solid #f0f0f0;
- background: #f0f0f0 url(images/ui-bg_flat_95_f0f0f0_40x100.png) 50% 50% repeat-x;
- color: #da3c3c;
-}
-.ui-state-error a,
-.ui-widget-content .ui-state-error a,
-.ui-widget-header .ui-state-error a {
- color: #da3c3c;
-}
-.ui-state-error-text,
-.ui-widget-content .ui-state-error-text,
-.ui-widget-header .ui-state-error-text {
- color: #da3c3c;
-}
-.ui-priority-primary,
-.ui-widget-content .ui-priority-primary,
-.ui-widget-header .ui-priority-primary {
- font-weight: bold;
-}
-.ui-priority-secondary,
-.ui-widget-content .ui-priority-secondary,
-.ui-widget-header .ui-priority-secondary {
- opacity: .7;
- filter:Alpha(Opacity=70);
- font-weight: normal;
-}
-.ui-state-disabled,
-.ui-widget-content .ui-state-disabled,
-.ui-widget-header .ui-state-disabled {
- opacity: .35;
- filter:Alpha(Opacity=35);
- background-image: none;
-}
-.ui-state-disabled .ui-icon {
- filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
-}
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon {
- width: 16px;
- height: 16px;
-}
-.ui-icon,
-.ui-widget-content .ui-icon {
- background-image: url(images/ui-icons_365724_256x240.png);
-}
-.ui-widget-header .ui-icon {
- background-image: url(images/ui-icons_e5ebe2_256x240.png);
-}
-.ui-state-default .ui-icon {
- background-image: url(images/ui-icons_e5ebe2_256x240.png);
-}
-.ui-state-hover .ui-icon,
-.ui-state-focus .ui-icon {
- background-image: url(images/ui-icons_e5ebe2_256x240.png);
-}
-.ui-state-active .ui-icon {
- background-image: url(images/ui-icons_365724_256x240.png);
-}
-.ui-state-highlight .ui-icon {
- background-image: url(images/ui-icons_365724_256x240.png);
-}
-.ui-state-error .ui-icon,
-.ui-state-error-text .ui-icon {
- background-image: url(images/ui-icons_da3c3c_256x240.png);
-}
-
-/* positioning */
-.ui-icon-blank { background-position: 16px 16px; }
-.ui-icon-carat-1-n { background-position: 0 0; }
-.ui-icon-carat-1-ne { background-position: -16px 0; }
-.ui-icon-carat-1-e { background-position: -32px 0; }
-.ui-icon-carat-1-se { background-position: -48px 0; }
-.ui-icon-carat-1-s { background-position: -64px 0; }
-.ui-icon-carat-1-sw { background-position: -80px 0; }
-.ui-icon-carat-1-w { background-position: -96px 0; }
-.ui-icon-carat-1-nw { background-position: -112px 0; }
-.ui-icon-carat-2-n-s { background-position: -128px 0; }
-.ui-icon-carat-2-e-w { background-position: -144px 0; }
-.ui-icon-triangle-1-n { background-position: 0 -16px; }
-.ui-icon-triangle-1-ne { background-position: -16px -16px; }
-.ui-icon-triangle-1-e { background-position: -32px -16px; }
-.ui-icon-triangle-1-se { background-position: -48px -16px; }
-.ui-icon-triangle-1-s { background-position: -64px -16px; }
-.ui-icon-triangle-1-sw { background-position: -80px -16px; }
-.ui-icon-triangle-1-w { background-position: -96px -16px; }
-.ui-icon-triangle-1-nw { background-position: -112px -16px; }
-.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
-.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
-.ui-icon-arrow-1-n { background-position: 0 -32px; }
-.ui-icon-arrow-1-ne { background-position: -16px -32px; }
-.ui-icon-arrow-1-e { background-position: -32px -32px; }
-.ui-icon-arrow-1-se { background-position: -48px -32px; }
-.ui-icon-arrow-1-s { background-position: -64px -32px; }
-.ui-icon-arrow-1-sw { background-position: -80px -32px; }
-.ui-icon-arrow-1-w { background-position: -96px -32px; }
-.ui-icon-arrow-1-nw { background-position: -112px -32px; }
-.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
-.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
-.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
-.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
-.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
-.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
-.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
-.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
-.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
-.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
-.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
-.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
-.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
-.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
-.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
-.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
-.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
-.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
-.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
-.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
-.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
-.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
-.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
-.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
-.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
-.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
-.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
-.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
-.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
-.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
-.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
-.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
-.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
-.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
-.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
-.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
-.ui-icon-arrow-4 { background-position: 0 -80px; }
-.ui-icon-arrow-4-diag { background-position: -16px -80px; }
-.ui-icon-extlink { background-position: -32px -80px; }
-.ui-icon-newwin { background-position: -48px -80px; }
-.ui-icon-refresh { background-position: -64px -80px; }
-.ui-icon-shuffle { background-position: -80px -80px; }
-.ui-icon-transfer-e-w { background-position: -96px -80px; }
-.ui-icon-transferthick-e-w { background-position: -112px -80px; }
-.ui-icon-folder-collapsed { background-position: 0 -96px; }
-.ui-icon-folder-open { background-position: -16px -96px; }
-.ui-icon-document { background-position: -32px -96px; }
-.ui-icon-document-b { background-position: -48px -96px; }
-.ui-icon-note { background-position: -64px -96px; }
-.ui-icon-mail-closed { background-position: -80px -96px; }
-.ui-icon-mail-open { background-position: -96px -96px; }
-.ui-icon-suitcase { background-position: -112px -96px; }
-.ui-icon-comment { background-position: -128px -96px; }
-.ui-icon-person { background-position: -144px -96px; }
-.ui-icon-print { background-position: -160px -96px; }
-.ui-icon-trash { background-position: -176px -96px; }
-.ui-icon-locked { background-position: -192px -96px; }
-.ui-icon-unlocked { background-position: -208px -96px; }
-.ui-icon-bookmark { background-position: -224px -96px; }
-.ui-icon-tag { background-position: -240px -96px; }
-.ui-icon-home { background-position: 0 -112px; }
-.ui-icon-flag { background-position: -16px -112px; }
-.ui-icon-calendar { background-position: -32px -112px; }
-.ui-icon-cart { background-position: -48px -112px; }
-.ui-icon-pencil { background-position: -64px -112px; }
-.ui-icon-clock { background-position: -80px -112px; }
-.ui-icon-disk { background-position: -96px -112px; }
-.ui-icon-calculator { background-position: -112px -112px; }
-.ui-icon-zoomin { background-position: -128px -112px; }
-.ui-icon-zoomout { background-position: -144px -112px; }
-.ui-icon-search { background-position: -160px -112px; }
-.ui-icon-wrench { background-position: -176px -112px; }
-.ui-icon-gear { background-position: -192px -112px; }
-.ui-icon-heart { background-position: -208px -112px; }
-.ui-icon-star { background-position: -224px -112px; }
-.ui-icon-link { background-position: -240px -112px; }
-.ui-icon-cancel { background-position: 0 -128px; }
-.ui-icon-plus { background-position: -16px -128px; }
-.ui-icon-plusthick { background-position: -32px -128px; }
-.ui-icon-minus { background-position: -48px -128px; }
-.ui-icon-minusthick { background-position: -64px -128px; }
-.ui-icon-close { background-position: -80px -128px; }
-.ui-icon-closethick { background-position: -96px -128px; }
-.ui-icon-key { background-position: -112px -128px; }
-.ui-icon-lightbulb { background-position: -128px -128px; }
-.ui-icon-scissors { background-position: -144px -128px; }
-.ui-icon-clipboard { background-position: -160px -128px; }
-.ui-icon-copy { background-position: -176px -128px; }
-.ui-icon-contact { background-position: -192px -128px; }
-.ui-icon-image { background-position: -208px -128px; }
-.ui-icon-video { background-position: -224px -128px; }
-.ui-icon-script { background-position: -240px -128px; }
-.ui-icon-alert { background-position: 0 -144px; }
-.ui-icon-info { background-position: -16px -144px; }
-.ui-icon-notice { background-position: -32px -144px; }
-.ui-icon-help { background-position: -48px -144px; }
-.ui-icon-check { background-position: -64px -144px; }
-.ui-icon-bullet { background-position: -80px -144px; }
-.ui-icon-radio-on { background-position: -96px -144px; }
-.ui-icon-radio-off { background-position: -112px -144px; }
-.ui-icon-pin-w { background-position: -128px -144px; }
-.ui-icon-pin-s { background-position: -144px -144px; }
-.ui-icon-play { background-position: 0 -160px; }
-.ui-icon-pause { background-position: -16px -160px; }
-.ui-icon-seek-next { background-position: -32px -160px; }
-.ui-icon-seek-prev { background-position: -48px -160px; }
-.ui-icon-seek-end { background-position: -64px -160px; }
-.ui-icon-seek-start { background-position: -80px -160px; }
-/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
-.ui-icon-seek-first { background-position: -80px -160px; }
-.ui-icon-stop { background-position: -96px -160px; }
-.ui-icon-eject { background-position: -112px -160px; }
-.ui-icon-volume-off { background-position: -128px -160px; }
-.ui-icon-volume-on { background-position: -144px -160px; }
-.ui-icon-power { background-position: 0 -176px; }
-.ui-icon-signal-diag { background-position: -16px -176px; }
-.ui-icon-signal { background-position: -32px -176px; }
-.ui-icon-battery-0 { background-position: -48px -176px; }
-.ui-icon-battery-1 { background-position: -64px -176px; }
-.ui-icon-battery-2 { background-position: -80px -176px; }
-.ui-icon-battery-3 { background-position: -96px -176px; }
-.ui-icon-circle-plus { background-position: 0 -192px; }
-.ui-icon-circle-minus { background-position: -16px -192px; }
-.ui-icon-circle-close { background-position: -32px -192px; }
-.ui-icon-circle-triangle-e { background-position: -48px -192px; }
-.ui-icon-circle-triangle-s { background-position: -64px -192px; }
-.ui-icon-circle-triangle-w { background-position: -80px -192px; }
-.ui-icon-circle-triangle-n { background-position: -96px -192px; }
-.ui-icon-circle-arrow-e { background-position: -112px -192px; }
-.ui-icon-circle-arrow-s { background-position: -128px -192px; }
-.ui-icon-circle-arrow-w { background-position: -144px -192px; }
-.ui-icon-circle-arrow-n { background-position: -160px -192px; }
-.ui-icon-circle-zoomin { background-position: -176px -192px; }
-.ui-icon-circle-zoomout { background-position: -192px -192px; }
-.ui-icon-circle-check { background-position: -208px -192px; }
-.ui-icon-circlesmall-plus { background-position: 0 -208px; }
-.ui-icon-circlesmall-minus { background-position: -16px -208px; }
-.ui-icon-circlesmall-close { background-position: -32px -208px; }
-.ui-icon-squaresmall-plus { background-position: -48px -208px; }
-.ui-icon-squaresmall-minus { background-position: -64px -208px; }
-.ui-icon-squaresmall-close { background-position: -80px -208px; }
-.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
-.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
-.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
-.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
-.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
-.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Corner radius */
-.ui-corner-all,
-.ui-corner-top,
-.ui-corner-left,
-.ui-corner-tl {
- border-top-left-radius: 5px;
-}
-.ui-corner-all,
-.ui-corner-top,
-.ui-corner-right,
-.ui-corner-tr {
- border-top-right-radius: 5px;
-}
-.ui-corner-all,
-.ui-corner-bottom,
-.ui-corner-left,
-.ui-corner-bl {
- border-bottom-left-radius: 5px;
-}
-.ui-corner-all,
-.ui-corner-bottom,
-.ui-corner-right,
-.ui-corner-br {
- border-bottom-right-radius: 5px;
-}
-
-/* Overlays */
-.ui-widget-overlay {
- background: #000000 url(images/ui-bg_flat_50_000000_40x100.png) 50% 50% repeat-x;
- opacity: .8;
- filter: Alpha(Opacity=80);
-}
-.ui-widget-shadow {
- margin: -4px 0 0 -4px;
- padding: 4px;
- background: #000000 url(images/ui-bg_flat_0_000000_40x100.png) 50% 50% repeat-x;
- opacity: .4;
- filter: Alpha(Opacity=40);
- border-radius: 8px;
-}
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/jquery-ui-1.10.3.min.css b/Duplicati/Server/webroot/greeno/stylesheets/green-theme/jquery-ui-1.10.3.min.css
deleted file mode 100755
index 6674b6199..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/green-theme/jquery-ui-1.10.3.min.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/*! jQuery UI - v1.10.3 - 2013-12-16
-* http://jqueryui.com
-* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
-* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CVerdana%2C%20sans-serif&fwDefault=bold&fsDefault=1.4em&cornerRadius=5px&bgColorHeader=%23365724&bgTextureHeader=flat&bgImgOpacityHeader=10&borderColorHeader=%23365724&fcHeader=%23e5ebe2&iconColorHeader=%23e5ebe2&bgColorContent=%23f0f0f0&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23f0f0f0&fcContent=%237d7d7d&iconColorContent=%23365724&bgColorDefault=%23365724&bgTextureDefault=flat&bgImgOpacityDefault=75&borderColorDefault=%234e7f33&fcDefault=%23e5ebe2&iconColorDefault=%23e5ebe2&bgColorHover=%234e7f33&bgTextureHover=flat&bgImgOpacityHover=75&borderColorHover=%234e7f33&fcHover=%23e5ebe2&iconColorHover=%23e5ebe2&bgColorActive=%23f0f0f0&bgTextureActive=flat&bgImgOpacityActive=65&borderColorActive=%23f0f0f0&fcActive=%23365724&iconColorActive=%23365724&bgColorHighlight=%23f0f0f0&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=%23f0f0f0&fcHighlight=%23365724&iconColorHighlight=%23365724&bgColorError=%23f0f0f0&bgTextureError=flat&bgImgOpacityError=95&borderColorError=%23f0f0f0&fcError=%23da3c3c&iconColorError=%23da3c3c&bgColorOverlay=%23000000&bgTextureOverlay=flat&bgImgOpacityOverlay=50&opacityOverlay=80&bgColorShadow=%23000000&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=40&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=8px
-* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
-
-.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;min-height:0}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:21px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;min-height:0;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("images/animated-overlay.gif");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Arial,Verdana,sans-serif;font-size:1.4em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Verdana,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #f0f0f0;background:#f0f0f0 url(images/ui-bg_flat_75_f0f0f0_40x100.png) 50% 50% repeat-x;color:#7d7d7d}.ui-widget-content a{color:#7d7d7d}.ui-widget-header{border:1px solid #365724;background:#365724 url(images/ui-bg_flat_10_365724_40x100.png) 50% 50% repeat-x;color:#e5ebe2;font-weight:bold}.ui-widget-header a{color:#e5ebe2}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #4e7f33;background:#365724 url(images/ui-bg_flat_75_365724_40x100.png) 50% 50% repeat-x;font-weight:bold;color:#e5ebe2}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#e5ebe2;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #4e7f33;background:#4e7f33 url(images/ui-bg_flat_75_4e7f33_40x100.png) 50% 50% repeat-x;font-weight:bold;color:#e5ebe2}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#e5ebe2;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #f0f0f0;background:#f0f0f0 url(images/ui-bg_flat_65_f0f0f0_40x100.png) 50% 50% repeat-x;font-weight:bold;color:#365724}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#365724;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #f0f0f0;background:#f0f0f0 url(images/ui-bg_flat_55_f0f0f0_40x100.png) 50% 50% repeat-x;color:#365724}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#365724}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f0f0f0;background:#f0f0f0 url(images/ui-bg_flat_95_f0f0f0_40x100.png) 50% 50% repeat-x;color:#da3c3c}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#da3c3c}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#da3c3c}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_365724_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_e5ebe2_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_e5ebe2_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_e5ebe2_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_365724_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_365724_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_da3c3c_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:5px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:5px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:5px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:5px}.ui-widget-overlay{background:#000 url(images/ui-bg_flat_50_000000_40x100.png) 50% 50% repeat-x;opacity:.8;filter:Alpha(Opacity=80)}.ui-widget-shadow{margin:-4px 0 0 -4px;padding:4px;background:#000 url(images/ui-bg_flat_0_000000_40x100.png) 50% 50% repeat-x;opacity:.4;filter:Alpha(Opacity=40);border-radius:8px}
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/jstree/32px.png b/Duplicati/Server/webroot/greeno/stylesheets/jstree/32px.png
deleted file mode 100755
index 153271524..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/jstree/32px.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/jstree/40px.png b/Duplicati/Server/webroot/greeno/stylesheets/jstree/40px.png
deleted file mode 100755
index 9e76db4f7..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/jstree/40px.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/jstree/style.css b/Duplicati/Server/webroot/greeno/stylesheets/jstree/style.css
deleted file mode 100755
index ebae5e903..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/jstree/style.css
+++ /dev/null
@@ -1,916 +0,0 @@
-/* jsTree default theme */
-.jstree-node,
-.jstree-children,
-.jstree-container-ul {
- display: block;
- margin: 0;
- padding: 0;
- list-style-type: none;
- list-style-image: none;
-}
-.jstree-node {
- white-space: nowrap;
-}
-.jstree-anchor {
- display: inline-block;
- color: black;
- white-space: nowrap;
- padding: 0 4px 0 1px;
- margin: 0;
- vertical-align: top;
-}
-.jstree-anchor:focus {
- outline: 0;
-}
-.jstree-anchor,
-.jstree-anchor:link,
-.jstree-anchor:visited,
-.jstree-anchor:hover,
-.jstree-anchor:active {
- text-decoration: none;
- color: inherit;
-}
-.jstree-icon {
- display: inline-block;
- text-decoration: none;
- margin: 0;
- padding: 0;
- vertical-align: top;
- text-align: center;
-}
-.jstree-icon:empty {
- display: inline-block;
- text-decoration: none;
- margin: 0;
- padding: 0;
- vertical-align: top;
- text-align: center;
-}
-.jstree-ocl {
- cursor: pointer;
-}
-.jstree .jstree-open > .jstree-children {
- display: block;
-}
-.jstree .jstree-closed > .jstree-children,
-.jstree .jstree-leaf > .jstree-children {
- display: none;
-}
-.jstree-anchor > .jstree-themeicon {
- margin-right: 2px;
-}
-.jstree-no-icons .jstree-themeicon,
-.jstree-anchor > .jstree-themeicon-hidden {
- display: none;
-}
-.jstree-rtl .jstree-anchor {
- padding: 0 1px 0 4px;
-}
-.jstree-rtl .jstree-anchor > .jstree-themeicon {
- margin-left: 2px;
- margin-right: 0;
-}
-.jstree-rtl .jstree-node {
- margin-left: 0;
-}
-.jstree-rtl .jstree-container-ul > .jstree-node {
- margin-right: 0;
-}
-.jstree-wholerow-ul {
- position: relative;
- display: inline-block;
- min-width: 100%;
-}
-.jstree-wholerow-ul .jstree-anchor,
-.jstree-wholerow-ul .jstree-icon {
- position: relative;
-}
-.jstree-wholerow-ul .jstree-wholerow {
- width: 100%;
- cursor: pointer;
- position: absolute;
- left: 0;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-.vakata-context {
- display: none;
-}
-.vakata-context,
-.vakata-context ul {
- margin: 0;
- padding: 2px;
- position: absolute;
- background: #f5f5f5;
- border: 1px solid #979797;
- -moz-box-shadow: 5px 5px 4px -4px #666666;
- -webkit-box-shadow: 2px 2px 2px #999999;
- box-shadow: 2px 2px 2px #999999;
-}
-.vakata-context ul {
- list-style: none;
- left: 100%;
- margin-top: -2.7em;
- margin-left: -4px;
-}
-.vakata-context .vakata-context-right ul {
- left: auto;
- right: 100%;
- margin-left: auto;
- margin-right: -4px;
-}
-.vakata-context li {
- list-style: none;
- display: inline;
-}
-.vakata-context li > a {
- display: block;
- padding: 0 2em 0 2em;
- text-decoration: none;
- width: auto;
- color: black;
- white-space: nowrap;
- line-height: 2.4em;
- -moz-text-shadow: 1px 1px 0 white;
- -webkit-text-shadow: 1px 1px 0 white;
- text-shadow: 1px 1px 0 white;
- -moz-border-radius: 1px;
- -webkit-border-radius: 1px;
- border-radius: 1px;
-}
-.vakata-context li > a:hover {
- position: relative;
- background-color: #e8eff7;
- -moz-box-shadow: 0 0 2px #0a6aa1;
- -webkit-box-shadow: 0 0 2px #0a6aa1;
- box-shadow: 0 0 2px #0a6aa1;
-}
-.vakata-context li > a.vakata-context-parent {
- background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");
- background-position: right center;
- background-repeat: no-repeat;
-}
-.vakata-context li > a:focus {
- outline: 0;
-}
-.vakata-context .vakata-context-hover > a {
- position: relative;
- background-color: #e8eff7;
- -moz-box-shadow: 0 0 2px #0a6aa1;
- -webkit-box-shadow: 0 0 2px #0a6aa1;
- box-shadow: 0 0 2px #0a6aa1;
-}
-.vakata-context .vakata-context-separator a,
-.vakata-context .vakata-context-separator a:hover {
- background: white;
- border: 0;
- border-top: 1px solid #e2e3e3;
- height: 1px;
- min-height: 1px;
- max-height: 1px;
- padding: 0;
- margin: 0 0 0 2.4em;
- border-left: 1px solid #e0e0e0;
- -moz-text-shadow: 0 0 0 transparent;
- -webkit-text-shadow: 0 0 0 transparent;
- text-shadow: 0 0 0 transparent;
- -moz-box-shadow: 0 0 0 transparent;
- -webkit-box-shadow: 0 0 0 transparent;
- box-shadow: 0 0 0 transparent;
- -moz-border-radius: 0;
- -webkit-border-radius: 0;
- border-radius: 0;
-}
-.vakata-context .vakata-contextmenu-disabled a,
-.vakata-context .vakata-contextmenu-disabled a:hover {
- color: silver;
- background-color: transparent;
- border: 0;
- box-shadow: 0 0 0;
-}
-.vakata-context li > a > i {
- text-decoration: none;
- display: inline-block;
- width: 2.4em;
- height: 2.4em;
- background: transparent;
- margin: 0 0 0 -2em;
- vertical-align: top;
- text-align: center;
- line-height: 2.4em;
-}
-.vakata-context li > a > i:empty {
- width: 2.4em;
- line-height: 2.4em;
-}
-.vakata-context li > a .vakata-contextmenu-sep {
- display: inline-block;
- width: 1px;
- height: 2.4em;
- background: white;
- margin: 0 0.5em 0 0;
- border-left: 1px solid #e2e3e3;
-}
-.vakata-context .vakata-contextmenu-shortcut {
- font-size: 0.8em;
- color: silver;
- opacity: 0.5;
- display: none;
-}
-.vakata-context-rtl ul {
- left: auto;
- right: 100%;
- margin-left: auto;
- margin-right: -4px;
-}
-.vakata-context-rtl li > a.vakata-context-parent {
- background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");
- background-position: left center;
- background-repeat: no-repeat;
-}
-.vakata-context-rtl .vakata-context-separator > a {
- margin: 0 2.4em 0 0;
- border-left: 0;
- border-right: 1px solid #e2e3e3;
-}
-.vakata-context-rtl .vakata-context-left ul {
- right: auto;
- left: 100%;
- margin-left: -4px;
- margin-right: auto;
-}
-.vakata-context-rtl li > a > i {
- margin: 0 -2em 0 0;
-}
-.vakata-context-rtl li > a .vakata-contextmenu-sep {
- margin: 0 0 0 0.5em;
- border-left-color: white;
- background: #e2e3e3;
-}
-#jstree-marker {
- position: absolute;
- top: 0;
- left: 0;
- margin: 0;
- padding: 0;
- border-right: 0;
- border-top: 5px solid transparent;
- border-bottom: 5px solid transparent;
- border-left: 5px solid;
- width: 0;
- height: 0;
- font-size: 0;
- line-height: 0;
-}
-#jstree-dnd {
- line-height: 16px;
- margin: 0;
- padding: 4px;
-}
-#jstree-dnd .jstree-icon,
-#jstree-dnd .jstree-copy {
- display: inline-block;
- text-decoration: none;
- margin: 0 2px 0 0;
- padding: 0;
- width: 16px;
- height: 16px;
-}
-#jstree-dnd .jstree-ok {
- background: green;
-}
-#jstree-dnd .jstree-er {
- background: red;
-}
-#jstree-dnd .jstree-copy {
- margin: 0 2px 0 2px;
-}
-.jstree-default .jstree-node,
-.jstree-default .jstree-icon {
- background-repeat: no-repeat;
- background-color: transparent;
-}
-.jstree-default .jstree-anchor,
-.jstree-default .jstree-wholerow {
- transition: background-color 0.15s, box-shadow 0.15s;
-}
-.jstree-default .jstree-hovered {
- background: #e7f4f9;
- border-radius: 2px;
- box-shadow: inset 0 0 1px #ccc;
-}
-.jstree-default .jstree-clicked {
- background: #beebff;
- border-radius: 2px;
- box-shadow: inset 0 0 1px #999;
-}
-.jstree-default .jstree-no-icons .jstree-anchor > .jstree-themeicon {
- display: none;
-}
-.jstree-default .jstree-disabled {
- background: transparent;
- color: #666;
-}
-.jstree-default .jstree-disabled.jstree-hovered {
- background: transparent;
- box-shadow: none;
-}
-.jstree-default .jstree-disabled.jstree-clicked {
- background: #efefef;
-}
-.jstree-default .jstree-disabled > .jstree-icon {
- opacity: 0.8;
- filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");
- /* Firefox 10+ */
- filter: gray;
- /* IE6-9 */
- -webkit-filter: grayscale(100%);
- /* Chrome 19+ & Safari 6+ */
-}
-.jstree-default .jstree-search {
- font-style: italic;
- color: #8b0000;
- font-weight: bold;
-}
-.jstree-default .jstree-no-checkboxes .jstree-checkbox {
- display: none !important;
-}
-.jstree-default.jstree-checkbox-no-clicked .jstree-clicked {
- background: transparent;
- box-shadow: none;
-}
-.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered {
- background: #e7f4f9;
-}
-.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked {
- background: transparent;
-}
-.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered {
- background: #e7f4f9;
-}
-#jstree-dnd.jstree-default .jstree-ok,
-#jstree-dnd.jstree-default .jstree-er {
- background-image: url("32px.png");
- background-repeat: no-repeat;
- background-color: transparent;
-}
-#jstree-dnd.jstree-default i {
- background: transparent;
- width: 16px;
- height: 16px;
-}
-#jstree-dnd.jstree-default .jstree-ok {
- background-position: -9px -71px;
-}
-#jstree-dnd.jstree-default .jstree-er {
- background-position: -39px -71px;
-}
-.jstree-default > .jstree-striped {
- background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat;
-}
-.jstree-default > .jstree-wholerow-ul .jstree-hovered,
-.jstree-default > .jstree-wholerow-ul .jstree-clicked {
- background: transparent;
- box-shadow: none;
- border-radius: 0;
-}
-.jstree-default .jstree-wholerow {
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
-}
-.jstree-default .jstree-wholerow-hovered {
- background: #e7f4f9;
-}
-.jstree-default .jstree-wholerow-clicked {
- background: #beebff;
- background: -moz-linear-gradient(top, #beebff 0%, #a8e4ff 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #beebff), color-stop(100%, #a8e4ff));
- background: -webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%);
- background: -o-linear-gradient(top, #beebff 0%, #a8e4ff 100%);
- background: -ms-linear-gradient(top, #beebff 0%, #a8e4ff 100%);
- background: linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%);
- /*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@color1', endColorstr='@color2',GradientType=0 );*/
-}
-.jstree-default .jstree-node {
- min-height: 24px;
- line-height: 24px;
- margin-left: 24px;
- min-width: 24px;
-}
-.jstree-default .jstree-anchor {
- line-height: 24px;
- height: 24px;
-}
-.jstree-default .jstree-icon {
- width: 24px;
- height: 24px;
- line-height: 24px;
-}
-.jstree-default .jstree-icon:empty {
- width: 24px;
- height: 24px;
- line-height: 24px;
-}
-.jstree-default.jstree-rtl .jstree-node {
- margin-right: 24px;
-}
-.jstree-default .jstree-wholerow {
- height: 24px;
-}
-.jstree-default .jstree-node,
-.jstree-default .jstree-icon {
- background-image: url("32px.png");
-}
-.jstree-default .jstree-node {
- background-position: -292px -4px;
- background-repeat: repeat-y;
-}
-.jstree-default .jstree-last {
- background: transparent;
-}
-.jstree-default .jstree-open > .jstree-ocl {
- background-position: -132px -4px;
-}
-.jstree-default .jstree-closed > .jstree-ocl {
- background-position: -100px -4px;
-}
-.jstree-default .jstree-leaf > .jstree-ocl {
- background-position: -68px -4px;
-}
-.jstree-default .jstree-anchor > .jstree-themeicon {
- background-position: -260px -4px;
-}
-.jstree-default > .jstree-no-dots .jstree-node,
-.jstree-default > .jstree-no-dots .jstree-leaf > .jstree-ocl {
- background: transparent;
-}
-.jstree-default > .jstree-no-dots .jstree-open > .jstree-ocl {
- background-position: -36px -4px;
-}
-.jstree-default > .jstree-no-dots .jstree-closed > .jstree-ocl {
- background-position: -4px -4px;
-}
-.jstree-default .jstree-disabled {
- background: transparent;
-}
-.jstree-default .jstree-disabled.jstree-hovered {
- background: transparent;
-}
-.jstree-default .jstree-disabled.jstree-clicked {
- background: #efefef;
-}
-.jstree-default .jstree-checkbox {
- background-position: -164px -4px;
-}
-.jstree-default .jstree-checkbox:hover {
- background-position: -164px -36px;
-}
-.jstree-default .jstree-clicked > .jstree-checkbox {
- background-position: -228px -4px;
-}
-.jstree-default .jstree-clicked > .jstree-checkbox:hover {
- background-position: -228px -36px;
-}
-.jstree-default .jstree-anchor > .jstree-undetermined {
- background-position: -196px -4px;
-}
-.jstree-default .jstree-anchor > .jstree-undetermined:hover {
- background-position: -196px -36px;
-}
-.jstree-default > .jstree-striped {
- background-size: auto 48px;
-}
-.jstree-default.jstree-rtl .jstree-node {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");
- background-position: 100% 1px;
- background-repeat: repeat-y;
-}
-.jstree-default.jstree-rtl .jstree-last {
- background: transparent;
-}
-.jstree-default.jstree-rtl .jstree-open > .jstree-ocl {
- background-position: -132px -36px;
-}
-.jstree-default.jstree-rtl .jstree-closed > .jstree-ocl {
- background-position: -100px -36px;
-}
-.jstree-default.jstree-rtl .jstree-leaf > .jstree-ocl {
- background-position: -68px -36px;
-}
-.jstree-default.jstree-rtl > .jstree-no-dots .jstree-node,
-.jstree-default.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl {
- background: transparent;
-}
-.jstree-default.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl {
- background-position: -36px -36px;
-}
-.jstree-default.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl {
- background-position: -4px -36px;
-}
-.jstree-default .jstree-themeicon-custom {
- background-color: transparent;
- background-image: none;
-}
-.jstree-default > .jstree-container-ul .jstree-loading > .jstree-ocl {
- background: url("throbber.gif") center center no-repeat;
-}
-.jstree-default.jstree-rtl .jstree-node {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");
-}
-.jstree-default.jstree-rtl .jstree-last {
- background: transparent;
-}
-.jstree-default-small .jstree-node {
- min-height: 18px;
- line-height: 18px;
- margin-left: 18px;
- min-width: 18px;
-}
-.jstree-default-small .jstree-anchor {
- line-height: 18px;
- height: 18px;
-}
-.jstree-default-small .jstree-icon {
- width: 18px;
- height: 18px;
- line-height: 18px;
-}
-.jstree-default-small .jstree-icon:empty {
- width: 18px;
- height: 18px;
- line-height: 18px;
-}
-.jstree-default-small.jstree-rtl .jstree-node {
- margin-right: 18px;
-}
-.jstree-default-small .jstree-wholerow {
- height: 18px;
-}
-.jstree-default-small .jstree-node,
-.jstree-default-small .jstree-icon {
- background-image: url("32px.png");
-}
-.jstree-default-small .jstree-node {
- background-position: -295px -7px;
- background-repeat: repeat-y;
-}
-.jstree-default-small .jstree-last {
- background: transparent;
-}
-.jstree-default-small .jstree-open > .jstree-ocl {
- background-position: -135px -7px;
-}
-.jstree-default-small .jstree-closed > .jstree-ocl {
- background-position: -103px -7px;
-}
-.jstree-default-small .jstree-leaf > .jstree-ocl {
- background-position: -71px -7px;
-}
-.jstree-default-small .jstree-anchor > .jstree-themeicon {
- background-position: -263px -7px;
-}
-.jstree-default-small > .jstree-no-dots .jstree-node,
-.jstree-default-small > .jstree-no-dots .jstree-leaf > .jstree-ocl {
- background: transparent;
-}
-.jstree-default-small > .jstree-no-dots .jstree-open > .jstree-ocl {
- background-position: -39px -7px;
-}
-.jstree-default-small > .jstree-no-dots .jstree-closed > .jstree-ocl {
- background-position: -7px -7px;
-}
-.jstree-default-small .jstree-disabled {
- background: transparent;
-}
-.jstree-default-small .jstree-disabled.jstree-hovered {
- background: transparent;
-}
-.jstree-default-small .jstree-disabled.jstree-clicked {
- background: #efefef;
-}
-.jstree-default-small .jstree-checkbox {
- background-position: -167px -7px;
-}
-.jstree-default-small .jstree-checkbox:hover {
- background-position: -167px -39px;
-}
-.jstree-default-small .jstree-clicked > .jstree-checkbox {
- background-position: -231px -7px;
-}
-.jstree-default-small .jstree-clicked > .jstree-checkbox:hover {
- background-position: -231px -39px;
-}
-.jstree-default-small .jstree-anchor > .jstree-undetermined {
- background-position: -199px -7px;
-}
-.jstree-default-small .jstree-anchor > .jstree-undetermined:hover {
- background-position: -199px -39px;
-}
-.jstree-default-small > .jstree-striped {
- background-size: auto 36px;
-}
-.jstree-default-small.jstree-rtl .jstree-node {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");
- background-position: 100% 1px;
- background-repeat: repeat-y;
-}
-.jstree-default-small.jstree-rtl .jstree-last {
- background: transparent;
-}
-.jstree-default-small.jstree-rtl .jstree-open > .jstree-ocl {
- background-position: -135px -39px;
-}
-.jstree-default-small.jstree-rtl .jstree-closed > .jstree-ocl {
- background-position: -103px -39px;
-}
-.jstree-default-small.jstree-rtl .jstree-leaf > .jstree-ocl {
- background-position: -71px -39px;
-}
-.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-node,
-.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl {
- background: transparent;
-}
-.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl {
- background-position: -39px -39px;
-}
-.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl {
- background-position: -7px -39px;
-}
-.jstree-default-small .jstree-themeicon-custom {
- background-color: transparent;
- background-image: none;
-}
-.jstree-default-small > .jstree-container-ul .jstree-loading > .jstree-ocl {
- background: url("throbber.gif") center center no-repeat;
-}
-.jstree-default-small.jstree-rtl .jstree-node {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==");
-}
-.jstree-default-small.jstree-rtl .jstree-last {
- background: transparent;
-}
-.jstree-default-large .jstree-node {
- min-height: 32px;
- line-height: 32px;
- margin-left: 32px;
- min-width: 32px;
-}
-.jstree-default-large .jstree-anchor {
- line-height: 32px;
- height: 32px;
-}
-.jstree-default-large .jstree-icon {
- width: 32px;
- height: 32px;
- line-height: 32px;
-}
-.jstree-default-large .jstree-icon:empty {
- width: 32px;
- height: 32px;
- line-height: 32px;
-}
-.jstree-default-large.jstree-rtl .jstree-node {
- margin-right: 32px;
-}
-.jstree-default-large .jstree-wholerow {
- height: 32px;
-}
-.jstree-default-large .jstree-node,
-.jstree-default-large .jstree-icon {
- background-image: url("32px.png");
-}
-.jstree-default-large .jstree-node {
- background-position: -288px 0px;
- background-repeat: repeat-y;
-}
-.jstree-default-large .jstree-last {
- background: transparent;
-}
-.jstree-default-large .jstree-open > .jstree-ocl {
- background-position: -128px 0px;
-}
-.jstree-default-large .jstree-closed > .jstree-ocl {
- background-position: -96px 0px;
-}
-.jstree-default-large .jstree-leaf > .jstree-ocl {
- background-position: -64px 0px;
-}
-.jstree-default-large .jstree-anchor > .jstree-themeicon {
- background-position: -256px 0px;
-}
-.jstree-default-large > .jstree-no-dots .jstree-node,
-.jstree-default-large > .jstree-no-dots .jstree-leaf > .jstree-ocl {
- background: transparent;
-}
-.jstree-default-large > .jstree-no-dots .jstree-open > .jstree-ocl {
- background-position: -32px 0px;
-}
-.jstree-default-large > .jstree-no-dots .jstree-closed > .jstree-ocl {
- background-position: 0px 0px;
-}
-.jstree-default-large .jstree-disabled {
- background: transparent;
-}
-.jstree-default-large .jstree-disabled.jstree-hovered {
- background: transparent;
-}
-.jstree-default-large .jstree-disabled.jstree-clicked {
- background: #efefef;
-}
-.jstree-default-large .jstree-checkbox {
- background-position: -160px 0px;
-}
-.jstree-default-large .jstree-checkbox:hover {
- background-position: -160px -32px;
-}
-.jstree-default-large .jstree-clicked > .jstree-checkbox {
- background-position: -224px 0px;
-}
-.jstree-default-large .jstree-clicked > .jstree-checkbox:hover {
- background-position: -224px -32px;
-}
-.jstree-default-large .jstree-anchor > .jstree-undetermined {
- background-position: -192px 0px;
-}
-.jstree-default-large .jstree-anchor > .jstree-undetermined:hover {
- background-position: -192px -32px;
-}
-.jstree-default-large > .jstree-striped {
- background-size: auto 64px;
-}
-.jstree-default-large.jstree-rtl .jstree-node {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");
- background-position: 100% 1px;
- background-repeat: repeat-y;
-}
-.jstree-default-large.jstree-rtl .jstree-last {
- background: transparent;
-}
-.jstree-default-large.jstree-rtl .jstree-open > .jstree-ocl {
- background-position: -128px -32px;
-}
-.jstree-default-large.jstree-rtl .jstree-closed > .jstree-ocl {
- background-position: -96px -32px;
-}
-.jstree-default-large.jstree-rtl .jstree-leaf > .jstree-ocl {
- background-position: -64px -32px;
-}
-.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-node,
-.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl {
- background: transparent;
-}
-.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl {
- background-position: -32px -32px;
-}
-.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl {
- background-position: 0px -32px;
-}
-.jstree-default-large .jstree-themeicon-custom {
- background-color: transparent;
- background-image: none;
-}
-.jstree-default-large > .jstree-container-ul .jstree-loading > .jstree-ocl {
- background: url("throbber.gif") center center no-repeat;
-}
-.jstree-default-large.jstree-rtl .jstree-node {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==");
-}
-.jstree-default-large.jstree-rtl .jstree-last {
- background: transparent;
-}
-@media (max-width: 768px) {
- .jstree-default-responsive {
- /*
- .jstree-open > .jstree-ocl,
- .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; }
- */
- }
- .jstree-default-responsive .jstree-icon {
- background-image: url("40px.png");
- }
- .jstree-default-responsive .jstree-node,
- .jstree-default-responsive .jstree-leaf > .jstree-ocl {
- background: transparent;
- }
- .jstree-default-responsive .jstree-node {
- min-height: 40px;
- line-height: 40px;
- margin-left: 40px;
- min-width: 40px;
- white-space: nowrap;
- }
- .jstree-default-responsive .jstree-anchor {
- line-height: 40px;
- height: 40px;
- }
- .jstree-default-responsive .jstree-icon,
- .jstree-default-responsive .jstree-icon:empty {
- width: 40px;
- height: 40px;
- line-height: 40px;
- }
- .jstree-default-responsive > .jstree-container-ul > .jstree-node {
- margin-left: 0;
- }
- .jstree-default-responsive.jstree-rtl .jstree-node {
- margin-left: 0;
- margin-right: 40px;
- }
- .jstree-default-responsive.jstree-rtl .jstree-container-ul > .jstree-node {
- margin-right: 0;
- }
- .jstree-default-responsive .jstree-ocl,
- .jstree-default-responsive .jstree-themeicon,
- .jstree-default-responsive .jstree-checkbox {
- background-size: 120px 200px;
- }
- .jstree-default-responsive .jstree-leaf > .jstree-ocl {
- background: transparent;
- }
- .jstree-default-responsive .jstree-open > .jstree-ocl {
- background-position: 0 0px !important;
- }
- .jstree-default-responsive .jstree-closed > .jstree-ocl {
- background-position: 0 -40px !important;
- }
- .jstree-default-responsive.jstree-rtl .jstree-closed > .jstree-ocl {
- background-position: -40px 0px !important;
- }
- .jstree-default-responsive .jstree-anchor > .jstree-themeicon {
- background-position: -40px -40px;
- }
- .jstree-default-responsive .jstree-checkbox,
- .jstree-default-responsive .jstree-checkbox:hover {
- background-position: -40px -80px;
- }
- .jstree-default-responsive .jstree-clicked > .jstree-checkbox,
- .jstree-default-responsive .jstree-clicked > .jstree-checkbox:hover {
- background-position: 0 -80px;
- }
- .jstree-default-responsive .jstree-anchor > .jstree-undetermined,
- .jstree-default-responsive .jstree-anchor > .jstree-undetermined:hover {
- background-position: 0 -120px;
- }
- .jstree-default-responsive .jstree-anchor {
- font-weight: bold;
- font-size: 1.1em;
- text-shadow: 1px 1px white;
- }
- .jstree-default-responsive > .jstree-striped {
- background: transparent;
- }
- .jstree-default-responsive .jstree-wholerow {
- border-top: 1px solid rgba(255, 255, 255, 0.7);
- border-bottom: 1px solid rgba(64, 64, 64, 0.2);
- background: #ebebeb;
- height: 40px;
- }
- .jstree-default-responsive .jstree-wholerow-hovered {
- background: #e7f4f9;
- }
- .jstree-default-responsive .jstree-wholerow-clicked {
- background: #beebff;
- }
- .jstree-default-responsive .jstree-children .jstree-last > .jstree-wholerow {
- box-shadow: inset 0 -6px 3px -5px #666666;
- }
- .jstree-default-responsive .jstree-children .jstree-open > .jstree-wholerow {
- box-shadow: inset 0 6px 3px -5px #666666;
- border-top: 0;
- }
- .jstree-default-responsive .jstree-children .jstree-open + .jstree-open {
- box-shadow: none;
- }
- .jstree-default-responsive .jstree-node,
- .jstree-default-responsive .jstree-icon,
- .jstree-default-responsive .jstree-node > .jstree-ocl,
- .jstree-default-responsive .jstree-themeicon,
- .jstree-default-responsive .jstree-checkbox {
- background-image: url("40px.png");
- background-size: 120px 200px;
- }
- .jstree-default-responsive .jstree-node {
- background-position: -80px 0;
- background-repeat: repeat-y;
- }
- .jstree-default-responsive .jstree-last {
- background: transparent;
- }
- .jstree-default-responsive .jstree-leaf > .jstree-ocl {
- background-position: -40px -120px;
- }
- .jstree-default-responsive .jstree-last > .jstree-ocl {
- background-position: -40px -160px;
- }
- .jstree-default-responsive .jstree-themeicon-custom {
- background-color: transparent;
- background-image: none;
- }
-}
-.jstree-default > .jstree-container-ul > .jstree-node {
- margin-left: 0;
- margin-right: 0;
-}
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/jstree/style.min.css b/Duplicati/Server/webroot/greeno/stylesheets/jstree/style.min.css
deleted file mode 100755
index 020af9f62..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/jstree/style.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:#000;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;-moz-box-shadow:5px 5px 4px -4px #666;-webkit-box-shadow:2px 2px 2px #999;box-shadow:2px 2px 2px #999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none;display:inline}.vakata-context li>a{display:block;padding:0 2em;text-decoration:none;width:auto;color:#000;white-space:nowrap;line-height:2.4em;-moz-text-shadow:1px 1px 0 #fff;-webkit-text-shadow:1px 1px 0 #fff;text-shadow:1px 1px 0 #fff;-moz-border-radius:1px;-webkit-border-radius:1px;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;-moz-box-shadow:0 0 2px #0a6aa1;-webkit-box-shadow:0 0 2px #0a6aa1;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==);background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;-moz-box-shadow:0 0 2px #0a6aa1;-webkit-box-shadow:0 0 2px #0a6aa1;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator a,.vakata-context .vakata-context-separator a:hover{background:#fff;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;-moz-text-shadow:0 0 0 transparent;-webkit-text-shadow:0 0 0 transparent;text-shadow:0 0 0 transparent;-moz-box-shadow:0 0 0 transparent;-webkit-box-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:0 0;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:#fff;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7);background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:#fff;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #ccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:0 0;color:#666}.jstree-default .jstree-disabled.jstree-hovered{background:0 0;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:700}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none!important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:0 0;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:0 0}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:0 0;width:16px;height:16px}#jstree-dnd.jstree-default .jstree-ok{background-position:-9px -71px}#jstree-dnd.jstree-default .jstree-er{background-position:-39px -71px}.jstree-default>.jstree-striped{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==) left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:0 0;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-moz-linear-gradient(top,#beebff 0,#a8e4ff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#beebff),color-stop(100%,#a8e4ff));background:-webkit-linear-gradient(top,#beebff 0,#a8e4ff 100%);background:-o-linear-gradient(top,#beebff 0,#a8e4ff 100%);background:-ms-linear-gradient(top,#beebff 0,#a8e4ff 100%);background:linear-gradient(to bottom,#beebff 0,#a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url(32px.png)}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background:0 0}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-anchor>.jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:0 0}.jstree-default .jstree-disabled.jstree-hovered{background:0 0}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default .jstree-clicked>.jstree-checkbox{background-position:-228px -4px}.jstree-default .jstree-clicked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background:0 0}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==)}.jstree-default.jstree-rtl .jstree-last{background:0 0}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url(32px.png)}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background:0 0}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-anchor>.jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:0 0}.jstree-default-small .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small .jstree-clicked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small .jstree-clicked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==)}.jstree-default-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url(32px.png)}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background:0 0}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-anchor>.jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:0 0}.jstree-default-large .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large .jstree-clicked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large .jstree-clicked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background:0 0}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==)}.jstree-default-large.jstree-rtl .jstree-last{background:0 0}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url(40px.png)}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 200px}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0!important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px!important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0!important}.jstree-default-responsive .jstree-anchor>.jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive .jstree-clicked>.jstree-checkbox,.jstree-default-responsive .jstree-clicked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}.jstree-default-responsive>.jstree-striped{background:0 0}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,.7);border-bottom:1px solid rgba(64,64,64,.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url(40px.png);background-size:120px 200px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background:0 0}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none}}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/jstree/throbber.gif b/Duplicati/Server/webroot/greeno/stylesheets/jstree/throbber.gif
deleted file mode 100755
index 1b5b2fde4..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/jstree/throbber.gif
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/logwindow.css b/Duplicati/Server/webroot/greeno/stylesheets/logwindow.css
deleted file mode 100644
index 06379c0a8..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/logwindow.css
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * CSS config for the log window
- */
-
-#log-dialog .log-backupid, #log-dialog .log-exception,
-#backup-log-tab-general .log-backupid, #backup-log-tab-general .log-exception, #backup-log-tab-general .log-message,
-#backup-log-tab-remote .log-operationid, #backup-log-tab-remote .log-data
-{
- display: none;
-}
-
-#log-dialog .log-message, #log-dialog .log-timestamp,
-#backup-log-tab-general .log-timestamp, #backup-log-tab-general .log-type,
-#backup-log-tab-remote .log-timestamp, #backup-log-tab-remote .log-type, #backup-log-tab-remote .log-path
-{
- display: inline-block;
- cursor: pointer;
-}
-
-#log-dialog .expanded div.log-exception,
-#backup-log-tab-general .expanded div.log-exception, #backup-log-tab-general .expanded div.log-message,
-#backup-log-tab-remote .expanded div.log-data
-{
- display: block;
- background-color: #ffffff;
- padding-left: 5px;
- padding-right: 5px;
-}
-
-#log-tab-live .log-entry .log-message
-{
- display: inline;
-}
-
-
-#log-tab-live .log-entry
-{
- height: 1.2em;
- overflow: hidden;
-}
-
-#log-tab-live .log-entry.expanded
-{
- height: auto;
-}
-
-
-
-
-
-
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/main.css b/Duplicati/Server/webroot/greeno/stylesheets/main.css
deleted file mode 100644
index afe3ae1b9..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/main.css
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * CSS config for the main window
- */
-
-#main-topbar {
- position: absolute;
- left: 0px;
- right: 0px;
- height: 46px;
- background-color: #3a5e30;
- color: #9dab98;
- vertical-align: middle;
-}
-
-#main-list {
- padding-top: 82px;
- overflow: auto;
- padding-bottom: 60px;
-}
-
-#main-list-container {
- background-color: #f3f3f3;
- overflow: hidden;
- /*min-height: calc(100vh - 82px);*/
-}
-
-#main-appname {
- display: inline-block;
- font-family: "Arial Black", "GillSans", Helvetica, Arial, sans-serif;
- font-size: 24px;
- font-weight: bold;
- line-height: 46px;
- text-transform: uppercase;
-}
-
-#main-appname.has-subtitle {
- padding-top: 5px;
- font-size: 16pt;
-}
-
-#main-appname-subtitle {
- font-size: 7em;
- font-weight: normal;
- font-style: italic;
-}
-
-#main-newbackup, #main-restorebackup {
- color: white;
- cursor: pointer;
- border-radius: 3px;
- display: inline-block;
- font-size: 12pt;
- clear: both;
- float: left;
- margin-top: 40px;
- margin-bottom: 0px;
-}
-
-#main-control-menu {
- margin-right: 10px;
-}
-
-.main-shortcuts {
- float: right;
- padding-top: 8px;
- padding-right: 8px;
- margin: 0px;
- padding-left: 0px;
- list-style: none;
-}
-
-.main-shortcuts li {
- padding-left: 8px;
- padding-right: 4px;
- cursor: pointer;
- background-color: #3a5e30;
- display: inline-block;
-}
-
-.main-backup-entry, #main-newbackup, #main-restorebackup {
- margin-top: 20px;
- clear: both;
- display: inline-block;
- height: 150px;
- width: 350px;
- vertical-align: top;
-}
-
-#main-restorebackup, #main-newbackup {
- margin-top: 0px;
- width: 1000px;
- height: auto;
-}
-
-.main-backup-entry .action-links {
- display: block;
- margin-top: 10px;
- padding-left: 0px;
-}
-
-.main-backup-entry ul.hint-text, #main-newbackup > ul.hint-text, #main-restorebackup > ul.hint-text {
- list-style: none;
- padding: 0px;
- margin: 0px;
-}
-.main-backup-entry ul.hint-text > li, #main-newbackup > ul.hint-text > li, #main-restorebackup > ul.hint-text > li {
- display: inline-block;
-}
-
-.main-backup-entry .action-links li {
- display: inline;
- border-right: 1px solid #56acbb;
- padding-left: 5px;
- padding-right: 5px;
-}
-
-.main-backup-entry .action-links .last {
- border-right: 0px none;
- padding-right: 0px;
-}
-
-.main-backup-entry .action-links .first {
- padding-left: 0px;
-}
-
-.main-backup-entry .hint-text-caption {
- padding-right: 5px;
-}
-
-.main-backup-entry .caption-text, #main-newbackup .caption-text, #main-restorebackup .caption-text {
- margin-bottom: 10px;
-}
-
-.main-backup-entry > .last-run-time.last-run-failed {
- color: red;
-}
-
-div.main-icon-plus {
- width: 24px;
- height: 24px;
- display: block;
- background-repeat: no-repeat;
- background-image: url('../images/plus.png');
-}
-
-div.main-icon-restore {
- width: 24px;
- height: 24px;
- display: block;
- background-repeat: no-repeat;
- background-image: url('../images/restore.png');
-}
-
-.main-icon-clock {
- width: 23px;
- height: 23px;
- background-repeat: no-repeat;
- background-image: url('../images/clock.png');
-}
-
-.main-icon-donate {
- width: 28px;
- height: 28px;
- background-repeat: no-repeat;
- background-image: url('../images/donate.png');
-}
-
-.main-icon-hourglass {
- width: 18px;
- height: 24px;
- background-repeat: no-repeat;
- background-image: url('../images/hourglass.png');
-}
-
-.main-icon-pause {
- width: 24px;
- height: 24px;
- background-repeat: no-repeat;
- background-image: url('../images/pause.png');
-}
-
-.main-icon-run {
- width: 24px;
- height: 24px;
- background-repeat: no-repeat;
- background-image: url('../images/play.png');
-}
-
-.main-icon-settings {
- width: 24px;
- height: 24px;
- background-repeat: no-repeat;
- background-image: url('../images/menu-grey.png');
-}
-
-.main-icon-small-close {
- width: 19px;
- height: 19px;
- background-repeat: no-repeat;
- background-image: url('../images/small-close');
-}
-
-#main-newbackup .main-icon-plus, #main-restorebackup .main-icon-restore {
- display: inline-block;
-}
-
-.main-backup-control {
- display: block;
- width: 24px;
- height: 24px;
- margin-left: 0px;
- margin-top: 4px;
- position: absolute;
- background-image: url('../images/menu-grey-small.png');
-}
-
-.main-backup-entry .caption-text, .main-backup-entry ul.hint-text, #main-newbackup > .caption-text, #main-newbackup > ul.hint-text, #main-restorebackup > .caption-text, #main-restorebackup > ul.hint-text {
- margin-left: 42px;
-}
-
-.main-backup-action-buttons > .caption-text {
- font-size: 14pt;
- margin-top: 4px;
-}
-
-.main-button-add-text {
- display: inline-block;
- vertical-align: top;
- padding-left: 10px;
- padding-top: 4px;
-}
-
-.progress-area {
- background-color: #c8d1c5;
- color: #8f968e;
- border-radius: 3px;
- display: block;
- padding: 6px 12px 6px 12px;
- display: block;
- position: relative;
-}
-
-.in-progress {
- color: #ecf0eb;
- min-height: 23px;
-}
-
-.main-progress-cell {
- width: 100%;
-}
-
-.progress-area .main-icon-hourglass, .progress-area .main-icon-clock {
- display: inline-block;
- margin-right: 8px;
-}
-
-.main-progress-text {
- display: inline-block;
- vertical-align: top;
- padding-top: 4px;
- white-space: nowrap;
- position: relative;
-}
-
-.backup-progress-indeterminate {
- background-image: url('green-theme/images/animated-overlay.gif');
-}
-
-.backup-progress-overall {
- border-radius: 3px;
- display: block;
- height: 100%;
- width: 20%;
- background-color: green;
- display: block;
- position: absolute;
- top: 0px;
- left: 0;
-
-}
-.backup-details {
- float: left;
- width: 300px;
-}
-
-.backup-progress {
- float: left;
- padding-bottom: 20px;
- min-width: 250px;
- white-space: nowrap;
- position: relative;
-}
-
-#edit-dialog {
- padding: 0px;
- border: 0px none;
-}
-
-/* Merge tabs in dialog */
-#backup-log-dialog, #log-dialog, #about-dialog {
- padding: 0px;
- border: 0px none;
- width: 100%;
- border-top-left-radius: 0px;
- border-top-right-radius: 0px;
-}
-
-.ui-dialog-titlebar {
- border-bottom-right-radius: 0px;
- border-bottom-left-radius: 0px;
-}
-
-#click-intercept {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- display: none;
- z-index: 9999;
-}
-
-#about-dialog-current {
- margin-bottom: 10px;
- margin-top: 10px;
-}
-
-.about-library-entry {
- margin-bottom: 10px;
- margin-top: 10px;
-}
-
-.about-library-name {
- font-weight: bold;
-}
-
-.about-library-name, .about-library-description, .about-library-license {
- display: inline;
-}
-
-.about-library-notes {
- display: none;
-}
-
-.main-status-area-outer {
- position: absolute;
- top: 46px;
- left: 0px;
- right: 0px;
- height: auto;
- z-index: 1;
- overflow: hidden;
- background-color: #91AA8A;
-}
-
-#main-status-area {
- font-size: 14px;
- margin-left: auto;
- margin-right: auto;
- height: 20px;
- padding: 8px 0;
- color: #f0f0f0;
-}
-
-#main-status-area-text {
- display: inline-block;
- min-width: 100px;
-}
-
-#main-status-area-progress-text {
- position: relative;
- z-index: 1;
- margin-left: 5px;
- margin-right: 5px;
- text-shadow:
- -1px -1px 0 #f0f0f0,
- 1px -1px 0 #f0f0f0,
- -1px 1px 0 #f0f0f0,
- 1px 1px 0 #f0f0f0;
-}
-
-#main-status-area-progress-outer {
- background-color: #f0f0f0;
- min-width: 180px;
- margin-left: 20px;
- float: right;
- position: relative;
- color: #3a5e30;
- border-radius: 100px;
- overflow: hidden;
-}
-
-#main-status-area-cancel-button {
- height: 19px;
- width: 19px;
- float: right;
- background-image: url('../images/small-close.png');
- cursor: pointer;
-}
-
-#main-status-area-progress-bar {
- border-radius: 100px;
- position: absolute;
- background-color: #ccc;
- height: 100%;
- width: 30%;
-}
-
-#about-dialog-current-version {
- display: inline;
-}
-
-#about-dialog-changelog, .noty-update-changelog-link {
- display: inline;
- cursor: pointer;
- text-decoration: underline;
-}
-
-.export-dialog-label, .import-dialog-label {
- display: inline;
-}
-
- .ui-icon-inline {
- display: inline-block;
- }
-
- #options-dialog .options-header {
- font-size: 22px;
- font-weight: bold;
- }
-
-#options-dialog .options-items, #options-dialog .edit-dialog-label {
- margin-left: 10px;
-}
-
-#options-dialog .hint-line-last {
- margin-left: 10px;
- font-style: italic;
-}
-
-#options-dialog .options-items > div {
- display: inline-block;
-}
-
-#options-dialog .options-header {
- padding-top: 15px;
-}
-
-#options-dialog .options-header.options-header-first {
- padding-top: 0px;
-}
-
-#global-advanced-options, #global-webservice-options {
- width: 320px;
-}
-
-#global-options-startup-delay-multiplier {
- width: 270px;
-}
-
-#webservice-password-label {
- min-width: 180px;
-}
-
-#source-folder-filter-area {
- margin-top: 10px;
-}
-
-#backup-context-menu > li > u {
- text-decoration: none;
-}
-
-#backup-context-menu > li > u > b {
- padding: 0.4em;
- padding-top: 2px;
- color: #7f7f7f;
-}
-
-/*
-* custom CSS
-*/
-
-header {
- position: fixed;
- width: 100%;
- z-index: 100;
-}
-
-footer{
- height: 50px;
- width: 100%;
- background-color: #3A5E30;
- color: #F0F0F0;
- bottom:0px;
- position:fixed;
- border-top: 10px solid #91AA8A;
- z-index: 100;
-}
-
-a.link_extern:hover, a.link_extern:active , a.link_extern:visited, a.link_extern:link {
- color: #F0F0F0;
-}
-
-div.box-duplicati-copy{
- float:left;
- margin-left:5px;
- text-align: left;
-}
-
-div.box-visit-us{
- float:right;
- margin-right: 5px;
- text-align: right;
-}
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/restoredialog.css b/Duplicati/Server/webroot/greeno/stylesheets/restoredialog.css
deleted file mode 100644
index ee6191741..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/restoredialog.css
+++ /dev/null
@@ -1,60 +0,0 @@
-#restore-dialog {
- overflow: hidden;
-}
-
-#restore-files-tree {
- overflow: auto;
- position: absolute;
- top: 58px;
- bottom: 16px;
- left: 16px;
- right: 8px;
-}
-
-#restore-search {
- width: 320px;
-}
-
-#restore-version {
- float: right;
-}
-
-.search-match {
- display: inline;
- font-weight: bold;
- color: black;
-}
-
-#restore-hint-paypal, #restore-hint-bitcoin {
- background-color: #9b9b9b;
- color: black;
- padding: 20px;
- border-radius: 8px;
- font-weight: bold;
- margin: 20px;
- cursor: pointer;
-}
-
-#restore-complete-page > .hint-text {
- margin: 20px;
-}
-
-#restore-hint-paypal > a, #restore-hint-bitcoin > a {
- color: black;
- text-decoration: none;
-}
-
-a.restore-current-time {
- font-weight: bold !important;
- color: black !important;
-}
-
-#restore-search-loader {
- display: inline-block;
- margin-left: 10px;
-}
-
-#restore-hint-overwrite, #restore-hint-metadata {
- margin-top: 20px;
-}
-
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/animated-overlay.gif b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/animated-overlay.gif
deleted file mode 100755
index d441f75eb..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/animated-overlay.gif
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
deleted file mode 100755
index c09235f60..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
deleted file mode 100755
index d29011d2a..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
deleted file mode 100755
index 1558bea51..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
deleted file mode 100755
index 0359b121f..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_75_dadada_1x400.png
deleted file mode 100755
index 4fce6c462..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_75_dadada_1x400.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
deleted file mode 100755
index 5299b5a0b..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
deleted file mode 100755
index 398c56a9c..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
deleted file mode 100755
index d819aa58a..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_222222_256x240.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_222222_256x240.png
deleted file mode 100755
index c1cb1170c..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_222222_256x240.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_2e83ff_256x240.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_2e83ff_256x240.png
deleted file mode 100755
index 84b601bf0..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_2e83ff_256x240.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_454545_256x240.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_454545_256x240.png
deleted file mode 100755
index b6db1acdd..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_454545_256x240.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_888888_256x240.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_888888_256x240.png
deleted file mode 100755
index feea0e202..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_888888_256x240.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_cd0a0a_256x240.png b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_cd0a0a_256x240.png
deleted file mode 100755
index ed5b6b093..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/images/ui-icons_cd0a0a_256x240.png
+++ /dev/null
Binary files differ
diff --git a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/jquery-ui-1.10.3.min.css b/Duplicati/Server/webroot/greeno/stylesheets/smoothness/jquery-ui-1.10.3.min.css
deleted file mode 100755
index a2371e3e6..000000000
--- a/Duplicati/Server/webroot/greeno/stylesheets/smoothness/jquery-ui-1.10.3.min.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/*! jQuery UI - v1.10.3 - 2013-12-08
-* http://jqueryui.com
-* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
-* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
-* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
-
-.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;min-height:0}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:21px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;min-height:0;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("images/animated-overlay.gif");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
diff --git a/Duplicati/Server/webroot/img/logo.png b/Duplicati/Server/webroot/img/logo.png
new file mode 100644
index 000000000..4600ffd78
--- /dev/null
+++ b/Duplicati/Server/webroot/img/logo.png
Binary files differ
diff --git a/Duplicati/Server/webroot/index.html b/Duplicati/Server/webroot/index.html
index c96c0407a..037af2924 100644
--- a/Duplicati/Server/webroot/index.html
+++ b/Duplicati/Server/webroot/index.html
@@ -41,6 +41,8 @@
var theme = parseCookies()['default-theme'];
if ((theme || '').trim().length == 0)
theme = 'ngax';
+ if (theme == 'greeno') // Make sure users are redirected automatically
+ theme = 'ngax';
setCookieAndRun(theme); // Refresh
diff --git a/Duplicati/Server/webroot/login.html b/Duplicati/Server/webroot/login.html
index acfc49c00..0ad4b6887 100644
--- a/Duplicati/Server/webroot/login.html
+++ b/Duplicati/Server/webroot/login.html
@@ -4,10 +4,10 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
- <title>Login</title>
+ <title>Duplicati Login</title>
- <script type="text/javascript" src="greeno/scripts/jquery-2.0.3.min.js"></script>
- <script type="text/javascript" src="greeno/scripts/cryptojs.js"></script>
+ <script type="text/javascript" src="login/jquery-2.0.3.min.js"></script>
+ <script type="text/javascript" src="login/cryptojs.js"></script>
<script type="text/javascript" src="login/login.js"></script>
<link rel="stylesheet" type="text/css" href="login/login.css" />
diff --git a/Duplicati/Server/webroot/greeno/scripts/cryptojs.js b/Duplicati/Server/webroot/login/cryptojs.js
index b4beb366a..b4beb366a 100644
--- a/Duplicati/Server/webroot/greeno/scripts/cryptojs.js
+++ b/Duplicati/Server/webroot/login/cryptojs.js
diff --git a/Duplicati/Server/webroot/greeno/scripts/jquery-2.0.3.min.js b/Duplicati/Server/webroot/login/jquery-2.0.3.min.js
index 2be209dd2..2be209dd2 100644
--- a/Duplicati/Server/webroot/greeno/scripts/jquery-2.0.3.min.js
+++ b/Duplicati/Server/webroot/login/jquery-2.0.3.min.js
diff --git a/Duplicati/Server/webroot/greeno/jquery-2.0.3.min.map b/Duplicati/Server/webroot/login/jquery-2.0.3.min.map
index 472d71bb0..472d71bb0 100644
--- a/Duplicati/Server/webroot/greeno/jquery-2.0.3.min.map
+++ b/Duplicati/Server/webroot/login/jquery-2.0.3.min.map
diff --git a/Duplicati/Server/webroot/login/login.css b/Duplicati/Server/webroot/login/login.css
index fa4d9e46c..f01a7829b 100644
--- a/Duplicati/Server/webroot/login/login.css
+++ b/Duplicati/Server/webroot/login/login.css
@@ -1,9 +1,12 @@
@charset "utf-8";
+* {
+ font-family: 'Clear Sans', sans-serif;
+}
body {
background: #C0C0C0;
color: #000;
- font: 100%/1.5em "Arial Black","GillSans",Helvetica,Arial,sans-serif;
+ font: 100%/1.5em;
margin: 0;
}
@@ -25,10 +28,9 @@ input {
}
#login h2 {
- background: #3A5E30;
- color: #9DAB98;
+ background: #65b1dd;
+ color: #d3d3d3;
font-size: 28px;
- text-transform: uppercase;
border-radius: 20px 20px 0 0;
padding: 18px 20px;
margin: 0px;
@@ -63,8 +65,8 @@ input {
}
#login fieldset input[type="submit"] {
- background: #91AA8A;
- color: #000000;
+ background: #65b1dd;
+ color: #fff;
width: 100px;
display: block;
margin: 0 auto;
@@ -72,5 +74,5 @@ input {
}
#login fieldset input[type="submit"]:hover {
- background: #91AA8A;
+ background: #65b1dd;
}
diff --git a/Duplicati/Server/webroot/login/login.js b/Duplicati/Server/webroot/login/login.js
index 0743b0206..e2c2de461 100644
--- a/Duplicati/Server/webroot/login/login.js
+++ b/Duplicati/Server/webroot/login/login.js
@@ -10,8 +10,8 @@ $(document).ready(function() {
// First we grab the nonce and salt
$.ajax({
- url: '/login.cgi',
- type: 'GET',
+ url: './login.cgi',
+ type: 'POST',
dataType: 'json',
data: {'get-nonce': 1}
})
@@ -21,8 +21,8 @@ $(document).ready(function() {
var noncedpwd = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse(data.Nonce) + saltedpwd)).toString(CryptoJS.enc.Base64);
$.ajax({
- url: '/login.cgi',
- type: 'GET',
+ url: './login.cgi',
+ type: 'POST',
dataType: 'json',
data: {'password': noncedpwd }
})
diff --git a/Duplicati/Server/webroot/ngax/favicon/android-icon-144x144.png b/Duplicati/Server/webroot/ngax/favicon/android-icon-144x144.png
index 46bc3bad5..749517259 100644
--- a/Duplicati/Server/webroot/ngax/favicon/android-icon-144x144.png
+++ b/Duplicati/Server/webroot/ngax/favicon/android-icon-144x144.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/android-icon-192x192.png b/Duplicati/Server/webroot/ngax/favicon/android-icon-192x192.png
index ee63f8053..3e38d7e91 100644
--- a/Duplicati/Server/webroot/ngax/favicon/android-icon-192x192.png
+++ b/Duplicati/Server/webroot/ngax/favicon/android-icon-192x192.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/android-icon-36x36.png b/Duplicati/Server/webroot/ngax/favicon/android-icon-36x36.png
index 32573f475..576c23c61 100644
--- a/Duplicati/Server/webroot/ngax/favicon/android-icon-36x36.png
+++ b/Duplicati/Server/webroot/ngax/favicon/android-icon-36x36.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/android-icon-48x48.png b/Duplicati/Server/webroot/ngax/favicon/android-icon-48x48.png
index 78081895a..e6b58b32f 100644
--- a/Duplicati/Server/webroot/ngax/favicon/android-icon-48x48.png
+++ b/Duplicati/Server/webroot/ngax/favicon/android-icon-48x48.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/android-icon-72x72.png b/Duplicati/Server/webroot/ngax/favicon/android-icon-72x72.png
index 14f0a518d..18e4e4664 100644
--- a/Duplicati/Server/webroot/ngax/favicon/android-icon-72x72.png
+++ b/Duplicati/Server/webroot/ngax/favicon/android-icon-72x72.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/android-icon-96x96.png b/Duplicati/Server/webroot/ngax/favicon/android-icon-96x96.png
index afc63e880..298a528da 100644
--- a/Duplicati/Server/webroot/ngax/favicon/android-icon-96x96.png
+++ b/Duplicati/Server/webroot/ngax/favicon/android-icon-96x96.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-114x114.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-114x114.png
index c0a85028b..e11f63977 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-114x114.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-114x114.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-120x120.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-120x120.png
index 0738d5ce7..714d96328 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-120x120.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-120x120.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-144x144.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-144x144.png
index 46bc3bad5..749517259 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-144x144.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-144x144.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-152x152.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-152x152.png
index 60bb2e782..d76d459e5 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-152x152.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-152x152.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-180x180.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-180x180.png
index 4beea6405..3aa575f79 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-180x180.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-180x180.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-57x57.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-57x57.png
index db6bbdc6d..95f8c696f 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-57x57.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-57x57.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-60x60.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-60x60.png
index 9462147b8..dc0a78e45 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-60x60.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-60x60.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-72x72.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-72x72.png
index 14f0a518d..18e4e4664 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-72x72.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-72x72.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-76x76.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-76x76.png
index 95c4d2a69..881830e92 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-76x76.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-76x76.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon-precomposed.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon-precomposed.png
index 91066267b..3e38d7e91 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon-precomposed.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon-precomposed.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/apple-icon.png b/Duplicati/Server/webroot/ngax/favicon/apple-icon.png
index 91066267b..3e38d7e91 100644
--- a/Duplicati/Server/webroot/ngax/favicon/apple-icon.png
+++ b/Duplicati/Server/webroot/ngax/favicon/apple-icon.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/favicon-16x16.png b/Duplicati/Server/webroot/ngax/favicon/favicon-16x16.png
index 97b599e42..be29d0917 100644
--- a/Duplicati/Server/webroot/ngax/favicon/favicon-16x16.png
+++ b/Duplicati/Server/webroot/ngax/favicon/favicon-16x16.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/favicon-32x32.png b/Duplicati/Server/webroot/ngax/favicon/favicon-32x32.png
index 773c50ec9..a529c335f 100644
--- a/Duplicati/Server/webroot/ngax/favicon/favicon-32x32.png
+++ b/Duplicati/Server/webroot/ngax/favicon/favicon-32x32.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/favicon-96x96.png b/Duplicati/Server/webroot/ngax/favicon/favicon-96x96.png
index afc63e880..298a528da 100644
--- a/Duplicati/Server/webroot/ngax/favicon/favicon-96x96.png
+++ b/Duplicati/Server/webroot/ngax/favicon/favicon-96x96.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/ms-icon-144x144.png b/Duplicati/Server/webroot/ngax/favicon/ms-icon-144x144.png
index 46bc3bad5..749517259 100644
--- a/Duplicati/Server/webroot/ngax/favicon/ms-icon-144x144.png
+++ b/Duplicati/Server/webroot/ngax/favicon/ms-icon-144x144.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/ms-icon-150x150.png b/Duplicati/Server/webroot/ngax/favicon/ms-icon-150x150.png
index 41738f7fa..2e7284956 100644
--- a/Duplicati/Server/webroot/ngax/favicon/ms-icon-150x150.png
+++ b/Duplicati/Server/webroot/ngax/favicon/ms-icon-150x150.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/ms-icon-310x310.png b/Duplicati/Server/webroot/ngax/favicon/ms-icon-310x310.png
index c6f0a92c4..358ac013f 100644
--- a/Duplicati/Server/webroot/ngax/favicon/ms-icon-310x310.png
+++ b/Duplicati/Server/webroot/ngax/favicon/ms-icon-310x310.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/favicon/ms-icon-70x70.png b/Duplicati/Server/webroot/ngax/favicon/ms-icon-70x70.png
index 7a75fe0eb..f51ae4099 100644
--- a/Duplicati/Server/webroot/ngax/favicon/ms-icon-70x70.png
+++ b/Duplicati/Server/webroot/ngax/favicon/ms-icon-70x70.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.eot b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.eot
index 3678ef2a4..8a75af5bf 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.eot
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.eot
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.svg b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.svg
index aa985aebf..4464a061e 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.svg
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.svg
@@ -3,15 +3,14 @@
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
-<font id="clear_sansbold" horiz-adv-x="1217" >
+<font id="clear_sansbold" horiz-adv-x="1044" >
<font-face units-per-em="2048" ascent="1489" descent="-559" />
<missing-glyph horiz-adv-x="492" />
-<glyph unicode="&#xfb01;" horiz-adv-x="1208" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM790 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34 t-29.5 97zM804 0v1049h258v-1049h-258z" />
-<glyph unicode="&#xfb02;" horiz-adv-x="1208" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM804 0v1489h258v-1489h-258z" />
-<glyph unicode="&#xfb03;" horiz-adv-x="1868" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM694 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5 t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM1450 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97zM1464 0v1049h258v-1049h-258z" />
-<glyph unicode="&#xfb04;" horiz-adv-x="1868" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM694 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5 t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM1464 0v1489h258v-1489h-258z" />
-<glyph horiz-adv-x="0" />
-<glyph unicode="&#xd;" horiz-adv-x="492" />
+<glyph unicode="ff" horiz-adv-x="1319" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM694 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5 t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133z" />
+<glyph unicode="fi" horiz-adv-x="1208" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM790 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34 t-29.5 97zM804 0v1049h258v-1049h-258z" />
+<glyph unicode="fl" horiz-adv-x="1208" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM804 0v1489h258v-1489h-258z" />
+<glyph unicode="ffi" horiz-adv-x="1868" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM694 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5 t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM1450 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97zM1464 0v1049h258v-1049h-258z" />
+<glyph unicode="ffl" horiz-adv-x="1868" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM694 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5 t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM1464 0v1489h258v-1489h-258z" />
<glyph horiz-adv-x="0" />
<glyph horiz-adv-x="0" />
<glyph unicode=" " horiz-adv-x="492" />
@@ -80,28 +79,28 @@
<glyph unicode="]" horiz-adv-x="764" d="M61 -188h310v1470h-310v207h549v-1884h-549v207z" />
<glyph unicode="^" horiz-adv-x="1300" d="M123 594l434 790h186l435 -790h-220l-307 557l-309 -557h-219z" />
<glyph unicode="_" horiz-adv-x="1024" d="M-10 -154h1044v-102h-1044v102z" />
-<glyph unicode="`" horiz-adv-x="1044" d="M195 1569h315l188 -361h-204z" />
+<glyph unicode="`" d="M195 1569h315l188 -361h-204z" />
<glyph unicode="a" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM350 299 q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
-<glyph unicode="b" d="M145 0v1489h258v-524q142 114 314 114q211 0 309 -145.5t98 -401.5q0 -261 -109.5 -412t-312.5 -151q-80 0 -174.5 36.5t-150.5 92.5l-35 -98h-197zM403 291q43 -37 104.5 -65.5t119.5 -28.5q111 0 171 84.5t60 246.5t-51 243t-164 81q-63 0 -127.5 -29.5t-112.5 -72.5 v-459z" />
+<glyph unicode="b" horiz-adv-x="1217" d="M145 0v1489h258v-524q142 114 314 114q211 0 309 -145.5t98 -401.5q0 -261 -109.5 -412t-312.5 -151q-80 0 -174.5 36.5t-150.5 92.5l-35 -98h-197zM403 291q43 -37 104.5 -65.5t119.5 -28.5q111 0 171 84.5t60 246.5t-51 243t-164 81q-63 0 -127.5 -29.5t-112.5 -72.5 v-459z" />
<glyph unicode="c" horiz-adv-x="1059" d="M92 518q0 265 126 413t378 148q135 0 240.5 -44t160.5 -136l-192 -137q-35 47 -82 69.5t-121 22.5q-132 0 -188 -81t-56 -251t57.5 -248.5t196.5 -78.5q60 0 110 17t95 75l195 -137q-60 -89 -158 -135t-248 -46q-254 0 -384 138.5t-130 410.5z" />
-<glyph unicode="d" d="M92 516q0 267 115.5 415t324.5 148q74 0 152 -30.5t129 -77.5v518h258v-1489h-237v102q-72 -61 -152 -97t-182 -36q-198 0 -303 143t-105 404zM358 520q0 -151 51.5 -237t159.5 -86q64 0 130.5 29.5t113.5 72.5v459q-41 37 -101.5 65.5t-123.5 28.5q-104 0 -167 -89.5 t-63 -242.5z" />
+<glyph unicode="d" horiz-adv-x="1217" d="M92 516q0 267 115.5 415t324.5 148q74 0 152 -30.5t129 -77.5v518h258v-1489h-237v102q-72 -61 -152 -97t-182 -36q-198 0 -303 143t-105 404zM358 520q0 -151 51.5 -237t159.5 -86q64 0 130.5 29.5t113.5 72.5v459q-41 37 -101.5 65.5t-123.5 28.5q-104 0 -167 -89.5 t-63 -242.5z" />
<glyph unicode="e" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z" />
<glyph unicode="f" horiz-adv-x="659" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133z" />
-<glyph unicode="g" d="M92 535q0 162 51.5 285.5t151 191t240.5 67.5q83 0 166 -36.5t139 -92.5l34 99h197v-1029q0 -210 -129 -312.5t-414 -102.5q-235 0 -411 90l76 211q163 -76 335 -76q160 0 222.5 46t62.5 155v86q-128 -117 -309 -117q-192 0 -302 138t-110 397zM358 539q0 -160 57.5 -236 t149.5 -76q128 0 248 103v428q-106 94 -231 94q-94 0 -159 -86t-65 -227z" />
-<glyph unicode="h" d="M145 0v1489h258v-576q82 82 175 124t182 42q176 0 247.5 -99t71.5 -280v-700h-258v578q0 166 -31 220t-110 54q-115 0 -277 -152v-700h-258z" />
+<glyph unicode="g" horiz-adv-x="1217" d="M92 535q0 162 51.5 285.5t151 191t240.5 67.5q83 0 166 -36.5t139 -92.5l34 99h197v-1029q0 -210 -129 -312.5t-414 -102.5q-235 0 -411 90l76 211q163 -76 335 -76q160 0 222.5 46t62.5 155v86q-128 -117 -309 -117q-192 0 -302 138t-110 397zM358 539q0 -160 57.5 -236 t149.5 -76q128 0 248 103v428q-106 94 -231 94q-94 0 -159 -86t-65 -227z" />
+<glyph unicode="h" horiz-adv-x="1217" d="M145 0v1489h258v-576q82 82 175 124t182 42q176 0 247.5 -99t71.5 -280v-700h-258v578q0 166 -31 220t-110 54q-115 0 -277 -152v-700h-258z" />
<glyph unicode="i" horiz-adv-x="549" d="M131 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97zM145 0v1049h258v-1049h-258z" />
<glyph unicode="j" horiz-adv-x="563" d="M-162 -365l56 224q73 -29 151 -29t96.5 48t18.5 159v1012h258v-1094q0 -188 -84 -269t-275 -81q-43 0 -113 9.5t-108 20.5zM145 1335q0 70 32 100.5t110 30.5t111.5 -29.5t33.5 -101.5q0 -73 -36 -102t-109 -29q-82 0 -112 34t-30 97z" />
<glyph unicode="k" horiz-adv-x="1100" d="M145 0v1489h258v-852l353 412h299l-396 -441l418 -608h-293l-280 434l-101 -108v-326h-258z" />
<glyph unicode="l" horiz-adv-x="549" d="M145 0v1489h258v-1489h-258z" />
<glyph unicode="m" horiz-adv-x="1790" d="M145 0v1049h258v-136q72 78 151 122t175 44q131 0 193.5 -45t85.5 -133q90 90 168.5 134t183.5 44q153 0 223 -87t70 -292v-700h-258v618q0 93 -11 145t-33.5 70.5t-74.5 18.5q-59 0 -125 -44t-123 -108v-700h-258v618q0 102 -9 147.5t-32 66t-78 20.5q-48 0 -111 -36.5 t-137 -115.5v-700h-258z" />
-<glyph unicode="n" d="M145 0v1049h258v-136q82 82 175 124t182 42q161 0 240 -88t79 -291v-700h-258v578q0 164 -29.5 219t-111.5 55q-115 0 -277 -152v-700h-258z" />
+<glyph unicode="n" horiz-adv-x="1217" d="M145 0v1049h258v-136q82 82 175 124t182 42q161 0 240 -88t79 -291v-700h-258v578q0 164 -29.5 219t-111.5 55q-115 0 -277 -152v-700h-258z" />
<glyph unicode="o" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5z" />
-<glyph unicode="p" d="M145 -395v1444h238v-103q72 62 151.5 97.5t182.5 35.5q199 0 303 -140t104 -407q0 -169 -51 -298t-146 -197t-227 -68q-174 0 -297 109v-473h-258zM403 291q41 -37 101.5 -65.5t124.5 -28.5q106 0 167.5 90.5t61.5 240.5q0 153 -53 238.5t-158 85.5q-63 0 -129.5 -29.5 t-114.5 -72.5v-459z" />
-<glyph unicode="q" d="M92 516q0 266 114 414.5t324 148.5q95 0 178 -40t132 -89l34 99h197v-1444h-258v479q-141 -115 -313 -115q-198 0 -303 140t-105 407zM358 520q0 -153 50 -238t161 -85q64 0 130.5 29.5t113.5 72.5v459q-47 43 -107.5 68.5t-117.5 25.5q-104 0 -167 -89.5t-63 -242.5z " />
+<glyph unicode="p" horiz-adv-x="1217" d="M145 -395v1444h238v-103q72 62 151.5 97.5t182.5 35.5q199 0 303 -140t104 -407q0 -169 -51 -298t-146 -197t-227 -68q-174 0 -297 109v-473h-258zM403 291q41 -37 101.5 -65.5t124.5 -28.5q106 0 167.5 90.5t61.5 240.5q0 153 -53 238.5t-158 85.5q-63 0 -129.5 -29.5 t-114.5 -72.5v-459z" />
+<glyph unicode="q" horiz-adv-x="1217" d="M92 516q0 266 114 414.5t324 148.5q95 0 178 -40t132 -89l34 99h197v-1444h-258v479q-141 -115 -313 -115q-198 0 -303 140t-105 407zM358 520q0 -153 50 -238t161 -85q64 0 130.5 29.5t113.5 72.5v459q-47 43 -107.5 68.5t-117.5 25.5q-104 0 -167 -89.5t-63 -242.5z " />
<glyph unicode="r" horiz-adv-x="840" d="M145 0v1049h258v-150q66 72 142 119t170 47q80 0 114 -21l-51 -247q-40 20 -106 20q-72 0 -136.5 -34.5t-132.5 -100.5v-682h-258z" />
<glyph unicode="s" horiz-adv-x="1026" d="M76 152l192 135q47 -64 108.5 -85.5t131.5 -21.5q184 0 184 107q0 47 -52 72.5t-163 52.5q-209 46 -294 130t-85 218q0 139 106.5 229t313.5 90q141 0 248.5 -45t165.5 -135l-193 -137q-69 106 -225 106q-80 0 -121 -27.5t-41 -70.5q0 -41 37 -65.5t146 -51.5 q179 -44 255.5 -87.5t116 -108t39.5 -158.5q0 -104 -52.5 -178t-149 -113t-220.5 -39q-329 0 -448 183z" />
<glyph unicode="t" horiz-adv-x="739" d="M31 844v205h133v292h258v-292h244v-205h-244v-494q0 -98 30.5 -133t86.5 -35q71 0 141 29l45 -211q-104 -31 -219 -31q-182 0 -262 82t-80 266v527h-133z" />
-<glyph unicode="u" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5z" />
+<glyph unicode="u" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5z" />
<glyph unicode="v" horiz-adv-x="1040" d="M27 1049h264l233 -691l232 691h258l-377 -1049h-238z" />
<glyph unicode="w" horiz-adv-x="1565" d="M27 1049h268l162 -676l235 676h195l237 -670l156 670h258l-281 -1049h-235l-236 668l-237 -668h-236z" />
<glyph unicode="x" horiz-adv-x="1079" d="M31 0l362 518l-356 531h301l209 -332l215 332h285l-361 -517l363 -532h-306l-208 334l-218 -334h-286z" />
@@ -118,23 +117,23 @@
<glyph unicode="&#xa5;" horiz-adv-x="1280" d="M45 1384h307l291 -538l295 538h297l-307 -538h211v-178h-314l-45 -80v-31h359v-176h-359v-381h-282v381h-361v176h361v27l-47 84h-314v178h213z" />
<glyph unicode="&#xa6;" horiz-adv-x="801" d="M281 283h239v-678h-239v678zM281 842v678h239v-678h-239z" />
<glyph unicode="&#xa7;" horiz-adv-x="1110" d="M92 545q0 188 211 307q-72 53 -110.5 110.5t-38.5 129.5q0 149 105.5 235t322.5 86q282 0 407 -160l-176 -131q-84 84 -227 84q-92 0 -133 -27.5t-41 -68.5q0 -31 45 -69.5t252 -166.5q128 -79 186.5 -133t90.5 -112.5t32 -126.5q0 -191 -211 -307q78 -60 113.5 -117.5 t35.5 -120.5q0 -162 -112.5 -243t-308.5 -81q-160 0 -257.5 43t-156.5 117l176 131q75 -84 233 -84q72 0 120 23.5t48 68.5t-74.5 97.5t-222.5 142.5q-153 92 -231 176t-78 197zM336 549q0 -41 67.5 -94.5t208.5 -139.5q68 41 115 89t47 90q0 24 -15.5 46.5t-48 49t-85 59.5 t-127.5 80q-80 -49 -121 -91t-41 -89z" />
-<glyph unicode="&#xa8;" horiz-adv-x="1044" d="M152 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM596 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#xa8;" d="M152 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM596 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
<glyph unicode="&#xa9;" horiz-adv-x="1802" d="M96 610q0 217 106 402.5t293.5 293t405.5 107.5q217 0 403 -106.5t293 -292.5t107 -404q0 -217 -105.5 -403t-292.5 -295t-405 -109q-219 0 -406 108.5t-293 295t-106 403.5zM258 610q0 -176 87.5 -328t235 -237.5t320.5 -85.5t320.5 85.5t235 237t87.5 328.5 q0 173 -86 323.5t-235.5 237t-321.5 86.5q-174 0 -323 -87t-234.5 -237.5t-85.5 -322.5zM504 612q0 217 100.5 331t317.5 114q133 0 209.5 -51.5t134.5 -143.5l-176 -100q-33 47 -67 78.5t-103 31.5q-109 0 -155 -59t-46 -201q0 -143 48 -200.5t155 -57.5q65 0 104 29t76 78 l180 -96q-71 -88 -118.5 -123.5t-106 -53.5t-131.5 -18q-422 0 -422 442z" />
<glyph unicode="&#xaa;" horiz-adv-x="834" d="M92 1014q0 105 65 164t222 73l129 13v20q0 49 -27.5 67.5t-93.5 18.5q-65 0 -95 -21.5t-46 -50.5l-148 93q31 53 100.5 91t192.5 38q146 0 224.5 -50.5t78.5 -191.5v-461h-174v57q-95 -75 -196 -75q-117 0 -174.5 59.5t-57.5 155.5zM285 1018q0 -39 19.5 -54.5 t57.5 -15.5q64 0 146 66v110l-68 -6q-90 -8 -122.5 -31.5t-32.5 -68.5z" />
<glyph unicode="&#xab;" horiz-adv-x="1436" d="M61 524l420 471h299l-420 -471l420 -471h-299zM635 524l420 471h299l-420 -471l420 -471h-299z" />
<glyph unicode="&#xac;" horiz-adv-x="1427" d="M133 801v205h1161v-682h-207v477h-954z" />
<glyph unicode="&#xad;" horiz-adv-x="786" d="M82 399v254h623v-254h-623z" />
<glyph unicode="&#xae;" horiz-adv-x="1802" d="M96 610q0 217 106 402.5t293.5 293t405.5 107.5q217 0 403 -106.5t293 -292.5t107 -404q0 -217 -105.5 -403t-292.5 -295t-405 -109q-219 0 -406 108.5t-293 295t-106 403.5zM258 610q0 -176 87.5 -328t235 -237.5t320.5 -85.5t320.5 85.5t235 237t87.5 328.5 q0 173 -86 323.5t-235.5 237t-321.5 86.5q-174 0 -323 -87t-234.5 -237.5t-85.5 -322.5zM588 201v850h305q178 0 260 -63t82 -197q0 -185 -145 -246l239 -344h-250l-211 307h-75v-307h-205zM793 682h96q54 0 81 7t39.5 25.5t12.5 65.5t-21.5 70.5t-103.5 23.5h-104v-192z " />
-<glyph unicode="&#xaf;" horiz-adv-x="1044" d="M186 1255v185h672v-185h-672z" />
+<glyph unicode="&#xaf;" d="M186 1255v185h672v-185h-672z" />
<glyph unicode="&#xb0;" horiz-adv-x="868" d="M123 1241q0 130 91.5 219.5t219.5 89.5q129 0 220 -90.5t91 -218.5q0 -83 -40.5 -154.5t-114 -115t-154.5 -43.5q-83 0 -157 42.5t-115 114t-41 156.5zM303 1241q0 -55 38 -94t95 -39q53 0 91 39t38 92q0 55 -38 93t-91 38q-59 0 -96 -39t-37 -90z" />
<glyph unicode="&#xb1;" horiz-adv-x="1427" d="M133 0v205h1161v-205h-1161zM133 829v205h479v479h205v-479h477v-205h-477v-477h-205v477h-479z" />
<glyph unicode="&#xb2;" horiz-adv-x="938" d="M76 1348q133 172 377 172q180 0 262 -71t82 -179q0 -60 -16 -107.5t-52.5 -92.5t-130.5 -115t-166 -111h397v-197h-737v182l108 78q228 160 283.5 217t55.5 113q0 78 -97 78q-101 0 -170 -88z" />
<glyph unicode="&#xb3;" horiz-adv-x="938" d="M59 801l199 102q64 -88 164 -88q72 0 98.5 32t26.5 66q0 91 -141 91h-115v176h102q92 0 124 22.5t32 63.5q0 28 -27.5 48.5t-85.5 20.5q-103 0 -168 -78l-182 107q61 74 143 115t224 41q172 0 255 -67t83 -159q0 -71 -38 -116t-124 -74q92 -23 134 -77t42 -126 q0 -137 -102.5 -203.5t-282.5 -66.5q-127 0 -221.5 49t-139.5 121z" />
-<glyph unicode="&#xb4;" horiz-adv-x="1044" d="M348 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#xb4;" d="M348 1208l189 361h315l-299 -361h-205z" />
<glyph unicode="&#xb5;" horiz-adv-x="1202" d="M131 -395v1444h258v-750q29 -39 83 -69.5t114 -30.5q131 0 227 120v730h256v-1049h-238l-4 111q-49 -70 -104 -106t-133 -36q-62 0 -109 17.5t-92 52.5v-434h-258z" />
<glyph unicode="&#xb6;" horiz-adv-x="1321" d="M41 1047q0 206 134 324t378 118h727v-207h-188v-1677h-234v1677h-162v-1677h-233v1001q-204 22 -313 138t-109 303z" />
<glyph unicode="&#xb7;" horiz-adv-x="584" d="M129 743q0 82 36 121t126 39q92 0 128 -38t36 -122q0 -86 -39 -122.5t-125 -36.5q-94 0 -128 41t-34 118z" />
-<glyph unicode="&#xb8;" horiz-adv-x="1044" d="M199 -350l69 145q106 -45 193 -45q53 0 74.5 11.5t21.5 35.5q0 63 -180 72l88 170h170l-31 -62q62 -14 104 -61t42 -121q0 -190 -287 -190q-174 0 -264 45z" />
+<glyph unicode="&#xb8;" d="M199 -350l69 145q106 -45 193 -45q53 0 74.5 11.5t21.5 35.5q0 63 -180 72l88 170h170l-31 -62q62 -14 104 -61t42 -121q0 -190 -287 -190q-174 0 -264 45z" />
<glyph unicode="&#xb9;" horiz-adv-x="938" d="M170 1200v152q97 3 150 17t82 43t49 91h200v-856h-252v553h-229z" />
<glyph unicode="&#xba;" horiz-adv-x="842" d="M92 1157q0 172 80 267.5t250 95.5q168 0 248 -95.5t80 -267.5q0 -170 -80 -264t-248 -94q-172 0 -251 95t-79 263zM285 1157q0 -100 31.5 -148t105.5 -48q72 0 103.5 47.5t31.5 148.5q0 119 -39 160t-96 41q-60 0 -98.5 -41t-38.5 -160z" />
<glyph unicode="&#xbb;" horiz-adv-x="1436" d="M82 53l420 471l-420 471h299l420 -471l-420 -471h-299zM655 53l420 471l-420 471h299l420 -471l-420 -471h-299z" />
@@ -173,7 +172,7 @@
<glyph unicode="&#xdc;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM353 1671q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29 q-82 0 -111.5 34t-29.5 97zM797 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
<glyph unicode="&#xdd;" horiz-adv-x="1188" d="M18 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522zM424 1544l189 361h315l-299 -361h-205z" />
<glyph unicode="&#xde;" horiz-adv-x="1239" d="M150 0v1384h282v-200h238q235 0 363 -109.5t128 -355.5q0 -250 -117.5 -371t-381.5 -121h-230v-227h-282zM432 473h115q155 0 214 21.5t84 71.5t25 151q0 81 -30 129.5t-91 70t-176 21.5h-141v-465z" />
-<glyph unicode="&#xdf;" d="M145 0v1020q0 252 117.5 376t355.5 124q203 0 313.5 -91t110.5 -255q0 -123 -53 -196t-129 -106q122 -27 193 -136.5t71 -262.5q0 -250 -93 -377t-312 -127q-47 0 -103.5 10.5t-89.5 20.5v227q86 -30 154 -30q88 0 131 63.5t43 220.5q0 108 -28.5 160.5t-92.5 74 t-190 21.5v224q93 0 143 18.5t72 57t22 118.5q0 70 -43 106.5t-123 36.5q-104 0 -157.5 -59t-53.5 -211v-1028h-258z" />
+<glyph unicode="&#xdf;" horiz-adv-x="1217" d="M145 0v1020q0 252 117.5 376t355.5 124q203 0 313.5 -91t110.5 -255q0 -123 -53 -196t-129 -106q122 -27 193 -136.5t71 -262.5q0 -250 -93 -377t-312 -127q-47 0 -103.5 10.5t-89.5 20.5v227q86 -30 154 -30q88 0 131 63.5t43 220.5q0 108 -28.5 160.5t-92.5 74 t-190 21.5v224q93 0 143 18.5t72 57t22 118.5q0 70 -43 106.5t-123 36.5q-104 0 -157.5 -59t-53.5 -211v-1028h-258z" />
<glyph unicode="&#xe0;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM207 1569h315 l188 -361h-204zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
<glyph unicode="&#xe1;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM350 299 q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM366 1208l189 361h315l-299 -361h-205z" />
<glyph unicode="&#xe2;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM195 1208l235 361 h244l236 -361h-211l-146 174l-149 -174h-209zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
@@ -191,7 +190,7 @@
<glyph unicode="&#xee;" horiz-adv-x="549" d="M-80 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209zM145 0v1049h258v-1049h-258z" />
<glyph unicode="&#xef;" horiz-adv-x="549" d="M-92 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM145 0v1049h258v-1049h-258zM352 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
<glyph unicode="&#xf0;" horiz-adv-x="1190" d="M92 520q0 156 55 278t158 186.5t238 64.5q41 0 94 -18.5t94 -49.5q-15 39 -65.5 122t-90.5 130l-225 -94l-67 149l180 76q-34 48 -184 156h274q49 -29 98 -78l187 78l69 -148l-131 -55q142 -147 232 -360t90 -435q0 -267 -126.5 -410t-375.5 -143q-247 0 -375.5 138 t-128.5 413zM358 520q0 -158 54.5 -241.5t183.5 -83.5t182 83.5t53 243.5q0 303 -237 303q-116 0 -176 -77.5t-60 -227.5z" />
-<glyph unicode="&#xf1;" d="M145 0v1049h258v-136q82 82 175 124t182 42q161 0 240 -88t79 -291v-700h-258v578q0 164 -29.5 219t-111.5 55q-115 0 -277 -152v-700h-258zM197 1231q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92h182q-10 -165 -75.5 -243.5 t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
+<glyph unicode="&#xf1;" horiz-adv-x="1217" d="M145 0v1049h258v-136q82 82 175 124t182 42q161 0 240 -88t79 -291v-700h-258v578q0 164 -29.5 219t-111.5 55q-115 0 -277 -152v-700h-258zM197 1231q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92h182q-10 -165 -75.5 -243.5 t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
<glyph unicode="&#xf2;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM269 1569h315l188 -361h-204zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5 t-56 -250.5z" />
<glyph unicode="&#xf3;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5zM428 1208l189 361h315 l-299 -361h-205z" />
<glyph unicode="&#xf4;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM242 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5 t-181 79.5q-126 0 -182 -81.5t-56 -250.5z" />
@@ -199,50 +198,760 @@
<glyph unicode="&#xf6;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM230 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM358 522q0 -168 55.5 -247.5 t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5zM674 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
<glyph unicode="&#xf7;" horiz-adv-x="1427" d="M133 479v205h1161v-205h-1161zM592 2v252h246v-252h-246zM592 911v252h246v-252h-246z" />
<glyph unicode="&#xf8;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q141 0 246 -47l61 92h182l-118 -180q131 -145 131 -422q0 -262 -121 -407.5t-381 -145.5q-144 0 -248 45l-59 -90h-183l117 176q-131 141 -131 422zM358 522q0 -103 23 -184l328 493q-45 23 -113 23q-126 0 -182 -81.5t-56 -250.5z M483 215q47 -20 113 -20q125 0 180 78.5t55 248.5q0 108 -22 185z" />
-<glyph unicode="&#xf9;" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM281 1569h315l188 -361h-204z" />
-<glyph unicode="&#xfa;" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM440 1208l189 361h315l-299 -361h-205z" />
-<glyph unicode="&#xfb;" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM244 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
-<glyph unicode="&#xfc;" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM232 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29 q-82 0 -111.5 34t-29.5 97zM676 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#xf9;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM281 1569h315l188 -361h-204z" />
+<glyph unicode="&#xfa;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM440 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#xfb;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM244 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#xfc;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM232 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29 q-82 0 -111.5 34t-29.5 97zM676 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
<glyph unicode="&#xfd;" horiz-adv-x="1085" d="M-20 -365l55 224q84 -29 151 -29q58 0 102 35t91 145l27 62l-379 977h268l248 -670l254 670h262l-451 -1121q-55 -135 -107 -200t-121.5 -94t-174.5 -29q-114 0 -225 30zM368 1208l189 361h315l-299 -361h-205z" />
-<glyph unicode="&#xfe;" d="M145 -395v1884h258v-533q127 123 316 123q198 0 301.5 -141.5t103.5 -405.5q0 -169 -51 -298t-146 -197t-227 -68q-174 0 -297 109v-473h-258zM403 291q41 -37 101.5 -65.5t124.5 -28.5q106 0 167.5 90.5t61.5 240.5q0 153 -53 238.5t-158 85.5q-63 0 -129.5 -29.5 t-114.5 -72.5v-459z" />
+<glyph unicode="&#xfe;" horiz-adv-x="1217" d="M145 -395v1884h258v-533q127 123 316 123q198 0 301.5 -141.5t103.5 -405.5q0 -169 -51 -298t-146 -197t-227 -68q-174 0 -297 109v-473h-258zM403 291q41 -37 101.5 -65.5t124.5 -28.5q106 0 167.5 90.5t61.5 240.5q0 153 -53 238.5t-158 85.5q-63 0 -129.5 -29.5 t-114.5 -72.5v-459z" />
<glyph unicode="&#xff;" horiz-adv-x="1085" d="M-20 -365l55 224q84 -29 151 -29q58 0 102 35t91 145l27 62l-379 977h268l248 -670l254 670h262l-451 -1121q-55 -135 -107 -200t-121.5 -94t-174.5 -29q-114 0 -225 30zM179 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29 q-82 0 -111.5 34t-29.5 97zM623 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x100;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM344 1591v185h672v-185h-672zM477 528h373l-186 572z" />
+<glyph unicode="&#x101;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM223 1255v185h672 v-185h-672zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
+<glyph unicode="&#x102;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM318 1845h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162zM477 528h373l-186 572z" />
+<glyph unicode="&#x103;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM193 1509h188 q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
+<glyph unicode="&#x104;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384q-137 -29 -194.5 -63.5t-57.5 -79.5q0 -33 17.5 -47.5t41.5 -14.5q17 0 46.5 7.5t54.5 23.5l94 -158q-128 -63 -240 -63q-104 0 -161.5 47t-57.5 133q0 139 164 223l-88 273h-533l-90 -281h-280zM477 528h373l-186 572z" />
+<glyph unicode="&#x105;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713q-137 -29 -195 -63.5t-58 -79.5q0 -62 59 -62q16 0 46 7.5t54 23.5l94 -158 q-128 -63 -239 -63q-105 0 -162 47t-57 133q0 78 56 141.5t165 106.5v76q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
+<glyph unicode="&#x106;" horiz-adv-x="1333" d="M96 692q0 369 163 545t470 176q203 0 331 -68.5t195 -179.5l-219 -170q-48 72 -88 104t-91 48t-122 16q-170 0 -259 -108.5t-89 -362.5q0 -237 83.5 -354t266.5 -117q123 0 191.5 47t124.5 125l223 -164q-89 -133 -218.5 -195.5t-318.5 -62.5q-643 0 -643 721zM553 1544 l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x107;" horiz-adv-x="1059" d="M92 518q0 265 126 413t378 148q135 0 240.5 -44t160.5 -136l-192 -137q-35 47 -82 69.5t-121 22.5q-132 0 -188 -81t-56 -251t57.5 -248.5t196.5 -78.5q60 0 110 17t95 75l195 -137q-60 -89 -158 -135t-248 -46q-254 0 -384 138.5t-130 410.5zM426 1208l189 361h315 l-299 -361h-205z" />
+<glyph unicode="&#x108;" horiz-adv-x="1333" d="M96 692q0 369 163 545t470 176q203 0 331 -68.5t195 -179.5l-219 -170q-48 72 -88 104t-91 48t-122 16q-170 0 -259 -108.5t-89 -362.5q0 -237 83.5 -354t266.5 -117q123 0 191.5 47t124.5 125l223 -164q-89 -133 -218.5 -195.5t-318.5 -62.5q-643 0 -643 721zM385 1544 l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x109;" horiz-adv-x="1059" d="M92 518q0 265 126 413t378 148q135 0 240.5 -44t160.5 -136l-192 -137q-35 47 -82 69.5t-121 22.5q-132 0 -188 -81t-56 -251t57.5 -248.5t196.5 -78.5q60 0 110 17t95 75l195 -137q-60 -89 -158 -135t-248 -46q-254 0 -384 138.5t-130 410.5zM223 1208l235 361h244 l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x10a;" horiz-adv-x="1333" d="M96 692q0 369 163 545t470 176q203 0 331 -68.5t195 -179.5l-219 -170q-48 72 -88 104t-91 48t-122 16q-170 0 -259 -108.5t-89 -362.5q0 -237 83.5 -354t266.5 -117q123 0 191.5 47t124.5 125l223 -164q-89 -133 -218.5 -195.5t-318.5 -62.5q-643 0 -643 721zM541 1671 q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x10b;" horiz-adv-x="1059" d="M92 518q0 265 126 413t378 148q135 0 240.5 -44t160.5 -136l-192 -137q-35 47 -82 69.5t-121 22.5q-132 0 -188 -81t-56 -251t57.5 -248.5t196.5 -78.5q60 0 110 17t95 75l195 -137q-60 -89 -158 -135t-248 -46q-254 0 -384 138.5t-130 410.5zM414 1335q0 70 31.5 100.5 t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x10c;" horiz-adv-x="1333" d="M96 692q0 369 163 545t470 176q203 0 331 -68.5t195 -179.5l-219 -170q-48 72 -88 104t-91 48t-122 16q-170 0 -259 -108.5t-89 -362.5q0 -237 83.5 -354t266.5 -117q123 0 191.5 47t124.5 125l223 -164q-89 -133 -218.5 -195.5t-318.5 -62.5q-643 0 -643 721zM367 1905 h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x10d;" horiz-adv-x="1059" d="M92 518q0 265 126 413t378 148q135 0 240.5 -44t160.5 -136l-192 -137q-35 47 -82 69.5t-121 22.5q-132 0 -188 -81t-56 -251t57.5 -248.5t196.5 -78.5q60 0 110 17t95 75l195 -137q-60 -89 -158 -135t-248 -46q-254 0 -384 138.5t-130 410.5zM199 1569h211l145 -174 l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x10e;" horiz-adv-x="1313" d="M137 0v1384h418q245 0 389.5 -71t213.5 -221.5t69 -399.5q0 -250 -69 -402t-208 -221t-391 -69h-422zM238 1905h211l145 -174l150 174h209l-236 -361h-244zM420 258h108q167 0 251.5 38.5t120.5 128.5t36 269q0 181 -35.5 268.5t-120.5 125.5t-252 38h-108v-868z" />
+<glyph unicode="&#x10f;" horiz-adv-x="1346" d="M92 516q0 267 115.5 415t324.5 148q74 0 152 -30.5t129 -77.5v518h258v-1489h-237v102q-72 -61 -152 -97t-182 -36q-198 0 -303 143t-105 404zM358 520q0 -151 51.5 -237t159.5 -86q64 0 130.5 29.5t113.5 72.5v459q-41 37 -101.5 65.5t-123.5 28.5q-104 0 -167 -89.5 t-63 -242.5zM1147 1128l55 361h271l-166 -361h-160z" />
+<glyph unicode="&#x110;" horiz-adv-x="1399" d="M2 580v225h148v579h434q263 0 416.5 -70.5t228 -222.5t74.5 -399q0 -250 -74.5 -402t-224.5 -221t-418 -69h-436v580h-148zM432 258h127q184 0 278 40t134.5 130t40.5 266t-39 264.5t-132 128t-282 39.5h-127v-321h322v-225h-322v-322z" />
+<glyph unicode="&#x111;" horiz-adv-x="1217" d="M92 516q0 267 115.5 415t324.5 148q74 0 152 -30.5t129 -77.5v227h-278v184h278v107h258v-107h135v-184h-135v-1198h-237v102q-72 -61 -152 -97t-182 -36q-198 0 -303 143t-105 404zM358 520q0 -151 51.5 -237t159.5 -86q64 0 130.5 29.5t113.5 72.5v459 q-41 37 -101.5 65.5t-123.5 28.5q-104 0 -167 -89.5t-63 -242.5z" />
+<glyph unicode="&#x112;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM252 1591v185h672v-185h-672z" />
+<glyph unicode="&#x113;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM254 1255v185h672v-185h-672zM365 635h434q0 239 -209 239q-69 0 -113 -23.5 t-70.5 -70t-41.5 -145.5z" />
+<glyph unicode="&#x114;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM266 1845h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162z" />
+<glyph unicode="&#x115;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM225 1509h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189 q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z" />
+<glyph unicode="&#x116;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM455 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x117;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z M447 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x118;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258q-138 -29 -196 -63.5t-58 -79.5q0 -62 59 -62q16 0 46 7.5t54 23.5l95 -158q-131 -63 -240 -63q-104 0 -161.5 47t-57.5 133q0 132 149 215h-589z" />
+<glyph unicode="&#x119;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-34 -50 -79 -87q-79 -61 -121.5 -109.5t-42.5 -96.5q0 -33 17.5 -47.5t41.5 -14.5q17 0 46.5 7.5t54.5 23.5l94 -158q-131 -63 -240 -63 q-104 0 -161.5 47t-57.5 133q0 93 68 184h-41q-268 0 -399.5 134.5t-131.5 412.5zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z" />
+<glyph unicode="&#x11a;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM240 1905h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x11b;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM234 1569h211l145 -174l150 174h209l-236 -361h-244zM365 635h434 q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z" />
+<glyph unicode="&#x11c;" horiz-adv-x="1415" d="M96 680q0 733 645 733q188 0 328 -63t213 -185l-217 -170q-53 86 -129 127t-191 41q-189 0 -273.5 -121.5t-84.5 -361.5q0 -238 83.5 -348.5t268.5 -110.5q140 0 258 58v215h-270v249h553v-612q-96 -72 -238.5 -116t-293.5 -44q-324 0 -488 169t-164 540zM385 1544 l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x11d;" horiz-adv-x="1217" d="M92 535q0 162 51.5 285.5t151 191t240.5 67.5q83 0 166 -36.5t139 -92.5l34 99h197v-1029q0 -210 -129 -312.5t-414 -102.5q-235 0 -411 90l76 211q163 -76 335 -76q160 0 222.5 46t62.5 155v86q-128 -117 -309 -117q-192 0 -302 138t-110 397zM242 1208l235 361h244 l236 -361h-211l-146 174l-149 -174h-209zM358 539q0 -160 57.5 -236t149.5 -76q128 0 248 103v428q-106 94 -231 94q-94 0 -159 -86t-65 -227z" />
+<glyph unicode="&#x11e;" horiz-adv-x="1415" d="M96 680q0 733 645 733q188 0 328 -63t213 -185l-217 -170q-53 86 -129 127t-191 41q-189 0 -273.5 -121.5t-84.5 -361.5q0 -238 83.5 -348.5t268.5 -110.5q140 0 258 58v215h-270v249h553v-612q-96 -72 -238.5 -116t-293.5 -44q-324 0 -488 169t-164 540zM373 1845h188 q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162z" />
+<glyph unicode="&#x11f;" horiz-adv-x="1217" d="M92 535q0 162 51.5 285.5t151 191t240.5 67.5q83 0 166 -36.5t139 -92.5l34 99h197v-1029q0 -210 -129 -312.5t-414 -102.5q-235 0 -411 90l76 211q163 -76 335 -76q160 0 222.5 46t62.5 155v86q-128 -117 -309 -117q-192 0 -302 138t-110 397zM232 1509h188 q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162zM358 539q0 -160 57.5 -236t149.5 -76q128 0 248 103v428q-106 94 -231 94q-94 0 -159 -86t-65 -227z" />
+<glyph unicode="&#x120;" horiz-adv-x="1415" d="M96 680q0 733 645 733q188 0 328 -63t213 -185l-217 -170q-53 86 -129 127t-191 41q-189 0 -273.5 -121.5t-84.5 -361.5q0 -238 83.5 -348.5t268.5 -110.5q140 0 258 58v215h-270v249h553v-612q-96 -72 -238.5 -116t-293.5 -44q-324 0 -488 169t-164 540zM586 1671 q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x121;" horiz-adv-x="1217" d="M92 535q0 162 51.5 285.5t151 191t240.5 67.5q83 0 166 -36.5t139 -92.5l34 99h197v-1029q0 -210 -129 -312.5t-414 -102.5q-235 0 -411 90l76 211q163 -76 335 -76q160 0 222.5 46t62.5 155v86q-128 -117 -309 -117q-192 0 -302 138t-110 397zM358 539q0 -160 57.5 -236 t149.5 -76q128 0 248 103v428q-106 94 -231 94q-94 0 -159 -86t-65 -227zM434 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x122;" horiz-adv-x="1415" d="M96 680q0 733 645 733q188 0 328 -63t213 -185l-217 -170q-53 86 -129 127t-191 41q-189 0 -273.5 -121.5t-84.5 -361.5q0 -238 83.5 -348.5t268.5 -110.5q140 0 258 58v215h-270v249h553v-612q-96 -72 -238.5 -116t-293.5 -44q-324 0 -488 169t-164 540zM604 -233 q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#x123;" horiz-adv-x="1217" d="M92 535q0 162 51.5 285.5t151 191t240.5 67.5q83 0 166 -36.5t139 -92.5l34 99h197v-1029q0 -210 -129 -312.5t-414 -102.5q-235 0 -411 90l76 211q163 -76 335 -76q160 0 222.5 46t62.5 155v86q-128 -117 -309 -117q-192 0 -302 138t-110 397zM358 539q0 -160 57.5 -236 t149.5 -76q128 0 248 103v428q-106 94 -231 94q-94 0 -159 -86t-65 -227zM416 1346q0 170 119 309h166q-47 -56 -63.5 -95.5t-20.5 -78.5q65 -4 95 -42t30 -114q0 -74 -35 -117t-131 -43q-160 0 -160 181z" />
+<glyph unicode="&#x124;" horiz-adv-x="1409" d="M150 0v1384h282v-538h545v538h283v-1384h-283v588h-545v-588h-282zM354 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x125;" horiz-adv-x="1217" d="M145 0v1489h258v-576q82 82 175 124t182 42q176 0 247.5 -99t71.5 -280v-700h-258v578q0 166 -31 220t-110 54q-115 0 -277 -152v-700h-258zM277 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x126;" horiz-adv-x="1409" d="M10 991v205h140v188h282v-188h545v188h283v-188h139v-205h-139v-991h-283v588h-545v-588h-282v991h-140zM432 846h545v145h-545v-145z" />
+<glyph unicode="&#x127;" horiz-adv-x="1217" d="M2 1198v184h143v107h258v-107h271v-184h-271v-285q82 82 175 124t182 42q176 0 247.5 -99t71.5 -280v-700h-258v578q0 166 -31 220t-110 54q-115 0 -277 -152v-700h-258v1198h-143z" />
+<glyph unicode="&#x128;" horiz-adv-x="872" d="M35 1567q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182zM102 0v217h193v950h-193v217h668v-217h-192v-950h192 v-217h-668z" />
+<glyph unicode="&#x129;" horiz-adv-x="549" d="M-137 1231q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182zM145 0v1049h258v-1049h-258z" />
+<glyph unicode="&#x12a;" horiz-adv-x="872" d="M102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668zM102 1591v185h672v-185h-672z" />
+<glyph unicode="&#x12b;" horiz-adv-x="549" d="M-60 1255v185h672v-185h-672zM145 0v1049h258v-1049h-258z" />
+<glyph unicode="&#x12c;" horiz-adv-x="872" d="M80 1845h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162zM102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668z" />
+<glyph unicode="&#x12d;" horiz-adv-x="549" d="M-90 1509h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162zM145 0v1049h258v-1049h-258z" />
+<glyph unicode="&#x12e;" horiz-adv-x="872" d="M102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217q-137 -29 -195.5 -63.5t-58.5 -79.5q0 -33 17.5 -47.5t41.5 -14.5q17 0 46.5 7.5t54.5 23.5l94 -158q-128 -63 -240 -63q-104 0 -161.5 47t-57.5 133q0 133 150 215h-359z" />
+<glyph unicode="&#x12f;" horiz-adv-x="549" d="M-14 -215q0 133 159 219v1045h258v-1049q-106 -23 -159.5 -60.5t-53.5 -82.5q0 -33 17.5 -47.5t42.5 -14.5q16 0 46 7.5t54 23.5l94 -158q-128 -63 -239 -63q-105 0 -162 47t-57 133zM131 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29 q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x130;" horiz-adv-x="872" d="M102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668zM289 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x131;" horiz-adv-x="549" d="M145 0v1049h258v-1049h-258z" />
+<glyph unicode="&#x132;" horiz-adv-x="1735" d="M102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668zM831 23l86 251q32 -17 102.5 -36t110.5 -19q74 0 107 20t47 70t14 144v931h283v-1007q0 -219 -110.5 -313.5t-346.5 -94.5q-51 0 -142 15t-151 39z" />
+<glyph unicode="&#x133;" horiz-adv-x="1112" d="M131 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97zM145 0v1049h258v-1049h-258zM387 -365l56 224q73 -29 151 -29t96.5 48t18.5 159v1012h258v-1094q0 -188 -84 -269t-275 -81q-43 0 -113 9.5t-108 20.5z M694 1335q0 70 32 100.5t110 30.5t111.5 -29.5t33.5 -101.5q0 -73 -36 -102t-109 -29q-82 0 -112 34t-30 97z" />
+<glyph unicode="&#x134;" horiz-adv-x="924" d="M20 23l86 251q32 -17 102.5 -36t110.5 -19q74 0 107 20t47 70t14 144v931h283v-1007q0 -219 -110.5 -313.5t-346.5 -94.5q-51 0 -142 15t-151 39zM277 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x135;" horiz-adv-x="563" d="M-162 -365l56 224q73 -29 151 -29t96.5 48t18.5 159v1012h258v-1094q0 -188 -84 -269t-275 -81q-43 0 -113 9.5t-108 20.5zM-70 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x136;" horiz-adv-x="1280" d="M150 0v1384h282v-540l453 540h329l-516 -596l553 -788h-352l-383 578l-84 -97v-481h-282zM461 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#x137;" horiz-adv-x="1100" d="M145 0v1489h258v-852l353 412h299l-396 -441l418 -608h-293l-280 434l-101 -108v-326h-258zM375 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#x138;" horiz-adv-x="1100" d="M145 0v1049h258v-412l304 356q73 86 165 86q58 0 175 -30l-62 -195q-45 16 -65 16q-17 0 -27 -7t-23 -19l-211 -236l418 -608h-293l-280 434l-101 -108v-326h-258z" />
+<glyph unicode="&#x139;" horiz-adv-x="1038" d="M150 0v1384h282v-1126h582v-258h-864zM352 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x13a;" horiz-adv-x="549" d="M104 1546l189 361h315l-299 -361h-205zM145 0v1489h258v-1489h-258z" />
+<glyph unicode="&#x13b;" horiz-adv-x="1038" d="M150 0v1384h282v-1126h582v-258h-864zM414 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#x13c;" horiz-adv-x="549" d="M117 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114zM145 0v1489h258v-1489h-258z" />
+<glyph unicode="&#x13d;" horiz-adv-x="1038" d="M150 0v1384h282v-1126h582v-258h-864zM514 1026l55 361h271l-166 -361h-160z" />
+<glyph unicode="&#x13e;" horiz-adv-x="674" d="M145 0v1489h258v-1489h-258zM475 1128l55 361h271l-166 -361h-160z" />
+<glyph unicode="&#x13f;" horiz-adv-x="1038" d="M150 0v1384h282v-1126h582v-258h-864zM664 762q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x140;" horiz-adv-x="831" d="M145 0v1489h258v-1489h-258zM547 762q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x141;" horiz-adv-x="1038" d="M10 391v268l140 109v616h282v-417l225 176v-269l-225 -176v-440h582v-258h-864v500z" />
+<glyph unicode="&#x142;" horiz-adv-x="549" d="M10 360v232l135 137v760h258v-520l136 137v-232l-136 -137v-737h-258v498z" />
+<glyph unicode="&#x143;" horiz-adv-x="1411" d="M150 0v1384h366l469 -933v933h277v-1384h-332l-504 989v-989h-276zM522 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x144;" horiz-adv-x="1217" d="M145 0v1049h258v-136q82 82 175 124t182 42q161 0 240 -88t79 -291v-700h-258v578q0 164 -29.5 219t-111.5 55q-115 0 -277 -152v-700h-258zM454 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x145;" horiz-adv-x="1411" d="M150 0v1384h366l469 -933v933h277v-1384h-332l-504 989v-989h-276zM563 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#x146;" horiz-adv-x="1217" d="M145 0v1049h258v-136q82 82 175 124t182 42q161 0 240 -88t79 -291v-700h-258v578q0 164 -29.5 219t-111.5 55q-115 0 -277 -152v-700h-258zM432 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#x147;" horiz-adv-x="1411" d="M150 0v1384h366l469 -933v933h277v-1384h-332l-504 989v-989h-276zM346 1905h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x148;" horiz-adv-x="1217" d="M145 0v1049h258v-136q82 82 175 124t182 42q161 0 240 -88t79 -291v-700h-258v578q0 164 -29.5 219t-111.5 55q-115 0 -277 -152v-700h-258zM268 1569h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x149;" horiz-adv-x="1452" d="M-20 815q61 86 91 165t34 118q-66 4 -95.5 42t-29.5 113q0 74 35 117t131 43q160 0 160 -180q0 -123 -42 -234.5t-91 -183.5h-193zM381 0v1049h258v-136q82 82 175 124t182 42q161 0 240 -88t79 -291v-700h-258v578q0 164 -29.5 219t-111.5 55q-115 0 -277 -152v-700 h-258z" />
+<glyph unicode="&#x14a;" horiz-adv-x="1411" d="M150 0v1384h366l469 -864v864h277v-1429q0 -188 -84 -269t-275 -81q-45 0 -115.5 9.5t-105.5 20.5l55 224q74 -29 152 -29q72 0 92 40t23 130l-578 989v-989h-276z" />
+<glyph unicode="&#x14b;" horiz-adv-x="1217" d="M145 0v1049h258v-136q82 82 175 124t182 42q161 0 240 -88t79 -291v-745q0 -188 -84 -269t-274 -81q-44 0 -114 9.5t-107 20.5l55 224q74 -29 152 -29q77 0 95.5 48t18.5 159v541q0 164 -29.5 219t-111.5 55q-115 0 -277 -152v-700h-258z" />
+<glyph unicode="&#x14c;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM356 1591v185h672v-185h-672zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5 t-235.5 112.5t-235.5 -112.5t-69.5 -358.5z" />
+<glyph unicode="&#x14d;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM254 1255v185h672v-185h-672zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5 t-56 -250.5z" />
+<glyph unicode="&#x14e;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM324 1845h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44 q-106 0 -188.5 43.5t-127 117.5t-44.5 162zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5z" />
+<glyph unicode="&#x14f;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM236 1509h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5 t-44.5 162zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5z" />
+<glyph unicode="&#x150;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM346 1544l189 361h315l-299 -361h-205zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5 t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5zM762 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x151;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM264 1208l189 361h315l-299 -361h-205zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5 q-126 0 -182 -81.5t-56 -250.5zM680 1208l189 361h315l-299 -361h-205z" />
<glyph unicode="&#x152;" horiz-adv-x="1919" d="M96 692q0 344 151.5 532.5t459.5 188.5q121 0 247 -29h865v-249h-568v-301h467v-250h-467v-326h568v-258h-861q-106 -29 -251 -29q-312 0 -461.5 189.5t-149.5 531.5zM387 692q0 -246 78 -358.5t264 -112.5q78 0 130 14.5t108 49.5v813q-100 65 -238 65q-182 0 -262 -110 t-80 -361z" />
<glyph unicode="&#x153;" horiz-adv-x="1874" d="M92 522q0 269 121 413t373 144q244 0 377 -149q57 63 144 106t230 43q219 0 334 -128.5t115 -366.5v-127h-696q6 -140 66.5 -201t193.5 -61q73 0 131.5 19t101.5 73l193 -137q-64 -91 -162 -136t-260 -45q-264 0 -391 152q-139 -152 -367 -152q-264 0 -384 146.5 t-120 406.5zM358 522q0 -168 55.5 -247.5t182.5 -79.5q117 0 176 74.5t59 252.5q0 184 -58 258t-177 74q-126 0 -182 -81.5t-56 -250.5zM1096 635h434q0 239 -209 239q-68 0 -113 -23.5t-71 -70.5t-41 -145z" />
+<glyph unicode="&#x154;" horiz-adv-x="1284" d="M150 0v1384h503q267 0 390.5 -96t123.5 -315q0 -177 -74.5 -282t-211.5 -134l370 -557h-323l-353 524h-143v-524h-282zM432 770h207q95 0 146 18t73.5 56t22.5 117q0 106 -53.5 142t-176.5 36h-219v-369zM436 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x155;" horiz-adv-x="840" d="M145 0v1049h258v-150q66 72 142 119t170 47q80 0 114 -21l-51 -247q-40 20 -106 20q-72 0 -136.5 -34.5t-132.5 -100.5v-682h-258zM307 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x156;" horiz-adv-x="1284" d="M150 0v1384h503q267 0 390.5 -96t123.5 -315q0 -177 -74.5 -282t-211.5 -134l370 -557h-323l-353 524h-143v-524h-282zM432 770h207q95 0 146 18t73.5 56t22.5 117q0 106 -53.5 142t-176.5 36h-219v-369zM489 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309 h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#x157;" horiz-adv-x="840" d="M113 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114zM145 0v1049h258v-150q66 72 142 119t170 47q80 0 114 -21l-51 -247q-40 20 -106 20q-72 0 -136.5 -34.5t-132.5 -100.5v-682h-258z" />
+<glyph unicode="&#x158;" horiz-adv-x="1284" d="M150 0v1384h503q267 0 390.5 -96t123.5 -315q0 -177 -74.5 -282t-211.5 -134l370 -557h-323l-353 524h-143v-524h-282zM270 1905h211l145 -174l150 174h209l-236 -361h-244zM432 770h207q95 0 146 18t73.5 56t22.5 117q0 106 -53.5 142t-176.5 36h-219v-369z" />
+<glyph unicode="&#x159;" horiz-adv-x="840" d="M100 1569h211l145 -174l150 174h209l-236 -361h-244zM145 0v1049h258v-150q66 72 142 119t170 47q80 0 114 -21l-51 -247q-40 20 -106 20q-72 0 -136.5 -34.5t-132.5 -100.5v-682h-258z" />
+<glyph unicode="&#x15a;" horiz-adv-x="1229" d="M66 229l217 166q48 -68 91 -102t102 -53t136 -19q115 0 179.5 39.5t64.5 120.5q0 46 -22.5 77t-67.5 53.5t-156 51.5q-108 29 -203.5 58.5t-165 76.5t-109.5 118t-40 179q0 197 133 307.5t381 110.5q359 0 508 -246l-215 -168q-57 88 -128 126t-169 38t-159.5 -35.5 t-61.5 -111.5q0 -67 64 -102.5t223 -71.5q88 -23 174 -49.5t153.5 -73.5t108.5 -123t41 -195q0 -208 -136.5 -319t-402.5 -111q-184 0 -319.5 61t-220.5 197zM450 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x15b;" horiz-adv-x="1026" d="M76 152l192 135q47 -64 108.5 -85.5t131.5 -21.5q184 0 184 107q0 47 -52 72.5t-163 52.5q-209 46 -294 130t-85 218q0 139 106.5 229t313.5 90q141 0 248.5 -45t165.5 -135l-193 -137q-69 106 -225 106q-80 0 -121 -27.5t-41 -70.5q0 -41 37 -65.5t146 -51.5 q179 -44 255.5 -87.5t116 -108t39.5 -158.5q0 -104 -52.5 -178t-149 -113t-220.5 -39q-329 0 -448 183zM354 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x15c;" horiz-adv-x="1229" d="M66 229l217 166q48 -68 91 -102t102 -53t136 -19q115 0 179.5 39.5t64.5 120.5q0 46 -22.5 77t-67.5 53.5t-156 51.5q-108 29 -203.5 58.5t-165 76.5t-109.5 118t-40 179q0 197 133 307.5t381 110.5q359 0 508 -246l-215 -168q-57 88 -128 126t-169 38t-159.5 -35.5 t-61.5 -111.5q0 -67 64 -102.5t223 -71.5q88 -23 174 -49.5t153.5 -73.5t108.5 -123t41 -195q0 -208 -136.5 -319t-402.5 -111q-184 0 -319.5 61t-220.5 197zM244 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x15d;" horiz-adv-x="1026" d="M76 152l192 135q47 -64 108.5 -85.5t131.5 -21.5q184 0 184 107q0 47 -52 72.5t-163 52.5q-209 46 -294 130t-85 218q0 139 106.5 229t313.5 90q141 0 248.5 -45t165.5 -135l-193 -137q-69 106 -225 106q-80 0 -121 -27.5t-41 -70.5q0 -41 37 -65.5t146 -51.5 q179 -44 255.5 -87.5t116 -108t39.5 -158.5q0 -104 -52.5 -178t-149 -113t-220.5 -39q-329 0 -448 183zM164 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x15e;" horiz-adv-x="1229" d="M66 229l217 166q48 -68 91 -102t102 -53t136 -19q115 0 179.5 39.5t64.5 120.5q0 46 -22.5 77t-67.5 53.5t-156 51.5q-108 29 -203.5 58.5t-165 76.5t-109.5 118t-40 179q0 197 133 307.5t381 110.5q359 0 508 -246l-215 -168q-57 88 -128 126t-169 38t-159.5 -35.5 t-61.5 -111.5q0 -67 64 -102.5t223 -71.5q88 -23 174 -49.5t153.5 -73.5t108.5 -123t41 -195q0 -186 -108.5 -294.5t-319.5 -129.5q59 -16 100 -63t41 -119q0 -190 -287 -190q-171 0 -264 45l70 145q106 -45 192 -45q54 0 75.5 11.5t21.5 35.5q0 63 -181 72l54 104 q-165 12 -279 71t-194 185z" />
+<glyph unicode="&#x15f;" horiz-adv-x="1026" d="M76 152l192 135q47 -64 108.5 -85.5t131.5 -21.5q184 0 184 107q0 47 -52 72.5t-163 52.5q-209 46 -294 130t-85 218q0 139 106.5 229t313.5 90q141 0 248.5 -45t165.5 -135l-193 -137q-69 106 -225 106q-80 0 -121 -27.5t-41 -70.5q0 -41 37 -65.5t146 -51.5 q179 -44 255.5 -87.5t116 -108t39.5 -158.5q0 -130 -80.5 -213t-228.5 -106v-3q61 -14 103 -61t42 -121q0 -190 -286 -190q-172 0 -265 45l70 145q106 -45 193 -45q53 0 74.5 11.5t21.5 35.5q0 63 -180 72l53 102q-281 19 -387 181z" />
+<glyph unicode="&#x160;" horiz-adv-x="1229" d="M66 229l217 166q48 -68 91 -102t102 -53t136 -19q115 0 179.5 39.5t64.5 120.5q0 46 -22.5 77t-67.5 53.5t-156 51.5q-108 29 -203.5 58.5t-165 76.5t-109.5 118t-40 179q0 197 133 307.5t381 110.5q359 0 508 -246l-215 -168q-57 88 -128 126t-169 38t-159.5 -35.5 t-61.5 -111.5q0 -67 64 -102.5t223 -71.5q88 -23 174 -49.5t153.5 -73.5t108.5 -123t41 -195q0 -208 -136.5 -319t-402.5 -111q-184 0 -319.5 61t-220.5 197zM223 1905h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x161;" horiz-adv-x="1026" d="M76 152l192 135q47 -64 108.5 -85.5t131.5 -21.5q184 0 184 107q0 47 -52 72.5t-163 52.5q-209 46 -294 130t-85 218q0 139 106.5 229t313.5 90q141 0 248.5 -45t165.5 -135l-193 -137q-69 106 -225 106q-80 0 -121 -27.5t-41 -70.5q0 -41 37 -65.5t146 -51.5 q179 -44 255.5 -87.5t116 -108t39.5 -158.5q0 -104 -52.5 -178t-149 -113t-220.5 -39q-329 0 -448 183zM129 1569h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x162;" horiz-adv-x="1204" d="M35 1126v258h1134v-258h-426v-1126h-65l-10 -23q94 -12 140 -60t46 -122q0 -190 -287 -190q-171 0 -264 45l70 145q106 -45 192 -45q53 0 75 11.5t22 35.5q0 63 -181 72l68 131h-88v1126h-426z" />
+<glyph unicode="&#x163;" horiz-adv-x="739" d="M31 844v205h133v292h258v-292h244v-205h-244v-494q0 -98 30.5 -133t86.5 -35q71 0 141 29l45 -211q-63 -18 -156 -27q54 -18 90.5 -63t36.5 -115q0 -190 -286 -190q-172 0 -265 45l70 145q106 -45 193 -45q53 0 74.5 11.5t21.5 35.5q0 63 -180 72l57 113 q-115 24 -166 106t-51 229v527h-133z" />
+<glyph unicode="&#x164;" horiz-adv-x="1204" d="M35 1126v258h1134v-258h-426v-1126h-282v1126h-426zM246 1905h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x165;" horiz-adv-x="739" d="M31 844v205h133v292h258v-292h244v-205h-244v-494q0 -98 30.5 -133t86.5 -35q71 0 141 29l45 -211q-104 -31 -219 -31q-182 0 -262 82t-80 266v527h-133zM514 1128l55 361h271l-166 -361h-160z" />
+<glyph unicode="&#x166;" horiz-adv-x="1204" d="M35 1126v258h1134v-258h-426v-270h195v-184h-195v-672h-282v672h-195v184h195v270h-426z" />
+<glyph unicode="&#x167;" horiz-adv-x="739" d="M10 537v184h154v123h-133v205h133v292h258v-292h244v-205h-244v-123h260v-184h-260v-187q0 -98 30.5 -133t86.5 -35q71 0 141 29l45 -211q-104 -31 -219 -31q-182 0 -262 82t-80 266v220h-154z" />
+<glyph unicode="&#x168;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM316 1567q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92h182 q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
+<glyph unicode="&#x169;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM217 1231q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92 h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
+<glyph unicode="&#x16a;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM397 1591v185h672v-185h-672z" />
+<glyph unicode="&#x16b;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM266 1255v185h672v-185h-672z" />
+<glyph unicode="&#x16c;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM371 1845h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5 t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162z" />
+<glyph unicode="&#x16d;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM242 1509h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5 t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162z" />
+<glyph unicode="&#x16e;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM494 1716q0 107 57.5 166.5t171.5 59.5q119 0 175.5 -60.5t56.5 -165.5q0 -110 -59.5 -167.5t-172.5 -57.5 q-117 0 -173 60.5t-56 164.5zM637 1716q0 -90 86 -90q88 0 88 90t-88 90q-86 0 -86 -90z" />
+<glyph unicode="&#x16f;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM363 1380q0 107 57.5 166.5t171.5 59.5q119 0 175.5 -60.5t56.5 -165.5q0 -110 -59.5 -167.5 t-172.5 -57.5q-117 0 -173 60.5t-56 164.5zM506 1380q0 -90 86 -90q88 0 88 90t-88 90q-86 0 -86 -90z" />
+<glyph unicode="&#x170;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM387 1544l189 361h315l-299 -361h-205zM803 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x171;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM286 1208l189 361h315l-299 -361h-205zM702 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x172;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -302 -110 -443q-69 -86 -106.5 -163.5t-37.5 -114.5q0 -33 17.5 -47.5t42.5 -14.5q16 0 45.5 7.5t54.5 23.5l94 -158q-128 -63 -239 -63q-105 0 -162.5 47t-57.5 133 q0 101 60 197q-78 -13 -170 -13q-302 0 -435.5 140.5t-133.5 468.5z" />
+<glyph unicode="&#x173;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049q-137 -29 -195.5 -63.5t-58.5 -79.5q0 -33 17.5 -47.5t42.5 -14.5q16 0 45.5 7.5t54.5 23.5l94 -158q-128 -63 -240 -63q-104 0 -161.5 47t-57.5 133q0 90 60.5 148.5 t140.5 91.5v110q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5z" />
+<glyph unicode="&#x174;" horiz-adv-x="1833" d="M43 1384h281l221 -903l229 903h279l231 -909l227 909h279l-358 -1384h-289l-232 915l-233 -915h-285zM561 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x175;" horiz-adv-x="1565" d="M27 1049h268l162 -676l235 676h195l237 -670l156 670h258l-281 -1049h-235l-236 668l-237 -668h-236zM428 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x176;" horiz-adv-x="1188" d="M18 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522zM238 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x177;" horiz-adv-x="1085" d="M-20 -365l55 224q84 -29 151 -29q58 0 102 35t91 145l27 62l-379 977h268l248 -670l254 670h262l-451 -1121q-55 -135 -107 -200t-121.5 -94t-174.5 -29q-114 0 -225 30zM182 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
<glyph unicode="&#x178;" horiz-adv-x="1188" d="M18 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522zM226 1671q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM670 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102 t-110 -29q-82 0 -111.5 34t-29.5 97z" />
-<glyph unicode="&#x2c6;" horiz-adv-x="1044" d="M164 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
-<glyph unicode="&#x2dc;" horiz-adv-x="1044" d="M113 1231q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
-<glyph unicode="&#x2000;" horiz-adv-x="971" />
-<glyph unicode="&#x2001;" horiz-adv-x="1942" />
-<glyph unicode="&#x2002;" horiz-adv-x="971" />
-<glyph unicode="&#x2003;" horiz-adv-x="1942" />
-<glyph unicode="&#x2004;" horiz-adv-x="647" />
-<glyph unicode="&#x2005;" horiz-adv-x="485" />
-<glyph unicode="&#x2006;" horiz-adv-x="323" />
-<glyph unicode="&#x2007;" horiz-adv-x="323" />
-<glyph unicode="&#x2008;" horiz-adv-x="242" />
-<glyph unicode="&#x2009;" horiz-adv-x="388" />
-<glyph unicode="&#x200a;" horiz-adv-x="107" />
+<glyph unicode="&#x179;" horiz-adv-x="1147" d="M72 0v238l635 888h-605v258h942v-227l-641 -899h658v-258h-989zM395 1542l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x17a;" horiz-adv-x="930" d="M57 0v188l490 656h-477v205h786v-187l-491 -657h507v-205h-815zM287 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x17b;" horiz-adv-x="1147" d="M72 0v238l635 888h-605v258h942v-227l-641 -899h658v-258h-989zM414 1669q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x17c;" horiz-adv-x="930" d="M57 0v188l490 656h-477v205h786v-187l-491 -657h507v-205h-815zM315 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x17d;" horiz-adv-x="1147" d="M72 0v238l635 888h-605v258h942v-227l-641 -899h658v-258h-989zM199 1903h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x17e;" horiz-adv-x="930" d="M57 0v188l490 656h-477v205h786v-187l-491 -657h507v-205h-815zM100 1569h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x17f;" horiz-adv-x="614" d="M45 844v205h123v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-1151h-258v844h-123z" />
+<glyph unicode="&#x192;" horiz-adv-x="1038" d="M-270 -365l90 230q97 -35 168 -35q75 0 110 33t52 110l169 871h-133l39 205h133l21 102q40 197 154 283t305 86q53 0 114.5 -8.5t104.5 -22.5l-90 -227q-94 32 -168 32q-76 0 -111 -32.5t-51 -110.5l-21 -102h203l-39 -205h-202l-170 -871q-35 -178 -141.5 -273 t-317.5 -95q-127 0 -219 30z" />
+<glyph unicode="&#x1a0;" horiz-adv-x="1540" d="M86 692q0 344 144.5 532.5t451.5 188.5q386 0 518 -297h23q86 0 116.5 40t30.5 128v162h211v-162q0 -170 -74.5 -255t-234.5 -85h-17q23 -119 23 -252q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM377 692q0 -246 70.5 -358.5t234.5 -112.5 q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5z" />
+<glyph unicode="&#x1a1;" horiz-adv-x="1352" d="M92 522q0 266 121 411.5t383 145.5q328 0 440 -237q84 0 115 40t31 128v120h211v-120q0 -318 -306 -340q11 -77 11 -148q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5 q-126 0 -182 -81.5t-56 -250.5z" />
+<glyph unicode="&#x1af;" horiz-adv-x="1622" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-268h17q86 0 116.5 40t30.5 128v162h211v-162q0 -340 -346 -340h-29v-366q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5z" />
+<glyph unicode="&#x1b0;" horiz-adv-x="1395" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-207h12q84 0 113 40t29 128v120h211v-120q0 -340 -340 -340h-25v-670h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5z" />
+<glyph unicode="&#x1cd;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM309 1905h211l145 -174l150 174h209l-236 -361h-244zM477 528h373l-186 572z" />
+<glyph unicode="&#x1ce;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM211 1569h211 l145 -174l150 174h209l-236 -361h-244zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
+<glyph unicode="&#x1cf;" horiz-adv-x="872" d="M80 1905h211l145 -174l150 174h209l-236 -361h-244zM102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668z" />
+<glyph unicode="&#x1d0;" horiz-adv-x="549" d="M-80 1569h211l145 -174l150 174h209l-236 -361h-244zM145 0v1049h258v-1049h-258z" />
+<glyph unicode="&#x1d1;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM322 1905h211l145 -174l150 174h209l-236 -361h-244zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5 t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5z" />
+<glyph unicode="&#x1d2;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM238 1569h211l145 -174l150 174h209l-236 -361h-244zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5 q-126 0 -182 -81.5t-56 -250.5z" />
+<glyph unicode="&#x1d3;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM369 1905h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x1d4;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM250 1569h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x1d5;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM351 1640q0 70 31.5 101t109.5 31t111.5 -30t33.5 -102q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34 t-29.5 97zM385 1835v184h672v-184h-672zM795 1640q0 70 31.5 101t109.5 31t112 -30t34 -102q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1d6;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM242 1305q0 69 31.5 100t109.5 31t111.5 -30t33.5 -101q0 -74 -35.5 -102.5t-109.5 -28.5 q-82 0 -111.5 33.5t-29.5 97.5zM276 1499v184h672v-184h-672zM686 1305q0 69 31.5 100t109.5 31t112 -30t34 -101q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 33.5t-29.5 97.5z" />
+<glyph unicode="&#x1d7;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM357 1640q0 70 31.5 101t109.5 31t111.5 -30t33.5 -102q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34 t-29.5 97zM608 1798l123 291h316l-244 -291h-195zM801 1640q0 70 31.5 101t109.5 31t112 -30t34 -102q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1d8;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM242 1305q0 69 31.5 100t109.5 31t111.5 -30t33.5 -101q0 -74 -35.5 -102.5t-109.5 -28.5 q-82 0 -111.5 33.5t-29.5 97.5zM493 1462l123 291h316l-244 -291h-195zM686 1305q0 69 31.5 100t109.5 31t112 -30t34 -101q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 33.5t-29.5 97.5z" />
+<glyph unicode="&#x1d9;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM359 1638q0 70 31.5 99.5t109.5 29.5t111.5 -28.5t33.5 -100.5q0 -73 -35.5 -101t-109.5 -28 q-82 0 -111.5 33t-29.5 96zM371 2089h211l145 -139l150 139h209l-236 -291h-244zM803 1638q0 70 31.5 99.5t109.5 29.5t112 -28.5t34 -100.5q0 -73 -36 -101t-110 -28q-82 0 -111.5 33t-29.5 96z" />
+<glyph unicode="&#x1da;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM242 1303q0 69 31.5 99t109.5 30t111.5 -29t33.5 -100q0 -74 -35.5 -101.5t-109.5 -27.5 q-82 0 -111.5 32.5t-29.5 96.5zM254 1753h211l145 -139l150 139h209l-236 -291h-244zM686 1303q0 69 31.5 99t109.5 30t112 -29t34 -100q0 -74 -36 -101.5t-110 -27.5q-82 0 -111.5 32.5t-29.5 96.5z" />
+<glyph unicode="&#x1db;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM355 1640q0 70 31.5 101t109.5 31t111.5 -30t33.5 -102q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34 t-29.5 97zM391 2089h316l123 -291h-195zM799 1640q0 70 31.5 101t109.5 31t112 -30t34 -102q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1dc;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM242 1305q0 69 31.5 100t109.5 31t111.5 -30t33.5 -101q0 -74 -35.5 -102.5t-109.5 -28.5 q-82 0 -111.5 33.5t-29.5 97.5zM278 1753h316l123 -291h-195zM686 1305q0 69 31.5 100t109.5 31t112 -30t34 -101q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 33.5t-29.5 97.5z" />
+<glyph unicode="&#x1fa;" horiz-adv-x="1337" d="M27 0l448 1352q-35 43 -35 123q0 106 57.5 163.5t172.5 57.5q118 0 174.5 -58.5t56.5 -162.5q0 -82 -37 -127l447 -1348h-289l-92 281h-533l-90 -281h-280zM477 528h373l-186 572zM557 1749l131 279h316l-242 -279h-205zM584 1475q0 -86 86 -86q88 0 88 86t-88 86 q-86 0 -86 -86z" />
+<glyph unicode="&#x1fb;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM309 1378 q0 107 57.5 166.5t171.5 59.5q119 0 175.5 -60.5t56.5 -165.5q0 -110 -59.5 -167.5t-172.5 -57.5q-117 0 -173 60.5t-56 164.5zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM379 1659l189 361h315 l-299 -361h-205zM452 1378q0 -90 86 -90q88 0 88 90t-88 90q-86 0 -86 -90z" />
+<glyph unicode="&#x1fc;" horiz-adv-x="1810" d="M20 0l555 1384h1135v-249h-567v-301h469v-250h-469v-326h567v-258h-850v360h-409l-144 -360h-287zM547 608h313v527h-104zM858 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x1fd;" horiz-adv-x="1786" d="M84 303q0 157 105.5 244t332.5 106l221 21v47q0 86 -52 119.5t-148 33.5q-109 0 -162 -32.5t-80 -75.5l-201 129q53 89 164.5 136.5t276.5 47.5q254 0 356 -123q121 123 350 123q220 0 335.5 -127.5t115.5 -367.5v-127h-697q7 -140 67 -201t196 -61q73 0 130.5 19 t100.5 73l193 -137q-64 -91 -162.5 -136t-257.5 -45q-299 0 -428 168q-97 -82 -196 -125t-212 -43q-170 0 -259 91.5t-89 242.5zM350 299q0 -125 139 -125q64 0 140 25.5t141 76.5q-13 40 -20 113t-7 98l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM743 1208l189 361h315 l-299 -361h-205zM1008 635h434q0 239 -211 239q-113 0 -160 -64.5t-63 -174.5z" />
+<glyph unicode="&#x1fe;" horiz-adv-x="1364" d="M27 -115l194 285q-135 180 -135 522q0 344 144.5 532.5t451.5 188.5q201 0 334 -84l108 160h199l-184 -270q139 -182 139 -527q0 -361 -152.5 -541t-443.5 -180q-207 0 -338 86l-117 -172h-200zM377 692q0 -157 26 -256l461 674q-69 53 -182 53q-166 0 -235.5 -112.5 t-69.5 -358.5zM496 276q67 -55 186 -55q166 0 235.5 112.5t69.5 358.5q0 158 -29 262zM512 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x1ff;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q141 0 246 -47l61 92h182l-118 -180q131 -145 131 -422q0 -262 -121 -407.5t-381 -145.5q-144 0 -248 45l-59 -90h-183l117 176q-131 141 -131 422zM358 522q0 -103 23 -184l328 493q-45 23 -113 23q-126 0 -182 -81.5t-56 -250.5z M426 1208l189 361h315l-299 -361h-205zM483 215q47 -20 113 -20q125 0 180 78.5t55 248.5q0 108 -22 185z" />
+<glyph unicode="&#x218;" horiz-adv-x="1229" d="M66 229l217 166q48 -68 91 -102t102 -53t136 -19q115 0 179.5 39.5t64.5 120.5q0 46 -22.5 77t-67.5 53.5t-156 51.5q-108 29 -203.5 58.5t-165 76.5t-109.5 118t-40 179q0 197 133 307.5t381 110.5q359 0 508 -246l-215 -168q-57 88 -128 126t-169 38t-159.5 -35.5 t-61.5 -111.5q0 -67 64 -102.5t223 -71.5q88 -23 174 -49.5t153.5 -73.5t108.5 -123t41 -195q0 -208 -136.5 -319t-402.5 -111q-184 0 -319.5 61t-220.5 197zM496 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42 t-29.5 114z" />
+<glyph unicode="&#x219;" horiz-adv-x="1026" d="M76 152l192 135q47 -64 108.5 -85.5t131.5 -21.5q184 0 184 107q0 47 -52 72.5t-163 52.5q-209 46 -294 130t-85 218q0 139 106.5 229t313.5 90q141 0 248.5 -45t165.5 -135l-193 -137q-69 106 -225 106q-80 0 -121 -27.5t-41 -70.5q0 -41 37 -65.5t146 -51.5 q179 -44 255.5 -87.5t116 -108t39.5 -158.5q0 -104 -52.5 -178t-149 -113t-220.5 -39q-329 0 -448 183zM371 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#x21a;" horiz-adv-x="1204" d="M35 1126v258h1134v-258h-426v-1126h-282v1126h-426zM453 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#x21b;" horiz-adv-x="739" d="M31 844v205h133v292h258v-292h244v-205h-244v-494q0 -98 30.5 -133t86.5 -35q71 0 141 29l45 -211q-104 -31 -219 -31q-182 0 -262 82t-80 266v527h-133zM270 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42 t-29.5 114z" />
+<glyph unicode="&#x237;" horiz-adv-x="563" d="M-162 -365l56 224q73 -29 151 -29t96.5 48t18.5 159v1012h258v-1094q0 -188 -84 -269t-275 -81q-43 0 -113 9.5t-108 20.5z" />
+<glyph unicode="&#x2c0;" horiz-adv-x="1018" d="M-10 1165q69 123 180 185.5t287 62.5q235 0 362 -106t127 -295q0 -111 -37 -195.5t-109 -153.5t-218 -147v-516h-263v639q137 61 211 113t107 108t33 137q0 78 -51.5 134.5t-159.5 56.5q-90 0 -144.5 -36t-99.5 -110z" />
+<glyph unicode="&#x2c6;" d="M164 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph unicode="&#x2c7;" d="M164 1569h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph unicode="&#x2c9;" d="M186 1255v185h672v-185h-672z" />
+<glyph unicode="&#x2d8;" d="M162 1509h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162z" />
+<glyph unicode="&#x2d9;" d="M379 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x2da;" d="M291 1378q0 107 57.5 166.5t171.5 59.5q119 0 175.5 -60.5t56.5 -165.5q0 -110 -59.5 -167.5t-172.5 -57.5q-117 0 -173 60.5t-56 164.5zM434 1378q0 -90 86 -90q88 0 88 90t-88 90q-86 0 -86 -90z" />
+<glyph unicode="&#x2db;" d="M375 -215q0 75 50.5 134.5t137 100.5t180.5 52l91 -72q-138 -29 -196 -63.5t-58 -79.5q0 -62 59 -62q16 0 46 7.5t54 23.5l95 -158q-131 -63 -240 -63q-105 0 -162 47t-57 133z" />
+<glyph unicode="&#x2dc;" d="M113 1231q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
+<glyph unicode="&#x2dd;" d="M145 1208l189 361h315l-299 -361h-205zM561 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x300;" horiz-adv-x="0" d="M-328 1569h316l188 -361h-205z" />
+<glyph unicode="&#x301;" horiz-adv-x="0" d="M-174 1208l188 361h316l-299 -361h-205z" />
+<glyph unicode="&#x302;" horiz-adv-x="0" d="M-358 1208l235 361h244l235 -361h-211l-145 174l-150 -174h-208z" />
+<glyph unicode="&#x303;" horiz-adv-x="0" d="M-410 1231q5 152 73 234.5t190 82.5q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q67 0 67 127h183q-13 -171 -79 -246.5t-186 -75.5q-65 0 -108 22.5t-76 50.5t-59.5 50.5t-59.5 22.5q-67 0 -67 -127h-183z" />
+<glyph unicode="&#x304;" horiz-adv-x="0" d="M-336 1255v185h672v-185h-672z" />
+<glyph unicode="&#x306;" horiz-adv-x="0" d="M-360 1530h188q14 -47 57 -76t117 -29q68 0 112 29t58 76h188q0 -89 -45 -163t-127.5 -117.5t-187.5 -43.5t-188 44t-127.5 118t-44.5 162z" />
+<glyph unicode="&#x307;" horiz-adv-x="0" d="M-143 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x308;" horiz-adv-x="0" d="M-367 1335q0 70 32 100.5t110 30.5t111.5 -29.5t33.5 -101.5q0 -73 -36 -102t-109 -29q-82 0 -112 34t-30 97zM80 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x309;" horiz-adv-x="0" d="M-207 1487q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-57 0 -97 -25z" />
+<glyph unicode="&#x30a;" horiz-adv-x="0" d="M-215 1366q0 100 52 156.5t161 56.5q113 0 164 -57.5t51 -155.5q0 -104 -54.5 -158.5t-160.5 -54.5q-111 0 -162 57.5t-51 155.5zM-88 1366q0 -90 86 -90q88 0 88 90t-88 90q-86 0 -86 -90z" />
+<glyph unicode="&#x30c;" horiz-adv-x="0" d="M-358 1569h211l145 -174l149 174h209l-235 -361h-244z" />
+<glyph unicode="&#x323;" d="M379 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x374;" horiz-adv-x="438" d="M72 1128l55 361h270l-166 -361h-159z" />
+<glyph unicode="&#x375;" horiz-adv-x="438" d="M57 -231l166 360h160l-55 -360h-271z" />
+<glyph unicode="&#x37e;" horiz-adv-x="584" d="M129 145q0 74 35 117t131 43q160 0 160 -180q0 -123 -42 -234.5t-91 -183.5h-177q41 69 72.5 151t36.5 132q-66 4 -95.5 42t-29.5 113zM129 889q0 82 36 121t126 39q92 0 128 -38t36 -122q0 -86 -39 -123t-125 -37q-94 0 -128 41t-34 119z" />
+<glyph unicode="&#x384;" horiz-adv-x="504" d="M0 1208l188 361h316l-299 -361h-205z" />
+<glyph unicode="&#x385;" horiz-adv-x="0" d="M152 1333q0 68 31.5 100.5t103.5 32.5q73 0 106 -31.5t33 -101.5q0 -71 -35 -100t-104 -29q-78 0 -106.5 35t-28.5 94zM471 1208l123 361h274l-213 -361h-184zM834 1333q0 68 32.5 100.5t104.5 32.5q73 0 106 -31.5t33 -101.5q0 -71 -35 -100t-104 -29q-78 0 -107.5 35 t-29.5 94z" />
+<glyph unicode="&#x386;" horiz-adv-x="1382" d="M2 1024l123 360h275l-213 -360h-185zM72 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM522 528h373l-186 572z" />
+<glyph unicode="&#x387;" horiz-adv-x="584" d="M129 743q0 82 36 121t126 39q92 0 128 -38t36 -122q0 -86 -39 -122.5t-125 -36.5q-94 0 -128 41t-34 118z" />
+<glyph unicode="&#x388;" horiz-adv-x="1438" d="M2 1024l123 360h275l-213 -360h-185zM439 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899z" />
+<glyph unicode="&#x389;" horiz-adv-x="1698" d="M2 1024l123 360h275l-213 -360h-185zM439 0v1384h282v-538h545v538h283v-1384h-283v588h-545v-588h-282z" />
+<glyph unicode="&#x38a;" horiz-adv-x="1210" d="M2 1024l123 360h275l-213 -360h-185zM440 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668z" />
+<glyph unicode="&#x38c;" horiz-adv-x="1614" d="M2 1024l123 360h275l-213 -360h-185zM336 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM627 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5 t-235.5 112.5t-235.5 -112.5t-69.5 -358.5z" />
+<glyph unicode="&#x38e;" horiz-adv-x="1599" d="M2 1024l123 360h275l-213 -360h-185zM430 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522z" />
+<glyph unicode="&#x38f;" horiz-adv-x="1751" d="M2 1024l123 360h275l-213 -360h-185zM336 807q0 182 69.5 319.5t202 212t324.5 74.5q289 0 444.5 -157.5t155.5 -448.5q0 -204 -58 -333t-194 -193v-31h242v-250h-490v401q107 16 156 115t49 291q0 168 -75.5 262t-229.5 94q-149 0 -227 -89t-78 -265q0 -139 18.5 -220.5 t58.5 -125t128 -62.5v-401h-486v250h248v31q-102 35 -155 94t-78 162t-25 270z" />
+<glyph unicode="&#x390;" horiz-adv-x="682" d="M-190 1333q0 68 31.5 100.5t103.5 32.5q73 0 106 -31.5t33 -101.5q0 -71 -35 -100t-104 -29q-78 0 -106.5 35t-28.5 94zM129 1208l123 361h274l-213 -361h-184zM137 311v738h258v-711q0 -90 20.5 -126t82.5 -36q64 0 110 19l60 -195q-105 -31 -224 -31q-161 0 -234 77.5 t-73 264.5zM492 1333q0 68 32.5 100.5t104.5 32.5q73 0 106 -31.5t33 -101.5q0 -71 -35 -100t-104 -29q-78 0 -107.5 35t-29.5 94z" />
+<glyph unicode="&#x391;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM477 528h373l-186 572z" />
+<glyph unicode="&#x392;" horiz-adv-x="1298" d="M150 0v1384h489q266 0 381 -77.5t115 -245.5q0 -129 -62.5 -209t-195.5 -107q174 -24 253.5 -110t79.5 -234q0 -208 -143 -304.5t-397 -96.5h-520zM432 250h143q165 0 227.5 16t91 54t28.5 106q0 93 -63 131.5t-236 38.5h-191v-346zM432 842h172q125 0 185.5 35t60.5 122 q0 79 -58 109.5t-180 30.5h-180v-297z" />
+<glyph unicode="&#x393;" horiz-adv-x="1065" d="M127 0v1384h897v-235h-614v-1149h-283z" />
+<glyph unicode="&#x394;" horiz-adv-x="1284" d="M27 0v115l222 635q141 406 224 634h344l440 -1269v-115h-1230zM340 236h584l-260 763q-13 37 -18 68t-9 41h-8q-14 -72 -25 -104z" />
+<glyph unicode="&#x395;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899z" />
+<glyph unicode="&#x396;" horiz-adv-x="1147" d="M72 0v238l635 888h-605v258h942v-227l-641 -899h658v-258h-989z" />
+<glyph unicode="&#x397;" horiz-adv-x="1409" d="M150 0v1384h282v-538h545v538h283v-1384h-283v588h-545v-588h-282z" />
+<glyph unicode="&#x398;" horiz-adv-x="1448" d="M86 692q0 368 156 544.5t483 176.5q326 0 481.5 -177.5t155.5 -543.5q0 -368 -157 -544.5t-480 -176.5q-322 0 -480.5 176.5t-158.5 544.5zM381 692q0 -246 78 -368.5t266 -122.5q186 0 263 122.5t77 368.5q0 248 -77 370t-263 122q-188 0 -266 -123t-78 -369zM473 582 v223h502v-223h-502z" />
+<glyph unicode="&#x399;" horiz-adv-x="872" d="M102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668z" />
+<glyph unicode="&#x39a;" horiz-adv-x="1280" d="M150 0v1384h282v-540l453 540h329l-516 -596l553 -788h-352l-383 578l-84 -97v-481h-282z" />
+<glyph unicode="&#x39b;" horiz-adv-x="1272" d="M27 0l469 1384h286l463 -1384h-291l-323 1024l-330 -1024h-274z" />
+<glyph unicode="&#x39c;" horiz-adv-x="1667" d="M150 0v1384h325l361 -657l364 657h318v-1384h-273v930l-332 -578h-163l-328 578v-930h-272z" />
+<glyph unicode="&#x39d;" horiz-adv-x="1411" d="M150 0v1384h366l469 -933v933h277v-1384h-332l-504 989v-989h-276z" />
+<glyph unicode="&#x39e;" horiz-adv-x="1096" d="M100 0v258h895v-258h-895zM100 1135v249h895v-249h-895zM160 590v250h776v-250h-776z" />
+<glyph unicode="&#x39f;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5 t-69.5 -358.5z" />
+<glyph unicode="&#x3a0;" horiz-adv-x="1417" d="M150 0v1384h1118v-1384h-289v1143h-541v-1143h-288z" />
+<glyph unicode="&#x3a1;" horiz-adv-x="1239" d="M150 0v1384h520q235 0 363 -109.5t128 -354.5q0 -250 -117.5 -371t-381.5 -121h-230v-428h-282zM432 674h115q155 0 214.5 21.5t84 72.5t24.5 150q0 117 -64.5 169t-232.5 52h-141v-465z" />
+<glyph unicode="&#x3a3;" horiz-adv-x="1169" d="M72 0v211l452 491l-452 478v204h977v-227h-603l347 -366v-175l-363 -389h655v-227h-1013z" />
+<glyph unicode="&#x3a4;" horiz-adv-x="1204" d="M35 1126v258h1134v-258h-426v-1126h-282v1126h-426z" />
+<glyph unicode="&#x3a5;" horiz-adv-x="1188" d="M18 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522z" />
+<glyph unicode="&#x3a6;" horiz-adv-x="1489" d="M86 690q0 270 132.5 413t387.5 171v188h279v-188q518 -64 518 -584q0 -522 -518 -586v-182h-279v182q-262 32 -391 177.5t-129 408.5zM381 690q0 -162 56.5 -246t168.5 -110v717q-112 -27 -168.5 -111t-56.5 -250zM885 334q114 26 169.5 110t55.5 246q0 166 -55.5 250 t-169.5 111v-717z" />
+<glyph unicode="&#x3a7;" horiz-adv-x="1286" d="M29 0l463 694l-451 690h321l287 -466l297 466h311l-454 -684l452 -700h-317l-297 477l-301 -477h-311z" />
+<glyph unicode="&#x3a8;" horiz-adv-x="1487" d="M102 795v589h283v-571q0 -149 62 -231t147 -82h8v884h283v-886h7q57 0 104.5 38.5t77.5 111.5t30 161v575h280v-589q0 -252 -121 -385t-378 -160v-275h-283v275q-259 27 -379.5 161t-120.5 384z" />
+<glyph unicode="&#x3a9;" horiz-adv-x="1368" d="M86 807q0 182 69.5 319.5t202 212t324.5 74.5q289 0 444.5 -157.5t155.5 -448.5q0 -204 -58 -333t-194 -193v-31h242v-250h-490v401q107 16 156 115t49 291q0 168 -75.5 262t-229.5 94q-149 0 -227 -89t-78 -265q0 -139 18.5 -220.5t58.5 -125t128 -62.5v-401h-486v250 h248v31q-102 35 -155 94t-78 162t-25 270z" />
+<glyph unicode="&#x3aa;" horiz-adv-x="872" d="M74 1671q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668zM518 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102 t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x3ab;" horiz-adv-x="1188" d="M18 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522zM226 1671q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM670 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102 t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x3ac;" horiz-adv-x="1327" d="M92 522q0 263 122.5 410t346.5 147q176 0 301 -118l17 88h258q-46 -213 -59 -304t-13 -170v-237q0 -96 22.5 -129t79.5 -33q52 0 90 19l60 -195q-87 -31 -203 -31q-137 0 -195.5 59.5t-70.5 182.5q-92 -242 -316 -242q-219 0 -329.5 144.5t-110.5 408.5zM360 516 q0 -167 49.5 -251.5t145.5 -84.5q115 0 192.5 154t94.5 418q-51 59 -117 90.5t-123 31.5q-123 0 -182.5 -87.5t-59.5 -270.5zM518 1208l188 361h316l-299 -361h-205z" />
+<glyph unicode="&#x3ad;" horiz-adv-x="1063" d="M92 299q0 70 44 134t106 89q-62 23 -106 78t-44 141q0 160 132.5 249t371.5 89q301 0 412 -180l-181 -125q-41 55 -92 82t-137 27q-112 0 -175 -36t-63 -108q0 -71 54.5 -89.5t171.5 -18.5h223v-189h-234q-122 0 -168.5 -31.5t-46.5 -103.5q0 -64 60.5 -101.5 t161.5 -37.5q96 0 161.5 22.5t110.5 79.5l168 -120q-59 -89 -164.5 -135t-271.5 -46q-241 0 -367.5 85.5t-126.5 244.5zM436 1208l188 361h316l-299 -361h-205z" />
+<glyph unicode="&#x3ae;" horiz-adv-x="1227" d="M145 0v1049h244v-125q193 155 369 155q168 0 250 -92t82 -291v-1085h-259v1007q0 132 -29.5 185t-117.5 53q-57 0 -133 -39t-148 -94v-723h-258zM467 1208l188 361h316l-299 -361h-205z" />
+<glyph unicode="&#x3af;" horiz-adv-x="682" d="M104 1208l188 361h316l-299 -361h-205zM137 311v738h258v-711q0 -90 20.5 -126t82.5 -36q64 0 110 19l60 -195q-105 -31 -224 -31q-161 0 -234 77.5t-73 264.5z" />
+<glyph unicode="&#x3b0;" horiz-adv-x="1212" d="M123 1333q0 68 31.5 100.5t103.5 32.5q73 0 106 -31.5t33 -101.5q0 -71 -35 -100t-104 -29q-78 0 -106.5 35t-28.5 94zM137 365v684h258v-678q0 -93 58.5 -144t150.5 -51q118 0 179 90.5t61 270.5q0 147 -28 283t-50 229h254q33 -80 62.5 -226.5t29.5 -265.5 q0 -296 -122.5 -442t-391.5 -146q-233 0 -347 102t-114 294zM442 1208l123 361h274l-213 -361h-184zM805 1333q0 68 32.5 100.5t104.5 32.5q73 0 106 -31.5t33 -101.5q0 -71 -35 -100t-104 -29q-78 0 -107.5 35t-29.5 94z" />
+<glyph unicode="&#x3b1;" horiz-adv-x="1327" d="M92 522q0 263 122.5 410t346.5 147q176 0 301 -118l17 88h258q-46 -213 -59 -304t-13 -170v-237q0 -96 22.5 -129t79.5 -33q52 0 90 19l60 -195q-87 -31 -203 -31q-137 0 -195.5 59.5t-70.5 182.5q-92 -242 -316 -242q-219 0 -329.5 144.5t-110.5 408.5zM360 516 q0 -167 49.5 -251.5t145.5 -84.5q115 0 192.5 154t94.5 418q-51 59 -117 90.5t-123 31.5q-123 0 -182.5 -87.5t-59.5 -270.5z" />
+<glyph unicode="&#x3b2;" horiz-adv-x="1249" d="M145 -383v1407q0 260 117.5 378t347.5 118q200 0 316 -88.5t116 -251.5q0 -254 -270 -310q178 -24 277.5 -133.5t99.5 -269.5q0 -243 -116 -370.5t-328 -127.5q-95 0 -174.5 20.5t-127.5 47.5v-420h-258zM403 244q116 -68 263 -68q104 0 160.5 71.5t56.5 213.5 q0 141 -81 210.5t-265 69.5v205q116 0 179.5 52.5t63.5 154.5q0 66 -44 116t-136 50q-75 0 -118 -25.5t-61 -82.5t-18 -179v-788z" />
+<glyph unicode="&#x3b3;" horiz-adv-x="1155" d="M37 1049h274l264 -756q41 76 87.5 162t84 179t62.5 189.5t25 190.5v35h258v-45q0 -189 -109.5 -440.5t-308.5 -506.5v-446h-256v446z" />
+<glyph unicode="&#x3b4;" horiz-adv-x="1266" d="M92 463q0 345 369 498q-94 63 -145.5 131.5t-51.5 160.5q0 127 81 197t249 70q123 0 251.5 -32.5t203.5 -78.5l-99 -203q-82 47 -173 84t-179 37q-45 0 -61.5 -18.5t-16.5 -38.5q0 -38 16 -61t52.5 -52.5t101.5 -62.5q185 -100 287 -186t149.5 -182.5t47.5 -233.5 q0 -242 -147 -382.5t-396 -140.5q-166 0 -288.5 61t-186.5 173t-64 260zM360 463q0 -136 75 -211.5t210 -75.5q115 0 187.5 80t72.5 231q0 138 -74.5 228t-189.5 145q-80 -27 -144.5 -84t-100.5 -137.5t-36 -175.5z" />
+<glyph unicode="&#x3b5;" horiz-adv-x="1063" d="M92 299q0 70 44 134t106 89q-62 23 -106 78t-44 141q0 160 132.5 249t371.5 89q301 0 412 -180l-181 -125q-41 55 -92 82t-137 27q-112 0 -175 -36t-63 -108q0 -71 54.5 -89.5t171.5 -18.5h223v-189h-234q-122 0 -168.5 -31.5t-46.5 -103.5q0 -64 60.5 -101.5 t161.5 -37.5q96 0 161.5 22.5t110.5 79.5l168 -120q-59 -89 -164.5 -135t-271.5 -46q-241 0 -367.5 85.5t-126.5 244.5z" />
+<glyph unicode="&#x3b6;" horiz-adv-x="971" d="M100 459q0 145 56 301t162 298t255 238h-430v193h758v-158q-140 -85 -264 -230t-196 -311.5t-72 -316.5q0 -88 28.5 -143t80 -88.5t165.5 -59.5q118 -25 178 -59.5t89.5 -89.5t29.5 -142q0 -48 -26.5 -132t-57.5 -154h-250q49 118 64.5 172.5t15.5 89.5q0 31 -17 51 t-47 33.5t-102 25.5q-67 15 -142 35.5t-136.5 70.5t-101.5 138t-40 238z" />
+<glyph unicode="&#x3b7;" horiz-adv-x="1227" d="M145 0v1049h244v-125q193 155 369 155q168 0 250 -92t82 -291v-1085h-259v1007q0 132 -29.5 185t-117.5 53q-57 0 -133 -39t-148 -94v-723h-258z" />
+<glyph unicode="&#x3b8;" horiz-adv-x="1231" d="M109 748q0 317 50 465t159 227.5t298 79.5q186 0 296 -78.5t160 -227t50 -466.5q0 -313 -50.5 -465.5t-160 -233t-295.5 -80.5q-187 0 -296 80t-160 232t-51 467zM373 672q0 -210 23.5 -305.5t74.5 -143t141 -47.5q92 0 144.5 47t77 140.5t24.5 308.5h-485zM373 860h485 q-4 189 -29 275t-76 131t-137 45t-138 -43t-76.5 -130.5t-28.5 -277.5z" />
+<glyph unicode="&#x3b9;" horiz-adv-x="682" d="M137 311v738h258v-711q0 -90 20.5 -126t82.5 -36q64 0 110 19l60 -195q-105 -31 -224 -31q-161 0 -234 77.5t-73 264.5z" />
+<glyph unicode="&#x3ba;" horiz-adv-x="1137" d="M145 0v1049h258v-402l371 402h293l-416 -443l461 -606h-295l-317 440l-97 -96v-344h-258z" />
+<glyph unicode="&#x3bb;" horiz-adv-x="1196" d="M35 0l452 1049q-47 150 -66.5 187t-43 55t-60.5 18q-28 0 -70 -11.5t-77 -27.5l-59 188q130 62 245 62q113 0 193 -59.5t123 -198.5l276 -926q33 -102 51.5 -130t40.5 -28q38 0 80 17l62 -195q-121 -31 -195 -31q-76 0 -122.5 23t-83 79t-60.5 144l-141 528l-281 -743 h-264z" />
+<glyph unicode="&#x3bc;" horiz-adv-x="1202" d="M131 -395v1444h258v-750q29 -39 83 -69.5t114 -30.5q131 0 227 120v730h256v-1049h-238l-4 111q-49 -70 -104 -106t-133 -36q-62 0 -109 17.5t-92 52.5v-434h-258z" />
+<glyph unicode="&#x3bd;" horiz-adv-x="1155" d="M37 1049h274l275 -777q152 273 200 421t48 288v68h258v-62q0 -210 -123 -481.5t-318 -505.5h-219z" />
+<glyph unicode="&#x3be;" horiz-adv-x="987" d="M100 428q0 122 70 220.5t195 142.5q-91 34 -143 108t-52 166q0 78 43 143.5t115 91.5h-209v189h755v-193h-90q-188 0 -268 -51t-80 -178q0 -81 52.5 -130.5t136.5 -49.5h223v-193h-242q-104 0 -170.5 -72.5t-66.5 -181.5q0 -70 26 -117.5t71.5 -78.5t168.5 -64 q140 -34 197 -68t86.5 -86.5t29.5 -134.5q0 -92 -80 -286h-243q75 191 75 262q0 32 -14.5 52.5t-42.5 35.5t-127 41q-67 18 -141 41.5t-135.5 70t-100.5 122t-39 198.5z" />
+<glyph unicode="&#x3bf;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5z" />
+<glyph unicode="&#x3c0;" horiz-adv-x="1419" d="M14 969q56 28 150 54t203 26h983v-193h-242v-514q0 -92 30.5 -127t84.5 -35q41 0 75 15l48 -175q-33 -16 -89.5 -27t-115.5 -11q-135 0 -213 80.5t-78 252.5v541h-283v-555q0 -92 -5 -163.5t-25 -137.5h-287q57 187 57 313v539q-138 -23 -217 -64z" />
+<glyph unicode="&#x3c1;" horiz-adv-x="1251" d="M129 -389v924q0 262 126 403t392 141q252 0 382 -144t130 -392q0 -265 -126.5 -419.5t-332.5 -154.5q-176 0 -313 109v-467h-258zM387 291q135 -111 266 -111q113 0 175.5 79t62.5 267q0 177 -59.5 262.5t-184.5 85.5q-260 0 -260 -319v-264z" />
+<glyph unicode="&#x3c2;" horiz-adv-x="1057" d="M92 522q0 275 132 416t394 141q284 0 394 -180l-193 -137q-77 112 -198 112q-140 0 -200.5 -90t-60.5 -262q0 -92 26 -150.5t67 -95t92 -56t104 -36.5q136 -42 186.5 -77t78.5 -86t28 -127q0 -89 -80 -283h-254q80 187 80 260q0 42 -28 68t-132 57q-69 20 -146 49 t-141.5 85t-106.5 149.5t-42 242.5z" />
+<glyph unicode="&#x3c3;" horiz-adv-x="1311" d="M92 492q0 290 135.5 423.5t425.5 133.5h607v-191h-271q158 -162 158 -383q0 -151 -62.5 -266.5t-180.5 -177.5t-279 -62q-251 0 -392 137.5t-141 385.5zM360 485q0 -135 64.5 -222t204.5 -87q124 0 187 85.5t63 248.5q0 100 -27 191.5t-84 156.5h-147q-94 0 -151.5 -38.5 t-83.5 -115t-26 -219.5z" />
+<glyph unicode="&#x3c4;" horiz-adv-x="1075" d="M-4 973q144 76 348 76h680v-191h-356v-520q0 -90 30.5 -124t83.5 -34q43 0 78 15l47 -175q-35 -16 -93 -27t-114 -11q-135 0 -212.5 80.5t-77.5 248.5v547h-78q-92 0 -160 -23.5t-102 -39.5z" />
+<glyph unicode="&#x3c5;" horiz-adv-x="1212" d="M137 365v684h258v-678q0 -93 58.5 -144t150.5 -51q118 0 179 90.5t61 270.5q0 147 -28 283t-50 229h254q33 -80 62.5 -226.5t29.5 -265.5q0 -296 -122.5 -442t-391.5 -146q-233 0 -347 102t-114 294z" />
+<glyph unicode="&#x3c6;" horiz-adv-x="1434" d="M92 524q0 496 502 551v414h246v-414q252 -29 376.5 -170.5t124.5 -380.5q0 -240 -126 -380t-375 -167v-368h-246v368q-244 26 -373 164.5t-129 382.5zM360 524q0 -149 50.5 -238t183.5 -118v719q-133 -29 -183.5 -119t-50.5 -244zM840 168q131 29 183 119t52 237 q0 146 -52 239t-183 122v-717z" />
+<glyph unicode="&#x3c7;" horiz-adv-x="1202" d="M35 1030q117 49 207 49q84 0 147.5 -46t110.5 -161l114 -262l207 439h279l-379 -682l176 -398q35 -71 60.5 -105t74.5 -34q31 0 84 16l55 -184q-121 -51 -204 -51q-68 0 -115 25.5t-89 85t-86 159t-108 246.5l-256 -516h-276l424 768l-148 330q-34 75 -60 118t-79 43 q-35 0 -84 -16z" />
+<glyph unicode="&#x3c8;" horiz-adv-x="1532" d="M137 410v639h258v-592q0 -116 61 -185.5t191 -89.5v1293h252v-1291q142 34 207 125t65 230q0 166 -29.5 294t-58.5 216h258q33 -74 66 -225t33 -265q0 -256 -134 -404t-407 -178v-368h-252v366q-510 40 -510 435z" />
+<glyph unicode="&#x3c9;" horiz-adv-x="1718" d="M92 424q0 166 59.5 344.5t143.5 294.5l244 -45q-179 -314 -179 -572q0 -131 46.5 -200.5t130.5 -69.5t138 86t54 281v291h260v-291q0 -195 54.5 -281t138.5 -86t130 69.5t46 200.5q0 260 -178 572l243 45q98 -147 150.5 -316.5t52.5 -322.5q0 -226 -111.5 -340.5 t-322.5 -114.5q-115 0 -202 52.5t-128 154.5q-41 -102 -131 -154.5t-205 -52.5q-214 0 -324 116.5t-110 338.5z" />
+<glyph unicode="&#x3ca;" horiz-adv-x="682" d="M-90 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM137 311v738h258v-711q0 -90 20.5 -126t82.5 -36q64 0 110 19l60 -195q-105 -31 -224 -31q-161 0 -234 77.5t-73 264.5zM354 1335q0 70 31.5 100.5 t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x3cb;" horiz-adv-x="1212" d="M137 365v684h258v-678q0 -93 58.5 -144t150.5 -51q118 0 179 90.5t61 270.5q0 147 -28 283t-50 229h254q33 -80 62.5 -226.5t29.5 -265.5q0 -296 -122.5 -442t-391.5 -146q-233 0 -347 102t-114 294zM222 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5 q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM666 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x3cc;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5zM477 1208l188 361h316 l-299 -361h-205z" />
+<glyph unicode="&#x3cd;" horiz-adv-x="1212" d="M137 365v684h258v-678q0 -93 58.5 -144t150.5 -51q118 0 179 90.5t61 270.5q0 147 -28 283t-50 229h254q33 -80 62.5 -226.5t29.5 -265.5q0 -296 -122.5 -442t-391.5 -146q-233 0 -347 102t-114 294zM418 1208l188 361h316l-299 -361h-205z" />
+<glyph unicode="&#x3ce;" horiz-adv-x="1718" d="M92 424q0 166 59.5 344.5t143.5 294.5l244 -45q-179 -314 -179 -572q0 -131 46.5 -200.5t130.5 -69.5t138 86t54 281v291h260v-291q0 -195 54.5 -281t138.5 -86t130 69.5t46 200.5q0 260 -178 572l243 45q98 -147 150.5 -316.5t52.5 -322.5q0 -226 -111.5 -340.5 t-322.5 -114.5q-115 0 -202 52.5t-128 154.5q-41 -102 -131 -154.5t-205 -52.5q-214 0 -324 116.5t-110 338.5zM727 1208l188 361h316l-299 -361h-205z" />
+<glyph unicode="&#x400;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM267 1905h315l188 -361h-204z" />
+<glyph unicode="&#x401;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM228 1671q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM672 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102 t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x402;" horiz-adv-x="1389" d="M25 1151v233h770v-233h-248v-307h172q307 0 455.5 -102t148.5 -310q0 -157 -62 -250.5t-190.5 -137.5t-355.5 -44v233q166 0 238.5 42t72.5 163q0 98 -65.5 137t-212.5 39h-201v-614h-283v1151h-239z" />
+<glyph unicode="&#x403;" horiz-adv-x="1065" d="M127 0v1384h897v-235h-614v-1149h-283zM424 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x404;" horiz-adv-x="1309" d="M96 692q0 369 163 545t470 176q203 0 331 -68.5t195 -179.5l-219 -170q-48 72 -88 104t-91 48t-122 16q-145 0 -231 -77.5t-109 -260.5h576v-250h-578q17 -174 100 -264t244 -90q123 0 191.5 47t124.5 125l223 -164q-89 -133 -218.5 -195.5t-318.5 -62.5q-643 0 -643 721 z" />
+<glyph unicode="&#x405;" horiz-adv-x="1229" d="M66 229l217 166q48 -68 91 -102t102 -53t136 -19q115 0 179.5 39.5t64.5 120.5q0 46 -22.5 77t-67.5 53.5t-156 51.5q-108 29 -203.5 58.5t-165 76.5t-109.5 118t-40 179q0 197 133 307.5t381 110.5q359 0 508 -246l-215 -168q-57 88 -128 126t-169 38t-159.5 -35.5 t-61.5 -111.5q0 -67 64 -102.5t223 -71.5q88 -23 174 -49.5t153.5 -73.5t108.5 -123t41 -195q0 -208 -136.5 -319t-402.5 -111q-184 0 -319.5 61t-220.5 197z" />
+<glyph unicode="&#x406;" horiz-adv-x="872" d="M102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668z" />
+<glyph unicode="&#x407;" horiz-adv-x="872" d="M72 1671q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668zM516 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102 t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x408;" horiz-adv-x="924" d="M20 23l86 251q32 -17 102.5 -36t110.5 -19q74 0 107 20t47 70t14 144v931h283v-1007q0 -219 -110.5 -313.5t-346.5 -94.5q-51 0 -142 15t-151 39z" />
+<glyph unicode="&#x409;" horiz-adv-x="2079" d="M18 31l88 221q62 -27 113 -27q70 0 110.5 83t60.5 271.5t20 503.5v301h839v-491h213q287 0 413 -107.5t126 -328.5q0 -238 -132 -347.5t-413 -109.5h-489v1149h-283v-113q0 -552 -98 -809.5t-314 -257.5q-151 0 -254 62zM1249 248h199q129 0 195.5 49t66.5 160 q0 106 -62.5 149t-199.5 43h-199v-401z" />
+<glyph unicode="&#x40a;" horiz-adv-x="2019" d="M150 0v1384h282v-491h475v491h283v-491h213q287 0 413 -107.5t126 -328.5q0 -238 -132.5 -347.5t-412.5 -109.5h-490v649h-475v-649h-282zM1190 248h199q129 0 195.5 49t66.5 160q0 106 -62.5 149t-199.5 43h-199v-401z" />
+<glyph unicode="&#x40b;" horiz-adv-x="1331" d="M25 1151v233h739v-233h-248v-293q147 35 283 35q183 0 275.5 -42t135.5 -137t43 -268v-446h-282v367q0 173 -46 235t-175 62q-88 0 -236 -33v-631h-281v1151h-208z" />
+<glyph unicode="&#x40c;" horiz-adv-x="1286" d="M150 0v1384h282v-565h160q56 0 99 55.5t86 178.5t95 331h291q-66 -288 -140 -450t-169 -225q81 -46 136 -117.5t100 -191.5t114 -400h-293q-39 145 -70.5 255t-68.5 182.5t-83 108.5t-116 36h-141v-582h-282zM483 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x40d;" horiz-adv-x="1405" d="M150 0v1384h264v-964l512 964h329v-1384h-264v1028l-540 -1028h-301zM363 1905h315l188 -361h-204z" />
+<glyph unicode="&#x40e;" horiz-adv-x="1262" d="M35 1384h305l326 -675l282 675h297l-510 -1130q-48 -106 -99 -167.5t-111.5 -88.5t-162.5 -27q-41 0 -137.5 18t-152.5 42l82 219q38 -19 101.5 -34t94.5 -15q48 0 89.5 40.5t86.5 170.5zM303 1800h221q0 -149 141 -149q56 0 97 32.5t41 116.5h221q0 -76 -45 -139.5 t-126.5 -101t-189.5 -37.5q-106 0 -188 37t-127 101t-45 140z" />
+<glyph unicode="&#x40f;" horiz-adv-x="1358" d="M150 0v1384h280v-1126h498v1126h280v-1384h-387v-246h-280v246h-391z" />
+<glyph unicode="&#x410;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM477 528h373l-186 572z" />
+<glyph unicode="&#x411;" horiz-adv-x="1303" d="M150 0v1384h942v-231h-660v-305h193q286 0 429.5 -112.5t143.5 -329.5q0 -203 -133.5 -304.5t-431.5 -101.5h-483zM432 231h180q142 0 218.5 40t76.5 153q0 72 -29.5 114t-89.5 60t-194 18h-162v-385z" />
+<glyph unicode="&#x412;" horiz-adv-x="1298" d="M150 0v1384h489q266 0 381 -77.5t115 -245.5q0 -129 -62.5 -209t-195.5 -107q174 -24 253.5 -110t79.5 -234q0 -208 -143 -304.5t-397 -96.5h-520zM432 250h143q165 0 227.5 16t91 54t28.5 106q0 93 -63 131.5t-236 38.5h-191v-346zM432 842h172q125 0 185.5 35t60.5 122 q0 79 -58 109.5t-180 30.5h-180v-297z" />
+<glyph unicode="&#x413;" horiz-adv-x="1065" d="M127 0v1384h897v-235h-614v-1149h-283z" />
+<glyph unicode="&#x414;" horiz-adv-x="1362" d="M27 231h127q105 233 152.5 518t47.5 635h817v-1153h164v-477h-282v246h-744v-246h-282v477zM434 236h457v913h-281q-14 -320 -69.5 -549t-106.5 -364z" />
+<glyph unicode="&#x415;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899z" />
+<glyph unicode="&#x416;" horiz-adv-x="1870" d="M82 0q73 298 117.5 411.5t100 185t134.5 114.5q-189 120 -309 673h293q75 -313 137.5 -439t138.5 -126h101v565h282v-565h101q54 0 95.5 51.5t85.5 178.5t93 335h293q-56 -259 -131.5 -435.5t-175.5 -239.5q80 -46 134.5 -116.5t99.5 -187.5t116 -405h-293 q-41 152 -73.5 262.5t-69.5 181t-82 104.5t-111 34h-82v-582h-282v582h-84q-77 0 -128.5 -49t-95.5 -157t-110 -376h-295z" />
+<glyph unicode="&#x417;" horiz-adv-x="1217" d="M33 258l231 137q112 -194 318 -194q106 0 177.5 55t71.5 147q0 101 -51 147t-168 46h-293v233h308q89 0 136.5 47.5t47.5 139.5q0 75 -70 121.5t-176 46.5q-78 0 -159.5 -24.5t-182.5 -96.5l-141 203q202 147 493 147q169 0 289.5 -46t183 -134.5t62.5 -210.5 q0 -117 -58.5 -201t-144.5 -114q221 -95 221 -310q0 -210 -141 -318t-399 -108q-190 0 -326 68.5t-229 218.5z" />
+<glyph unicode="&#x418;" horiz-adv-x="1405" d="M150 0v1384h264v-964l512 964h329v-1384h-264v1028l-540 -1028h-301z" />
+<glyph unicode="&#x419;" horiz-adv-x="1405" d="M150 0v1384h264v-964l512 964h329v-1384h-264v1028l-540 -1028h-301zM355 1800h221q0 -149 141 -149q56 0 97 32.5t41 116.5h221q0 -76 -45 -139.5t-126.5 -101t-189.5 -37.5q-106 0 -188 37t-127 101t-45 140z" />
+<glyph unicode="&#x41a;" horiz-adv-x="1286" d="M150 0v1384h282v-565h160q56 0 99 55.5t86 178.5t95 331h291q-66 -288 -140 -450t-169 -225q81 -46 136 -117.5t100 -191.5t114 -400h-293q-39 145 -70.5 255t-68.5 182.5t-83 108.5t-116 36h-141v-582h-282z" />
+<glyph unicode="&#x41b;" horiz-adv-x="1452" d="M18 31l88 221q62 -27 113 -27q70 0 110.5 83t60.5 271.5t20 503.5v301h893v-1384h-281v1149h-338v-113q0 -552 -98 -809.5t-314 -257.5q-151 0 -254 62z" />
+<glyph unicode="&#x41c;" horiz-adv-x="1667" d="M150 0v1384h325l361 -657l364 657h318v-1384h-273v930l-332 -578h-163l-328 578v-930h-272z" />
+<glyph unicode="&#x41d;" horiz-adv-x="1409" d="M150 0v1384h282v-538h545v538h283v-1384h-283v588h-545v-588h-282z" />
+<glyph unicode="&#x41e;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5 t-69.5 -358.5z" />
+<glyph unicode="&#x41f;" horiz-adv-x="1417" d="M150 0v1384h1118v-1384h-289v1143h-541v-1143h-288z" />
+<glyph unicode="&#x420;" horiz-adv-x="1239" d="M150 0v1384h520q235 0 363 -109.5t128 -354.5q0 -250 -117.5 -371t-381.5 -121h-230v-428h-282zM432 674h115q155 0 214.5 21.5t84 72.5t24.5 150q0 117 -64.5 169t-232.5 52h-141v-465z" />
+<glyph unicode="&#x421;" horiz-adv-x="1333" d="M96 692q0 369 163 545t470 176q203 0 331 -68.5t195 -179.5l-219 -170q-48 72 -88 104t-91 48t-122 16q-170 0 -259 -108.5t-89 -362.5q0 -237 83.5 -354t266.5 -117q123 0 191.5 47t124.5 125l223 -164q-89 -133 -218.5 -195.5t-318.5 -62.5q-643 0 -643 721z" />
+<glyph unicode="&#x422;" horiz-adv-x="1204" d="M35 1126v258h1134v-258h-426v-1126h-282v1126h-426z" />
+<glyph unicode="&#x423;" horiz-adv-x="1262" d="M35 1384h305l326 -675l282 675h297l-510 -1130q-48 -106 -99 -167.5t-111.5 -88.5t-162.5 -27q-41 0 -137.5 18t-152.5 42l82 219q38 -19 101.5 -34t94.5 -15q48 0 89.5 40.5t86.5 170.5z" />
+<glyph unicode="&#x424;" horiz-adv-x="1548" d="M78 698q0 263 142.5 395t424.5 154v183h264v-183q281 -22 421 -154t140 -395q0 -262 -138.5 -396.5t-422.5 -158.5v-188h-264v188q-286 23 -426.5 157t-140.5 398zM365 698q0 -159 70.5 -235t209.5 -94v655q-137 -18 -208.5 -93t-71.5 -233zM909 369q135 18 205 94 t70 235q0 158 -70 230.5t-205 93.5v-653z" />
+<glyph unicode="&#x425;" horiz-adv-x="1286" d="M29 0l463 694l-451 690h321l287 -466l297 466h311l-454 -684l452 -700h-317l-297 477l-301 -477h-311z" />
+<glyph unicode="&#x426;" horiz-adv-x="1415" d="M150 0v1384h282v-1126h510v1126h283v-1126h164v-504h-283v246h-956z" />
+<glyph unicode="&#x427;" horiz-adv-x="1288" d="M88 926v458h283v-356q0 -130 16.5 -188.5t57 -83.5t124.5 -25q157 0 287 33v620h283v-1384h-283v514q-160 -41 -330 -41q-175 0 -266.5 43.5t-131.5 141t-40 268.5z" />
+<glyph unicode="&#x428;" horiz-adv-x="1870" d="M150 0v1384h282v-1126h363v1126h280v-1126h363v1126h282v-1384h-1570z" />
+<glyph unicode="&#x429;" horiz-adv-x="1907" d="M150 0v1384h282v-1126h363v1126h280v-1126h363v1126h282v-1130h160v-500h-283v246h-1447z" />
+<glyph unicode="&#x42a;" horiz-adv-x="1561" d="M35 1149v235h696v-491h213q287 0 413 -107.5t126 -328.5q0 -238 -132 -347.5t-413 -109.5h-489v1149h-414zM731 248h199q129 0 195.5 49t66.5 160q0 106 -62.5 149t-199.5 43h-199v-401z" />
+<glyph unicode="&#x42b;" horiz-adv-x="1812" d="M150 0v1384h282v-491h213q287 0 413 -107.5t126 -328.5q0 -238 -132 -347.5t-413 -109.5h-489zM432 248h199q129 0 195.5 49t66.5 160q0 106 -62.5 149t-199.5 43h-199v-401zM1382 0v1384h281v-1384h-281z" />
+<glyph unicode="&#x42c;" horiz-adv-x="1262" d="M150 0v1384h282v-491h213q287 0 413 -107.5t126 -328.5q0 -238 -132 -347.5t-413 -109.5h-489zM432 248h199q129 0 195.5 49t66.5 160q0 106 -62.5 149t-199.5 43h-199v-401z" />
+<glyph unicode="&#x42d;" horiz-adv-x="1270" d="M33 229l223 164q55 -78 124 -125t191 -47q162 0 244.5 89.5t99.5 264.5h-577v250h575q-22 183 -108 260.5t-232 77.5q-70 0 -120 -15.5t-89.5 -46.5t-91.5 -106l-219 170q68 111 196 179.5t331 68.5q632 0 632 -721t-643 -721q-187 0 -316 62t-220 196z" />
+<glyph unicode="&#x42e;" horiz-adv-x="1939" d="M150 0v1384h282v-579h242q21 297 168.5 452.5t419.5 155.5q291 0 441 -182.5t150 -540.5q0 -355 -151 -537t-440 -182q-268 0 -415 153t-173 449h-242v-573h-282zM965 690q0 -247 74 -368t223 -121q150 0 223.5 126t73.5 363q0 494 -297 494q-147 0 -222 -120t-75 -374z " />
+<glyph unicode="&#x42f;" horiz-adv-x="1284" d="M33 0l370 557q-135 27 -210.5 132.5t-75.5 283.5q0 219 122.5 315t391.5 96h504v-1384h-283v524h-143l-353 -524h-323zM403 961q0 -79 22.5 -117t73.5 -56t146 -18h207v369h-219q-123 0 -176.5 -36t-53.5 -142z" />
+<glyph unicode="&#x430;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM350 299 q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
+<glyph unicode="&#x431;" horiz-adv-x="1247" d="M106 655q0 191 26 326t78 227t132 147.5t187.5 88.5t243.5 48t302 28v-211q-164 -11 -290 -24t-214 -51t-137 -112.5t-59 -206.5q128 103 319 103q461 0 461 -488q0 -265 -133.5 -413t-366.5 -148q-270 0 -409.5 175t-139.5 511zM373 614q0 -204 71.5 -322t212.5 -118 q107 0 170.5 94.5t63.5 253.5q0 152 -55.5 222.5t-178.5 70.5q-72 0 -147 -33t-135 -90l-2 -38v-40z" />
+<glyph unicode="&#x432;" horiz-adv-x="1143" d="M131 0v1049h426q229 0 330.5 -57.5t101.5 -192.5q0 -90 -52 -145.5t-120 -84.5q107 -22 175.5 -82.5t68.5 -173.5q0 -149 -116 -231t-355 -82h-459zM387 184h150q116 0 187 28t71 114q0 77 -55.5 105t-170.5 28h-182v-275zM387 641h152q108 0 150 27.5t42 89.5 q0 63 -51 85.5t-152 22.5h-141v-225z" />
+<glyph unicode="&#x433;" horiz-adv-x="889" d="M131 0v1049h741v-191h-483v-858h-258z" />
+<glyph unicode="&#x434;" horiz-adv-x="1210" d="M29 186h112q86 160 132 376t46 487h717v-863h146v-448h-246v262h-662v-262h-245v448zM387 193h393v665h-223q-10 -191 -58 -372.5t-112 -292.5z" />
+<glyph unicode="&#x435;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z" />
+<glyph unicode="&#x436;" horiz-adv-x="1579" d="M41 0q69 236 106 317t84 134.5t119 87.5q-81 51 -146.5 170t-125.5 340h266q57 -210 113 -313t123 -103h82v416h258v-416h79q67 0 116.5 86.5t119.5 329.5h266q-59 -215 -122.5 -336t-147.5 -174q63 -31 106 -77t77 -110.5t61.5 -151.5t62.5 -200h-266q-37 115 -65.5 198 t-59.5 137t-69 79.5t-93 25.5h-65v-440h-258v440h-68q-66 0 -110.5 -39t-81.5 -120.5t-93 -280.5h-268z" />
+<glyph unicode="&#x437;" horiz-adv-x="1008" d="M47 150l195 137q45 -58 95 -81.5t116 -23.5q90 0 148 32t58 93q0 70 -39.5 102.5t-150.5 32.5h-233v185h223q96 0 138 20.5t42 91.5q0 72 -45 100.5t-131 28.5q-82 0 -133 -25.5t-86 -72.5l-183 129q56 92 161.5 136t240.5 44q229 0 335.5 -93t106.5 -245 q0 -71 -34.5 -127.5t-104.5 -87.5q69 -25 114.5 -91t45.5 -138q0 -158 -118 -243t-355 -85q-286 0 -406 181z" />
+<glyph unicode="&#x438;" horiz-adv-x="1217" d="M131 0v1049h234v-709l485 709h246v-1049h-234v707l-487 -707h-244z" />
+<glyph unicode="&#x439;" horiz-adv-x="1217" d="M131 0v1049h234v-709l485 709h246v-1049h-234v707l-487 -707h-244zM256 1466h221q0 -149 139 -149q58 0 99 32.5t41 116.5h221q0 -77 -45.5 -140.5t-128 -100.5t-189.5 -37q-103 0 -185 36t-127.5 101t-45.5 141z" />
+<glyph unicode="&#x43a;" horiz-adv-x="1108" d="M131 0v1049h256v-416h135q51 0 89 42.5t73 126.5t82 247h264q-56 -206 -121.5 -329t-154.5 -181q65 -31 110 -77t79 -110.5t61.5 -151.5t62.5 -200h-264q-35 109 -63.5 191.5t-60.5 138t-73 83t-100 27.5h-119v-440h-256z" />
+<glyph unicode="&#x43b;" horiz-adv-x="1223" d="M16 8l45 187q31 -9 56 -9q107 0 153.5 154.5t46.5 490.5v218h775v-1049h-256v858h-269v-65q0 -421 -95 -616t-310 -195q-35 0 -79 8t-67 18z" />
+<glyph unicode="&#x43c;" horiz-adv-x="1393" d="M131 0v1049h287l289 -498l274 498h281v-1049h-228v748l-262 -486h-141l-273 486v-748h-227z" />
+<glyph unicode="&#x43d;" horiz-adv-x="1202" d="M131 0v1049h258v-414h424v414h258v-1049h-258v442h-424v-442h-258z" />
+<glyph unicode="&#x43e;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5z" />
+<glyph unicode="&#x43f;" horiz-adv-x="1202" d="M131 0v1049h940v-1049h-258v858h-424v-858h-258z" />
+<glyph unicode="&#x440;" horiz-adv-x="1217" d="M145 -395v1444h238v-103q72 62 151.5 97.5t182.5 35.5q199 0 303 -140t104 -407q0 -169 -51 -298t-146 -197t-227 -68q-174 0 -297 109v-473h-258zM403 291q41 -37 101.5 -65.5t124.5 -28.5q106 0 167.5 90.5t61.5 240.5q0 153 -53 238.5t-158 85.5q-63 0 -129.5 -29.5 t-114.5 -72.5v-459z" />
+<glyph unicode="&#x441;" horiz-adv-x="1059" d="M92 518q0 265 126 413t378 148q135 0 240.5 -44t160.5 -136l-192 -137q-35 47 -82 69.5t-121 22.5q-132 0 -188 -81t-56 -251t57.5 -248.5t196.5 -78.5q60 0 110 17t95 75l195 -137q-60 -89 -158 -135t-248 -46q-254 0 -384 138.5t-130 410.5z" />
+<glyph unicode="&#x442;" horiz-adv-x="1004" d="M16 862v187h971v-187h-356v-862h-256v862h-359z" />
+<glyph unicode="&#x443;" horiz-adv-x="1085" d="M-20 -365l55 224q84 -29 151 -29q58 0 102 35t91 145l27 62l-379 977h268l248 -670l254 670h262l-451 -1121q-55 -135 -107 -200t-121.5 -94t-174.5 -29q-114 0 -225 30z" />
+<glyph unicode="&#x444;" horiz-adv-x="1393" d="M78 524q0 496 495 551v400h246v-400q249 -28 372.5 -168.5t123.5 -382.5q0 -243 -125 -382t-371 -165v-368h-246v368q-241 25 -368 162t-127 385zM344 524q0 -149 50 -238t179 -118v719q-129 -31 -179 -120t-50 -243zM819 168q127 29 178.5 119t51.5 237q0 146 -51.5 238 t-178.5 123v-717z" />
+<glyph unicode="&#x445;" horiz-adv-x="1079" d="M31 0l362 518l-356 531h301l209 -332l215 332h285l-361 -517l363 -532h-306l-208 334l-218 -334h-286z" />
+<glyph unicode="&#x446;" horiz-adv-x="1237" d="M131 0v1049h258v-861h420v861h256v-861h143v-450h-235v262h-842z" />
+<glyph unicode="&#x447;" horiz-adv-x="1151" d="M90 711v338h256v-281q0 -94 14 -138t46.5 -62.5t109.5 -18.5q103 0 248 20v480h256v-1049h-256v393q-74 -12 -151.5 -23.5t-139.5 -11.5q-212 0 -297.5 79t-85.5 274z" />
+<glyph unicode="&#x448;" horiz-adv-x="1634" d="M131 0v1049h258v-861h299v861h258v-861h299v861h258v-1049h-1372z" />
+<glyph unicode="&#x449;" horiz-adv-x="1667" d="M131 0v1049h258v-861h297v861h258v-861h297v861h258v-863h139v-448h-237v262h-1270z" />
+<glyph unicode="&#x44a;" horiz-adv-x="1352" d="M16 862v187h605v-371h184q248 0 364.5 -83t116.5 -251q0 -180 -123 -262t-372 -82h-426v862h-349zM621 188h163q127 0 181.5 36t54.5 122q0 82 -58.5 112.5t-185.5 30.5h-155v-301z" />
+<glyph unicode="&#x44b;" horiz-adv-x="1575" d="M131 0v1049h256v-371h182q248 0 363 -83t115 -251q0 -180 -120 -262t-372 -82h-424zM387 188h162q125 0 178 36t53 122q0 82 -55 112.5t-184 30.5h-154v-301zM1188 0v1049h256v-1049h-256z" />
+<glyph unicode="&#x44c;" horiz-adv-x="1112" d="M131 0v1049h256v-371h182q248 0 363 -83t115 -251q0 -180 -120 -262t-372 -82h-424zM387 188h162q125 0 178 36t53 122q0 82 -55 112.5t-184 30.5h-154v-301z" />
+<glyph unicode="&#x44d;" horiz-adv-x="1059" d="M47 150l195 137q45 -58 95 -75t109 -17q117 0 177.5 56t72.5 191h-473v185h471q-16 129 -77.5 178t-159.5 49q-74 0 -121 -22.5t-82 -69.5l-193 137q56 92 161.5 136t240.5 44q250 0 377 -147.5t127 -413.5q0 -273 -131.5 -411t-382.5 -138q-286 0 -406 181z" />
+<glyph unicode="&#x44e;" horiz-adv-x="1726" d="M131 0v1051h256v-437h221q19 233 151.5 349t366.5 116q256 0 389.5 -142t133.5 -415q0 -176 -59.5 -301.5t-175.5 -188.5t-288 -63q-235 0 -367 118t-151 339h-221v-426h-256zM870 522q0 -180 61.5 -263t194.5 -83q134 0 195 84t61 262q0 187 -61 269.5t-195 82.5 q-133 0 -194.5 -82.5t-61.5 -269.5z" />
+<glyph unicode="&#x44f;" horiz-adv-x="1090" d="M41 0l289 438q-248 57 -248 320q0 155 100.5 223t343.5 68h432v-1049h-256v418h-105l-275 -418h-281zM342 735q0 -78 40 -106.5t148 -28.5h172v266h-172q-100 0 -144 -30.5t-44 -100.5z" />
+<glyph unicode="&#x450;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM248 1569h315l188 -361h-204zM365 635h434q0 239 -209 239q-69 0 -113 -23.5 t-70.5 -70t-41.5 -145.5z" />
+<glyph unicode="&#x451;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM168 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5 q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5zM612 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x452;" horiz-adv-x="1319" d="M23 1204v180h149v105h252v-105h287v-180h-287v-293q77 77 177.5 122.5t182.5 45.5q205 0 305.5 -138t100.5 -400q0 -437 -132.5 -670t-391.5 -262l-45 205q123 35 187.5 115t94 224.5t29.5 374.5q0 328 -221 328q-59 0 -143.5 -49.5t-143.5 -104.5v-702h-252v1204h-149z " />
+<glyph unicode="&#x453;" horiz-adv-x="889" d="M131 0v1049h741v-191h-483v-858h-258zM321 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x454;" horiz-adv-x="1059" d="M92 518q0 265 126 413t378 148q135 0 240.5 -44t160.5 -136l-192 -137q-35 47 -82 69.5t-121 22.5q-98 0 -159.5 -49t-77.5 -178h471v-185h-474q13 -135 73.5 -191t176.5 -56q60 0 110 17t95 75l195 -137q-60 -89 -158 -135t-248 -46q-254 0 -384 138.5t-130 410.5z" />
+<glyph unicode="&#x455;" horiz-adv-x="1026" d="M76 152l192 135q47 -64 108.5 -85.5t131.5 -21.5q184 0 184 107q0 47 -52 72.5t-163 52.5q-209 46 -294 130t-85 218q0 139 106.5 229t313.5 90q141 0 248.5 -45t165.5 -135l-193 -137q-69 106 -225 106q-80 0 -121 -27.5t-41 -70.5q0 -41 37 -65.5t146 -51.5 q179 -44 255.5 -87.5t116 -108t39.5 -158.5q0 -104 -52.5 -178t-149 -113t-220.5 -39q-329 0 -448 183z" />
+<glyph unicode="&#x456;" horiz-adv-x="549" d="M131 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97zM145 0v1049h258v-1049h-258z" />
+<glyph unicode="&#x457;" horiz-adv-x="549" d="M-92 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM145 0v1049h258v-1049h-258zM352 1335q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x458;" horiz-adv-x="563" d="M-162 -365l56 224q73 -29 151 -29t96.5 48t18.5 159v1012h258v-1094q0 -188 -84 -269t-275 -81q-43 0 -113 9.5t-108 20.5zM145 1335q0 70 32 100.5t110 30.5t111.5 -29.5t33.5 -101.5q0 -73 -36 -102t-109 -29q-82 0 -112 34t-30 97z" />
+<glyph unicode="&#x459;" horiz-adv-x="1790" d="M16 8l45 187q31 -9 56 -9q103 0 149.5 146.5t46.5 498.5v218h760v-371h180q244 0 357.5 -83t113.5 -251q0 -180 -119.5 -262t-367.5 -82h-422v862h-250v-69q0 -421 -95 -616t-308 -195q-35 0 -78 8t-68 18zM1073 188h158q121 0 174 37t53 121q0 82 -56 112.5t-177 30.5 h-152v-301z" />
+<glyph unicode="&#x45a;" horiz-adv-x="1761" d="M131 0v1049h256v-385h406v385h256v-385h180q241 0 354 -73t113 -247q0 -180 -120 -262t-364 -82h-419v475h-406v-475h-256zM1049 188h157q119 0 171.5 36t52.5 122q0 72 -54.5 100.5t-175.5 28.5h-151v-287z" />
+<glyph unicode="&#x45b;" horiz-adv-x="1243" d="M23 1192v174h149v123h252v-123h285v-174h-285v-281q68 70 166 119t201 49q169 0 247 -92t78 -287v-700h-252v580q0 166 -31 221t-118 55q-116 0 -291 -154v-702h-252v1192h-149z" />
+<glyph unicode="&#x45c;" horiz-adv-x="1108" d="M131 0v1049h256v-416h135q51 0 89 42.5t73 126.5t82 247h264q-56 -206 -121.5 -329t-154.5 -181q65 -31 110 -77t79 -110.5t61.5 -151.5t62.5 -200h-264q-35 109 -63.5 191.5t-60.5 138t-73 83t-100 27.5h-119v-440h-256zM407 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x45d;" horiz-adv-x="1217" d="M131 0v1049h234v-709l485 709h246v-1049h-234v707l-487 -707h-244zM273 1569h315l188 -361h-204z" />
+<glyph unicode="&#x45e;" horiz-adv-x="1085" d="M-20 -365l55 224q84 -29 151 -29q58 0 102 35t91 145l27 62l-379 977h268l248 -670l254 670h262l-451 -1121q-55 -135 -107 -200t-121.5 -94t-174.5 -29q-114 0 -225 30zM182 1466h221q0 -149 139 -149q58 0 99 32.5t41 116.5h221q0 -77 -45.5 -140.5t-128 -100.5 t-189.5 -37q-103 0 -185 36t-127.5 101t-45.5 141z" />
+<glyph unicode="&#x45f;" horiz-adv-x="1202" d="M131 0v1049h258v-861h424v861h258v-1049h-342v-264h-256v264h-342z" />
+<glyph unicode="&#x490;" horiz-adv-x="999" d="M150 0v1384h538v250h283v-508h-541v-1126h-280z" />
+<glyph unicode="&#x491;" horiz-adv-x="905" d="M131 0v1049h490v286h256v-479h-488v-856h-258z" />
+<glyph unicode="&#x1e80;" horiz-adv-x="1833" d="M43 1384h281l221 -903l229 903h279l231 -909l227 909h279l-358 -1384h-289l-232 915l-233 -915h-285zM588 1905h315l188 -361h-204z" />
+<glyph unicode="&#x1e81;" horiz-adv-x="1565" d="M27 1049h268l162 -676l235 676h195l237 -670l156 670h258l-281 -1049h-235l-236 668l-237 -668h-236zM435 1569h315l188 -361h-204z" />
+<glyph unicode="&#x1e82;" horiz-adv-x="1833" d="M43 1384h281l221 -903l229 903h279l231 -909l227 909h279l-358 -1384h-289l-232 915l-233 -915h-285zM747 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x1e83;" horiz-adv-x="1565" d="M27 1049h268l162 -676l235 676h195l237 -670l156 670h258l-281 -1049h-235l-236 668l-237 -668h-236zM655 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x1e84;" horiz-adv-x="1833" d="M43 1384h281l221 -903l229 903h279l231 -909l227 909h279l-358 -1384h-289l-232 915l-233 -915h-285zM549 1671q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM993 1671q0 70 31.5 100.5t109.5 30.5 t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1e85;" horiz-adv-x="1565" d="M27 1049h268l162 -676l235 676h195l237 -670l156 670h258l-281 -1049h-235l-236 668l-237 -668h-236zM416 1335q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM860 1335q0 70 31.5 100.5t109.5 30.5 t112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1e9e;" horiz-adv-x="1503" d="M150 0v868q0 289 136 418t433 129q129 0 219 -15.5t174 -37.5v-199q-98 0 -159.5 -35.5t-61.5 -111.5q0 -43 17 -68.5t59.5 -50.5t122.5 -55q167 -62 248 -165.5t81 -275.5q0 -196 -128 -313t-363 -117q-157 0 -254.5 55t-169.5 185l217 166q41 -84 96 -120t129 -36 q184 0 184 166q0 66 -35.5 117t-133.5 88q-201 76 -280 164.5t-79 238.5q0 92 51 170q-128 -8 -174.5 -70.5t-46.5 -215.5v-879h-282z" />
+<glyph unicode="&#x1ea0;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM477 528h373l-186 572zM524 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ea1;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM350 299 q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM377 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ea2;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM458 1823q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25zM477 528h373l-186 572z" />
+<glyph unicode="&#x1ea3;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM350 299 q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM350 1487q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ea4;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM318 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM477 528h373l-186 572zM906 1716l153 291h316l-265 -291h-204z" />
+<glyph unicode="&#x1ea5;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM184 1167l235 299 h244l236 -299h-211l-146 144l-149 -144h-209zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM772 1380l153 291h316l-265 -291h-204z" />
+<glyph unicode="&#x1ea6;" horiz-adv-x="1337" d="M-22 2007h315l154 -291h-205zM27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM318 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM477 528h373l-186 572z" />
+<glyph unicode="&#x1ea7;" horiz-adv-x="1139" d="M-156 1671h315l154 -291h-205zM84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5 t-89 234.5zM184 1167l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
+<glyph unicode="&#x1ea8;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM318 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM477 528h373l-186 572zM813 2001q70 53 197 53q105 0 161 -46t56 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60 q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ea9;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM184 1167l235 299 h244l236 -299h-211l-146 133l-149 -133h-209zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM679 1665q67 53 197 53q105 0 161 -46t56 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v138h43q74 0 74 59 q0 51 -76 51q-56 0 -96 -24z" />
+<glyph unicode="&#x1eaa;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM267 1849q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -35t65.5 -15.5q37 0 50 24t18 62h182q-10 -144 -76 -212t-188 -68q-54 0 -96 16.5t-77.5 36t-66.5 35.5t-64 16q-38 0 -50.5 -23.5 t-16.5 -62.5h-182zM318 1503l235 279h244l236 -279h-211l-146 123l-149 -123h-209zM477 528h373l-186 572z" />
+<glyph unicode="&#x1eab;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM133 1513 q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -34.5t65.5 -15q37 0 50 23.5t18 62.5h182q-10 -145 -75.5 -213t-188.5 -68q-54 0 -96 16.5t-77.5 36t-66.5 35.5t-64 16q-38 0 -50.5 -23.5t-16.5 -62.5h-182zM184 1167l235 279h244l236 -279h-211l-146 123l-149 -123 h-209zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
+<glyph unicode="&#x1eac;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM318 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209zM477 528h373l-186 572zM522 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34 t-29.5 97z" />
+<glyph unicode="&#x1ead;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM184 1208l235 361 h244l236 -361h-211l-146 174l-149 -174h-209zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM379 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34 t-29.5 97z" />
+<glyph unicode="&#x1eae;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM305 1835h188q15 -61 58 -86t116 -25q145 0 170 111h189q0 -87 -43.5 -158.5t-126.5 -113t-191 -41.5t-190.5 41.5t-126 114t-43.5 157.5zM477 528h373l-186 572zM555 1819l104 249h315l-225 -249h-194z " />
+<glyph unicode="&#x1eaf;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM182 1520h188 q15 -62 58 -86.5t116 -24.5q68 0 112 24.5t58 86.5h189q0 -88 -43.5 -159.5t-126 -113t-191.5 -41.5q-108 0 -190.5 41.5t-126 114t-43.5 158.5zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM432 1503 l104 250h315l-225 -250h-194z" />
+<glyph unicode="&#x1eb0;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM305 1835h188q15 -61 58 -86t116 -25q145 0 170 111h189q0 -87 -43.5 -158.5t-126.5 -113t-191 -41.5t-190.5 41.5t-126 114t-43.5 157.5zM356 2068h315l105 -249h-195zM477 528h373l-186 572z" />
+<glyph unicode="&#x1eb1;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM182 1520h188 q15 -62 58 -86.5t116 -24.5q68 0 112 24.5t58 86.5h189q0 -88 -43.5 -159.5t-126 -113t-191.5 -41.5q-108 0 -190.5 41.5t-126 114t-43.5 158.5zM233 1753h315l105 -250h-195zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12 q-139 -12 -200.5 -53t-61.5 -123z" />
+<glyph unicode="&#x1eb2;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM305 1835h188q15 -61 58 -86t116 -25q145 0 170 111h189q0 -87 -43.5 -158.5t-126.5 -113t-191 -41.5t-190.5 41.5t-126 114t-43.5 157.5zM477 528h373l-186 572zM483 2152q68 54 197 54q104 0 160.5 -46 t56.5 -120q0 -71 -47.5 -118t-128.5 -52v-43h-125v137h43q73 0 73 59q0 52 -75 52q-53 0 -97 -25z" />
+<glyph unicode="&#x1eb3;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM182 1520h188 q15 -62 58 -86.5t116 -24.5q68 0 112 24.5t58 86.5h189q0 -88 -43.5 -159.5t-126 -113t-191.5 -41.5q-108 0 -190.5 41.5t-126 114t-43.5 158.5zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM360 1837 q67 53 197 53q104 0 160.5 -46t56.5 -120q0 -72 -49 -118.5t-127 -51.5v-43h-125v138h43q73 0 73 59q0 51 -75 51q-55 0 -97 -24z" />
+<glyph unicode="&#x1eb4;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM256 1903q5 135 74 205.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -34.5t65.5 -15q37 0 50 23.5t18 62.5h182q-10 -145 -75.5 -213t-188.5 -68q-54 0 -96 16.5t-77.5 36t-66.5 36t-64 16.5q-38 0 -50.5 -23.5 t-16.5 -62.5h-182zM305 1825h188q15 -62 58 -86.5t116 -24.5q68 0 112 24.5t58 86.5h189q0 -133 -98 -218t-263 -85q-166 0 -263 85.5t-97 217.5zM477 528h373l-186 572z" />
+<glyph unicode="&#x1eb5;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM133 1587 q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -35t65.5 -15.5q37 0 50 23.5t18 62.5h182q-10 -144 -76 -212t-188 -68q-54 0 -96 16.5t-77.5 35.5t-66.5 35.5t-64 16.5q-38 0 -50.5 -23.5t-16.5 -62.5h-182zM182 1509h188q15 -61 58 -85.5t116 -24.5q68 0 112 24.5 t58 85.5h189q0 -133 -98 -218t-263 -85q-110 0 -190.5 38.5t-125 109t-44.5 155.5zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123z" />
+<glyph unicode="&#x1eb6;" horiz-adv-x="1337" d="M27 0l458 1384h367l459 -1384h-289l-92 281h-533l-90 -281h-280zM305 1845h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162zM477 528h373l-186 572zM522 -248 q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1eb7;" horiz-adv-x="1139" d="M84 295q0 112 45.5 185t135 114.5t257.5 58.5l221 21v47q0 88 -53 120.5t-155 32.5q-84 0 -144.5 -28t-89.5 -80l-201 129q53 89 166 136.5t273 47.5q245 0 353.5 -85.5t108.5 -280.5v-713h-237v109q-153 -140 -328 -140q-174 0 -263 91.5t-89 234.5zM182 1509h188 q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162zM350 299q0 -72 40 -98.5t106 -26.5q47 0 114.5 29.5t132.5 83.5v200l-131 -12q-139 -12 -200.5 -53t-61.5 -123zM379 -248 q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1eb8;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM451 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1eb9;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z M438 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1eba;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM391 1823q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ebb;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z M385 1487q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ebc;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM189 1567q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q34 0 51 33t17 94h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5 q-67 0 -67 -127h-182z" />
+<glyph unicode="&#x1ebd;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM179 1231q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5 q35 0 51.5 35t16.5 92h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z" />
+<glyph unicode="&#x1ebe;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM236 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM824 1716l153 291h316l-265 -291h-204z" />
+<glyph unicode="&#x1ebf;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM225 1167l235 299h244l236 -299h-211l-146 144l-149 -144h-209zM365 635h434 q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5zM813 1380l153 291h316l-265 -291h-204z" />
+<glyph unicode="&#x1ec0;" horiz-adv-x="1149" d="M-104 2007h315l154 -291h-205zM150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM236 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209z" />
+<glyph unicode="&#x1ec1;" horiz-adv-x="1143" d="M-104 1671h315l154 -291h-205zM92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM236 1167l235 299h244l236 -299h-211 l-146 133l-149 -133h-209zM365 635h434q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5z" />
+<glyph unicode="&#x1ec2;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM236 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM731 2001q70 53 197 53q105 0 161 -46t56 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z " />
+<glyph unicode="&#x1ec3;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM225 1167l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM365 635h434 q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5zM720 1665q67 53 197 53q105 0 161 -46t56 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v138h43q74 0 74 59q0 51 -76 51q-56 0 -96 -24z" />
+<glyph unicode="&#x1ec4;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM195 1849q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -35t65.5 -15.5q37 0 50 24t18 62h182q-10 -144 -76 -212t-188 -68q-54 0 -96 16.5t-77.5 36t-66.5 35.5t-64 16q-38 0 -50.5 -23.5 t-16.5 -62.5h-182zM246 1503l235 279h244l236 -279h-211l-146 123l-149 -123h-209z" />
+<glyph unicode="&#x1ec5;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM174 1513q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -34.5 t65.5 -15q37 0 50 23.5t18 62.5h182q-10 -145 -75.5 -213t-188.5 -68q-54 0 -96 16.5t-77.5 36t-66.5 35.5t-64 16q-38 0 -50.5 -23.5t-16.5 -62.5h-182zM225 1167l235 279h244l236 -279h-211l-146 123l-149 -123h-209zM365 635h434q0 239 -209 239q-69 0 -113 -23.5 t-70.5 -70t-41.5 -145.5z" />
+<glyph unicode="&#x1ec6;" horiz-adv-x="1149" d="M150 0v1384h899v-249h-617v-295h520v-250h-520v-332h617v-258h-899zM246 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209zM451 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ec7;" horiz-adv-x="1143" d="M92 516q0 563 504 563q224 0 341.5 -126.5t117.5 -368.5v-127h-697q7 -140 68 -201t192 -61q76 0 133.5 19t100.5 73l192 -137q-63 -91 -163.5 -136t-274.5 -45q-259 0 -386.5 136t-127.5 411zM225 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209zM365 635h434 q0 239 -209 239q-69 0 -113 -23.5t-70.5 -70t-41.5 -145.5zM440 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ec8;" horiz-adv-x="872" d="M102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668zM225 1823q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ec9;" horiz-adv-x="549" d="M69 1487q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25zM145 0v1049h258v-1049h-258z" />
+<glyph unicode="&#x1eca;" horiz-adv-x="872" d="M102 0v217h193v950h-193v217h668v-217h-192v-950h192v-217h-668zM295 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ecb;" horiz-adv-x="549" d="M131 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97zM133 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97zM145 0v1049h258v-1049h-258z" />
+<glyph unicode="&#x1ecc;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5 t-69.5 -358.5zM539 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ecd;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5zM451 -248 q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ece;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5 t-69.5 -358.5zM454 1823q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ecf;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5zM387 1487q70 53 197 53 q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ed0;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM318 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM377 692q0 -246 70.5 -358.5t234.5 -112.5 q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5zM906 1716l153 291h316l-265 -291h-204z" />
+<glyph unicode="&#x1ed1;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM236 1167l235 299h244l236 -299h-211l-146 144l-149 -144h-209zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5 t-181 79.5q-126 0 -182 -81.5t-56 -250.5zM824 1380l153 291h316l-265 -291h-204z" />
+<glyph unicode="&#x1ed2;" horiz-adv-x="1364" d="M-12 2007h315l154 -291h-205zM86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM328 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM377 692q0 -246 70.5 -358.5 t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5z" />
+<glyph unicode="&#x1ed3;" horiz-adv-x="1190" d="M-104 1671h315l154 -291h-205zM92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM236 1167l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM358 522q0 -168 55.5 -247.5t182.5 -79.5 q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5z" />
+<glyph unicode="&#x1ed4;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM328 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM377 692q0 -246 70.5 -358.5t234.5 -112.5 q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5zM823 2001q70 53 197 53q105 0 161 -46t56 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ed5;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM236 1167l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5 t-181 79.5q-126 0 -182 -81.5t-56 -250.5zM731 1665q67 53 197 53q105 0 161 -46t56 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v138h43q74 0 74 59q0 51 -76 51q-56 0 -96 -24z" />
+<glyph unicode="&#x1ed6;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM277 1849q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -35t65.5 -15.5q37 0 50 24t18 62h182q-10 -144 -76 -212 t-188 -68q-54 0 -96 16.5t-77.5 36t-66.5 35.5t-64 16q-38 0 -50.5 -23.5t-16.5 -62.5h-182zM328 1503l235 279h244l236 -279h-211l-146 123l-149 -123h-209zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5 t-235.5 -112.5t-69.5 -358.5z" />
+<glyph unicode="&#x1ed7;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM195 1513q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -34.5t65.5 -15q37 0 50 23.5t18 62.5h182q-10 -145 -75.5 -213t-188.5 -68 q-54 0 -96 16.5t-77.5 36t-66.5 35.5t-64 16q-38 0 -50.5 -23.5t-16.5 -62.5h-182zM246 1167l235 279h244l236 -279h-211l-146 123l-149 -123h-209zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5 t-56 -250.5z" />
+<glyph unicode="&#x1ed8;" horiz-adv-x="1364" d="M86 692q0 344 144.5 532.5t451.5 188.5q309 0 452.5 -188.5t143.5 -532.5q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM318 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209zM377 692q0 -246 70.5 -358.5t234.5 -112.5 q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5zM522 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ed9;" horiz-adv-x="1190" d="M92 522q0 266 121 411.5t383 145.5q260 0 381 -145.5t121 -411.5q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM246 1208l235 361h244l236 -361h-211l-146 174l-149 -174h-209zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5 t-181 79.5q-126 0 -182 -81.5t-56 -250.5zM451 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1eda;" horiz-adv-x="1540" d="M86 692q0 344 144.5 532.5t451.5 188.5q386 0 518 -297h23q86 0 116.5 40t30.5 128v162h211v-162q0 -170 -74.5 -255t-234.5 -85h-17q23 -119 23 -252q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM377 692q0 -246 70.5 -358.5t234.5 -112.5 q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5zM512 1544l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x1edb;" horiz-adv-x="1352" d="M92 522q0 266 121 411.5t383 145.5q328 0 440 -237q84 0 115 40t31 128v120h211v-120q0 -318 -306 -340q11 -77 11 -148q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5 q-126 0 -182 -81.5t-56 -250.5zM430 1208l189 361h315l-299 -361h-205z" />
+<glyph unicode="&#x1edc;" horiz-adv-x="1540" d="M86 692q0 344 144.5 532.5t451.5 188.5q386 0 518 -297h23q86 0 116.5 40t30.5 128v162h211v-162q0 -170 -74.5 -255t-234.5 -85h-17q23 -119 23 -252q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM359 1905h315l188 -361h-204zM377 692 q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5z" />
+<glyph unicode="&#x1edd;" horiz-adv-x="1352" d="M92 522q0 266 121 411.5t383 145.5q328 0 440 -237q84 0 115 40t31 128v120h211v-120q0 -318 -306 -340q11 -77 11 -148q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM277 1569h315l188 -361h-204zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5 q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5z" />
+<glyph unicode="&#x1ede;" horiz-adv-x="1540" d="M86 692q0 344 144.5 532.5t451.5 188.5q386 0 518 -297h23q86 0 116.5 40t30.5 128v162h211v-162q0 -170 -74.5 -255t-234.5 -85h-17q23 -119 23 -252q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM377 692q0 -246 70.5 -358.5t234.5 -112.5 q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5zM479 1823q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1edf;" horiz-adv-x="1352" d="M92 522q0 266 121 411.5t383 145.5q328 0 440 -237q84 0 115 40t31 128v120h211v-120q0 -318 -306 -340q11 -77 11 -148q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5 q-126 0 -182 -81.5t-56 -250.5zM397 1487q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ee0;" horiz-adv-x="1540" d="M86 692q0 344 144.5 532.5t451.5 188.5q386 0 518 -297h23q86 0 116.5 40t30.5 128v162h211v-162q0 -170 -74.5 -255t-234.5 -85h-17q23 -119 23 -252q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM277 1567q5 155 73 236t189 81q61 0 104 -22.5 t77 -48t62.5 -48t61.5 -22.5q34 0 51 33t17 94h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182zM377 692q0 -246 70.5 -358.5t234.5 -112.5q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5 t-235.5 -112.5t-69.5 -358.5z" />
+<glyph unicode="&#x1ee1;" horiz-adv-x="1352" d="M92 522q0 266 121 411.5t383 145.5q328 0 440 -237q84 0 115 40t31 128v120h211v-120q0 -318 -306 -340q11 -77 11 -148q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM185 1231q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35 t16.5 92h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5q-126 0 -182 -81.5t-56 -250.5z" />
+<glyph unicode="&#x1ee2;" horiz-adv-x="1540" d="M86 692q0 344 144.5 532.5t451.5 188.5q386 0 518 -297h23q86 0 116.5 40t30.5 128v162h211v-162q0 -170 -74.5 -255t-234.5 -85h-17q23 -119 23 -252q0 -361 -152.5 -541t-443.5 -180q-307 0 -451.5 189.5t-144.5 531.5zM377 692q0 -246 70.5 -358.5t234.5 -112.5 q166 0 235.5 112.5t69.5 358.5t-69.5 358.5t-235.5 112.5t-235.5 -112.5t-69.5 -358.5zM533 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ee3;" horiz-adv-x="1352" d="M92 522q0 266 121 411.5t383 145.5q328 0 440 -237q84 0 115 40t31 128v120h211v-120q0 -318 -306 -340q11 -77 11 -148q0 -262 -121 -407.5t-381 -145.5q-504 0 -504 553zM358 522q0 -168 55.5 -247.5t182.5 -79.5q125 0 180 78.5t55 248.5q0 173 -54 252.5t-181 79.5 q-126 0 -182 -81.5t-56 -250.5zM451 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ee4;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM576 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34 t-29.5 97z" />
+<glyph unicode="&#x1ee5;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM420 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5 q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ee6;" horiz-adv-x="1438" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-806q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM510 1823q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43 q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ee7;" horiz-adv-x="1217" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-1049h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM401 1487q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43 q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ee8;" horiz-adv-x="1622" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-268h17q86 0 116.5 40t30.5 128v162h211v-162q0 -340 -346 -340h-29v-366q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM553 1544l189 361h315l-299 -361h-205 z" />
+<glyph unicode="&#x1ee9;" horiz-adv-x="1395" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-207h12q84 0 113 40t29 128v120h211v-120q0 -340 -340 -340h-25v-670h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM440 1208l189 361h315l-299 -361 h-205z" />
+<glyph unicode="&#x1eea;" horiz-adv-x="1622" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-268h17q86 0 116.5 40t30.5 128v162h211v-162q0 -340 -346 -340h-29v-366q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM379 1905h315l188 -361h-204z" />
+<glyph unicode="&#x1eeb;" horiz-adv-x="1395" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-207h12q84 0 113 40t29 128v120h211v-120q0 -340 -340 -340h-25v-670h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM256 1569h315l188 -361h-204z" />
+<glyph unicode="&#x1eec;" horiz-adv-x="1622" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-268h17q86 0 116.5 40t30.5 128v162h211v-162q0 -340 -346 -340h-29v-366q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM514 1823q70 53 197 53 q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1eed;" horiz-adv-x="1395" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-207h12q84 0 113 40t29 128v120h211v-120q0 -340 -340 -340h-25v-670h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM397 1487q70 53 197 53 q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1eee;" horiz-adv-x="1622" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-268h17q86 0 116.5 40t30.5 128v162h211v-162q0 -340 -346 -340h-29v-366q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM312 1567q5 155 73 236t189 81 q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q34 0 51 33t17 94h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
+<glyph unicode="&#x1eef;" horiz-adv-x="1395" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-207h12q84 0 113 40t29 128v120h211v-120q0 -340 -340 -340h-25v-670h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM195 1231q5 155 73 236t189 81 q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
+<glyph unicode="&#x1ef0;" horiz-adv-x="1622" d="M150 578v806h282v-786q0 -141 27 -222t86 -119t172 -38q161 0 225 85.5t64 289.5v790h282v-268h17q86 0 116.5 40t30.5 128v162h211v-162q0 -340 -346 -340h-29v-366q0 -325 -132 -467t-437 -142q-302 0 -435.5 140.5t-133.5 468.5zM563 -248q0 70 31.5 100.5t109.5 30.5 t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ef1;" horiz-adv-x="1395" d="M137 348v701h258v-578q0 -111 13 -170t42.5 -81.5t86.5 -22.5q115 0 276 151v701h258v-207h12q84 0 113 40t29 128v120h211v-120q0 -340 -340 -340h-25v-670h-258v135q-68 -73 -166.5 -119.5t-189.5 -46.5q-178 0 -249 98.5t-71 280.5zM420 -248q0 70 31.5 100.5 t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ef2;" horiz-adv-x="1188" d="M18 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522zM261 1905h315l188 -361h-204z" />
+<glyph unicode="&#x1ef3;" horiz-adv-x="1085" d="M-20 -365l55 224q84 -29 151 -29q58 0 102 35t91 145l27 62l-379 977h268l248 -670l254 670h262l-451 -1121q-55 -135 -107 -200t-121.5 -94t-174.5 -29q-114 0 -225 30zM191 1569h315l188 -361h-204z" />
+<glyph unicode="&#x1ef4;" horiz-adv-x="1188" d="M18 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522zM451 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ef5;" horiz-adv-x="1085" d="M-20 -365l55 224q84 -29 151 -29q58 0 102 35t91 145l27 62l-379 977h268l248 -670l254 670h262l-451 -1121q-55 -135 -107 -200t-121.5 -94t-174.5 -29q-114 0 -225 30zM655 -248q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5 q-82 0 -111.5 34t-29.5 97z" />
+<glyph unicode="&#x1ef6;" horiz-adv-x="1188" d="M18 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522zM387 1823q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ef7;" horiz-adv-x="1085" d="M-20 -365l55 224q84 -29 151 -29q58 0 102 35t91 145l27 62l-379 977h268l248 -670l254 670h262l-451 -1121q-55 -135 -107 -200t-121.5 -94t-174.5 -29q-114 0 -225 30zM335 1487q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43 q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph unicode="&#x1ef8;" horiz-adv-x="1188" d="M18 1384h308l270 -579l276 579h297l-434 -856v-528h-284v522zM189 1567q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q34 0 51 33t17 94h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127 h-182z" />
+<glyph unicode="&#x1ef9;" horiz-adv-x="1085" d="M-20 -365l55 224q84 -29 151 -29q58 0 102 35t91 145l27 62l-379 977h268l248 -670l254 670h262l-451 -1121q-55 -135 -107 -200t-121.5 -94t-174.5 -29q-114 0 -225 30zM133 1231q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q35 0 51.5 35t16.5 92 h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
+<glyph unicode="&#x2000;" horiz-adv-x="1103" />
+<glyph unicode="&#x2001;" horiz-adv-x="2206" />
+<glyph unicode="&#x2002;" horiz-adv-x="1103" />
+<glyph unicode="&#x2003;" horiz-adv-x="2206" />
+<glyph unicode="&#x2004;" horiz-adv-x="735" />
+<glyph unicode="&#x2005;" horiz-adv-x="551" />
+<glyph unicode="&#x2006;" horiz-adv-x="367" />
+<glyph unicode="&#x2007;" horiz-adv-x="367" />
+<glyph unicode="&#x2008;" horiz-adv-x="275" />
+<glyph unicode="&#x2009;" horiz-adv-x="441" />
+<glyph unicode="&#x200a;" horiz-adv-x="122" />
<glyph unicode="&#x2010;" horiz-adv-x="786" d="M82 399v254h623v-254h-623z" />
<glyph unicode="&#x2011;" horiz-adv-x="786" d="M82 399v254h623v-254h-623z" />
<glyph unicode="&#x2012;" horiz-adv-x="786" d="M82 399v254h623v-254h-623z" />
-<glyph unicode="&#x2013;" horiz-adv-x="1044" d="M31 424v205h983v-205h-983z" />
+<glyph unicode="&#x2013;" d="M31 424v205h983v-205h-983z" />
<glyph unicode="&#x2014;" horiz-adv-x="2068" d="M31 424v205h2007v-205h-2007z" />
+<glyph unicode="&#x2015;" horiz-adv-x="2068" d="M31 424v205h2007v-205h-2007z" />
+<glyph unicode="&#x2017;" horiz-adv-x="1024" d="M-10 -105h1044v-102h-1044v102zM-10 -290h1044v-102h-1044v102z" />
<glyph unicode="&#x2018;" horiz-adv-x="584" d="M129 967q0 123 42 234.5t91 182.5h193q-62 -86 -91.5 -164.5t-33.5 -117.5q65 -4 95 -42t30 -114q0 -74 -35 -117t-131 -43q-160 0 -160 181z" />
<glyph unicode="&#x2019;" horiz-adv-x="584" d="M129 815q61 86 91 165t34 118q-66 4 -95.5 42t-29.5 113q0 74 35 117t131 43q160 0 160 -180q0 -123 -42 -234.5t-91 -183.5h-193z" />
<glyph unicode="&#x201a;" horiz-adv-x="584" d="M129 145q0 74 35 117t131 43q160 0 160 -180q0 -123 -42 -234.5t-91 -183.5h-193q61 86 91 165t34 118q-66 4 -95.5 42t-29.5 113z" />
+<glyph unicode="&#x201b;" horiz-adv-x="584" d="M129 1233q0 180 160 180q96 0 131 -43t35 -117q0 -75 -30 -113t-95 -42q4 -39 33.5 -118t91.5 -165h-193q-49 72 -91 183.5t-42 234.5z" />
<glyph unicode="&#x201c;" horiz-adv-x="1047" d="M129 967q0 123 42 234.5t91 182.5h193q-62 -86 -91.5 -164.5t-33.5 -117.5q65 -4 95 -42t30 -114q0 -74 -35 -117t-131 -43q-160 0 -160 181zM592 967q0 123 42 234.5t91 182.5h193q-62 -86 -91.5 -164.5t-33.5 -117.5q65 -4 95 -42t30 -114q0 -74 -35 -117t-131 -43 q-160 0 -160 181z" />
<glyph unicode="&#x201d;" horiz-adv-x="1047" d="M129 815q61 86 91 165t34 118q-66 4 -95.5 42t-29.5 113q0 74 35 117t131 43q160 0 160 -180q0 -123 -42 -234.5t-91 -183.5h-193zM592 815q61 86 91 165t34 118q-66 4 -95.5 42t-29.5 113q0 74 35 117t131 43q160 0 160 -180q0 -123 -42 -234.5t-92 -183.5h-192z" />
<glyph unicode="&#x201e;" horiz-adv-x="1047" d="M129 145q0 74 35 117t131 43q160 0 160 -180q0 -123 -42 -234.5t-91 -183.5h-193q61 86 91 165t34 118q-66 4 -95.5 42t-29.5 113zM592 145q0 74 35 117t131 43q160 0 160 -180q0 -123 -42 -234.5t-92 -183.5h-192q61 86 91 165t34 118q-66 4 -95.5 42t-29.5 113z" />
+<glyph unicode="&#x2020;" horiz-adv-x="1110" d="M59 797v241l396 -22l-27 504h252l-27 -504l398 22v-241l-398 24l31 -1216h-260l31 1216z" />
+<glyph unicode="&#x2021;" horiz-adv-x="1075" d="M59 37v242l377 -25l-16 309l16 307l-377 -24v241l377 -22l-26 455h256l-27 -455l377 22v-241l-377 24l16 -311l-16 -305l377 25v-242l-377 22l27 -454h-256l26 454z" />
<glyph unicode="&#x2022;" horiz-adv-x="760" d="M92 745q0 78 38.5 145t106.5 105.5t144 38.5q115 0 201 -83t86 -206q0 -118 -84 -202t-203 -84q-76 0 -143 37.5t-106.5 104.5t-39.5 144z" />
<glyph unicode="&#x2026;" horiz-adv-x="2068" d="M188 145q0 82 36 121t126 39q92 0 128 -38t36 -122q0 -86 -39 -122.5t-125 -36.5q-94 0 -128 41t-34 118zM870 145q0 82 36 121t126 39q92 0 128 -38t36 -122q0 -86 -39 -122.5t-125 -36.5q-94 0 -128 41t-34 118zM1552 145q0 82 36 121t126 39q92 0 128 -38t36 -122 q0 -86 -39 -122.5t-125 -36.5q-94 0 -128 41t-34 118z" />
-<glyph unicode="&#x202f;" horiz-adv-x="388" />
+<glyph unicode="&#x202f;" horiz-adv-x="441" />
+<glyph unicode="&#x2030;" horiz-adv-x="2963" d="M80 963q0 220 95 335t280 115q182 0 279 -111t97 -339q0 -224 -99.5 -334.5t-276.5 -110.5q-180 0 -277.5 114t-97.5 331zM326 963q0 -152 31.5 -208.5t97.5 -56.5q72 0 101.5 60.5t29.5 204.5q0 141 -28 205.5t-103 64.5q-70 0 -99.5 -61t-29.5 -209zM545 -51l751 1487 h238l-754 -1487h-235zM1241 414q0 219 94.5 334.5t280.5 115.5t281.5 -113t95.5 -337q0 -222 -98.5 -333.5t-278.5 -111.5t-277.5 114t-97.5 331zM1487 414q0 -152 31.5 -208t97.5 -56q71 0 101 57.5t30 206.5q0 101 -12.5 159t-39 84.5t-79.5 26.5q-70 0 -99.5 -61 t-29.5 -209zM2132 414q0 219 94.5 334.5t280.5 115.5t281.5 -113t95.5 -337q0 -222 -98.5 -333.5t-278.5 -111.5t-277.5 114t-97.5 331zM2378 414q0 -152 31.5 -208t97.5 -56q73 0 102 60.5t29 203.5q0 99 -13 158.5t-39 85.5t-79 26q-70 0 -99.5 -61t-29.5 -209z" />
+<glyph unicode="&#x2032;" horiz-adv-x="549" d="M131 772l37 612h274l-127 -612h-184z" />
+<glyph unicode="&#x2033;" horiz-adv-x="1036" d="M131 772l37 612h274l-127 -612h-184zM618 772l37 612h274l-127 -612h-184z" />
<glyph unicode="&#x2039;" horiz-adv-x="862" d="M61 524l420 471h299l-420 -471l420 -471h-299z" />
<glyph unicode="&#x203a;" horiz-adv-x="862" d="M82 53l420 471l-420 471h299l420 -471l-420 -471h-299z" />
-<glyph unicode="&#x205f;" horiz-adv-x="485" />
+<glyph unicode="&#x203c;" horiz-adv-x="1167" d="M129 139q0 82 36 118t126 36q92 0 128 -35t36 -119q0 -86 -39 -119.5t-125 -33.5q-94 0 -128 37.5t-34 115.5zM152 1384h280l-31 -944h-215zM713 139q0 82 36 118t126 36q92 0 128 -35t36 -119q0 -86 -39 -119.5t-125 -33.5q-94 0 -128 37.5t-34 115.5zM736 1384h280 l-31 -944h-215z" />
+<glyph unicode="&#x203d;" horiz-adv-x="1071" d="M35 1270q69 123 184 186.5t291 63.5q238 0 363.5 -103.5t125.5 -292.5q0 -105 -39 -185t-111.5 -145t-244.5 -155v-199h-272l-17 756q-26 -29 -47 -66zM309 139q0 82 36 118t126 36q92 0 128 -36t36 -118q0 -86 -39 -119.5t-125 -33.5q-94 0 -128 37.5t-34 115.5z M569 895q140 96 140 217q0 132 -127 160z" />
+<glyph unicode="&#x203e;" horiz-adv-x="1024" d="M-10 1526v102h1044v-102h-1044z" />
+<glyph unicode="&#x2044;" horiz-adv-x="211" d="M-397 -51l747 1489h238l-750 -1489h-235z" />
+<glyph unicode="&#x205f;" horiz-adv-x="551" />
+<glyph unicode="&#x2070;" horiz-adv-x="938" d="M70 1075q0 230 96 337.5t303 107.5q205 0 302 -107.5t97 -337.5q0 -229 -97 -336.5t-302 -107.5q-207 0 -303 107.5t-96 336.5zM328 1075q0 -127 33.5 -185.5t105.5 -58.5t107.5 58.5t35.5 185.5t-35.5 185.5t-107.5 58.5t-105.5 -58.5t-33.5 -185.5z" />
+<glyph unicode="&#x2074;" horiz-adv-x="938" d="M45 807v166l492 530h227v-524h115v-172h-115v-160h-232v160h-487zM276 979h256v276z" />
+<glyph unicode="&#x2075;" horiz-adv-x="938" d="M45 801l207 114q61 -90 170 -90q70 0 114 29t44 88q0 47 -34 74.5t-122 27.5q-85 0 -135 -53h-176l63 512h606v-188h-399l-16 -107q62 17 143 17q155 0 242.5 -78.5t87.5 -208.5q0 -143 -107.5 -225t-308.5 -82q-239 0 -379 170z" />
+<glyph unicode="&#x2076;" horiz-adv-x="938" d="M90 1044q0 229 114 352.5t320 123.5q191 0 316 -80l-121 -154q-84 62 -193 62q-90 0 -132 -49.5t-52 -118.5q84 39 197 39q147 0 232 -71t85 -222q0 -140 -102.5 -217.5t-280.5 -77.5t-280.5 106.5t-102.5 306.5zM336 1018q0 -123 40 -171t111 -48q127 0 127 125 q0 63 -35.5 99t-93.5 36q-41 0 -84 -12.5t-65 -28.5z" />
+<glyph unicode="&#x2077;" horiz-adv-x="938" d="M70 1315v188h768v-139l-365 -717h-287l381 668h-497z" />
+<glyph unicode="&#x2078;" horiz-adv-x="938" d="M84 893q0 61 38 114.5t114 88.5q-58 24 -92.5 71t-34.5 107q0 119 94 182.5t266 63.5q166 0 262 -60.5t96 -183.5q0 -119 -131 -182q88 -39 122 -85t34 -116q0 -125 -100.5 -193.5t-282.5 -68.5q-184 0 -284.5 65.5t-100.5 196.5zM324 893q0 -39 33.5 -64.5t111.5 -25.5 t110.5 27.5t32.5 68.5q0 33 -29.5 62.5t-113.5 54.5q-86 -25 -115.5 -53.5t-29.5 -69.5zM338 1272q0 -35 24.5 -58.5t108.5 -44.5q72 19 99.5 42.5t27.5 56.5q-5 80 -133 80q-72 0 -99.5 -24t-27.5 -52z" />
+<glyph unicode="&#x2079;" horiz-adv-x="938" d="M80 1225q0 139 102.5 217t280.5 78t280.5 -106.5t102.5 -307.5q0 -228 -113.5 -351.5t-320.5 -123.5q-191 0 -316 80l121 153q83 -61 193 -61q90 0 132 49t52 119q-80 -39 -197 -39q-147 0 -232 70.5t-85 222.5zM322 1227q0 -64 35.5 -99.5t93.5 -35.5q41 0 84 12t65 29 q0 122 -40 170.5t-111 48.5q-127 0 -127 -125z" />
+<glyph unicode="&#x207f;" horiz-adv-x="874" d="M123 649v668h184v-80q41 41 106.5 70.5t131.5 29.5q121 0 168 -61.5t47 -173.5v-453h-180v373q0 96 -19.5 132t-75.5 36q-75 0 -178 -92v-449h-184z" />
+<glyph unicode="&#x2080;" horiz-adv-x="938" d="M70 121q0 230 96 337.5t303 107.5q205 0 302 -107.5t97 -337.5q0 -229 -97 -336.5t-302 -107.5q-207 0 -303 107.5t-96 336.5zM328 121q0 -127 33.5 -185.5t105.5 -58.5t107.5 58.5t35.5 185.5t-35.5 185.5t-107.5 58.5t-105.5 -58.5t-33.5 -185.5z" />
+<glyph unicode="&#x2081;" horiz-adv-x="938" d="M170 246v152q97 3 150 17t82 43t49 91h200v-856h-252v553h-229z" />
+<glyph unicode="&#x2082;" horiz-adv-x="938" d="M76 394q133 172 377 172q180 0 262 -71t82 -179q0 -60 -16 -107.5t-52.5 -92.5t-130.5 -115t-166 -111h397v-197h-737v182l108 78q228 160 283.5 217t55.5 113q0 78 -97 78q-101 0 -170 -88z" />
+<glyph unicode="&#x2083;" horiz-adv-x="938" d="M59 -153l199 102q64 -88 164 -88q72 0 98.5 32t26.5 66q0 91 -141 91h-115v176h102q92 0 124 22.5t32 63.5q0 28 -27.5 48.5t-85.5 20.5q-103 0 -168 -78l-182 107q61 74 143 115t224 41q172 0 255 -67t83 -159q0 -71 -38 -116t-124 -74q92 -23 134 -77t42 -126 q0 -137 -102.5 -203.5t-282.5 -66.5q-127 0 -221.5 49t-139.5 121z" />
+<glyph unicode="&#x2084;" horiz-adv-x="938" d="M45 19l492 530h227v-524h115v-172h-115v-160h-232v160h-487v166zM276 25h256v276z" />
+<glyph unicode="&#x2085;" horiz-adv-x="938" d="M45 -153l207 114q61 -90 170 -90q70 0 114 29t44 88q0 47 -34 74.5t-122 27.5q-85 0 -135 -53h-176l63 512h606v-188h-399l-16 -107q62 17 143 17q155 0 242.5 -78.5t87.5 -208.5q0 -143 -107.5 -225t-308.5 -82q-239 0 -379 170z" />
+<glyph unicode="&#x2086;" horiz-adv-x="938" d="M90 90q0 229 114 352.5t320 123.5q191 0 316 -80l-121 -154q-84 62 -193 62q-90 0 -132 -49.5t-52 -118.5q84 39 197 39q147 0 232 -71t85 -222q0 -140 -102.5 -217.5t-280.5 -77.5t-280.5 106.5t-102.5 306.5zM336 64q0 -123 40 -171t111 -48q127 0 127 125 q0 63 -35.5 99t-93.5 36q-41 0 -84 -12.5t-65 -28.5z" />
+<glyph unicode="&#x2087;" horiz-adv-x="938" d="M70 361v188h768v-139l-365 -717h-287l381 668h-497z" />
+<glyph unicode="&#x2088;" horiz-adv-x="938" d="M84 -61q0 61 38 114.5t114 88.5q-58 24 -92.5 71t-34.5 107q0 119 94 182.5t266 63.5q166 0 262 -60.5t96 -183.5q0 -119 -131 -182q88 -39 122 -85t34 -116q0 -125 -100.5 -193.5t-282.5 -68.5q-184 0 -284.5 65.5t-100.5 196.5zM324 -61q0 -39 33.5 -64.5t111.5 -25.5 t110.5 27.5t32.5 68.5q0 33 -29.5 62.5t-113.5 54.5q-86 -25 -115.5 -53.5t-29.5 -69.5zM338 318q0 -35 24.5 -58.5t108.5 -44.5q72 19 99.5 42.5t27.5 56.5q-5 80 -133 80q-72 0 -99.5 -24t-27.5 -52z" />
+<glyph unicode="&#x2089;" horiz-adv-x="938" d="M80 271q0 139 102.5 217t280.5 78t280.5 -106.5t102.5 -307.5q0 -228 -113.5 -351.5t-320.5 -123.5q-191 0 -316 80l121 153q83 -61 193 -61q90 0 132 49t52 119q-80 -39 -197 -39q-147 0 -232 70.5t-85 222.5zM322 273q0 -64 35.5 -99.5t93.5 -35.5q41 0 84 12t65 29 q0 122 -40 170.5t-111 48.5q-127 0 -127 -125z" />
+<glyph unicode="&#x20a3;" horiz-adv-x="1280" d="M92 174v188h148v1022h890v-258h-608v-299h510v-249h-510v-216h377v-188h-377v-174h-282v174h-148z" />
+<glyph unicode="&#x20a4;" horiz-adv-x="1280" d="M100 0v213q76 16 118 73.5t56 135.5h-165v170h167q0 62 -18 110h-149v170h112q-12 62 -12 154q0 187 135 287t367 100q176 0 296.5 -61.5t184.5 -167.5l-217 -131q-41 65 -111.5 104t-152.5 39q-119 0 -176.5 -54.5t-57.5 -144.5q0 -57 10 -125h428v-170h-391 q17 -76 17 -110h374v-170h-387q-16 -57 -45.5 -105.5t-58.5 -76.5h784v-240h-1108z" />
+<glyph unicode="&#x20a7;" horiz-adv-x="2720" d="M150 0v1384h479q205 0 326.5 -78.5t154.5 -256.5h139v292h258v-292h224v-205h-224v-494q0 -98 26 -133t73 -35q60 0 118 29l37 -211q-91 -31 -200 -31q-166 0 -239 82t-73 266v527h-131q-16 -211 -135 -313.5t-362 -102.5h-189v-428h-282zM432 674h74q155 0 214.5 21.5 t84 72.5t24.5 150q0 121 -67 171t-230 50h-100v-465zM1769 152l193 135q47 -64 108.5 -85.5t131.5 -21.5q184 0 184 107q0 47 -52.5 72.5t-162.5 52.5q-209 46 -294 130.5t-85 217.5q0 139 106.5 229t313.5 90q141 0 248.5 -45t165.5 -135l-193 -137q-70 106 -225 106 q-80 0 -121 -27.5t-41 -70.5q0 -41 37 -65.5t145 -51.5q180 -44 256 -87t116 -108t40 -159q0 -104 -52 -177.5t-149.5 -113t-220.5 -39.5q-328 0 -449 183z" />
+<glyph unicode="&#x20ab;" horiz-adv-x="1217" d="M92 479q0 249 116.5 387t323.5 138q74 0 152 -31t129 -78v207h-278v184h278v98h258v-98h135v-184h-135v-1102h-237v102q-72 -61 -152 -97t-182 -36q-198 0 -303 132.5t-105 377.5zM133 -121h938v-184h-938v184zM358 483q0 -134 53 -210t158 -76q64 0 130.5 29.5 t113.5 72.5v383q-41 37 -101.5 65.5t-123.5 28.5q-104 0 -167 -79.5t-63 -213.5z" />
<glyph unicode="&#x20ac;" horiz-adv-x="1280" d="M20 444l39 191h58v119h-97l43 190h76q96 469 592 469q197 0 321 -68.5t189 -179.5l-201 -161q-53 78 -90.5 107.5t-85.5 44.5t-116 15q-132 0 -206.5 -55t-107.5 -172h522l-43 -190h-505v-119h487l-39 -191h-424q35 -127 110.5 -179t205.5 -52q92 0 162 40t143 146 l209 -149q-80 -118 -149 -174t-157 -80.5t-215 -24.5q-505 0 -602 473h-119z" />
+<glyph unicode="&#x20b9;" horiz-adv-x="1280" d="M139 881l107 190h403q-38 125 -172 125h-338l107 188h913l-106 -188h-191q37 -59 53 -125h244l-106 -190h-129q-23 -146 -125.5 -241t-263.5 -112l393 -528h-299l-383 528v228h192q103 0 151 32.5t64 92.5h-514z" />
+<glyph unicode="&#x20ba;" horiz-adv-x="1280" d="M123 481v187l176 63v146l-176 -64v188l176 64v319h258v-237l256 92v-186l-256 -95v-145l256 94v-186l-256 -94v-404h4q102 0 179.5 49t119 141t41.5 228h256q0 -317 -160.5 -493.5t-488.5 -176.5q-113 0 -209 29v545z" />
+<glyph unicode="&#x2105;" horiz-adv-x="1929" d="M74 1149q0 170 82 269.5t266 99.5q180 0 274 -140l-137 -86q-49 78 -135 78q-85 0 -122.5 -53.5t-37.5 -167.5q0 -118 42 -168.5t126 -50.5q71 0 148 53l96 -129q-111 -72 -254 -72q-186 0 -267 99.5t-81 267.5zM473 -31l741 1520h232l-741 -1520h-232zM1178 334 q0 187 88 276.5t252 89.5q161 0 249 -89t88 -277q0 -186 -89 -275.5t-248 -89.5q-162 0 -251 89.5t-89 275.5zM1372 334q0 -113 37 -162t109 -49q71 0 107 49t36 162q0 117 -36 165t-107 48q-72 0 -109 -48t-37 -165z" />
+<glyph unicode="&#x2113;" horiz-adv-x="1090" d="M137 465l191 182v406q0 204 85 321t244 117q78 0 134 -34t85 -92t29 -130q0 -96 -34 -187.5t-98.5 -184.5t-190.5 -228v-277q0 -196 129 -196q51 0 93 28.5t70 55.5l78 -148q-51 -45 -133 -88t-184 -43q-148 0 -227.5 94t-79.5 261v127l-92 -91zM582 842 q88 108 125.5 193t37.5 165q0 41 -17 68.5t-52 27.5q-94 0 -94 -190v-264z" />
+<glyph unicode="&#x2116;" horiz-adv-x="2402" d="M143 0v1384h349l579 -942v942h270v-1384h-315l-612 1008v-1008h-271zM1505 872q0 206 99.5 307t283.5 101q186 0 283.5 -103.5t97.5 -304.5q0 -196 -97.5 -299.5t-283.5 -103.5q-184 0 -283.5 100.5t-99.5 302.5zM1538 0v233h698v-233h-698zM1743 872q0 -116 37 -166.5 t108 -50.5q142 0 142 217q0 222 -142 222q-71 0 -108 -51.5t-37 -170.5z" />
<glyph unicode="&#x2122;" horiz-adv-x="1692" d="M43 1208v176h639v-176h-219v-538h-199v538h-221zM836 670v714h215l149 -303l152 303h215v-714h-193v391l-117 -232h-110l-119 234v-393h-192z" />
+<glyph unicode="&#x2126;" horiz-adv-x="1368" d="M86 807q0 182 69.5 319.5t202 212t324.5 74.5q289 0 444.5 -157.5t155.5 -448.5q0 -204 -58 -333t-194 -193v-31h242v-250h-490v401q107 16 156 115t49 291q0 168 -75.5 262t-229.5 94q-149 0 -227 -89t-78 -265q0 -139 18.5 -220.5t58.5 -125t128 -62.5v-401h-486v250 h248v31q-102 35 -155 94t-78 162t-25 270z" />
+<glyph unicode="&#x212e;" horiz-adv-x="1417" d="M96 625q0 183 76 330.5t216.5 232t318.5 84.5q177 0 317 -83t217 -230.5t80 -335.5h-959v-430q144 -140 340 -140q168 0 276.5 79t186.5 206l74 -47q-108 -165 -233.5 -240.5t-303.5 -75.5q-175 0 -314 85.5t-215.5 236t-76.5 328.5zM362 702h687v353q-66 63 -156 102 t-188 39q-206 0 -343 -139v-355z" />
+<glyph unicode="&#x215b;" horiz-adv-x="2095" d="M96 1085v152q97 3 150 17t82 43t49 91h200v-856h-252v553h-229zM504 -51l747 1489h238l-750 -1489h-235zM1241 246q0 61 38 114.5t114 88.5q-58 24 -92.5 71t-34.5 107q0 119 94 182.5t266 63.5q166 0 262 -60.5t96 -183.5q0 -119 -131 -182q88 -39 122 -85t34 -116 q0 -125 -100.5 -193.5t-282.5 -68.5q-184 0 -284.5 65.5t-100.5 196.5zM1481 246q0 -39 33.5 -64.5t111.5 -25.5t110.5 27.5t32.5 68.5q0 33 -29.5 62.5t-113.5 54.5q-86 -25 -115.5 -53.5t-29.5 -69.5zM1495 625q0 -35 24.5 -58.5t108.5 -44.5q72 19 99.5 42.5t27.5 56.5 q-5 80 -133 80q-72 0 -99.5 -24t-27.5 -52z" />
+<glyph unicode="&#x215c;" horiz-adv-x="2095" d="M59 686l199 102q64 -88 164 -88q72 0 98.5 32t26.5 66q0 91 -141 91h-115v176h102q92 0 124 22.5t32 63.5q0 28 -27.5 48.5t-85.5 20.5q-103 0 -168 -78l-182 107q61 74 143 115t224 41q172 0 255 -67t83 -159q0 -71 -38 -116t-124 -74q92 -23 134 -77t42 -126 q0 -137 -102.5 -203.5t-282.5 -66.5q-127 0 -221.5 49t-139.5 121zM543 -51l747 1489h238l-750 -1489h-235zM1241 246q0 61 38 114.5t114 88.5q-58 24 -92.5 71t-34.5 107q0 119 94 182.5t266 63.5q166 0 262 -60.5t96 -183.5q0 -119 -131 -182q88 -39 122 -85t34 -116 q0 -125 -100.5 -193.5t-282.5 -68.5q-184 0 -284.5 65.5t-100.5 196.5zM1481 246q0 -39 33.5 -64.5t111.5 -25.5t110.5 27.5t32.5 68.5q0 33 -29.5 62.5t-113.5 54.5q-86 -25 -115.5 -53.5t-29.5 -69.5zM1495 625q0 -35 24.5 -58.5t108.5 -44.5q72 19 99.5 42.5t27.5 56.5 q-5 80 -133 80q-72 0 -99.5 -24t-27.5 -52z" />
+<glyph unicode="&#x215d;" horiz-adv-x="2095" d="M45 686l207 114q61 -90 170 -90q70 0 114 29t44 88q0 47 -34 74.5t-122 27.5q-85 0 -135 -53h-176l63 512h606v-188h-399l-16 -107q62 17 143 17q155 0 242.5 -78.5t87.5 -208.5q0 -143 -107.5 -225t-308.5 -82q-239 0 -379 170zM551 -51l747 1489h238l-750 -1489h-235z M1241 246q0 61 38 114.5t114 88.5q-58 24 -92.5 71t-34.5 107q0 119 94 182.5t266 63.5q166 0 262 -60.5t96 -183.5q0 -119 -131 -182q88 -39 122 -85t34 -116q0 -125 -100.5 -193.5t-282.5 -68.5q-184 0 -284.5 65.5t-100.5 196.5zM1481 246q0 -39 33.5 -64.5t111.5 -25.5 t110.5 27.5t32.5 68.5q0 33 -29.5 62.5t-113.5 54.5q-86 -25 -115.5 -53.5t-29.5 -69.5zM1495 625q0 -35 24.5 -58.5t108.5 -44.5q72 19 99.5 42.5t27.5 56.5q-5 80 -133 80q-72 0 -99.5 -24t-27.5 -52z" />
+<glyph unicode="&#x215e;" horiz-adv-x="2095" d="M70 1200v188h768v-139l-365 -717h-287l381 668h-497zM525 -51l747 1489h238l-750 -1489h-235zM1241 246q0 61 38 114.5t114 88.5q-58 24 -92.5 71t-34.5 107q0 119 94 182.5t266 63.5q166 0 262 -60.5t96 -183.5q0 -119 -131 -182q88 -39 122 -85t34 -116 q0 -125 -100.5 -193.5t-282.5 -68.5q-184 0 -284.5 65.5t-100.5 196.5zM1481 246q0 -39 33.5 -64.5t111.5 -25.5t110.5 27.5t32.5 68.5q0 33 -29.5 62.5t-113.5 54.5q-86 -25 -115.5 -53.5t-29.5 -69.5zM1495 625q0 -35 24.5 -58.5t108.5 -44.5q72 19 99.5 42.5t27.5 56.5 q-5 80 -133 80q-72 0 -99.5 -24t-27.5 -52z" />
+<glyph unicode="&#x2190;" horiz-adv-x="2048" d="M190 494v47q80 40 144.5 85.5t129 106t138.5 144.5h78q-76 -157 -168 -273h1346v-176h-1346q57 -69 94.5 -132t73.5 -138h-78q-109 122 -196 193.5t-216 142.5z" />
+<glyph unicode="&#x2191;" horiz-adv-x="1024" d="M154 1178v75q151 140 215 223t120 191h46q63 -121 131 -203t206 -211v-75q-66 29 -128 64.5t-144 100.5v-1343h-174v1343q-70 -52 -120.5 -84.5t-151.5 -80.5z" />
+<glyph unicode="&#x2192;" horiz-adv-x="2048" d="M190 428v176h1344q-70 90 -97.5 139t-68.5 134h76q140 -154 223 -218t191 -120v-45q-121 -64 -221 -146.5t-193 -189.5h-76q49 100 84 157t82 113h-1344z" />
+<glyph unicode="&#x2193;" horiz-adv-x="1024" d="M152 414v75q94 -45 149 -79t123 -86v1343h174v-1343q68 49 120 83.5t152 81.5v-75q-135 -123 -204 -211q-68 -82 -131 -203h-46q-63 121 -131 203t-206 211z" />
+<glyph unicode="&#x2194;" horiz-adv-x="2048" d="M190 494v47q80 40 144.5 85.5t129 106t138.5 144.5h78q-76 -157 -168 -273h1022q-60 78 -73.5 98.5t-39.5 69.5t-53 105h76q140 -154 223 -218t191 -120v-45q-121 -64 -221 -146.5t-193 -189.5h-76q60 122 76 147q30 50 90 123h-1022q57 -69 94.5 -132t73.5 -138h-78 q-109 122 -196 193.5t-216 142.5z" />
+<glyph unicode="&#x2195;" horiz-adv-x="1024" d="M154 414v75q73 -34 135.5 -70t136.5 -95v1019q-53 -43 -106.5 -78t-165.5 -87v75q125 112 197.5 201t137.5 213h46q60 -114 128 -201t209 -213v-75q-116 54 -159 81.5t-113 83.5v-1019l65 48q78 56 207 117v-75q-139 -123 -206 -209t-131 -205h-46q-63 121 -145 220.5 t-190 193.5z" />
+<glyph unicode="&#x21a8;" horiz-adv-x="1024" d="M154 -74h718v-174h-718v174zM154 414v75q62 -29 127 -66.5t145 -98.5v1019q-48 -38 -110 -78t-162 -87v75q141 128 215 226t120 188h46q54 -104 118 -190.5t219 -223.5v-75q-116 54 -159 81.5t-113 83.5v-1019q105 78 152 105t120 60v-75q-80 -69 -135 -126.5 t-104.5 -127t-97.5 -160.5h-46q-63 121 -145 220.5t-190 193.5z" />
+<glyph unicode="&#x2202;" horiz-adv-x="1286" d="M90 397q0 180 73 319.5t199 215.5t267 76q102 0 175 -40t105 -94h4q7 35 7 105q0 141 -70 226t-203 85q-115 0 -213 -61l-59 184q49 35 134 59.5t185 24.5q236 0 368 -150t132 -407q0 -261 -89 -491t-240 -352t-335 -122q-193 0 -316.5 119t-123.5 303zM373 387 q0 -90 45 -144.5t123 -54.5q116 0 209 137t129 347q-21 61 -68 102t-125 41q-83 0 -155 -56.5t-115 -157t-43 -214.5z" />
+<glyph unicode="&#x2206;" horiz-adv-x="1284" d="M27 0v115l222 635q141 406 224 634h344l440 -1269v-115h-1230zM340 236h584l-260 763q-13 37 -18 68t-9 41h-8q-14 -72 -25 -104z" />
+<glyph unicode="&#x220f;" horiz-adv-x="1610" d="M162 -471v1905h1286v-1905h-287v1659h-712v-1659h-287z" />
+<glyph unicode="&#x2211;" horiz-adv-x="1407" d="M72 -319l643 811l-606 778v164h1183v-230h-815l547 -706l-580 -740h891v-229h-1263v152z" />
+<glyph unicode="&#x2212;" horiz-adv-x="1427" d="M133 479v205h1161v-205h-1161z" />
+<glyph unicode="&#x2215;" horiz-adv-x="1036" d="M-12 -299l690 1819h256l-692 -1819h-254z" />
+<glyph unicode="&#x2219;" horiz-adv-x="545" d="M113 598q0 152 157 152q162 0 162 -152q0 -84 -42 -116.5t-120 -32.5q-88 0 -122.5 39.5t-34.5 109.5z" />
+<glyph unicode="&#x221a;" horiz-adv-x="1196" d="M39 666l315 202l267 -614l350 1239h186l-432 -1518h-207l-278 631l-121 -76z" />
+<glyph unicode="&#x221e;" horiz-adv-x="1763" d="M96 596q0 162 107 269.5t278 107.5q129 0 229.5 -63.5t170.5 -161.5h4q70 103 173.5 164t221.5 61q169 0 278 -104t109 -267q0 -169 -108 -276t-275 -107q-121 0 -224.5 60.5t-172.5 164.5h-4q-68 -94 -170.5 -159.5t-227.5 -65.5q-176 0 -282.5 106t-106.5 271zM309 596 q0 -80 53.5 -134t139.5 -54q84 0 153.5 55t120.5 135q-53 80 -124.5 133t-153.5 53q-90 0 -139.5 -55t-49.5 -133zM989 598q117 -190 277 -190q96 0 143 58t47 132t-47 130t-145 56q-156 0 -275 -186z" />
+<glyph unicode="&#x221f;" horiz-adv-x="2048" d="M123 0v1667h135v-1532h1667v-135h-1802z" />
+<glyph unicode="&#x2229;" horiz-adv-x="1473" d="M158 0v588q0 186 7 307.5t51.5 225.5t123.5 181t182 117.5t215 40.5q137 0 246 -49t182 -137q75 -89 108 -194.5t37.5 -208t4.5 -283.5v-588h-146v596q0 225 -10.5 323t-51.5 177t-95 126.5t-122.5 70t-154.5 22.5q-136 0 -227.5 -56.5t-141.5 -156t-57 -221.5 q-4 -108 -4 -285v-596h-147z" />
+<glyph unicode="&#x222b;" horiz-adv-x="1083" d="M96 -453l54 201q45 -20 98 -20q71 0 110 45t39 133v1206q0 195 95.5 309.5t291.5 114.5q60 0 117 -11.5t86 -25.5l-57 -196q-57 20 -101 20q-69 0 -108 -44t-39 -134v-1208q0 -197 -97.5 -309.5t-291.5 -112.5q-49 0 -107.5 9t-89.5 23z" />
+<glyph unicode="&#x2248;" horiz-adv-x="1427" d="M133 139v213q190 144 350 144q66 0 127.5 -22.5t123 -49.5t123 -49.5t126.5 -22.5q57 0 139.5 36t171.5 97v-213q-192 -143 -342 -143q-69 0 -132.5 22.5t-125 49t-123 49t-127.5 22.5q-114 0 -311 -133zM133 610v213q190 144 350 144q66 0 127.5 -22.5t123 -49.5 t123 -49.5t126.5 -22.5q57 0 139.5 36t171.5 97v-213q-192 -143 -342 -143q-69 0 -132.5 22.5t-125 49t-123 49t-127.5 22.5q-114 0 -311 -133z" />
+<glyph unicode="&#x2260;" horiz-adv-x="1427" d="M133 233v205h381l145 287h-526v205h629l188 375h238l-189 -375h295v-205h-399l-143 -287h542v-205h-647l-158 -315h-235l158 315h-279z" />
+<glyph unicode="&#x2261;" horiz-adv-x="1427" d="M133 0v205h1161v-205h-1161zM133 432v205h1161v-205h-1161zM133 866v205h1161v-205h-1161z" />
+<glyph unicode="&#x2264;" horiz-adv-x="1427" d="M133 0v217h1161v-217h-1161zM133 719v207l1161 436v-223l-870 -318l870 -266v-223z" />
+<glyph unicode="&#x2265;" horiz-adv-x="1427" d="M133 0v217h1161v-217h-1161zM133 332v223l871 266l-871 318v223l1161 -436v-207z" />
+<glyph unicode="&#x2302;" horiz-adv-x="1229" d="M154 0v635l460 518l461 -518v-635h-921zM233 82h762v518l-381 426l-381 -426v-518z" />
+<glyph unicode="&#x2310;" horiz-adv-x="1427" d="M133 324v682h1161v-205h-954v-477h-207z" />
+<glyph unicode="&#x2320;" horiz-adv-x="1237" d="M547 -381v1608q0 223 88 329q88 111 203 111q67 0 103 -34t36 -74q0 -37 -25.5 -65t-62.5 -28q-29 0 -52.5 11.5t-48.5 50.5q-22 37 -45 37q-30 0 -43 -27q-10 -31 -10 -152v-1767h-143z" />
+<glyph unicode="&#x2321;" horiz-adv-x="1237" d="M260 -272q0 39 26.5 65.5t61.5 26.5q31 0 53.5 -12.5t47.5 -51.5q22 -35 45 -35q33 0 43 32.5t10 146.5v1767h143v-1608q0 -219 -88 -327q-86 -113 -203 -113q-69 0 -104 33t-35 76z" />
+<glyph unicode="&#x2500;" horiz-adv-x="1450" d="M-23 535v174h1496v-174h-1496z" />
+<glyph unicode="&#x2502;" horiz-adv-x="1450" d="M639 -621v2485h174v-2485h-174z" />
+<glyph unicode="&#x250c;" horiz-adv-x="1450" d="M639 -621v1330h836v-174h-662v-1156h-174z" />
+<glyph unicode="&#x2510;" horiz-adv-x="1450" d="M-23 535v174h834v-1330h-174v1156h-660z" />
+<glyph unicode="&#x2514;" horiz-adv-x="1450" d="M639 535v1329h174v-1155h662v-174h-836z" />
+<glyph unicode="&#x2518;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-1329h-834z" />
+<glyph unicode="&#x251c;" horiz-adv-x="1450" d="M639 -621v2485h174v-1155h662v-174h-662v-1156h-174z" />
+<glyph unicode="&#x2524;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-2485h-174v1156h-660z" />
+<glyph unicode="&#x252c;" horiz-adv-x="1450" d="M-23 535v174h1496v-174h-662v-1156h-174v1156h-660z" />
+<glyph unicode="&#x2534;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-1155h662v-174h-1496z" />
+<glyph unicode="&#x253c;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-1155h662v-174h-662v-1156h-174v1156h-660z" />
+<glyph unicode="&#x2550;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-1496zM-23 725v174h1496v-174h-1496z" />
+<glyph unicode="&#x2551;" horiz-adv-x="1450" d="M449 -621v2485h174v-2485h-174zM829 -621v2485h175v-2485h-175z" />
+<glyph unicode="&#x2552;" horiz-adv-x="1450" d="M639 -621v1520h836v-174h-662v-207h662v-174h-662v-965h-174z" />
+<glyph unicode="&#x2553;" horiz-adv-x="1450" d="M449 -621v1330h1026v-174h-471v-1156h-175v1156h-206v-1156h-174z" />
+<glyph unicode="&#x2554;" horiz-adv-x="1450" d="M449 -621v1520h1026v-174h-852v-1346h-174zM829 518h646v-174h-471v-965h-175v1139z" />
+<glyph unicode="&#x2555;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h834v-1520h-174v965h-660z" />
+<glyph unicode="&#x2556;" horiz-adv-x="1450" d="M-23 535v174h1027v-1330h-177v1156h-204v-1156h-174v1156h-472z" />
+<glyph unicode="&#x2557;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h1027v-1520h-177v1346h-850z" />
+<glyph unicode="&#x2558;" horiz-adv-x="1450" d="M639 344v1520h174v-965h662v-174h-662v-207h662v-174h-836z" />
+<glyph unicode="&#x2559;" horiz-adv-x="1450" d="M449 535v1329h174v-1155h206v1155h175v-1155h471v-174h-1026z" />
+<glyph unicode="&#x255a;" horiz-adv-x="1450" d="M449 344v1520h174v-1346h850v-174h-1024zM829 725v1139h175v-965h471v-174h-646z" />
+<glyph unicode="&#x255b;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h660v965h174v-1520h-834z" />
+<glyph unicode="&#x255c;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1329h-1027z" />
+<glyph unicode="&#x255d;" horiz-adv-x="1450" d="M-23 344v174h850v1346h177v-1520h-1027zM-23 725v174h469v965h177v-1139h-646z" />
+<glyph unicode="&#x255e;" horiz-adv-x="1450" d="M639 -621v2485h174v-965h662v-174h-662v-207h662v-174h-662v-965h-174z" />
+<glyph unicode="&#x255f;" horiz-adv-x="1450" d="M449 -621v2485h174v-2485h-174zM829 -621v2485h175v-1155h471v-174h-471v-1156h-175z" />
+<glyph unicode="&#x2560;" horiz-adv-x="1450" d="M449 -621v2485h174v-2485h-174zM829 518h646v-174h-471v-965h-175v1139zM829 725v1139h175v-965h471v-174h-646z" />
+<glyph unicode="&#x2561;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h660v965h174v-2485h-174v965h-660z" />
+<glyph unicode="&#x2562;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-2485h-177l3 1156h-472zM827 -621v2485h177v-2485h-177z" />
+<glyph unicode="&#x2563;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h469v965h177v-1139h-646zM827 -621v2485h177v-2485h-177z" />
+<glyph unicode="&#x2564;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-662v-965h-174v965h-660zM-23 725v174h1496v-174h-1496z" />
+<glyph unicode="&#x2565;" horiz-adv-x="1450" d="M-23 535v174h1496v-174h-469v-1156h-177v1156h-204v-1156h-177v1156h-469z" />
+<glyph unicode="&#x2566;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h1496v-174h-1496zM827 518h646v-174h-469v-965h-177v1139z" />
+<glyph unicode="&#x2567;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-1496zM-23 725v174h660v965h174v-965h662v-174h-1496z" />
+<glyph unicode="&#x2568;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1155h469v-174h-1496z" />
+<glyph unicode="&#x2569;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-1496zM-23 725v174h469v965h177v-1139h-646zM827 725v1139h177v-965h469v-174h-646z" />
+<glyph unicode="&#x256a;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h660v965h174v-965h662v-174h-662v-207h662v-174h-662v-965h-174v965h-660z" />
+<glyph unicode="&#x256b;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1155h469v-174h-469v-1156h-177v1156h-204v-1156h-177v1156h-469z" />
+<glyph unicode="&#x256c;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h469v965h177v-1139h-646zM827 518h646v-174h-469v-965h-177v1139zM827 725v1139h177v-965h469v-174h-646z" />
+<glyph unicode="&#x2580;" horiz-adv-x="1450" d="M-23 621v1243h1496v-1243h-1496z" />
+<glyph unicode="&#x2584;" horiz-adv-x="1450" d="M-23 -621v1242h1496v-1242h-1496z" />
+<glyph unicode="&#x2588;" horiz-adv-x="1450" d="M-23 -621v2485h1496v-2485h-1496z" />
+<glyph unicode="&#x258c;" horiz-adv-x="1450" d="M-23 -621v2485h748v-2485h-748z" />
+<glyph unicode="&#x2590;" horiz-adv-x="1450" d="M725 -621v2485h750v-2485h-750z" />
+<glyph unicode="&#x2591;" horiz-adv-x="1450" d="M0 -129h121v-127h-121v127zM0 244v125h121v-125h-121zM0 741v125h121v-125h-121zM0 1241v125h121v-125h-121zM0 1739v125h121v-125h-121zM242 -4v125h120v-125h-120zM242 -379h120v-125h-120v125zM242 494v124h120v-124h-120zM242 991v125h120v-125h-120zM242 1491v125 h120v-125h-120zM481 -129h121v-127h-121v127zM481 244v125h121v-125h-121zM481 741v125h121v-125h-121zM481 1241v125h121v-125h-121zM481 1739v125h121v-125h-121zM723 -4v125h121v-125h-121zM723 -379h121v-125h-121v125zM723 494v124h121v-124h-121zM723 991v125h121 v-125h-121zM723 1491v125h121v-125h-121zM965 -129h120v-127h-120v127zM965 244v125h120v-125h-120zM965 741v125h120v-125h-120zM965 1241v125h120v-125h-120zM965 1739v125h120v-125h-120zM1206 -4v125h121v-125h-121zM1206 -379h121v-125h-121v125zM1206 494v124h121 v-124h-121zM1206 991v125h121v-125h-121zM1206 1491v125h121v-125h-121z" />
+<glyph unicode="&#x2592;" horiz-adv-x="1450" d="M0 -4v123h121v-123h-121zM0 -379h121v-125h-121v125zM0 494v124h121v-124h-121zM0 991v125h121v-125h-121zM0 1491v125h121v-125h-121zM121 -129h121v-127h-121v127zM121 244v125h121v-125h-121zM121 741v125h121v-125h-121zM121 1241v125h121v-125h-121zM121 1739v125 h121v-125h-121zM242 -4v123h120v-123h-120zM242 -379h120v-125h-120v125zM242 494v124h120v-124h-120zM242 991v125h120v-125h-120zM242 1491v125h120v-125h-120zM362 -129h119v-127h-119v127zM362 244v125h119v-125h-119zM362 741v125h119v-125h-119zM362 1241v125h119 v-125h-119zM362 1739v125h119v-125h-119zM481 -4v123h121v-123h-121zM481 -379h121v-125h-121v125zM481 494v124h121v-124h-121zM481 991v125h121v-125h-121zM481 1491v125h121v-125h-121zM602 -129h123v-127h-123v127zM602 244v125h123v-125h-123zM602 741v125h123v-125 h-123zM602 1241v125h123v-125h-123zM602 1739v125h123v-125h-123zM725 -4v123h119v-123h-119zM725 -379h119v-125h-119v125zM725 494v124h119v-124h-119zM725 991v125h119v-125h-119zM725 1491v125h119v-125h-119zM844 -129h121v-127h-121v127zM844 244v125h121v-125h-121z M844 741v125h121v-125h-121zM844 1241v125h121v-125h-121zM844 1739v125h121v-125h-121zM965 -4v123h120v-123h-120zM965 -381l120 2v-125h-120v123zM965 494v124h120v-124h-120zM965 991v125h120v-125h-120zM965 1491v125h120v-125h-120zM1085 -129h121v-127h-121v127z M1085 244v125h121v-125h-121zM1085 741v125h121v-125h-121zM1085 1241v125h121v-125h-121zM1085 1739v125h121v-125h-121zM1206 -4v123h121v-123h-121zM1206 -379h121v-125h-121v125zM1206 494v124h121v-124h-121zM1206 991v125h121v-125h-121zM1206 1491v125h121v-125h-121 zM1327 -129h121v-127h-121v127zM1327 244v125h121v-125h-121zM1327 741v125h121v-125h-121zM1327 1241v125h121v-125h-121zM1327 1739v125h121v-125h-121z" />
+<glyph unicode="&#x2593;" horiz-adv-x="1450" d="M0 -129v373h121v125h-121v372h121v125h-121v375h121v125h-121v373h121v125h121v-125h120v125h119v-125h121v125h123v-125h119v125h121v-125h120v125h121v-125h121v125h121v-248h-121v-125h121v-375h-121v-125h121v-373h-121v-124h121v-375h-121v-123h121v-375h-121v-125 h121v-125h-1448v373h121v127h-121zM121 -4h121v123h-121v-123zM121 -379v-125h121v125h-121zM121 494h121v124h-121v-124zM121 991h121v125h-121v-125zM121 1491h121v125h-121v-125zM242 -129v-127h120v127h-120zM242 244h120v125h-120v-125zM242 741h120v125h-120v-125z M242 1241h120v125h-120v-125zM362 -4h119v123h-119v-123zM362 -379v-125h119v125h-119zM362 494h119v124h-119v-124zM362 991h119v125h-119v-125zM362 1491h119v125h-119v-125zM481 -129v-127h121v127h-121zM481 244h121v125h-121v-125zM481 741h121v125h-121v-125z M481 1241h121v125h-121v-125zM602 -4h123v123h-123v-123zM602 -379v-125h123v125h-123zM602 494h123v124h-123v-124zM602 991h123v125h-123v-125zM602 1491h123v125h-123v-125zM725 -129v-127h119v127h-119zM725 244h119v125h-119v-125zM725 741h119v125h-119v-125z M725 1241h119v125h-119v-125zM844 -4h121v123h-121v-123zM844 -379v-125h121v125h-121zM844 494h121v124h-121v-124zM844 991h121v125h-121v-125zM844 1491h121v125h-121v-125zM965 -129v-127h120v127h-120zM965 244h120v125h-120v-125zM965 741h120v125h-120v-125z M965 1241h120v125h-120v-125zM1085 -4h121v123h-121v-123zM1085 -379v-125h121v125h-121zM1085 494h121v124h-121v-124zM1085 991h121v125h-121v-125zM1085 1491h121v125h-121v-125zM1206 -129v-127h121v127h-121zM1206 244h121v125h-121v-125zM1206 741h121v125h-121v-125z M1206 1241h121v125h-121v-125z" />
+<glyph unicode="&#x25a0;" horiz-adv-x="1237" d="M145 0v944h945v-944h-945z" />
+<glyph unicode="&#x25a1;" horiz-adv-x="1237" d="M145 0v944h945v-944h-945zM221 76h793v792h-793v-792z" />
+<glyph unicode="&#x25aa;" horiz-adv-x="725" d="M131 444v463l463 2v-465h-463z" />
+<glyph unicode="&#x25ab;" horiz-adv-x="725" d="M131 444v463h463v-463h-463zM207 520h311v311h-311v-311z" />
+<glyph unicode="&#x25ac;" horiz-adv-x="2048" d="M340 0v385h1368v-385h-1368z" />
+<glyph unicode="&#x25b2;" horiz-adv-x="2028" d="M303 0l711 1419l710 -1419h-1421z" />
+<glyph unicode="&#x25ba;" horiz-adv-x="2028" d="M289 -31v1448l1450 -725z" />
+<glyph unicode="&#x25bc;" horiz-adv-x="2028" d="M303 1389h1421l-710 -1420z" />
+<glyph unicode="&#x25c4;" horiz-adv-x="2028" d="M289 692l1450 725v-1448z" />
+<glyph unicode="&#x25ca;" horiz-adv-x="1229" d="M145 715l451 719h100l453 -717l-453 -717h-100zM307 717l340 -541l338 541l-338 538z" />
+<glyph unicode="&#x25cb;" horiz-adv-x="1237" d="M178 595q0 105 62 205.5t159.5 159t218.5 58.5q120 0 218.5 -58t160.5 -158.5t62 -206.5q0 -139 -58.5 -238.5t-157.5 -159.5t-225 -60q-124 0 -223 59.5t-158 159t-59 239.5zM254 594q0 -117 48 -199.5t130.5 -132t185.5 -49.5q155 0 260 107t105 267q0 87 -47.5 169 t-131 134t-186.5 52q-101 0 -183.5 -50.5t-131.5 -131.5t-49 -166z" />
+<glyph unicode="&#x25cf;" horiz-adv-x="1237" d="M178 595q0 105 62 205.5t159.5 159t218.5 58.5q120 0 218.5 -58t160.5 -158.5t62 -206.5q0 -139 -58.5 -238.5t-157.5 -159.5t-225 -60q-124 0 -223 59.5t-158 159t-59 239.5z" />
+<glyph unicode="&#x25d8;" horiz-adv-x="1237" d="M127 0v981h981v-981h-981zM416 489q0 -84 60.5 -142t141.5 -58t141 59t60 141q0 86 -57 144.5t-144 58.5q-86 0 -144 -58.5t-58 -144.5z" />
+<glyph unicode="&#x25d9;" horiz-adv-x="1237" d="M43 0v1155h1153v-1155h-1153zM178 595q0 -139 58.5 -238.5t158 -159.5t223.5 -60q126 0 225.5 59.5t158.5 159.5t59 239q0 105 -62 205.5t-160 159t-221 58.5q-120 0 -218 -58.5t-160 -159t-62 -205.5zM256 595q0 88 49.5 168.5t132 129.5t183.5 49q97 0 179.5 -48.5 t132.5 -129t50 -169.5q0 -171 -106.5 -276.5t-255.5 -105.5q-104 0 -186.5 49t-130.5 132t-48 201z" />
+<glyph unicode="&#x25e6;" horiz-adv-x="725" d="M113 678q0 106 73 178t176 72q104 0 178 -73t74 -177q0 -105 -73.5 -178.5t-178.5 -73.5q-108 0 -178.5 75t-70.5 177zM188 678q0 -74 51.5 -125t122.5 -51q79 0 128 54.5t49 121.5q0 72 -51.5 123t-125.5 51q-71 0 -122.5 -51t-51.5 -123z" />
<glyph unicode="&#x25fc;" horiz-adv-x="1050" d="M0 0v1050h1050v-1050h-1050z" />
+<glyph unicode="&#x263a;" horiz-adv-x="2048" d="M385 518q0 164 84 316t236 236.5t319 84.5q168 0 321 -86.5t235.5 -237t82.5 -313.5q0 -132 -53 -252t-137 -203t-203 -132.5t-246 -49.5q-165 0 -315.5 83t-237 232.5t-86.5 321.5zM479 518q0 -135 68 -262.5t198.5 -205t278.5 -77.5q145 0 274 74t200 202.5t71 268.5 q0 133 -68 261.5t-200 206t-277 77.5q-136 0 -269 -72.5t-204.5 -204t-71.5 -268.5zM698 649q0 35 23.5 58.5t56.5 23.5q35 0 58.5 -23.5t23.5 -58.5q0 -33 -23.5 -56.5t-58.5 -23.5q-33 0 -56.5 23.5t-23.5 56.5zM729 313l64 35q75 -143 231 -143t231 143l64 -35 q-102 -194 -295 -194t-295 194zM1188 649q0 35 23.5 58.5t56.5 23.5q35 0 58.5 -23.5t23.5 -58.5q0 -33 -23.5 -56.5t-58.5 -23.5q-33 0 -56.5 23.5t-23.5 56.5z" />
+<glyph unicode="&#x263b;" horiz-adv-x="2048" d="M385 518q0 164 84 316t236 236.5t319 84.5q168 0 321 -86.5t235.5 -237t82.5 -313.5q0 -132 -53 -252t-137 -203t-203 -132.5t-246 -49.5q-165 0 -315.5 83t-237 232.5t-86.5 321.5zM698 649q0 -33 23.5 -56.5t56.5 -23.5q35 0 58.5 23.5t23.5 56.5q0 35 -23.5 58.5 t-58.5 23.5q-33 0 -56.5 -23.5t-23.5 -58.5zM729 313q102 -194 295 -194t295 194l-64 35q-75 -143 -231 -143t-231 143zM1188 649q0 -33 23.5 -56.5t56.5 -23.5q35 0 58.5 23.5t23.5 56.5q0 35 -23.5 58.5t-58.5 23.5q-33 0 -56.5 -23.5t-23.5 -58.5z" />
+<glyph unicode="&#x263c;" horiz-adv-x="1878" d="M16 666v67h336q8 107 41 186.5t103 163.5l-283 287l47 57l293 -282q100 69 179 100t169 39v338h78v-338q100 -6 180 -38t168 -103l291 284l51 -53l-287 -287q87 -113 115.5 -196t30.5 -158h334v-67h-334q-23 -197 -144 -353l285 -290l-57 -50l-283 283 q-100 -76 -172 -102q-67 -27 -178 -39v-338h-78v338q-110 14 -187 44.5t-157 92.5l-295 -279l-49 52l285 286q-68 86 -102 167t-44 188h-336zM426 698q0 -124 59.5 -243t183.5 -194t269 -75q131 0 254 68t190.5 189.5t67.5 254.5q0 111 -46 210.5t-119 166t-161 101 t-186 34.5q-122 0 -243.5 -59.5t-195 -184.5t-73.5 -268z" />
+<glyph unicode="&#x2640;" horiz-adv-x="1536" d="M244 983q0 134 68 258t192.5 195t263.5 71q132 0 254 -65.5t195 -189.5t73 -269q0 -214 -147 -364.5t-346 -157.5v-402h458v-59h-458v-381h-60v381h-461v59h461v402q-97 0 -218.5 62t-198 188t-76.5 272zM299 981q0 -195 137 -332t332 -137q132 0 238 63t168.5 169 t62.5 254q0 113 -65.5 220t-170 169.5t-233.5 62.5q-122 0 -232.5 -62t-173.5 -173t-63 -234z" />
+<glyph unicode="&#x2642;" horiz-adv-x="1536" d="M111 262q0 218 154 370t372 152q80 0 166 -26l360 772l-536 -266l-25 53l615 303l34 -16l164 -666l-57 -14l-141 579l-359 -768q148 -73 223.5 -199t75.5 -274q0 -135 -69.5 -259.5t-193 -194.5t-259.5 -70q-131 0 -251 63t-196.5 186.5t-76.5 274.5zM166 262 q0 -196 138.5 -333.5t330.5 -137.5q191 0 330 137t139 334q0 99 -43 193t-108 153t-149 91t-169 32q-117 0 -228 -59t-176 -172.5t-65 -237.5z" />
+<glyph unicode="&#x2660;" horiz-adv-x="1343" d="M186 494q0 87 45.5 157t133.5 142q114 93 175.5 167t89.5 136.5t44 134.5q28 -124 86.5 -207t183.5 -197q146 -133 179.5 -198t33.5 -131q0 -91 -62 -157.5t-155 -66.5q-156 0 -256 191q4 -213 87 -310.5t292 -117.5l6 -37h-793l9 37q186 0 284.5 104.5t98.5 307.5v16 q-90 -191 -262 -191q-90 0 -155 65t-65 155z" />
+<glyph unicode="&#x2663;" horiz-adv-x="1343" d="M55 553q0 116 73 194t167 82q65 -4 166 -53q-25 39 -42.5 75.5t-21.5 54.5t-4 52q0 116 79.5 194.5t197.5 78.5q116 0 196 -80q82 -76 82 -188q0 -91 -69 -187q79 40 102 45q25 8 59 8q102 0 175 -78t73 -194q0 -118 -78.5 -199t-197.5 -86q-78 4 -135.5 34t-108.5 79 q-46 61 -86 127q4 -160 48 -252t136 -154q68 -40 224 -71l8 -35h-848l8 35q123 26 183.5 50t112 86.5t80 139.5t28.5 154v20l-3 27q-61 -125 -147 -182.5t-178 -57.5q-122 0 -200.5 81.5t-78.5 199.5z" />
+<glyph unicode="&#x2665;" horiz-adv-x="1343" d="M127 969q0 108 73.5 185t180.5 77q99 0 175.5 -63t117.5 -189q38 128 112.5 190t169.5 62q111 0 185 -74t76 -176q0 -86 -39 -179t-174 -265q-155 -199 -240 -340q-59 -111 -90 -222q-32 125 -93.5 231t-218.5 312l-97 132q-72 95 -105 170t-33 149z" />
+<glyph unicode="&#x2666;" horiz-adv-x="1343" d="M213 604q77 88 192 238t169.5 233.5t97.5 159.5q98 -172 247.5 -368t210.5 -263q-54 -59 -208 -260t-250 -369q-52 93 -160 243t-175 232z" />
+<glyph unicode="&#x266a;" horiz-adv-x="1024" d="M37 186q0 113 80.5 180.5t193.5 67.5q76 0 174 -47v977h39q176 0 228 -14q123 -35 179 -128t56 -247v-103h-98v43q0 108 -73 164t-204 56h-26v-836q0 -123 -33 -190t-111.5 -106.5t-169.5 -39.5q-110 0 -172.5 61.5t-62.5 161.5z" />
+<glyph unicode="&#x266b;" horiz-adv-x="1536" d="M86 94q0 67 32 123t97.5 90.5t144.5 34.5q82 0 175 -45v975l794 248v-1108q0 -119 -28 -183t-106.5 -106.5t-172.5 -42.5q-111 0 -175.5 62.5t-64.5 160.5q0 103 76 172q76 74 201 74q47 0 81 -10t89 -33v723l-596 -185v-835q0 -125 -33 -191t-108.5 -106t-169.5 -41 q-111 0 -173.5 62.5t-62.5 160.5z" />
+<glyph unicode="&#xf001;" horiz-adv-x="1208" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM790 1335q0 70 32 100.5t109 30.5q78 0 112 -29.5t34 -101.5q0 -73 -36 -102t-110 -29q-82 0 -111.5 34 t-29.5 97zM804 0v1049h258v-1049h-258z" />
+<glyph unicode="&#xf002;" horiz-adv-x="1208" d="M35 844v205h133v102q0 195 96.5 282t290.5 87q91 0 193 -25l-50 -225q-72 24 -139 24q-76 0 -104.5 -31.5t-28.5 -111.5v-102h213v-205h-213v-844h-258v844h-133zM804 0v1489h258v-1489h-258z" />
+<glyph unicode="&#xf6c3;" horiz-adv-x="584" d="M129 -233q0 73 35 116t131 43q160 0 160 -180q0 -170 -119 -309h-166q47 55 63.5 95t20.5 79q-66 4 -95.5 42t-29.5 114z" />
+<glyph unicode="&#xfeff;" horiz-adv-x="0" />
+<glyph horiz-adv-x="584" d="M129 1346q0 170 119 309h166q-47 -56 -63.5 -95.5t-20.5 -78.5q65 -4 95 -42t30 -114q0 -74 -35 -117t-131 -43q-160 0 -160 181z" />
+<glyph horiz-adv-x="504" d="M53 1024l123 360h275l-213 -360h-185z" />
+<glyph horiz-adv-x="938" d="M70 428q0 230 96 337.5t303 107.5q205 0 302 -107.5t97 -337.5q0 -229 -97 -336.5t-302 -107.5q-207 0 -303 107.5t-96 336.5zM328 428q0 -127 33.5 -185.5t105.5 -58.5t107.5 58.5t35.5 185.5t-35.5 185.5t-107.5 58.5t-105.5 -58.5t-33.5 -185.5z" />
+<glyph horiz-adv-x="938" d="M170 553v152q97 3 150 17t82 43t49 91h200v-856h-252v553h-229z" />
+<glyph horiz-adv-x="938" d="M76 701q133 172 377 172q180 0 262 -71t82 -179q0 -60 -16 -107.5t-52.5 -92.5t-130.5 -115t-166 -111h397v-197h-737v182l108 78q228 160 283.5 217t55.5 113q0 78 -97 78q-101 0 -170 -88z" />
+<glyph horiz-adv-x="938" d="M59 154l199 102q64 -88 164 -88q72 0 98.5 32t26.5 66q0 91 -141 91h-115v176h102q92 0 124 22.5t32 63.5q0 28 -27.5 48.5t-85.5 20.5q-103 0 -168 -78l-182 107q61 74 143 115t224 41q172 0 255 -67t83 -159q0 -71 -38 -116t-124 -74q92 -23 134 -77t42 -126 q0 -137 -102.5 -203.5t-282.5 -66.5q-127 0 -221.5 49t-139.5 121z" />
+<glyph horiz-adv-x="938" d="M45 160v166l492 530h227v-524h115v-172h-115v-160h-232v160h-487zM276 332h256v276z" />
+<glyph horiz-adv-x="938" d="M45 154l207 114q61 -90 170 -90q70 0 114 29t44 88q0 47 -34 74.5t-122 27.5q-85 0 -135 -53h-176l63 512h606v-188h-399l-16 -107q62 17 143 17q155 0 242.5 -78.5t87.5 -208.5q0 -143 -107.5 -225t-308.5 -82q-239 0 -379 170z" />
+<glyph horiz-adv-x="938" d="M90 397q0 229 114 352.5t320 123.5q191 0 316 -80l-121 -154q-84 62 -193 62q-90 0 -132 -49.5t-52 -118.5q84 39 197 39q147 0 232 -71t85 -222q0 -140 -102.5 -217.5t-280.5 -77.5t-280.5 106.5t-102.5 306.5zM336 371q0 -123 40 -171t111 -48q127 0 127 125 q0 63 -35.5 99t-93.5 36q-41 0 -84 -12.5t-65 -28.5z" />
+<glyph horiz-adv-x="938" d="M70 668v188h768v-139l-365 -717h-287l381 668h-497z" />
+<glyph horiz-adv-x="938" d="M84 246q0 61 38 114.5t114 88.5q-58 24 -92.5 71t-34.5 107q0 119 94 182.5t266 63.5q166 0 262 -60.5t96 -183.5q0 -119 -131 -182q88 -39 122 -85t34 -116q0 -125 -100.5 -193.5t-282.5 -68.5q-184 0 -284.5 65.5t-100.5 196.5zM324 246q0 -39 33.5 -64.5t111.5 -25.5 t110.5 27.5t32.5 68.5q0 33 -29.5 62.5t-113.5 54.5q-86 -25 -115.5 -53.5t-29.5 -69.5zM338 625q0 -35 24.5 -58.5t108.5 -44.5q72 19 99.5 42.5t27.5 56.5q-5 80 -133 80q-72 0 -99.5 -24t-27.5 -52z" />
+<glyph horiz-adv-x="938" d="M80 578q0 139 102.5 217t280.5 78t280.5 -106.5t102.5 -307.5q0 -228 -113.5 -351.5t-320.5 -123.5q-191 0 -316 80l121 153q83 -61 193 -61q90 0 132 49t52 119q-80 -39 -197 -39q-147 0 -232 70.5t-85 222.5zM322 580q0 -64 35.5 -99.5t93.5 -35.5q41 0 84 12t65 29 q0 122 -40 170.5t-111 48.5q-127 0 -127 -125z" />
+<glyph horiz-adv-x="938" d="M70 960q0 230 96 337.5t303 107.5q205 0 302 -107.5t97 -337.5q0 -229 -97 -336.5t-302 -107.5q-207 0 -303 107.5t-96 336.5zM328 960q0 -127 33.5 -185.5t105.5 -58.5t107.5 58.5t35.5 185.5t-35.5 185.5t-107.5 58.5t-105.5 -58.5t-33.5 -185.5z" />
+<glyph horiz-adv-x="938" d="M170 1085v152q97 3 150 17t82 43t49 91h200v-856h-252v553h-229z" />
+<glyph horiz-adv-x="938" d="M76 1233q133 172 377 172q180 0 262 -71t82 -179q0 -60 -16 -107.5t-52.5 -92.5t-130.5 -115t-166 -111h397v-197h-737v182l108 78q228 160 283.5 217t55.5 113q0 78 -97 78q-101 0 -170 -88z" />
+<glyph horiz-adv-x="938" d="M59 686l199 102q64 -88 164 -88q72 0 98.5 32t26.5 66q0 91 -141 91h-115v176h102q92 0 124 22.5t32 63.5q0 28 -27.5 48.5t-85.5 20.5q-103 0 -168 -78l-182 107q61 74 143 115t224 41q172 0 255 -67t83 -159q0 -71 -38 -116t-124 -74q92 -23 134 -77t42 -126 q0 -137 -102.5 -203.5t-282.5 -66.5q-127 0 -221.5 49t-139.5 121z" />
+<glyph horiz-adv-x="938" d="M45 692v166l492 530h227v-524h115v-172h-115v-160h-232v160h-487zM276 864h256v276z" />
+<glyph horiz-adv-x="938" d="M45 686l207 114q61 -90 170 -90q70 0 114 29t44 88q0 47 -34 74.5t-122 27.5q-85 0 -135 -53h-176l63 512h606v-188h-399l-16 -107q62 17 143 17q155 0 242.5 -78.5t87.5 -208.5q0 -143 -107.5 -225t-308.5 -82q-239 0 -379 170z" />
+<glyph horiz-adv-x="938" d="M90 929q0 229 114 352.5t320 123.5q191 0 316 -80l-121 -154q-84 62 -193 62q-90 0 -132 -49.5t-52 -118.5q84 39 197 39q147 0 232 -71t85 -222q0 -140 -102.5 -217.5t-280.5 -77.5t-280.5 106.5t-102.5 306.5zM336 903q0 -123 40 -171t111 -48q127 0 127 125 q0 63 -35.5 99t-93.5 36q-41 0 -84 -12.5t-65 -28.5z" />
+<glyph horiz-adv-x="938" d="M70 1200v188h768v-139l-365 -717h-287l381 668h-497z" />
+<glyph horiz-adv-x="938" d="M84 778q0 61 38 114.5t114 88.5q-58 24 -92.5 71t-34.5 107q0 119 94 182.5t266 63.5q166 0 262 -60.5t96 -183.5q0 -119 -131 -182q88 -39 122 -85t34 -116q0 -125 -100.5 -193.5t-282.5 -68.5q-184 0 -284.5 65.5t-100.5 196.5zM324 778q0 -39 33.5 -64.5t111.5 -25.5 t110.5 27.5t32.5 68.5q0 33 -29.5 62.5t-113.5 54.5q-86 -25 -115.5 -53.5t-29.5 -69.5zM338 1157q0 -35 24.5 -58.5t108.5 -44.5q72 19 99.5 42.5t27.5 56.5q-5 80 -133 80q-72 0 -99.5 -24t-27.5 -52z" />
+<glyph horiz-adv-x="938" d="M80 1110q0 139 102.5 217t280.5 78t280.5 -106.5t102.5 -307.5q0 -228 -113.5 -351.5t-320.5 -123.5q-191 0 -316 80l121 153q83 -61 193 -61q90 0 132 49t52 119q-80 -39 -197 -39q-147 0 -232 70.5t-85 222.5zM322 1112q0 -64 35.5 -99.5t93.5 -35.5q41 0 84 12t65 29 q0 122 -40 170.5t-111 48.5q-127 0 -127 -125z" />
+<glyph d="M195 1905h315l188 -361h-204z" />
+<glyph d="M348 1544l189 361h315l-299 -361h-205z" />
+<glyph d="M164 1544l235 361h244l236 -361h-211l-146 174l-149 -174h-209z" />
+<glyph d="M164 1905h211l145 -174l150 174h209l-236 -361h-244z" />
+<glyph d="M514 1128l55 361h271l-166 -361h-160z" />
+<glyph d="M113 1567q5 155 73 236t189 81q61 0 104 -22.5t77 -48t62.5 -48t61.5 -22.5q34 0 51 33t17 94h182q-10 -165 -75.5 -243.5t-188.5 -78.5q-66 0 -109 22.5t-75.5 50.5t-59.5 50.5t-60 22.5q-67 0 -67 -127h-182z" />
+<glyph d="M152 1671q0 70 31.5 100.5t109.5 30.5t111.5 -29.5t33.5 -101.5q0 -74 -35.5 -102.5t-109.5 -28.5q-82 0 -111.5 34t-29.5 97zM596 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph d="M186 1591v185h672v-185h-672z" />
+<glyph d="M162 1845h188q15 -47 58 -75.5t116 -28.5q68 0 112 28.5t58 75.5h189q0 -88 -44.5 -161.5t-127 -117.5t-189.5 -44q-106 0 -188.5 43.5t-127 117.5t-44.5 162z" />
+<glyph d="M307 1704q0 100 52.5 156.5t160.5 56.5q113 0 164 -57.5t51 -155.5q0 -213 -215 -213q-110 0 -161.5 57.5t-51.5 155.5zM434 1704q0 -90 86 -90q88 0 88 90t-88 90q-86 0 -86 -90z" />
+<glyph d="M145 1544l189 361h315l-299 -361h-205zM561 1544l189 361h315l-299 -361h-205z" />
+<glyph d="M379 1671q0 70 31.5 100.5t109.5 30.5t112 -29.5t34 -101.5q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 34t-29.5 97z" />
+<glyph d="M164 1167l235 299h244l236 -299h-211l-146 144l-149 -144h-209zM752 1380l153 291h316l-265 -291h-204z" />
+<glyph d="M-176 1671h315l154 -291h-205zM164 1167l235 299h244l236 -299h-211l-146 133l-149 -133h-209z" />
+<glyph d="M164 1167l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM659 1665q67 53 197 53q105 0 161 -46t56 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v138h43q74 0 74 59q0 51 -76 51q-56 0 -96 -24z" />
+<glyph d="M113 1513q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -34.5t65.5 -15q37 0 50 23.5t18 62.5h182q-10 -145 -75.5 -213t-188.5 -68q-54 0 -96 16.5t-77.5 36t-66.5 35.5t-64 16q-38 0 -50.5 -23.5t-16.5 -62.5h-182zM164 1167l235 279h244l236 -279h-211 l-146 123l-149 -123h-209z" />
+<glyph d="M162 1520h188q15 -62 58 -86.5t116 -24.5q68 0 112 24.5t58 86.5h189q0 -88 -43.5 -159.5t-126 -113t-191.5 -41.5q-108 0 -190.5 41.5t-126 114t-43.5 158.5zM412 1503l104 250h315l-225 -250h-194z" />
+<glyph d="M162 1520h188q15 -62 58 -86.5t116 -24.5q68 0 112 24.5t58 86.5h189q0 -88 -43.5 -159.5t-126 -113t-191.5 -41.5q-108 0 -190.5 41.5t-126 114t-43.5 158.5zM213 1753h315l105 -250h-195z" />
+<glyph d="M162 1520h188q15 -62 58 -86.5t116 -24.5q68 0 112 24.5t58 86.5h189q0 -88 -43.5 -159.5t-126 -113t-191.5 -41.5q-108 0 -190.5 41.5t-126 114t-43.5 158.5zM340 1837q67 53 197 53q104 0 160.5 -46t56.5 -120q0 -72 -49 -118.5t-127 -51.5v-43h-125v138h43q73 0 73 59 q0 51 -75 51q-55 0 -97 -24z" />
+<glyph d="M113 1587q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -35t65.5 -15.5q37 0 50 23.5t18 62.5h182q-10 -144 -76 -212t-188 -68q-54 0 -96 16.5t-77.5 35.5t-66.5 35.5t-64 16.5q-38 0 -50.5 -23.5t-16.5 -62.5h-182zM162 1509h188q15 -61 58 -85.5t116 -24.5 q68 0 112 24.5t58 85.5h189q0 -133 -98 -218t-263 -85q-110 0 -190.5 38.5t-125 109t-44.5 155.5z" />
+<glyph d="M152 1305q0 69 31.5 100t109.5 31t111.5 -30t33.5 -101q0 -74 -35.5 -102.5t-109.5 -28.5q-82 0 -111.5 33.5t-29.5 97.5zM186 1499v184h672v-184h-672zM596 1305q0 69 31.5 100t109.5 31t112 -30t34 -101q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 33.5t-29.5 97.5z " />
+<glyph d="M152 1305q0 69 31.5 100t109.5 31t111.5 -30t33.5 -101q0 -74 -35.5 -102.5t-109.5 -28.5q-82 0 -111.5 33.5t-29.5 97.5zM403 1462l123 291h316l-244 -291h-195zM596 1305q0 69 31.5 100t109.5 31t112 -30t34 -101q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 33.5 t-29.5 97.5z" />
+<glyph d="M152 1303q0 69 31.5 99t109.5 30t111.5 -29t33.5 -100q0 -74 -35.5 -101.5t-109.5 -27.5q-82 0 -111.5 32.5t-29.5 96.5zM164 1753h211l145 -139l150 139h209l-236 -291h-244zM596 1303q0 69 31.5 99t109.5 30t112 -29t34 -100q0 -74 -36 -101.5t-110 -27.5 q-82 0 -111.5 32.5t-29.5 96.5z" />
+<glyph d="M152 1305q0 69 31.5 100t109.5 31t111.5 -30t33.5 -101q0 -74 -35.5 -102.5t-109.5 -28.5q-82 0 -111.5 33.5t-29.5 97.5zM188 1753h316l123 -291h-195zM596 1305q0 69 31.5 100t109.5 31t112 -30t34 -101q0 -74 -36 -102.5t-110 -28.5q-82 0 -111.5 33.5t-29.5 97.5z " />
+<glyph d="M164 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM752 1716l153 291h316l-265 -291h-204z" />
+<glyph d="M-176 2007h315l154 -291h-205zM164 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209z" />
+<glyph d="M164 1503l235 299h244l236 -299h-211l-146 133l-149 -133h-209zM659 2001q70 53 197 53q105 0 161 -46t56 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph d="M113 1849q5 136 74 206.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -35t65.5 -15.5q37 0 50 24t18 62h182q-10 -144 -76 -212t-188 -68q-54 0 -96 16.5t-77.5 36t-66.5 35.5t-64 16q-38 0 -50.5 -23.5t-16.5 -62.5h-182zM164 1503l235 279h244l236 -279h-211l-146 123 l-149 -123h-209z" />
+<glyph d="M162 1835h188q15 -61 58 -86t116 -25q145 0 170 111h189q0 -87 -43.5 -158.5t-126.5 -113t-191 -41.5t-190.5 41.5t-126 114t-43.5 157.5zM412 1819l104 249h315l-225 -249h-194z" />
+<glyph d="M162 1835h188q15 -61 58 -86t116 -25q145 0 170 111h189q0 -87 -43.5 -158.5t-126.5 -113t-191 -41.5t-190.5 41.5t-126 114t-43.5 157.5zM213 2068h315l105 -249h-195z" />
+<glyph d="M162 1835h188q15 -61 58 -86t116 -25q145 0 170 111h189q0 -87 -43.5 -158.5t-126.5 -113t-191 -41.5t-190.5 41.5t-126 114t-43.5 157.5zM340 2152q68 54 197 54q104 0 160.5 -46t56.5 -120q0 -71 -47.5 -118t-128.5 -52v-43h-125v137h43q73 0 73 59q0 52 -75 52 q-53 0 -97 -25z" />
+<glyph d="M113 1903q5 135 74 205.5t188 70.5q49 0 91 -15.5t79 -35t69.5 -34.5t65.5 -15q37 0 50 23.5t18 62.5h182q-10 -145 -75.5 -213t-188.5 -68q-54 0 -96 16.5t-77.5 36t-66.5 36t-64 16.5q-38 0 -50.5 -23.5t-16.5 -62.5h-182zM162 1825h188q15 -62 58 -86.5t116 -24.5 q68 0 112 24.5t58 86.5h189q0 -133 -98 -218t-263 -85q-166 0 -263 85.5t-97 217.5z" />
+<glyph d="M152 1640q0 70 31.5 101t109.5 31t111.5 -30t33.5 -102q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM186 1835v184h672v-184h-672zM596 1640q0 70 31.5 101t109.5 31t112 -30t34 -102q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph d="M152 1640q0 70 31.5 101t109.5 31t111.5 -30t33.5 -102q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM403 1798l123 291h316l-244 -291h-195zM596 1640q0 70 31.5 101t109.5 31t112 -30t34 -102q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph d="M152 1638q0 70 31.5 99.5t109.5 29.5t111.5 -28.5t33.5 -100.5q0 -73 -35.5 -101t-109.5 -28q-82 0 -111.5 33t-29.5 96zM164 2089h211l145 -139l150 139h209l-236 -291h-244zM596 1638q0 70 31.5 99.5t109.5 29.5t112 -28.5t34 -100.5q0 -73 -36 -101t-110 -28 q-82 0 -111.5 33t-29.5 96z" />
+<glyph d="M152 1640q0 70 31.5 101t109.5 31t111.5 -30t33.5 -102q0 -73 -35.5 -102t-109.5 -29q-82 0 -111.5 34t-29.5 97zM188 2089h316l123 -291h-195zM596 1640q0 70 31.5 101t109.5 31t112 -30t34 -102q0 -73 -36 -102t-110 -29q-82 0 -111.5 34t-29.5 97z" />
+<glyph d="M315 1487q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph d="M315 1823q70 53 197 53q104 0 160.5 -46t56.5 -120q0 -69 -47 -116.5t-127 -53.5v-43h-127v137h43q74 0 74 60q0 51 -76 51q-58 0 -96 -25z" />
+<glyph d="M164 1466h221q0 -149 139 -149q58 0 99 32.5t41 116.5h221q0 -77 -45.5 -140.5t-128 -100.5t-189.5 -37q-103 0 -185 36t-127.5 101t-45.5 141z" />
+<glyph d="M162 1800h221q0 -149 141 -149q56 0 97 32.5t41 116.5h221q0 -76 -45 -139.5t-126.5 -101t-189.5 -37.5q-106 0 -188 37t-127 101t-45 140z" />
+<hkern u1="&#x28;" u2="&#x458;" k="-164" />
+<hkern u1="&#x28;" u2="&#x3ca;" k="-102" />
+<hkern u1="&#x28;" u2="&#x390;" k="-184" />
<hkern u1="&#x28;" u2="j" k="-164" />
+<hkern u1="&#x2a;" u2="&#x2206;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1eb6;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1eb4;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1eb2;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1eb0;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1eae;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1eac;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1eaa;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1ea8;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1ea6;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1ea4;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1ea2;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1ea0;" k="123" />
+<hkern u1="&#x2a;" u2="&#x459;" k="123" />
+<hkern u1="&#x2a;" u2="&#x457;" k="-123" />
+<hkern u1="&#x2a;" u2="&#x442;" k="-82" />
+<hkern u1="&#x2a;" u2="&#x43b;" k="123" />
+<hkern u1="&#x2a;" u2="&#x422;" k="-92" />
+<hkern u1="&#x2a;" u2="&#x41b;" k="184" />
+<hkern u1="&#x2a;" u2="&#x414;" k="61" />
+<hkern u1="&#x2a;" u2="&#x410;" k="123" />
+<hkern u1="&#x2a;" u2="&#x409;" k="184" />
+<hkern u1="&#x2a;" u2="&#x408;" k="174" />
+<hkern u1="&#x2a;" u2="&#x3ca;" k="-123" />
+<hkern u1="&#x2a;" u2="&#x3c7;" k="-41" />
+<hkern u1="&#x2a;" u2="&#x3be;" k="-41" />
+<hkern u1="&#x2a;" u2="&#x3a4;" k="-92" />
+<hkern u1="&#x2a;" u2="&#x39b;" k="123" />
+<hkern u1="&#x2a;" u2="&#x394;" k="123" />
+<hkern u1="&#x2a;" u2="&#x391;" k="123" />
+<hkern u1="&#x2a;" u2="&#x38f;" k="-369" />
+<hkern u1="&#x2a;" u2="&#x38e;" k="-369" />
+<hkern u1="&#x2a;" u2="&#x38c;" k="-369" />
+<hkern u1="&#x2a;" u2="&#x38a;" k="-369" />
+<hkern u1="&#x2a;" u2="&#x389;" k="-369" />
+<hkern u1="&#x2a;" u2="&#x388;" k="-369" />
+<hkern u1="&#x2a;" u2="&#x386;" k="-164" />
+<hkern u1="&#x2a;" u2="&#x21a;" k="-92" />
+<hkern u1="&#x2a;" u2="&#x1fa;" k="123" />
+<hkern u1="&#x2a;" u2="&#x1cd;" k="123" />
+<hkern u1="&#x2a;" u2="&#x166;" k="-92" />
+<hkern u1="&#x2a;" u2="&#x164;" k="-92" />
+<hkern u1="&#x2a;" u2="&#x162;" k="-92" />
+<hkern u1="&#x2a;" u2="&#x134;" k="174" />
+<hkern u1="&#x2a;" u2="&#x104;" k="123" />
+<hkern u1="&#x2a;" u2="&#x102;" k="123" />
+<hkern u1="&#x2a;" u2="&#x100;" k="123" />
<hkern u1="&#x2a;" u2="&#xc5;" k="123" />
<hkern u1="&#x2a;" u2="&#xc4;" k="123" />
<hkern u1="&#x2a;" u2="&#xc3;" k="123" />
@@ -252,15 +961,55 @@
<hkern u1="&#x2a;" u2="T" k="-92" />
<hkern u1="&#x2a;" u2="J" k="174" />
<hkern u1="&#x2a;" u2="A" k="123" />
+<hkern u1="&#x2c;" u2="&#x42a;" k="143" />
+<hkern u1="&#x2e;" u2="&#x42a;" k="143" />
+<hkern u1="&#x3a;" u2="&#x42a;" k="143" />
+<hkern u1="&#x3b;" u2="&#x42a;" k="143" />
<hkern u1="A" u2="&#x3f;" k="102" />
<hkern u1="A" u2="&#x2a;" k="123" />
+<hkern u1="F" u2="&#x135;" k="-41" />
+<hkern u1="F" u2="&#x12b;" k="-41" />
+<hkern u1="F" u2="&#x129;" k="-123" />
<hkern u1="F" u2="&#xef;" k="-61" />
<hkern u1="F" u2="&#xee;" k="-20" />
+<hkern u1="K" u2="&#x135;" k="20" />
+<hkern u1="K" u2="&#x12d;" k="10" />
+<hkern u1="K" u2="&#x12b;" k="-10" />
+<hkern u1="K" u2="&#x129;" k="-61" />
<hkern u1="K" u2="&#xef;" k="-10" />
<hkern u1="K" u2="&#xee;" k="41" />
<hkern u1="L" u2="&#xd8;" k="10" />
<hkern u1="L" u2="&#x3f;" k="102" />
<hkern u1="L" u2="&#x2a;" k="205" />
+<hkern u1="T" u2="&#x1ef9;" k="41" />
+<hkern u1="T" u2="&#x1ee1;" k="123" />
+<hkern u1="T" u2="&#x1ed7;" k="154" />
+<hkern u1="T" u2="&#x1ed3;" k="102" />
+<hkern u1="T" u2="&#x1ec5;" k="174" />
+<hkern u1="T" u2="&#x1ec1;" k="123" />
+<hkern u1="T" u2="&#x1ebd;" k="123" />
+<hkern u1="T" u2="&#x1eb7;" k="143" />
+<hkern u1="T" u2="&#x1eb5;" k="123" />
+<hkern u1="T" u2="&#x1eb3;" k="143" />
+<hkern u1="T" u2="&#x1eb1;" k="143" />
+<hkern u1="T" u2="&#x1eaf;" k="123" />
+<hkern u1="T" u2="&#x1ead;" k="102" />
+<hkern u1="T" u2="&#x1eab;" k="123" />
+<hkern u1="T" u2="&#x1ea9;" k="143" />
+<hkern u1="T" u2="&#x1ea7;" k="61" />
+<hkern u1="T" u2="&#x1ea5;" k="133" />
+<hkern u1="T" u2="&#x1e9e;" k="61" />
+<hkern u1="T" u2="&#x1d6;" k="143" />
+<hkern u1="T" u2="&#x1d0;" k="-20" />
+<hkern u1="T" u2="&#x161;" k="242" />
+<hkern u1="T" u2="&#x15d;" k="221" />
+<hkern u1="T" u2="&#x159;" k="184" />
+<hkern u1="T" u2="&#x135;" k="-61" />
+<hkern u1="T" u2="&#x12d;" k="-82" />
+<hkern u1="T" u2="&#x12b;" k="-82" />
+<hkern u1="T" u2="&#x129;" k="-123" />
+<hkern u1="T" u2="&#x103;" k="205" />
+<hkern u1="T" u2="&#x101;" k="164" />
<hkern u1="T" u2="&#xef;" k="-123" />
<hkern u1="T" u2="&#xee;" k="-61" />
<hkern u1="T" u2="&#xe4;" k="123" />
@@ -268,31 +1017,108 @@
<hkern u1="T" u2="&#xe2;" k="164" />
<hkern u1="T" u2="&#x3f;" k="-82" />
<hkern u1="T" u2="&#x2a;" k="-92" />
+<hkern u1="V" u2="&#x1e9e;" k="20" />
+<hkern u1="V" u2="&#x135;" k="-10" />
+<hkern u1="V" u2="&#x12d;" k="-31" />
+<hkern u1="V" u2="&#x12b;" k="-51" />
+<hkern u1="V" u2="&#x129;" k="-133" />
+<hkern u1="V" u2="&#x127;" k="10" />
<hkern u1="V" u2="&#xef;" k="-72" />
<hkern u1="V" u2="&#xee;" k="-10" />
+<hkern u1="W" u2="&#x1e9e;" k="20" />
+<hkern u1="W" u2="&#x135;" k="-10" />
+<hkern u1="W" u2="&#x12d;" k="-31" />
+<hkern u1="W" u2="&#x12b;" k="-51" />
+<hkern u1="W" u2="&#x129;" k="-133" />
+<hkern u1="W" u2="&#x127;" k="10" />
<hkern u1="W" u2="&#xef;" k="-72" />
<hkern u1="W" u2="&#xee;" k="-10" />
+<hkern u1="X" u2="&#x1e9e;" k="20" />
+<hkern u1="X" u2="&#x1d0;" k="-41" />
+<hkern u1="X" u2="&#x12d;" k="-61" />
+<hkern u1="X" u2="&#x12b;" k="-61" />
+<hkern u1="X" u2="&#x129;" k="-82" />
<hkern u1="X" u2="&#xef;" k="-82" />
<hkern u1="X" u2="&#xee;" k="-41" />
+<hkern u1="Y" u2="&#x1ed3;" k="102" />
+<hkern u1="Y" u2="&#x1ebd;" k="102" />
+<hkern u1="Y" u2="&#x1ea7;" k="82" />
+<hkern u1="Y" u2="&#x1e9e;" k="82" />
+<hkern u1="Y" u2="&#x135;" k="41" />
+<hkern u1="Y" u2="&#x12d;" k="-41" />
+<hkern u1="Y" u2="&#x12b;" k="-82" />
+<hkern u1="Y" u2="&#x129;" k="-123" />
<hkern u1="Y" u2="&#xef;" k="-102" />
<hkern u1="Y" u2="&#xee;" k="-20" />
+<hkern u1="[" u2="&#x458;" k="-164" />
+<hkern u1="[" u2="&#x3ca;" k="-102" />
+<hkern u1="[" u2="&#x390;" k="-246" />
<hkern u1="[" u2="j" k="-164" />
+<hkern u1="a" u2="&#x167;" k="20" />
+<hkern u1="f" u2="&#x1ef9;" k="-20" />
+<hkern u1="f" u2="&#x1ed3;" k="-61" />
+<hkern u1="f" u2="&#x1ec9;" k="-51" />
+<hkern u1="f" u2="&#x1ec1;" k="-51" />
+<hkern u1="f" u2="&#x1eb5;" k="-20" />
+<hkern u1="f" u2="&#x1eb3;" k="-20" />
+<hkern u1="f" u2="&#x1eb1;" k="-20" />
+<hkern u1="f" u2="&#x1eaf;" k="-20" />
+<hkern u1="f" u2="&#x1eab;" k="-20" />
+<hkern u1="f" u2="&#x1ea7;" k="-113" />
+<hkern u1="f" u2="&#x1d0;" k="-184" />
+<hkern u1="f" u2="&#x135;" k="-102" />
+<hkern u1="f" u2="&#x12d;" k="-205" />
+<hkern u1="f" u2="&#x12b;" k="-184" />
+<hkern u1="f" u2="&#x129;" k="-246" />
+<hkern u1="f" u2="&#x127;" k="-102" />
<hkern u1="f" u2="&#xef;" k="-225" />
<hkern u1="f" u2="&#xee;" k="-102" />
<hkern u1="f" u2="&#xec;" k="-82" />
<hkern u1="f" u2="&#x3f;" k="-123" />
<hkern u1="f" u2="&#x2a;" k="-143" />
<hkern u1="f" u2="&#x21;" k="-61" />
+<hkern u1="j" u2="&#x1ef9;" k="-41" />
+<hkern u1="j" u2="&#x1ef7;" k="-41" />
+<hkern u1="j" u2="&#x1ef5;" k="-41" />
+<hkern u1="j" u2="&#x1ef3;" k="-41" />
+<hkern u1="j" u2="&#x177;" k="-41" />
<hkern u1="j" u2="&#xff;" k="-41" />
<hkern u1="j" u2="&#xfd;" k="-41" />
<hkern u1="j" u2="y" k="-41" />
+<hkern u1="&#x7b;" u2="&#x458;" k="-164" />
+<hkern u1="&#x7b;" u2="&#x3ca;" k="-102" />
+<hkern u1="&#x7b;" u2="&#x390;" k="-184" />
<hkern u1="&#x7b;" u2="j" k="-164" />
+<hkern u1="&#xa1;" u2="&#x1ef8;" k="102" />
+<hkern u1="&#xa1;" u2="&#x1ef6;" k="102" />
+<hkern u1="&#xa1;" u2="&#x1ef4;" k="102" />
+<hkern u1="&#xa1;" u2="&#x1ef2;" k="102" />
+<hkern u1="&#xa1;" u2="&#x1e84;" k="61" />
+<hkern u1="&#xa1;" u2="&#x1e82;" k="61" />
+<hkern u1="&#xa1;" u2="&#x1e80;" k="61" />
<hkern u1="&#xa1;" u2="&#x178;" k="102" />
+<hkern u1="&#xa1;" u2="&#x176;" k="102" />
+<hkern u1="&#xa1;" u2="&#x174;" k="61" />
<hkern u1="&#xa1;" u2="&#xdd;" k="102" />
<hkern u1="&#xa1;" u2="Y" k="102" />
<hkern u1="&#xa1;" u2="W" k="61" />
<hkern u1="&#xa1;" u2="V" k="61" />
+<hkern u1="&#xab;" u2="&#x386;" k="-82" />
+<hkern u1="&#xb5;" u2="&#x3c7;" k="31" />
+<hkern u1="&#xbf;" u2="&#x1ef8;" k="184" />
+<hkern u1="&#xbf;" u2="&#x1ef6;" k="184" />
+<hkern u1="&#xbf;" u2="&#x1ef4;" k="184" />
+<hkern u1="&#xbf;" u2="&#x1ef2;" k="184" />
+<hkern u1="&#xbf;" u2="&#x1e84;" k="123" />
+<hkern u1="&#xbf;" u2="&#x1e82;" k="123" />
+<hkern u1="&#xbf;" u2="&#x1e80;" k="123" />
+<hkern u1="&#xbf;" u2="&#x21a;" k="184" />
<hkern u1="&#xbf;" u2="&#x178;" k="184" />
+<hkern u1="&#xbf;" u2="&#x176;" k="184" />
+<hkern u1="&#xbf;" u2="&#x174;" k="123" />
+<hkern u1="&#xbf;" u2="&#x166;" k="184" />
+<hkern u1="&#xbf;" u2="&#x164;" k="184" />
+<hkern u1="&#xbf;" u2="&#x162;" k="184" />
<hkern u1="&#xbf;" u2="&#xdd;" k="184" />
<hkern u1="&#xbf;" u2="Y" k="184" />
<hkern u1="&#xbf;" u2="W" k="123" />
@@ -310,331 +1136,1611 @@
<hkern u1="&#xc4;" u2="&#x2a;" k="123" />
<hkern u1="&#xc5;" u2="&#x3f;" k="102" />
<hkern u1="&#xc5;" u2="&#x2a;" k="123" />
+<hkern u1="&#xdd;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#xdd;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#xdd;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#xdd;" u2="&#x1e9e;" k="82" />
+<hkern u1="&#xdd;" u2="&#x135;" k="41" />
+<hkern u1="&#xdd;" u2="&#x12d;" k="-41" />
+<hkern u1="&#xdd;" u2="&#x12b;" k="-82" />
+<hkern u1="&#xdd;" u2="&#x129;" k="-123" />
<hkern u1="&#xdd;" u2="&#xef;" k="-102" />
<hkern u1="&#xdd;" u2="&#xee;" k="-20" />
+<hkern u1="&#xde;" u2="&#x1e84;" k="31" />
+<hkern u1="&#xde;" u2="&#x1e82;" k="31" />
+<hkern u1="&#xde;" u2="&#x1e80;" k="31" />
+<hkern u1="&#xde;" u2="&#x21a;" k="82" />
+<hkern u1="&#xde;" u2="&#x174;" k="31" />
+<hkern u1="&#xde;" u2="&#x166;" k="82" />
+<hkern u1="&#xde;" u2="&#x164;" k="82" />
+<hkern u1="&#xde;" u2="&#x162;" k="82" />
<hkern u1="&#xde;" u2="X" k="123" />
<hkern u1="&#xde;" u2="W" k="31" />
<hkern u1="&#xde;" u2="V" k="31" />
<hkern u1="&#xde;" u2="T" k="82" />
+<hkern u1="&#xe0;" u2="&#x167;" k="20" />
+<hkern u1="&#xe1;" u2="&#x167;" k="20" />
+<hkern u1="&#xe2;" u2="&#x167;" k="20" />
+<hkern u1="&#xe3;" u2="&#x167;" k="20" />
+<hkern u1="&#xe4;" u2="&#x167;" k="20" />
+<hkern u1="&#xe5;" u2="&#x167;" k="20" />
+<hkern u1="&#x100;" u2="&#x3f;" k="102" />
+<hkern u1="&#x100;" u2="&#x2a;" k="123" />
+<hkern u1="&#x101;" u2="&#x167;" k="20" />
+<hkern u1="&#x102;" u2="&#x3f;" k="102" />
+<hkern u1="&#x102;" u2="&#x2a;" k="123" />
+<hkern u1="&#x103;" u2="&#x167;" k="20" />
+<hkern u1="&#x104;" u2="&#x3f;" k="102" />
+<hkern u1="&#x104;" u2="&#x2a;" k="123" />
+<hkern u1="&#x105;" u2="&#x167;" k="20" />
+<hkern u1="&#x10f;" u2="&#xe4;" k="-20" />
+<hkern u1="&#x10f;" u2="&#x3f;" k="-102" />
+<hkern u1="&#x136;" u2="&#x135;" k="20" />
+<hkern u1="&#x136;" u2="&#x12d;" k="10" />
+<hkern u1="&#x136;" u2="&#x12b;" k="-10" />
+<hkern u1="&#x136;" u2="&#x129;" k="-61" />
+<hkern u1="&#x136;" u2="&#xef;" k="-10" />
+<hkern u1="&#x136;" u2="&#xee;" k="41" />
+<hkern u1="&#x139;" u2="&#xd8;" k="10" />
+<hkern u1="&#x139;" u2="&#x3f;" k="102" />
+<hkern u1="&#x139;" u2="&#x2a;" k="205" />
+<hkern u1="&#x13b;" u2="&#xd8;" k="10" />
+<hkern u1="&#x13b;" u2="&#x3f;" k="102" />
+<hkern u1="&#x13b;" u2="&#x2a;" k="205" />
+<hkern u1="&#x13d;" u2="&#xd8;" k="10" />
+<hkern u1="&#x13d;" u2="&#x3f;" k="102" />
+<hkern u1="&#x13d;" u2="&#x2a;" k="205" />
+<hkern u1="&#x13e;" u2="&#xe4;" k="-20" />
+<hkern u1="&#x13e;" u2="&#x3f;" k="-102" />
+<hkern u1="&#x141;" u2="&#xd8;" k="10" />
+<hkern u1="&#x141;" u2="&#x3f;" k="102" />
+<hkern u1="&#x141;" u2="&#x2a;" k="205" />
+<hkern u1="&#x142;" u2="&#x21b;" k="-31" />
+<hkern u1="&#x142;" u2="&#x167;" k="-31" />
+<hkern u1="&#x142;" u2="&#x165;" k="-31" />
+<hkern u1="&#x142;" u2="&#x163;" k="-31" />
+<hkern u1="&#x142;" u2="t" k="-31" />
+<hkern u1="&#x162;" u2="&#x1ef9;" k="41" />
+<hkern u1="&#x162;" u2="&#x1ee1;" k="123" />
+<hkern u1="&#x162;" u2="&#x1ed7;" k="154" />
+<hkern u1="&#x162;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x162;" u2="&#x1ec5;" k="174" />
+<hkern u1="&#x162;" u2="&#x1ec1;" k="123" />
+<hkern u1="&#x162;" u2="&#x1ebd;" k="123" />
+<hkern u1="&#x162;" u2="&#x1eb7;" k="143" />
+<hkern u1="&#x162;" u2="&#x1eb5;" k="123" />
+<hkern u1="&#x162;" u2="&#x1eb3;" k="143" />
+<hkern u1="&#x162;" u2="&#x1eb1;" k="143" />
+<hkern u1="&#x162;" u2="&#x1eaf;" k="123" />
+<hkern u1="&#x162;" u2="&#x1ead;" k="102" />
+<hkern u1="&#x162;" u2="&#x1eab;" k="123" />
+<hkern u1="&#x162;" u2="&#x1ea9;" k="143" />
+<hkern u1="&#x162;" u2="&#x1ea7;" k="61" />
+<hkern u1="&#x162;" u2="&#x1ea5;" k="133" />
+<hkern u1="&#x162;" u2="&#x1e9e;" k="61" />
+<hkern u1="&#x162;" u2="&#x1d6;" k="143" />
+<hkern u1="&#x162;" u2="&#x1d0;" k="-20" />
+<hkern u1="&#x162;" u2="&#x161;" k="242" />
+<hkern u1="&#x162;" u2="&#x15d;" k="221" />
+<hkern u1="&#x162;" u2="&#x159;" k="184" />
+<hkern u1="&#x162;" u2="&#x135;" k="-61" />
+<hkern u1="&#x162;" u2="&#x12d;" k="-82" />
+<hkern u1="&#x162;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x162;" u2="&#x129;" k="-123" />
+<hkern u1="&#x162;" u2="&#x103;" k="205" />
+<hkern u1="&#x162;" u2="&#x101;" k="164" />
+<hkern u1="&#x162;" u2="&#xef;" k="-123" />
+<hkern u1="&#x162;" u2="&#xee;" k="-61" />
+<hkern u1="&#x162;" u2="&#xe4;" k="123" />
+<hkern u1="&#x162;" u2="&#xe3;" k="123" />
+<hkern u1="&#x162;" u2="&#xe2;" k="164" />
+<hkern u1="&#x162;" u2="&#x3f;" k="-82" />
+<hkern u1="&#x162;" u2="&#x2a;" k="-92" />
+<hkern u1="&#x164;" u2="&#x1ef9;" k="41" />
+<hkern u1="&#x164;" u2="&#x1ee1;" k="123" />
+<hkern u1="&#x164;" u2="&#x1ed7;" k="154" />
+<hkern u1="&#x164;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x164;" u2="&#x1ec5;" k="174" />
+<hkern u1="&#x164;" u2="&#x1ec1;" k="123" />
+<hkern u1="&#x164;" u2="&#x1ebd;" k="123" />
+<hkern u1="&#x164;" u2="&#x1eb7;" k="143" />
+<hkern u1="&#x164;" u2="&#x1eb5;" k="123" />
+<hkern u1="&#x164;" u2="&#x1eb3;" k="143" />
+<hkern u1="&#x164;" u2="&#x1eb1;" k="143" />
+<hkern u1="&#x164;" u2="&#x1eaf;" k="123" />
+<hkern u1="&#x164;" u2="&#x1ead;" k="102" />
+<hkern u1="&#x164;" u2="&#x1eab;" k="123" />
+<hkern u1="&#x164;" u2="&#x1ea9;" k="143" />
+<hkern u1="&#x164;" u2="&#x1ea7;" k="61" />
+<hkern u1="&#x164;" u2="&#x1ea5;" k="133" />
+<hkern u1="&#x164;" u2="&#x1e9e;" k="61" />
+<hkern u1="&#x164;" u2="&#x1d6;" k="143" />
+<hkern u1="&#x164;" u2="&#x1d0;" k="-20" />
+<hkern u1="&#x164;" u2="&#x161;" k="242" />
+<hkern u1="&#x164;" u2="&#x15d;" k="221" />
+<hkern u1="&#x164;" u2="&#x159;" k="184" />
+<hkern u1="&#x164;" u2="&#x135;" k="-61" />
+<hkern u1="&#x164;" u2="&#x12d;" k="-82" />
+<hkern u1="&#x164;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x164;" u2="&#x129;" k="-123" />
+<hkern u1="&#x164;" u2="&#x103;" k="205" />
+<hkern u1="&#x164;" u2="&#x101;" k="164" />
+<hkern u1="&#x164;" u2="&#xef;" k="-123" />
+<hkern u1="&#x164;" u2="&#xee;" k="-61" />
+<hkern u1="&#x164;" u2="&#xe4;" k="123" />
+<hkern u1="&#x164;" u2="&#xe3;" k="123" />
+<hkern u1="&#x164;" u2="&#xe2;" k="164" />
+<hkern u1="&#x164;" u2="&#x3f;" k="-82" />
+<hkern u1="&#x164;" u2="&#x2a;" k="-92" />
+<hkern u1="&#x166;" u2="&#x1ef9;" k="41" />
+<hkern u1="&#x166;" u2="&#x1ee1;" k="123" />
+<hkern u1="&#x166;" u2="&#x1ed7;" k="154" />
+<hkern u1="&#x166;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x166;" u2="&#x1ec5;" k="174" />
+<hkern u1="&#x166;" u2="&#x1ec1;" k="123" />
+<hkern u1="&#x166;" u2="&#x1ebd;" k="123" />
+<hkern u1="&#x166;" u2="&#x1eb7;" k="143" />
+<hkern u1="&#x166;" u2="&#x1eb5;" k="123" />
+<hkern u1="&#x166;" u2="&#x1eb3;" k="143" />
+<hkern u1="&#x166;" u2="&#x1eb1;" k="143" />
+<hkern u1="&#x166;" u2="&#x1eaf;" k="123" />
+<hkern u1="&#x166;" u2="&#x1ead;" k="102" />
+<hkern u1="&#x166;" u2="&#x1eab;" k="123" />
+<hkern u1="&#x166;" u2="&#x1ea9;" k="143" />
+<hkern u1="&#x166;" u2="&#x1ea7;" k="61" />
+<hkern u1="&#x166;" u2="&#x1ea5;" k="133" />
+<hkern u1="&#x166;" u2="&#x1e9e;" k="61" />
+<hkern u1="&#x166;" u2="&#x1d6;" k="143" />
+<hkern u1="&#x166;" u2="&#x1d0;" k="-20" />
+<hkern u1="&#x166;" u2="&#x161;" k="242" />
+<hkern u1="&#x166;" u2="&#x15d;" k="221" />
+<hkern u1="&#x166;" u2="&#x159;" k="184" />
+<hkern u1="&#x166;" u2="&#x135;" k="-61" />
+<hkern u1="&#x166;" u2="&#x12d;" k="-82" />
+<hkern u1="&#x166;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x166;" u2="&#x129;" k="-123" />
+<hkern u1="&#x166;" u2="&#x103;" k="205" />
+<hkern u1="&#x166;" u2="&#x101;" k="164" />
+<hkern u1="&#x166;" u2="&#xef;" k="-123" />
+<hkern u1="&#x166;" u2="&#xee;" k="-61" />
+<hkern u1="&#x166;" u2="&#xe4;" k="123" />
+<hkern u1="&#x166;" u2="&#xe3;" k="123" />
+<hkern u1="&#x166;" u2="&#xe2;" k="164" />
+<hkern u1="&#x166;" u2="&#x3f;" k="-82" />
+<hkern u1="&#x166;" u2="&#x2a;" k="-92" />
+<hkern u1="&#x174;" u2="&#x1e9e;" k="20" />
+<hkern u1="&#x174;" u2="&#x135;" k="-10" />
+<hkern u1="&#x174;" u2="&#x12d;" k="-31" />
+<hkern u1="&#x174;" u2="&#x12b;" k="-51" />
+<hkern u1="&#x174;" u2="&#x129;" k="-133" />
+<hkern u1="&#x174;" u2="&#x127;" k="10" />
+<hkern u1="&#x174;" u2="&#xef;" k="-72" />
+<hkern u1="&#x174;" u2="&#xee;" k="-10" />
+<hkern u1="&#x176;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x176;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x176;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x176;" u2="&#x1e9e;" k="82" />
+<hkern u1="&#x176;" u2="&#x135;" k="41" />
+<hkern u1="&#x176;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x176;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x176;" u2="&#x129;" k="-123" />
+<hkern u1="&#x176;" u2="&#xef;" k="-102" />
+<hkern u1="&#x176;" u2="&#xee;" k="-20" />
+<hkern u1="&#x178;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x178;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x178;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x178;" u2="&#x1e9e;" k="82" />
+<hkern u1="&#x178;" u2="&#x135;" k="41" />
+<hkern u1="&#x178;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x178;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x178;" u2="&#x129;" k="-123" />
<hkern u1="&#x178;" u2="&#xef;" k="-102" />
<hkern u1="&#x178;" u2="&#xee;" k="-20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="T" k="164" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="V" k="82" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="W" k="61" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="Y,Yacute,Ydieresis" k="113" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quotedbl,quotesingle" k="123" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="colon,semicolon" k="-41" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="41" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="t" k="31" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="z" k="-31" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="trademark" k="164" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quoteleft,quotedblleft" k="184" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quoteright,quotedblright" k="164" />
-<hkern g1="B" g2="J" k="61" />
-<hkern g1="B" g2="T" k="41" />
+<hkern u1="&#x1cd;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1cd;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1ce;" u2="&#x167;" k="20" />
+<hkern u1="&#x1fa;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1fa;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1fb;" u2="&#x167;" k="20" />
+<hkern u1="&#x21a;" u2="&#x1ef9;" k="41" />
+<hkern u1="&#x21a;" u2="&#x1ee1;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1ed7;" k="154" />
+<hkern u1="&#x21a;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x21a;" u2="&#x1ec5;" k="174" />
+<hkern u1="&#x21a;" u2="&#x1ec1;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1ebd;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1eb7;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1eb5;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1eb3;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1eb1;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1eaf;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1ead;" k="102" />
+<hkern u1="&#x21a;" u2="&#x1eab;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1ea9;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1ea7;" k="61" />
+<hkern u1="&#x21a;" u2="&#x1ea5;" k="133" />
+<hkern u1="&#x21a;" u2="&#x1e9e;" k="61" />
+<hkern u1="&#x21a;" u2="&#x1d6;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1d0;" k="-20" />
+<hkern u1="&#x21a;" u2="&#x161;" k="242" />
+<hkern u1="&#x21a;" u2="&#x15d;" k="221" />
+<hkern u1="&#x21a;" u2="&#x159;" k="184" />
+<hkern u1="&#x21a;" u2="&#x135;" k="-61" />
+<hkern u1="&#x21a;" u2="&#x12d;" k="-82" />
+<hkern u1="&#x21a;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x21a;" u2="&#x129;" k="-123" />
+<hkern u1="&#x21a;" u2="&#x103;" k="205" />
+<hkern u1="&#x21a;" u2="&#x101;" k="164" />
+<hkern u1="&#x21a;" u2="&#xef;" k="-123" />
+<hkern u1="&#x21a;" u2="&#xee;" k="-61" />
+<hkern u1="&#x21a;" u2="&#xe4;" k="123" />
+<hkern u1="&#x21a;" u2="&#xe3;" k="123" />
+<hkern u1="&#x21a;" u2="&#xe2;" k="164" />
+<hkern u1="&#x21a;" u2="&#x3f;" k="-82" />
+<hkern u1="&#x21a;" u2="&#x2a;" k="-92" />
+<hkern u1="&#x386;" u2="&#x3f;" k="102" />
+<hkern u1="&#x388;" u2="&#x390;" k="-164" />
+<hkern u1="&#x389;" u2="&#x390;" k="-143" />
+<hkern u1="&#x390;" u2="&#x3be;" k="-43" />
+<hkern u1="&#x390;" u2="&#x3b8;" k="31" />
+<hkern u1="&#x390;" u2="&#x3b6;" k="-20" />
+<hkern u1="&#x390;" u2="&#x3f;" k="-143" />
+<hkern u1="&#x391;" u2="&#x3f;" k="102" />
+<hkern u1="&#x393;" u2="&#x3ca;" k="-127" />
+<hkern u1="&#x393;" u2="&#x3b4;" k="123" />
+<hkern u1="&#x393;" u2="&#x3af;" k="82" />
+<hkern u1="&#x393;" u2="&#x3a6;" k="82" />
+<hkern u1="&#x393;" u2="&#x390;" k="-236" />
+<hkern u1="&#x394;" u2="&#x3f;" k="102" />
+<hkern u1="&#x395;" u2="&#x390;" k="-164" />
+<hkern u1="&#x396;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x396;" u2="&#x390;" k="-184" />
+<hkern u1="&#x397;" u2="&#x390;" k="-143" />
+<hkern u1="&#x39a;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x39a;" u2="&#x3a6;" k="82" />
+<hkern u1="&#x39a;" u2="&#x390;" k="-170" />
+<hkern u1="&#x39b;" u2="&#x3f;" k="102" />
+<hkern u1="&#x39c;" u2="&#x390;" k="-143" />
+<hkern u1="&#x39d;" u2="&#x390;" k="-143" />
+<hkern u1="&#x39e;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x39e;" u2="&#x390;" k="-190" />
+<hkern u1="&#x3a0;" u2="&#x390;" k="-143" />
+<hkern u1="&#x3a3;" u2="&#x3ca;" k="-20" />
+<hkern u1="&#x3a3;" u2="&#x390;" k="-164" />
+<hkern u1="&#x3a4;" u2="&#x3cb;" k="123" />
+<hkern u1="&#x3a4;" u2="&#x3ca;" k="-143" />
+<hkern u1="&#x3a4;" u2="&#x3b4;" k="164" />
+<hkern u1="&#x3a4;" u2="&#x3b0;" k="61" />
+<hkern u1="&#x3a4;" u2="&#x390;" k="-246" />
+<hkern u1="&#x3a4;" u2="&#x3f;" k="-82" />
+<hkern u1="&#x3a4;" u2="&#x2a;" k="-92" />
+<hkern u1="&#x3a7;" u2="&#x3ca;" k="-102" />
+<hkern u1="&#x3a7;" u2="&#x390;" k="-205" />
+<hkern u1="&#x3a8;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x3a8;" u2="&#x390;" k="-172" />
+<hkern u1="&#x3b1;" u2="&#x3c4;" k="72" />
+<hkern u1="&#x3b1;" u2="&#x3c0;" k="82" />
+<hkern u1="&#x3b2;" u2="&#x3c4;" k="51" />
+<hkern u1="&#x3b6;" u2="&#x3ca;" k="-82" />
+<hkern u1="&#x3b6;" u2="&#x390;" k="-205" />
+<hkern u1="&#x3bb;" u2="&#x3f;" k="164" />
+<hkern u1="&#x3bb;" u2="&#x2a;" k="102" />
+<hkern u1="&#x3bd;" u2="&#x3c4;" k="-20" />
+<hkern u1="&#x3be;" u2="&#x390;" k="-150" />
+<hkern u1="&#x3be;" u2="&#x2a;" k="-41" />
+<hkern u1="&#x3c7;" u2="&#x3f;" k="82" />
+<hkern u1="&#x3c7;" u2="&#x2a;" k="41" />
+<hkern u1="&#x3c9;" u2="&#x3f;" k="41" />
+<hkern u1="&#x3ca;" u2="&#x3f;" k="-20" />
+<hkern u1="&#x3ce;" u2="&#x3f;" k="41" />
+<hkern u1="&#x403;" u2="&#x45e;" k="123" />
+<hkern u1="&#x403;" u2="&#x457;" k="-143" />
+<hkern u1="&#x403;" u2="&#x451;" k="113" />
+<hkern u1="&#x403;" u2="&#x424;" k="102" />
+<hkern u1="&#x409;" u2="&#x42a;" k="174" />
+<hkern u1="&#x40a;" u2="&#x42a;" k="174" />
+<hkern u1="&#x40c;" u2="&#x457;" k="-10" />
+<hkern u1="&#x40c;" u2="&#x456;" k="41" />
+<hkern u1="&#x40e;" u2="&#x457;" k="-123" />
+<hkern u1="&#x410;" u2="&#x42a;" k="184" />
+<hkern u1="&#x410;" u2="&#x3f;" k="82" />
+<hkern u1="&#x413;" u2="&#x45e;" k="123" />
+<hkern u1="&#x413;" u2="&#x457;" k="-143" />
+<hkern u1="&#x413;" u2="&#x451;" k="113" />
+<hkern u1="&#x413;" u2="&#x424;" k="102" />
+<hkern u1="&#x414;" u2="&#x458;" k="-164" />
+<hkern u1="&#x416;" u2="&#x457;" k="-10" />
+<hkern u1="&#x416;" u2="&#x456;" k="41" />
+<hkern u1="&#x41a;" u2="&#x457;" k="-10" />
+<hkern u1="&#x41a;" u2="&#x456;" k="41" />
+<hkern u1="&#x422;" u2="&#x457;" k="-123" />
+<hkern u1="&#x422;" u2="&#x456;" k="41" />
+<hkern u1="&#x422;" u2="&#x451;" k="82" />
+<hkern u1="&#x422;" u2="&#x424;" k="72" />
+<hkern u1="&#x422;" u2="&#x2a;" k="-92" />
+<hkern u1="&#x423;" u2="&#x457;" k="-123" />
+<hkern u1="&#x424;" u2="&#x422;" k="72" />
+<hkern u1="&#x425;" u2="&#x457;" k="-82" />
+<hkern u1="&#x426;" u2="&#x458;" k="-164" />
+<hkern u1="&#x429;" u2="&#x458;" k="-164" />
+<hkern u1="&#x42a;" u2="&#x42a;" k="174" />
+<hkern u1="&#x42c;" u2="&#x42a;" k="174" />
+<hkern u1="&#x434;" u2="&#x458;" k="-150" />
+<hkern u1="&#x442;" u2="&#x2a;" k="-82" />
+<hkern u1="&#x446;" u2="&#x458;" k="-150" />
+<hkern u1="&#x449;" u2="&#x458;" k="-150" />
+<hkern u1="&#x456;" u2="&#x457;" k="-41" />
+<hkern u1="&#x457;" u2="&#x45b;" k="-164" />
+<hkern u1="&#x457;" u2="&#x452;" k="-164" />
+<hkern u1="&#x457;" u2="&#x3f;" k="-102" />
+<hkern u1="&#x457;" u2="&#x2a;" k="-143" />
+<hkern u1="&#x490;" u2="&#x491;" k="256" />
+<hkern u1="&#x490;" u2="&#x45f;" k="256" />
+<hkern u1="&#x490;" u2="&#x45e;" k="123" />
+<hkern u1="&#x490;" u2="&#x45d;" k="256" />
+<hkern u1="&#x490;" u2="&#x45c;" k="256" />
+<hkern u1="&#x490;" u2="&#x45a;" k="256" />
+<hkern u1="&#x490;" u2="&#x458;" k="256" />
+<hkern u1="&#x490;" u2="&#x457;" k="-143" />
+<hkern u1="&#x490;" u2="&#x456;" k="256" />
+<hkern u1="&#x490;" u2="&#x453;" k="256" />
+<hkern u1="&#x490;" u2="&#x451;" k="113" />
+<hkern u1="&#x490;" u2="&#x44e;" k="256" />
+<hkern u1="&#x490;" u2="&#x44c;" k="256" />
+<hkern u1="&#x490;" u2="&#x44b;" k="256" />
+<hkern u1="&#x490;" u2="&#x449;" k="256" />
+<hkern u1="&#x490;" u2="&#x448;" k="256" />
+<hkern u1="&#x490;" u2="&#x446;" k="256" />
+<hkern u1="&#x490;" u2="&#x440;" k="256" />
+<hkern u1="&#x490;" u2="&#x43f;" k="256" />
+<hkern u1="&#x490;" u2="&#x43d;" k="256" />
+<hkern u1="&#x490;" u2="&#x43c;" k="256" />
+<hkern u1="&#x490;" u2="&#x43a;" k="256" />
+<hkern u1="&#x490;" u2="&#x439;" k="195" />
+<hkern u1="&#x490;" u2="&#x438;" k="256" />
+<hkern u1="&#x490;" u2="&#x433;" k="256" />
+<hkern u1="&#x490;" u2="&#x432;" k="256" />
+<hkern u1="&#x490;" u2="&#x42d;" k="10" />
+<hkern u1="&#x490;" u2="&#x424;" k="102" />
+<hkern u1="&#x490;" u2="&#x417;" k="10" />
+<hkern u1="&#x491;" u2="&#x45b;" k="-41" />
+<hkern u1="&#x491;" u2="&#x457;" k="-164" />
+<hkern u1="&#x491;" u2="&#x452;" k="-41" />
+<hkern u1="&#x1e80;" u2="&#x1e9e;" k="20" />
+<hkern u1="&#x1e80;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1e80;" u2="&#x12d;" k="-31" />
+<hkern u1="&#x1e80;" u2="&#x12b;" k="-51" />
+<hkern u1="&#x1e80;" u2="&#x129;" k="-133" />
+<hkern u1="&#x1e80;" u2="&#x127;" k="10" />
+<hkern u1="&#x1e80;" u2="&#xef;" k="-72" />
+<hkern u1="&#x1e80;" u2="&#xee;" k="-10" />
+<hkern u1="&#x1e82;" u2="&#x1e9e;" k="20" />
+<hkern u1="&#x1e82;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1e82;" u2="&#x12d;" k="-31" />
+<hkern u1="&#x1e82;" u2="&#x12b;" k="-51" />
+<hkern u1="&#x1e82;" u2="&#x129;" k="-133" />
+<hkern u1="&#x1e82;" u2="&#x127;" k="10" />
+<hkern u1="&#x1e82;" u2="&#xef;" k="-72" />
+<hkern u1="&#x1e82;" u2="&#xee;" k="-10" />
+<hkern u1="&#x1e84;" u2="&#x1e9e;" k="20" />
+<hkern u1="&#x1e84;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1e84;" u2="&#x12d;" k="-31" />
+<hkern u1="&#x1e84;" u2="&#x12b;" k="-51" />
+<hkern u1="&#x1e84;" u2="&#x129;" k="-133" />
+<hkern u1="&#x1e84;" u2="&#x127;" k="10" />
+<hkern u1="&#x1e84;" u2="&#xef;" k="-72" />
+<hkern u1="&#x1e84;" u2="&#xee;" k="-10" />
+<hkern u1="&#x1e9e;" u2="&#x1ef8;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x1ef6;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x1ef4;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x1ef2;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x1eb6;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eb4;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eb2;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eb0;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eae;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eac;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eaa;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea8;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea6;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea4;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea2;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea0;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1e9e;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#x1e84;" k="72" />
+<hkern u1="&#x1e9e;" u2="&#x1e82;" k="72" />
+<hkern u1="&#x1e9e;" u2="&#x1e80;" k="72" />
+<hkern u1="&#x1e9e;" u2="&#x21a;" k="123" />
+<hkern u1="&#x1e9e;" u2="&#x1fc;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#x1fa;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1cd;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x178;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x176;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x174;" k="72" />
+<hkern u1="&#x1e9e;" u2="&#x166;" k="123" />
+<hkern u1="&#x1e9e;" u2="&#x164;" k="123" />
+<hkern u1="&#x1e9e;" u2="&#x162;" k="123" />
+<hkern u1="&#x1e9e;" u2="&#x104;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x102;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x100;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xdd;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#xc6;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#xc5;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc4;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc3;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc2;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc1;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc0;" k="41" />
+<hkern u1="&#x1e9e;" u2="Y" k="102" />
+<hkern u1="&#x1e9e;" u2="X" k="41" />
+<hkern u1="&#x1e9e;" u2="W" k="72" />
+<hkern u1="&#x1e9e;" u2="V" k="72" />
+<hkern u1="&#x1e9e;" u2="T" k="123" />
+<hkern u1="&#x1e9e;" u2="A" k="41" />
+<hkern u1="&#x1ea0;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1ea0;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1ea1;" u2="&#x167;" k="20" />
+<hkern u1="&#x1ea2;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1ea2;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1ea3;" u2="&#x167;" k="20" />
+<hkern u1="&#x1ea4;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1ea4;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1ea5;" u2="&#x167;" k="20" />
+<hkern u1="&#x1ea6;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1ea6;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1ea7;" u2="&#x167;" k="20" />
+<hkern u1="&#x1ea8;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1ea8;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1ea9;" u2="&#x167;" k="20" />
+<hkern u1="&#x1eaa;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1eaa;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1eab;" u2="&#x167;" k="20" />
+<hkern u1="&#x1eac;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1eac;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1ead;" u2="&#x167;" k="20" />
+<hkern u1="&#x1eae;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1eae;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1eaf;" u2="&#x167;" k="20" />
+<hkern u1="&#x1eb0;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1eb0;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1eb1;" u2="&#x167;" k="20" />
+<hkern u1="&#x1eb2;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1eb2;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1eb3;" u2="&#x167;" k="20" />
+<hkern u1="&#x1eb4;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1eb4;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1eb5;" u2="&#x167;" k="20" />
+<hkern u1="&#x1eb6;" u2="&#x3f;" k="102" />
+<hkern u1="&#x1eb6;" u2="&#x2a;" k="123" />
+<hkern u1="&#x1eb7;" u2="&#x167;" k="20" />
+<hkern u1="&#x1ecb;" u2="j" k="-61" />
+<hkern u1="&#x1ef2;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x1ef2;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x1ef2;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x1ef2;" u2="&#x1e9e;" k="82" />
+<hkern u1="&#x1ef2;" u2="&#x135;" k="41" />
+<hkern u1="&#x1ef2;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x1ef2;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x1ef2;" u2="&#x129;" k="-123" />
+<hkern u1="&#x1ef2;" u2="&#xef;" k="-102" />
+<hkern u1="&#x1ef2;" u2="&#xee;" k="-20" />
+<hkern u1="&#x1ef4;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x1ef4;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x1ef4;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x1ef4;" u2="&#x1e9e;" k="82" />
+<hkern u1="&#x1ef4;" u2="&#x135;" k="41" />
+<hkern u1="&#x1ef4;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x1ef4;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x1ef4;" u2="&#x129;" k="-123" />
+<hkern u1="&#x1ef4;" u2="&#xef;" k="-102" />
+<hkern u1="&#x1ef4;" u2="&#xee;" k="-20" />
+<hkern u1="&#x1ef5;" u2="j" k="-82" />
+<hkern u1="&#x1ef6;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x1ef6;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x1ef6;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x1ef6;" u2="&#x1e9e;" k="82" />
+<hkern u1="&#x1ef6;" u2="&#x135;" k="41" />
+<hkern u1="&#x1ef6;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x1ef6;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x1ef6;" u2="&#x129;" k="-123" />
+<hkern u1="&#x1ef6;" u2="&#xef;" k="-102" />
+<hkern u1="&#x1ef6;" u2="&#xee;" k="-20" />
+<hkern u1="&#x1ef8;" u2="&#x1ed3;" k="102" />
+<hkern u1="&#x1ef8;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x1ef8;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x1ef8;" u2="&#x1e9e;" k="82" />
+<hkern u1="&#x1ef8;" u2="&#x135;" k="41" />
+<hkern u1="&#x1ef8;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x1ef8;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x1ef8;" u2="&#x129;" k="-123" />
+<hkern u1="&#x1ef8;" u2="&#xef;" k="-102" />
+<hkern u1="&#x1ef8;" u2="&#xee;" k="-20" />
+<hkern u1="&#x2018;" u2="&#x3ca;" k="-41" />
+<hkern u1="&#x2018;" u2="&#x390;" k="-143" />
+<hkern u1="&#x2018;" u2="&#x38e;" k="-266" />
+<hkern u1="&#x2018;" u2="&#x386;" k="-102" />
+<hkern u1="&#x2019;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x2019;" u2="&#x390;" k="-184" />
+<hkern u1="&#x2019;" u2="&#x38e;" k="-266" />
+<hkern u1="&#x2019;" u2="&#x386;" k="-102" />
+<hkern u1="&#x201a;" u2="&#x42a;" k="143" />
+<hkern u1="&#x201b;" u2="&#x2206;" k="184" />
+<hkern u1="&#x201b;" u2="&#x2026;" k="174" />
+<hkern u1="&#x201b;" u2="&#x201e;" k="174" />
+<hkern u1="&#x201b;" u2="&#x201b;" k="113" />
+<hkern u1="&#x201b;" u2="&#x201a;" k="174" />
+<hkern u1="&#x201b;" u2="&#x1ee3;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ee1;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1edf;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1edd;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1edb;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ed9;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ed7;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ed5;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ed3;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ed1;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ecf;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ecd;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ec7;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ec5;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ec3;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ec1;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ebf;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ebd;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1ebb;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1eb9;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1eb6;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eb4;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eb2;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eb0;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eae;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eac;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eaa;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea8;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea6;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea4;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea2;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea0;" k="184" />
+<hkern u1="&#x201b;" u2="&#x459;" k="164" />
+<hkern u1="&#x201b;" u2="&#x43b;" k="164" />
+<hkern u1="&#x201b;" u2="&#x42a;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x41b;" k="205" />
+<hkern u1="&#x201b;" u2="&#x410;" k="184" />
+<hkern u1="&#x201b;" u2="&#x40b;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x409;" k="205" />
+<hkern u1="&#x201b;" u2="&#x408;" k="246" />
+<hkern u1="&#x201b;" u2="&#x402;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x3ce;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3cc;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x201b;" u2="&#x3c9;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3c6;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3c3;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3c2;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3c1;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3bf;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3b4;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3b1;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3ac;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3a4;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x39b;" k="184" />
+<hkern u1="&#x201b;" u2="&#x394;" k="184" />
+<hkern u1="&#x201b;" u2="&#x391;" k="184" />
+<hkern u1="&#x201b;" u2="&#x390;" k="-184" />
+<hkern u1="&#x201b;" u2="&#x38f;" k="-266" />
+<hkern u1="&#x201b;" u2="&#x38e;" k="-266" />
+<hkern u1="&#x201b;" u2="&#x38c;" k="-266" />
+<hkern u1="&#x201b;" u2="&#x38a;" k="-266" />
+<hkern u1="&#x201b;" u2="&#x389;" k="-266" />
+<hkern u1="&#x201b;" u2="&#x388;" k="-266" />
+<hkern u1="&#x201b;" u2="&#x386;" k="-102" />
+<hkern u1="&#x201b;" u2="&#x21a;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x1ff;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1fc;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1fa;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1d2;" k="61" />
+<hkern u1="&#x201b;" u2="&#x1cd;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1a1;" k="61" />
+<hkern u1="&#x201b;" u2="&#x166;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x164;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x162;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x153;" k="61" />
+<hkern u1="&#x201b;" u2="&#x151;" k="61" />
+<hkern u1="&#x201b;" u2="&#x14f;" k="61" />
+<hkern u1="&#x201b;" u2="&#x14d;" k="61" />
+<hkern u1="&#x201b;" u2="&#x134;" k="246" />
+<hkern u1="&#x201b;" u2="&#x123;" k="61" />
+<hkern u1="&#x201b;" u2="&#x121;" k="61" />
+<hkern u1="&#x201b;" u2="&#x11f;" k="61" />
+<hkern u1="&#x201b;" u2="&#x11d;" k="61" />
+<hkern u1="&#x201b;" u2="&#x11b;" k="61" />
+<hkern u1="&#x201b;" u2="&#x119;" k="61" />
+<hkern u1="&#x201b;" u2="&#x117;" k="61" />
+<hkern u1="&#x201b;" u2="&#x115;" k="61" />
+<hkern u1="&#x201b;" u2="&#x113;" k="61" />
+<hkern u1="&#x201b;" u2="&#x111;" k="61" />
+<hkern u1="&#x201b;" u2="&#x10f;" k="61" />
+<hkern u1="&#x201b;" u2="&#x10d;" k="61" />
+<hkern u1="&#x201b;" u2="&#x10b;" k="61" />
+<hkern u1="&#x201b;" u2="&#x109;" k="61" />
+<hkern u1="&#x201b;" u2="&#x107;" k="61" />
+<hkern u1="&#x201b;" u2="&#x104;" k="184" />
+<hkern u1="&#x201b;" u2="&#x102;" k="184" />
+<hkern u1="&#x201b;" u2="&#x100;" k="184" />
+<hkern u1="&#x201b;" u2="&#xf8;" k="61" />
+<hkern u1="&#x201b;" u2="&#xf6;" k="61" />
+<hkern u1="&#x201b;" u2="&#xf5;" k="61" />
+<hkern u1="&#x201b;" u2="&#xf4;" k="61" />
+<hkern u1="&#x201b;" u2="&#xf3;" k="61" />
+<hkern u1="&#x201b;" u2="&#xf2;" k="61" />
+<hkern u1="&#x201b;" u2="&#xf0;" k="61" />
+<hkern u1="&#x201b;" u2="&#xeb;" k="61" />
+<hkern u1="&#x201b;" u2="&#xea;" k="61" />
+<hkern u1="&#x201b;" u2="&#xe9;" k="61" />
+<hkern u1="&#x201b;" u2="&#xe8;" k="61" />
+<hkern u1="&#x201b;" u2="&#xe7;" k="61" />
+<hkern u1="&#x201b;" u2="&#xc6;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc5;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc4;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc3;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc2;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc1;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc0;" k="184" />
+<hkern u1="&#x201b;" u2="q" k="61" />
+<hkern u1="&#x201b;" u2="o" k="61" />
+<hkern u1="&#x201b;" u2="g" k="61" />
+<hkern u1="&#x201b;" u2="e" k="61" />
+<hkern u1="&#x201b;" u2="d" k="61" />
+<hkern u1="&#x201b;" u2="c" k="61" />
+<hkern u1="&#x201b;" u2="T" k="-41" />
+<hkern u1="&#x201b;" u2="J" k="246" />
+<hkern u1="&#x201b;" u2="A" k="184" />
+<hkern u1="&#x201b;" u2="&#x2e;" k="174" />
+<hkern u1="&#x201b;" u2="&#x2c;" k="174" />
+<hkern u1="&#x201c;" u2="&#x3ca;" k="-41" />
+<hkern u1="&#x201c;" u2="&#x390;" k="-143" />
+<hkern u1="&#x201c;" u2="&#x38e;" k="-266" />
+<hkern u1="&#x201c;" u2="&#x386;" k="-102" />
+<hkern u1="&#x201d;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x201d;" u2="&#x390;" k="-184" />
+<hkern u1="&#x201d;" u2="&#x38e;" k="-266" />
+<hkern u1="&#x201d;" u2="&#x386;" k="-102" />
+<hkern u1="&#x201e;" u2="&#x42a;" k="143" />
+<hkern u1="&#x2026;" u2="&#x42a;" k="143" />
+<hkern u1="&#x2039;" u2="&#x386;" k="-82" />
+<hkern u1="&#x207f;" u2="&#x1e85;" k="6" />
+<hkern u1="&#x207f;" u2="&#x1e83;" k="6" />
+<hkern u1="&#x207f;" u2="&#x1e81;" k="6" />
+<hkern u1="&#x207f;" u2="&#x175;" k="6" />
+<hkern u1="&#x207f;" u2="w" k="6" />
+<hkern u1="&#x207f;" u2="v" k="6" />
+<hkern u1="&#x2206;" u2="&#x3f;" k="102" />
+<hkern g1="f_f" u2="&#x1ef9;" k="-20" />
+<hkern g1="f_f" u2="&#x1ed3;" k="-61" />
+<hkern g1="f_f" u2="&#x1ec9;" k="-51" />
+<hkern g1="f_f" u2="&#x1ec1;" k="-51" />
+<hkern g1="f_f" u2="&#x1eb5;" k="-20" />
+<hkern g1="f_f" u2="&#x1eb3;" k="-20" />
+<hkern g1="f_f" u2="&#x1eb1;" k="-20" />
+<hkern g1="f_f" u2="&#x1eaf;" k="-20" />
+<hkern g1="f_f" u2="&#x1eab;" k="-20" />
+<hkern g1="f_f" u2="&#x1ea7;" k="-113" />
+<hkern g1="f_f" u2="&#x1d0;" k="-184" />
+<hkern g1="f_f" u2="&#x135;" k="-102" />
+<hkern g1="f_f" u2="&#x12d;" k="-205" />
+<hkern g1="f_f" u2="&#x12b;" k="-184" />
+<hkern g1="f_f" u2="&#x129;" k="-246" />
+<hkern g1="f_f" u2="&#x127;" k="-102" />
+<hkern g1="f_f" u2="&#xef;" k="-225" />
+<hkern g1="f_f" u2="&#xee;" k="-102" />
+<hkern g1="f_f" u2="&#xec;" k="-82" />
+<hkern g1="f_f" u2="&#x3f;" k="-123" />
+<hkern g1="f_f" u2="&#x2a;" k="-143" />
+<hkern g1="f_f" u2="&#x21;" k="-61" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="164" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="V" k="82" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="61" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="113" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quotedbl,quotesingle" k="123" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="colon,semicolon" k="-41" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="20" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="41" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="31" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="z,zacute,zdotaccent,zcaron" k="-31" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="trademark" k="164" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quoteleft,quotedblleft" k="184" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quoteright,quotedblright" k="164" />
+<hkern g1="B" g2="J,Jcircumflex" k="61" />
+<hkern g1="B" g2="T,uni0162,Tcaron,Tbar,uni021A" k="41" />
<hkern g1="B" g2="V" k="41" />
-<hkern g1="B" g2="W" k="41" />
-<hkern g1="B" g2="Y,Yacute,Ydieresis" k="51" />
-<hkern g1="C,Ccedilla" g2="J" k="20" />
-<hkern g1="C,Ccedilla" g2="V" k="31" />
-<hkern g1="C,Ccedilla" g2="W" k="31" />
-<hkern g1="C,Ccedilla" g2="X" k="31" />
-<hkern g1="C,Ccedilla" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="F" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="102" />
-<hkern g1="F" g2="J" k="246" />
+<hkern g1="B" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="41" />
+<hkern g1="B" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="51" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="J,Jcircumflex" k="20" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="V" k="31" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="31" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="X" k="31" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="F" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="102" />
+<hkern g1="F" g2="J,Jcircumflex" k="246" />
<hkern g1="F" g2="X" k="41" />
<hkern g1="F" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="231" />
-<hkern g1="F" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="20" />
-<hkern g1="F" g2="t" k="20" />
-<hkern g1="F" g2="z" k="61" />
-<hkern g1="F" g2="S" k="20" />
-<hkern g1="F" g2="Z" k="41" />
-<hkern g1="F" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="41" />
-<hkern g1="F" g2="i,j,igrave,iacute,icircumflex,idieresis" k="41" />
-<hkern g1="F" g2="m,n,p,r,ntilde" k="72" />
-<hkern g1="F" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="F" g2="s" k="82" />
-<hkern g1="F" g2="u,ugrave,uacute,ucircumflex,udieresis" k="41" />
+<hkern g1="F" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="20" />
+<hkern g1="F" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="F" g2="z,zacute,zdotaccent,zcaron" k="61" />
+<hkern g1="F" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="20" />
+<hkern g1="F" g2="Z,Zacute,Zdotaccent,Zcaron" k="41" />
+<hkern g1="F" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="41" />
+<hkern g1="F" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="41" />
+<hkern g1="F" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="72" />
+<hkern g1="F" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="F" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="82" />
+<hkern g1="F" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="41" />
<hkern g1="F" g2="v" k="41" />
-<hkern g1="F" g2="w" k="41" />
+<hkern g1="F" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="41" />
<hkern g1="F" g2="x" k="82" />
-<hkern g1="F" g2="y,yacute,ydieresis" k="61" />
-<hkern g1="G" g2="J" k="51" />
-<hkern g1="G" g2="T" k="41" />
-<hkern g1="G" g2="V" k="41" />
-<hkern g1="G" g2="W" k="41" />
-<hkern g1="G" g2="X" k="31" />
-<hkern g1="G" g2="Y,Yacute,Ydieresis" k="61" />
-<hkern g1="J" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="41" />
-<hkern g1="J" g2="J" k="61" />
-<hkern g1="J" g2="X" k="20" />
-<hkern g1="J" g2="AE" k="61" />
-<hkern g1="K" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="41" />
-<hkern g1="K" g2="T" k="31" />
-<hkern g1="K" g2="V" k="51" />
-<hkern g1="K" g2="W" k="51" />
-<hkern g1="K" g2="X" k="41" />
-<hkern g1="K" g2="Y,Yacute,Ydieresis" k="82" />
-<hkern g1="K" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="41" />
-<hkern g1="K" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="41" />
-<hkern g1="K" g2="t" k="61" />
-<hkern g1="K" g2="S" k="51" />
-<hkern g1="K" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="61" />
-<hkern g1="K" g2="i,j,igrave,iacute,icircumflex,idieresis" k="41" />
-<hkern g1="K" g2="m,n,p,r,ntilde" k="41" />
-<hkern g1="K" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="41" />
-<hkern g1="K" g2="s" k="61" />
-<hkern g1="K" g2="u,ugrave,uacute,ucircumflex,udieresis" k="61" />
-<hkern g1="K" g2="v" k="51" />
-<hkern g1="K" g2="w" k="51" />
-<hkern g1="K" g2="y,yacute,ydieresis" k="102" />
-<hkern g1="K" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
-<hkern g1="L" g2="T" k="143" />
-<hkern g1="L" g2="V" k="102" />
-<hkern g1="L" g2="W" k="102" />
-<hkern g1="L" g2="Y,Yacute,Ydieresis" k="143" />
-<hkern g1="L" g2="quotedbl,quotesingle" k="287" />
-<hkern g1="L" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
-<hkern g1="L" g2="colon,semicolon" k="-41" />
-<hkern g1="L" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="20" />
-<hkern g1="L" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="41" />
-<hkern g1="L" g2="t" k="31" />
-<hkern g1="L" g2="trademark" k="287" />
-<hkern g1="L" g2="quoteleft,quotedblleft" k="328" />
-<hkern g1="L" g2="quoteright,quotedblright" k="328" />
-<hkern g1="L" g2="S" k="10" />
-<hkern g1="L" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="L" g2="v" k="61" />
-<hkern g1="L" g2="w" k="61" />
-<hkern g1="L" g2="y,yacute,ydieresis" k="102" />
-<hkern g1="L" g2="copyright,registered" k="61" />
-<hkern g1="P,Thorn" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="102" />
-<hkern g1="P,Thorn" g2="J" k="164" />
-<hkern g1="P,Thorn" g2="T" k="20" />
+<hkern g1="F" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="61" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="J,Jcircumflex" k="51" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="T,uni0162,Tcaron,Tbar,uni021A" k="41" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="V" k="41" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="41" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="X" k="31" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="61" />
+<hkern g1="J,IJ,Jcircumflex" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="41" />
+<hkern g1="J,IJ,Jcircumflex" g2="J,Jcircumflex" k="61" />
+<hkern g1="J,IJ,Jcircumflex" g2="X" k="20" />
+<hkern g1="J,IJ,Jcircumflex" g2="AE,AEacute" k="61" />
+<hkern g1="K,Kcommaaccent" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="41" />
+<hkern g1="K,Kcommaaccent" g2="T,uni0162,Tcaron,Tbar,uni021A" k="31" />
+<hkern g1="K,Kcommaaccent" g2="V" k="51" />
+<hkern g1="K,Kcommaaccent" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="51" />
+<hkern g1="K,Kcommaaccent" g2="X" k="41" />
+<hkern g1="K,Kcommaaccent" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="82" />
+<hkern g1="K,Kcommaaccent" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="41" />
+<hkern g1="K,Kcommaaccent" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="41" />
+<hkern g1="K,Kcommaaccent" g2="t,uni0163,tcaron,tbar,uni021B" k="61" />
+<hkern g1="K,Kcommaaccent" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="51" />
+<hkern g1="K,Kcommaaccent" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="61" />
+<hkern g1="K,Kcommaaccent" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="41" />
+<hkern g1="K,Kcommaaccent" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="41" />
+<hkern g1="K,Kcommaaccent" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="41" />
+<hkern g1="K,Kcommaaccent" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="61" />
+<hkern g1="K,Kcommaaccent" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="61" />
+<hkern g1="K,Kcommaaccent" g2="v" k="51" />
+<hkern g1="K,Kcommaaccent" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="51" />
+<hkern g1="K,Kcommaaccent" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="102" />
+<hkern g1="K,Kcommaaccent" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="T,uni0162,Tcaron,Tbar,uni021A" k="143" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="V" k="102" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="102" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="143" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quotedbl,quotesingle" k="287" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="colon,semicolon" k="-41" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="41" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="t,uni0163,tcaron,tbar,uni021B" k="31" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="trademark" k="287" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quoteleft,quotedblleft" k="328" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quoteright,quotedblright" k="328" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="10" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="v" k="61" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="61" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="102" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="copyright,registered" k="61" />
+<hkern g1="P,Thorn" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="102" />
+<hkern g1="P,Thorn" g2="J,Jcircumflex" k="164" />
+<hkern g1="P,Thorn" g2="T,uni0162,Tcaron,Tbar,uni021A" k="20" />
<hkern g1="P,Thorn" g2="V" k="-10" />
-<hkern g1="P,Thorn" g2="W" k="-10" />
+<hkern g1="P,Thorn" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-10" />
<hkern g1="P,Thorn" g2="X" k="20" />
<hkern g1="P,Thorn" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="266" />
-<hkern g1="P,Thorn" g2="S" k="-20" />
-<hkern g1="P,Thorn" g2="Z" k="41" />
-<hkern g1="P,Thorn" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="20" />
-<hkern g1="P,Thorn" g2="AE" k="82" />
-<hkern g1="P,Thorn" g2="I,Igrave,Iacute,Icircumflex,Idieresis" k="41" />
-<hkern g1="R" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="41" />
-<hkern g1="R" g2="T" k="20" />
-<hkern g1="R" g2="V" k="41" />
-<hkern g1="R" g2="W" k="41" />
-<hkern g1="R" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="S" g2="J" k="41" />
-<hkern g1="S" g2="T" k="41" />
-<hkern g1="S" g2="V" k="31" />
-<hkern g1="S" g2="W" k="31" />
-<hkern g1="S" g2="X" k="20" />
-<hkern g1="S" g2="Y,Yacute,Ydieresis" k="61" />
-<hkern g1="T" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="164" />
-<hkern g1="T" g2="J" k="143" />
-<hkern g1="T" g2="X" k="20" />
-<hkern g1="T" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="184" />
-<hkern g1="T" g2="colon,semicolon" k="82" />
-<hkern g1="T" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="51" />
-<hkern g1="T" g2="t" k="20" />
-<hkern g1="T" g2="z" k="156" />
-<hkern g1="T" g2="trademark" k="-82" />
-<hkern g1="T" g2="quoteleft,quotedblleft" k="-41" />
-<hkern g1="T" g2="quoteright,quotedblright" k="-41" />
-<hkern g1="T" g2="S" k="41" />
-<hkern g1="T" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="205" />
-<hkern g1="T" g2="i,j,igrave,iacute,icircumflex,idieresis" k="41" />
-<hkern g1="T" g2="m,n,p,r,ntilde" k="184" />
-<hkern g1="T" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="205" />
-<hkern g1="T" g2="s" k="205" />
-<hkern g1="T" g2="u,ugrave,uacute,ucircumflex,udieresis" k="143" />
-<hkern g1="T" g2="v" k="184" />
-<hkern g1="T" g2="w" k="184" />
-<hkern g1="T" g2="x" k="205" />
-<hkern g1="T" g2="y,yacute,ydieresis" k="143" />
-<hkern g1="T" g2="AE" k="184" />
-<hkern g1="T" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
-<hkern g1="T" g2="copyright,registered" k="102" />
-<hkern g1="T" g2="hyphen,endash,emdash" k="102" />
-<hkern g1="T" g2="guillemotleft,guilsinglleft" k="143" />
-<hkern g1="T" g2="guillemotright,guilsinglright" k="61" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="41" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="J" k="51" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="X" k="41" />
-<hkern g1="W" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="61" />
-<hkern g1="W" g2="J" k="143" />
-<hkern g1="W" g2="X" k="20" />
-<hkern g1="W" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="W" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
-<hkern g1="W" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="20" />
-<hkern g1="W" g2="t" k="20" />
-<hkern g1="W" g2="z" k="41" />
-<hkern g1="W" g2="S" k="10" />
-<hkern g1="W" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="61" />
-<hkern g1="W" g2="m,n,p,r,ntilde" k="61" />
-<hkern g1="W" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="W" g2="s" k="61" />
-<hkern g1="W" g2="u,ugrave,uacute,ucircumflex,udieresis" k="61" />
-<hkern g1="W" g2="x" k="31" />
-<hkern g1="W" g2="y,yacute,ydieresis" k="20" />
-<hkern g1="W" g2="AE" k="41" />
-<hkern g1="W" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
-<hkern g1="W" g2="b,h,k,l,germandbls,thorn" k="31" />
-<hkern g1="X" g2="T" k="20" />
+<hkern g1="P,Thorn" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-20" />
+<hkern g1="P,Thorn" g2="Z,Zacute,Zdotaccent,Zcaron" k="41" />
+<hkern g1="P,Thorn" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="20" />
+<hkern g1="P,Thorn" g2="AE,AEacute" k="82" />
+<hkern g1="P,Thorn" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="T,uni0162,Tcaron,Tbar,uni021A" k="20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="V" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="J,Jcircumflex" k="41" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="T,uni0162,Tcaron,Tbar,uni021A" k="41" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="V" k="31" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="31" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="X" k="20" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="61" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="164" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="J,Jcircumflex" k="143" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="X" k="20" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="184" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="colon,semicolon" k="82" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="51" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="z,zacute,zdotaccent,zcaron" k="156" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="trademark" k="-82" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="quoteleft,quotedblleft" k="-41" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="quoteright,quotedblright" k="-41" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="41" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="205" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="41" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="184" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="205" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="205" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="143" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="v" k="184" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="184" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="x" k="205" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="143" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="AE,AEacute" k="184" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="copyright,registered" k="102" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="hyphen,endash,emdash,afii00208" k="102" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="guillemotleft,guilsinglleft" k="143" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="guillemotright,guilsinglright" k="61" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="41" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="J,Jcircumflex" k="51" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="X" k="41" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="J,Jcircumflex" k="143" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="X" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="z,zacute,zdotaccent,zcaron" k="41" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="10" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="x" k="31" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="AE,AEacute" k="41" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="31" />
+<hkern g1="X" g2="T,uni0162,Tcaron,Tbar,uni021A" k="20" />
<hkern g1="X" g2="V" k="20" />
-<hkern g1="X" g2="W" k="20" />
-<hkern g1="X" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="X" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="41" />
-<hkern g1="X" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="41" />
-<hkern g1="X" g2="S" k="20" />
-<hkern g1="X" g2="m,n,p,r,ntilde" k="31" />
-<hkern g1="X" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="X" g2="u,ugrave,uacute,ucircumflex,udieresis" k="82" />
+<hkern g1="X" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="X" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="X" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="41" />
+<hkern g1="X" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="41" />
+<hkern g1="X" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="20" />
+<hkern g1="X" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="31" />
+<hkern g1="X" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="X" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="82" />
<hkern g1="X" g2="v" k="41" />
-<hkern g1="X" g2="w" k="41" />
-<hkern g1="X" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="31" />
+<hkern g1="X" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="41" />
+<hkern g1="X" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="31" />
<hkern g1="X" g2="copyright,registered" k="61" />
-<hkern g1="Y,Yacute,Ydieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="113" />
-<hkern g1="Y,Yacute,Ydieresis" g2="J" k="184" />
-<hkern g1="Y,Yacute,Ydieresis" g2="V" k="41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="W" k="41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="X" k="41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="205" />
-<hkern g1="Y,Yacute,Ydieresis" g2="colon,semicolon" k="41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="61" />
-<hkern g1="Y,Yacute,Ydieresis" g2="t" k="31" />
-<hkern g1="Y,Yacute,Ydieresis" g2="z" k="102" />
-<hkern g1="Y,Yacute,Ydieresis" g2="S" k="61" />
-<hkern g1="Y,Yacute,Ydieresis" g2="Z" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="123" />
-<hkern g1="Y,Yacute,Ydieresis" g2="i,j,igrave,iacute,icircumflex,idieresis" k="41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="m,n,p,r,ntilde" k="133" />
-<hkern g1="Y,Yacute,Ydieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="143" />
-<hkern g1="Y,Yacute,Ydieresis" g2="s" k="123" />
-<hkern g1="Y,Yacute,Ydieresis" g2="u,ugrave,uacute,ucircumflex,udieresis" k="102" />
-<hkern g1="Y,Yacute,Ydieresis" g2="v" k="82" />
-<hkern g1="Y,Yacute,Ydieresis" g2="w" k="82" />
-<hkern g1="Y,Yacute,Ydieresis" g2="x" k="82" />
-<hkern g1="Y,Yacute,Ydieresis" g2="AE" k="143" />
-<hkern g1="Y,Yacute,Ydieresis" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="copyright,registered" k="82" />
-<hkern g1="Y,Yacute,Ydieresis" g2="guillemotleft,guilsinglleft" k="102" />
-<hkern g1="Y,Yacute,Ydieresis" g2="b,h,k,l,germandbls,thorn" k="41" />
-<hkern g1="Z" g2="Y,Yacute,Ydieresis" k="31" />
-<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="t" k="20" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="20" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="quoteleft,quotedblleft" k="61" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="quoteright,quotedblright" k="61" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="v" k="20" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="x" k="31" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="y,yacute,ydieresis" k="10" />
-<hkern g1="h,m,n,ntilde" g2="v" k="10" />
-<hkern g1="h,m,n,ntilde" g2="w" k="10" />
-<hkern g1="f" g2="quotedbl,quotesingle" k="-123" />
-<hkern g1="f" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="41" />
-<hkern g1="f" g2="trademark" k="-164" />
-<hkern g1="f" g2="quoteleft,quotedblleft" k="-102" />
-<hkern g1="f" g2="quoteright,quotedblright" k="-123" />
-<hkern g1="f" g2="parenright,bracketright,braceright" k="-164" />
-<hkern g1="k" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="31" />
-<hkern g1="k" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="41" />
-<hkern g1="k" g2="s" k="20" />
-<hkern g1="k" g2="v" k="20" />
-<hkern g1="k" g2="w" k="20" />
-<hkern g1="r" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="266" />
-<hkern g1="r" g2="quoteleft,quotedblleft" k="-41" />
-<hkern g1="r" g2="quoteright,quotedblright" k="-41" />
-<hkern g1="r" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="20" />
-<hkern g1="r" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="41" />
-<hkern g1="r" g2="s" k="20" />
-<hkern g1="r" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="-20" />
-<hkern g1="r" g2="guillemotright,guilsinglright" k="-41" />
-<hkern g1="s" g2="t" k="20" />
-<hkern g1="s" g2="v" k="41" />
-<hkern g1="s" g2="w" k="41" />
-<hkern g1="s" g2="x" k="20" />
-<hkern g1="t" g2="z" k="-31" />
-<hkern g1="t" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="-20" />
-<hkern g1="t" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="t" g2="u,ugrave,uacute,ucircumflex,udieresis" k="10" />
-<hkern g1="t" g2="v" k="10" />
-<hkern g1="t" g2="w" k="10" />
-<hkern g1="t" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="10" />
-<hkern g1="w" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
-<hkern g1="w" g2="s" k="20" />
-<hkern g1="w" g2="y,yacute,ydieresis" k="10" />
-<hkern g1="x" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="31" />
-<hkern g1="y,yacute,ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
-<hkern g1="y,yacute,ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="31" />
-<hkern g1="y,yacute,ydieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="41" />
-<hkern g1="y,yacute,ydieresis" g2="s" k="31" />
-<hkern g1="y,yacute,ydieresis" g2="v" k="20" />
-<hkern g1="y,yacute,ydieresis" g2="w" k="20" />
-<hkern g1="y,yacute,ydieresis" g2="x" k="31" />
-<hkern g1="y,yacute,ydieresis" g2="parenright,bracketright,braceright" k="61" />
-<hkern g1="z" g2="z" k="-31" />
-<hkern g1="colon,semicolon" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-41" />
-<hkern g1="colon,semicolon" g2="J" k="-41" />
-<hkern g1="colon,semicolon" g2="T" k="82" />
-<hkern g1="colon,semicolon" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-41" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="J" k="-41" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="T" k="184" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="113" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="J,Jcircumflex" k="184" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="V" k="41" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="41" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="X" k="41" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="205" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="colon,semicolon" k="41" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="61" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="t,uni0163,tcaron,tbar,uni021B" k="31" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="z,zacute,zdotaccent,zcaron" k="102" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="61" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="Z,Zacute,Zdotaccent,Zcaron" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="123" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="41" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="133" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="143" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="123" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="102" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="v" k="82" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="82" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="x" k="82" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="AE,AEacute" k="143" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="copyright,registered" k="82" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="guillemotleft,guilsinglleft" k="102" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="41" />
+<hkern g1="Z,Zacute,Zdotaccent,Zcaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="31" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring,amacron,abreve,aogonek,acaron,aringacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="20" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="quoteleft,quotedblleft" k="61" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="quoteright,quotedblright" k="61" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="v" k="20" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="x" k="31" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="h,m,n,ntilde,hcircumflex,hbar,nacute,ncommaaccent,ncaron,napostrophe,eng" g2="v" k="10" />
+<hkern g1="h,m,n,ntilde,hcircumflex,hbar,nacute,ncommaaccent,ncaron,napostrophe,eng" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="10" />
+<hkern g1="f,f_f" g2="quotedbl,quotesingle" k="-123" />
+<hkern g1="f,f_f" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="41" />
+<hkern g1="f,f_f" g2="trademark" k="-164" />
+<hkern g1="f,f_f" g2="quoteleft,quotedblleft" k="-102" />
+<hkern g1="f,f_f" g2="quoteright,quotedblright" k="-123" />
+<hkern g1="f,f_f" g2="parenright,bracketright,braceright" k="-164" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="31" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="41" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="20" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="v" k="20" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="266" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="quoteleft,quotedblleft" k="-41" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="quoteright,quotedblright" k="-41" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="20" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="41" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="20" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-20" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="guillemotright,guilsinglright" k="-41" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="v" k="41" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="41" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="x" k="20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="z,zacute,zdotaccent,zcaron" k="-31" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="-20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="v" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="10" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="20" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="x" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="31" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="31" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="41" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="31" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="v" k="20" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="x" k="31" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="parenright,bracketright,braceright" k="61" />
+<hkern g1="z,zacute,zdotaccent,zcaron" g2="z,zacute,zdotaccent,zcaron" k="-31" />
+<hkern g1="colon,semicolon" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="-41" />
+<hkern g1="colon,semicolon" g2="J,Jcircumflex" k="-41" />
+<hkern g1="colon,semicolon" g2="T,uni0162,Tcaron,Tbar,uni021A" k="82" />
+<hkern g1="colon,semicolon" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="colon,semicolon" g2="uni0410" k="-41" />
+<hkern g1="colon,semicolon" g2="uni0409,uni041B" k="-41" />
+<hkern g1="colon,semicolon" g2="uni0422" k="82" />
+<hkern g1="colon,semicolon" g2="uni0408" k="-41" />
+<hkern g1="colon,semicolon" g2="uni0402,uni040B,uni042A" k="41" />
+<hkern g1="colon,semicolon" g2="uni043B,uni0459" k="-41" />
+<hkern g1="colon,semicolon" g2="Alpha,uni0394,Lambda,Delta" k="-41" />
+<hkern g1="colon,semicolon" g2="Tau" k="82" />
+<hkern g1="colon,semicolon" g2="Upsilon,Upsilondieresis" k="41" />
+<hkern g1="colon,semicolon" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-205" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="J,Jcircumflex" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="T,uni0162,Tcaron,Tbar,uni021A" k="184" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="V" k="143" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="W" k="143" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Y,Yacute,Ydieresis" k="205" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="143" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="205" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="quoteleft,quotedblleft" k="174" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="quoteright,quotedblright" k="174" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="v" k="61" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="w" k="61" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="AE" k="-61" />
-<hkern g1="guillemotleft,guilsinglleft" g2="T" k="61" />
-<hkern g1="guillemotright,guilsinglright" g2="T" k="143" />
-<hkern g1="guillemotright,guilsinglright" g2="Y,Yacute,Ydieresis" k="102" />
-<hkern g1="hyphen,endash,emdash" g2="T" k="102" />
-<hkern g1="parenleft,bracketleft,braceleft" g2="y,yacute,ydieresis" k="-61" />
-<hkern g1="quoteleft,quotedblleft" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="184" />
-<hkern g1="quoteleft,quotedblleft" g2="J" k="246" />
-<hkern g1="quoteleft,quotedblleft" g2="T" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="61" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="AE,AEacute" k="-61" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0410" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0409,uni041B" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0422" k="184" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0408" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0402,uni040B,uni042A" k="61" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni043B,uni0459" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Alpha,uni0394,Lambda,Delta" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Tau" k="184" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Upsilon,Upsilondieresis" k="205" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="pi" k="227" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0427" k="143" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0442" k="123" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0447" k="102" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni044A" k="123" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Psi" k="82" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="gamma,nu" k="82" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="tau" k="227" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="chi" k="61" />
+<hkern g1="guillemotleft,guilsinglleft" g2="T,uni0162,Tcaron,Tbar,uni021A" k="61" />
+<hkern g1="guillemotleft,guilsinglleft" g2="uni0422" k="143" />
+<hkern g1="guillemotleft,guilsinglleft" g2="Tau" k="61" />
+<hkern g1="guillemotleft,guilsinglleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-266" />
+<hkern g1="guillemotright,guilsinglright" g2="T,uni0162,Tcaron,Tbar,uni021A" k="143" />
+<hkern g1="guillemotright,guilsinglright" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="102" />
+<hkern g1="guillemotright,guilsinglright" g2="uni0422" k="164" />
+<hkern g1="guillemotright,guilsinglright" g2="Tau" k="143" />
+<hkern g1="guillemotright,guilsinglright" g2="Upsilon,Upsilondieresis" k="102" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="T,uni0162,Tcaron,Tbar,uni021A" k="102" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="uni0422" k="102" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="Tau" k="102" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="pi" k="61" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="tau" k="61" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="xi" k="-41" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-61" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-205" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="uni0443,uni045E" k="-61" />
+<hkern g1="parenright,bracketright,braceright" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-184" />
+<hkern g1="quoteleft,quotedblleft" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="184" />
+<hkern g1="quoteleft,quotedblleft" g2="J,Jcircumflex" k="246" />
+<hkern g1="quoteleft,quotedblleft" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-41" />
<hkern g1="quoteleft,quotedblleft" g2="quoteleft,quotedblleft" k="113" />
-<hkern g1="quoteleft,quotedblleft" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="quoteleft,quotedblleft" g2="AE" k="184" />
-<hkern g1="quoteright,quotedblright" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="184" />
-<hkern g1="quoteright,quotedblright" g2="J" k="246" />
-<hkern g1="quoteright,quotedblright" g2="T" k="-41" />
+<hkern g1="quoteleft,quotedblleft" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="quoteleft,quotedblleft" g2="AE,AEacute" k="184" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0410" k="184" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0409,uni041B" k="184" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0408" k="246" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0402,uni040B,uni042A" k="-41" />
+<hkern g1="quoteleft,quotedblleft" g2="uni043B,uni0459" k="164" />
+<hkern g1="quoteleft,quotedblleft" g2="Alpha,uni0394,Lambda,Delta" k="184" />
+<hkern g1="quoteleft,quotedblleft" g2="Tau" k="-41" />
+<hkern g1="quoteleft,quotedblleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-266" />
+<hkern g1="quoteleft,quotedblleft" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="quoteleft,quotedblleft" g2="rho" k="61" />
+<hkern g1="quoteleft,quotedblleft" g2="omega,omegatonos" k="61" />
+<hkern g1="quoteright,quotedblright" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="184" />
+<hkern g1="quoteright,quotedblright" g2="J,Jcircumflex" k="246" />
+<hkern g1="quoteright,quotedblright" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-41" />
<hkern g1="quoteright,quotedblright" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="174" />
<hkern g1="quoteright,quotedblright" g2="quoteright,quotedblright" k="113" />
-<hkern g1="quoteright,quotedblright" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="quoteright,quotedblright" g2="AE" k="184" />
-<hkern g1="quotedbl,quotesingle" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="123" />
-<hkern g1="quotedbl,quotesingle" g2="J" k="225" />
-<hkern g1="V" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="82" />
-<hkern g1="V" g2="J" k="143" />
+<hkern g1="quoteright,quotedblright" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="quoteright,quotedblright" g2="AE,AEacute" k="184" />
+<hkern g1="quoteright,quotedblright" g2="uni0410" k="184" />
+<hkern g1="quoteright,quotedblright" g2="uni0409,uni041B" k="205" />
+<hkern g1="quoteright,quotedblright" g2="uni0408" k="246" />
+<hkern g1="quoteright,quotedblright" g2="uni0402,uni040B,uni042A" k="-41" />
+<hkern g1="quoteright,quotedblright" g2="uni043B,uni0459" k="164" />
+<hkern g1="quoteright,quotedblright" g2="Alpha,uni0394,Lambda,Delta" k="184" />
+<hkern g1="quoteright,quotedblright" g2="Tau" k="-41" />
+<hkern g1="quoteright,quotedblright" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-266" />
+<hkern g1="quoteright,quotedblright" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="quoteright,quotedblright" g2="rho" k="61" />
+<hkern g1="quoteright,quotedblright" g2="omega,omegatonos" k="61" />
+<hkern g1="quotedbl,quotesingle" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="123" />
+<hkern g1="quotedbl,quotesingle" g2="J,Jcircumflex" k="225" />
+<hkern g1="dcaron,lcaron" g2="quoteleft,quotedblleft" k="-82" />
+<hkern g1="dcaron,lcaron" g2="quoteright,quotedblright" k="-61" />
+<hkern g1="dcaron,lcaron" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="82" />
+<hkern g1="dcaron,lcaron" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="82" />
+<hkern g1="dcaron,lcaron" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="82" />
+<hkern g1="dcaron,lcaron" g2="parenright,bracketright,braceright" k="-162" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="colon,semicolon" k="-41" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="quoteleft,quotedblleft" k="184" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="quoteright,quotedblright" k="184" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Tau" k="164" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Upsilon,Upsilondieresis" k="113" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="pi" k="92" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Psi" k="20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="gamma,nu" k="20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="tau" k="143" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Theta,Omicron,Phi" k="20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="theta" k="20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="41" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Alpha,uni0394,Lambda,Delta" k="20" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Tau" k="51" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Upsilon,Upsilondieresis" k="61" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Chi" k="41" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="lambda" k="41" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="205" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="colon,semicolon" k="41" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="guillemotleft,guilsinglleft" k="102" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Alpha,uni0394,Lambda,Delta" k="113" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="pi" k="123" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="143" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="tau" k="102" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Theta,Omicron,Phi" k="61" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Chi" k="41" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Zeta" k="20" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="mu,etatonos,eta,uni03BC" k="133" />
+<hkern g1="Iotatonos,Iota,Iotadieresis" g2="pi" k="61" />
+<hkern g1="Iotatonos,Iota,Iotadieresis" g2="tau" k="82" />
+<hkern g1="Omegatonos,uni03A9,Omega" g2="Tau" k="41" />
+<hkern g1="Omegatonos,uni03A9,Omega" g2="Chi" k="20" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="pi" k="31" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="gamma,nu" k="20" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="tau" k="41" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="chi" k="61" />
+<hkern g1="Beta" g2="Tau" k="41" />
+<hkern g1="Beta" g2="Upsilon,Upsilondieresis" k="51" />
+<hkern g1="Beta" g2="pi" k="61" />
+<hkern g1="Beta" g2="gamma,nu" k="20" />
+<hkern g1="Beta" g2="tau" k="61" />
+<hkern g1="Beta" g2="lambda" k="41" />
+<hkern g1="Gamma" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="287" />
+<hkern g1="Gamma" g2="colon,semicolon" k="184" />
+<hkern g1="Gamma" g2="quoteleft,quotedblleft" k="-41" />
+<hkern g1="Gamma" g2="quoteright,quotedblright" k="-41" />
+<hkern g1="Gamma" g2="hyphen,endash,emdash,afii00208" k="205" />
+<hkern g1="Gamma" g2="guillemotleft,guilsinglleft" k="246" />
+<hkern g1="Gamma" g2="guillemotright,guilsinglright" k="205" />
+<hkern g1="Gamma" g2="Alpha,uni0394,Lambda,Delta" k="215" />
+<hkern g1="Gamma" g2="pi" k="287" />
+<hkern g1="Gamma" g2="gamma,nu" k="266" />
+<hkern g1="Gamma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="276" />
+<hkern g1="Gamma" g2="tau" k="184" />
+<hkern g1="Gamma" g2="chi" k="266" />
+<hkern g1="Gamma" g2="rho" k="297" />
+<hkern g1="Gamma" g2="omega,omegatonos" k="317" />
+<hkern g1="Gamma" g2="theta" k="20" />
+<hkern g1="Gamma" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="256" />
+<hkern g1="Gamma" g2="lambda" k="102" />
+<hkern g1="Gamma" g2="mu,etatonos,eta,uni03BC" k="276" />
+<hkern g1="Gamma" g2="uni03A9,Omega" k="41" />
+<hkern g1="Gamma" g2="beta" k="61" />
+<hkern g1="Gamma" g2="epsilontonos,epsilon" k="297" />
+<hkern g1="Gamma" g2="zeta" k="41" />
+<hkern g1="Gamma" g2="kappa" k="276" />
+<hkern g1="Gamma" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="266" />
+<hkern g1="Zeta" g2="Upsilon,Upsilondieresis" k="31" />
+<hkern g1="Zeta" g2="pi" k="92" />
+<hkern g1="Zeta" g2="gamma,nu" k="41" />
+<hkern g1="Zeta" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="Zeta" g2="tau" k="72" />
+<hkern g1="Zeta" g2="chi" k="61" />
+<hkern g1="Zeta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="41" />
+<hkern g1="Kappa" g2="Alpha,uni0394,Lambda,Delta" k="41" />
+<hkern g1="Kappa" g2="Tau" k="31" />
+<hkern g1="Kappa" g2="Upsilon,Upsilondieresis" k="82" />
+<hkern g1="Kappa" g2="pi" k="164" />
+<hkern g1="Kappa" g2="gamma,nu" k="82" />
+<hkern g1="Kappa" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="Kappa" g2="tau" k="143" />
+<hkern g1="Kappa" g2="chi" k="123" />
+<hkern g1="Kappa" g2="rho" k="41" />
+<hkern g1="Kappa" g2="Theta,Omicron,Phi" k="41" />
+<hkern g1="Kappa" g2="theta" k="61" />
+<hkern g1="Kappa" g2="Chi" k="41" />
+<hkern g1="Kappa" g2="mu,etatonos,eta,uni03BC" k="41" />
+<hkern g1="Kappa" g2="uni03A9,Omega" k="41" />
+<hkern g1="Kappa" g2="beta" k="61" />
+<hkern g1="Kappa" g2="zeta" k="41" />
+<hkern g1="Kappa" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="92" />
+<hkern g1="Rho" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="266" />
+<hkern g1="Rho" g2="Alpha,uni0394,Lambda,Delta" k="102" />
+<hkern g1="Rho" g2="Tau" k="20" />
+<hkern g1="Rho" g2="pi" k="-10" />
+<hkern g1="Rho" g2="tau" k="-31" />
+<hkern g1="Rho" g2="Chi" k="20" />
+<hkern g1="Rho" g2="Zeta" k="41" />
+<hkern g1="Rho" g2="Iota,Iotadieresis" k="41" />
+<hkern g1="Sigma" g2="pi" k="102" />
+<hkern g1="Sigma" g2="gamma,nu" k="82" />
+<hkern g1="Sigma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="Sigma" g2="tau" k="102" />
+<hkern g1="Sigma" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="41" />
+<hkern g1="Tau" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="184" />
+<hkern g1="Tau" g2="colon,semicolon" k="82" />
+<hkern g1="Tau" g2="quoteleft,quotedblleft" k="-41" />
+<hkern g1="Tau" g2="quoteright,quotedblright" k="-41" />
+<hkern g1="Tau" g2="hyphen,endash,emdash,afii00208" k="102" />
+<hkern g1="Tau" g2="guillemotleft,guilsinglleft" k="143" />
+<hkern g1="Tau" g2="guillemotright,guilsinglright" k="61" />
+<hkern g1="Tau" g2="Alpha,uni0394,Lambda,Delta" k="164" />
+<hkern g1="Tau" g2="pi" k="164" />
+<hkern g1="Tau" g2="gamma,nu" k="164" />
+<hkern g1="Tau" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="205" />
+<hkern g1="Tau" g2="tau" k="164" />
+<hkern g1="Tau" g2="chi" k="205" />
+<hkern g1="Tau" g2="rho" k="205" />
+<hkern g1="Tau" g2="omega,omegatonos" k="205" />
+<hkern g1="Tau" g2="Theta,Omicron,Phi" k="51" />
+<hkern g1="Tau" g2="theta" k="20" />
+<hkern g1="Tau" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="205" />
+<hkern g1="Tau" g2="Chi" k="20" />
+<hkern g1="Tau" g2="lambda" k="82" />
+<hkern g1="Tau" g2="mu,etatonos,eta,uni03BC" k="184" />
+<hkern g1="Tau" g2="uni03A9,Omega" k="41" />
+<hkern g1="Tau" g2="beta" k="61" />
+<hkern g1="Tau" g2="epsilontonos,epsilon" k="205" />
+<hkern g1="Tau" g2="kappa" k="174" />
+<hkern g1="Tau" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="215" />
+<hkern g1="Chi" g2="Tau" k="20" />
+<hkern g1="Chi" g2="Upsilon,Upsilondieresis" k="41" />
+<hkern g1="Chi" g2="pi" k="133" />
+<hkern g1="Chi" g2="gamma,nu" k="61" />
+<hkern g1="Chi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="Chi" g2="tau" k="133" />
+<hkern g1="Chi" g2="chi" k="82" />
+<hkern g1="Chi" g2="rho" k="41" />
+<hkern g1="Chi" g2="omega,omegatonos" k="41" />
+<hkern g1="Chi" g2="Theta,Omicron,Phi" k="41" />
+<hkern g1="Chi" g2="theta" k="20" />
+<hkern g1="Chi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="41" />
+<hkern g1="Chi" g2="mu,etatonos,eta,uni03BC" k="31" />
+<hkern g1="Chi" g2="uni03A9,Omega" k="20" />
+<hkern g1="Chi" g2="beta" k="41" />
+<hkern g1="Chi" g2="zeta" k="20" />
+<hkern g1="Chi" g2="kappa" k="31" />
+<hkern g1="Chi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="61" />
+<hkern g1="Psi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="82" />
+<hkern g1="Psi" g2="Alpha,uni0394,Lambda,Delta" k="20" />
+<hkern g1="Psi" g2="lambda" k="82" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="pi" k="102" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="gamma,nu" k="41" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="31" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="tau" k="113" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="chi" k="61" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="xi" k="41" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="theta" k="51" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="zeta" k="20" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="20" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="quoteleft,quotedblleft" k="61" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="quoteright,quotedblright" k="61" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="pi" k="31" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="gamma,nu" k="20" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="tau" k="41" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="chi" k="41" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="xi" k="20" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="lambda" k="41" />
+<hkern g1="omega,omegatonos" g2="quoteleft,quotedblleft" k="61" />
+<hkern g1="omega,omegatonos" g2="quoteright,quotedblright" k="61" />
+<hkern g1="omega,omegatonos" g2="pi" k="20" />
+<hkern g1="omega,omegatonos" g2="tau" k="20" />
+<hkern g1="omega,omegatonos" g2="chi" k="61" />
+<hkern g1="epsilontonos,epsilon" g2="pi" k="20" />
+<hkern g1="epsilontonos,epsilon" g2="gamma,nu" k="20" />
+<hkern g1="epsilontonos,epsilon" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="epsilontonos,epsilon" g2="chi" k="20" />
+<hkern g1="epsilontonos,epsilon" g2="xi" k="20" />
+<hkern g1="epsilontonos,epsilon" g2="lambda" k="20" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="pi" k="31" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="tau" k="31" />
+<hkern g1="gamma,nu" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="82" />
+<hkern g1="gamma,nu" g2="tau" k="-20" />
+<hkern g1="chi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="chi" g2="quoteleft,quotedblleft" k="41" />
+<hkern g1="chi" g2="quoteright,quotedblright" k="41" />
+<hkern g1="chi" g2="pi" k="82" />
+<hkern g1="chi" g2="gamma,nu" k="82" />
+<hkern g1="chi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="82" />
+<hkern g1="chi" g2="tau" k="61" />
+<hkern g1="chi" g2="xi" k="82" />
+<hkern g1="chi" g2="omega,omegatonos" k="61" />
+<hkern g1="chi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="82" />
+<hkern g1="chi" g2="lambda" k="61" />
+<hkern g1="chi" g2="mu,etatonos,eta,uni03BC" k="41" />
+<hkern g1="chi" g2="epsilontonos,epsilon" k="61" />
+<hkern g1="chi" g2="zeta" k="82" />
+<hkern g1="chi" g2="kappa" k="61" />
+<hkern g1="chi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="51" />
+<hkern g1="zeta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="zeta" g2="hyphen,endash,emdash,afii00208" k="82" />
+<hkern g1="zeta" g2="pi" k="102" />
+<hkern g1="zeta" g2="gamma,nu" k="102" />
+<hkern g1="zeta" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="zeta" g2="tau" k="143" />
+<hkern g1="zeta" g2="omega,omegatonos" k="41" />
+<hkern g1="zeta" g2="theta" k="61" />
+<hkern g1="zeta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="41" />
+<hkern g1="zeta" g2="epsilontonos,epsilon" k="31" />
+<hkern g1="zeta" g2="kappa" k="61" />
+<hkern g1="zeta" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="41" />
+<hkern g1="theta" g2="gamma,nu" k="41" />
+<hkern g1="kappa" g2="pi" k="61" />
+<hkern g1="kappa" g2="gamma,nu" k="61" />
+<hkern g1="kappa" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="kappa" g2="tau" k="41" />
+<hkern g1="kappa" g2="chi" k="41" />
+<hkern g1="kappa" g2="xi" k="61" />
+<hkern g1="kappa" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="31" />
+<hkern g1="kappa" g2="epsilontonos,epsilon" k="31" />
+<hkern g1="kappa" g2="zeta" k="41" />
+<hkern g1="lambda" g2="quoteleft,quotedblleft" k="123" />
+<hkern g1="lambda" g2="quoteright,quotedblright" k="123" />
+<hkern g1="lambda" g2="pi" k="164" />
+<hkern g1="lambda" g2="gamma,nu" k="92" />
+<hkern g1="lambda" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="lambda" g2="tau" k="184" />
+<hkern g1="lambda" g2="chi" k="102" />
+<hkern g1="lambda" g2="xi" k="82" />
+<hkern g1="lambda" g2="theta" k="41" />
+<hkern g1="lambda" g2="zeta" k="41" />
+<hkern g1="xi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-31" />
+<hkern g1="xi" g2="pi" k="20" />
+<hkern g1="xi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="xi" g2="tau" k="20" />
+<hkern g1="xi" g2="omega,omegatonos" k="20" />
+<hkern g1="xi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="10" />
+<hkern g1="xi" g2="epsilontonos,epsilon" k="20" />
+<hkern g1="sigma" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
+<hkern g1="sigma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="sigma" g2="xi" k="20" />
+<hkern g1="sigma" g2="omega,omegatonos" k="20" />
+<hkern g1="sigma" g2="lambda" k="41" />
+<hkern g1="sigma" g2="kappa" k="41" />
+<hkern g1="sigma1" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="sigma1" g2="xi" k="61" />
+<hkern g1="sigma1" g2="omega,omegatonos" k="41" />
+<hkern g1="sigma1" g2="lambda" k="31" />
+<hkern g1="tau" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="tau" g2="xi" k="31" />
+<hkern g1="tau" g2="omega,omegatonos" k="20" />
+<hkern g1="tau" g2="lambda" k="41" />
+<hkern g1="tau" g2="epsilontonos,epsilon" k="41" />
+<hkern g1="tau" g2="zeta" k="20" />
+<hkern g1="tau" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0410" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0422" k="31" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0408" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0442" k="82" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0443,uni045E" k="51" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0404,uni041E,uni0421,uni0424" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0425" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0405" k="31" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0430" k="61" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0455" k="61" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="quoteleft,quotedblleft" k="41" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="quoteright,quotedblright" k="61" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0422" k="184" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0402,uni040B,uni042A" k="41" />
+<hkern g1="uni0411,uni0412,uni0417" g2="uni0422" k="41" />
+<hkern g1="uni0411,uni0412,uni0417" g2="uni0408" k="61" />
+<hkern g1="uni0403,uni0413,uni0490" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="287" />
+<hkern g1="uni0403,uni0413,uni0490" g2="colon,semicolon" k="205" />
+<hkern g1="uni0403,uni0413,uni0490" g2="hyphen,endash,emdash,afii00208" k="205" />
+<hkern g1="uni0403,uni0413,uni0490" g2="guillemotleft,guilsinglleft" k="287" />
+<hkern g1="uni0403,uni0413,uni0490" g2="guillemotright,guilsinglright" k="205" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0410" k="215" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0409,uni041B" k="256" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0408" k="276" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0402,uni040B,uni042A" k="-20" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni043B,uni0459" k="358" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0442" k="246" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0447" k="256" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni044A" k="307" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0443,uni045E" k="246" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0404,uni041E,uni0421,uni0424" k="41" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0405" k="31" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0430" k="266" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="276" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0455" k="266" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0414" k="195" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0417,uni042D" k="31" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni042F" k="82" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0431" k="82" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0434" k="340" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0436" k="246" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0437,uni044D" k="307" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="276" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0445" k="205" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni044F" k="256" />
+<hkern g1="uni0400,uni0401,uni0415" g2="uni0409,uni041B" k="41" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0410" k="20" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0409,uni041B" k="82" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0422" k="51" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0425" k="41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="colon,semicolon" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="guillemotright,guilsinglright" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0410" k="-31" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0409,uni041B" k="-31" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0408" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni043B,uni0459" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0443,uni045E" k="-61" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0414" k="-61" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0417,uni042D" k="-31" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni042F" k="-10" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0434" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0436" k="-41" />
+<hkern g1="uni0404,uni0421" g2="uni0408" k="20" />
+<hkern g1="uni0404,uni0421" g2="uni0425" k="31" />
+<hkern g1="uni040E,uni0423" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="317" />
+<hkern g1="uni040E,uni0423" g2="colon,semicolon" k="102" />
+<hkern g1="uni040E,uni0423" g2="uni0410" k="102" />
+<hkern g1="uni040E,uni0423" g2="uni0409,uni041B" k="184" />
+<hkern g1="uni040E,uni0423" g2="uni0408" k="184" />
+<hkern g1="uni040E,uni0423" g2="uni043B,uni0459" k="225" />
+<hkern g1="uni040E,uni0423" g2="uni0442" k="61" />
+<hkern g1="uni040E,uni0423" g2="uni0447" k="102" />
+<hkern g1="uni040E,uni0423" g2="uni044A" k="82" />
+<hkern g1="uni040E,uni0423" g2="uni0443,uni045E" k="123" />
+<hkern g1="uni040E,uni0423" g2="uni0404,uni041E,uni0421,uni0424" k="41" />
+<hkern g1="uni040E,uni0423" g2="uni0405" k="31" />
+<hkern g1="uni040E,uni0423" g2="uni0430" k="143" />
+<hkern g1="uni040E,uni0423" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="123" />
+<hkern g1="uni040E,uni0423" g2="uni0455" k="143" />
+<hkern g1="uni040E,uni0423" g2="uni0414" k="164" />
+<hkern g1="uni040E,uni0423" g2="uni042F" k="20" />
+<hkern g1="uni040E,uni0423" g2="uni0434" k="225" />
+<hkern g1="uni040E,uni0423" g2="uni0436" k="123" />
+<hkern g1="uni040E,uni0423" g2="uni0437,uni044D" k="184" />
+<hkern g1="uni040E,uni0423" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="123" />
+<hkern g1="uni040E,uni0423" g2="uni0445" k="123" />
+<hkern g1="uni040E,uni0423" g2="uni044F" k="102" />
+<hkern g1="uni040E,uni0423" g2="uni0416" k="41" />
+<hkern g1="uni0410" g2="quoteleft,quotedblleft" k="184" />
+<hkern g1="uni0410" g2="quoteright,quotedblright" k="184" />
+<hkern g1="uni0410" g2="uni0422" k="164" />
+<hkern g1="uni0410" g2="uni0402,uni040B,uni042A" k="61" />
+<hkern g1="uni0410" g2="uni0447" k="82" />
+<hkern g1="uni0410" g2="uni044A" k="102" />
+<hkern g1="uni0410" g2="uni0404,uni041E,uni0421,uni0424" k="20" />
+<hkern g1="uni0420" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="266" />
+<hkern g1="uni0420" g2="uni0410" k="102" />
+<hkern g1="uni0420" g2="uni0409,uni041B" k="123" />
+<hkern g1="uni0420" g2="uni0422" k="20" />
+<hkern g1="uni0420" g2="uni0408" k="164" />
+<hkern g1="uni0420" g2="uni043B,uni0459" k="123" />
+<hkern g1="uni0420" g2="uni0427" k="-20" />
+<hkern g1="uni0420" g2="uni0447" k="-10" />
+<hkern g1="uni0420" g2="uni0425" k="20" />
+<hkern g1="uni0420" g2="uni0405" k="-20" />
+<hkern g1="uni0420" g2="uni0430" k="20" />
+<hkern g1="uni0420" g2="uni0414" k="82" />
+<hkern g1="uni0402,uni040B" g2="quoteleft,quotedblleft" k="41" />
+<hkern g1="uni0402,uni040B" g2="quoteright,quotedblright" k="41" />
+<hkern g1="uni0402,uni040B" g2="hyphen,endash,emdash,afii00208" k="-41" />
+<hkern g1="uni0402,uni040B" g2="parenright,bracketright,braceright" k="102" />
+<hkern g1="uni0402,uni040B" g2="uni0422" k="123" />
+<hkern g1="uni0422" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="184" />
+<hkern g1="uni0422" g2="colon,semicolon" k="82" />
+<hkern g1="uni0422" g2="hyphen,endash,emdash,afii00208" k="102" />
+<hkern g1="uni0422" g2="guillemotleft,guilsinglleft" k="164" />
+<hkern g1="uni0422" g2="guillemotright,guilsinglright" k="143" />
+<hkern g1="uni0422" g2="uni0410" k="164" />
+<hkern g1="uni0422" g2="uni0409,uni041B" k="164" />
+<hkern g1="uni0422" g2="uni0408" k="143" />
+<hkern g1="uni0422" g2="uni043B,uni0459" k="276" />
+<hkern g1="uni0422" g2="uni0442" k="164" />
+<hkern g1="uni0422" g2="uni0447" k="164" />
+<hkern g1="uni0422" g2="uni044A" k="184" />
+<hkern g1="uni0422" g2="uni0443,uni045E" k="143" />
+<hkern g1="uni0422" g2="uni0404,uni041E,uni0421,uni0424" k="51" />
+<hkern g1="uni0422" g2="uni0425" k="20" />
+<hkern g1="uni0422" g2="uni0405" k="41" />
+<hkern g1="uni0422" g2="uni0430" k="205" />
+<hkern g1="uni0422" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="205" />
+<hkern g1="uni0422" g2="uni0455" k="205" />
+<hkern g1="uni0422" g2="uni0414" k="143" />
+<hkern g1="uni0422" g2="uni042F" k="20" />
+<hkern g1="uni0422" g2="uni0431" k="61" />
+<hkern g1="uni0422" g2="uni0434" k="215" />
+<hkern g1="uni0422" g2="uni0436" k="184" />
+<hkern g1="uni0422" g2="uni0437,uni044D" k="225" />
+<hkern g1="uni0422" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="184" />
+<hkern g1="uni0422" g2="uni0445" k="205" />
+<hkern g1="uni0422" g2="uni044F" k="184" />
+<hkern g1="uni0425" g2="uni0422" k="20" />
+<hkern g1="uni0425" g2="uni0404,uni041E,uni0421,uni0424" k="41" />
+<hkern g1="uni0425" g2="uni0405" k="20" />
+<hkern g1="uni0425" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="61" />
+<hkern g1="uni0405" g2="uni0409,uni041B" k="41" />
+<hkern g1="uni0405" g2="uni0422" k="41" />
+<hkern g1="uni0405" g2="uni0408" k="41" />
+<hkern g1="uni0405" g2="uni0442" k="41" />
+<hkern g1="uni0405" g2="uni0425" k="20" />
+<hkern g1="uni0405" g2="uni0434" k="31" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0442" k="31" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0443,uni045E" k="10" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0434" k="41" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0436" k="41" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0445" k="31" />
+<hkern g1="uni0433,uni0453,uni0491" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="205" />
+<hkern g1="uni0433,uni0453,uni0491" g2="colon,semicolon" k="-41" />
+<hkern g1="uni0433,uni0453,uni0491" g2="quoteleft,quotedblleft" k="-61" />
+<hkern g1="uni0433,uni0453,uni0491" g2="quoteright,quotedblright" k="-41" />
+<hkern g1="uni0433,uni0453,uni0491" g2="hyphen,endash,emdash,afii00208" k="102" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni043B,uni0459" k="143" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0442" k="-61" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni044A" k="-41" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0430" k="41" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="41" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0434" k="143" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0430" k="31" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="41" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0455" k="20" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0431" k="41" />
+<hkern g1="uni0434,uni0446,uni0449" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="uni0434,uni0446,uni0449" g2="colon,semicolon" k="-41" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni043B,uni0459" k="-31" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0443,uni045E" k="-51" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0434" k="-41" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0436" k="-20" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni043B,uni0459" k="31" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni0442" k="102" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni044A" k="123" />
+<hkern g1="uni0430" g2="uni0442" k="20" />
+<hkern g1="uni0430" g2="uni044A" k="41" />
+<hkern g1="uni0443,uni045E" g2="parenright,bracketright,braceright" k="61" />
+<hkern g1="uni0443,uni045E" g2="uni043B,uni0459" k="102" />
+<hkern g1="uni0443,uni045E" g2="uni0430" k="31" />
+<hkern g1="uni0443,uni045E" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="41" />
+<hkern g1="uni0443,uni045E" g2="uni0455" k="31" />
+<hkern g1="uni0443,uni045E" g2="uni0445" k="31" />
+<hkern g1="uni0443,uni045E" g2="uni044F" k="20" />
+<hkern g1="uni0442" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="123" />
+<hkern g1="uni0442" g2="uni043B,uni0459" k="102" />
+<hkern g1="uni0442" g2="uni0442" k="-41" />
+<hkern g1="uni0442" g2="uni044A" k="-41" />
+<hkern g1="uni0442" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="31" />
+<hkern g1="uni0445" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="31" />
+<hkern g1="uni0455" g2="uni0445" k="20" />
+<hkern g1="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" g2="chi" k="41" />
+<hkern g1="uni0408" g2="uni0410" k="20" />
+<hkern g1="uni0408" g2="uni0409,uni041B" k="41" />
+<hkern g1="uni0408" g2="uni0408" k="61" />
+<hkern g1="uni0408" g2="uni043B,uni0459" k="61" />
+<hkern g1="uni0408" g2="uni0425" k="20" />
+<hkern g1="uni0408" g2="uni0414" k="61" />
+<hkern g1="uni0408" g2="uni0434" k="82" />
+<hkern g1="V" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="82" />
+<hkern g1="V" g2="J,Jcircumflex" k="143" />
<hkern g1="V" g2="X" k="20" />
-<hkern g1="V" g2="Y,Yacute,Ydieresis" k="41" />
+<hkern g1="V" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
<hkern g1="V" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
-<hkern g1="V" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="20" />
-<hkern g1="V" g2="t" k="20" />
-<hkern g1="V" g2="z" k="41" />
-<hkern g1="V" g2="S" k="10" />
-<hkern g1="V" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="61" />
-<hkern g1="V" g2="m,n,p,r,ntilde" k="61" />
-<hkern g1="V" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="V" g2="s" k="61" />
-<hkern g1="V" g2="u,ugrave,uacute,ucircumflex,udieresis" k="61" />
+<hkern g1="V" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="20" />
+<hkern g1="V" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="V" g2="z,zacute,zdotaccent,zcaron" k="41" />
+<hkern g1="V" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="10" />
+<hkern g1="V" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="61" />
+<hkern g1="V" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="61" />
+<hkern g1="V" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="V" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="61" />
+<hkern g1="V" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="61" />
<hkern g1="V" g2="x" k="31" />
-<hkern g1="V" g2="y,yacute,ydieresis" k="20" />
-<hkern g1="V" g2="AE" k="41" />
-<hkern g1="V" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
-<hkern g1="V" g2="b,h,k,l,germandbls,thorn" k="31" />
+<hkern g1="V" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="20" />
+<hkern g1="V" g2="AE,AEacute" k="41" />
+<hkern g1="V" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
+<hkern g1="V" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="31" />
+<hkern g1="pi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="10" />
+<hkern g1="pi" g2="xi" k="31" />
+<hkern g1="pi" g2="lambda" k="41" />
+<hkern g1="pi" g2="epsilontonos,epsilon" k="41" />
+<hkern g1="pi" g2="zeta" k="20" />
+<hkern g1="pi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="41" />
<hkern g1="v" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
-<hkern g1="v" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="20" />
-<hkern g1="v" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="v" g2="s" k="20" />
-<hkern g1="v" g2="y,yacute,ydieresis" k="10" />
+<hkern g1="v" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="20" />
+<hkern g1="v" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="v" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="20" />
+<hkern g1="v" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="82" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="J,Jcircumflex" k="143" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-102" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="V" k="-102" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-92" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="X" k="-72" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="-82" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-82" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="Z,Zacute,Zdotaccent,Zcaron" k="-51" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="-61" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="B,D,E,F,H,K,L,M,N,P,R,Egrave,Eacute,Ecircumflex,Edieresis,Eth,Ntilde,Thorn,Dcaron,Dcroat,Emacron,Ebreve,Edotaccent,Eogonek,Ecaron,Hcircumflex,Hbar,Kcommaaccent,Lacute,Lcommaaccent,Lcaron,Ldot,Lslash,Nacute,Ncommaaccent,Ncaron,Eng,Racute,Rcommaaccent,Rcaron,Eszett,Edotbelow,Ehookabove,Etilde,Ecircumflexacute,Ecircumflexgrave,Ecircumflexhookabove,Ecircumflextilde,Ecircumflexdotbelow" k="-82" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="-82" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="z,zacute,zdotaccent,zcaron" k="-82" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="-20" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="-31" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="-20" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="-41" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="v" k="-61" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="-82" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="x" k="-82" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-82" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-92" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="-41" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="72" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="J,Jcircumflex" k="164" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-102" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="V" k="-102" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-82" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="X" k="-61" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="-102" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-61" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="Z,Zacute,Zdotaccent,Zcaron" k="-61" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="-61" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="B,D,E,F,H,K,L,M,N,P,R,Egrave,Eacute,Ecircumflex,Edieresis,Eth,Ntilde,Thorn,Dcaron,Dcroat,Emacron,Ebreve,Edotaccent,Eogonek,Ecaron,Hcircumflex,Hbar,Kcommaaccent,Lacute,Lcommaaccent,Lcaron,Ldot,Lslash,Nacute,Ncommaaccent,Ncaron,Eng,Racute,Rcommaaccent,Rcaron,Eszett,Edotbelow,Ehookabove,Etilde,Ecircumflexacute,Ecircumflexgrave,Ecircumflexhookabove,Ecircumflextilde,Ecircumflexdotbelow" k="-61" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="-82" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="z,zacute,zdotaccent,zcaron" k="-61" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="-20" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="-31" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="-10" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="-20" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="-20" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="v" k="-82" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="-61" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="x" k="-51" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-61" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-82" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="-61" />
+<hkern g1="longs" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="-41" />
+<hkern g1="longs" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="31" />
</font>
</defs></svg> \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.ttf b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.ttf
index 9efe37dc7..f90f1b600 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.ttf
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.ttf
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.woff b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.woff
index 184a945da..742fb6069 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.woff
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Bold-webfont.woff
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.eot b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.eot
index 0dc609d13..30cac5a77 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.eot
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.eot
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.svg b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.svg
index 1d5d2eceb..82cd2df55 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.svg
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.svg
@@ -3,21 +3,20 @@
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
-<font id="clear_sans_lightregular" horiz-adv-x="541" >
+<font id="clear_sans_lightregular" horiz-adv-x="1450" >
<font-face units-per-em="2048" ascent="1489" descent="-559" />
<missing-glyph horiz-adv-x="539" />
-<glyph unicode="&#xfb01;" horiz-adv-x="1110" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM772 1305q0 45 20 65.5t70 20.5 q51 0 71.5 -20t20.5 -66q0 -51 -21.5 -69.5t-70.5 -18.5q-51 0 -70.5 23t-19.5 65zM798 0v1049h129v-1049h-129z" />
-<glyph unicode="&#xfb02;" horiz-adv-x="1135" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM811 0v1489h129v-1489h-129z" />
-<glyph unicode="&#xfb03;" horiz-adv-x="1729" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM665 938v111h164v116q0 91 15 158t49.5 111 t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM1391 1305q0 45 20 65.5t70 20.5q51 0 71.5 -20t20.5 -66q0 -51 -21.5 -69.5t-70.5 -18.5 q-51 0 -70.5 23t-19.5 65zM1417 0v1049h129v-1049h-129z" />
-<glyph unicode="&#xfb04;" horiz-adv-x="1753" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM665 938v111h164v116q0 91 15 158t49.5 111 t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM1430 0v1489h129v-1489h-129z" />
-<glyph horiz-adv-x="0" />
-<glyph unicode="&#xd;" horiz-adv-x="539" />
+<glyph unicode="ff" horiz-adv-x="1239" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM665 938v111h164v116q0 91 15 158t49.5 111 t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164z" />
+<glyph unicode="fi" horiz-adv-x="1110" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM772 1305q0 45 20 65.5t70 20.5 q51 0 71.5 -20t20.5 -66q0 -51 -21.5 -69.5t-70.5 -18.5q-51 0 -70.5 23t-19.5 65zM798 0v1049h129v-1049h-129z" />
+<glyph unicode="fl" horiz-adv-x="1135" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM811 0v1489h129v-1489h-129z" />
+<glyph unicode="ffi" horiz-adv-x="1729" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM665 938v111h164v116q0 91 15 158t49.5 111 t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM1391 1305q0 45 20 65.5t70 20.5q51 0 71.5 -20t20.5 -66q0 -51 -21.5 -69.5t-70.5 -18.5 q-51 0 -70.5 23t-19.5 65zM1417 0v1049h129v-1049h-129z" />
+<glyph unicode="ffl" horiz-adv-x="1753" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM665 938v111h164v116q0 91 15 158t49.5 111 t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM1430 0v1489h129v-1489h-129z" />
<glyph horiz-adv-x="0" />
<glyph horiz-adv-x="0" />
<glyph unicode=" " horiz-adv-x="539" />
<glyph unicode="&#x09;" horiz-adv-x="539" />
<glyph unicode="&#xa0;" horiz-adv-x="539" />
-<glyph unicode="!" d="M168 78q0 49 23 70.5t77 21.5q57 0 80 -22t23 -70q0 -53 -25 -72.5t-78 -19.5q-29 0 -48.5 6t-31 18t-16 29t-4.5 39zM195 1384h149l-18 -1005h-107z" />
+<glyph unicode="!" horiz-adv-x="541" d="M168 78q0 49 23 70.5t77 21.5q57 0 80 -22t23 -70q0 -53 -25 -72.5t-78 -19.5q-29 0 -48.5 6t-31 18t-16 29t-4.5 39zM195 1384h149l-18 -1005h-107z" />
<glyph unicode="&#x22;" horiz-adv-x="892" d="M197 1452h166l-37 -520h-94zM529 1452h166l-37 -520h-94z" />
<glyph unicode="#" horiz-adv-x="1466" d="M119 397v95h289l108 399h-280v96h305l104 397h103l-105 -397h336l106 397h103l-105 -397h265v-96h-289l-107 -399h279v-95h-307l-107 -397h-102l104 397h-336l-106 -397h-101l105 397h-262zM508 492h340l108 399h-338z" />
<glyph unicode="$" horiz-adv-x="1255" d="M199 324l106 61q16 -32 40.5 -64t59 -59t81 -46.5t106.5 -25.5v476q-100 21 -169.5 50.5t-113 69t-63 89.5t-19.5 112t21 118.5t65.5 100.5t113.5 71.5t165 31.5v104h102v-104q72 -4 129.5 -21t103 -46t80.5 -69.5t64 -91.5l-108 -59q-19 37 -43.5 68t-57 55t-74.5 38.5 t-94 18.5v-438q78 -18 148 -43t122 -65t82.5 -98t30.5 -142q0 -81 -30 -142t-81.5 -102.5t-121.5 -63.5t-150 -26v-215h-102v215q-83 4 -146 28t-110 58.5t-80 75.5t-57 80zM356 989q0 -48 20 -81t53 -56t75.5 -38t87.5 -26v414q-66 -4 -111 -21t-73 -44.5t-40 -65 t-12 -82.5zM694 190q48 3 93.5 17t81 40.5t57.5 67.5t22 99q0 88 -61 142.5t-193 86.5v-453z" />
@@ -28,9 +27,9 @@
<glyph unicode=")" horiz-adv-x="797" d="M131 -395q193 213 282 449.5t89 506.5q0 275 -90.5 517t-280.5 440h145q88 -102 154 -210.5t110 -226t65.5 -247t21.5 -273.5q0 -147 -22 -274.5t-66 -243t-109.5 -223.5t-153.5 -215h-145z" />
<glyph unicode="*" horiz-adv-x="967" d="M123 1016l285 155l-285 156l45 78l272 -158l-4 273h92l-4 -273l275 158l45 -78l-287 -156l287 -155l-45 -78l-275 160l4 -273h-92l4 273l-272 -160z" />
<glyph unicode="+" horiz-adv-x="1427" d="M178 528v111h477v481h111v-481h481v-111h-481v-477h-111v477h-477z" />
-<glyph unicode="," d="M172 78q0 46 22 69t74 23q101 0 101 -115q0 -56 -10.5 -107.5t-26 -95t-34.5 -75.5t-36 -49h-76q20 22 35.5 54t26 67t15.5 71t5 66q-55 0 -75.5 22t-20.5 70z" />
+<glyph unicode="," horiz-adv-x="541" d="M172 78q0 46 22 69t74 23q101 0 101 -115q0 -56 -10.5 -107.5t-26 -95t-34.5 -75.5t-36 -49h-76q20 22 35.5 54t26 67t15.5 71t5 66q-55 0 -75.5 22t-20.5 70z" />
<glyph unicode="-" horiz-adv-x="848" d="M113 463v127h622v-127h-622z" />
-<glyph unicode="." d="M172 78q0 48 22 70t74 22q54 0 77.5 -21.5t23.5 -70.5q0 -53 -25 -72.5t-76 -19.5q-55 0 -75.5 23.5t-20.5 68.5z" />
+<glyph unicode="." horiz-adv-x="541" d="M172 78q0 48 22 70t74 22q54 0 77.5 -21.5t23.5 -70.5q0 -53 -25 -72.5t-76 -19.5q-55 0 -75.5 23.5t-20.5 68.5z" />
<glyph unicode="/" horiz-adv-x="952" d="M18 -299l727 1819h123l-729 -1819h-121z" />
<glyph unicode="0" horiz-adv-x="1255" d="M137 686q0 185 29.5 320.5t89.5 223.5t152.5 130.5t218.5 42.5t218.5 -42.5t153 -130.5t90 -223t29.5 -319q0 -368 -119.5 -543.5t-371.5 -175.5q-126 0 -218.5 42.5t-152.5 131t-89.5 223.5t-29.5 320zM281 686q0 -156 21 -269t63.5 -186t107.5 -108t154 -35 q88 0 153 35t108 108.5t64 186.5t21 270t-21 269.5t-64 185t-108 107t-153 34.5q-91 0 -156.5 -35t-107.5 -108.5t-62 -186.5t-20 -268z" />
<glyph unicode="1" horiz-adv-x="1255" d="M297 1004v112q80 4 142 27t107.5 59.5t75 83.5t44.5 98h98v-1384h-133v1128q-28 -30 -66 -53.5t-82 -39t-91.5 -23.5t-94.5 -8z" />
@@ -42,8 +41,8 @@
<glyph unicode="7" horiz-adv-x="1255" d="M152 1262v122h929v-129l-530 -1255h-150l543 1262h-792z" />
<glyph unicode="8" horiz-adv-x="1180" d="M121 346q0 140 82.5 234.5t245.5 156.5q-65 31 -119 61.5t-92.5 68.5t-60 86.5t-21.5 115.5q0 76 26.5 139.5t80.5 109t136 70.5t193 25q213 0 323.5 -87.5t110.5 -254.5q0 -73 -26.5 -126.5t-68.5 -93t-93.5 -67.5t-100.5 -49q72 -34 132 -69t102.5 -79.5t66 -102.5 t23.5 -138q0 -94 -32 -164t-92.5 -117t-147.5 -70.5t-197 -23.5q-236 0 -353.5 96t-117.5 279zM258 344q0 -120 82.5 -190t251.5 -70q170 0 251 70t81 192q0 58 -19.5 103t-60 83t-103 72.5t-147.5 73.5q-83 -30 -146 -63t-105 -73t-63.5 -88.5t-21.5 -109.5zM293 1073 q0 -39 13 -72t47 -65t93.5 -65.5t151.5 -73.5q73 27 127.5 55t91 60t54.5 69.5t18 85.5q0 52 -17.5 95t-54 73.5t-92.5 47.5t-133 17q-78 0 -134.5 -16.5t-93 -46.5t-54 -71.5t-17.5 -92.5z" />
<glyph unicode="9" horiz-adv-x="1180" d="M123 936q0 114 30.5 202.5t88 149.5t141 93t190.5 32q129 0 219 -45t146 -132.5t81 -216t25 -294.5q0 -104 -12.5 -200.5t-39.5 -180.5t-69 -152.5t-100.5 -117.5t-135.5 -76t-173 -27q-119 0 -206 40.5t-152 111.5l88 98q27 -30 56 -54t62 -41.5t71.5 -26.5t84.5 -9 q94 0 162.5 39t114.5 109t70.5 168t31.5 217q-29 -20 -67 -40t-83.5 -36t-97 -26.5t-106.5 -10.5q-95 0 -172.5 24.5t-132.5 76.5t-85 132.5t-30 192.5zM262 942q0 -90 22.5 -150t64 -95.5t98.5 -50.5t126 -15q39 0 82.5 8t86 21.5t83 31t74.5 37.5q0 135 -16.5 240.5 t-55 177.5t-101.5 109.5t-155 37.5q-79 0 -137 -25t-96.5 -71t-57 -111t-18.5 -145z" />
-<glyph unicode=":" d="M172 78q0 48 22 70t74 22q54 0 77.5 -21.5t23.5 -70.5q0 -53 -25 -72.5t-76 -19.5q-55 0 -75.5 23.5t-20.5 68.5zM172 956q0 50 22 71.5t74 21.5q54 0 77.5 -21.5t23.5 -71.5q0 -52 -25 -72t-76 -20q-55 0 -75.5 24.5t-20.5 67.5z" />
-<glyph unicode=";" d="M172 78q0 46 22 69t74 23q53 0 77 -28t24 -87q0 -56 -10.5 -107.5t-26 -95t-34.5 -75.5t-36 -49h-76q20 22 35.5 54t26 67t15.5 71t5 66q-55 0 -75.5 22t-20.5 70zM172 956q0 50 22 71.5t74 21.5q54 0 77.5 -21.5t23.5 -71.5q0 -52 -25 -72t-76 -20q-55 0 -75.5 24.5 t-20.5 67.5z" />
+<glyph unicode=":" horiz-adv-x="541" d="M172 78q0 48 22 70t74 22q54 0 77.5 -21.5t23.5 -70.5q0 -53 -25 -72.5t-76 -19.5q-55 0 -75.5 23.5t-20.5 68.5zM172 956q0 50 22 71.5t74 21.5q54 0 77.5 -21.5t23.5 -71.5q0 -52 -25 -72t-76 -20q-55 0 -75.5 24.5t-20.5 67.5z" />
+<glyph unicode=";" horiz-adv-x="541" d="M172 78q0 46 22 69t74 23q53 0 77 -28t24 -87q0 -56 -10.5 -107.5t-26 -95t-34.5 -75.5t-36 -49h-76q20 22 35.5 54t26 67t15.5 71t5 66q-55 0 -75.5 22t-20.5 70zM172 956q0 50 22 71.5t74 21.5q54 0 77.5 -21.5t23.5 -71.5q0 -52 -25 -72t-76 -20q-55 0 -75.5 24.5 t-20.5 67.5z" />
<glyph unicode="&#x3c;" horiz-adv-x="1427" d="M180 543v88l1067 454v-120l-897 -379l897 -377v-121z" />
<glyph unicode="=" horiz-adv-x="1427" d="M178 305v111h1069v-111h-1069zM178 756v110h1069v-110h-1069z" />
<glyph unicode="&#x3e;" horiz-adv-x="1427" d="M180 88v121l897 377l-897 379v120l1067 -454v-88z" />
@@ -111,7 +110,7 @@
<glyph unicode="|" horiz-adv-x="850" d="M367 -395v1915h116v-1915h-116z" />
<glyph unicode="}" horiz-adv-x="975" d="M100 -293h45q148 0 213.5 70.5t65.5 212.5v176q0 173 69.5 268t200.5 127q-129 35 -199.5 129.5t-70.5 267.5v175q0 140 -69.5 211t-209.5 71h-45v105h60q90 0 161 -25.5t120.5 -73.5t75.5 -116.5t26 -153.5v-170q0 -91 16.5 -159t53 -113.5t96 -68t145.5 -22.5h18v-110 h-18q-87 0 -146.5 -24t-96 -70t-52.5 -114.5t-16 -156.5v-170q0 -90 -26 -159t-75 -115.5t-120.5 -70t-161.5 -23.5h-60v102z" />
<glyph unicode="~" horiz-adv-x="1427" d="M164 631v125q85 68 159 98.5t136 30.5q61 0 127.5 -24.5t134 -54.5t132.5 -54.5t122 -24.5q39 0 75.5 11t72 29.5t70.5 44.5t71 56v-129q-29 -22 -60.5 -44t-67 -39.5t-75 -28.5t-84.5 -11q-40 0 -84.5 11.5t-91 29.5t-93.5 38t-91.5 38t-84.5 29.5t-73 11.5 q-41 0 -78.5 -11t-73.5 -30.5t-71 -45.5t-72 -56z" />
-<glyph unicode="&#xa1;" d="M168 987q0 51 25.5 71.5t76.5 20.5q30 0 49.5 -6.5t31 -18.5t16 -29t4.5 -38q0 -49 -22.5 -70.5t-78.5 -21.5q-55 0 -78.5 21.5t-23.5 70.5zM195 -395l20 1093h107l22 -1093h-149z" />
+<glyph unicode="&#xa1;" horiz-adv-x="541" d="M168 987q0 51 25.5 71.5t76.5 20.5q30 0 49.5 -6.5t31 -18.5t16 -29t4.5 -38q0 -49 -22.5 -70.5t-78.5 -21.5q-55 0 -78.5 21.5t-23.5 70.5zM195 -395l20 1093h107l22 -1093h-149z" />
<glyph unicode="&#xa2;" horiz-adv-x="1016" d="M129 520q0 128 24.5 231.5t77 176t135 112t199.5 39.5q33 0 68 -6l45 215h98l-51 -237q60 -22 106.5 -64.5t81.5 -107.5l-106 -64q-23 42 -49 71t-58 48l-180 -852q11 0 23 -1t24 -1q49 0 86.5 10.5t67.5 30.5t54 48.5t46 63.5l105 -65q-25 -47 -58 -84t-77 -62.5 t-99.5 -39t-124.5 -13.5q-18 0 -36 1t-35 3l-50 -233h-96l53 254q-76 24 -128 73.5t-84.5 118t-47 153.5t-14.5 181zM262 516q0 -152 37.5 -257t128.5 -150l180 854q-12 3 -24.5 3.5t-24.5 0.5q-155 0 -226 -114t-71 -337z" />
<glyph unicode="&#xa3;" horiz-adv-x="1255" d="M119 0v117q54 11 91 55.5t60.5 109.5t34 144.5t10.5 161.5h-172v104h168q-2 32 -12.5 68.5t-22 79t-21 92t-9.5 106.5q0 94 35 164t96.5 117t143.5 70.5t177 23.5q63 0 121.5 -11.5t111 -36.5t97.5 -65t82 -98l-111 -72q-47 74 -122.5 121t-178.5 47q-77 0 -135.5 -19.5 t-98 -55.5t-59.5 -86t-20 -111q0 -46 8.5 -91t20 -87t22 -81.5t13.5 -74.5h378v-104h-374q0 -164 -40.5 -286t-127.5 -185h850v-117h-1016z" />
<glyph unicode="&#xa4;" horiz-adv-x="1255" d="M137 1004l72 71l188 -188q51 40 109.5 60t120.5 20t120 -19t109 -59l188 186l72 -71l-186 -189q40 -51 59 -109t19 -120t-21 -119.5t-59 -108.5l186 -190l-70 -70l-190 187q-53 -41 -109 -58.5t-118 -17.5t-119.5 19.5t-108.5 56.5l-188 -187l-72 70l189 190 q-39 50 -58.5 108t-19.5 120t18.5 120.5t57.5 106.5zM362 586q0 -56 20.5 -104.5t56 -85.5t84 -58t104.5 -21q57 0 106 21t85.5 58t57.5 85.5t21 104.5q0 55 -20.5 104.5t-56.5 86.5t-85.5 59t-107.5 22q-57 0 -105.5 -21.5t-84 -58.5t-55.5 -86.5t-20 -105.5z" />
@@ -133,7 +132,7 @@
<glyph unicode="&#xb4;" horiz-adv-x="1106" d="M455 1208l186 361h178l-260 -361h-104z" />
<glyph unicode="&#xb5;" horiz-adv-x="1141" d="M166 -395v1444h131v-832q51 -59 117.5 -92t146.5 -33q76 0 146 42t129 120v795h131v-1049h-121l-10 123q-28 -35 -57.5 -63t-63.5 -48.5t-72.5 -31.5t-83.5 -11q-40 0 -74.5 5t-66 16.5t-61 30t-60.5 45.5v-461h-131z" />
<glyph unicode="&#xb6;" horiz-adv-x="1225" d="M68 1079q0 94 35 169.5t97 129t146.5 82.5t183.5 29h623v-107h-195v-1777h-122v1777h-211v-1777h-123v1059q-75 0 -152 23t-139.5 72.5t-102.5 128.5t-40 191z" />
-<glyph unicode="&#xb7;" d="M172 745q0 50 22 71.5t74 21.5q54 0 77.5 -21.5t23.5 -71.5q0 -52 -25 -72t-76 -20q-55 0 -75.5 24.5t-20.5 67.5z" />
+<glyph unicode="&#xb7;" horiz-adv-x="541" d="M172 745q0 50 22 71.5t74 21.5q54 0 77.5 -21.5t23.5 -71.5q0 -52 -25 -72t-76 -20q-55 0 -75.5 24.5t-20.5 67.5z" />
<glyph unicode="&#xb8;" horiz-adv-x="1106" d="M266 -348l39 80q18 -7 40.5 -13.5t47.5 -12t51 -8.5t52 -3q68 0 102.5 25t34.5 71q0 29 -14 50t-39 35.5t-59.5 22t-76.5 9.5l56 106h86l-25 -49q90 -18 133 -63.5t43 -114.5q0 -45 -18.5 -79.5t-51.5 -57t-77.5 -34t-95.5 -11.5q-32 0 -66 4.5t-65.5 11t-57 15 t-39.5 16.5z" />
<glyph unicode="&#xb9;" horiz-adv-x="883" d="M182 1249v88q61 2 106.5 15t78.5 35.5t53.5 52.5t30.5 67h92v-837h-119v649q-42 -34 -104.5 -52t-137.5 -18z" />
<glyph unicode="&#xba;" horiz-adv-x="817" d="M106 1051q0 78 16 144.5t52 115t94 75.5t142 27q82 0 139 -28t92.5 -76.5t51.5 -115t16 -142.5q0 -77 -16 -142.5t-51.5 -113.5t-92.5 -75.5t-139 -27.5q-83 0 -141 27.5t-94 75.5t-52.5 113.5t-16.5 142.5zM217 1051q0 -54 7 -102.5t27.5 -85t58 -58t98.5 -21.5 q60 0 97.5 21.5t58.5 58t28.5 85t7.5 102.5t-7.5 102.5t-28.5 86t-58.5 59.5t-97.5 22q-62 0 -99.5 -22t-57.5 -59.5t-27 -86t-7 -102.5z" />
@@ -206,43 +205,756 @@
<glyph unicode="&#xfd;" horiz-adv-x="1018" d="M4 -365l37 109q25 -14 61 -21.5t70 -7.5q75 0 129 59.5t98 176.5l41 104l-383 994h140l311 -832l315 832h138l-453 -1147q-32 -81 -67.5 -138t-76.5 -92t-89 -51t-105 -16q-21 0 -44.5 2t-46 6t-42 9.5t-33.5 12.5zM415 1208l186 361h178l-260 -361h-104z" />
<glyph unicode="&#xfe;" horiz-adv-x="1151" d="M182 -395v1884h129v-555q31 31 67.5 58t77 46t84.5 30t89 11q106 0 180.5 -42.5t121.5 -116.5t69 -173.5t22 -214.5q0 -123 -25 -226.5t-76 -178.5t-128.5 -116.5t-182.5 -41.5q-77 0 -153.5 34.5t-145.5 100.5v-499h-129zM311 225q69 -65 143.5 -104t145.5 -39 q62 0 115 26t91.5 80.5t60.5 138.5t22 201q0 101 -16.5 182t-51 137.5t-87.5 87t-126 30.5q-80 0 -154.5 -42.5t-142.5 -111.5v-586z" />
<glyph unicode="&#xff;" horiz-adv-x="1018" d="M4 -365l37 109q25 -14 61 -21.5t70 -7.5q75 0 129 59.5t98 176.5l41 104l-383 994h140l311 -832l315 832h138l-453 -1147q-32 -81 -67.5 -138t-76.5 -92t-89 -51t-105 -16q-21 0 -44.5 2t-46 6t-42 9.5t-33.5 12.5zM237 1300q0 45 18.5 67t69.5 22q53 0 71.5 -21.5 t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM607 1300q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x100;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM338 1591v111h580v-111h-580zM381 522h493l-247 731z" />
+<glyph unicode="&#x101;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM228 1255v111h580v-111h-580zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45 t-58.5 -71t-18.5 -102.5z" />
+<glyph unicode="&#x102;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM320 1794h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98zM381 522h493l-247 731z " />
+<glyph unicode="&#x103;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM206 1468h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5 t-55.5 83.5t-19 98zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5z" />
+<glyph unicode="&#x104;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384q-82 -27 -132.5 -53t-78 -51t-36.5 -49t-9 -46q0 -43 22 -63.5t60 -20.5q34 0 68 12.5t65 30.5l41 -82q-43 -32 -93 -48.5t-95 -16.5q-82 0 -129 43t-47 131q0 30 9 61t32 61t63 59.5t102 56.5l-124 374h-578l-135 -399h-142zM381 522h493 l-247 731z" />
+<glyph unicode="&#x105;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 q-81 -28 -131 -53.5t-77.5 -50.5t-36.5 -48.5t-9 -46.5q0 -43 22 -63.5t60 -20.5q34 0 68 12.5t65 30.5l41 -82q-43 -32 -93 -48.5t-95 -16.5q-82 0 -129 43t-47 131q0 32 10 64.5t36.5 64t71.5 61.5t115 58v117q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14 q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5z" />
+<glyph unicode="&#x106;" horiz-adv-x="1315" d="M145 692q0 174 34 308.5t105 226t180.5 139t260.5 47.5q97 0 173 -19t133.5 -54t100 -84t74.5 -109l-116 -74q-26 48 -58 87.5t-75.5 68.5t-100 45t-131.5 16q-118 0 -201 -39.5t-135 -116t-76 -187.5t-24 -255t24 -255t77 -187.5t137 -116t204 -39.5q84 0 145.5 20 t105.5 52t74.5 71.5t53.5 79.5l115 -71q-33 -59 -75 -109t-100 -87t-135.5 -58t-181.5 -21q-302 0 -445 181t-143 540zM609 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x107;" horiz-adv-x="1016" d="M129 520q0 128 24.5 231.5t77 176t135 112t199.5 39.5q124 0 207.5 -49t140.5 -151l-106 -64q-21 39 -45 67.5t-53.5 47t-65.5 28t-82 9.5q-157 0 -228 -114t-71 -337q0 -98 15.5 -178t51 -137.5t94 -89t144.5 -31.5q49 0 86.5 10.5t67.5 30.5t54 48.5t46 63.5l105 -65 q-25 -47 -58 -84t-77 -62.5t-99.5 -39t-124.5 -13.5q-123 0 -206.5 42t-135 115.5t-74 174.5t-22.5 219zM457 1208l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x108;" horiz-adv-x="1315" d="M145 692q0 174 34 308.5t105 226t180.5 139t260.5 47.5q97 0 173 -19t133.5 -54t100 -84t74.5 -109l-116 -74q-26 48 -58 87.5t-75.5 68.5t-100 45t-131.5 16q-118 0 -201 -39.5t-135 -116t-76 -187.5t-24 -255t24 -255t77 -187.5t137 -116t204 -39.5q84 0 145.5 20 t105.5 52t74.5 71.5t53.5 79.5l115 -71q-33 -59 -75 -109t-100 -87t-135.5 -58t-181.5 -21q-302 0 -445 181t-143 540zM408 1544l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x109;" horiz-adv-x="1016" d="M129 520q0 128 24.5 231.5t77 176t135 112t199.5 39.5q124 0 207.5 -49t140.5 -151l-106 -64q-21 39 -45 67.5t-53.5 47t-65.5 28t-82 9.5q-157 0 -228 -114t-71 -337q0 -98 15.5 -178t51 -137.5t94 -89t144.5 -31.5q49 0 86.5 10.5t67.5 30.5t54 48.5t46 63.5l105 -65 q-25 -47 -58 -84t-77 -62.5t-99.5 -39t-124.5 -13.5q-123 0 -206.5 42t-135 115.5t-74 174.5t-22.5 219zM250 1208l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x10a;" horiz-adv-x="1315" d="M145 692q0 174 34 308.5t105 226t180.5 139t260.5 47.5q97 0 173 -19t133.5 -54t100 -84t74.5 -109l-116 -74q-26 48 -58 87.5t-75.5 68.5t-100 45t-131.5 16q-118 0 -201 -39.5t-135 -116t-76 -187.5t-24 -255t24 -255t77 -187.5t137 -116t204 -39.5q84 0 145.5 20 t105.5 52t74.5 71.5t53.5 79.5l115 -71q-33 -59 -75 -109t-100 -87t-135.5 -58t-181.5 -21q-302 0 -445 181t-143 540zM615 1641q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x10b;" horiz-adv-x="1016" d="M129 520q0 128 24.5 231.5t77 176t135 112t199.5 39.5q124 0 207.5 -49t140.5 -151l-106 -64q-21 39 -45 67.5t-53.5 47t-65.5 28t-82 9.5q-157 0 -228 -114t-71 -337q0 -98 15.5 -178t51 -137.5t94 -89t144.5 -31.5q49 0 86.5 10.5t67.5 30.5t54 48.5t46 63.5l105 -65 q-25 -47 -58 -84t-77 -62.5t-99.5 -39t-124.5 -13.5q-123 0 -206.5 42t-135 115.5t-74 174.5t-22.5 219zM465 1305q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x10c;" horiz-adv-x="1315" d="M145 692q0 174 34 308.5t105 226t180.5 139t260.5 47.5q97 0 173 -19t133.5 -54t100 -84t74.5 -109l-116 -74q-26 48 -58 87.5t-75.5 68.5t-100 45t-131.5 16q-118 0 -201 -39.5t-135 -116t-76 -187.5t-24 -255t24 -255t77 -187.5t137 -116t204 -39.5q84 0 145.5 20 t105.5 52t74.5 71.5t53.5 79.5l115 -71q-33 -59 -75 -109t-100 -87t-135.5 -58t-181.5 -21q-302 0 -445 181t-143 540zM394 1905h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x10d;" horiz-adv-x="1016" d="M129 520q0 128 24.5 231.5t77 176t135 112t199.5 39.5q124 0 207.5 -49t140.5 -151l-106 -64q-21 39 -45 67.5t-53.5 47t-65.5 28t-82 9.5q-157 0 -228 -114t-71 -337q0 -98 15.5 -178t51 -137.5t94 -89t144.5 -31.5q49 0 86.5 10.5t67.5 30.5t54 48.5t46 63.5l105 -65 q-25 -47 -58 -84t-77 -62.5t-99.5 -39t-124.5 -13.5q-123 0 -206.5 42t-135 115.5t-74 174.5t-22.5 219zM248 1569h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x10e;" horiz-adv-x="1282" d="M186 0v1384h324q163 0 282.5 -35t198.5 -116t117.5 -213.5t38.5 -327.5q0 -203 -41.5 -336.5t-122 -212.5t-199 -111t-272.5 -32h-326zM293 1905h110l203 -264l203 264h110l-229 -361h-168zM322 123h176q136 0 232 28.5t156 95.5t87.5 176.5t27.5 270.5 q0 157 -26.5 265.5t-86 176t-155.5 97t-235 29.5h-176v-1139z" />
+<glyph unicode="&#x10f;" horiz-adv-x="1204" d="M129 516q0 109 23.5 210.5t73 180t126 125.5t183.5 47q90 0 163 -33.5t142 -87.5v531h129v-1489h-129v115q-32 -31 -69.5 -57.5t-78.5 -46t-85 -31t-89 -11.5q-98 0 -171 37t-121.5 107.5t-72.5 172t-24 230.5zM262 520q0 -99 15 -180t47.5 -138t83.5 -88.5t124 -31.5 q43 0 84.5 12.5t80.5 34t75 49.5t68 60v600q-75 60 -148 93.5t-145 33.5q-65 0 -118 -30.5t-90 -87.5t-57 -139.5t-20 -187.5zM1063 1128l80 361h162l-150 -361h-92z" />
+<glyph unicode="&#x110;" horiz-adv-x="1325" d="M63 641v109h130v634h331q169 0 293.5 -35t206 -116t121 -213.5t39.5 -327.5q0 -203 -43 -336.5t-127 -212.5t-207 -111t-283 -32h-331v641h-130zM328 123h184q142 0 242.5 28.5t164 95.5t92.5 176.5t29 270.5q0 157 -28 265.5t-91 176t-163.5 97t-245.5 29.5h-184v-512 h338v-109h-338v-518z" />
+<glyph unicode="&#x111;" horiz-adv-x="1151" d="M129 516q0 109 23.5 210.5t73 180t126 125.5t183.5 47q90 0 163 -33.5t142 -87.5v248h-297v109h297v174h129v-174h153v-109h-153v-1206h-129v115q-32 -31 -69.5 -57.5t-78.5 -46t-85 -31t-89 -11.5q-98 0 -171 37t-121.5 107.5t-72.5 172t-24 230.5zM262 520 q0 -99 15 -180t47.5 -138t83.5 -88.5t124 -31.5q43 0 84.5 12.5t80.5 34t75 49.5t68 60v600q-75 60 -148 93.5t-145 33.5q-65 0 -118 -30.5t-90 -87.5t-57 -139.5t-20 -187.5z" />
+<glyph unicode="&#x112;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM321 1591v111h580v-111h-580z" />
+<glyph unicode="&#x113;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5zM270 1255v111h580v-111h-580z" />
+<glyph unicode="&#x114;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM318 1804h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98z" />
+<glyph unicode="&#x115;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM246 1468h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98zM264 629h547q-3 177 -66 259.5t-196 82.5 q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5z" />
+<glyph unicode="&#x116;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM502 1641q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x117;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5zM452 1305q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z " />
+<glyph unicode="&#x118;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123q-82 -28 -132 -53.5t-77 -50.5t-36 -48.5t-9 -46.5q0 -43 21 -63.5t59 -20.5q34 0 68.5 12.5t66.5 30.5l41 -82q-45 -32 -94.5 -48.5t-96.5 -16.5q-80 0 -128 43t-48 131q0 27 7 54t25 54t49 53t79 52h-614z " />
+<glyph unicode="&#x119;" horiz-adv-x="1051" d="M129 516q0 121 20 224.5t68.5 178.5t130 117.5t205.5 42.5q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-14 -22 -29.5 -42.5t-34.5 -37.5q-34 -36 -65.5 -70 t-56 -68.5t-39.5 -69.5t-15 -73q0 -43 21 -61.5t61 -18.5q34 0 68 12.5t65 30.5l41 -82q-43 -32 -93.5 -48.5t-95.5 -16.5q-81 0 -128.5 42t-47.5 124q0 24 4 47.5t14.5 47t28.5 49t46 54.5q-23 -3 -48 -5.5t-53 -2.5q-107 0 -188 30t-135 95.5t-81.5 169.5t-27.5 252z M264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5z" />
+<glyph unicode="&#x11a;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM279 1905h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x11b;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM233 1569h110l203 -264l203 264h110l-229 -361h-168zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5z" />
+<glyph unicode="&#x11c;" horiz-adv-x="1378" d="M145 694q0 167 31 300t100 226t179 143t268 50q98 0 173 -19.5t131 -55t97 -84.5t72 -107l-115 -74q-27 53 -60.5 93.5t-77.5 68t-100 41.5t-126 14q-113 0 -194 -37.5t-133 -112.5t-76.5 -187t-24.5 -261q0 -140 23 -251t76 -188t139.5 -118t213.5 -41q42 0 81 4.5 t77 14t77.5 24t82.5 33.5v389h-369v123h504v-588q-58 -30 -109.5 -53t-104.5 -38.5t-112 -23.5t-131 -8q-164 0 -276.5 50.5t-183 144.5t-101.5 227.5t-31 300.5zM402 1544l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x11d;" horiz-adv-x="1151" d="M129 535q0 114 24 213t74.5 172.5t128 116t185.5 42.5q83 0 158 -32.5t141 -88.5v91h129v-1026q0 -111 -24 -190.5t-73.5 -130t-125.5 -74t-181 -23.5q-127 0 -220 29.5t-148 72.5l55 100q51 -42 128 -68t185 -26q75 0 127 17t85 53.5t48 94t15 138.5v127 q-30 -29 -66.5 -55t-78 -45.5t-86.5 -31t-93 -11.5q-101 0 -174 36t-120 104.5t-70 168t-23 226.5zM262 539q0 -79 9 -155.5t38 -136.5t83 -97t143 -37q46 0 88.5 13.5t81 35.5t72.5 49.5t63 54.5v574q-73 57 -143.5 91t-145.5 34q-76 0 -130.5 -31t-90 -87.5t-52 -135 t-16.5 -172.5zM275 1208l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x11e;" horiz-adv-x="1378" d="M145 694q0 167 31 300t100 226t179 143t268 50q98 0 173 -19.5t131 -55t97 -84.5t72 -107l-115 -74q-27 53 -60.5 93.5t-77.5 68t-100 41.5t-126 14q-113 0 -194 -37.5t-133 -112.5t-76.5 -187t-24.5 -261q0 -140 23 -251t76 -188t139.5 -118t213.5 -41q42 0 81 4.5 t77 14t77.5 24t82.5 33.5v389h-369v123h504v-588q-58 -30 -109.5 -53t-104.5 -38.5t-112 -23.5t-131 -8q-164 0 -276.5 50.5t-183 144.5t-101.5 227.5t-31 300.5zM404 1804h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5 t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98z" />
+<glyph unicode="&#x11f;" horiz-adv-x="1151" d="M129 535q0 114 24 213t74.5 172.5t128 116t185.5 42.5q83 0 158 -32.5t141 -88.5v91h129v-1026q0 -111 -24 -190.5t-73.5 -130t-125.5 -74t-181 -23.5q-127 0 -220 29.5t-148 72.5l55 100q51 -42 128 -68t185 -26q75 0 127 17t85 53.5t48 94t15 138.5v127 q-30 -29 -66.5 -55t-78 -45.5t-86.5 -31t-93 -11.5q-101 0 -174 36t-120 104.5t-70 168t-23 226.5zM252 1468h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5 t-19 98zM262 539q0 -79 9 -155.5t38 -136.5t83 -97t143 -37q46 0 88.5 13.5t81 35.5t72.5 49.5t63 54.5v574q-73 57 -143.5 91t-145.5 34q-76 0 -130.5 -31t-90 -87.5t-52 -135t-16.5 -172.5z" />
+<glyph unicode="&#x120;" horiz-adv-x="1378" d="M145 694q0 167 31 300t100 226t179 143t268 50q98 0 173 -19.5t131 -55t97 -84.5t72 -107l-115 -74q-27 53 -60.5 93.5t-77.5 68t-100 41.5t-126 14q-113 0 -194 -37.5t-133 -112.5t-76.5 -187t-24.5 -261q0 -140 23 -251t76 -188t139.5 -118t213.5 -41q42 0 81 4.5 t77 14t77.5 24t82.5 33.5v389h-369v123h504v-588q-58 -30 -109.5 -53t-104.5 -38.5t-112 -23.5t-131 -8q-164 0 -276.5 50.5t-183 144.5t-101.5 227.5t-31 300.5zM609 1641q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19 t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x121;" horiz-adv-x="1151" d="M129 535q0 114 24 213t74.5 172.5t128 116t185.5 42.5q83 0 158 -32.5t141 -88.5v91h129v-1026q0 -111 -24 -190.5t-73.5 -130t-125.5 -74t-181 -23.5q-127 0 -220 29.5t-148 72.5l55 100q51 -42 128 -68t185 -26q75 0 127 17t85 53.5t48 94t15 138.5v127 q-30 -29 -66.5 -55t-78 -45.5t-86.5 -31t-93 -11.5q-101 0 -174 36t-120 104.5t-70 168t-23 226.5zM262 539q0 -79 9 -155.5t38 -136.5t83 -97t143 -37q46 0 88.5 13.5t81 35.5t72.5 49.5t63 54.5v574q-73 57 -143.5 91t-145.5 34q-76 0 -130.5 -31t-90 -87.5t-52 -135 t-16.5 -172.5zM457 1305q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x122;" horiz-adv-x="1378" d="M145 694q0 167 31 300t100 226t179 143t268 50q98 0 173 -19.5t131 -55t97 -84.5t72 -107l-115 -74q-27 53 -60.5 93.5t-77.5 68t-100 41.5t-126 14q-113 0 -194 -37.5t-133 -112.5t-76.5 -187t-24.5 -261q0 -140 23 -251t76 -188t139.5 -118t213.5 -41q42 0 81 4.5 t77 14t77.5 24t82.5 33.5v389h-369v123h504v-588q-58 -30 -109.5 -53t-104.5 -38.5t-112 -23.5t-131 -8q-164 0 -276.5 50.5t-183 144.5t-101.5 227.5t-31 300.5zM645 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74 q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x123;" horiz-adv-x="1151" d="M129 535q0 114 24 213t74.5 172.5t128 116t185.5 42.5q83 0 158 -32.5t141 -88.5v91h129v-1026q0 -111 -24 -190.5t-73.5 -130t-125.5 -74t-181 -23.5q-127 0 -220 29.5t-148 72.5l55 100q51 -42 128 -68t185 -26q75 0 127 17t85 53.5t48 94t15 138.5v127 q-30 -29 -66.5 -55t-78 -45.5t-86.5 -31t-93 -11.5q-101 0 -174 36t-120 104.5t-70 168t-23 226.5zM262 539q0 -79 9 -155.5t38 -136.5t83 -97t143 -37q46 0 88.5 13.5t81 35.5t72.5 49.5t63 54.5v574q-73 57 -143.5 91t-145.5 34q-76 0 -130.5 -31t-90 -87.5t-52 -135 t-16.5 -172.5zM452 1272q0 37 8 68.5t22.5 59t33.5 52.5t41 49h73q-28 -35 -52 -74t-26 -79q53 0 75 -19t22 -72q0 -46 -22 -69t-75 -23q-51 0 -75.5 25.5t-24.5 81.5z" />
+<glyph unicode="&#x124;" horiz-adv-x="1341" d="M199 0v1384h135v-606h674v606h135v-1384h-135v655h-674v-655h-135zM359 1544l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x125;" horiz-adv-x="1137" d="M182 0v1489h129v-606q44 41 89 77t91.5 62.5t93.5 41.5t95 15q84 0 139 -25t87 -73.5t44.5 -119t12.5 -161.5v-700h-129v651q0 89 -8 148t-28 94t-54.5 49t-86.5 14q-69 0 -160 -51.5t-186 -142.5v-762h-129zM299 1544l229 361h168l229 -361h-110l-203 265l-203 -265 h-110z" />
+<glyph unicode="&#x126;" horiz-adv-x="1341" d="M41 1038v111h158v235h135v-235h674v235h135v-235h157v-111h-157v-1038h-135v655h-674v-655h-135v1038h-158zM334 778h674v260h-674v-260z" />
+<glyph unicode="&#x127;" horiz-adv-x="1137" d="M14 1206v109h168v174h129v-174h283v-109h-283v-323q44 41 89 77t91.5 62.5t93.5 41.5t95 15q84 0 139 -25t87 -73.5t44.5 -119t12.5 -161.5v-700h-129v651q0 89 -8 148t-28 94t-54.5 49t-86.5 14q-69 0 -160 -51.5t-186 -142.5v-762h-129v1206h-168z" />
+<glyph unicode="&#x128;" horiz-adv-x="719" d="M-4 1550q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -34.5t45 -34.5t44.5 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -34t-29 -104h-95zM102 0v119h189 v1147h-189v118h514v-118h-190v-1147h190v-119h-514z" />
+<glyph unicode="&#x129;" horiz-adv-x="494" d="M-114 1214q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -34.5t45 -34.5t44.5 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -34t-29 -104h-95zM182 0v1049h129 v-1049h-129z" />
+<glyph unicode="&#x12a;" horiz-adv-x="719" d="M73 1591v111h580v-111h-580zM102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514z" />
+<glyph unicode="&#x12b;" horiz-adv-x="494" d="M-44 1255v111h580v-111h-580zM182 0v1049h129v-1049h-129z" />
+<glyph unicode="&#x12c;" horiz-adv-x="719" d="M50 1804h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98zM102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514z" />
+<glyph unicode="&#x12d;" horiz-adv-x="494" d="M-64 1468h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98zM182 0v1049h129v-1049h-129z" />
+<glyph unicode="&#x12e;" horiz-adv-x="770" d="M102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119q-82 -28 -132 -53.5t-77 -50.5t-36 -48.5t-9 -46.5q0 -43 21 -63.5t59 -20.5q34 0 69 12.5t67 30.5l40 -82q-45 -32 -94.5 -48.5t-95.5 -16.5q-80 0 -128 43t-48 131q0 27 7 54t25 54t49 53t79 52h-310z" />
+<glyph unicode="&#x12f;" horiz-adv-x="512" d="M4 -213q0 69 42.5 132.5t135.5 107.5v1022h129v-1049q-106 -35 -152 -88t-46 -111q0 -43 21.5 -63.5t60.5 -20.5q34 0 68 12.5t65 30.5l41 -82q-44 -32 -94 -48.5t-95 -16.5q-81 0 -128.5 43t-47.5 131zM156 1305q0 45 20 65.5t70 20.5q51 0 71.5 -20t20.5 -66 q0 -51 -21.5 -69.5t-70.5 -18.5q-51 0 -70.5 23t-19.5 65z" />
+<glyph unicode="&#x130;" horiz-adv-x="719" d="M102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514zM257 1641q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x131;" horiz-adv-x="494" d="M182 0v1049h129v-1049h-129z" />
+<glyph unicode="&#x132;" horiz-adv-x="1495" d="M102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514zM697 18l51 119q17 -9 40.5 -17t49.5 -14.5t52.5 -10t49.5 -3.5q70 0 113.5 21.5t67.5 66t32 112.5t8 161v931h136v-989q0 -104 -18 -183.5t-59.5 -133.5t-110 -81.5t-169.5 -27.5q-31 0 -64.5 4 t-65.5 10.5t-61.5 15.5t-51.5 19z" />
+<glyph unicode="&#x133;" horiz-adv-x="1016" d="M156 1305q0 45 20 65.5t70 20.5q51 0 71.5 -20t20.5 -66q0 -51 -21.5 -69.5t-70.5 -18.5q-51 0 -70.5 23t-19.5 65zM182 0v1049h129v-1049h-129zM348 -365l32 107q36 -14 73 -21.5t79 -7.5q43 0 72 14t46 44t24.5 76.5t7.5 111.5v1090h129v-1104q0 -86 -13.5 -149.5 t-46 -106t-87.5 -63.5t-138 -21q-40 0 -86 7.5t-92 22.5zM655 1305q0 45 21.5 65.5t70.5 20.5q51 0 71.5 -20t20.5 -66q0 -51 -22 -69.5t-70 -18.5q-53 0 -72.5 23t-19.5 65z" />
+<glyph unicode="&#x134;" horiz-adv-x="864" d="M66 18l51 119q17 -9 40.5 -17t49.5 -14.5t52.5 -10t49.5 -3.5q70 0 113.5 21.5t67.5 66t32 112.5t8 161v931h136v-989q0 -104 -18 -183.5t-59.5 -133.5t-110 -81.5t-169.5 -27.5q-31 0 -64.5 4t-65.5 10.5t-61.5 15.5t-51.5 19zM283 1544l229 361h168l229 -361h-110 l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x135;" horiz-adv-x="508" d="M-141 -365l32 107q36 -14 73 -21.5t79 -7.5q43 0 72 14t46 44t24.5 76.5t7.5 111.5v1090h129v-1104q0 -86 -13.5 -149.5t-46 -106t-87.5 -63.5t-138 -21q-40 0 -86 7.5t-92 22.5zM-44 1208l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x136;" horiz-adv-x="1255" d="M199 0v1384h135v-739l661 739h170l-587 -649l612 -735h-176l-527 639l-153 -164v-475h-135zM532 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x137;" horiz-adv-x="1022" d="M182 0v1489h129v-973l469 533h160l-426 -471l449 -578h-162l-371 489l-119 -131v-358h-129zM420 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x138;" horiz-adv-x="1022" d="M182 0v1047h129v-531l414 479q22 26 49 44t74 20q15 0 42 -2t58 -10l-33 -107q-8 3 -18 5.5t-23 2.5q-21 0 -35.5 -9t-31.5 -26l-295 -333l451 -580h-162l-371 489l-119 -131v-358h-129z" />
+<glyph unicode="&#x139;" horiz-adv-x="1038" d="M199 0v1384h135v-1261h649v-123h-784zM450 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x13a;" horiz-adv-x="518" d="M155 1587l186 361h178l-260 -361h-104zM195 0v1489h129v-1489h-129z" />
+<glyph unicode="&#x13b;" horiz-adv-x="1038" d="M199 0v1384h135v-1261h649v-123h-784zM496 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x13c;" horiz-adv-x="518" d="M161 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71zM195 0v1489h129v-1489h-129z" />
+<glyph unicode="&#x13d;" horiz-adv-x="1038" d="M199 0v1384h135v-1261h649v-123h-784zM516 1025l80 361h162l-150 -361h-92z" />
+<glyph unicode="&#x13e;" horiz-adv-x="575" d="M195 0v1489h129v-1489h-129zM433 1128l80 361h162l-150 -361h-92z" />
+<glyph unicode="&#x13f;" horiz-adv-x="1038" d="M199 0v1384h135v-1261h649v-123h-784zM647 731q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x140;" horiz-adv-x="659" d="M195 0v1489h129v-1489h-129zM488 731q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x141;" horiz-adv-x="1038" d="M41 389v131l158 129v735h135v-636l262 215v-132l-262 -215v-493h649v-123h-784v518z" />
+<glyph unicode="&#x142;" horiz-adv-x="518" d="M41 530v129l154 121v709h129v-617l153 121v-129l-153 -121v-743h-129v651z" />
+<glyph unicode="&#x143;" horiz-adv-x="1374" d="M199 0v1384h196l647 -1165v1165h134v-1384h-160l-686 1235v-1235h-131zM578 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x144;" horiz-adv-x="1137" d="M182 0v1049h129v-166q45 43 90.5 79t92 62t93.5 40.5t95 14.5q84 0 138 -25t86 -73.5t44.5 -119t12.5 -161.5v-700h-129v651q0 88 -8 147t-28 94t-54.5 49.5t-86.5 14.5q-69 0 -160 -51.5t-186 -142.5v-762h-129zM465 1208l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x145;" horiz-adv-x="1374" d="M199 0v1384h196l647 -1165v1165h134v-1384h-160l-686 1235v-1235h-131zM602 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x146;" horiz-adv-x="1137" d="M182 0v1049h129v-166q45 43 90.5 79t92 62t93.5 40.5t95 14.5q84 0 138 -25t86 -73.5t44.5 -119t12.5 -161.5v-700h-129v651q0 88 -8 147t-28 94t-54.5 49.5t-86.5 14.5q-69 0 -160 -51.5t-186 -142.5v-762h-129zM473 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5 q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x147;" horiz-adv-x="1374" d="M199 0v1384h196l647 -1165v1165h134v-1384h-160l-686 1235v-1235h-131zM369 1905h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x148;" horiz-adv-x="1137" d="M182 0v1049h129v-166q45 43 90.5 79t92 62t93.5 40.5t95 14.5q84 0 138 -25t86 -73.5t44.5 -119t12.5 -161.5v-700h-129v651q0 88 -8 147t-28 94t-54.5 49.5t-86.5 14.5q-69 0 -160 -51.5t-186 -142.5v-762h-129zM260 1569h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x149;" horiz-adv-x="1235" d="M26 1319q0 48 22 71t74 23q57 0 79 -30.5t22 -86.5q0 -52 -9 -103.5t-24 -97t-34 -83t-38 -62.5h-76q20 27 35 64.5t25 76.5t15 75t5 61q-54 0 -75 21t-21 71zM280 0v1049h129v-166q45 43 90.5 79t92 62t93.5 40.5t95 14.5q84 0 138 -25t86 -73.5t44.5 -119t12.5 -161.5 v-700h-129v651q0 88 -8 147t-28 94t-54.5 49.5t-86.5 14.5q-69 0 -160 -51.5t-186 -142.5v-762h-129z" />
+<glyph unicode="&#x14a;" horiz-adv-x="1374" d="M199 0v1384h196l647 -1130v1130h134v-1407q0 -91 -16.5 -160.5t-54 -116.5t-99 -71t-152.5 -24q-25 0 -52.5 3t-55 8t-53 12t-46.5 16l39 110q35 -17 79.5 -27t92.5 -10q55 0 91 17.5t56.5 53t28.5 89.5t8 127l-712 1231v-1235h-131z" />
+<glyph unicode="&#x14b;" horiz-adv-x="1137" d="M182 0v1049h129v-166q45 43 90.5 79t91.5 62t93 40.5t96 14.5q81 0 135.5 -24t86.5 -71t45.5 -118.5t13.5 -165.5v-745q0 -91 -14.5 -157t-47.5 -109t-87.5 -63.5t-135.5 -20.5q-37 0 -85 7.5t-93 22.5l30 107q32 -14 71 -21.5t81 -7.5q43 0 72 13.5t47 43.5t25.5 77.5 t7.5 115.5v688q0 85 -7 143.5t-26.5 94.5t-54 51.5t-89.5 15.5q-35 0 -75.5 -13t-84.5 -38t-91 -61t-95 -82v-762h-129z" />
+<glyph unicode="&#x14c;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM389 1591v111h580v-111h-580z" />
+<glyph unicode="&#x14d;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30 q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM278 1255v111h580v-111h-580z" />
+<glyph unicode="&#x14e;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM367 1804h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5 t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98z" />
+<glyph unicode="&#x14f;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30 q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM265 1468h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5 t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98z" />
+<glyph unicode="&#x150;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM438 1544l195 361h174l-264 -361h-105zM754 1544l192 361h176l-264 -361h-104z" />
+<glyph unicode="&#x151;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30 q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM336 1208l195 361h174l-264 -361h-105zM652 1208l192 361h176l-264 -361h-104z" />
<glyph unicode="&#x152;" horiz-adv-x="1835" d="M139 692q0 168 29.5 301.5t98.5 226.5t181.5 143t278.5 50q60 0 115.5 -8t109.5 -21h746v-122h-633v-469h545v-123h-545v-547h633v-123h-744q-51 -14 -108 -21.5t-119 -7.5q-165 0 -277.5 50t-181.5 144t-99 227t-30 300zM285 692q0 -164 26.5 -278.5t81 -186 t138.5 -103.5t198 -32q51 0 104.5 8.5t94.5 24.5v1132q-41 16 -93 25.5t-106 9.5q-122 0 -207 -36t-137.5 -109.5t-76 -187t-23.5 -267.5z" />
<glyph unicode="&#x153;" horiz-adv-x="1792" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q135 0 228 -60.5t139 -166.5q45 112 134 169.5t222 57.5q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-673q-1 -110 12.5 -193t47.5 -139t91.5 -84t145.5 -28q41 0 76 7.5t66 25t58 45t53 67.5l105 -67 q-29 -45 -62.5 -80t-76 -59t-96.5 -37t-123 -13q-134 0 -226 51.5t-139 167.5q-51 -104 -141 -161.5t-226 -57.5q-119 0 -203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q86 0 144.5 32t94.5 89.5t51.5 138t15.5 178.5 q0 97 -14 179.5t-49 142.5t-94 93.5t-149 33.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM1006 629h546q-2 177 -64.5 259.5t-195.5 82.5q-71 0 -122.5 -20t-86 -61.5t-53.5 -106t-24 -154.5z" />
+<glyph unicode="&#x154;" horiz-adv-x="1212" d="M199 0v1384h393q114 0 200.5 -20t145.5 -65.5t89 -119t30 -180.5q0 -92 -19.5 -159.5t-57 -114.5t-92 -75.5t-124.5 -43.5l377 -606h-162l-354 586h-291v-586h-135zM334 707h250q94 0 157 15.5t101 49.5t54.5 88.5t16.5 132.5q0 73 -17 124.5t-55 84t-99.5 47.5 t-151.5 15h-256v-557zM502 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x155;" horiz-adv-x="797" d="M182 0v1049h129v-181q45 45 85.5 81.5t81 62t82 39.5t87.5 14q29 0 53 -5t45 -16l-28 -122q-35 14 -76 14q-48 0 -87.5 -12t-77.5 -36t-77.5 -59.5t-87.5 -83.5v-745h-129zM317 1208l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x156;" horiz-adv-x="1212" d="M199 0v1384h393q114 0 200.5 -20t145.5 -65.5t89 -119t30 -180.5q0 -92 -19.5 -159.5t-57 -114.5t-92 -75.5t-124.5 -43.5l377 -606h-162l-354 586h-291v-586h-135zM334 707h250q94 0 157 15.5t101 49.5t54.5 88.5t16.5 132.5q0 73 -17 124.5t-55 84t-99.5 47.5 t-151.5 15h-256v-557zM520 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x157;" horiz-adv-x="797" d="M153 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71zM182 0v1049h129v-181q45 45 85.5 81.5t81 62t82 39.5t87.5 14q29 0 53 -5t45 -16l-28 -122q-35 14 -76 14 q-48 0 -87.5 -12t-77.5 -36t-77.5 -59.5t-87.5 -83.5v-745h-129z" />
+<glyph unicode="&#x158;" horiz-adv-x="1212" d="M199 0v1384h393q114 0 200.5 -20t145.5 -65.5t89 -119t30 -180.5q0 -92 -19.5 -159.5t-57 -114.5t-92 -75.5t-124.5 -43.5l377 -606h-162l-354 586h-291v-586h-135zM289 1905h110l203 -264l203 264h110l-229 -361h-168zM334 707h250q94 0 157 15.5t101 49.5t54.5 88.5 t16.5 132.5q0 73 -17 124.5t-55 84t-99.5 47.5t-151.5 15h-256v-557z" />
+<glyph unicode="&#x159;" horiz-adv-x="797" d="M137 1569h110l203 -264l203 264h110l-229 -361h-168zM182 0v1049h129v-181q45 45 85.5 81.5t81 62t82 39.5t87.5 14q29 0 53 -5t45 -16l-28 -122q-35 14 -76 14q-48 0 -87.5 -12t-77.5 -36t-77.5 -59.5t-87.5 -83.5v-745h-129z" />
+<glyph unicode="&#x15a;" horiz-adv-x="1225" d="M111 248l116 69q20 -40 52 -79.5t78 -71.5t107.5 -52t141.5 -20q73 0 136.5 15t110.5 47t74 81.5t27 118.5q0 64 -21 108.5t-64 77t-109 56.5t-156 47q-120 31 -207 60.5t-144 71t-84.5 101t-27.5 150.5q0 86 28 157t84.5 121.5t141.5 78.5t199 28q86 0 156 -17.5 t126 -50t100 -78.5t79 -104l-113 -76q-26 45 -59 82.5t-75 64.5t-94.5 41.5t-117.5 14.5q-79 0 -138 -18t-98 -51t-58 -80t-19 -105q0 -56 17.5 -93.5t58.5 -65t109 -50t169 -47.5q107 -27 192 -58t144.5 -77t91 -113.5t31.5 -169.5q0 -107 -38 -181t-103 -121t-153 -68 t-188 -21q-105 0 -184 21t-138.5 57.5t-103 87.5t-77.5 111zM496 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x15b;" horiz-adv-x="973" d="M117 154l104 65q35 -63 98.5 -101t163.5 -38q52 0 97 8.5t78 29.5t52 56.5t19 89.5q0 42 -12 72.5t-42.5 54t-82.5 42.5t-133 40q-84 22 -144.5 47t-100 60.5t-58.5 85t-19 120.5q0 58 21.5 111.5t66 93.5t111.5 64t158 24q69 0 123.5 -15t96.5 -40.5t72 -59.5t50 -71 l-105 -62q-15 28 -36.5 53t-50 43.5t-65.5 29t-85 10.5q-107 0 -168.5 -47t-61.5 -132q0 -41 11 -70t37 -50.5t70.5 -38.5t111.5 -35q101 -27 170.5 -55t112 -65t61 -86.5t18.5 -119.5q0 -74 -25.5 -130t-74 -93.5t-118 -56.5t-157.5 -19q-81 0 -142 17.5t-105.5 44.5 t-73 59.5t-43.5 63.5zM401 1208l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x15c;" horiz-adv-x="1225" d="M111 248l116 69q20 -40 52 -79.5t78 -71.5t107.5 -52t141.5 -20q73 0 136.5 15t110.5 47t74 81.5t27 118.5q0 64 -21 108.5t-64 77t-109 56.5t-156 47q-120 31 -207 60.5t-144 71t-84.5 101t-27.5 150.5q0 86 28 157t84.5 121.5t141.5 78.5t199 28q86 0 156 -17.5 t126 -50t100 -78.5t79 -104l-113 -76q-26 45 -59 82.5t-75 64.5t-94.5 41.5t-117.5 14.5q-79 0 -138 -18t-98 -51t-58 -80t-19 -105q0 -56 17.5 -93.5t58.5 -65t109 -50t169 -47.5q107 -27 192 -58t144.5 -77t91 -113.5t31.5 -169.5q0 -107 -38 -181t-103 -121t-153 -68 t-188 -21q-105 0 -184 21t-138.5 57.5t-103 87.5t-77.5 111zM289 1544l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x15d;" horiz-adv-x="973" d="M117 154l104 65q35 -63 98.5 -101t163.5 -38q52 0 97 8.5t78 29.5t52 56.5t19 89.5q0 42 -12 72.5t-42.5 54t-82.5 42.5t-133 40q-84 22 -144.5 47t-100 60.5t-58.5 85t-19 120.5q0 58 21.5 111.5t66 93.5t111.5 64t158 24q69 0 123.5 -15t96.5 -40.5t72 -59.5t50 -71 l-105 -62q-15 28 -36.5 53t-50 43.5t-65.5 29t-85 10.5q-107 0 -168.5 -47t-61.5 -132q0 -41 11 -70t37 -50.5t70.5 -38.5t111.5 -35q101 -27 170.5 -55t112 -65t61 -86.5t18.5 -119.5q0 -74 -25.5 -130t-74 -93.5t-118 -56.5t-157.5 -19q-81 0 -142 17.5t-105.5 44.5 t-73 59.5t-43.5 63.5zM182 1208l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x15e;" horiz-adv-x="1225" d="M111 248l116 69q20 -40 52 -79.5t78 -71.5t107.5 -52t141.5 -20q73 0 136.5 15t110.5 47t74 81.5t27 118.5q0 64 -21 108.5t-64 77t-109 56.5t-156 47q-120 31 -207 60.5t-144 71t-84.5 101t-27.5 150.5q0 86 28 157t84.5 121.5t141.5 78.5t199 28q86 0 156 -17.5 t126 -50t100 -78.5t79 -104l-113 -76q-26 45 -59 82.5t-75 64.5t-94.5 41.5t-117.5 14.5q-79 0 -138 -18t-98 -51t-58 -80t-19 -105q0 -56 17.5 -93.5t58.5 -65t109 -50t169 -47.5q107 -27 192 -58t144.5 -77t91 -113.5t31.5 -169.5t-34.5 -174.5t-95 -119t-142 -70 t-175.5 -27.5l-2 -6q90 -18 133 -63.5t43 -114.5q0 -45 -18.5 -79.5t-51.5 -57t-77.5 -34t-95.5 -11.5q-32 0 -66 4.5t-65.5 11t-57 15t-39.5 16.5l39 80q18 -7 40.5 -13.5t47.5 -12t51 -8.5t52 -3q68 0 102.5 25t34.5 71q0 29 -14 50t-39 35.5t-59.5 22t-76.5 9.5l33 65 q-92 5 -162.5 27.5t-124.5 58.5t-94 84.5t-71 104.5z" />
+<glyph unicode="&#x15f;" horiz-adv-x="973" d="M117 154l104 65q35 -63 98.5 -101t163.5 -38q52 0 97 8.5t78 29.5t52 56.5t19 89.5q0 42 -12 72.5t-42.5 54t-82.5 42.5t-133 40q-84 22 -144.5 47t-100 60.5t-58.5 85t-19 120.5q0 58 21.5 111.5t66 93.5t111.5 64t158 24q69 0 123.5 -15t96.5 -40.5t72 -59.5t50 -71 l-105 -62q-15 28 -36.5 53t-50 43.5t-65.5 29t-85 10.5q-107 0 -168.5 -47t-61.5 -132q0 -41 11 -70t37 -50.5t70.5 -38.5t111.5 -35q101 -27 170.5 -55t112 -65t61 -86.5t18.5 -119.5q0 -71 -23 -124.5t-67 -91t-107.5 -58.5t-144.5 -25l-2 -4q90 -18 133 -63.5t43 -114.5 q0 -45 -18.5 -79.5t-51.5 -57t-77.5 -34t-96.5 -11.5q-32 0 -66 4.5t-65 11t-56.5 15t-39.5 16.5l39 80q18 -7 40.5 -13.5t47 -12t51 -8.5t51.5 -3q69 0 103.5 25t34.5 71q0 29 -14 50t-39 35.5t-59.5 22t-76.5 9.5l33 63q-68 6 -120 24.5t-90 44.5t-62.5 56t-38.5 58z" />
+<glyph unicode="&#x160;" horiz-adv-x="1225" d="M111 248l116 69q20 -40 52 -79.5t78 -71.5t107.5 -52t141.5 -20q73 0 136.5 15t110.5 47t74 81.5t27 118.5q0 64 -21 108.5t-64 77t-109 56.5t-156 47q-120 31 -207 60.5t-144 71t-84.5 101t-27.5 150.5q0 86 28 157t84.5 121.5t141.5 78.5t199 28q86 0 156 -17.5 t126 -50t100 -78.5t79 -104l-113 -76q-26 45 -59 82.5t-75 64.5t-94.5 41.5t-117.5 14.5q-79 0 -138 -18t-98 -51t-58 -80t-19 -105q0 -56 17.5 -93.5t58.5 -65t109 -50t169 -47.5q107 -27 192 -58t144.5 -77t91 -113.5t31.5 -169.5q0 -107 -38 -181t-103 -121t-153 -68 t-188 -21q-105 0 -184 21t-138.5 57.5t-103 87.5t-77.5 111zM283 1905h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x161;" horiz-adv-x="973" d="M117 154l104 65q35 -63 98.5 -101t163.5 -38q52 0 97 8.5t78 29.5t52 56.5t19 89.5q0 42 -12 72.5t-42.5 54t-82.5 42.5t-133 40q-84 22 -144.5 47t-100 60.5t-58.5 85t-19 120.5q0 58 21.5 111.5t66 93.5t111.5 64t158 24q69 0 123.5 -15t96.5 -40.5t72 -59.5t50 -71 l-105 -62q-15 28 -36.5 53t-50 43.5t-65.5 29t-85 10.5q-107 0 -168.5 -47t-61.5 -132q0 -41 11 -70t37 -50.5t70.5 -38.5t111.5 -35q101 -27 170.5 -55t112 -65t61 -86.5t18.5 -119.5q0 -74 -25.5 -130t-74 -93.5t-118 -56.5t-157.5 -19q-81 0 -142 17.5t-105.5 44.5 t-73 59.5t-43.5 63.5zM178 1569h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x162;" horiz-adv-x="1174" d="M43 1262v122h1085v-122h-475v-1262h-20l-17 -35q90 -18 133.5 -63.5t43.5 -114.5q0 -45 -19 -79.5t-52 -57t-77.5 -34t-95.5 -11.5q-32 0 -66 4.5t-65 11t-56.5 15t-39.5 16.5l38 80q38 -14 89 -25.5t102 -11.5q69 0 103 25t34 71q0 29 -14 50t-38.5 35.5t-59 22 t-74.5 9.5l47 92h-31v1262h-475z" />
+<glyph unicode="&#x163;" horiz-adv-x="723" d="M55 938v111h158v292h129v-292h276v-111h-276v-606q0 -73 7 -122t24.5 -78t47.5 -41.5t77 -12.5q35 0 76.5 8.5t70.5 19.5l33 -104q-32 -12 -71 -20.5t-83 -10.5q-14 -2 -27.5 -2h-25.5q-2 -2 -2 -3t-2 -3q90 -18 133 -62.5t43 -113.5q0 -45 -18.5 -79.5t-51.5 -57 t-77.5 -34t-96.5 -11.5q-32 0 -65.5 4.5t-64.5 11t-56.5 15t-40.5 16.5l39 80q37 -14 88 -25.5t102 -11.5q56 0 88.5 16.5t40.5 50.5q10 30 -6 58q-12 42 -55.5 62.5t-116.5 23.5l37 74q-49 11 -82.5 36.5t-54.5 66.5t-30 99t-9 135v621h-158z" />
+<glyph unicode="&#x164;" horiz-adv-x="1174" d="M43 1262v122h1085v-122h-475v-1262h-135v1262h-475zM273 1905h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x165;" horiz-adv-x="723" d="M55 938v111h158v292h129v-292h276v-111h-276v-606q0 -73 7 -122t24.5 -78t47.5 -41.5t77 -12.5q35 0 76.5 8.5t70.5 19.5l33 -104q-40 -14 -89 -23.5t-100 -9.5q-78 0 -131 19.5t-85 61.5t-46 108t-14 159v621h-158zM465 1128l80 361h162l-150 -361h-92z" />
+<glyph unicode="&#x166;" horiz-adv-x="1174" d="M43 1262v122h1085v-122h-475v-482h224v-108h-224v-672h-135v672h-221v108h221v482h-475z" />
+<glyph unicode="&#x167;" horiz-adv-x="723" d="M41 608v109h172v221h-158v111h158v292h129v-292h276v-111h-276v-221h279v-109h-279v-276q0 -73 7 -122t24.5 -78t47.5 -41.5t77 -12.5q35 0 76.5 8.5t70.5 19.5l33 -104q-40 -14 -89 -23.5t-100 -9.5q-78 0 -131 19.5t-85 61.5t-46 108t-14 159v291h-172z" />
+<glyph unicode="&#x168;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM340 1550q5 118 60 177t149 59 q37 0 68 -10.5t57 -26.5t49 -34.5t45 -34.5t44.5 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -34t-29 -104h-95z" />
+<glyph unicode="&#x169;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM202 1214q5 118 60 177t149 59q37 0 68 -10.5 t57 -26.5t49 -34.5t45 -34.5t44.5 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -34t-29 -104h-95z" />
+<glyph unicode="&#x16a;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM399 1591v111h580v-111h-580z " />
+<glyph unicode="&#x16b;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM272 1255v111h580v-111h-580z" />
+<glyph unicode="&#x16c;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM383 1804h98q12 -69 65 -106 t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98z" />
+<glyph unicode="&#x16d;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM258 1468h98q12 -69 65 -106t140 -37 q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98z" />
+<glyph unicode="&#x16e;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM512 1677q0 39 10.5 72.5 t32.5 57.5t56 37.5t81 13.5q94 0 138 -49.5t44 -131.5q0 -40 -11 -73t-33.5 -57t-56.5 -37t-81 -13q-49 0 -83.5 14t-56 38.5t-31 57t-9.5 70.5zM592 1677q0 -46 22 -75t78 -29q54 0 77 27.5t23 76.5q0 103 -100 103q-48 0 -74 -26.5t-26 -76.5z" />
+<glyph unicode="&#x16f;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM373 1341q0 39 10.5 72.5t32.5 57.5t56 37.5 t81 13.5q94 0 138 -49.5t44 -131.5q0 -40 -11 -73t-33.5 -57t-56.5 -37t-81 -13q-49 0 -83.5 14t-56 38.5t-31 57t-9.5 70.5zM453 1341q0 -46 22 -75t78 -29q54 0 77 27.5t23 76.5q0 103 -100 103q-48 0 -74 -26.5t-26 -76.5z" />
+<glyph unicode="&#x170;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM444 1544l195 361h174l-264 -361 h-105zM760 1544l192 361h176l-264 -361h-104z" />
+<glyph unicode="&#x171;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM327 1208l195 361h174l-264 -361h-105zM643 1208 l192 361h176l-264 -361h-104z" />
+<glyph unicode="&#x172;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -166 -24.5 -279t-78.5 -184q-38 -59 -64.5 -107t-42.5 -87t-23 -69.5t-7 -54.5q0 -43 20 -61.5t60 -18.5q34 0 68.5 12.5t66.5 30.5 l41 -82q-45 -32 -94.5 -48.5t-95.5 -16.5q-81 0 -128.5 42t-47.5 124q0 52 19 108t50 109q-45 -14 -97 -20.5t-114 -6.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283z" />
+<glyph unicode="&#x173;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049q-82 -28 -132 -53.5t-77 -50.5t-36 -48.5t-9 -46.5q0 -43 21 -63.5t59 -20.5q34 0 68.5 12.5t66.5 30.5l41 -82q-45 -32 -94.5 -48.5t-95.5 -16.5q-81 0 -128.5 43 t-47.5 131q0 32 10.5 64.5t36.5 64t71.5 61.5t116.5 58v131q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5z" />
+<glyph unicode="&#x174;" horiz-adv-x="1718" d="M80 1384h137l277 -1202l278 1202h168l287 -1212l278 1212h133l-325 -1384h-176l-281 1204l-283 -1204h-170zM545 1544l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x175;" horiz-adv-x="1430" d="M82 1049h133l186 -861l258 861h117l262 -861l181 861h129l-244 -1049h-125l-264 870l-264 -870h-125zM412 1208l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x176;" horiz-adv-x="1126" d="M51 1384h150l362 -720l367 720h145l-444 -847v-537h-137v530zM252 1544l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x177;" horiz-adv-x="1018" d="M4 -365l37 109q25 -14 61 -21.5t70 -7.5q75 0 129 59.5t98 176.5l41 104l-383 994h140l311 -832l315 832h138l-453 -1147q-32 -81 -67.5 -138t-76.5 -92t-89 -51t-105 -16q-21 0 -44.5 2t-46 6t-42 9.5t-33.5 12.5zM198 1208l229 361h168l229 -361h-110l-203 265 l-203 -265h-110z" />
<glyph unicode="&#x178;" horiz-adv-x="1126" d="M51 1384h150l362 -720l367 720h145l-444 -847v-537h-137v530zM291 1636q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM661 1636q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68q0 -48 -19.5 -69 t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x179;" horiz-adv-x="1171" d="M102 0v129l779 1133h-748v122h905v-122l-784 -1139h801v-123h-953zM461 1542l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x17a;" horiz-adv-x="936" d="M94 0v98l576 840h-564v111h719v-97l-577 -841h594v-111h-748zM362 1208l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x17b;" horiz-adv-x="1171" d="M102 0v129l779 1133h-748v122h905v-122l-784 -1139h801v-123h-953zM450 1639q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x17c;" horiz-adv-x="936" d="M94 0v98l576 840h-564v111h719v-97l-577 -841h594v-111h-748zM345 1305q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x17d;" horiz-adv-x="1171" d="M102 0v129l779 1133h-748v122h905v-122l-784 -1139h801v-123h-953zM246 1903h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x17e;" horiz-adv-x="936" d="M94 0v98l576 840h-564v111h719v-97l-577 -841h594v-111h-748zM143 1569h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x17f;" horiz-adv-x="559" d="M57 938v111h154v116q0 91 14.5 158t47.5 111t86 65t130 21q57 0 109.5 -14.5t87.5 -32.5l-43 -109q-13 8 -31 16t-38.5 14t-41.5 9.5t-40 3.5q-44 0 -73 -13t-46.5 -42t-25 -76t-7.5 -115v-1161h-129v938h-154z" />
+<glyph unicode="&#x192;" horiz-adv-x="1092" d="M-43 -356l31 100q37 -14 74.5 -22.5t80.5 -8.5q31 0 55 8.5t43.5 35.5t37 77.5t36.5 134.5l215 969h-190l25 111h190l51 213q15 66 36.5 114.5t52 80.5t71 47.5t94.5 15.5t103.5 -14.5t85.5 -28.5l-37 -111q-38 15 -76 28t-78 13q-25 0 -43.5 -6t-33.5 -24t-27.5 -50.5 t-24.5 -85.5l-45 -192h217l-22 -111h-220l-231 -1047q-14 -61 -33.5 -114t-50.5 -92t-77 -61.5t-113 -22.5q-54 0 -105.5 12t-91.5 31z" />
+<glyph unicode="&#x1a0;" horiz-adv-x="1452" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5q103 0 183.5 -23.5t142 -68.5t104 -110.5t68.5 -149.5h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-29q23 -121 23 -264q0 -167 -29 -300.5t-94 -227 t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5 t-21 -256.5z" />
+<glyph unicode="&#x1a1;" horiz-adv-x="1190" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q82 0 148 -20t116 -58t85.5 -92t56.5 -123q70 1 99.5 46.5t29.5 146.5v151h121v-151q0 -71 -12.5 -124.5t-39.5 -90.5t-70.5 -57.5t-105.5 -24.5q7 -37 10 -77.5t3 -82.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5 t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5z" />
+<glyph unicode="&#x1af;" horiz-adv-x="1456" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-323h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-55v-378q0 -170 -26 -286.5 t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283z" />
+<glyph unicode="&#x1b0;" horiz-adv-x="1208" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-263h31q76 0 107.5 44.5t31.5 148.5v151h121v-151q0 -74 -13.5 -129.5t-43.5 -93t-78.5 -56t-118.5 -18.5h-37v-682h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41 t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5z" />
+<glyph unicode="&#x1cd;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM320 1905h110l203 -265l203 265h110l-229 -361h-168zM381 522h493l-247 731z" />
+<glyph unicode="&#x1ce;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM218 1569h110l203 -264l203 264h110l-229 -361h-168zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18 q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5z" />
+<glyph unicode="&#x1cf;" horiz-adv-x="719" d="M46 1905h110l203 -265l203 265h110l-229 -361h-168zM102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514z" />
+<glyph unicode="&#x1d0;" horiz-adv-x="494" d="M-66 1569h110l203 -264l203 264h110l-229 -361h-168zM182 0v1049h129v-1049h-129z" />
+<glyph unicode="&#x1d1;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM369 1905h110l203 -265l203 265h110l-229 -361h-168z" />
+<glyph unicode="&#x1d2;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM256 1569h110l203 -264l203 264h110l-229 -361h-168z M262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5z" />
+<glyph unicode="&#x1d3;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM375 1905h110l203 -265l203 265 h110l-229 -361h-168z" />
+<glyph unicode="&#x1d4;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM254 1569h110l203 -264l203 264h110l-229 -361 h-168z" />
+<glyph unicode="&#x1d5;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM397 1794v111h579v-111h-579z M413 1606q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 24.5t-18.5 65.5zM786 1606q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z" />
+<glyph unicode="&#x1d6;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM277 1458v111h579v-111h-579zM293 1270 q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 25t-18.5 65zM666 1270q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z" />
+<glyph unicode="&#x1d7;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM411 1606q0 45 19 66.5t71 21.5 q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 24.5t-18.5 65.5zM620 1735l135 293h170l-202 -293h-103zM784 1606q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z" />
+<glyph unicode="&#x1d8;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM291 1270q0 45 19 66.5t71 21.5q53 0 72 -21 t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 25t-18.5 65zM500 1399l135 293h170l-202 -293h-103zM664 1270q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z" />
+<glyph unicode="&#x1d9;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM374 2028h111l203 -189l202 189 h111l-233 -285h-162zM413 1606q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 24.5t-18.5 65.5zM786 1606q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z" />
+<glyph unicode="&#x1da;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM254 1692h111l203 -189l202 189h111l-233 -285 h-162zM293 1270q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 25t-18.5 65zM666 1270q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z" />
+<glyph unicode="&#x1db;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM411 1606q0 45 19 66.5t71 21.5 q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 24.5t-18.5 65.5zM448 2028h170l135 -293h-102zM784 1606q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z" />
+<glyph unicode="&#x1dc;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM291 1270q0 45 19 66.5t71 21.5q53 0 72 -21 t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 25t-18.5 65zM328 1692h170l135 -293h-102zM664 1270q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z" />
+<glyph unicode="&#x1fa;" horiz-adv-x="1288" d="M63 0l463 1337q-42 23 -59.5 64t-17.5 92q0 39 10.5 72t32.5 57t56 37.5t81 13.5q94 0 138 -49t44 -131q0 -53 -19 -92.5t-61 -61.5l469 -1339h-147l-135 399h-578l-135 -399h-142zM381 522h493l-247 731zM530 1497q0 -46 22.5 -75t76.5 -29t78 27.5t24 76.5 q0 53 -25.5 77.5t-76.5 24.5q-47 0 -73 -26t-26 -76zM571 1729l134 276h178l-207 -276h-105z" />
+<glyph unicode="&#x1fb;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM345 1339 q0 39 10.5 72.5t32.5 57.5t56 37.5t81 13.5q94 0 138 -49.5t44 -131.5q0 -40 -11 -73t-33.5 -57t-56.5 -37t-81 -13q-49 0 -83.5 14t-56 38.5t-31 57t-9.5 70.5zM425 1339q0 -46 22 -75t78 -29q54 0 77 27.5t23 76.5q0 103 -100 103q-48 0 -74 -26.5t-26 -76.5zM438 1599 l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x1fc;" horiz-adv-x="1714" d="M57 0l521 1384h999v-122h-623v-467h555v-123h-555v-549h623v-123h-758v393h-477l-145 -393h-140zM387 516h432v746h-157zM848 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x1fd;" horiz-adv-x="1694" d="M121 299q0 84 25.5 144t77.5 101t130.5 64.5t184.5 32.5l237 21v59q0 69 -18 116t-53 76t-86 41.5t-117 12.5q-101 0 -163.5 -36.5t-94.5 -92.5l-103 63q25 40 56.5 73t75 56t102 36t137.5 13q63 0 118 -9.5t100 -30.5t79 -54.5t55 -81.5q47 81 130 128.5t198 47.5 q108 0 182.5 -32.5t120.5 -93t66 -148t20 -197.5v-84h-676q0 -95 12.5 -176t46 -140.5t91.5 -93.5t149 -34q45 0 81 9.5t66 28t56 45.5t51 62l103 -67q-28 -45 -60.5 -80t-74.5 -59t-96 -37t-124 -13q-127 0 -220 48.5t-142 142.5q-45 -37 -96 -71.5t-106.5 -61t-115 -42.5 t-123.5 -16q-68 0 -120.5 24t-88.5 67.5t-54.5 104.5t-18.5 134zM254 295q0 -109 49.5 -161t134.5 -52q48 0 94 13.5t91 37t90.5 55t91.5 68.5q-16 48 -22.5 125.5t-6.5 173.5l-188 -16q-86 -7 -149 -21.5t-104 -42.5t-61 -71.5t-20 -108.5zM756 1208l186 361h178l-260 -361 h-104zM907 629h547q-3 175 -65.5 258.5t-198.5 83.5q-62 0 -112 -20.5t-87 -62.5t-58.5 -106.5t-25.5 -152.5z" />
+<glyph unicode="&#x1fe;" horiz-adv-x="1364" d="M63 -115l195 281q-66 93 -94.5 225.5t-28.5 300.5q0 166 29.5 299.5t94.5 227t169 144t254 50.5q118 0 206.5 -31t151.5 -90l140 197h116l-190 -272q65 -94 94 -226t29 -299t-29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50q-118 0 -206.5 30.5t-151.5 90.5l-144 -207 h-117zM279 692q0 -127 16 -226.5t51 -174.5l617 887q-48 55 -117.5 83.5t-163.5 28.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM401 205q51 -56 118 -83.5t163 -27.5q111 0 188 39.5t124 115.5t68 187.5t21 255.5q0 124 -16 222.5t-51 172.5zM586 1544 l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x1ff;" horiz-adv-x="1141" d="M96 -76l137 195q-55 72 -79.5 174t-24.5 229q0 122 24 224.5t77 176.5t137 115t204 41q173 0 277 -92l96 137h113l-146 -204q51 -73 76 -173.5t25 -224.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5q-88 0 -155 21t-117 63l-92 -129h-111zM262 522 q0 -91 11.5 -164t37.5 -129l467 658q-38 42 -89.5 61t-117.5 19q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM369 152q38 -39 87.5 -55.5t114.5 -16.5q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 87 -10.5 158t-35.5 125zM461 1208l186 361h178l-260 -361h-104z " />
+<glyph unicode="&#x218;" horiz-adv-x="1225" d="M111 248l116 69q20 -40 52 -79.5t78 -71.5t107.5 -52t141.5 -20q73 0 136.5 15t110.5 47t74 81.5t27 118.5q0 64 -21 108.5t-64 77t-109 56.5t-156 47q-120 31 -207 60.5t-144 71t-84.5 101t-27.5 150.5q0 86 28 157t84.5 121.5t141.5 78.5t199 28q86 0 156 -17.5 t126 -50t100 -78.5t79 -104l-113 -76q-26 45 -59 82.5t-75 64.5t-94.5 41.5t-117.5 14.5q-79 0 -138 -18t-98 -51t-58 -80t-19 -105q0 -56 17.5 -93.5t58.5 -65t109 -50t169 -47.5q107 -27 192 -58t144.5 -77t91 -113.5t31.5 -169.5q0 -107 -38 -181t-103 -121t-153 -68 t-188 -21q-105 0 -184 21t-138.5 57.5t-103 87.5t-77.5 111zM526 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x219;" horiz-adv-x="973" d="M117 154l104 65q35 -63 98.5 -101t163.5 -38q52 0 97 8.5t78 29.5t52 56.5t19 89.5q0 42 -12 72.5t-42.5 54t-82.5 42.5t-133 40q-84 22 -144.5 47t-100 60.5t-58.5 85t-19 120.5q0 58 21.5 111.5t66 93.5t111.5 64t158 24q69 0 123.5 -15t96.5 -40.5t72 -59.5t50 -71 l-105 -62q-15 28 -36.5 53t-50 43.5t-65.5 29t-85 10.5q-107 0 -168.5 -47t-61.5 -132q0 -41 11 -70t37 -50.5t70.5 -38.5t111.5 -35q101 -27 170.5 -55t112 -65t61 -86.5t18.5 -119.5q0 -74 -25.5 -130t-74 -93.5t-118 -56.5t-157.5 -19q-81 0 -142 17.5t-105.5 44.5 t-73 59.5t-43.5 63.5zM401 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x21a;" horiz-adv-x="1174" d="M43 1262v122h1085v-122h-475v-1262h-135v1262h-475zM494 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x21b;" horiz-adv-x="723" d="M55 938v111h158v292h129v-292h276v-111h-276v-606q0 -73 7 -122t24.5 -78t47.5 -41.5t77 -12.5q35 0 76.5 8.5t70.5 19.5l33 -104q-40 -14 -89 -23.5t-100 -9.5q-78 0 -131 19.5t-85 61.5t-46 108t-14 159v621h-158zM352 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5 q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#x237;" horiz-adv-x="508" d="M-141 -365l32 107q36 -14 73 -21.5t79 -7.5q43 0 72 14t46 44t24.5 76.5t7.5 111.5v1090h129v-1104q0 -86 -13.5 -149.5t-46 -106t-87.5 -63.5t-138 -21q-40 0 -86 7.5t-92 22.5z" />
+<glyph unicode="&#x2c0;" horiz-adv-x="967" d="M27 1225q21 39 56.5 73t84 59.5t110 40.5t136.5 15q93 0 172.5 -23.5t138 -71t92 -118.5t33.5 -166q0 -90 -29 -162t-83 -133.5t-130.5 -116.5t-171.5 -112v-510h-131v567q107 59 184 111.5t127 106t73.5 112t23.5 129.5q0 61 -19.5 110.5t-57.5 85t-93.5 55t-126.5 19.5 q-59 0 -104 -12t-79.5 -31.5t-58.5 -44.5t-39 -51z" />
<glyph unicode="&#x2c6;" horiz-adv-x="1106" d="M240 1208l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x2c7;" horiz-adv-x="1106" d="M240 1569h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x2c9;" horiz-adv-x="1106" d="M262 1255v111h580v-111h-580z" />
+<glyph unicode="&#x2d8;" horiz-adv-x="1106" d="M242 1468h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98z" />
+<glyph unicode="&#x2d9;" horiz-adv-x="1106" d="M457 1305q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x2da;" horiz-adv-x="1106" d="M371 1339q0 39 10.5 72.5t32.5 57.5t56 37.5t81 13.5q94 0 138 -49.5t44 -131.5q0 -40 -11 -73t-33.5 -57t-56.5 -37t-81 -13q-49 0 -83.5 14t-56 38.5t-31 57t-9.5 70.5zM451 1339q0 -46 22 -75t78 -29q54 0 77 27.5t23 76.5q0 103 -100 103q-48 0 -74 -26.5t-26 -76.5z " />
+<glyph unicode="&#x2db;" horiz-adv-x="872" d="M270 -213q0 37 14 73.5t50 72t96.5 68t153.5 60.5l49 -61q-81 -28 -131 -53.5t-77.5 -50.5t-36.5 -48.5t-9 -46.5q0 -43 22 -63.5t60 -20.5q34 0 68 12.5t65 30.5l41 -82q-43 -32 -93.5 -48.5t-95.5 -16.5q-81 0 -128.5 43t-47.5 131z" />
<glyph unicode="&#x2dc;" horiz-adv-x="1106" d="M190 1214q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -34.5t45 -34.5t44.5 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -34t-29 -104h-95z" />
-<glyph unicode="&#x2000;" horiz-adv-x="952" />
-<glyph unicode="&#x2001;" horiz-adv-x="1905" />
-<glyph unicode="&#x2002;" horiz-adv-x="952" />
-<glyph unicode="&#x2003;" horiz-adv-x="1905" />
-<glyph unicode="&#x2004;" horiz-adv-x="635" />
-<glyph unicode="&#x2005;" horiz-adv-x="476" />
-<glyph unicode="&#x2006;" horiz-adv-x="317" />
-<glyph unicode="&#x2007;" horiz-adv-x="317" />
-<glyph unicode="&#x2008;" horiz-adv-x="238" />
-<glyph unicode="&#x2009;" horiz-adv-x="381" />
-<glyph unicode="&#x200a;" horiz-adv-x="105" />
+<glyph unicode="&#x2dd;" horiz-adv-x="1106" d="M264 1208l195 361h174l-264 -361h-105zM580 1208l192 361h176l-264 -361h-104z" />
+<glyph unicode="&#x300;" horiz-adv-x="0" d="M-244 1569h178l187 -361h-105z" />
+<glyph unicode="&#x301;" horiz-adv-x="0" d="M-121 1208l187 361h176l-258 -361h-105z" />
+<glyph unicode="&#x302;" horiz-adv-x="0" d="M-313 1208l229 361h168l229 -361h-110l-203 265l-203 -265h-110z" />
+<glyph unicode="&#x303;" horiz-adv-x="0" d="M-362 1214q5 118 59.5 177t148.5 59q37 0 68 -10.5t57 -26.5t48.5 -34.5t45 -34.5t45 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-42 0 -74 11t-57 27t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -34t-29 -104h-94z" />
+<glyph unicode="&#x304;" horiz-adv-x="0" d="M-291 1255v111h580v-111h-580z" />
+<glyph unicode="&#x306;" horiz-adv-x="0" d="M-311 1468h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98z" />
+<glyph unicode="&#x307;" horiz-adv-x="0" d="M-96 1305q0 48 21 72t75 24q56 0 76 -23.5t20 -72.5q0 -53 -21.5 -74t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 39.5z" />
+<glyph unicode="&#x308;" horiz-adv-x="0" d="M-276 1300q0 45 18.5 67t71.5 22q52 0 71 -21t19 -68q0 -48 -19.5 -69t-70.5 -21q-54 0 -72 25t-18 65zM96 1300q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x309;" horiz-adv-x="0" d="M-170 1432q12 9 29.5 18t39 15.5t46.5 11t51 4.5q87 0 133.5 -35.5t46.5 -97.5q0 -66 -39.5 -102t-111.5 -44v-41h-82v107h28q92 0 92 65q0 29 -18 45.5t-63 16.5q-26 0 -54.5 -8t-56.5 -25z" />
+<glyph unicode="&#x30a;" horiz-adv-x="0" d="M-178 1335q0 39 10 71t31.5 55.5t55 36.5t79.5 13q91 0 134.5 -47.5t43.5 -128.5q0 -78 -43 -127t-135 -49q-48 0 -81.5 13.5t-54.5 37.5t-30.5 56t-9.5 69zM-104 1335q0 -48 22.5 -77t79.5 -29q56 0 80 27.5t24 78.5q0 107 -104 107q-50 0 -76 -28t-26 -79z" />
+<glyph unicode="&#x30c;" horiz-adv-x="0" d="M-313 1569h110l203 -264l203 264h110l-229 -361h-168z" />
+<glyph unicode="&#x323;" horiz-adv-x="1106" d="M457 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x374;" horiz-adv-x="410" d="M88 1024l80 360h164l-150 -360h-94z" />
+<glyph unicode="&#x375;" horiz-adv-x="410" d="M82 -231l147 360h95l-78 -360h-164z" />
+<glyph unicode="&#x37e;" horiz-adv-x="541" d="M172 78q0 46 22 69t74 23q53 0 77 -28t24 -87q0 -56 -10.5 -107.5t-26 -95t-34.5 -75.5t-36 -49h-76q20 22 35.5 54t26 67t15.5 71t5 66q-55 0 -75.5 22t-20.5 70zM172 956q0 50 22 71.5t74 21.5q54 0 77.5 -21.5t23.5 -71.5q0 -52 -25 -72t-76 -20q-55 0 -75.5 24.5 t-20.5 67.5z" />
+<glyph unicode="&#x384;" horiz-adv-x="369" d="M4 1208l162 361h176l-233 -361h-105z" />
+<glyph unicode="&#x385;" horiz-adv-x="1106" d="M186 1294q0 44 18.5 65t69.5 21q52 0 70 -20.5t18 -65.5q0 -48 -19 -68t-69 -20q-53 0 -70.5 24t-17.5 64zM455 1208l133 361h174l-203 -361h-104zM741 1294q0 44 18.5 65t69.5 21q53 0 71 -20.5t18 -65.5q0 -48 -19.5 -68t-69.5 -20q-53 0 -70.5 24t-17.5 64z" />
+<glyph unicode="&#x386;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM67 1024l134 360h178l-205 -360h-107zM381 522h493l-247 731z" />
+<glyph unicode="&#x387;" horiz-adv-x="541" d="M172 745q0 50 22 71.5t74 21.5q54 0 77.5 -21.5t23.5 -71.5q0 -52 -25 -72t-76 -20q-55 0 -75.5 24.5t-20.5 67.5z" />
+<glyph unicode="&#x388;" horiz-adv-x="1376" d="M13 1024l134 360h178l-205 -360h-107zM420 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819z" />
+<glyph unicode="&#x389;" horiz-adv-x="1563" d="M13 1024l134 360h178l-205 -360h-107zM420 0v1384h135v-606h674v606h135v-1384h-135v655h-674v-655h-135z" />
+<glyph unicode="&#x38a;" horiz-adv-x="989" d="M13 1024l134 360h178l-205 -360h-107zM372 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514z" />
+<glyph unicode="&#x38c;" horiz-adv-x="1532" d="M13 1024l134 360h178l-205 -360h-107zM303 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM447 692q0 -144 21 -255 t68.5 -187.5t124.5 -116t189 -39.5q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5z" />
+<glyph unicode="&#x38e;" horiz-adv-x="1462" d="M13 1024l134 360h178l-205 -360h-107zM387 1384h150l362 -720l367 720h145l-444 -847v-537h-137v530z" />
+<glyph unicode="&#x38f;" horiz-adv-x="1520" d="M13 1024l134 360h178l-205 -360h-107zM291 791q0 142 33 257t100 196t167 125t235 44q145 0 250.5 -37.5t174 -114.5t101.5 -193.5t33 -274.5q0 -265 -85.5 -410.5t-248.5 -185.5v-72h303v-125h-424v276q77 11 135 41.5t96.5 89.5t58 151t19.5 226q0 115 -17.5 208.5 t-63 159.5t-126 102t-206.5 36q-90 0 -162.5 -26.5t-123 -86t-78 -155.5t-27.5 -236q0 -128 15 -218.5t51 -150.5t96 -93.5t149 -47.5v-276h-424v125h303v72q-90 20 -153.5 66t-103.5 119.5t-58.5 175t-18.5 233.5z" />
+<glyph unicode="&#x390;" horiz-adv-x="565" d="M-110 1294q0 44 18.5 65t69.5 21q52 0 70 -20.5t18 -65.5q0 -48 -19 -68t-69 -20q-53 0 -70.5 24t-17.5 64zM159 1208l133 361h174l-203 -361h-104zM180 266v783h131v-773q0 -53 4 -91t16 -62t34 -35.5t57 -11.5q25 0 51.5 5t44.5 13l31 -102q-23 -8 -62.5 -15.5 t-83.5 -7.5q-61 0 -103.5 16.5t-69 52t-38.5 92t-12 136.5zM445 1294q0 44 18.5 65t69.5 21q53 0 71 -20.5t18 -65.5q0 -48 -19.5 -68t-69.5 -20q-53 0 -70.5 24t-17.5 64z" />
+<glyph unicode="&#x391;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM381 522h493l-247 731z" />
+<glyph unicode="&#x392;" horiz-adv-x="1257" d="M199 0v1384h395q125 0 210 -19.5t137 -58.5t74.5 -97t22.5 -136q0 -67 -14 -118.5t-41.5 -90t-67 -65t-90.5 -43.5q65 -9 121 -33.5t97 -67t64 -103.5t23 -144q0 -107 -34 -184t-99.5 -127t-162 -73.5t-220.5 -23.5h-415zM334 123h219q102 0 182.5 11t136.5 41.5 t85.5 86.5t29.5 146q0 86 -28 137.5t-80 79.5t-124.5 36.5t-162.5 8.5h-258v-547zM334 791h221q177 0 259.5 59.5t82.5 191.5q0 63 -17 105.5t-56 68.5t-103 37t-158 11h-229v-473z" />
+<glyph unicode="&#x393;" horiz-adv-x="1067" d="M209 0v1384h817v-120h-682v-1264h-135z" />
+<glyph unicode="&#x394;" horiz-adv-x="1247" d="M63 0v74q119 323 239 655t241 655h162q57 -158 116.5 -323t120.5 -331.5t122 -332t120 -323.5v-74h-1121zM217 119h805l-338 940q-14 42 -31 95.5t-32 109.5h-7q-12 -56 -30 -111t-33 -98z" />
+<glyph unicode="&#x395;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819z" />
+<glyph unicode="&#x396;" horiz-adv-x="1171" d="M102 0v129l779 1133h-748v122h905v-122l-784 -1139h801v-123h-953z" />
+<glyph unicode="&#x397;" horiz-adv-x="1341" d="M199 0v1384h135v-606h674v606h135v-1384h-135v655h-674v-655h-135z" />
+<glyph unicode="&#x398;" horiz-adv-x="1430" d="M135 692q0 166 30.5 299.5t99 227t179 144t271.5 50.5q160 0 271 -50t179 -143.5t98.5 -227t30.5 -300.5t-30.5 -300.5t-98.5 -227t-179 -143.5t-271 -50q-161 0 -271.5 50t-179 144t-99 227t-30.5 300zM279 692q0 -144 22.5 -256t73.5 -189t134.5 -117t205.5 -40 q121 0 204 39.5t134 116t73.5 189t22.5 257.5q0 144 -22.5 256t-73.5 188.5t-134 116t-204 39.5q-122 0 -205 -39t-134.5 -115t-74 -188t-22.5 -258zM457 637v129h514v-129h-514z" />
+<glyph unicode="&#x399;" horiz-adv-x="719" d="M102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514z" />
+<glyph unicode="&#x39a;" horiz-adv-x="1255" d="M199 0v1384h135v-739l661 739h170l-587 -649l612 -735h-176l-527 639l-153 -164v-475h-135z" />
+<glyph unicode="&#x39b;" horiz-adv-x="1217" d="M63 0l465 1384h166l459 -1384h-141l-404 1239l-405 -1239h-140z" />
+<glyph unicode="&#x39c;" horiz-adv-x="1556" d="M199 0v1384h190l391 -806l389 806h189v-1384h-131v1219l-406 -828h-90l-401 828v-1219h-131z" />
+<glyph unicode="&#x39d;" horiz-adv-x="1374" d="M199 0v1384h196l647 -1165v1165h134v-1384h-160l-686 1235v-1235h-131z" />
+<glyph unicode="&#x39e;" horiz-adv-x="1104" d="M127 0v125h850v-125h-850zM137 1260v124h830v-124h-830zM203 668v125h698v-125h-698z" />
+<glyph unicode="&#x39f;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5z" />
+<glyph unicode="&#x3a0;" horiz-adv-x="1282" d="M199 0v1384h884v-1384h-135v1262h-614v-1262h-135z" />
+<glyph unicode="&#x3a1;" horiz-adv-x="1153" d="M199 0v1384h383q238 0 350 -107.5t112 -324.5q0 -126 -29 -214t-88.5 -143.5t-149.5 -80.5t-212 -25h-231v-489h-135zM334 612h209q93 0 160 15t110.5 52.5t64.5 102.5t21 166q0 90 -22.5 150.5t-65 96.5t-103.5 51.5t-139 15.5h-235v-650z" />
+<glyph unicode="&#x3a3;" horiz-adv-x="1077" d="M74 0v125l542 580l-542 561v118h878v-122h-706l516 -533v-45l-529 -563h748v-121h-907z" />
+<glyph unicode="&#x3a4;" horiz-adv-x="1174" d="M43 1262v122h1085v-122h-475v-1262h-135v1262h-475z" />
+<glyph unicode="&#x3a5;" horiz-adv-x="1126" d="M51 1384h150l362 -720l367 720h145l-444 -847v-537h-137v530z" />
+<glyph unicode="&#x3a6;" horiz-adv-x="1493" d="M133 694q0 283 135 433t410 165v131h131v-129q133 -8 235.5 -45.5t172.5 -110.5t106.5 -183t36.5 -261t-35 -261.5t-104.5 -183.5t-172.5 -111.5t-239 -45.5v-131h-131v131q-141 8 -243.5 48t-169.5 114t-99.5 183.5t-32.5 256.5zM274 694q0 -117 23.5 -205t72.5 -147.5 t125.5 -92.5t182.5 -40v969q-212 -17 -308 -140.5t-96 -343.5zM809 209q110 7 187.5 40.5t127 93.5t72.5 147.5t23 203.5q0 230 -97.5 349t-312.5 135v-969z" />
+<glyph unicode="&#x3a7;" horiz-adv-x="1169" d="M66 0l444 694l-432 690h155l357 -585l362 585h152l-440 -686l440 -698h-156l-364 594l-371 -594h-147z" />
+<glyph unicode="&#x3a8;" horiz-adv-x="1516" d="M156 803v581h135v-559q0 -115 25.5 -196t76 -133.5t125.5 -80t174 -34.5v1003h131v-1003q96 7 171 33.5t127 79t79 133t27 194.5v563h133v-581q0 -139 -35 -238.5t-103 -164t-168.5 -97.5t-230.5 -39v-307h-131v307q-131 6 -231 39t-167.5 97.5t-102.5 164t-35 238.5z " />
+<glyph unicode="&#x3a9;" horiz-adv-x="1364" d="M135 791q0 142 33 257t100 196t167 125t235 44q145 0 250.5 -37.5t174 -114.5t101.5 -193.5t33 -274.5q0 -265 -85.5 -410.5t-248.5 -185.5v-72h303v-125h-424v276q77 11 135 41.5t96.5 89.5t58 151t19.5 226q0 115 -17.5 208.5t-63 159.5t-126 102t-206.5 36 q-90 0 -162.5 -26.5t-123 -86t-78 -155.5t-27.5 -236q0 -128 15 -218.5t51 -150.5t96 -93.5t149 -47.5v-276h-424v125h303v72q-90 20 -153.5 66t-103.5 119.5t-58.5 175t-18.5 233.5z" />
+<glyph unicode="&#x3aa;" horiz-adv-x="719" d="M89 1636q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514zM459 1636q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68 q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x3ab;" horiz-adv-x="1126" d="M51 1384h150l362 -720l367 720h145l-444 -847v-537h-137v530zM293 1636q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM663 1636q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68q0 -48 -19.5 -69 t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x3ac;" horiz-adv-x="1171" d="M129 522q0 134 30 237.5t83.5 174.5t127.5 108t162 37q87 0 166.5 -33t141.5 -114q2 32 4 63t4 54h133q-12 -91 -19 -159t-11 -122.5t-5.5 -100.5t-1.5 -92v-286q0 -68 5.5 -109.5t17 -64.5t30 -31t45.5 -8q22 0 44.5 5t43.5 13l31 -102q-26 -9 -63 -16t-74 -7 q-57 0 -94 16.5t-58.5 51.5t-31 89.5t-11.5 129.5q-20 -75 -54 -129.5t-77.5 -89.5t-95 -51.5t-106.5 -16.5q-87 0 -155 36.5t-115.5 107t-72 173.5t-24.5 236zM264 516q0 -113 18 -194t51 -133.5t78.5 -77.5t100.5 -25q81 0 139.5 48t97 139t58 222t24.5 296 q-57 81 -124.5 128.5t-155.5 47.5q-62 0 -115 -25t-91 -79t-59.5 -140t-21.5 -207zM487 1208l162 361h176l-233 -361h-105z" />
+<glyph unicode="&#x3ad;" horiz-adv-x="1026" d="M145 281q0 40 12.5 78.5t36.5 71t58.5 57.5t77.5 40q-84 26 -134.5 85t-50.5 149q0 80 30.5 139.5t82 99t120.5 59t146 19.5q136 0 225 -49t146 -149l-107 -64q-40 74 -104 114t-160 40q-53 0 -98 -13.5t-77.5 -40t-51 -66t-18.5 -91.5q0 -49 19 -81t55.5 -51t89 -26.5 t120.5 -7.5h221v-109h-231q-134 0 -204 -49t-70 -151q0 -51 18.5 -89.5t52.5 -64.5t81.5 -39.5t105.5 -13.5q48 0 86.5 10t70 29t58 47.5t49.5 66.5l106 -63q-29 -47 -62.5 -84t-77.5 -62.5t-100.5 -39t-129.5 -13.5q-90 0 -162.5 20t-123.5 59t-78.5 97.5t-27.5 135.5z M455 1208l162 361h176l-233 -361h-105z" />
+<glyph unicode="&#x3ae;" horiz-adv-x="1137" d="M182 0v1049h129v-168q95 92 185.5 145t185.5 53q78 0 132 -23t87 -70.5t47.5 -118.5t14.5 -167v-1095h-129v1067q0 85 -10 140.5t-31 87.5t-53 45t-76 13q-78 0 -166 -50t-187 -146v-762h-129zM489 1208l162 361h176l-233 -361h-105z" />
+<glyph unicode="&#x3af;" horiz-adv-x="565" d="M147 1208l162 361h176l-233 -361h-105zM180 266v783h131v-773q0 -53 4 -91t16 -62t34 -35.5t57 -11.5q25 0 51.5 5t44.5 13l31 -102q-23 -8 -62.5 -15.5t-83.5 -7.5q-61 0 -103.5 16.5t-69 52t-38.5 92t-12 136.5z" />
+<glyph unicode="&#x3b0;" horiz-adv-x="1116" d="M173 1294q0 44 18.5 65t69.5 21q52 0 70 -20.5t18 -65.5q0 -48 -19 -68t-69 -20q-53 0 -70.5 24t-17.5 64zM174 352v697h131v-695q0 -74 19.5 -126.5t53.5 -85.5t81 -48.5t102 -15.5q65 0 118.5 25.5t91.5 82t58.5 145.5t20.5 216q0 90 -8.5 166.5t-21 138.5t-27.5 111.5 t-27 85.5h139q10 -27 23.5 -76.5t25.5 -114.5t20.5 -141.5t8.5 -157.5q0 -171 -31.5 -285t-88 -181.5t-135.5 -95.5t-173 -28q-79 0 -148.5 18.5t-121 62.5t-81.5 117.5t-30 184.5zM442 1208l133 361h174l-203 -361h-104zM728 1294q0 44 18.5 65t69.5 21q53 0 71 -20.5 t18 -65.5q0 -48 -19.5 -68t-69.5 -20q-53 0 -70.5 24t-17.5 64z" />
+<glyph unicode="&#x3b1;" horiz-adv-x="1171" d="M129 522q0 134 30 237.5t83.5 174.5t127.5 108t162 37q87 0 166.5 -33t141.5 -114q2 32 4 63t4 54h133q-12 -91 -19 -159t-11 -122.5t-5.5 -100.5t-1.5 -92v-286q0 -68 5.5 -109.5t17 -64.5t30 -31t45.5 -8q22 0 44.5 5t43.5 13l31 -102q-26 -9 -63 -16t-74 -7 q-57 0 -94 16.5t-58.5 51.5t-31 89.5t-11.5 129.5q-20 -75 -54 -129.5t-77.5 -89.5t-95 -51.5t-106.5 -16.5q-87 0 -155 36.5t-115.5 107t-72 173.5t-24.5 236zM264 516q0 -113 18 -194t51 -133.5t78.5 -77.5t100.5 -25q81 0 139.5 48t97 139t58 222t24.5 296 q-57 81 -124.5 128.5t-155.5 47.5q-62 0 -115 -25t-91 -79t-59.5 -140t-21.5 -207z" />
+<glyph unicode="&#x3b2;" horiz-adv-x="1155" d="M178 -406v1487q0 97 22.5 177.5t69 138.5t117.5 90.5t168 32.5q75 0 142 -21t117 -63.5t79 -107.5t29 -152q0 -70 -19.5 -128.5t-53.5 -103.5t-79.5 -74t-97.5 -41q75 -9 140 -37.5t113 -78t75.5 -120.5t27.5 -165q0 -103 -28.5 -187.5t-81.5 -145t-129.5 -93.5 t-172.5 -33q-50 0 -95.5 10t-85.5 26.5t-72.5 37t-55.5 41.5v-490h-129zM307 197q59 -48 134.5 -81.5t172.5 -33.5q61 0 112 21.5t88 65t58 109.5t21 154q0 91 -30.5 154t-88.5 102t-142 56.5t-192 17.5v110q69 0 132 12.5t111 45t76.5 89.5t28.5 146q0 121 -59.5 181.5 t-175.5 60.5q-67 0 -113.5 -23t-76 -65t-43 -101t-13.5 -131v-890z" />
+<glyph unicode="&#x3b3;" horiz-adv-x="1020" d="M57 1049h138l294 -902q34 41 71 98.5t72.5 126t67 146.5t55.5 161t38 167.5t14 167.5v35h133v-43q0 -88 -17 -181t-46.5 -185t-69 -180.5t-84.5 -168t-93.5 -146.5t-94.5 -116v-428h-129v428z" />
+<glyph unicode="&#x3b4;" horiz-adv-x="1167" d="M129 467q0 117 32.5 208t87 157t126 109t149.5 65q-61 38 -107.5 73t-78 71t-48 75t-16.5 84q0 43 16 81.5t51.5 67.5t91 45.5t134.5 16.5q119 0 208 -20.5t143 -43.5l-46 -104q-61 24 -141 44.5t-170 20.5q-84 0 -118.5 -28.5t-34.5 -71.5q0 -28 8.5 -53.5t34 -54 t71.5 -62.5t121 -78q78 -46 149 -102t126 -125.5t87.5 -155t32.5 -190.5q0 -125 -33 -223t-93 -165.5t-144.5 -103t-187.5 -35.5q-111 0 -195.5 35t-141.5 100t-85.5 157t-28.5 206zM264 463q0 -81 17.5 -151t56.5 -122t100.5 -82t149.5 -30q65 0 122.5 26t100 78t67.5 129 t25 178q0 82 -19.5 148.5t-55.5 121.5t-87.5 99.5t-115.5 83.5q-68 -14 -133 -48t-115.5 -92.5t-81.5 -142t-31 -196.5z" />
+<glyph unicode="&#x3b5;" horiz-adv-x="1026" d="M145 281q0 40 12.5 78.5t36.5 71t58.5 57.5t77.5 40q-84 26 -134.5 85t-50.5 149q0 80 30.5 139.5t82 99t120.5 59t146 19.5q136 0 225 -49t146 -149l-107 -64q-40 74 -104 114t-160 40q-53 0 -98 -13.5t-77.5 -40t-51 -66t-18.5 -91.5q0 -49 19 -81t55.5 -51t89 -26.5 t120.5 -7.5h221v-109h-231q-134 0 -204 -49t-70 -151q0 -51 18.5 -89.5t52.5 -64.5t81.5 -39.5t105.5 -13.5q48 0 86.5 10t70 29t58 47.5t49.5 66.5l106 -63q-29 -47 -62.5 -84t-77.5 -62.5t-100.5 -39t-129.5 -13.5q-90 0 -162.5 20t-123.5 59t-78.5 97.5t-27.5 135.5z" />
+<glyph unicode="&#x3b6;" horiz-adv-x="852" d="M135 449q0 61 11.5 134.5t35.5 154.5t61.5 166t89 168t118 161t149.5 145h-428v111h606v-94q-67 -46 -130.5 -109t-120 -138t-104 -159.5t-81.5 -173.5t-53 -180t-19 -178q0 -91 16.5 -152t49 -101.5t79.5 -63.5t109 -38q73 -18 128 -35t91.5 -45t55 -70.5t18.5 -111.5 q0 -38 -11 -79.5t-24 -76.5q-15 -40 -34 -79h-134q20 36 37 74q14 32 25.5 71.5t11.5 77.5q0 35 -11.5 59.5t-37 42.5t-67 32t-101.5 28q-71 16 -132.5 42.5t-106.5 77t-71 132t-26 207.5z" />
+<glyph unicode="&#x3b7;" horiz-adv-x="1137" d="M182 0v1049h129v-168q95 92 185.5 145t185.5 53q78 0 132 -23t87 -70.5t47.5 -118.5t14.5 -167v-1095h-129v1067q0 85 -10 140.5t-31 87.5t-53 45t-76 13q-78 0 -166 -50t-187 -146v-762h-129z" />
+<glyph unicode="&#x3b8;" horiz-adv-x="1137" d="M141 748q0 183 17.5 327t64.5 243.5t130.5 151.5t215.5 52q131 0 214 -52.5t130 -152.5t64.5 -243.5t17.5 -325.5q0 -181 -16.5 -325t-63 -245t-130 -155t-216.5 -54q-136 0 -219.5 52t-130 151.5t-62.5 244.5t-16 331zM276 715q-1 -153 9.5 -271.5t42 -200t89 -123.5 t150.5 -42q90 0 146.5 43.5t89 125t44.5 200t13 268.5h-584zM276 821h584q-2 142 -15.5 252.5t-45.5 186t-87.5 114.5t-142.5 39q-88 0 -145 -36.5t-90 -110t-45.5 -184.5t-12.5 -261z" />
+<glyph unicode="&#x3b9;" horiz-adv-x="565" d="M180 266v783h131v-773q0 -53 4 -91t16 -62t34 -35.5t57 -11.5q25 0 51.5 5t44.5 13l31 -102q-23 -8 -62.5 -15.5t-83.5 -7.5q-61 0 -103.5 16.5t-69 52t-38.5 92t-12 136.5z" />
+<glyph unicode="&#x3ba;" horiz-adv-x="1016" d="M182 0v1049h129v-541l477 541h156l-424 -471l447 -578h-158l-377 498l-121 -136v-362h-129z" />
+<glyph unicode="&#x3bb;" horiz-adv-x="1036" d="M57 0l412 1053q-27 106 -48.5 175t-43.5 109.5t-46 57t-55 16.5q-34 0 -66.5 -11.5t-53.5 -25.5l-33 107q15 7 34 14.5t40.5 13.5t43.5 9.5t42 3.5q58 0 98.5 -14.5t71 -53.5t56 -107t54.5 -176l246 -909q14 -50 27.5 -82t28 -50t29.5 -25t32 -7q15 0 30.5 2.5t24.5 5.5 l31 -106q-29 -8 -62.5 -11t-56.5 -3q-39 0 -70.5 11.5t-57 42t-46.5 84.5t-41 138l-158 629l-319 -891h-144z" />
+<glyph unicode="&#x3bc;" horiz-adv-x="1141" d="M166 -395v1444h131v-832q51 -59 117.5 -92t146.5 -33q76 0 146 42t129 120v795h131v-1049h-121l-10 123q-28 -35 -57.5 -63t-63.5 -48.5t-72.5 -31.5t-83.5 -11q-40 0 -74.5 5t-66 16.5t-61 30t-60.5 45.5v-461h-131z" />
+<glyph unicode="&#x3bd;" horiz-adv-x="975" d="M57 1049h140l268 -914q41 60 80.5 130.5t74.5 146.5t64 155.5t50 157.5t32.5 153t11.5 142v29h135v-23q0 -86 -17 -178t-46 -185t-68.5 -184.5t-85 -176.5t-95 -162t-97.5 -140h-125z" />
+<glyph unicode="&#x3be;" horiz-adv-x="868" d="M139 410q0 67 16.5 126.5t48.5 107.5t80 83t111 55q-91 37 -140.5 110.5t-49.5 190.5q0 47 10 92.5t32 85.5t57 72t85 51h-237v105h602v-109h-49q-88 0 -156 -12.5t-115 -45.5t-71.5 -90.5t-24.5 -146.5q0 -69 22 -114.5t56 -72t76 -37.5t83 -11h152v-111h-160 q-65 0 -119 -25.5t-92.5 -70t-60 -103t-21.5 -124.5q0 -79 20 -129.5t57 -83t90 -53t120 -39.5q58 -16 106 -35.5t81.5 -49.5t52 -74t18.5 -108q0 -40 -9.5 -82t-20.5 -77q-13 -41 -29 -80h-129q18 35 32 73q12 32 22.5 71t10.5 75q0 37 -11 64t-34.5 47t-60.5 36t-90 31 q-82 23 -148.5 52t-114 74.5t-73 113.5t-25.5 168z" />
+<glyph unicode="&#x3bf;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30 q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5z" />
+<glyph unicode="&#x3c0;" horiz-adv-x="1272" d="M0 983q53 26 130 46t179 20h916v-107h-267v-649q0 -63 5 -102.5t18.5 -62t37.5 -30.5t62 -8q26 0 55.5 6.5t49.5 14.5l33 -103q-25 -9 -67 -16.5t-87 -7.5q-70 0 -116 15.5t-73 52t-38 95.5t-11 146v649h-397v-659q0 -93 -7 -160t-26 -123h-145q22 63 34.5 134.5 t12.5 156.5v651q-32 0 -67 -4.5t-69.5 -12t-66 -18t-55.5 -22.5z" />
+<glyph unicode="&#x3c1;" horiz-adv-x="1147" d="M152 -399v934q0 277 111 410.5t323 133.5q107 0 188 -37.5t135 -107.5t81.5 -169.5t27.5 -223.5q0 -154 -34 -262.5t-91.5 -177.5t-133 -100.5t-157.5 -31.5q-55 0 -104 13.5t-90 36.5t-73.5 53.5t-53.5 64.5v-536h-129zM281 295q23 -47 55.5 -86t72.5 -67.5t86 -44 t95 -15.5q61 0 114 26.5t93 82t63 140t23 201.5q0 86 -14.5 165t-49 139.5t-90.5 96.5t-139 36q-69 0 -126 -22t-97.5 -75t-63 -141t-22.5 -221v-215z" />
+<glyph unicode="&#x3c2;" horiz-adv-x="971" d="M129 522q0 271 109.5 414t330.5 143q126 0 212 -49.5t143 -146.5l-109 -66q-42 72 -100 112t-148 40q-155 0 -229 -114.5t-74 -332.5q0 -103 22 -171t62 -113.5t95 -74t120 -52.5q64 -24 112.5 -47t80 -52.5t47.5 -70.5t16 -101q0 -39 -10 -81.5t-21 -77.5 q-13 -41 -30 -80h-133q18 35 32 73q12 32 22.5 71t10.5 75q0 34 -10 59.5t-31.5 46t-54.5 37t-78 33.5q-80 29 -150.5 64.5t-123 93t-83 145.5t-30.5 223z" />
+<glyph unicode="&#x3c3;" horiz-adv-x="1198" d="M129 492q0 140 27 244.5t85 174t148 104t215 34.5h522v-111h-264q78 -71 120 -186.5t42 -255.5q0 -111 -25 -207.5t-80 -167.5t-143 -111.5t-213 -40.5q-109 0 -190.5 36.5t-135.5 105t-81 165t-27 216.5zM264 485q0 -95 19 -170t56.5 -128t93 -81t128.5 -28 q92 0 155 32.5t102 88t56 130t17 158.5q0 155 -40.5 268.5t-113.5 182.5h-147q-97 0 -160 -29.5t-100 -86.5t-51.5 -141.5t-14.5 -195.5z" />
+<glyph unicode="&#x3c4;" horiz-adv-x="938" d="M14 983q50 29 117 47.5t166 18.5h590v-109h-367v-651q0 -58 4 -96t15.5 -61t33.5 -32.5t58 -9.5q25 0 55.5 6.5t50.5 14.5l31 -105q-25 -8 -68 -15t-84 -7q-68 0 -111.5 15t-69.5 50t-36 92t-10 140v659h-98q-46 0 -83 -5t-66 -13t-50.5 -17.5t-36.5 -17.5z" />
+<glyph unicode="&#x3c5;" horiz-adv-x="1116" d="M174 352v697h131v-695q0 -74 19.5 -126.5t53.5 -85.5t81 -48.5t102 -15.5q65 0 118.5 25.5t91.5 82t58.5 145.5t20.5 216q0 90 -8.5 166.5t-21 138.5t-27.5 111.5t-27 85.5h139q10 -27 23.5 -76.5t25.5 -114.5t20.5 -141.5t8.5 -157.5q0 -171 -31.5 -285t-88 -181.5 t-135.5 -95.5t-173 -28q-79 0 -148.5 18.5t-121 62.5t-81.5 117.5t-30 184.5z" />
+<glyph unicode="&#x3c6;" horiz-adv-x="1333" d="M129 520q0 141 29.5 243.5t88.5 169.5t148 101.5t209 40.5v414h127v-414q113 -6 201 -39t148.5 -99.5t92 -169t31.5 -247.5t-31.5 -247t-91.5 -167t-148 -97t-202 -38v-368h-127v368q-116 6 -204.5 38.5t-148.5 97.5t-91 166.5t-31 246.5zM264 520q0 -108 17 -188 t57 -134t105 -84t161 -38v891q-97 -9 -162 -38.5t-104.5 -83.5t-56.5 -134t-17 -191zM731 78q90 7 154.5 34.5t105.5 80.5t60.5 133.5t19.5 193.5q0 111 -20 192.5t-61.5 135.5t-106 83t-152.5 36v-889z" />
+<glyph unicode="&#x3c7;" horiz-adv-x="1001" d="M66 1057q15 6 45.5 14t58.5 8q37 0 66 -9t53 -30t44 -56t38 -87l153 -430l258 582h140l-340 -691l180 -469q22 -55 39 -89.5t32.5 -53.5t31.5 -26t36 -7q14 0 28.5 3.5t26.5 7.5l31 -103q-20 -8 -50 -14t-65 -6q-30 0 -57.5 8t-52.5 29.5t-48.5 59.5t-45.5 99l-166 449 l-281 -629h-139l362 739l-157 418q-21 55 -36.5 92t-30 59.5t-30.5 32t-38 9.5q-13 0 -29.5 -3.5t-24.5 -7.5z" />
+<glyph unicode="&#x3c8;" horiz-adv-x="1307" d="M174 383v666h129v-664q0 -66 16 -120.5t51.5 -94.5t91 -64.5t134.5 -29.5v1413h127v-1411q72 9 130 42t98.5 91t62.5 141.5t22 194.5q0 87 -6.5 160.5t-17 136t-23 113.5t-24.5 92h139q9 -30 20.5 -81.5t22 -116.5t17.5 -140t7 -152q0 -157 -34 -265t-94 -177 t-142 -102.5t-178 -41.5v-368h-127v366q-101 5 -179.5 30t-132.5 74.5t-82 125.5t-28 182z" />
+<glyph unicode="&#x3c9;" horiz-adv-x="1595" d="M129 401q0 82 16.5 173.5t44 178.5t64 164t76.5 132h149q-45 -59 -84 -134.5t-68 -159.5t-46 -171t-17 -168q0 -171 54.5 -253.5t168.5 -82.5q52 0 96.5 24t77.5 77t51.5 136.5t18.5 202.5v277h133v-277q0 -116 18.5 -199t51.5 -136.5t77.5 -79t96.5 -25.5q51 0 92 19.5 t70 60.5t45 104.5t16 151.5q0 72 -15.5 157t-43 170.5t-66.5 165t-86 140.5h150q40 -53 75.5 -128t62.5 -161t42.5 -177t15.5 -177q0 -108 -24.5 -190t-70 -137t-110 -82.5t-143.5 -27.5q-127 0 -208.5 70.5t-112.5 204.5q-14 -65 -43 -116.5t-70 -86.5t-93.5 -53.5 t-113.5 -18.5q-81 0 -145.5 26t-109.5 79.5t-69 134.5t-24 192z" />
+<glyph unicode="&#x3ca;" horiz-adv-x="565" d="M-27 1300q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM180 266v783h131v-773q0 -53 4 -91t16 -62t34 -35.5t57 -11.5q25 0 51.5 5t44.5 13l31 -102q-23 -8 -62.5 -15.5t-83.5 -7.5 q-61 0 -103.5 16.5t-69 52t-38.5 92t-12 136.5zM343 1300q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x3cb;" horiz-adv-x="1116" d="M174 352v697h131v-695q0 -74 19.5 -126.5t53.5 -85.5t81 -48.5t102 -15.5q65 0 118.5 25.5t91.5 82t58.5 145.5t20.5 216q0 90 -8.5 166.5t-21 138.5t-27.5 111.5t-27 85.5h139q10 -27 23.5 -76.5t25.5 -114.5t20.5 -141.5t8.5 -157.5q0 -171 -31.5 -285t-88 -181.5 t-135.5 -95.5t-173 -28q-79 0 -148.5 18.5t-121 62.5t-81.5 117.5t-30 184.5zM264 1300q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM634 1300q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68 q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x3cc;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30 q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM485 1208l162 361h176l-233 -361h-105z" />
+<glyph unicode="&#x3cd;" horiz-adv-x="1116" d="M174 352v697h131v-695q0 -74 19.5 -126.5t53.5 -85.5t81 -48.5t102 -15.5q65 0 118.5 25.5t91.5 82t58.5 145.5t20.5 216q0 90 -8.5 166.5t-21 138.5t-27.5 111.5t-27 85.5h139q10 -27 23.5 -76.5t25.5 -114.5t20.5 -141.5t8.5 -157.5q0 -171 -31.5 -285t-88 -181.5 t-135.5 -95.5t-173 -28q-79 0 -148.5 18.5t-121 62.5t-81.5 117.5t-30 184.5zM457 1208l162 361h176l-233 -361h-105z" />
+<glyph unicode="&#x3ce;" horiz-adv-x="1595" d="M129 401q0 82 16.5 173.5t44 178.5t64 164t76.5 132h149q-45 -59 -84 -134.5t-68 -159.5t-46 -171t-17 -168q0 -171 54.5 -253.5t168.5 -82.5q52 0 96.5 24t77.5 77t51.5 136.5t18.5 202.5v277h133v-277q0 -116 18.5 -199t51.5 -136.5t77.5 -79t96.5 -25.5q51 0 92 19.5 t70 60.5t45 104.5t16 151.5q0 72 -15.5 157t-43 170.5t-66.5 165t-86 140.5h150q40 -53 75.5 -128t62.5 -161t42.5 -177t15.5 -177q0 -108 -24.5 -190t-70 -137t-110 -82.5t-143.5 -27.5q-127 0 -208.5 70.5t-112.5 204.5q-14 -65 -43 -116.5t-70 -86.5t-93.5 -53.5 t-113.5 -18.5q-81 0 -145.5 26t-109.5 79.5t-69 134.5t-24 192zM723 1208l162 361h176l-233 -361h-105z" />
+<glyph unicode="&#x400;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM357 1905h176l186 -361h-104z" />
+<glyph unicode="&#x401;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM330 1636q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM700 1636q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68 q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x402;" horiz-adv-x="1372" d="M20 1268v116h838v-116h-346v-480h229q138 0 238 -22t164.5 -69.5t95.5 -121.5t31 -178q0 -106 -35 -181t-105 -123t-175.5 -70.5t-247.5 -22.5v115q119 0 199 15.5t128.5 49.5t69 88t20.5 131q0 69 -19 119.5t-62 84.5t-111.5 50.5t-167.5 16.5h-252v-670h-135v1268h-357 z" />
+<glyph unicode="&#x403;" horiz-adv-x="1067" d="M209 0v1384h817v-120h-682v-1264h-135zM490 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x404;" horiz-adv-x="1321" d="M139 692q0 174 34 308.5t105.5 226t181 139t261.5 47.5q97 0 172 -19t132.5 -54t100 -84t74.5 -109l-115 -74q-25 48 -57 87.5t-75.5 68.5t-101 45t-132.5 16q-111 0 -190.5 -35t-132 -102.5t-79.5 -167t-32 -227.5h723v-125h-723q4 -129 31 -229.5t80 -169t134 -104.5 t195 -36q84 0 145 20t105.5 52t75 71.5t53.5 79.5l115 -71q-33 -59 -75 -109t-100 -87t-135 -58t-182 -21q-301 0 -444.5 181t-143.5 540z" />
+<glyph unicode="&#x405;" horiz-adv-x="1225" d="M111 248l116 69q20 -40 52 -79.5t78 -71.5t107.5 -52t141.5 -20q73 0 136.5 15t110.5 47t74 81.5t27 118.5q0 64 -21 108.5t-64 77t-109 56.5t-156 47q-120 31 -207 60.5t-144 71t-84.5 101t-27.5 150.5q0 86 28 157t84.5 121.5t141.5 78.5t199 28q86 0 156 -17.5 t126 -50t100 -78.5t79 -104l-113 -76q-26 45 -59 82.5t-75 64.5t-94.5 41.5t-117.5 14.5q-79 0 -138 -18t-98 -51t-58 -80t-19 -105q0 -56 17.5 -93.5t58.5 -65t109 -50t169 -47.5q107 -27 192 -58t144.5 -77t91 -113.5t31.5 -169.5q0 -107 -38 -181t-103 -121t-153 -68 t-188 -21q-105 0 -184 21t-138.5 57.5t-103 87.5t-77.5 111z" />
+<glyph unicode="&#x406;" horiz-adv-x="719" d="M102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514z" />
+<glyph unicode="&#x407;" horiz-adv-x="719" d="M92 1636q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514zM462 1636q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68 q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x408;" horiz-adv-x="864" d="M66 18l51 119q17 -9 40.5 -17t49.5 -14.5t52.5 -10t49.5 -3.5q70 0 113.5 21.5t67.5 66t32 112.5t8 161v931h136v-989q0 -104 -18 -183.5t-59.5 -133.5t-110 -81.5t-169.5 -27.5q-31 0 -64.5 4t-65.5 10.5t-61.5 15.5t-51.5 19z" />
+<glyph unicode="&#x409;" horiz-adv-x="1913" d="M-12 0l20 111q13 -5 28.5 -7t26.5 -2q87 0 152.5 74t109 217.5t65.5 353.5t22 482v155h678v-550h210q136 0 234 -24.5t161 -76t92.5 -132t29.5 -191.5q0 -110 -34 -187.5t-99 -127t-158.5 -72.5t-212.5 -23h-359v1264h-407v-74q0 -171 -11.5 -327.5t-35.5 -290.5 t-61 -242.5t-87.5 -185.5t-115.5 -118.5t-144 -41.5q-31 0 -56 4t-48 12zM1090 119h210q190 0 281.5 69t91.5 224q0 87 -21.5 145.5t-68.5 93.5t-122 49.5t-183 14.5h-188v-596z" />
+<glyph unicode="&#x40a;" horiz-adv-x="1956" d="M199 0v1384h135v-581h663v581h138v-581h206q136 0 234.5 -21t162 -69t94 -125t30.5 -189q0 -105 -33.5 -180.5t-98.5 -124t-159.5 -71.5t-216.5 -23h-357v684h-663v-684h-135zM1135 119h211q192 0 282 69t90 213q0 90 -25 145.5t-75 86t-124 41t-171 10.5h-188v-565z" />
+<glyph unicode="&#x40b;" horiz-adv-x="1423" d="M20 1268v116h846v-116h-358v-471q88 34 181.5 53.5t182.5 19.5q102 0 177 -23.5t124 -76.5t73 -138t24 -208v-424h-135v379q0 111 -14 183.5t-47.5 115t-90.5 59.5t-143 17q-66 0 -152.5 -17t-177.5 -49v-688h-137v1268h-353z" />
+<glyph unicode="&#x40c;" horiz-adv-x="1233" d="M199 0v1384h135v-620h225q48 0 88 11t75.5 38t66 72.5t59.5 114.5t56.5 163.5t56.5 220.5h141q-29 -130 -58 -227t-58.5 -168t-60 -119t-62 -79.5t-64.5 -50.5t-68 -31q55 -17 98 -41.5t78.5 -61.5t65 -89t57.5 -125t55.5 -169.5t59.5 -222.5h-141q-32 120 -59.5 214 t-56 165.5t-59.5 121.5t-69.5 81.5t-87 46t-111.5 14.5h-227v-643h-135zM537 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x40d;" horiz-adv-x="1376" d="M199 0v1384h131v-1191l653 1191h195v-1384h-131v1239l-685 -1239h-163zM428 1905h176l186 -361h-104z" />
+<glyph unicode="&#x40e;" horiz-adv-x="1182" d="M63 1384h146l393 -925l402 925h141l-514 -1169q-31 -71 -66 -117.5t-78.5 -75t-97.5 -40t-123 -11.5q-24 0 -49.5 3t-48.5 7t-42.5 9t-31.5 10l43 115q28 -11 65 -19t72 -8q83 0 139 34.5t91 117.5l22 57zM291 1769h133q9 -78 48.5 -120.5t121.5 -42.5q50 0 83 9.5t54 30 t31.5 51t15.5 72.5h135q-1 -48 -17.5 -92.5t-54 -79t-98 -55t-147.5 -20.5q-78 0 -135.5 20.5t-95 55t-55.5 79t-19 92.5z" />
+<glyph unicode="&#x40f;" horiz-adv-x="1358" d="M199 0v1384h137v-1261h686v1261h137v-1384h-411v-262h-138v262h-411z" />
+<glyph unicode="&#x410;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM381 522h493l-247 731z" />
+<glyph unicode="&#x411;" horiz-adv-x="1225" d="M199 0v1384h835v-118h-700v-480h284q137 0 232 -23.5t154.5 -71t86.5 -120t27 -170.5q0 -199 -126 -300t-374 -101h-419zM334 119h235q96 0 171.5 13t127.5 45t79.5 86t27.5 136q0 78 -22.5 129.5t-68 82.5t-116 44t-166.5 13h-268v-549z" />
+<glyph unicode="&#x412;" horiz-adv-x="1257" d="M199 0v1384h395q125 0 210 -19.5t137 -58.5t74.5 -97t22.5 -136q0 -67 -14 -118.5t-41.5 -90t-67 -65t-90.5 -43.5q65 -9 121 -33.5t97 -67t64 -103.5t23 -144q0 -107 -34 -184t-99.5 -127t-162 -73.5t-220.5 -23.5h-415zM334 123h219q102 0 182.5 11t136.5 41.5 t85.5 86.5t29.5 146q0 86 -28 137.5t-80 79.5t-124.5 36.5t-162.5 8.5h-258v-547zM334 791h221q177 0 259.5 59.5t82.5 191.5q0 63 -17 105.5t-56 68.5t-103 37t-158 11h-229v-473z" />
+<glyph unicode="&#x413;" horiz-adv-x="1067" d="M209 0v1384h817v-120h-682v-1264h-135z" />
+<glyph unicode="&#x414;" horiz-adv-x="1309" d="M29 119h112q54 96 103.5 230.5t88 297.5t61.5 350t24 387h676v-1265h172v-381h-133v262h-971v-262h-133v381zM276 119h682v1145h-407q-6 -172 -31.5 -340.5t-63.5 -318.5t-84.5 -275t-95.5 -211z" />
+<glyph unicode="&#x415;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819z" />
+<glyph unicode="&#x416;" horiz-adv-x="1790" d="M82 0q32 126 59.5 222.5t55.5 169.5t57.5 125t65 89t78.5 61t98 42q-35 12 -68.5 31t-65 50.5t-62 79.5t-60 119t-58 168t-57.5 227h143q28 -126 56 -220.5t56.5 -163.5t59.5 -114.5t66 -72.5t75 -38t87 -11h159v620h136v-620h159q48 0 88 11t75 38t65.5 72.5t59 114.5 t56 163.5t56.5 220.5h141q-29 -130 -57.5 -227t-58 -168t-59.5 -119t-61.5 -79.5t-65 -50.5t-69.5 -31q55 -17 98 -41.5t79 -61.5t65.5 -89t57.5 -125t56 -169.5t60 -222.5h-143q-48 183 -88.5 306t-87.5 198t-109.5 107t-155.5 32h-161v-643h-136v643h-161 q-59 0 -106 -12.5t-85.5 -41.5t-70.5 -77t-61.5 -119.5t-58.5 -168.5t-61 -224h-141z" />
+<glyph unicode="&#x417;" horiz-adv-x="1157" d="M59 172l103 86q29 -33 66 -63.5t81.5 -54.5t97 -38t113.5 -14q184 0 275.5 81.5t91.5 227.5q0 128 -75.5 198.5t-233.5 70.5h-244v118h217q157 0 236 60.5t79 195.5q0 124 -83 190t-236 66q-119 0 -209 -32.5t-164 -104.5l-86 103q38 34 83.5 62t102 48t125.5 30.5 t154 10.5q120 0 206 -29t142 -79.5t82.5 -118.5t26.5 -146q0 -117 -53.5 -197.5t-168.5 -117.5q58 -16 102.5 -47.5t75 -75.5t46.5 -98.5t16 -116.5q0 -80 -28 -155t-89.5 -133t-158 -93t-234.5 -35q-135 0 -254.5 47.5t-204.5 153.5z" />
+<glyph unicode="&#x418;" horiz-adv-x="1376" d="M199 0v1384h131v-1191l653 1191h195v-1384h-131v1239l-685 -1239h-163z" />
+<glyph unicode="&#x419;" horiz-adv-x="1376" d="M199 0v1384h131v-1191l653 1191h195v-1384h-131v1239l-685 -1239h-163zM375 1769h133q9 -78 48.5 -120.5t121.5 -42.5q50 0 83 9.5t54 30t31.5 51t15.5 72.5h135q-1 -48 -17.5 -92.5t-54 -79t-98 -55t-147.5 -20.5q-78 0 -135.5 20.5t-95 55t-55.5 79t-19 92.5z" />
+<glyph unicode="&#x41a;" horiz-adv-x="1233" d="M199 0v1384h135v-620h225q48 0 88 11t75.5 38t66 72.5t59.5 114.5t56.5 163.5t56.5 220.5h141q-29 -130 -58 -227t-58.5 -168t-60 -119t-62 -79.5t-64.5 -50.5t-68 -31q55 -17 98 -41.5t78.5 -61.5t65 -89t57.5 -125t55.5 -169.5t59.5 -222.5h-141q-32 120 -59.5 214 t-56 165.5t-59.5 121.5t-69.5 81.5t-87 46t-111.5 14.5h-227v-643h-135z" />
+<glyph unicode="&#x41b;" horiz-adv-x="1303" d="M-12 0l20 111q13 -5 27 -7t26 -2q79 0 144 65t111 203t71 352.5t25 514.5v147h692v-1384h-135v1264h-422v-74q0 -285 -30 -509t-88 -379t-144 -236.5t-197 -81.5q-25 0 -52 4t-48 12z" />
+<glyph unicode="&#x41c;" horiz-adv-x="1556" d="M199 0v1384h190l391 -806l389 806h189v-1384h-131v1219l-406 -828h-90l-401 828v-1219h-131z" />
+<glyph unicode="&#x41d;" horiz-adv-x="1341" d="M199 0v1384h135v-606h674v606h135v-1384h-135v655h-674v-655h-135z" />
+<glyph unicode="&#x41e;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5z" />
+<glyph unicode="&#x41f;" horiz-adv-x="1282" d="M199 0v1384h884v-1384h-135v1262h-614v-1262h-135z" />
+<glyph unicode="&#x420;" horiz-adv-x="1153" d="M199 0v1384h383q238 0 350 -107.5t112 -324.5q0 -126 -29 -214t-88.5 -143.5t-149.5 -80.5t-212 -25h-231v-489h-135zM334 612h209q93 0 160 15t110.5 52.5t64.5 102.5t21 166q0 90 -22.5 150.5t-65 96.5t-103.5 51.5t-139 15.5h-235v-650z" />
+<glyph unicode="&#x421;" horiz-adv-x="1315" d="M145 692q0 174 34 308.5t105 226t180.5 139t260.5 47.5q97 0 173 -19t133.5 -54t100 -84t74.5 -109l-116 -74q-26 48 -58 87.5t-75.5 68.5t-100 45t-131.5 16q-118 0 -201 -39.5t-135 -116t-76 -187.5t-24 -255t24 -255t77 -187.5t137 -116t204 -39.5q84 0 145.5 20 t105.5 52t74.5 71.5t53.5 79.5l115 -71q-33 -59 -75 -109t-100 -87t-135.5 -58t-181.5 -21q-302 0 -445 181t-143 540z" />
+<glyph unicode="&#x422;" horiz-adv-x="1174" d="M43 1262v122h1085v-122h-475v-1262h-135v1262h-475z" />
+<glyph unicode="&#x423;" horiz-adv-x="1182" d="M63 1384h146l393 -925l402 925h141l-514 -1169q-31 -71 -66 -117.5t-78.5 -75t-97.5 -40t-123 -11.5q-24 0 -49.5 3t-48.5 7t-42.5 9t-31.5 10l43 115q28 -11 65 -19t72 -8q83 0 139 34.5t91 117.5l22 57z" />
+<glyph unicode="&#x424;" horiz-adv-x="1530" d="M102 692q0 141 38.5 242.5t114.5 168t188.5 100t261.5 38.5v182h122v-182q153 -5 266 -39t187 -101t110.5 -168.5t36.5 -240.5q0 -144 -39.5 -245t-116 -165.5t-188.5 -95t-256 -34.5v-191h-122v191q-155 4 -268.5 38.5t-187.5 101t-110.5 166.5t-36.5 234zM242 692 q0 -100 23 -177t77 -130t142.5 -82.5t220.5 -34.5v856q-135 -5 -224.5 -34.5t-142.5 -84t-74.5 -133t-21.5 -180.5zM827 268q130 5 218.5 34.5t142.5 82.5t77 130t23 177q0 102 -23 180.5t-77 133t-142.5 85t-218.5 35.5v-858z" />
+<glyph unicode="&#x425;" horiz-adv-x="1169" d="M66 0l444 694l-432 690h155l357 -585l362 585h152l-440 -686l440 -698h-156l-364 594l-371 -594h-147z" />
+<glyph unicode="&#x426;" horiz-adv-x="1331" d="M199 0v1384h135v-1261h647v1261h135v-1265h170v-381h-133v262h-954z" />
+<glyph unicode="&#x427;" horiz-adv-x="1272" d="M133 958v426h135v-378q0 -108 13.5 -180.5t47 -116t91.5 -62t147 -18.5q84 0 181 18t188 49v688h137v-1384h-135v586q-105 -34 -204.5 -54t-190.5 -20q-109 0 -187 25t-127.5 79t-72.5 138.5t-23 203.5z" />
+<glyph unicode="&#x428;" horiz-adv-x="1890" d="M199 0v1384h135v-1263h545v1263h133v-1263h544v1263h136v-1384h-1493z" />
+<glyph unicode="&#x429;" horiz-adv-x="1907" d="M199 0v1384h135v-1265h545v1265h133v-1265h544v1265h136v-1265h172v-381h-133v262h-1532z" />
+<glyph unicode="&#x42a;" horiz-adv-x="1370" d="M29 1264v120h518v-550h221q139 0 235.5 -26t156.5 -78t87 -130.5t27 -183.5q0 -214 -128 -315t-374 -101h-360v1264h-383zM547 119h217q91 0 160 16t114.5 52t68.5 93t23 138q0 86 -21 143t-66.5 91.5t-117.5 48.5t-175 14h-203v-596z" />
+<glyph unicode="&#x42b;" horiz-adv-x="1659" d="M199 0v1384h135v-550h227q138 0 234.5 -26t157 -78t87.5 -130.5t27 -183.5q0 -215 -128 -315.5t-374 -100.5h-366zM334 119h223q91 0 159.5 16t114.5 52t68.5 93t22.5 138q0 86 -21 143t-66.5 91.5t-117.5 48.5t-174 14h-209v-596zM1325 0v1384h135v-1384h-135z" />
+<glyph unicode="&#x42c;" horiz-adv-x="1161" d="M199 0v1384h135v-550h227q138 0 234.5 -26t157 -78t87.5 -130.5t27 -183.5q0 -215 -128 -315.5t-374 -100.5h-366zM334 119h223q91 0 159.5 16t114.5 52t68.5 93t22.5 138q0 86 -21 143t-66.5 91.5t-117.5 48.5t-174 14h-209v-596z" />
+<glyph unicode="&#x42d;" horiz-adv-x="1321" d="M127 246l115 71q23 -40 53 -79.5t74.5 -71.5t105.5 -52t146 -20q114 0 196 36t135 104.5t79 169t30 229.5h-723v125h723q-5 128 -31.5 227.5t-79 167t-132.5 102.5t-191 35q-75 0 -131.5 -16t-100 -45t-76 -68.5t-57.5 -87.5l-117 74q31 60 74 109t101 84t133.5 54 t173.5 19q151 0 260.5 -47.5t180 -139t104.5 -226t34 -308.5q0 -359 -142.5 -540t-445.5 -181q-104 0 -181 21t-135 58t-100 87t-75 109z" />
+<glyph unicode="&#x42e;" horiz-adv-x="1866" d="M199 0v1384h135v-622h301q6 150 39 270.5t98.5 205t166.5 130t243 45.5q152 0 256.5 -50t169.5 -143.5t94 -227t29 -300.5t-29.5 -300t-94.5 -227t-170 -144t-255 -50q-145 0 -247.5 47t-167.5 134t-96.5 211.5t-35.5 279.5h-301v-643h-135zM778 692q0 -143 21 -255 t68.5 -189t124.5 -117.5t190 -40.5q114 0 191.5 40t125 116.5t68 189t20.5 256.5t-20.5 255.5t-68 188t-125 116.5t-191.5 40q-113 0 -190 -39.5t-124.5 -115.5t-68.5 -188t-21 -257z" />
+<glyph unicode="&#x42f;" horiz-adv-x="1237" d="M72 0l377 606q-70 15 -124.5 43.5t-92 75.5t-57 114.5t-19.5 159.5q0 107 30 180.5t88.5 119t145.5 65.5t201 20h393v-1384h-135v586h-291l-355 -586h-161zM299 993q0 -78 16.5 -132.5t55 -88.5t101.5 -49.5t157 -15.5h250v557h-256q-90 0 -152 -15t-100 -47.5t-55 -84 t-17 -124.5z" />
+<glyph unicode="&#x430;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5z" />
+<glyph unicode="&#x431;" horiz-adv-x="1122" d="M125 639q0 184 17 317t55.5 226.5t100.5 152.5t151.5 96t209 56.5t273.5 34.5v-127q-114 -8 -207.5 -18.5t-167 -32t-127.5 -58t-90.5 -96t-55.5 -146t-22 -208.5q33 34 74.5 63t88.5 50t97.5 32.5t102.5 11.5q187 0 287 -117.5t100 -357.5q0 -122 -27.5 -223t-81 -173.5 t-133 -112.5t-182.5 -40q-120 0 -207.5 45.5t-144 132t-84 210.5t-27.5 282zM260 612q0 -128 21 -228t62 -168.5t103 -104t144 -35.5q63 0 116 28.5t91.5 83.5t60 136t21.5 186q0 193 -69 284t-220 91q-58 0 -107.5 -18t-90.5 -44.5t-73.5 -57t-56.5 -56.5q-2 -26 -2 -49 v-48z" />
+<glyph unicode="&#x432;" horiz-adv-x="1069" d="M182 0v1049h357q106 0 178.5 -14.5t116 -44.5t62.5 -77.5t19 -113.5q0 -88 -40.5 -152t-131.5 -96q47 -9 86 -27t66.5 -47.5t43 -71t15.5 -98.5q0 -84 -28 -142t-81.5 -95t-131 -53.5t-176.5 -16.5h-355zM307 104h182q92 0 156 10.5t103.5 34t57 62t17.5 94.5 q0 46 -13 79.5t-45 55.5t-86.5 32.5t-137.5 10.5h-234v-379zM307 588h199q142 0 211 52.5t69 139.5q0 52 -16 84t-49 50t-82 24t-115 6h-217v-356z" />
+<glyph unicode="&#x433;" horiz-adv-x="868" d="M182 0v1049h670v-109h-541v-940h-129z" />
+<glyph unicode="&#x434;" horiz-adv-x="1055" d="M20 109h99q40 73 77.5 169.5t65.5 215t45 257.5t17 298h530v-940h166v-371h-123v262h-754v-262h-123v371zM248 109h481v833h-283q-5 -141 -22 -261t-43 -222.5t-60 -189.5t-73 -160z" />
+<glyph unicode="&#x435;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5z" />
+<glyph unicode="&#x436;" horiz-adv-x="1438" d="M78 0q33 133 62 227.5t62.5 157.5t76 98.5t102.5 51.5q-35 10 -68 34t-65 79.5t-63.5 151.5t-63.5 249h133q30 -144 60.5 -235t63.5 -142t70 -69.5t80 -18.5h127v465h127v-465h127q44 0 81 18.5t70 69.5t63.5 142t60.5 235h131q-32 -153 -63 -248.5t-63 -151t-65 -80 t-67 -34.5q60 -15 102.5 -50.5t76 -98.5t62.5 -158t62 -228h-131q-25 95 -47.5 167t-44.5 125t-45.5 87.5t-51.5 55.5t-62 29.5t-77 8.5h-119v-473h-127v473h-120q-64 0 -108.5 -20t-80.5 -73t-68 -144.5t-69 -235.5h-131z" />
+<glyph unicode="&#x437;" horiz-adv-x="985" d="M94 168l109 63q47 -77 107 -114t155 -37q121 0 189.5 53t68.5 152t-64.5 151.5t-191.5 52.5h-199v109h189q65 0 115 8.5t84 29t51.5 55t17.5 85.5q0 48 -18.5 83.5t-52 59.5t-80 36t-101.5 12q-101 0 -161 -40t-101 -112l-102 66q55 100 143 149t219 49q89 0 160 -21.5 t120 -60.5t75 -94.5t26 -124.5q0 -51 -13.5 -91.5t-38 -70.5t-59 -50t-75.5 -31q42 -12 76 -37t58 -59.5t37 -76t13 -86.5q0 -146 -96 -226.5t-291 -80.5q-73 0 -129 13.5t-99.5 39t-77.5 62.5t-63 84z" />
+<glyph unicode="&#x438;" horiz-adv-x="1157" d="M182 0v1049h123v-875l535 875h135v-1049h-125v864l-531 -864h-137z" />
+<glyph unicode="&#x439;" horiz-adv-x="1157" d="M182 0v1049h123v-875l535 875h135v-1049h-125v864l-531 -864h-137zM271 1444h131q9 -79 49.5 -121.5t122.5 -42.5q50 0 83.5 9.5t55 30t32 51.5t15.5 73h133q-1 -47 -17.5 -91.5t-54 -79.5t-98 -56t-147.5 -21q-78 0 -135.5 21t-95 56t-55.5 79.5t-19 91.5z" />
+<glyph unicode="&#x43a;" horiz-adv-x="979" d="M182 0v1049h127v-465h158q43 0 79.5 18.5t69.5 69.5t63 142t60 235h133q-32 -153 -63.5 -248.5t-63 -151t-64.5 -80t-69 -34.5q61 -15 103.5 -50.5t76.5 -98.5t62.5 -158t60.5 -228h-131q-25 96 -47 168t-44 124.5t-45.5 87.5t-51 55.5t-61.5 29t-76 8.5h-150v-473h-127z " />
+<glyph unicode="&#x43b;" horiz-adv-x="1040" d="M12 0l27 113q15 -5 33.5 -7t33.5 -2q45 0 83.5 43t67.5 139.5t45.5 251.5t16.5 380v131h539v-1049h-127v940h-287v-51q0 -232 -23.5 -402.5t-66.5 -282t-105 -166t-138 -54.5q-11 0 -24.5 1.5t-27 3.5t-26 5t-21.5 6z" />
+<glyph unicode="&#x43c;" horiz-adv-x="1276" d="M182 0v1049h127l328 -592l330 592h127v-1049h-125v834l-299 -551h-68l-297 551v-834h-123z" />
+<glyph unicode="&#x43d;" horiz-adv-x="1163" d="M182 0v1049h127v-455h545v455h127v-1049h-127v487h-545v-487h-127z" />
+<glyph unicode="&#x43e;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30 q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5z" />
+<glyph unicode="&#x43f;" horiz-adv-x="1139" d="M182 0v1049h774v-1049h-129v938h-516v-938h-129z" />
+<glyph unicode="&#x440;" horiz-adv-x="1151" d="M182 -395v1444h129v-115q31 31 67.5 58t77 46t84.5 30t89 11q106 0 180.5 -42.5t121.5 -116.5t69 -173.5t22 -214.5q0 -123 -25 -226.5t-76 -178.5t-128.5 -116.5t-182.5 -41.5q-77 0 -153.5 34.5t-145.5 100.5v-499h-129zM311 225q69 -65 143.5 -104t145.5 -39 q62 0 115 26t91.5 80.5t60.5 138.5t22 201q0 101 -16.5 182t-51 137.5t-87.5 87t-126 30.5q-80 0 -154.5 -42.5t-142.5 -111.5v-586z" />
+<glyph unicode="&#x441;" horiz-adv-x="1016" d="M129 520q0 128 24.5 231.5t77 176t135 112t199.5 39.5q124 0 207.5 -49t140.5 -151l-106 -64q-21 39 -45 67.5t-53.5 47t-65.5 28t-82 9.5q-157 0 -228 -114t-71 -337q0 -98 15.5 -178t51 -137.5t94 -89t144.5 -31.5q49 0 86.5 10.5t67.5 30.5t54 48.5t46 63.5l105 -65 q-25 -47 -58 -84t-77 -62.5t-99.5 -39t-124.5 -13.5q-123 0 -206.5 42t-135 115.5t-74 174.5t-22.5 219z" />
+<glyph unicode="&#x442;" horiz-adv-x="807" d="M16 942v107h775v-107h-326v-942h-127v942h-322z" />
+<glyph unicode="&#x443;" horiz-adv-x="1018" d="M4 -365l37 109q25 -14 61 -21.5t70 -7.5q75 0 129 59.5t98 176.5l41 104l-383 994h140l311 -832l315 832h138l-453 -1147q-32 -81 -67.5 -138t-76.5 -92t-89 -51t-105 -16q-21 0 -44.5 2t-46 6t-42 9.5t-33.5 12.5z" />
+<glyph unicode="&#x444;" horiz-adv-x="1343" d="M129 520q0 149 31 253.5t92.5 170.5t152 97.5t209.5 35.5v412h121v-412q122 -5 212 -38t149.5 -100.5t88.5 -171t29 -247.5q0 -148 -30.5 -249.5t-90.5 -166t-150 -95.5t-208 -38v-366h-121v366q-118 5 -208.5 36t-152 96t-93 167.5t-31.5 249.5zM260 520 q0 -105 17.5 -185t59 -135t109 -85.5t168.5 -36.5v891q-98 -6 -165.5 -34.5t-109.5 -82.5t-60.5 -136t-18.5 -196zM735 80q97 6 163.5 34t107 81.5t58 133.5t17.5 191q0 108 -17 190t-57.5 137.5t-107 85.5t-164.5 36v-889z" />
+<glyph unicode="&#x445;" horiz-adv-x="965" d="M59 0l351 522l-344 527h151l270 -431l273 431h143l-344 -519l344 -530h-155l-269 432l-276 -432h-144z" />
+<glyph unicode="&#x446;" horiz-adv-x="1180" d="M182 0v1049h129v-940h541v940h129v-943h164v-368h-121v262h-842z" />
+<glyph unicode="&#x447;" horiz-adv-x="1049" d="M98 723v326h127v-289q0 -95 9.5 -155t30.5 -95t54.5 -48t81.5 -13q39 0 83 6t88.5 16.5t87.5 25.5t79 33v519h127v-1049h-127v420q-41 -17 -85.5 -33t-90 -29t-91.5 -20.5t-89 -7.5q-77 0 -131 23t-88.5 71.5t-50 122.5t-15.5 176z" />
+<glyph unicode="&#x448;" horiz-adv-x="1628" d="M182 0v1049h127v-945h449v945h127v-945h448v945h127v-1049h-1278z" />
+<glyph unicode="&#x449;" horiz-adv-x="1663" d="M182 0v1049h127v-943h449v943h127v-943h448v943h127v-943h166v-368h-123v262h-1321z" />
+<glyph unicode="&#x44a;" horiz-adv-x="1032" d="M16 942v107h375v-412h166q102 0 176 -18t121.5 -57.5t70.5 -102.5t23 -152q0 -85 -25 -143.5t-73.5 -95t-121.5 -52.5t-169 -16h-295v942h-248zM391 104h160q74 0 124.5 11.5t81.5 36.5t44.5 64t13.5 93q0 64 -14.5 107t-47.5 69t-85.5 36.5t-128.5 10.5h-148v-428z" />
+<glyph unicode="&#x44b;" horiz-adv-x="1425" d="M182 0v1049h127v-412h166q102 0 176 -18t122 -57.5t70.5 -102.5t22.5 -152q0 -81 -22.5 -139.5t-69.5 -95.5t-121 -54.5t-176 -17.5h-295zM309 104h162q75 0 125 12t80.5 37t43.5 63.5t13 92.5q0 61 -13 104t-44.5 69t-84.5 38t-134 12h-148v-428zM1114 0v1049h129v-1049 h-129z" />
+<glyph unicode="&#x44c;" horiz-adv-x="952" d="M182 0v1049h127v-412h166q102 0 176 -18t122 -57.5t70.5 -102.5t22.5 -152q0 -81 -22.5 -139.5t-69.5 -95.5t-121 -54.5t-176 -17.5h-295zM309 104h162q75 0 125 12t80.5 37t43.5 63.5t13 92.5q0 61 -13 104t-44.5 69t-84.5 38t-134 12h-148v-428z" />
+<glyph unicode="&#x44d;" horiz-adv-x="1016" d="M88 168l107 65q21 -35 45 -63.5t54 -48.5t67.5 -30.5t87.5 -10.5q80 0 136 27.5t92 78.5t54 123.5t21 161.5h-529v107h529q-11 193 -82.5 291t-216.5 98q-45 0 -81.5 -9.5t-65.5 -28t-52.5 -47t-44.5 -67.5l-107 64q56 102 140.5 151t208.5 49q116 0 198.5 -39.5 t135.5 -112t77.5 -176t24.5 -231.5q0 -118 -23 -219t-74.5 -174.5t-136 -115.5t-207.5 -42q-69 0 -124 13.5t-98.5 39t-77 62.5t-58.5 84z" />
+<glyph unicode="&#x44e;" horiz-adv-x="1544" d="M182 0v1049h125v-463h230q5 110 32.5 200.5t80.5 155.5t133.5 101t191.5 36q117 0 200 -39t136.5 -111.5t78.5 -175.5t25 -231q0 -125 -24.5 -227t-77.5 -174.5t-136.5 -112t-201.5 -39.5q-114 0 -195.5 36.5t-134.5 103t-79.5 161t-30.5 211.5h-228v-481h-125zM662 522 q0 -104 18 -187t56 -140.5t97 -88t142 -30.5q81 0 139.5 30.5t96 87.5t55.5 140t18 188q0 106 -17 190t-54 142t-95.5 88.5t-142.5 30.5t-143.5 -31.5t-97 -90t-55 -142t-17.5 -187.5z" />
+<glyph unicode="&#x44f;" horiz-adv-x="1032" d="M68 0l270 459q-111 29 -161 102.5t-50 198.5q0 79 23 134t70 89.5t118.5 50t169.5 15.5h342v-1049h-127v442h-219h-43l-252 -442h-141zM258 754q0 -57 12 -96.5t42 -64t81 -35.5t129 -11h201v397h-203q-77 0 -127.5 -10t-80.5 -32.5t-42 -58.5t-12 -89z" />
+<glyph unicode="&#x450;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5zM313 1569h176l186 -361h-104z" />
+<glyph unicode="&#x451;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5zM272 1300q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5 t-3.5 36.5zM642 1300q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x452;" horiz-adv-x="1090" d="M25 1217v106h141v166h129v-166h295v-106h-295v-324q47 52 92 87.5t88 57.5t82.5 31.5t75.5 9.5q86 0 150 -33.5t106 -104t63 -180t21 -261.5q0 -181 -19.5 -333t-69 -266.5t-135.5 -188t-219 -97.5l-20 111q81 14 143 59.5t103.5 133.5t62.5 225t21 335q0 138 -15 230 t-43.5 147t-71.5 77.5t-98 22.5q-27 0 -60.5 -8t-73 -28.5t-85.5 -56.5t-98 -91v-772h-129v1217h-141z" />
+<glyph unicode="&#x453;" horiz-adv-x="868" d="M182 0v1049h670v-109h-541v-940h-129zM401 1208l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x454;" horiz-adv-x="1016" d="M129 520q0 128 24.5 231.5t77 176t135 112t199.5 39.5q124 0 207.5 -49t140.5 -151l-106 -64q-21 39 -45 67.5t-53.5 47t-65.5 28t-82 9.5q-145 0 -216.5 -97t-80.5 -292h527v-107h-527q3 -89 20.5 -161.5t53.5 -123.5t92 -78.5t137 -27.5q49 0 86.5 10.5t67.5 30.5 t54 48.5t46 63.5l105 -65q-25 -47 -58 -84t-77 -62.5t-99.5 -39t-124.5 -13.5q-123 0 -206.5 42t-135 115.5t-74 174.5t-22.5 219z" />
+<glyph unicode="&#x455;" horiz-adv-x="973" d="M117 154l104 65q35 -63 98.5 -101t163.5 -38q52 0 97 8.5t78 29.5t52 56.5t19 89.5q0 42 -12 72.5t-42.5 54t-82.5 42.5t-133 40q-84 22 -144.5 47t-100 60.5t-58.5 85t-19 120.5q0 58 21.5 111.5t66 93.5t111.5 64t158 24q69 0 123.5 -15t96.5 -40.5t72 -59.5t50 -71 l-105 -62q-15 28 -36.5 53t-50 43.5t-65.5 29t-85 10.5q-107 0 -168.5 -47t-61.5 -132q0 -41 11 -70t37 -50.5t70.5 -38.5t111.5 -35q101 -27 170.5 -55t112 -65t61 -86.5t18.5 -119.5q0 -74 -25.5 -130t-74 -93.5t-118 -56.5t-157.5 -19q-81 0 -142 17.5t-105.5 44.5 t-73 59.5t-43.5 63.5z" />
+<glyph unicode="&#x456;" horiz-adv-x="494" d="M156 1305q0 45 20 65.5t70 20.5q51 0 71.5 -20t20.5 -66q0 -51 -21.5 -69.5t-70.5 -18.5q-51 0 -70.5 23t-19.5 65zM182 0v1049h129v-1049h-129z" />
+<glyph unicode="&#x457;" horiz-adv-x="494" d="M-35 1300q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM182 0v1049h129v-1049h-129zM335 1300q0 45 18.5 67t69.5 22q54 0 72 -21t18 -68q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25 t-17.5 65z" />
+<glyph unicode="&#x458;" horiz-adv-x="508" d="M-141 -365l32 107q36 -14 73 -21.5t79 -7.5q43 0 72 14t46 44t24.5 76.5t7.5 111.5v1090h129v-1104q0 -86 -13.5 -149.5t-46 -106t-87.5 -63.5t-138 -21q-40 0 -86 7.5t-92 22.5zM166 1305q0 45 21.5 65.5t70.5 20.5q51 0 71.5 -20t20.5 -66q0 -51 -22 -69.5t-70 -18.5 q-53 0 -72.5 23t-19.5 65z" />
+<glyph unicode="&#x459;" horiz-adv-x="1497" d="M12 0l27 113q15 -5 33.5 -7t33.5 -2q45 0 83.5 43t67.5 139.5t45.5 251.5t16.5 380v131h537v-412h164q103 0 177 -18t122 -57.5t71 -102.5t23 -152q0 -85 -25 -143.5t-74 -95t-122 -52.5t-170 -16h-293v940h-285v-51q0 -232 -23.5 -402.5t-66.5 -282t-105 -166 t-138 -54.5q-11 0 -24.5 1.5t-27 3.5t-26 5t-21.5 6zM856 104h160q70 0 120 10.5t82 34.5t47 63.5t15 96.5q0 64 -14.5 107t-47.5 69t-85.5 36.5t-128.5 10.5h-148v-428z" />
+<glyph unicode="&#x45a;" horiz-adv-x="1587" d="M182 0v1049h127v-435h508v435h127v-435h166q103 0 177 -17t122 -54.5t71 -96.5t23 -143t-25 -142t-74 -94t-122 -51.5t-170 -15.5h-295v508h-508v-508h-127zM944 104h162q74 0 124.5 11.5t81.5 35.5t44.5 62t13.5 92q0 56 -12.5 95t-44 63t-85.5 34.5t-136 10.5h-148 v-404z" />
+<glyph unicode="&#x45b;" horiz-adv-x="1137" d="M14 1206v109h168v174h129v-174h283v-109h-283v-323q44 41 89 77t91.5 62.5t93.5 41.5t95 15q84 0 139 -25t87 -73.5t44.5 -119t12.5 -161.5v-700h-129v651q0 89 -8 148t-28 94t-54.5 49t-86.5 14q-69 0 -160 -51.5t-186 -142.5v-762h-129v1206h-168z" />
+<glyph unicode="&#x45c;" horiz-adv-x="979" d="M182 0v1049h127v-465h158q43 0 79.5 18.5t69.5 69.5t63 142t60 235h133q-32 -153 -63.5 -248.5t-63 -151t-64.5 -80t-69 -34.5q61 -15 103.5 -50.5t76.5 -98.5t62.5 -158t60.5 -228h-131q-25 96 -47 168t-44 124.5t-45.5 87.5t-51 55.5t-61.5 29t-76 8.5h-150v-473h-127z M417 1208l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x45d;" horiz-adv-x="1157" d="M182 0v1049h123v-875l535 875h135v-1049h-125v864l-531 -864h-137zM317 1569h176l186 -361h-104z" />
+<glyph unicode="&#x45e;" horiz-adv-x="1018" d="M4 -365l37 109q25 -14 61 -21.5t70 -7.5q75 0 129 59.5t98 176.5l41 104l-383 994h140l311 -832l315 832h138l-453 -1147q-32 -81 -67.5 -138t-76.5 -92t-89 -51t-105 -16q-21 0 -44.5 2t-46 6t-42 9.5t-33.5 12.5zM198 1444h131q9 -79 49.5 -121.5t122.5 -42.5 q50 0 83.5 9.5t55 30t32 51.5t15.5 73h133q-1 -47 -17.5 -91.5t-54 -79.5t-98 -56t-147.5 -21q-78 0 -135.5 21t-95 56t-55.5 79.5t-19 91.5z" />
+<glyph unicode="&#x45f;" horiz-adv-x="1135" d="M166 0v1049h131v-940h541v940h129v-1049h-336v-262h-129v262h-336z" />
+<glyph unicode="&#x490;" horiz-adv-x="1065" d="M199 0v1384h696v250h133v-372h-692v-1262h-137z" />
+<glyph unicode="&#x491;" horiz-adv-x="829" d="M166 0v1049h514v307h125v-416h-508v-940h-131z" />
+<glyph unicode="&#x1e80;" horiz-adv-x="1718" d="M80 1384h137l277 -1202l278 1202h168l287 -1212l278 1212h133l-325 -1384h-176l-281 1204l-283 -1204h-170zM600 1905h176l186 -361h-104z" />
+<glyph unicode="&#x1e81;" horiz-adv-x="1430" d="M82 1049h133l186 -861l258 861h117l262 -861l181 861h129l-244 -1049h-125l-264 870l-264 -870h-125zM443 1569h176l186 -361h-104z" />
+<glyph unicode="&#x1e82;" horiz-adv-x="1718" d="M80 1384h137l277 -1202l278 1202h168l287 -1212l278 1212h133l-325 -1384h-176l-281 1204l-283 -1204h-170zM779 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x1e83;" horiz-adv-x="1430" d="M82 1049h133l186 -861l258 861h117l262 -861l181 861h129l-244 -1049h-125l-264 870l-264 -870h-125zM645 1208l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x1e84;" horiz-adv-x="1718" d="M80 1384h137l277 -1202l278 1202h168l287 -1212l278 1212h133l-325 -1384h-176l-281 1204l-283 -1204h-170zM586 1636q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM956 1636q0 45 18.5 67 t69.5 22q54 0 72 -21t18 -68q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x1e85;" horiz-adv-x="1430" d="M82 1049h133l186 -861l258 861h117l262 -861l181 861h129l-244 -1049h-125l-264 870l-264 -870h-125zM453 1300q0 45 18.5 67t69.5 22q53 0 71.5 -21.5t18.5 -67.5q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5zM823 1300q0 45 18.5 67 t69.5 22q54 0 72 -21t18 -68q0 -48 -19.5 -69t-70.5 -21q-53 0 -70.5 25t-17.5 65z" />
+<glyph unicode="&#x1e9e;" horiz-adv-x="1364" d="M199 0v915q0 132 27 226.5t84.5 155t147.5 89.5t216 29q74 0 136 -4.5t124 -15.5v-103q-149 0 -217 -68.5t-68 -191.5q0 -52 11 -91.5t37.5 -70.5t71 -55.5t112.5 -46.5q93 -32 162.5 -71.5t115.5 -89t69 -110.5t23 -137q0 -95 -31 -168t-85.5 -122t-130 -74t-164.5 -25 q-88 0 -153.5 19.5t-113.5 55t-81 86t-56 112.5l121 55q34 -98 101.5 -152.5t181.5 -54.5q57 0 106.5 15.5t86 47.5t58 81t21.5 116q0 51 -14.5 94t-48.5 79t-88.5 66t-135.5 56q-87 28 -146 65t-96 83t-53 102.5t-16 124.5q0 104 39.5 170.5t99.5 101.5q-87 0 -147.5 -17.5 t-98.5 -59.5t-55.5 -112.5t-17.5 -176.5v-928h-135z" />
+<glyph unicode="&#x1ea0;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM381 522h493l-247 731zM535 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ea1;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM397 -240 q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ea2;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM381 522h493l-247 731zM451 1767q23 19 68 34.5t98 15.5q86 0 133 -36t47 -98q0 -66 -39.5 -101.5t-112.5 -43.5v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z " />
+<glyph unicode="&#x1ea3;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM352 1432 q23 18 68 33.5t98 15.5q86 0 133 -35.5t47 -97.5q0 -66 -39.5 -102t-112.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ea4;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM315 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM381 522h493l-247 731zM811 1733l135 274h170l-203 -274h-102z" />
+<glyph unicode="&#x1ea5;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM201 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18 q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM697 1397l135 274h170l-203 -274h-102z" />
+<glyph unicode="&#x1ea6;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM141 2007h170l135 -274h-102zM315 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM381 522h493l-247 731z" />
+<glyph unicode="&#x1ea7;" horiz-adv-x="1079" d="M36 1671h170l135 -274h-102zM121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5 t69 -113t21.5 -169.5v-713h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM210 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58 t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5z" />
+<glyph unicode="&#x1ea8;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM315 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM381 522h493l-247 731zM739 1948q12 9 29.5 18t39 15.5t46.5 11t51 4.5q87 0 133.5 -35.5t46.5 -97.5q0 -66 -39.5 -102t-111.5 -44v-41 h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8t-56.5 -25z" />
+<glyph unicode="&#x1ea9;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM210 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18 q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM634 1612q12 9 29.5 18t39 15.5t46.5 11t51 4.5q87 0 133.5 -35.5t46.5 -97.5q0 -66 -39.5 -102t-111.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8t-56.5 -25z" />
+<glyph unicode="&#x1eaa;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM268 1833q5 106 60 160.5t149 54.5q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -104 -59 -158.5t-150 -54.5q-40 0 -70.5 9.5t-55 23t-46 30t-43.5 30t-46 23t-54 9.5 q-51 0 -75.5 -27.5t-29.5 -87.5h-94zM317 1503l234 269h160l233 -269h-111l-202 172l-203 -172h-111zM381 522h493l-247 731z" />
+<glyph unicode="&#x1eab;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM161 1507q5 107 60 161t149 54q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -103 -59 -158t-150 -55q-40 0 -70.5 9.5t-55 23 t-46 30t-43.5 30t-46 23t-54 9.5q-51 0 -75.5 -27.5t-29.5 -87.5h-94zM210 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71 t-18.5 -102.5z" />
+<glyph unicode="&#x1eac;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM318 1544l229 361h168l229 -361h-110l-203 264l-203 -264h-110zM381 522h493l-247 731zM535 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5 t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ead;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM212 1208l229 361h168l229 -361h-110l-203 265l-203 -265h-110zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18 q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM397 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1eae;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM319 1784h99q12 -69 65 -106.5t140 -37.5q54 0 93 8.5t65.5 26t41.5 44.5t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM381 522h493 l-247 731zM551 1733l135 274h172l-205 -274h-102z" />
+<glyph unicode="&#x1eaf;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM212 1468h99q12 -69 65 -106t140 -37q54 0 93 8.5t65.5 25.5t41.5 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5 t-56 83.5t-19.5 98zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM444 1417l135 275h172l-205 -275h-102z" />
+<glyph unicode="&#x1eb0;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM317 1784h99q12 -69 65 -106.5t140 -37.5q54 0 93 8.5t65.5 26t41.5 44.5t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM381 522h493 l-247 731zM401 2007h170l136 -274h-103z" />
+<glyph unicode="&#x1eb1;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM212 1468h99q12 -69 65 -106t140 -37q54 0 93 8.5t65.5 25.5t41.5 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5 t-56 83.5t-19.5 98zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM296 1692h170l136 -275h-103z" />
+<glyph unicode="&#x1eb2;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM317 1784h99q12 -69 65 -106.5t140 -37.5q54 0 93 8.5t65.5 26t41.5 44.5t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM381 522h493 l-247 731zM451 2001q23 18 68 33.5t97 15.5q87 0 134 -35.5t47 -97.5q0 -66 -40 -101.5t-112 -43.5v-41h-82v106h29q45 0 68.5 17t23.5 49q0 29 -18.5 45t-63.5 16q-26 0 -54.5 -8t-55.5 -25z" />
+<glyph unicode="&#x1eb3;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM212 1468h99q12 -69 65 -106t140 -37q54 0 93 8.5t65.5 25.5t41.5 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5 t-56 83.5t-19.5 98zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM346 1686q23 18 68 33.5t97 15.5q87 0 134 -36t47 -97q0 -67 -40 -102.5t-112 -43.5v-41h-82v107h29 q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8t-55.5 -25z" />
+<glyph unicode="&#x1eb4;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM266 1843q5 107 60 161t149 54q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -103 -59 -158t-150 -55q-40 0 -70.5 9.5t-55 23t-46 30t-43.5 30t-46 23t-54 9.5 q-51 0 -75.5 -27.5t-29.5 -87.5h-94zM317 1784h99q12 -69 65 -106.5t140 -37.5q54 0 93 8.5t65.5 26t41.5 44.5t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM381 522h493l-247 731z" />
+<glyph unicode="&#x1eb5;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM161 1528q5 106 60 160.5t149 54.5q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -104 -59 -158.5t-150 -54.5q-40 0 -70.5 9 t-55 23t-46 30t-43.5 30t-46 23t-54 9q-51 0 -75.5 -27t-29.5 -87h-94zM212 1468h99q12 -69 65 -106t140 -37q54 0 93 8.5t65.5 25.5t41.5 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM254 299 q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5z" />
+<glyph unicode="&#x1eb6;" horiz-adv-x="1264" d="M63 0l480 1384h174l483 -1384h-147l-135 399h-578l-135 -399h-142zM318 1794h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98zM381 522h493l-247 731z M535 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1eb7;" horiz-adv-x="1079" d="M121 295q0 82 24 143t75 103.5t130.5 67.5t190.5 36l235 23v53q0 66 -15 112.5t-47.5 76.5t-83 43.5t-120.5 13.5q-59 0 -102.5 -10.5t-75 -28t-52.5 -40.5t-36 -48l-103 63q22 36 52.5 68t75 56t104 38t139.5 14q106 0 180.5 -20t122 -63.5t69 -113t21.5 -169.5v-713 h-129v152q-45 -39 -87 -72.5t-85.5 -58t-90 -38.5t-99.5 -14q-74 0 -129 22.5t-91.5 65t-54.5 103t-18 135.5zM212 1468h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5 t-55.5 83.5t-19 98zM254 299q0 -114 46 -165.5t144 -51.5q37 0 72.5 11t74.5 33.5t84 58t101 83.5v293l-188 -18q-90 -9 -153.5 -25.5t-103.5 -45t-58.5 -71t-18.5 -102.5zM397 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7 t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1eb8;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM504 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1eb9;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5zM446 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5 t-4 38z" />
+<glyph unicode="&#x1eba;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM434 1767q23 19 68 34.5t98 15.5q86 0 133 -36t47 -98q0 -66 -39.5 -101.5t-112.5 -43.5v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ebb;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5zM377 1432q23 18 68 33.5t98 15.5q86 0 133 -35.5t47 -97.5q0 -66 -39.5 -102t-112.5 -44v-41h-82v107h29q45 0 68.5 16.5 t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ebc;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM249 1550q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -35t45 -35t44.5 -26.5t48.5 -10.5q51 0 77 31.5t31 100.5h94q-3 -113 -58.5 -173.5t-149.5 -60.5q-43 0 -74.5 11t-56.5 27t-45.5 35 t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -33.5t-29 -102.5h-95z" />
+<glyph unicode="&#x1ebd;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM181 1214q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -34.5t45 -34.5t44.5 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35t-44.5 27 t-53.5 11q-51 0 -75 -34t-29 -104h-95zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5z" />
+<glyph unicode="&#x1ebe;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM292 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM788 1733l135 274h170l-203 -274h-102z" />
+<glyph unicode="&#x1ebf;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM239 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5zM735 1397l135 274h170l-203 -274h-102z" />
+<glyph unicode="&#x1ec0;" horiz-adv-x="1155" d="M121 2007h170l135 -274h-102zM199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM295 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111z" />
+<glyph unicode="&#x1ec1;" horiz-adv-x="1051" d="M59 1671h170l135 -274h-102zM129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59 t-99 -37t-127.5 -13q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM233 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5z" />
+<glyph unicode="&#x1ec2;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM292 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM716 1948q12 9 29.5 18t39 15.5t46.5 11t51 4.5q87 0 133.5 -35.5t46.5 -97.5q0 -66 -39.5 -102t-111.5 -44v-41h-82v107h29 q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8t-56.5 -25z" />
+<glyph unicode="&#x1ec3;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM233 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5zM657 1612q12 9 29.5 18t39 15.5t46.5 11t51 4.5 q87 0 133.5 -35.5t46.5 -97.5q0 -66 -39.5 -102t-111.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8t-56.5 -25z" />
+<glyph unicode="&#x1ec4;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM246 1833q5 106 60 160.5t149 54.5q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -104 -59 -158.5t-150 -54.5q-40 0 -70.5 9.5t-55 23t-46 30t-43.5 30t-46 23t-54 9.5 q-51 0 -75.5 -27.5t-29.5 -87.5h-94zM295 1503l234 269h160l233 -269h-111l-202 172l-203 -172h-111z" />
+<glyph unicode="&#x1ec5;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM188 1507q5 107 60 161t149 54q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -103 -59 -158t-150 -55q-40 0 -70.5 9.5t-55 23t-46 30t-43.5 30t-46 23t-54 9.5q-51 0 -75.5 -27.5 t-29.5 -87.5h-94zM237 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5z" />
+<glyph unicode="&#x1ec6;" horiz-adv-x="1155" d="M199 0v1384h819v-122h-684v-467h588v-123h-588v-549h684v-123h-819zM293 1544l229 361h168l229 -361h-110l-203 265l-203 -265h-110zM504 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ec7;" horiz-adv-x="1051" d="M129 516q0 133 23 237.5t73.5 177t131 110.5t196.5 38q102 0 175 -32t119.5 -92.5t68.5 -148t22 -198.5v-84h-676q0 -115 14.5 -199t49 -138.5t91.5 -80.5t142 -26q42 0 77 7.5t65.5 25t58.5 45t55 67.5l103 -67q-28 -45 -61.5 -80t-77 -59t-99 -37t-127.5 -13 q-104 0 -183 30t-132.5 95.5t-81 169.5t-27.5 252zM235 1208l229 361h168l229 -361h-110l-203 265l-203 -265h-110zM264 629h547q-3 177 -66 259.5t-196 82.5q-69 0 -119.5 -20t-85 -62t-54 -106.5t-26.5 -153.5zM452 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5 q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ec8;" horiz-adv-x="719" d="M102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514zM188 1767q23 19 68 34.5t98 15.5q86 0 133 -36t47 -98q0 -66 -39.5 -101.5t-112.5 -43.5v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ec9;" horiz-adv-x="494" d="M83 1432q23 18 68 33.5t98 15.5q86 0 133 -35.5t47 -97.5q0 -66 -39.5 -102t-112.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33zM182 0v1049h129v-1049h-129z" />
+<glyph unicode="&#x1eca;" horiz-adv-x="719" d="M102 0v119h189v1147h-189v118h514v-118h-190v-1147h190v-119h-514zM263 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ecb;" horiz-adv-x="494" d="M151 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38zM156 1305q0 45 20 65.5t70 20.5q51 0 71.5 -20t20.5 -66q0 -51 -21.5 -69.5t-70.5 -18.5q-51 0 -70.5 23t-19.5 65zM182 0v1049h129v-1049 h-129z" />
+<glyph unicode="&#x1ecc;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM584 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5 t-4 38z" />
+<glyph unicode="&#x1ecd;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30 q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM473 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38 z" />
+<glyph unicode="&#x1ece;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM508 1767q23 19 68 34.5t98 15.5q86 0 133 -36t47 -98q0 -66 -39.5 -101.5t-112.5 -43.5v-41h-82v107h29q45 0 68.5 16.5 t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ecf;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30 q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM396 1432q23 18 68 33.5t98 15.5q86 0 133 -35.5t47 -97.5q0 -66 -39.5 -102t-112.5 -44v-41h-82v107h29q45 0 68.5 16.5 t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ed0;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM362 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM858 1733l135 274h170l-203 -274h-102z" />
+<glyph unicode="&#x1ed1;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM249 1167l234 279h160l233 -279h-111l-202 183l-203 -183 h-111zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM745 1397l135 274h170l-203 -274h-102z" />
+<glyph unicode="&#x1ed2;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM188 2007h170l135 -274h-102zM279 692q0 -144 21 -255t68.5 -187.5 t124.5 -116t189 -39.5q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM362 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111z" />
+<glyph unicode="&#x1ed3;" horiz-adv-x="1141" d="M80 1671h170l135 -274h-102zM129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM254 1167l234 279h160 l233 -279h-111l-202 183l-203 -183h-111zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5z" />
+<glyph unicode="&#x1ed4;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM360 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM784 1948q12 9 29.5 18t39 15.5t46.5 11t51 4.5 q87 0 133.5 -35.5t46.5 -97.5q0 -66 -39.5 -102t-111.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8t-56.5 -25z" />
+<glyph unicode="&#x1ed5;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM249 1167l234 279h160l233 -279h-111l-202 183l-203 -183 h-111zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM673 1612q12 9 29.5 18t39 15.5t46.5 11t51 4.5q87 0 133.5 -35.5 t46.5 -97.5q0 -66 -39.5 -102t-111.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8t-56.5 -25z" />
+<glyph unicode="&#x1ed6;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM315 1833q5 106 60 160.5t149 54.5q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94 q-3 -104 -59 -158.5t-150 -54.5q-40 0 -70.5 9.5t-55 23t-46 30t-43.5 30t-46 23t-54 9.5q-51 0 -75.5 -27.5t-29.5 -87.5h-94zM364 1503l234 269h160l233 -269h-111l-202 172l-203 -172h-111z" />
+<glyph unicode="&#x1ed7;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM205 1507q5 107 60 161t149 54q52 0 93 -19t76.5 -42.5 t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -103 -59 -158t-150 -55q-40 0 -70.5 9.5t-55 23t-46 30t-43.5 30t-46 23t-54 9.5q-51 0 -75.5 -27.5t-29.5 -87.5h-94zM254 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM262 522q0 -104 16.5 -186t53 -139 t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5z" />
+<glyph unicode="&#x1ed8;" horiz-adv-x="1364" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5t254.5 -50t169.5 -143t94 -226.5t29 -301.5q0 -167 -29 -300.5t-94 -227t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5 q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5t-21 -256.5zM369 1544l229 361h168l229 -361h-110l-203 265l-203 -265h-110zM584 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5 q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ed9;" horiz-adv-x="1141" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q117 0 200.5 -39.5t137 -112.5t78.5 -175.5t25 -229.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM256 1208l229 361h168l229 -361h-110l-203 265l-203 -265 h-110zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM473 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5 q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1eda;" horiz-adv-x="1452" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5q103 0 183.5 -23.5t142 -68.5t104 -110.5t68.5 -149.5h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-29q23 -121 23 -264q0 -167 -29 -300.5t-94 -227 t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5 t-21 -256.5zM570 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x1edb;" horiz-adv-x="1190" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q82 0 148 -20t116 -58t85.5 -92t56.5 -123q70 1 99.5 46.5t29.5 146.5v151h121v-151q0 -71 -12.5 -124.5t-39.5 -90.5t-70.5 -57.5t-105.5 -24.5q7 -37 10 -77.5t3 -82.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5 t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM469 1208 l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x1edc;" horiz-adv-x="1452" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5q103 0 183.5 -23.5t142 -68.5t104 -110.5t68.5 -149.5h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-29q23 -121 23 -264q0 -167 -29 -300.5t-94 -227 t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5 t-21 -256.5zM441 1905h176l186 -361h-104z" />
+<glyph unicode="&#x1edd;" horiz-adv-x="1190" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q82 0 148 -20t116 -58t85.5 -92t56.5 -123q70 1 99.5 46.5t29.5 146.5v151h121v-151q0 -71 -12.5 -124.5t-39.5 -90.5t-70.5 -57.5t-105.5 -24.5q7 -37 10 -77.5t3 -82.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5 t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM342 1569 h176l186 -361h-104z" />
+<glyph unicode="&#x1ede;" horiz-adv-x="1452" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5q103 0 183.5 -23.5t142 -68.5t104 -110.5t68.5 -149.5h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-29q23 -121 23 -264q0 -167 -29 -300.5t-94 -227 t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5 t-21 -256.5zM525 1767q23 19 68 34.5t98 15.5q86 0 133 -36t47 -98q0 -66 -39.5 -101.5t-112.5 -43.5v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1edf;" horiz-adv-x="1190" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q82 0 148 -20t116 -58t85.5 -92t56.5 -123q70 1 99.5 46.5t29.5 146.5v151h121v-151q0 -71 -12.5 -124.5t-39.5 -90.5t-70.5 -57.5t-105.5 -24.5q7 -37 10 -77.5t3 -82.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5 t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM414 1432 q23 18 68 33.5t98 15.5q86 0 133 -35.5t47 -97.5q0 -66 -39.5 -102t-112.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ee0;" horiz-adv-x="1452" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5q103 0 183.5 -23.5t142 -68.5t104 -110.5t68.5 -149.5h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-29q23 -121 23 -264q0 -167 -29 -300.5t-94 -227 t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5 t-21 -256.5zM319 1550q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -35t45 -35t44.5 -26.5t48.5 -10.5q51 0 77 31.5t31 100.5h94q-3 -113 -58.5 -173.5t-149.5 -60.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -33.5t-29 -102.5h-95z " />
+<glyph unicode="&#x1ee1;" horiz-adv-x="1190" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q82 0 148 -20t116 -58t85.5 -92t56.5 -123q70 1 99.5 46.5t29.5 146.5v151h121v-151q0 -71 -12.5 -124.5t-39.5 -90.5t-70.5 -57.5t-105.5 -24.5q7 -37 10 -77.5t3 -82.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5 t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM206 1214q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -34.5t45 -34.5t44.5 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35 t-44.5 27t-53.5 11q-51 0 -75 -34t-29 -104h-95zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5z" />
+<glyph unicode="&#x1ee2;" horiz-adv-x="1452" d="M135 692q0 166 29.5 299.5t94.5 227t169 144t254 50.5q103 0 183.5 -23.5t142 -68.5t104 -110.5t68.5 -149.5h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-29q23 -121 23 -264q0 -167 -29 -300.5t-94 -227 t-169.5 -143.5t-254.5 -50t-254 50t-169 144t-94.5 227t-29.5 300zM279 692q0 -144 21 -255t68.5 -187.5t124.5 -116t189 -39.5q111 0 188 39.5t124 115.5t68 187.5t21 255.5t-21 255.5t-68 187.5t-124 115.5t-188 39.5q-112 0 -189 -39t-124.5 -115t-68.5 -187.5 t-21 -256.5zM588 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ee3;" horiz-adv-x="1190" d="M129 522q0 122 24 224.5t77 176.5t137 115t204 41q82 0 148 -20t116 -58t85.5 -92t56.5 -123q70 1 99.5 46.5t29.5 146.5v151h121v-151q0 -71 -12.5 -124.5t-39.5 -90.5t-70.5 -57.5t-105.5 -24.5q7 -37 10 -77.5t3 -82.5q0 -125 -24 -226.5t-77 -174.5t-137 -112.5 t-203 -39.5t-203 39.5t-137 112.5t-77.5 174.5t-24.5 226.5zM262 522q0 -104 16.5 -186t53 -139t95.5 -87t144 -30q83 0 141.5 29.5t95 86.5t53 139t16.5 187q0 106 -16 189t-52 140t-94.5 86.5t-143.5 29.5q-86 0 -145 -30.5t-95.5 -88t-52.5 -140t-16 -186.5zM473 -240 q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ee4;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM592 -240q0 48 21 72.5t75 24.5 q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ee5;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM444 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5 t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ee6;" horiz-adv-x="1378" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-806q0 -170 -26 -286.5t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM514 1767q23 19 68 34.5t98 15.5 q86 0 133 -36t47 -98q0 -66 -39.5 -101.5t-112.5 -43.5v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ee7;" horiz-adv-x="1137" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-1049h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM389 1432q23 18 68 33.5t98 15.5q86 0 133 -35.5 t47 -97.5q0 -66 -39.5 -102t-112.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ee8;" horiz-adv-x="1456" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-323h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-55v-378q0 -170 -26 -286.5 t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM594 1544l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x1ee9;" horiz-adv-x="1208" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-263h31q76 0 107.5 44.5t31.5 148.5v151h121v-151q0 -74 -13.5 -129.5t-43.5 -93t-78.5 -56t-118.5 -18.5h-37v-682h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41 t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM480 1208l186 361h178l-260 -361h-104z" />
+<glyph unicode="&#x1eea;" horiz-adv-x="1456" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-323h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-55v-378q0 -170 -26 -286.5 t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM439 1905h176l186 -361h-104z" />
+<glyph unicode="&#x1eeb;" horiz-adv-x="1208" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-263h31q76 0 107.5 44.5t31.5 148.5v151h121v-151q0 -74 -13.5 -129.5t-43.5 -93t-78.5 -56t-118.5 -18.5h-37v-682h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41 t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM307 1569h176l186 -361h-104z" />
+<glyph unicode="&#x1eec;" horiz-adv-x="1456" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-323h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-55v-378q0 -170 -26 -286.5 t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM523 1767q23 19 68 34.5t98 15.5q86 0 133 -36t47 -98q0 -66 -39.5 -101.5t-112.5 -43.5v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1eed;" horiz-adv-x="1208" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-263h31q76 0 107.5 44.5t31.5 148.5v151h121v-151q0 -74 -13.5 -129.5t-43.5 -93t-78.5 -56t-118.5 -18.5h-37v-682h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41 t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM398 1432q23 18 68 33.5t98 15.5q86 0 133 -35.5t47 -97.5q0 -66 -39.5 -102t-112.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1eee;" horiz-adv-x="1456" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-323h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-55v-378q0 -170 -26 -286.5 t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM329 1550q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -35t45 -35t44.5 -26.5t48.5 -10.5q51 0 77 31.5t31 100.5h94q-3 -113 -58.5 -173.5t-149.5 -60.5q-43 0 -74.5 11t-56.5 27 t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -33.5t-29 -102.5h-95z" />
+<glyph unicode="&#x1eef;" horiz-adv-x="1208" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-263h31q76 0 107.5 44.5t31.5 148.5v151h121v-151q0 -74 -13.5 -129.5t-43.5 -93t-78.5 -56t-118.5 -18.5h-37v-682h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41 t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM204 1214q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -34.5t45 -34.5t44.5 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35 t-44.5 27t-53.5 11q-51 0 -75 -34t-29 -104h-95z" />
+<glyph unicode="&#x1ef0;" horiz-adv-x="1456" d="M193 578v806h135v-786q0 -144 17 -241t59 -156.5t111.5 -85t174.5 -25.5q106 0 175.5 25.5t110 85t57 156t16.5 237.5v790h135v-323h49q76 0 106.5 44t30.5 148v193h123v-193q0 -74 -13.5 -129.5t-43.5 -92.5t-78.5 -56t-118.5 -19h-55v-378q0 -170 -26 -286.5 t-84.5 -188t-152.5 -103t-229 -31.5q-141 0 -237 32.5t-154 105t-83 188.5t-25 283zM598 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ef1;" horiz-adv-x="1208" d="M174 348v701h129v-654q0 -88 7.5 -146.5t27 -94t53.5 -50t86 -14.5q71 0 161 52t187 145v762h129v-263h31q76 0 107.5 44.5t31.5 148.5v151h121v-151q0 -74 -13.5 -129.5t-43.5 -93t-78.5 -56t-118.5 -18.5h-37v-682h-129v166q-44 -42 -89.5 -78.5t-92 -62.5t-93 -41 t-93.5 -15q-85 0 -139.5 25t-86.5 73.5t-44.5 119t-12.5 161.5zM461 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ef2;" horiz-adv-x="1126" d="M51 1384h150l362 -720l367 720h145l-444 -847v-537h-137v530zM309 1905h176l186 -361h-104z" />
+<glyph unicode="&#x1ef3;" horiz-adv-x="1018" d="M4 -365l37 109q25 -14 61 -21.5t70 -7.5q75 0 129 59.5t98 176.5l41 104l-383 994h140l311 -832l315 832h138l-453 -1147q-32 -81 -67.5 -138t-76.5 -92t-89 -51t-105 -16q-21 0 -44.5 2t-46 6t-42 9.5t-33.5 12.5zM253 1569h176l186 -361h-104z" />
+<glyph unicode="&#x1ef4;" horiz-adv-x="1126" d="M51 1384h150l362 -720l367 720h145l-444 -847v-537h-137v530zM465 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ef5;" horiz-adv-x="1018" d="M4 -365l37 109q25 -14 61 -21.5t70 -7.5q75 0 129 59.5t98 176.5l41 104l-383 994h140l311 -832l315 832h138l-453 -1147q-32 -81 -67.5 -138t-76.5 -92t-89 -51t-105 -16q-21 0 -44.5 2t-46 6t-42 9.5t-33.5 12.5zM617 -240q0 48 21 72.5t75 24.5q56 0 76 -23.5 t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 7t-29.5 19.5t-14.5 29.5t-4 38z" />
+<glyph unicode="&#x1ef6;" horiz-adv-x="1126" d="M51 1384h150l362 -720l367 720h145l-444 -847v-537h-137v530zM389 1767q23 19 68 34.5t98 15.5q86 0 133 -36t47 -98q0 -66 -39.5 -101.5t-112.5 -43.5v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ef7;" horiz-adv-x="1018" d="M4 -365l37 109q25 -14 61 -21.5t70 -7.5q75 0 129 59.5t98 176.5l41 104l-383 994h140l311 -832l315 832h138l-453 -1147q-32 -81 -67.5 -138t-76.5 -92t-89 -51t-105 -16q-21 0 -44.5 2t-46 6t-42 9.5t-33.5 12.5zM337 1432q23 18 68 33.5t98 15.5q86 0 133 -35.5 t47 -97.5q0 -66 -39.5 -102t-112.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph unicode="&#x1ef8;" horiz-adv-x="1126" d="M51 1384h150l362 -720l367 720h145l-444 -847v-537h-137v530zM200 1550q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -35t45 -35t44.5 -26.5t48.5 -10.5q51 0 77 31.5t31 100.5h94q-3 -113 -58.5 -173.5t-149.5 -60.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35 t-44.5 27t-53.5 11q-51 0 -75 -33.5t-29 -102.5h-95z" />
+<glyph unicode="&#x1ef9;" horiz-adv-x="1018" d="M4 -365l37 109q25 -14 61 -21.5t70 -7.5q75 0 129 59.5t98 176.5l41 104l-383 994h140l311 -832l315 832h138l-453 -1147q-32 -81 -67.5 -138t-76.5 -92t-89 -51t-105 -16q-21 0 -44.5 2t-46 6t-42 9.5t-33.5 12.5zM148 1214q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5 t49 -34.5t45 -34.5t44.5 -26.5t48.5 -10.5q51 0 77 32t31 101h94q-3 -115 -58.5 -174.5t-149.5 -59.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -34t-29 -104h-95z" />
+<glyph unicode="&#x2000;" horiz-adv-x="1029" />
+<glyph unicode="&#x2001;" horiz-adv-x="2058" />
+<glyph unicode="&#x2002;" horiz-adv-x="1029" />
+<glyph unicode="&#x2003;" horiz-adv-x="2058" />
+<glyph unicode="&#x2004;" horiz-adv-x="686" />
+<glyph unicode="&#x2005;" horiz-adv-x="514" />
+<glyph unicode="&#x2006;" horiz-adv-x="343" />
+<glyph unicode="&#x2007;" horiz-adv-x="343" />
+<glyph unicode="&#x2008;" horiz-adv-x="257" />
+<glyph unicode="&#x2009;" horiz-adv-x="411" />
+<glyph unicode="&#x200a;" horiz-adv-x="114" />
<glyph unicode="&#x2010;" horiz-adv-x="848" d="M113 463v127h622v-127h-622z" />
<glyph unicode="&#x2011;" horiz-adv-x="848" d="M113 463v127h622v-127h-622z" />
<glyph unicode="&#x2012;" horiz-adv-x="848" d="M113 463v127h622v-127h-622z" />
<glyph unicode="&#x2013;" horiz-adv-x="1106" d="M61 471v111h983v-111h-983z" />
<glyph unicode="&#x2014;" horiz-adv-x="2130" d="M61 471v111h2007v-111h-2007z" />
-<glyph unicode="&#x2018;" d="M172 1036q0 53 9 105t23.5 98t33 83.5t36.5 61.5h76q-20 -27 -35 -64.5t-25 -76.5t-15 -75t-5 -60q56 0 77.5 -22.5t21.5 -71.5q0 -47 -22.5 -69.5t-76.5 -22.5q-55 0 -76.5 30t-21.5 84z" />
-<glyph unicode="&#x2019;" d="M172 1319q0 48 22 71t74 23q57 0 79 -30.5t22 -86.5q0 -52 -9 -103.5t-24 -97t-34 -83t-38 -62.5h-76q20 27 35 64.5t25 76.5t15 75t5 61q-54 0 -75 21t-21 71z" />
-<glyph unicode="&#x201a;" d="M172 76q0 48 22 71t74 23q57 0 79 -30.5t22 -86.5q0 -52 -9 -103.5t-24 -97t-34 -83t-38 -62.5h-76q20 27 35 64.5t25 76.5t15 75t5 61q-54 0 -75 21t-21 71z" />
+<glyph unicode="&#x2015;" horiz-adv-x="2130" d="M61 471v111h2007v-111h-2007z" />
+<glyph unicode="&#x2017;" horiz-adv-x="1024" d="M-10 -103h1044v-92h-1044v92zM-10 -304h1044v-92h-1044v92z" />
+<glyph unicode="&#x2018;" horiz-adv-x="541" d="M172 1036q0 53 9 105t23.5 98t33 83.5t36.5 61.5h76q-20 -27 -35 -64.5t-25 -76.5t-15 -75t-5 -60q56 0 77.5 -22.5t21.5 -71.5q0 -47 -22.5 -69.5t-76.5 -22.5q-55 0 -76.5 30t-21.5 84z" />
+<glyph unicode="&#x2019;" horiz-adv-x="541" d="M172 1319q0 48 22 71t74 23q57 0 79 -30.5t22 -86.5q0 -52 -9 -103.5t-24 -97t-34 -83t-38 -62.5h-76q20 27 35 64.5t25 76.5t15 75t5 61q-54 0 -75 21t-21 71z" />
+<glyph unicode="&#x201a;" horiz-adv-x="541" d="M172 76q0 48 22 71t74 23q57 0 79 -30.5t22 -86.5q0 -52 -9 -103.5t-24 -97t-34 -83t-38 -62.5h-76q20 27 35 64.5t25 76.5t15 75t5 61q-54 0 -75 21t-21 71z" />
+<glyph unicode="&#x201b;" horiz-adv-x="541" d="M172 1296q0 56 21.5 86.5t76.5 30.5q54 0 76.5 -23t22.5 -71q0 -50 -21.5 -71t-77.5 -21q0 -25 5 -61t15 -75t25 -76.5t35 -64.5h-76q-18 25 -36.5 62.5t-33 83t-23.5 97t-9 103.5z" />
<glyph unicode="&#x201c;" horiz-adv-x="897" d="M172 1036q0 53 9 105t23.5 98t33 83.5t36.5 61.5h76q-20 -27 -35 -64.5t-25 -76.5t-15 -75t-5 -60q56 0 77.5 -22.5t21.5 -71.5q0 -47 -22.5 -69.5t-76.5 -22.5q-55 0 -76.5 30t-21.5 84zM528 1036q0 53 9 105t24 98t34 83.5t38 61.5h76q-20 -27 -35 -64.5t-25 -76.5 t-15 -75t-5 -60q54 0 75 -22.5t21 -71.5q0 -47 -22 -69.5t-74 -22.5q-57 0 -79 30t-22 84z" />
<glyph unicode="&#x201d;" horiz-adv-x="897" d="M172 1319q0 48 22 71t74 23q57 0 79 -30.5t22 -86.5q0 -52 -9 -103.5t-24 -97t-34 -83t-38 -62.5h-76q20 27 35 64.5t25 76.5t15 75t5 61q-54 0 -75 21t-21 71zM528 1319q0 48 22.5 71t76.5 23q55 0 76.5 -30.5t21.5 -86.5q0 -52 -9 -103.5t-23.5 -97t-33 -83 t-36.5 -62.5h-76q20 27 35 64.5t25 76.5t15 75t5 61q-56 0 -77.5 21t-21.5 71z" />
<glyph unicode="&#x201e;" horiz-adv-x="897" d="M172 76q0 48 22 71t74 23q57 0 79 -30.5t22 -86.5q0 -52 -9 -103.5t-24 -97t-34 -83t-38 -62.5h-76q20 27 35 64.5t25 76.5t15 75t5 61q-54 0 -75 21t-21 71zM528 76q0 48 22.5 71t76.5 23q55 0 76.5 -30.5t21.5 -86.5q0 -52 -9 -103.5t-23.5 -97t-33 -83t-36.5 -62.5 h-76q20 27 35 64.5t25 76.5t15 75t5 61q-56 0 -77.5 21t-21.5 71z" />
+<glyph unicode="&#x2020;" horiz-adv-x="1122" d="M115 788v134l397 -19l-18 481h133l-17 -481l398 19v-134l-398 17l21 -1200h-144l25 1200z" />
+<glyph unicode="&#x2021;" horiz-adv-x="1139" d="M139 23v135l379 -19l-14 357l14 354l-379 -19v136l379 -19l-18 436h135l-19 -436l381 19v-136l-381 19l15 -354l-15 -357l381 19v-135l-381 20l19 -438h-135l18 438z" />
<glyph unicode="&#x2022;" horiz-adv-x="780" d="M147 745q0 51 19.5 95t53 77t78 51.5t93.5 18.5t92.5 -18.5t76.5 -51t52 -76.5t19 -96q0 -50 -19 -94t-51.5 -76.5t-76 -51.5t-93.5 -19q-51 0 -95.5 19t-77.5 51.5t-52 76.5t-19 94z" />
<glyph unicode="&#x2026;" horiz-adv-x="2048" d="M242 78q0 48 22.5 70t75.5 22q54 0 76 -21.5t22 -70.5q0 -53 -23.5 -72.5t-74.5 -19.5q-56 0 -77 23.5t-21 68.5zM924 78q0 48 22.5 70t75.5 22q54 0 76 -21.5t22 -70.5q0 -53 -23.5 -72.5t-74.5 -19.5q-56 0 -77 23.5t-21 68.5zM1606 78q0 48 22.5 70t75.5 22 q54 0 76 -21.5t22 -70.5q0 -53 -23.5 -72.5t-74.5 -19.5q-56 0 -77 23.5t-21 68.5z" />
-<glyph unicode="&#x202f;" horiz-adv-x="381" />
+<glyph unicode="&#x202f;" horiz-adv-x="411" />
+<glyph unicode="&#x2030;" horiz-adv-x="2664" d="M98 975q0 210 80.5 324t253.5 114q87 0 150.5 -29.5t105.5 -86t62 -138t20 -184.5q0 -104 -21 -185.5t-63 -137.5t-105.5 -85.5t-148.5 -29.5q-173 0 -253.5 112t-80.5 326zM229 975q0 -70 9 -131.5t32 -107t62 -71.5t100 -26q64 0 104.5 27t62.5 73t30 107t8 129 q0 75 -9.5 137t-33 105.5t-63 67.5t-99.5 24q-63 0 -102.5 -26t-62 -71t-30.5 -106t-8 -131zM473 -51q25 46 66.5 124.5t94.5 177.5t113.5 212t123 229.5t123 229.5t113.5 212t94.5 177t66.5 125h116l-794 -1487h-117zM1094 408q0 106 19.5 187.5t60 137t103.5 84.5t150 29 t150.5 -29.5t105.5 -86t62 -138t20 -184.5q0 -104 -21 -185.5t-63 -138t-105.5 -86t-148.5 -29.5q-175 0 -254 112t-79 327zM1225 408q0 -70 9 -131.5t31.5 -107t62 -71.5t99.5 -26q64 0 104.5 27t62.5 72.5t30 106.5t8 130q0 70 -9.5 130.5t-32.5 105.5t-62.5 71t-100.5 26 q-63 0 -102 -26t-61.5 -71t-30.5 -105.5t-8 -130.5zM1894 408q0 106 19.5 187.5t61 137t105 84.5t150.5 29t150.5 -29.5t104.5 -86t61 -138t20 -184.5q0 -104 -20.5 -185.5t-62.5 -138t-105 -86t-148 -29.5q-175 0 -255.5 112t-80.5 327zM2025 408q0 -70 9 -131.5t32 -107 t62.5 -71.5t101.5 -26q64 0 104 27t62.5 72.5t30.5 106.5t8 130q0 70 -9.5 130.5t-33 105.5t-63 71t-99.5 26q-63 0 -103 -26t-62.5 -71t-31 -105.5t-8.5 -130.5z" />
+<glyph unicode="&#x2032;" horiz-adv-x="561" d="M176 834l47 550h166l-119 -550h-94z" />
+<glyph unicode="&#x2033;" horiz-adv-x="989" d="M176 834l47 550h166l-119 -550h-94zM604 834l47 550h166l-119 -550h-94z" />
<glyph unicode="&#x2039;" horiz-adv-x="672" d="M76 524l381 471h145l-381 -471l381 -471h-145z" />
<glyph unicode="&#x203a;" horiz-adv-x="672" d="M70 53l379 471l-379 471h145l379 -471l-379 -471h-145z" />
-<glyph unicode="&#x205f;" horiz-adv-x="476" />
+<glyph unicode="&#x203c;" horiz-adv-x="1040" d="M168 78q0 49 23 70.5t77 21.5q57 0 80 -22t23 -70q0 -53 -25 -72.5t-78 -19.5q-29 0 -48.5 6t-31 18t-16 29t-4.5 39zM195 1384h149l-18 -1005h-107zM668 78q0 49 23 70.5t77 21.5q57 0 80 -22t23 -70q0 -53 -25 -72.5t-78 -19.5q-29 0 -48.5 6t-31 18t-16 29t-4.5 39z M695 1384h149l-18 -1005h-107z" />
+<glyph unicode="&#x203d;" horiz-adv-x="1036" d="M86 1225q21 39 56.5 73t84 59.5t110 40.5t136.5 15q93 0 172.5 -22t138 -66.5t92 -111t33.5 -156.5q0 -85 -29.5 -152.5t-84 -125t-131.5 -109.5t-172 -105q0 -48 -1.5 -94t-1.5 -92h-110l-19 897q-65 -19 -105 -52.5t-60 -70.5zM330 78q0 49 23 70.5t77 21.5 q57 0 79.5 -22t22.5 -70q0 -53 -24.5 -72.5t-77.5 -19.5q-29 0 -48.5 6t-31 18t-16 29t-4.5 39zM494 688q74 44 126 84.5t84.5 82.5t47 89t14.5 103q0 105 -67 170t-195 73z" />
+<glyph unicode="&#x203e;" horiz-adv-x="1024" d="M-10 1526v92h1044v-92h-1044z" />
+<glyph unicode="&#x2044;" horiz-adv-x="260" d="M-307 -51l801 1487h122l-804 -1487h-119z" />
+<glyph unicode="&#x205f;" horiz-adv-x="514" />
+<glyph unicode="&#x2070;" horiz-adv-x="883" d="M98 1081q0 116 22.5 199t65.5 136.5t106.5 78.5t145.5 25q169 0 256.5 -107.5t87.5 -331.5q0 -117 -23 -200t-67 -136t-108 -77.5t-146 -24.5q-173 0 -256.5 107t-83.5 331zM227 1081q0 -95 13.5 -159.5t40.5 -104t66.5 -57t90.5 -17.5q55 0 95.5 18.5t67 59t39.5 104.5 t13 156q0 93 -14.5 157.5t-42 104.5t-67.5 58t-91 18q-52 0 -91.5 -18t-66 -58.5t-40 -105t-13.5 -156.5z" />
+<glyph unicode="&#x2074;" horiz-adv-x="883" d="M78 860v96l495 549h95v-547h133v-98h-133v-190h-119v190h-471zM215 958h334v371z" />
+<glyph unicode="&#x2075;" horiz-adv-x="883" d="M117 776l98 58q11 -17 29 -33.5t42.5 -29.5t55 -20.5t66.5 -7.5q60 0 101.5 13.5t67 38t37 59.5t11.5 78q0 41 -15 71t-42 49.5t-65.5 28.5t-86.5 9q-101 0 -187 -46h-61l61 451h484v-102h-385l-31 -226q28 11 68.5 17t78.5 6q71 0 128 -16t97 -48.5t61.5 -81 t21.5 -112.5q0 -137 -86 -213t-258 -76q-106 0 -180 38t-111 95z" />
+<glyph unicode="&#x2076;" horiz-adv-x="883" d="M113 1065q0 90 19.5 172.5t63 146t113 101t168.5 37.5q83 0 144 -23.5t116 -71.5l-73 -84q-51 42 -93.5 60t-93.5 18q-54 0 -94.5 -19t-69 -54.5t-45 -86t-22.5 -112.5q49 25 108.5 41t112.5 16q145 0 223 -64.5t78 -201.5q0 -73 -23.5 -128.5t-66 -93t-101.5 -56.5 t-131 -19q-168 0 -250.5 107.5t-82.5 314.5zM242 1053q1 -86 16 -145t42 -95.5t64.5 -53t81.5 -16.5q96 0 145.5 48.5t49.5 144.5q0 87 -45 127.5t-145 40.5q-57 0 -111.5 -15t-97.5 -36z" />
+<glyph unicode="&#x2077;" horiz-adv-x="883" d="M119 1393v102h637v-94l-365 -731h-133l365 723h-504z" />
+<glyph unicode="&#x2078;" horiz-adv-x="883" d="M109 877q0 72 47 130t153 101q-93 42 -134.5 89.5t-41.5 109.5q0 103 76.5 159t230.5 56q146 0 224.5 -53.5t78.5 -159.5q0 -62 -45 -109t-147 -90q42 -15 81 -36t69 -49.5t48.5 -64.5t18.5 -81q0 -61 -23 -105.5t-65.5 -73.5t-103.5 -43t-136 -14q-165 0 -248 59 t-83 175zM233 877q0 -32 11.5 -57.5t36 -44t64 -28.5t95.5 -10q108 0 155.5 37.5t47.5 102.5q0 33 -16 59t-44.5 47t-67.5 39t-85 35q-99 -32 -148 -73.5t-49 -106.5zM256 1309q0 -22 9 -41t30 -37t55.5 -36t85.5 -36q96 32 139 66.5t43 81.5q0 60 -47 90t-131 30 q-88 0 -136 -30t-48 -88z" />
+<glyph unicode="&#x2079;" horiz-adv-x="883" d="M109 1225q0 72 23.5 127.5t66.5 93t101.5 57t129.5 19.5q84 0 147 -27.5t104.5 -80.5t62 -130.5t20.5 -177.5q0 -93 -19.5 -177t-63.5 -147.5t-114 -101t-172 -37.5q-84 0 -146.5 23.5t-117.5 70.5l76 84q49 -42 93 -60t95 -18q56 0 97.5 19t70 54t45 85.5t23.5 112.5 q-50 -23 -108 -39.5t-109 -16.5q-150 0 -227.5 64.5t-77.5 202.5zM233 1229q0 -88 46.5 -129t146.5 -41q59 0 112 16t95 41q0 69 -12 125.5t-37 96t-63.5 61.5t-90.5 22q-96 0 -146.5 -48t-50.5 -144z" />
+<glyph unicode="&#x207f;" horiz-adv-x="852" d="M141 676v710h117v-96q25 22 55.5 43.5t63.5 37.5t67.5 26t67.5 10q58 0 97 -16t63 -46t34.5 -74t10.5 -100v-495h-117v452q0 46 -5 79t-18 54.5t-36.5 31.5t-59.5 10q-22 0 -49.5 -8t-56.5 -22.5t-59 -34t-58 -42.5v-520h-117z" />
+<glyph unicode="&#x2080;" horiz-adv-x="883" d="M98 97q0 116 22.5 199t65.5 136.5t106.5 78.5t145.5 25q169 0 256.5 -107.5t87.5 -331.5q0 -117 -23 -200t-67 -136t-108 -77.5t-146 -24.5q-173 0 -256.5 107t-83.5 331zM227 97q0 -95 13.5 -159.5t40.5 -104t66.5 -57t90.5 -17.5q55 0 95.5 18.5t67 59t39.5 104.5 t13 156q0 93 -14.5 157.5t-42 104.5t-67.5 58t-91 18q-52 0 -91.5 -18t-66 -58.5t-40 -105t-13.5 -156.5z" />
+<glyph unicode="&#x2081;" horiz-adv-x="883" d="M182 265v88q61 2 106.5 15t78.5 35.5t53.5 52.5t30.5 67h92v-837h-119v649q-42 -34 -104.5 -52t-137.5 -18z" />
+<glyph unicode="&#x2082;" horiz-adv-x="883" d="M121 376q17 28 42 57t62.5 52.5t88.5 38t120 14.5q66 0 122 -13.5t97.5 -42t64.5 -73.5t23 -109q0 -46 -12 -85t-30.5 -71t-41 -57t-43.5 -43q-71 -60 -151 -122.5t-180 -133.5h491v-102h-649v106q42 31 88 66.5t90.5 70.5t84 68t67.5 59q47 37 77.5 67t48 57.5 t24.5 55.5t7 62q0 66 -44 101.5t-138 35.5q-78 0 -127.5 -32.5t-83.5 -88.5z" />
+<glyph unicode="&#x2083;" horiz-adv-x="883" d="M102 -202l97 62q35 -47 90.5 -74t113.5 -27q106 0 156.5 43.5t50.5 124.5q0 75 -46.5 112.5t-155.5 37.5h-93v100h80q105 0 154 38t49 97q0 57 -43.5 91t-134.5 34q-72 0 -123 -25t-92 -83l-96 57q19 31 47 58.5t66.5 48.5t88.5 33t113 12q80 0 137.5 -17t94 -46 t54 -68.5t17.5 -85.5q0 -65 -38 -114.5t-114 -72.5q75 -21 119.5 -75t44.5 -136q0 -129 -87.5 -196.5t-243.5 -67.5q-43 0 -87.5 8.5t-85 25.5t-75 43.5t-58.5 61.5z" />
+<glyph unicode="&#x2084;" horiz-adv-x="883" d="M63 -28l495 549h95v-547h133v-98h-133v-190h-119v190h-471v96zM200 -26h334v371z" />
+<glyph unicode="&#x2085;" horiz-adv-x="883" d="M117 -208l98 58q11 -17 29 -33.5t42.5 -29.5t55 -20.5t66.5 -7.5q60 0 101.5 13.5t67 38t37 59.5t11.5 78q0 41 -15 71t-42 49.5t-65.5 28.5t-86.5 9q-101 0 -187 -46h-61l61 451h484v-102h-385l-31 -226q28 11 68.5 17t78.5 6q71 0 128 -16t97 -48.5t61.5 -81 t21.5 -112.5q0 -137 -86 -213t-258 -76q-106 0 -180 38t-111 95z" />
+<glyph unicode="&#x2086;" horiz-adv-x="883" d="M113 81q0 90 19.5 172.5t63 146t113 101t168.5 37.5q83 0 144 -23.5t116 -71.5l-73 -84q-51 42 -93.5 60t-93.5 18q-54 0 -94.5 -19t-69 -54.5t-45 -86t-22.5 -112.5q49 25 108.5 41t112.5 16q145 0 223 -64.5t78 -201.5q0 -73 -23.5 -128.5t-66 -93t-101.5 -56.5 t-131 -19q-168 0 -250.5 107.5t-82.5 314.5zM242 69q1 -86 16 -145t42 -95.5t64.5 -53t81.5 -16.5q96 0 145.5 48.5t49.5 144.5q0 87 -45 127.5t-145 40.5q-57 0 -111.5 -15t-97.5 -36z" />
+<glyph unicode="&#x2087;" horiz-adv-x="883" d="M119 409v102h637v-94l-365 -731h-133l365 723h-504z" />
+<glyph unicode="&#x2088;" horiz-adv-x="883" d="M109 -107q0 72 47 130t153 101q-93 42 -134.5 89.5t-41.5 109.5q0 103 76.5 159t230.5 56q146 0 224.5 -53.5t78.5 -159.5q0 -62 -45 -109t-147 -90q42 -15 81 -36t69 -49.5t48.5 -64.5t18.5 -81q0 -61 -23 -105.5t-65.5 -73.5t-103.5 -43t-136 -14q-165 0 -248 59 t-83 175zM233 -107q0 -32 11.5 -57.5t36 -44t64 -28.5t95.5 -10q108 0 155.5 37.5t47.5 102.5q0 33 -16 59t-44.5 47t-67.5 39t-85 35q-99 -32 -148 -73.5t-49 -106.5zM256 325q0 -22 9 -41t30 -37t55.5 -36t85.5 -36q96 32 139 66.5t43 81.5q0 60 -47 90t-131 30 q-88 0 -136 -30t-48 -88z" />
+<glyph unicode="&#x2089;" horiz-adv-x="883" d="M109 241q0 72 23.5 127.5t66.5 93t101.5 57t129.5 19.5q84 0 147 -27.5t104.5 -80.5t62 -130.5t20.5 -177.5q0 -93 -19.5 -177t-63.5 -147.5t-114 -101t-172 -37.5q-84 0 -146.5 23.5t-117.5 70.5l76 84q49 -42 93 -60t95 -18q56 0 97.5 19t70 54t45 85.5t23.5 112.5 q-50 -23 -108 -39.5t-109 -16.5q-150 0 -227.5 64.5t-77.5 202.5zM233 245q0 -88 46.5 -129t146.5 -41q59 0 112 16t95 41q0 69 -12 125.5t-37 96t-63.5 61.5t-90.5 22q-96 0 -146.5 -48t-50.5 -144z" />
+<glyph unicode="&#x20a3;" horiz-adv-x="1255" d="M113 238v104h161v1042h811v-122h-675v-461h577v-123h-577v-336h352v-104h-352v-238h-136v238h-161z" />
+<glyph unicode="&#x20a4;" horiz-adv-x="1255" d="M119 0v117q38 8 70.5 37t57.5 75t41 107.5t21 136.5h-176v96h182q-2 54 -6 92t-10 72h-166v98h146q-13 53 -23 102.5t-10 104.5q0 94 35 164t96.5 117t143.5 70.5t177 23.5q63 0 121.5 -11.5t111 -36.5t97.5 -65t82 -98l-111 -72q-47 74 -122.5 121t-178.5 47 q-77 0 -135.5 -19.5t-98 -55.5t-59.5 -86t-20 -111q0 -48 10 -95t23 -100h409v-98h-389q6 -32 10.5 -71t4.5 -93h374v-96h-381q-12 -131 -55.5 -221t-105.5 -135h850v-117h-1016z" />
+<glyph unicode="&#x20a7;" horiz-adv-x="2464" d="M199 0v1384h352q212 0 323.5 -84.5t133.5 -250.5h163v292h129v-292h252v-111h-252v-606q0 -73 6 -122t21.5 -78t42 -41.5t68.5 -12.5q31 0 67 8.5t62 19.5l32 -104q-38 -14 -82.5 -23.5t-91.5 -9.5q-72 0 -120.5 19.5t-78.5 61.5t-42.5 108t-12.5 159v621h-159 q-2 -123 -32.5 -208.5t-90 -139t-148 -77.5t-206.5 -24h-201v-489h-135zM334 612h178q93 0 160 15t110.5 53.5t64.5 105t21 170.5q0 87 -22.5 145.5t-65 94.5t-103.5 51t-138 15h-205v-650zM1608 154l104 65q34 -63 97 -101t163 -38q51 0 96.5 8.5t79 29.5t53 56.5 t19.5 89.5q0 42 -12 72.5t-42.5 54t-83.5 42.5t-134 40q-83 22 -143.5 47t-99.5 60.5t-58 85t-19 120.5q0 58 21.5 111.5t65 93.5t110.5 64t157 24q70 0 125 -15t97 -40.5t72.5 -59.5t50.5 -71l-107 -62q-15 28 -36 53t-50 43.5t-66.5 29t-85.5 10.5q-106 0 -166.5 -47 t-60.5 -132q0 -41 11 -70t37 -50.5t70.5 -38.5t111.5 -35q100 -27 169.5 -55t112 -65t61.5 -86.5t19 -119.5q0 -74 -26 -130t-74.5 -93.5t-118 -56.5t-156.5 -19q-81 0 -143 17.5t-106 44.5t-72 59.5t-43 63.5z" />
+<glyph unicode="&#x20ab;" horiz-adv-x="1151" d="M129 494q0 105 23.5 202.5t73 172.5t126 120t183.5 45q90 0 163 -33.5t142 -87.5v226h-314v108h314v137h129v-137h153v-108h-153v-1139h-129v115q-32 -31 -69.5 -57.5t-78.5 -46t-85 -31t-89 -11.5q-98 0 -171 35.5t-121.5 103t-72.5 165t-24 221.5zM164 -156h805v-108 h-805v108zM262 498q0 -95 15 -171.5t47.5 -131t83.5 -84t124 -29.5q43 0 84.5 12.5t80.5 34t75 49.5t68 60v555q-75 60 -148 93.5t-145 33.5q-65 0 -118 -29t-90 -83t-57 -132.5t-20 -177.5z" />
<glyph unicode="&#x20ac;" horiz-adv-x="1255" d="M35 518l35 96h65v160h-100l35 96h73q15 132 55 233t107 170t161 104.5t218 35.5q92 0 164 -19.5t127.5 -54.5t96.5 -84.5t73 -109.5l-119 -70q-24 48 -53.5 88t-70 69t-93.5 45.5t-123 16.5q-92 0 -161.5 -28t-118.5 -82t-78.5 -133t-42.5 -181h624l-32 -96h-598v-160 h555l-35 -96h-514q13 -103 43 -182.5t79.5 -134t120 -83t164.5 -28.5q79 0 136 21t98 54.5t69 75t49 83.5l115 -64q-32 -64 -72.5 -117t-95.5 -91.5t-128.5 -59.5t-170.5 -21q-249 0 -384.5 137t-164.5 410h-108z" />
+<glyph unicode="&#x20b9;" horiz-adv-x="1255" d="M150 971l65 112h547q-5 42 -20 76.5t-42 59.5t-65.5 39t-89.5 14h-395l65 112h918l-66 -112h-272q48 -35 71 -85t29 -104h238l-66 -112h-172q-15 -94 -63.5 -152t-119.5 -90.5t-158 -45t-177 -13.5l520 -670h-152l-522 672v112h146q99 0 169 10t116.5 32t71.5 58t34 87 h-610z" />
+<glyph unicode="&#x20ba;" horiz-adv-x="1255" d="M174 600v111l180 65v166l-180 -65v110l180 66v331h129v-292l308 116v-112l-308 -113v-166l308 113v-111l-308 -112v-609h43q121 0 201.5 38t128.5 111.5t68 181t20 247.5h127q0 -179 -32.5 -310.5t-100.5 -218t-174.5 -128.5t-253.5 -42q-40 0 -81 5.5t-75 17.5v666z" />
+<glyph unicode="&#x2105;" horiz-adv-x="1626" d="M70 1053q0 83 17.5 150t56.5 114t100.5 72.5t148.5 25.5q93 0 156.5 -39.5t97.5 -107.5l-96 -54q-28 50 -68.5 73.5t-93.5 23.5q-97 0 -145.5 -61.5t-48.5 -196.5q0 -61 10 -109t33.5 -81t61.5 -50.5t95 -17.5q51 0 94 20t80 55l70 -82q-20 -18 -43.5 -35.5t-52.5 -31.5 t-66 -22.5t-84 -8.5q-91 0 -153 27t-99.5 75.5t-54 115t-16.5 145.5zM342 -31l786 1444h125l-788 -1444h-123zM918 324q0 85 19 152t58 113t99 70.5t141 24.5q82 0 142 -24.5t99.5 -70.5t58.5 -113t19 -152q0 -83 -19 -149t-58.5 -112t-99.5 -70t-142 -24q-163 0 -240 92.5 t-77 262.5zM1042 324q0 -56 9 -102.5t31 -80t59.5 -52.5t93.5 -19q55 0 92.5 19t60 52.5t32.5 80t10 102.5q0 57 -10 105t-32.5 82.5t-60 53.5t-92.5 19q-56 0 -93.5 -19t-59.5 -53.5t-31 -82.5t-9 -105z" />
+<glyph unicode="&#x2113;" horiz-adv-x="1055" d="M166 467l192 203v483q0 78 16 141t47.5 106.5t79 67t109.5 23.5q58 0 99 -21.5t66 -54t36.5 -72t11.5 -75.5q0 -66 -14.5 -129t-51 -135.5t-100.5 -160t-163 -202.5v-354q0 -110 36.5 -156.5t108.5 -46.5q30 0 56 9.5t49 25t42.5 35.5t36.5 41l64 -82q-23 -27 -52 -52.5 t-63.5 -45t-73.5 -31t-82 -11.5q-69 0 -118 20.5t-80 60t-45.5 97t-14.5 130.5v243l-127 -131zM494 793q61 69 103 131t67.5 118.5t37 108.5t11.5 100q0 59 -26 93t-71 34q-63 0 -92.5 -54t-29.5 -163v-368z" />
+<glyph unicode="&#x2116;" horiz-adv-x="2247" d="M188 0v1384h205l686 -1165v1165h135v-1384h-161l-729 1243v-1243h-136zM1450 879q0 83 17.5 152.5t56 119.5t100 78t150.5 28t150.5 -28.5t100 -78.5t55.5 -119.5t17 -151.5q0 -81 -17 -149.5t-55.5 -118.5t-100 -78.5t-150.5 -28.5q-88 0 -149.5 28.5t-100.5 78.5 t-56.5 118.5t-17.5 149.5zM1475 0v127h600v-127h-600zM1583 879q0 -53 7.5 -102t28 -86.5t58 -60t97.5 -22.5t97.5 22.5t58.5 60t28.5 86.5t7.5 102q0 54 -7.5 104t-28.5 87.5t-58.5 60t-97.5 22.5q-61 0 -98.5 -22.5t-58 -60t-27.5 -87.5t-7 -104z" />
<glyph unicode="&#x2122;" horiz-adv-x="1565" d="M92 1282v102h553v-102h-221v-612h-111v612h-221zM807 670v714h139l187 -374l194 374h131v-714h-108v538l-183 -346h-75l-174 342v-534h-111z" />
+<glyph unicode="&#x2126;" horiz-adv-x="1364" d="M135 791q0 142 33 257t100 196t167 125t235 44q145 0 250.5 -37.5t174 -114.5t101.5 -193.5t33 -274.5q0 -265 -85.5 -410.5t-248.5 -185.5v-72h303v-125h-424v276q77 11 135 41.5t96.5 89.5t58 151t19.5 226q0 115 -17.5 208.5t-63 159.5t-126 102t-206.5 36 q-90 0 -162.5 -26.5t-123 -86t-78 -155.5t-27.5 -236q0 -128 15 -218.5t51 -150.5t96 -93.5t149 -47.5v-276h-424v125h303v72q-90 20 -153.5 66t-103.5 119.5t-58.5 175t-18.5 233.5z" />
+<glyph unicode="&#x212e;" horiz-adv-x="1389" d="M84 621q0 134 41.5 252t120 205.5t191 138.5t253.5 51q144 0 256.5 -51t191 -139t121.5 -205t46 -250h-959v-430q69 -69 155 -104.5t185 -35.5q84 0 152.5 20.5t124 57t100.5 88.5t84 115q20 -9 38.5 -20.5t37.5 -22.5q-47 -71 -99.5 -129t-117 -99.5t-143 -64.5 t-177.5 -23q-138 0 -249 50.5t-189.5 138.5t-121 205.5t-42.5 251.5zM346 698h686v351q-66 65 -155 103t-185 38q-204 0 -346 -139v-353z" />
+<glyph unicode="&#x215b;" horiz-adv-x="1870" d="M182 1133v88q61 2 106.5 15t78.5 35.5t53.5 52.5t30.5 67h92v-837h-119v649q-42 -34 -104.5 -52t-137.5 -18zM443 -51l801 1487h122l-804 -1487h-119zM1096 200q0 72 47 130t153 101q-93 42 -134.5 89.5t-41.5 109.5q0 103 76.5 159t230.5 56q146 0 224.5 -53.5 t78.5 -159.5q0 -62 -45 -109t-147 -90q42 -15 81 -36t69 -49.5t48.5 -64.5t18.5 -81q0 -61 -23 -105.5t-65.5 -73.5t-103.5 -43t-136 -14q-165 0 -248 59t-83 175zM1220 200q0 -32 11.5 -57.5t36 -44t64 -28.5t95.5 -10q108 0 155.5 37.5t47.5 102.5q0 33 -16 59t-44.5 47 t-67.5 39t-85 35q-99 -32 -148 -73.5t-49 -106.5zM1243 632q0 -22 9 -41t30 -37t55.5 -36t85.5 -36q96 32 139 66.5t43 81.5q0 60 -47 90t-131 30q-88 0 -136 -30t-48 -88z" />
+<glyph unicode="&#x215c;" horiz-adv-x="1870" d="M102 666l97 62q35 -47 90.5 -74t113.5 -27q106 0 156.5 43.5t50.5 124.5q0 75 -46.5 112.5t-155.5 37.5h-93v100h80q105 0 154 38t49 97q0 57 -43.5 91t-134.5 34q-72 0 -123 -25t-92 -83l-96 57q19 31 47 58.5t66.5 48.5t88.5 33t113 12q80 0 137.5 -17t94 -46t54 -68.5 t17.5 -85.5q0 -65 -38 -114.5t-114 -72.5q75 -21 119.5 -75t44.5 -136q0 -129 -87.5 -196.5t-243.5 -67.5q-43 0 -87.5 8.5t-85 25.5t-75 43.5t-58.5 61.5zM469 -51l801 1487h122l-804 -1487h-119zM1096 200q0 72 47 130t153 101q-93 42 -134.5 89.5t-41.5 109.5 q0 103 76.5 159t230.5 56q146 0 224.5 -53.5t78.5 -159.5q0 -62 -45 -109t-147 -90q42 -15 81 -36t69 -49.5t48.5 -64.5t18.5 -81q0 -61 -23 -105.5t-65.5 -73.5t-103.5 -43t-136 -14q-165 0 -248 59t-83 175zM1220 200q0 -32 11.5 -57.5t36 -44t64 -28.5t95.5 -10 q108 0 155.5 37.5t47.5 102.5q0 33 -16 59t-44.5 47t-67.5 39t-85 35q-99 -32 -148 -73.5t-49 -106.5zM1243 632q0 -22 9 -41t30 -37t55.5 -36t85.5 -36q96 32 139 66.5t43 81.5q0 60 -47 90t-131 30q-88 0 -136 -30t-48 -88z" />
+<glyph unicode="&#x215d;" horiz-adv-x="1870" d="M117 660l98 58q11 -17 29 -33.5t42.5 -29.5t55 -20.5t66.5 -7.5q60 0 101.5 13.5t67 38t37 59.5t11.5 78q0 41 -15 71t-42 49.5t-65.5 28.5t-86.5 9q-101 0 -187 -46h-61l61 451h484v-102h-385l-31 -226q28 11 68.5 17t78.5 6q71 0 128 -16t97 -48.5t61.5 -81 t21.5 -112.5q0 -137 -86 -213t-258 -76q-106 0 -180 38t-111 95zM469 -51l801 1487h122l-804 -1487h-119zM1096 200q0 72 47 130t153 101q-93 42 -134.5 89.5t-41.5 109.5q0 103 76.5 159t230.5 56q146 0 224.5 -53.5t78.5 -159.5q0 -62 -45 -109t-147 -90q42 -15 81 -36 t69 -49.5t48.5 -64.5t18.5 -81q0 -61 -23 -105.5t-65.5 -73.5t-103.5 -43t-136 -14q-165 0 -248 59t-83 175zM1220 200q0 -32 11.5 -57.5t36 -44t64 -28.5t95.5 -10q108 0 155.5 37.5t47.5 102.5q0 33 -16 59t-44.5 47t-67.5 39t-85 35q-99 -32 -148 -73.5t-49 -106.5z M1243 632q0 -22 9 -41t30 -37t55.5 -36t85.5 -36q96 32 139 66.5t43 81.5q0 60 -47 90t-131 30q-88 0 -136 -30t-48 -88z" />
+<glyph unicode="&#x215e;" horiz-adv-x="1870" d="M119 1277v102h637v-94l-365 -731h-133l365 723h-504zM422 -51l801 1487h122l-804 -1487h-119zM1096 200q0 72 47 130t153 101q-93 42 -134.5 89.5t-41.5 109.5q0 103 76.5 159t230.5 56q146 0 224.5 -53.5t78.5 -159.5q0 -62 -45 -109t-147 -90q42 -15 81 -36t69 -49.5 t48.5 -64.5t18.5 -81q0 -61 -23 -105.5t-65.5 -73.5t-103.5 -43t-136 -14q-165 0 -248 59t-83 175zM1220 200q0 -32 11.5 -57.5t36 -44t64 -28.5t95.5 -10q108 0 155.5 37.5t47.5 102.5q0 33 -16 59t-44.5 47t-67.5 39t-85 35q-99 -32 -148 -73.5t-49 -106.5zM1243 632 q0 -22 9 -41t30 -37t55.5 -36t85.5 -36q96 32 139 66.5t43 81.5q0 60 -47 90t-131 30q-88 0 -136 -30t-48 -88z" />
+<glyph unicode="&#x2190;" horiz-adv-x="2048" d="M190 494v47q57 29 107.5 61.5t93.5 67.5q45 35 97 86t114 121h78q-23 -48 -43 -85t-37 -63q-29 -51 -88 -125h1346v-176h-1346q28 -34 49.5 -64.5t38.5 -56.5t37 -63.5t43 -85.5h-78q-118 133 -209 204q-45 36 -95.5 68.5t-107.5 63.5z" />
+<glyph unicode="&#x2191;" horiz-adv-x="1024" d="M154 1178v75q68 62 118.5 114t85.5 95q72 90 131 205h46q60 -118 131 -203q35 -43 86 -95.5t120 -115.5v-75q-49 23 -86 42.5t-63 34.5q-26 17 -57 39t-66 49v-1343h-174v1343q-35 -26 -66 -47.5t-57 -38.5q-53 -33 -149 -79z" />
+<glyph unicode="&#x2192;" horiz-adv-x="2048" d="M190 428v176h1344q-26 35 -48.5 66t-39.5 57t-36 64t-42 86h76q62 -69 113.5 -120.5t95.5 -86.5q45 -35 95.5 -67.5t109.5 -63.5v-45q-59 -31 -109.5 -63.5t-93.5 -68.5q-85 -66 -211 -204h-76q23 48 42 84.5t36 62.5t38.5 57t49.5 66h-1344z" />
+<glyph unicode="&#x2193;" horiz-adv-x="1024" d="M152 414v75q49 -23 86 -42.5t63 -36.5q26 -16 57 -37.5t66 -48.5v1343h174v-1343q35 26 66 47.5t57 38.5q53 33 149 79v-75q-68 -62 -118.5 -114t-85.5 -97q-71 -85 -131 -203h-46q-60 118 -131 203q-35 43 -86 95.5t-120 115.5z" />
+<glyph unicode="&#x2194;" horiz-adv-x="2048" d="M190 494v47q57 29 107.5 61.5t93.5 67.5q45 35 97 86t114 121h78q-23 -48 -43 -85t-37 -63q-29 -51 -88 -125h1022q-26 34 -48.5 64.5t-39.5 56.5q-17 28 -36 66t-42 86h76q62 -69 113.5 -120.5t95.5 -86.5q45 -35 95.5 -67.5t109.5 -63.5v-45q-59 -31 -109.5 -63.5 t-93.5 -68.5q-85 -66 -211 -204h-76q23 48 41.5 84.5t34.5 62.5q17 26 39 57t51 66h-1022q28 -34 49.5 -64.5t38.5 -56.5t37 -63.5t43 -85.5h-78q-118 133 -209 204q-45 36 -95.5 68.5t-107.5 63.5z" />
+<glyph unicode="&#x2195;" horiz-adv-x="1024" d="M154 414v75q48 -23 84.5 -42.5t62.5 -34.5q51 -31 125 -88v1019q-35 -27 -66 -49t-57 -39t-63.5 -35.5t-85.5 -41.5v75q68 60 118.5 112t85.5 97q72 90 131 205h46q59 -115 131 -205q35 -43 86 -95t120 -114v-75q-49 23 -86 41.5t-63 33.5q-26 17 -57 39t-66 51v-1019 q34 26 64.5 47.5t56.5 38.5q28 17 65.5 36.5t85.5 42.5v-75q-135 -120 -206 -209q-72 -90 -131 -205h-46q-60 118 -131 203q-35 45 -85.5 97t-118.5 114z" />
+<glyph unicode="&#x21a8;" horiz-adv-x="1024" d="M154 -74h718v-174h-718v174zM154 414v75q49 -24 82 -41t61.5 -34.5t57.5 -38t71 -51.5v1019q-39 -30 -68 -51t-58 -38.5t-63 -34.5t-83 -41v75q67 61 115.5 110t86.5 96t69.5 96.5t63.5 111.5h46q32 -62 62 -111t67 -95.5t86.5 -95.5t121.5 -112v-75q-51 24 -86 41 t-64 34t-57 38t-65 52v-1019q36 28 63.5 48t57 38t65 36.5t86.5 42.5v-75q-71 -62 -120.5 -111.5t-87.5 -96.5t-68 -96t-61 -110h-46q-33 61 -64 110.5t-69 96t-86.5 96t-115.5 111.5z" />
+<glyph unicode="&#x2202;" horiz-adv-x="1239" d="M109 362q0 151 49.5 264.5t129 189.5t178 114.5t196.5 38.5q56 0 104.5 -13.5t87.5 -36t68 -52t45 -60.5h4q3 31 5.5 67t2.5 76q0 167 -81.5 256.5t-229.5 89.5q-26 0 -54 -4t-56 -11.5t-54.5 -18.5t-48.5 -25l-45 100q20 14 49.5 27.5t65.5 24.5t77 17.5t84 6.5 q97 0 177.5 -31t138 -92t89 -151.5t31.5 -210.5q0 -91 -12.5 -186.5t-38.5 -192.5q-31 -117 -86 -221t-130.5 -182t-168.5 -123.5t-199 -45.5q-87 0 -156.5 27.5t-119 78t-76 121.5t-26.5 158zM252 360q0 -62 17 -111t48.5 -83.5t75.5 -53t99 -18.5q76 0 148.5 39.5t133 114 t107 180.5t71.5 238q-13 41 -38.5 76.5t-61 61t-79.5 40t-95 14.5q-94 0 -172 -38.5t-134.5 -105.5t-88 -158t-31.5 -196z" />
+<glyph unicode="&#x2206;" horiz-adv-x="1247" d="M63 0v74q119 323 239 655t241 655h162q57 -158 116.5 -323t120.5 -331.5t122 -332t120 -323.5v-74h-1121zM217 119h805l-338 940q-14 42 -31 95.5t-32 109.5h-7q-12 -56 -30 -111t-33 -98z" />
+<glyph unicode="&#x220f;" horiz-adv-x="1550" d="M197 -471v1905h1157v-1905h-144v1774h-870v-1774h-143z" />
+<glyph unicode="&#x2211;" horiz-adv-x="1354" d="M55 -397l717 884l-668 859v88h1139v-121h-944l641 -821l-680 -842h1034v-121h-1239v74z" />
+<glyph unicode="&#x2212;" horiz-adv-x="1427" d="M178 532v111h1069v-111h-1069z" />
+<glyph unicode="&#x2215;" horiz-adv-x="952" d="M18 -299l727 1819h123l-729 -1819h-121z" />
+<glyph unicode="&#x2219;" horiz-adv-x="516" d="M156 739q0 51 23 74t77 23q56 0 79 -23t23 -74q0 -54 -24.5 -74t-77.5 -20q-57 0 -78.5 24.5t-21.5 69.5z" />
+<glyph unicode="&#x221a;" horiz-adv-x="1130" d="M51 696l230 138l301 -695l383 1354h112l-430 -1518h-123l-307 707l-117 -72z" />
+<glyph unicode="&#x221e;" horiz-adv-x="1696" d="M102 592q0 78 25 141.5t70 109t108.5 70.5t140.5 25q69 0 127 -20t107 -53.5t89.5 -77t72.5 -91.5h6q27 40 66 83t88.5 78t109.5 58t129 23q75 0 139 -23.5t110.5 -67.5t72.5 -106t26 -139q0 -71 -24 -133.5t-69 -110t-109.5 -75t-145.5 -27.5q-65 0 -122.5 18.5 t-107.5 51.5t-91.5 77.5t-73.5 96.5h-6q-36 -53 -79 -97.5t-92 -77t-103.5 -51t-114.5 -18.5q-78 0 -142.5 25.5t-110.5 70.5t-71 106.5t-25 133.5zM225 592q0 -50 17 -91.5t47.5 -71.5t72 -47t89.5 -17q51 0 98 18.5t89 50.5t78.5 74t67.5 90q-32 52 -69.5 94.5t-79.5 73 t-88.5 47t-95.5 16.5q-58 0 -100.5 -19t-70.5 -51.5t-41.5 -75.5t-13.5 -91zM903 598q66 -109 152 -171t180 -62q61 0 104.5 19.5t71.5 52t41.5 75t13.5 88.5q0 45 -13.5 86.5t-41 73t-71 50.5t-103.5 19q-54 0 -100.5 -17.5t-87.5 -48t-77 -73t-69 -92.5z" />
+<glyph unicode="&#x221f;" horiz-adv-x="2048" d="M143 0v1667h111v-1558h1671v-109h-1782z" />
+<glyph unicode="&#x2229;" horiz-adv-x="1473" d="M158 0v588q0 128 2.5 214.5t7.5 133.5q12 107 55 201t115.5 164.5t173 111.5t225.5 41q138 0 246 -46t182 -134q55 -65 85 -128t44.5 -140.5t17.5 -177.5t3 -240v-588h-121v606q0 244 -12 342q-10 83 -44.5 154.5t-91.5 124t-135.5 82.5t-175.5 30q-150 0 -248 -61.5 t-149 -167.5q-23 -50 -35.5 -95t-17.5 -100.5t-5.5 -129t-0.5 -179.5v-606h-121z" />
+<glyph unicode="&#x222b;" horiz-adv-x="1047" d="M129 -446l35 110q18 -8 44 -14t58 -6q43 0 77.5 12.5t59 39.5t37.5 69.5t13 101.5v1321q0 79 20 142.5t59 108.5t97.5 69t136.5 24q21 0 44 -2t43 -6t36.5 -8.5t25.5 -10.5l-32 -110q-16 9 -44 14.5t-65 5.5q-83 0 -130.5 -53.5t-47.5 -159.5v-1327q0 -83 -21.5 -147.5 t-61.5 -109t-98.5 -68t-131.5 -23.5q-19 0 -40.5 2t-42.5 5.5t-40 8.5t-31 11z" />
+<glyph unicode="&#x2248;" horiz-adv-x="1427" d="M162 694v125q86 68 160.5 97.5t136.5 29.5q60 0 126 -24.5t133.5 -54.5t133 -54.5t123.5 -24.5q39 0 75.5 11t72 30.5t70 46t69.5 56.5v-129q-36 -30 -69.5 -53.5t-67 -39t-70 -24t-78.5 -8.5q-40 0 -85 11.5t-91.5 29.5t-93.5 38t-91.5 38t-85 29.5t-73.5 11.5 q-41 0 -78.5 -11t-73.5 -30.5t-71 -45.5t-72 -55zM164 264v125q85 68 159 97.5t136 29.5q61 0 127.5 -24.5t134 -54.5t132.5 -54.5t122 -24.5q39 0 75.5 11t72 30.5t70.5 46t71 56.5v-129q-41 -33 -77.5 -56.5t-71.5 -39t-69 -22.5t-69 -7q-40 0 -84.5 11.5t-91 29.5 t-93.5 38t-91.5 38t-84.5 29.5t-73 11.5q-41 0 -78.5 -11t-73.5 -30.5t-71 -45.5t-72 -55z" />
+<glyph unicode="&#x2260;" horiz-adv-x="1427" d="M178 305v111h361l182 340h-543v110h600l232 432h127l-232 -432h342v-110h-399l-182 -340h581v-111h-639l-207 -387h-127l207 387h-303z" />
+<glyph unicode="&#x2261;" horiz-adv-x="1427" d="M178 0v111h1069v-111h-1069zM178 451v110h1069v-110h-1069zM178 901v111h1069v-111h-1069z" />
+<glyph unicode="&#x2264;" horiz-adv-x="1380" d="M156 0v111h1069v-111h-1069zM156 608v86l1069 436v-120l-893 -359l893 -327v-123z" />
+<glyph unicode="&#x2265;" horiz-adv-x="1427" d="M156 0v111h1069v-111h-1069zM156 201v123l893 327l-893 359v120l1069 -436v-86z" />
+<glyph unicode="&#x2302;" horiz-adv-x="1229" d="M154 0v635l460 518l461 -518v-635h-921zM233 82h762v518l-381 426l-381 -426v-518z" />
+<glyph unicode="&#x2310;" horiz-adv-x="1427" d="M178 387v565h1069v-110h-958v-455h-111z" />
+<glyph unicode="&#x2320;" horiz-adv-x="1237" d="M547 -381v1608q0 111 21.5 193t66.5 136q88 111 203 111q34 0 60 -9t43.5 -24t26.5 -34.5t9 -40.5q0 -19 -7 -36t-19 -29.5t-28 -20t-34 -7.5q-29 0 -52.5 12t-48.5 50q-22 37 -45 37q-30 0 -43 -27q-5 -14 -7.5 -51.5t-2.5 -100.5v-1767h-143z" />
+<glyph unicode="&#x2321;" horiz-adv-x="1237" d="M260 -272q0 19 7 36t19 29.5t28 19.5t34 7q31 0 53.5 -13t47.5 -51q22 -35 45 -35q30 0 41 27q12 28 12 152v1767h143v-1608q0 -109 -21.5 -190.5t-66.5 -136.5q-85 -113 -203 -113q-35 0 -61 9t-43 24t-26 34.5t-9 41.5z" />
+<glyph unicode="&#x2500;" d="M-23 535v174h1496v-174h-1496z" />
+<glyph unicode="&#x2502;" d="M639 -621v2485h174v-2485h-174z" />
+<glyph unicode="&#x250c;" d="M639 -621v1330h836v-174h-662v-1156h-174z" />
+<glyph unicode="&#x2510;" d="M-23 535v174h834v-1330h-174v1156h-660z" />
+<glyph unicode="&#x2514;" d="M639 535v1329h174v-1155h662v-174h-836z" />
+<glyph unicode="&#x2518;" d="M-23 535v174h660v1155h174v-1329h-834z" />
+<glyph unicode="&#x251c;" d="M639 -621v2485h174v-1155h662v-174h-662v-1156h-174z" />
+<glyph unicode="&#x2524;" d="M-23 535v174h660v1155h174v-2485h-174v1156h-660z" />
+<glyph unicode="&#x252c;" d="M-23 535v174h1496v-174h-662v-1156h-174v1156h-660z" />
+<glyph unicode="&#x2534;" d="M-23 535v174h660v1155h174v-1155h662v-174h-1496z" />
+<glyph unicode="&#x253c;" d="M-23 535v174h660v1155h174v-1155h662v-174h-662v-1156h-174v1156h-660z" />
+<glyph unicode="&#x2550;" d="M-23 344v174h1496v-174h-1496zM-23 725v174h1496v-174h-1496z" />
+<glyph unicode="&#x2551;" d="M449 -621v2485h174v-2485h-174zM829 -621v2485h175v-2485h-175z" />
+<glyph unicode="&#x2552;" d="M639 -621v1520h836v-174h-662v-207h662v-174h-662v-965h-174z" />
+<glyph unicode="&#x2553;" d="M449 -621v1330h1026v-174h-471v-1156h-175v1156h-206v-1156h-174z" />
+<glyph unicode="&#x2554;" d="M449 -621v1520h1026v-174h-852v-1346h-174zM829 518h646v-174h-471v-965h-175v1139z" />
+<glyph unicode="&#x2555;" d="M-23 344v174h660v207h-660v174h834v-1520h-174v965h-660z" />
+<glyph unicode="&#x2556;" d="M-23 535v174h1027v-1330h-177v1156h-204v-1156h-174v1156h-472z" />
+<glyph unicode="&#x2557;" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h1027v-1520h-177v1346h-850z" />
+<glyph unicode="&#x2558;" d="M639 344v1520h174v-965h662v-174h-662v-207h662v-174h-836z" />
+<glyph unicode="&#x2559;" d="M449 535v1329h174v-1155h206v1155h175v-1155h471v-174h-1026z" />
+<glyph unicode="&#x255a;" d="M449 344v1520h174v-1346h850v-174h-1024zM829 725v1139h175v-965h471v-174h-646z" />
+<glyph unicode="&#x255b;" d="M-23 344v174h660v207h-660v174h660v965h174v-1520h-834z" />
+<glyph unicode="&#x255c;" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1329h-1027z" />
+<glyph unicode="&#x255d;" d="M-23 344v174h850v1346h177v-1520h-1027zM-23 725v174h469v965h177v-1139h-646z" />
+<glyph unicode="&#x255e;" d="M639 -621v2485h174v-965h662v-174h-662v-207h662v-174h-662v-965h-174z" />
+<glyph unicode="&#x255f;" d="M449 -621v2485h174v-2485h-174zM829 -621v2485h175v-1155h471v-174h-471v-1156h-175z" />
+<glyph unicode="&#x2560;" d="M449 -621v2485h174v-2485h-174zM829 518h646v-174h-471v-965h-175v1139zM829 725v1139h175v-965h471v-174h-646z" />
+<glyph unicode="&#x2561;" d="M-23 344v174h660v207h-660v174h660v965h174v-2485h-174v965h-660z" />
+<glyph unicode="&#x2562;" d="M-23 535v174h469v1155h177v-2485h-177l3 1156h-472zM827 -621v2485h177v-2485h-177z" />
+<glyph unicode="&#x2563;" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h469v965h177v-1139h-646zM827 -621v2485h177v-2485h-177z" />
+<glyph unicode="&#x2564;" d="M-23 344v174h1496v-174h-662v-965h-174v965h-660zM-23 725v174h1496v-174h-1496z" />
+<glyph unicode="&#x2565;" d="M-23 535v174h1496v-174h-469v-1156h-177v1156h-204v-1156h-177v1156h-469z" />
+<glyph unicode="&#x2566;" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h1496v-174h-1496zM827 518h646v-174h-469v-965h-177v1139z" />
+<glyph unicode="&#x2567;" d="M-23 344v174h1496v-174h-1496zM-23 725v174h660v965h174v-965h662v-174h-1496z" />
+<glyph unicode="&#x2568;" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1155h469v-174h-1496z" />
+<glyph unicode="&#x2569;" d="M-23 344v174h1496v-174h-1496zM-23 725v174h469v965h177v-1139h-646zM827 725v1139h177v-965h469v-174h-646z" />
+<glyph unicode="&#x256a;" d="M-23 344v174h660v207h-660v174h660v965h174v-965h662v-174h-662v-207h662v-174h-662v-965h-174v965h-660z" />
+<glyph unicode="&#x256b;" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1155h469v-174h-469v-1156h-177v1156h-204v-1156h-177v1156h-469z" />
+<glyph unicode="&#x256c;" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h469v965h177v-1139h-646zM827 518h646v-174h-469v-965h-177v1139zM827 725v1139h177v-965h469v-174h-646z" />
+<glyph unicode="&#x2580;" d="M-23 621v1243h1496v-1243h-1496z" />
+<glyph unicode="&#x2584;" d="M-23 -621v1242h1496v-1242h-1496z" />
+<glyph unicode="&#x2588;" d="M-23 -621v2485h1496v-2485h-1496z" />
+<glyph unicode="&#x258c;" d="M-23 -621v2485h748v-2485h-748z" />
+<glyph unicode="&#x2590;" d="M725 -621v2485h750v-2485h-750z" />
+<glyph unicode="&#x2591;" d="M0 -129h121v-127h-121v127zM0 244v125h121v-125h-121zM0 741v125h121v-125h-121zM0 1241v125h121v-125h-121zM0 1739v125h121v-125h-121zM242 -4v125h120v-125h-120zM242 -379h120v-125h-120v125zM242 494v124h120v-124h-120zM242 991v125h120v-125h-120zM242 1491v125 h120v-125h-120zM481 -129h121v-127h-121v127zM481 244v125h121v-125h-121zM481 741v125h121v-125h-121zM481 1241v125h121v-125h-121zM481 1739v125h121v-125h-121zM723 -4v125h121v-125h-121zM723 -379h121v-125h-121v125zM723 494v124h121v-124h-121zM723 991v125h121 v-125h-121zM723 1491v125h121v-125h-121zM965 -129h120v-127h-120v127zM965 244v125h120v-125h-120zM965 741v125h120v-125h-120zM965 1241v125h120v-125h-120zM965 1739v125h120v-125h-120zM1206 -4v125h121v-125h-121zM1206 -379h121v-125h-121v125zM1206 494v124h121 v-124h-121zM1206 991v125h121v-125h-121zM1206 1491v125h121v-125h-121z" />
+<glyph unicode="&#x2592;" d="M0 -4v123h121v-123h-121zM0 -379h121v-125h-121v125zM0 494v124h121v-124h-121zM0 991v125h121v-125h-121zM0 1491v125h121v-125h-121zM121 -129h121v-127h-121v127zM121 244v125h121v-125h-121zM121 741v125h121v-125h-121zM121 1241v125h121v-125h-121zM121 1739v125 h121v-125h-121zM242 -4v123h120v-123h-120zM242 -379h120v-125h-120v125zM242 494v124h120v-124h-120zM242 991v125h120v-125h-120zM242 1491v125h120v-125h-120zM362 -129h119v-127h-119v127zM362 244v125h119v-125h-119zM362 741v125h119v-125h-119zM362 1241v125h119 v-125h-119zM362 1739v125h119v-125h-119zM481 -4v123h121v-123h-121zM481 -379h121v-125h-121v125zM481 494v124h121v-124h-121zM481 991v125h121v-125h-121zM481 1491v125h121v-125h-121zM602 -129h123v-127h-123v127zM602 244v125h123v-125h-123zM602 741v125h123v-125 h-123zM602 1241v125h123v-125h-123zM602 1739v125h123v-125h-123zM725 -4v123h119v-123h-119zM725 -379h119v-125h-119v125zM725 494v124h119v-124h-119zM725 991v125h119v-125h-119zM725 1491v125h119v-125h-119zM844 -129h121v-127h-121v127zM844 244v125h121v-125h-121z M844 741v125h121v-125h-121zM844 1241v125h121v-125h-121zM844 1739v125h121v-125h-121zM965 -4v123h120v-123h-120zM965 -381l120 2v-125h-120v123zM965 494v124h120v-124h-120zM965 991v125h120v-125h-120zM965 1491v125h120v-125h-120zM1085 -129h121v-127h-121v127z M1085 244v125h121v-125h-121zM1085 741v125h121v-125h-121zM1085 1241v125h121v-125h-121zM1085 1739v125h121v-125h-121zM1206 -4v123h121v-123h-121zM1206 -379h121v-125h-121v125zM1206 494v124h121v-124h-121zM1206 991v125h121v-125h-121zM1206 1491v125h121v-125h-121 zM1327 -129h121v-127h-121v127zM1327 244v125h121v-125h-121zM1327 741v125h121v-125h-121zM1327 1241v125h121v-125h-121zM1327 1739v125h121v-125h-121z" />
+<glyph unicode="&#x2593;" d="M0 -129v373h121v125h-121v372h121v125h-121v375h121v125h-121v373h121v125h121v-125h120v125h119v-125h121v125h123v-125h119v125h121v-125h120v125h121v-125h121v125h121v-248h-121v-125h121v-375h-121v-125h121v-373h-121v-124h121v-375h-121v-123h121v-375h-121v-125 h121v-125h-1448v373h121v127h-121zM121 -4h121v123h-121v-123zM121 -379v-125h121v125h-121zM121 494h121v124h-121v-124zM121 991h121v125h-121v-125zM121 1491h121v125h-121v-125zM242 -129v-127h120v127h-120zM242 244h120v125h-120v-125zM242 741h120v125h-120v-125z M242 1241h120v125h-120v-125zM362 -4h119v123h-119v-123zM362 -379v-125h119v125h-119zM362 494h119v124h-119v-124zM362 991h119v125h-119v-125zM362 1491h119v125h-119v-125zM481 -129v-127h121v127h-121zM481 244h121v125h-121v-125zM481 741h121v125h-121v-125z M481 1241h121v125h-121v-125zM602 -4h123v123h-123v-123zM602 -379v-125h123v125h-123zM602 494h123v124h-123v-124zM602 991h123v125h-123v-125zM602 1491h123v125h-123v-125zM725 -129v-127h119v127h-119zM725 244h119v125h-119v-125zM725 741h119v125h-119v-125z M725 1241h119v125h-119v-125zM844 -4h121v123h-121v-123zM844 -379v-125h121v125h-121zM844 494h121v124h-121v-124zM844 991h121v125h-121v-125zM844 1491h121v125h-121v-125zM965 -129v-127h120v127h-120zM965 244h120v125h-120v-125zM965 741h120v125h-120v-125z M965 1241h120v125h-120v-125zM1085 -4h121v123h-121v-123zM1085 -379v-125h121v125h-121zM1085 494h121v124h-121v-124zM1085 991h121v125h-121v-125zM1085 1491h121v125h-121v-125zM1206 -129v-127h121v127h-121zM1206 244h121v125h-121v-125zM1206 741h121v125h-121v-125z M1206 1241h121v125h-121v-125z" />
+<glyph unicode="&#x25a0;" horiz-adv-x="1237" d="M145 0v944h945v-944h-945z" />
+<glyph unicode="&#x25a1;" horiz-adv-x="1237" d="M145 0v944h945v-944h-945zM221 76h793v792h-793v-792z" />
+<glyph unicode="&#x25aa;" horiz-adv-x="725" d="M131 444v463l463 2v-465h-463z" />
+<glyph unicode="&#x25ab;" horiz-adv-x="725" d="M131 444v463h463v-463h-463zM207 520h311v311h-311v-311z" />
+<glyph unicode="&#x25ac;" horiz-adv-x="2048" d="M340 0v385h1368v-385h-1368z" />
+<glyph unicode="&#x25b2;" horiz-adv-x="2028" d="M303 0l711 1419l710 -1419h-1421z" />
+<glyph unicode="&#x25ba;" horiz-adv-x="2028" d="M289 -31v1448l1450 -725z" />
+<glyph unicode="&#x25bc;" horiz-adv-x="2028" d="M303 1389h1421l-710 -1420z" />
+<glyph unicode="&#x25c4;" horiz-adv-x="2028" d="M289 692l1450 725v-1448z" />
+<glyph unicode="&#x25ca;" horiz-adv-x="1210" d="M129 715l449 719h84l452 -717l-452 -717h-84zM256 717l365 -582l362 582l-362 579z" />
+<glyph unicode="&#x25cb;" horiz-adv-x="1237" d="M178 578q-3 58 13 114t46 106t72.5 92t92.5 71.5t105 44.5t111 12q84 4 165 -31t144 -97t99.5 -143.5t32.5 -168.5q0 -183 -129 -312t-312 -129q-182 0 -311 129t-129 312zM254 578q0 -152 106 -259q107 -106 258 -106q152 0 259 106q106 107 106 259q2 48 -11.5 94.5 t-38 87.5t-59.5 75.5t-76.5 59t-87 37t-92.5 10.5q-46 2 -92 -10.5t-87 -37t-76 -59t-59.5 -75.5t-38 -87.5t-11.5 -94.5z" />
+<glyph unicode="&#x25cf;" horiz-adv-x="1237" d="M178 578q-3 58 13 114t46 106t72.5 92t92.5 71.5t105 44.5t111 12q84 4 165 -31t144 -97t99.5 -143.5t32.5 -168.5q0 -183 -129 -312t-312 -129q-182 0 -311 129t-129 312z" />
+<glyph unicode="&#x25d8;" horiz-adv-x="1237" d="M127 0v981h981v-981h-981zM416 489q0 -41 16 -77t43 -63.5t64 -43.5t79 -16t79 16t64 43.5t42.5 63.5t15.5 77q0 42 -15.5 79t-42.5 64.5t-64 43.5t-79 16t-79 -16t-64 -43.5t-43 -64.5t-16 -79z" />
+<glyph unicode="&#x25d9;" horiz-adv-x="1237" d="M43 0v1155h1153v-1155h-1153zM178 578q0 -183 129 -312t311 -129q185 0 314 129t129 312q3 58 -13.5 114t-46.5 106t-72.5 92t-92.5 71.5t-105.5 44.5t-112.5 12q-56 3 -111 -12t-105 -44.5t-92.5 -71.5t-72.5 -92t-46 -106t-13 -114zM256 578q-4 73 26 140t82 118 t119 80t138 26q69 3 136 -26t118.5 -80t81.5 -118t26 -140q0 -152 -106 -259q-107 -106 -256 -106q-152 0 -259 106q-106 107 -106 259z" />
+<glyph unicode="&#x25e6;" horiz-adv-x="725" d="M113 678q0 51 19.5 96.5t53.5 79.5t79.5 54t96.5 20q52 0 97.5 -20t80 -54.5t54.5 -79.5t20 -96q0 -52 -20 -98t-54.5 -80t-80 -54t-97.5 -20t-97.5 19.5t-79 53.5t-53 80t-19.5 99zM188 678q0 -37 13.5 -69t37.5 -56t55.5 -37.5t67.5 -13.5t68.5 13.5t56.5 37.5t38 56 t14 69q0 36 -13.5 67.5t-37.5 55.5t-56.5 37.5t-69.5 13.5q-36 0 -67.5 -13.5t-55.5 -37.5t-37.5 -55.5t-13.5 -67.5z" />
<glyph unicode="&#x25fc;" horiz-adv-x="1050" d="M0 0v1050h1050v-1050h-1050z" />
+<glyph unicode="&#x263a;" horiz-adv-x="2048" d="M385 518q0 165 86 320q85 151 238 235q152 82 315 82q161 0 313 -82q155 -83 240 -235q86 -155 86 -320q0 -166 -86 -317q-83 -153 -236 -236q-75 -42 -154 -63t-163 -21t-163 21t-154 63q-76 42 -135.5 101t-102.5 135q-42 75 -63 154.5t-21 162.5zM479 518 q0 -71 18.5 -138t53.5 -132q36 -65 88 -116t114 -86t131 -54t140 -19t138 18.5t132 53.5q65 37 116 89t86.5 114t54 130.5t18.5 139.5q0 139 -74 273q-37 65 -89.5 116t-114.5 85.5t-130.5 52.5t-136.5 18q-69 0 -135.5 -18.5t-132.5 -53.5q-65 -35 -115.5 -84.5 t-87.5 -115.5q-74 -134 -74 -273zM698 649q0 35 24 58.5t56 23.5q35 0 58.5 -23.5t23.5 -58.5q0 -32 -23.5 -56t-58.5 -24q-16 0 -30.5 6.5t-25.5 17.5t-17.5 25.5t-6.5 30.5zM729 313l64 35q76 -143 231 -143t231 143l64 -35q-102 -194 -295 -194q-99 0 -171.5 48.5 t-123.5 145.5zM1188 649q0 35 24 58.5t56 23.5q35 0 58.5 -23.5t23.5 -58.5q0 -32 -23.5 -56t-58.5 -24q-16 0 -30.5 6.5t-25.5 17.5t-17.5 25.5t-6.5 30.5z" />
+<glyph unicode="&#x263b;" horiz-adv-x="2048" d="M385 518q0 165 86 320q85 151 238 235q152 82 315 82q161 0 313 -82q155 -83 240 -235q86 -155 86 -320q0 -166 -86 -317q-83 -153 -236 -236q-75 -42 -154 -63t-163 -21t-163 21t-154 63q-76 42 -135.5 101t-102.5 135q-42 75 -63 154.5t-21 162.5zM698 649 q0 -16 6.5 -30.5t17.5 -25.5t25.5 -17.5t30.5 -6.5q35 0 58.5 24t23.5 56q0 35 -23.5 58.5t-58.5 23.5q-32 0 -56 -23.5t-24 -58.5zM729 313q51 -97 123.5 -145.5t171.5 -48.5q193 0 295 194l-64 35q-76 -143 -231 -143t-231 143zM1188 649q0 -16 6.5 -30.5t17.5 -25.5 t25.5 -17.5t30.5 -6.5q35 0 58.5 24t23.5 56q0 35 -23.5 58.5t-58.5 23.5q-32 0 -56 -23.5t-24 -58.5z" />
+<glyph unicode="&#x263c;" horiz-adv-x="1878" d="M16 666v67h336q4 53 14 98.5t27 87.5t42.5 82t60.5 82l-283 287l47 57l293 -282q50 34 93.5 59t85 41.5t83 25.5t86.5 13v338h78v-338q50 -3 94 -12t86 -25.5t83 -42t85 -61.5l291 284l51 -53l-287 -287q42 -54 69.5 -100t44 -89t23.5 -83t9 -82h334v-67h-334 q-11 -97 -46.5 -185.5t-97.5 -167.5l285 -290l-57 -50l-283 283q-50 -38 -89 -62t-78 -40t-82 -24.5t-101 -14.5v-338h-78v338q-55 7 -100.5 17.5t-86.5 27t-79 39t-78 53.5l-295 -279l-49 52l285 286q-34 42 -59 83t-42.5 83.5t-28 89t-16.5 99.5h-336zM426 698 q0 -114 42.5 -208t113.5 -161.5t163.5 -105t192.5 -37.5q111 0 205 43t162.5 114t106.5 163.5t38 191.5q0 76 -20.5 143.5t-56 124t-84 102t-105.5 77t-120 48.5t-126 17q-112 0 -206 -42.5t-162 -113.5t-106 -163.5t-38 -192.5z" />
+<glyph unicode="&#x2640;" horiz-adv-x="1536" d="M244 983q0 112 43.5 208t116.5 166t167.5 110t196.5 40q76 0 144 -20t126 -56t104.5 -85.5t79.5 -107.5t50.5 -123t17.5 -132q0 -104 -39 -196.5t-105.5 -163.5t-156.5 -114.5t-192 -47.5v-402h458v-59h-458v-381h-60v381h-461v59h461v402q-65 0 -127 20t-116.5 55 t-100.5 84t-79 107t-51.5 123t-18.5 133zM299 981q0 -97 37 -182.5t100.5 -149t149 -100.5t182.5 -37q64 0 123.5 17t111.5 47.5t95.5 73.5t74 95t47.5 111.5t17 124.5q2 62 -15 122t-49 113t-77 97.5t-97.5 76t-111.5 47.5t-119 13q-101 0 -186.5 -38.5t-148.5 -103.5 t-98.5 -150t-35.5 -177z" />
+<glyph unicode="&#x2642;" horiz-adv-x="1536" d="M111 262q0 217 153 369q154 153 373 153q38 0 79.5 -6t86.5 -20l360 772l-536 -266l-25 53l615 303l34 -16l164 -666l-57 -14l-141 579l-359 -768q74 -37 130 -88t93.5 -112t56.5 -130.5t19 -142.5q0 -68 -17 -132.5t-53 -127.5q-34 -62 -83.5 -111t-109 -83t-126 -52 t-133.5 -18q-69 0 -134 17t-128 52q-62 35 -110.5 85t-82 110t-51.5 126t-18 134zM166 262q0 -194 137 -332q139 -139 332 -139q191 0 332 139q137 138 137 332q0 121 -64 234q-31 57 -76 101t-98 74t-112.5 45t-118.5 15q-119 0 -232 -61q-56 -30 -100 -74.5t-74.5 -98.5 t-46.5 -114t-16 -121z" />
+<glyph unicode="&#x2660;" horiz-adv-x="1343" d="M186 494q0 73 31 133q46 82 148 166q101 83 149 137q37 42 63.5 78.5t43.5 68.5t30.5 70.5t22.5 83.5q12 -54 32 -102.5t46 -92.5q55 -84 192 -209q69 -63 113.5 -110.5t62.5 -81.5q37 -67 37 -137q0 -47 -17 -88t-46 -71t-69 -47.5t-85 -17.5q-83 0 -154 58 q-27 21 -53 54.5t-49 78.5q2 -108 23 -185t65.5 -127.5t116 -78t174.5 -37.5l6 -37h-793l9 37q92 0 164 27t121.5 80.5t74.5 133.5t23 187q-45 -94 -111 -142.5t-151 -48.5q-90 0 -156 66q-64 64 -64 154z" />
+<glyph unicode="&#x2663;" horiz-adv-x="1343" d="M55 553q0 116 74 195q72 78 166 81q31 -2 72 -14.5t94 -38.5q-22 34 -35 59.5t-20.5 45.5t-10 38t-2.5 39q0 115 78 193q80 80 199 80q116 0 196 -80q42 -38 62 -85.5t20 -102.5q0 -90 -69 -187q42 20 67.5 31.5t34.5 13.5q14 5 28 6.5t31 1.5q100 0 174 -77t74 -195 q0 -60 -20 -110.5t-62 -92.5q-79 -79 -194 -82q-79 5 -136 34t-108 79q-17 20 -38.5 51t-47.5 76q2 -80 14 -142t34.5 -110.5t56 -85.5t79.5 -68q32 -20 87.5 -38t136.5 -33l8 -35h-848l8 35q164 33 219 67q40 25 74 64.5t58.5 87t38.5 101.5t14 110q0 8 -0.5 19t-2.5 28 q-30 -62 -68 -107.5t-80 -75t-87 -43.5t-90 -14q-116 0 -199 80q-40 42 -60 91.5t-20 109.5z" />
+<glyph unicode="&#x2665;" horiz-adv-x="1343" d="M127 969q0 109 74 186q73 76 180 76q57 0 104.5 -20t89.5 -60q62 -59 99 -172q33 113 92 172q83 80 190 80q111 0 185 -74q76 -73 76 -176q0 -88 -43 -188q-22 -48 -64.5 -112t-105.5 -144q-82 -104 -142 -189t-98 -151q-29 -54 -52 -109.5t-38 -112.5 q-16 60 -37.5 115.5t-50.5 106.5q-29 52 -84.5 132t-139.5 189q-60 82 -97.5 132.5t-51.5 72.5q-45 69 -65.5 127.5t-20.5 118.5z" />
+<glyph unicode="&#x2666;" horiz-adv-x="1343" d="M213 604q51 57 115.5 139.5t144.5 188.5q60 78 109 154.5t90 148.5q45 -79 98.5 -160t118.5 -168q75 -100 135 -176t106 -127q-37 -38 -96.5 -114t-144.5 -189q-135 -182 -217 -326q-14 26 -32.5 56.5t-41.5 64.5q-42 60 -92.5 130t-110.5 151q-12 17 -58 73.5 t-124 153.5z" />
+<glyph unicode="&#x266a;" horiz-adv-x="1024" d="M37 186q0 52 19.5 97.5t55.5 79t86.5 52.5t112.5 19q78 0 174 -47v977h39q87 0 143.5 -3t84.5 -11q38 -11 73 -30t66 -48q45 -42 70.5 -118t25.5 -179v-103h-98v43q0 136 -115 189q-73 31 -162 31h-26v-836q0 -121 -33 -188q-16 -34 -44.5 -61.5t-66 -46.5t-81 -29.5 t-89.5 -10.5q-54 0 -97.5 16t-74 45.5t-47 70.5t-16.5 91z" />
+<glyph unicode="&#x266b;" horiz-adv-x="1536" d="M86 94q0 52 20 97.5t56 79t86.5 52.5t111.5 19q39 0 83 -11t92 -34v975l794 248v-1108q0 -126 -31 -189q-15 -31 -42.5 -57t-64 -45t-79.5 -30t-90 -11q-56 0 -100 16.5t-75.5 46t-48 70.5t-16.5 90q0 102 76 172q77 74 201 74q19 0 35 -1t34.5 -5.5t42 -13t58.5 -23.5 v723l-596 -185v-835q0 -62 -8 -109.5t-25 -81.5q-15 -33 -43.5 -60t-65 -46.5t-80 -30t-89.5 -10.5q-55 0 -98.5 16.5t-74 46t-47 70.5t-16.5 90z" />
+<glyph unicode="&#xf001;" horiz-adv-x="1110" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM772 1305q0 45 20 65.5t70 20.5 q51 0 71.5 -20t20.5 -66q0 -51 -21.5 -69.5t-70.5 -18.5q-51 0 -70.5 23t-19.5 65zM798 0v1049h129v-1049h-129z" />
+<glyph unicode="&#xf002;" horiz-adv-x="1135" d="M47 938v111h164v116q0 91 15 158t49.5 111t90 65t136.5 21q60 0 114.5 -14.5t90.5 -32.5l-43 -109q-14 8 -33.5 16t-41 14t-44 9.5t-43.5 3.5q-46 0 -77 -13t-50 -42t-27 -76t-8 -115v-112h244v-111h-244v-938h-129v938h-164zM811 0v1489h129v-1489h-129z" />
+<glyph unicode="&#xf6c3;" horiz-adv-x="541" d="M170 -238q0 47 22 70t76 23q51 0 75 -26.5t24 -80.5q0 -38 -8 -69.5t-22 -59t-32.5 -52t-40.5 -48.5h-74q28 35 51 74t25 79q-51 0 -73.5 19t-22.5 71z" />
+<glyph unicode="&#xfeff;" horiz-adv-x="0" />
+<glyph horiz-adv-x="555" d="M176 1272q0 37 8 68.5t22.5 59t33.5 52.5t41 49h73q-28 -35 -52 -74t-26 -79q53 0 75 -19t22 -72q0 -46 -22 -69t-75 -23q-51 0 -75.5 25.5t-24.5 81.5z" />
+<glyph horiz-adv-x="369" d="M18 1024l134 360h178l-205 -360h-107z" />
+<glyph horiz-adv-x="883" d="M98 404q0 116 22.5 199t65.5 136.5t106.5 78.5t145.5 25q169 0 256.5 -107.5t87.5 -331.5q0 -117 -23 -200t-67 -136t-108 -77.5t-146 -24.5q-173 0 -256.5 107t-83.5 331zM227 404q0 -95 13.5 -159.5t40.5 -104t66.5 -57t90.5 -17.5q55 0 95.5 18.5t67 59t39.5 104.5 t13 156q0 93 -14.5 157.5t-42 104.5t-67.5 58t-91 18q-52 0 -91.5 -18t-66 -58.5t-40 -105t-13.5 -156.5z" />
+<glyph horiz-adv-x="883" d="M182 572v88q61 2 106.5 15t78.5 35.5t53.5 52.5t30.5 67h92v-837h-119v649q-42 -34 -104.5 -52t-137.5 -18z" />
+<glyph horiz-adv-x="883" d="M121 683q17 28 42 57t62.5 52.5t88.5 38t120 14.5q66 0 122 -13.5t97.5 -42t64.5 -73.5t23 -109q0 -46 -12 -85t-30.5 -71t-41 -57t-43.5 -43q-71 -60 -151 -122.5t-180 -133.5h491v-102h-649v106q42 31 88 66.5t90.5 70.5t84 68t67.5 59q47 37 77.5 67t48 57.5 t24.5 55.5t7 62q0 66 -44 101.5t-138 35.5q-78 0 -127.5 -32.5t-83.5 -88.5z" />
+<glyph horiz-adv-x="883" d="M102 105l97 62q35 -47 90.5 -74t113.5 -27q106 0 156.5 43.5t50.5 124.5q0 75 -46.5 112.5t-155.5 37.5h-93v100h80q105 0 154 38t49 97q0 57 -43.5 91t-134.5 34q-72 0 -123 -25t-92 -83l-96 57q19 31 47 58.5t66.5 48.5t88.5 33t113 12q80 0 137.5 -17t94 -46t54 -68.5 t17.5 -85.5q0 -65 -38 -114.5t-114 -72.5q75 -21 119.5 -75t44.5 -136q0 -129 -87.5 -196.5t-243.5 -67.5q-43 0 -87.5 8.5t-85 25.5t-75 43.5t-58.5 61.5z" />
+<glyph horiz-adv-x="883" d="M63 183v96l495 549h95v-547h133v-98h-133v-190h-119v190h-471zM200 281h334v371z" />
+<glyph horiz-adv-x="883" d="M117 99l98 58q11 -17 29 -33.5t42.5 -29.5t55 -20.5t66.5 -7.5q60 0 101.5 13.5t67 38t37 59.5t11.5 78q0 41 -15 71t-42 49.5t-65.5 28.5t-86.5 9q-101 0 -187 -46h-61l61 451h484v-102h-385l-31 -226q28 11 68.5 17t78.5 6q71 0 128 -16t97 -48.5t61.5 -81t21.5 -112.5 q0 -137 -86 -213t-258 -76q-106 0 -180 38t-111 95z" />
+<glyph horiz-adv-x="883" d="M113 388q0 90 19.5 172.5t63 146t113 101t168.5 37.5q83 0 144 -23.5t116 -71.5l-73 -84q-51 42 -93.5 60t-93.5 18q-54 0 -94.5 -19t-69 -54.5t-45 -86t-22.5 -112.5q49 25 108.5 41t112.5 16q145 0 223 -64.5t78 -201.5q0 -73 -23.5 -128.5t-66 -93t-101.5 -56.5 t-131 -19q-168 0 -250.5 107.5t-82.5 314.5zM242 376q1 -86 16 -145t42 -95.5t64.5 -53t81.5 -16.5q96 0 145.5 48.5t49.5 144.5q0 87 -45 127.5t-145 40.5q-57 0 -111.5 -15t-97.5 -36z" />
+<glyph horiz-adv-x="883" d="M119 716v102h637v-94l-365 -731h-133l365 723h-504z" />
+<glyph horiz-adv-x="883" d="M109 200q0 72 47 130t153 101q-93 42 -134.5 89.5t-41.5 109.5q0 103 76.5 159t230.5 56q146 0 224.5 -53.5t78.5 -159.5q0 -62 -45 -109t-147 -90q42 -15 81 -36t69 -49.5t48.5 -64.5t18.5 -81q0 -61 -23 -105.5t-65.5 -73.5t-103.5 -43t-136 -14q-165 0 -248 59 t-83 175zM233 200q0 -32 11.5 -57.5t36 -44t64 -28.5t95.5 -10q108 0 155.5 37.5t47.5 102.5q0 33 -16 59t-44.5 47t-67.5 39t-85 35q-99 -32 -148 -73.5t-49 -106.5zM256 632q0 -22 9 -41t30 -37t55.5 -36t85.5 -36q96 32 139 66.5t43 81.5q0 60 -47 90t-131 30 q-88 0 -136 -30t-48 -88z" />
+<glyph horiz-adv-x="883" d="M109 548q0 72 23.5 127.5t66.5 93t101.5 57t129.5 19.5q84 0 147 -27.5t104.5 -80.5t62 -130.5t20.5 -177.5q0 -93 -19.5 -177t-63.5 -147.5t-114 -101t-172 -37.5q-84 0 -146.5 23.5t-117.5 70.5l76 84q49 -42 93 -60t95 -18q56 0 97.5 19t70 54t45 85.5t23.5 112.5 q-50 -23 -108 -39.5t-109 -16.5q-150 0 -227.5 64.5t-77.5 202.5zM233 552q0 -88 46.5 -129t146.5 -41q59 0 112 16t95 41q0 69 -12 125.5t-37 96t-63.5 61.5t-90.5 22q-96 0 -146.5 -48t-50.5 -144z" />
+<glyph horiz-adv-x="883" d="M98 965q0 116 22.5 199t65.5 136.5t106.5 78.5t145.5 25q169 0 256.5 -107.5t87.5 -331.5q0 -117 -23 -200t-67 -136t-108 -77.5t-146 -24.5q-173 0 -256.5 107t-83.5 331zM227 965q0 -95 13.5 -159.5t40.5 -104t66.5 -57t90.5 -17.5q55 0 95.5 18.5t67 59t39.5 104.5 t13 156q0 93 -14.5 157.5t-42 104.5t-67.5 58t-91 18q-52 0 -91.5 -18t-66 -58.5t-40 -105t-13.5 -156.5z" />
+<glyph horiz-adv-x="883" d="M182 1133v88q61 2 106.5 15t78.5 35.5t53.5 52.5t30.5 67h92v-837h-119v649q-42 -34 -104.5 -52t-137.5 -18z" />
+<glyph horiz-adv-x="883" d="M121 1244q17 28 42 57t62.5 52.5t88.5 38t120 14.5q66 0 122 -13.5t97.5 -42t64.5 -73.5t23 -109q0 -46 -12 -85t-30.5 -71t-41 -57t-43.5 -43q-71 -60 -151 -122.5t-180 -133.5h491v-102h-649v106q42 31 88 66.5t90.5 70.5t84 68t67.5 59q47 37 77.5 67t48 57.5 t24.5 55.5t7 62q0 66 -44 101.5t-138 35.5q-78 0 -127.5 -32.5t-83.5 -88.5z" />
+<glyph horiz-adv-x="883" d="M102 666l97 62q35 -47 90.5 -74t113.5 -27q106 0 156.5 43.5t50.5 124.5q0 75 -46.5 112.5t-155.5 37.5h-93v100h80q105 0 154 38t49 97q0 57 -43.5 91t-134.5 34q-72 0 -123 -25t-92 -83l-96 57q19 31 47 58.5t66.5 48.5t88.5 33t113 12q80 0 137.5 -17t94 -46t54 -68.5 t17.5 -85.5q0 -65 -38 -114.5t-114 -72.5q75 -21 119.5 -75t44.5 -136q0 -129 -87.5 -196.5t-243.5 -67.5q-43 0 -87.5 8.5t-85 25.5t-75 43.5t-58.5 61.5z" />
+<glyph horiz-adv-x="883" d="M63 744v96l495 549h95v-547h133v-98h-133v-190h-119v190h-471zM200 842h334v371z" />
+<glyph horiz-adv-x="883" d="M117 660l98 58q11 -17 29 -33.5t42.5 -29.5t55 -20.5t66.5 -7.5q60 0 101.5 13.5t67 38t37 59.5t11.5 78q0 41 -15 71t-42 49.5t-65.5 28.5t-86.5 9q-101 0 -187 -46h-61l61 451h484v-102h-385l-31 -226q28 11 68.5 17t78.5 6q71 0 128 -16t97 -48.5t61.5 -81 t21.5 -112.5q0 -137 -86 -213t-258 -76q-106 0 -180 38t-111 95z" />
+<glyph horiz-adv-x="883" d="M113 949q0 90 19.5 172.5t63 146t113 101t168.5 37.5q83 0 144 -23.5t116 -71.5l-73 -84q-51 42 -93.5 60t-93.5 18q-54 0 -94.5 -19t-69 -54.5t-45 -86t-22.5 -112.5q49 25 108.5 41t112.5 16q145 0 223 -64.5t78 -201.5q0 -73 -23.5 -128.5t-66 -93t-101.5 -56.5 t-131 -19q-168 0 -250.5 107.5t-82.5 314.5zM242 937q1 -86 16 -145t42 -95.5t64.5 -53t81.5 -16.5q96 0 145.5 48.5t49.5 144.5q0 87 -45 127.5t-145 40.5q-57 0 -111.5 -15t-97.5 -36z" />
+<glyph horiz-adv-x="883" d="M119 1277v102h637v-94l-365 -731h-133l365 723h-504z" />
+<glyph horiz-adv-x="883" d="M109 761q0 72 47 130t153 101q-93 42 -134.5 89.5t-41.5 109.5q0 103 76.5 159t230.5 56q146 0 224.5 -53.5t78.5 -159.5q0 -62 -45 -109t-147 -90q42 -15 81 -36t69 -49.5t48.5 -64.5t18.5 -81q0 -61 -23 -105.5t-65.5 -73.5t-103.5 -43t-136 -14q-165 0 -248 59 t-83 175zM233 761q0 -32 11.5 -57.5t36 -44t64 -28.5t95.5 -10q108 0 155.5 37.5t47.5 102.5q0 33 -16 59t-44.5 47t-67.5 39t-85 35q-99 -32 -148 -73.5t-49 -106.5zM256 1193q0 -22 9 -41t30 -37t55.5 -36t85.5 -36q96 32 139 66.5t43 81.5q0 60 -47 90t-131 30 q-88 0 -136 -30t-48 -88z" />
+<glyph horiz-adv-x="883" d="M109 1109q0 72 23.5 127.5t66.5 93t101.5 57t129.5 19.5q84 0 147 -27.5t104.5 -80.5t62 -130.5t20.5 -177.5q0 -93 -19.5 -177t-63.5 -147.5t-114 -101t-172 -37.5q-84 0 -146.5 23.5t-117.5 70.5l76 84q49 -42 93 -60t95 -18q56 0 97.5 19t70 54t45 85.5t23.5 112.5 q-50 -23 -108 -39.5t-109 -16.5q-150 0 -227.5 64.5t-77.5 202.5zM233 1113q0 -88 46.5 -129t146.5 -41q59 0 112 16t95 41q0 69 -12 125.5t-37 96t-63.5 61.5t-90.5 22q-96 0 -146.5 -48t-50.5 -144z" />
+<glyph horiz-adv-x="1106" d="M326 1905h176l186 -361h-104z" />
+<glyph horiz-adv-x="1106" d="M455 1544l186 361h178l-260 -361h-104z" />
+<glyph horiz-adv-x="1106" d="M240 1544l229 361h168l229 -361h-110l-203 264l-203 -264h-110z" />
+<glyph horiz-adv-x="1106" d="M240 1905h110l203 -265l203 265h110l-229 -361h-168z" />
+<glyph horiz-adv-x="1106" d="M465 1128l80 361h162l-150 -361h-92z" />
+<glyph horiz-adv-x="1106" d="M190 1550q5 118 60 177t149 59q37 0 68 -10.5t57 -26.5t49 -35t45 -35t44.5 -26.5t48.5 -10.5q51 0 77 31.5t31 100.5h94q-3 -113 -58.5 -173.5t-149.5 -60.5q-43 0 -74.5 11t-56.5 27t-45.5 35t-41.5 35t-44.5 27t-53.5 11q-51 0 -75 -33.5t-29 -102.5h-95z" />
+<glyph horiz-adv-x="1106" d="M278 1636q0 44 18.5 66t69.5 22q53 0 71.5 -21.5t18.5 -66.5q0 -49 -19.5 -70.5t-70.5 -21.5q-27 0 -44 7t-27 19t-13.5 29t-3.5 37zM648 1636q0 44 19 66t71 22q53 0 71.5 -21.5t18.5 -66.5q0 -49 -19.5 -70.5t-70.5 -21.5q-53 0 -71.5 26t-18.5 66z" />
+<glyph horiz-adv-x="1106" d="M262 1591v111h580v-111h-580z" />
+<glyph horiz-adv-x="1106" d="M242 1794h98q12 -69 65 -106t140 -37q54 0 93.5 8.5t65.5 25.5t41 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-55.5 83.5t-19 98z" />
+<glyph horiz-adv-x="1106" d="M375 1673q0 39 10 71t31.5 55.5t55 36.5t79.5 13q91 0 134.5 -47.5t43.5 -128.5q0 -78 -43 -127t-135 -49q-48 0 -81.5 13.5t-54.5 37.5t-30.5 56t-9.5 69zM449 1673q0 -48 22.5 -77t79.5 -29q56 0 80 27.5t24 78.5q0 54 -26.5 80.5t-77.5 26.5q-50 0 -76 -28t-26 -79z " />
+<glyph horiz-adv-x="1106" d="M264 1544l195 361h174l-264 -361h-105zM580 1544l192 361h176l-264 -361h-104z" />
+<glyph horiz-adv-x="1106" d="M457 1640q0 48 21 72.5t75 24.5q56 0 76 -23.5t20 -73.5q0 -52 -21.5 -73t-74.5 -21q-29 0 -48 6.5t-29.5 19t-14.5 30t-4 38.5z" />
+<glyph horiz-adv-x="1085" d="M229 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM725 1397l135 274h170l-203 -274h-102z" />
+<glyph horiz-adv-x="1085" d="M55 1671h170l135 -274h-102zM229 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111z" />
+<glyph horiz-adv-x="1085" d="M229 1167l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM653 1612q12 9 29.5 18t39 15.5t46.5 11t51 4.5q87 0 133.5 -35.5t46.5 -97.5q0 -66 -39.5 -102t-111.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8 t-56.5 -25z" />
+<glyph horiz-adv-x="1085" d="M180 1507q5 107 60 161t149 54q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -103 -59 -158t-150 -55q-40 0 -70.5 9.5t-55 23t-46 30t-43.5 30t-46 23t-54 9.5q-51 0 -75.5 -27.5t-29.5 -87.5h-94zM229 1167l234 279h160l233 -279h-111 l-202 183l-203 -183h-111z" />
+<glyph horiz-adv-x="1085" d="M231 1468h99q12 -69 65 -106t140 -37q54 0 93 8.5t65.5 25.5t41.5 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM463 1417l135 275h172l-205 -275h-102z" />
+<glyph horiz-adv-x="1085" d="M231 1468h99q12 -69 65 -106t140 -37q54 0 93 8.5t65.5 25.5t41.5 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM315 1692h170l136 -275h-103z" />
+<glyph horiz-adv-x="1085" d="M231 1468h99q12 -69 65 -106t140 -37q54 0 93 8.5t65.5 25.5t41.5 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM365 1686q23 18 68 33.5t97 15.5q87 0 134 -36t47 -97q0 -67 -40 -102.5t-112 -43.5v-41 h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8t-55.5 -25z" />
+<glyph horiz-adv-x="1085" d="M180 1528q5 106 60 160.5t149 54.5q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -104 -59 -158.5t-150 -54.5q-40 0 -70.5 9t-55 23t-46 30t-43.5 30t-46 23t-54 9q-51 0 -75.5 -27t-29.5 -87h-94zM231 1468h99q12 -69 65 -106t140 -37 q54 0 93 8.5t65.5 25.5t41.5 44t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98z" />
+<glyph horiz-adv-x="1085" d="M252 1458v111h579v-111h-579zM268 1270q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 25t-18.5 65zM641 1270q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z " />
+<glyph horiz-adv-x="1085" d="M268 1270q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 25t-18.5 65zM477 1399l135 293h170l-202 -293h-103zM641 1270q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5 t-3.5 36.5z" />
+<glyph horiz-adv-x="1085" d="M229 1692h111l203 -189l202 189h111l-233 -285h-162zM268 1270q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 25t-18.5 65zM641 1270q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5 t-13.5 28.5t-3.5 36.5z" />
+<glyph horiz-adv-x="1085" d="M268 1270q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 25t-18.5 65zM305 1692h170l135 -293h-102zM641 1270q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5z " />
+<glyph horiz-adv-x="1085" d="M229 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM725 1733l135 274h170l-203 -274h-102z" />
+<glyph horiz-adv-x="1085" d="M55 2007h170l135 -274h-102zM229 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111z" />
+<glyph horiz-adv-x="1085" d="M229 1503l234 279h160l233 -279h-111l-202 183l-203 -183h-111zM653 1948q12 9 29.5 18t39 15.5t46.5 11t51 4.5q87 0 133.5 -35.5t46.5 -97.5q0 -66 -39.5 -102t-111.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-26 0 -54.5 -8 t-56.5 -25z" />
+<glyph horiz-adv-x="1085" d="M180 1833q5 106 60 160.5t149 54.5q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -104 -59 -158.5t-150 -54.5q-40 0 -70.5 9.5t-55 23t-46 30t-43.5 30t-46 23t-54 9.5q-51 0 -75.5 -27.5t-29.5 -87.5h-94zM229 1503l234 269h160l233 -269 h-111l-202 172l-203 -172h-111z" />
+<glyph horiz-adv-x="1085" d="M231 1784h99q12 -69 65 -106.5t140 -37.5q54 0 93 8.5t65.5 26t41.5 44.5t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM463 1733l135 274h172l-205 -274h-102z" />
+<glyph horiz-adv-x="1085" d="M231 1784h99q12 -69 65 -106.5t140 -37.5q54 0 93 8.5t65.5 26t41.5 44.5t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM315 2007h170l136 -274h-103z" />
+<glyph horiz-adv-x="1085" d="M231 1784h99q12 -69 65 -106.5t140 -37.5q54 0 93 8.5t65.5 26t41.5 44.5t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98zM365 2001q23 18 68 33.5t97 15.5q87 0 134 -35.5t47 -97.5q0 -66 -40 -101.5 t-112 -43.5v-41h-82v106h29q45 0 68.5 17t23.5 49q0 29 -18.5 45t-63.5 16q-26 0 -54.5 -8t-55.5 -25z" />
+<glyph horiz-adv-x="1085" d="M180 1843q5 107 60 161t149 54q52 0 93 -19t76.5 -42.5t69.5 -42.5t72 -19q51 0 77.5 25.5t31.5 85.5h94q-3 -103 -59 -158t-150 -55q-40 0 -70.5 9.5t-55 23t-46 30t-43.5 30t-46 23t-54 9.5q-51 0 -75.5 -27.5t-29.5 -87.5h-94zM231 1784h99q12 -69 65 -106.5 t140 -37.5q54 0 93 8.5t65.5 26t41.5 44.5t21 65h98q-1 -51 -17.5 -98t-54 -83.5t-98 -58.5t-147.5 -22q-78 0 -135.5 22t-95 58.5t-56 83.5t-19.5 98z" />
+<glyph horiz-adv-x="1085" d="M252 1794v111h579v-111h-579zM268 1606q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 24.5t-18.5 65.5zM641 1606q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5 z" />
+<glyph horiz-adv-x="1085" d="M268 1606q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 24.5t-18.5 65.5zM477 1735l135 293h170l-202 -293h-103zM641 1606q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5 t-3.5 36.5z" />
+<glyph horiz-adv-x="1085" d="M229 2028h111l203 -189l202 189h111l-233 -285h-162zM268 1606q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 24.5t-18.5 65.5zM641 1606q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5 t-27 18.5t-13.5 28.5t-3.5 36.5z" />
+<glyph horiz-adv-x="1085" d="M268 1606q0 45 19 66.5t71 21.5q53 0 72 -21t19 -67q0 -48 -20 -69t-71 -21q-53 0 -71.5 24.5t-18.5 65.5zM305 2028h170l135 -293h-102zM641 1606q0 45 18.5 66.5t69.5 21.5q54 0 72 -21t18 -67q0 -48 -19.5 -69t-70.5 -21q-27 0 -44 6.5t-27 18.5t-13.5 28.5t-3.5 36.5 z" />
+<glyph horiz-adv-x="1085" d="M371 1432q23 18 68 33.5t98 15.5q86 0 133 -35.5t47 -97.5q0 -66 -39.5 -102t-112.5 -44v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph horiz-adv-x="1085" d="M371 1767q23 19 68 34.5t98 15.5q86 0 133 -36t47 -98q0 -66 -39.5 -101.5t-112.5 -43.5v-41h-82v107h29q45 0 68.5 16.5t23.5 48.5q0 29 -18.5 45.5t-63.5 16.5q-55 0 -110 -33z" />
+<glyph horiz-adv-x="1106" d="M242 1444h131q9 -79 49.5 -121.5t122.5 -42.5q50 0 83.5 9.5t55 30t32 51.5t15.5 73h133q-1 -47 -17.5 -91.5t-54 -79.5t-98 -56t-147.5 -21q-78 0 -135.5 21t-95 56t-55.5 79.5t-19 91.5z" />
+<glyph horiz-adv-x="1106" d="M242 1769h133q9 -78 48.5 -120.5t121.5 -42.5q50 0 83 9.5t54 30t31.5 51t15.5 72.5h135q-1 -48 -17.5 -92.5t-54 -79t-98 -55t-147.5 -20.5q-78 0 -135.5 20.5t-95 55t-55.5 79t-19 92.5z" />
+<hkern u1="&#x28;" u2="&#x458;" k="-50" />
+<hkern u1="&#x28;" u2="&#x3ca;" k="-35" />
+<hkern u1="&#x28;" u2="&#x390;" k="-30" />
<hkern u1="&#x28;" u2="j" k="-50" />
+<hkern u1="&#x2a;" u2="&#x2206;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1eb6;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1eb4;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1eb2;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1eb0;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1eae;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1eac;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1eaa;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1ea8;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1ea6;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1ea4;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1ea2;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1ea0;" k="90" />
+<hkern u1="&#x2a;" u2="&#x459;" k="113" />
+<hkern u1="&#x2a;" u2="&#x44a;" k="-45" />
+<hkern u1="&#x2a;" u2="&#x442;" k="-10" />
+<hkern u1="&#x2a;" u2="&#x43b;" k="113" />
+<hkern u1="&#x2a;" u2="&#x42a;" k="-45" />
+<hkern u1="&#x2a;" u2="&#x422;" k="-22" />
+<hkern u1="&#x2a;" u2="&#x41b;" k="105" />
+<hkern u1="&#x2a;" u2="&#x414;" k="75" />
+<hkern u1="&#x2a;" u2="&#x410;" k="90" />
+<hkern u1="&#x2a;" u2="&#x40b;" k="-45" />
+<hkern u1="&#x2a;" u2="&#x409;" k="105" />
+<hkern u1="&#x2a;" u2="&#x408;" k="123" />
+<hkern u1="&#x2a;" u2="&#x402;" k="-45" />
+<hkern u1="&#x2a;" u2="&#x3ca;" k="-45" />
+<hkern u1="&#x2a;" u2="&#x3c7;" k="-20" />
+<hkern u1="&#x2a;" u2="&#x3be;" k="-5" />
+<hkern u1="&#x2a;" u2="&#x3a4;" k="-22" />
+<hkern u1="&#x2a;" u2="&#x39b;" k="90" />
+<hkern u1="&#x2a;" u2="&#x394;" k="90" />
+<hkern u1="&#x2a;" u2="&#x391;" k="90" />
+<hkern u1="&#x2a;" u2="&#x38f;" k="-75" />
+<hkern u1="&#x2a;" u2="&#x38e;" k="-75" />
+<hkern u1="&#x2a;" u2="&#x38c;" k="-75" />
+<hkern u1="&#x2a;" u2="&#x38a;" k="-75" />
+<hkern u1="&#x2a;" u2="&#x389;" k="-75" />
+<hkern u1="&#x2a;" u2="&#x388;" k="-75" />
+<hkern u1="&#x2a;" u2="&#x386;" k="-125" />
+<hkern u1="&#x2a;" u2="&#x21a;" k="-22" />
+<hkern u1="&#x2a;" u2="&#x1fa;" k="90" />
+<hkern u1="&#x2a;" u2="&#x1cd;" k="90" />
+<hkern u1="&#x2a;" u2="&#x166;" k="-22" />
+<hkern u1="&#x2a;" u2="&#x164;" k="-22" />
+<hkern u1="&#x2a;" u2="&#x162;" k="-22" />
+<hkern u1="&#x2a;" u2="&#x134;" k="123" />
+<hkern u1="&#x2a;" u2="&#x104;" k="90" />
+<hkern u1="&#x2a;" u2="&#x102;" k="90" />
+<hkern u1="&#x2a;" u2="&#x100;" k="90" />
<hkern u1="&#x2a;" u2="&#xef;" k="-45" />
<hkern u1="&#x2a;" u2="&#xc5;" k="90" />
<hkern u1="&#x2a;" u2="&#xc4;" k="90" />
@@ -253,15 +965,34 @@
<hkern u1="&#x2a;" u2="T" k="-22" />
<hkern u1="&#x2a;" u2="J" k="123" />
<hkern u1="&#x2a;" u2="A" k="90" />
+<hkern u1="&#x2c;" u2="&#x42a;" k="115" />
+<hkern u1="&#x2e;" u2="&#x42a;" k="115" />
+<hkern u1="&#x3a;" u2="&#x42a;" k="70" />
+<hkern u1="&#x3b;" u2="&#x42a;" k="70" />
<hkern u1="A" u2="&#x3f;" k="35" />
<hkern u1="A" u2="&#x2a;" k="90" />
+<hkern u1="F" u2="&#x135;" k="-5" />
+<hkern u1="F" u2="&#x12b;" k="-20" />
+<hkern u1="F" u2="&#x129;" k="-30" />
<hkern u1="F" u2="&#xef;" k="-15" />
<hkern u1="F" u2="&#xee;" k="-10" />
+<hkern u1="K" u2="&#x135;" k="25" />
+<hkern u1="K" u2="&#x12d;" k="13" />
+<hkern u1="K" u2="&#x12b;" k="10" />
<hkern u1="K" u2="&#xef;" k="-5" />
<hkern u1="K" u2="&#xee;" k="-17" />
<hkern u1="L" u2="&#xd8;" k="13" />
<hkern u1="L" u2="&#x3f;" k="50" />
<hkern u1="L" u2="&#x2a;" k="160" />
+<hkern u1="T" u2="&#x161;" k="88" />
+<hkern u1="T" u2="&#x15d;" k="33" />
+<hkern u1="T" u2="&#x159;" k="45" />
+<hkern u1="T" u2="&#x135;" k="-30" />
+<hkern u1="T" u2="&#x12d;" k="-10" />
+<hkern u1="T" u2="&#x12b;" k="-40" />
+<hkern u1="T" u2="&#x129;" k="-75" />
+<hkern u1="T" u2="&#x103;" k="70" />
+<hkern u1="T" u2="&#x101;" k="80" />
<hkern u1="T" u2="&#xef;" k="-45" />
<hkern u1="T" u2="&#xee;" k="-30" />
<hkern u1="T" u2="&#xe4;" k="90" />
@@ -269,32 +1000,94 @@
<hkern u1="T" u2="&#xe2;" k="65" />
<hkern u1="T" u2="&#x3f;" k="35" />
<hkern u1="T" u2="&#x2a;" k="-22" />
+<hkern u1="V" u2="&#x135;" k="-20" />
+<hkern u1="V" u2="&#x12d;" k="-7" />
+<hkern u1="V" u2="&#x12b;" k="-17" />
+<hkern u1="V" u2="&#x129;" k="-27" />
+<hkern u1="V" u2="&#x127;" k="20" />
<hkern u1="V" u2="&#xef;" k="-27" />
<hkern u1="V" u2="&#xee;" k="-27" />
+<hkern u1="W" u2="&#x135;" k="-20" />
+<hkern u1="W" u2="&#x12d;" k="-7" />
+<hkern u1="W" u2="&#x12b;" k="-17" />
+<hkern u1="W" u2="&#x129;" k="-27" />
+<hkern u1="W" u2="&#x127;" k="20" />
<hkern u1="W" u2="&#xef;" k="-27" />
<hkern u1="W" u2="&#xee;" k="-27" />
+<hkern u1="X" u2="&#x12d;" k="-15" />
+<hkern u1="X" u2="&#x129;" k="-40" />
<hkern u1="X" u2="&#xef;" k="-25" />
<hkern u1="X" u2="&#xee;" k="-20" />
+<hkern u1="Y" u2="&#x135;" k="-17" />
+<hkern u1="Y" u2="&#x12d;" k="-5" />
+<hkern u1="Y" u2="&#x12b;" k="-10" />
+<hkern u1="Y" u2="&#x129;" k="-30" />
<hkern u1="Y" u2="&#xef;" k="-20" />
<hkern u1="Y" u2="&#xee;" k="-32" />
+<hkern u1="[" u2="&#x458;" k="-50" />
+<hkern u1="[" u2="&#x3ca;" k="-35" />
+<hkern u1="[" u2="&#x390;" k="-30" />
<hkern u1="[" u2="j" k="-50" />
+<hkern u1="a" u2="&#x167;" k="-12" />
+<hkern u1="f" u2="&#x159;" k="-30" />
+<hkern u1="f" u2="&#x135;" k="-65" />
+<hkern u1="f" u2="&#x12d;" k="-70" />
+<hkern u1="f" u2="&#x12b;" k="-45" />
+<hkern u1="f" u2="&#x129;" k="-105" />
+<hkern u1="f" u2="&#x127;" k="-20" />
<hkern u1="f" u2="&#xef;" k="-35" />
<hkern u1="f" u2="&#xee;" k="-50" />
<hkern u1="f" u2="&#xec;" k="-40" />
<hkern u1="f" u2="&#x3f;" k="-30" />
<hkern u1="f" u2="&#x2a;" k="-25" />
<hkern u1="f" u2="&#x21;" k="-30" />
+<hkern u1="j" u2="&#x1ef9;" k="-12" />
+<hkern u1="j" u2="&#x1ef7;" k="-12" />
+<hkern u1="j" u2="&#x1ef5;" k="-12" />
+<hkern u1="j" u2="&#x1ef3;" k="-12" />
+<hkern u1="j" u2="&#x177;" k="-12" />
<hkern u1="j" u2="&#xff;" k="-12" />
<hkern u1="j" u2="&#xfd;" k="-12" />
<hkern u1="j" u2="y" k="-12" />
+<hkern u1="&#x7b;" u2="&#x458;" k="-50" />
+<hkern u1="&#x7b;" u2="&#x3ca;" k="-35" />
+<hkern u1="&#x7b;" u2="&#x390;" k="-30" />
<hkern u1="&#x7b;" u2="j" k="-50" />
+<hkern u1="&#xa1;" u2="&#x1ef8;" k="58" />
+<hkern u1="&#xa1;" u2="&#x1ef6;" k="58" />
+<hkern u1="&#xa1;" u2="&#x1ef4;" k="58" />
+<hkern u1="&#xa1;" u2="&#x1ef2;" k="58" />
+<hkern u1="&#xa1;" u2="&#x1e84;" k="30" />
+<hkern u1="&#xa1;" u2="&#x1e82;" k="30" />
+<hkern u1="&#xa1;" u2="&#x1e80;" k="30" />
+<hkern u1="&#xa1;" u2="&#x21a;" k="105" />
<hkern u1="&#xa1;" u2="&#x178;" k="58" />
+<hkern u1="&#xa1;" u2="&#x176;" k="58" />
+<hkern u1="&#xa1;" u2="&#x174;" k="30" />
+<hkern u1="&#xa1;" u2="&#x166;" k="105" />
+<hkern u1="&#xa1;" u2="&#x164;" k="105" />
+<hkern u1="&#xa1;" u2="&#x162;" k="105" />
<hkern u1="&#xa1;" u2="&#xdd;" k="58" />
<hkern u1="&#xa1;" u2="Y" k="58" />
<hkern u1="&#xa1;" u2="W" k="30" />
<hkern u1="&#xa1;" u2="V" k="30" />
<hkern u1="&#xa1;" u2="T" k="105" />
+<hkern u1="&#xab;" u2="&#x386;" k="-175" />
+<hkern u1="&#xb5;" u2="&#x3c7;" k="8" />
+<hkern u1="&#xbf;" u2="&#x1ef8;" k="113" />
+<hkern u1="&#xbf;" u2="&#x1ef6;" k="113" />
+<hkern u1="&#xbf;" u2="&#x1ef4;" k="113" />
+<hkern u1="&#xbf;" u2="&#x1ef2;" k="113" />
+<hkern u1="&#xbf;" u2="&#x1e84;" k="60" />
+<hkern u1="&#xbf;" u2="&#x1e82;" k="60" />
+<hkern u1="&#xbf;" u2="&#x1e80;" k="60" />
+<hkern u1="&#xbf;" u2="&#x21a;" k="60" />
<hkern u1="&#xbf;" u2="&#x178;" k="113" />
+<hkern u1="&#xbf;" u2="&#x176;" k="113" />
+<hkern u1="&#xbf;" u2="&#x174;" k="60" />
+<hkern u1="&#xbf;" u2="&#x166;" k="60" />
+<hkern u1="&#xbf;" u2="&#x164;" k="60" />
+<hkern u1="&#xbf;" u2="&#x162;" k="60" />
<hkern u1="&#xbf;" u2="&#xdd;" k="113" />
<hkern u1="&#xbf;" u2="Y" k="113" />
<hkern u1="&#xbf;" u2="W" k="60" />
@@ -312,359 +1105,1372 @@
<hkern u1="&#xc4;" u2="&#x2a;" k="90" />
<hkern u1="&#xc5;" u2="&#x3f;" k="35" />
<hkern u1="&#xc5;" u2="&#x2a;" k="90" />
+<hkern u1="&#xdd;" u2="&#x135;" k="-17" />
+<hkern u1="&#xdd;" u2="&#x12d;" k="-5" />
+<hkern u1="&#xdd;" u2="&#x12b;" k="-10" />
+<hkern u1="&#xdd;" u2="&#x129;" k="-30" />
<hkern u1="&#xdd;" u2="&#xef;" k="-20" />
<hkern u1="&#xdd;" u2="&#xee;" k="-32" />
+<hkern u1="&#xde;" u2="&#x1e84;" k="-15" />
+<hkern u1="&#xde;" u2="&#x1e82;" k="-15" />
+<hkern u1="&#xde;" u2="&#x1e80;" k="-15" />
+<hkern u1="&#xde;" u2="&#x21a;" k="-5" />
+<hkern u1="&#xde;" u2="&#x174;" k="-15" />
+<hkern u1="&#xde;" u2="&#x166;" k="-5" />
+<hkern u1="&#xde;" u2="&#x164;" k="-5" />
+<hkern u1="&#xde;" u2="&#x162;" k="-5" />
<hkern u1="&#xde;" u2="W" k="-15" />
<hkern u1="&#xde;" u2="V" k="-15" />
<hkern u1="&#xde;" u2="T" k="-5" />
+<hkern u1="&#xe0;" u2="&#x167;" k="-12" />
+<hkern u1="&#xe1;" u2="&#x167;" k="-12" />
+<hkern u1="&#xe2;" u2="&#x167;" k="-12" />
+<hkern u1="&#xe3;" u2="&#x167;" k="-12" />
+<hkern u1="&#xe4;" u2="&#x167;" k="-12" />
+<hkern u1="&#xe5;" u2="&#x167;" k="-12" />
<hkern u1="&#xef;" u2="&#xef;" k="-135" />
<hkern u1="&#xef;" u2="&#x2a;" k="-45" />
+<hkern u1="&#x100;" u2="&#x3f;" k="35" />
+<hkern u1="&#x100;" u2="&#x2a;" k="90" />
+<hkern u1="&#x101;" u2="&#x167;" k="-12" />
+<hkern u1="&#x102;" u2="&#x3f;" k="35" />
+<hkern u1="&#x102;" u2="&#x2a;" k="90" />
+<hkern u1="&#x103;" u2="&#x167;" k="-12" />
+<hkern u1="&#x104;" u2="&#x3f;" k="35" />
+<hkern u1="&#x104;" u2="&#x2a;" k="90" />
+<hkern u1="&#x105;" u2="&#x167;" k="-12" />
+<hkern u1="&#x10f;" u2="&#x159;" k="-10" />
+<hkern u1="&#x10f;" u2="&#x155;" k="50" />
+<hkern u1="&#x10f;" u2="&#x12b;" k="-70" />
+<hkern u1="&#x10f;" u2="&#xf1;" k="50" />
+<hkern u1="&#x10f;" u2="&#xef;" k="-65" />
+<hkern u1="&#x10f;" u2="&#xee;" k="-55" />
+<hkern u1="&#x10f;" u2="&#xec;" k="-45" />
+<hkern u1="&#x10f;" u2="&#xe4;" k="20" />
+<hkern u1="&#x10f;" u2="&#x3f;" k="-35" />
+<hkern u1="&#x136;" u2="&#x135;" k="25" />
+<hkern u1="&#x136;" u2="&#x12d;" k="13" />
+<hkern u1="&#x136;" u2="&#x12b;" k="10" />
+<hkern u1="&#x136;" u2="&#xef;" k="-5" />
+<hkern u1="&#x136;" u2="&#xee;" k="-17" />
+<hkern u1="&#x139;" u2="&#xd8;" k="13" />
+<hkern u1="&#x139;" u2="&#x3f;" k="50" />
+<hkern u1="&#x139;" u2="&#x2a;" k="160" />
+<hkern u1="&#x13b;" u2="&#xd8;" k="13" />
+<hkern u1="&#x13b;" u2="&#x3f;" k="50" />
+<hkern u1="&#x13b;" u2="&#x2a;" k="160" />
+<hkern u1="&#x13d;" u2="&#xd8;" k="13" />
+<hkern u1="&#x13d;" u2="&#x3f;" k="50" />
+<hkern u1="&#x13d;" u2="&#x2a;" k="160" />
+<hkern u1="&#x13e;" u2="&#x159;" k="-10" />
+<hkern u1="&#x13e;" u2="&#x155;" k="50" />
+<hkern u1="&#x13e;" u2="&#x12b;" k="-70" />
+<hkern u1="&#x13e;" u2="&#xf1;" k="50" />
+<hkern u1="&#x13e;" u2="&#xef;" k="-65" />
+<hkern u1="&#x13e;" u2="&#xee;" k="-55" />
+<hkern u1="&#x13e;" u2="&#xec;" k="-45" />
+<hkern u1="&#x13e;" u2="&#xe4;" k="20" />
+<hkern u1="&#x13e;" u2="&#x3f;" k="-35" />
+<hkern u1="&#x141;" u2="&#xd8;" k="13" />
+<hkern u1="&#x141;" u2="&#x3f;" k="50" />
+<hkern u1="&#x141;" u2="&#x2a;" k="160" />
+<hkern u1="&#x142;" u2="&#x21b;" k="-7" />
+<hkern u1="&#x142;" u2="&#x167;" k="-7" />
+<hkern u1="&#x142;" u2="&#x165;" k="-7" />
+<hkern u1="&#x142;" u2="&#x163;" k="-7" />
+<hkern u1="&#x142;" u2="t" k="-7" />
+<hkern u1="&#x162;" u2="&#x161;" k="88" />
+<hkern u1="&#x162;" u2="&#x15d;" k="33" />
+<hkern u1="&#x162;" u2="&#x159;" k="45" />
+<hkern u1="&#x162;" u2="&#x135;" k="-30" />
+<hkern u1="&#x162;" u2="&#x12d;" k="-10" />
+<hkern u1="&#x162;" u2="&#x12b;" k="-40" />
+<hkern u1="&#x162;" u2="&#x129;" k="-75" />
+<hkern u1="&#x162;" u2="&#x103;" k="70" />
+<hkern u1="&#x162;" u2="&#x101;" k="80" />
+<hkern u1="&#x162;" u2="&#xef;" k="-45" />
+<hkern u1="&#x162;" u2="&#xee;" k="-30" />
+<hkern u1="&#x162;" u2="&#xe4;" k="90" />
+<hkern u1="&#x162;" u2="&#xe3;" k="45" />
+<hkern u1="&#x162;" u2="&#xe2;" k="65" />
+<hkern u1="&#x162;" u2="&#x3f;" k="35" />
+<hkern u1="&#x162;" u2="&#x2a;" k="-22" />
+<hkern u1="&#x164;" u2="&#x161;" k="88" />
+<hkern u1="&#x164;" u2="&#x15d;" k="33" />
+<hkern u1="&#x164;" u2="&#x159;" k="45" />
+<hkern u1="&#x164;" u2="&#x135;" k="-30" />
+<hkern u1="&#x164;" u2="&#x12d;" k="-10" />
+<hkern u1="&#x164;" u2="&#x12b;" k="-40" />
+<hkern u1="&#x164;" u2="&#x129;" k="-75" />
+<hkern u1="&#x164;" u2="&#x103;" k="70" />
+<hkern u1="&#x164;" u2="&#x101;" k="80" />
+<hkern u1="&#x164;" u2="&#xef;" k="-45" />
+<hkern u1="&#x164;" u2="&#xee;" k="-30" />
+<hkern u1="&#x164;" u2="&#xe4;" k="90" />
+<hkern u1="&#x164;" u2="&#xe3;" k="45" />
+<hkern u1="&#x164;" u2="&#xe2;" k="65" />
+<hkern u1="&#x164;" u2="&#x3f;" k="35" />
+<hkern u1="&#x164;" u2="&#x2a;" k="-22" />
+<hkern u1="&#x165;" u2="&#x12b;" k="-25" />
+<hkern u1="&#x165;" u2="&#xef;" k="-25" />
+<hkern u1="&#x165;" u2="&#xee;" k="-15" />
+<hkern u1="&#x165;" u2="&#xec;" k="-10" />
+<hkern u1="&#x166;" u2="&#x161;" k="88" />
+<hkern u1="&#x166;" u2="&#x15d;" k="33" />
+<hkern u1="&#x166;" u2="&#x159;" k="45" />
+<hkern u1="&#x166;" u2="&#x135;" k="-30" />
+<hkern u1="&#x166;" u2="&#x12d;" k="-10" />
+<hkern u1="&#x166;" u2="&#x12b;" k="-40" />
+<hkern u1="&#x166;" u2="&#x129;" k="-75" />
+<hkern u1="&#x166;" u2="&#x103;" k="70" />
+<hkern u1="&#x166;" u2="&#x101;" k="80" />
+<hkern u1="&#x166;" u2="&#xef;" k="-45" />
+<hkern u1="&#x166;" u2="&#xee;" k="-30" />
+<hkern u1="&#x166;" u2="&#xe4;" k="90" />
+<hkern u1="&#x166;" u2="&#xe3;" k="45" />
+<hkern u1="&#x166;" u2="&#xe2;" k="65" />
+<hkern u1="&#x166;" u2="&#x3f;" k="35" />
+<hkern u1="&#x166;" u2="&#x2a;" k="-22" />
+<hkern u1="&#x174;" u2="&#x135;" k="-20" />
+<hkern u1="&#x174;" u2="&#x12d;" k="-7" />
+<hkern u1="&#x174;" u2="&#x12b;" k="-17" />
+<hkern u1="&#x174;" u2="&#x129;" k="-27" />
+<hkern u1="&#x174;" u2="&#x127;" k="20" />
+<hkern u1="&#x174;" u2="&#xef;" k="-27" />
+<hkern u1="&#x174;" u2="&#xee;" k="-27" />
+<hkern u1="&#x176;" u2="&#x135;" k="-17" />
+<hkern u1="&#x176;" u2="&#x12d;" k="-5" />
+<hkern u1="&#x176;" u2="&#x12b;" k="-10" />
+<hkern u1="&#x176;" u2="&#x129;" k="-30" />
+<hkern u1="&#x176;" u2="&#xef;" k="-20" />
+<hkern u1="&#x176;" u2="&#xee;" k="-32" />
+<hkern u1="&#x178;" u2="&#x135;" k="-17" />
+<hkern u1="&#x178;" u2="&#x12d;" k="-5" />
+<hkern u1="&#x178;" u2="&#x12b;" k="-10" />
+<hkern u1="&#x178;" u2="&#x129;" k="-30" />
<hkern u1="&#x178;" u2="&#xef;" k="-20" />
<hkern u1="&#x178;" u2="&#xee;" k="-32" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="T" k="80" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="V" k="48" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="W" k="30" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="Y,Yacute,Ydieresis" k="70" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quotedbl,quotesingle" k="60" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="colon,semicolon" k="-20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="25" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="15" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="t" k="15" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="z" k="-7" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="copyright,registered" k="30" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="trademark" k="110" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quoteleft,quotedblleft" k="90" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quoteright,quotedblright" k="95" />
-<hkern g1="B" g2="J" k="30" />
-<hkern g1="B" g2="T" k="35" />
+<hkern u1="&#x1cd;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1cd;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1ce;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1fa;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1fa;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1fb;" u2="&#x167;" k="-12" />
+<hkern u1="&#x21a;" u2="&#x161;" k="88" />
+<hkern u1="&#x21a;" u2="&#x15d;" k="33" />
+<hkern u1="&#x21a;" u2="&#x159;" k="45" />
+<hkern u1="&#x21a;" u2="&#x135;" k="-30" />
+<hkern u1="&#x21a;" u2="&#x12d;" k="-10" />
+<hkern u1="&#x21a;" u2="&#x12b;" k="-40" />
+<hkern u1="&#x21a;" u2="&#x129;" k="-75" />
+<hkern u1="&#x21a;" u2="&#x103;" k="70" />
+<hkern u1="&#x21a;" u2="&#x101;" k="80" />
+<hkern u1="&#x21a;" u2="&#xef;" k="-45" />
+<hkern u1="&#x21a;" u2="&#xee;" k="-30" />
+<hkern u1="&#x21a;" u2="&#xe4;" k="90" />
+<hkern u1="&#x21a;" u2="&#xe3;" k="45" />
+<hkern u1="&#x21a;" u2="&#xe2;" k="65" />
+<hkern u1="&#x21a;" u2="&#x3f;" k="35" />
+<hkern u1="&#x21a;" u2="&#x2a;" k="-22" />
+<hkern u1="&#x386;" u2="&#x3f;" k="35" />
+<hkern u1="&#x388;" u2="&#x390;" k="-65" />
+<hkern u1="&#x389;" u2="&#x390;" k="-10" />
+<hkern u1="&#x390;" u2="&#x3be;" k="33" />
+<hkern u1="&#x390;" u2="&#x3b8;" k="8" />
+<hkern u1="&#x390;" u2="&#x3b6;" k="20" />
+<hkern u1="&#x390;" u2="&#x3f;" k="-10" />
+<hkern u1="&#x391;" u2="&#x3f;" k="35" />
+<hkern u1="&#x393;" u2="&#x3cb;" k="120" />
+<hkern u1="&#x393;" u2="&#x3ca;" k="-47" />
+<hkern u1="&#x393;" u2="&#x3b4;" k="113" />
+<hkern u1="&#x393;" u2="&#x3b0;" k="75" />
+<hkern u1="&#x393;" u2="&#x3af;" k="73" />
+<hkern u1="&#x393;" u2="&#x3a6;" k="70" />
+<hkern u1="&#x393;" u2="&#x390;" k="-67" />
+<hkern u1="&#x394;" u2="&#x3f;" k="35" />
+<hkern u1="&#x395;" u2="&#x390;" k="-65" />
+<hkern u1="&#x396;" u2="&#x3ca;" k="-30" />
+<hkern u1="&#x396;" u2="&#x390;" k="-45" />
+<hkern u1="&#x397;" u2="&#x390;" k="-10" />
+<hkern u1="&#x39a;" u2="&#x3ca;" k="-15" />
+<hkern u1="&#x39a;" u2="&#x3a6;" k="25" />
+<hkern u1="&#x39a;" u2="&#x390;" k="-33" />
+<hkern u1="&#x39b;" u2="&#x3f;" k="35" />
+<hkern u1="&#x39c;" u2="&#x390;" k="-10" />
+<hkern u1="&#x39d;" u2="&#x390;" k="-10" />
+<hkern u1="&#x39e;" u2="&#x3ca;" k="-15" />
+<hkern u1="&#x39e;" u2="&#x390;" k="-43" />
+<hkern u1="&#x3a0;" u2="&#x390;" k="-10" />
+<hkern u1="&#x3a3;" u2="&#x3ca;" k="-25" />
+<hkern u1="&#x3a3;" u2="&#x390;" k="-50" />
+<hkern u1="&#x3a4;" u2="&#x3cb;" k="75" />
+<hkern u1="&#x3a4;" u2="&#x3ca;" k="-55" />
+<hkern u1="&#x3a4;" u2="&#x3b4;" k="80" />
+<hkern u1="&#x3a4;" u2="&#x3b0;" k="45" />
+<hkern u1="&#x3a4;" u2="&#x3af;" k="60" />
+<hkern u1="&#x3a4;" u2="&#x390;" k="-90" />
+<hkern u1="&#x3a4;" u2="&#x3f;" k="35" />
+<hkern u1="&#x3a4;" u2="&#x2a;" k="68" />
+<hkern u1="&#x3a7;" u2="&#x3ca;" k="-20" />
+<hkern u1="&#x3a7;" u2="&#x390;" k="-47" />
+<hkern u1="&#x3a8;" u2="&#x390;" k="-33" />
+<hkern u1="&#x3b1;" u2="&#x3c4;" k="5" />
+<hkern u1="&#x3b1;" u2="&#x3c0;" k="3" />
+<hkern u1="&#x3b2;" u2="&#x3c4;" k="33" />
+<hkern u1="&#x3b6;" u2="&#x3ca;" k="-25" />
+<hkern u1="&#x3b6;" u2="&#x390;" k="-70" />
+<hkern u1="&#x3bb;" u2="&#x3f;" k="80" />
+<hkern u1="&#x3bb;" u2="&#x2a;" k="95" />
+<hkern u1="&#x3bd;" u2="&#x3c4;" k="-10" />
+<hkern u1="&#x3be;" u2="&#x390;" k="-23" />
+<hkern u1="&#x3be;" u2="&#x2a;" k="-5" />
+<hkern u1="&#x3c7;" u2="&#x3f;" k="85" />
+<hkern u1="&#x3c7;" u2="&#x2a;" k="20" />
+<hkern u1="&#x3c9;" u2="&#x3f;" k="50" />
+<hkern u1="&#x3ca;" u2="&#x3ca;" k="-60" />
+<hkern u1="&#x3ca;" u2="&#x3f;" k="20" />
+<hkern u1="&#x3ce;" u2="&#x3f;" k="50" />
+<hkern u1="&#x403;" u2="&#x45e;" k="180" />
+<hkern u1="&#x403;" u2="&#x458;" k="60" />
+<hkern u1="&#x403;" u2="&#x457;" k="-70" />
+<hkern u1="&#x403;" u2="&#x456;" k="60" />
+<hkern u1="&#x403;" u2="&#x451;" k="198" />
+<hkern u1="&#x403;" u2="&#x424;" k="50" />
+<hkern u1="&#x409;" u2="&#x42a;" k="18" />
+<hkern u1="&#x40a;" u2="&#x42a;" k="18" />
+<hkern u1="&#x40c;" u2="&#x457;" k="-5" />
+<hkern u1="&#x40c;" u2="&#x456;" k="20" />
+<hkern u1="&#x40e;" u2="&#x457;" k="-45" />
+<hkern u1="&#x410;" u2="&#x42a;" k="45" />
+<hkern u1="&#x410;" u2="&#x3f;" k="40" />
+<hkern u1="&#x410;" u2="&#x2a;" k="120" />
+<hkern u1="&#x413;" u2="&#x45e;" k="180" />
+<hkern u1="&#x413;" u2="&#x458;" k="60" />
+<hkern u1="&#x413;" u2="&#x457;" k="-70" />
+<hkern u1="&#x413;" u2="&#x456;" k="60" />
+<hkern u1="&#x413;" u2="&#x451;" k="198" />
+<hkern u1="&#x413;" u2="&#x424;" k="50" />
+<hkern u1="&#x414;" u2="&#x458;" k="-80" />
+<hkern u1="&#x414;" u2="&#x42d;" k="-15" />
+<hkern u1="&#x416;" u2="&#x457;" k="-5" />
+<hkern u1="&#x416;" u2="&#x456;" k="20" />
+<hkern u1="&#x41a;" u2="&#x457;" k="-5" />
+<hkern u1="&#x41a;" u2="&#x456;" k="20" />
+<hkern u1="&#x422;" u2="&#x458;" k="30" />
+<hkern u1="&#x422;" u2="&#x457;" k="-60" />
+<hkern u1="&#x422;" u2="&#x456;" k="20" />
+<hkern u1="&#x422;" u2="&#x451;" k="130" />
+<hkern u1="&#x422;" u2="&#x424;" k="43" />
+<hkern u1="&#x422;" u2="&#x2a;" k="-22" />
+<hkern u1="&#x423;" u2="&#x457;" k="-45" />
+<hkern u1="&#x424;" u2="&#x422;" k="43" />
+<hkern u1="&#x425;" u2="&#x457;" k="-25" />
+<hkern u1="&#x426;" u2="&#x458;" k="-80" />
+<hkern u1="&#x429;" u2="&#x458;" k="-80" />
+<hkern u1="&#x42a;" u2="&#x42a;" k="18" />
+<hkern u1="&#x42c;" u2="&#x42a;" k="18" />
+<hkern u1="&#x434;" u2="&#x458;" k="22" />
+<hkern u1="&#x442;" u2="&#x2a;" k="-10" />
+<hkern u1="&#x446;" u2="&#x458;" k="22" />
+<hkern u1="&#x449;" u2="&#x458;" k="22" />
+<hkern u1="&#x456;" u2="&#x457;" k="-5" />
+<hkern u1="&#x457;" u2="&#x45b;" k="-42" />
+<hkern u1="&#x457;" u2="&#x452;" k="-42" />
+<hkern u1="&#x457;" u2="&#x3f;" k="-5" />
+<hkern u1="&#x457;" u2="&#x2a;" k="5" />
+<hkern u1="&#x490;" u2="&#x491;" k="163" />
+<hkern u1="&#x490;" u2="&#x45f;" k="163" />
+<hkern u1="&#x490;" u2="&#x45e;" k="60" />
+<hkern u1="&#x490;" u2="&#x45d;" k="163" />
+<hkern u1="&#x490;" u2="&#x45c;" k="163" />
+<hkern u1="&#x490;" u2="&#x45a;" k="163" />
+<hkern u1="&#x490;" u2="&#x458;" k="60" />
+<hkern u1="&#x490;" u2="&#x457;" k="-70" />
+<hkern u1="&#x490;" u2="&#x456;" k="60" />
+<hkern u1="&#x490;" u2="&#x453;" k="163" />
+<hkern u1="&#x490;" u2="&#x451;" k="198" />
+<hkern u1="&#x490;" u2="&#x450;" k="195" />
+<hkern u1="&#x490;" u2="&#x44e;" k="163" />
+<hkern u1="&#x490;" u2="&#x44c;" k="163" />
+<hkern u1="&#x490;" u2="&#x44b;" k="163" />
+<hkern u1="&#x490;" u2="&#x449;" k="163" />
+<hkern u1="&#x490;" u2="&#x448;" k="163" />
+<hkern u1="&#x490;" u2="&#x446;" k="163" />
+<hkern u1="&#x490;" u2="&#x440;" k="163" />
+<hkern u1="&#x490;" u2="&#x43f;" k="163" />
+<hkern u1="&#x490;" u2="&#x43d;" k="163" />
+<hkern u1="&#x490;" u2="&#x43c;" k="163" />
+<hkern u1="&#x490;" u2="&#x43a;" k="163" />
+<hkern u1="&#x490;" u2="&#x439;" k="178" />
+<hkern u1="&#x490;" u2="&#x438;" k="163" />
+<hkern u1="&#x490;" u2="&#x433;" k="163" />
+<hkern u1="&#x490;" u2="&#x432;" k="163" />
+<hkern u1="&#x490;" u2="&#x42d;" k="13" />
+<hkern u1="&#x490;" u2="&#x424;" k="50" />
+<hkern u1="&#x490;" u2="&#x417;" k="13" />
+<hkern u1="&#x491;" u2="&#x45b;" k="-27" />
+<hkern u1="&#x491;" u2="&#x457;" k="-80" />
+<hkern u1="&#x491;" u2="&#x452;" k="-27" />
+<hkern u1="&#x1e80;" u2="&#x135;" k="-20" />
+<hkern u1="&#x1e80;" u2="&#x12d;" k="-7" />
+<hkern u1="&#x1e80;" u2="&#x12b;" k="-17" />
+<hkern u1="&#x1e80;" u2="&#x129;" k="-27" />
+<hkern u1="&#x1e80;" u2="&#x127;" k="20" />
+<hkern u1="&#x1e80;" u2="&#xef;" k="-27" />
+<hkern u1="&#x1e80;" u2="&#xee;" k="-27" />
+<hkern u1="&#x1e82;" u2="&#x135;" k="-20" />
+<hkern u1="&#x1e82;" u2="&#x12d;" k="-7" />
+<hkern u1="&#x1e82;" u2="&#x12b;" k="-17" />
+<hkern u1="&#x1e82;" u2="&#x129;" k="-27" />
+<hkern u1="&#x1e82;" u2="&#x127;" k="20" />
+<hkern u1="&#x1e82;" u2="&#xef;" k="-27" />
+<hkern u1="&#x1e82;" u2="&#xee;" k="-27" />
+<hkern u1="&#x1e84;" u2="&#x135;" k="-20" />
+<hkern u1="&#x1e84;" u2="&#x12d;" k="-7" />
+<hkern u1="&#x1e84;" u2="&#x12b;" k="-17" />
+<hkern u1="&#x1e84;" u2="&#x129;" k="-27" />
+<hkern u1="&#x1e84;" u2="&#x127;" k="20" />
+<hkern u1="&#x1e84;" u2="&#xef;" k="-27" />
+<hkern u1="&#x1e84;" u2="&#xee;" k="-27" />
+<hkern u1="&#x1ea0;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1ea0;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1ea1;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1ea2;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1ea2;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1ea3;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1ea4;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1ea4;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1ea5;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1ea6;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1ea6;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1ea7;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1ea8;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1ea8;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1ea9;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1eaa;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1eaa;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1eab;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1eac;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1eac;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1ead;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1eae;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1eae;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1eaf;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1eb0;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1eb0;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1eb1;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1eb2;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1eb2;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1eb3;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1eb4;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1eb4;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1eb5;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1eb6;" u2="&#x3f;" k="35" />
+<hkern u1="&#x1eb6;" u2="&#x2a;" k="90" />
+<hkern u1="&#x1eb7;" u2="&#x167;" k="-12" />
+<hkern u1="&#x1ef2;" u2="&#x135;" k="-17" />
+<hkern u1="&#x1ef2;" u2="&#x12d;" k="-5" />
+<hkern u1="&#x1ef2;" u2="&#x12b;" k="-10" />
+<hkern u1="&#x1ef2;" u2="&#x129;" k="-30" />
+<hkern u1="&#x1ef2;" u2="&#xef;" k="-20" />
+<hkern u1="&#x1ef2;" u2="&#xee;" k="-32" />
+<hkern u1="&#x1ef4;" u2="&#x135;" k="-17" />
+<hkern u1="&#x1ef4;" u2="&#x12d;" k="-5" />
+<hkern u1="&#x1ef4;" u2="&#x12b;" k="-10" />
+<hkern u1="&#x1ef4;" u2="&#x129;" k="-30" />
+<hkern u1="&#x1ef4;" u2="&#xef;" k="-20" />
+<hkern u1="&#x1ef4;" u2="&#xee;" k="-32" />
+<hkern u1="&#x1ef6;" u2="&#x135;" k="-17" />
+<hkern u1="&#x1ef6;" u2="&#x12d;" k="-5" />
+<hkern u1="&#x1ef6;" u2="&#x12b;" k="-10" />
+<hkern u1="&#x1ef6;" u2="&#x129;" k="-30" />
+<hkern u1="&#x1ef6;" u2="&#xef;" k="-20" />
+<hkern u1="&#x1ef6;" u2="&#xee;" k="-32" />
+<hkern u1="&#x1ef8;" u2="&#x135;" k="-17" />
+<hkern u1="&#x1ef8;" u2="&#x12d;" k="-5" />
+<hkern u1="&#x1ef8;" u2="&#x12b;" k="-10" />
+<hkern u1="&#x1ef8;" u2="&#x129;" k="-30" />
+<hkern u1="&#x1ef8;" u2="&#xef;" k="-20" />
+<hkern u1="&#x1ef8;" u2="&#xee;" k="-32" />
+<hkern u1="&#x2018;" u2="&#x3ca;" k="-50" />
+<hkern u1="&#x2018;" u2="&#x390;" k="-40" />
+<hkern u1="&#x2018;" u2="&#x38e;" k="-115" />
+<hkern u1="&#x2018;" u2="&#x386;" k="-35" />
+<hkern u1="&#x2019;" u2="&#x3ca;" k="-45" />
+<hkern u1="&#x2019;" u2="&#x390;" k="-45" />
+<hkern u1="&#x2019;" u2="&#x38e;" k="-100" />
+<hkern u1="&#x2019;" u2="&#x386;" k="-65" />
+<hkern u1="&#x201a;" u2="&#x42a;" k="115" />
+<hkern u1="&#x201c;" u2="&#x3ca;" k="-50" />
+<hkern u1="&#x201c;" u2="&#x390;" k="-40" />
+<hkern u1="&#x201c;" u2="&#x38e;" k="-115" />
+<hkern u1="&#x201c;" u2="&#x386;" k="-35" />
+<hkern u1="&#x201d;" u2="&#x3ca;" k="-45" />
+<hkern u1="&#x201d;" u2="&#x390;" k="-45" />
+<hkern u1="&#x201d;" u2="&#x38e;" k="-100" />
+<hkern u1="&#x201d;" u2="&#x386;" k="-65" />
+<hkern u1="&#x201e;" u2="&#x42a;" k="115" />
+<hkern u1="&#x2026;" u2="&#x42a;" k="115" />
+<hkern u1="&#x2039;" u2="&#x386;" k="-175" />
+<hkern u1="&#x2206;" u2="&#x3f;" k="35" />
+<hkern g1="f_f" u2="&#x159;" k="-30" />
+<hkern g1="f_f" u2="&#x135;" k="-65" />
+<hkern g1="f_f" u2="&#x12d;" k="-70" />
+<hkern g1="f_f" u2="&#x12b;" k="-45" />
+<hkern g1="f_f" u2="&#x129;" k="-105" />
+<hkern g1="f_f" u2="&#x127;" k="-20" />
+<hkern g1="f_f" u2="&#xef;" k="-35" />
+<hkern g1="f_f" u2="&#xee;" k="-50" />
+<hkern g1="f_f" u2="&#xec;" k="-40" />
+<hkern g1="f_f" u2="&#x3f;" k="-30" />
+<hkern g1="f_f" u2="&#x2a;" k="-25" />
+<hkern g1="f_f" u2="&#x21;" k="-30" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="80" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="V" k="48" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="30" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="70" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quotedbl,quotesingle" k="60" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="colon,semicolon" k="-20" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="25" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="20" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="15" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="15" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="z,zacute,zdotaccent,zcaron" k="-7" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="copyright,registered" k="30" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="trademark" k="110" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quoteleft,quotedblleft" k="90" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quoteright,quotedblright" k="95" />
+<hkern g1="B" g2="J,Jcircumflex" k="30" />
+<hkern g1="B" g2="T,uni0162,Tcaron,Tbar,uni021A" k="35" />
<hkern g1="B" g2="V" k="20" />
-<hkern g1="B" g2="W" k="20" />
-<hkern g1="B" g2="Y,Yacute,Ydieresis" k="25" />
+<hkern g1="B" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="B" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="25" />
<hkern g1="B" g2="trademark" k="45" />
-<hkern g1="C,Ccedilla" g2="J" k="10" />
-<hkern g1="C,Ccedilla" g2="V" k="8" />
-<hkern g1="C,Ccedilla" g2="W" k="8" />
-<hkern g1="C,Ccedilla" g2="X" k="15" />
-<hkern g1="C,Ccedilla" g2="Y,Yacute,Ydieresis" k="20" />
-<hkern g1="E,AE,Egrave,Eacute,Ecircumflex,Edieresis,OE" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="15" />
-<hkern g1="F" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="65" />
-<hkern g1="F" g2="J" k="75" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="J,Jcircumflex" k="10" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="V" k="8" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="8" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="X" k="15" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
+<hkern g1="E,AE,Egrave,Eacute,Ecircumflex,Edieresis,Emacron,Ebreve,Edotaccent,Eogonek,Ecaron,OE,AEacute,Edotbelow,Ehookabove,Etilde,Ecircumflexacute,Ecircumflexgrave,Ecircumflexhookabove,Ecircumflextilde,Ecircumflexdotbelow" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="15" />
+<hkern g1="F" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="65" />
+<hkern g1="F" g2="J,Jcircumflex" k="75" />
<hkern g1="F" g2="X" k="35" />
<hkern g1="F" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="144" />
-<hkern g1="F" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="40" />
-<hkern g1="F" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="50" />
-<hkern g1="F" g2="t" k="20" />
-<hkern g1="F" g2="z" k="40" />
+<hkern g1="F" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="40" />
+<hkern g1="F" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="50" />
+<hkern g1="F" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="F" g2="z,zacute,zdotaccent,zcaron" k="40" />
<hkern g1="F" g2="copyright,registered" k="45" />
-<hkern g1="F" g2="S" k="25" />
-<hkern g1="F" g2="Z" k="20" />
-<hkern g1="F" g2="i,j,igrave,iacute,icircumflex,idieresis" k="20" />
-<hkern g1="F" g2="m,n,p,r,ntilde" k="38" />
-<hkern g1="F" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="50" />
-<hkern g1="F" g2="s" k="45" />
-<hkern g1="F" g2="u,ugrave,uacute,ucircumflex,udieresis" k="30" />
+<hkern g1="F" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="25" />
+<hkern g1="F" g2="Z,Zacute,Zdotaccent,Zcaron" k="20" />
+<hkern g1="F" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="20" />
+<hkern g1="F" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="38" />
+<hkern g1="F" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="50" />
+<hkern g1="F" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="45" />
+<hkern g1="F" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="30" />
<hkern g1="F" g2="v" k="30" />
-<hkern g1="F" g2="w" k="30" />
+<hkern g1="F" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="30" />
<hkern g1="F" g2="x" k="40" />
-<hkern g1="F" g2="y,yacute,ydieresis" k="35" />
-<hkern g1="F" g2="b,h,k,l,germandbls,thorn" k="10" />
-<hkern g1="F" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="10" />
-<hkern g1="G" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="15" />
-<hkern g1="G" g2="J" k="25" />
-<hkern g1="G" g2="T" k="20" />
-<hkern g1="G" g2="V" k="20" />
-<hkern g1="G" g2="W" k="20" />
-<hkern g1="G" g2="X" k="15" />
-<hkern g1="G" g2="Y,Yacute,Ydieresis" k="15" />
-<hkern g1="G" g2="trademark" k="30" />
-<hkern g1="J" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="20" />
-<hkern g1="J" g2="J" k="30" />
-<hkern g1="J" g2="X" k="10" />
-<hkern g1="J" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="45" />
-<hkern g1="J" g2="AE" k="30" />
-<hkern g1="K" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="20" />
-<hkern g1="K" g2="J" k="30" />
-<hkern g1="K" g2="T" k="38" />
-<hkern g1="K" g2="V" k="25" />
-<hkern g1="K" g2="W" k="25" />
-<hkern g1="K" g2="X" k="20" />
-<hkern g1="K" g2="Y,Yacute,Ydieresis" k="40" />
-<hkern g1="K" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="35" />
-<hkern g1="K" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="5" />
-<hkern g1="K" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="30" />
-<hkern g1="K" g2="t" k="30" />
-<hkern g1="K" g2="S" k="40" />
-<hkern g1="K" g2="i,j,igrave,iacute,icircumflex,idieresis" k="20" />
-<hkern g1="K" g2="m,n,p,r,ntilde" k="20" />
-<hkern g1="K" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="35" />
-<hkern g1="K" g2="s" k="30" />
-<hkern g1="K" g2="u,ugrave,uacute,ucircumflex,udieresis" k="30" />
-<hkern g1="K" g2="v" k="25" />
-<hkern g1="K" g2="w" k="25" />
-<hkern g1="K" g2="y,yacute,ydieresis" k="50" />
-<hkern g1="K" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="25" />
-<hkern g1="L" g2="T" k="115" />
-<hkern g1="L" g2="V" k="88" />
-<hkern g1="L" g2="W" k="50" />
-<hkern g1="L" g2="Y,Yacute,Ydieresis" k="85" />
-<hkern g1="L" g2="quotedbl,quotesingle" k="80" />
-<hkern g1="L" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-10" />
-<hkern g1="L" g2="colon,semicolon" k="-20" />
-<hkern g1="L" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="40" />
-<hkern g1="L" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="20" />
-<hkern g1="L" g2="t" k="15" />
-<hkern g1="L" g2="copyright,registered" k="60" />
-<hkern g1="L" g2="trademark" k="140" />
-<hkern g1="L" g2="quoteleft,quotedblleft" k="108" />
-<hkern g1="L" g2="quoteright,quotedblright" k="108" />
-<hkern g1="L" g2="S" k="28" />
-<hkern g1="L" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="18" />
-<hkern g1="L" g2="v" k="30" />
-<hkern g1="L" g2="w" k="30" />
-<hkern g1="L" g2="y,yacute,ydieresis" k="50" />
-<hkern g1="P,Thorn" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="50" />
-<hkern g1="P,Thorn" g2="J" k="65" />
-<hkern g1="P,Thorn" g2="T" k="10" />
+<hkern g1="F" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="35" />
+<hkern g1="F" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="10" />
+<hkern g1="F" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="10" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="15" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="J,Jcircumflex" k="25" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="T,uni0162,Tcaron,Tbar,uni021A" k="20" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="V" k="20" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="X" k="15" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="15" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="trademark" k="30" />
+<hkern g1="J,IJ,Jcircumflex" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="20" />
+<hkern g1="J,IJ,Jcircumflex" g2="J,Jcircumflex" k="30" />
+<hkern g1="J,IJ,Jcircumflex" g2="X" k="10" />
+<hkern g1="J,IJ,Jcircumflex" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="45" />
+<hkern g1="J,IJ,Jcircumflex" g2="AE,AEacute" k="30" />
+<hkern g1="K,Kcommaaccent" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="20" />
+<hkern g1="K,Kcommaaccent" g2="J,Jcircumflex" k="30" />
+<hkern g1="K,Kcommaaccent" g2="T,uni0162,Tcaron,Tbar,uni021A" k="38" />
+<hkern g1="K,Kcommaaccent" g2="V" k="25" />
+<hkern g1="K,Kcommaaccent" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="25" />
+<hkern g1="K,Kcommaaccent" g2="X" k="20" />
+<hkern g1="K,Kcommaaccent" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="40" />
+<hkern g1="K,Kcommaaccent" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="35" />
+<hkern g1="K,Kcommaaccent" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="5" />
+<hkern g1="K,Kcommaaccent" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="30" />
+<hkern g1="K,Kcommaaccent" g2="t,uni0163,tcaron,tbar,uni021B" k="30" />
+<hkern g1="K,Kcommaaccent" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="40" />
+<hkern g1="K,Kcommaaccent" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="20" />
+<hkern g1="K,Kcommaaccent" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="20" />
+<hkern g1="K,Kcommaaccent" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="35" />
+<hkern g1="K,Kcommaaccent" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="30" />
+<hkern g1="K,Kcommaaccent" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="30" />
+<hkern g1="K,Kcommaaccent" g2="v" k="25" />
+<hkern g1="K,Kcommaaccent" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="25" />
+<hkern g1="K,Kcommaaccent" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="50" />
+<hkern g1="K,Kcommaaccent" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="25" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="T,uni0162,Tcaron,Tbar,uni021A" k="115" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="V" k="88" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="50" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="85" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quotedbl,quotesingle" k="80" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-10" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="colon,semicolon" k="-20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="40" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="t,uni0163,tcaron,tbar,uni021B" k="15" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="copyright,registered" k="60" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="trademark" k="140" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quoteleft,quotedblleft" k="108" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quoteright,quotedblright" k="108" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="28" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="18" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="v" k="30" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="30" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="50" />
+<hkern g1="P,Thorn" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="50" />
+<hkern g1="P,Thorn" g2="J,Jcircumflex" k="65" />
+<hkern g1="P,Thorn" g2="T,uni0162,Tcaron,Tbar,uni021A" k="10" />
<hkern g1="P,Thorn" g2="V" k="-5" />
-<hkern g1="P,Thorn" g2="W" k="-5" />
+<hkern g1="P,Thorn" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-5" />
<hkern g1="P,Thorn" g2="X" k="25" />
<hkern g1="P,Thorn" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="145" />
-<hkern g1="P,Thorn" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="10" />
-<hkern g1="P,Thorn" g2="S" k="-17" />
-<hkern g1="P,Thorn" g2="Z" k="20" />
-<hkern g1="P,Thorn" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="15" />
-<hkern g1="P,Thorn" g2="AE" k="70" />
-<hkern g1="P,Thorn" g2="I,Igrave,Iacute,Icircumflex,Idieresis" k="20" />
-<hkern g1="R" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-10" />
-<hkern g1="R" g2="J" k="30" />
-<hkern g1="R" g2="T" k="25" />
-<hkern g1="R" g2="V" k="20" />
-<hkern g1="R" g2="W" k="20" />
-<hkern g1="R" g2="Y,Yacute,Ydieresis" k="20" />
-<hkern g1="R" g2="z" k="-15" />
-<hkern g1="R" g2="AE" k="45" />
-<hkern g1="S" g2="J" k="35" />
-<hkern g1="S" g2="T" k="20" />
-<hkern g1="S" g2="V" k="15" />
-<hkern g1="S" g2="W" k="15" />
-<hkern g1="S" g2="X" k="10" />
-<hkern g1="S" g2="Y,Yacute,Ydieresis" k="30" />
-<hkern g1="T" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="80" />
-<hkern g1="T" g2="J" k="70" />
-<hkern g1="T" g2="X" k="10" />
-<hkern g1="T" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="120" />
-<hkern g1="T" g2="colon,semicolon" k="85" />
-<hkern g1="T" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="33" />
-<hkern g1="T" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="100" />
-<hkern g1="T" g2="t" k="55" />
-<hkern g1="T" g2="z" k="76" />
-<hkern g1="T" g2="copyright,registered" k="50" />
-<hkern g1="T" g2="trademark" k="-25" />
-<hkern g1="T" g2="quoteleft,quotedblleft" k="-35" />
-<hkern g1="T" g2="quoteright,quotedblright" k="-35" />
-<hkern g1="T" g2="S" k="20" />
-<hkern g1="T" g2="i,j,igrave,iacute,icircumflex,idieresis" k="20" />
-<hkern g1="T" g2="m,n,p,r,ntilde" k="90" />
-<hkern g1="T" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="100" />
-<hkern g1="T" g2="s" k="127" />
-<hkern g1="T" g2="u,ugrave,uacute,ucircumflex,udieresis" k="85" />
-<hkern g1="T" g2="v" k="120" />
-<hkern g1="T" g2="w" k="120" />
-<hkern g1="T" g2="x" k="100" />
-<hkern g1="T" g2="y,yacute,ydieresis" k="70" />
-<hkern g1="T" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="40" />
-<hkern g1="T" g2="AE" k="90" />
-<hkern g1="T" g2="hyphen,endash,emdash" k="50" />
-<hkern g1="T" g2="guillemotleft,guilsinglleft" k="70" />
-<hkern g1="T" g2="guillemotright,guilsinglright" k="75" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="20" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="J" k="25" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="X" k="5" />
-<hkern g1="W" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="30" />
-<hkern g1="W" g2="J" k="70" />
-<hkern g1="W" g2="X" k="10" />
-<hkern g1="W" g2="Y,Yacute,Ydieresis" k="20" />
-<hkern g1="W" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
-<hkern g1="W" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="25" />
-<hkern g1="W" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="30" />
-<hkern g1="W" g2="t" k="18" />
-<hkern g1="W" g2="z" k="20" />
-<hkern g1="W" g2="copyright,registered" k="30" />
-<hkern g1="W" g2="S" k="5" />
-<hkern g1="W" g2="m,n,p,r,ntilde" k="30" />
-<hkern g1="W" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="30" />
-<hkern g1="W" g2="s" k="30" />
-<hkern g1="W" g2="u,ugrave,uacute,ucircumflex,udieresis" k="30" />
-<hkern g1="W" g2="x" k="15" />
-<hkern g1="W" g2="y,yacute,ydieresis" k="10" />
-<hkern g1="W" g2="b,h,k,l,germandbls,thorn" k="15" />
-<hkern g1="W" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="10" />
-<hkern g1="W" g2="AE" k="50" />
-<hkern g1="X" g2="T" k="10" />
+<hkern g1="P,Thorn" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="10" />
+<hkern g1="P,Thorn" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-17" />
+<hkern g1="P,Thorn" g2="Z,Zacute,Zdotaccent,Zcaron" k="20" />
+<hkern g1="P,Thorn" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="15" />
+<hkern g1="P,Thorn" g2="AE,AEacute" k="70" />
+<hkern g1="P,Thorn" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="-10" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="J,Jcircumflex" k="30" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="T,uni0162,Tcaron,Tbar,uni021A" k="25" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="V" k="20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="z,zacute,zdotaccent,zcaron" k="-15" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="AE,AEacute" k="45" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="J,Jcircumflex" k="35" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="T,uni0162,Tcaron,Tbar,uni021A" k="20" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="V" k="15" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="15" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="X" k="10" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="30" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="80" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="J,Jcircumflex" k="70" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="X" k="10" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="120" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="colon,semicolon" k="85" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="33" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="100" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="t,uni0163,tcaron,tbar,uni021B" k="55" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="z,zacute,zdotaccent,zcaron" k="76" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="copyright,registered" k="50" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="trademark" k="-25" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="quoteleft,quotedblleft" k="-35" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="quoteright,quotedblright" k="-35" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="20" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="20" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="90" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="100" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="127" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="85" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="v" k="120" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="120" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="x" k="100" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="70" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="40" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="AE,AEacute" k="90" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="hyphen,endash,emdash,afii00208" k="50" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="guillemotleft,guilsinglleft" k="70" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="guillemotright,guilsinglright" k="75" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="20" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="J,Jcircumflex" k="25" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="X" k="5" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="J,Jcircumflex" k="70" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="X" k="10" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="25" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="t,uni0163,tcaron,tbar,uni021B" k="18" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="z,zacute,zdotaccent,zcaron" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="copyright,registered" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="5" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="x" k="15" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="15" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="10" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="AE,AEacute" k="50" />
+<hkern g1="X" g2="T,uni0162,Tcaron,Tbar,uni021A" k="10" />
<hkern g1="X" g2="V" k="10" />
-<hkern g1="X" g2="W" k="10" />
-<hkern g1="X" g2="Y,Yacute,Ydieresis" k="20" />
-<hkern g1="X" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="20" />
-<hkern g1="X" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="5" />
+<hkern g1="X" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="10" />
+<hkern g1="X" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
+<hkern g1="X" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="20" />
+<hkern g1="X" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="5" />
<hkern g1="X" g2="copyright,registered" k="15" />
-<hkern g1="X" g2="S" k="10" />
-<hkern g1="X" g2="m,n,p,r,ntilde" k="15" />
-<hkern g1="X" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="30" />
-<hkern g1="X" g2="u,ugrave,uacute,ucircumflex,udieresis" k="40" />
+<hkern g1="X" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="10" />
+<hkern g1="X" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="15" />
+<hkern g1="X" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="30" />
+<hkern g1="X" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="40" />
<hkern g1="X" g2="v" k="20" />
-<hkern g1="X" g2="w" k="20" />
-<hkern g1="X" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="8" />
+<hkern g1="X" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
+<hkern g1="X" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="8" />
<hkern g1="X" g2="guillemotleft,guilsinglleft" k="45" />
<hkern g1="X" g2="guillemotright,guilsinglright" k="-30" />
-<hkern g1="Y,Yacute,Ydieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="70" />
-<hkern g1="Y,Yacute,Ydieresis" g2="J" k="90" />
-<hkern g1="Y,Yacute,Ydieresis" g2="V" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="W" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="X" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
-<hkern g1="Y,Yacute,Ydieresis" g2="colon,semicolon" k="35" />
-<hkern g1="Y,Yacute,Ydieresis" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="30" />
-<hkern g1="Y,Yacute,Ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="60" />
-<hkern g1="Y,Yacute,Ydieresis" g2="t" k="15" />
-<hkern g1="Y,Yacute,Ydieresis" g2="z" k="50" />
-<hkern g1="Y,Yacute,Ydieresis" g2="copyright,registered" k="40" />
-<hkern g1="Y,Yacute,Ydieresis" g2="S" k="30" />
-<hkern g1="Y,Yacute,Ydieresis" g2="Z" k="10" />
-<hkern g1="Y,Yacute,Ydieresis" g2="i,j,igrave,iacute,icircumflex,idieresis" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="m,n,p,r,ntilde" k="65" />
-<hkern g1="Y,Yacute,Ydieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="70" />
-<hkern g1="Y,Yacute,Ydieresis" g2="s" k="60" />
-<hkern g1="Y,Yacute,Ydieresis" g2="u,ugrave,uacute,ucircumflex,udieresis" k="50" />
-<hkern g1="Y,Yacute,Ydieresis" g2="v" k="70" />
-<hkern g1="Y,Yacute,Ydieresis" g2="w" k="70" />
-<hkern g1="Y,Yacute,Ydieresis" g2="x" k="40" />
-<hkern g1="Y,Yacute,Ydieresis" g2="b,h,k,l,germandbls,thorn" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="10" />
-<hkern g1="Y,Yacute,Ydieresis" g2="AE" k="48" />
-<hkern g1="Y,Yacute,Ydieresis" g2="guillemotleft,guilsinglleft" k="50" />
-<hkern g1="Z" g2="Y,Yacute,Ydieresis" k="15" />
-<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="t" k="10" />
-<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="v" k="23" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="25" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="quoteleft,quotedblleft" k="45" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="quoteright,quotedblright" k="45" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="v" k="10" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="x" k="8" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="y,yacute,ydieresis" k="5" />
-<hkern g1="h,m,n,ntilde" g2="v" k="13" />
-<hkern g1="h,m,n,ntilde" g2="w" k="13" />
-<hkern g1="f" g2="quotedbl,quotesingle" k="-45" />
-<hkern g1="f" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="35" />
-<hkern g1="f" g2="trademark" k="-65" />
-<hkern g1="f" g2="quoteleft,quotedblleft" k="-50" />
-<hkern g1="f" g2="quoteright,quotedblright" k="-45" />
-<hkern g1="f" g2="parenright,bracketright,braceright" k="-65" />
-<hkern g1="k" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="15" />
-<hkern g1="k" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="k" g2="s" k="10" />
-<hkern g1="k" g2="v" k="25" />
-<hkern g1="k" g2="w" k="-5" />
-<hkern g1="k" g2="guillemotright,guilsinglright" k="-30" />
-<hkern g1="d,l,uniFB02,uniFB04" g2="t" k="15" />
-<hkern g1="r" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="130" />
-<hkern g1="r" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="10" />
-<hkern g1="r" g2="quoteleft,quotedblleft" k="-50" />
-<hkern g1="r" g2="quoteright,quotedblright" k="-50" />
-<hkern g1="r" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="35" />
-<hkern g1="r" g2="s" k="25" />
-<hkern g1="r" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="-10" />
-<hkern g1="r" g2="guillemotright,guilsinglright" k="-50" />
-<hkern g1="s" g2="t" k="10" />
-<hkern g1="s" g2="v" k="20" />
-<hkern g1="s" g2="w" k="20" />
-<hkern g1="s" g2="x" k="10" />
-<hkern g1="t" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="-10" />
-<hkern g1="t" g2="t" k="15" />
-<hkern g1="t" g2="z" k="-15" />
-<hkern g1="t" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="10" />
-<hkern g1="t" g2="u,ugrave,uacute,ucircumflex,udieresis" k="20" />
-<hkern g1="t" g2="v" k="20" />
-<hkern g1="t" g2="w" k="20" />
-<hkern g1="t" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="28" />
-<hkern g1="w" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="30" />
-<hkern g1="w" g2="s" k="10" />
-<hkern g1="w" g2="y,yacute,ydieresis" k="5" />
-<hkern g1="x" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="8" />
-<hkern g1="y,yacute,ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="55" />
-<hkern g1="y,yacute,ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="8" />
-<hkern g1="y,yacute,ydieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="y,yacute,ydieresis" g2="s" k="15" />
-<hkern g1="y,yacute,ydieresis" g2="v" k="10" />
-<hkern g1="y,yacute,ydieresis" g2="w" k="10" />
-<hkern g1="y,yacute,ydieresis" g2="x" k="15" />
-<hkern g1="y,yacute,ydieresis" g2="parenright,bracketright,braceright" k="30" />
-<hkern g1="z" g2="z" k="-7" />
-<hkern g1="colon,semicolon" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-20" />
-<hkern g1="colon,semicolon" g2="J" k="-20" />
-<hkern g1="colon,semicolon" g2="T" k="85" />
-<hkern g1="colon,semicolon" g2="Y,Yacute,Ydieresis" k="35" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-20" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="J" k="-20" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="T" k="120" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="70" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="J,Jcircumflex" k="90" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="V" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="X" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="colon,semicolon" k="35" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="30" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="60" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="t,uni0163,tcaron,tbar,uni021B" k="15" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="z,zacute,zdotaccent,zcaron" k="50" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="copyright,registered" k="40" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="30" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="Z,Zacute,Zdotaccent,Zcaron" k="10" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="65" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="70" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="60" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="50" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="v" k="70" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="70" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="x" k="40" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="10" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="AE,AEacute" k="48" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="guillemotleft,guilsinglleft" k="50" />
+<hkern g1="Z,Zacute,Zdotaccent,Zcaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="15" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring,amacron,abreve,aogonek,acaron,aringacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="10" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring,amacron,abreve,aogonek,acaron,aringacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" g2="v" k="23" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="25" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="quoteleft,quotedblleft" k="45" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="quoteright,quotedblright" k="45" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="v" k="10" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="x" k="8" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="5" />
+<hkern g1="h,m,n,ntilde,hcircumflex,hbar,nacute,ncommaaccent,ncaron,napostrophe,eng" g2="v" k="13" />
+<hkern g1="h,m,n,ntilde,hcircumflex,hbar,nacute,ncommaaccent,ncaron,napostrophe,eng" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="13" />
+<hkern g1="f,f_f" g2="quotedbl,quotesingle" k="-45" />
+<hkern g1="f,f_f" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="35" />
+<hkern g1="f,f_f" g2="trademark" k="-65" />
+<hkern g1="f,f_f" g2="quoteleft,quotedblleft" k="-50" />
+<hkern g1="f,f_f" g2="quoteright,quotedblright" k="-45" />
+<hkern g1="f,f_f" g2="parenright,bracketright,braceright" k="-65" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="15" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="10" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="v" k="25" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="-5" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="guillemotright,guilsinglright" k="-30" />
+<hkern g1="d,l,dcroat,lacute,lcommaaccent,lslash,f_l,fl,f_f_l" g2="t,uni0163,tcaron,tbar,uni021B" k="15" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="130" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="10" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="quoteleft,quotedblleft" k="-50" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="quoteright,quotedblright" k="-50" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="35" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="25" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-10" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="guillemotright,guilsinglright" k="-50" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="t,uni0163,tcaron,tbar,uni021B" k="10" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="v" k="20" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="x" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="-10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="t,uni0163,tcaron,tbar,uni021B" k="15" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="z,zacute,zdotaccent,zcaron" k="-15" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="v" k="20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="28" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="30" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="10" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="5" />
+<hkern g1="x" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="8" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="55" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="8" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="15" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="v" k="10" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="10" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="x" k="15" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="parenright,bracketright,braceright" k="30" />
+<hkern g1="z,zacute,zdotaccent,zcaron" g2="z,zacute,zdotaccent,zcaron" k="-7" />
+<hkern g1="colon,semicolon" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="-20" />
+<hkern g1="colon,semicolon" g2="J,Jcircumflex" k="-20" />
+<hkern g1="colon,semicolon" g2="T,uni0162,Tcaron,Tbar,uni021A" k="85" />
+<hkern g1="colon,semicolon" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="35" />
+<hkern g1="colon,semicolon" g2="uni0410" k="-20" />
+<hkern g1="colon,semicolon" g2="uni0409,uni041B" k="-20" />
+<hkern g1="colon,semicolon" g2="uni0422" k="85" />
+<hkern g1="colon,semicolon" g2="uni0408" k="-20" />
+<hkern g1="colon,semicolon" g2="uni0402,uni040B,uni042A" k="50" />
+<hkern g1="colon,semicolon" g2="uni043B,uni0459" k="-20" />
+<hkern g1="colon,semicolon" g2="Alpha,uni0394,Lambda,Delta" k="-20" />
+<hkern g1="colon,semicolon" g2="Tau" k="85" />
+<hkern g1="colon,semicolon" g2="Upsilon,Upsilondieresis" k="35" />
+<hkern g1="colon,semicolon" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-85" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="J,Jcircumflex" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="T,uni0162,Tcaron,Tbar,uni021A" k="120" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="V" k="70" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="W" k="70" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Y,Yacute,Ydieresis" k="70" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="70" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="70" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="quoteleft,quotedblleft" k="93" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="quoteright,quotedblright" k="63" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="25" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="25" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="v" k="30" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="w" k="30" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="AE" k="-30" />
-<hkern g1="guillemotleft,guilsinglleft" g2="T" k="75" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="30" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="AE,AEacute" k="-30" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0410" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0409,uni041B" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0422" k="120" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0408" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0402,uni040B,uni042A" k="60" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni043B,uni0459" k="-5" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Alpha,uni0394,Lambda,Delta" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Tau" k="120" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Upsilon,Upsilondieresis" k="70" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="pi" k="80" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0427" k="115" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0442" k="75" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0447" k="50" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni044A" k="30" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Psi" k="85" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="gamma,nu" k="55" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="theta" k="45" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="25" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="tau" k="80" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="chi" k="45" />
+<hkern g1="guillemotleft,guilsinglleft" g2="T,uni0162,Tcaron,Tbar,uni021A" k="75" />
<hkern g1="guillemotleft,guilsinglleft" g2="X" k="-30" />
-<hkern g1="guillemotright,guilsinglright" g2="T" k="70" />
+<hkern g1="guillemotleft,guilsinglleft" g2="uni0422" k="55" />
+<hkern g1="guillemotleft,guilsinglleft" g2="uni0402,uni040B,uni042A" k="45" />
+<hkern g1="guillemotleft,guilsinglleft" g2="Tau" k="75" />
+<hkern g1="guillemotleft,guilsinglleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-130" />
+<hkern g1="guillemotright,guilsinglright" g2="T,uni0162,Tcaron,Tbar,uni021A" k="70" />
<hkern g1="guillemotright,guilsinglright" g2="X" k="45" />
-<hkern g1="guillemotright,guilsinglright" g2="Y,Yacute,Ydieresis" k="50" />
-<hkern g1="hyphen,endash,emdash" g2="T" k="50" />
-<hkern g1="parenleft,bracketleft,braceleft" g2="y,yacute,ydieresis" k="-30" />
-<hkern g1="quoteleft,quotedblleft" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="90" />
-<hkern g1="quoteleft,quotedblleft" g2="J" k="83" />
-<hkern g1="quoteleft,quotedblleft" g2="T" k="-35" />
-<hkern g1="quoteleft,quotedblleft" g2="t" k="-45" />
+<hkern g1="guillemotright,guilsinglright" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="50" />
+<hkern g1="guillemotright,guilsinglright" g2="uni0422" k="65" />
+<hkern g1="guillemotright,guilsinglright" g2="uni0402,uni040B,uni042A" k="45" />
+<hkern g1="guillemotright,guilsinglright" g2="Tau" k="70" />
+<hkern g1="guillemotright,guilsinglright" g2="Upsilon,Upsilondieresis" k="50" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="T,uni0162,Tcaron,Tbar,uni021A" k="50" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="uni0422" k="50" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="Tau" k="50" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="pi" k="30" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="tau" k="30" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="xi" k="-20" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-30" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-40" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="uni0443,uni045E" k="-30" />
+<hkern g1="parenright,bracketright,braceright" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-90" />
+<hkern g1="quoteleft,quotedblleft" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="90" />
+<hkern g1="quoteleft,quotedblleft" g2="J,Jcircumflex" k="83" />
+<hkern g1="quoteleft,quotedblleft" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-35" />
+<hkern g1="quoteleft,quotedblleft" g2="t,uni0163,tcaron,tbar,uni021B" k="-45" />
<hkern g1="quoteleft,quotedblleft" g2="quoteleft,quotedblleft" k="63" />
-<hkern g1="quoteleft,quotedblleft" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="45" />
-<hkern g1="quoteleft,quotedblleft" g2="AE" k="83" />
-<hkern g1="quoteright,quotedblright" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="90" />
-<hkern g1="quoteright,quotedblright" g2="J" k="81" />
-<hkern g1="quoteright,quotedblright" g2="T" k="-35" />
+<hkern g1="quoteleft,quotedblleft" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="45" />
+<hkern g1="quoteleft,quotedblleft" g2="AE,AEacute" k="83" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0410" k="90" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0409,uni041B" k="120" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0408" k="81" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0402,uni040B,uni042A" k="-20" />
+<hkern g1="quoteleft,quotedblleft" g2="uni043B,uni0459" k="65" />
+<hkern g1="quoteleft,quotedblleft" g2="Alpha,uni0394,Lambda,Delta" k="90" />
+<hkern g1="quoteleft,quotedblleft" g2="Tau" k="-35" />
+<hkern g1="quoteleft,quotedblleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-70" />
+<hkern g1="quoteleft,quotedblleft" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="45" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0414" k="120" />
+<hkern g1="quoteleft,quotedblleft" g2="rho" k="30" />
+<hkern g1="quoteleft,quotedblleft" g2="omega,omegatonos" k="60" />
+<hkern g1="quoteright,quotedblright" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="90" />
+<hkern g1="quoteright,quotedblright" g2="J,Jcircumflex" k="81" />
+<hkern g1="quoteright,quotedblright" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-35" />
<hkern g1="quoteright,quotedblright" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="78" />
<hkern g1="quoteright,quotedblright" g2="quoteright,quotedblright" k="63" />
-<hkern g1="quoteright,quotedblright" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="45" />
-<hkern g1="quoteright,quotedblright" g2="AE" k="83" />
-<hkern g1="quotedbl,quotesingle" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="60" />
-<hkern g1="quotedbl,quotesingle" g2="J" k="95" />
-<hkern g1="V" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="48" />
-<hkern g1="V" g2="J" k="70" />
+<hkern g1="quoteright,quotedblright" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="45" />
+<hkern g1="quoteright,quotedblright" g2="AE,AEacute" k="83" />
+<hkern g1="quoteright,quotedblright" g2="uni0410" k="90" />
+<hkern g1="quoteright,quotedblright" g2="uni0409,uni041B" k="115" />
+<hkern g1="quoteright,quotedblright" g2="uni0408" k="81" />
+<hkern g1="quoteright,quotedblright" g2="uni0402,uni040B,uni042A" k="-20" />
+<hkern g1="quoteright,quotedblright" g2="uni043B,uni0459" k="80" />
+<hkern g1="quoteright,quotedblright" g2="Alpha,uni0394,Lambda,Delta" k="90" />
+<hkern g1="quoteright,quotedblright" g2="Tau" k="-35" />
+<hkern g1="quoteright,quotedblright" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-70" />
+<hkern g1="quoteright,quotedblright" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="45" />
+<hkern g1="quoteright,quotedblright" g2="uni0414" k="135" />
+<hkern g1="quoteright,quotedblright" g2="rho" k="30" />
+<hkern g1="quoteright,quotedblright" g2="omega,omegatonos" k="60" />
+<hkern g1="quotedbl,quotesingle" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="60" />
+<hkern g1="quotedbl,quotesingle" g2="J,Jcircumflex" k="95" />
+<hkern g1="dcaron,lcaron" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="40" />
+<hkern g1="dcaron,lcaron" g2="quoteleft,quotedblleft" k="-40" />
+<hkern g1="dcaron,lcaron" g2="quoteright,quotedblright" k="-30" />
+<hkern g1="dcaron,lcaron" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="60" />
+<hkern g1="dcaron,lcaron" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="40" />
+<hkern g1="dcaron,lcaron" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="25" />
+<hkern g1="dcaron,lcaron" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="40" />
+<hkern g1="dcaron,lcaron" g2="parenright,bracketright,braceright" k="-35" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="colon,semicolon" k="-20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="quoteleft,quotedblleft" k="90" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="quoteright,quotedblright" k="90" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Tau" k="80" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Upsilon,Upsilondieresis" k="70" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="pi" k="38" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Psi" k="40" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="gamma,nu" k="25" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="theta" k="10" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="tau" k="40" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Theta,Omicron,Phi" k="25" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="20" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Alpha,uni0394,Lambda,Delta" k="25" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Tau" k="33" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Upsilon,Upsilondieresis" k="30" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Chi" k="20" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="lambda" k="5" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="colon,semicolon" k="35" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="guillemotleft,guilsinglleft" k="50" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Alpha,uni0394,Lambda,Delta" k="70" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="pi" k="38" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="70" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="tau" k="50" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Theta,Omicron,Phi" k="30" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Chi" k="20" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Zeta" k="10" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="mu,etatonos,eta,uni03BC" k="65" />
+<hkern g1="Iotatonos,Iota,Iotadieresis" g2="tau" k="10" />
+<hkern g1="Omegatonos,uni03A9,Omega" g2="Tau" k="35" />
+<hkern g1="Omegatonos,uni03A9,Omega" g2="Chi" k="40" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="pi" k="38" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="gamma,nu" k="40" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="tau" k="35" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="chi" k="15" />
+<hkern g1="Beta" g2="Tau" k="35" />
+<hkern g1="Beta" g2="Upsilon,Upsilondieresis" k="25" />
+<hkern g1="Beta" g2="pi" k="15" />
+<hkern g1="Beta" g2="gamma,nu" k="25" />
+<hkern g1="Beta" g2="tau" k="15" />
+<hkern g1="Beta" g2="lambda" k="20" />
+<hkern g1="Gamma" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="140" />
+<hkern g1="Gamma" g2="colon,semicolon" k="105" />
+<hkern g1="Gamma" g2="quoteleft,quotedblleft" k="-5" />
+<hkern g1="Gamma" g2="quoteright,quotedblright" k="-5" />
+<hkern g1="Gamma" g2="hyphen,endash,emdash,afii00208" k="168" />
+<hkern g1="Gamma" g2="guillemotleft,guilsinglleft" k="90" />
+<hkern g1="Gamma" g2="guillemotright,guilsinglright" k="100" />
+<hkern g1="Gamma" g2="Alpha,uni0394,Lambda,Delta" k="75" />
+<hkern g1="Gamma" g2="pi" k="103" />
+<hkern g1="Gamma" g2="gamma,nu" k="93" />
+<hkern g1="Gamma" g2="theta" k="25" />
+<hkern g1="Gamma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="158" />
+<hkern g1="Gamma" g2="tau" k="128" />
+<hkern g1="Gamma" g2="chi" k="108" />
+<hkern g1="Gamma" g2="rho" k="145" />
+<hkern g1="Gamma" g2="omega,omegatonos" k="125" />
+<hkern g1="Gamma" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="157" />
+<hkern g1="Gamma" g2="lambda" k="35" />
+<hkern g1="Gamma" g2="mu,etatonos,eta,uni03BC" k="158" />
+<hkern g1="Gamma" g2="uni03A9,Omega" k="35" />
+<hkern g1="Gamma" g2="beta" k="15" />
+<hkern g1="Gamma" g2="epsilontonos,epsilon" k="183" />
+<hkern g1="Gamma" g2="zeta" k="50" />
+<hkern g1="Gamma" g2="kappa" k="158" />
+<hkern g1="Gamma" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="130" />
+<hkern g1="Zeta" g2="Upsilon,Upsilondieresis" k="15" />
+<hkern g1="Zeta" g2="pi" k="38" />
+<hkern g1="Zeta" g2="gamma,nu" k="35" />
+<hkern g1="Zeta" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="35" />
+<hkern g1="Zeta" g2="tau" k="58" />
+<hkern g1="Zeta" g2="chi" k="15" />
+<hkern g1="Zeta" g2="rho" k="15" />
+<hkern g1="Zeta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="50" />
+<hkern g1="Zeta" g2="beta" k="30" />
+<hkern g1="Kappa" g2="Alpha,uni0394,Lambda,Delta" k="20" />
+<hkern g1="Kappa" g2="Tau" k="38" />
+<hkern g1="Kappa" g2="Upsilon,Upsilondieresis" k="40" />
+<hkern g1="Kappa" g2="pi" k="73" />
+<hkern g1="Kappa" g2="Psi" k="38" />
+<hkern g1="Kappa" g2="gamma,nu" k="55" />
+<hkern g1="Kappa" g2="theta" k="45" />
+<hkern g1="Kappa" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="35" />
+<hkern g1="Kappa" g2="tau" k="78" />
+<hkern g1="Kappa" g2="chi" k="45" />
+<hkern g1="Kappa" g2="rho" k="35" />
+<hkern g1="Kappa" g2="omega,omegatonos" k="23" />
+<hkern g1="Kappa" g2="Theta,Omicron,Phi" k="35" />
+<hkern g1="Kappa" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="105" />
+<hkern g1="Kappa" g2="Chi" k="20" />
+<hkern g1="Kappa" g2="lambda" k="45" />
+<hkern g1="Kappa" g2="mu,etatonos,eta,uni03BC" k="20" />
+<hkern g1="Kappa" g2="uni03A9,Omega" k="35" />
+<hkern g1="Kappa" g2="beta" k="30" />
+<hkern g1="Kappa" g2="epsilontonos,epsilon" k="45" />
+<hkern g1="Kappa" g2="zeta" k="35" />
+<hkern g1="Kappa" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="38" />
+<hkern g1="Rho" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="145" />
+<hkern g1="Rho" g2="Alpha,uni0394,Lambda,Delta" k="50" />
+<hkern g1="Rho" g2="Tau" k="10" />
+<hkern g1="Rho" g2="pi" k="3" />
+<hkern g1="Rho" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="15" />
+<hkern g1="Rho" g2="tau" k="8" />
+<hkern g1="Rho" g2="Chi" k="25" />
+<hkern g1="Rho" g2="Zeta" k="20" />
+<hkern g1="Rho" g2="Iota,Iotadieresis" k="20" />
+<hkern g1="Sigma" g2="pi" k="50" />
+<hkern g1="Sigma" g2="gamma,nu" k="25" />
+<hkern g1="Sigma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="Sigma" g2="tau" k="50" />
+<hkern g1="Sigma" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="35" />
+<hkern g1="Tau" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="120" />
+<hkern g1="Tau" g2="colon,semicolon" k="85" />
+<hkern g1="Tau" g2="copyright,registered" k="75" />
+<hkern g1="Tau" g2="quoteleft,quotedblleft" k="-35" />
+<hkern g1="Tau" g2="quoteright,quotedblright" k="-35" />
+<hkern g1="Tau" g2="hyphen,endash,emdash,afii00208" k="35" />
+<hkern g1="Tau" g2="guillemotleft,guilsinglleft" k="70" />
+<hkern g1="Tau" g2="guillemotright,guilsinglright" k="75" />
+<hkern g1="Tau" g2="Alpha,uni0394,Lambda,Delta" k="80" />
+<hkern g1="Tau" g2="pi" k="125" />
+<hkern g1="Tau" g2="gamma,nu" k="95" />
+<hkern g1="Tau" g2="theta" k="40" />
+<hkern g1="Tau" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="100" />
+<hkern g1="Tau" g2="tau" k="125" />
+<hkern g1="Tau" g2="chi" k="108" />
+<hkern g1="Tau" g2="rho" k="78" />
+<hkern g1="Tau" g2="omega,omegatonos" k="70" />
+<hkern g1="Tau" g2="Theta,Omicron,Phi" k="33" />
+<hkern g1="Tau" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="100" />
+<hkern g1="Tau" g2="Chi" k="10" />
+<hkern g1="Tau" g2="lambda" k="40" />
+<hkern g1="Tau" g2="mu,etatonos,eta,uni03BC" k="90" />
+<hkern g1="Tau" g2="uni03A9,Omega" k="35" />
+<hkern g1="Tau" g2="beta" k="45" />
+<hkern g1="Tau" g2="epsilontonos,epsilon" k="108" />
+<hkern g1="Tau" g2="zeta" k="30" />
+<hkern g1="Tau" g2="kappa" k="93" />
+<hkern g1="Tau" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="98" />
+<hkern g1="Chi" g2="Tau" k="10" />
+<hkern g1="Chi" g2="Upsilon,Upsilondieresis" k="20" />
+<hkern g1="Chi" g2="pi" k="50" />
+<hkern g1="Chi" g2="gamma,nu" k="15" />
+<hkern g1="Chi" g2="theta" k="25" />
+<hkern g1="Chi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="30" />
+<hkern g1="Chi" g2="tau" k="73" />
+<hkern g1="Chi" g2="chi" k="10" />
+<hkern g1="Chi" g2="rho" k="20" />
+<hkern g1="Chi" g2="omega,omegatonos" k="20" />
+<hkern g1="Chi" g2="Theta,Omicron,Phi" k="20" />
+<hkern g1="Chi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="50" />
+<hkern g1="Chi" g2="mu,etatonos,eta,uni03BC" k="15" />
+<hkern g1="Chi" g2="uni03A9,Omega" k="40" />
+<hkern g1="Chi" g2="beta" k="5" />
+<hkern g1="Chi" g2="zeta" k="25" />
+<hkern g1="Chi" g2="kappa" k="23" />
+<hkern g1="Chi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="45" />
+<hkern g1="Psi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="85" />
+<hkern g1="Psi" g2="Alpha,uni0394,Lambda,Delta" k="40" />
+<hkern g1="Psi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="15" />
+<hkern g1="Psi" g2="lambda" k="10" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="pi" k="5" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="gamma,nu" k="20" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="theta" k="3" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="23" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="tau" k="3" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="chi" k="15" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="xi" k="13" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="epsilontonos,epsilon" k="15" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="zeta" k="10" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="25" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="quoteleft,quotedblleft" k="45" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="quoteright,quotedblright" k="45" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="pi" k="-7" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="gamma,nu" k="25" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="tau" k="20" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="chi" k="35" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="xi" k="10" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="lambda" k="5" />
+<hkern g1="omega,omegatonos" g2="quoteleft,quotedblleft" k="45" />
+<hkern g1="omega,omegatonos" g2="quoteright,quotedblright" k="60" />
+<hkern g1="omega,omegatonos" g2="pi" k="10" />
+<hkern g1="omega,omegatonos" g2="tau" k="25" />
+<hkern g1="omega,omegatonos" g2="chi" k="15" />
+<hkern g1="epsilontonos,epsilon" g2="pi" k="25" />
+<hkern g1="epsilontonos,epsilon" g2="gamma,nu" k="10" />
+<hkern g1="epsilontonos,epsilon" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="10" />
+<hkern g1="epsilontonos,epsilon" g2="chi" k="25" />
+<hkern g1="epsilontonos,epsilon" g2="xi" k="10" />
+<hkern g1="epsilontonos,epsilon" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="15" />
+<hkern g1="epsilontonos,epsilon" g2="lambda" k="10" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="pi" k="23" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="gamma,nu" k="15" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="tau" k="23" />
+<hkern g1="gamma,nu" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
+<hkern g1="gamma,nu" g2="tau" k="5" />
+<hkern g1="chi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="chi" g2="quoteleft,quotedblleft" k="50" />
+<hkern g1="chi" g2="quoteright,quotedblright" k="35" />
+<hkern g1="chi" g2="pi" k="-5" />
+<hkern g1="chi" g2="gamma,nu" k="10" />
+<hkern g1="chi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="25" />
+<hkern g1="chi" g2="tau" k="15" />
+<hkern g1="chi" g2="xi" k="25" />
+<hkern g1="chi" g2="omega,omegatonos" k="23" />
+<hkern g1="chi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="25" />
+<hkern g1="chi" g2="lambda" k="15" />
+<hkern g1="chi" g2="mu,etatonos,eta,uni03BC" k="5" />
+<hkern g1="chi" g2="epsilontonos,epsilon" k="15" />
+<hkern g1="chi" g2="zeta" k="10" />
+<hkern g1="chi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="18" />
+<hkern g1="zeta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="zeta" g2="hyphen,endash,emdash,afii00208" k="55" />
+<hkern g1="zeta" g2="pi" k="35" />
+<hkern g1="zeta" g2="gamma,nu" k="35" />
+<hkern g1="zeta" g2="theta" k="15" />
+<hkern g1="zeta" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="30" />
+<hkern g1="zeta" g2="tau" k="55" />
+<hkern g1="zeta" g2="omega,omegatonos" k="20" />
+<hkern g1="zeta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="35" />
+<hkern g1="zeta" g2="epsilontonos,epsilon" k="8" />
+<hkern g1="zeta" g2="kappa" k="15" />
+<hkern g1="zeta" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="20" />
+<hkern g1="theta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="45" />
+<hkern g1="theta" g2="gamma,nu" k="5" />
+<hkern g1="kappa" g2="hyphen,endash,emdash,afii00208" k="45" />
+<hkern g1="kappa" g2="pi" k="8" />
+<hkern g1="kappa" g2="gamma,nu" k="15" />
+<hkern g1="kappa" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="35" />
+<hkern g1="kappa" g2="tau" k="13" />
+<hkern g1="kappa" g2="chi" k="5" />
+<hkern g1="kappa" g2="omega,omegatonos" k="30" />
+<hkern g1="kappa" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="8" />
+<hkern g1="kappa" g2="epsilontonos,epsilon" k="15" />
+<hkern g1="kappa" g2="zeta" k="5" />
+<hkern g1="lambda" g2="quoteleft,quotedblleft" k="90" />
+<hkern g1="lambda" g2="quoteright,quotedblright" k="90" />
+<hkern g1="lambda" g2="pi" k="20" />
+<hkern g1="lambda" g2="gamma,nu" k="8" />
+<hkern g1="lambda" g2="theta" k="13" />
+<hkern g1="lambda" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="13" />
+<hkern g1="lambda" g2="tau" k="53" />
+<hkern g1="lambda" g2="chi" k="20" />
+<hkern g1="lambda" g2="xi" k="10" />
+<hkern g1="lambda" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="38" />
+<hkern g1="lambda" g2="zeta" k="20" />
+<hkern g1="xi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-22" />
+<hkern g1="xi" g2="hyphen,endash,emdash,afii00208" k="30" />
+<hkern g1="xi" g2="pi" k="10" />
+<hkern g1="xi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="25" />
+<hkern g1="xi" g2="tau" k="10" />
+<hkern g1="xi" g2="omega,omegatonos" k="10" />
+<hkern g1="xi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="28" />
+<hkern g1="xi" g2="epsilontonos,epsilon" k="10" />
+<hkern g1="sigma" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="60" />
+<hkern g1="sigma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="10" />
+<hkern g1="sigma" g2="xi" k="33" />
+<hkern g1="sigma" g2="omega,omegatonos" k="25" />
+<hkern g1="sigma" g2="lambda" k="20" />
+<hkern g1="sigma" g2="kappa" k="20" />
+<hkern g1="sigma1" g2="pi" k="-30" />
+<hkern g1="sigma1" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="5" />
+<hkern g1="sigma1" g2="tau" k="-15" />
+<hkern g1="sigma1" g2="omega,omegatonos" k="5" />
+<hkern g1="sigma1" g2="lambda" k="23" />
+<hkern g1="tau" g2="hyphen,endash,emdash,afii00208" k="45" />
+<hkern g1="tau" g2="pi" k="-15" />
+<hkern g1="tau" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="18" />
+<hkern g1="tau" g2="tau" k="-15" />
+<hkern g1="tau" g2="xi" k="8" />
+<hkern g1="tau" g2="omega,omegatonos" k="25" />
+<hkern g1="tau" g2="lambda" k="20" />
+<hkern g1="tau" g2="epsilontonos,epsilon" k="20" />
+<hkern g1="tau" g2="zeta" k="10" />
+<hkern g1="tau" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="5" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0410" k="20" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0422" k="38" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0408" k="20" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0442" k="10" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0443,uni045E" k="33" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0404,uni041E,uni0421,uni0424" k="20" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0425" k="20" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0405" k="45" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0430" k="30" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="35" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0455" k="30" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="quoteleft,quotedblleft" k="35" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="quoteright,quotedblright" k="15" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="hyphen,endash,emdash,afii00208" k="-60" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0422" k="60" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0402,uni040B,uni042A" k="50" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0417,uni042D" k="-22" />
+<hkern g1="uni0411,uni0412,uni0417" g2="uni0422" k="35" />
+<hkern g1="uni0411,uni0412,uni0417" g2="uni0408" k="30" />
+<hkern g1="uni0403,uni0413,uni0490" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="230" />
+<hkern g1="uni0403,uni0413,uni0490" g2="colon,semicolon" k="100" />
+<hkern g1="uni0403,uni0413,uni0490" g2="hyphen,endash,emdash,afii00208" k="130" />
+<hkern g1="uni0403,uni0413,uni0490" g2="guillemotleft,guilsinglleft" k="80" />
+<hkern g1="uni0403,uni0413,uni0490" g2="guillemotright,guilsinglright" k="100" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0410" k="75" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0409,uni041B" k="43" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0408" k="83" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0402,uni040B,uni042A" k="-10" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni043B,uni0459" k="138" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0442" k="150" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0447" k="118" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni044A" k="135" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0443,uni045E" k="150" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0414" k="50" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0404,uni041E,uni0421,uni0424" k="50" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0405" k="23" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0430" k="130" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="158" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0455" k="160" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0417,uni042D" k="8" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni042F" k="10" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0431" k="25" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0434" k="157" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0436" k="165" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0437,uni044D" k="120" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="158" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0445" k="175" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni044F" k="163" />
+<hkern g1="uni0400,uni0401,uni0415" g2="uni0409,uni041B" k="13" />
+<hkern g1="uni0400,uni0401,uni0415" g2="uni040E,uni0423" k="-22" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0410" k="25" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0409,uni041B" k="18" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0422" k="33" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0408" k="30" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0425" k="20" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0416" k="30" />
+<hkern g1="uni0414,uni0426,uni0429" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-35" />
+<hkern g1="uni0414,uni0426,uni0429" g2="colon,semicolon" k="-35" />
+<hkern g1="uni0414,uni0426,uni0429" g2="guillemotright,guilsinglright" k="-35" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0410" k="-37" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0409,uni041B" k="-30" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0408" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni043B,uni0459" k="-40" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0427" k="-15" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0443,uni045E" k="-15" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0414" k="-45" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0425" k="-15" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0417,uni042D" k="-22" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni042F" k="-27" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0434" k="-35" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0436" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0437,uni044D" k="-30" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni040E,uni0423" k="-37" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0416" k="-15" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0400,uni0401,uni0403,uni040A,uni040C,uni040D,uni040F,uni0411,uni0412,uni0413,uni0415,uni0418,uni0419,uni041A,uni041C,uni041D,uni041F,uni0420,uni0426,uni0428,uni0429,uni042B,uni042C,uni042E,uni0490" k="-15" />
+<hkern g1="uni0404,uni0421" g2="uni0408" k="10" />
+<hkern g1="uni0404,uni0421" g2="uni0414" k="-15" />
+<hkern g1="uni0404,uni0421" g2="uni0425" k="15" />
+<hkern g1="uni040E,uni0423" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="58" />
+<hkern g1="uni040E,uni0423" g2="colon,semicolon" k="65" />
+<hkern g1="uni040E,uni0423" g2="uni0410" k="80" />
+<hkern g1="uni040E,uni0423" g2="uni0409,uni041B" k="90" />
+<hkern g1="uni040E,uni0423" g2="uni0408" k="90" />
+<hkern g1="uni040E,uni0423" g2="uni043B,uni0459" k="80" />
+<hkern g1="uni040E,uni0423" g2="uni0427" k="-30" />
+<hkern g1="uni040E,uni0423" g2="uni0442" k="30" />
+<hkern g1="uni040E,uni0423" g2="uni0447" k="5" />
+<hkern g1="uni040E,uni0423" g2="uni044A" k="40" />
+<hkern g1="uni040E,uni0423" g2="uni0414" k="50" />
+<hkern g1="uni040E,uni0423" g2="uni0404,uni041E,uni0421,uni0424" k="5" />
+<hkern g1="uni040E,uni0423" g2="uni0425" k="15" />
+<hkern g1="uni040E,uni0423" g2="uni0405" k="8" />
+<hkern g1="uni040E,uni0423" g2="uni0430" k="55" />
+<hkern g1="uni040E,uni0423" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="45" />
+<hkern g1="uni040E,uni0423" g2="uni0455" k="70" />
+<hkern g1="uni040E,uni0423" g2="uni0417,uni042D" k="15" />
+<hkern g1="uni040E,uni0423" g2="uni042F" k="25" />
+<hkern g1="uni040E,uni0423" g2="uni0434" k="65" />
+<hkern g1="uni040E,uni0423" g2="uni0436" k="30" />
+<hkern g1="uni040E,uni0423" g2="uni0437,uni044D" k="30" />
+<hkern g1="uni040E,uni0423" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="30" />
+<hkern g1="uni040E,uni0423" g2="uni0445" k="45" />
+<hkern g1="uni040E,uni0423" g2="uni044F" k="65" />
+<hkern g1="uni040E,uni0423" g2="uni0416" k="35" />
+<hkern g1="uni0410" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-30" />
+<hkern g1="uni0410" g2="colon,semicolon" k="-30" />
+<hkern g1="uni0410" g2="quoteleft,quotedblleft" k="90" />
+<hkern g1="uni0410" g2="quoteright,quotedblright" k="90" />
+<hkern g1="uni0410" g2="uni0422" k="80" />
+<hkern g1="uni0410" g2="uni0402,uni040B,uni042A" k="75" />
+<hkern g1="uni0410" g2="uni0447" k="10" />
+<hkern g1="uni0410" g2="uni044A" k="28" />
+<hkern g1="uni0410" g2="uni0404,uni041E,uni0421,uni0424" k="25" />
+<hkern g1="uni0410" g2="uni0430" k="15" />
+<hkern g1="uni0410" g2="uni0416" k="30" />
+<hkern g1="uni0420" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="145" />
+<hkern g1="uni0420" g2="uni0410" k="50" />
+<hkern g1="uni0420" g2="uni0409,uni041B" k="68" />
+<hkern g1="uni0420" g2="uni0422" k="10" />
+<hkern g1="uni0420" g2="uni0408" k="65" />
+<hkern g1="uni0420" g2="uni043B,uni0459" k="60" />
+<hkern g1="uni0420" g2="uni0427" k="-32" />
+<hkern g1="uni0420" g2="uni0447" k="-27" />
+<hkern g1="uni0420" g2="uni0414" k="55" />
+<hkern g1="uni0420" g2="uni0425" k="25" />
+<hkern g1="uni0420" g2="uni0405" k="-17" />
+<hkern g1="uni0420" g2="uni0430" k="10" />
+<hkern g1="uni0420" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="15" />
+<hkern g1="uni0420" g2="uni0434" k="90" />
+<hkern g1="uni0402,uni040B" g2="quoteleft,quotedblleft" k="95" />
+<hkern g1="uni0402,uni040B" g2="quoteright,quotedblright" k="95" />
+<hkern g1="uni0402,uni040B" g2="hyphen,endash,emdash,afii00208" k="-20" />
+<hkern g1="uni0402,uni040B" g2="parenright,bracketright,braceright" k="-10" />
+<hkern g1="uni0402,uni040B" g2="uni0422" k="75" />
+<hkern g1="uni0422" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="120" />
+<hkern g1="uni0422" g2="colon,semicolon" k="85" />
+<hkern g1="uni0422" g2="hyphen,endash,emdash,afii00208" k="50" />
+<hkern g1="uni0422" g2="guillemotleft,guilsinglleft" k="65" />
+<hkern g1="uni0422" g2="guillemotright,guilsinglright" k="55" />
+<hkern g1="uni0422" g2="uni0410" k="80" />
+<hkern g1="uni0422" g2="uni0409,uni041B" k="65" />
+<hkern g1="uni0422" g2="uni0408" k="70" />
+<hkern g1="uni0422" g2="uni043B,uni0459" k="113" />
+<hkern g1="uni0422" g2="uni0427" k="-22" />
+<hkern g1="uni0422" g2="uni0442" k="110" />
+<hkern g1="uni0422" g2="uni0447" k="95" />
+<hkern g1="uni0422" g2="uni044A" k="90" />
+<hkern g1="uni0422" g2="uni0443,uni045E" k="70" />
+<hkern g1="uni0422" g2="uni0414" k="55" />
+<hkern g1="uni0422" g2="uni0404,uni041E,uni0421,uni0424" k="33" />
+<hkern g1="uni0422" g2="uni0425" k="10" />
+<hkern g1="uni0422" g2="uni0405" k="20" />
+<hkern g1="uni0422" g2="uni0430" k="100" />
+<hkern g1="uni0422" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="100" />
+<hkern g1="uni0422" g2="uni0455" k="127" />
+<hkern g1="uni0422" g2="uni042F" k="25" />
+<hkern g1="uni0422" g2="uni0431" k="30" />
+<hkern g1="uni0422" g2="uni0434" k="128" />
+<hkern g1="uni0422" g2="uni0436" k="90" />
+<hkern g1="uni0422" g2="uni0437,uni044D" k="80" />
+<hkern g1="uni0422" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="90" />
+<hkern g1="uni0422" g2="uni0445" k="100" />
+<hkern g1="uni0422" g2="uni044F" k="90" />
+<hkern g1="uni0425" g2="uni0422" k="10" />
+<hkern g1="uni0425" g2="uni0404,uni041E,uni0421,uni0424" k="20" />
+<hkern g1="uni0425" g2="uni0405" k="10" />
+<hkern g1="uni0425" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="30" />
+<hkern g1="uni0425" g2="uni040E,uni0423" k="-15" />
+<hkern g1="uni0405" g2="uni0409,uni041B" k="13" />
+<hkern g1="uni0405" g2="uni0422" k="20" />
+<hkern g1="uni0405" g2="uni0408" k="35" />
+<hkern g1="uni0405" g2="uni0442" k="20" />
+<hkern g1="uni0405" g2="uni0425" k="10" />
+<hkern g1="uni0405" g2="uni0434" k="23" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0442" k="15" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0443,uni045E" k="5" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0434" k="20" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0436" k="5" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0445" k="8" />
+<hkern g1="uni0433,uni0453,uni0491" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="100" />
+<hkern g1="uni0433,uni0453,uni0491" g2="colon,semicolon" k="-20" />
+<hkern g1="uni0433,uni0453,uni0491" g2="quoteleft,quotedblleft" k="-15" />
+<hkern g1="uni0433,uni0453,uni0491" g2="quoteright,quotedblright" k="-20" />
+<hkern g1="uni0433,uni0453,uni0491" g2="hyphen,endash,emdash,afii00208" k="80" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni043B,uni0459" k="55" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0442" k="-15" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni044A" k="-27" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0430" k="5" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="5" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0434" k="55" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni044F" k="15" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0430" k="15" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="5" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0455" k="10" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0431" k="5" />
+<hkern g1="uni0434,uni0446,uni0449" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="uni0434,uni0446,uni0449" g2="colon,semicolon" k="-20" />
+<hkern g1="uni0434,uni0446,uni0449" g2="guillemotright,guilsinglright" k="-30" />
+<hkern g1="uni0434,uni0446,uni0449" g2="parenright,bracketright,braceright" k="-30" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni043B,uni0459" k="-30" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0443,uni045E" k="-17" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0431" k="-22" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0434" k="-35" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0436" k="-10" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0437,uni044D" k="-15" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="-15" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0445" k="-22" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni044F" k="-22" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni043B,uni0459" k="-22" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni0442" k="5" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni044A" k="15" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni0434" k="-15" />
+<hkern g1="uni0430" g2="uni0442" k="18" />
+<hkern g1="uni0430" g2="uni044A" k="5" />
+<hkern g1="uni0443,uni045E" g2="parenright,bracketright,braceright" k="30" />
+<hkern g1="uni0443,uni045E" g2="uni043B,uni0459" k="20" />
+<hkern g1="uni0443,uni045E" g2="uni0430" k="8" />
+<hkern g1="uni0443,uni045E" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="20" />
+<hkern g1="uni0443,uni045E" g2="uni0455" k="15" />
+<hkern g1="uni0443,uni045E" g2="uni0434" k="60" />
+<hkern g1="uni0443,uni045E" g2="uni0445" k="15" />
+<hkern g1="uni0443,uni045E" g2="uni044F" k="18" />
+<hkern g1="uni0442" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="75" />
+<hkern g1="uni0442" g2="uni043B,uni0459" k="50" />
+<hkern g1="uni0442" g2="uni0442" k="-20" />
+<hkern g1="uni0442" g2="uni0447" k="-15" />
+<hkern g1="uni0442" g2="uni044A" k="-20" />
+<hkern g1="uni0442" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="15" />
+<hkern g1="uni0442" g2="uni0434" k="60" />
+<hkern g1="uni0445" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="8" />
+<hkern g1="uni0455" g2="uni0445" k="10" />
+<hkern g1="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" g2="tau" k="15" />
+<hkern g1="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" g2="chi" k="5" />
+<hkern g1="uni0408" g2="uni0410" k="10" />
+<hkern g1="uni0408" g2="uni0409,uni041B" k="20" />
+<hkern g1="uni0408" g2="uni0408" k="30" />
+<hkern g1="uni0408" g2="uni043B,uni0459" k="15" />
+<hkern g1="uni0408" g2="uni0427" k="-30" />
+<hkern g1="uni0408" g2="uni0414" k="60" />
+<hkern g1="uni0408" g2="uni0425" k="10" />
+<hkern g1="uni0408" g2="uni0434" k="10" />
+<hkern g1="V" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="48" />
+<hkern g1="V" g2="J,Jcircumflex" k="70" />
<hkern g1="V" g2="X" k="10" />
-<hkern g1="V" g2="Y,Yacute,Ydieresis" k="20" />
+<hkern g1="V" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
<hkern g1="V" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
-<hkern g1="V" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="25" />
-<hkern g1="V" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="30" />
-<hkern g1="V" g2="t" k="18" />
-<hkern g1="V" g2="z" k="20" />
+<hkern g1="V" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="25" />
+<hkern g1="V" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="30" />
+<hkern g1="V" g2="t,uni0163,tcaron,tbar,uni021B" k="18" />
+<hkern g1="V" g2="z,zacute,zdotaccent,zcaron" k="20" />
<hkern g1="V" g2="copyright,registered" k="30" />
-<hkern g1="V" g2="S" k="5" />
-<hkern g1="V" g2="m,n,p,r,ntilde" k="30" />
-<hkern g1="V" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="30" />
-<hkern g1="V" g2="s" k="30" />
-<hkern g1="V" g2="u,ugrave,uacute,ucircumflex,udieresis" k="30" />
+<hkern g1="V" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="5" />
+<hkern g1="V" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="30" />
+<hkern g1="V" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="30" />
+<hkern g1="V" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="30" />
+<hkern g1="V" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="30" />
<hkern g1="V" g2="x" k="15" />
-<hkern g1="V" g2="y,yacute,ydieresis" k="10" />
-<hkern g1="V" g2="b,h,k,l,germandbls,thorn" k="15" />
-<hkern g1="V" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="10" />
-<hkern g1="V" g2="AE" k="50" />
+<hkern g1="V" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="V" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="15" />
+<hkern g1="V" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="10" />
+<hkern g1="V" g2="AE,AEacute" k="50" />
+<hkern g1="pi" g2="hyphen,endash,emdash,afii00208" k="45" />
+<hkern g1="pi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="-2" />
+<hkern g1="pi" g2="xi" k="8" />
+<hkern g1="pi" g2="lambda" k="20" />
+<hkern g1="pi" g2="epsilontonos,epsilon" k="20" />
+<hkern g1="pi" g2="zeta" k="10" />
+<hkern g1="pi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="5" />
<hkern g1="v" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="30" />
-<hkern g1="v" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="18" />
-<hkern g1="v" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="10" />
-<hkern g1="v" g2="s" k="10" />
+<hkern g1="v" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="18" />
+<hkern g1="v" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="10" />
+<hkern g1="v" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="10" />
<hkern g1="v" g2="v" k="15" />
-<hkern g1="v" g2="y,yacute,ydieresis" k="5" />
+<hkern g1="v" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="5" />
</font>
</defs></svg> \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.ttf b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.ttf
index fcd57cf5e..7575cf399 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.ttf
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.ttf
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.woff b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.woff
index 44555e04e..46157f949 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.woff
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Light-webfont.woff
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.eot b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.eot
index 948ccbe6e..3fa8aa3f5 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.eot
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.eot
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.svg b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.svg
index b58e0e52f..620272dbc 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.svg
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.svg
@@ -3,15 +3,14 @@
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
-<font id="clear_sans_mediumregular" horiz-adv-x="1272" >
+<font id="clear_sans_mediumregular" horiz-adv-x="1065" >
<font-face units-per-em="2048" ascent="1489" descent="-559" />
<missing-glyph horiz-adv-x="522" />
-<glyph unicode="&#xfb01;" horiz-adv-x="1176" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM782 1325q0 62 29 89.5t98 27.5t99 -27t30 -90 q0 -66 -31.5 -91.5t-97.5 -25.5q-72 0 -99.5 30t-27.5 87zM803 0v1049h215v-1049h-215z" />
-<glyph unicode="&#xfb02;" horiz-adv-x="1184" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM807 0v1489h215v-1489h-215z" />
-<glyph unicode="&#xfb03;" horiz-adv-x="1821" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM684 874v175h143v102q0 92 19 161.5t61 115.5 t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM1427 1325q0 62 29 89.5t98 27.5t99 -27t30 -90q0 -66 -31.5 -91.5t-97.5 -25.5q-72 0 -99.5 30 t-27.5 87zM1448 0v1049h215v-1049h-215z" />
-<glyph unicode="&#xfb04;" horiz-adv-x="1829" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM684 874v175h143v102q0 92 19 161.5t61 115.5 t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM1452 0v1489h215v-1489h-215z" />
-<glyph horiz-adv-x="0" />
-<glyph unicode="&#xd;" horiz-adv-x="522" />
+<glyph unicode="ff" horiz-adv-x="1292" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM684 874v175h143v102q0 92 19 161.5t61 115.5 t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143z" />
+<glyph unicode="fi" horiz-adv-x="1176" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM782 1325q0 62 29 89.5t98 27.5t99 -27t30 -90 q0 -66 -31.5 -91.5t-97.5 -25.5q-72 0 -99.5 30t-27.5 87zM803 0v1049h215v-1049h-215z" />
+<glyph unicode="fl" horiz-adv-x="1184" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM807 0v1489h215v-1489h-215z" />
+<glyph unicode="ffi" horiz-adv-x="1821" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM684 874v175h143v102q0 92 19 161.5t61 115.5 t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM1427 1325q0 62 29 89.5t98 27.5t99 -27t30 -90q0 -66 -31.5 -91.5t-97.5 -25.5q-72 0 -99.5 30 t-27.5 87zM1448 0v1049h215v-1049h-215z" />
+<glyph unicode="ffl" horiz-adv-x="1829" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM684 874v175h143v102q0 92 19 161.5t61 115.5 t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM1452 0v1489h215v-1489h-215z" />
<glyph horiz-adv-x="0" />
<glyph horiz-adv-x="0" />
<glyph unicode=" " horiz-adv-x="522" />
@@ -20,7 +19,7 @@
<glyph unicode="!" horiz-adv-x="569" d="M141 119q0 71 32 102t110 31q79 0 111 -31.5t32 -101.5q0 -76 -34 -104.5t-109 -28.5q-41 0 -68 8.5t-43.5 25t-23.5 41.5t-7 58zM164 1384h239l-26 -964h-180z" />
<glyph unicode="&#x22;" horiz-adv-x="950" d="M156 1384h241l-43 -581h-155zM553 1384h242l-43 -581h-156z" />
<glyph unicode="#" horiz-adv-x="1425" d="M86 387v152h285l84 305h-252v153h293l104 387h160l-105 -387h279l106 387h160l-104 -387h241v-153h-282l-82 -305h248v-152h-289l-105 -387h-159l102 387h-278l-105 -387h-160l105 387h-246zM532 539h279l84 305h-281z" />
-<glyph unicode="$" d="M147 301l172 111q17 -26 41.5 -52.5t56 -49.5t70 -39.5t84.5 -20.5v371q-100 24 -174.5 52.5t-124 68t-74 94.5t-24.5 131q0 73 26 132.5t76.5 103.5t124.5 71t170 33v106h154v-106q76 -5 137.5 -24t110.5 -48.5t86.5 -69t64.5 -84.5l-166 -110q-18 27 -40.5 52.5 t-51 46.5t-63.5 35t-78 19v-336q89 -22 165 -49t131.5 -68t86.5 -100t31 -145q0 -84 -30.5 -148t-85 -108.5t-131 -69t-167.5 -30.5v-203h-154v201q-84 5 -150 25.5t-118 52t-90 71.5t-66 84zM393 977q0 -57 46 -91t132 -59v299q-88 -6 -133 -44.5t-45 -104.5zM725 248 q41 4 76.5 16t62 32.5t41.5 49t15 64.5q0 63 -45.5 103t-149.5 71v-336z" />
+<glyph unicode="$" horiz-adv-x="1272" d="M147 301l172 111q17 -26 41.5 -52.5t56 -49.5t70 -39.5t84.5 -20.5v371q-100 24 -174.5 52.5t-124 68t-74 94.5t-24.5 131q0 73 26 132.5t76.5 103.5t124.5 71t170 33v106h154v-106q76 -5 137.5 -24t110.5 -48.5t86.5 -69t64.5 -84.5l-166 -110q-18 27 -40.5 52.5 t-51 46.5t-63.5 35t-78 19v-336q89 -22 165 -49t131.5 -68t86.5 -100t31 -145q0 -84 -30.5 -148t-85 -108.5t-131 -69t-167.5 -30.5v-203h-154v201q-84 5 -150 25.5t-118 52t-90 71.5t-66 84zM393 977q0 -57 46 -91t132 -59v299q-88 -6 -133 -44.5t-45 -104.5zM725 248 q41 4 76.5 16t62 32.5t41.5 49t15 64.5q0 63 -45.5 103t-149.5 71v-336z" />
<glyph unicode="%" horiz-adv-x="2126" d="M100 967q0 100 21.5 182t67.5 140.5t117.5 91t172.5 32.5q102 0 174 -32.5t118 -91.5t67.5 -141t21.5 -181q0 -98 -21.5 -179.5t-67.5 -140t-118 -91t-174 -32.5q-103 0 -175 32.5t-117.5 91.5t-66 140t-20.5 179zM311 967q0 -75 8.5 -129.5t28.5 -89.5t52 -51.5 t79 -16.5q46 0 78 16.5t52 51t29 89t9 130.5t-8.5 130.5t-28.5 89.5t-52 51.5t-79 16.5t-79 -17t-52 -52t-28.5 -89.5t-8.5 -129.5zM584 -51l764 1487h200l-764 -1487h-200zM1266 412q0 100 21.5 182t67 140.5t117.5 91t173 32.5q103 0 175 -32t117.5 -90.5t66.5 -141 t21 -182.5q0 -99 -21.5 -181t-68 -140t-118.5 -90t-172 -32q-103 0 -175 33t-117.5 92.5t-66 140.5t-20.5 177zM1477 412q0 -74 8.5 -128t28.5 -89.5t52 -52.5t79 -17q46 0 78.5 16.5t53 51t29.5 89t9 130.5t-9 131t-29.5 89.5t-53 51t-78.5 16.5q-47 0 -79 -17t-52 -52 t-28.5 -89.5t-8.5 -129.5z" />
<glyph unicode="&#x26;" horiz-adv-x="1421" d="M115 367q0 78 19.5 135.5t58 104t95.5 88t132 87.5q-32 37 -60 75t-49 77t-33 78.5t-12 79.5q0 150 96.5 235.5t294.5 85.5q82 0 148.5 -19.5t113.5 -55.5t72 -87t25 -114q0 -65 -23.5 -120.5t-63 -102.5t-92.5 -88t-112 -78l297 -351q29 37 62 101t55 149l192 -45 q-32 -126 -79 -212t-99 -146l207 -244h-277l-82 98q-35 -25 -73.5 -48t-84.5 -40.5t-102 -28t-127 -10.5q-121 0 -214 29t-156.5 81.5t-96 125.5t-32.5 160zM340 362q0 -53 22 -92.5t60 -66t88.5 -40t107.5 -13.5q49 0 88.5 8.5t72 22t57.5 30t45 31.5l-338 395 q-64 -41 -103.5 -74.5t-61.5 -65t-30 -64t-8 -71.5zM485 1100q0 -47 33 -96.5t82 -108.5q61 37 99.5 69t60.5 61t30.5 56t8.5 54q0 51 -39.5 83.5t-108.5 32.5q-46 0 -78 -12t-51.5 -32.5t-28 -48t-8.5 -58.5z" />
<glyph unicode="'" horiz-adv-x="553" d="M156 1384h241l-43 -581h-155z" />
@@ -32,14 +31,14 @@
<glyph unicode="-" horiz-adv-x="807" d="M92 420v213h623v-213h-623z" />
<glyph unicode="." horiz-adv-x="569" d="M141 121q0 71 32 104t110 33q79 0 111 -32.5t32 -104.5q0 -74 -34 -104.5t-109 -30.5q-41 0 -68 9t-43.5 26t-23.5 42.5t-7 57.5z" />
<glyph unicode="/" horiz-adv-x="1014" d="M-2 -299l702 1819h211l-704 -1819h-209z" />
-<glyph unicode="0" d="M113 688q0 186 31 322t95.5 224.5t162.5 131.5t233 43q134 0 233 -43t163.5 -131.5t96 -224t31.5 -320.5t-31.5 -320.5t-96 -224.5t-163.5 -132.5t-233 -43.5q-135 0 -233 43t-162.5 131.5t-95.5 224t-31 320.5zM354 688q0 -266 68 -392t213 -126q144 0 212 126.5 t68 393.5q0 268 -68 393t-212 125q-145 0 -213 -126.5t-68 -393.5z" />
-<glyph unicode="1" d="M264 958v160q99 6 166 21t111 45.5t71 79t45 120.5h174v-1384h-231v958h-336z" />
+<glyph unicode="0" horiz-adv-x="1272" d="M113 688q0 186 31 322t95.5 224.5t162.5 131.5t233 43q134 0 233 -43t163.5 -131.5t96 -224t31.5 -320.5t-31.5 -320.5t-96 -224.5t-163.5 -132.5t-233 -43.5q-135 0 -233 43t-162.5 131.5t-95.5 224t-31 320.5zM354 688q0 -266 68 -392t213 -126q144 0 212 126.5 t68 393.5q0 268 -68 393t-212 125q-145 0 -213 -126.5t-68 -393.5z" />
+<glyph unicode="1" horiz-adv-x="1272" d="M264 958v160q99 6 166 21t111 45.5t71 79t45 120.5h174v-1384h-231v958h-336z" />
<glyph unicode="2" horiz-adv-x="1196" d="M119 1178q30 49 71 92t97 74.5t130.5 50t172.5 18.5q90 0 171.5 -21t143 -67t97.5 -118.5t36 -174.5q0 -66 -12 -121.5t-32.5 -102.5t-49 -88.5t-61.5 -78.5q-47 -53 -102 -106t-115.5 -106.5t-124 -107.5t-127.5 -108h669v-213h-960v215q72 61 152 131.5t156 141 t142 137.5t111 123q24 30 44.5 61t35 64.5t23 70t8.5 78.5q0 45 -16.5 79.5t-45.5 58t-69 35t-86 11.5q-50 0 -90 -12t-72.5 -33.5t-58.5 -50t-48 -61.5z" />
<glyph unicode="3" horiz-adv-x="1196" d="M84 184l190 127q19 -28 44 -52.5t56.5 -42.5t70 -28t85.5 -10q72 0 123 15t83 44t46.5 72t14.5 99q0 111 -72.5 166t-214.5 55h-113v200h97q136 0 206 55.5t70 151.5q0 82 -55 126t-158 44q-97 0 -160.5 -35t-109.5 -104l-191 129q32 48 74.5 87.5t99.5 68.5t131.5 45 t171.5 16q114 0 197 -27t137.5 -73.5t80.5 -108t26 -129.5q0 -139 -71.5 -220.5t-207.5 -115.5q62 -5 117 -29t96.5 -68t65.5 -107t24 -144q0 -106 -34.5 -184.5t-100 -131t-160 -78.5t-213.5 -26q-77 0 -147 15.5t-128 44t-102 67.5t-69 86z" />
-<glyph unicode="4" d="M63 268v219l699 897h229v-915h180v-201h-180v-268h-223v268h-705zM293 469h475v598z" />
+<glyph unicode="4" horiz-adv-x="1272" d="M63 268v219l699 897h229v-915h180v-201h-180v-268h-223v268h-705zM293 469h475v598z" />
<glyph unicode="5" horiz-adv-x="1196" d="M80 186l190 129q17 -29 42 -54t58 -43.5t75 -29t92 -10.5q138 0 216 67t78 206q0 62 -22 107.5t-61 75.5t-92.5 45t-116.5 15q-76 0 -134 -20.5t-100 -52.5h-143l80 763h766v-213h-578l-37 -319q42 19 97 31t118 12q99 0 183.5 -25.5t147 -79.5t97.5 -138.5t35 -202.5 q0 -111 -34 -199.5t-101 -150.5t-166 -95t-229 -33q-85 0 -156 15.5t-128.5 44t-101.5 68t-75 87.5z" />
<glyph unicode="6" horiz-adv-x="1196" d="M111 637q0 161 30.5 302.5t97.5 246.5t173 166t258 61q128 0 221 -32t158 -91l-138 -180q-53 49 -109 75.5t-132 26.5q-78 0 -132.5 -30.5t-91 -85t-56.5 -130.5t-28 -167q29 20 62.5 38t72.5 32t83.5 22t95.5 8q96 0 174 -28.5t133 -84.5t85 -140.5t30 -196.5 q0 -114 -34 -203t-96.5 -150t-151.5 -93t-200 -32q-128 -1 -222.5 43t-157.5 129t-94 209t-31 285zM356 616q0 -93 11.5 -174t41 -141t80 -94.5t129.5 -34.5q115 0 180.5 65t65.5 205q0 58 -15.5 105t-46.5 80.5t-78 52t-110 18.5q-39 0 -76 -7.5t-70 -19t-61.5 -26 t-50.5 -29.5z" />
-<glyph unicode="7" d="M125 1171v213h1003v-172l-524 -1212h-260l528 1171h-747z" />
+<glyph unicode="7" horiz-adv-x="1272" d="M125 1171v213h1003v-172l-524 -1212h-260l528 1171h-747z" />
<glyph unicode="8" horiz-adv-x="1196" d="M96 365q0 128 73 222t206 148q-41 19 -84.5 45.5t-79.5 64t-59 88t-23 116.5q0 87 31 154.5t90.5 114t147 71t200.5 24.5q111 0 197.5 -23.5t146.5 -69.5t91.5 -113.5t31.5 -155.5q0 -64 -24.5 -113.5t-62.5 -87.5t-83.5 -66.5t-87.5 -50.5q63 -30 116.5 -63t92 -76 t60.5 -98.5t22 -130.5q0 -101 -36 -175t-102 -123t-158 -72.5t-204 -23.5q-121 0 -214.5 25t-157.5 74.5t-97 123.5t-33 171zM330 362q0 -46 16.5 -83.5t49.5 -64.5t83.5 -41.5t118.5 -14.5q69 0 119 15.5t83 43.5t48.5 65.5t15.5 82.5q0 51 -19 90.5t-54 72.5t-84 61 t-109 56q-59 -24 -108 -52t-84.5 -61.5t-55.5 -75.5t-20 -94zM360 1053q0 -26 8 -52.5t33 -54.5t72 -58.5t125 -64.5q122 51 180 104t58 120q0 40 -14.5 73.5t-44 57.5t-74 37.5t-105.5 13.5q-65 0 -110 -13.5t-73.5 -37.5t-41.5 -56t-13 -69z" />
<glyph unicode="9" horiz-adv-x="1196" d="M96 936q0 114 35 202.5t98 149.5t150.5 93t193.5 32q133 0 229.5 -43.5t158.5 -127t92 -205.5t30 -279q0 -166 -30 -310t-97 -250t-173.5 -166.5t-260.5 -60.5q-133 0 -228.5 31t-164.5 94l135 178q54 -51 117.5 -76.5t140.5 -25.5q78 0 132.5 30.5t91.5 85t58 130.5 t30 168q-60 -42 -135 -72.5t-169 -30.5q-101 0 -181 28.5t-136.5 85.5t-86.5 142t-30 197zM330 942q0 -59 15.5 -106.5t47 -81t78.5 -52t109 -18.5q38 0 75.5 7.5t71 19.5t62 26.5t49.5 28.5q0 92 -10 173.5t-38.5 142t-80 95.5t-134.5 35q-55 0 -100 -17t-77.5 -51 t-50 -84.5t-17.5 -117.5z" />
<glyph unicode=":" horiz-adv-x="569" d="M141 121q0 71 32 104t110 33q79 0 111 -32.5t32 -104.5q0 -74 -34 -104.5t-109 -30.5q-41 0 -68 9t-43.5 26t-23.5 42.5t-7 57.5zM141 911q0 72 32 105t110 33q79 0 111 -32.5t32 -105.5q0 -74 -34 -104.5t-109 -30.5q-41 0 -68 9t-43.5 26t-23.5 42.5t-7 57.5z" />
@@ -59,7 +58,7 @@
<glyph unicode="H" horiz-adv-x="1386" d="M166 0v1384h233v-561h588v561h234v-1384h-234v610h-588v-610h-233z" />
<glyph unicode="I" horiz-adv-x="821" d="M102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617z" />
<glyph unicode="J" horiz-adv-x="903" d="M35 20l78 205q15 -8 40.5 -16.5t53.5 -15.5t56.5 -12t49.5 -5q57 0 93.5 13.5t58 45.5t29.5 85t8 133v931h233v-1007q0 -105 -24.5 -182t-76 -127.5t-132 -74.5t-191.5 -24q-27 0 -62 3.5t-72.5 10.5t-74.5 16.5t-67 20.5z" />
-<glyph unicode="K" d="M166 0v1384h233v-610l519 610h280l-541 -616l574 -768h-295l-430 596l-107 -123v-473h-233z" />
+<glyph unicode="K" horiz-adv-x="1272" d="M166 0v1384h233v-610l519 610h280l-541 -616l574 -768h-295l-430 596l-107 -123v-473h-233z" />
<glyph unicode="L" horiz-adv-x="1038" d="M166 0v1384h233v-1171h605v-213h-838z" />
<glyph unicode="M" horiz-adv-x="1630" d="M166 0v1384h287l364 -706l367 706h280v-1384h-225v1038l-356 -673h-140l-354 673v-1038h-223z" />
<glyph unicode="N" horiz-adv-x="1399" d="M166 0v1384h317l523 -1011v1011h227v-1384h-277l-563 1087v-1087h-227z" />
@@ -78,9 +77,9 @@
<glyph unicode="[" horiz-adv-x="784" d="M174 -395v1884h518v-170h-319v-1544h319v-170h-518z" />
<glyph unicode="\" horiz-adv-x="1014" d="M100 1520h213l703 -1819h-211z" />
<glyph unicode="]" horiz-adv-x="784" d="M92 -225h320v1544h-320v170h518v-1884h-518v170z" />
-<glyph unicode="^" d="M133 594l418 790h168l420 -790h-187l-315 596l-320 -596h-184z" />
+<glyph unicode="^" horiz-adv-x="1272" d="M133 594l418 790h168l420 -790h-187l-315 596l-320 -596h-184z" />
<glyph unicode="_" horiz-adv-x="1024" d="M-10 -154h1044v-102h-1044v102z" />
-<glyph unicode="`" horiz-adv-x="1065" d="M231 1569h275l184 -361h-174z" />
+<glyph unicode="`" d="M231 1569h275l184 -361h-174z" />
<glyph unicode="a" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5z" />
<glyph unicode="b" horiz-adv-x="1194" d="M158 0v1489h215v-535q62 54 142 89.5t173 35.5q106 0 182 -39t125 -110.5t72 -172.5t23 -225q0 -113 -23 -215t-73 -179.5t-129 -123t-191 -45.5q-45 0 -89.5 10t-85.5 27t-77 39.5t-64 46.5l-16 -92h-184zM373 262q24 -21 54 -39.5t63 -32.5t67 -22t66 -8q51 0 96 20 t78 64t52 114t19 170q0 180 -56 270.5t-177 90.5q-35 0 -71 -9.5t-69.5 -26t-64.5 -38t-57 -45.5v-508z" />
<glyph unicode="c" horiz-adv-x="1044" d="M104 520q0 128 28.5 231.5t87.5 176t150 112t216 39.5q133 0 231 -46t154 -140l-168 -113q-35 54 -86 82.5t-129 28.5q-135 0 -198.5 -89.5t-63.5 -281.5q0 -88 14 -156t45.5 -114t83.5 -70t127 -24q35 0 65.5 5.5t57.5 18.5t51 34t47 52l168 -110q-28 -43 -64 -77.5 t-83.5 -59t-108 -37.5t-135.5 -13q-132 0 -225 40t-152 113t-86 174t-27 224z" />
@@ -113,28 +112,28 @@
<glyph unicode="~" horiz-adv-x="1407" d="M154 596v195q51 43 96.5 67.5t84.5 37t71.5 16t58.5 3.5q63 0 127 -24.5t125.5 -54t120 -54t110.5 -24.5q44 0 85 12.5t79 33t73.5 46.5t67.5 53v-190q-24 -19 -56.5 -41.5t-71 -42t-82 -32.5t-91.5 -13q-65 0 -132 24.5t-131 54t-122 54t-106 24.5q-46 0 -89.5 -13.5 t-82.5 -34.5t-73 -46.5t-62 -50.5z" />
<glyph unicode="&#xa1;" horiz-adv-x="569" d="M141 961q0 69 32.5 101t111.5 32q77 0 109 -32t32 -101q0 -71 -31.5 -102.5t-109.5 -31.5q-79 0 -111.5 31t-32.5 103zM164 -395l31 1073h180l28 -1073h-239z" />
<glyph unicode="&#xa2;" horiz-adv-x="1044" d="M104 520q0 128 28.5 231.5t87.5 176t150 112t216 39.5q11 0 20.5 -1t20.5 -1l47 211h149l-53 -237q65 -22 116 -61.5t85 -96.5l-168 -113q-16 25 -34.5 43.5t-41.5 32.5l-154 -700h23q35 0 65.5 5.5t57.5 18.5t51 34t47 52l168 -110q-28 -43 -64 -77.5t-83.5 -59 t-108 -37.5t-135.5 -13q-17 0 -32.5 1t-29.5 1l-51 -231h-149l57 260q-76 27 -130 75.5t-88.5 115.5t-50.5 150t-16 179zM326 520q0 -114 24 -195.5t84 -123.5l152 690h-25q-115 0 -175 -95t-60 -276z" />
-<glyph unicode="&#xa3;" d="M106 0v184q43 9 73 32.5t50 56.5t31.5 72t17 79.5t6.5 79.5t1 71h-154v160h143q-2 18 -10.5 47.5t-18 68.5t-17 85.5t-7.5 97.5q0 97 38 168.5t104 118.5t154.5 69.5t189.5 22.5q159 0 276.5 -57t183.5 -168l-184 -111q-43 69 -115.5 110.5t-160.5 41.5q-128 0 -192 -60 t-64 -163q0 -40 7.5 -80.5t17 -76.5t18 -66t10.5 -48h379v-160h-371q-1 -51 -5.5 -103t-19 -101.5t-42 -94t-72.5 -79.5h811v-197h-1078z" />
-<glyph unicode="&#xa4;" d="M129 221l168 168q-37 56 -54.5 114t-17.5 113q0 56 16 115t54 113l-166 166l107 108l167 -164q57 41 116.5 57.5t115.5 16.5q57 0 117 -17.5t114 -56.5l168 164l107 -108l-164 -164q40 -57 56 -116.5t16 -113.5q0 -55 -18 -112.5t-56 -116.5l166 -166l-107 -106l-168 164 q-55 -39 -113 -54.5t-118 -15.5q-56 0 -115 15.5t-114 56.5l-170 -166zM385 616q0 -51 19.5 -97t53.5 -80t79.5 -54t97.5 -20q54 0 100 20t80.5 54t54 80t19.5 97q0 53 -20 99.5t-54.5 81t-80.5 54t-99 19.5q-55 0 -101 -20.5t-79 -55t-51.5 -80.5t-18.5 -98z" />
-<glyph unicode="&#xa5;" d="M55 1384h258l326 -581l330 581h248l-343 -581h259v-150h-345l-36 -63v-68h381v-147h-381v-375h-234v375h-381v147h381v62l-41 69h-340v150h256z" />
+<glyph unicode="&#xa3;" horiz-adv-x="1272" d="M106 0v184q43 9 73 32.5t50 56.5t31.5 72t17 79.5t6.5 79.5t1 71h-154v160h143q-2 18 -10.5 47.5t-18 68.5t-17 85.5t-7.5 97.5q0 97 38 168.5t104 118.5t154.5 69.5t189.5 22.5q159 0 276.5 -57t183.5 -168l-184 -111q-43 69 -115.5 110.5t-160.5 41.5q-128 0 -192 -60 t-64 -163q0 -40 7.5 -80.5t17 -76.5t18 -66t10.5 -48h379v-160h-371q-1 -51 -5.5 -103t-19 -101.5t-42 -94t-72.5 -79.5h811v-197h-1078z" />
+<glyph unicode="&#xa4;" horiz-adv-x="1272" d="M129 221l168 168q-37 56 -54.5 114t-17.5 113q0 56 16 115t54 113l-166 166l107 108l167 -164q57 41 116.5 57.5t115.5 16.5q57 0 117 -17.5t114 -56.5l168 164l107 -108l-164 -164q40 -57 56 -116.5t16 -113.5q0 -55 -18 -112.5t-56 -116.5l166 -166l-107 -106l-168 164 q-55 -39 -113 -54.5t-118 -15.5q-56 0 -115 15.5t-114 56.5l-170 -166zM385 616q0 -51 19.5 -97t53.5 -80t79.5 -54t97.5 -20q54 0 100 20t80.5 54t54 80t19.5 97q0 53 -20 99.5t-54.5 81t-80.5 54t-99 19.5q-55 0 -101 -20.5t-79 -55t-51.5 -80.5t-18.5 -98z" />
+<glyph unicode="&#xa5;" horiz-adv-x="1272" d="M55 1384h258l326 -581l330 581h248l-343 -581h259v-150h-345l-36 -63v-68h381v-147h-381v-375h-234v375h-381v147h381v62l-41 69h-340v150h256z" />
<glyph unicode="&#xa6;" horiz-adv-x="825" d="M313 262h199v-657h-199v657zM313 862v658h199v-658h-199z" />
<glyph unicode="&#xa7;" horiz-adv-x="1096" d="M100 545q0 51 17 95t47 82.5t72 71.5t92 62q-82 59 -124 118t-42 130q0 70 25.5 127.5t76.5 97.5t128 62t181 22q144 0 241.5 -40.5t154.5 -112.5l-152 -115q-38 43 -98 67.5t-141 24.5q-101 0 -149 -31t-48 -90q0 -24 14.5 -46t46 -47.5t81 -56.5t120.5 -73 q75 -42 139 -84.5t111.5 -89.5t74.5 -101t27 -118q0 -100 -59 -173.5t-168 -138.5q90 -63 129 -121.5t39 -121.5q0 -78 -29 -136.5t-82.5 -97.5t-129 -58.5t-169.5 -19.5q-147 0 -243 40t-154 114l152 113q45 -50 105.5 -71.5t135.5 -21.5q54 0 91 9t60.5 25.5t33.5 38.5 t10 48q0 27 -17.5 51.5t-52 51t-85.5 56.5t-118 69q-68 40 -130.5 80.5t-110 87t-75.5 100.5t-28 121zM305 549q0 -33 25.5 -65.5t67.5 -64.5t96.5 -64.5t111.5 -65.5q34 22 67 44.5t58.5 47.5t41 52t15.5 59q0 33 -20.5 63t-59 60.5t-94 64.5t-125.5 76 q-85 -53 -134.5 -101.5t-49.5 -105.5z" />
-<glyph unicode="&#xa8;" horiz-adv-x="1065" d="M197 1325q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM616 1325q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#xa8;" d="M197 1325q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM616 1325q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
<glyph unicode="&#xa9;" horiz-adv-x="1829" d="M109 610q0 113 28.5 216t81 192.5t125.5 162t162.5 124.5t192 80t214.5 28q113 0 216.5 -28.5t193 -80.5t162 -125.5t124 -162.5t79.5 -192t28 -214q0 -113 -28.5 -217t-80 -194t-124.5 -163t-162 -125t-192.5 -80t-215.5 -28q-113 0 -216.5 28.5t-193 81t-162 126 t-124.5 163t-80 193t-28 215.5zM256 610q0 -91 23.5 -176t66 -159t102.5 -135t133 -104t157 -67t175 -24q92 0 176.5 24t157.5 67t132.5 104t102 135t66 158.5t23.5 176.5q0 137 -51 257.5t-140 210.5t-209 142t-258 52q-137 0 -256.5 -52t-208.5 -142t-140.5 -210.5 t-51.5 -257.5zM530 612q0 218 98 331.5t306 113.5q64 0 114.5 -13.5t90.5 -38t71 -59t56 -76.5l-148 -86q-15 25 -32 46.5t-38.5 37.5t-49.5 25.5t-66 9.5q-120 0 -170.5 -71t-50.5 -220q0 -153 53 -220.5t170 -67.5q37 0 66 8.5t52 24.5t42 37.5t36 47.5l150 -84 q-28 -39 -59 -73.5t-71.5 -60t-92 -40t-119.5 -14.5q-209 0 -308.5 112t-99.5 330z" />
<glyph unicode="&#xaa;" horiz-adv-x="807" d="M92 907q0 63 21 105.5t58 69.5t88 41t110 20l143 12v23q0 59 -33.5 80.5t-103.5 21.5q-33 0 -57 -6t-41.5 -16.5t-30 -23.5t-21.5 -28l-127 78q15 26 38.5 49.5t57.5 41t79.5 28t105.5 10.5q72 0 127 -12t91.5 -40t55.5 -74.5t19 -115.5v-460h-154v63q-45 -37 -95 -59.5 t-110 -22.5q-54 0 -95 15.5t-69 44t-42.5 68t-14.5 87.5zM256 909q0 -46 23 -65t71 -19q37 0 78.5 23t83.5 55v129l-82 -8q-91 -8 -132.5 -33t-41.5 -82z" />
<glyph unicode="&#xab;" horiz-adv-x="1329" d="M66 524l407 471h248l-408 -471l408 -471h-248zM598 524l406 471h247l-405 -471l405 -471h-247z" />
<glyph unicode="&#xac;" horiz-adv-x="1427" d="M147 813v174h1131v-643h-174v469h-957z" />
<glyph unicode="&#xad;" horiz-adv-x="807" d="M92 420v213h623v-213h-623z" />
<glyph unicode="&#xae;" horiz-adv-x="1829" d="M109 610q0 113 28.5 216t81 192.5t125.5 162t162.5 124.5t192 80t214.5 28q113 0 216.5 -28.5t193 -80.5t162 -125.5t124 -162.5t79.5 -192t28 -214q0 -113 -28.5 -217t-80 -194t-124.5 -163t-162 -125t-192.5 -80t-215.5 -28q-113 0 -216.5 28.5t-193 81t-162 126 t-124.5 163t-80 193t-28 215.5zM256 610q0 -91 23.5 -176t66 -159t102.5 -135t133 -104t157 -67t175 -24q92 0 176.5 24t157.5 67t132.5 104t102 135t66 158.5t23.5 176.5q0 137 -51 257.5t-140 210.5t-209 142t-258 52q-137 0 -256.5 -52t-208.5 -142t-140.5 -210.5 t-51.5 -257.5zM614 201v850h291q75 0 136 -12t103.5 -41.5t65.5 -78.5t23 -122q0 -104 -43 -162.5t-115 -83.5l236 -350h-207l-213 321h-105v-321h-172zM786 670h113q48 0 78.5 6.5t47 20.5t22.5 36.5t6 54.5q0 31 -6.5 52.5t-23 35.5t-44.5 20.5t-72 6.5h-121v-233z" />
-<glyph unicode="&#xaf;" horiz-adv-x="1065" d="M211 1255v162h641v-162h-641z" />
+<glyph unicode="&#xaf;" d="M211 1255v162h641v-162h-641z" />
<glyph unicode="&#xb0;" horiz-adv-x="866" d="M137 1241q0 61 23.5 114.5t64 93.5t94 62.5t113.5 22.5q62 0 116.5 -23.5t94.5 -63t63 -93t23 -113.5q0 -62 -24 -116.5t-64.5 -95t-94 -64t-112.5 -23.5q-61 0 -115 23.5t-94.5 64t-64 95t-23.5 116.5zM287 1241q0 -31 11 -58t31 -47.5t46.5 -32t58.5 -11.5 q31 0 57.5 11.5t46 32t31 47t11.5 56.5q0 31 -11.5 57.5t-31 46t-46 30.5t-57.5 11q-32 0 -59 -11.5t-46.5 -31.5t-30.5 -46t-11 -54z" />
<glyph unicode="&#xb1;" horiz-adv-x="1427" d="M147 0v174h1131v-174h-1131zM147 819v174h480v477h174v-477h477v-174h-477v-479h-174v479h-480z" />
<glyph unicode="&#xb2;" horiz-adv-x="913" d="M90 1354q56 77 142.5 122.5t209.5 45.5q156 0 242 -63t86 -185q0 -80 -31 -137t-82 -105q-21 -20 -52 -45.5t-68 -54t-78 -59t-82 -58.5h424v-164h-699v160q50 37 107.5 79t112 84t101 81t75.5 71q31 32 45 63t14 66q0 51 -36 75t-87 24q-59 0 -103 -28.5t-75 -70.5z" />
<glyph unicode="&#xb3;" horiz-adv-x="913" d="M72 788l166 89q26 -36 69.5 -61t100.5 -25q41 0 70 9t47 24.5t26 37.5t8 49q0 57 -41 84t-123 27h-102v152h90q90 0 130 26.5t40 77.5q0 40 -33.5 64t-95.5 24q-59 0 -101.5 -22.5t-74.5 -65.5l-158 90q24 32 54.5 60t72 49t96 33t125.5 12q82 0 142.5 -17.5t100.5 -48 t59.5 -71t19.5 -85.5q0 -138 -150 -190q81 -25 122.5 -78t41.5 -129q0 -68 -25 -118.5t-72 -84t-115 -50.5t-154 -17q-57 0 -109 11.5t-95.5 32t-77 49t-54.5 62.5z" />
-<glyph unicode="&#xb4;" horiz-adv-x="1065" d="M414 1208l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#xb4;" d="M414 1208l184 361h274l-284 -361h-174z" />
<glyph unicode="&#xb5;" horiz-adv-x="1186" d="M135 -395v1444h215v-773q18 -22 43 -41.5t54.5 -34.5t63 -23.5t67.5 -8.5q142 0 249 133v748h215v-1049h-200l-8 115q-54 -73 -114 -109.5t-140 -36.5q-34 0 -63.5 4t-57 13t-54.5 23.5t-55 35.5v-440h-215z" />
<glyph unicode="&#xb6;" horiz-adv-x="1288" d="M49 1057q0 100 35 180t99.5 136t156 86t205.5 30h692v-170h-190v-1714h-197v1714h-178v-1714h-197v1020q-87 5 -164 34t-135.5 82.5t-92.5 132t-34 183.5z" />
<glyph unicode="&#xb7;" horiz-adv-x="569" d="M141 743q0 72 32 105t110 33q79 0 111 -32.5t32 -105.5q0 -74 -34 -104.5t-109 -30.5q-41 0 -68 9t-43.5 26t-23.5 42.5t-7 57.5z" />
-<glyph unicode="&#xb8;" horiz-adv-x="1065" d="M221 -350l60 123q19 -7 42.5 -14t48.5 -12.5t51 -9t50 -3.5q56 0 82.5 14.5t26.5 48.5q0 22 -15 38t-39.5 26t-57 15t-67.5 7l76 146h137l-26 -56q72 -18 112.5 -67t40.5 -117q0 -88 -68 -136t-202 -48q-45 0 -84.5 4.5t-72 11t-57 14.5t-38.5 15z" />
+<glyph unicode="&#xb8;" d="M221 -350l60 123q19 -7 42.5 -14t48.5 -12.5t51 -9t50 -3.5q56 0 82.5 14.5t26.5 48.5q0 22 -15 38t-39.5 26t-57 15t-67.5 7l76 146h137l-26 -56q72 -18 112.5 -67t40.5 -117q0 -88 -68 -136t-202 -48q-45 0 -84.5 4.5t-72 11t-57 14.5t-38.5 15z" />
<glyph unicode="&#xb9;" horiz-adv-x="913" d="M176 1221v129q68 2 114.5 11t77 26.5t48.5 46t30 69.5h162v-852h-207v570h-225z" />
<glyph unicode="&#xba;" horiz-adv-x="834" d="M96 1051q0 83 18.5 150t58 114t100.5 72.5t145 25.5q83 0 143 -26t98.5 -73t57 -114t18.5 -149q0 -83 -18.5 -149t-57 -113t-98.5 -72t-143 -25q-84 0 -145 25.5t-100.5 72.5t-58 113.5t-18.5 147.5zM262 1051q0 -116 37 -169t119 -53q78 0 115.5 53t37.5 169 q0 115 -37.5 169t-115.5 54q-81 0 -118.5 -54t-37.5 -169z" />
<glyph unicode="&#xbb;" horiz-adv-x="1329" d="M78 53l405 471l-405 471h248l405 -471l-405 -471h-248zM608 53l408 471l-408 471h248l408 -471l-408 -471h-248z" />
@@ -206,43 +205,757 @@
<glyph unicode="&#xfd;" horiz-adv-x="1063" d="M-12 -365l49 183q35 -14 74.5 -21.5t76.5 -7.5q30 0 56.5 10.5t51 34t47 61.5t44.5 93l31 75l-381 986h227l268 -719l273 719h221l-451 -1125q-35 -86 -71 -146.5t-81 -99t-101 -56t-129 -17.5q-50 0 -105 8t-100 22zM386 1208l184 361h274l-284 -361h-174z" />
<glyph unicode="&#xfe;" horiz-adv-x="1194" d="M158 -395v1884h215v-539q59 57 140 93t177 36q105 0 180.5 -40t124 -112.5t72 -173t23.5 -221.5q0 -110 -24 -212t-75 -180t-131 -124.5t-192 -46.5q-85 0 -159 29.5t-136 83.5v-477h-215zM373 262q24 -21 52.5 -39.5t60.5 -32.5t66 -22t69 -8q50 0 95 21t78.5 65.5 t53.5 114t20 167.5q0 177 -58.5 269t-172.5 92q-36 0 -72.5 -9.5t-70.5 -26t-65 -38t-56 -45.5v-508z" />
<glyph unicode="&#xff;" horiz-adv-x="1063" d="M-12 -365l49 183q35 -14 74.5 -21.5t76.5 -7.5q30 0 56.5 10.5t51 34t47 61.5t44.5 93l31 75l-381 986h227l268 -719l273 719h221l-451 -1125q-35 -86 -71 -146.5t-81 -99t-101 -56t-129 -17.5q-50 0 -105 8t-100 22zM199 1325q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91 q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM618 1325q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x100;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM340 1591v162h641v-162h-641zM444 528h412l-205 623z" />
+<glyph unicode="&#x101;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM221 1255v162h641v-162h-641zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5z" />
+<glyph unicode="&#x102;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM317 1825h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5zM444 528h412 l-205 623z" />
+<glyph unicode="&#x103;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM198 1499h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5 t-22 113.5zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5z" />
+<glyph unicode="&#x104;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384q-75 -19 -124 -39t-78 -40.5t-40.5 -41.5t-11.5 -43q0 -34 18 -50.5t47 -16.5q26 0 55.5 8.5t57.5 25.5l74 -133q-53 -31 -106 -48t-113 -17q-45 0 -83 11t-65.5 33.5t-43 56.5t-15.5 81q0 75 48 133t130 98l-98 301h-549l-105 -319h-233z M444 528h412l-205 623z" />
+<glyph unicode="&#x105;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159.5t87 105t132 61t167.5 28.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713q-74 -19 -123 -39t-78 -40.5t-41 -41.5t-12 -43q0 -34 19 -50.5t48 -16.5q25 0 54 8.5t57 25.5l76 -133q-53 -31 -106 -48t-113 -17q-46 0 -84 11t-65.5 33.5t-42.5 56.5t-15 81q0 85 60.5 148.5t160.5 101.5v82q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24 t-104 67.5t-64 103t-22 131.5zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5z" />
+<glyph unicode="&#x106;" horiz-adv-x="1327" d="M113 692q0 363 154 542t460 179q105 0 186 -19.5t143 -53.5t106.5 -80.5t76.5 -100.5l-186 -135q-22 34 -48.5 67t-64 58.5t-88.5 41t-121 15.5q-195 0 -286 -129t-91 -385q0 -137 24.5 -234t72.5 -159.5t119 -91.5t163 -29q69 0 121 15t91.5 40.5t69.5 60t56 73.5 l189 -131q-36 -56 -81.5 -104.5t-107 -84t-143.5 -56t-191 -20.5q-317 0 -470.5 180t-153.5 541zM570 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x107;" horiz-adv-x="1044" d="M104 520q0 128 28.5 231.5t87.5 176t150 112t216 39.5q133 0 231 -46t154 -140l-168 -113q-35 54 -86 82.5t-129 28.5q-135 0 -198.5 -89.5t-63.5 -281.5q0 -88 14 -156t45.5 -114t83.5 -70t127 -24q35 0 65.5 5.5t57.5 18.5t51 34t47 52l168 -110q-28 -43 -64 -77.5 t-83.5 -59t-108 -37.5t-135.5 -13q-132 0 -225 40t-152 113t-86 174t-27 224zM437 1208l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x108;" horiz-adv-x="1327" d="M113 692q0 363 154 542t460 179q105 0 186 -19.5t143 -53.5t106.5 -80.5t76.5 -100.5l-186 -135q-22 34 -48.5 67t-64 58.5t-88.5 41t-121 15.5q-195 0 -286 -129t-91 -385q0 -137 24.5 -234t72.5 -159.5t119 -91.5t163 -29q69 0 121 15t91.5 40.5t69.5 60t56 73.5 l189 -131q-36 -56 -81.5 -104.5t-107 -84t-143.5 -56t-191 -20.5q-317 0 -470.5 180t-153.5 541zM387 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x109;" horiz-adv-x="1044" d="M104 520q0 128 28.5 231.5t87.5 176t150 112t216 39.5q133 0 231 -46t154 -140l-168 -113q-35 54 -86 82.5t-129 28.5q-135 0 -198.5 -89.5t-63.5 -281.5q0 -88 14 -156t45.5 -114t83.5 -70t127 -24q35 0 65.5 5.5t57.5 18.5t51 34t47 52l168 -110q-28 -43 -64 -77.5 t-83.5 -59t-108 -37.5t-135.5 -13q-132 0 -225 40t-152 113t-86 174t-27 224zM235 1208l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x10a;" horiz-adv-x="1327" d="M113 692q0 363 154 542t460 179q105 0 186 -19.5t143 -53.5t106.5 -80.5t76.5 -100.5l-186 -135q-22 34 -48.5 67t-64 58.5t-88.5 41t-121 15.5q-195 0 -286 -129t-91 -385q0 -137 24.5 -234t72.5 -159.5t119 -91.5t163 -29q69 0 121 15t91.5 40.5t69.5 60t56 73.5 l189 -131q-36 -56 -81.5 -104.5t-107 -84t-143.5 -56t-191 -20.5q-317 0 -470.5 180t-153.5 541zM565 1665q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x10b;" horiz-adv-x="1044" d="M104 520q0 128 28.5 231.5t87.5 176t150 112t216 39.5q133 0 231 -46t154 -140l-168 -113q-35 54 -86 82.5t-129 28.5q-135 0 -198.5 -89.5t-63.5 -281.5q0 -88 14 -156t45.5 -114t83.5 -70t127 -24q35 0 65.5 5.5t57.5 18.5t51 34t47 52l168 -110q-28 -43 -64 -77.5 t-83.5 -59t-108 -37.5t-135.5 -13q-132 0 -225 40t-152 113t-86 174t-27 224zM438 1329q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x10c;" horiz-adv-x="1327" d="M113 692q0 363 154 542t460 179q105 0 186 -19.5t143 -53.5t106.5 -80.5t76.5 -100.5l-186 -135q-22 34 -48.5 67t-64 58.5t-88.5 41t-121 15.5q-195 0 -286 -129t-91 -385q0 -137 24.5 -234t72.5 -159.5t119 -91.5t163 -29q69 0 121 15t91.5 40.5t69.5 60t56 73.5 l189 -131q-36 -56 -81.5 -104.5t-107 -84t-143.5 -56t-191 -20.5q-317 0 -470.5 180t-153.5 541zM368 1905h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x10d;" horiz-adv-x="1044" d="M104 520q0 128 28.5 231.5t87.5 176t150 112t216 39.5q133 0 231 -46t154 -140l-168 -113q-35 54 -86 82.5t-129 28.5q-135 0 -198.5 -89.5t-63.5 -281.5q0 -88 14 -156t45.5 -114t83.5 -70t127 -24q35 0 65.5 5.5t57.5 18.5t51 34t47 52l168 -110q-28 -43 -64 -77.5 t-83.5 -59t-108 -37.5t-135.5 -13q-132 0 -225 40t-152 113t-86 174t-27 224zM221 1569h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x10e;" horiz-adv-x="1303" d="M154 0v1384h383q166 0 290.5 -35t207.5 -116t124 -213.5t41 -327.5q0 -204 -42 -338t-125.5 -212.5t-206.5 -110t-285 -31.5h-387zM260 1905h181l163 -207l168 207h179l-232 -361h-227zM387 213h131q126 0 210 23.5t135 79t72 148t21 230.5q0 140 -22 232t-73 146.5 t-135 76.5t-208 22h-131v-958z" />
+<glyph unicode="&#x10f;" horiz-adv-x="1298" d="M104 516q0 108 23 209.5t74.5 180t133.5 126t200 47.5q78 0 153.5 -30.5t132.5 -81.5v522h215v-1489h-205v102q-65 -58 -146.5 -95.5t-178.5 -37.5q-106 0 -182 40.5t-125 113.5t-72 173t-23 220zM326 520q0 -176 58.5 -268t172.5 -92q36 0 72.5 9.5t70.5 26t65 38 t56 45.5v505q-24 21 -52.5 40t-60.5 33.5t-66 23t-69 8.5q-50 0 -95 -21.5t-78.5 -66.5t-53.5 -114.5t-20 -166.5zM1114 1128l60 361h243l-164 -361h-139z" />
+<glyph unicode="&#x110;" horiz-adv-x="1389" d="M33 602v184h133v598h399q179 0 312.5 -35t222 -116t132.5 -213.5t44 -327.5q0 -204 -45.5 -338t-134.5 -212.5t-222 -110t-307 -31.5h-401v602h-133zM399 213h150q136 0 229 23.5t149 79t80.5 148t24.5 230.5q0 140 -25 232t-81.5 146.5t-149 76.5t-227.5 22h-150v-385 h328v-184h-328v-389z" />
+<glyph unicode="&#x111;" horiz-adv-x="1194" d="M104 516q0 108 23 209.5t74.5 180t133.5 126t200 47.5q78 0 153.5 -30.5t132.5 -81.5v229h-289v162h289v131h215v-131h138v-162h-138v-1196h-205v102q-65 -58 -146.5 -95.5t-178.5 -37.5q-106 0 -182 40.5t-125 113.5t-72 173t-23 220zM326 520q0 -176 58.5 -268 t172.5 -92q36 0 72.5 9.5t70.5 26t65 38t56 45.5v505q-24 21 -52.5 40t-60.5 33.5t-66 23t-69 8.5q-50 0 -95 -21.5t-78.5 -66.5t-53.5 -114.5t-20 -166.5z" />
+<glyph unicode="&#x112;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM277 1591v162h641v-162h-641z" />
+<glyph unicode="&#x113;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM268 1255v162h641v-162h-641zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115z" />
+<glyph unicode="&#x114;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM292 1835h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5z" />
+<glyph unicode="&#x115;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM235 1499h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5zM330 637h473q0 131 -55 199.5t-173 68.5 q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115z" />
+<glyph unicode="&#x116;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM469 1665q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x117;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115zM444 1329q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x118;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213q-74 -19 -123 -39t-78 -40.5t-41 -41.5t-12 -43q0 -34 18.5 -50.5t47.5 -16.5q26 0 55.5 8.5t57.5 25.5l73 -133q-52 -31 -105.5 -48t-113.5 -17q-45 0 -83 11t-65.5 33.5t-43 56.5t-15.5 81q0 68 39 120.5 t105 92.5h-588z" />
+<glyph unicode="&#x119;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-34 -51 -75 -86q-82 -75 -123 -130.5t-41 -105.5 q0 -32 18 -46.5t49 -14.5q25 0 54 8.5t57 25.5l76 -133q-53 -31 -106 -48t-113 -17q-46 0 -84 10.5t-65.5 32.5t-42.5 54.5t-15 76.5q0 56 18.5 99.5t59.5 92.5q-14 -2 -28.5 -2h-31.5q-261 0 -382.5 138.5t-121.5 408.5zM330 637h473q0 131 -55 199.5t-173 68.5 q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115z" />
+<glyph unicode="&#x11a;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM241 1905h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x11b;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM229 1569h181l163 -207l168 207h179l-232 -361h-227zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115z" />
+<glyph unicode="&#x11c;" horiz-adv-x="1403" d="M113 684q0 176 36.5 312t113 228.5t194 140.5t278.5 48q109 0 193 -20.5t146.5 -55.5t106 -81t72.5 -97l-184 -137q-51 88 -129.5 136t-204.5 48q-88 0 -158.5 -27.5t-120 -89.5t-76 -161.5t-26.5 -243.5q0 -126 21.5 -221t68 -158t119.5 -95t176 -32q77 0 143.5 16.5 t135.5 47.5v272h-303v209h536v-604q-105 -68 -231.5 -108t-276.5 -40q-324 0 -477 177.5t-153 535.5zM387 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x11d;" horiz-adv-x="1194" d="M104 535q0 104 23.5 202t75 174t134 122t200.5 46q83 0 161 -33.5t138 -89.5l16 93h184v-1029q0 -105 -28 -183t-88 -129.5t-154 -77t-225 -25.5q-121 0 -220.5 24.5t-177.5 69.5l70 174q68 -37 149.5 -60.5t178.5 -23.5q76 0 129 13t86.5 40.5t49 71.5t15.5 106v105 q-59 -54 -138 -89.5t-175 -35.5q-105 0 -181.5 39.5t-126 110.5t-73 169t-23.5 216zM249 1208l232 361h227l232 -361h-181l-164 205l-167 -205h-179zM326 539q0 -79 13 -143.5t40.5 -110t71 -70.5t104.5 -25q69 0 136.5 32t129.5 87v475q-55 48 -117.5 76.5t-132.5 28.5 q-59 0 -104.5 -26.5t-77 -73t-47.5 -110.5t-16 -140z" />
+<glyph unicode="&#x11e;" horiz-adv-x="1403" d="M113 684q0 176 36.5 312t113 228.5t194 140.5t278.5 48q109 0 193 -20.5t146.5 -55.5t106 -81t72.5 -97l-184 -137q-51 88 -129.5 136t-204.5 48q-88 0 -158.5 -27.5t-120 -89.5t-76 -161.5t-26.5 -243.5q0 -126 21.5 -221t68 -158t119.5 -95t176 -32q77 0 143.5 16.5 t135.5 47.5v272h-303v209h536v-604q-105 -68 -231.5 -108t-276.5 -40q-324 0 -477 177.5t-153 535.5zM387 1835h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5 t-22 113.5z" />
+<glyph unicode="&#x11f;" horiz-adv-x="1194" d="M104 535q0 104 23.5 202t75 174t134 122t200.5 46q83 0 161 -33.5t138 -89.5l16 93h184v-1029q0 -105 -28 -183t-88 -129.5t-154 -77t-225 -25.5q-121 0 -220.5 24.5t-177.5 69.5l70 174q68 -37 149.5 -60.5t178.5 -23.5q76 0 129 13t86.5 40.5t49 71.5t15.5 106v105 q-59 -54 -138 -89.5t-175 -35.5q-105 0 -181.5 39.5t-126 110.5t-73 169t-23.5 216zM231 1499h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5z M326 539q0 -79 13 -143.5t40.5 -110t71 -70.5t104.5 -25q69 0 136.5 32t129.5 87v475q-55 48 -117.5 76.5t-132.5 28.5q-59 0 -104.5 -26.5t-77 -73t-47.5 -110.5t-16 -140z" />
+<glyph unicode="&#x120;" horiz-adv-x="1403" d="M113 684q0 176 36.5 312t113 228.5t194 140.5t278.5 48q109 0 193 -20.5t146.5 -55.5t106 -81t72.5 -97l-184 -137q-51 88 -129.5 136t-204.5 48q-88 0 -158.5 -27.5t-120 -89.5t-76 -161.5t-26.5 -243.5q0 -126 21.5 -221t68 -158t119.5 -95t176 -32q77 0 143.5 16.5 t135.5 47.5v272h-303v209h536v-604q-105 -68 -231.5 -108t-276.5 -40q-324 0 -477 177.5t-153 535.5zM589 1665q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x121;" horiz-adv-x="1194" d="M104 535q0 104 23.5 202t75 174t134 122t200.5 46q83 0 161 -33.5t138 -89.5l16 93h184v-1029q0 -105 -28 -183t-88 -129.5t-154 -77t-225 -25.5q-121 0 -220.5 24.5t-177.5 69.5l70 174q68 -37 149.5 -60.5t178.5 -23.5q76 0 129 13t86.5 40.5t49 71.5t15.5 106v105 q-59 -54 -138 -89.5t-175 -35.5q-105 0 -181.5 39.5t-126 110.5t-73 169t-23.5 216zM326 539q0 -79 13 -143.5t40.5 -110t71 -70.5t104.5 -25q69 0 136.5 32t129.5 87v475q-55 48 -117.5 76.5t-132.5 28.5q-59 0 -104.5 -26.5t-77 -73t-47.5 -110.5t-16 -140zM438 1329 q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x122;" horiz-adv-x="1403" d="M113 684q0 176 36.5 312t113 228.5t194 140.5t278.5 48q109 0 193 -20.5t146.5 -55.5t106 -81t72.5 -97l-184 -137q-51 88 -129.5 136t-204.5 48q-88 0 -158.5 -27.5t-120 -89.5t-76 -161.5t-26.5 -243.5q0 -126 21.5 -221t68 -158t119.5 -95t176 -32q77 0 143.5 16.5 t135.5 47.5v272h-303v209h536v-604q-105 -68 -231.5 -108t-276.5 -40q-324 0 -477 177.5t-153 535.5zM616 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z " />
+<glyph unicode="&#x123;" horiz-adv-x="1194" d="M104 535q0 104 23.5 202t75 174t134 122t200.5 46q83 0 161 -33.5t138 -89.5l16 93h184v-1029q0 -105 -28 -183t-88 -129.5t-154 -77t-225 -25.5q-121 0 -220.5 24.5t-177.5 69.5l70 174q68 -37 149.5 -60.5t178.5 -23.5q76 0 129 13t86.5 40.5t49 71.5t15.5 106v105 q-59 -54 -138 -89.5t-175 -35.5q-105 0 -181.5 39.5t-126 110.5t-73 169t-23.5 216zM326 539q0 -79 13 -143.5t40.5 -110t71 -70.5t104.5 -25q69 0 136.5 32t129.5 87v475q-55 48 -117.5 76.5t-132.5 28.5q-59 0 -104.5 -26.5t-77 -73t-47.5 -110.5t-16 -140zM422 1321 q0 88 32.5 156t82.5 127h135q-38 -48 -60 -89t-24 -79q63 -3 91 -34t28 -99q0 -32 -7 -57.5t-23 -43.5t-43.5 -27.5t-67.5 -9.5q-78 0 -111 40.5t-33 115.5z" />
+<glyph unicode="&#x124;" horiz-adv-x="1386" d="M166 0v1384h233v-561h588v561h234v-1384h-234v610h-588v-610h-233zM352 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x125;" horiz-adv-x="1190" d="M158 0v1489h215v-586q34 34 76 66t88.5 56.5t96 39t99.5 14.5q87 0 146 -25t94.5 -73.5t51 -119t15.5 -161.5v-700h-215v598q0 79 -5.5 133.5t-22 88t-46.5 48.5t-79 15q-33 0 -70.5 -13t-76 -35.5t-77.5 -52t-75 -61.5v-721h-215zM286 1544l232 361h227l232 -361h-181 l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x126;" horiz-adv-x="1386" d="M20 1006v174h146v204h233v-204h588v204h234v-204h145v-174h-145v-1006h-234v610h-588v-610h-233v1006h-146zM399 823h588v183h-588v-183z" />
+<glyph unicode="&#x127;" horiz-adv-x="1190" d="M2 1196v162h156v131h215v-131h270v-162h-270v-293q34 34 76 66t88.5 56.5t96 39t99.5 14.5q87 0 146 -25t94.5 -73.5t51 -119t15.5 -161.5v-700h-215v598q0 79 -5.5 133.5t-22 88t-46.5 48.5t-79 15q-33 0 -70.5 -13t-76 -35.5t-77.5 -52t-75 -61.5v-721h-215v1196h-156z " />
+<glyph unicode="&#x128;" horiz-adv-x="821" d="M21 1561q3 62 18.5 115.5t45.5 92.5t75 61t107 22q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11 q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152zM102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617z" />
+<glyph unicode="&#x129;" horiz-adv-x="530" d="M-128 1225q3 62 18.5 115.5t45.5 92.5t75 61t107 22q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11 q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152zM158 0v1049h215v-1049h-215z" />
+<glyph unicode="&#x12a;" horiz-adv-x="821" d="M93 1591v162h641v-162h-641zM102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617z" />
+<glyph unicode="&#x12b;" horiz-adv-x="530" d="M-56 1255v162h641v-162h-641zM158 0v1049h215v-1049h-215z" />
+<glyph unicode="&#x12c;" horiz-adv-x="821" d="M68 1835h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5zM102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617z" />
+<glyph unicode="&#x12d;" horiz-adv-x="530" d="M-81 1499h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5zM158 0v1049h215v-1049h-215z" />
+<glyph unicode="&#x12e;" horiz-adv-x="821" d="M102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188q-75 -19 -124 -39t-78 -40.5t-40.5 -41.5t-11.5 -43q0 -34 18 -50.5t47 -16.5q26 0 55.5 8.5t57.5 25.5l74 -133q-53 -31 -106 -48t-113 -17q-45 0 -83 11t-65.5 33.5t-43 56.5t-15.5 81q0 68 38.5 120.5 t104.5 92.5h-332z" />
+<glyph unicode="&#x12f;" horiz-adv-x="530" d="M-14 -213q0 75 48 133t124 96v1033h215v-1049q-60 -15 -101 -35.5t-65.5 -42.5t-35.5 -44.5t-11 -41.5q0 -34 18 -50.5t47 -16.5q26 0 55.5 8.5t57.5 25.5l74 -133q-53 -31 -106 -48t-113 -17q-45 0 -83 11t-65.5 33.5t-43 56.5t-15.5 81zM137 1325q0 62 29 89.5t98 27.5 t99 -27t30 -90q0 -66 -31.5 -91.5t-97.5 -25.5q-72 0 -99.5 30t-27.5 87z" />
+<glyph unicode="&#x130;" horiz-adv-x="821" d="M102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617zM281 1665q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x131;" horiz-adv-x="530" d="M158 0v1049h215v-1049h-215z" />
+<glyph unicode="&#x132;" horiz-adv-x="1663" d="M102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617zM795 20l78 205q15 -8 40.5 -16.5t53.5 -15.5t56.5 -12t49.5 -5q57 0 93.5 13.5t58 45.5t29.5 85t8 133v931h233v-1007q0 -105 -24.5 -182t-76 -127.5t-132 -74.5t-191.5 -24q-27 0 -62 3.5t-72.5 10.5 t-74.5 16.5t-67 20.5z" />
+<glyph unicode="&#x133;" horiz-adv-x="1079" d="M137 1325q0 62 29 89.5t98 27.5t99 -27t30 -90q0 -66 -31.5 -91.5t-97.5 -25.5q-72 0 -99.5 30t-27.5 87zM158 0v1049h215v-1049h-215zM374 -365l50 183q35 -14 72 -21.5t79 -7.5q41 0 65.5 13t38 40t17.5 68t4 96v1043h215v-1094q0 -91 -17.5 -157t-57.5 -109 t-104 -63.5t-157 -20.5q-18 0 -42.5 2t-52 5.5t-56.5 9t-54 13.5zM682 1325q0 62 28 89.5t97 27.5q71 0 100 -27t29 -90q0 -66 -31.5 -91.5t-97.5 -25.5q-36 0 -60.5 7.5t-38.5 22.5t-20 36.5t-6 50.5z" />
+<glyph unicode="&#x134;" horiz-adv-x="903" d="M35 20l78 205q15 -8 40.5 -16.5t53.5 -15.5t56.5 -12t49.5 -5q57 0 93.5 13.5t58 45.5t29.5 85t8 133v931h233v-1007q0 -105 -24.5 -182t-76 -127.5t-132 -74.5t-191.5 -24q-27 0 -62 3.5t-72.5 10.5t-74.5 16.5t-67 20.5zM274 1544l232 361h227l232 -361h-181l-164 205 l-167 -205h-179z" />
+<glyph unicode="&#x135;" horiz-adv-x="549" d="M-154 -365l50 183q35 -14 72 -21.5t79 -7.5q41 0 65.5 13t38 40t17.5 68t4 96v1043h215v-1094q0 -91 -17.5 -157t-57.5 -109t-104 -63.5t-157 -20.5q-18 0 -42.5 2t-52 5.5t-56.5 9t-54 13.5zM-65 1208l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x136;" horiz-adv-x="1272" d="M166 0v1384h233v-610l519 610h280l-541 -616l574 -768h-295l-430 596l-107 -123v-473h-233zM483 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x137;" horiz-adv-x="1073" d="M158 0v1489h215v-891l389 451h254l-406 -451l428 -598h-252l-307 453l-106 -117v-336h-215zM387 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x138;" horiz-adv-x="1073" d="M158 0v1047h215v-449l340 395q29 35 65 56.5t84 21.5q22 0 59 -4t93 -18l-53 -168q-16 5 -30.5 8.5t-27.5 3.5q-18 0 -29.5 -8t-23.5 -21l-240 -266l428 -598h-252l-307 453l-106 -117v-336h-215z" />
+<glyph unicode="&#x139;" horiz-adv-x="1038" d="M166 0v1384h233v-1171h605v-213h-838zM380 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x13a;" horiz-adv-x="539" d="M120 1587l184 361h274l-284 -361h-174zM162 0v1489h215v-1489h-215z" />
+<glyph unicode="&#x13b;" horiz-adv-x="1038" d="M166 0v1384h233v-1171h605v-213h-838zM448 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x13c;" horiz-adv-x="539" d="M128 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5zM162 0v1489h215v-1489h-215z" />
+<glyph unicode="&#x13d;" horiz-adv-x="1038" d="M166 0v1384h233v-1171h605v-213h-838zM514 1025l61 361h242l-162 -361h-141z" />
+<glyph unicode="&#x13e;" horiz-adv-x="641" d="M162 0v1489h215v-1489h-215zM453 1128l61 361h242l-162 -361h-141z" />
+<glyph unicode="&#x13f;" horiz-adv-x="1038" d="M166 0v1384h233v-1171h605v-213h-838zM661 755q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x140;" horiz-adv-x="774" d="M162 0v1489h215v-1489h-215zM522 755q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x141;" horiz-adv-x="1038" d="M20 399v222l146 114v649h233v-477l238 189v-222l-238 -188v-473h605v-213h-838v514z" />
+<glyph unicode="&#x142;" horiz-adv-x="539" d="M20 426v201l142 131v731h215v-539l141 131v-200l-141 -131v-750h-215v557z" />
+<glyph unicode="&#x143;" horiz-adv-x="1399" d="M166 0v1384h317l523 -1011v1011h227v-1384h-277l-563 1087v-1087h-227zM549 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x144;" horiz-adv-x="1190" d="M158 0v1049h215v-146q34 34 76 66t88.5 56.5t96 39t99.5 14.5q88 0 147 -25t94.5 -73.5t50.5 -119t15 -161.5v-700h-215v598q0 78 -5 132.5t-21.5 88.5t-46.5 49t-80 15q-33 0 -70.5 -13t-76 -35.5t-77.5 -52t-75 -61.5v-721h-215zM465 1208l184 361h274l-284 -361h-174z " />
+<glyph unicode="&#x145;" horiz-adv-x="1399" d="M166 0v1384h317l523 -1011v1011h227v-1384h-277l-563 1087v-1087h-227zM577 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x146;" horiz-adv-x="1190" d="M158 0v1049h215v-146q34 34 76 66t88.5 56.5t96 39t99.5 14.5q88 0 147 -25t94.5 -73.5t50.5 -119t15 -161.5v-700h-215v598q0 78 -5 132.5t-21.5 88.5t-46.5 49t-80 15q-33 0 -70.5 -13t-76 -35.5t-77.5 -52t-75 -61.5v-721h-215zM444 -246q0 32 7 57.5t24 43t44.5 27 t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x147;" horiz-adv-x="1399" d="M166 0v1384h317l523 -1011v1011h227v-1384h-277l-563 1087v-1087h-227zM348 1905h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x148;" horiz-adv-x="1190" d="M158 0v1049h215v-146q34 34 76 66t88.5 56.5t96 39t99.5 14.5q88 0 147 -25t94.5 -73.5t50.5 -119t15 -161.5v-700h-215v598q0 78 -5 132.5t-21.5 88.5t-46.5 49t-80 15q-33 0 -70.5 -13t-76 -35.5t-77.5 -52t-75 -61.5v-721h-215zM264 1569h181l163 -207l168 207h179 l-232 -361h-227z" />
+<glyph unicode="&#x149;" horiz-adv-x="1366" d="M-22 1276q0 32 7 57.5t24 43t44.5 27t68.5 9.5q77 0 109 -41t32 -117q0 -60 -11 -118t-28.5 -109.5t-39.5 -94t-44 -71.5h-147q27 36 46 78t32 81t19 71.5t7 50.5q-63 2 -91 33.5t-28 99.5zM334 0v1049h215v-146q34 34 76 66t88.5 56.5t96 39t99.5 14.5q88 0 147 -25 t94.5 -73.5t50.5 -119t15 -161.5v-700h-215v598q0 78 -5 132.5t-21.5 88.5t-46.5 49t-80 15q-33 0 -70.5 -13t-76 -35.5t-77.5 -52t-75 -61.5v-721h-215z" />
+<glyph unicode="&#x14a;" horiz-adv-x="1399" d="M166 0v1384h317l523 -956v956h227v-1429q0 -91 -18.5 -157t-59 -109t-105 -63.5t-157.5 -20.5q-18 0 -42.5 2t-52 5.5t-56.5 9t-54 13.5l49 183q72 -29 152 -29q40 0 64.5 12t38 37.5t18 65.5t4.5 96l-621 1087v-1087h-227z" />
+<glyph unicode="&#x14b;" horiz-adv-x="1190" d="M158 0v1049h215v-146q34 34 76 66t88.5 56.5t96 39t99.5 14.5q88 0 147 -25t94.5 -73.5t50.5 -119t15 -161.5v-745q0 -91 -17.5 -157t-57.5 -109t-103.5 -63.5t-156.5 -20.5q-18 0 -43 2t-53 5.5t-56.5 9t-52.5 13.5l49 183q35 -14 72 -21.5t79 -7.5q40 0 64.5 13t38 40 t18 68t4.5 96v592q0 78 -5 132.5t-21.5 88.5t-46.5 49t-80 15q-33 0 -70.5 -13t-76 -35.5t-77.5 -52t-75 -61.5v-721h-215z" />
+<glyph unicode="&#x14c;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32 t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5zM365 1591v162h641v-162h-641z" />
+<glyph unicode="&#x14d;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM260 1255v162h641v-162h-641zM326 522q0 -182 61.5 -274 t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x14e;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM335 1835h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5 t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32 q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5z" />
+<glyph unicode="&#x14f;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM245 1499h158q14 -56 61.5 -85.5t122.5 -29.5 q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x150;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32 t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5zM379 1544l185 361h274l-285 -361h-174zM762 1544l183 361h276l-287 -361h-172z" />
+<glyph unicode="&#x151;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM286 1208l185 361h274l-285 -361h-174zM326 522 q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM669 1208l183 361h276l-287 -361h-172z" />
<glyph unicode="&#x152;" horiz-adv-x="1884" d="M113 692q0 171 34.5 305t108 226.5t188 141t273.5 48.5q62 0 119 -7.5t116 -21.5h820v-208h-586v-355h495v-209h-495v-399h586v-213h-818q-49 -14 -111.5 -21.5t-125.5 -7.5q-160 0 -274 49t-187.5 142t-108 226.5t-34.5 303.5zM354 692q0 -129 20 -225.5t64.5 -160.5 t116 -96t174.5 -32q71 0 121.5 13t99.5 40v920q-38 23 -94 39t-127 16q-104 0 -175.5 -32t-115.5 -96t-64 -160.5t-20 -225.5z" />
<glyph unicode="&#x153;" horiz-adv-x="1847" d="M104 522q0 129 28 232t86.5 175.5t148.5 111t215 38.5q127 0 222 -46.5t150 -125.5q54 79 144.5 125.5t224.5 46.5q114 0 195.5 -35t133 -99t75.5 -154t24 -199v-113h-690q1 -74 15 -133.5t46 -101.5t85.5 -65t133.5 -23q73 0 128 24.5t102 83.5l166 -112 q-30 -45 -67.5 -79t-85 -57t-107 -35t-134.5 -12q-73 0 -132.5 12t-107 34.5t-84.5 54t-65 71.5q-60 -81 -150.5 -126.5t-215.5 -45.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q83 0 133.5 32t78.5 83t37 116t9 131t-8 132.5 t-35 120t-78 87t-137 33.5q-137 0 -199.5 -91t-62.5 -278zM1065 637h473q0 131 -55 199.5t-172 68.5q-61 0 -104.5 -17t-72.5 -51t-45.5 -84t-23.5 -116z" />
+<glyph unicode="&#x154;" horiz-adv-x="1260" d="M166 0v1384h467q124 0 217.5 -21.5t155.5 -69t93 -124t31 -186.5q0 -98 -21.5 -169t-60 -120t-91.5 -77.5t-115 -41.5l372 -575h-270l-352 545h-193v-545h-233zM399 750h219q79 0 131.5 11.5t84 37.5t44.5 68t13 104q0 61 -15 101t-46.5 64t-81 34t-117.5 10h-232v-430z M463 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x155;" horiz-adv-x="825" d="M158 0v1049h215v-160q34 36 70 68t75.5 56t82.5 38t91 14q37 0 63.5 -5.5t45.5 -15.5l-43 -206q-16 6 -41.5 11t-52.5 5q-44 0 -83 -12t-74.5 -32.5t-68.5 -48.5t-65 -59v-702h-215zM292 1208l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x156;" horiz-adv-x="1260" d="M166 0v1384h467q124 0 217.5 -21.5t155.5 -69t93 -124t31 -186.5q0 -98 -21.5 -169t-60 -120t-91.5 -77.5t-115 -41.5l372 -575h-270l-352 545h-193v-545h-233zM399 750h219q79 0 131.5 11.5t84 37.5t44.5 68t13 104q0 61 -15 101t-46.5 64t-81 34t-117.5 10h-232v-430z M501 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x157;" horiz-adv-x="825" d="M124 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5zM158 0v1049h215v-160q34 36 70 68t75.5 56t82.5 38t91 14q37 0 63.5 -5.5t45.5 -15.5l-43 -206 q-16 6 -41.5 11t-52.5 5q-44 0 -83 -12t-74.5 -32.5t-68.5 -48.5t-65 -59v-702h-215z" />
+<glyph unicode="&#x158;" horiz-adv-x="1260" d="M166 0v1384h467q124 0 217.5 -21.5t155.5 -69t93 -124t31 -186.5q0 -98 -21.5 -169t-60 -120t-91.5 -77.5t-115 -41.5l372 -575h-270l-352 545h-193v-545h-233zM272 1905h181l163 -207l168 207h179l-232 -361h-227zM399 750h219q79 0 131.5 11.5t84 37.5t44.5 68t13 104 q0 61 -15 101t-46.5 64t-81 34t-117.5 10h-232v-430z" />
+<glyph unicode="&#x159;" horiz-adv-x="825" d="M111 1569h181l163 -207l168 207h179l-232 -361h-227zM158 0v1049h215v-160q34 36 70 68t75.5 56t82.5 38t91 14q37 0 63.5 -5.5t45.5 -15.5l-43 -206q-16 6 -41.5 11t-52.5 5q-44 0 -83 -12t-74.5 -32.5t-68.5 -48.5t-65 -59v-702h-215z" />
+<glyph unicode="&#x15a;" horiz-adv-x="1227" d="M80 236l184 133q25 -39 55.5 -73.5t71 -60.5t94.5 -41.5t125 -15.5q53 0 103.5 10t89.5 33t62.5 60t23.5 92q0 52 -22.5 87t-60.5 59t-89 40t-109 31q-106 27 -197 55.5t-158 72.5t-105.5 112t-38.5 174q0 94 32 169.5t94 129t154.5 82t212.5 28.5q90 0 164.5 -16.5 t135 -48t108.5 -78t84 -105.5l-181 -135q-55 88 -130 132t-183 44q-117 0 -185.5 -48t-68.5 -136q0 -44 18.5 -73.5t57 -51.5t97 -39.5t138.5 -36.5q62 -15 120.5 -32t111 -39.5t96.5 -53t75.5 -73.5t49.5 -100.5t18 -133.5q0 -117 -41.5 -196.5t-112.5 -129t-165.5 -71 t-200.5 -21.5q-112 0 -196 21t-147 57t-107.5 84t-77.5 103zM467 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x15b;" horiz-adv-x="1008" d="M88 154l164 110q43 -63 106 -90t142 -27q39 0 76 6t65.5 21.5t46 41.5t17.5 65q0 30 -13 51t-41 37.5t-72.5 31t-107.5 29.5q-71 18 -136 41t-114.5 60.5t-79.5 94t-30 140.5q0 67 25 124t75.5 99t125 66t173.5 24q69 0 129.5 -13t110 -37t87.5 -57.5t62 -74.5l-164 -111 q-15 22 -36 43t-49.5 37t-64 25.5t-79.5 9.5q-84 0 -134 -32.5t-50 -94.5q0 -29 10.5 -49t34 -36t61.5 -28.5t92 -25.5q91 -23 164.5 -49t124.5 -64t78.5 -93.5t27.5 -137.5q0 -87 -33.5 -148t-90 -100t-130.5 -56.5t-155 -17.5q-82 0 -148.5 14t-118.5 38.5t-89.5 58.5 t-61.5 74zM372 1208l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x15c;" horiz-adv-x="1227" d="M80 236l184 133q25 -39 55.5 -73.5t71 -60.5t94.5 -41.5t125 -15.5q53 0 103.5 10t89.5 33t62.5 60t23.5 92q0 52 -22.5 87t-60.5 59t-89 40t-109 31q-106 27 -197 55.5t-158 72.5t-105.5 112t-38.5 174q0 94 32 169.5t94 129t154.5 82t212.5 28.5q90 0 164.5 -16.5 t135 -48t108.5 -78t84 -105.5l-181 -135q-55 88 -130 132t-183 44q-117 0 -185.5 -48t-68.5 -136q0 -44 18.5 -73.5t57 -51.5t97 -39.5t138.5 -36.5q62 -15 120.5 -32t111 -39.5t96.5 -53t75.5 -73.5t49.5 -100.5t18 -133.5q0 -117 -41.5 -196.5t-112.5 -129t-165.5 -71 t-200.5 -21.5q-112 0 -196 21t-147 57t-107.5 84t-77.5 103zM256 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x15d;" horiz-adv-x="1008" d="M88 154l164 110q43 -63 106 -90t142 -27q39 0 76 6t65.5 21.5t46 41.5t17.5 65q0 30 -13 51t-41 37.5t-72.5 31t-107.5 29.5q-71 18 -136 41t-114.5 60.5t-79.5 94t-30 140.5q0 67 25 124t75.5 99t125 66t173.5 24q69 0 129.5 -13t110 -37t87.5 -57.5t62 -74.5l-164 -111 q-15 22 -36 43t-49.5 37t-64 25.5t-79.5 9.5q-84 0 -134 -32.5t-50 -94.5q0 -29 10.5 -49t34 -36t61.5 -28.5t92 -25.5q91 -23 164.5 -49t124.5 -64t78.5 -93.5t27.5 -137.5q0 -87 -33.5 -148t-90 -100t-130.5 -56.5t-155 -17.5q-82 0 -148.5 14t-118.5 38.5t-89.5 58.5 t-61.5 74zM164 1208l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x15e;" horiz-adv-x="1227" d="M80 236l184 133q25 -39 55.5 -73.5t71 -60.5t94.5 -41.5t125 -15.5q53 0 103.5 10t89.5 33t62.5 60t23.5 92q0 52 -22.5 87t-60.5 59t-89 40t-109 31q-106 27 -197 55.5t-158 72.5t-105.5 112t-38.5 174q0 94 32 169.5t94 129t154.5 82t212.5 28.5q90 0 164.5 -16.5 t135 -48t108.5 -78t84 -105.5l-181 -135q-55 88 -130 132t-183 44q-117 0 -185.5 -48t-68.5 -136q0 -44 18.5 -73.5t57 -51.5t97 -39.5t138.5 -36.5q62 -15 120.5 -32t111 -39.5t96.5 -53t75.5 -73.5t49.5 -100.5t18 -133.5q0 -104 -33 -178t-91 -123.5t-136 -76.5t-168 -36 l-2 -4q75 -18 115.5 -66t40.5 -116q0 -88 -69 -136t-203 -48q-44 0 -83.5 4.5t-72 11t-57 14.5t-39.5 15l61 123q18 -7 41.5 -14t49 -12.5t51.5 -9t51 -3.5q55 0 81.5 14.5t26.5 48.5q0 22 -15 37.5t-39.5 25.5t-57 14.5t-66.5 6.5l45 92q-100 5 -175.5 27t-133 57.5 t-98.5 81t-72 97.5z" />
+<glyph unicode="&#x15f;" horiz-adv-x="1008" d="M88 154l164 110q43 -63 106 -90t142 -27q39 0 76 6t65.5 21.5t46 41.5t17.5 65q0 30 -13 51t-41 37.5t-72.5 31t-107.5 29.5q-71 18 -136 41t-114.5 60.5t-79.5 94t-30 140.5q0 67 25 124t75.5 99t125 66t173.5 24q69 0 129.5 -13t110 -37t87.5 -57.5t62 -74.5l-164 -111 q-15 22 -36 43t-49.5 37t-64 25.5t-79.5 9.5q-84 0 -134 -32.5t-50 -94.5q0 -29 10.5 -49t34 -36t61.5 -28.5t92 -25.5q91 -23 164.5 -49t124.5 -64t78.5 -93.5t27.5 -137.5q0 -74 -24.5 -129t-67 -93.5t-100 -61.5t-123.5 -32l-2 -4q74 -18 115 -66t41 -116 q0 -88 -69.5 -136t-203.5 -48q-44 0 -83 4.5t-72 11t-57.5 14.5t-39.5 15l62 123q18 -7 41.5 -14t48.5 -12.5t51.5 -9t50.5 -3.5q56 0 82.5 14.5t26.5 48.5q0 22 -15 37.5t-39.5 25.5t-57 14.5t-66.5 6.5l45 90q-72 3 -131 18.5t-105 39.5t-79.5 56t-55.5 69z" />
+<glyph unicode="&#x160;" horiz-adv-x="1227" d="M80 236l184 133q25 -39 55.5 -73.5t71 -60.5t94.5 -41.5t125 -15.5q53 0 103.5 10t89.5 33t62.5 60t23.5 92q0 52 -22.5 87t-60.5 59t-89 40t-109 31q-106 27 -197 55.5t-158 72.5t-105.5 112t-38.5 174q0 94 32 169.5t94 129t154.5 82t212.5 28.5q90 0 164.5 -16.5 t135 -48t108.5 -78t84 -105.5l-181 -135q-55 88 -130 132t-183 44q-117 0 -185.5 -48t-68.5 -136q0 -44 18.5 -73.5t57 -51.5t97 -39.5t138.5 -36.5q62 -15 120.5 -32t111 -39.5t96.5 -53t75.5 -73.5t49.5 -100.5t18 -133.5q0 -117 -41.5 -196.5t-112.5 -129t-165.5 -71 t-200.5 -21.5q-112 0 -196 21t-147 57t-107.5 84t-77.5 103zM245 1905h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x161;" horiz-adv-x="1008" d="M88 154l164 110q43 -63 106 -90t142 -27q39 0 76 6t65.5 21.5t46 41.5t17.5 65q0 30 -13 51t-41 37.5t-72.5 31t-107.5 29.5q-71 18 -136 41t-114.5 60.5t-79.5 94t-30 140.5q0 67 25 124t75.5 99t125 66t173.5 24q69 0 129.5 -13t110 -37t87.5 -57.5t62 -74.5l-164 -111 q-15 22 -36 43t-49.5 37t-64 25.5t-79.5 9.5q-84 0 -134 -32.5t-50 -94.5q0 -29 10.5 -49t34 -36t61.5 -28.5t92 -25.5q91 -23 164.5 -49t124.5 -64t78.5 -93.5t27.5 -137.5q0 -87 -33.5 -148t-90 -100t-130.5 -56.5t-155 -17.5q-82 0 -148.5 14t-118.5 38.5t-89.5 58.5 t-61.5 74zM150 1569h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x162;" horiz-adv-x="1194" d="M37 1171v213h1118v-213h-442v-1171h-25l-12 -27q72 -18 112.5 -67t40.5 -117q0 -88 -68 -136t-202 -48q-45 0 -84.5 4.5t-72 11t-57 14.5t-38.5 15l60 123q19 -7 42.5 -14t48.5 -12.5t51 -9t50 -3.5q56 0 82.5 14.5t26.5 48.5q0 22 -15 38t-39.5 26t-57 15t-67.5 7 l60 117h-70v1171h-442z" />
+<glyph unicode="&#x163;" horiz-adv-x="733" d="M39 874v175h141v292h215v-292h254v-175h-254v-524q0 -56 6.5 -94.5t21.5 -62.5t39.5 -35t59.5 -11t74 8.5t68 20.5l45 -176q-39 -11 -83 -19t-89 -10q66 -21 103.5 -69t37.5 -113q0 -88 -69 -136t-203 -48q-44 0 -83.5 4.5t-72 11t-57 14.5t-39.5 15l61 123 q18 -7 41.5 -14t49 -12.5t51.5 -9t51 -3.5q55 0 81.5 14.5t26.5 48.5q0 22 -15 38t-39.5 26.5t-57 16t-66.5 7.5l49 97q-109 23 -158 105t-49 230v557h-141z" />
+<glyph unicode="&#x164;" horiz-adv-x="1194" d="M37 1171v213h1118v-213h-442v-1171h-234v1171h-442zM252 1905h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x165;" horiz-adv-x="733" d="M39 874v175h141v292h215v-292h254v-175h-254v-524q0 -56 6.5 -94.5t21.5 -62.5t39.5 -35t59.5 -11t74 8.5t68 20.5l45 -176q-45 -14 -101.5 -22.5t-107.5 -8.5q-86 0 -146.5 20.5t-99 63t-56.5 108.5t-18 156v557h-141zM494 1128l61 361h242l-162 -361h-141z" />
+<glyph unicode="&#x166;" horiz-adv-x="1194" d="M37 1171v213h1118v-213h-442v-342h205v-161h-205v-668h-234v668h-203v161h203v342h-442z" />
+<glyph unicode="&#x167;" horiz-adv-x="733" d="M20 557v162h160v155h-141v175h141v292h215v-292h254v-175h-254v-155h267v-162h-267v-207q0 -56 6.5 -94.5t21.5 -62.5t39.5 -35t59.5 -11t74 8.5t68 20.5l45 -176q-45 -14 -101.5 -22.5t-107.5 -8.5q-86 0 -146.5 20.5t-99 63t-56.5 108.5t-18 156v240h-160z" />
+<glyph unicode="&#x168;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM323 1561q3 62 18.5 115.5t45.5 92.5 t75 61t107 22q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42 t-4 -46.5h-152z" />
+<glyph unicode="&#x169;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM207 1225q3 62 18.5 115.5t45.5 92.5 t75 61t107 22q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42 t-4 -46.5h-152z" />
+<glyph unicode="&#x16a;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM395 1591v162h641v-162h-641z" />
+<glyph unicode="&#x16b;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM270 1255v162h641v-162h-641z" />
+<glyph unicode="&#x16c;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM374 1835h158q14 -56 61.5 -85.5 t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5z" />
+<glyph unicode="&#x16d;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM247 1499h158q14 -56 61.5 -85.5 t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5z" />
+<glyph unicode="&#x16e;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM499 1704q0 97 52.5 154t160.5 57 q111 0 163 -57t52 -154q0 -100 -54 -155.5t-161 -55.5q-55 0 -95 15t-66.5 43t-39 66.5t-12.5 86.5zM620 1704q0 -43 21.5 -69.5t70.5 -26.5q50 0 71.5 25t21.5 71q0 48 -24 71t-69 23t-68.5 -24.5t-23.5 -69.5z" />
+<glyph unicode="&#x16f;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM358 1368q0 97 52.5 154t160.5 57 q111 0 163 -57t52 -154q0 -100 -54 -155.5t-161 -55.5q-55 0 -95 15t-66.5 43t-39 66.5t-12.5 86.5zM479 1368q0 -43 21.5 -69.5t70.5 -26.5q50 0 71.5 25t21.5 71q0 48 -24 71t-69 23t-68.5 -24.5t-23.5 -69.5z" />
+<glyph unicode="&#x170;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM409 1544l185 361h274l-285 -361h-174z M792 1544l183 361h276l-287 -361h-172z" />
+<glyph unicode="&#x171;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM299 1208l185 361h274l-285 -361h-174z M682 1208l183 361h276l-287 -361h-172z" />
+<glyph unicode="&#x172;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -156 -25 -266.5t-81 -182.5q-32 -49 -59 -93.5t-46.5 -82.5t-31 -69t-11.5 -54q0 -32 18.5 -46.5t49.5 -14.5q25 0 54 8.5t57 25.5 l75 -133q-52 -31 -105.5 -48t-113.5 -17q-46 0 -84 10.5t-65.5 32.5t-42.5 54.5t-15 76.5q0 57 18.5 107t49.5 100q-42 -10 -88 -13.5t-98 -3.5q-146 0 -249.5 32.5t-169 105t-96 188.5t-30.5 283z" />
+<glyph unicode="&#x173;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049q-74 -19 -123 -39t-78 -40.5t-41 -41.5t-12 -43q0 -34 18.5 -50.5t47.5 -16.5q26 0 55.5 8.5t56.5 25.5l74 -133q-52 -31 -105.5 -48t-113.5 -17 q-45 0 -83 11t-65.5 33.5t-43 56.5t-15.5 81q0 84 57 146t156 100v112q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5z" />
+<glyph unicode="&#x174;" horiz-adv-x="1794" d="M55 1384h232l239 -1011l246 1011h244l250 -1017l243 1017h230l-346 -1384h-254l-246 1012l-248 -1012h-252zM553 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x175;" horiz-adv-x="1520" d="M45 1049h223l170 -738l242 738h170l246 -736l164 736h215l-271 -1049h-196l-246 735l-248 -735h-197zM419 1208l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x176;" horiz-adv-x="1167" d="M29 1384h258l299 -626l303 626h248l-437 -854v-530h-235v524zM239 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x177;" horiz-adv-x="1063" d="M-12 -365l49 183q35 -14 74.5 -21.5t76.5 -7.5q30 0 56.5 10.5t51 34t47 61.5t44.5 93l31 75l-381 986h227l268 -719l273 719h221l-451 -1125q-35 -86 -71 -146.5t-81 -99t-101 -56t-129 -17.5q-50 0 -105 8t-100 22zM185 1208l232 361h227l232 -361h-181l-164 205 l-167 -205h-179z" />
<glyph unicode="&#x178;" horiz-adv-x="1167" d="M29 1384h258l299 -626l303 626h248l-437 -854v-530h-235v524zM250 1661q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM669 1661q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5 q-72 0 -97.5 31t-25.5 88z" />
-<glyph unicode="&#x2c6;" horiz-adv-x="1065" d="M186 1208l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
-<glyph unicode="&#x2dc;" horiz-adv-x="1065" d="M139 1225q3 62 18.5 115.5t45.5 92.5t75 61t107 22q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11 q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152z" />
-<glyph unicode="&#x2000;" horiz-adv-x="957" />
-<glyph unicode="&#x2001;" horiz-adv-x="1915" />
-<glyph unicode="&#x2002;" horiz-adv-x="957" />
-<glyph unicode="&#x2003;" horiz-adv-x="1915" />
-<glyph unicode="&#x2004;" horiz-adv-x="638" />
-<glyph unicode="&#x2005;" horiz-adv-x="478" />
-<glyph unicode="&#x2006;" horiz-adv-x="319" />
-<glyph unicode="&#x2007;" horiz-adv-x="319" />
-<glyph unicode="&#x2008;" horiz-adv-x="239" />
-<glyph unicode="&#x2009;" horiz-adv-x="383" />
-<glyph unicode="&#x200a;" horiz-adv-x="106" />
+<glyph unicode="&#x179;" horiz-adv-x="1155" d="M82 0v207l682 964h-651v213h929v-196l-690 -975h707v-213h-977zM413 1542l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x17a;" horiz-adv-x="932" d="M70 0v160l518 714h-506v175h764v-156l-520 -719h536v-174h-792zM313 1208l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x17b;" horiz-adv-x="1155" d="M82 0v207l682 964h-651v213h929v-196l-690 -975h707v-213h-977zM411 1663q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x17c;" horiz-adv-x="932" d="M70 0v160l518 714h-506v175h764v-156l-520 -719h536v-174h-792zM318 1329q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x17d;" horiz-adv-x="1155" d="M82 0v207l682 964h-651v213h929v-196l-690 -975h707v-213h-977zM204 1903h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x17e;" horiz-adv-x="932" d="M70 0v160l518 714h-506v175h764v-156l-520 -719h536v-174h-792zM109 1569h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x17f;" horiz-adv-x="602" d="M53 874v175h129v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-1151h-215v874h-129z" />
+<glyph unicode="&#x192;" horiz-adv-x="1069" d="M-168 -362l62 184q42 -14 81 -22.5t84 -8.5q36 0 61 8.5t43 30t31 58.5t25 94l182 892h-151l35 175h151l27 122q19 88 49.5 153.5t76.5 109t110 65t151 21.5q60 0 117.5 -11.5t95.5 -23.5l-70 -189q-48 16 -86.5 25.5t-79.5 9.5q-31 0 -53.5 -6t-40 -24t-30.5 -50 t-25 -84l-25 -118h205l-33 -175h-207l-194 -946q-12 -60 -36.5 -118.5t-67 -104.5t-108 -74t-159.5 -28q-31 0 -62 3t-60 8t-54.5 11.5t-44.5 12.5z" />
+<glyph unicode="&#x1a0;" horiz-adv-x="1513" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49q100 0 181 -21t144 -61t109.5 -98.5t77.5 -134.5h31q39 0 65.5 9.5t43 30.5t23.5 54.5t7 81.5v172h186v-172q0 -78 -16 -139t-51.5 -103.5t-92 -65t-137.5 -22.5h-14q11 -57 17 -120t6 -132q0 -170 -32.5 -303.5 t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5 t-18 -225.5z" />
+<glyph unicode="&#x1a1;" horiz-adv-x="1300" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q167 0 272 -67.5t156 -188.5q75 0 105 41t30 135v131h186v-131q0 -74 -16 -132.5t-49.5 -101t-86.5 -67t-126 -28.5q5 -34 7.5 -72t2.5 -76q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39 t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x1af;" horiz-adv-x="1573" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-286h29q39 0 66 9.5t43 30.5t23 54.5t7 81.5v172h187v-172q0 -78 -18 -139t-56 -103.5t-98 -65t-144 -22.5h-39v-366q0 -168 -30.5 -284 t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283z" />
+<glyph unicode="&#x1b0;" horiz-adv-x="1339" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-226h23q39 0 65.5 9.5t42 30.5t22.5 54.5t7 81.5v131h184v-131q0 -77 -17 -138t-54.5 -103.5t-96.5 -65t-143 -22.5h-33v-670h-215v145q-35 -35 -76.5 -67 t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5z" />
+<glyph unicode="&#x1cd;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM311 1905h181l163 -207l168 207h179l-232 -361h-227zM444 528h412l-205 623z" />
+<glyph unicode="&#x1ce;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM213 1569h181l163 -207l168 207h179l-232 -361h-227zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36 t-55.5 -57.5t-19 -84.5z" />
+<glyph unicode="&#x1cf;" horiz-adv-x="821" d="M64 1905h181l163 -207l168 207h179l-232 -361h-227zM102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617z" />
+<glyph unicode="&#x1d0;" horiz-adv-x="530" d="M-79 1569h181l163 -207l168 207h179l-232 -361h-227zM158 0v1049h215v-1049h-215z" />
+<glyph unicode="&#x1d1;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM333 1905h181l163 -207l168 207h179l-232 -361h-227zM344 692 q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5z" />
+<glyph unicode="&#x1d2;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM239 1569h181l163 -207l168 207h179l-232 -361h-227z M326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x1d3;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM368 1905h181l163 -207l168 207h179 l-232 -361h-227z" />
+<glyph unicode="&#x1d4;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM247 1569h181l163 -207l168 207h179 l-232 -361h-227z" />
+<glyph unicode="&#x1d5;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM375 1624q0 62 27 90.5t95 28.5 q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM389 1815v161h641v-161h-641zM794 1624q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph unicode="&#x1d6;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM260 1288q0 62 27 90.5t95 28.5 q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM274 1479v161h641v-161h-641zM679 1288q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph unicode="&#x1d7;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM377 1624q0 62 27 90.5t95 28.5 q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM612 1767l123 301h276l-231 -301h-168zM796 1624q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8t-38 23.5t-20 37.5t-5.5 50z " />
+<glyph unicode="&#x1d8;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM258 1288q0 62 27 90.5t95 28.5 q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM493 1432l123 301h276l-231 -301h-168zM677 1288q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8t-38 23.5t-20 37.5t-5.5 50z " />
+<glyph unicode="&#x1d9;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM368 2068h181l163 -155l168 155h179 l-232 -290h-227zM379 1624q0 62 27 89.5t95 27.5q71 0 99 -27t28 -90q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM798 1624q0 62 27.5 89.5t95.5 27.5q71 0 99 -27t28 -90q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x1da;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM249 1733h181l163 -156l168 156h179 l-232 -291h-227zM260 1288q0 62 27 89.5t95 27.5q71 0 99 -27t28 -90q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM679 1288q0 62 27.5 89.5t95.5 27.5q71 0 99 -27t28 -90q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x1db;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM375 1624q0 62 27 90.5t95 28.5 q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM407 2068h275l123 -301h-168zM794 1624q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph unicode="&#x1dc;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM258 1288q0 62 27 90.5t95 28.5 q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM290 1733h275l123 -301h-168zM677 1288q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph unicode="&#x1fa;" horiz-adv-x="1313" d="M39 0l453 1346q-26 24 -38 58t-12 81q0 97 52.5 153t160.5 56q111 0 163 -56t52 -153q0 -93 -49 -142l453 -1343h-242l-106 319h-549l-105 -319h-233zM444 528h412l-205 623zM557 1749l129 276h275l-230 -276h-174zM563 1485q0 -44 21.5 -68t70.5 -24q50 0 71.5 23.5 t21.5 68.5q0 48 -24 71t-69 23t-68.5 -24t-23.5 -70z" />
+<glyph unicode="&#x1fb;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM316 1366q0 97 52.5 154t160.5 57q111 0 163 -57t52 -154q0 -100 -54 -155.5t-161 -55.5q-55 0 -95 15t-66.5 43t-39 66.5t-12.5 86.5zM317 299q0 -83 44 -117.5t124 -34.5 q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5zM392 1632l184 361h274l-284 -361h-174zM437 1366q0 -43 21.5 -69.5t70.5 -26.5q50 0 71.5 25t21.5 71q0 48 -24 71t-69 23t-68.5 -24.5t-23.5 -69.5z" />
+<glyph unicode="&#x1fc;" horiz-adv-x="1778" d="M33 0l542 1384h1090v-208h-586v-355h498v-209h-498v-399h586v-213h-819v371h-430l-146 -371h-237zM494 580h352v596h-121zM852 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x1fd;" horiz-adv-x="1755" d="M96 301q0 93 33 156t89.5 103t132.5 60.5t163 28.5l240 23v49q0 51 -15.5 85.5t-44.5 55.5t-71.5 30t-96.5 9t-93.5 -9.5t-68.5 -25.5t-48.5 -36t-32.5 -42l-170 109q20 34 53 67t83.5 58.5t120 41t162.5 15.5q268 0 357 -137q54 65 137 101t201 36q117 0 199 -35 t133.5 -99t75.5 -154t24 -199v-113h-690q1 -78 16 -138t47 -101t84 -62.5t127 -21.5q40 0 73 6t61 19t53 33.5t49 49.5l166 -112q-30 -45 -67.5 -79t-85 -57t-107 -35t-134.5 -12q-143 0 -246.5 43t-162.5 131q-45 -38 -95 -69.5t-103 -55t-109 -36.5t-113 -13 q-77 0 -137.5 23.5t-102.5 67t-64 105t-22 136.5zM317 297q0 -40 11.5 -68.5t32.5 -46.5t50 -26.5t64 -8.5q74 0 152 34.5t153 92.5q-14 42 -20 98.5t-6 137.5l-150 -14q-68 -6 -121.5 -19t-90.5 -35.5t-56 -58t-19 -86.5zM740 1208l184 361h274l-284 -361h-174zM973 637 h473q0 131 -55.5 199.5t-173.5 68.5q-116 0 -173 -67.5t-71 -200.5z" />
+<glyph unicode="&#x1fe;" horiz-adv-x="1364" d="M47 -115l189 277q-70 93 -102 226t-32 304q0 170 33 304t103.5 226.5t180 141.5t263.5 49q108 0 194 -25t152 -73l119 174h174l-188 -277q66 -92 97.5 -222.5t31.5 -297.5q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49q-209 0 -340 90l-121 -176h-174zM344 692 q0 -97 10 -174t33 -137l512 747q-77 78 -217 78q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5zM469 246q38 -35 91.5 -51.5t121.5 -16.5q92 0 156 31.5t104 95.5t58 160.5t18 226.5q0 184 -37 299zM547 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x1ff;" horiz-adv-x="1174" d="M104 -76l123 182q-65 73 -94 178t-29 238q0 129 28 232t86.5 175.5t150 111t219.5 38.5q153 0 256 -59l71 104h162l-129 -190q62 -72 91.5 -176.5t29.5 -235.5q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-153 0 -254 56l-68 -101h-162zM326 522 q0 -68 7.5 -123t24.5 -98l373 551q-28 20 -63 29.5t-80 9.5q-137 0 -199.5 -91t-62.5 -278zM439 1208l184 361h274l-284 -361h-174zM446 190q57 -34 142 -34q135 0 196.5 92t61.5 274q0 65 -6.5 118.5t-22.5 96.5z" />
+<glyph unicode="&#x218;" horiz-adv-x="1227" d="M80 236l184 133q25 -39 55.5 -73.5t71 -60.5t94.5 -41.5t125 -15.5q53 0 103.5 10t89.5 33t62.5 60t23.5 92q0 52 -22.5 87t-60.5 59t-89 40t-109 31q-106 27 -197 55.5t-158 72.5t-105.5 112t-38.5 174q0 94 32 169.5t94 129t154.5 82t212.5 28.5q90 0 164.5 -16.5 t135 -48t108.5 -78t84 -105.5l-181 -135q-55 88 -130 132t-183 44q-117 0 -185.5 -48t-68.5 -136q0 -44 18.5 -73.5t57 -51.5t97 -39.5t138.5 -36.5q62 -15 120.5 -32t111 -39.5t96.5 -53t75.5 -73.5t49.5 -100.5t18 -133.5q0 -117 -41.5 -196.5t-112.5 -129t-165.5 -71 t-200.5 -21.5q-112 0 -196 21t-147 57t-107.5 84t-77.5 103zM508 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x219;" horiz-adv-x="1008" d="M88 154l164 110q43 -63 106 -90t142 -27q39 0 76 6t65.5 21.5t46 41.5t17.5 65q0 30 -13 51t-41 37.5t-72.5 31t-107.5 29.5q-71 18 -136 41t-114.5 60.5t-79.5 94t-30 140.5q0 67 25 124t75.5 99t125 66t173.5 24q69 0 129.5 -13t110 -37t87.5 -57.5t62 -74.5l-164 -111 q-15 22 -36 43t-49.5 37t-64 25.5t-79.5 9.5q-84 0 -134 -32.5t-50 -94.5q0 -29 10.5 -49t34 -36t61.5 -28.5t92 -25.5q91 -23 164.5 -49t124.5 -64t78.5 -93.5t27.5 -137.5q0 -87 -33.5 -148t-90 -100t-130.5 -56.5t-155 -17.5q-82 0 -148.5 14t-118.5 38.5t-89.5 58.5 t-61.5 74zM383 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x21a;" horiz-adv-x="1194" d="M37 1171v213h1118v-213h-442v-1171h-234v1171h-442zM465 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x21b;" horiz-adv-x="733" d="M39 874v175h141v292h215v-292h254v-175h-254v-524q0 -56 6.5 -94.5t21.5 -62.5t39.5 -35t59.5 -11t74 8.5t68 20.5l45 -176q-45 -14 -101.5 -22.5t-107.5 -8.5q-86 0 -146.5 20.5t-99 63t-56.5 108.5t-18 156v557h-141zM299 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5 q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#x237;" horiz-adv-x="549" d="M-154 -365l50 183q35 -14 72 -21.5t79 -7.5q41 0 65.5 13t38 40t17.5 68t4 96v1043h215v-1094q0 -91 -17.5 -157t-57.5 -109t-104 -63.5t-157 -20.5q-18 0 -42.5 2t-52 5.5t-56.5 9t-54 13.5z" />
+<glyph unicode="&#x2c0;" horiz-adv-x="1004" d="M0 1186q30 53 71 95t95 71.5t122.5 45t153.5 15.5q99 0 184.5 -23t149.5 -72t100.5 -124t36.5 -178q0 -98 -31 -172t-83.5 -133t-123 -106.5t-149.5 -92.5v-512h-217v612q99 49 170 93.5t116.5 90t67 95.5t21.5 110q0 47 -16 87t-46.5 69.5t-75 46.5t-102.5 17 q-98 0 -157 -38.5t-99 -105.5z" />
+<glyph unicode="&#x2c6;" d="M186 1208l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph unicode="&#x2c7;" d="M186 1569h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph unicode="&#x2c9;" d="M211 1255v162h641v-162h-641z" />
+<glyph unicode="&#x2d8;" d="M188 1499h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5z" />
+<glyph unicode="&#x2d9;" d="M403 1329q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x2da;" d="M317 1366q0 97 52.5 154t160.5 57q111 0 163 -57t52 -154q0 -100 -54 -155.5t-161 -55.5q-55 0 -95 15t-66.5 43t-39 66.5t-12.5 86.5zM438 1366q0 -43 21.5 -69.5t70.5 -26.5q50 0 71.5 25t21.5 71q0 48 -24 71t-69 23t-68.5 -24.5t-23.5 -69.5z" />
+<glyph unicode="&#x2db;" horiz-adv-x="987" d="M340 -213q0 57 28.5 103.5t76.5 82.5t110.5 61t130.5 40l80 -74q-74 -19 -123 -39t-78 -40.5t-41 -41.5t-12 -43q0 -34 19.5 -50.5t48.5 -16.5q24 0 53 8.5t57 25.5l76 -133q-53 -31 -106 -48t-113 -17q-46 0 -84 11t-65.5 33.5t-42.5 56.5t-15 81z" />
+<glyph unicode="&#x2dc;" d="M139 1225q3 62 18.5 115.5t45.5 92.5t75 61t107 22q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11 q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152z" />
+<glyph unicode="&#x2dd;" d="M184 1208l185 361h274l-285 -361h-174zM567 1208l183 361h276l-287 -361h-172z" />
+<glyph unicode="&#x300;" horiz-adv-x="0" d="M-301 1569h274l185 -361h-174z" />
+<glyph unicode="&#x301;" horiz-adv-x="0" d="M-158 1208l185 361h274l-285 -361h-174z" />
+<glyph unicode="&#x302;" horiz-adv-x="0" d="M-346 1208l231 361h228l231 -361h-180l-164 205l-168 -205h-178z" />
+<glyph unicode="&#x303;" horiz-adv-x="0" d="M-393 1225q3 62 18.5 115.5t45.5 92.5t75 61t107 22q39 0 70 -10.5t57.5 -26.5t49 -34t43 -34t41.5 -26.5t44 -10.5q24 0 39 12t24 31t13 41t6 43h151q-5 -62 -20 -115.5t-44 -92.5t-74.5 -61t-109.5 -22q-44 0 -76.5 11t-58 27t-46 35t-39.5 35t-38.5 27t-44.5 11 t-40.5 -12t-24.5 -30.5t-12.5 -42t-4.5 -46.5h-151z" />
+<glyph unicode="&#x304;" horiz-adv-x="0" d="M-322 1255v162h641v-162h-641z" />
+<glyph unicode="&#x306;" horiz-adv-x="0" d="M-344 1509h158q14 -55 61.5 -84.5t122.5 -29.5q85 0 129.5 29.5t58.5 84.5h158q0 -58 -21.5 -112.5t-64.5 -97t-108 -68t-152 -25.5q-84 0 -148 25.5t-107 68t-65 97t-22 112.5z" />
+<glyph unicode="&#x307;" horiz-adv-x="0" d="M-129 1329q0 63 28 93t99 30q72 0 101.5 -29t29.5 -94q0 -69 -31 -96t-100 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph unicode="&#x308;" horiz-adv-x="0" d="M-336 1325q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88zM84 1325q0 62 28 90.5t97 28.5t98 -28t29 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -98.5 31t-26.5 88z" />
+<glyph unicode="&#x309;" horiz-adv-x="0" d="M-195 1462q25 20 73.5 37t113.5 17q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-113v125h33q74 0 74 57q0 54 -72 54q-23 0 -50 -7.5t-48 -21.5z" />
+<glyph unicode="&#x30a;" horiz-adv-x="0" d="M-203 1356q0 93 49 146.5t152 53.5q104 0 153.5 -54t49.5 -146q0 -96 -50.5 -148.5t-152.5 -52.5q-104 0 -152.5 55t-48.5 146zM-96 1356q0 -45 21.5 -72t72.5 -27t73.5 25.5t22.5 73.5q0 49 -25 73.5t-71 24.5t-70 -26t-24 -72z" />
+<glyph unicode="&#x30c;" horiz-adv-x="0" d="M-346 1569h180l164 -207l168 207h178l-231 -361h-228z" />
+<glyph unicode="&#x323;" d="M403 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x374;" horiz-adv-x="428" d="M76 1128l61 361h242l-162 -361h-141z" />
+<glyph unicode="&#x375;" horiz-adv-x="428" d="M61 -231l164 360h140l-60 -360h-244z" />
+<glyph unicode="&#x37e;" horiz-adv-x="569" d="M141 121q0 32 7 57.5t24 43t44.5 27t68.5 9.5q77 0 109 -41t32 -117q0 -60 -11 -118t-28.5 -109.5t-39.5 -94t-44 -71.5h-139q23 34 40.5 75t29.5 80t18.5 72.5t7.5 53.5q-63 2 -91 33.5t-28 99.5zM141 911q0 72 32 105t110 33q79 0 111 -32.5t32 -105.5 q0 -74 -34 -104.5t-109 -30.5q-41 0 -68 9t-43.5 26t-23.5 42.5t-7 57.5z" />
+<glyph unicode="&#x384;" horiz-adv-x="459" d="M0 1208l182 361h277l-287 -361h-172z" />
+<glyph unicode="&#x385;" d="M86 1317q0 60 26.5 89.5t92.5 29.5t94.5 -28.5t28.5 -90.5q0 -65 -30 -90t-93 -25q-69 0 -94 30.5t-25 84.5zM391 1208l123 361h252l-213 -361h-162zM737 1317q0 60 27 89.5t92 29.5q68 0 95.5 -28.5t27.5 -90.5q0 -65 -30 -90t-93 -25q-69 0 -94 30.5t-25 84.5z" />
+<glyph unicode="&#x386;" horiz-adv-x="1335" d="M20 1024l123 360h256l-213 -360h-166zM62 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM467 528h412l-205 623z" />
+<glyph unicode="&#x387;" horiz-adv-x="569" d="M141 743q0 72 32 105t110 33q79 0 111 -32.5t32 -105.5q0 -74 -34 -104.5t-109 -30.5q-41 0 -68 9t-43.5 26t-23.5 42.5t-7 57.5z" />
+<glyph unicode="&#x388;" horiz-adv-x="1415" d="M-1 1024l123 360h256l-213 -360h-166zM430 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872z" />
+<glyph unicode="&#x389;" horiz-adv-x="1651" d="M-1 1024l123 360h256l-213 -360h-166zM430 0v1384h233v-561h588v561h234v-1384h-234v610h-588v-610h-233z" />
+<glyph unicode="&#x38a;" horiz-adv-x="1135" d="M-1 1024l123 360h256l-213 -360h-166zM415 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617z" />
+<glyph unicode="&#x38c;" horiz-adv-x="1583" d="M-1 1024l123 360h256l-213 -360h-166zM321 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM563 692q0 -129 18 -225.5 t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5z" />
+<glyph unicode="&#x38e;" horiz-adv-x="1548" d="M-1 1024l123 360h256l-213 -360h-166zM410 1384h258l299 -626l303 626h248l-437 -854v-530h-235v524z" />
+<glyph unicode="&#x38f;" horiz-adv-x="1581" d="M-1 1024l123 360h256l-213 -360h-166zM317 809q0 118 31.5 227t100.5 193t178 134t264 50q149 0 259.5 -40.5t183.5 -118t109 -189.5t36 -256q0 -125 -18.5 -218.5t-55 -161t-90 -111.5t-123.5 -68v-41h266v-209h-473v360q60 8 106 33.5t77.5 77t48 132t16.5 198.5 q0 202 -83.5 303.5t-258.5 101.5q-89 0 -151.5 -28.5t-103 -81t-59 -127t-18.5 -166.5q0 -125 15.5 -205t47 -128.5t77.5 -72.5t108 -37v-360h-469v209h268v41q-75 23 -130 64t-90 107.5t-52 161.5t-17 226z" />
+<glyph unicode="&#x390;" horiz-adv-x="647" d="M-175 1317q0 60 26.5 89.5t92.5 29.5t94.5 -28.5t28.5 -90.5q0 -65 -30 -90t-93 -25q-69 0 -94 30.5t-25 84.5zM130 1208l123 361h252l-213 -361h-162zM152 305v744h217v-727q0 -50 4 -84t15.5 -56t32 -31.5t52.5 -9.5q26 0 55.5 5.5t51.5 13.5l49 -164 q-38 -12 -90.5 -19.5t-106.5 -7.5q-81 0 -135 21t-86.5 63t-45.5 105t-13 147zM476 1317q0 60 27 89.5t92 29.5q68 0 95.5 -28.5t27.5 -90.5q0 -65 -30 -90t-93 -25q-69 0 -94 30.5t-25 84.5z" />
+<glyph unicode="&#x391;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM444 528h412l-205 623z" />
+<glyph unicode="&#x392;" horiz-adv-x="1284" d="M166 0v1384h448q134 0 227 -19t151 -58.5t84 -99.5t26 -142q0 -74 -18.5 -128t-50.5 -91.5t-75 -60.5t-92 -35q71 -9 129.5 -33t100.5 -65.5t65 -102.5t23 -146q0 -105 -36 -181t-104.5 -125.5t-167.5 -73t-225 -23.5h-485zM399 209h166q91 0 161 6t118 28t73 63.5 t25 113.5q0 61 -19 100t-59.5 61.5t-103 31t-148.5 8.5h-213v-412zM399 825h189q78 0 130.5 12t85 35.5t46.5 59t14 82.5t-14 78.5t-45.5 51t-82.5 28t-126 8.5h-197v-355z" />
+<glyph unicode="&#x393;" d="M154 0v1384h870v-198h-637v-1186h-233z" />
+<glyph unicode="&#x394;" horiz-adv-x="1272" d="M39 0v100q55 154 112 316.5t114.5 326t115 325.5t113.5 316h288q55 -154 111.5 -316t113.5 -325.5t113.5 -326t112.5 -316.5v-100h-1194zM303 197h649l-282 825q-13 38 -22 76.5t-17 64.5h-6q-7 -26 -16 -63.5t-23 -75.5z" />
+<glyph unicode="&#x395;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872z" />
+<glyph unicode="&#x396;" horiz-adv-x="1155" d="M82 0v207l682 964h-651v213h929v-196l-690 -975h707v-213h-977z" />
+<glyph unicode="&#x397;" horiz-adv-x="1386" d="M166 0v1384h233v-561h588v561h234v-1384h-234v610h-588v-610h-233z" />
+<glyph unicode="&#x398;" horiz-adv-x="1446" d="M102 692q0 168 32.5 302t106 227t192 142.5t290.5 49.5q171 0 289.5 -49.5t192 -142.5t106 -227t32.5 -302t-32.5 -301.5t-105.5 -227t-191.5 -143t-290.5 -49.5t-290.5 50t-192 143.5t-106 227t-32.5 300.5zM346 692q0 -130 19.5 -228.5t64 -165t116.5 -100.5t177 -34 q103 0 175 34t116 100.5t64 165t20 228.5t-20 228.5t-64 165t-116 100t-175 33.5q-105 0 -177 -33.5t-116.5 -100t-64 -165t-19.5 -228.5zM477 600v199h490v-199h-490z" />
+<glyph unicode="&#x399;" horiz-adv-x="821" d="M102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617z" />
+<glyph unicode="&#x39a;" horiz-adv-x="1272" d="M166 0v1384h233v-610l519 610h280l-541 -616l574 -768h-295l-430 596l-107 -123v-473h-233z" />
+<glyph unicode="&#x39b;" horiz-adv-x="1249" d="M39 0l457 1384h262l452 -1384h-241l-348 1114l-353 -1114h-229z" />
+<glyph unicode="&#x39c;" horiz-adv-x="1630" d="M166 0v1384h287l364 -706l367 706h280v-1384h-225v1038l-356 -673h-140l-354 673v-1038h-223z" />
+<glyph unicode="&#x39d;" horiz-adv-x="1399" d="M166 0v1384h317l523 -1011v1011h227v-1384h-277l-563 1087v-1087h-227z" />
+<glyph unicode="&#x39e;" horiz-adv-x="1098" d="M113 0v213h872v-213h-872zM113 1176v208h872v-208h-872zM172 616v209h754v-209h-754z" />
+<glyph unicode="&#x39f;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32 t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5z" />
+<glyph unicode="&#x3a0;" horiz-adv-x="1372" d="M166 0v1384h1040v-1384h-237v1180h-568v-1180h-235z" />
+<glyph unicode="&#x3a1;" horiz-adv-x="1210" d="M166 0v1384h465q118 0 209.5 -24.5t154 -78.5t95 -140.5t32.5 -210.5q0 -125 -28.5 -215.5t-89 -149.5t-155 -87.5t-226.5 -28.5h-224v-449h-233zM399 655h146q88 0 151.5 9t104 37.5t59.5 82.5t19 144q0 75 -20.5 123.5t-59.5 76.5t-96.5 39t-131.5 11h-172v-523z" />
+<glyph unicode="&#x3a3;" horiz-adv-x="1139" d="M72 0v190l483 512l-483 498v184h944v-196h-637l414 -430v-107l-433 -454h691v-197h-979z" />
+<glyph unicode="&#x3a4;" horiz-adv-x="1194" d="M37 1171v213h1118v-213h-442v-1171h-234v1171h-442z" />
+<glyph unicode="&#x3a5;" horiz-adv-x="1167" d="M29 1384h258l299 -626l303 626h248l-437 -854v-530h-235v524z" />
+<glyph unicode="&#x3a6;" horiz-adv-x="1493" d="M102 690q0 124 27.5 227.5t90 180t163.5 124t248 60.5v166h227v-164q147 -14 248.5 -62t164.5 -125t91.5 -180t28.5 -227q0 -125 -28.5 -228.5t-91.5 -180t-164.5 -124t-248.5 -61.5v-159h-227v159q-146 14 -247 62t-163.5 124.5t-90.5 179.5t-28 228zM346 690 q0 -90 16.5 -159.5t51 -119t88.5 -80t129 -42.5v805q-151 -23 -218 -123t-67 -281zM858 289q154 22 222.5 121t68.5 280q0 183 -68 282.5t-223 121.5v-805z" />
+<glyph unicode="&#x3a7;" horiz-adv-x="1247" d="M41 0l455 694l-443 690h269l307 -507l317 507h260l-448 -684l446 -700h-266l-317 516l-322 -516h-258z" />
+<glyph unicode="&#x3a8;" horiz-adv-x="1489" d="M117 797v587h233v-567q0 -88 22 -154t60 -111t88.5 -68.5t108.5 -26.5v927h231v-929q58 4 109 28.5t89 69.5t60.5 110.5t22.5 149.5v571h231v-587q0 -141 -36 -239.5t-102.5 -162.5t-161 -97.5t-212.5 -43.5v-289h-231v289q-118 10 -212.5 43.5t-161 97.5t-102.5 162.5 t-36 239.5z" />
+<glyph unicode="&#x3a9;" horiz-adv-x="1366" d="M102 809q0 118 31.5 227t100.5 193t178 134t264 50q149 0 259.5 -40.5t183.5 -118t109 -189.5t36 -256q0 -125 -18.5 -218.5t-55 -161t-90 -111.5t-123.5 -68v-41h266v-209h-473v360q60 8 106 33.5t77.5 77t48 132t16.5 198.5q0 202 -83.5 303.5t-258.5 101.5 q-89 0 -151.5 -28.5t-103 -81t-59 -127t-18.5 -166.5q0 -125 15.5 -205t47 -128.5t77.5 -72.5t108 -37v-360h-469v209h268v41q-75 23 -130 64t-90 107.5t-52 161.5t-17 226z" />
+<glyph unicode="&#x3aa;" horiz-adv-x="821" d="M81 1661q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617zM500 1661q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5 q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x3ab;" horiz-adv-x="1167" d="M29 1384h258l299 -626l303 626h248l-437 -854v-530h-235v524zM250 1661q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM669 1661q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5 q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x3ac;" horiz-adv-x="1272" d="M104 522q0 140 33.5 244.5t93 174t141 104t177.5 34.5q40 0 79.5 -6t78 -21t75 -40t70.5 -62q2 28 5.5 53.5t6.5 45.5h217q-18 -97 -29 -168.5t-18 -126t-9.5 -97.5t-2.5 -82v-253q0 -56 5.5 -91t17.5 -55t31 -27.5t46 -7.5q20 0 45 5.5t45 13.5l50 -164 q-36 -12 -84.5 -19.5t-96.5 -7.5q-65 0 -109 15.5t-72.5 47t-43 80t-18.5 113.5q-45 -131 -128 -193.5t-192 -62.5q-101 0 -178.5 37t-130 107.5t-79 173.5t-26.5 235zM328 516q0 -99 16 -167.5t44 -111.5t67 -62t84 -19q70 0 122.5 45t89 125t57.5 191t28 243 q-53 68 -119 104.5t-129 36.5q-58 0 -105.5 -19.5t-82 -64.5t-53.5 -119t-19 -182zM500 1208l182 361h277l-287 -361h-172z" />
+<glyph unicode="&#x3ad;" horiz-adv-x="1053" d="M111 293q0 42 13 79t35 66.5t50 51t57 32.5q-32 12 -60.5 33t-49.5 49.5t-33 64t-12 76.5q0 90 38.5 153.5t102.5 103.5t147 58.5t172 18.5q288 0 398 -186l-160 -107q-40 59 -94 91t-142 32q-48 0 -91 -8.5t-76 -28t-52.5 -51.5t-19.5 -78q0 -41 16.5 -65t48 -36.5 t77 -16.5t102.5 -4h223v-166h-234q-126 0 -179.5 -37t-53.5 -117q0 -43 20.5 -74t54 -50.5t76.5 -28.5t88 -9q90 0 150.5 28.5t105.5 90.5l154 -102q-27 -43 -64 -77.5t-87 -59t-113.5 -37.5t-143.5 -13q-101 0 -186.5 18t-147 57t-96 100.5t-34.5 148.5zM440 1208l182 361 h277l-287 -361h-172z" />
+<glyph unicode="&#x3ae;" horiz-adv-x="1194" d="M158 0v1049h207v-142q84 76 174 124t188 48q163 0 240 -94.5t77 -292.5v-1085h-215v1030q0 70 -7.5 117.5t-25 77t-46.5 42.5t-72 13q-72 0 -149.5 -43t-155.5 -111v-733h-215zM475 1208l182 361h277l-287 -361h-172z" />
+<glyph unicode="&#x3af;" horiz-adv-x="647" d="M119 1208l182 361h277l-287 -361h-172zM152 305v744h217v-727q0 -50 4 -84t15.5 -56t32 -31.5t52.5 -9.5q26 0 55.5 5.5t51.5 13.5l49 -164q-38 -12 -90.5 -19.5t-106.5 -7.5q-81 0 -135 21t-86.5 63t-45.5 105t-13 147z" />
+<glyph unicode="&#x3b0;" horiz-adv-x="1178" d="M137 1317q0 60 26.5 89.5t92.5 29.5t94.5 -28.5t28.5 -90.5q0 -65 -30 -90t-93 -25q-69 0 -94 30.5t-25 84.5zM150 358v691h217v-684q0 -62 20.5 -104.5t53 -68t72 -36.5t77.5 -11q57 0 103.5 21.5t80 68.5t52 121.5t18.5 180.5q0 80 -8 154t-19.5 139.5t-25 121 t-25.5 97.5h219q9 -24 23.5 -75t28 -118t23 -144.5t9.5 -154.5q0 -174 -36.5 -287.5t-101.5 -180t-154 -93.5t-193 -27q-49 0 -100 6t-99 21.5t-91 43t-75 70.5t-50.5 104t-18.5 144zM442 1208l123 361h252l-213 -361h-162zM788 1317q0 60 27 89.5t92 29.5q68 0 95.5 -28.5 t27.5 -90.5q0 -65 -30 -90t-93 -25q-69 0 -94 30.5t-25 84.5z" />
+<glyph unicode="&#x3b1;" horiz-adv-x="1272" d="M104 522q0 140 33.5 244.5t93 174t141 104t177.5 34.5q40 0 79.5 -6t78 -21t75 -40t70.5 -62q2 28 5.5 53.5t6.5 45.5h217q-18 -97 -29 -168.5t-18 -126t-9.5 -97.5t-2.5 -82v-253q0 -56 5.5 -91t17.5 -55t31 -27.5t46 -7.5q20 0 45 5.5t45 13.5l50 -164 q-36 -12 -84.5 -19.5t-96.5 -7.5q-65 0 -109 15.5t-72.5 47t-43 80t-18.5 113.5q-45 -131 -128 -193.5t-192 -62.5q-101 0 -178.5 37t-130 107.5t-79 173.5t-26.5 235zM328 516q0 -99 16 -167.5t44 -111.5t67 -62t84 -19q70 0 122.5 45t89 125t57.5 191t28 243 q-53 68 -119 104.5t-129 36.5q-58 0 -105.5 -19.5t-82 -64.5t-53.5 -119t-19 -182z" />
+<glyph unicode="&#x3b2;" horiz-adv-x="1212" d="M154 -391v1419q0 106 21 196t72 156t135 103t210 37q83 0 157 -20t129.5 -62t88 -106.5t32.5 -153.5q0 -68 -19 -122t-53.5 -94.5t-83 -67t-108.5 -38.5q85 -10 153.5 -43.5t117 -86t74.5 -122t26 -153.5q0 -102 -27 -190t-81 -153t-135.5 -102t-190.5 -37q-51 0 -97 8 t-84.5 21t-69.5 28t-52 29v-446h-215zM369 227q21 -13 50 -27.5t64 -26.5t77.5 -20t90.5 -8q55 0 98.5 22t73 62t45 96.5t15.5 125.5q0 90 -29.5 147.5t-81 90.5t-121 46t-149.5 13v176q61 0 112.5 12.5t88 40t57 71.5t20.5 107q0 90 -49.5 140.5t-146.5 50.5 q-66 0 -108 -20.5t-65.5 -60t-32.5 -97t-9 -132.5v-809z" />
+<glyph unicode="&#x3b3;" horiz-adv-x="1110" d="M43 1049h231l273 -803q27 43 58 97.5t61 116.5t58.5 130t49.5 139t34 143t13 142v35h219v-45q0 -84 -18 -173t-49.5 -177.5t-72.5 -174t-87 -164t-94 -146.5t-92 -122v-440h-215v440z" />
+<glyph unicode="&#x3b4;" horiz-adv-x="1233" d="M104 459q0 112 34.5 197.5t89 147t121.5 101t132 60.5q-48 33 -88 66t-69 69t-45.5 77t-16.5 91q0 57 19 103.5t58.5 79.5t99.5 51t143 18q73 0 138.5 -9.5t119.5 -23.5t95.5 -30.5t65.5 -31.5l-79 -168q-36 19 -75.5 37t-82.5 32t-88.5 23t-93.5 9q-29 0 -49 -6.5 t-32 -16.5t-17 -23t-5 -26q0 -23 5.5 -44.5t26 -45.5t59 -53t104.5 -66q108 -60 192 -121t142.5 -131t89 -153t30.5 -185q0 -123 -37 -219t-104.5 -162.5t-162.5 -101.5t-210 -35q-131 0 -227 38.5t-159 105t-93.5 155.5t-30.5 191zM328 457q0 -52 13.5 -107t47 -100.5 t92 -75t148.5 -29.5q60 0 110 22.5t86.5 65.5t57 105.5t20.5 142.5q0 75 -21 135t-57.5 108t-85.5 85.5t-104 67.5q-42 -13 -95 -41.5t-100 -78t-79.5 -123.5t-32.5 -177z" />
+<glyph unicode="&#x3b5;" horiz-adv-x="1053" d="M111 293q0 42 13 79t35 66.5t50 51t57 32.5q-32 12 -60.5 33t-49.5 49.5t-33 64t-12 76.5q0 90 38.5 153.5t102.5 103.5t147 58.5t172 18.5q288 0 398 -186l-160 -107q-40 59 -94 91t-142 32q-48 0 -91 -8.5t-76 -28t-52.5 -51.5t-19.5 -78q0 -41 16.5 -65t48 -36.5 t77 -16.5t102.5 -4h223v-166h-234q-126 0 -179.5 -37t-53.5 -117q0 -43 20.5 -74t54 -50.5t76.5 -28.5t88 -9q90 0 150.5 28.5t105.5 90.5l154 -102q-27 -43 -64 -77.5t-87 -59t-113.5 -37.5t-143.5 -13q-101 0 -186.5 18t-147 57t-96 100.5t-34.5 148.5z" />
+<glyph unicode="&#x3b6;" horiz-adv-x="940" d="M115 453q0 52 9.5 119t31.5 142t58 155t88 159t122 153t160 138h-428v170h706v-141q-65 -42 -129.5 -99.5t-122.5 -127.5t-107.5 -149t-85.5 -163t-56.5 -171t-20.5 -171q0 -87 23 -142t60 -89t84 -51.5t95 -28.5q56 -13 110 -28t96 -43.5t67.5 -78t25.5 -131.5 q0 -39 -12 -86t-26 -88q-17 -48 -38 -96h-215q21 46 39 91q7 19 14 39.5t12.5 41t9 39t3.5 34.5q0 35 -14.5 56.5t-39.5 34.5t-58.5 20.5t-71.5 15.5q-42 9 -87.5 21t-89 32.5t-82 52.5t-67.5 81.5t-46 120t-17 168.5z" />
+<glyph unicode="&#x3b7;" horiz-adv-x="1194" d="M158 0v1049h207v-142q84 76 174 124t188 48q163 0 240 -94.5t77 -292.5v-1085h-215v1030q0 70 -7.5 117.5t-25 77t-46.5 42.5t-72 13q-72 0 -149.5 -43t-155.5 -111v-733h-215z" />
+<glyph unicode="&#x3b8;" horiz-adv-x="1200" d="M119 748q0 102 5 198.5t22 182.5t49 157.5t85.5 123.5t131.5 81t188 29q109 0 187 -29t131 -81t85 -123.5t49 -157.5t22 -182.5t5 -198.5q0 -103 -5 -201t-21.5 -184.5t-48 -158.5t-84.5 -124.5t-131.5 -81.5t-188.5 -29t-188.5 29t-132 81.5t-85 124.5t-48.5 158.5 t-22 184.5t-5 201zM342 684q0 -115 7 -213.5t32.5 -171t76 -113.5t138.5 -41q89 0 141 41t78.5 113.5t34 171t8.5 213.5h-516zM342 848h516q-2 108 -11 198.5t-36.5 156.5t-77.5 103t-133 37q-84 0 -135 -36.5t-78 -102.5t-35.5 -157t-9.5 -199z" />
+<glyph unicode="&#x3b9;" horiz-adv-x="647" d="M152 305v744h217v-727q0 -50 4 -84t15.5 -56t32 -31.5t52.5 -9.5q26 0 55.5 5.5t51.5 13.5l49 -164q-38 -12 -90.5 -19.5t-106.5 -7.5q-81 0 -135 21t-86.5 63t-45.5 105t-13 147z" />
+<glyph unicode="&#x3ba;" horiz-adv-x="1096" d="M158 0v1049h215v-453l403 453h250l-414 -453l449 -596h-252l-330 463l-106 -113v-350h-215z" />
+<glyph unicode="&#x3bb;" horiz-adv-x="1143" d="M43 0l436 1051q-21 75 -39 129.5t-37 90.5t-42 53t-54 17q-34 0 -74 -12.5t-69 -28.5l-49 166q46 22 105 38t112 16q60 0 106 -15t82 -49t64 -89t51 -136l266 -920q15 -48 28 -78.5t26 -47.5t26 -23t27 -6t31 3t32 9l53 -168q-55 -15 -101.5 -20t-68.5 -5q-44 0 -81 11 t-68.5 41.5t-58.5 86.5t-50 146l-135 537l-291 -797h-227z" />
+<glyph unicode="&#x3bc;" horiz-adv-x="1186" d="M135 -395v1444h215v-773q18 -22 43 -41.5t54.5 -34.5t63 -23.5t67.5 -8.5q142 0 249 133v748h215v-1049h-200l-8 115q-54 -73 -114 -109.5t-140 -36.5q-34 0 -63.5 4t-57 13t-54.5 23.5t-55 35.5v-440h-215z" />
+<glyph unicode="&#x3bd;" horiz-adv-x="1090" d="M43 1049h231l273 -822q48 84 95.5 177.5t85 191.5t60.5 198.5t23 198.5v56h221v-50q0 -83 -18 -172.5t-49 -180t-72.5 -180t-89.5 -173t-99.5 -158t-101.5 -135.5h-188z" />
+<glyph unicode="&#x3be;" horiz-adv-x="948" d="M115 422q0 68 19.5 125.5t53.5 103.5t80.5 79t100.5 52q-40 18 -74 47t-58.5 66t-38.5 81.5t-14 94.5q0 42 10.5 81t31.5 72.5t52.5 60t73.5 42.5h-221v162h705v-168h-70q-95 0 -163.5 -11.5t-112 -40t-64 -76.5t-20.5 -120q0 -62 22.5 -100.5t54 -59.5t66.5 -28.5 t59 -7.5h201v-170h-219q-54 0 -100 -22.5t-80 -60t-53 -87t-19 -103.5q0 -76 24 -124t63.5 -78t89.5 -46.5t101 -29.5q55 -14 107 -31t92.5 -47t65 -78.5t24.5 -124.5q0 -39 -11 -86t-25 -88q-16 -48 -35 -96h-207q20 46 36 91q14 38 25.5 80t11.5 74q0 34 -15 57t-40.5 39 t-60 27t-72.5 21q-43 11 -89.5 24.5t-90.5 33.5t-83.5 49.5t-69 73t-47 104t-17.5 143.5z" />
+<glyph unicode="&#x3bf;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92 t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x3c0;" horiz-adv-x="1374" d="M12 977q25 12 60 25t78 23.5t92.5 17t103.5 6.5h965v-166h-250v-559q0 -50 6 -83.5t19.5 -53t35 -27.5t52.5 -8q21 0 46 4t44 12l45 -156q-15 -5 -36.5 -10.5t-46.5 -10t-52.5 -7t-53.5 -2.5q-144 0 -210 77.5t-66 247.5v576h-320v-590q0 -93 -4.5 -164.5t-21.5 -128.5 h-244q22 66 37.5 145.5t15.5 159.5v576q-24 -3 -55 -8t-63 -12t-62 -16.5t-51 -21.5z" />
+<glyph unicode="&#x3c1;" horiz-adv-x="1214" d="M133 -393v928q0 131 29.5 232.5t90.5 170.5t153.5 105t218.5 36q120 0 210.5 -37.5t151.5 -107t92 -169t31 -222.5q0 -142 -33.5 -249.5t-93 -179.5t-140.5 -108.5t-175 -36.5q-104 0 -184 37t-134 94v-493h-217zM350 295q56 -65 128 -104t151 -39q55 0 102 20.5t81 65.5 t53.5 116t19.5 172q0 78 -12.5 147t-42.5 120t-80 80.5t-125 29.5q-58 0 -108 -17t-87 -60.5t-58.5 -117t-21.5 -186.5v-227z" />
+<glyph unicode="&#x3c2;" horiz-adv-x="1018" d="M104 522q0 127 28 230t88 176t154.5 112t227.5 39t229 -46t152 -140l-168 -113q-35 57 -87.5 90t-127.5 33q-72 0 -123.5 -25.5t-84.5 -74.5t-48.5 -119.5t-15.5 -161.5q0 -100 26.5 -162.5t69 -101t96 -59.5t107.5 -39q53 -18 102.5 -37t87.5 -49.5t61 -77.5t23 -119 q0 -39 -11.5 -86t-25.5 -88q-17 -48 -37 -96h-215q21 46 38 91q14 38 26 80.5t12 74.5q0 30 -11.5 51t-32 36t-48 26.5t-59.5 21.5q-45 14 -95 30t-98 40.5t-91.5 61t-76.5 91t-52.5 130.5t-19.5 181z" />
+<glyph unicode="&#x3c3;" horiz-adv-x="1278" d="M104 492q0 138 29 242.5t92.5 174t165 105t246.5 35.5h577v-168h-266q81 -79 119.5 -180.5t38.5 -213.5q0 -106 -28 -200t-88.5 -164.5t-155.5 -112t-230 -41.5q-130 0 -224 39t-155.5 109t-91 166t-29.5 209zM328 485q0 -75 17 -137.5t51.5 -107.5t86 -70t121.5 -25 q82 0 136 30.5t85.5 80.5t44.5 113.5t13 130.5q0 124 -31.5 220t-93.5 161h-154q-92 0 -147 -32.5t-83.5 -87t-37 -126.5t-8.5 -150z" />
+<glyph unicode="&#x3c4;" horiz-adv-x="1036" d="M6 977q25 13 56.5 26t71.5 23t89 16.5t109 6.5h651v-168h-358v-559q0 -50 6 -82.5t19 -52t34 -27.5t51 -8q22 0 45 4t41 12l45 -156q-31 -12 -83 -21t-105 -9q-140 0 -205 77t-65 246v576h-86q-48 0 -88 -6t-71 -15t-54.5 -18.5t-38.5 -16.5z" />
+<glyph unicode="&#x3c5;" horiz-adv-x="1178" d="M150 358v691h217v-684q0 -62 20.5 -104.5t53 -68t72 -36.5t77.5 -11q57 0 103.5 21.5t80 68.5t52 121.5t18.5 180.5q0 80 -8 154t-19.5 139.5t-25 121t-25.5 97.5h219q9 -24 23.5 -75t28 -118t23 -144.5t9.5 -154.5q0 -174 -36.5 -287.5t-101.5 -180t-154 -93.5t-193 -27 q-49 0 -100 6t-99 21.5t-91 43t-75 70.5t-50.5 104t-18.5 144z" />
+<glyph unicode="&#x3c6;" horiz-adv-x="1399" d="M104 522q0 122 27 219.5t86.5 167.5t153 112t227.5 54v414h207v-414q130 -12 223 -54t152 -112.5t86.5 -168t27.5 -218.5q0 -120 -27.5 -216t-86.5 -165.5t-152 -111.5t-223 -54v-368h-207v368q-132 12 -225.5 54t-153.5 111.5t-87.5 165.5t-27.5 216zM328 522 q0 -84 13.5 -150t45 -113.5t83 -77.5t128.5 -42v772q-77 -13 -128.5 -43t-83 -78t-45 -115t-13.5 -153zM805 139q75 12 126 42t82.5 78t45.5 113.5t14 149.5t-14 150t-45.5 115t-82.5 79.5t-126 42.5v-770z" />
+<glyph unicode="&#x3c7;" horiz-adv-x="1135" d="M45 1038q42 17 86 29t84 12t74.5 -10.5t64 -33.5t54.5 -61t47 -93l129 -332l223 500h233l-364 -691l172 -399q18 -42 34 -73.5t32.5 -52t34.5 -30.5t42 -10q13 0 30 4t36 10l51 -161q-16 -7 -37 -14t-44 -12.5t-47 -9t-46 -3.5q-46 0 -82 12.5t-66.5 42.5t-58 80 t-57.5 125l-123 301l-260 -555h-234l402 749l-156 365q-18 43 -32 75.5t-28.5 54t-31.5 32t-41 10.5q-16 0 -35.5 -4t-36.5 -10z" />
+<glyph unicode="&#x3c8;" horiz-adv-x="1454" d="M150 412v637h215v-611q0 -67 19 -117.5t53.5 -86.5t83.5 -57.5t110 -29.5v1336h211v-1333q61 11 112.5 40.5t89 77.5t58 115.5t20.5 155.5q0 84 -7.5 158.5t-19.5 138.5t-26 117.5t-27 95.5h222q10 -24 24.5 -74.5t28 -117.5t23.5 -144t10 -154q0 -158 -42.5 -265 t-113 -174.5t-162 -101t-190.5 -43.5v-368h-211v366q-109 8 -198 35.5t-152 80t-97 132.5t-34 191z" />
+<glyph unicode="&#x3c9;" horiz-adv-x="1677" d="M104 410q0 84 16.5 174.5t44 176t63.5 162t75 132.5l215 -41q-41 -65 -75.5 -137.5t-59 -147.5t-38 -150t-13.5 -145q0 -140 47.5 -214.5t140.5 -74.5q44 0 82 23t66.5 71t44.5 122.5t16 177.5v282h219v-282q0 -103 16 -177.5t44.5 -122.5t66.5 -71t82 -23 q91 0 138.5 74.5t47.5 214.5q0 71 -13.5 147t-37.5 151t-58 147t-75 135l215 41q42 -60 78.5 -137.5t63.5 -163t42 -173.5t15 -169q0 -116 -29.5 -200t-83 -138t-128 -79.5t-165.5 -25.5q-118 0 -204 60t-123 172q-37 -112 -124 -172t-206 -60q-92 0 -166.5 25.5t-128 79 t-82.5 137t-29 199.5z" />
+<glyph unicode="&#x3ca;" horiz-adv-x="647" d="M-72 1325q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM152 305v744h217v-727q0 -50 4 -84t15.5 -56t32 -31.5t52.5 -9.5q26 0 55.5 5.5t51.5 13.5l49 -164q-38 -12 -90.5 -19.5t-106.5 -7.5q-81 0 -135 21t-86.5 63 t-45.5 105t-13 147zM347 1325q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x3cb;" horiz-adv-x="1178" d="M150 358v691h217v-684q0 -62 20.5 -104.5t53 -68t72 -36.5t77.5 -11q57 0 103.5 21.5t80 68.5t52 121.5t18.5 180.5q0 80 -8 154t-19.5 139.5t-25 121t-25.5 97.5h219q9 -24 23.5 -75t28 -118t23 -144.5t9.5 -154.5q0 -174 -36.5 -287.5t-101.5 -180t-154 -93.5t-193 -27 q-49 0 -100 6t-99 21.5t-91 43t-75 70.5t-50.5 104t-18.5 144zM236 1325q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM655 1325q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31 t-25.5 88z" />
+<glyph unicode="&#x3cc;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92 t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM479 1208l182 361h277l-287 -361h-172z" />
+<glyph unicode="&#x3cd;" horiz-adv-x="1178" d="M150 358v691h217v-684q0 -62 20.5 -104.5t53 -68t72 -36.5t77.5 -11q57 0 103.5 21.5t80 68.5t52 121.5t18.5 180.5q0 80 -8 154t-19.5 139.5t-25 121t-25.5 97.5h219q9 -24 23.5 -75t28 -118t23 -144.5t9.5 -154.5q0 -174 -36.5 -287.5t-101.5 -180t-154 -93.5t-193 -27 q-49 0 -100 6t-99 21.5t-91 43t-75 70.5t-50.5 104t-18.5 144zM430 1208l182 361h277l-287 -361h-172z" />
+<glyph unicode="&#x3ce;" horiz-adv-x="1677" d="M104 410q0 84 16.5 174.5t44 176t63.5 162t75 132.5l215 -41q-41 -65 -75.5 -137.5t-59 -147.5t-38 -150t-13.5 -145q0 -140 47.5 -214.5t140.5 -74.5q44 0 82 23t66.5 71t44.5 122.5t16 177.5v282h219v-282q0 -103 16 -177.5t44.5 -122.5t66.5 -71t82 -23 q91 0 138.5 74.5t47.5 214.5q0 71 -13.5 147t-37.5 151t-58 147t-75 135l215 41q42 -60 78.5 -137.5t63.5 -163t42 -173.5t15 -169q0 -116 -29.5 -200t-83 -138t-128 -79.5t-165.5 -25.5q-118 0 -204 60t-123 172q-37 -112 -124 -172t-206 -60q-92 0 -166.5 25.5t-128 79 t-82.5 137t-29 199.5zM727 1208l182 361h277l-287 -361h-172z" />
+<glyph unicode="&#x400;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM303 1905h275l184 -361h-174z" />
+<glyph unicode="&#x401;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM256 1661q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM675 1661q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5 q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x402;" horiz-adv-x="1374" d="M20 1190v194h793v-194h-281v-365h191q141 0 249.5 -22t182 -70.5t111 -127t37.5 -191.5q0 -122 -41.5 -201.5t-118.5 -127t-187 -66.5t-247 -19v193q95 0 161.5 11.5t108 37.5t60 69.5t18.5 108.5q0 52 -15.5 91.5t-51.5 66t-94.5 40t-145.5 13.5h-218v-631h-233v1190 h-279z" />
+<glyph unicode="&#x403;" d="M154 0v1384h870v-198h-637v-1186h-233zM428 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x404;" horiz-adv-x="1315" d="M113 692q0 363 154 542t460 179q105 0 186 -19.5t143 -53.5t106.5 -80.5t76.5 -100.5l-186 -135q-22 34 -48.5 67t-64 58.5t-88.5 41t-121 15.5q-172 0 -263 -102t-108 -301h625v-209h-627q9 -110 37 -188.5t75.5 -129t113 -74.5t149.5 -24q69 0 121 15t91.5 40.5 t69.5 60t56 73.5l189 -131q-36 -56 -81.5 -104.5t-107 -84t-143.5 -56t-191 -20.5q-317 0 -470.5 180t-153.5 541z" />
+<glyph unicode="&#x405;" horiz-adv-x="1227" d="M80 236l184 133q25 -39 55.5 -73.5t71 -60.5t94.5 -41.5t125 -15.5q53 0 103.5 10t89.5 33t62.5 60t23.5 92q0 52 -22.5 87t-60.5 59t-89 40t-109 31q-106 27 -197 55.5t-158 72.5t-105.5 112t-38.5 174q0 94 32 169.5t94 129t154.5 82t212.5 28.5q90 0 164.5 -16.5 t135 -48t108.5 -78t84 -105.5l-181 -135q-55 88 -130 132t-183 44q-117 0 -185.5 -48t-68.5 -136q0 -44 18.5 -73.5t57 -51.5t97 -39.5t138.5 -36.5q62 -15 120.5 -32t111 -39.5t96.5 -53t75.5 -73.5t49.5 -100.5t18 -133.5q0 -117 -41.5 -196.5t-112.5 -129t-165.5 -71 t-200.5 -21.5q-112 0 -196 21t-147 57t-107.5 84t-77.5 103z" />
+<glyph unicode="&#x406;" horiz-adv-x="821" d="M102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617z" />
+<glyph unicode="&#x407;" horiz-adv-x="821" d="M79 1661q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617zM498 1661q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5 q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x408;" horiz-adv-x="903" d="M35 20l78 205q15 -8 40.5 -16.5t53.5 -15.5t56.5 -12t49.5 -5q57 0 93.5 13.5t58 45.5t29.5 85t8 133v931h233v-1007q0 -105 -24.5 -182t-76 -127.5t-132 -74.5t-191.5 -24q-27 0 -62 3.5t-72.5 10.5t-74.5 16.5t-67 20.5z" />
+<glyph unicode="&#x409;" horiz-adv-x="2011" d="M16 16l62 185q25 -11 46 -14t32 -3q64 0 110.5 58.5t76.5 177.5t44 300t14 427v237h789v-512h215q141 0 241 -26t164.5 -80t94.5 -136.5t30 -195.5q0 -226 -132.5 -330t-397.5 -104h-451v1186h-323v-99q0 -260 -25.5 -466t-78 -349.5t-132.5 -220t-190 -76.5 q-63 0 -110 13t-79 28zM1190 205h205q72 0 127.5 12.5t94 40.5t58 72t19.5 106q0 69 -19 114.5t-57.5 72t-97 37t-138.5 10.5h-192v-465z" />
+<glyph unicode="&#x40a;" horiz-adv-x="1999" d="M166 0v1384h233v-522h543v522h236v-522h213q140 0 241 -25t165.5 -77t95 -133t30.5 -193q0 -226 -133.5 -330t-398.5 -104h-449v659h-543v-659h-233zM1178 205h204q72 0 128 12.5t94 40.5t57.5 72t19.5 106q0 66 -18.5 109t-57 68.5t-97 35.5t-138.5 10h-192v-454z" />
+<glyph unicode="&#x40b;" horiz-adv-x="1356" d="M20 1190v194h775v-194h-285v-352q84 23 161 35t158 12q109 0 189.5 -21t133 -72.5t78 -137.5t25.5 -216v-438h-233v356q0 104 -10.5 169.5t-38.5 102.5t-75.5 50.5t-121.5 13.5q-42 0 -114 -10.5t-152 -32.5v-649h-234v1190h-256z" />
+<glyph unicode="&#x40c;" horiz-adv-x="1266" d="M166 0v1384h233v-583h191q42 0 79.5 24.5t74.5 89t75.5 178t81.5 291.5h242q-40 -177 -81.5 -297t-84 -196.5t-85.5 -118.5t-87 -63q82 -37 137 -94.5t95.5 -142.5t74 -201.5t72.5 -270.5h-244q-40 150 -73 262.5t-72.5 187.5t-92 112.5t-131.5 37.5h-172v-600h-233z M504 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x40d;" horiz-adv-x="1397" d="M166 0v1384h219v-1054l549 1054h297v-1384h-219v1110l-580 -1110h-266zM391 1905h275l184 -361h-174z" />
+<glyph unicode="&#x40e;" horiz-adv-x="1229" d="M43 1384h252l344 -751l322 751h243l-514 -1148q-36 -82 -75.5 -133.5t-85 -81t-98 -40t-114.5 -10.5q-24 0 -57 4t-67.5 10.5t-67 15t-55.5 17.5l69 187q21 -10 46 -17.5t49.5 -13t45.5 -8t35 -2.5q25 0 50 7t49 25.5t46 50.5t40 81l18 47zM297 1788h209 q7 -77 38.5 -113.5t94.5 -36.5q69 0 100 35.5t36 114.5h211q0 -56 -22 -104.5t-66 -84.5t-109 -56.5t-150 -20.5q-87 0 -151 21.5t-106.5 58t-63.5 84.5t-21 102z" />
+<glyph unicode="&#x40f;" horiz-adv-x="1378" d="M166 0v1384h235v-1171h576v1171h235v-1384h-405v-262h-234v262h-407z" />
+<glyph unicode="&#x410;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM444 528h412l-205 623z" />
+<glyph unicode="&#x411;" horiz-adv-x="1270" d="M166 0v1384h909v-194h-676v-363h224q143 0 246.5 -26.5t170.5 -78.5t99 -130.5t32 -181.5q0 -116 -39 -194.5t-110 -126.5t-170.5 -68.5t-220.5 -20.5h-465zM399 197h187q74 0 137 8t109 31.5t72 66.5t26 113t-23.5 112.5t-67 65.5t-105 31t-138.5 8h-197v-436z" />
+<glyph unicode="&#x412;" horiz-adv-x="1284" d="M166 0v1384h448q134 0 227 -19t151 -58.5t84 -99.5t26 -142q0 -74 -18.5 -128t-50.5 -91.5t-75 -60.5t-92 -35q71 -9 129.5 -33t100.5 -65.5t65 -102.5t23 -146q0 -105 -36 -181t-104.5 -125.5t-167.5 -73t-225 -23.5h-485zM399 209h166q91 0 161 6t118 28t73 63.5 t25 113.5q0 61 -19 100t-59.5 61.5t-103 31t-148.5 8.5h-213v-412zM399 825h189q78 0 130.5 12t85 35.5t46.5 59t14 82.5t-14 78.5t-45.5 51t-82.5 28t-126 8.5h-197v-355z" />
+<glyph unicode="&#x413;" d="M154 0v1384h870v-198h-637v-1186h-233z" />
+<glyph unicode="&#x414;" horiz-adv-x="1337" d="M27 197h120q36 73 76 183t73.5 258t55.5 334t23 412h770v-1187h166v-459h-232v262h-821v-262h-231v459zM379 199h532v987h-319q-9 -177 -32 -329t-53.5 -276.5t-64.5 -221t-63 -160.5z" />
+<glyph unicode="&#x415;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872z" />
+<glyph unicode="&#x416;" horiz-adv-x="1843" d="M82 0q38 155 71.5 271.5t74.5 201.5t96.5 142.5t138.5 93.5q-45 22 -89 64t-86.5 118.5t-83.5 196t-79 296.5h244q41 -178 79.5 -291.5t76 -178t75 -89t76.5 -24.5h129v583h233v-583h131q42 0 79 24.5t73.5 89t74 178t79.5 291.5h243q-39 -177 -80 -297t-83.5 -196.5 t-86 -118.5t-88.5 -63q83 -37 138.5 -94.5t96.5 -142.5t74 -201.5t72 -270.5h-243q-43 157 -77.5 270t-73.5 186.5t-89.5 108.5t-126.5 35h-113v-600h-233v600h-113q-68 0 -118 -30t-91 -99.5t-78 -184.5t-79 -286h-244z" />
+<glyph unicode="&#x417;" horiz-adv-x="1192" d="M39 227l188 123q24 -38 56.5 -72t73 -59.5t89.5 -40t107 -14.5q137 0 215 61.5t78 175.5q0 106 -59.5 161.5t-188.5 55.5h-276v197h276q49 0 90.5 10.5t72 34.5t47.5 63.5t17 98.5q0 48 -19 85.5t-53 62.5t-81.5 38t-104.5 13q-46 0 -90 -6t-87.5 -21t-87.5 -40t-91 -62 l-125 172q42 34 92 61.5t110 47t131 30t156 10.5q129 0 222.5 -28.5t155 -80t91 -122.5t29.5 -156q0 -58 -15 -107.5t-42 -89.5t-65.5 -69.5t-86.5 -46.5q113 -42 170.5 -127t57.5 -197q0 -75 -27 -150t-89.5 -134.5t-165.5 -96.5t-255 -37q-94 0 -172 17.5t-141.5 50.5 t-114 80.5t-88.5 107.5z" />
+<glyph unicode="&#x418;" horiz-adv-x="1397" d="M166 0v1384h219v-1054l549 1054h297v-1384h-219v1110l-580 -1110h-266z" />
+<glyph unicode="&#x419;" horiz-adv-x="1397" d="M166 0v1384h219v-1054l549 1054h297v-1384h-219v1110l-580 -1110h-266zM364 1788h209q7 -77 38.5 -113.5t94.5 -36.5q69 0 100 35.5t36 114.5h211q0 -56 -22 -104.5t-66 -84.5t-109 -56.5t-150 -20.5q-87 0 -151 21.5t-106.5 58t-63.5 84.5t-21 102z" />
+<glyph unicode="&#x41a;" horiz-adv-x="1266" d="M166 0v1384h233v-583h191q42 0 79.5 24.5t74.5 89t75.5 178t81.5 291.5h242q-40 -177 -81.5 -297t-84 -196.5t-85.5 -118.5t-87 -63q82 -37 137 -94.5t95.5 -142.5t74 -201.5t72.5 -270.5h-244q-40 150 -73 262.5t-72.5 187.5t-92 112.5t-131.5 37.5h-172v-600h-233z" />
+<glyph unicode="&#x41b;" horiz-adv-x="1395" d="M16 16l62 185q25 -11 46 -14t32 -3q64 0 110.5 58.5t76.5 177.5t44 300t14 427v237h828v-1384h-234v1186h-364v-99q0 -260 -25.5 -466t-78 -349.5t-132.5 -220t-190 -76.5q-63 0 -110 13t-79 28z" />
+<glyph unicode="&#x41c;" horiz-adv-x="1630" d="M166 0v1384h287l364 -706l367 706h280v-1384h-225v1038l-356 -673h-140l-354 673v-1038h-223z" />
+<glyph unicode="&#x41d;" horiz-adv-x="1386" d="M166 0v1384h233v-561h588v561h234v-1384h-234v610h-588v-610h-233z" />
+<glyph unicode="&#x41e;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32 t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5z" />
+<glyph unicode="&#x41f;" horiz-adv-x="1372" d="M166 0v1384h1040v-1384h-237v1180h-568v-1180h-235z" />
+<glyph unicode="&#x420;" horiz-adv-x="1210" d="M166 0v1384h465q118 0 209.5 -24.5t154 -78.5t95 -140.5t32.5 -210.5q0 -125 -28.5 -215.5t-89 -149.5t-155 -87.5t-226.5 -28.5h-224v-449h-233zM399 655h146q88 0 151.5 9t104 37.5t59.5 82.5t19 144q0 75 -20.5 123.5t-59.5 76.5t-96.5 39t-131.5 11h-172v-523z" />
+<glyph unicode="&#x421;" horiz-adv-x="1327" d="M113 692q0 363 154 542t460 179q105 0 186 -19.5t143 -53.5t106.5 -80.5t76.5 -100.5l-186 -135q-22 34 -48.5 67t-64 58.5t-88.5 41t-121 15.5q-195 0 -286 -129t-91 -385q0 -137 24.5 -234t72.5 -159.5t119 -91.5t163 -29q69 0 121 15t91.5 40.5t69.5 60t56 73.5 l189 -131q-36 -56 -81.5 -104.5t-107 -84t-143.5 -56t-191 -20.5q-317 0 -470.5 180t-153.5 541z" />
+<glyph unicode="&#x422;" horiz-adv-x="1194" d="M37 1171v213h1118v-213h-442v-1171h-234v1171h-442z" />
+<glyph unicode="&#x423;" horiz-adv-x="1229" d="M43 1384h252l344 -751l322 751h243l-514 -1148q-36 -82 -75.5 -133.5t-85 -81t-98 -40t-114.5 -10.5q-24 0 -57 4t-67.5 10.5t-67 15t-55.5 17.5l69 187q21 -10 46 -17.5t49.5 -13t45.5 -8t35 -2.5q25 0 50 7t49 25.5t46 50.5t40 81l18 47z" />
+<glyph unicode="&#x424;" horiz-adv-x="1526" d="M78 696q0 125 32.5 222.5t102.5 166.5t180 109t264 51v187h215v-187q153 -10 262 -49.5t179 -108.5t102.5 -167t32.5 -224t-32.5 -224t-102.5 -167.5t-179 -109.5t-262 -50v-192h-215v192q-154 10 -264 50t-180 109.5t-102.5 167.5t-32.5 224zM315 696q0 -173 81.5 -259 t260.5 -101v721q-90 -9 -155 -34t-106.5 -69t-61 -108t-19.5 -150zM872 336q175 15 256.5 101.5t81.5 258.5t-81.5 257t-256.5 102v-719z" />
+<glyph unicode="&#x425;" horiz-adv-x="1247" d="M41 0l455 694l-443 690h269l307 -507l317 507h260l-448 -684l446 -700h-266l-317 516l-322 -516h-258z" />
+<glyph unicode="&#x426;" horiz-adv-x="1380" d="M166 0v1384h233v-1171h555v1171h234v-1175h166v-471h-232v262h-956z" />
+<glyph unicode="&#x427;" horiz-adv-x="1270" d="M84 938v446h233v-352q0 -101 8.5 -166t33.5 -102.5t70.5 -52.5t119.5 -15q77 0 161.5 11.5t159.5 31.5v645h234v-1384h-234v539q-100 -26 -191.5 -39t-174.5 -13q-111 0 -190.5 22.5t-130.5 75.5t-75 139t-24 214z" />
+<glyph unicode="&#x428;" horiz-adv-x="1884" d="M166 0v1384h233v-1175h426v1175h232v-1175h428v1175h233v-1384h-1552z" />
+<glyph unicode="&#x429;" horiz-adv-x="1909" d="M166 0v1384h233v-1175h426v1175h232v-1175h428v1175h233v-1177h164v-469h-231v262h-1485z" />
+<glyph unicode="&#x42a;" horiz-adv-x="1497" d="M37 1186v198h633v-512h219q141 0 241.5 -26t165 -80t95 -136t30.5 -194q0 -227 -133.5 -331.5t-398.5 -104.5h-453v1186h-399zM670 205h211q71 0 126.5 12.5t94 40.5t58.5 72t20 106q0 69 -19 114.5t-57.5 72t-97 37t-138.5 10.5h-198v-465z" />
+<glyph unicode="&#x42b;" horiz-adv-x="1763" d="M166 0v1384h233v-512h219q141 0 241.5 -26t165.5 -80t95.5 -136t30.5 -194q0 -114 -33.5 -196.5t-100 -136t-166.5 -78.5t-233 -25h-452zM399 205h211q72 0 128 12.5t94 40.5t57.5 72t19.5 106q0 69 -18.5 114.5t-57 72t-97 37t-138.5 10.5h-199v-465zM1364 0v1384h233 v-1384h-233z" />
+<glyph unicode="&#x42c;" horiz-adv-x="1227" d="M166 0v1384h233v-512h219q141 0 241.5 -26t165.5 -80t95.5 -136t30.5 -194q0 -114 -33.5 -196.5t-100 -136t-166.5 -78.5t-233 -25h-452zM399 205h211q72 0 128 12.5t94 40.5t57.5 72t19.5 106q0 69 -18.5 114.5t-57 72t-97 37t-138.5 10.5h-199v-465z" />
+<glyph unicode="&#x42d;" horiz-adv-x="1294" d="M80 236l188 131q26 -39 56.5 -73.5t70 -60t91 -40.5t120.5 -15q84 0 149.5 24t113 74.5t75.5 129t37 188.5h-627v209h625q-17 199 -108 301t-263 102q-70 0 -120.5 -15.5t-88 -41t-64.5 -58.5t-48 -67l-187 135q31 54 76 100.5t107 80.5t143.5 53.5t185.5 19.5 q306 0 460.5 -179t154.5 -542q0 -361 -154.5 -541t-470.5 -180q-109 0 -191 20.5t-143.5 56t-106.5 84t-81 104.5z" />
+<glyph unicode="&#x42e;" horiz-adv-x="1917" d="M166 0v1384h233v-598h260q9 146 46 262.5t107 197.5t174.5 124t248.5 43q157 0 267 -50.5t179.5 -144t101.5 -227.5t32 -301q0 -164 -32 -297t-102 -227t-180 -144.5t-266 -50.5q-144 0 -248.5 43t-174 123.5t-107 195t-46.5 257.5h-260v-590h-233zM901 690 q0 -119 16.5 -216t55.5 -166t103 -106.5t159 -37.5t159.5 37.5t103.5 106t56 165.5t17 217q0 121 -17 219t-56 167t-103.5 106t-159.5 37t-159 -37t-103 -106t-55.5 -167t-16.5 -219z" />
+<glyph unicode="&#x42f;" horiz-adv-x="1260" d="M45 0l373 575q-62 13 -115 41.5t-91.5 77.5t-60.5 120t-22 169q0 110 31 186.5t93.5 124t155.5 69t218 21.5h467v-1384h-234v545h-192l-353 -545h-270zM369 971q0 -62 13 -104t44 -68t83.5 -37.5t131.5 -11.5h219v430h-231q-69 0 -118 -10t-80.5 -34t-46.5 -64t-15 -101z " />
+<glyph unicode="&#x430;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5z" />
+<glyph unicode="&#x431;" horiz-adv-x="1180" d="M102 653q0 192 23 327.5t71 227.5t121.5 147t175.5 87.5t232.5 48.5t292.5 29v-187q-111 -8 -204 -16t-169 -24.5t-133.5 -44.5t-97.5 -75t-61.5 -116t-24.5 -168q66 57 154.5 89t179.5 32q213 0 322.5 -120t109.5 -364q0 -123 -30 -225.5t-89 -176t-147 -114.5t-205 -41 q-135 0 -233.5 46.5t-162.5 135t-94.5 215t-30.5 287.5zM326 612q0 -107 19 -193.5t56.5 -148.5t93.5 -95.5t130 -33.5q60 0 106.5 29t77.5 80t47 120t16 148q0 161 -59 239.5t-190 78.5q-65 0 -119 -22.5t-93 -48.5q-46 -32 -83 -71q-2 -23 -2 -41.5v-40.5z" />
+<glyph unicode="&#x432;" horiz-adv-x="1120" d="M150 0v1049h399q115 0 195 -14t130 -44t72.5 -77t22.5 -113q0 -90 -46.5 -149.5t-121.5 -90.5q50 -11 91.5 -29.5t71.5 -48t47 -71t17 -97.5q0 -159 -115.5 -237t-345.5 -78h-417zM362 160h148q70 0 125.5 6.5t93.5 24t58 48.5t20 80q0 42 -14 70t-44 44.5t-76.5 23 t-111.5 6.5h-199v-303zM362 623h168q119 0 171.5 36t52.5 107q0 37 -14 61.5t-42.5 38.5t-70.5 19.5t-97 5.5h-168v-268z" />
+<glyph unicode="&#x433;" horiz-adv-x="885" d="M150 0v1049h718v-166h-501v-883h-217z" />
+<glyph unicode="&#x434;" horiz-adv-x="1155" d="M25 162h106q28 54 61 136.5t60.5 193.5t46 250.5t18.5 306.5h656v-887h155v-424h-204v262h-695v-262h-204v424zM336 164h424v721h-242q-7 -124 -26.5 -234.5t-45 -203t-55 -164.5t-55.5 -119z" />
+<glyph unicode="&#x435;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115z" />
+<glyph unicode="&#x436;" horiz-adv-x="1536" d="M57 0q34 120 61.5 209.5t60 154t75.5 106.5t108 67q-34 15 -67.5 45t-67.5 88t-67.5 149.5t-67.5 229.5h221q35 -133 66.5 -217.5t61.5 -132.5t59.5 -65.5t60.5 -17.5h101v433h212v-433h99q33 0 63 17.5t59.5 65.5t60.5 132.5t67 217.5h219q-34 -138 -67.5 -229.5 t-67 -149.5t-67 -88t-66.5 -45q63 -25 106 -67t76 -106.5t61 -154t62 -209.5h-222q-35 118 -63 202.5t-59.5 138.5t-73 79.5t-103.5 25.5h-84v-446h-212v446h-87q-59 0 -99.5 -23.5t-72.5 -76t-60.5 -137.5t-63.5 -209h-222z" />
+<glyph unicode="&#x437;" horiz-adv-x="983" d="M49 156l168 110q23 -31 47 -53t51 -36t57.5 -20.5t67.5 -6.5q51 0 93.5 9.5t74 28.5t49 47t17.5 66q0 76 -46.5 117t-156.5 41h-231v164h221q48 0 86 5t64 19t39.5 38t13.5 63q0 43 -16 72t-44.5 46.5t-68 25t-86.5 7.5q-83 0 -136 -30.5t-88 -84.5l-162 109 q56 94 153.5 140t232.5 46q109 0 190.5 -23.5t135 -66t80 -103t26.5 -134.5q0 -82 -42 -140.5t-110 -83.5q32 -12 61.5 -34t52 -53t35.5 -70t13 -84q0 -156 -112 -237t-339 -81q-76 0 -136.5 13t-108 37.5t-83.5 59t-63 77.5z" />
+<glyph unicode="&#x438;" horiz-adv-x="1202" d="M150 0v1049h198v-768l500 768h209v-1049h-197v758l-498 -758h-212z" />
+<glyph unicode="&#x439;" horiz-adv-x="1202" d="M150 0v1049h198v-768l500 768h209v-1049h-197v758l-498 -758h-212zM264 1454h211q7 -77 37.5 -113t93.5 -36q70 0 100.5 35.5t37.5 113.5h209q0 -55 -22 -103.5t-65.5 -84.5t-108.5 -57t-151 -21q-84 0 -148 21.5t-107 58t-65 84.5t-22 102z" />
+<glyph unicode="&#x43a;" horiz-adv-x="1053" d="M150 0v1049h212v-433h142q33 0 63.5 17.5t60.5 65.5t61.5 132.5t66.5 217.5h219q-35 -138 -69 -229.5t-68 -149.5t-68 -88t-68 -45q66 -25 110 -67t77 -106.5t60.5 -154t60.5 -209.5h-219q-36 116 -64 200t-60 139t-74 81t-106 26h-125v-446h-212z" />
+<glyph unicode="&#x43b;" horiz-adv-x="1155" d="M12 4l39 168q17 -3 33.5 -4.5t26.5 -1.5q50 0 87.5 38t63 121.5t38.5 216t13 320.5v187h693v-1049h-213v883h-273v-70q0 -210 -25 -366t-73.5 -259.5t-119 -154.5t-161.5 -51q-15 0 -33.5 2t-36.5 5t-33.5 7t-25.5 8z" />
+<glyph unicode="&#x43c;" horiz-adv-x="1352" d="M150 0v1049h233l297 -519l291 519h229v-1049h-194v772l-273 -504h-115l-274 504v-772h-194z" />
+<glyph unicode="&#x43d;" horiz-adv-x="1194" d="M150 0v1049h212v-426h467v426h213v-1049h-213v457h-467v-457h-212z" />
+<glyph unicode="&#x43e;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92 t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x43f;" horiz-adv-x="1186" d="M150 0v1049h884v-1049h-215v883h-454v-883h-215z" />
+<glyph unicode="&#x440;" horiz-adv-x="1194" d="M158 -395v1444h204v-105q66 60 147.5 97.5t178.5 37.5q105 0 180.5 -40t125 -112t73 -173t23.5 -222q0 -110 -24 -212t-75 -180t-131 -124.5t-192 -46.5q-85 0 -159 29.5t-136 83.5v-477h-215zM373 262q24 -21 52.5 -39.5t60.5 -32.5t66 -22t69 -8q50 0 95 21t78.5 65.5 t53.5 114t20 167.5q0 177 -58.5 269t-172.5 92q-36 0 -72.5 -9.5t-70.5 -26t-65 -38t-56 -45.5v-508z" />
+<glyph unicode="&#x441;" horiz-adv-x="1044" d="M104 520q0 128 28.5 231.5t87.5 176t150 112t216 39.5q133 0 231 -46t154 -140l-168 -113q-35 54 -86 82.5t-129 28.5q-135 0 -198.5 -89.5t-63.5 -281.5q0 -88 14 -156t45.5 -114t83.5 -70t127 -24q35 0 65.5 5.5t57.5 18.5t51 34t47 52l168 -110q-28 -43 -64 -77.5 t-83.5 -59t-108 -37.5t-135.5 -13q-132 0 -225 40t-152 113t-86 174t-27 224z" />
+<glyph unicode="&#x442;" horiz-adv-x="938" d="M16 887v162h906v-162h-347v-887h-213v887h-346z" />
+<glyph unicode="&#x443;" horiz-adv-x="1063" d="M-12 -365l49 183q35 -14 74.5 -21.5t76.5 -7.5q30 0 56.5 10.5t51 34t47 61.5t44.5 93l31 75l-381 986h227l268 -719l273 719h221l-451 -1125q-35 -86 -71 -146.5t-81 -99t-101 -56t-129 -17.5q-50 0 -105 8t-100 22z" />
+<glyph unicode="&#x444;" horiz-adv-x="1376" d="M96 522q0 123 27.5 220.5t86.5 167.5t152.5 111.5t225.5 53.5v408h200v-408q132 -12 225 -54t152 -112t86 -167.5t27 -219.5q0 -120 -27.5 -216.5t-86.5 -166.5t-152 -111.5t-224 -52.5v-368h-200v368q-131 11 -224.5 52.5t-153 111.5t-87 166.5t-27.5 216.5zM317 522 q0 -84 14 -150t45.5 -114t83.5 -77t128 -40v768q-77 -11 -129 -40.5t-83.5 -78t-45 -115.5t-13.5 -153zM788 141q75 12 127 41.5t84 77t46 113t14 149.5q0 85 -14 151.5t-46 114.5t-84 78t-127 41v-766z" />
+<glyph unicode="&#x445;" horiz-adv-x="1044" d="M43 0l354 518l-350 531h256l225 -365l232 365h241l-354 -519l354 -530h-260l-225 367l-233 -367h-240z" />
+<glyph unicode="&#x446;" horiz-adv-x="1219" d="M150 0v1049h217v-885h458v885h215v-887h154v-424h-199v262h-845z" />
+<glyph unicode="&#x447;" horiz-adv-x="1104" d="M86 715v334h211v-275q0 -79 7.5 -130t27 -81t52 -41.5t83.5 -11.5q27 0 61.5 4t71.5 10.5t73.5 15.5t67.5 19v490h213v-1049h-213v397q-38 -11 -78.5 -22t-82 -20t-81 -15t-73.5 -6q-89 0 -153 19.5t-105.5 64.5t-61.5 118t-20 179z" />
+<glyph unicode="&#x448;" horiz-adv-x="1626" d="M150 0v1049h212v-887h353v887h213v-887h350v887h213v-1049h-1341z" />
+<glyph unicode="&#x449;" horiz-adv-x="1667" d="M150 0v1049h212v-887h351v887h213v-887h350v887h213v-887h153v-424h-200v262h-1292z" />
+<glyph unicode="&#x44a;" horiz-adv-x="1229" d="M16 887v162h525v-383h174q236 0 345 -82.5t109 -255.5q0 -89 -29 -151.5t-87 -101.5t-143.5 -57t-198.5 -18h-383v887h-312zM541 162h161q131 0 188.5 39.5t57.5 128.5q0 52 -15.5 85.5t-47.5 52.5t-81 26.5t-116 7.5h-147v-340z" />
+<glyph unicode="&#x44b;" horiz-adv-x="1497" d="M150 0v1049h212v-383h173q236 0 345 -82.5t109 -255.5q0 -85 -26.5 -146.5t-83 -102t-143 -60t-206.5 -19.5h-380zM362 162h162q132 0 188 40t56 128q0 49 -13.5 82t-44.5 53t-80.5 28.5t-121.5 8.5h-146v-340zM1135 0v1049h213v-1049h-213z" />
+<glyph unicode="&#x44c;" horiz-adv-x="1049" d="M150 0v1049h212v-383h173q236 0 345 -82.5t109 -255.5q0 -85 -26.5 -146.5t-83 -102t-143 -60t-206.5 -19.5h-380zM362 162h162q132 0 188 40t56 128q0 49 -13.5 82t-44.5 53t-80.5 28.5t-121.5 8.5h-146v-340z" />
+<glyph unicode="&#x44d;" horiz-adv-x="1044" d="M59 156l168 110q46 -62 98.5 -86t123.5 -24q67 0 115 19t79.5 56.5t48.5 92t23 125.5h-494v163h492q-14 144 -76.5 211.5t-179.5 67.5q-80 0 -130 -28.5t-87 -82.5l-166 113q55 94 153 140t232 46q124 0 215 -39.5t150 -112t87.5 -176t28.5 -231.5q0 -123 -27 -224 t-85.5 -174t-151.5 -113t-225 -40q-76 0 -136.5 13t-108.5 37.5t-84 59t-63 77.5z" />
+<glyph unicode="&#x44e;" horiz-adv-x="1645" d="M150 0v1049h210v-447h209q8 105 38 192.5t88.5 150.5t147.5 98.5t214 35.5q136 0 229.5 -42.5t151.5 -117t84 -176.5t26 -221q0 -117 -26 -218.5t-84 -175.5t-151.5 -116.5t-229.5 -42.5q-125 0 -214.5 35.5t-148 98.5t-88.5 149.5t-37 189.5h-209v-442h-210zM784 522 q0 -88 15 -158.5t48 -120t85 -76t125 -26.5t124.5 26.5t84.5 76t48 120t15 158.5q0 91 -15 162.5t-48 121t-84.5 75.5t-124.5 26t-125 -26t-85 -75.5t-48 -121t-15 -162.5z" />
+<glyph unicode="&#x44f;" horiz-adv-x="1071" d="M47 0l281 440q-115 29 -174.5 107t-59.5 211q0 84 27 139.5t80 89.5t132.5 48t184.5 14h402v-1049h-211v422h-164l-262 -422h-236zM309 741q0 -45 10.5 -75.5t36 -49t69.5 -26.5t110 -8h174v309h-179q-62 0 -104 -8t-68 -25.5t-37.5 -46t-11.5 -70.5z" />
+<glyph unicode="&#x450;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM284 1569h275l184 -361h-174zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115z" />
+<glyph unicode="&#x451;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM213 1325q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115zM632 1325q0 62 27.5 90.5t95.5 28.5 q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x452;" horiz-adv-x="1210" d="M23 1210v156h131v123h213v-123h290v-156h-290v-309q74 82 164 130t190 48q196 0 290.5 -146t94.5 -435q0 -222 -30.5 -382.5t-92 -267t-155 -164t-220.5 -73.5l-37 170q52 13 95.5 35t79 58t62 87.5t45 124.5t27.5 169.5t9 221.5q0 116 -14 194t-41.5 125.5t-69.5 68 t-98 20.5q-69 0 -144 -39.5t-155 -124.5v-721h-213v1210h-131z" />
+<glyph unicode="&#x453;" horiz-adv-x="885" d="M150 0v1049h718v-166h-501v-883h-217zM343 1208l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x454;" horiz-adv-x="1044" d="M104 520q0 128 28.5 231.5t87.5 176t150 112t216 39.5q133 0 231 -46t154 -140l-168 -113q-35 54 -86 82.5t-129 28.5q-118 0 -180.5 -67.5t-77.5 -211.5h491v-163h-491q4 -71 21 -125.5t49 -92t80 -56.5t116 -19q35 0 65.5 5.5t57.5 18.5t51 34t47 52l168 -110 q-28 -43 -64 -77.5t-83.5 -59t-108 -37.5t-135.5 -13q-132 0 -225 40t-152 113t-86 174t-27 224z" />
+<glyph unicode="&#x455;" horiz-adv-x="1008" d="M88 154l164 110q43 -63 106 -90t142 -27q39 0 76 6t65.5 21.5t46 41.5t17.5 65q0 30 -13 51t-41 37.5t-72.5 31t-107.5 29.5q-71 18 -136 41t-114.5 60.5t-79.5 94t-30 140.5q0 67 25 124t75.5 99t125 66t173.5 24q69 0 129.5 -13t110 -37t87.5 -57.5t62 -74.5l-164 -111 q-15 22 -36 43t-49.5 37t-64 25.5t-79.5 9.5q-84 0 -134 -32.5t-50 -94.5q0 -29 10.5 -49t34 -36t61.5 -28.5t92 -25.5q91 -23 164.5 -49t124.5 -64t78.5 -93.5t27.5 -137.5q0 -87 -33.5 -148t-90 -100t-130.5 -56.5t-155 -17.5q-82 0 -148.5 14t-118.5 38.5t-89.5 58.5 t-61.5 74z" />
+<glyph unicode="&#x456;" horiz-adv-x="530" d="M137 1325q0 62 29 89.5t98 27.5t99 -27t30 -90q0 -66 -31.5 -91.5t-97.5 -25.5q-72 0 -99.5 30t-27.5 87zM158 0v1049h215v-1049h-215z" />
+<glyph unicode="&#x457;" horiz-adv-x="530" d="M-78 1325q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM158 0v1049h215v-1049h-215zM341 1325q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x458;" horiz-adv-x="549" d="M-154 -365l50 183q35 -14 72 -21.5t79 -7.5q41 0 65.5 13t38 40t17.5 68t4 96v1043h215v-1094q0 -91 -17.5 -157t-57.5 -109t-104 -63.5t-157 -20.5q-18 0 -42.5 2t-52 5.5t-56.5 9t-54 13.5zM154 1325q0 62 28 89.5t97 27.5q71 0 100 -27t29 -90q0 -66 -31.5 -91.5 t-97.5 -25.5q-36 0 -60.5 7.5t-38.5 22.5t-20 36.5t-6 50.5z" />
+<glyph unicode="&#x459;" horiz-adv-x="1677" d="M12 4l39 168q17 -3 33.5 -4.5t26.5 -1.5q49 0 86.5 38t62.5 121.5t38 216t13 320.5v187h684v-383h172q234 0 342.5 -82.5t108.5 -255.5q0 -89 -29 -151.5t-86.5 -101.5t-143 -57t-198.5 -18h-379v885h-262v-72q0 -419 -99.5 -625t-279.5 -206q-15 0 -32.5 2t-35.5 5 t-34 7t-27 8zM995 162h160q120 0 181 37t61 131q0 52 -15.5 85.5t-47 52.5t-80 26.5t-113.5 7.5h-146v-340z" />
+<glyph unicode="&#x45a;" horiz-adv-x="1712" d="M150 0v1049h212v-404h457v404h213v-404h172q116 0 200.5 -18t140 -56t82 -98.5t26.5 -144.5q0 -89 -29 -151.5t-86.5 -101.5t-142.5 -57t-197 -18h-379v481h-457v-481h-212zM1032 162h160q127 0 183.5 39.5t56.5 128.5q0 43 -13.5 72t-43.5 46.5t-78.5 25t-118.5 7.5 h-146v-319z" />
+<glyph unicode="&#x45b;" horiz-adv-x="1169" d="M18 1204v154h136v131h213v-131h286v-154h-286v-303q35 35 77.5 67.5t89 57t96.5 39t101 14.5q88 0 148 -25t96 -73.5t51.5 -119t15.5 -161.5v-700h-213v598q0 80 -5 135t-21.5 88.5t-47 48.5t-81.5 15q-34 0 -72.5 -13.5t-78 -36t-79.5 -52t-77 -62.5v-721h-213v1204 h-136z" />
+<glyph unicode="&#x45c;" horiz-adv-x="1053" d="M150 0v1049h212v-433h142q33 0 63.5 17.5t60.5 65.5t61.5 132.5t66.5 217.5h219q-35 -138 -69 -229.5t-68 -149.5t-68 -88t-68 -45q66 -25 110 -67t77 -106.5t60.5 -154t60.5 -209.5h-219q-36 116 -64 200t-60 139t-74 81t-106 26h-125v-446h-212zM405 1208l184 361h274 l-284 -361h-174z" />
+<glyph unicode="&#x45d;" horiz-adv-x="1202" d="M150 0v1049h198v-768l500 768h209v-1049h-197v758l-498 -758h-212zM292 1569h275l184 -361h-174z" />
+<glyph unicode="&#x45e;" horiz-adv-x="1063" d="M-12 -365l49 183q35 -14 74.5 -21.5t76.5 -7.5q30 0 56.5 10.5t51 34t47 61.5t44.5 93l31 75l-381 986h227l268 -719l273 719h221l-451 -1125q-35 -86 -71 -146.5t-81 -99t-101 -56t-129 -17.5q-50 0 -105 8t-100 22zM188 1454h211q7 -77 37.5 -113t93.5 -36 q70 0 100.5 35.5t37.5 113.5h209q0 -55 -22 -103.5t-65.5 -84.5t-108.5 -57t-151 -21q-84 0 -148 21.5t-107 58t-65 84.5t-22 102z" />
+<glyph unicode="&#x45f;" horiz-adv-x="1165" d="M135 0v1049h215v-885h463v885h217v-1049h-342v-262h-213v262h-340z" />
+<glyph unicode="&#x490;" horiz-adv-x="1026" d="M166 0v1384h594v250h231v-463h-590v-1171h-235z" />
+<glyph unicode="&#x491;" horiz-adv-x="877" d="M135 0v1049h508v297h211v-465h-504v-881h-215z" />
+<glyph unicode="&#x1e80;" horiz-adv-x="1794" d="M55 1384h232l239 -1011l246 1011h244l250 -1017l243 1017h230l-346 -1384h-254l-246 1012l-248 -1012h-252zM587 1905h275l184 -361h-174z" />
+<glyph unicode="&#x1e81;" horiz-adv-x="1520" d="M45 1049h223l170 -738l242 738h170l246 -736l164 736h215l-271 -1049h-196l-246 735l-248 -735h-197zM434 1569h275l184 -361h-174z" />
+<glyph unicode="&#x1e82;" horiz-adv-x="1794" d="M55 1384h232l239 -1011l246 1011h244l250 -1017l243 1017h230l-346 -1384h-254l-246 1012l-248 -1012h-252zM764 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x1e83;" horiz-adv-x="1520" d="M45 1049h223l170 -738l242 738h170l246 -736l164 736h215l-271 -1049h-196l-246 735l-248 -735h-197zM652 1208l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x1e84;" horiz-adv-x="1794" d="M55 1384h232l239 -1011l246 1011h244l250 -1017l243 1017h230l-346 -1384h-254l-246 1012l-248 -1012h-252zM564 1661q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM983 1661q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91 q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x1e85;" horiz-adv-x="1520" d="M45 1049h223l170 -738l242 738h170l246 -736l164 736h215l-271 -1049h-196l-246 735l-248 -735h-197zM430 1325q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM849 1325q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91 q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph unicode="&#x1e9e;" horiz-adv-x="1454" d="M166 0v879q0 139 31.5 240t97 167t166 97.5t239.5 31.5q58 0 105.5 -3t89.5 -8.5t80.5 -13.5t77.5 -18v-166q-116 0 -180 -46.5t-64 -137.5q0 -35 9 -63t32.5 -52.5t64.5 -46.5t105 -45q87 -31 151 -71t106.5 -91.5t63.5 -117t21 -146.5q0 -101 -33 -178.5t-93 -131 t-145 -81t-190 -27.5q-85 0 -150.5 17t-116 49.5t-88.5 79.5t-69 108l187 127q40 -88 99.5 -131t147.5 -43q47 0 86 12t67.5 36.5t44 61.5t15.5 87q0 39 -11 72.5t-35.5 62.5t-65 54t-99.5 46q-101 36 -167 77.5t-104.5 90t-53.5 104.5t-15 122t21 115t61 89 q-74 -2 -123.5 -20t-79 -55.5t-41.5 -96t-12 -141.5v-895h-233z" />
+<glyph unicode="&#x1ea0;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM444 528h412l-205 623zM526 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ea1;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5zM377 -254q0 65 28 94t99 29 q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ea2;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM444 528h412l-205 623zM453 1798q25 20 73 36.5t113 16.5q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51 -31.5t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5 t-48.5 -21.5z" />
+<glyph unicode="&#x1ea3;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5zM348 1462q25 20 73 37t113 17 q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ea4;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM313 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM444 528h412l-205 623zM864 1724l140 283h274l-240 -283h-174z" />
+<glyph unicode="&#x1ea5;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM190 1167l232 289h227l232 -289h-181l-164 152l-167 -152h-179zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19 t-90 -36t-55.5 -57.5t-19 -84.5zM741 1389l140 282h274l-240 -282h-174z" />
+<glyph unicode="&#x1ea6;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM39 2007h276l138 -283h-172zM313 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM444 528h412l-205 623z" />
+<glyph unicode="&#x1ea7;" horiz-adv-x="1118" d="M-84 1671h276l138 -282h-172zM96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18 t138.5 -60t83.5 -112.5t28 -175.5v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM190 1167l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5 v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5z" />
+<glyph unicode="&#x1ea8;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM313 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM444 528h412l-205 623zM786 1976q25 22 73.5 38t113.5 16q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49t-51 -31.5t-62 -14.5 v-41h-113v125h33q74 0 74 58q0 53 -72 53q-23 0 -50 -7.5t-48 -21.5z" />
+<glyph unicode="&#x1ea9;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM190 1167l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19 t-90 -36t-55.5 -57.5t-19 -84.5zM663 1640q25 22 73.5 38t113.5 16q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49t-51 -31.5t-62 -14.5v-41h-113v125h33q74 0 74 58q0 53 -72 53q-23 0 -50 -7.5t-48 -21.5z" />
+<glyph unicode="&#x1eaa;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM266 1835q3 53 18.5 98.5t45.5 79.5t75 53t107 19q48 0 89 -15.5t77.5 -34.5t70 -34.5t68.5 -15.5q44 0 61.5 23.5t20.5 62.5h152q-5 -54 -20 -100t-44.5 -79t-74.5 -52t-109 -19q-37 0 -67.5 7.5 t-56 19.5t-47.5 25t-43 25t-43 19.5t-46 7.5q-45 0 -62 -24t-20 -66h-152zM313 1503l232 269h227l232 -269h-181l-164 131l-167 -131h-179zM444 528h412l-205 623z" />
+<glyph unicode="&#x1eab;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM143 1509q3 53 18.5 99t45.5 79.5t75 52.5t107 19q48 0 89 -15.5t77.5 -34.5t70 -34.5t68.5 -15.5q44 0 61.5 24t20.5 62h152q-5 -54 -20 -99.5t-44.5 -79t-74.5 -52.5t-109 -19 q-37 0 -67.5 7.5t-56 19.5t-47.5 25t-43 25t-43 19.5t-46 7.5q-45 0 -62 -24t-20 -66h-152zM190 1167l232 279h227l232 -279h-181l-164 142l-167 -142h-179zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19 t-90 -36t-55.5 -57.5t-19 -84.5z" />
+<glyph unicode="&#x1eac;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM313 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179zM444 528h412l-205 623zM524 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5 t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ead;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM190 1208l232 361h227l232 -361h-181l-164 205l-167 -205h-179zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19 t-90 -36t-55.5 -57.5t-19 -84.5zM379 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1eae;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM309 1808h158q14 -62 61.5 -89t122.5 -27q85 0 130 27t59 89h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5zM444 528h412l-205 623zM551 1776 l113 262h276l-221 -262h-168z" />
+<glyph unicode="&#x1eaf;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM192 1503h158q14 -62 61.5 -89.5t122.5 -27.5q85 0 130 27.5t59 89.5h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5z M317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5zM434 1470l113 263h276l-221 -263h-168z" />
+<glyph unicode="&#x1eb0;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM311 1808h158q14 -62 61.5 -89t122.5 -27q85 0 130 27t59 89h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5zM369 2038h274l115 -262h-168zM444 528 h412l-205 623z" />
+<glyph unicode="&#x1eb1;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM192 1503h158q14 -62 61.5 -89.5t122.5 -27.5q85 0 130 27.5t59 89.5h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5z M250 1733h274l115 -263h-168zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5z" />
+<glyph unicode="&#x1eb2;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM311 1808h158q14 -62 61.5 -89t122.5 -27q85 0 130 27t59 89h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5zM444 528h412l-205 623zM467 2083 q25 21 73 37t113 16q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51.5 -31t-63.5 -14v-41h-110v125h33q73 0 73 57q0 53 -71 53q-23 0 -50 -7t-49 -21z" />
+<glyph unicode="&#x1eb3;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM192 1503h158q14 -62 61.5 -89.5t122.5 -27.5q85 0 130 27.5t59 89.5h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5z M317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5zM348 1778q25 21 73 37t113 16q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49t-51.5 -31t-63.5 -14v-41h-110v125h33 q73 0 73 57q0 53 -71 53q-23 0 -50 -7.5t-49 -21.5z" />
+<glyph unicode="&#x1eb4;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM262 1872q3 53 18.5 98.5t45.5 79.5t75 53t107 19q48 0 89 -16t77.5 -34.5t70 -34.5t68.5 -16q44 0 61.5 24t20.5 62h152q-5 -54 -20 -99.5t-44.5 -78.5t-74.5 -52t-109 -19q-37 0 -67.5 7.5t-56 19.5 t-47.5 25t-43 25t-43 19.5t-46 7.5q-45 0 -62 -24t-20 -66h-152zM311 1804h158q14 -63 61.5 -90.5t122.5 -27.5q85 0 130 27.5t59 90.5h158q0 -58 -21.5 -111t-64.5 -93.5t-108 -64.5t-153 -24q-84 0 -148 24t-107 64.5t-65 93.5t-22 111zM444 528h412l-205 623z" />
+<glyph unicode="&#x1eb5;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM143 1567q3 53 18.5 98.5t45.5 79.5t75 53t107 19q48 0 89 -16t77.5 -34.5t70 -34.5t68.5 -16q44 0 61.5 24t20.5 62h152q-5 -54 -20 -99.5t-44.5 -79t-74.5 -52.5t-109 -19 q-56 0 -96.5 16.5t-74.5 36t-64.5 36t-67.5 16.5q-45 0 -62 -24t-20 -66h-152zM192 1499h158q14 -63 61.5 -91t122.5 -28q85 0 130 28t59 91h158q0 -59 -21.5 -112t-64.5 -93t-108 -64t-153 -24q-84 0 -148 24t-107 64t-65 93t-22 112zM317 299q0 -83 44 -117.5t124 -34.5 q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5z" />
+<glyph unicode="&#x1eb6;" horiz-adv-x="1313" d="M39 0l465 1384h303l467 -1384h-242l-106 319h-549l-105 -319h-233zM311 1825h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5zM444 528h412 l-205 623zM526 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1eb7;" horiz-adv-x="1118" d="M96 295q0 95 31.5 159t87 104.5t132 61t167.5 29.5l240 23v49q0 52 -15.5 86.5t-45 55.5t-73 29.5t-98.5 8.5q-53 0 -92.5 -10t-68.5 -26t-48 -36.5t-30 -40.5l-170 109q19 34 52.5 66.5t83.5 58t118.5 41.5t158.5 16q110 0 193 -18t138.5 -60t83.5 -112.5t28 -175.5 v-713h-205v119q-74 -66 -156.5 -108t-179.5 -42q-80 0 -142 24t-104 67.5t-64 103t-22 131.5zM192 1499h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5 t-22 113.5zM317 299q0 -83 44 -117.5t124 -34.5q31 0 64.5 11t68 29t69 42.5t67.5 51.5v229l-150 -14q-69 -6 -122.5 -19t-90 -36t-55.5 -57.5t-19 -84.5zM379 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5 t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1eb8;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM464 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1eb9;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115zM442 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1eba;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM408 1798q25 20 73 36.5t113 16.5q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51 -31.5t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ebb;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115zM383 1462q25 20 73 37t113 17q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-112v125h32q74 0 74 57 q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ebc;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM215 1561q3 62 18.5 115t45.5 92t75 61t107 22q39 0 70.5 -10.5t57.5 -26t48.5 -34t43.5 -34t41.5 -26t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61 t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152z" />
+<glyph unicode="&#x1ebd;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM182 1225q3 62 18.5 115.5t45.5 92.5t75 61t107 22q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27 t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115z" />
+<glyph unicode="&#x1ebe;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM252 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM803 1724l140 283h274l-240 -283h-174z" />
+<glyph unicode="&#x1ebf;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM231 1167l232 289h227l232 -289h-181l-164 152l-167 -152h-179zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115zM782 1389l140 282h274l-240 -282h-174z" />
+<glyph unicode="&#x1ec0;" horiz-adv-x="1151" d="M-22 2007h276l138 -283h-172zM166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM252 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179z" />
+<glyph unicode="&#x1ec1;" horiz-adv-x="1112" d="M-37 1671h276l138 -282h-172zM104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57 t-111.5 -35t-142.5 -12q-251 0 -370.5 138.5t-119.5 408.5zM237 1167l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115z" />
+<glyph unicode="&#x1ec2;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM252 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM725 1976q25 22 73.5 38t113.5 16q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49t-51 -31.5t-62 -14.5v-41h-113v125h33 q74 0 74 58q0 53 -72 53q-23 0 -50 -7.5t-48 -21.5z" />
+<glyph unicode="&#x1ec3;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM231 1167l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115zM704 1640q25 22 73.5 38t113.5 16q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67 t-34.5 -49t-51 -31.5t-62 -14.5v-41h-113v125h33q74 0 74 58q0 53 -72 53q-23 0 -50 -7.5t-48 -21.5z" />
+<glyph unicode="&#x1ec4;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM211 1835q3 53 18.5 98.5t45.5 79.5t75 53t107 19q48 0 89 -15.5t77.5 -34.5t70 -34.5t68.5 -15.5q44 0 61.5 23.5t20.5 62.5h152q-5 -54 -20 -100t-44.5 -79t-74.5 -52t-109 -19q-37 0 -67.5 7.5 t-56 19.5t-47.5 25t-43 25t-43 19.5t-46 7.5q-45 0 -62 -24t-20 -66h-152zM258 1503l232 269h227l232 -269h-181l-164 131l-167 -131h-179z" />
+<glyph unicode="&#x1ec5;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM184 1509q3 53 18.5 99t45.5 79.5t75 52.5t107 19q48 0 89 -15.5t77.5 -34.5t70 -34.5t68.5 -15.5q44 0 61.5 24t20.5 62h152q-5 -54 -20 -99.5t-44.5 -79t-74.5 -52.5t-109 -19q-37 0 -67.5 7.5t-56 19.5t-47.5 25t-43 25t-43 19.5 t-46 7.5q-45 0 -62 -24t-20 -66h-152zM231 1167l232 279h227l232 -279h-181l-164 142l-167 -142h-179zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115z" />
+<glyph unicode="&#x1ec6;" horiz-adv-x="1151" d="M166 0v1384h872v-208h-639v-351h543v-209h-543v-403h639v-213h-872zM258 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179zM464 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z " />
+<glyph unicode="&#x1ec7;" horiz-adv-x="1112" d="M104 516q0 127 25.5 230.5t82 177.5t147.5 114.5t223 40.5q117 0 199.5 -35t134.5 -99t76 -154t24 -199v-113h-690q1 -79 16.5 -139.5t48.5 -101t85.5 -61.5t129.5 -21q72 0 127.5 24.5t102.5 83.5l165 -112q-30 -45 -67 -79t-86 -57t-111.5 -35t-142.5 -12 q-251 0 -370.5 138.5t-119.5 408.5zM231 1208l232 361h227l232 -361h-181l-164 205l-167 -205h-179zM330 637h473q0 131 -55 199.5t-173 68.5q-60 0 -102.5 -17.5t-71 -51.5t-45.5 -84t-26 -115zM448 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5 t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ec8;" horiz-adv-x="821" d="M102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617zM214 1798q25 20 73 36.5t113 16.5q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51 -31.5t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ec9;" horiz-adv-x="530" d="M73 1462q25 20 73 37t113 17q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5zM158 0v1049h215v-1049h-215z" />
+<glyph unicode="&#x1eca;" horiz-adv-x="821" d="M102 0v188h191v1008h-191v188h617v-188h-193v-1008h193v-188h-617zM281 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ecb;" horiz-adv-x="530" d="M136 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5zM137 1325q0 62 29 89.5t98 27.5t99 -27t30 -90q0 -66 -31.5 -91.5t-97.5 -25.5q-72 0 -99.5 30t-27.5 87zM158 0v1049h215v-1049h-215 z" />
+<glyph unicode="&#x1ecc;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32 t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5zM550 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5 z" />
+<glyph unicode="&#x1ecd;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92 t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM456 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ece;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32 t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5zM477 1798q25 20 73 36.5t113 16.5q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51 -31.5t-62 -15.5v-39h-112v125h32 q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ecf;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92 t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM391 1462q25 20 73 37t113 17q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ed0;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM329 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179z M344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5zM880 1724l140 283h274l-240 -283h-174z" />
+<glyph unicode="&#x1ed1;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM237 1167l232 289h227l232 -289h-181l-164 152l-167 -152 h-179zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM788 1389l140 282h274l-240 -282h-174z" />
+<glyph unicode="&#x1ed2;" horiz-adv-x="1364" d="M59 2007h276l138 -283h-172zM102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM333 1503l232 289h227l232 -289 h-181l-164 148l-167 -148h-179zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5z" />
+<glyph unicode="&#x1ed3;" horiz-adv-x="1174" d="M-37 1671h276l138 -282h-172zM104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM237 1167l232 289h227 l232 -289h-181l-164 148l-167 -148h-179zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x1ed4;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM333 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179z M344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5zM806 1976q25 22 73.5 38t113.5 16q96 0 148.5 -42t52.5 -110 q0 -38 -12.5 -67t-34.5 -49t-51 -31.5t-62 -14.5v-41h-113v125h33q74 0 74 58q0 53 -72 53q-23 0 -50 -7.5t-48 -21.5z" />
+<glyph unicode="&#x1ed5;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM237 1167l232 289h227l232 -289h-181l-164 148l-167 -148 h-179zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM710 1640q25 22 73.5 38t113.5 16q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49t-51 -31.5t-62 -14.5v-41h-113v125h33q74 0 74 58 q0 53 -72 53q-23 0 -50 -7.5t-48 -21.5z" />
+<glyph unicode="&#x1ed6;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM286 1835q3 53 18.5 98.5t45.5 79.5t75 53t107 19q48 0 89 -15.5 t77.5 -34.5t70 -34.5t68.5 -15.5q44 0 61.5 23.5t20.5 62.5h152q-5 -54 -20 -100t-44.5 -79t-74.5 -52t-109 -19q-37 0 -67.5 7.5t-56 19.5t-47.5 25t-43 25t-43 19.5t-46 7.5q-45 0 -62 -24t-20 -66h-152zM333 1503l232 269h227l232 -269h-181l-164 131l-167 -131h-179z M344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5z" />
+<glyph unicode="&#x1ed7;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM194 1509q3 53 18.5 99t45.5 79.5t75 52.5t107 19 q48 0 89 -15.5t77.5 -34.5t70 -34.5t68.5 -15.5q44 0 61.5 24t20.5 62h152q-5 -54 -20 -99.5t-44.5 -79t-74.5 -52.5t-109 -19q-37 0 -67.5 7.5t-56 19.5t-47.5 25t-43 25t-43 19.5t-46 7.5q-45 0 -62 -24t-20 -66h-152zM241 1167l232 279h227l232 -279h-181l-164 142 l-167 -142h-179zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x1ed8;" horiz-adv-x="1364" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49t264 -48.5t180.5 -141t103 -226.5t32.5 -305q0 -170 -32.5 -303.5t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM331 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179z M344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5zM542 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5 t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ed9;" horiz-adv-x="1174" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q127 0 218 -38.5t149.5 -111t86 -175.5t27.5 -232q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39t-150.5 111t-86 174t-27.5 229zM243 1208l232 361h227l232 -361h-181l-164 205l-167 -205 h-179zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM456 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1eda;" horiz-adv-x="1513" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49q100 0 181 -21t144 -61t109.5 -98.5t77.5 -134.5h31q39 0 65.5 9.5t43 30.5t23.5 54.5t7 81.5v172h186v-172q0 -78 -16 -139t-51.5 -103.5t-92 -65t-137.5 -22.5h-14q11 -57 17 -120t6 -132q0 -170 -32.5 -303.5 t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5 t-18 -225.5zM533 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x1edb;" horiz-adv-x="1300" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q167 0 272 -67.5t156 -188.5q75 0 105 41t30 135v131h186v-131q0 -74 -16 -132.5t-49.5 -101t-86.5 -67t-126 -28.5q5 -34 7.5 -72t2.5 -76q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39 t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM443 1208l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x1edc;" horiz-adv-x="1513" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49q100 0 181 -21t144 -61t109.5 -98.5t77.5 -134.5h31q39 0 65.5 9.5t43 30.5t23.5 54.5t7 81.5v172h186v-172q0 -78 -16 -139t-51.5 -103.5t-92 -65t-137.5 -22.5h-14q11 -57 17 -120t6 -132q0 -170 -32.5 -303.5 t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5 t-18 -225.5zM378 1905h275l184 -361h-174z" />
+<glyph unicode="&#x1edd;" horiz-adv-x="1300" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q167 0 272 -67.5t156 -188.5q75 0 105 41t30 135v131h186v-131q0 -74 -16 -132.5t-49.5 -101t-86.5 -67t-126 -28.5q5 -34 7.5 -72t2.5 -76q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39 t-150.5 111t-86 174t-27.5 229zM290 1569h275l184 -361h-174zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x1ede;" horiz-adv-x="1513" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49q100 0 181 -21t144 -61t109.5 -98.5t77.5 -134.5h31q39 0 65.5 9.5t43 30.5t23.5 54.5t7 81.5v172h186v-172q0 -78 -16 -139t-51.5 -103.5t-92 -65t-137.5 -22.5h-14q11 -57 17 -120t6 -132q0 -170 -32.5 -303.5 t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5 t-18 -225.5zM498 1798q25 20 73 36.5t113 16.5q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51 -31.5t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1edf;" horiz-adv-x="1300" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q167 0 272 -67.5t156 -188.5q75 0 105 41t30 135v131h186v-131q0 -74 -16 -132.5t-49.5 -101t-86.5 -67t-126 -28.5q5 -34 7.5 -72t2.5 -76q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39 t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM406 1462q25 20 73 37t113 17q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-112v125h32 q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ee0;" horiz-adv-x="1513" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49q100 0 181 -21t144 -61t109.5 -98.5t77.5 -134.5h31q39 0 65.5 9.5t43 30.5t23.5 54.5t7 81.5v172h186v-172q0 -78 -16 -139t-51.5 -103.5t-92 -65t-137.5 -22.5h-14q11 -57 17 -120t6 -132q0 -170 -32.5 -303.5 t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM291 1561q3 62 18.5 115t45.5 92t75 61t107 22q39 0 70.5 -10.5t57.5 -26t48.5 -34t43.5 -34t41.5 -26t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5 t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96 t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5t-18 -225.5z" />
+<glyph unicode="&#x1ee1;" horiz-adv-x="1300" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q167 0 272 -67.5t156 -188.5q75 0 105 41t30 135v131h186v-131q0 -74 -16 -132.5t-49.5 -101t-86.5 -67t-126 -28.5q5 -34 7.5 -72t2.5 -76q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39 t-150.5 111t-86 174t-27.5 229zM190 1225q3 62 18.5 115.5t45.5 92.5t75 61t107 22q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27 t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278z" />
+<glyph unicode="&#x1ee2;" horiz-adv-x="1513" d="M102 692q0 170 33 304t103.5 226.5t180 141.5t263.5 49q100 0 181 -21t144 -61t109.5 -98.5t77.5 -134.5h31q39 0 65.5 9.5t43 30.5t23.5 54.5t7 81.5v172h186v-172q0 -78 -16 -139t-51.5 -103.5t-92 -65t-137.5 -22.5h-14q11 -57 17 -120t6 -132q0 -170 -32.5 -303.5 t-103 -226.5t-180.5 -142t-264 -49t-263.5 49t-180 142t-103.5 226.5t-33 303.5zM344 692q0 -129 18 -225.5t58.5 -160.5t105 -96t156.5 -32t156 31.5t104 95.5t58 160.5t18 226.5q0 129 -18 225.5t-58 160.5t-104 96t-156 32q-93 0 -157.5 -32t-104.5 -96t-58 -160.5 t-18 -225.5zM548 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ee3;" horiz-adv-x="1300" d="M104 522q0 129 28 232t86.5 175.5t150 111t219.5 38.5q167 0 272 -67.5t156 -188.5q75 0 105 41t30 135v131h186v-131q0 -74 -16 -132.5t-49.5 -101t-86.5 -67t-126 -28.5q5 -34 7.5 -72t2.5 -76q0 -128 -27.5 -230t-86 -174t-149.5 -110.5t-218 -38.5q-128 0 -220 39 t-150.5 111t-86 174t-27.5 229zM326 522q0 -182 61.5 -274t200.5 -92q135 0 196.5 92t61.5 274q0 187 -60.5 278t-197.5 91t-199.5 -91t-62.5 -278zM454 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5 t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ee4;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM579 -254q0 65 28 94t99 29 q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ee5;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM426 -254q0 65 28 94t99 29 q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ee6;" horiz-adv-x="1421" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-806q0 -168 -30.5 -284t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM514 1798q25 20 73 36.5t113 16.5 q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51 -31.5t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ee7;" horiz-adv-x="1190" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-1049h-215v145q-35 -35 -76.5 -67t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM395 1462q25 20 73 37t113 17 q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ee8;" horiz-adv-x="1573" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-286h29q39 0 66 9.5t43 30.5t23 54.5t7 81.5v172h187v-172q0 -78 -18 -139t-56 -103.5t-98 -65t-144 -22.5h-39v-366q0 -168 -30.5 -284 t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM568 1544l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x1ee9;" horiz-adv-x="1339" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-226h23q39 0 65.5 9.5t42 30.5t22.5 54.5t7 81.5v131h184v-131q0 -77 -17 -138t-54.5 -103.5t-96.5 -65t-143 -22.5h-33v-670h-215v145q-35 -35 -76.5 -67 t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM455 1208l184 361h274l-284 -361h-174z" />
+<glyph unicode="&#x1eea;" horiz-adv-x="1573" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-286h29q39 0 66 9.5t43 30.5t23 54.5t7 81.5v172h187v-172q0 -78 -18 -139t-56 -103.5t-98 -65t-144 -22.5h-39v-366q0 -168 -30.5 -284 t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM389 1905h275l184 -361h-174z" />
+<glyph unicode="&#x1eeb;" horiz-adv-x="1339" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-226h23q39 0 65.5 9.5t42 30.5t22.5 54.5t7 81.5v131h184v-131q0 -77 -17 -138t-54.5 -103.5t-96.5 -65t-143 -22.5h-33v-670h-215v145q-35 -35 -76.5 -67 t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM268 1569h275l184 -361h-174z" />
+<glyph unicode="&#x1eec;" horiz-adv-x="1573" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-286h29q39 0 66 9.5t43 30.5t23 54.5t7 81.5v172h187v-172q0 -78 -18 -139t-56 -103.5t-98 -65t-144 -22.5h-39v-366q0 -168 -30.5 -284 t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM516 1798q25 20 73 36.5t113 16.5q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51 -31.5t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z " />
+<glyph unicode="&#x1eed;" horiz-adv-x="1339" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-226h23q39 0 65.5 9.5t42 30.5t22.5 54.5t7 81.5v131h184v-131q0 -77 -17 -138t-54.5 -103.5t-96.5 -65t-143 -22.5h-33v-670h-215v145q-35 -35 -76.5 -67 t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM395 1462q25 20 73 37t113 17q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1eee;" horiz-adv-x="1573" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-286h29q39 0 66 9.5t43 30.5t23 54.5t7 81.5v172h187v-172q0 -78 -18 -139t-56 -103.5t-98 -65t-144 -22.5h-39v-366q0 -168 -30.5 -284 t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM325 1561q3 62 18.5 115t45.5 92t75 61t107 22q39 0 70.5 -10.5t57.5 -26t48.5 -34t43.5 -34t41.5 -26t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5 t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152z" />
+<glyph unicode="&#x1eef;" horiz-adv-x="1339" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-226h23q39 0 65.5 9.5t42 30.5t22.5 54.5t7 81.5v131h184v-131q0 -77 -17 -138t-54.5 -103.5t-96.5 -65t-143 -22.5h-33v-670h-215v145q-35 -35 -76.5 -67 t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM205 1225q3 62 18.5 115.5t45.5 92.5t75 61t107 22q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5 t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152z" />
+<glyph unicode="&#x1ef0;" horiz-adv-x="1573" d="M166 578v806h233v-786q0 -120 16.5 -200.5t53.5 -130t96 -70.5t144 -21q86 0 145.5 21.5t97 70.5t54 129t16.5 197v790h233v-286h29q39 0 66 9.5t43 30.5t23 54.5t7 81.5v172h187v-172q0 -78 -18 -139t-56 -103.5t-98 -65t-144 -22.5h-39v-366q0 -168 -30.5 -284 t-96 -188t-168.5 -104.5t-249 -32.5t-249.5 32.5t-169 105t-96 188.5t-30.5 283zM571 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ef1;" horiz-adv-x="1339" d="M150 348v701h215v-598q0 -79 5 -133.5t21 -88t46 -48.5t79 -15q33 0 70.5 13t77 35t78.5 51.5t75 62.5v721h215v-226h23q39 0 65.5 9.5t42 30.5t22.5 54.5t7 81.5v131h184v-131q0 -77 -17 -138t-54.5 -103.5t-96.5 -65t-143 -22.5h-33v-670h-215v145q-35 -35 -76.5 -67 t-88 -56t-96 -38.5t-99.5 -14.5q-88 0 -147 25t-94.5 73.5t-50.5 119t-15 161.5zM438 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ef2;" horiz-adv-x="1167" d="M29 1384h258l299 -626l303 626h248l-437 -854v-530h-235v524zM282 1905h275l184 -361h-174z" />
+<glyph unicode="&#x1ef3;" horiz-adv-x="1063" d="M-12 -365l49 183q35 -14 74.5 -21.5t76.5 -7.5q30 0 56.5 10.5t51 34t47 61.5t44.5 93l31 75l-381 986h227l268 -719l273 719h221l-451 -1125q-35 -86 -71 -146.5t-81 -99t-101 -56t-129 -17.5q-50 0 -105 8t-100 22zM209 1569h275l184 -361h-174z" />
+<glyph unicode="&#x1ef4;" horiz-adv-x="1167" d="M29 1384h258l299 -626l303 626h248l-437 -854v-530h-235v524zM452 -254q0 65 28 94t99 29q73 0 102.5 -28.5t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ef5;" horiz-adv-x="1063" d="M-12 -365l49 183q35 -14 74.5 -21.5t76.5 -7.5q30 0 56.5 10.5t51 34t47 61.5t44.5 93l31 75l-381 986h227l268 -719l273 719h221l-451 -1125q-35 -86 -71 -146.5t-81 -99t-101 -56t-129 -17.5q-50 0 -105 8t-100 22zM643 -254q0 65 28 94t99 29q73 0 102.5 -28.5 t29.5 -94.5q0 -68 -31 -95.5t-101 -27.5q-38 0 -62.5 8.5t-38.5 24.5t-20 38.5t-6 51.5z" />
+<glyph unicode="&#x1ef6;" horiz-adv-x="1167" d="M29 1384h258l299 -626l303 626h248l-437 -854v-530h-235v524zM389 1798q25 20 73 36.5t113 16.5q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51 -31.5t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ef7;" horiz-adv-x="1063" d="M-12 -365l49 183q35 -14 74.5 -21.5t76.5 -7.5q30 0 56.5 10.5t51 34t47 61.5t44.5 93l31 75l-381 986h227l268 -719l273 719h221l-451 -1125q-35 -86 -71 -146.5t-81 -99t-101 -56t-129 -17.5q-50 0 -105 8t-100 22zM338 1462q25 20 73 37t113 17q96 0 148.5 -42 t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph unicode="&#x1ef8;" horiz-adv-x="1167" d="M29 1384h258l299 -626l303 626h248l-437 -854v-530h-235v524zM192 1561q3 62 18.5 115t45.5 92t75 61t107 22q39 0 70.5 -10.5t57.5 -26t48.5 -34t43.5 -34t41.5 -26t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22 q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152z" />
+<glyph unicode="&#x1ef9;" horiz-adv-x="1063" d="M-12 -365l49 183q35 -14 74.5 -21.5t76.5 -7.5q30 0 56.5 10.5t51 34t47 61.5t44.5 93l31 75l-381 986h227l268 -719l273 719h221l-451 -1125q-35 -86 -71 -146.5t-81 -99t-101 -56t-129 -17.5q-50 0 -105 8t-100 22zM139 1225q3 62 18.5 115.5t45.5 92.5t75 61t107 22 q39 0 70.5 -10.5t57.5 -26.5t48.5 -34t43.5 -34t41.5 -26.5t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152z " />
+<glyph unicode="&#x2000;" horiz-adv-x="1068" />
+<glyph unicode="&#x2001;" horiz-adv-x="2136" />
+<glyph unicode="&#x2002;" horiz-adv-x="1068" />
+<glyph unicode="&#x2003;" horiz-adv-x="2136" />
+<glyph unicode="&#x2004;" horiz-adv-x="712" />
+<glyph unicode="&#x2005;" horiz-adv-x="534" />
+<glyph unicode="&#x2006;" horiz-adv-x="356" />
+<glyph unicode="&#x2007;" horiz-adv-x="356" />
+<glyph unicode="&#x2008;" horiz-adv-x="267" />
+<glyph unicode="&#x2009;" horiz-adv-x="427" />
+<glyph unicode="&#x200a;" horiz-adv-x="118" />
<glyph unicode="&#x2010;" horiz-adv-x="807" d="M92 420v213h623v-213h-623z" />
<glyph unicode="&#x2011;" horiz-adv-x="807" d="M92 420v213h623v-213h-623z" />
<glyph unicode="&#x2012;" horiz-adv-x="807" d="M92 420v213h623v-213h-623z" />
-<glyph unicode="&#x2013;" horiz-adv-x="1065" d="M41 438v174h983v-174h-983z" />
+<glyph unicode="&#x2013;" d="M41 438v174h983v-174h-983z" />
<glyph unicode="&#x2014;" horiz-adv-x="2089" d="M41 438v174h2007v-174h-2007z" />
+<glyph unicode="&#x2015;" horiz-adv-x="2089" d="M41 438v174h2007v-174h-2007z" />
+<glyph unicode="&#x2017;" horiz-adv-x="1024" d="M-10 -105h1044v-102h-1044v102zM-10 -290h1044v-102h-1044v102z" />
<glyph unicode="&#x2018;" horiz-adv-x="569" d="M141 989q0 61 11 119.5t29 110t40 94t43 71.5h150q-27 -36 -46.5 -78t-32.5 -81t-19 -71.5t-7 -49.5q62 -3 89.5 -35t27.5 -100q0 -65 -31 -100t-112 -35q-77 0 -109.5 40.5t-32.5 114.5z" />
<glyph unicode="&#x2019;" horiz-adv-x="569" d="M141 1276q0 32 7 57.5t24 43t44.5 27t68.5 9.5q77 0 109 -41t32 -117q0 -60 -11 -118t-28.5 -109.5t-39.5 -94t-44 -71.5h-147q27 36 46 78t32 81t19 71.5t7 50.5q-63 2 -91 33.5t-28 99.5z" />
<glyph unicode="&#x201a;" horiz-adv-x="569" d="M141 121q0 32 7 57.5t24 43t44.5 27t68.5 9.5q77 0 109 -41t32 -117q0 -60 -11 -118t-28.5 -109.5t-39.5 -94t-44 -71.5h-147q27 36 46 78t32 81t19 71.5t7 50.5q-63 2 -91 33.5t-28 99.5z" />
+<glyph unicode="&#x201b;" horiz-adv-x="569" d="M141 1255q0 76 32.5 117t109.5 41q81 0 112 -36t31 -101q0 -68 -27.5 -99.5t-89.5 -33.5q1 -18 7 -50.5t19 -71.5t32.5 -81t46.5 -78h-150q-21 29 -43 71.5t-40 94t-29 109.5t-11 118z" />
<glyph unicode="&#x201c;" horiz-adv-x="1006" d="M141 989q0 61 11 119.5t29 110t40 94t43 71.5h150q-27 -36 -46.5 -78t-32.5 -81t-19 -71.5t-7 -49.5q62 -3 89.5 -35t27.5 -100q0 -65 -31 -100t-112 -35q-77 0 -109.5 40.5t-32.5 114.5zM578 989q0 61 11 119.5t28.5 110t39.5 94t43 71.5h150q-27 -36 -46.5 -78t-32 -81 t-19 -71.5t-7.5 -49.5q62 -3 89.5 -35t27.5 -100q0 -65 -31 -100t-112 -35q-77 0 -109 40.5t-32 114.5z" />
<glyph unicode="&#x201d;" horiz-adv-x="1006" d="M141 1276q0 32 7 57.5t24 43t44.5 27t68.5 9.5q77 0 109 -41t32 -117q0 -60 -11 -118t-28.5 -109.5t-39.5 -94t-44 -71.5h-147q27 36 46 78t32 81t19 71.5t7 50.5q-63 2 -91 33.5t-28 99.5zM578 1276q0 32 7 57.5t23.5 43t44 27t68.5 9.5q77 0 109 -41t32 -117 q0 -60 -11 -118t-28 -109.5t-39.5 -94t-44.5 -71.5h-147q27 36 46.5 78t32 81t18.5 71.5t7 50.5q-63 2 -90.5 33.5t-27.5 99.5z" />
<glyph unicode="&#x201e;" horiz-adv-x="1006" d="M141 121q0 32 7 57.5t24 43t44.5 27t68.5 9.5q77 0 109 -41t32 -117q0 -60 -11 -118t-28.5 -109.5t-39.5 -94t-44 -71.5h-147q27 36 46 78t32 81t19 71.5t7 50.5q-63 2 -91 33.5t-28 99.5zM578 121q0 32 7 57.5t23.5 43t44 27t68.5 9.5q77 0 109 -41t32 -117 q0 -60 -11 -118t-28 -109.5t-39.5 -94t-44.5 -71.5h-147q27 36 46.5 78t32 81t18.5 71.5t7 50.5q-63 2 -90.5 33.5t-27.5 99.5z" />
+<glyph unicode="&#x2020;" horiz-adv-x="1114" d="M78 731v209l395 -22l-27 466h218l-25 -466l397 22v-209l-397 23l31 -1149h-228l31 1149z" />
+<glyph unicode="&#x2021;" horiz-adv-x="1096" d="M86 -2v211l377 -25l-17 312l17 309l-377 -25v211l377 -22l-27 415h221l-26 -415l379 22v-211l-379 25l18 -311l-18 -310l379 25v-211l-379 22l26 -415h-221l27 415z" />
<glyph unicode="&#x2022;" horiz-adv-x="766" d="M111 745q0 58 22 107.5t59 86.5t86.5 58t104.5 21t104.5 -21t86.5 -58t59 -86.5t22 -107.5q0 -56 -21.5 -105.5t-58.5 -86.5t-86.5 -58.5t-105.5 -21.5q-57 0 -106.5 21.5t-86.5 58.5t-58 86.5t-21 105.5z" />
<glyph unicode="&#x2026;" horiz-adv-x="2048" d="M199 121q0 71 31.5 104t109.5 33t110.5 -32.5t32.5 -104.5q0 -74 -34.5 -104.5t-108.5 -30.5q-42 0 -69 9t-43 26t-22.5 42.5t-6.5 57.5zM881 121q0 71 31.5 104t109.5 33t110.5 -32.5t32.5 -104.5q0 -74 -34.5 -104.5t-108.5 -30.5q-42 0 -69 9t-43 26t-22.5 42.5 t-6.5 57.5zM1563 121q0 71 31 104t110 33q78 0 110.5 -32.5t32.5 -104.5q0 -74 -34.5 -104.5t-108.5 -30.5q-42 0 -69 9t-43 26t-22.5 42.5t-6.5 57.5z" />
-<glyph unicode="&#x202f;" horiz-adv-x="383" />
+<glyph unicode="&#x202f;" horiz-adv-x="427" />
+<glyph unicode="&#x2030;" horiz-adv-x="2863" d="M86 967q0 97 19 179t62 141.5t111.5 92.5t167.5 33t168.5 -33t113 -92t63.5 -141t20 -180q0 -97 -20 -178t-64 -140t-113 -92t-168 -33t-167.5 33t-111.5 92.5t-62 140.5t-19 177zM297 967q0 -64 6 -116.5t22 -90.5t45 -59t76 -21q48 0 77.5 20.5t46 58t22.5 90.5t6 118 t-6 118.5t-23 91t-46.5 58t-76.5 20.5q-48 0 -77 -21t-45 -58.5t-21.5 -91t-5.5 -117.5zM520 -51l766 1487h197l-766 -1487h-197zM1192 412q0 98 19 180t61.5 141t111 92t168.5 33q99 0 168.5 -33t113 -92t63.5 -141t20 -180q0 -97 -20 -178t-64 -140t-113 -92t-168 -33 q-100 0 -168.5 33t-111 92t-61.5 140t-19 178zM1403 412q0 -64 5.5 -116.5t22 -90.5t45.5 -59t76 -21q48 0 77.5 20.5t46 58t22.5 90.5t6 118t-6 118.5t-23 91t-46.5 58t-76.5 20.5q-48 0 -77 -21t-45 -58.5t-21.5 -91t-5.5 -117.5zM2052 412q0 98 19 180t62 141t112.5 92 t169.5 33q99 0 168 -33t112 -92t62.5 -141t19.5 -180q0 -97 -20 -178t-63.5 -140t-112.5 -92t-166 -33q-100 0 -169.5 33t-112.5 92t-62 140t-19 178zM2263 412q0 -64 6 -116.5t23 -90.5t46.5 -59t76.5 -21t76.5 20.5t46 58t22.5 90.5t6 118t-6 118.5t-22.5 91t-46 58 t-76.5 20.5q-48 0 -78 -21t-46.5 -58.5t-22 -91t-5.5 -117.5z" />
+<glyph unicode="&#x2032;" horiz-adv-x="553" d="M141 803l39 581h242l-125 -581h-156z" />
+<glyph unicode="&#x2033;" horiz-adv-x="1024" d="M141 803l39 581h242l-125 -581h-156zM612 803l39 581h242l-125 -581h-156z" />
<glyph unicode="&#x2039;" horiz-adv-x="799" d="M66 524l407 471h248l-408 -471l408 -471h-248z" />
<glyph unicode="&#x203a;" horiz-adv-x="799" d="M78 53l405 471l-405 471h248l405 -471l-405 -471h-248z" />
-<glyph unicode="&#x205f;" horiz-adv-x="478" />
-<glyph unicode="&#x20ac;" d="M25 475l38 154h60v129h-98l41 155h73q84 500 578 500q100 0 178.5 -19.5t138 -53.5t102.5 -80.5t74 -100.5l-176 -129q-21 34 -46.5 67t-61.5 58.5t-85 41t-116 15.5q-148 0 -229.5 -77t-112.5 -222h557l-39 -155h-536v-129h509l-38 -154h-453q31 -156 114 -229.5 t230 -73.5q67 0 116 16.5t86.5 44.5t66 65t53.5 79l178 -121q-41 -68 -85.5 -120.5t-102.5 -89.5t-133.5 -56t-178.5 -19q-255 0 -401.5 126t-186.5 378h-114z" />
+<glyph unicode="&#x203c;" horiz-adv-x="1139" d="M141 119q0 71 32 102t110 31q79 0 111 -31.5t32 -101.5q0 -76 -34 -104.5t-109 -28.5q-41 0 -68 8.5t-43.5 25t-23.5 41.5t-7 58zM164 1384h239l-26 -964h-180zM710 119q0 71 32 102t110 31q79 0 111 -31.5t32 -101.5q0 -76 -34 -104.5t-109 -28.5q-41 0 -68 8.5 t-43.5 25t-23.5 41.5t-7 58zM733 1384h239l-26 -964h-180z" />
+<glyph unicode="&#x203d;" horiz-adv-x="1059" d="M51 1290q30 53 71.5 95.5t96.5 72.5t124 46t155 16q98 0 184 -21.5t149.5 -68.5t100.5 -121t37 -179q0 -98 -33 -171t-88.5 -131t-128.5 -104.5t-152 -90.5v-213h-223l-16 842q-28 -17 -48.5 -41t-35.5 -50zM315 119q0 71 32 102t110 31q79 0 111 -31.5t32 -101.5 q0 -76 -34 -104.5t-109 -28.5q-41 0 -68 8.5t-43.5 25t-23.5 41.5t-7 58zM543 848q37 25 70.5 53.5t59 61.5t40 71.5t14.5 83.5q0 82 -42.5 132t-129.5 63z" />
+<glyph unicode="&#x203e;" horiz-adv-x="1024" d="M-10 1526v102h1044v-102h-1044z" />
+<glyph unicode="&#x2044;" horiz-adv-x="227" d="M-360 -51l761 1487h203l-766 -1487h-198z" />
+<glyph unicode="&#x205f;" horiz-adv-x="534" />
+<glyph unicode="&#x2070;" horiz-adv-x="913" d="M76 1077q0 227 92 335t289 108q193 0 286 -108t93 -335t-93 -335.5t-286 -108.5q-197 0 -289 107.5t-92 336.5zM291 1077q0 -145 40 -212.5t124 -67.5q85 0 125.5 67.5t40.5 212.5q0 144 -40.5 211.5t-125.5 67.5q-84 0 -124 -67.5t-40 -211.5z" />
+<glyph unicode="&#x2074;" horiz-adv-x="913" d="M43 821v146l494 536h184v-532h121v-150h-121v-170h-195v170h-483zM248 971h278v301z" />
+<glyph unicode="&#x2075;" horiz-adv-x="913" d="M68 791l170 94q26 -38 70 -64t104 -26q81 0 126.5 37t45.5 106q0 62 -45 92.5t-125 30.5q-50 0 -87 -14.5t-65 -34.5h-131l57 491h566v-160h-392l-20 -147q26 8 57 12t76 4q67 0 126 -16t103 -49.5t69.5 -85.5t25.5 -125q0 -70 -24.5 -126t-73.5 -95.5t-121 -60.5 t-166 -21q-122 0 -208 44t-138 114z" />
+<glyph unicode="&#x2076;" horiz-adv-x="913" d="M96 1055q0 95 23 180t72 148.5t126.5 101t186.5 37.5q91 0 162 -21.5t131 -66.5l-111 -131q-43 34 -87 51.5t-93 17.5q-47 0 -81 -16t-57 -43t-37 -63.5t-20 -78.5q38 19 92 31t105 12q71 0 128.5 -17t98 -52t62.5 -88t22 -125q0 -71 -25 -126.5t-71.5 -94t-112.5 -58.5 t-149 -20q-181 0 -273 107t-92 315zM305 1028q1 -68 11.5 -115t31 -76.5t51 -43t70.5 -13.5q66 0 105.5 35t39.5 113q0 71 -39.5 107t-107.5 36q-43 0 -88.5 -13t-73.5 -30z" />
+<glyph unicode="&#x2077;" horiz-adv-x="913" d="M78 1343v160h729v-129l-363 -723h-233l371 692h-504z" />
+<glyph unicode="&#x2078;" horiz-adv-x="913" d="M88 887q0 66 43 122t125 93q-143 65 -143 182q0 115 87 176.5t255 61.5q162 0 251 -60t89 -176q0 -113 -150 -186q85 -34 128.5 -84.5t43.5 -128.5q0 -65 -26.5 -112.5t-74 -79t-114 -47t-147.5 -15.5q-178 0 -272.5 64.5t-94.5 189.5zM291 887q0 -48 39.5 -77.5 t124.5 -29.5q84 0 122.5 31.5t38.5 79.5q0 46 -42 78.5t-119 58.5q-76 -23 -120 -56t-44 -85zM309 1286q0 -17 6 -32t22.5 -29t45.5 -27.5t74 -28.5q74 20 106.5 47.5t32.5 65.5q0 40 -34 67t-109 27q-39 0 -66 -7.5t-44.5 -20t-25.5 -28.5t-8 -34z" />
+<glyph unicode="&#x2079;" horiz-adv-x="913" d="M86 1225q0 70 25 125t71.5 93t113 58.5t148.5 20.5q181 0 273 -107.5t92 -308.5q0 -98 -22.5 -184t-72 -150t-128 -101.5t-189.5 -37.5q-91 0 -163 22.5t-132 65.5l111 133q84 -72 184 -72q48 0 83 15.5t58 42.5t36.5 64t19.5 79q-40 -20 -91.5 -31.5t-105.5 -11.5 q-71 0 -128.5 17t-98 52.5t-62.5 89t-22 126.5zM289 1227q0 -71 40.5 -107.5t108.5 -36.5q45 0 89.5 13.5t72.5 33.5q-1 52 -8.5 96.5t-26 77.5t-49.5 51.5t-78 18.5q-68 0 -108.5 -35t-40.5 -112z" />
+<glyph unicode="&#x207f;" horiz-adv-x="872" d="M111 657v729h182v-86q22 22 50 41.5t59.5 34t65.5 23t67 8.5q118 0 174.5 -61.5t56.5 -174.5v-514h-178v422q0 48 -5 81t-17 53.5t-32 29t-51 8.5q-22 0 -46.5 -8t-49.5 -21t-49 -30.5t-45 -36.5v-498h-182z" />
+<glyph unicode="&#x2080;" horiz-adv-x="913" d="M76 111q0 227 92 335t289 108q193 0 286 -108t93 -335t-93 -335.5t-286 -108.5q-197 0 -289 107.5t-92 336.5zM291 111q0 -145 40 -212.5t124 -67.5q85 0 125.5 67.5t40.5 212.5q0 144 -40.5 211.5t-125.5 67.5q-84 0 -124 -67.5t-40 -211.5z" />
+<glyph unicode="&#x2081;" horiz-adv-x="913" d="M176 255v129q68 2 114.5 11t77 26.5t48.5 46t30 69.5h162v-852h-207v570h-225z" />
+<glyph unicode="&#x2082;" horiz-adv-x="913" d="M90 388q56 77 142.5 122.5t209.5 45.5q156 0 242 -63t86 -185q0 -80 -31 -137t-82 -105q-21 -20 -52 -45.5t-68 -54t-78 -59t-82 -58.5h424v-164h-699v160q50 37 107.5 79t112 84t101 81t75.5 71q31 32 45 63t14 66q0 51 -36 75t-87 24q-59 0 -103 -28.5t-75 -70.5z" />
+<glyph unicode="&#x2083;" horiz-adv-x="913" d="M72 -178l166 89q26 -36 69.5 -61t100.5 -25q41 0 70 9t47 24.5t26 37.5t8 49q0 57 -41 84t-123 27h-102v152h90q90 0 130 26.5t40 77.5q0 40 -33.5 64t-95.5 24q-59 0 -101.5 -22.5t-74.5 -65.5l-158 90q24 32 54.5 60t72 49t96 33t125.5 12q82 0 142.5 -17.5t100.5 -48 t59.5 -71t19.5 -85.5q0 -138 -150 -190q81 -25 122.5 -78t41.5 -129q0 -68 -25 -118.5t-72 -84t-115 -50.5t-154 -17q-57 0 -109 11.5t-95.5 32t-77 49t-54.5 62.5z" />
+<glyph unicode="&#x2084;" horiz-adv-x="913" d="M43 1l494 536h184v-532h121v-150h-121v-170h-195v170h-483v146zM248 5h278v301z" />
+<glyph unicode="&#x2085;" horiz-adv-x="913" d="M68 -175l170 94q26 -38 70 -64t104 -26q81 0 126.5 37t45.5 106q0 62 -45 92.5t-125 30.5q-50 0 -87 -14.5t-65 -34.5h-131l57 491h566v-160h-392l-20 -147q26 8 57 12t76 4q67 0 126 -16t103 -49.5t69.5 -85.5t25.5 -125q0 -70 -24.5 -126t-73.5 -95.5t-121 -60.5 t-166 -21q-122 0 -208 44t-138 114z" />
+<glyph unicode="&#x2086;" horiz-adv-x="913" d="M96 89q0 95 23 180t72 148.5t126.5 101t186.5 37.5q91 0 162 -21.5t131 -66.5l-111 -131q-43 34 -87 51.5t-93 17.5q-47 0 -81 -16t-57 -43t-37 -63.5t-20 -78.5q38 19 92 31t105 12q71 0 128.5 -17t98 -52t62.5 -88t22 -125q0 -71 -25 -126.5t-71.5 -94t-112.5 -58.5 t-149 -20q-181 0 -273 107t-92 315zM305 62q1 -68 11.5 -115t31 -76.5t51 -43t70.5 -13.5q66 0 105.5 35t39.5 113q0 71 -39.5 107t-107.5 36q-43 0 -88.5 -13t-73.5 -30z" />
+<glyph unicode="&#x2087;" horiz-adv-x="913" d="M78 377v160h729v-129l-363 -723h-233l371 692h-504z" />
+<glyph unicode="&#x2088;" horiz-adv-x="913" d="M88 -79q0 66 43 122t125 93q-143 65 -143 182q0 115 87 176.5t255 61.5q162 0 251 -60t89 -176q0 -113 -150 -186q85 -34 128.5 -84.5t43.5 -128.5q0 -65 -26.5 -112.5t-74 -79t-114 -47t-147.5 -15.5q-178 0 -272.5 64.5t-94.5 189.5zM291 -79q0 -48 39.5 -77.5 t124.5 -29.5q84 0 122.5 31.5t38.5 79.5q0 46 -42 78.5t-119 58.5q-76 -23 -120 -56t-44 -85zM309 320q0 -17 6 -32t22.5 -29t45.5 -27.5t74 -28.5q74 20 106.5 47.5t32.5 65.5q0 40 -34 67t-109 27q-39 0 -66 -7.5t-44.5 -20t-25.5 -28.5t-8 -34z" />
+<glyph unicode="&#x2089;" horiz-adv-x="913" d="M86 259q0 70 25 125t71.5 93t113 58.5t148.5 20.5q181 0 273 -107.5t92 -308.5q0 -98 -22.5 -184t-72 -150t-128 -101.5t-189.5 -37.5q-91 0 -163 22.5t-132 65.5l111 133q84 -72 184 -72q48 0 83 15.5t58 42.5t36.5 64t19.5 79q-40 -20 -91.5 -31.5t-105.5 -11.5 q-71 0 -128.5 17t-98 52.5t-62.5 89t-22 126.5zM289 261q0 -71 40.5 -107.5t108.5 -36.5q45 0 89.5 13.5t72.5 33.5q-1 52 -8.5 96.5t-26 77.5t-49.5 51.5t-78 18.5q-68 0 -108.5 -35t-40.5 -112z" />
+<glyph unicode="&#x20a3;" horiz-adv-x="1272" d="M92 201v159h160v1024h864v-213h-631v-352h533v-209h-533v-250h363v-159h-363v-201h-233v201h-160z" />
+<glyph unicode="&#x20a4;" horiz-adv-x="1272" d="M106 0v184q39 8 68.5 30t50.5 55t34.5 76t19.5 93h-162v146h168q0 46 -5.5 77t-11.5 54h-151v145h121q-17 79 -17 174q0 97 38 168.5t104 118.5t154.5 69.5t189.5 22.5q159 0 276.5 -57t183.5 -168l-184 -111q-43 69 -115.5 110.5t-160.5 41.5q-128 0 -192 -60t-64 -163 q0 -41 4 -76.5t12 -69.5h422v-145h-391q5 -23 9.5 -56t4.5 -75h377v-146h-389q-16 -80 -48.5 -142t-78.5 -99h811v-197h-1078z" />
+<glyph unicode="&#x20a7;" horiz-adv-x="2630" d="M166 0v1384h424q103 0 185.5 -18.5t143 -58.5t99 -104t53.5 -154h150v292h215v-292h235v-175h-235v-524q0 -56 5.5 -94.5t18.5 -62.5t33.5 -35t50.5 -11q29 0 61.5 8.5t57.5 20.5l41 -176q-43 -14 -94.5 -22.5t-98.5 -8.5q-77 0 -131.5 20.5t-90 63t-52 108.5t-16.5 156 v557h-142q-6 -110 -38 -190.5t-93 -132.5t-152 -77t-214 -25h-183v-449h-233zM399 655h105q88 0 151.5 9t104 37.5t59.5 82.5t19 144q0 75 -20.5 123.5t-59.5 76.5t-96.5 39t-131.5 11h-131v-523zM1708 154l166 110q43 -63 105 -90t141 -27q40 0 77 6t66 21.5t46.5 41.5 t17.5 65q0 30 -13 51t-41.5 37.5t-73 31t-108.5 29.5q-70 18 -134.5 41t-114 60.5t-79.5 94t-30 140.5q0 67 25 124t75 99t124.5 66t172.5 24q140 0 240 -50t151 -132l-166 -111q-15 22 -36 43t-49.5 37t-64 25.5t-79.5 9.5q-82 0 -132 -32.5t-50 -94.5q0 -29 10.5 -49 t33.5 -36t61 -28.5t93 -25.5q91 -23 164 -49t124.5 -64t79 -93.5t27.5 -137.5q0 -87 -34 -148t-91 -100t-131 -56.5t-155 -17.5t-147.5 14t-118 38.5t-89.5 58.5t-63 74z" />
+<glyph unicode="&#x20ab;" horiz-adv-x="1194" d="M104 483q0 102 23 197t74.5 169t133.5 118.5t200 44.5q78 0 153.5 -31t132.5 -82v213h-289v162h289v110h215v-110h138v-162h-138v-1112h-205v102q-65 -58 -146.5 -95.5t-178.5 -37.5q-106 0 -182 38t-125 106t-72 162.5t-23 207.5zM145 -137h891v-162h-891v162zM326 487 q0 -161 58.5 -244t172.5 -83q36 0 72.5 9.5t70.5 26t65 38t56 45.5v438q-24 21 -52.5 39.5t-60.5 33t-66 23t-69 8.5q-50 0 -95 -19.5t-78.5 -60t-53.5 -103.5t-20 -151z" />
+<glyph unicode="&#x20ac;" horiz-adv-x="1272" d="M25 475l38 154h60v129h-98l41 155h73q84 500 578 500q100 0 178.5 -19.5t138 -53.5t102.5 -80.5t74 -100.5l-176 -129q-21 34 -46.5 67t-61.5 58.5t-85 41t-116 15.5q-148 0 -229.5 -77t-112.5 -222h557l-39 -155h-536v-129h509l-38 -154h-453q31 -156 114 -229.5 t230 -73.5q67 0 116 16.5t86.5 44.5t66 65t53.5 79l178 -121q-41 -68 -85.5 -120.5t-102.5 -89.5t-133.5 -56t-178.5 -19q-255 0 -401.5 126t-186.5 378h-114z" />
+<glyph unicode="&#x20b9;" horiz-adv-x="1272" d="M143 907l95 168h448q-14 68 -58.5 105t-127.5 37h-357l95 167h913l-94 -167h-217q55 -61 67 -142h244l-94 -168h-146q-12 -80 -49 -139.5t-93 -100.5t-129 -63.5t-157 -28.5l435 -575h-250l-430 575v189h184q64 0 111 8.5t78.5 25.5t50 44t26.5 65h-545z" />
+<glyph unicode="&#x20ba;" horiz-adv-x="1272" d="M139 528v166l178 64v147l-178 -63v166l178 63v313h215v-245l273 100v-166l-273 -100v-148l273 101v-166l-273 -101v-481h15q81 0 149 25t116.5 81.5t75.5 146.5t27 220h213q0 -164 -37.5 -290.5t-114 -213t-193 -131.5t-275.5 -45q-53 0 -100 7t-91 22v592z" />
+<glyph unicode="&#x2105;" horiz-adv-x="1763" d="M72 1047q0 84 19 152t60 115.5t105.5 73t155.5 25.5q93 0 158 -33.5t108 -105.5l-123 -90q-26 38 -60.5 59t-82.5 21q-43 0 -72.5 -15t-47.5 -43.5t-26 -68.5t-8 -90q0 -48 7.5 -88t26.5 -68.5t50 -44t78 -15.5q46 0 86 19t67 39l91 -129q-22 -15 -47 -29t-55.5 -25 t-67.5 -17.5t-82 -6.5q-92 0 -157 26t-105.5 74t-59 115t-18.5 150zM395 -31l742 1444h188l-741 -1444h-189zM1026 330q0 76 16.5 142t55.5 115.5t102.5 78t157.5 28.5t157.5 -28.5t102.5 -78t55.5 -115.5t16.5 -142q0 -75 -16.5 -140.5t-55.5 -114.5t-102.5 -77.5 t-157.5 -28.5t-157.5 28t-102.5 77t-55.5 115t-16.5 141zM1214 330q0 -106 34 -160.5t110 -54.5q75 0 109 54.5t34 160.5q0 109 -34 164t-109 55q-76 0 -110 -55t-34 -164z" />
+<glyph unicode="&#x2113;" horiz-adv-x="1077" d="M145 461l193 190v426q0 98 20.5 175t59 130t95 81t128.5 28q64 0 108.5 -23t72.5 -58.5t40 -78.5t12 -84q0 -82 -23.5 -157.5t-66 -149t-101 -148t-128.5 -155.5v-305q0 -53 10 -90t27 -60t41 -33t53 -10q27 0 52 8.5t46.5 22t40 29t33.5 30.5l72 -127q-23 -21 -55 -44.5 t-71 -43t-84 -32.5t-95 -13q-75 0 -129 25.5t-89 70.5t-52 107t-17 135v162l-119 -119zM555 829q36 43 67.5 90.5t55.5 97t37.5 100t13.5 100.5q0 45 -17 74.5t-55 29.5q-49 0 -75.5 -51.5t-26.5 -153.5v-287z" />
+<glyph unicode="&#x2116;" horiz-adv-x="2402" d="M154 0v1384h315l616 -1015v1015h226v-1384h-271l-661 1106v-1106h-225zM1509 874q0 85 19 158.5t62.5 127.5t114 85t173.5 31t173.5 -31t114 -85t62.5 -127.5t19 -158.5q0 -83 -19 -155.5t-62.5 -126t-114 -84.5t-173.5 -31t-173.5 31t-114 84.5t-62.5 126t-19 155.5z M1540 0v203h678v-203h-678zM1720 874q0 -112 37 -172.5t121 -60.5t121 60.5t37 172.5q0 116 -37 178t-121 62t-121 -62t-37 -178z" />
<glyph unicode="&#x2122;" horiz-adv-x="1649" d="M59 1233v151h611v-151h-219v-563h-170v563h-222zM825 670v714h191l162 -323l165 323h187v-714h-164v436l-139 -266h-99l-137 266v-436h-166z" />
+<glyph unicode="&#x2126;" horiz-adv-x="1366" d="M102 809q0 118 31.5 227t100.5 193t178 134t264 50q149 0 259.5 -40.5t183.5 -118t109 -189.5t36 -256q0 -125 -18.5 -218.5t-55 -161t-90 -111.5t-123.5 -68v-41h266v-209h-473v360q60 8 106 33.5t77.5 77t48 132t16.5 198.5q0 202 -83.5 303.5t-258.5 101.5 q-89 0 -151.5 -28.5t-103 -81t-59 -127t-18.5 -166.5q0 -125 15.5 -205t47 -128.5t77.5 -72.5t108 -37v-360h-469v209h268v41q-75 23 -130 64t-90 107.5t-52 161.5t-17 226z" />
+<glyph unicode="&#x212e;" horiz-adv-x="1407" d="M92 623q0 134 42 252t120.5 205.5t191 138.5t254.5 51q144 0 257.5 -51t192 -139t121 -206t44.5 -251h-959v-430q70 -69 155 -104.5t185 -35.5q85 0 153 20.5t124 58t101.5 89.5t84.5 115q19 -11 37 -22.5t37 -22.5q-47 -71 -99 -129t-116 -99.5t-143 -64.5t-179 -23 q-138 0 -249.5 51t-190.5 139t-121.5 206t-42.5 252zM356 700h686v353q-33 31 -72.5 57t-83 45t-91 29t-95.5 10q-203 0 -344 -139v-355z" />
+<glyph unicode="&#x215b;" horiz-adv-x="2019" d="M138 1105v129q68 2 114.5 11t77 26.5t48.5 46t30 69.5h162v-852h-207v570h-225zM478 -51l761 1487h203l-766 -1487h-198zM1194 229q0 66 43 122t125 93q-143 65 -143 182q0 115 87 176.5t255 61.5q162 0 251 -60t89 -176q0 -113 -150 -186q85 -34 128.5 -84.5 t43.5 -128.5q0 -65 -26.5 -112.5t-74 -79t-114 -47t-147.5 -15.5q-178 0 -272.5 64.5t-94.5 189.5zM1397 229q0 -48 39.5 -77.5t124.5 -29.5q84 0 122.5 31.5t38.5 79.5q0 46 -42 78.5t-119 58.5q-76 -23 -120 -56t-44 -85zM1415 628q0 -17 6 -32t22.5 -29t45.5 -27.5 t74 -28.5q74 20 106.5 47.5t32.5 65.5q0 40 -34 67t-109 27q-39 0 -66 -7.5t-44.5 -20t-25.5 -28.5t-8 -34z" />
+<glyph unicode="&#x215c;" horiz-adv-x="2019" d="M72 672l166 89q26 -36 69.5 -61t100.5 -25q41 0 70 9t47 24.5t26 37.5t8 49q0 57 -41 84t-123 27h-102v152h90q90 0 130 26.5t40 77.5q0 40 -33.5 64t-95.5 24q-59 0 -101.5 -22.5t-74.5 -65.5l-158 90q24 32 54.5 60t72 49t96 33t125.5 12q82 0 142.5 -17.5t100.5 -48 t59.5 -71t19.5 -85.5q0 -138 -150 -190q81 -25 122.5 -78t41.5 -129q0 -68 -25 -118.5t-72 -84t-115 -50.5t-154 -17q-57 0 -109 11.5t-95.5 32t-77 49t-54.5 62.5zM514 -51l761 1487h203l-766 -1487h-198zM1194 229q0 66 43 122t125 93q-143 65 -143 182q0 115 87 176.5 t255 61.5q162 0 251 -60t89 -176q0 -113 -150 -186q85 -34 128.5 -84.5t43.5 -128.5q0 -65 -26.5 -112.5t-74 -79t-114 -47t-147.5 -15.5q-178 0 -272.5 64.5t-94.5 189.5zM1397 229q0 -48 39.5 -77.5t124.5 -29.5q84 0 122.5 31.5t38.5 79.5q0 46 -42 78.5t-119 58.5 q-76 -23 -120 -56t-44 -85zM1415 628q0 -17 6 -32t22.5 -29t45.5 -27.5t74 -28.5q74 20 106.5 47.5t32.5 65.5q0 40 -34 67t-109 27q-39 0 -66 -7.5t-44.5 -20t-25.5 -28.5t-8 -34z" />
+<glyph unicode="&#x215d;" horiz-adv-x="2019" d="M68 675l170 94q26 -38 70 -64t104 -26q81 0 126.5 37t45.5 106q0 62 -45 92.5t-125 30.5q-50 0 -87 -14.5t-65 -34.5h-131l57 491h566v-160h-392l-20 -147q26 8 57 12t76 4q67 0 126 -16t103 -49.5t69.5 -85.5t25.5 -125q0 -70 -24.5 -126t-73.5 -95.5t-121 -60.5 t-166 -21q-122 0 -208 44t-138 114zM521 -51l761 1487h203l-766 -1487h-198zM1194 229q0 66 43 122t125 93q-143 65 -143 182q0 115 87 176.5t255 61.5q162 0 251 -60t89 -176q0 -113 -150 -186q85 -34 128.5 -84.5t43.5 -128.5q0 -65 -26.5 -112.5t-74 -79t-114 -47 t-147.5 -15.5q-178 0 -272.5 64.5t-94.5 189.5zM1397 229q0 -48 39.5 -77.5t124.5 -29.5q84 0 122.5 31.5t38.5 79.5q0 46 -42 78.5t-119 58.5q-76 -23 -120 -56t-44 -85zM1415 628q0 -17 6 -32t22.5 -29t45.5 -27.5t74 -28.5q74 20 106.5 47.5t32.5 65.5q0 40 -34 67 t-109 27q-39 0 -66 -7.5t-44.5 -20t-25.5 -28.5t-8 -34z" />
+<glyph unicode="&#x215e;" horiz-adv-x="2019" d="M78 1227v160h729v-129l-363 -723h-233l371 692h-504zM488 -51l761 1487h203l-766 -1487h-198zM1194 229q0 66 43 122t125 93q-143 65 -143 182q0 115 87 176.5t255 61.5q162 0 251 -60t89 -176q0 -113 -150 -186q85 -34 128.5 -84.5t43.5 -128.5q0 -65 -26.5 -112.5 t-74 -79t-114 -47t-147.5 -15.5q-178 0 -272.5 64.5t-94.5 189.5zM1397 229q0 -48 39.5 -77.5t124.5 -29.5q84 0 122.5 31.5t38.5 79.5q0 46 -42 78.5t-119 58.5q-76 -23 -120 -56t-44 -85zM1415 628q0 -17 6 -32t22.5 -29t45.5 -27.5t74 -28.5q74 20 106.5 47.5t32.5 65.5 q0 40 -34 67t-109 27q-39 0 -66 -7.5t-44.5 -20t-25.5 -28.5t-8 -34z" />
+<glyph unicode="&#x2190;" horiz-adv-x="2048" d="M190 494v47q57 29 107.5 61.5t93.5 67.5q45 35 97 86t114 121h78q-23 -48 -43 -85t-37 -63q-29 -51 -88 -125h1346v-176h-1346q28 -34 49.5 -64.5t38.5 -56.5t37 -63.5t43 -85.5h-78q-118 133 -209 204q-45 36 -95.5 68.5t-107.5 63.5z" />
+<glyph unicode="&#x2191;" horiz-adv-x="1024" d="M154 1178v75q68 62 118.5 114t85.5 95q72 90 131 205h46q60 -118 131 -203q35 -43 86 -95.5t120 -115.5v-75q-49 23 -86 42.5t-63 34.5q-26 17 -57 39t-66 49v-1343h-174v1343q-35 -26 -66 -47.5t-57 -38.5q-53 -33 -149 -79z" />
+<glyph unicode="&#x2192;" horiz-adv-x="2048" d="M190 428v176h1344q-26 35 -48.5 66t-39.5 57t-36 64t-42 86h76q62 -69 113.5 -120.5t95.5 -86.5q45 -35 95.5 -67.5t109.5 -63.5v-45q-59 -31 -109.5 -63.5t-93.5 -68.5q-85 -66 -211 -204h-76q23 48 42 84.5t36 62.5t38.5 57t49.5 66h-1344z" />
+<glyph unicode="&#x2193;" horiz-adv-x="1024" d="M152 414v75q49 -23 86 -42.5t63 -36.5q26 -16 57 -37.5t66 -48.5v1343h174v-1343q35 26 66 47.5t57 38.5q53 33 149 79v-75q-68 -62 -118.5 -114t-85.5 -97q-71 -85 -131 -203h-46q-60 118 -131 203q-35 43 -86 95.5t-120 115.5z" />
+<glyph unicode="&#x2194;" horiz-adv-x="2048" d="M190 494v47q57 29 107.5 61.5t93.5 67.5q45 35 97 86t114 121h78q-23 -48 -43 -85t-37 -63q-29 -51 -88 -125h1022q-26 34 -48.5 64.5t-39.5 56.5q-17 28 -36 66t-42 86h76q62 -69 113.5 -120.5t95.5 -86.5q45 -35 95.5 -67.5t109.5 -63.5v-45q-59 -31 -109.5 -63.5 t-93.5 -68.5q-85 -66 -211 -204h-76q23 48 41.5 84.5t34.5 62.5q17 26 39 57t51 66h-1022q28 -34 49.5 -64.5t38.5 -56.5t37 -63.5t43 -85.5h-78q-118 133 -209 204q-45 36 -95.5 68.5t-107.5 63.5z" />
+<glyph unicode="&#x2195;" horiz-adv-x="1024" d="M154 414v75q48 -23 84.5 -42.5t62.5 -34.5q51 -31 125 -88v1019q-35 -27 -66 -49t-57 -39t-63.5 -35.5t-85.5 -41.5v75q68 60 118.5 112t85.5 97q72 90 131 205h46q59 -115 131 -205q35 -43 86 -95t120 -114v-75q-49 23 -86 41.5t-63 33.5q-26 17 -57 39t-66 51v-1019 q34 26 64.5 47.5t56.5 38.5q28 17 65.5 36.5t85.5 42.5v-75q-135 -120 -206 -209q-72 -90 -131 -205h-46q-60 118 -131 203q-35 45 -85.5 97t-118.5 114z" />
+<glyph unicode="&#x21a8;" horiz-adv-x="1024" d="M154 -74h718v-174h-718v174zM154 414v75q48 -23 83.5 -42.5t61.5 -34.5q26 -16 57.5 -37.5t69.5 -50.5v1019q-35 -27 -67 -49t-58 -39t-62.5 -35.5t-84.5 -41.5v75q66 60 116.5 112t85.5 97t69 95.5t64 109.5h46q30 -59 62 -109.5t67 -95.5q35 -43 87 -95t121 -114v-75 q-49 23 -86 41.5t-63 33.5q-26 17 -57 39t-66 51v-1019q34 26 64.5 47.5t56.5 38.5t64 36.5t87 42.5v-75q-69 -60 -120 -112t-86 -97q-72 -90 -131 -205h-46q-60 118 -131 203q-35 45 -85.5 97t-118.5 114z" />
+<glyph unicode="&#x2202;" horiz-adv-x="1270" d="M96 371q0 147 49 258.5t126.5 186.5t173 113t188.5 38q51 0 95 -12t79.5 -31.5t62.5 -45t43 -53.5h5q2 26 4 53t2 56q0 142 -73.5 220.5t-209.5 78.5q-54 0 -111 -17t-102 -45l-53 160q23 16 55.5 31t72 26t84.5 18t93 7q111 0 199.5 -35.5t150 -101.5t94.5 -161t33 -214 q0 -91 -12.5 -183t-38.5 -181q-33 -114 -88 -216t-129.5 -179t-168 -122t-204.5 -45q-94 0 -171 29t-132.5 81.5t-86 125.5t-30.5 160zM336 367q0 -47 13.5 -85t38 -65t59 -42t77.5 -15q65 0 123 38.5t105.5 105t83 155.5t55.5 190q-10 31 -28 58t-45 47.5t-62 32.5t-80 12 q-66 0 -127.5 -33.5t-108.5 -91.5t-75.5 -137t-28.5 -170z" />
+<glyph unicode="&#x2206;" horiz-adv-x="1272" d="M39 0v100q55 154 112 316.5t114.5 326t115 325.5t113.5 316h288q55 -154 111.5 -316t113.5 -325.5t113.5 -326t112.5 -316.5v-100h-1194zM303 197h649l-282 825q-13 38 -22 76.5t-17 64.5h-6q-7 -26 -16 -63.5t-23 -75.5z" />
+<glyph unicode="&#x220f;" horiz-adv-x="1589" d="M170 -471v1905h1249v-1905h-243v1694h-762v-1694h-244z" />
+<glyph unicode="&#x2211;" horiz-adv-x="1389" d="M66 -346l667 835l-627 805v140h1170v-197h-852l575 -741l-610 -770h932v-197h-1255v125z" />
+<glyph unicode="&#x2212;" horiz-adv-x="1427" d="M147 496v174h1131v-174h-1131z" />
+<glyph unicode="&#x2215;" horiz-adv-x="1014" d="M-2 -299l702 1819h211l-704 -1819h-209z" />
+<glyph unicode="&#x2219;" horiz-adv-x="524" d="M119 731q0 71 33 103t108 32q77 0 111.5 -32t34.5 -103q0 -74 -37 -103.5t-109 -29.5q-40 0 -67 9t-43.5 26t-23.5 41.5t-7 56.5z" />
+<glyph unicode="&#x221a;" horiz-adv-x="1174" d="M43 676l289 184l276 -635l357 1268h165l-430 -1518h-182l-287 654l-118 -74z" />
+<glyph unicode="&#x221e;" horiz-adv-x="1741" d="M98 594q0 84 28.5 152t78.5 116t118 73.5t146 25.5q66 0 124 -18t108 -49t91.5 -73t75.5 -90h4q27 39 65.5 80t88 74.5t109.5 54.5t129 21q83 0 152 -26t119 -73.5t77.5 -113.5t27.5 -146q0 -79 -26.5 -147t-75 -117.5t-116.5 -78t-152 -28.5q-62 0 -119 16.5t-107.5 47 t-94 73t-77.5 93.5h-4q-35 -48 -77.5 -90t-93 -73t-107 -49t-117.5 -18q-81 0 -149.5 26t-118.5 73.5t-78.5 114.5t-28.5 149zM285 594q0 -42 14.5 -78.5t41 -63.5t63.5 -42t81 -15q45 0 86 16t77.5 43.5t68.5 64.5t59 79q-28 43 -61 79.5t-70.5 63t-78.5 41.5t-83 15 q-48 0 -85 -16t-62 -44t-38 -64.5t-13 -78.5zM963 598q55 -93 129.5 -148t160.5 -55q52 0 90 17t63 45.5t36.5 65t11.5 75.5t-11.5 75t-36.5 63.5t-63 44t-90 16.5q-46 0 -86.5 -14.5t-76 -41t-67 -63t-60.5 -80.5z" />
+<glyph unicode="&#x221f;" horiz-adv-x="2048" d="M123 0v1667h135v-1532h1667v-135h-1802z" />
+<glyph unicode="&#x2229;" horiz-adv-x="1473" d="M158 0v588q0 128 2.5 214.5t7.5 133.5q9 93 49 186q31 73 82 135t117.5 107t147.5 70.5t173 25.5q138 0 246 -49t182 -137q37 -45 64.5 -94t44.5 -103t26 -106t11 -103t3 -120t1 -160v-588h-146v596q0 238 -12 334q-5 49 -21 96.5t-42 93.5q-51 94 -141 144.5t-218 50.5 q-141 0 -234 -60.5t-141 -164.5q-45 -105 -51 -209q-2 -53 -3 -123.5t-1 -161.5v-596h-147z" />
+<glyph unicode="&#x222b;" horiz-adv-x="1071" d="M106 -451l48 175q18 -8 43.5 -14.5t56.5 -6.5q77 0 117.5 48t40.5 140v1246q0 91 23 164.5t69 125t114.5 79.5t159.5 28q27 0 54.5 -3t52.5 -7.5t45.5 -10.5t32.5 -12l-50 -172q-15 8 -42 14.5t-58 6.5q-75 0 -116.5 -48t-41.5 -141v-1245q0 -93 -24 -166.5t-70.5 -125 t-114.5 -78.5t-157 -27q-23 0 -48.5 2t-50.5 6t-47 9.5t-37 12.5z" />
+<glyph unicode="&#x2248;" horiz-adv-x="1427" d="M147 166v186q84 63 167.5 99t160.5 36q63 0 126.5 -23.5t126.5 -52t125 -52t122 -23.5q40 0 82 14t82 35t75.5 45t63.5 45v-186q-74 -60 -157 -97.5t-160 -37.5q-43 0 -87 11t-87.5 27.5t-86.5 36t-85 36t-82 27.5t-78 11q-40 0 -81 -13t-81 -33t-77 -44t-69 -47z M147 627v186q82 63 166.5 99t161.5 36q63 0 126.5 -23.5t126.5 -52t124.5 -52t120.5 -23.5q41 0 83 14t82 35t75.5 45t64.5 45v-186q-34 -27 -70.5 -51.5t-76 -43.5t-82 -30t-88.5 -11q-66 0 -132 23.5t-131 51.5t-126.5 51.5t-118.5 23.5q-40 0 -81 -13t-80 -33t-76 -44 t-69 -47z" />
+<glyph unicode="&#x2260;" horiz-adv-x="1427" d="M147 258v174h379l156 301h-535v174h623l203 396h203l-203 -396h305v-174h-395l-156 -301h551v-174h-641l-174 -340h-199l174 340h-291z" />
+<glyph unicode="&#x2261;" horiz-adv-x="1427" d="M147 0v174h1131v-174h-1131zM147 446v175h1131v-175h-1131zM147 895v174h1131v-174h-1131z" />
+<glyph unicode="&#x2264;" horiz-adv-x="1427" d="M147 0v180h1131v-180h-1131zM147 676v166l1131 442v-188l-885 -338l885 -281v-188z" />
+<glyph unicode="&#x2265;" horiz-adv-x="1427" d="M147 0v180h1131v-180h-1131zM147 289v188l887 281l-887 338v188l1131 -442v-166z" />
+<glyph unicode="&#x2302;" horiz-adv-x="1229" d="M154 0v635l460 518l461 -518v-635h-921zM233 82h762v518l-381 426l-381 -426v-518z" />
+<glyph unicode="&#x2310;" horiz-adv-x="1427" d="M147 344v643h1131v-174h-954v-469h-177z" />
+<glyph unicode="&#x2320;" horiz-adv-x="1237" d="M547 -381v1608q0 111 21.5 193t66.5 136q88 111 203 111q34 0 60 -9t43.5 -24t26.5 -34.5t9 -40.5q0 -19 -7 -36t-19 -29.5t-28 -20t-34 -7.5q-29 0 -52.5 12t-48.5 50q-22 37 -45 37q-30 0 -43 -27q-5 -14 -7.5 -51.5t-2.5 -100.5v-1767h-143z" />
+<glyph unicode="&#x2321;" horiz-adv-x="1237" d="M260 -272q0 19 7 36t19 29.5t28 19.5t34 7q31 0 53.5 -13t47.5 -51q22 -35 45 -35q30 0 41 27q12 28 12 152v1767h143v-1608q0 -109 -21.5 -190.5t-66.5 -136.5q-85 -113 -203 -113q-35 0 -61 9t-43 24t-26 34.5t-9 41.5z" />
+<glyph unicode="&#x2500;" horiz-adv-x="1450" d="M-23 535v174h1496v-174h-1496z" />
+<glyph unicode="&#x2502;" horiz-adv-x="1450" d="M639 -621v2485h174v-2485h-174z" />
+<glyph unicode="&#x250c;" horiz-adv-x="1450" d="M639 -621v1330h836v-174h-662v-1156h-174z" />
+<glyph unicode="&#x2510;" horiz-adv-x="1450" d="M-23 535v174h834v-1330h-174v1156h-660z" />
+<glyph unicode="&#x2514;" horiz-adv-x="1450" d="M639 535v1329h174v-1155h662v-174h-836z" />
+<glyph unicode="&#x2518;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-1329h-834z" />
+<glyph unicode="&#x251c;" horiz-adv-x="1450" d="M639 -621v2485h174v-1155h662v-174h-662v-1156h-174z" />
+<glyph unicode="&#x2524;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-2485h-174v1156h-660z" />
+<glyph unicode="&#x252c;" horiz-adv-x="1450" d="M-23 535v174h1496v-174h-662v-1156h-174v1156h-660z" />
+<glyph unicode="&#x2534;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-1155h662v-174h-1496z" />
+<glyph unicode="&#x253c;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-1155h662v-174h-662v-1156h-174v1156h-660z" />
+<glyph unicode="&#x2550;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-1496zM-23 725v174h1496v-174h-1496z" />
+<glyph unicode="&#x2551;" horiz-adv-x="1450" d="M449 -621v2485h174v-2485h-174zM829 -621v2485h175v-2485h-175z" />
+<glyph unicode="&#x2552;" horiz-adv-x="1450" d="M639 -621v1520h836v-174h-662v-207h662v-174h-662v-965h-174z" />
+<glyph unicode="&#x2553;" horiz-adv-x="1450" d="M449 -621v1330h1026v-174h-471v-1156h-175v1156h-206v-1156h-174z" />
+<glyph unicode="&#x2554;" horiz-adv-x="1450" d="M449 -621v1520h1026v-174h-852v-1346h-174zM829 518h646v-174h-471v-965h-175v1139z" />
+<glyph unicode="&#x2555;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h834v-1520h-174v965h-660z" />
+<glyph unicode="&#x2556;" horiz-adv-x="1450" d="M-23 535v174h1027v-1330h-177v1156h-204v-1156h-174v1156h-472z" />
+<glyph unicode="&#x2557;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h1027v-1520h-177v1346h-850z" />
+<glyph unicode="&#x2558;" horiz-adv-x="1450" d="M639 344v1520h174v-965h662v-174h-662v-207h662v-174h-836z" />
+<glyph unicode="&#x2559;" horiz-adv-x="1450" d="M449 535v1329h174v-1155h206v1155h175v-1155h471v-174h-1026z" />
+<glyph unicode="&#x255a;" horiz-adv-x="1450" d="M449 344v1520h174v-1346h850v-174h-1024zM829 725v1139h175v-965h471v-174h-646z" />
+<glyph unicode="&#x255b;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h660v965h174v-1520h-834z" />
+<glyph unicode="&#x255c;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1329h-1027z" />
+<glyph unicode="&#x255d;" horiz-adv-x="1450" d="M-23 344v174h850v1346h177v-1520h-1027zM-23 725v174h469v965h177v-1139h-646z" />
+<glyph unicode="&#x255e;" horiz-adv-x="1450" d="M639 -621v2485h174v-965h662v-174h-662v-207h662v-174h-662v-965h-174z" />
+<glyph unicode="&#x255f;" horiz-adv-x="1450" d="M449 -621v2485h174v-2485h-174zM829 -621v2485h175v-1155h471v-174h-471v-1156h-175z" />
+<glyph unicode="&#x2560;" horiz-adv-x="1450" d="M449 -621v2485h174v-2485h-174zM829 518h646v-174h-471v-965h-175v1139zM829 725v1139h175v-965h471v-174h-646z" />
+<glyph unicode="&#x2561;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h660v965h174v-2485h-174v965h-660z" />
+<glyph unicode="&#x2562;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-2485h-177l3 1156h-472zM827 -621v2485h177v-2485h-177z" />
+<glyph unicode="&#x2563;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h469v965h177v-1139h-646zM827 -621v2485h177v-2485h-177z" />
+<glyph unicode="&#x2564;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-662v-965h-174v965h-660zM-23 725v174h1496v-174h-1496z" />
+<glyph unicode="&#x2565;" horiz-adv-x="1450" d="M-23 535v174h1496v-174h-469v-1156h-177v1156h-204v-1156h-177v1156h-469z" />
+<glyph unicode="&#x2566;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h1496v-174h-1496zM827 518h646v-174h-469v-965h-177v1139z" />
+<glyph unicode="&#x2567;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-1496zM-23 725v174h660v965h174v-965h662v-174h-1496z" />
+<glyph unicode="&#x2568;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1155h469v-174h-1496z" />
+<glyph unicode="&#x2569;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-1496zM-23 725v174h469v965h177v-1139h-646zM827 725v1139h177v-965h469v-174h-646z" />
+<glyph unicode="&#x256a;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h660v965h174v-965h662v-174h-662v-207h662v-174h-662v-965h-174v965h-660z" />
+<glyph unicode="&#x256b;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1155h469v-174h-469v-1156h-177v1156h-204v-1156h-177v1156h-469z" />
+<glyph unicode="&#x256c;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h469v965h177v-1139h-646zM827 518h646v-174h-469v-965h-177v1139zM827 725v1139h177v-965h469v-174h-646z" />
+<glyph unicode="&#x2580;" horiz-adv-x="1450" d="M-23 621v1243h1496v-1243h-1496z" />
+<glyph unicode="&#x2584;" horiz-adv-x="1450" d="M-23 -621v1242h1496v-1242h-1496z" />
+<glyph unicode="&#x2588;" horiz-adv-x="1450" d="M-23 -621v2485h1496v-2485h-1496z" />
+<glyph unicode="&#x258c;" horiz-adv-x="1450" d="M-23 -621v2485h748v-2485h-748z" />
+<glyph unicode="&#x2590;" horiz-adv-x="1450" d="M725 -621v2485h750v-2485h-750z" />
+<glyph unicode="&#x2591;" horiz-adv-x="1450" d="M0 -129h121v-127h-121v127zM0 244v125h121v-125h-121zM0 741v125h121v-125h-121zM0 1241v125h121v-125h-121zM0 1739v125h121v-125h-121zM242 -4v125h120v-125h-120zM242 -379h120v-125h-120v125zM242 494v124h120v-124h-120zM242 991v125h120v-125h-120zM242 1491v125 h120v-125h-120zM481 -129h121v-127h-121v127zM481 244v125h121v-125h-121zM481 741v125h121v-125h-121zM481 1241v125h121v-125h-121zM481 1739v125h121v-125h-121zM723 -4v125h121v-125h-121zM723 -379h121v-125h-121v125zM723 494v124h121v-124h-121zM723 991v125h121 v-125h-121zM723 1491v125h121v-125h-121zM965 -129h120v-127h-120v127zM965 244v125h120v-125h-120zM965 741v125h120v-125h-120zM965 1241v125h120v-125h-120zM965 1739v125h120v-125h-120zM1206 -4v125h121v-125h-121zM1206 -379h121v-125h-121v125zM1206 494v124h121 v-124h-121zM1206 991v125h121v-125h-121zM1206 1491v125h121v-125h-121z" />
+<glyph unicode="&#x2592;" horiz-adv-x="1450" d="M0 -4v123h121v-123h-121zM0 -379h121v-125h-121v125zM0 494v124h121v-124h-121zM0 991v125h121v-125h-121zM0 1491v125h121v-125h-121zM121 -129h121v-127h-121v127zM121 244v125h121v-125h-121zM121 741v125h121v-125h-121zM121 1241v125h121v-125h-121zM121 1739v125 h121v-125h-121zM242 -4v123h120v-123h-120zM242 -379h120v-125h-120v125zM242 494v124h120v-124h-120zM242 991v125h120v-125h-120zM242 1491v125h120v-125h-120zM362 -129h119v-127h-119v127zM362 244v125h119v-125h-119zM362 741v125h119v-125h-119zM362 1241v125h119 v-125h-119zM362 1739v125h119v-125h-119zM481 -4v123h121v-123h-121zM481 -379h121v-125h-121v125zM481 494v124h121v-124h-121zM481 991v125h121v-125h-121zM481 1491v125h121v-125h-121zM602 -129h123v-127h-123v127zM602 244v125h123v-125h-123zM602 741v125h123v-125 h-123zM602 1241v125h123v-125h-123zM602 1739v125h123v-125h-123zM725 -4v123h119v-123h-119zM725 -379h119v-125h-119v125zM725 494v124h119v-124h-119zM725 991v125h119v-125h-119zM725 1491v125h119v-125h-119zM844 -129h121v-127h-121v127zM844 244v125h121v-125h-121z M844 741v125h121v-125h-121zM844 1241v125h121v-125h-121zM844 1739v125h121v-125h-121zM965 -4v123h120v-123h-120zM965 -381l120 2v-125h-120v123zM965 494v124h120v-124h-120zM965 991v125h120v-125h-120zM965 1491v125h120v-125h-120zM1085 -129h121v-127h-121v127z M1085 244v125h121v-125h-121zM1085 741v125h121v-125h-121zM1085 1241v125h121v-125h-121zM1085 1739v125h121v-125h-121zM1206 -4v123h121v-123h-121zM1206 -379h121v-125h-121v125zM1206 494v124h121v-124h-121zM1206 991v125h121v-125h-121zM1206 1491v125h121v-125h-121 zM1327 -129h121v-127h-121v127zM1327 244v125h121v-125h-121zM1327 741v125h121v-125h-121zM1327 1241v125h121v-125h-121zM1327 1739v125h121v-125h-121z" />
+<glyph unicode="&#x2593;" horiz-adv-x="1450" d="M0 -129v373h121v125h-121v372h121v125h-121v375h121v125h-121v373h121v125h121v-125h120v125h119v-125h121v125h123v-125h119v125h121v-125h120v125h121v-125h121v125h121v-248h-121v-125h121v-375h-121v-125h121v-373h-121v-124h121v-375h-121v-123h121v-375h-121v-125 h121v-125h-1448v373h121v127h-121zM121 -4h121v123h-121v-123zM121 -379v-125h121v125h-121zM121 494h121v124h-121v-124zM121 991h121v125h-121v-125zM121 1491h121v125h-121v-125zM242 -129v-127h120v127h-120zM242 244h120v125h-120v-125zM242 741h120v125h-120v-125z M242 1241h120v125h-120v-125zM362 -4h119v123h-119v-123zM362 -379v-125h119v125h-119zM362 494h119v124h-119v-124zM362 991h119v125h-119v-125zM362 1491h119v125h-119v-125zM481 -129v-127h121v127h-121zM481 244h121v125h-121v-125zM481 741h121v125h-121v-125z M481 1241h121v125h-121v-125zM602 -4h123v123h-123v-123zM602 -379v-125h123v125h-123zM602 494h123v124h-123v-124zM602 991h123v125h-123v-125zM602 1491h123v125h-123v-125zM725 -129v-127h119v127h-119zM725 244h119v125h-119v-125zM725 741h119v125h-119v-125z M725 1241h119v125h-119v-125zM844 -4h121v123h-121v-123zM844 -379v-125h121v125h-121zM844 494h121v124h-121v-124zM844 991h121v125h-121v-125zM844 1491h121v125h-121v-125zM965 -129v-127h120v127h-120zM965 244h120v125h-120v-125zM965 741h120v125h-120v-125z M965 1241h120v125h-120v-125zM1085 -4h121v123h-121v-123zM1085 -379v-125h121v125h-121zM1085 494h121v124h-121v-124zM1085 991h121v125h-121v-125zM1085 1491h121v125h-121v-125zM1206 -129v-127h121v127h-121zM1206 244h121v125h-121v-125zM1206 741h121v125h-121v-125z M1206 1241h121v125h-121v-125z" />
+<glyph unicode="&#x25a0;" horiz-adv-x="1237" d="M145 0v944h945v-944h-945z" />
+<glyph unicode="&#x25a1;" horiz-adv-x="1237" d="M145 0v944h945v-944h-945zM221 76h793v792h-793v-792z" />
+<glyph unicode="&#x25aa;" horiz-adv-x="725" d="M131 444v463l463 2v-465h-463z" />
+<glyph unicode="&#x25ab;" horiz-adv-x="725" d="M131 444v463h463v-463h-463zM207 520h311v311h-311v-311z" />
+<glyph unicode="&#x25ac;" horiz-adv-x="2048" d="M340 0v385h1368v-385h-1368z" />
+<glyph unicode="&#x25b2;" horiz-adv-x="2028" d="M303 0l711 1419l710 -1419h-1421z" />
+<glyph unicode="&#x25ba;" horiz-adv-x="2028" d="M289 -31v1448l1450 -725z" />
+<glyph unicode="&#x25bc;" horiz-adv-x="2028" d="M303 1389h1421l-710 -1420z" />
+<glyph unicode="&#x25c4;" horiz-adv-x="2028" d="M289 692l1450 725v-1448z" />
+<glyph unicode="&#x25ca;" horiz-adv-x="1229" d="M145 715l451 719h100l453 -717l-453 -717h-100zM307 717l340 -541l338 541l-338 538z" />
+<glyph unicode="&#x25cb;" horiz-adv-x="1237" d="M178 578q-3 58 13 114t46 106t72.5 92t92.5 71.5t105 44.5t111 12q84 4 165 -31t144 -97t99.5 -143.5t32.5 -168.5q0 -183 -129 -312t-312 -129q-182 0 -311 129t-129 312zM254 578q0 -152 106 -259q107 -106 258 -106q152 0 259 106q106 107 106 259q2 48 -11.5 94.5 t-38 87.5t-59.5 75.5t-76.5 59t-87 37t-92.5 10.5q-46 2 -92 -10.5t-87 -37t-76 -59t-59.5 -75.5t-38 -87.5t-11.5 -94.5z" />
+<glyph unicode="&#x25cf;" horiz-adv-x="1237" d="M178 578q-3 58 13 114t46 106t72.5 92t92.5 71.5t105 44.5t111 12q84 4 165 -31t144 -97t99.5 -143.5t32.5 -168.5q0 -183 -129 -312t-312 -129q-182 0 -311 129t-129 312z" />
+<glyph unicode="&#x25d8;" horiz-adv-x="1237" d="M127 0v981h981v-981h-981zM416 489q0 -41 16 -77t43 -63.5t64 -43.5t79 -16t79 16t64 43.5t42.5 63.5t15.5 77q0 42 -15.5 79t-42.5 64.5t-64 43.5t-79 16t-79 -16t-64 -43.5t-43 -64.5t-16 -79z" />
+<glyph unicode="&#x25d9;" horiz-adv-x="1237" d="M43 0v1155h1153v-1155h-1153zM178 578q0 -183 129 -312t311 -129q185 0 314 129t129 312q3 58 -13.5 114t-46.5 106t-72.5 92t-92.5 71.5t-105.5 44.5t-112.5 12q-56 3 -111 -12t-105 -44.5t-92.5 -71.5t-72.5 -92t-46 -106t-13 -114zM256 578q-4 73 26 140t82 118 t119 80t138 26q69 3 136 -26t118.5 -80t81.5 -118t26 -140q0 -152 -106 -259q-107 -106 -256 -106q-152 0 -259 106q-106 107 -106 259z" />
+<glyph unicode="&#x25e6;" horiz-adv-x="725" d="M113 678q0 102 71 176q74 74 178 74q105 0 179 -74q73 -73 73 -176q0 -105 -73 -178q-74 -74 -179 -74q-104 0 -178 74q-71 74 -71 178zM188 678q0 -37 13.5 -69t37.5 -56t55.5 -37.5t67.5 -13.5t68.5 13.5t56.5 37.5t38 56t14 69q0 36 -13.5 67.5t-37.5 55.5t-56.5 37.5 t-69.5 13.5q-36 0 -67.5 -13.5t-55.5 -37.5t-37.5 -55.5t-13.5 -67.5z" />
<glyph unicode="&#x25fc;" horiz-adv-x="1050" d="M0 0v1050h1050v-1050h-1050z" />
+<glyph unicode="&#x263a;" horiz-adv-x="2048" d="M385 518q0 165 86 320q85 151 238 235q152 82 315 82q161 0 313 -82q155 -83 240 -235q86 -155 86 -320q0 -166 -86 -317q-83 -153 -236 -236q-75 -42 -154 -63t-163 -21t-163 21t-154 63q-76 42 -135.5 101t-102.5 135q-42 75 -63 154.5t-21 162.5zM479 518 q0 -71 18.5 -138t53.5 -132q36 -65 88 -116t114 -86t131 -54t140 -19t138 18.5t132 53.5q65 37 116 89t86.5 114t54 130.5t18.5 139.5q0 139 -74 273q-37 65 -89.5 116t-114.5 85.5t-130.5 52.5t-136.5 18q-69 0 -135.5 -18.5t-132.5 -53.5q-65 -35 -115.5 -84.5 t-87.5 -115.5q-74 -134 -74 -273zM698 649q0 35 24 58.5t56 23.5q35 0 58.5 -23.5t23.5 -58.5q0 -32 -23.5 -56t-58.5 -24q-16 0 -30.5 6.5t-25.5 17.5t-17.5 25.5t-6.5 30.5zM729 313l64 35q76 -143 231 -143t231 143l64 -35q-102 -194 -295 -194q-99 0 -171.5 48.5 t-123.5 145.5zM1188 649q0 35 24 58.5t56 23.5q35 0 58.5 -23.5t23.5 -58.5q0 -32 -23.5 -56t-58.5 -24q-16 0 -30.5 6.5t-25.5 17.5t-17.5 25.5t-6.5 30.5z" />
+<glyph unicode="&#x263b;" horiz-adv-x="2048" d="M385 518q0 165 86 320q85 151 238 235q152 82 315 82q161 0 313 -82q155 -83 240 -235q86 -155 86 -320q0 -166 -86 -317q-83 -153 -236 -236q-75 -42 -154 -63t-163 -21t-163 21t-154 63q-76 42 -135.5 101t-102.5 135q-42 75 -63 154.5t-21 162.5zM698 649 q0 -16 6.5 -30.5t17.5 -25.5t25.5 -17.5t30.5 -6.5q35 0 58.5 24t23.5 56q0 35 -23.5 58.5t-58.5 23.5q-32 0 -56 -23.5t-24 -58.5zM729 313q51 -97 123.5 -145.5t171.5 -48.5q193 0 295 194l-64 35q-76 -143 -231 -143t-231 143zM1188 649q0 -16 6.5 -30.5t17.5 -25.5 t25.5 -17.5t30.5 -6.5q35 0 58.5 24t23.5 56q0 35 -23.5 58.5t-58.5 23.5q-32 0 -56 -23.5t-24 -58.5z" />
+<glyph unicode="&#x263c;" horiz-adv-x="1878" d="M16 666v67h336q4 53 14 98.5t27 87.5t42.5 82t60.5 82l-283 287l47 57l293 -282q50 34 93.5 59t85 41.5t83 25.5t86.5 13v338h78v-338q50 -3 94 -12t86 -25.5t83 -42t85 -61.5l291 284l51 -53l-287 -287q38 -48 63.5 -89t41.5 -78q18 -48 28.5 -95t12.5 -92h334v-67h-334 q-11 -97 -46.5 -185.5t-97.5 -167.5l285 -290l-57 -50l-283 283q-49 -37 -92 -62.5t-80 -39.5q-35 -14 -79.5 -23.5t-98.5 -15.5v-338h-78v338q-55 7 -100.5 17.5t-86.5 27t-79 39t-78 53.5l-295 -279l-49 52l285 286q-34 42 -59 83t-42.5 83.5t-28 89t-16.5 99.5h-336z M426 698q0 -66 17 -130t49 -126q34 -60 82.5 -107.5t107 -80.5t124 -50.5t132.5 -17.5q130 0 254 68q61 34 109 82.5t81 106.5t50.5 123t17.5 132q0 134 -70 256q-34 62 -83 110t-107.5 80.5t-123 49t-128.5 16.5q-127 0 -254 -65q-62 -33 -110 -82t-81 -107.5t-50 -124.5 t-17 -133z" />
+<glyph unicode="&#x2640;" horiz-adv-x="1536" d="M244 983q0 68 17 132.5t52 127.5q35 62 85 111t109.5 83t126 52t134.5 18t132.5 -17t127.5 -52q62 -35 111 -85t82.5 -109.5t51 -126.5t17.5 -134q0 -211 -143 -360q-145 -153 -350 -162v-402h458v-59h-458v-381h-60v381h-461v59h461v402q-101 0 -225 65 q-62 33 -111.5 82.5t-84 109.5t-53.5 127.5t-19 137.5zM299 981q0 -195 137 -332t332 -137t332 137t137 332q2 62 -15 122t-49 113t-77 97.5t-97.5 76t-111.5 47.5t-119 13q-119 0 -231 -61q-56 -30 -100.5 -74.5t-75 -98t-46.5 -114t-16 -121.5z" />
+<glyph unicode="&#x2642;" horiz-adv-x="1536" d="M111 262q0 217 153 369q154 153 373 153q38 0 79.5 -6t86.5 -20l360 772l-536 -266l-25 53l615 303l34 -16l164 -666l-57 -14l-141 579l-359 -768q74 -37 130 -88t93.5 -112t56.5 -130.5t19 -142.5q0 -68 -17 -132.5t-53 -127.5q-34 -62 -83.5 -111t-109 -83t-126 -52 t-133.5 -18q-69 0 -134 17t-128 52q-62 35 -110.5 85t-82 110t-51.5 126t-18 134zM166 262q0 -194 137 -332q139 -139 332 -139q191 0 332 139q137 138 137 332q0 121 -64 234q-31 57 -76 101t-98 74t-112.5 45t-118.5 15q-119 0 -232 -61q-56 -30 -100 -74.5t-74.5 -98.5 t-46.5 -114t-16 -121z" />
+<glyph unicode="&#x2660;" horiz-adv-x="1343" d="M186 494q0 73 31 133q46 82 148 166q101 83 149 137q37 42 63.5 78.5t43.5 68.5t30.5 70.5t22.5 83.5q12 -54 32 -102.5t46 -92.5q55 -84 192 -209q69 -63 113.5 -110.5t62.5 -81.5q37 -67 37 -137q0 -47 -17 -88t-46 -71t-69 -47.5t-85 -17.5q-83 0 -154 58 q-27 21 -53 54.5t-49 78.5q2 -108 23 -185t65.5 -127.5t116 -78t174.5 -37.5l6 -37h-793l9 37q92 0 164 27t121.5 80.5t74.5 133.5t23 187q-45 -94 -111 -142.5t-151 -48.5q-90 0 -156 66q-64 64 -64 154z" />
+<glyph unicode="&#x2663;" horiz-adv-x="1343" d="M55 553q0 116 74 195q72 78 166 81q31 -2 72 -14.5t94 -38.5q-22 34 -35 59.5t-20.5 45.5t-10 38t-2.5 39q0 115 78 193q80 80 199 80q116 0 196 -80q42 -38 62 -85.5t20 -102.5q0 -90 -69 -187q42 20 67.5 31.5t34.5 13.5q14 5 28 6.5t31 1.5q100 0 174 -77t74 -195 q0 -60 -20 -110.5t-62 -92.5q-79 -79 -194 -82q-79 5 -136 34t-108 79q-17 20 -38.5 51t-47.5 76q2 -80 14 -142t34.5 -110.5t56 -85.5t79.5 -68q32 -20 87.5 -38t136.5 -33l8 -35h-848l8 35q164 33 219 67q40 25 74 64.5t58.5 87t38.5 101.5t14 110q0 8 -0.5 19t-2.5 28 q-30 -62 -68 -107.5t-80 -75t-87 -43.5t-90 -14q-116 0 -199 80q-40 42 -60 91.5t-20 109.5z" />
+<glyph unicode="&#x2665;" horiz-adv-x="1343" d="M127 969q0 109 74 186q73 76 180 76q57 0 104.5 -20t89.5 -60q62 -59 99 -172q33 113 92 172q83 80 190 80q111 0 185 -74q76 -73 76 -176q0 -88 -43 -188q-22 -48 -64.5 -112t-105.5 -144q-82 -104 -142 -189t-98 -151q-29 -54 -52 -109.5t-38 -112.5 q-16 60 -37.5 115.5t-50.5 106.5q-29 52 -84.5 132t-139.5 189q-60 82 -97.5 132.5t-51.5 72.5q-45 69 -65.5 127.5t-20.5 118.5z" />
+<glyph unicode="&#x2666;" horiz-adv-x="1343" d="M213 604q51 57 115.5 139.5t144.5 188.5q60 78 109 154.5t90 148.5q45 -79 98.5 -160t118.5 -168q75 -100 135 -176t106 -127q-37 -38 -96.5 -114t-144.5 -189q-135 -182 -217 -326q-14 26 -32.5 56.5t-41.5 64.5q-42 60 -92.5 130t-110.5 151q-12 17 -58 73.5 t-124 153.5z" />
+<glyph unicode="&#x266a;" horiz-adv-x="1024" d="M37 186q0 52 19.5 97.5t55.5 79t86.5 52.5t112.5 19q78 0 174 -47v977h39q87 0 143.5 -3t84.5 -11q38 -11 73 -30t66 -48q45 -42 70.5 -118t25.5 -179v-103h-98v43q0 136 -115 189q-73 31 -162 31h-26v-836q0 -121 -33 -188q-16 -34 -44.5 -61.5t-66 -46.5t-81 -29.5 t-89.5 -10.5q-54 0 -97.5 16t-74 45.5t-47 70.5t-16.5 91z" />
+<glyph unicode="&#x266b;" horiz-adv-x="1536" d="M86 94q0 52 20 97.5t56 79t86.5 52.5t111.5 19q39 0 83 -11t92 -34v975l794 248v-1108q0 -126 -31 -189q-15 -31 -42.5 -57t-64 -45t-79.5 -30t-90 -11q-56 0 -100 16.5t-75.5 46t-48 70.5t-16.5 90q0 102 76 172q77 74 201 74q19 0 35 -1t34.5 -5.5t42 -13t58.5 -23.5 v723l-596 -185v-835q0 -62 -8 -109.5t-25 -81.5q-15 -33 -43.5 -60t-65 -46.5t-80 -30t-89.5 -10.5q-55 0 -98.5 16.5t-74 46t-47 70.5t-16.5 90z" />
+<glyph unicode="&#xf001;" horiz-adv-x="1176" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM782 1325q0 62 29 89.5t98 27.5t99 -27t30 -90 q0 -66 -31.5 -91.5t-97.5 -25.5q-72 0 -99.5 30t-27.5 87zM803 0v1049h215v-1049h-215z" />
+<glyph unicode="&#xf002;" horiz-adv-x="1184" d="M39 874v175h143v102q0 92 19 161.5t61 115.5t109.5 69t165.5 23q55 0 106.5 -9.5t91.5 -23.5l-49 -187q-32 14 -70 22.5t-75 8.5q-42 0 -70 -10t-44.5 -31.5t-23 -56t-6.5 -82.5v-102h224v-175h-224v-874h-215v874h-143zM807 0v1489h215v-1489h-215z" />
+<glyph unicode="&#xf6c3;" horiz-adv-x="569" d="M141 -246q0 32 7 57.5t24 43t44.5 27t68.5 9.5q75 0 108 -40.5t33 -114.5q0 -89 -32.5 -157t-80.5 -126h-135q37 47 58.5 87.5t23.5 80.5q-62 2 -90.5 33.5t-28.5 99.5z" />
+<glyph unicode="&#xfeff;" horiz-adv-x="0" />
+<glyph horiz-adv-x="569" d="M141 1321q0 88 32.5 156t82.5 127h135q-38 -48 -60 -89t-24 -79q63 -3 91 -34t28 -99q0 -32 -7 -57.5t-23 -43.5t-43.5 -27.5t-67.5 -9.5q-78 0 -111 40.5t-33 115.5z" />
+<glyph horiz-adv-x="459" d="M39 1024l123 360h256l-213 -360h-166z" />
+<glyph horiz-adv-x="913" d="M76 419q0 227 92 335t289 108q193 0 286 -108t93 -335t-93 -335.5t-286 -108.5q-197 0 -289 107.5t-92 336.5zM291 419q0 -145 40 -212.5t124 -67.5q85 0 125.5 67.5t40.5 212.5q0 144 -40.5 211.5t-125.5 67.5q-84 0 -124 -67.5t-40 -211.5z" />
+<glyph horiz-adv-x="913" d="M176 563v129q68 2 114.5 11t77 26.5t48.5 46t30 69.5h162v-852h-207v570h-225z" />
+<glyph horiz-adv-x="913" d="M90 696q56 77 142.5 122.5t209.5 45.5q156 0 242 -63t86 -185q0 -80 -31 -137t-82 -105q-21 -20 -52 -45.5t-68 -54t-78 -59t-82 -58.5h424v-164h-699v160q50 37 107.5 79t112 84t101 81t75.5 71q31 32 45 63t14 66q0 51 -36 75t-87 24q-59 0 -103 -28.5t-75 -70.5z" />
+<glyph horiz-adv-x="913" d="M72 130l166 89q26 -36 69.5 -61t100.5 -25q41 0 70 9t47 24.5t26 37.5t8 49q0 57 -41 84t-123 27h-102v152h90q90 0 130 26.5t40 77.5q0 40 -33.5 64t-95.5 24q-59 0 -101.5 -22.5t-74.5 -65.5l-158 90q24 32 54.5 60t72 49t96 33t125.5 12q82 0 142.5 -17.5t100.5 -48 t59.5 -71t19.5 -85.5q0 -138 -150 -190q81 -25 122.5 -78t41.5 -129q0 -68 -25 -118.5t-72 -84t-115 -50.5t-154 -17q-57 0 -109 11.5t-95.5 32t-77 49t-54.5 62.5z" />
+<glyph horiz-adv-x="913" d="M43 163v146l494 536h184v-532h121v-150h-121v-170h-195v170h-483zM248 313h278v301z" />
+<glyph horiz-adv-x="913" d="M68 133l170 94q26 -38 70 -64t104 -26q81 0 126.5 37t45.5 106q0 62 -45 92.5t-125 30.5q-50 0 -87 -14.5t-65 -34.5h-131l57 491h566v-160h-392l-20 -147q26 8 57 12t76 4q67 0 126 -16t103 -49.5t69.5 -85.5t25.5 -125q0 -70 -24.5 -126t-73.5 -95.5t-121 -60.5 t-166 -21q-122 0 -208 44t-138 114z" />
+<glyph horiz-adv-x="913" d="M96 397q0 95 23 180t72 148.5t126.5 101t186.5 37.5q91 0 162 -21.5t131 -66.5l-111 -131q-43 34 -87 51.5t-93 17.5q-47 0 -81 -16t-57 -43t-37 -63.5t-20 -78.5q38 19 92 31t105 12q71 0 128.5 -17t98 -52t62.5 -88t22 -125q0 -71 -25 -126.5t-71.5 -94t-112.5 -58.5 t-149 -20q-181 0 -273 107t-92 315zM305 370q1 -68 11.5 -115t31 -76.5t51 -43t70.5 -13.5q66 0 105.5 35t39.5 113q0 71 -39.5 107t-107.5 36q-43 0 -88.5 -13t-73.5 -30z" />
+<glyph horiz-adv-x="913" d="M78 685v160h729v-129l-363 -723h-233l371 692h-504z" />
+<glyph horiz-adv-x="913" d="M88 229q0 66 43 122t125 93q-143 65 -143 182q0 115 87 176.5t255 61.5q162 0 251 -60t89 -176q0 -113 -150 -186q85 -34 128.5 -84.5t43.5 -128.5q0 -65 -26.5 -112.5t-74 -79t-114 -47t-147.5 -15.5q-178 0 -272.5 64.5t-94.5 189.5zM291 229q0 -48 39.5 -77.5 t124.5 -29.5q84 0 122.5 31.5t38.5 79.5q0 46 -42 78.5t-119 58.5q-76 -23 -120 -56t-44 -85zM309 628q0 -17 6 -32t22.5 -29t45.5 -27.5t74 -28.5q74 20 106.5 47.5t32.5 65.5q0 40 -34 67t-109 27q-39 0 -66 -7.5t-44.5 -20t-25.5 -28.5t-8 -34z" />
+<glyph horiz-adv-x="913" d="M86 567q0 70 25 125t71.5 93t113 58.5t148.5 20.5q181 0 273 -107.5t92 -308.5q0 -98 -22.5 -184t-72 -150t-128 -101.5t-189.5 -37.5q-91 0 -163 22.5t-132 65.5l111 133q84 -72 184 -72q48 0 83 15.5t58 42.5t36.5 64t19.5 79q-40 -20 -91.5 -31.5t-105.5 -11.5 q-71 0 -128.5 17t-98 52.5t-62.5 89t-22 126.5zM289 569q0 -71 40.5 -107.5t108.5 -36.5q45 0 89.5 13.5t72.5 33.5q-1 52 -8.5 96.5t-26 77.5t-49.5 51.5t-78 18.5q-68 0 -108.5 -35t-40.5 -112z" />
+<glyph horiz-adv-x="913" d="M76 961q0 227 92 335t289 108q193 0 286 -108t93 -335t-93 -335.5t-286 -108.5q-197 0 -289 107.5t-92 336.5zM291 961q0 -145 40 -212.5t124 -67.5q85 0 125.5 67.5t40.5 212.5q0 144 -40.5 211.5t-125.5 67.5q-84 0 -124 -67.5t-40 -211.5z" />
+<glyph horiz-adv-x="913" d="M176 1105v129q68 2 114.5 11t77 26.5t48.5 46t30 69.5h162v-852h-207v570h-225z" />
+<glyph horiz-adv-x="913" d="M90 1238q56 77 142.5 122.5t209.5 45.5q156 0 242 -63t86 -185q0 -80 -31 -137t-82 -105q-21 -20 -52 -45.5t-68 -54t-78 -59t-82 -58.5h424v-164h-699v160q50 37 107.5 79t112 84t101 81t75.5 71q31 32 45 63t14 66q0 51 -36 75t-87 24q-59 0 -103 -28.5t-75 -70.5z" />
+<glyph horiz-adv-x="913" d="M72 672l166 89q26 -36 69.5 -61t100.5 -25q41 0 70 9t47 24.5t26 37.5t8 49q0 57 -41 84t-123 27h-102v152h90q90 0 130 26.5t40 77.5q0 40 -33.5 64t-95.5 24q-59 0 -101.5 -22.5t-74.5 -65.5l-158 90q24 32 54.5 60t72 49t96 33t125.5 12q82 0 142.5 -17.5t100.5 -48 t59.5 -71t19.5 -85.5q0 -138 -150 -190q81 -25 122.5 -78t41.5 -129q0 -68 -25 -118.5t-72 -84t-115 -50.5t-154 -17q-57 0 -109 11.5t-95.5 32t-77 49t-54.5 62.5z" />
+<glyph horiz-adv-x="913" d="M43 705v146l494 536h184v-532h121v-150h-121v-170h-195v170h-483zM248 855h278v301z" />
+<glyph horiz-adv-x="913" d="M68 675l170 94q26 -38 70 -64t104 -26q81 0 126.5 37t45.5 106q0 62 -45 92.5t-125 30.5q-50 0 -87 -14.5t-65 -34.5h-131l57 491h566v-160h-392l-20 -147q26 8 57 12t76 4q67 0 126 -16t103 -49.5t69.5 -85.5t25.5 -125q0 -70 -24.5 -126t-73.5 -95.5t-121 -60.5 t-166 -21q-122 0 -208 44t-138 114z" />
+<glyph horiz-adv-x="913" d="M96 939q0 95 23 180t72 148.5t126.5 101t186.5 37.5q91 0 162 -21.5t131 -66.5l-111 -131q-43 34 -87 51.5t-93 17.5q-47 0 -81 -16t-57 -43t-37 -63.5t-20 -78.5q38 19 92 31t105 12q71 0 128.5 -17t98 -52t62.5 -88t22 -125q0 -71 -25 -126.5t-71.5 -94t-112.5 -58.5 t-149 -20q-181 0 -273 107t-92 315zM305 912q1 -68 11.5 -115t31 -76.5t51 -43t70.5 -13.5q66 0 105.5 35t39.5 113q0 71 -39.5 107t-107.5 36q-43 0 -88.5 -13t-73.5 -30z" />
+<glyph horiz-adv-x="913" d="M78 1227v160h729v-129l-363 -723h-233l371 692h-504z" />
+<glyph horiz-adv-x="913" d="M88 771q0 66 43 122t125 93q-143 65 -143 182q0 115 87 176.5t255 61.5q162 0 251 -60t89 -176q0 -113 -150 -186q85 -34 128.5 -84.5t43.5 -128.5q0 -65 -26.5 -112.5t-74 -79t-114 -47t-147.5 -15.5q-178 0 -272.5 64.5t-94.5 189.5zM291 771q0 -48 39.5 -77.5 t124.5 -29.5q84 0 122.5 31.5t38.5 79.5q0 46 -42 78.5t-119 58.5q-76 -23 -120 -56t-44 -85zM309 1170q0 -17 6 -32t22.5 -29t45.5 -27.5t74 -28.5q74 20 106.5 47.5t32.5 65.5q0 40 -34 67t-109 27q-39 0 -66 -7.5t-44.5 -20t-25.5 -28.5t-8 -34z" />
+<glyph horiz-adv-x="913" d="M86 1109q0 70 25 125t71.5 93t113 58.5t148.5 20.5q181 0 273 -107.5t92 -308.5q0 -98 -22.5 -184t-72 -150t-128 -101.5t-189.5 -37.5q-91 0 -163 22.5t-132 65.5l111 133q84 -72 184 -72q48 0 83 15.5t58 42.5t36.5 64t19.5 79q-40 -20 -91.5 -31.5t-105.5 -11.5 q-71 0 -128.5 17t-98 52.5t-62.5 89t-22 126.5zM289 1111q0 -71 40.5 -107.5t108.5 -36.5q45 0 89.5 13.5t72.5 33.5q-1 52 -8.5 96.5t-26 77.5t-49.5 51.5t-78 18.5q-68 0 -108.5 -35t-40.5 -112z" />
+<glyph d="M231 1905h275l184 -361h-174z" />
+<glyph d="M414 1544l184 361h274l-284 -361h-174z" />
+<glyph d="M186 1544l232 361h227l232 -361h-181l-164 205l-167 -205h-179z" />
+<glyph d="M186 1905h181l163 -207l168 207h179l-232 -361h-227z" />
+<glyph d="M494 1128l61 361h242l-162 -361h-141z" />
+<glyph d="M139 1561q3 62 18.5 115t45.5 92t75 61t107 22q39 0 70.5 -10.5t57.5 -26t48.5 -34t43.5 -34t41.5 -26t43.5 -10.5q24 0 39 12t24 31t13 41t6 43h152q-5 -62 -20 -115.5t-44.5 -92.5t-74.5 -61t-109 -22q-44 0 -77 11t-58.5 27t-45.5 35t-39 35t-39 27t-44 11 q-26 0 -41.5 -12t-24.5 -30.5t-12 -42t-4 -46.5h-152z" />
+<glyph d="M195 1661q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM614 1661q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31t-25.5 88z" />
+<glyph d="M211 1591v162h641v-162h-641z" />
+<glyph d="M188 1825h158q14 -56 61.5 -85.5t122.5 -29.5q85 0 130 29.5t59 85.5h158q0 -59 -21.5 -113.5t-64.5 -96.5t-108 -67.5t-153 -25.5q-84 0 -148 25.5t-107 67.5t-65 96.5t-22 113.5z" />
+<glyph d="M330 1694q0 93 48.5 146.5t151.5 53.5q105 0 154 -54t49 -146q0 -96 -50 -148.5t-153 -52.5q-104 0 -152 55t-48 146zM436 1694q0 -45 21.5 -72t72.5 -27t74 25.5t23 73.5q0 49 -25 73.5t-72 24.5q-46 0 -70 -26t-24 -72z" />
+<glyph d="M184 1544l185 361h274l-285 -361h-174zM567 1544l183 361h276l-287 -361h-172z" />
+<glyph d="M403 1665q0 63 28 93t99 30q73 0 102.5 -29t29.5 -94q0 -69 -31 -96t-101 -27q-38 0 -62.5 8t-38.5 24t-20 39t-6 52z" />
+<glyph d="M186 1167l232 289h227l232 -289h-181l-164 152l-167 -152h-179zM737 1389l140 282h274l-240 -282h-174z" />
+<glyph d="M-88 1671h276l138 -282h-172zM186 1167l232 289h227l232 -289h-181l-164 148l-167 -148h-179z" />
+<glyph d="M186 1167l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM659 1640q25 22 73.5 38t113.5 16q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49t-51 -31.5t-62 -14.5v-41h-113v125h33q74 0 74 58q0 53 -72 53q-23 0 -50 -7.5t-48 -21.5z" />
+<glyph d="M139 1509q3 53 18.5 99t45.5 79.5t75 52.5t107 19q48 0 89 -15.5t77.5 -34.5t70 -34.5t68.5 -15.5q44 0 61.5 24t20.5 62h152q-5 -54 -20 -99.5t-44.5 -79t-74.5 -52.5t-109 -19q-37 0 -67.5 7.5t-56 19.5t-47.5 25t-43 25t-43 19.5t-46 7.5q-45 0 -62 -24t-20 -66h-152z M186 1167l232 279h227l232 -279h-181l-164 142l-167 -142h-179z" />
+<glyph d="M188 1503h158q14 -62 61.5 -89.5t122.5 -27.5q85 0 130 27.5t59 89.5h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5zM430 1470l113 263h276l-221 -263h-168z" />
+<glyph d="M188 1503h158q14 -62 61.5 -89.5t122.5 -27.5q85 0 130 27.5t59 89.5h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5zM246 1733h274l115 -263h-168z" />
+<glyph d="M188 1503h158q14 -62 61.5 -89.5t122.5 -27.5q85 0 130 27.5t59 89.5h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5zM344 1778q25 21 73 37t113 16q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49t-51.5 -31 t-63.5 -14v-41h-110v125h33q73 0 73 57q0 53 -71 53q-23 0 -50 -7.5t-49 -21.5z" />
+<glyph d="M139 1567q3 53 18.5 98.5t45.5 79.5t75 53t107 19q48 0 89 -16t77.5 -34.5t70 -34.5t68.5 -16q44 0 61.5 24t20.5 62h152q-5 -54 -20 -99.5t-44.5 -79t-74.5 -52.5t-109 -19q-56 0 -96.5 16.5t-74.5 36t-64.5 36t-67.5 16.5q-45 0 -62 -24t-20 -66h-152zM188 1499h158 q14 -63 61.5 -91t122.5 -28q85 0 130 28t59 91h158q0 -59 -21.5 -112t-64.5 -93t-108 -64t-153 -24q-84 0 -148 24t-107 64t-65 93t-22 112z" />
+<glyph d="M197 1288q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM211 1479v161h641v-161h-641zM616 1288q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8 t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph d="M197 1288q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM432 1432l123 301h276l-231 -301h-168zM616 1288q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5 q-36 0 -59.5 8t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph d="M186 1733h181l163 -156l168 156h179l-232 -291h-227zM197 1288q0 62 27 89.5t95 27.5q71 0 99 -27t28 -90q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM616 1288q0 62 27.5 89.5t95.5 27.5q71 0 99 -27t28 -90q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31 t-25.5 88z" />
+<glyph d="M197 1288q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM229 1733h275l123 -301h-168zM616 1288q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8 t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph d="M186 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM737 1724l140 283h274l-240 -283h-174z" />
+<glyph d="M-88 2007h276l138 -283h-172zM186 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179z" />
+<glyph d="M186 1503l232 289h227l232 -289h-181l-164 148l-167 -148h-179zM659 1976q25 22 73.5 38t113.5 16q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49t-51 -31.5t-62 -14.5v-41h-113v125h33q74 0 74 58q0 53 -72 53q-23 0 -50 -7.5t-48 -21.5z" />
+<glyph d="M139 1835q3 53 18.5 98.5t45.5 79.5t75 53t107 19q48 0 89 -15.5t77.5 -34.5t70 -34.5t68.5 -15.5q44 0 61.5 23.5t20.5 62.5h152q-5 -54 -20 -100t-44.5 -79t-74.5 -52t-109 -19q-37 0 -67.5 7.5t-56 19.5t-47.5 25t-43 25t-43 19.5t-46 7.5q-45 0 -62 -24t-20 -66h-152 zM186 1503l232 269h227l232 -269h-181l-164 131l-167 -131h-179z" />
+<glyph d="M188 1808h158q14 -62 61.5 -89t122.5 -27q85 0 130 27t59 89h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5zM430 1776l113 262h276l-221 -262h-168z" />
+<glyph d="M188 1808h158q14 -62 61.5 -89t122.5 -27q85 0 130 27t59 89h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5zM246 2038h274l115 -262h-168z" />
+<glyph d="M188 1808h158q14 -62 61.5 -89t122.5 -27q85 0 130 27t59 89h158q0 -58 -21.5 -111.5t-64.5 -95t-108 -66t-153 -24.5q-84 0 -148 24.5t-107 66t-65 95t-22 111.5zM344 2083q25 21 73 37t113 16q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51.5 -31 t-63.5 -14v-41h-110v125h33q73 0 73 57q0 53 -71 53q-23 0 -50 -7t-49 -21z" />
+<glyph d="M139 1872q3 53 18.5 98.5t45.5 79.5t75 53t107 19q48 0 89 -16t77.5 -34.5t70 -34.5t68.5 -16q44 0 61.5 24t20.5 62h152q-5 -54 -20 -99.5t-44.5 -78.5t-74.5 -52t-109 -19q-37 0 -67.5 7.5t-56 19.5t-47.5 25t-43 25t-43 19.5t-46 7.5q-45 0 -62 -24t-20 -66h-152z M188 1804h158q14 -63 61.5 -90.5t122.5 -27.5q85 0 130 27.5t59 90.5h158q0 -58 -21.5 -111t-64.5 -93.5t-108 -64.5t-153 -24q-84 0 -148 24t-107 64.5t-65 93.5t-22 111z" />
+<glyph d="M197 1624q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM211 1815v161h641v-161h-641zM616 1624q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8 t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph d="M197 1624q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM432 1767l123 301h276l-231 -301h-168zM616 1624q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5 q-36 0 -59.5 8t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph d="M186 2068h181l163 -155l168 155h179l-232 -290h-227zM197 1624q0 62 27 89.5t95 27.5q71 0 99 -27t28 -90q0 -66 -30 -92.5t-97 -26.5q-72 0 -97 31t-25 88zM616 1624q0 62 27.5 89.5t95.5 27.5q71 0 99 -27t28 -90q0 -66 -30.5 -92.5t-96.5 -26.5q-72 0 -97.5 31 t-25.5 88z" />
+<glyph d="M197 1624q0 62 27 90.5t95 28.5q71 0 99 -28t28 -91q0 -66 -30 -92.5t-97 -26.5q-36 0 -59.5 8t-37.5 23.5t-19.5 37.5t-5.5 50zM229 2068h275l123 -301h-168zM616 1624q0 62 27.5 90.5t95.5 28.5q71 0 99 -28t28 -91q0 -66 -30.5 -92.5t-96.5 -26.5q-36 0 -59.5 8 t-38 23.5t-20 37.5t-5.5 50z" />
+<glyph d="M338 1462q25 20 73 37t113 17q96 0 148.5 -42t52.5 -110q0 -38 -12.5 -67t-34.5 -49.5t-51 -32t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph d="M338 1798q25 20 73 36.5t113 16.5q96 0 148.5 -41.5t52.5 -109.5q0 -39 -12.5 -68t-34.5 -49t-51 -31.5t-62 -15.5v-39h-112v125h32q74 0 74 57q0 54 -72 54q-23 0 -49.5 -7.5t-48.5 -21.5z" />
+<glyph d="M188 1454h211q7 -77 37.5 -113t93.5 -36q70 0 100.5 35.5t37.5 113.5h209q0 -55 -22 -103.5t-65.5 -84.5t-108.5 -57t-151 -21q-84 0 -148 21.5t-107 58t-65 84.5t-22 102z" />
+<glyph d="M188 1788h209q7 -77 38.5 -113.5t94.5 -36.5q69 0 100 35.5t36 114.5h211q0 -56 -22 -104.5t-66 -84.5t-109 -56.5t-150 -20.5q-87 0 -151 21.5t-106.5 58t-63.5 84.5t-21 102z" />
+<hkern u1="&#x28;" u2="&#x458;" k="-70" />
+<hkern u1="&#x28;" u2="&#x3ca;" k="-45" />
+<hkern u1="&#x28;" u2="&#x390;" k="-70" />
<hkern u1="&#x28;" u2="j" k="-70" />
+<hkern u1="&#x2a;" u2="&#x2206;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1eb6;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1eb4;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1eb2;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1eb0;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1eae;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1eac;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1eaa;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1ea8;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1ea6;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1ea4;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1ea2;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1ea0;" k="70" />
+<hkern u1="&#x2a;" u2="&#x459;" k="78" />
+<hkern u1="&#x2a;" u2="&#x457;" k="-40" />
+<hkern u1="&#x2a;" u2="&#x44a;" k="-15" />
+<hkern u1="&#x2a;" u2="&#x442;" k="-30" />
+<hkern u1="&#x2a;" u2="&#x43b;" k="78" />
+<hkern u1="&#x2a;" u2="&#x42a;" k="-15" />
+<hkern u1="&#x2a;" u2="&#x422;" k="-37" />
+<hkern u1="&#x2a;" u2="&#x41b;" k="95" />
+<hkern u1="&#x2a;" u2="&#x414;" k="45" />
+<hkern u1="&#x2a;" u2="&#x410;" k="70" />
+<hkern u1="&#x2a;" u2="&#x40b;" k="-15" />
+<hkern u1="&#x2a;" u2="&#x409;" k="95" />
+<hkern u1="&#x2a;" u2="&#x408;" k="98" />
+<hkern u1="&#x2a;" u2="&#x402;" k="-15" />
+<hkern u1="&#x2a;" u2="&#x3ca;" k="-55" />
+<hkern u1="&#x2a;" u2="&#x3c7;" k="-20" />
+<hkern u1="&#x2a;" u2="&#x3be;" k="-15" />
+<hkern u1="&#x2a;" u2="&#x3a4;" k="-37" />
+<hkern u1="&#x2a;" u2="&#x39b;" k="70" />
+<hkern u1="&#x2a;" u2="&#x394;" k="70" />
+<hkern u1="&#x2a;" u2="&#x391;" k="70" />
+<hkern u1="&#x2a;" u2="&#x38f;" k="-145" />
+<hkern u1="&#x2a;" u2="&#x38e;" k="-145" />
+<hkern u1="&#x2a;" u2="&#x38c;" k="-145" />
+<hkern u1="&#x2a;" u2="&#x38a;" k="-145" />
+<hkern u1="&#x2a;" u2="&#x389;" k="-145" />
+<hkern u1="&#x2a;" u2="&#x388;" k="-145" />
+<hkern u1="&#x2a;" u2="&#x386;" k="-95" />
+<hkern u1="&#x2a;" u2="&#x21a;" k="-37" />
+<hkern u1="&#x2a;" u2="&#x1fa;" k="70" />
+<hkern u1="&#x2a;" u2="&#x1cd;" k="70" />
+<hkern u1="&#x2a;" u2="&#x166;" k="-37" />
+<hkern u1="&#x2a;" u2="&#x164;" k="-37" />
+<hkern u1="&#x2a;" u2="&#x162;" k="-37" />
+<hkern u1="&#x2a;" u2="&#x134;" k="98" />
+<hkern u1="&#x2a;" u2="&#x104;" k="70" />
+<hkern u1="&#x2a;" u2="&#x102;" k="70" />
+<hkern u1="&#x2a;" u2="&#x100;" k="70" />
<hkern u1="&#x2a;" u2="&#xef;" k="-15" />
<hkern u1="&#x2a;" u2="&#xc5;" k="70" />
<hkern u1="&#x2a;" u2="&#xc4;" k="70" />
@@ -253,15 +966,54 @@
<hkern u1="&#x2a;" u2="T" k="-37" />
<hkern u1="&#x2a;" u2="J" k="98" />
<hkern u1="&#x2a;" u2="A" k="70" />
+<hkern u1="&#x2c;" u2="&#x42a;" k="85" />
+<hkern u1="&#x2e;" u2="&#x42a;" k="85" />
+<hkern u1="&#x3a;" u2="&#x42a;" k="70" />
+<hkern u1="&#x3b;" u2="&#x42a;" k="70" />
<hkern u1="A" u2="&#x3f;" k="45" />
<hkern u1="A" u2="&#x2a;" k="70" />
+<hkern u1="F" u2="&#x135;" k="-15" />
+<hkern u1="F" u2="&#x12b;" k="-20" />
+<hkern u1="F" u2="&#x129;" k="-50" />
<hkern u1="F" u2="&#xef;" k="-25" />
<hkern u1="F" u2="&#xee;" k="-10" />
+<hkern u1="K" u2="&#x135;" k="15" />
+<hkern u1="K" u2="&#x12d;" k="8" />
+<hkern u1="K" u2="&#x129;" k="-20" />
<hkern u1="K" u2="&#xef;" k="-5" />
<hkern u1="K" u2="&#xee;" k="8" />
<hkern u1="L" u2="&#xd8;" k="8" />
<hkern u1="L" u2="&#x3f;" k="50" />
<hkern u1="L" u2="&#x2a;" k="120" />
+<hkern u1="T" u2="&#x1ef9;" k="30" />
+<hkern u1="T" u2="&#x1ee1;" k="60" />
+<hkern u1="T" u2="&#x1ed7;" k="80" />
+<hkern u1="T" u2="&#x1ed3;" k="60" />
+<hkern u1="T" u2="&#x1ec5;" k="83" />
+<hkern u1="T" u2="&#x1ec1;" k="65" />
+<hkern u1="T" u2="&#x1ebd;" k="55" />
+<hkern u1="T" u2="&#x1eb7;" k="70" />
+<hkern u1="T" u2="&#x1eb5;" k="65" />
+<hkern u1="T" u2="&#x1eb3;" k="70" />
+<hkern u1="T" u2="&#x1eb1;" k="70" />
+<hkern u1="T" u2="&#x1eaf;" k="65" />
+<hkern u1="T" u2="&#x1ead;" k="55" />
+<hkern u1="T" u2="&#x1eab;" k="60" />
+<hkern u1="T" u2="&#x1ea9;" k="70" />
+<hkern u1="T" u2="&#x1ea7;" k="50" />
+<hkern u1="T" u2="&#x1ea5;" k="68" />
+<hkern u1="T" u2="&#x1e9e;" k="25" />
+<hkern u1="T" u2="&#x1d6;" k="65" />
+<hkern u1="T" u2="&#x1d0;" k="5" />
+<hkern u1="T" u2="&#x161;" k="108" />
+<hkern u1="T" u2="&#x15d;" k="83" />
+<hkern u1="T" u2="&#x159;" k="75" />
+<hkern u1="T" u2="&#x135;" k="-30" />
+<hkern u1="T" u2="&#x12d;" k="-30" />
+<hkern u1="T" u2="&#x12b;" k="-40" />
+<hkern u1="T" u2="&#x129;" k="-65" />
+<hkern u1="T" u2="&#x103;" k="90" />
+<hkern u1="T" u2="&#x101;" k="80" />
<hkern u1="T" u2="&#xef;" k="-55" />
<hkern u1="T" u2="&#xee;" k="-30" />
<hkern u1="T" u2="&#xe4;" k="70" />
@@ -269,32 +1021,115 @@
<hkern u1="T" u2="&#xe2;" k="75" />
<hkern u1="T" u2="&#x3f;" k="-15" />
<hkern u1="T" u2="&#x2a;" k="-37" />
+<hkern u1="V" u2="&#x1e9e;" k="10" />
+<hkern u1="V" u2="&#x135;" k="-10" />
+<hkern u1="V" u2="&#x12d;" k="-12" />
+<hkern u1="V" u2="&#x12b;" k="-22" />
+<hkern u1="V" u2="&#x129;" k="-52" />
+<hkern u1="V" u2="&#x127;" k="10" />
<hkern u1="V" u2="&#xef;" k="-32" />
<hkern u1="V" u2="&#xee;" k="-12" />
+<hkern u1="W" u2="&#x1e9e;" k="10" />
+<hkern u1="W" u2="&#x135;" k="-10" />
+<hkern u1="W" u2="&#x12d;" k="-12" />
+<hkern u1="W" u2="&#x12b;" k="-22" />
+<hkern u1="W" u2="&#x129;" k="-52" />
+<hkern u1="W" u2="&#x127;" k="10" />
<hkern u1="W" u2="&#xef;" k="-32" />
<hkern u1="W" u2="&#xee;" k="-12" />
+<hkern u1="X" u2="&#x1e9e;" k="15" />
+<hkern u1="X" u2="&#x1d0;" k="-10" />
+<hkern u1="X" u2="&#x12d;" k="-25" />
+<hkern u1="X" u2="&#x12b;" k="-20" />
+<hkern u1="X" u2="&#x129;" k="-40" />
<hkern u1="X" u2="&#xef;" k="-35" />
<hkern u1="X" u2="&#xee;" k="-20" />
+<hkern u1="Y" u2="&#x1ed3;" k="60" />
+<hkern u1="Y" u2="&#x1ebd;" k="60" />
+<hkern u1="Y" u2="&#x1ea7;" k="40" />
+<hkern u1="Y" u2="&#x1e9e;" k="30" />
+<hkern u1="Y" u2="&#x1d0;" k="10" />
+<hkern u1="Y" u2="&#x135;" k="8" />
+<hkern u1="Y" u2="&#x12d;" k="-15" />
+<hkern u1="Y" u2="&#x12b;" k="-30" />
+<hkern u1="Y" u2="&#x129;" k="-50" />
<hkern u1="Y" u2="&#xef;" k="-40" />
<hkern u1="Y" u2="&#xee;" k="-17" />
+<hkern u1="[" u2="&#x458;" k="-70" />
+<hkern u1="[" u2="&#x3ca;" k="-45" />
+<hkern u1="[" u2="&#x390;" k="-80" />
<hkern u1="[" u2="j" k="-70" />
+<hkern u1="a" u2="&#x167;" k="3" />
+<hkern u1="f" u2="&#x1ef9;" k="-5" />
+<hkern u1="f" u2="&#x1ed3;" k="-15" />
+<hkern u1="f" u2="&#x1ec9;" k="-12" />
+<hkern u1="f" u2="&#x1ec1;" k="-12" />
+<hkern u1="f" u2="&#x1eb5;" k="-10" />
+<hkern u1="f" u2="&#x1eb3;" k="-10" />
+<hkern u1="f" u2="&#x1eb1;" k="-10" />
+<hkern u1="f" u2="&#x1eaf;" k="-10" />
+<hkern u1="f" u2="&#x1eab;" k="-12" />
+<hkern u1="f" u2="&#x1ea7;" k="-42" />
+<hkern u1="f" u2="&#x1d0;" k="-85" />
+<hkern u1="f" u2="&#x159;" k="-10" />
+<hkern u1="f" u2="&#x135;" k="-55" />
+<hkern u1="f" u2="&#x12d;" k="-90" />
+<hkern u1="f" u2="&#x12b;" k="-75" />
+<hkern u1="f" u2="&#x129;" k="-115" />
+<hkern u1="f" u2="&#x127;" k="-40" />
<hkern u1="f" u2="&#xef;" k="-85" />
<hkern u1="f" u2="&#xee;" k="-50" />
<hkern u1="f" u2="&#xec;" k="-40" />
<hkern u1="f" u2="&#x3f;" k="-50" />
<hkern u1="f" u2="&#x2a;" k="-55" />
<hkern u1="f" u2="&#x21;" k="-30" />
+<hkern u1="j" u2="&#x1ef9;" k="-17" />
+<hkern u1="j" u2="&#x1ef7;" k="-17" />
+<hkern u1="j" u2="&#x1ef5;" k="-17" />
+<hkern u1="j" u2="&#x1ef3;" k="-17" />
+<hkern u1="j" u2="&#x177;" k="-17" />
<hkern u1="j" u2="&#xff;" k="-17" />
<hkern u1="j" u2="&#xfd;" k="-17" />
<hkern u1="j" u2="y" k="-17" />
+<hkern u1="&#x7b;" u2="&#x458;" k="-70" />
+<hkern u1="&#x7b;" u2="&#x3ca;" k="-45" />
+<hkern u1="&#x7b;" u2="&#x390;" k="-70" />
<hkern u1="&#x7b;" u2="j" k="-70" />
+<hkern u1="&#xa1;" u2="&#x1ef8;" k="53" />
+<hkern u1="&#xa1;" u2="&#x1ef6;" k="53" />
+<hkern u1="&#xa1;" u2="&#x1ef4;" k="53" />
+<hkern u1="&#xa1;" u2="&#x1ef2;" k="53" />
+<hkern u1="&#xa1;" u2="&#x1e84;" k="30" />
+<hkern u1="&#xa1;" u2="&#x1e82;" k="30" />
+<hkern u1="&#xa1;" u2="&#x1e80;" k="30" />
+<hkern u1="&#xa1;" u2="&#x21a;" k="35" />
<hkern u1="&#xa1;" u2="&#x178;" k="53" />
+<hkern u1="&#xa1;" u2="&#x176;" k="53" />
+<hkern u1="&#xa1;" u2="&#x174;" k="30" />
+<hkern u1="&#xa1;" u2="&#x166;" k="35" />
+<hkern u1="&#xa1;" u2="&#x164;" k="35" />
+<hkern u1="&#xa1;" u2="&#x162;" k="35" />
<hkern u1="&#xa1;" u2="&#xdd;" k="53" />
<hkern u1="&#xa1;" u2="Y" k="53" />
<hkern u1="&#xa1;" u2="W" k="30" />
<hkern u1="&#xa1;" u2="V" k="30" />
<hkern u1="&#xa1;" u2="T" k="35" />
+<hkern u1="&#xab;" u2="&#x386;" k="-85" />
+<hkern u1="&#xb5;" u2="&#x3c7;" k="13" />
+<hkern u1="&#xbf;" u2="&#x1ef8;" k="98" />
+<hkern u1="&#xbf;" u2="&#x1ef6;" k="98" />
+<hkern u1="&#xbf;" u2="&#x1ef4;" k="98" />
+<hkern u1="&#xbf;" u2="&#x1ef2;" k="98" />
+<hkern u1="&#xbf;" u2="&#x1e84;" k="60" />
+<hkern u1="&#xbf;" u2="&#x1e82;" k="60" />
+<hkern u1="&#xbf;" u2="&#x1e80;" k="60" />
+<hkern u1="&#xbf;" u2="&#x21a;" k="80" />
<hkern u1="&#xbf;" u2="&#x178;" k="98" />
+<hkern u1="&#xbf;" u2="&#x176;" k="98" />
+<hkern u1="&#xbf;" u2="&#x174;" k="60" />
+<hkern u1="&#xbf;" u2="&#x166;" k="80" />
+<hkern u1="&#xbf;" u2="&#x164;" k="80" />
+<hkern u1="&#xbf;" u2="&#x162;" k="80" />
<hkern u1="&#xbf;" u2="&#xdd;" k="98" />
<hkern u1="&#xbf;" u2="Y" k="98" />
<hkern u1="&#xbf;" u2="W" k="60" />
@@ -312,360 +1147,1755 @@
<hkern u1="&#xc4;" u2="&#x2a;" k="70" />
<hkern u1="&#xc5;" u2="&#x3f;" k="45" />
<hkern u1="&#xc5;" u2="&#x2a;" k="70" />
+<hkern u1="&#xdd;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#xdd;" u2="&#x1ebd;" k="60" />
+<hkern u1="&#xdd;" u2="&#x1ea7;" k="40" />
+<hkern u1="&#xdd;" u2="&#x1e9e;" k="30" />
+<hkern u1="&#xdd;" u2="&#x1d0;" k="10" />
+<hkern u1="&#xdd;" u2="&#x135;" k="8" />
+<hkern u1="&#xdd;" u2="&#x12d;" k="-15" />
+<hkern u1="&#xdd;" u2="&#x12b;" k="-30" />
+<hkern u1="&#xdd;" u2="&#x129;" k="-50" />
<hkern u1="&#xdd;" u2="&#xef;" k="-40" />
<hkern u1="&#xdd;" u2="&#xee;" k="-17" />
+<hkern u1="&#xde;" u2="&#x1e84;" k="5" />
+<hkern u1="&#xde;" u2="&#x1e82;" k="5" />
+<hkern u1="&#xde;" u2="&#x1e80;" k="5" />
+<hkern u1="&#xde;" u2="&#x21a;" k="25" />
+<hkern u1="&#xde;" u2="&#x174;" k="5" />
+<hkern u1="&#xde;" u2="&#x166;" k="25" />
+<hkern u1="&#xde;" u2="&#x164;" k="25" />
+<hkern u1="&#xde;" u2="&#x162;" k="25" />
<hkern u1="&#xde;" u2="X" k="40" />
<hkern u1="&#xde;" u2="W" k="5" />
<hkern u1="&#xde;" u2="V" k="5" />
<hkern u1="&#xde;" u2="T" k="25" />
+<hkern u1="&#xe0;" u2="&#x167;" k="3" />
+<hkern u1="&#xe1;" u2="&#x167;" k="3" />
+<hkern u1="&#xe2;" u2="&#x167;" k="3" />
+<hkern u1="&#xe3;" u2="&#x167;" k="3" />
+<hkern u1="&#xe4;" u2="&#x167;" k="3" />
+<hkern u1="&#xe5;" u2="&#x167;" k="3" />
<hkern u1="&#xef;" u2="&#xef;" k="-45" />
<hkern u1="&#xef;" u2="&#x2a;" k="-15" />
+<hkern u1="&#x100;" u2="&#x3f;" k="45" />
+<hkern u1="&#x100;" u2="&#x2a;" k="70" />
+<hkern u1="&#x101;" u2="&#x167;" k="3" />
+<hkern u1="&#x102;" u2="&#x3f;" k="45" />
+<hkern u1="&#x102;" u2="&#x2a;" k="70" />
+<hkern u1="&#x103;" u2="&#x167;" k="3" />
+<hkern u1="&#x104;" u2="&#x3f;" k="45" />
+<hkern u1="&#x104;" u2="&#x2a;" k="70" />
+<hkern u1="&#x105;" u2="&#x167;" k="3" />
+<hkern u1="&#x10f;" u2="&#x159;" k="-20" />
+<hkern u1="&#x10f;" u2="&#x12b;" k="-90" />
+<hkern u1="&#x10f;" u2="&#xef;" k="-96" />
+<hkern u1="&#x10f;" u2="&#xee;" k="-61" />
+<hkern u1="&#x10f;" u2="&#xec;" k="-65" />
+<hkern u1="&#x10f;" u2="&#xe3;" k="28" />
+<hkern u1="&#x10f;" u2="&#x3f;" k="-45" />
+<hkern u1="&#x136;" u2="&#x135;" k="15" />
+<hkern u1="&#x136;" u2="&#x12d;" k="8" />
+<hkern u1="&#x136;" u2="&#x129;" k="-20" />
+<hkern u1="&#x136;" u2="&#xef;" k="-5" />
+<hkern u1="&#x136;" u2="&#xee;" k="8" />
+<hkern u1="&#x139;" u2="&#xd8;" k="8" />
+<hkern u1="&#x139;" u2="&#x3f;" k="50" />
+<hkern u1="&#x139;" u2="&#x2a;" k="120" />
+<hkern u1="&#x13b;" u2="&#xd8;" k="8" />
+<hkern u1="&#x13b;" u2="&#x3f;" k="50" />
+<hkern u1="&#x13b;" u2="&#x2a;" k="120" />
+<hkern u1="&#x13d;" u2="&#xd8;" k="8" />
+<hkern u1="&#x13d;" u2="&#x3f;" k="50" />
+<hkern u1="&#x13d;" u2="&#x2a;" k="120" />
+<hkern u1="&#x13e;" u2="&#x159;" k="-20" />
+<hkern u1="&#x13e;" u2="&#x12b;" k="-90" />
+<hkern u1="&#x13e;" u2="&#xef;" k="-100" />
+<hkern u1="&#x13e;" u2="&#xee;" k="-73" />
+<hkern u1="&#x13e;" u2="&#xec;" k="-65" />
+<hkern u1="&#x13e;" u2="&#xe3;" k="28" />
+<hkern u1="&#x13e;" u2="&#x3f;" k="-45" />
+<hkern u1="&#x141;" u2="&#xd8;" k="8" />
+<hkern u1="&#x141;" u2="&#x3f;" k="50" />
+<hkern u1="&#x141;" u2="&#x2a;" k="120" />
+<hkern u1="&#x142;" u2="&#x21b;" k="-12" />
+<hkern u1="&#x142;" u2="&#x167;" k="-12" />
+<hkern u1="&#x142;" u2="&#x165;" k="-12" />
+<hkern u1="&#x142;" u2="&#x163;" k="-12" />
+<hkern u1="&#x142;" u2="t" k="-12" />
+<hkern u1="&#x162;" u2="&#x1ef9;" k="30" />
+<hkern u1="&#x162;" u2="&#x1ee1;" k="60" />
+<hkern u1="&#x162;" u2="&#x1ed7;" k="80" />
+<hkern u1="&#x162;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x162;" u2="&#x1ec5;" k="83" />
+<hkern u1="&#x162;" u2="&#x1ec1;" k="65" />
+<hkern u1="&#x162;" u2="&#x1ebd;" k="55" />
+<hkern u1="&#x162;" u2="&#x1eb7;" k="70" />
+<hkern u1="&#x162;" u2="&#x1eb5;" k="65" />
+<hkern u1="&#x162;" u2="&#x1eb3;" k="70" />
+<hkern u1="&#x162;" u2="&#x1eb1;" k="70" />
+<hkern u1="&#x162;" u2="&#x1eaf;" k="65" />
+<hkern u1="&#x162;" u2="&#x1ead;" k="55" />
+<hkern u1="&#x162;" u2="&#x1eab;" k="60" />
+<hkern u1="&#x162;" u2="&#x1ea9;" k="70" />
+<hkern u1="&#x162;" u2="&#x1ea7;" k="50" />
+<hkern u1="&#x162;" u2="&#x1ea5;" k="68" />
+<hkern u1="&#x162;" u2="&#x1e9e;" k="25" />
+<hkern u1="&#x162;" u2="&#x1d6;" k="65" />
+<hkern u1="&#x162;" u2="&#x1d0;" k="5" />
+<hkern u1="&#x162;" u2="&#x161;" k="108" />
+<hkern u1="&#x162;" u2="&#x15d;" k="83" />
+<hkern u1="&#x162;" u2="&#x159;" k="75" />
+<hkern u1="&#x162;" u2="&#x135;" k="-30" />
+<hkern u1="&#x162;" u2="&#x12d;" k="-30" />
+<hkern u1="&#x162;" u2="&#x12b;" k="-40" />
+<hkern u1="&#x162;" u2="&#x129;" k="-65" />
+<hkern u1="&#x162;" u2="&#x103;" k="90" />
+<hkern u1="&#x162;" u2="&#x101;" k="80" />
+<hkern u1="&#x162;" u2="&#xef;" k="-55" />
+<hkern u1="&#x162;" u2="&#xee;" k="-30" />
+<hkern u1="&#x162;" u2="&#xe4;" k="70" />
+<hkern u1="&#x162;" u2="&#xe3;" k="55" />
+<hkern u1="&#x162;" u2="&#xe2;" k="75" />
+<hkern u1="&#x162;" u2="&#x3f;" k="-15" />
+<hkern u1="&#x162;" u2="&#x2a;" k="-37" />
+<hkern u1="&#x164;" u2="&#x1ef9;" k="30" />
+<hkern u1="&#x164;" u2="&#x1ee1;" k="60" />
+<hkern u1="&#x164;" u2="&#x1ed7;" k="80" />
+<hkern u1="&#x164;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x164;" u2="&#x1ec5;" k="83" />
+<hkern u1="&#x164;" u2="&#x1ec1;" k="65" />
+<hkern u1="&#x164;" u2="&#x1ebd;" k="55" />
+<hkern u1="&#x164;" u2="&#x1eb7;" k="70" />
+<hkern u1="&#x164;" u2="&#x1eb5;" k="65" />
+<hkern u1="&#x164;" u2="&#x1eb3;" k="70" />
+<hkern u1="&#x164;" u2="&#x1eb1;" k="70" />
+<hkern u1="&#x164;" u2="&#x1eaf;" k="65" />
+<hkern u1="&#x164;" u2="&#x1ead;" k="55" />
+<hkern u1="&#x164;" u2="&#x1eab;" k="60" />
+<hkern u1="&#x164;" u2="&#x1ea9;" k="70" />
+<hkern u1="&#x164;" u2="&#x1ea7;" k="50" />
+<hkern u1="&#x164;" u2="&#x1ea5;" k="68" />
+<hkern u1="&#x164;" u2="&#x1e9e;" k="25" />
+<hkern u1="&#x164;" u2="&#x1d6;" k="65" />
+<hkern u1="&#x164;" u2="&#x1d0;" k="5" />
+<hkern u1="&#x164;" u2="&#x161;" k="108" />
+<hkern u1="&#x164;" u2="&#x15d;" k="83" />
+<hkern u1="&#x164;" u2="&#x159;" k="75" />
+<hkern u1="&#x164;" u2="&#x135;" k="-30" />
+<hkern u1="&#x164;" u2="&#x12d;" k="-30" />
+<hkern u1="&#x164;" u2="&#x12b;" k="-40" />
+<hkern u1="&#x164;" u2="&#x129;" k="-65" />
+<hkern u1="&#x164;" u2="&#x103;" k="90" />
+<hkern u1="&#x164;" u2="&#x101;" k="80" />
+<hkern u1="&#x164;" u2="&#xef;" k="-55" />
+<hkern u1="&#x164;" u2="&#xee;" k="-30" />
+<hkern u1="&#x164;" u2="&#xe4;" k="70" />
+<hkern u1="&#x164;" u2="&#xe3;" k="55" />
+<hkern u1="&#x164;" u2="&#xe2;" k="75" />
+<hkern u1="&#x164;" u2="&#x3f;" k="-15" />
+<hkern u1="&#x164;" u2="&#x2a;" k="-37" />
+<hkern u1="&#x165;" u2="&#x12b;" k="-61" />
+<hkern u1="&#x165;" u2="&#xef;" k="-75" />
+<hkern u1="&#x165;" u2="&#xee;" k="-40" />
+<hkern u1="&#x165;" u2="&#xec;" k="-25" />
+<hkern u1="&#x166;" u2="&#x1ef9;" k="30" />
+<hkern u1="&#x166;" u2="&#x1ee1;" k="60" />
+<hkern u1="&#x166;" u2="&#x1ed7;" k="80" />
+<hkern u1="&#x166;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x166;" u2="&#x1ec5;" k="83" />
+<hkern u1="&#x166;" u2="&#x1ec1;" k="65" />
+<hkern u1="&#x166;" u2="&#x1ebd;" k="55" />
+<hkern u1="&#x166;" u2="&#x1eb7;" k="70" />
+<hkern u1="&#x166;" u2="&#x1eb5;" k="65" />
+<hkern u1="&#x166;" u2="&#x1eb3;" k="70" />
+<hkern u1="&#x166;" u2="&#x1eb1;" k="70" />
+<hkern u1="&#x166;" u2="&#x1eaf;" k="65" />
+<hkern u1="&#x166;" u2="&#x1ead;" k="55" />
+<hkern u1="&#x166;" u2="&#x1eab;" k="60" />
+<hkern u1="&#x166;" u2="&#x1ea9;" k="70" />
+<hkern u1="&#x166;" u2="&#x1ea7;" k="50" />
+<hkern u1="&#x166;" u2="&#x1ea5;" k="68" />
+<hkern u1="&#x166;" u2="&#x1e9e;" k="25" />
+<hkern u1="&#x166;" u2="&#x1d6;" k="65" />
+<hkern u1="&#x166;" u2="&#x1d0;" k="5" />
+<hkern u1="&#x166;" u2="&#x161;" k="108" />
+<hkern u1="&#x166;" u2="&#x15d;" k="83" />
+<hkern u1="&#x166;" u2="&#x159;" k="75" />
+<hkern u1="&#x166;" u2="&#x135;" k="-30" />
+<hkern u1="&#x166;" u2="&#x12d;" k="-30" />
+<hkern u1="&#x166;" u2="&#x12b;" k="-40" />
+<hkern u1="&#x166;" u2="&#x129;" k="-65" />
+<hkern u1="&#x166;" u2="&#x103;" k="90" />
+<hkern u1="&#x166;" u2="&#x101;" k="80" />
+<hkern u1="&#x166;" u2="&#xef;" k="-55" />
+<hkern u1="&#x166;" u2="&#xee;" k="-30" />
+<hkern u1="&#x166;" u2="&#xe4;" k="70" />
+<hkern u1="&#x166;" u2="&#xe3;" k="55" />
+<hkern u1="&#x166;" u2="&#xe2;" k="75" />
+<hkern u1="&#x166;" u2="&#x3f;" k="-15" />
+<hkern u1="&#x166;" u2="&#x2a;" k="-37" />
+<hkern u1="&#x174;" u2="&#x1e9e;" k="10" />
+<hkern u1="&#x174;" u2="&#x135;" k="-10" />
+<hkern u1="&#x174;" u2="&#x12d;" k="-12" />
+<hkern u1="&#x174;" u2="&#x12b;" k="-22" />
+<hkern u1="&#x174;" u2="&#x129;" k="-52" />
+<hkern u1="&#x174;" u2="&#x127;" k="10" />
+<hkern u1="&#x174;" u2="&#xef;" k="-32" />
+<hkern u1="&#x174;" u2="&#xee;" k="-12" />
+<hkern u1="&#x176;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x176;" u2="&#x1ebd;" k="60" />
+<hkern u1="&#x176;" u2="&#x1ea7;" k="40" />
+<hkern u1="&#x176;" u2="&#x1e9e;" k="30" />
+<hkern u1="&#x176;" u2="&#x1d0;" k="10" />
+<hkern u1="&#x176;" u2="&#x135;" k="8" />
+<hkern u1="&#x176;" u2="&#x12d;" k="-15" />
+<hkern u1="&#x176;" u2="&#x12b;" k="-30" />
+<hkern u1="&#x176;" u2="&#x129;" k="-50" />
+<hkern u1="&#x176;" u2="&#xef;" k="-40" />
+<hkern u1="&#x176;" u2="&#xee;" k="-17" />
+<hkern u1="&#x178;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x178;" u2="&#x1ebd;" k="60" />
+<hkern u1="&#x178;" u2="&#x1ea7;" k="40" />
+<hkern u1="&#x178;" u2="&#x1e9e;" k="30" />
+<hkern u1="&#x178;" u2="&#x1d0;" k="10" />
+<hkern u1="&#x178;" u2="&#x135;" k="8" />
+<hkern u1="&#x178;" u2="&#x12d;" k="-15" />
+<hkern u1="&#x178;" u2="&#x12b;" k="-30" />
+<hkern u1="&#x178;" u2="&#x129;" k="-50" />
<hkern u1="&#x178;" u2="&#xef;" k="-40" />
<hkern u1="&#x178;" u2="&#xee;" k="-17" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="T" k="80" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="V" k="43" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="W" k="30" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="Y,Yacute,Ydieresis" k="60" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quotedbl,quotesingle" k="60" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="colon,semicolon" k="-20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="15" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="5" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="t" k="15" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="z" k="-12" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="copyright,registered" k="10" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="trademark" k="90" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quoteleft,quotedblleft" k="90" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quoteright,quotedblright" k="85" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="10" />
-<hkern g1="B" g2="J" k="30" />
-<hkern g1="B" g2="T" k="25" />
+<hkern u1="&#x1cd;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1cd;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1ce;" u2="&#x167;" k="3" />
+<hkern u1="&#x1fa;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1fa;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1fb;" u2="&#x167;" k="3" />
+<hkern u1="&#x21a;" u2="&#x1ef9;" k="30" />
+<hkern u1="&#x21a;" u2="&#x1ee1;" k="60" />
+<hkern u1="&#x21a;" u2="&#x1ed7;" k="80" />
+<hkern u1="&#x21a;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x21a;" u2="&#x1ec5;" k="83" />
+<hkern u1="&#x21a;" u2="&#x1ec1;" k="65" />
+<hkern u1="&#x21a;" u2="&#x1ebd;" k="55" />
+<hkern u1="&#x21a;" u2="&#x1eb7;" k="70" />
+<hkern u1="&#x21a;" u2="&#x1eb5;" k="65" />
+<hkern u1="&#x21a;" u2="&#x1eb3;" k="70" />
+<hkern u1="&#x21a;" u2="&#x1eb1;" k="70" />
+<hkern u1="&#x21a;" u2="&#x1eaf;" k="65" />
+<hkern u1="&#x21a;" u2="&#x1ead;" k="55" />
+<hkern u1="&#x21a;" u2="&#x1eab;" k="60" />
+<hkern u1="&#x21a;" u2="&#x1ea9;" k="70" />
+<hkern u1="&#x21a;" u2="&#x1ea7;" k="50" />
+<hkern u1="&#x21a;" u2="&#x1ea5;" k="68" />
+<hkern u1="&#x21a;" u2="&#x1e9e;" k="25" />
+<hkern u1="&#x21a;" u2="&#x1d6;" k="65" />
+<hkern u1="&#x21a;" u2="&#x1d0;" k="5" />
+<hkern u1="&#x21a;" u2="&#x161;" k="108" />
+<hkern u1="&#x21a;" u2="&#x15d;" k="83" />
+<hkern u1="&#x21a;" u2="&#x159;" k="75" />
+<hkern u1="&#x21a;" u2="&#x135;" k="-30" />
+<hkern u1="&#x21a;" u2="&#x12d;" k="-30" />
+<hkern u1="&#x21a;" u2="&#x12b;" k="-40" />
+<hkern u1="&#x21a;" u2="&#x129;" k="-65" />
+<hkern u1="&#x21a;" u2="&#x103;" k="90" />
+<hkern u1="&#x21a;" u2="&#x101;" k="80" />
+<hkern u1="&#x21a;" u2="&#xef;" k="-55" />
+<hkern u1="&#x21a;" u2="&#xee;" k="-30" />
+<hkern u1="&#x21a;" u2="&#xe4;" k="70" />
+<hkern u1="&#x21a;" u2="&#xe3;" k="55" />
+<hkern u1="&#x21a;" u2="&#xe2;" k="75" />
+<hkern u1="&#x21a;" u2="&#x3f;" k="-15" />
+<hkern u1="&#x21a;" u2="&#x2a;" k="-37" />
+<hkern u1="&#x386;" u2="&#x3f;" k="45" />
+<hkern u1="&#x388;" u2="&#x390;" k="-75" />
+<hkern u1="&#x389;" u2="&#x390;" k="-50" />
+<hkern u1="&#x390;" u2="&#x3be;" k="-3" />
+<hkern u1="&#x390;" u2="&#x3b8;" k="13" />
+<hkern u1="&#x390;" u2="&#x3f;" k="-50" />
+<hkern u1="&#x391;" u2="&#x3f;" k="45" />
+<hkern u1="&#x393;" u2="&#x3cb;" k="40" />
+<hkern u1="&#x393;" u2="&#x3ca;" k="-57" />
+<hkern u1="&#x393;" u2="&#x3b4;" k="78" />
+<hkern u1="&#x393;" u2="&#x3b0;" k="25" />
+<hkern u1="&#x393;" u2="&#x3af;" k="51" />
+<hkern u1="&#x393;" u2="&#x3a6;" k="50" />
+<hkern u1="&#x393;" u2="&#x390;" k="-99" />
+<hkern u1="&#x394;" u2="&#x3f;" k="45" />
+<hkern u1="&#x395;" u2="&#x390;" k="-75" />
+<hkern u1="&#x396;" u2="&#x3ca;" k="-30" />
+<hkern u1="&#x396;" u2="&#x390;" k="-75" />
+<hkern u1="&#x397;" u2="&#x390;" k="-50" />
+<hkern u1="&#x39a;" u2="&#x3ca;" k="-25" />
+<hkern u1="&#x39a;" u2="&#x3a6;" k="35" />
+<hkern u1="&#x39a;" u2="&#x390;" k="-66" />
+<hkern u1="&#x39b;" u2="&#x3f;" k="45" />
+<hkern u1="&#x39c;" u2="&#x390;" k="-50" />
+<hkern u1="&#x39d;" u2="&#x390;" k="-50" />
+<hkern u1="&#x39e;" u2="&#x3ca;" k="-25" />
+<hkern u1="&#x39e;" u2="&#x390;" k="-76" />
+<hkern u1="&#x3a0;" u2="&#x390;" k="-50" />
+<hkern u1="&#x3a3;" u2="&#x3ca;" k="-15" />
+<hkern u1="&#x3a3;" u2="&#x390;" k="-70" />
+<hkern u1="&#x3a4;" u2="&#x3cb;" k="65" />
+<hkern u1="&#x3a4;" u2="&#x3ca;" k="-65" />
+<hkern u1="&#x3a4;" u2="&#x3b4;" k="80" />
+<hkern u1="&#x3a4;" u2="&#x3b0;" k="35" />
+<hkern u1="&#x3a4;" u2="&#x3af;" k="20" />
+<hkern u1="&#x3a4;" u2="&#x390;" k="-110" />
+<hkern u1="&#x3a4;" u2="&#x3f;" k="-15" />
+<hkern u1="&#x3a4;" u2="&#x2a;" k="-7" />
+<hkern u1="&#x3a7;" u2="&#x3ca;" k="-40" />
+<hkern u1="&#x3a7;" u2="&#x390;" k="-82" />
+<hkern u1="&#x3a8;" u2="&#x3ca;" k="-20" />
+<hkern u1="&#x3a8;" u2="&#x390;" k="-67" />
+<hkern u1="&#x3b1;" u2="&#x3c4;" k="25" />
+<hkern u1="&#x3b1;" u2="&#x3c0;" k="28" />
+<hkern u1="&#x3b2;" u2="&#x3c4;" k="28" />
+<hkern u1="&#x3b6;" u2="&#x3ca;" k="-35" />
+<hkern u1="&#x3b6;" u2="&#x390;" k="-90" />
+<hkern u1="&#x3bb;" u2="&#x3f;" k="80" />
+<hkern u1="&#x3bb;" u2="&#x2a;" k="65" />
+<hkern u1="&#x3bd;" u2="&#x3c4;" k="-10" />
+<hkern u1="&#x3be;" u2="&#x390;" k="-56" />
+<hkern u1="&#x3be;" u2="&#x2a;" k="-15" />
+<hkern u1="&#x3c7;" u2="&#x3f;" k="55" />
+<hkern u1="&#x3c7;" u2="&#x2a;" k="20" />
+<hkern u1="&#x3c9;" u2="&#x3f;" k="30" />
+<hkern u1="&#x3ca;" u2="&#x3ca;" k="-20" />
+<hkern u1="&#x3ce;" u2="&#x3f;" k="30" />
+<hkern u1="&#x403;" u2="&#x45e;" k="100" />
+<hkern u1="&#x403;" u2="&#x458;" k="20" />
+<hkern u1="&#x403;" u2="&#x457;" k="-70" />
+<hkern u1="&#x403;" u2="&#x456;" k="20" />
+<hkern u1="&#x403;" u2="&#x451;" k="103" />
+<hkern u1="&#x403;" u2="&#x424;" k="50" />
+<hkern u1="&#x409;" u2="&#x42a;" k="63" />
+<hkern u1="&#x40a;" u2="&#x42a;" k="63" />
+<hkern u1="&#x40c;" u2="&#x457;" k="-5" />
+<hkern u1="&#x40c;" u2="&#x456;" k="20" />
+<hkern u1="&#x40e;" u2="&#x457;" k="-55" />
+<hkern u1="&#x410;" u2="&#x42a;" k="75" />
+<hkern u1="&#x410;" u2="&#x3f;" k="40" />
+<hkern u1="&#x410;" u2="&#x2a;" k="40" />
+<hkern u1="&#x413;" u2="&#x45e;" k="100" />
+<hkern u1="&#x413;" u2="&#x458;" k="20" />
+<hkern u1="&#x413;" u2="&#x457;" k="-70" />
+<hkern u1="&#x413;" u2="&#x456;" k="20" />
+<hkern u1="&#x413;" u2="&#x451;" k="103" />
+<hkern u1="&#x413;" u2="&#x424;" k="50" />
+<hkern u1="&#x414;" u2="&#x458;" k="-80" />
+<hkern u1="&#x414;" u2="&#x42d;" k="-5" />
+<hkern u1="&#x416;" u2="&#x457;" k="-5" />
+<hkern u1="&#x416;" u2="&#x456;" k="20" />
+<hkern u1="&#x41a;" u2="&#x457;" k="-5" />
+<hkern u1="&#x41a;" u2="&#x456;" k="20" />
+<hkern u1="&#x422;" u2="&#x458;" k="10" />
+<hkern u1="&#x422;" u2="&#x457;" k="-60" />
+<hkern u1="&#x422;" u2="&#x456;" k="20" />
+<hkern u1="&#x422;" u2="&#x451;" k="70" />
+<hkern u1="&#x422;" u2="&#x424;" k="38" />
+<hkern u1="&#x422;" u2="&#x2a;" k="-37" />
+<hkern u1="&#x423;" u2="&#x457;" k="-55" />
+<hkern u1="&#x424;" u2="&#x422;" k="38" />
+<hkern u1="&#x425;" u2="&#x457;" k="-35" />
+<hkern u1="&#x426;" u2="&#x458;" k="-80" />
+<hkern u1="&#x429;" u2="&#x458;" k="-80" />
+<hkern u1="&#x42a;" u2="&#x42a;" k="63" />
+<hkern u1="&#x42c;" u2="&#x42a;" k="63" />
+<hkern u1="&#x434;" u2="&#x458;" k="-41" />
+<hkern u1="&#x442;" u2="&#x2a;" k="-30" />
+<hkern u1="&#x446;" u2="&#x458;" k="-41" />
+<hkern u1="&#x449;" u2="&#x458;" k="-41" />
+<hkern u1="&#x456;" u2="&#x457;" k="-15" />
+<hkern u1="&#x457;" u2="&#x45b;" k="-67" />
+<hkern u1="&#x457;" u2="&#x452;" k="-67" />
+<hkern u1="&#x457;" u2="&#x3f;" k="-35" />
+<hkern u1="&#x457;" u2="&#x2a;" k="-45" />
+<hkern u1="&#x490;" u2="&#x491;" k="138" />
+<hkern u1="&#x490;" u2="&#x45f;" k="138" />
+<hkern u1="&#x490;" u2="&#x45e;" k="20" />
+<hkern u1="&#x490;" u2="&#x45d;" k="138" />
+<hkern u1="&#x490;" u2="&#x45c;" k="138" />
+<hkern u1="&#x490;" u2="&#x45a;" k="138" />
+<hkern u1="&#x490;" u2="&#x458;" k="20" />
+<hkern u1="&#x490;" u2="&#x457;" k="-70" />
+<hkern u1="&#x490;" u2="&#x456;" k="20" />
+<hkern u1="&#x490;" u2="&#x453;" k="138" />
+<hkern u1="&#x490;" u2="&#x451;" k="103" />
+<hkern u1="&#x490;" u2="&#x450;" k="65" />
+<hkern u1="&#x490;" u2="&#x44e;" k="138" />
+<hkern u1="&#x490;" u2="&#x44c;" k="138" />
+<hkern u1="&#x490;" u2="&#x44b;" k="138" />
+<hkern u1="&#x490;" u2="&#x449;" k="138" />
+<hkern u1="&#x490;" u2="&#x448;" k="138" />
+<hkern u1="&#x490;" u2="&#x446;" k="138" />
+<hkern u1="&#x490;" u2="&#x440;" k="138" />
+<hkern u1="&#x490;" u2="&#x43f;" k="138" />
+<hkern u1="&#x490;" u2="&#x43d;" k="138" />
+<hkern u1="&#x490;" u2="&#x43c;" k="138" />
+<hkern u1="&#x490;" u2="&#x43a;" k="138" />
+<hkern u1="&#x490;" u2="&#x439;" k="123" />
+<hkern u1="&#x490;" u2="&#x438;" k="138" />
+<hkern u1="&#x490;" u2="&#x433;" k="138" />
+<hkern u1="&#x490;" u2="&#x432;" k="138" />
+<hkern u1="&#x490;" u2="&#x42d;" k="8" />
+<hkern u1="&#x490;" u2="&#x424;" k="50" />
+<hkern u1="&#x490;" u2="&#x417;" k="8" />
+<hkern u1="&#x491;" u2="&#x45b;" k="-22" />
+<hkern u1="&#x491;" u2="&#x457;" k="-80" />
+<hkern u1="&#x491;" u2="&#x452;" k="-22" />
+<hkern u1="&#x1e80;" u2="&#x1e9e;" k="10" />
+<hkern u1="&#x1e80;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1e80;" u2="&#x12d;" k="-12" />
+<hkern u1="&#x1e80;" u2="&#x12b;" k="-22" />
+<hkern u1="&#x1e80;" u2="&#x129;" k="-52" />
+<hkern u1="&#x1e80;" u2="&#x127;" k="10" />
+<hkern u1="&#x1e80;" u2="&#xef;" k="-32" />
+<hkern u1="&#x1e80;" u2="&#xee;" k="-12" />
+<hkern u1="&#x1e82;" u2="&#x1e9e;" k="10" />
+<hkern u1="&#x1e82;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1e82;" u2="&#x12d;" k="-12" />
+<hkern u1="&#x1e82;" u2="&#x12b;" k="-22" />
+<hkern u1="&#x1e82;" u2="&#x129;" k="-52" />
+<hkern u1="&#x1e82;" u2="&#x127;" k="10" />
+<hkern u1="&#x1e82;" u2="&#xef;" k="-32" />
+<hkern u1="&#x1e82;" u2="&#xee;" k="-12" />
+<hkern u1="&#x1e84;" u2="&#x1e9e;" k="10" />
+<hkern u1="&#x1e84;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1e84;" u2="&#x12d;" k="-12" />
+<hkern u1="&#x1e84;" u2="&#x12b;" k="-22" />
+<hkern u1="&#x1e84;" u2="&#x129;" k="-52" />
+<hkern u1="&#x1e84;" u2="&#x127;" k="10" />
+<hkern u1="&#x1e84;" u2="&#xef;" k="-32" />
+<hkern u1="&#x1e84;" u2="&#xee;" k="-12" />
+<hkern u1="&#x1e9e;" u2="&#x2026;" k="15" />
+<hkern u1="&#x1e9e;" u2="&#x201e;" k="15" />
+<hkern u1="&#x1e9e;" u2="&#x201a;" k="15" />
+<hkern u1="&#x1e9e;" u2="&#x1ef8;" k="50" />
+<hkern u1="&#x1e9e;" u2="&#x1ef6;" k="50" />
+<hkern u1="&#x1e9e;" u2="&#x1ef4;" k="50" />
+<hkern u1="&#x1e9e;" u2="&#x1ef2;" k="50" />
+<hkern u1="&#x1e9e;" u2="&#x1eb6;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1eb4;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1eb2;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1eb0;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1eae;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1eac;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1eaa;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1ea8;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1ea6;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1ea4;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1ea2;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1ea0;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1e9e;" k="30" />
+<hkern u1="&#x1e9e;" u2="&#x1e84;" k="25" />
+<hkern u1="&#x1e9e;" u2="&#x1e82;" k="25" />
+<hkern u1="&#x1e9e;" u2="&#x1e80;" k="25" />
+<hkern u1="&#x1e9e;" u2="&#x21a;" k="70" />
+<hkern u1="&#x1e9e;" u2="&#x1fc;" k="30" />
+<hkern u1="&#x1e9e;" u2="&#x1fa;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x1cd;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x178;" k="50" />
+<hkern u1="&#x1e9e;" u2="&#x176;" k="50" />
+<hkern u1="&#x1e9e;" u2="&#x174;" k="25" />
+<hkern u1="&#x1e9e;" u2="&#x166;" k="70" />
+<hkern u1="&#x1e9e;" u2="&#x164;" k="70" />
+<hkern u1="&#x1e9e;" u2="&#x162;" k="70" />
+<hkern u1="&#x1e9e;" u2="&#x104;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x102;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x100;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#xdd;" k="50" />
+<hkern u1="&#x1e9e;" u2="&#xc6;" k="30" />
+<hkern u1="&#x1e9e;" u2="&#xc5;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#xc4;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#xc3;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#xc2;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#xc1;" k="20" />
+<hkern u1="&#x1e9e;" u2="&#xc0;" k="20" />
+<hkern u1="&#x1e9e;" u2="Y" k="50" />
+<hkern u1="&#x1e9e;" u2="X" k="15" />
+<hkern u1="&#x1e9e;" u2="W" k="25" />
+<hkern u1="&#x1e9e;" u2="V" k="25" />
+<hkern u1="&#x1e9e;" u2="T" k="70" />
+<hkern u1="&#x1e9e;" u2="A" k="20" />
+<hkern u1="&#x1e9e;" u2="&#x2e;" k="15" />
+<hkern u1="&#x1e9e;" u2="&#x2c;" k="15" />
+<hkern u1="&#x1ea0;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1ea0;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1ea1;" u2="&#x167;" k="3" />
+<hkern u1="&#x1ea2;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1ea2;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1ea3;" u2="&#x167;" k="3" />
+<hkern u1="&#x1ea4;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1ea4;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1ea5;" u2="&#x167;" k="3" />
+<hkern u1="&#x1ea6;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1ea6;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1ea7;" u2="&#x167;" k="3" />
+<hkern u1="&#x1ea8;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1ea8;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1ea9;" u2="&#x167;" k="3" />
+<hkern u1="&#x1eaa;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1eaa;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1eab;" u2="&#x167;" k="3" />
+<hkern u1="&#x1eac;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1eac;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1ead;" u2="&#x167;" k="3" />
+<hkern u1="&#x1eae;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1eae;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1eaf;" u2="&#x167;" k="3" />
+<hkern u1="&#x1eb0;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1eb0;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1eb1;" u2="&#x167;" k="3" />
+<hkern u1="&#x1eb2;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1eb2;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1eb3;" u2="&#x167;" k="3" />
+<hkern u1="&#x1eb4;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1eb4;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1eb5;" u2="&#x167;" k="3" />
+<hkern u1="&#x1eb6;" u2="&#x3f;" k="45" />
+<hkern u1="&#x1eb6;" u2="&#x2a;" k="70" />
+<hkern u1="&#x1eb7;" u2="&#x167;" k="3" />
+<hkern u1="&#x1ecb;" u2="j" k="-30" />
+<hkern u1="&#x1ef2;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x1ef2;" u2="&#x1ebd;" k="60" />
+<hkern u1="&#x1ef2;" u2="&#x1ea7;" k="40" />
+<hkern u1="&#x1ef2;" u2="&#x1e9e;" k="30" />
+<hkern u1="&#x1ef2;" u2="&#x1d0;" k="10" />
+<hkern u1="&#x1ef2;" u2="&#x135;" k="8" />
+<hkern u1="&#x1ef2;" u2="&#x12d;" k="-15" />
+<hkern u1="&#x1ef2;" u2="&#x12b;" k="-30" />
+<hkern u1="&#x1ef2;" u2="&#x129;" k="-50" />
+<hkern u1="&#x1ef2;" u2="&#xef;" k="-40" />
+<hkern u1="&#x1ef2;" u2="&#xee;" k="-17" />
+<hkern u1="&#x1ef4;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x1ef4;" u2="&#x1ebd;" k="60" />
+<hkern u1="&#x1ef4;" u2="&#x1ea7;" k="40" />
+<hkern u1="&#x1ef4;" u2="&#x1e9e;" k="30" />
+<hkern u1="&#x1ef4;" u2="&#x1d0;" k="10" />
+<hkern u1="&#x1ef4;" u2="&#x135;" k="8" />
+<hkern u1="&#x1ef4;" u2="&#x12d;" k="-15" />
+<hkern u1="&#x1ef4;" u2="&#x12b;" k="-30" />
+<hkern u1="&#x1ef4;" u2="&#x129;" k="-50" />
+<hkern u1="&#x1ef4;" u2="&#xef;" k="-40" />
+<hkern u1="&#x1ef4;" u2="&#xee;" k="-17" />
+<hkern u1="&#x1ef5;" u2="j" k="-20" />
+<hkern u1="&#x1ef6;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x1ef6;" u2="&#x1ebd;" k="60" />
+<hkern u1="&#x1ef6;" u2="&#x1ea7;" k="40" />
+<hkern u1="&#x1ef6;" u2="&#x1e9e;" k="30" />
+<hkern u1="&#x1ef6;" u2="&#x1d0;" k="10" />
+<hkern u1="&#x1ef6;" u2="&#x135;" k="8" />
+<hkern u1="&#x1ef6;" u2="&#x12d;" k="-15" />
+<hkern u1="&#x1ef6;" u2="&#x12b;" k="-30" />
+<hkern u1="&#x1ef6;" u2="&#x129;" k="-50" />
+<hkern u1="&#x1ef6;" u2="&#xef;" k="-40" />
+<hkern u1="&#x1ef6;" u2="&#xee;" k="-17" />
+<hkern u1="&#x1ef8;" u2="&#x1ed3;" k="60" />
+<hkern u1="&#x1ef8;" u2="&#x1ebd;" k="60" />
+<hkern u1="&#x1ef8;" u2="&#x1ea7;" k="40" />
+<hkern u1="&#x1ef8;" u2="&#x1e9e;" k="30" />
+<hkern u1="&#x1ef8;" u2="&#x1d0;" k="10" />
+<hkern u1="&#x1ef8;" u2="&#x135;" k="8" />
+<hkern u1="&#x1ef8;" u2="&#x12d;" k="-15" />
+<hkern u1="&#x1ef8;" u2="&#x12b;" k="-30" />
+<hkern u1="&#x1ef8;" u2="&#x129;" k="-50" />
+<hkern u1="&#x1ef8;" u2="&#xef;" k="-40" />
+<hkern u1="&#x1ef8;" u2="&#xee;" k="-17" />
+<hkern u1="&#x2018;" u2="&#x3ca;" k="-30" />
+<hkern u1="&#x2018;" u2="&#x390;" k="-60" />
+<hkern u1="&#x2018;" u2="&#x38e;" k="-125" />
+<hkern u1="&#x2018;" u2="&#x386;" k="-45" />
+<hkern u1="&#x2019;" u2="&#x3ca;" k="-35" />
+<hkern u1="&#x2019;" u2="&#x390;" k="-75" />
+<hkern u1="&#x2019;" u2="&#x38e;" k="-120" />
+<hkern u1="&#x2019;" u2="&#x386;" k="-55" />
+<hkern u1="&#x201a;" u2="&#x42a;" k="85" />
+<hkern u1="&#x201b;" u2="&#x2206;" k="90" />
+<hkern u1="&#x201b;" u2="&#x2026;" k="83" />
+<hkern u1="&#x201b;" u2="&#x201e;" k="83" />
+<hkern u1="&#x201b;" u2="&#x201b;" k="58" />
+<hkern u1="&#x201b;" u2="&#x201a;" k="83" />
+<hkern u1="&#x201b;" u2="&#x1ee3;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ee1;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1edf;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1edd;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1edb;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ed9;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ed7;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ed5;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ed3;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ed1;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ecf;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ecd;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ec7;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ec5;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ec3;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ec1;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ebf;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ebd;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1ebb;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1eb9;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1eb6;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1eb4;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1eb2;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1eb0;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1eae;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1eac;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1eaa;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1ea8;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1ea6;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1ea4;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1ea2;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1ea0;" k="90" />
+<hkern u1="&#x201b;" u2="&#x459;" k="80" />
+<hkern u1="&#x201b;" u2="&#x43b;" k="80" />
+<hkern u1="&#x201b;" u2="&#x42a;" k="-20" />
+<hkern u1="&#x201b;" u2="&#x41b;" k="105" />
+<hkern u1="&#x201b;" u2="&#x414;" k="45" />
+<hkern u1="&#x201b;" u2="&#x410;" k="90" />
+<hkern u1="&#x201b;" u2="&#x40b;" k="-20" />
+<hkern u1="&#x201b;" u2="&#x409;" k="105" />
+<hkern u1="&#x201b;" u2="&#x408;" k="107" />
+<hkern u1="&#x201b;" u2="&#x402;" k="-20" />
+<hkern u1="&#x201b;" u2="&#x3ce;" k="40" />
+<hkern u1="&#x201b;" u2="&#x3cc;" k="35" />
+<hkern u1="&#x201b;" u2="&#x3ca;" k="-35" />
+<hkern u1="&#x201b;" u2="&#x3c9;" k="40" />
+<hkern u1="&#x201b;" u2="&#x3c6;" k="35" />
+<hkern u1="&#x201b;" u2="&#x3c3;" k="35" />
+<hkern u1="&#x201b;" u2="&#x3c2;" k="35" />
+<hkern u1="&#x201b;" u2="&#x3c1;" k="30" />
+<hkern u1="&#x201b;" u2="&#x3bf;" k="35" />
+<hkern u1="&#x201b;" u2="&#x3b4;" k="35" />
+<hkern u1="&#x201b;" u2="&#x3b1;" k="35" />
+<hkern u1="&#x201b;" u2="&#x3ac;" k="35" />
+<hkern u1="&#x201b;" u2="&#x3a4;" k="-25" />
+<hkern u1="&#x201b;" u2="&#x39b;" k="90" />
+<hkern u1="&#x201b;" u2="&#x394;" k="90" />
+<hkern u1="&#x201b;" u2="&#x391;" k="90" />
+<hkern u1="&#x201b;" u2="&#x390;" k="-75" />
+<hkern u1="&#x201b;" u2="&#x38f;" k="-110" />
+<hkern u1="&#x201b;" u2="&#x38e;" k="-120" />
+<hkern u1="&#x201b;" u2="&#x38c;" k="-110" />
+<hkern u1="&#x201b;" u2="&#x38a;" k="-110" />
+<hkern u1="&#x201b;" u2="&#x389;" k="-110" />
+<hkern u1="&#x201b;" u2="&#x388;" k="-110" />
+<hkern u1="&#x201b;" u2="&#x386;" k="-55" />
+<hkern u1="&#x201b;" u2="&#x21a;" k="-25" />
+<hkern u1="&#x201b;" u2="&#x1ff;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1fc;" k="88" />
+<hkern u1="&#x201b;" u2="&#x1fa;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1d2;" k="35" />
+<hkern u1="&#x201b;" u2="&#x1cd;" k="90" />
+<hkern u1="&#x201b;" u2="&#x1a1;" k="35" />
+<hkern u1="&#x201b;" u2="&#x166;" k="-25" />
+<hkern u1="&#x201b;" u2="&#x164;" k="-25" />
+<hkern u1="&#x201b;" u2="&#x162;" k="-25" />
+<hkern u1="&#x201b;" u2="&#x153;" k="35" />
+<hkern u1="&#x201b;" u2="&#x151;" k="35" />
+<hkern u1="&#x201b;" u2="&#x14f;" k="35" />
+<hkern u1="&#x201b;" u2="&#x14d;" k="35" />
+<hkern u1="&#x201b;" u2="&#x134;" k="107" />
+<hkern u1="&#x201b;" u2="&#x123;" k="35" />
+<hkern u1="&#x201b;" u2="&#x121;" k="35" />
+<hkern u1="&#x201b;" u2="&#x11f;" k="35" />
+<hkern u1="&#x201b;" u2="&#x11d;" k="35" />
+<hkern u1="&#x201b;" u2="&#x11b;" k="35" />
+<hkern u1="&#x201b;" u2="&#x119;" k="35" />
+<hkern u1="&#x201b;" u2="&#x117;" k="35" />
+<hkern u1="&#x201b;" u2="&#x115;" k="35" />
+<hkern u1="&#x201b;" u2="&#x113;" k="35" />
+<hkern u1="&#x201b;" u2="&#x111;" k="35" />
+<hkern u1="&#x201b;" u2="&#x10f;" k="35" />
+<hkern u1="&#x201b;" u2="&#x10d;" k="35" />
+<hkern u1="&#x201b;" u2="&#x10b;" k="35" />
+<hkern u1="&#x201b;" u2="&#x109;" k="35" />
+<hkern u1="&#x201b;" u2="&#x107;" k="35" />
+<hkern u1="&#x201b;" u2="&#x104;" k="90" />
+<hkern u1="&#x201b;" u2="&#x102;" k="90" />
+<hkern u1="&#x201b;" u2="&#x100;" k="90" />
+<hkern u1="&#x201b;" u2="&#xf8;" k="35" />
+<hkern u1="&#x201b;" u2="&#xf6;" k="35" />
+<hkern u1="&#x201b;" u2="&#xf5;" k="35" />
+<hkern u1="&#x201b;" u2="&#xf4;" k="35" />
+<hkern u1="&#x201b;" u2="&#xf3;" k="35" />
+<hkern u1="&#x201b;" u2="&#xf2;" k="35" />
+<hkern u1="&#x201b;" u2="&#xf0;" k="35" />
+<hkern u1="&#x201b;" u2="&#xeb;" k="35" />
+<hkern u1="&#x201b;" u2="&#xea;" k="35" />
+<hkern u1="&#x201b;" u2="&#xe9;" k="35" />
+<hkern u1="&#x201b;" u2="&#xe8;" k="35" />
+<hkern u1="&#x201b;" u2="&#xe7;" k="35" />
+<hkern u1="&#x201b;" u2="&#xc6;" k="88" />
+<hkern u1="&#x201b;" u2="&#xc5;" k="90" />
+<hkern u1="&#x201b;" u2="&#xc4;" k="90" />
+<hkern u1="&#x201b;" u2="&#xc3;" k="90" />
+<hkern u1="&#x201b;" u2="&#xc2;" k="90" />
+<hkern u1="&#x201b;" u2="&#xc1;" k="90" />
+<hkern u1="&#x201b;" u2="&#xc0;" k="90" />
+<hkern u1="&#x201b;" u2="q" k="35" />
+<hkern u1="&#x201b;" u2="o" k="35" />
+<hkern u1="&#x201b;" u2="g" k="35" />
+<hkern u1="&#x201b;" u2="e" k="35" />
+<hkern u1="&#x201b;" u2="d" k="35" />
+<hkern u1="&#x201b;" u2="c" k="35" />
+<hkern u1="&#x201b;" u2="T" k="-25" />
+<hkern u1="&#x201b;" u2="J" k="107" />
+<hkern u1="&#x201b;" u2="A" k="90" />
+<hkern u1="&#x201b;" u2="&#x2e;" k="83" />
+<hkern u1="&#x201b;" u2="&#x2c;" k="83" />
+<hkern u1="&#x201c;" u2="&#x3ca;" k="-30" />
+<hkern u1="&#x201c;" u2="&#x390;" k="-60" />
+<hkern u1="&#x201c;" u2="&#x38e;" k="-125" />
+<hkern u1="&#x201c;" u2="&#x386;" k="-45" />
+<hkern u1="&#x201d;" u2="&#x3ca;" k="-35" />
+<hkern u1="&#x201d;" u2="&#x390;" k="-75" />
+<hkern u1="&#x201d;" u2="&#x38e;" k="-120" />
+<hkern u1="&#x201d;" u2="&#x386;" k="-55" />
+<hkern u1="&#x201e;" u2="&#x42a;" k="85" />
+<hkern u1="&#x2026;" u2="&#x42a;" k="85" />
+<hkern u1="&#x2039;" u2="&#x386;" k="-85" />
+<hkern u1="&#x207f;" u2="&#x1e85;" k="5" />
+<hkern u1="&#x207f;" u2="&#x1e83;" k="5" />
+<hkern u1="&#x207f;" u2="&#x1e81;" k="5" />
+<hkern u1="&#x207f;" u2="&#x175;" k="5" />
+<hkern u1="&#x207f;" u2="w" k="5" />
+<hkern u1="&#x207f;" u2="v" k="5" />
+<hkern u1="&#x2206;" u2="&#x3f;" k="45" />
+<hkern g1="f_f" u2="&#x1ef9;" k="-5" />
+<hkern g1="f_f" u2="&#x1ed3;" k="-15" />
+<hkern g1="f_f" u2="&#x1ec9;" k="-12" />
+<hkern g1="f_f" u2="&#x1ec1;" k="-12" />
+<hkern g1="f_f" u2="&#x1eb5;" k="-10" />
+<hkern g1="f_f" u2="&#x1eb3;" k="-10" />
+<hkern g1="f_f" u2="&#x1eb1;" k="-10" />
+<hkern g1="f_f" u2="&#x1eaf;" k="-10" />
+<hkern g1="f_f" u2="&#x1eab;" k="-12" />
+<hkern g1="f_f" u2="&#x1ea7;" k="-42" />
+<hkern g1="f_f" u2="&#x1d0;" k="-85" />
+<hkern g1="f_f" u2="&#x159;" k="-10" />
+<hkern g1="f_f" u2="&#x135;" k="-55" />
+<hkern g1="f_f" u2="&#x12d;" k="-90" />
+<hkern g1="f_f" u2="&#x12b;" k="-75" />
+<hkern g1="f_f" u2="&#x129;" k="-115" />
+<hkern g1="f_f" u2="&#x127;" k="-40" />
+<hkern g1="f_f" u2="&#xef;" k="-85" />
+<hkern g1="f_f" u2="&#xee;" k="-50" />
+<hkern g1="f_f" u2="&#xec;" k="-40" />
+<hkern g1="f_f" u2="&#x3f;" k="-50" />
+<hkern g1="f_f" u2="&#x2a;" k="-55" />
+<hkern g1="f_f" u2="&#x21;" k="-30" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="80" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="V" k="43" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="30" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="60" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quotedbl,quotesingle" k="60" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="colon,semicolon" k="-20" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="15" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="20" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="5" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="15" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="z,zacute,zdotaccent,zcaron" k="-12" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="copyright,registered" k="10" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="trademark" k="90" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quoteleft,quotedblleft" k="90" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quoteright,quotedblright" k="85" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="10" />
+<hkern g1="B" g2="J,Jcircumflex" k="30" />
+<hkern g1="B" g2="T,uni0162,Tcaron,Tbar,uni021A" k="25" />
<hkern g1="B" g2="V" k="20" />
-<hkern g1="B" g2="W" k="20" />
-<hkern g1="B" g2="Y,Yacute,Ydieresis" k="25" />
+<hkern g1="B" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="B" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="25" />
<hkern g1="B" g2="trademark" k="15" />
-<hkern g1="C,Ccedilla" g2="J" k="10" />
-<hkern g1="C,Ccedilla" g2="V" k="13" />
-<hkern g1="C,Ccedilla" g2="W" k="13" />
-<hkern g1="C,Ccedilla" g2="X" k="15" />
-<hkern g1="C,Ccedilla" g2="Y,Yacute,Ydieresis" k="20" />
-<hkern g1="E,AE,Egrave,Eacute,Ecircumflex,Edieresis,OE" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="5" />
-<hkern g1="F" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="55" />
-<hkern g1="F" g2="J" k="105" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="J,Jcircumflex" k="10" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="V" k="13" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="13" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="X" k="15" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
+<hkern g1="E,AE,Egrave,Eacute,Ecircumflex,Edieresis,Emacron,Ebreve,Edotaccent,Eogonek,Ecaron,OE,AEacute,Edotbelow,Ehookabove,Etilde,Ecircumflexacute,Ecircumflexgrave,Ecircumflexhookabove,Ecircumflextilde,Ecircumflexdotbelow" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="5" />
+<hkern g1="F" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="55" />
+<hkern g1="F" g2="J,Jcircumflex" k="105" />
<hkern g1="F" g2="X" k="25" />
<hkern g1="F" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="117" />
-<hkern g1="F" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="20" />
-<hkern g1="F" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="30" />
-<hkern g1="F" g2="t" k="10" />
-<hkern g1="F" g2="z" k="30" />
+<hkern g1="F" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="20" />
+<hkern g1="F" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="30" />
+<hkern g1="F" g2="t,uni0163,tcaron,tbar,uni021B" k="10" />
+<hkern g1="F" g2="z,zacute,zdotaccent,zcaron" k="30" />
<hkern g1="F" g2="copyright,registered" k="15" />
-<hkern g1="F" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="30" />
-<hkern g1="F" g2="S" k="15" />
-<hkern g1="F" g2="Z" k="20" />
-<hkern g1="F" g2="i,j,igrave,iacute,icircumflex,idieresis" k="20" />
-<hkern g1="F" g2="m,n,p,r,ntilde" k="35" />
-<hkern g1="F" g2="s" k="40" />
-<hkern g1="F" g2="u,ugrave,uacute,ucircumflex,udieresis" k="20" />
+<hkern g1="F" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="30" />
+<hkern g1="F" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="15" />
+<hkern g1="F" g2="Z,Zacute,Zdotaccent,Zcaron" k="20" />
+<hkern g1="F" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="20" />
+<hkern g1="F" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="35" />
+<hkern g1="F" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="40" />
+<hkern g1="F" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="20" />
<hkern g1="F" g2="v" k="20" />
-<hkern g1="F" g2="w" k="20" />
+<hkern g1="F" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
<hkern g1="F" g2="x" k="40" />
-<hkern g1="F" g2="y,yacute,ydieresis" k="30" />
-<hkern g1="G" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="5" />
-<hkern g1="G" g2="J" k="25" />
-<hkern g1="G" g2="T" k="20" />
-<hkern g1="G" g2="V" k="20" />
-<hkern g1="G" g2="W" k="20" />
-<hkern g1="G" g2="X" k="15" />
-<hkern g1="G" g2="Y,Yacute,Ydieresis" k="25" />
-<hkern g1="G" g2="trademark" k="10" />
-<hkern g1="J" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="20" />
-<hkern g1="J" g2="J" k="30" />
-<hkern g1="J" g2="X" k="10" />
-<hkern g1="J" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="15" />
-<hkern g1="J" g2="AE" k="30" />
-<hkern g1="K" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="20" />
-<hkern g1="K" g2="J" k="10" />
-<hkern g1="K" g2="T" k="23" />
-<hkern g1="K" g2="V" k="25" />
-<hkern g1="K" g2="W" k="25" />
-<hkern g1="K" g2="X" k="20" />
-<hkern g1="K" g2="Y,Yacute,Ydieresis" k="40" />
-<hkern g1="K" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="25" />
-<hkern g1="K" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="15" />
-<hkern g1="K" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="30" />
-<hkern g1="K" g2="t" k="30" />
-<hkern g1="K" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="25" />
-<hkern g1="K" g2="S" k="30" />
-<hkern g1="K" g2="i,j,igrave,iacute,icircumflex,idieresis" k="20" />
-<hkern g1="K" g2="m,n,p,r,ntilde" k="20" />
-<hkern g1="K" g2="s" k="30" />
-<hkern g1="K" g2="u,ugrave,uacute,ucircumflex,udieresis" k="30" />
-<hkern g1="K" g2="v" k="25" />
-<hkern g1="K" g2="w" k="25" />
-<hkern g1="K" g2="y,yacute,ydieresis" k="50" />
-<hkern g1="K" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="15" />
-<hkern g1="L" g2="T" k="85" />
-<hkern g1="L" g2="V" k="63" />
-<hkern g1="L" g2="W" k="50" />
-<hkern g1="L" g2="Y,Yacute,Ydieresis" k="75" />
-<hkern g1="L" g2="quotedbl,quotesingle" k="120" />
-<hkern g1="L" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-10" />
-<hkern g1="L" g2="colon,semicolon" k="-20" />
-<hkern g1="L" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="20" />
-<hkern g1="L" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="20" />
-<hkern g1="L" g2="t" k="15" />
-<hkern g1="L" g2="copyright,registered" k="40" />
-<hkern g1="L" g2="trademark" k="140" />
-<hkern g1="L" g2="quoteleft,quotedblleft" k="143" />
-<hkern g1="L" g2="quoteright,quotedblright" k="143" />
-<hkern g1="L" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="13" />
-<hkern g1="L" g2="S" k="13" />
-<hkern g1="L" g2="v" k="30" />
-<hkern g1="L" g2="w" k="30" />
-<hkern g1="L" g2="y,yacute,ydieresis" k="50" />
-<hkern g1="P,Thorn" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="50" />
-<hkern g1="P,Thorn" g2="J" k="75" />
-<hkern g1="P,Thorn" g2="T" k="10" />
+<hkern g1="F" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="30" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="5" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="J,Jcircumflex" k="25" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="T,uni0162,Tcaron,Tbar,uni021A" k="20" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="V" k="20" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="X" k="15" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="25" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="trademark" k="10" />
+<hkern g1="J,IJ,Jcircumflex" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="20" />
+<hkern g1="J,IJ,Jcircumflex" g2="J,Jcircumflex" k="30" />
+<hkern g1="J,IJ,Jcircumflex" g2="X" k="10" />
+<hkern g1="J,IJ,Jcircumflex" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="15" />
+<hkern g1="J,IJ,Jcircumflex" g2="AE,AEacute" k="30" />
+<hkern g1="K,Kcommaaccent" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="20" />
+<hkern g1="K,Kcommaaccent" g2="J,Jcircumflex" k="10" />
+<hkern g1="K,Kcommaaccent" g2="T,uni0162,Tcaron,Tbar,uni021A" k="23" />
+<hkern g1="K,Kcommaaccent" g2="V" k="25" />
+<hkern g1="K,Kcommaaccent" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="25" />
+<hkern g1="K,Kcommaaccent" g2="X" k="20" />
+<hkern g1="K,Kcommaaccent" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="40" />
+<hkern g1="K,Kcommaaccent" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="25" />
+<hkern g1="K,Kcommaaccent" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="15" />
+<hkern g1="K,Kcommaaccent" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="30" />
+<hkern g1="K,Kcommaaccent" g2="t,uni0163,tcaron,tbar,uni021B" k="30" />
+<hkern g1="K,Kcommaaccent" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="25" />
+<hkern g1="K,Kcommaaccent" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="30" />
+<hkern g1="K,Kcommaaccent" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="20" />
+<hkern g1="K,Kcommaaccent" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="20" />
+<hkern g1="K,Kcommaaccent" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="30" />
+<hkern g1="K,Kcommaaccent" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="30" />
+<hkern g1="K,Kcommaaccent" g2="v" k="25" />
+<hkern g1="K,Kcommaaccent" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="25" />
+<hkern g1="K,Kcommaaccent" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="50" />
+<hkern g1="K,Kcommaaccent" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="15" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="T,uni0162,Tcaron,Tbar,uni021A" k="85" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="V" k="63" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="50" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="75" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quotedbl,quotesingle" k="120" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-10" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="colon,semicolon" k="-20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="t,uni0163,tcaron,tbar,uni021B" k="15" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="copyright,registered" k="40" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="trademark" k="140" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quoteleft,quotedblleft" k="143" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quoteright,quotedblright" k="143" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="13" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="13" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="v" k="30" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="30" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="50" />
+<hkern g1="P,Thorn" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="50" />
+<hkern g1="P,Thorn" g2="J,Jcircumflex" k="75" />
+<hkern g1="P,Thorn" g2="T,uni0162,Tcaron,Tbar,uni021A" k="10" />
<hkern g1="P,Thorn" g2="V" k="-5" />
-<hkern g1="P,Thorn" g2="W" k="-5" />
+<hkern g1="P,Thorn" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-5" />
<hkern g1="P,Thorn" g2="X" k="15" />
<hkern g1="P,Thorn" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="135" />
-<hkern g1="P,Thorn" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="10" />
-<hkern g1="P,Thorn" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="5" />
-<hkern g1="P,Thorn" g2="S" k="-12" />
-<hkern g1="P,Thorn" g2="Z" k="20" />
-<hkern g1="P,Thorn" g2="AE" k="50" />
-<hkern g1="P,Thorn" g2="I,Igrave,Iacute,Icircumflex,Idieresis" k="20" />
-<hkern g1="R" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="10" />
-<hkern g1="R" g2="J" k="10" />
-<hkern g1="R" g2="T" k="15" />
-<hkern g1="R" g2="V" k="20" />
-<hkern g1="R" g2="W" k="20" />
-<hkern g1="R" g2="Y,Yacute,Ydieresis" k="20" />
-<hkern g1="R" g2="z" k="-5" />
-<hkern g1="R" g2="AE" k="15" />
-<hkern g1="S" g2="J" k="25" />
-<hkern g1="S" g2="T" k="20" />
-<hkern g1="S" g2="V" k="15" />
-<hkern g1="S" g2="W" k="15" />
-<hkern g1="S" g2="X" k="10" />
-<hkern g1="S" g2="Y,Yacute,Ydieresis" k="30" />
-<hkern g1="T" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="80" />
-<hkern g1="T" g2="J" k="70" />
-<hkern g1="T" g2="X" k="10" />
-<hkern g1="T" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="100" />
-<hkern g1="T" g2="colon,semicolon" k="55" />
-<hkern g1="T" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="28" />
-<hkern g1="T" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="100" />
-<hkern g1="T" g2="t" k="25" />
-<hkern g1="T" g2="z" k="76" />
-<hkern g1="T" g2="copyright,registered" k="50" />
-<hkern g1="T" g2="trademark" k="-35" />
-<hkern g1="T" g2="quoteleft,quotedblleft" k="-25" />
-<hkern g1="T" g2="quoteright,quotedblright" k="-25" />
-<hkern g1="T" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="100" />
-<hkern g1="T" g2="S" k="20" />
-<hkern g1="T" g2="i,j,igrave,iacute,icircumflex,idieresis" k="20" />
-<hkern g1="T" g2="m,n,p,r,ntilde" k="90" />
-<hkern g1="T" g2="s" k="109" />
-<hkern g1="T" g2="u,ugrave,uacute,ucircumflex,udieresis" k="75" />
-<hkern g1="T" g2="v" k="100" />
-<hkern g1="T" g2="w" k="100" />
-<hkern g1="T" g2="x" k="100" />
-<hkern g1="T" g2="y,yacute,ydieresis" k="70" />
-<hkern g1="T" g2="AE" k="90" />
-<hkern g1="T" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
-<hkern g1="T" g2="hyphen,endash,emdash" k="50" />
-<hkern g1="T" g2="guillemotleft,guilsinglleft" k="70" />
-<hkern g1="T" g2="guillemotright,guilsinglright" k="45" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="20" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="J" k="25" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="X" k="15" />
-<hkern g1="W" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="30" />
-<hkern g1="W" g2="J" k="70" />
-<hkern g1="W" g2="X" k="10" />
-<hkern g1="W" g2="Y,Yacute,Ydieresis" k="20" />
-<hkern g1="W" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
-<hkern g1="W" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="15" />
-<hkern g1="W" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="30" />
-<hkern g1="W" g2="t" k="13" />
-<hkern g1="W" g2="z" k="20" />
-<hkern g1="W" g2="copyright,registered" k="10" />
-<hkern g1="W" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="30" />
-<hkern g1="W" g2="S" k="5" />
-<hkern g1="W" g2="m,n,p,r,ntilde" k="30" />
-<hkern g1="W" g2="s" k="30" />
-<hkern g1="W" g2="u,ugrave,uacute,ucircumflex,udieresis" k="30" />
-<hkern g1="W" g2="x" k="15" />
-<hkern g1="W" g2="y,yacute,ydieresis" k="10" />
-<hkern g1="W" g2="AE" k="30" />
-<hkern g1="W" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="10" />
-<hkern g1="W" g2="b,h,k,l,germandbls,thorn" k="15" />
-<hkern g1="X" g2="T" k="10" />
+<hkern g1="P,Thorn" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="10" />
+<hkern g1="P,Thorn" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="5" />
+<hkern g1="P,Thorn" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-12" />
+<hkern g1="P,Thorn" g2="Z,Zacute,Zdotaccent,Zcaron" k="20" />
+<hkern g1="P,Thorn" g2="AE,AEacute" k="50" />
+<hkern g1="P,Thorn" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="10" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="J,Jcircumflex" k="10" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="T,uni0162,Tcaron,Tbar,uni021A" k="15" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="V" k="20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="z,zacute,zdotaccent,zcaron" k="-5" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="AE,AEacute" k="15" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="J,Jcircumflex" k="25" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="T,uni0162,Tcaron,Tbar,uni021A" k="20" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="V" k="15" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="15" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="X" k="10" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="30" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="80" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="J,Jcircumflex" k="70" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="X" k="10" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="100" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="colon,semicolon" k="55" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="28" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="100" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="t,uni0163,tcaron,tbar,uni021B" k="25" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="z,zacute,zdotaccent,zcaron" k="76" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="copyright,registered" k="50" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="trademark" k="-35" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="quoteleft,quotedblleft" k="-25" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="quoteright,quotedblright" k="-25" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="100" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="20" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="20" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="90" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="109" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="75" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="v" k="100" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="100" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="x" k="100" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="70" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="AE,AEacute" k="90" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="hyphen,endash,emdash,afii00208" k="50" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="guillemotleft,guilsinglleft" k="70" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="guillemotright,guilsinglright" k="45" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="20" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="J,Jcircumflex" k="25" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="X" k="15" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="J,Jcircumflex" k="70" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="X" k="10" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="15" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="t,uni0163,tcaron,tbar,uni021B" k="13" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="z,zacute,zdotaccent,zcaron" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="copyright,registered" k="10" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="5" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="x" k="15" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="AE,AEacute" k="30" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="10" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="15" />
+<hkern g1="X" g2="T,uni0162,Tcaron,Tbar,uni021A" k="10" />
<hkern g1="X" g2="V" k="10" />
-<hkern g1="X" g2="W" k="10" />
-<hkern g1="X" g2="Y,Yacute,Ydieresis" k="20" />
-<hkern g1="X" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="20" />
-<hkern g1="X" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="15" />
+<hkern g1="X" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="10" />
+<hkern g1="X" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
+<hkern g1="X" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="20" />
+<hkern g1="X" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="15" />
<hkern g1="X" g2="copyright,registered" k="25" />
-<hkern g1="X" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="30" />
-<hkern g1="X" g2="S" k="10" />
-<hkern g1="X" g2="m,n,p,r,ntilde" k="15" />
-<hkern g1="X" g2="u,ugrave,uacute,ucircumflex,udieresis" k="40" />
+<hkern g1="X" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="30" />
+<hkern g1="X" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="10" />
+<hkern g1="X" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="15" />
+<hkern g1="X" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="40" />
<hkern g1="X" g2="v" k="20" />
-<hkern g1="X" g2="w" k="20" />
-<hkern g1="X" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="13" />
+<hkern g1="X" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
+<hkern g1="X" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="13" />
<hkern g1="X" g2="guillemotleft,guilsinglleft" k="15" />
<hkern g1="X" g2="guillemotright,guilsinglright" k="-10" />
-<hkern g1="Y,Yacute,Ydieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="60" />
-<hkern g1="Y,Yacute,Ydieresis" g2="J" k="90" />
-<hkern g1="Y,Yacute,Ydieresis" g2="V" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="W" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="X" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="90" />
-<hkern g1="Y,Yacute,Ydieresis" g2="colon,semicolon" k="25" />
-<hkern g1="Y,Yacute,Ydieresis" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="30" />
-<hkern g1="Y,Yacute,Ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="60" />
-<hkern g1="Y,Yacute,Ydieresis" g2="t" k="15" />
-<hkern g1="Y,Yacute,Ydieresis" g2="z" k="50" />
-<hkern g1="Y,Yacute,Ydieresis" g2="copyright,registered" k="40" />
-<hkern g1="Y,Yacute,Ydieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="70" />
-<hkern g1="Y,Yacute,Ydieresis" g2="S" k="30" />
-<hkern g1="Y,Yacute,Ydieresis" g2="Z" k="10" />
-<hkern g1="Y,Yacute,Ydieresis" g2="i,j,igrave,iacute,icircumflex,idieresis" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="m,n,p,r,ntilde" k="65" />
-<hkern g1="Y,Yacute,Ydieresis" g2="s" k="60" />
-<hkern g1="Y,Yacute,Ydieresis" g2="u,ugrave,uacute,ucircumflex,udieresis" k="50" />
-<hkern g1="Y,Yacute,Ydieresis" g2="v" k="50" />
-<hkern g1="Y,Yacute,Ydieresis" g2="w" k="50" />
-<hkern g1="Y,Yacute,Ydieresis" g2="x" k="40" />
-<hkern g1="Y,Yacute,Ydieresis" g2="AE" k="63" />
-<hkern g1="Y,Yacute,Ydieresis" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="10" />
-<hkern g1="Y,Yacute,Ydieresis" g2="guillemotleft,guilsinglleft" k="50" />
-<hkern g1="Y,Yacute,Ydieresis" g2="b,h,k,l,germandbls,thorn" k="20" />
-<hkern g1="Z" g2="Y,Yacute,Ydieresis" k="15" />
-<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="t" k="10" />
-<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="v" k="8" />
-<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="w" k="3" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="15" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="quoteleft,quotedblleft" k="35" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="quoteright,quotedblright" k="35" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="v" k="10" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="x" k="13" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="y,yacute,ydieresis" k="5" />
-<hkern g1="h,m,n,ntilde" g2="v" k="8" />
-<hkern g1="h,m,n,ntilde" g2="w" k="8" />
-<hkern g1="f" g2="quotedbl,quotesingle" k="-55" />
-<hkern g1="f" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="25" />
-<hkern g1="f" g2="trademark" k="-75" />
-<hkern g1="f" g2="quoteleft,quotedblleft" k="-50" />
-<hkern g1="f" g2="quoteright,quotedblright" k="-55" />
-<hkern g1="f" g2="parenright,bracketright,braceright" k="-75" />
-<hkern g1="k" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="15" />
-<hkern g1="k" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="k" g2="s" k="10" />
-<hkern g1="k" g2="v" k="15" />
-<hkern g1="k" g2="w" k="5" />
-<hkern g1="k" g2="guillemotright,guilsinglright" k="-10" />
-<hkern g1="d,l,uniFB02,uniFB04" g2="t" k="5" />
-<hkern g1="r" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="130" />
-<hkern g1="r" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="10" />
-<hkern g1="r" g2="quoteleft,quotedblleft" k="-30" />
-<hkern g1="r" g2="quoteright,quotedblright" k="-30" />
-<hkern g1="r" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="25" />
-<hkern g1="r" g2="s" k="15" />
-<hkern g1="r" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="-10" />
-<hkern g1="r" g2="guillemotright,guilsinglright" k="-30" />
-<hkern g1="s" g2="t" k="10" />
-<hkern g1="s" g2="v" k="20" />
-<hkern g1="s" g2="w" k="20" />
-<hkern g1="s" g2="x" k="10" />
-<hkern g1="t" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="-10" />
-<hkern g1="t" g2="t" k="5" />
-<hkern g1="t" g2="z" k="-15" />
-<hkern g1="t" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="10" />
-<hkern g1="t" g2="u,ugrave,uacute,ucircumflex,udieresis" k="10" />
-<hkern g1="t" g2="v" k="10" />
-<hkern g1="t" g2="w" k="10" />
-<hkern g1="t" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="13" />
-<hkern g1="w" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="30" />
-<hkern g1="w" g2="s" k="10" />
-<hkern g1="w" g2="y,yacute,ydieresis" k="5" />
-<hkern g1="x" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="13" />
-<hkern g1="y,yacute,ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="65" />
-<hkern g1="y,yacute,ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="13" />
-<hkern g1="y,yacute,ydieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="y,yacute,ydieresis" g2="s" k="15" />
-<hkern g1="y,yacute,ydieresis" g2="v" k="10" />
-<hkern g1="y,yacute,ydieresis" g2="w" k="10" />
-<hkern g1="y,yacute,ydieresis" g2="x" k="15" />
-<hkern g1="y,yacute,ydieresis" g2="parenright,bracketright,braceright" k="30" />
-<hkern g1="z" g2="z" k="-12" />
-<hkern g1="colon,semicolon" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-20" />
-<hkern g1="colon,semicolon" g2="J" k="-20" />
-<hkern g1="colon,semicolon" g2="T" k="55" />
-<hkern g1="colon,semicolon" g2="Y,Yacute,Ydieresis" k="25" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-20" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="J" k="-20" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="T" k="100" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="60" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="J,Jcircumflex" k="90" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="V" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="X" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="90" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="colon,semicolon" k="25" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="30" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="60" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="t,uni0163,tcaron,tbar,uni021B" k="15" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="z,zacute,zdotaccent,zcaron" k="50" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="copyright,registered" k="40" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="70" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="30" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="Z,Zacute,Zdotaccent,Zcaron" k="10" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="65" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="60" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="50" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="v" k="50" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="50" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="x" k="40" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="AE,AEacute" k="63" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="10" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="guillemotleft,guilsinglleft" k="50" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="20" />
+<hkern g1="Z,Zacute,Zdotaccent,Zcaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="15" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring,amacron,abreve,aogonek,acaron,aringacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="10" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring,amacron,abreve,aogonek,acaron,aringacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" g2="v" k="8" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring,amacron,abreve,aogonek,acaron,aringacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="3" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="15" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="quoteleft,quotedblleft" k="35" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="quoteright,quotedblright" k="35" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="v" k="10" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="x" k="13" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="5" />
+<hkern g1="h,m,n,ntilde,hcircumflex,hbar,nacute,ncommaaccent,ncaron,napostrophe,eng" g2="v" k="8" />
+<hkern g1="h,m,n,ntilde,hcircumflex,hbar,nacute,ncommaaccent,ncaron,napostrophe,eng" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="8" />
+<hkern g1="f,f_f" g2="quotedbl,quotesingle" k="-55" />
+<hkern g1="f,f_f" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="25" />
+<hkern g1="f,f_f" g2="trademark" k="-75" />
+<hkern g1="f,f_f" g2="quoteleft,quotedblleft" k="-50" />
+<hkern g1="f,f_f" g2="quoteright,quotedblright" k="-55" />
+<hkern g1="f,f_f" g2="parenright,bracketright,braceright" k="-75" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="15" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="10" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="v" k="15" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="5" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="guillemotright,guilsinglright" k="-10" />
+<hkern g1="d,l,dcroat,lacute,lcommaaccent,lslash,f_l,fl,f_f_l" g2="t,uni0163,tcaron,tbar,uni021B" k="5" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="130" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="10" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="quoteleft,quotedblleft" k="-30" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="quoteright,quotedblright" k="-30" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="25" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="15" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-10" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="guillemotright,guilsinglright" k="-30" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="t,uni0163,tcaron,tbar,uni021B" k="10" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="v" k="20" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="x" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="-10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="t,uni0163,tcaron,tbar,uni021B" k="5" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="z,zacute,zdotaccent,zcaron" k="-15" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="v" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="10" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="13" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="30" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="10" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="5" />
+<hkern g1="x" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="13" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="65" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="13" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="15" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="v" k="10" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="10" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="x" k="15" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="parenright,bracketright,braceright" k="30" />
+<hkern g1="z,zacute,zdotaccent,zcaron" g2="z,zacute,zdotaccent,zcaron" k="-12" />
+<hkern g1="colon,semicolon" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="-20" />
+<hkern g1="colon,semicolon" g2="J,Jcircumflex" k="-20" />
+<hkern g1="colon,semicolon" g2="T,uni0162,Tcaron,Tbar,uni021A" k="55" />
+<hkern g1="colon,semicolon" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="25" />
+<hkern g1="colon,semicolon" g2="uni0410" k="-20" />
+<hkern g1="colon,semicolon" g2="uni0409,uni041B" k="-20" />
+<hkern g1="colon,semicolon" g2="uni0422" k="55" />
+<hkern g1="colon,semicolon" g2="uni0408" k="-20" />
+<hkern g1="colon,semicolon" g2="uni0402,uni040B,uni042A" k="30" />
+<hkern g1="colon,semicolon" g2="uni043B,uni0459" k="-20" />
+<hkern g1="colon,semicolon" g2="Alpha,uni0394,Lambda,Delta" k="-20" />
+<hkern g1="colon,semicolon" g2="Tau" k="55" />
+<hkern g1="colon,semicolon" g2="Upsilon,Upsilondieresis" k="25" />
+<hkern g1="colon,semicolon" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-95" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="J,Jcircumflex" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="T,uni0162,Tcaron,Tbar,uni021A" k="100" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="V" k="70" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="W" k="70" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Y,Yacute,Ydieresis" k="90" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="70" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="90" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="quoteleft,quotedblleft" k="88" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="quoteright,quotedblright" k="78" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="15" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="15" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="v" k="30" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="w" k="30" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="AE" k="-30" />
-<hkern g1="guillemotleft,guilsinglleft" g2="T" k="45" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="30" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="AE,AEacute" k="-30" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0410" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0409,uni041B" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0422" k="100" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0408" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0402,uni040B,uni042A" k="40" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni043B,uni0459" k="-15" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Alpha,uni0394,Lambda,Delta" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Tau" k="100" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Upsilon,Upsilondieresis" k="90" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="pi" k="101" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0427" k="85" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0442" k="65" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0447" k="50" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni044A" k="50" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Psi" k="55" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="gamma,nu" k="45" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="theta" k="15" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="15" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="tau" k="101" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="chi" k="35" />
+<hkern g1="guillemotleft,guilsinglleft" g2="T,uni0162,Tcaron,Tbar,uni021A" k="45" />
<hkern g1="guillemotleft,guilsinglleft" g2="X" k="-10" />
-<hkern g1="guillemotright,guilsinglright" g2="T" k="70" />
+<hkern g1="guillemotleft,guilsinglleft" g2="uni0422" k="65" />
+<hkern g1="guillemotleft,guilsinglleft" g2="uni0402,uni040B,uni042A" k="15" />
+<hkern g1="guillemotleft,guilsinglleft" g2="Tau" k="45" />
+<hkern g1="guillemotleft,guilsinglleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-130" />
+<hkern g1="guillemotright,guilsinglright" g2="T,uni0162,Tcaron,Tbar,uni021A" k="70" />
<hkern g1="guillemotright,guilsinglright" g2="X" k="15" />
-<hkern g1="guillemotright,guilsinglright" g2="Y,Yacute,Ydieresis" k="50" />
-<hkern g1="hyphen,endash,emdash" g2="T" k="50" />
-<hkern g1="parenleft,bracketleft,braceleft" g2="y,yacute,ydieresis" k="-30" />
-<hkern g1="quoteleft,quotedblleft" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="90" />
-<hkern g1="quoteleft,quotedblleft" g2="J" k="108" />
-<hkern g1="quoteleft,quotedblleft" g2="T" k="-25" />
-<hkern g1="quoteleft,quotedblleft" g2="t" k="-15" />
+<hkern g1="guillemotright,guilsinglright" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="50" />
+<hkern g1="guillemotright,guilsinglright" g2="uni0422" k="75" />
+<hkern g1="guillemotright,guilsinglright" g2="uni0402,uni040B,uni042A" k="15" />
+<hkern g1="guillemotright,guilsinglright" g2="Tau" k="70" />
+<hkern g1="guillemotright,guilsinglright" g2="Upsilon,Upsilondieresis" k="50" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="T,uni0162,Tcaron,Tbar,uni021A" k="50" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="uni0422" k="50" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="Tau" k="50" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="pi" k="30" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="tau" k="30" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="xi" k="-20" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-30" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-80" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="uni0443,uni045E" k="-30" />
+<hkern g1="parenright,bracketright,braceright" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-90" />
+<hkern g1="quoteleft,quotedblleft" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="90" />
+<hkern g1="quoteleft,quotedblleft" g2="J,Jcircumflex" k="108" />
+<hkern g1="quoteleft,quotedblleft" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-25" />
+<hkern g1="quoteleft,quotedblleft" g2="t,uni0163,tcaron,tbar,uni021B" k="-15" />
<hkern g1="quoteleft,quotedblleft" g2="quoteleft,quotedblleft" k="58" />
-<hkern g1="quoteleft,quotedblleft" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="35" />
-<hkern g1="quoteleft,quotedblleft" g2="AE" k="88" />
-<hkern g1="quoteright,quotedblright" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="90" />
-<hkern g1="quoteright,quotedblright" g2="J" k="107" />
-<hkern g1="quoteright,quotedblright" g2="T" k="-25" />
+<hkern g1="quoteleft,quotedblleft" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="35" />
+<hkern g1="quoteleft,quotedblleft" g2="AE,AEacute" k="88" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0410" k="90" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0409,uni041B" k="100" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0408" k="107" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0402,uni040B,uni042A" k="-20" />
+<hkern g1="quoteleft,quotedblleft" g2="uni043B,uni0459" k="75" />
+<hkern g1="quoteleft,quotedblleft" g2="Alpha,uni0394,Lambda,Delta" k="90" />
+<hkern g1="quoteleft,quotedblleft" g2="Tau" k="-25" />
+<hkern g1="quoteleft,quotedblleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-110" />
+<hkern g1="quoteleft,quotedblleft" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="35" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0414" k="40" />
+<hkern g1="quoteleft,quotedblleft" g2="rho" k="30" />
+<hkern g1="quoteleft,quotedblleft" g2="omega,omegatonos" k="40" />
+<hkern g1="quoteright,quotedblright" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="90" />
+<hkern g1="quoteright,quotedblright" g2="J,Jcircumflex" k="107" />
+<hkern g1="quoteright,quotedblright" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-25" />
<hkern g1="quoteright,quotedblright" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="83" />
<hkern g1="quoteright,quotedblright" g2="quoteright,quotedblright" k="58" />
-<hkern g1="quoteright,quotedblright" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="35" />
-<hkern g1="quoteright,quotedblright" g2="AE" k="88" />
-<hkern g1="quotedbl,quotesingle" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="60" />
-<hkern g1="quotedbl,quotesingle" g2="J" k="105" />
-<hkern g1="V" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="43" />
-<hkern g1="V" g2="J" k="70" />
+<hkern g1="quoteright,quotedblright" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="35" />
+<hkern g1="quoteright,quotedblright" g2="AE,AEacute" k="88" />
+<hkern g1="quoteright,quotedblright" g2="uni0410" k="90" />
+<hkern g1="quoteright,quotedblright" g2="uni0409,uni041B" k="105" />
+<hkern g1="quoteright,quotedblright" g2="uni0408" k="107" />
+<hkern g1="quoteright,quotedblright" g2="uni0402,uni040B,uni042A" k="-20" />
+<hkern g1="quoteright,quotedblright" g2="uni043B,uni0459" k="80" />
+<hkern g1="quoteright,quotedblright" g2="Alpha,uni0394,Lambda,Delta" k="90" />
+<hkern g1="quoteright,quotedblright" g2="Tau" k="-25" />
+<hkern g1="quoteright,quotedblright" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-110" />
+<hkern g1="quoteright,quotedblright" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="35" />
+<hkern g1="quoteright,quotedblright" g2="uni0414" k="45" />
+<hkern g1="quoteright,quotedblright" g2="rho" k="30" />
+<hkern g1="quoteright,quotedblright" g2="omega,omegatonos" k="40" />
+<hkern g1="quotedbl,quotesingle" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="60" />
+<hkern g1="quotedbl,quotesingle" g2="J,Jcircumflex" k="105" />
+<hkern g1="dcaron,lcaron" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="40" />
+<hkern g1="dcaron,lcaron" g2="quoteleft,quotedblleft" k="-40" />
+<hkern g1="dcaron,lcaron" g2="quoteright,quotedblright" k="-30" />
+<hkern g1="dcaron,lcaron" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="40" />
+<hkern g1="dcaron,lcaron" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="20" />
+<hkern g1="dcaron,lcaron" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="30" />
+<hkern g1="dcaron,lcaron" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="40" />
+<hkern g1="dcaron,lcaron" g2="parenright,bracketright,braceright" k="-64" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="colon,semicolon" k="-20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="quoteleft,quotedblleft" k="90" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="quoteright,quotedblright" k="90" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Tau" k="80" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Upsilon,Upsilondieresis" k="60" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="pi" k="43" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Psi" k="20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="gamma,nu" k="15" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="theta" k="10" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="tau" k="60" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Theta,Omicron,Phi" k="15" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="20" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Alpha,uni0394,Lambda,Delta" k="15" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Tau" k="28" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Upsilon,Upsilondieresis" k="30" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Chi" k="20" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="lambda" k="15" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="90" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="colon,semicolon" k="25" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="guillemotleft,guilsinglleft" k="50" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Alpha,uni0394,Lambda,Delta" k="60" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="pi" k="53" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="70" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="tau" k="50" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Theta,Omicron,Phi" k="30" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Chi" k="20" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Zeta" k="10" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="mu,etatonos,eta,uni03BC" k="65" />
+<hkern g1="Iotatonos,Iota,Iotadieresis" g2="pi" k="20" />
+<hkern g1="Iotatonos,Iota,Iotadieresis" g2="tau" k="30" />
+<hkern g1="Omegatonos,uni03A9,Omega" g2="Tau" k="25" />
+<hkern g1="Omegatonos,uni03A9,Omega" g2="Chi" k="20" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="pi" k="23" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="gamma,nu" k="20" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="tau" k="25" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="chi" k="25" />
+<hkern g1="Beta" g2="Tau" k="25" />
+<hkern g1="Beta" g2="Upsilon,Upsilondieresis" k="25" />
+<hkern g1="Beta" g2="pi" k="25" />
+<hkern g1="Beta" g2="gamma,nu" k="15" />
+<hkern g1="Beta" g2="tau" k="25" />
+<hkern g1="Beta" g2="lambda" k="20" />
+<hkern g1="Gamma" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="140" />
+<hkern g1="Gamma" g2="colon,semicolon" k="95" />
+<hkern g1="Gamma" g2="quoteleft,quotedblleft" k="-15" />
+<hkern g1="Gamma" g2="quoteright,quotedblright" k="-15" />
+<hkern g1="Gamma" g2="hyphen,endash,emdash,afii00208" k="123" />
+<hkern g1="Gamma" g2="guillemotleft,guilsinglleft" k="110" />
+<hkern g1="Gamma" g2="guillemotright,guilsinglright" k="100" />
+<hkern g1="Gamma" g2="Alpha,uni0394,Lambda,Delta" k="95" />
+<hkern g1="Gamma" g2="pi" k="128" />
+<hkern g1="Gamma" g2="gamma,nu" k="118" />
+<hkern g1="Gamma" g2="theta" k="15" />
+<hkern g1="Gamma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="143" />
+<hkern g1="Gamma" g2="tau" k="103" />
+<hkern g1="Gamma" g2="chi" k="123" />
+<hkern g1="Gamma" g2="rho" k="145" />
+<hkern g1="Gamma" g2="omega,omegatonos" k="145" />
+<hkern g1="Gamma" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="136" />
+<hkern g1="Gamma" g2="lambda" k="45" />
+<hkern g1="Gamma" g2="mu,etatonos,eta,uni03BC" k="143" />
+<hkern g1="Gamma" g2="uni03A9,Omega" k="25" />
+<hkern g1="Gamma" g2="beta" k="25" />
+<hkern g1="Gamma" g2="epsilontonos,epsilon" k="158" />
+<hkern g1="Gamma" g2="zeta" k="30" />
+<hkern g1="Gamma" g2="kappa" k="143" />
+<hkern g1="Gamma" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="130" />
+<hkern g1="Zeta" g2="Upsilon,Upsilondieresis" k="15" />
+<hkern g1="Zeta" g2="pi" k="43" />
+<hkern g1="Zeta" g2="gamma,nu" k="25" />
+<hkern g1="Zeta" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="25" />
+<hkern g1="Zeta" g2="tau" k="43" />
+<hkern g1="Zeta" g2="chi" k="25" />
+<hkern g1="Zeta" g2="rho" k="5" />
+<hkern g1="Zeta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="30" />
+<hkern g1="Zeta" g2="beta" k="10" />
+<hkern g1="Kappa" g2="Alpha,uni0394,Lambda,Delta" k="20" />
+<hkern g1="Kappa" g2="Tau" k="23" />
+<hkern g1="Kappa" g2="Upsilon,Upsilondieresis" k="40" />
+<hkern g1="Kappa" g2="pi" k="78" />
+<hkern g1="Kappa" g2="Psi" k="13" />
+<hkern g1="Kappa" g2="gamma,nu" k="45" />
+<hkern g1="Kappa" g2="theta" k="35" />
+<hkern g1="Kappa" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="25" />
+<hkern g1="Kappa" g2="tau" k="73" />
+<hkern g1="Kappa" g2="chi" k="55" />
+<hkern g1="Kappa" g2="rho" k="25" />
+<hkern g1="Kappa" g2="omega,omegatonos" k="8" />
+<hkern g1="Kappa" g2="Theta,Omicron,Phi" k="25" />
+<hkern g1="Kappa" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="35" />
+<hkern g1="Kappa" g2="Chi" k="20" />
+<hkern g1="Kappa" g2="lambda" k="15" />
+<hkern g1="Kappa" g2="mu,etatonos,eta,uni03BC" k="20" />
+<hkern g1="Kappa" g2="uni03A9,Omega" k="25" />
+<hkern g1="Kappa" g2="beta" k="30" />
+<hkern g1="Kappa" g2="epsilontonos,epsilon" k="15" />
+<hkern g1="Kappa" g2="zeta" k="25" />
+<hkern g1="Kappa" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="43" />
+<hkern g1="Rho" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="135" />
+<hkern g1="Rho" g2="Alpha,uni0394,Lambda,Delta" k="50" />
+<hkern g1="Rho" g2="Tau" k="10" />
+<hkern g1="Rho" g2="pi" k="-2" />
+<hkern g1="Rho" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="5" />
+<hkern g1="Rho" g2="tau" k="-7" />
+<hkern g1="Rho" g2="Chi" k="15" />
+<hkern g1="Rho" g2="Zeta" k="20" />
+<hkern g1="Rho" g2="Iota,Iotadieresis" k="20" />
+<hkern g1="Sigma" g2="pi" k="50" />
+<hkern g1="Sigma" g2="gamma,nu" k="35" />
+<hkern g1="Sigma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="Sigma" g2="tau" k="50" />
+<hkern g1="Sigma" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="25" />
+<hkern g1="Tau" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="100" />
+<hkern g1="Tau" g2="colon,semicolon" k="55" />
+<hkern g1="Tau" g2="copyright,registered" k="25" />
+<hkern g1="Tau" g2="quoteleft,quotedblleft" k="-25" />
+<hkern g1="Tau" g2="quoteright,quotedblright" k="-25" />
+<hkern g1="Tau" g2="hyphen,endash,emdash,afii00208" k="45" />
+<hkern g1="Tau" g2="guillemotleft,guilsinglleft" k="70" />
+<hkern g1="Tau" g2="guillemotright,guilsinglright" k="45" />
+<hkern g1="Tau" g2="Alpha,uni0394,Lambda,Delta" k="80" />
+<hkern g1="Tau" g2="pi" k="95" />
+<hkern g1="Tau" g2="gamma,nu" k="85" />
+<hkern g1="Tau" g2="theta" k="20" />
+<hkern g1="Tau" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="100" />
+<hkern g1="Tau" g2="tau" k="95" />
+<hkern g1="Tau" g2="chi" k="103" />
+<hkern g1="Tau" g2="rho" k="93" />
+<hkern g1="Tau" g2="omega,omegatonos" k="90" />
+<hkern g1="Tau" g2="Theta,Omicron,Phi" k="28" />
+<hkern g1="Tau" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="100" />
+<hkern g1="Tau" g2="Chi" k="10" />
+<hkern g1="Tau" g2="lambda" k="40" />
+<hkern g1="Tau" g2="mu,etatonos,eta,uni03BC" k="90" />
+<hkern g1="Tau" g2="uni03A9,Omega" k="25" />
+<hkern g1="Tau" g2="beta" k="35" />
+<hkern g1="Tau" g2="epsilontonos,epsilon" k="103" />
+<hkern g1="Tau" g2="zeta" k="10" />
+<hkern g1="Tau" g2="kappa" k="88" />
+<hkern g1="Tau" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="103" />
+<hkern g1="Chi" g2="Tau" k="10" />
+<hkern g1="Chi" g2="Upsilon,Upsilondieresis" k="20" />
+<hkern g1="Chi" g2="pi" k="60" />
+<hkern g1="Chi" g2="gamma,nu" k="25" />
+<hkern g1="Chi" g2="theta" k="15" />
+<hkern g1="Chi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="30" />
+<hkern g1="Chi" g2="tau" k="68" />
+<hkern g1="Chi" g2="chi" k="30" />
+<hkern g1="Chi" g2="rho" k="20" />
+<hkern g1="Chi" g2="omega,omegatonos" k="20" />
+<hkern g1="Chi" g2="Theta,Omicron,Phi" k="20" />
+<hkern g1="Chi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="30" />
+<hkern g1="Chi" g2="mu,etatonos,eta,uni03BC" k="15" />
+<hkern g1="Chi" g2="uni03A9,Omega" k="20" />
+<hkern g1="Chi" g2="beta" k="15" />
+<hkern g1="Chi" g2="zeta" k="15" />
+<hkern g1="Chi" g2="kappa" k="18" />
+<hkern g1="Chi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="35" />
+<hkern g1="Psi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="55" />
+<hkern g1="Psi" g2="Alpha,uni0394,Lambda,Delta" k="20" />
+<hkern g1="Psi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="5" />
+<hkern g1="Psi" g2="lambda" k="30" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="pi" k="35" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="gamma,nu" k="20" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="theta" k="18" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="18" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="tau" k="38" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="chi" k="25" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="xi" k="18" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="epsilontonos,epsilon" k="5" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="zeta" k="10" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="15" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="quoteleft,quotedblleft" k="35" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="quoteright,quotedblright" k="35" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="pi" k="8" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="gamma,nu" k="15" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="tau" k="20" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="chi" k="25" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="xi" k="10" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="lambda" k="15" />
+<hkern g1="omega,omegatonos" g2="quoteleft,quotedblleft" k="35" />
+<hkern g1="omega,omegatonos" g2="quoteright,quotedblright" k="40" />
+<hkern g1="omega,omegatonos" g2="pi" k="10" />
+<hkern g1="omega,omegatonos" g2="tau" k="15" />
+<hkern g1="omega,omegatonos" g2="chi" k="25" />
+<hkern g1="epsilontonos,epsilon" g2="pi" k="15" />
+<hkern g1="epsilontonos,epsilon" g2="gamma,nu" k="10" />
+<hkern g1="epsilontonos,epsilon" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="10" />
+<hkern g1="epsilontonos,epsilon" g2="chi" k="15" />
+<hkern g1="epsilontonos,epsilon" g2="xi" k="10" />
+<hkern g1="epsilontonos,epsilon" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="5" />
+<hkern g1="epsilontonos,epsilon" g2="lambda" k="10" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="pi" k="18" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="gamma,nu" k="5" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="tau" k="18" />
+<hkern g1="gamma,nu" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="50" />
+<hkern g1="gamma,nu" g2="tau" k="-5" />
+<hkern g1="chi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="chi" g2="quoteleft,quotedblleft" k="30" />
+<hkern g1="chi" g2="quoteright,quotedblright" k="25" />
+<hkern g1="chi" g2="pi" k="25" />
+<hkern g1="chi" g2="gamma,nu" k="30" />
+<hkern g1="chi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="35" />
+<hkern g1="chi" g2="tau" k="25" />
+<hkern g1="chi" g2="xi" k="35" />
+<hkern g1="chi" g2="omega,omegatonos" k="28" />
+<hkern g1="chi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="35" />
+<hkern g1="chi" g2="lambda" k="25" />
+<hkern g1="chi" g2="mu,etatonos,eta,uni03BC" k="15" />
+<hkern g1="chi" g2="epsilontonos,epsilon" k="25" />
+<hkern g1="chi" g2="zeta" k="30" />
+<hkern g1="chi" g2="kappa" k="20" />
+<hkern g1="chi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="23" />
+<hkern g1="zeta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="zeta" g2="hyphen,endash,emdash,afii00208" k="45" />
+<hkern g1="zeta" g2="pi" k="45" />
+<hkern g1="zeta" g2="gamma,nu" k="45" />
+<hkern g1="zeta" g2="theta" k="25" />
+<hkern g1="zeta" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="30" />
+<hkern g1="zeta" g2="tau" k="65" />
+<hkern g1="zeta" g2="omega,omegatonos" k="20" />
+<hkern g1="zeta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="25" />
+<hkern g1="zeta" g2="epsilontonos,epsilon" k="13" />
+<hkern g1="zeta" g2="kappa" k="25" />
+<hkern g1="zeta" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="20" />
+<hkern g1="theta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="15" />
+<hkern g1="theta" g2="gamma,nu" k="15" />
+<hkern g1="kappa" g2="hyphen,endash,emdash,afii00208" k="15" />
+<hkern g1="kappa" g2="pi" k="23" />
+<hkern g1="kappa" g2="gamma,nu" k="25" />
+<hkern g1="kappa" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="25" />
+<hkern g1="kappa" g2="tau" k="18" />
+<hkern g1="kappa" g2="chi" k="15" />
+<hkern g1="kappa" g2="xi" k="20" />
+<hkern g1="kappa" g2="omega,omegatonos" k="10" />
+<hkern g1="kappa" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="13" />
+<hkern g1="kappa" g2="epsilontonos,epsilon" k="15" />
+<hkern g1="kappa" g2="zeta" k="15" />
+<hkern g1="lambda" g2="quoteleft,quotedblleft" k="70" />
+<hkern g1="lambda" g2="quoteright,quotedblright" k="70" />
+<hkern g1="lambda" g2="pi" k="60" />
+<hkern g1="lambda" g2="gamma,nu" k="33" />
+<hkern g1="lambda" g2="theta" k="18" />
+<hkern g1="lambda" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="18" />
+<hkern g1="lambda" g2="tau" k="78" />
+<hkern g1="lambda" g2="chi" k="40" />
+<hkern g1="lambda" g2="xi" k="30" />
+<hkern g1="lambda" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="13" />
+<hkern g1="lambda" g2="zeta" k="20" />
+<hkern g1="xi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-17" />
+<hkern g1="xi" g2="hyphen,endash,emdash,afii00208" k="10" />
+<hkern g1="xi" g2="pi" k="10" />
+<hkern g1="xi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="15" />
+<hkern g1="xi" g2="tau" k="10" />
+<hkern g1="xi" g2="omega,omegatonos" k="10" />
+<hkern g1="xi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="13" />
+<hkern g1="xi" g2="epsilontonos,epsilon" k="10" />
+<hkern g1="sigma" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="40" />
+<hkern g1="sigma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="10" />
+<hkern g1="sigma" g2="xi" k="18" />
+<hkern g1="sigma" g2="omega,omegatonos" k="15" />
+<hkern g1="sigma" g2="lambda" k="20" />
+<hkern g1="sigma" g2="kappa" k="20" />
+<hkern g1="sigma1" g2="pi" k="-10" />
+<hkern g1="sigma1" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="15" />
+<hkern g1="sigma1" g2="tau" k="-5" />
+<hkern g1="sigma1" g2="xi" k="20" />
+<hkern g1="sigma1" g2="omega,omegatonos" k="15" />
+<hkern g1="sigma1" g2="lambda" k="18" />
+<hkern g1="tau" g2="hyphen,endash,emdash,afii00208" k="15" />
+<hkern g1="tau" g2="pi" k="-5" />
+<hkern g1="tau" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="13" />
+<hkern g1="tau" g2="tau" k="-5" />
+<hkern g1="tau" g2="xi" k="13" />
+<hkern g1="tau" g2="omega,omegatonos" k="15" />
+<hkern g1="tau" g2="lambda" k="20" />
+<hkern g1="tau" g2="epsilontonos,epsilon" k="20" />
+<hkern g1="tau" g2="zeta" k="10" />
+<hkern g1="tau" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="15" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0410" k="20" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0422" k="23" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0408" k="20" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0442" k="30" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0443,uni045E" k="28" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0404,uni041E,uni0421,uni0424" k="20" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0425" k="20" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0405" k="25" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0430" k="30" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="25" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0455" k="30" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="quoteleft,quotedblleft" k="25" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="quoteright,quotedblright" k="25" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="hyphen,endash,emdash,afii00208" k="-20" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0422" k="80" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0402,uni040B,uni042A" k="30" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0417,uni042D" k="-7" />
+<hkern g1="uni0411,uni0412,uni0417" g2="uni0422" k="25" />
+<hkern g1="uni0411,uni0412,uni0417" g2="uni0408" k="30" />
+<hkern g1="uni0403,uni0413,uni0490" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="170" />
+<hkern g1="uni0403,uni0413,uni0490" g2="colon,semicolon" k="100" />
+<hkern g1="uni0403,uni0413,uni0490" g2="hyphen,endash,emdash,afii00208" k="110" />
+<hkern g1="uni0403,uni0413,uni0490" g2="guillemotleft,guilsinglleft" k="120" />
+<hkern g1="uni0403,uni0413,uni0490" g2="guillemotright,guilsinglright" k="100" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0410" k="95" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0409,uni041B" k="98" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0408" k="118" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0402,uni040B,uni042A" k="-10" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni043B,uni0459" k="163" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0442" k="130" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0447" k="123" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni044A" k="145" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0443,uni045E" k="130" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0414" k="80" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0404,uni041E,uni0421,uni0424" k="30" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0405" k="18" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0430" k="130" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="143" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0455" k="140" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0417,uni042D" k="13" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni042F" k="30" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0431" k="35" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0434" k="163" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0436" k="135" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0437,uni044D" k="140" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="143" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0445" k="125" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni044F" k="138" />
+<hkern g1="uni0400,uni0401,uni0415" g2="uni0409,uni041B" k="18" />
+<hkern g1="uni0400,uni0401,uni0415" g2="uni040E,uni0423" k="-7" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0410" k="15" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0409,uni041B" k="33" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0422" k="28" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0408" k="10" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0425" k="20" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0416" k="10" />
+<hkern g1="uni0414,uni0426,uni0429" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-25" />
+<hkern g1="uni0414,uni0426,uni0429" g2="colon,semicolon" k="-25" />
+<hkern g1="uni0414,uni0426,uni0429" g2="guillemotright,guilsinglright" k="-25" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0410" k="-22" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0409,uni041B" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0408" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni043B,uni0459" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0427" k="-5" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0443,uni045E" k="-25" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0414" k="-35" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0425" k="-5" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0417,uni042D" k="-17" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni042F" k="-12" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0434" k="-25" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0436" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0437,uni044D" k="-10" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni040E,uni0423" k="-12" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0416" k="-5" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0400,uni0401,uni0403,uni040A,uni040C,uni040D,uni040F,uni0411,uni0412,uni0413,uni0415,uni0418,uni0419,uni041A,uni041C,uni041D,uni041F,uni0420,uni0426,uni0428,uni0429,uni042B,uni042C,uni042E,uni0490" k="-5" />
+<hkern g1="uni0404,uni0421" g2="uni0408" k="10" />
+<hkern g1="uni0404,uni0421" g2="uni0414" k="-5" />
+<hkern g1="uni0404,uni0421" g2="uni0425" k="15" />
+<hkern g1="uni040E,uni0423" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="123" />
+<hkern g1="uni040E,uni0423" g2="colon,semicolon" k="55" />
+<hkern g1="uni040E,uni0423" g2="uni0410" k="60" />
+<hkern g1="uni040E,uni0423" g2="uni0409,uni041B" k="90" />
+<hkern g1="uni040E,uni0423" g2="uni0408" k="90" />
+<hkern g1="uni040E,uni0423" g2="uni043B,uni0459" k="100" />
+<hkern g1="uni040E,uni0423" g2="uni0427" k="-10" />
+<hkern g1="uni040E,uni0423" g2="uni0442" k="30" />
+<hkern g1="uni040E,uni0423" g2="uni0447" k="35" />
+<hkern g1="uni040E,uni0423" g2="uni044A" k="40" />
+<hkern g1="uni040E,uni0423" g2="uni0443,uni045E" k="40" />
+<hkern g1="uni040E,uni0423" g2="uni0414" k="70" />
+<hkern g1="uni040E,uni0423" g2="uni0404,uni041E,uni0421,uni0424" k="15" />
+<hkern g1="uni040E,uni0423" g2="uni0425" k="5" />
+<hkern g1="uni040E,uni0423" g2="uni0405" k="13" />
+<hkern g1="uni040E,uni0423" g2="uni0430" k="65" />
+<hkern g1="uni040E,uni0423" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="55" />
+<hkern g1="uni040E,uni0423" g2="uni0455" k="70" />
+<hkern g1="uni040E,uni0423" g2="uni0417,uni042D" k="5" />
+<hkern g1="uni040E,uni0423" g2="uni042F" k="15" />
+<hkern g1="uni040E,uni0423" g2="uni0434" k="95" />
+<hkern g1="uni040E,uni0423" g2="uni0436" k="50" />
+<hkern g1="uni040E,uni0423" g2="uni0437,uni044D" k="70" />
+<hkern g1="uni040E,uni0423" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="50" />
+<hkern g1="uni040E,uni0423" g2="uni0445" k="55" />
+<hkern g1="uni040E,uni0423" g2="uni044F" k="55" />
+<hkern g1="uni040E,uni0423" g2="uni0416" k="25" />
+<hkern g1="uni0410" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-10" />
+<hkern g1="uni0410" g2="colon,semicolon" k="-10" />
+<hkern g1="uni0410" g2="quoteleft,quotedblleft" k="90" />
+<hkern g1="uni0410" g2="quoteright,quotedblright" k="90" />
+<hkern g1="uni0410" g2="uni0422" k="80" />
+<hkern g1="uni0410" g2="uni0402,uni040B,uni042A" k="45" />
+<hkern g1="uni0410" g2="uni0447" k="30" />
+<hkern g1="uni0410" g2="uni044A" k="43" />
+<hkern g1="uni0410" g2="uni0404,uni041E,uni0421,uni0424" k="15" />
+<hkern g1="uni0410" g2="uni0430" k="5" />
+<hkern g1="uni0410" g2="uni0416" k="10" />
+<hkern g1="uni0420" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="135" />
+<hkern g1="uni0420" g2="uni0410" k="50" />
+<hkern g1="uni0420" g2="uni0409,uni041B" k="63" />
+<hkern g1="uni0420" g2="uni0422" k="10" />
+<hkern g1="uni0420" g2="uni0408" k="75" />
+<hkern g1="uni0420" g2="uni043B,uni0459" k="60" />
+<hkern g1="uni0420" g2="uni0427" k="-17" />
+<hkern g1="uni0420" g2="uni0447" k="-12" />
+<hkern g1="uni0420" g2="uni0414" k="45" />
+<hkern g1="uni0420" g2="uni0425" k="15" />
+<hkern g1="uni0420" g2="uni0405" k="-12" />
+<hkern g1="uni0420" g2="uni0430" k="10" />
+<hkern g1="uni0420" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="5" />
+<hkern g1="uni0420" g2="uni0434" k="30" />
+<hkern g1="uni0402,uni040B" g2="quoteleft,quotedblleft" k="45" />
+<hkern g1="uni0402,uni040B" g2="quoteright,quotedblright" k="45" />
+<hkern g1="uni0402,uni040B" g2="hyphen,endash,emdash,afii00208" k="-20" />
+<hkern g1="uni0402,uni040B" g2="parenright,bracketright,braceright" k="30" />
+<hkern g1="uni0402,uni040B" g2="uni0422" k="65" />
+<hkern g1="uni0422" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="100" />
+<hkern g1="uni0422" g2="colon,semicolon" k="55" />
+<hkern g1="uni0422" g2="hyphen,endash,emdash,afii00208" k="50" />
+<hkern g1="uni0422" g2="guillemotleft,guilsinglleft" k="75" />
+<hkern g1="uni0422" g2="guillemotright,guilsinglright" k="65" />
+<hkern g1="uni0422" g2="uni0410" k="80" />
+<hkern g1="uni0422" g2="uni0409,uni041B" k="75" />
+<hkern g1="uni0422" g2="uni0408" k="70" />
+<hkern g1="uni0422" g2="uni043B,uni0459" k="128" />
+<hkern g1="uni0422" g2="uni0427" k="-7" />
+<hkern g1="uni0422" g2="uni0442" k="90" />
+<hkern g1="uni0422" g2="uni0447" k="85" />
+<hkern g1="uni0422" g2="uni044A" k="90" />
+<hkern g1="uni0422" g2="uni0443,uni045E" k="70" />
+<hkern g1="uni0422" g2="uni0414" k="65" />
+<hkern g1="uni0422" g2="uni0404,uni041E,uni0421,uni0424" k="28" />
+<hkern g1="uni0422" g2="uni0425" k="10" />
+<hkern g1="uni0422" g2="uni0405" k="20" />
+<hkern g1="uni0422" g2="uni0430" k="100" />
+<hkern g1="uni0422" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="100" />
+<hkern g1="uni0422" g2="uni0455" k="109" />
+<hkern g1="uni0422" g2="uni042F" k="15" />
+<hkern g1="uni0422" g2="uni0431" k="30" />
+<hkern g1="uni0422" g2="uni0434" k="113" />
+<hkern g1="uni0422" g2="uni0436" k="90" />
+<hkern g1="uni0422" g2="uni0437,uni044D" k="100" />
+<hkern g1="uni0422" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="90" />
+<hkern g1="uni0422" g2="uni0445" k="100" />
+<hkern g1="uni0422" g2="uni044F" k="90" />
+<hkern g1="uni0425" g2="uni0422" k="10" />
+<hkern g1="uni0425" g2="uni0404,uni041E,uni0421,uni0424" k="20" />
+<hkern g1="uni0425" g2="uni0405" k="10" />
+<hkern g1="uni0425" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="30" />
+<hkern g1="uni0425" g2="uni040E,uni0423" k="-5" />
+<hkern g1="uni0405" g2="uni0409,uni041B" k="18" />
+<hkern g1="uni0405" g2="uni0422" k="20" />
+<hkern g1="uni0405" g2="uni0408" k="25" />
+<hkern g1="uni0405" g2="uni0442" k="20" />
+<hkern g1="uni0405" g2="uni0425" k="10" />
+<hkern g1="uni0405" g2="uni0434" k="18" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0442" k="15" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0443,uni045E" k="5" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0434" k="20" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0436" k="15" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0445" k="13" />
+<hkern g1="uni0433,uni0453,uni0491" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="100" />
+<hkern g1="uni0433,uni0453,uni0491" g2="colon,semicolon" k="-20" />
+<hkern g1="uni0433,uni0453,uni0491" g2="quoteleft,quotedblleft" k="-25" />
+<hkern g1="uni0433,uni0453,uni0491" g2="quoteright,quotedblright" k="-20" />
+<hkern g1="uni0433,uni0453,uni0491" g2="hyphen,endash,emdash,afii00208" k="60" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni043B,uni0459" k="65" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0442" k="-25" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni044A" k="-22" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0430" k="15" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="15" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0434" k="65" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni044F" k="5" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0430" k="15" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="15" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0455" k="10" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0431" k="15" />
+<hkern g1="uni0434,uni0446,uni0449" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="uni0434,uni0446,uni0449" g2="colon,semicolon" k="-20" />
+<hkern g1="uni0434,uni0446,uni0449" g2="guillemotright,guilsinglright" k="-10" />
+<hkern g1="uni0434,uni0446,uni0449" g2="parenright,bracketright,braceright" k="-10" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni043B,uni0459" k="-20" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0443,uni045E" k="-22" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0431" k="-7" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0434" k="-25" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0436" k="-10" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0437,uni044D" k="-5" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="-5" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0445" k="-7" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni044F" k="-7" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni043B,uni0459" k="3" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni0442" k="35" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni044A" k="45" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni0434" k="-5" />
+<hkern g1="uni0430" g2="uni0442" k="13" />
+<hkern g1="uni0430" g2="uni044A" k="15" />
+<hkern g1="uni0443,uni045E" g2="parenright,bracketright,braceright" k="30" />
+<hkern g1="uni0443,uni045E" g2="uni043B,uni0459" k="40" />
+<hkern g1="uni0443,uni045E" g2="uni0430" k="13" />
+<hkern g1="uni0443,uni045E" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="20" />
+<hkern g1="uni0443,uni045E" g2="uni0455" k="15" />
+<hkern g1="uni0443,uni045E" g2="uni0434" k="20" />
+<hkern g1="uni0443,uni045E" g2="uni0445" k="15" />
+<hkern g1="uni0443,uni045E" g2="uni044F" k="13" />
+<hkern g1="uni0442" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="65" />
+<hkern g1="uni0442" g2="uni043B,uni0459" k="50" />
+<hkern g1="uni0442" g2="uni0442" k="-20" />
+<hkern g1="uni0442" g2="uni0447" k="-5" />
+<hkern g1="uni0442" g2="uni044A" k="-20" />
+<hkern g1="uni0442" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="15" />
+<hkern g1="uni0442" g2="uni0434" k="20" />
+<hkern g1="uni0445" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="13" />
+<hkern g1="uni0455" g2="uni0445" k="10" />
+<hkern g1="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" g2="tau" k="5" />
+<hkern g1="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" g2="chi" k="15" />
+<hkern g1="uni0408" g2="uni0410" k="10" />
+<hkern g1="uni0408" g2="uni0409,uni041B" k="20" />
+<hkern g1="uni0408" g2="uni0408" k="30" />
+<hkern g1="uni0408" g2="uni043B,uni0459" k="25" />
+<hkern g1="uni0408" g2="uni0427" k="-10" />
+<hkern g1="uni0408" g2="uni0414" k="40" />
+<hkern g1="uni0408" g2="uni0425" k="10" />
+<hkern g1="uni0408" g2="uni0434" k="30" />
+<hkern g1="V" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="43" />
+<hkern g1="V" g2="J,Jcircumflex" k="70" />
<hkern g1="V" g2="X" k="10" />
-<hkern g1="V" g2="Y,Yacute,Ydieresis" k="20" />
+<hkern g1="V" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="20" />
<hkern g1="V" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="70" />
-<hkern g1="V" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="15" />
-<hkern g1="V" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="30" />
-<hkern g1="V" g2="t" k="13" />
-<hkern g1="V" g2="z" k="20" />
+<hkern g1="V" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="15" />
+<hkern g1="V" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="30" />
+<hkern g1="V" g2="t,uni0163,tcaron,tbar,uni021B" k="13" />
+<hkern g1="V" g2="z,zacute,zdotaccent,zcaron" k="20" />
<hkern g1="V" g2="copyright,registered" k="10" />
-<hkern g1="V" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="30" />
-<hkern g1="V" g2="S" k="5" />
-<hkern g1="V" g2="m,n,p,r,ntilde" k="30" />
-<hkern g1="V" g2="s" k="30" />
-<hkern g1="V" g2="u,ugrave,uacute,ucircumflex,udieresis" k="30" />
+<hkern g1="V" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="30" />
+<hkern g1="V" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="5" />
+<hkern g1="V" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="30" />
+<hkern g1="V" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="30" />
+<hkern g1="V" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="30" />
<hkern g1="V" g2="x" k="15" />
-<hkern g1="V" g2="y,yacute,ydieresis" k="10" />
-<hkern g1="V" g2="AE" k="30" />
-<hkern g1="V" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="10" />
-<hkern g1="V" g2="b,h,k,l,germandbls,thorn" k="15" />
+<hkern g1="V" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="V" g2="AE,AEacute" k="30" />
+<hkern g1="V" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="10" />
+<hkern g1="V" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="15" />
+<hkern g1="pi" g2="hyphen,endash,emdash,afii00208" k="15" />
+<hkern g1="pi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="3" />
+<hkern g1="pi" g2="xi" k="13" />
+<hkern g1="pi" g2="lambda" k="20" />
+<hkern g1="pi" g2="epsilontonos,epsilon" k="20" />
+<hkern g1="pi" g2="zeta" k="10" />
+<hkern g1="pi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="15" />
<hkern g1="v" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="30" />
-<hkern g1="v" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="13" />
-<hkern g1="v" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="10" />
-<hkern g1="v" g2="s" k="10" />
+<hkern g1="v" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="13" />
+<hkern g1="v" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="10" />
+<hkern g1="v" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="10" />
<hkern g1="v" g2="v" k="5" />
-<hkern g1="v" g2="y,yacute,ydieresis" k="5" />
+<hkern g1="v" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="5" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="45" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="J,Jcircumflex" k="65" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-50" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="V" k="-40" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-32" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="X" k="-32" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="-40" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="13" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-30" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="Z,Zacute,Zdotaccent,Zcaron" k="-22" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="-30" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="B,D,E,F,H,K,L,M,N,P,R,Egrave,Eacute,Ecircumflex,Edieresis,Eth,Ntilde,Thorn,Dcaron,Dcroat,Emacron,Ebreve,Edotaccent,Eogonek,Ecaron,Hcircumflex,Hbar,Kcommaaccent,Lacute,Lcommaaccent,Lcaron,Ldot,Lslash,Nacute,Ncommaaccent,Ncaron,Eng,Racute,Rcommaaccent,Rcaron,Eszett,Edotbelow,Ehookabove,Etilde,Ecircumflexacute,Ecircumflexgrave,Ecircumflexhookabove,Ecircumflextilde,Ecircumflexdotbelow" k="-30" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="-10" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="-45" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="z,zacute,zdotaccent,zcaron" k="-40" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="-10" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="-10" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="-15" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="-12" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="-10" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="v" k="-25" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="-30" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="x" k="-35" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-35" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-42" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="-20" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="38" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="J,Jcircumflex" k="75" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-45" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="V" k="-45" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-40" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="X" k="-35" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="-45" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="15" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-25" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="Z,Zacute,Zdotaccent,Zcaron" k="-25" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="-35" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="B,D,E,F,H,K,L,M,N,P,R,Egrave,Eacute,Ecircumflex,Edieresis,Eth,Ntilde,Thorn,Dcaron,Dcroat,Emacron,Ebreve,Edotaccent,Eogonek,Ecaron,Hcircumflex,Hbar,Kcommaaccent,Lacute,Lcommaaccent,Lcaron,Ldot,Lslash,Nacute,Ncommaaccent,Ncaron,Eng,Racute,Rcommaaccent,Rcaron,Eszett,Edotbelow,Ehookabove,Etilde,Ecircumflexacute,Ecircumflexgrave,Ecircumflexhookabove,Ecircumflextilde,Ecircumflexdotbelow" k="-30" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="-40" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="z,zacute,zdotaccent,zcaron" k="-25" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="-12" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="-5" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="-7" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="-15" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="-15" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="v" k="-40" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="-30" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="x" k="-27" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-35" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-40" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="-15" />
+<hkern g1="longs" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="8" />
+<hkern g1="longs" g2="t,uni0163,tcaron,tbar,uni021B" k="5" />
+<hkern g1="longs" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="15" />
+<hkern g1="longs" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="-15" />
+<hkern g1="longs" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="8" />
+<hkern g1="longs" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="5" />
+<hkern g1="longs" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="-7" />
</font>
</defs></svg> \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.ttf b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.ttf
index 421a81026..71aa164c4 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.ttf
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.ttf
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.woff b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.woff
index 7633468f3..ea3d3a436 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.woff
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Medium-webfont.woff
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.eot b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.eot
index b020e058c..9df1d1bc3 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.eot
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.eot
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.svg b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.svg
index 1e2cffdc2..e1f76a38a 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.svg
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.svg
@@ -3,21 +3,20 @@
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
-<font id="clear_sansregular" horiz-adv-x="555" >
+<font id="clear_sansregular" horiz-adv-x="1085" >
<font-face units-per-em="2048" ascent="1489" descent="-559" />
<missing-glyph horiz-adv-x="553" />
-<glyph unicode="&#xfb01;" horiz-adv-x="1143" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM776 1315q0 53 26 77.5t85 24.5q61 0 87 -23.5t26 -78.5q0 -60 -27 -81.5t-86 -21.5q-63 0 -87 27 t-24 76zM801 0v1049h172v-1049h-172z" />
-<glyph unicode="&#xfb02;" horiz-adv-x="1159" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM809 0v1489h172v-1489h-172z" />
-<glyph unicode="&#xfb03;" horiz-adv-x="1776" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM676 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11 q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM1409 1315q0 53 26 77.5t85 24.5q61 0 87 -23.5t26 -78.5q0 -60 -27 -81.5t-86 -21.5q-63 0 -87 27t-24 76zM1434 0v1049h172v-1049h-172z" />
-<glyph unicode="&#xfb04;" horiz-adv-x="1792" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM676 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11 q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM1442 0v1489h172v-1489h-172z" />
-<glyph horiz-adv-x="0" />
-<glyph unicode="&#xd;" horiz-adv-x="553" />
+<glyph unicode="ff" horiz-adv-x="1266" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM676 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11 q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154z" />
+<glyph unicode="fi" horiz-adv-x="1143" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM776 1315q0 53 26 77.5t85 24.5q61 0 87 -23.5t26 -78.5q0 -60 -27 -81.5t-86 -21.5q-63 0 -87 27 t-24 76zM801 0v1049h172v-1049h-172z" />
+<glyph unicode="fl" horiz-adv-x="1159" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM809 0v1489h172v-1489h-172z" />
+<glyph unicode="ffi" horiz-adv-x="1776" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM676 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11 q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM1409 1315q0 53 26 77.5t85 24.5q61 0 87 -23.5t26 -78.5q0 -60 -27 -81.5t-86 -21.5q-63 0 -87 27t-24 76zM1434 0v1049h172v-1049h-172z" />
+<glyph unicode="ffl" horiz-adv-x="1792" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM676 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11 q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM1442 0v1489h172v-1489h-172z" />
<glyph horiz-adv-x="0" />
<glyph horiz-adv-x="0" />
<glyph unicode=" " horiz-adv-x="553" />
<glyph unicode="&#x09;" horiz-adv-x="553" />
<glyph unicode="&#xa0;" horiz-adv-x="553" />
-<glyph unicode="!" d="M156 98q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5zM178 1384h199l-25 -985h-145z" />
+<glyph unicode="!" horiz-adv-x="555" d="M156 98q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5zM178 1384h199l-25 -985h-145z" />
<glyph unicode="&#x22;" horiz-adv-x="924" d="M174 1384h209l-41 -550h-127zM541 1384h209l-41 -550h-127z" />
<glyph unicode="#" horiz-adv-x="1446" d="M102 393v123h289l96 352h-268v125h301l105 391h129l-105 -391h309l107 391h129l-104 -391h253v-125h-286l-94 -352h264v-123h-299l-105 -393h-129l103 393h-310l-104 -393h-129l104 393h-256zM520 516h311l97 352h-312z" />
<glyph unicode="$" horiz-adv-x="1264" d="M174 313l139 82q92 -159 269 -178v426q-217 49 -299 124.5t-82 209.5q0 148 105 236.5t276 95.5v104h129v-104q89 -4 159.5 -31t123.5 -71t106 -128l-142 -82q-87 157 -247 170v-391q219 -52 308 -134.5t89 -219.5q0 -151 -103.5 -244t-293.5 -102v-209h-129v209 q-271 13 -408 237zM375 983q0 -76 59.5 -115t147.5 -61v360q-207 -15 -207 -184zM711 217q103 10 164 60.5t61 134.5q0 77 -53.5 123.5t-171.5 78.5v-397z" />
@@ -28,9 +27,9 @@
<glyph unicode=")" horiz-adv-x="797" d="M82 -395q196 193 297.5 434.5t101.5 521.5q0 256 -93 504t-306 455h194q189 -218 278 -446t89 -513q0 -275 -85.5 -501t-281.5 -455h-194z" />
<glyph unicode="*" horiz-adv-x="948" d="M92 1001l285 156l-285 156l58 96l270 -158l-2 269h112l-4 -269l273 158l57 -98l-285 -154l285 -156l-57 -96l-271 158l2 -268h-112l2 268l-270 -160z" />
<glyph unicode="+" horiz-adv-x="1427" d="M164 514v143h477v480h143v-480h480v-143h-480v-477h-143v477h-477z" />
-<glyph unicode="," d="M156 98q0 56 27.5 84.5t92.5 28.5q66 0 94.5 -34t28.5 -99q0 -123 -36.5 -223.5t-75.5 -147.5h-105q37 46 60.5 125.5t23.5 153.5q-59 0 -84.5 26.5t-25.5 85.5z" />
+<glyph unicode="," horiz-adv-x="555" d="M156 98q0 56 27.5 84.5t92.5 28.5q66 0 94.5 -34t28.5 -99q0 -123 -36.5 -223.5t-75.5 -147.5h-105q37 46 60.5 125.5t23.5 153.5q-59 0 -84.5 26.5t-25.5 85.5z" />
<glyph unicode="-" horiz-adv-x="827" d="M102 440v172h623v-172h-623z" />
-<glyph unicode="." d="M156 98q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5z" />
+<glyph unicode="." horiz-adv-x="555" d="M156 98q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5z" />
<glyph unicode="/" horiz-adv-x="991" d="M8 -299l715 1819h168l-717 -1819h-166z" />
<glyph unicode="0" horiz-adv-x="1264" d="M125 688q0 371 123 545t383 174q262 0 385 -173t123 -544t-124 -546t-384 -175t-383 174t-123 545zM319 688q0 -289 76 -424t236 -135q162 0 237.5 135t75.5 426q0 289 -75.5 423t-237.5 134q-160 0 -236 -135t-76 -424z" />
<glyph unicode="1" horiz-adv-x="1264" d="M281 989v129q136 8 205.5 32t108.5 73t69 161h133v-1384h-181v989h-335z" />
@@ -42,8 +41,8 @@
<glyph unicode="7" horiz-adv-x="1264" d="M139 1217v167h967v-172l-528 -1212h-205l547 1217h-781z" />
<glyph unicode="8" horiz-adv-x="1188" d="M111 356q0 267 299 379q-116 57 -163 98.5t-75.5 96.5t-28.5 129q0 168 115 261t338 93q219 0 335 -90t116 -262q0 -72 -30 -129.5t-80 -101.5t-159 -95q158 -69 229.5 -159t71.5 -220q0 -194 -131 -289.5t-352 -95.5q-240 0 -362.5 98.5t-122.5 286.5zM295 354 q0 -106 73.5 -169.5t227.5 -63.5q156 0 227.5 65.5t71.5 169.5q0 62 -28 111t-84.5 91t-186.5 101q-128 -53 -183 -94t-86.5 -93t-31.5 -118zM328 1063q0 -54 25 -90.5t79.5 -73.5t163.5 -88q125 51 195.5 108.5t70.5 137.5q0 94 -66.5 151.5t-199.5 57.5 q-141 0 -204.5 -57.5t-63.5 -145.5z" />
<glyph unicode="9" horiz-adv-x="1188" d="M111 936q0 229 124.5 353t342.5 124q260 0 373.5 -173t113.5 -501q0 -247 -61 -416.5t-184 -260.5t-306 -91q-228 0 -373 135l113 142q59 -58 120.5 -87.5t139.5 -29.5q158 0 244 113.5t106 359.5q-59 -41 -146 -73.5t-186 -32.5q-192 0 -306.5 106.5t-114.5 331.5z M295 942q0 -283 283 -283q77 0 156 28t132 61q0 189 -28.5 288t-90 158t-169.5 59q-138 0 -210.5 -80.5t-72.5 -230.5z" />
-<glyph unicode=":" d="M156 98q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5zM156 936q0 59 27.5 86t92.5 27q68 0 95.5 -27t27.5 -86q0 -64 -29.5 -88.5t-93.5 -24.5q-71 0 -95.5 30t-24.5 83z" />
-<glyph unicode=";" d="M156 98q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -34t27.5 -99q0 -123 -36.5 -223.5t-75.5 -147.5h-105q36 46 60 128t24 151q-59 0 -84.5 26.5t-25.5 85.5zM156 936q0 59 27.5 86t92.5 27q68 0 95.5 -27t27.5 -86q0 -64 -29.5 -88.5t-93.5 -24.5q-71 0 -95.5 30t-24.5 83z " />
+<glyph unicode=":" horiz-adv-x="555" d="M156 98q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5zM156 936q0 59 27.5 86t92.5 27q68 0 95.5 -27t27.5 -86q0 -64 -29.5 -88.5t-93.5 -24.5q-71 0 -95.5 30t-24.5 83z" />
+<glyph unicode=";" horiz-adv-x="555" d="M156 98q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -34t27.5 -99q0 -123 -36.5 -223.5t-75.5 -147.5h-105q36 46 60 128t24 151q-59 0 -84.5 26.5t-25.5 85.5zM156 936q0 59 27.5 86t92.5 27q68 0 95.5 -27t27.5 -86q0 -64 -29.5 -88.5t-93.5 -24.5q-71 0 -95.5 30t-24.5 83z " />
<glyph unicode="&#x3c;" horiz-adv-x="1427" d="M164 524v125l1100 463v-156l-902 -370l902 -369v-156z" />
<glyph unicode="=" horiz-adv-x="1427" d="M164 283v143h1100v-143h-1100zM164 745v144h1100v-144h-1100z" />
<glyph unicode="&#x3e;" horiz-adv-x="1427" d="M164 61v156l899 369l-899 370v156l1100 -463v-125z" />
@@ -80,7 +79,7 @@
<glyph unicode="]" horiz-adv-x="805" d="M123 -262h330v1618h-330v133h487v-1884h-487v133z" />
<glyph unicode="^" horiz-adv-x="1243" d="M143 594l404 790h149l404 -790h-152l-325 637l-328 -637h-152z" />
<glyph unicode="_" horiz-adv-x="1024" d="M-10 -154h1044v-102h-1044v102z" />
-<glyph unicode="`" horiz-adv-x="1085" d="M268 1569h236l178 -361h-141z" />
+<glyph unicode="`" d="M268 1569h236l178 -361h-141z" />
<glyph unicode="a" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM287 299 q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z" />
<glyph unicode="b" horiz-adv-x="1174" d="M170 0v1489h172v-545q59 57 142 96t178 39q194 0 294.5 -142t100.5 -405q0 -265 -108.5 -414t-303.5 -149q-84 0 -164 34t-139 83v-86h-172zM342 236q57 -48 132 -80.5t147 -32.5q116 0 187 98t71 307q0 210 -64 304t-186 94q-80 0 -155 -41t-132 -94v-555z" />
<glyph unicode="c" horiz-adv-x="1030" d="M117 522q0 274 116 415.5t342 141.5q259 0 369 -192l-141 -86q-39 61 -91.5 95t-138.5 34q-151 0 -214.5 -109.5t-63.5 -302.5q0 -147 30 -229t93.5 -126t161.5 -44q84 0 137 31.5t100 97.5l141 -86q-49 -84 -136 -138.5t-240 -54.5q-231 0 -348 139.5t-117 413.5z" />
@@ -111,30 +110,30 @@
<glyph unicode="|" horiz-adv-x="852" d="M348 -395v1915h156v-1915h-156z" />
<glyph unicode="}" horiz-adv-x="977" d="M102 -262h52q131 0 192.5 65.5t61.5 198.5v172q0 292 280 387q-133 47 -206.5 139.5t-73.5 249.5v172q0 133 -61.5 198.5t-192.5 65.5h-52v134h70q193 0 293 -98.5t100 -282.5v-146q0 -356 291 -356h18v-148h-18q-142 0 -216.5 -89t-74.5 -267v-147q0 -185 -105.5 -283 t-287.5 -98h-70v133z" />
<glyph unicode="~" horiz-adv-x="1427" d="M164 614v160q100 80 178 103.5t127 23.5q61 0 125.5 -24.5t129 -54t126 -54.5t117.5 -25q47 0 91.5 16t84.5 38.5t121 89.5v-160q-17 -12 -45.5 -32.5t-66.5 -42t-85 -37t-96 -15.5q-62 0 -130.5 24.5t-136 54.5t-130 54.5t-109.5 24.5q-66 0 -144 -37.5t-157 -106.5z " />
-<glyph unicode="&#xa1;" d="M156 967q0 63 29.5 87.5t93.5 24.5q71 0 95.5 -29.5t24.5 -82.5q0 -60 -27.5 -86.5t-92.5 -26.5q-68 0 -95.5 26.5t-27.5 86.5zM178 -395l25 1087h145l29 -1087h-199z" />
+<glyph unicode="&#xa1;" horiz-adv-x="555" d="M156 967q0 63 29.5 87.5t93.5 24.5q71 0 95.5 -29.5t24.5 -82.5q0 -60 -27.5 -86.5t-92.5 -26.5q-68 0 -95.5 26.5t-27.5 86.5zM178 -395l25 1087h145l29 -1087h-199z" />
<glyph unicode="&#xa2;" horiz-adv-x="1030" d="M117 522q0 274 116 415.5t342 141.5q32 0 64 -4l47 213h119l-53 -237q125 -43 192 -164l-141 -86q-41 61 -86 90l-168 -772h31q84 0 137 31.5t100 97.5l141 -86q-49 -84 -136 -138.5t-240 -54.5q-34 0 -66 4l-51 -233h-119l55 256q-153 51 -218.5 190.5t-65.5 335.5z M295 518q0 -129 29.5 -225t111.5 -141l170 776l-16 2h-17q-151 0 -214.5 -109.5t-63.5 -302.5z" />
<glyph unicode="&#xa3;" horiz-adv-x="1264" d="M113 0v156q69 14 107 70.5t55.5 135t17.5 226.5h-156v131h150l-10 49q-44 159 -44 276q0 173 127 271t342 98q306 0 443 -219l-154 -90q-45 72 -118.5 115t-170.5 43q-135 0 -206.5 -64.5t-71.5 -181.5q0 -76 24 -172q25 -104 27 -125h381v-131h-373q0 -175 -41 -276.5 t-120 -155.5h837v-156h-1046z" />
<glyph unicode="&#xa4;" horiz-adv-x="1264" d="M119 164l194 198q-71 100 -71 224q0 135 69 225l-192 195l92 92l192 -191q100 76 228 76q133 0 229 -74l193 189l90 -92l-187 -191q74 -96 74 -229q0 -115 -76 -228l189 -194l-90 -90l-195 190q-59 -41 -113.5 -55t-113.5 -14q-127 0 -223 71l-197 -192zM387 586 q0 -66 31 -124t88.5 -93t124.5 -35q109 0 181.5 74t72.5 178q0 109 -73.5 183.5t-180.5 74.5q-106 0 -175 -75.5t-69 -182.5z" />
<glyph unicode="&#xa5;" horiz-adv-x="1264" d="M66 1384h208l361 -624l364 624h199l-375 -624h303v-121h-374l-29 -45v-105h403v-120h-403v-369h-184v369h-402v120h402v97l-33 53h-369v121h299z" />
<glyph unicode="&#xa6;" horiz-adv-x="852" d="M348 242h156v-637h-156v637zM348 883v637h156v-637h-156z" />
<glyph unicode="&#xa7;" horiz-adv-x="1081" d="M109 545q0 104 68.5 179t174.5 138q-92 64 -136 123t-44 131q0 135 98.5 216t296.5 81q270 0 383 -147l-127 -97q-87 101 -252 101q-219 0 -219 -146q0 -59 55.5 -103t172.5 -110q173 -96 248 -156.5t110 -122.5t35 -132q0 -101 -59.5 -170.5t-182.5 -145.5 q100 -67 142 -127.5t42 -124.5q0 -151 -108.5 -225t-286.5 -74q-263 0 -383 148l127 96q95 -102 252 -102q115 0 167 36.5t52 112.5q0 53 -50.5 97.5t-195.5 119.5q-161 87 -230.5 142.5t-109.5 118t-40 143.5zM276 551q0 -55 60.5 -116t164.5 -117l101 -56q90 60 146.5 108 t56.5 122q0 42 -30 83t-88.5 84.5t-203.5 124.5q-90 -55 -148.5 -110.5t-58.5 -122.5z" />
-<glyph unicode="&#xa8;" horiz-adv-x="1085" d="M242 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM637 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#xa8;" d="M242 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM637 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
<glyph unicode="&#xa9;" horiz-adv-x="1855" d="M123 610q0 221 106 405.5t293.5 291t405.5 106.5q221 0 405.5 -106t291 -293.5t106.5 -403.5q0 -221 -106.5 -408t-292 -293t-404.5 -106q-220 0 -405.5 107.5t-292.5 294t-107 405.5zM256 610q0 -183 89 -339t245 -247.5t338 -91.5q179 0 335.5 90.5t246 247.5t89.5 340 t-90.5 340t-246 246.5t-334.5 89.5q-181 0 -336.5 -90.5t-245.5 -247.5t-90 -338zM557 612q0 224 94 334.5t297 110.5q123 0 200 -49.5t118 -126.5l-119 -74q-29 51 -73 89t-128 38q-135 0 -189.5 -81t-54.5 -241q0 -163 58.5 -241t187.5 -78q136 0 211 133l119 -72 q-57 -96 -136 -140t-190 -44q-204 0 -299.5 109.5t-95.5 332.5z" />
<glyph unicode="&#xaa;" horiz-adv-x="780" d="M92 1014q0 104 62.5 160.5t205.5 72.5l158 13v24q0 72 -39 96.5t-114 24.5q-113 0 -158 -78l-109 66q31 51 91.5 89t177.5 38q147 0 215.5 -52.5t68.5 -189.5v-461h-133v72q-47 -39 -98 -64.5t-115 -25.5q-102 0 -157.5 60.5t-55.5 154.5zM227 1016q0 -53 28 -77t85 -24 q47 0 91 29t87 64v145l-98 -10q-92 -8 -142.5 -33t-50.5 -94z" />
<glyph unicode="&#xab;" horiz-adv-x="1225" d="M72 524l393 471h197l-394 -471l394 -471h-197zM561 524l393 471h197l-393 -471l393 -471h-197z" />
<glyph unicode="&#xac;" horiz-adv-x="1427" d="M164 827v144h1100v-604h-144v460h-956z" />
<glyph unicode="&#xad;" horiz-adv-x="827" d="M102 440v172h623v-172h-623z" />
<glyph unicode="&#xae;" horiz-adv-x="1855" d="M123 610q0 221 106 405.5t293.5 291t405.5 106.5q221 0 405.5 -106t291 -293.5t106.5 -403.5q0 -221 -106.5 -408t-292 -293t-404.5 -106q-220 0 -405.5 107.5t-292.5 294t-107 405.5zM256 610q0 -183 89 -339t245 -247.5t338 -91.5q179 0 335.5 90.5t246 247.5t89.5 340 t-90.5 340t-246 246.5t-334.5 89.5q-181 0 -336.5 -90.5t-245.5 -247.5t-90 -338zM643 201v850h275q151 0 232 -52.5t81 -193.5q0 -111 -46 -168t-124 -80l233 -356h-164l-217 336h-131v-336h-139zM782 657h129q103 0 138.5 32t35.5 110q0 73 -36.5 103t-130.5 30h-136v-275 z" />
-<glyph unicode="&#xaf;" horiz-adv-x="1085" d="M238 1255v140h610v-140h-610z" />
+<glyph unicode="&#xaf;" d="M238 1255v140h610v-140h-610z" />
<glyph unicode="&#xb0;" horiz-adv-x="864" d="M152 1241q0 112 80 195.5t200 83.5q116 0 198.5 -81.5t82.5 -197.5q0 -76 -39 -143t-103 -103.5t-137 -36.5q-119 0 -200.5 84t-81.5 199zM270 1241q0 -67 47.5 -115.5t116.5 -48.5q68 0 114 48.5t46 113.5q0 68 -46 115t-114 47q-72 0 -118 -48t-46 -112z" />
<glyph unicode="&#xb1;" horiz-adv-x="1427" d="M164 0v143h1100v-143h-1100zM164 809v143h477v478h143v-478h480v-143h-480v-479h-143v479h-477z" />
<glyph unicode="&#xb2;" horiz-adv-x="889" d="M106 1362q106 162 326 162q148 0 230.5 -63.5t82.5 -180.5q0 -85 -38.5 -147t-122.5 -137t-260 -210h450v-131h-659v138q74 52 208.5 161t195 180t56.5 142q0 59 -44 89t-103 30q-108 0 -188 -111z" />
<glyph unicode="&#xb3;" horiz-adv-x="889" d="M84 778l133 74q27 -35 73 -60.5t103 -25.5q94 0 137 36t43 109q0 70 -48 100.5t-140 30.5h-90v127h78q86 0 136 32t50 91q0 54 -40 79.5t-105 25.5q-117 0 -187 -99l-133 76q40 56 82.5 85.5t105.5 47t142 17.5q160 0 233.5 -63.5t73.5 -151.5q0 -140 -139 -193 q67 -24 110 -78.5t43 -132.5q0 -133 -92 -200.5t-258 -67.5q-102 0 -186 39t-125 102z" />
-<glyph unicode="&#xb4;" horiz-adv-x="1085" d="M481 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#xb4;" d="M481 1208l178 361h236l-272 -361h-142z" />
<glyph unicode="&#xb5;" horiz-adv-x="1169" d="M139 -395v1444h174v-793q43 -53 113 -85t143 -32q153 0 273 144v766h176v-1049h-166l-10 119q-60 -76 -123.5 -113t-147.5 -37q-75 0 -132.5 15.5t-125.5 66.5v-446h-174z" />
<glyph unicode="&#xb6;" horiz-adv-x="1257" d="M59 1069q0 191 132.5 305.5t347.5 114.5h657v-133h-192v-1751h-160v1751h-195v-1751h-160v1040q-120 0 -219 51.5t-155 148t-56 224.5z" />
-<glyph unicode="&#xb7;" d="M156 745q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5z" />
-<glyph unicode="&#xb8;" horiz-adv-x="1085" d="M244 -348l51 100q29 -10 85 -21.5t107 -11.5q121 0 121 78q0 40 -42.5 68t-133.5 35l62 118h106l-25 -49q87 -22 125.5 -73.5t38.5 -110.5q0 -86 -68.5 -133t-187.5 -47q-77 0 -147 17.5t-92 29.5z" />
+<glyph unicode="&#xb7;" horiz-adv-x="555" d="M156 745q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5z" />
+<glyph unicode="&#xb8;" d="M244 -348l51 100q29 -10 85 -21.5t107 -11.5q121 0 121 78q0 40 -42.5 68t-133.5 35l62 118h106l-25 -49q87 -22 125.5 -73.5t38.5 -110.5q0 -86 -68.5 -133t-187.5 -47q-77 0 -147 17.5t-92 29.5z" />
<glyph unicode="&#xb9;" horiz-adv-x="889" d="M182 1241v107q129 4 182.5 37.5t77.5 119.5h125v-850h-161v586h-224z" />
<glyph unicode="&#xba;" horiz-adv-x="825" d="M102 1157q0 180 80 271.5t232 91.5q151 0 230 -93.5t79 -269.5t-79.5 -267t-229.5 -91q-154 0 -233 91.5t-79 266.5zM240 1157q0 -129 41.5 -186.5t132.5 -57.5q100 0 137 67t37 177q0 113 -37 180.5t-137 67.5q-91 0 -132.5 -58.5t-41.5 -189.5z" />
<glyph unicode="&#xbb;" horiz-adv-x="1225" d="M74 53l393 471l-393 471h196l394 -471l-394 -471h-196zM563 53l393 471l-393 471h197l393 -471l-393 -471h-197z" />
@@ -206,43 +205,757 @@
<glyph unicode="&#xfd;" horiz-adv-x="1040" d="M-4 -365l43 142q65 -29 151 -29q121 0 205 219l35 90l-383 992h186l289 -768l291 768h180l-448 -1129q-71 -173 -152 -244t-211 -71q-47 0 -100 9t-86 21zM405 1208l178 361h236l-272 -361h-142z" />
<glyph unicode="&#xfe;" horiz-adv-x="1174" d="M170 -395v1884h172v-545q59 57 142 96t178 39q187 0 291 -141.5t104 -405.5q0 -258 -112.5 -410.5t-309.5 -152.5q-157 0 -293 117v-481h-172zM342 236q134 -113 270 -113q117 0 192 98t75 307q0 398 -250 398q-82 0 -157 -41t-130 -94v-555z" />
<glyph unicode="&#xff;" horiz-adv-x="1040" d="M-4 -365l43 142q65 -29 151 -29q121 0 205 219l35 90l-383 992h186l289 -768l291 768h180l-448 -1129q-71 -173 -152 -244t-211 -71q-47 0 -100 9t-86 21zM221 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29 t-21.5 78zM616 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x100;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM340 1591v140h610v-140h-610zM414 528h450l-225 674z" />
+<glyph unicode="&#x101;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM226 1255 v140h610v-140h-610zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z" />
+<glyph unicode="&#x102;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM319 1804h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM414 528h450l-225 674z" />
+<glyph unicode="&#x103;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM207 1489 h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z" />
+<glyph unicode="&#x104;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384q-128 -40 -191 -82t-63 -102q0 -35 19.5 -53.5t54.5 -18.5t63.5 11.5t59.5 27.5l55 -109q-53 -34 -99 -51.5t-100 -17.5q-90 0 -142 45.5t-52 138.5q0 153 190 240l-110 331h-564l-118 -360h-189zM414 528h450l-225 674z" />
+<glyph unicode="&#x105;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713q-128 -40 -191 -82t-63 -102q0 -35 19.5 -53.5t54.5 -18.5t63.5 11.5t59.5 27.5 l55 -109q-53 -34 -99 -51.5t-100 -17.5q-90 0 -142 45.5t-52 138.5q0 164 223 254v88q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z " />
+<glyph unicode="&#x106;" horiz-adv-x="1321" d="M129 692q0 361 146.5 541t451.5 180q121 0 216 -30t160.5 -82.5t119.5 -147.5l-152 -100q-44 74 -89 112.5t-108 61t-147 22.5q-208 0 -305.5 -138.5t-97.5 -418.5q0 -276 96 -416.5t309 -140.5q118 0 205 46.5t156 160.5l153 -100q-66 -106 -134.5 -160.5t-159.5 -82.5 t-214 -28q-311 0 -458.5 179.5t-147.5 541.5zM587 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x107;" horiz-adv-x="1030" d="M117 522q0 274 116 415.5t342 141.5q259 0 369 -192l-141 -86q-39 61 -91.5 95t-138.5 34q-151 0 -214.5 -109.5t-63.5 -302.5q0 -147 30 -229t93.5 -126t161.5 -44q84 0 137 31.5t100 97.5l141 -86q-49 -84 -136 -138.5t-240 -54.5q-231 0 -348 139.5t-117 413.5z M452 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x108;" horiz-adv-x="1321" d="M129 692q0 361 146.5 541t451.5 180q121 0 216 -30t160.5 -82.5t119.5 -147.5l-152 -100q-44 74 -89 112.5t-108 61t-147 22.5q-208 0 -305.5 -138.5t-97.5 -418.5q0 -276 96 -416.5t309 -140.5q118 0 205 46.5t156 160.5l153 -100q-66 -106 -134.5 -160.5t-159.5 -82.5 t-214 -28q-311 0 -458.5 179.5t-147.5 541.5zM391 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x109;" horiz-adv-x="1030" d="M117 522q0 274 116 415.5t342 141.5q259 0 369 -192l-141 -86q-39 61 -91.5 95t-138.5 34q-151 0 -214.5 -109.5t-63.5 -302.5q0 -147 30 -229t93.5 -126t161.5 -44q84 0 137 31.5t100 97.5l141 -86q-49 -84 -136 -138.5t-240 -54.5q-231 0 -348 139.5t-117 413.5z M248 1208l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x10a;" horiz-adv-x="1321" d="M129 692q0 361 146.5 541t451.5 180q121 0 216 -30t160.5 -82.5t119.5 -147.5l-152 -100q-44 74 -89 112.5t-108 61t-147 22.5q-208 0 -305.5 -138.5t-97.5 -418.5q0 -276 96 -416.5t309 -140.5q118 0 205 46.5t156 160.5l153 -100q-66 -106 -134.5 -160.5t-159.5 -82.5 t-214 -28q-311 0 -458.5 179.5t-147.5 541.5zM590 1659q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x10b;" horiz-adv-x="1030" d="M117 522q0 274 116 415.5t342 141.5q259 0 369 -192l-141 -86q-39 61 -91.5 95t-138.5 34q-151 0 -214.5 -109.5t-63.5 -302.5q0 -147 30 -229t93.5 -126t161.5 -44q84 0 137 31.5t100 97.5l141 -86q-49 -84 -136 -138.5t-240 -54.5q-231 0 -348 139.5t-117 413.5z M463 1323q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x10c;" horiz-adv-x="1321" d="M129 692q0 361 146.5 541t451.5 180q121 0 216 -30t160.5 -82.5t119.5 -147.5l-152 -100q-44 74 -89 112.5t-108 61t-147 22.5q-208 0 -305.5 -138.5t-97.5 -418.5q0 -276 96 -416.5t309 -140.5q118 0 205 46.5t156 160.5l153 -100q-66 -106 -134.5 -160.5t-159.5 -82.5 t-214 -28q-311 0 -458.5 179.5t-147.5 541.5zM371 1905h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x10d;" horiz-adv-x="1030" d="M117 522q0 274 116 415.5t342 141.5q259 0 369 -192l-141 -86q-39 61 -91.5 95t-138.5 34q-151 0 -214.5 -109.5t-63.5 -302.5q0 -147 30 -229t93.5 -126t161.5 -44q84 0 137 31.5t100 97.5l141 -86q-49 -84 -136 -138.5t-240 -54.5q-231 0 -348 139.5t-117 413.5z M244 1569h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x10e;" horiz-adv-x="1292" d="M170 0v1384h348q242 0 382 -69.5t207 -220.5t67 -402q0 -254 -65.5 -404t-202 -219t-384.5 -69h-352zM283 1905h149l185 -238l184 238h150l-230 -361h-211zM354 168h154q182 0 281.5 50.5t144.5 162t45 313.5q0 198 -44 310t-145 162.5t-282 50.5h-154v-1049z" />
+<glyph unicode="&#x10f;" horiz-adv-x="1251" d="M117 516q0 257 112 410t310 153q159 0 292 -116v526h173v-1489h-173v104q-59 -57 -142 -96t-177 -39q-189 0 -292 142.5t-103 404.5zM295 520q0 -397 250 -397q82 0 156.5 41t129.5 94v555q-137 113 -270 113q-117 0 -191.5 -98.5t-74.5 -307.5zM1083 1128l64 361h215 l-160 -361h-119z" />
+<glyph unicode="&#x110;" horiz-adv-x="1378" d="M63 627v141h119v616h365q261 0 410.5 -70.5t220.5 -222.5t71 -399q0 -254 -70 -404t-217 -219t-413 -69h-367v627h-119zM367 168h172q198 0 307 50.5t159 164t50 311.5q0 292 -115 407.5t-401 115.5h-172v-449h335v-141h-335v-459z" />
+<glyph unicode="&#x111;" horiz-adv-x="1174" d="M117 516q0 257 112 410t310 153q159 0 292 -116v231h-301v139h301v156h173v-156h137v-139h-137v-1194h-173v104q-59 -57 -142 -96t-177 -39q-189 0 -292 142.5t-103 404.5zM295 520q0 -397 250 -397q82 0 156.5 41t129.5 94v555q-137 113 -270 113q-117 0 -191.5 -98.5 t-74.5 -307.5z" />
+<glyph unicode="&#x112;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM304 1591v140h610v-140h-610z" />
+<glyph unicode="&#x113;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM285 1255v140h610v-140h-610zM297 639h512q-2 141 -59.5 219 t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5z" />
+<glyph unicode="&#x114;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM319 1825h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202z" />
+<glyph unicode="&#x115;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM246 1489h127q14 -64 66.5 -94.5t130.5 -30.5 q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5z" />
+<glyph unicode="&#x116;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM483 1659q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x117;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM297 639h512q-2 141 -59.5 219t-186.5 78 q-123 0 -184.5 -70.5t-81.5 -226.5zM444 1323q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x118;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168q-131 -41 -192.5 -83.5t-61.5 -100.5q0 -35 19.5 -53.5t54.5 -18.5t63.5 11.5t59.5 27.5l55 -109q-53 -34 -99 -51.5t-100 -17.5q-92 0 -143 47.5t-51 136.5q0 127 137 211h-588z" />
+<glyph unicode="&#x119;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-42 -62 -74 -88q-162 -160 -162 -263q0 -61 74 -61q35 0 63.5 11.5t59.5 27.5l55 -109q-53 -34 -99.5 -51.5t-99.5 -17.5 q-78 0 -136 40t-58 130q0 61 21 105t69 93q-38 -4 -78 -4q-240 0 -359.5 133.5t-119.5 413.5zM297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5z" />
+<glyph unicode="&#x11a;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM244 1905h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x11b;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM225 1569h149l185 -238l184 238h150l-230 -361h-211z M297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5z" />
+<glyph unicode="&#x11c;" horiz-adv-x="1391" d="M129 690q0 366 150.5 544.5t449.5 178.5q170 0 293.5 -60t202.5 -200l-150 -102q-49 90 -130 144t-218 54q-209 0 -306 -138t-97 -423q0 -291 105 -422t312 -131q80 0 148.5 18.5t148.5 53.5v328h-336v167h521v-596q-113 -63 -224.5 -99t-257.5 -36q-312 0 -462 179 t-150 540zM391 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x11d;" horiz-adv-x="1174" d="M117 535q0 256 113 400t309 144q159 0 292 -116v86h173v-1026q0 -211 -104.5 -314.5t-346.5 -103.5q-231 0 -381 98l64 139q135 -94 317 -94q147 0 212.5 61.5t65.5 202.5v123q-59 -57 -141 -96t-178 -39q-193 0 -294 137.5t-101 397.5zM258 1208l229 361h211l228 -361 h-150l-184 238l-185 -238h-149zM295 539q0 -202 63 -293.5t187 -91.5q144 0 286 135v524q-137 113 -270 113q-131 0 -198.5 -102t-67.5 -285z" />
+<glyph unicode="&#x11e;" horiz-adv-x="1391" d="M129 690q0 366 150.5 544.5t449.5 178.5q170 0 293.5 -60t202.5 -200l-150 -102q-49 90 -130 144t-218 54q-209 0 -306 -138t-97 -423q0 -291 105 -422t312 -131q80 0 148.5 18.5t148.5 53.5v328h-336v167h521v-596q-113 -63 -224.5 -99t-257.5 -36q-312 0 -462 179 t-150 540zM401 1825h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202z" />
+<glyph unicode="&#x11f;" horiz-adv-x="1174" d="M117 535q0 256 113 400t309 144q159 0 292 -116v86h173v-1026q0 -211 -104.5 -314.5t-346.5 -103.5q-231 0 -381 98l64 139q135 -94 317 -94q147 0 212.5 61.5t65.5 202.5v123q-59 -57 -141 -96t-178 -39q-193 0 -294 137.5t-101 397.5zM233 1489h127q14 -64 66.5 -94.5 t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM295 539q0 -202 63 -293.5t187 -91.5q144 0 286 135v524q-137 113 -270 113q-131 0 -198.5 -102t-67.5 -285z" />
+<glyph unicode="&#x120;" horiz-adv-x="1391" d="M129 690q0 366 150.5 544.5t449.5 178.5q170 0 293.5 -60t202.5 -200l-150 -102q-49 90 -130 144t-218 54q-209 0 -306 -138t-97 -423q0 -291 105 -422t312 -131q80 0 148.5 18.5t148.5 53.5v328h-336v167h521v-596q-113 -63 -224.5 -99t-257.5 -36q-312 0 -462 179 t-150 540zM594 1659q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x121;" horiz-adv-x="1174" d="M117 535q0 256 113 400t309 144q159 0 292 -116v86h173v-1026q0 -211 -104.5 -314.5t-346.5 -103.5q-231 0 -381 98l64 139q135 -94 317 -94q147 0 212.5 61.5t65.5 202.5v123q-59 -57 -141 -96t-178 -39q-193 0 -294 137.5t-101 397.5zM295 539q0 -202 63 -293.5 t187 -91.5q144 0 286 135v524q-137 113 -270 113q-131 0 -198.5 -102t-67.5 -285zM442 1323q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x122;" horiz-adv-x="1391" d="M129 690q0 366 150.5 544.5t449.5 178.5q170 0 293.5 -60t202.5 -200l-150 -102q-49 90 -130 144t-218 54q-209 0 -306 -138t-97 -423q0 -291 105 -422t312 -131q80 0 148.5 18.5t148.5 53.5v328h-336v167h521v-596q-113 -63 -224.5 -99t-257.5 -36q-312 0 -462 179 t-150 540zM631 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x123;" horiz-adv-x="1174" d="M117 535q0 256 113 400t309 144q159 0 292 -116v86h173v-1026q0 -211 -104.5 -314.5t-346.5 -103.5q-231 0 -381 98l64 139q135 -94 317 -94q147 0 212.5 61.5t65.5 202.5v123q-59 -57 -141 -96t-178 -39q-193 0 -294 137.5t-101 397.5zM295 539q0 -202 63 -293.5 t187 -91.5q144 0 286 135v524q-137 113 -270 113q-131 0 -198.5 -102t-67.5 -285zM432 1296q0 62 22.5 120.5t85.5 135.5h105q-29 -39 -55.5 -79.5t-26.5 -81.5q59 0 85.5 -26t26.5 -85q0 -55 -26.5 -85t-91.5 -30q-66 0 -95.5 33t-29.5 98z" />
+<glyph unicode="&#x124;" horiz-adv-x="1364" d="M182 0v1384h185v-583h630v583h185v-1384h-185v633h-630v-633h-185zM352 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x125;" horiz-adv-x="1163" d="M170 0v1489h172v-596q73 73 170 129.5t195 56.5q152 0 223 -86.5t71 -292.5v-700h-172v618q0 150 -14.5 199.5t-48.5 72.5t-100 23t-154 -50t-170 -122v-741h-172zM297 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x126;" horiz-adv-x="1364" d="M31 1022v143h151v219h185v-219h630v219h185v-219h151v-143h-151v-1022h-185v633h-630v-633h-185v1022h-151zM367 801h630v221h-630v-221z" />
+<glyph unicode="&#x127;" horiz-adv-x="1163" d="M2 1194v139h168v156h172v-156h270v-139h-270v-301q73 73 170 129.5t195 56.5q152 0 223 -86.5t71 -292.5v-700h-172v618q0 150 -14.5 199.5t-48.5 72.5t-100 23t-154 -50t-170 -122v-741h-172v1194h-168z" />
+<glyph unicode="&#x128;" horiz-adv-x="770" d="M10 1557q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121zM102 0v160h191v1067h-191v157h566v-157h-191v-1067h191 v-160h-566z" />
+<glyph unicode="&#x129;" horiz-adv-x="512" d="M-117 1221q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121zM170 0v1049h172v-1049h-172z" />
+<glyph unicode="&#x12a;" horiz-adv-x="770" d="M88 1591v140h610v-140h-610zM102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566z" />
+<glyph unicode="&#x12b;" horiz-adv-x="512" d="M-47 1255v140h610v-140h-610zM170 0v1049h172v-1049h-172z" />
+<glyph unicode="&#x12c;" horiz-adv-x="770" d="M61 1825h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566z" />
+<glyph unicode="&#x12d;" horiz-adv-x="512" d="M-70 1489h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM170 0v1049h172v-1049h-172z" />
+<glyph unicode="&#x12e;" horiz-adv-x="770" d="M102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160q-131 -41 -192.5 -82.5t-61.5 -101.5q0 -35 19.5 -53.5t53.5 -18.5q50 0 123 39l56 -109q-54 -34 -100 -51.5t-99 -17.5q-93 0 -144 47t-51 137q0 127 138 211h-308z" />
+<glyph unicode="&#x12f;" horiz-adv-x="512" d="M-12 -211q0 74 48 136.5t134 103.5v1020h172v-1049q-111 -33 -162 -86t-51 -98q0 -35 19.5 -53.5t54.5 -18.5t63.5 11.5t59.5 27.5l55 -109q-53 -34 -99 -51.5t-100 -17.5q-90 0 -142 45.5t-52 138.5zM145 1315q0 53 26 77.5t85 24.5q61 0 87 -23.5t26 -78.5 q0 -60 -27 -81.5t-86 -21.5q-63 0 -87 27t-24 76z" />
+<glyph unicode="&#x130;" horiz-adv-x="770" d="M102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566zM276 1659q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x131;" horiz-adv-x="512" d="M170 0v1049h172v-1049h-172z" />
+<glyph unicode="&#x132;" horiz-adv-x="1593" d="M102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566zM760 20l68 158q32 -16 92 -30.5t98 -14.5q81 0 125 28t63 92.5t19 199.5v931h184v-1007q0 -203 -89 -305.5t-300 -102.5q-59 0 -133 14.5t-127 36.5z" />
+<glyph unicode="&#x133;" horiz-adv-x="1049" d="M145 1315q0 53 26 77.5t85 24.5q61 0 87 -23.5t26 -78.5q0 -60 -27 -81.5t-86 -21.5q-63 0 -87 27t-24 76zM170 0v1049h172v-1049h-172zM367 -365l43 142q73 -29 151 -29q84 0 109.5 58.5t25.5 168.5v1074h172v-1094q0 -190 -74 -270t-239 -80q-100 0 -188 30zM672 1315 q0 53 25.5 77.5t84.5 24.5q62 0 87.5 -23.5t25.5 -78.5q0 -60 -26.5 -81.5t-86.5 -21.5q-63 0 -86.5 27t-23.5 76z" />
+<glyph unicode="&#x134;" horiz-adv-x="885" d="M51 20l68 158q32 -16 92 -30.5t98 -14.5q81 0 125 28t63 92.5t19 199.5v931h184v-1007q0 -203 -89 -305.5t-300 -102.5q-59 0 -133 14.5t-127 36.5zM275 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x135;" horiz-adv-x="537" d="M-143 -365l43 142q73 -29 151 -29q84 0 109.5 58.5t25.5 168.5v1074h172v-1094q0 -190 -74 -270t-239 -80q-100 0 -188 30zM-57 1208l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x136;" horiz-adv-x="1264" d="M182 0v1384h185v-679l585 679h230l-566 -636l594 -748h-235l-477 614l-131 -147v-467h-185zM508 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x137;" horiz-adv-x="1049" d="M170 0v1489h172v-930l426 490h211l-418 -459l440 -590h-213l-333 471l-113 -125v-346h-172zM402 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x138;" horiz-adv-x="1049" d="M170 0v1047h172v-488l377 434q52 69 135 72q60 0 129 -16l-47 -142q-20 8 -47 8q-21 0 -33 -8t-27 -22l-268 -295l440 -590h-213l-333 471l-113 -125v-346h-172z" />
+<glyph unicode="&#x139;" horiz-adv-x="1038" d="M182 0v1384h185v-1216h626v-168h-811zM409 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x13a;" horiz-adv-x="528" d="M139 1546l178 361h236l-272 -361h-142zM178 0v1489h172v-1489h-172z" />
+<glyph unicode="&#x13b;" horiz-adv-x="1038" d="M182 0v1384h185v-1216h626v-168h-811zM486 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x13c;" horiz-adv-x="528" d="M144 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85zM178 0v1489h172v-1489h-172z" />
+<glyph unicode="&#x13d;" horiz-adv-x="1038" d="M182 0v1384h185v-1216h626v-168h-811zM516 1026l66 361h215l-160 -361h-121z" />
+<glyph unicode="&#x13e;" horiz-adv-x="608" d="M178 0v1489h172v-1489h-172zM432 1128l66 361h215l-160 -361h-121z" />
+<glyph unicode="&#x13f;" horiz-adv-x="1038" d="M182 0v1384h185v-1216h626v-168h-811zM661 750q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x140;" horiz-adv-x="717" d="M178 0v1489h172v-1489h-172zM498 750q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x141;" horiz-adv-x="1038" d="M31 383v174l151 122v705h185v-556l249 202v-174l-249 -202v-486h626v-168h-811v505z" />
+<glyph unicode="&#x142;" horiz-adv-x="528" d="M31 469v170l147 125v725h172v-578l148 127v-170l-148 -127v-741h-172v596z" />
+<glyph unicode="&#x143;" horiz-adv-x="1386" d="M182 0v1384h271l573 -1087v1087h178v-1384h-219l-625 1188v-1188h-178zM577 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x144;" horiz-adv-x="1163" d="M170 0v1049h172v-156q73 73 170 129.5t195 56.5q152 0 223 -86.5t71 -292.5v-700h-172v618q0 150 -15 200t-49 72.5t-99 22.5q-66 0 -154 -50t-170 -122v-741h-172zM481 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x145;" horiz-adv-x="1386" d="M182 0v1384h271l573 -1087v1087h178v-1384h-219l-625 1188v-1188h-178zM596 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x146;" horiz-adv-x="1163" d="M170 0v1049h172v-156q73 73 170 129.5t195 56.5q152 0 223 -86.5t71 -292.5v-700h-172v618q0 150 -15 200t-49 72.5t-99 22.5q-66 0 -154 -50t-170 -122v-741h-172zM459 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105 q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x147;" horiz-adv-x="1386" d="M182 0v1384h271l573 -1087v1087h178v-1384h-219l-625 1188v-1188h-178zM350 1905h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x148;" horiz-adv-x="1163" d="M170 0v1049h172v-156q73 73 170 129.5t195 56.5q152 0 223 -86.5t71 -292.5v-700h-172v618q0 150 -15 200t-49 72.5t-99 22.5q-66 0 -154 -50t-170 -122v-741h-172zM260 1569h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x149;" horiz-adv-x="1280" d="M-18 1300q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -33.5t27.5 -99.5q0 -123 -36.5 -223.5t-75.5 -147.5h-105q35 44 59.5 130t24.5 149q-59 0 -84.5 26.5t-25.5 85.5zM287 0v1049h172v-156q73 73 170 129.5t195 56.5q152 0 223 -86.5t71 -292.5v-700h-172v618q0 150 -15 200 t-49 72.5t-99 22.5q-66 0 -154 -50t-170 -122v-741h-172z" />
+<glyph unicode="&#x14a;" horiz-adv-x="1386" d="M182 0v1384h271l573 -1046v1046h178v-1429q0 -185 -75 -267.5t-244 -82.5q-101 0 -189 30l43 142q74 -29 152 -29q86 0 110.5 59.5t24.5 192.5l-666 1188v-1188h-178z" />
+<glyph unicode="&#x14b;" horiz-adv-x="1163" d="M170 0v1049h172v-156q73 73 170 129.5t195 56.5q152 0 223 -86.5t71 -292.5v-745q0 -190 -74 -270t-239 -80q-100 0 -188 30l43 142q73 -29 151 -29q84 0 109.5 58.5t25.5 168.5v643q0 150 -15 200t-49 72.5t-99 22.5q-66 0 -154 -50t-170 -122v-741h-172z" />
+<glyph unicode="&#x14c;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM375 1591v140h610v-140 h-610z" />
+<glyph unicode="&#x14d;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM271 1255v140h610v-140h-610zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5 t-70 -310.5z" />
+<glyph unicode="&#x14e;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM350 1825h127 q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202z" />
+<glyph unicode="&#x14f;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM256 1489h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM295 522 q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5z" />
+<glyph unicode="&#x150;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM415 1544l178 361h236 l-272 -361h-142zM763 1544l179 361h235l-272 -361h-142z" />
+<glyph unicode="&#x151;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM313 1208l178 361 h236l-272 -361h-142zM661 1208l179 361h235l-272 -361h-142z" />
<glyph unicode="&#x152;" horiz-adv-x="1849" d="M129 692q0 366 145.5 543.5t452.5 177.5q124 0 223 -29h774v-167h-604v-408h525v-168h-525v-473h604v-168h-772q-102 -29 -225 -29q-305 0 -451.5 177t-146.5 544zM324 692q0 -288 95.5 -422.5t309.5 -134.5q121 0 205 43v1028q-84 43 -205 43q-216 0 -310.5 -135.5 t-94.5 -421.5z" />
<glyph unicode="&#x153;" horiz-adv-x="1821" d="M117 522q0 281 119.5 419t343.5 138q120 0 217.5 -51t148.5 -141q51 94 144.5 143t218.5 49q203 0 305 -117t102 -362v-96h-682v-21q0 -188 74 -276t225 -88q72 0 124 29.5t102 95.5l141 -88q-60 -90 -145 -138.5t-220 -48.5q-274 0 -389 193q-121 -193 -366 -193 q-225 0 -344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q139 0 210.5 96.5t71.5 300.5q0 153 -29.5 237.5t-91 130.5t-161.5 46q-145 0 -215 -97.5t-70 -310.5zM1036 639h512q-2 141 -59 219t-186 78q-123 0 -188.5 -68.5t-78.5 -228.5z" />
+<glyph unicode="&#x154;" horiz-adv-x="1237" d="M182 0v1384h430q258 0 370 -95t112 -294q0 -170 -68.5 -269t-222.5 -132l375 -594h-217l-353 565h-241v-565h-185zM367 729h231q116 0 182.5 24.5t94.5 78t28 149.5q0 137 -69.5 188.5t-223.5 51.5h-243v-492zM491 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x155;" horiz-adv-x="811" d="M170 0v1049h172v-170q72 73 151.5 129.5t176.5 56.5q65 0 104 -21l-37 -165q-28 12 -80 12q-77 0 -148.5 -35.5t-166.5 -130.5v-725h-172zM280 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x156;" horiz-adv-x="1237" d="M182 0v1384h430q258 0 370 -95t112 -294q0 -170 -68.5 -269t-222.5 -132l375 -594h-217l-353 565h-241v-565h-185zM367 729h231q116 0 182.5 24.5t94.5 78t28 149.5q0 137 -69.5 188.5t-223.5 51.5h-243v-492zM516 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98 q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x157;" horiz-adv-x="811" d="M140 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85zM170 0v1049h172v-170q72 73 151.5 129.5t176.5 56.5q65 0 104 -21l-37 -165q-28 12 -80 12q-77 0 -148.5 -35.5t-166.5 -130.5 v-725h-172z" />
+<glyph unicode="&#x158;" horiz-adv-x="1237" d="M182 0v1384h430q258 0 370 -95t112 -294q0 -170 -68.5 -269t-222.5 -132l375 -594h-217l-353 565h-241v-565h-185zM275 1905h149l185 -238l184 238h150l-230 -361h-211zM367 729h231q116 0 182.5 24.5t94.5 78t28 149.5q0 137 -69.5 188.5t-223.5 51.5h-243v-492z" />
+<glyph unicode="&#x159;" horiz-adv-x="811" d="M125 1569h149l185 -238l184 238h150l-230 -361h-211zM170 0v1049h172v-170q72 73 151.5 129.5t176.5 56.5q65 0 104 -21l-37 -165q-28 12 -80 12q-77 0 -148.5 -35.5t-166.5 -130.5v-725h-172z" />
+<glyph unicode="&#x15a;" horiz-adv-x="1227" d="M96 242l150 100q117 -207 362 -207q147 0 231.5 61.5t84.5 168.5q0 61 -27 103t-71 70.5t-101 46t-119 33.5q-102 25 -190 51.5t-152.5 68.5t-101.5 107.5t-37 168.5q0 184 118.5 291.5t354.5 107.5q188 0 300 -69.5t177 -178.5l-147 -104q-54 90 -131.5 139t-198.5 49 q-135 0 -210 -59.5t-75 -159.5q0 -53 22.5 -89t64.5 -60.5t104.5 -42t142.5 -37.5q94 -25 179 -52.5t148.5 -72.5t100.5 -116t37 -181q0 -194 -127.5 -301t-372.5 -107q-187 0 -312 66t-204 205zM485 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x15b;" horiz-adv-x="991" d="M100 158l138 84q79 -127 254 -127q114 0 170.5 43.5t56.5 117.5q0 44 -20 71.5t-62 48t-172 55.5q-187 43 -263.5 119t-76.5 202q0 139 100 223t277 84q137 0 230 -54t136 -130l-137 -84q-82 123 -233 123q-86 0 -145.5 -38t-59.5 -118q0 -71 52 -103t163 -59 q178 -46 246 -86t100.5 -98.5t32.5 -148.5q0 -147 -104 -230.5t-296 -83.5q-131 0 -235 49.5t-152 139.5zM391 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x15c;" horiz-adv-x="1227" d="M96 242l150 100q117 -207 362 -207q147 0 231.5 61.5t84.5 168.5q0 61 -27 103t-71 70.5t-101 46t-119 33.5q-102 25 -190 51.5t-152.5 68.5t-101.5 107.5t-37 168.5q0 184 118.5 291.5t354.5 107.5q188 0 300 -69.5t177 -178.5l-147 -104q-54 90 -131.5 139t-198.5 49 q-135 0 -210 -59.5t-75 -159.5q0 -53 22.5 -89t64.5 -60.5t104.5 -42t142.5 -37.5q94 -25 179 -52.5t148.5 -72.5t100.5 -116t37 -181q0 -194 -127.5 -301t-372.5 -107q-187 0 -312 66t-204 205zM268 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x15d;" horiz-adv-x="991" d="M100 158l138 84q79 -127 254 -127q114 0 170.5 43.5t56.5 117.5q0 44 -20 71.5t-62 48t-172 55.5q-187 43 -263.5 119t-76.5 202q0 139 100 223t277 84q137 0 230 -54t136 -130l-137 -84q-82 123 -233 123q-86 0 -145.5 -38t-59.5 -118q0 -71 52 -103t163 -59 q178 -46 246 -86t100.5 -98.5t32.5 -148.5q0 -147 -104 -230.5t-296 -83.5q-131 0 -235 49.5t-152 139.5zM168 1208l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x15e;" horiz-adv-x="1227" d="M96 242l150 100q117 -207 362 -207q147 0 231.5 61.5t84.5 168.5q0 61 -27 103t-71 70.5t-101 46t-119 33.5q-102 25 -190 51.5t-152.5 68.5t-101.5 107.5t-37 168.5q0 184 118.5 291.5t354.5 107.5q188 0 300 -69.5t177 -178.5l-147 -104q-54 90 -131.5 139t-198.5 49 q-135 0 -210 -59.5t-75 -159.5q0 -53 22.5 -89t64.5 -60.5t104.5 -42t142.5 -37.5q94 -25 179 -52.5t148.5 -72.5t100.5 -116t37 -181q0 -180 -108 -283.5t-316 -120.5l-2 -6q86 -22 125 -73.5t39 -110.5q0 -86 -68.5 -133t-187.5 -47q-78 0 -147.5 17.5t-92.5 29.5l52 100 q28 -10 84.5 -21.5t107.5 -11.5q121 0 121 78q0 40 -42.5 68t-133.5 35l37 73q-339 7 -484 269z" />
+<glyph unicode="&#x15f;" horiz-adv-x="991" d="M100 158l138 84q79 -127 254 -127q114 0 170.5 43.5t56.5 117.5q0 44 -20 71.5t-62 48t-172 55.5q-187 43 -263.5 119t-76.5 202q0 139 100 223t277 84q137 0 230 -54t136 -130l-137 -84q-82 123 -233 123q-86 0 -145.5 -38t-59.5 -118q0 -71 52 -103t163 -59 q178 -46 246 -86t100.5 -98.5t32.5 -148.5q0 -131 -81 -209.5t-243 -100.5l-2 -4q86 -22 125 -73.5t39 -110.5q0 -86 -68.5 -133t-187.5 -47q-78 0 -147.5 17.5t-92.5 29.5l52 100q28 -10 84.5 -21.5t107.5 -11.5q121 0 121 78q0 40 -42.5 68t-133.5 35l37 71 q-146 6 -233 62.5t-122 124.5z" />
+<glyph unicode="&#x160;" horiz-adv-x="1227" d="M96 242l150 100q117 -207 362 -207q147 0 231.5 61.5t84.5 168.5q0 61 -27 103t-71 70.5t-101 46t-119 33.5q-102 25 -190 51.5t-152.5 68.5t-101.5 107.5t-37 168.5q0 184 118.5 291.5t354.5 107.5q188 0 300 -69.5t177 -178.5l-147 -104q-54 90 -131.5 139t-198.5 49 q-135 0 -210 -59.5t-75 -159.5q0 -53 22.5 -89t64.5 -60.5t104.5 -42t142.5 -37.5q94 -25 179 -52.5t148.5 -72.5t100.5 -116t37 -181q0 -194 -127.5 -301t-372.5 -107q-187 0 -312 66t-204 205zM268 1905h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x161;" horiz-adv-x="991" d="M100 158l138 84q79 -127 254 -127q114 0 170.5 43.5t56.5 117.5q0 44 -20 71.5t-62 48t-172 55.5q-187 43 -263.5 119t-76.5 202q0 139 100 223t277 84q137 0 230 -54t136 -130l-137 -84q-82 123 -233 123q-86 0 -145.5 -38t-59.5 -118q0 -71 52 -103t163 -59 q178 -46 246 -86t100.5 -98.5t32.5 -148.5q0 -147 -104 -230.5t-296 -83.5q-131 0 -235 49.5t-152 139.5zM174 1569h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x162;" horiz-adv-x="1184" d="M41 1217v167h1102v-167h-459v-1217h-27l-14 -31q86 -22 125 -73.5t39 -110.5q0 -86 -68.5 -133t-187.5 -47q-78 0 -147.5 17.5t-92.5 29.5l51 100q29 -10 85.5 -21.5t107.5 -11.5q121 0 121 78q0 40 -42.5 68t-133.5 35l51 100h-51v1217h-459z" />
+<glyph unicode="&#x163;" horiz-adv-x="729" d="M47 905v144h150v292h172v-292h266v-144h-266v-555q0 -127 25.5 -182t113.5 -55q76 0 141 28l45 -141q-100 -31 -198 -31q86 -22 124.5 -73.5t38.5 -110.5q0 -86 -68.5 -133t-187.5 -47q-77 0 -147 17.5t-92 29.5l51 100q29 -10 85 -21.5t108 -11.5q120 0 120 78 q0 41 -43.5 68.5t-132.5 34.5l41 80q-104 24 -150 107t-46 230v588h-150z" />
+<glyph unicode="&#x164;" horiz-adv-x="1184" d="M41 1217v167h1102v-167h-459v-1217h-184v1217h-459zM258 1905h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x165;" horiz-adv-x="729" d="M47 905v144h150v292h172v-292h266v-144h-266v-555q0 -127 25.5 -182t113.5 -55q76 0 141 28l45 -141q-100 -31 -198 -31q-160 0 -229.5 84t-69.5 264v588h-150zM475 1128l66 361h215l-160 -361h-121z" />
+<glyph unicode="&#x166;" horiz-adv-x="1184" d="M41 1217v167h1102v-167h-459v-412h213v-139h-213v-666h-184v666h-213v139h213v412h-459z" />
+<glyph unicode="&#x167;" horiz-adv-x="729" d="M31 580v139h166v186h-150v144h150v292h172v-292h266v-144h-266v-186h272v-139h-272v-230q0 -127 25.5 -182t113.5 -55q76 0 141 28l45 -141q-100 -31 -198 -31q-160 0 -229.5 84t-69.5 264v263h-166z" />
+<glyph unicode="&#x168;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM334 1557q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5t75.5 -48.5 t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121z" />
+<glyph unicode="&#x169;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM197 1221q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5t75.5 -48.5t66 -48.5 t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121z" />
+<glyph unicode="&#x16a;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM398 1591v140h610v-140h-610z" />
+<glyph unicode="&#x16b;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM277 1255v140h610v-140h-610z" />
+<glyph unicode="&#x16c;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM379 1825h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5 t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202z" />
+<glyph unicode="&#x16d;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM256 1489h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127 q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202z" />
+<glyph unicode="&#x16e;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM506 1692q0 88 47 142t150 54q104 0 151 -53t47 -143t-48 -143.5 t-150 -53.5q-105 0 -151 55.5t-46 141.5zM606 1692q0 -101 97 -101q98 0 98 101q0 100 -98 100q-97 0 -97 -100z" />
+<glyph unicode="&#x16f;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM354 1356q0 88 47 142t150 54q104 0 151 -53t47 -143t-48 -143.5t-150 -53.5 q-105 0 -151 55.5t-46 141.5zM454 1356q0 -101 97 -101q98 0 98 101q0 100 -98 100q-97 0 -97 -100z" />
+<glyph unicode="&#x170;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM436 1544l178 361h236l-272 -361h-142zM784 1544l179 361h235 l-272 -361h-142z" />
+<glyph unicode="&#x171;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM315 1208l178 361h236l-272 -361h-142zM663 1208l179 361h235l-272 -361h-142z" />
+<glyph unicode="&#x172;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -316 -103 -453q-149 -197 -149 -320q0 -61 73 -61q50 0 123 39l56 -109q-54 -34 -100 -51.5t-99 -17.5q-78 0 -136.5 40t-58.5 130q0 59 20.5 109 t55.5 106q-82 -21 -200 -21q-196 0 -309 61t-163.5 193t-50.5 355z" />
+<glyph unicode="&#x173;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049q-131 -41 -192.5 -83.5t-61.5 -100.5q0 -35 19.5 -53.5t54.5 -18.5t63.5 11.5t59.5 27.5l55 -109q-53 -34 -99 -51.5t-99 -17.5q-93 0 -144 47t-51 137q0 164 223 254v113 q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5z" />
+<glyph unicode="&#x174;" horiz-adv-x="1757" d="M68 1384h184l258 -1118l262 1118h209l266 -1126l262 1126h181l-334 -1384h-221l-261 1108l-262 -1108h-217zM545 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x175;" horiz-adv-x="1475" d="M63 1049h179l178 -799l250 799h143l256 -799l170 799h172l-258 -1049h-160l-256 803l-256 -803h-157zM412 1208l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x176;" horiz-adv-x="1147" d="M41 1384h209l325 -673l332 673h199l-440 -849v-535h-187v526zM242 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x177;" horiz-adv-x="1040" d="M-4 -365l43 142q65 -29 151 -29q121 0 205 219l35 90l-383 992h186l289 -768l291 768h180l-448 -1129q-71 -173 -152 -244t-211 -71q-47 0 -100 9t-86 21zM188 1208l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
<glyph unicode="&#x178;" horiz-adv-x="1147" d="M41 1384h209l325 -673l332 673h199l-440 -849v-535h-187v526zM275 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM670 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5 q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
-<glyph unicode="&#x2c6;" horiz-adv-x="1085" d="M209 1208l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
-<glyph unicode="&#x2dc;" horiz-adv-x="1085" d="M166 1221q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121z" />
-<glyph unicode="&#x2000;" horiz-adv-x="952" />
-<glyph unicode="&#x2001;" horiz-adv-x="1905" />
-<glyph unicode="&#x2002;" horiz-adv-x="952" />
-<glyph unicode="&#x2003;" horiz-adv-x="1905" />
-<glyph unicode="&#x2004;" horiz-adv-x="635" />
-<glyph unicode="&#x2005;" horiz-adv-x="476" />
-<glyph unicode="&#x2006;" horiz-adv-x="317" />
-<glyph unicode="&#x2007;" horiz-adv-x="317" />
-<glyph unicode="&#x2008;" horiz-adv-x="238" />
-<glyph unicode="&#x2009;" horiz-adv-x="381" />
-<glyph unicode="&#x200a;" horiz-adv-x="105" />
+<glyph unicode="&#x179;" horiz-adv-x="1163" d="M92 0v176l729 1041h-698v167h917v-165l-737 -1051h754v-168h-965zM432 1542l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x17a;" horiz-adv-x="934" d="M82 0v131l547 774h-535v144h742v-125l-549 -779h565v-145h-770zM342 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x17b;" horiz-adv-x="1163" d="M92 0v176l729 1041h-698v167h917v-165l-737 -1051h754v-168h-965zM414 1657q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x17c;" horiz-adv-x="934" d="M82 0v131l547 774h-535v144h742v-125l-549 -779h565v-145h-770zM324 1323q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x17d;" horiz-adv-x="1163" d="M92 0v176l729 1041h-698v167h917v-165l-737 -1051h754v-168h-965zM213 1903h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x17e;" horiz-adv-x="934" d="M82 0v131l547 774h-535v144h742v-125l-549 -779h565v-145h-770zM121 1569h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x17f;" horiz-adv-x="592" d="M63 905v144h134v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-1151h-172v905h-134z" />
+<glyph unicode="&#x192;" horiz-adv-x="1100" d="M-66 -358l35 137q94 -27 162 -27q65 0 95 41t65 199l194 913h-172l31 144h172l33 143q39 174 108.5 251t204.5 77q68 0 120 -14.5t87 -24.5l-47 -148q-47 17 -84 27t-80 10q-45 0 -66.5 -18t-38.5 -58.5t-32 -109.5l-31 -135h209l-29 -144h-211l-219 -1022 q-20 -98 -53.5 -154t-89 -91t-139.5 -35q-119 0 -224 39z" />
+<glyph unicode="&#x1a0;" horiz-adv-x="1487" d="M119 692q0 364 137 542.5t426 178.5q207 0 329 -87t179 -247h37q71 0 102 41t31 144v182h160v-182q0 -167 -71 -243.5t-212 -76.5h-12q20 -114 20 -252q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134 q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422z" />
+<glyph unicode="&#x1a1;" horiz-adv-x="1249" d="M117 522q0 281 119.5 419t343.5 138q317 0 417 -274q68 2 96.5 44t28.5 140v141h160v-141q0 -305 -252 -319q10 -87 10 -148q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311 t-211.5 97q-145 0 -215 -97.5t-70 -310.5z" />
+<glyph unicode="&#x1af;" horiz-adv-x="1524" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-305h41q71 0 102 41t31 144v182h159v-182q0 -170 -71.5 -245t-210.5 -75h-51v-366q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193 t-50.5 355z" />
+<glyph unicode="&#x1b0;" horiz-adv-x="1286" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-244h33q72 0 102.5 41t30.5 143v141h160v-141q0 -166 -69.5 -242.5t-213.5 -76.5h-43v-670h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5z " />
+<glyph unicode="&#x1cd;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM313 1905h149l185 -238l184 238h150l-230 -361h-211zM414 528h450l-225 674z" />
+<glyph unicode="&#x1ce;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM215 1569 h149l185 -238l184 238h150l-230 -361h-211zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z" />
+<glyph unicode="&#x1cf;" horiz-adv-x="770" d="M53 1905h149l185 -238l184 238h150l-230 -361h-211zM102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566z" />
+<glyph unicode="&#x1d0;" horiz-adv-x="512" d="M-76 1569h149l185 -238l184 238h150l-230 -361h-211zM170 0v1049h172v-1049h-172z" />
+<glyph unicode="&#x1d1;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM348 1905h149l185 -238 l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x1d2;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM244 1569h149l185 -238l184 238h150l-230 -361h-211zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97 q-145 0 -215 -97.5t-70 -310.5z" />
+<glyph unicode="&#x1d3;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM369 1905h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x1d4;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM248 1569h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x1d5;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM396 1794v139h610v-139h-610zM400 1610q0 53 23.5 79.5t82.5 26.5 q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM795 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1d6;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM275 1458v139h610v-139h-610zM279 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5 t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM674 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1d7;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM398 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5 q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM619 1737l123 311h235l-217 -311h-141zM793 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1d8;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM277 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5 t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM498 1401l123 311h235l-217 -311h-141zM672 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1d9;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM369 2048h149l185 -172l184 172h150l-230 -289h-211zM402 1610 q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM797 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1da;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM248 1712h149l185 -172l184 172h150l-230 -289h-211zM281 1274q0 53 23.5 79.5 t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM676 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1db;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM398 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5 q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM426 2048h236l123 -311h-142zM793 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1dc;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM277 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5 t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM305 1712h236l123 -311h-142zM672 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1fa;" horiz-adv-x="1288" d="M51 0l457 1339q-64 49 -64 158q0 88 47.5 142.5t149.5 54.5q104 0 151.5 -53.5t47.5 -143.5q0 -104 -62 -156l459 -1341h-195l-120 360h-564l-118 -360h-189zM414 528h450l-225 674zM545 1497q0 -100 96 -100q98 0 98 100t-98 100q-96 0 -96 -100zM559 1749l125 276h236 l-220 -276h-141z" />
+<glyph unicode="&#x1fb;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM287 299 q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5zM323 1354q0 88 47 142t150 54q104 0 151 -53t47 -143t-48 -143.5t-150 -53.5q-105 0 -151 55.5t-46 141.5zM407 1605l178 361h236l-272 -361h-142zM423 1354 q0 -101 97 -101q98 0 98 101q0 100 -98 100q-97 0 -97 -100z" />
+<glyph unicode="&#x1fc;" horiz-adv-x="1747" d="M45 0l533 1384h1044v-167h-604v-408h526v-168h-526v-473h604v-168h-788v383h-453l-145 -383h-191zM442 551h392v666h-140zM850 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x1fd;" horiz-adv-x="1724" d="M109 301q0 152 95 238.5t304 107.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q103 180 401 180q123 0 217.5 -32.5t137.5 -116.5q49 71 126.5 110t200.5 39q208 0 310 -117.5t102 -361.5v-96h-682q0 -200 68.5 -292.5t218.5 -92.5 q84 0 135 29.5t102 95.5l142 -88q-60 -90 -144 -138.5t-225 -48.5q-129 0 -232.5 44t-158.5 139q-95 -81 -213 -132t-217 -51q-140 0 -222.5 90.5t-82.5 241.5zM287 297q0 -92 49 -133t127 -41q86 0 165 42t163 107q-16 51 -20.5 95.5t-4.5 164.5l-168 -16 q-126 -11 -187 -35.5t-92.5 -70t-31.5 -113.5zM739 1208l178 361h236l-272 -361h-142zM940 639h512q-2 141 -58.5 219t-189.5 78q-121 0 -187.5 -70.5t-76.5 -226.5z" />
+<glyph unicode="&#x1fe;" horiz-adv-x="1364" d="M68 -115l184 271q-133 170 -133 536q0 364 137 542.5t426 178.5q225 0 360 -110l129 186h150l-195 -283q119 -177 119 -514q0 -373 -140.5 -547t-422.5 -174q-213 0 -340 97l-125 -183h-149zM313 692q0 -237 58 -366l565 823q-88 100 -254 100q-196 0 -282.5 -135 t-86.5 -422zM444 217q84 -82 238 -82q193 0 281 133t88 424q0 211 -47 338zM585 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x1ff;" horiz-adv-x="1157" d="M102 -76l129 189q-114 137 -114 409q0 281 119.5 419t343.5 138q161 0 268 -71l80 116h141l-137 -198q108 -145 108 -404q0 -273 -117.5 -413t-342.5 -140q-158 0 -261 66l-75 -111h-142zM295 522q0 -164 41 -258l420 608q-68 58 -176 58q-145 0 -215 -97.5t-70 -310.5z M410 168q63 -49 170 -49q143 0 212.5 98t69.5 305q0 158 -37 248zM454 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x218;" horiz-adv-x="1227" d="M96 242l150 100q117 -207 362 -207q147 0 231.5 61.5t84.5 168.5q0 61 -27 103t-71 70.5t-101 46t-119 33.5q-102 25 -190 51.5t-152.5 68.5t-101.5 107.5t-37 168.5q0 184 118.5 291.5t354.5 107.5q188 0 300 -69.5t177 -178.5l-147 -104q-54 90 -131.5 139t-198.5 49 q-135 0 -210 -59.5t-75 -159.5q0 -53 22.5 -89t64.5 -60.5t104.5 -42t142.5 -37.5q94 -25 179 -52.5t148.5 -72.5t100.5 -116t37 -181q0 -194 -127.5 -301t-372.5 -107q-187 0 -312 66t-204 205zM523 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151 t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x219;" horiz-adv-x="991" d="M100 158l138 84q79 -127 254 -127q114 0 170.5 43.5t56.5 117.5q0 44 -20 71.5t-62 48t-172 55.5q-187 43 -263.5 119t-76.5 202q0 139 100 223t277 84q137 0 230 -54t136 -130l-137 -84q-82 123 -233 123q-86 0 -145.5 -38t-59.5 -118q0 -71 52 -103t163 -59 q178 -46 246 -86t100.5 -98.5t32.5 -148.5q0 -147 -104 -230.5t-296 -83.5q-131 0 -235 49.5t-152 139.5zM398 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x21a;" horiz-adv-x="1184" d="M41 1217v167h1102v-167h-459v-1217h-184v1217h-459zM480 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x21b;" horiz-adv-x="729" d="M47 905v144h150v292h172v-292h266v-144h-266v-555q0 -127 25.5 -182t113.5 -55q76 0 141 28l45 -141q-100 -31 -198 -31q-160 0 -229.5 84t-69.5 264v588h-150zM332 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79 t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#x237;" horiz-adv-x="537" d="M-143 -365l43 142q73 -29 151 -29q84 0 109.5 58.5t25.5 168.5v1074h172v-1094q0 -190 -74 -270t-239 -80q-100 0 -188 30z" />
+<glyph unicode="&#x2c0;" horiz-adv-x="991" d="M10 1206q51 92 151.5 149.5t266.5 57.5q212 0 333.5 -104.5t121.5 -286.5q0 -103 -39.5 -184.5t-112 -150t-258.5 -177.5v-510h-174v586q175 95 251 155.5t112 125t36 139.5q0 112 -71.5 180.5t-196.5 68.5q-108 0 -170.5 -40.5t-97.5 -100.5z" />
+<glyph unicode="&#x2c6;" d="M209 1208l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph unicode="&#x2c7;" d="M209 1569h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph unicode="&#x2c9;" d="M238 1255v140h610v-140h-610z" />
+<glyph unicode="&#x2d8;" d="M215 1489h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202z" />
+<glyph unicode="&#x2d9;" d="M428 1323q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -63 -26.5 -89t-89.5 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x2da;" d="M344 1354q0 88 47 142t150 54q104 0 151 -53t47 -143t-48 -143.5t-150 -53.5q-105 0 -151 55.5t-46 141.5zM444 1354q0 -101 97 -101q98 0 98 101q0 100 -98 100q-97 0 -97 -100z" />
+<glyph unicode="&#x2db;" horiz-adv-x="930" d="M305 -211q0 92 79 167t245 120l71 -76q-133 -42 -193.5 -84t-60.5 -100q0 -35 19.5 -53.5t54.5 -18.5t63.5 11.5t59.5 27.5l55 -109q-53 -34 -99 -51.5t-99 -17.5q-93 0 -144 47t-51 137z" />
+<glyph unicode="&#x2dc;" d="M166 1221q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121z" />
+<glyph unicode="&#x2dd;" d="M225 1208l178 361h236l-272 -361h-142zM573 1208l179 361h235l-272 -361h-142z" />
+<glyph unicode="&#x300;" horiz-adv-x="0" d="M-274 1569h235l178 -361h-141z" />
+<glyph unicode="&#x301;" horiz-adv-x="0" d="M-61 1208l178 361h235l-272 -361h-141z" />
+<glyph unicode="&#x302;" horiz-adv-x="0" d="M-334 1208l230 361h210l228 -361h-150l-184 238l-184 -238h-150z" />
+<glyph unicode="&#x303;" horiz-adv-x="0" d="M-377 1221q6 125 67.5 193.5t162.5 68.5q55 0 96 -22.5t75.5 -48.5t65.5 -48.5t68 -22.5q87 0 96 129h121q-8 -122 -64.5 -192t-167.5 -70q-65 0 -105 22.5t-70.5 50.5t-58.5 50.5t-69 22.5q-51 0 -71.5 -36t-24.5 -97h-121z" />
+<glyph unicode="&#x304;" horiz-adv-x="0" d="M-305 1255v140h610v-140h-610z" />
+<glyph unicode="&#x306;" horiz-adv-x="0" d="M-328 1489h127q29 -125 197 -125q102 0 147 30.5t58 94.5h127q0 -125 -87.5 -204t-242.5 -79q-152 0 -239 81t-87 202z" />
+<glyph unicode="&#x307;" horiz-adv-x="0" d="M-115 1323q0 59 24.5 87t90.5 28t91.5 -28t25.5 -87q0 -63 -27 -89t-90 -26q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x308;" horiz-adv-x="0" d="M-305 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM90 1315q0 53 23.5 79.5t83.5 26.5q61 0 84.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-83.5 -23.5q-64 0 -85.5 29t-21.5 78z" />
+<glyph unicode="&#x309;" horiz-adv-x="0" d="M-182 1438q22 20 69 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -147 -156v-37h-99v113h25q74 0 74 55q0 27 -15.5 41t-54.5 14q-20 0 -49 -8t-51 -24z" />
+<glyph unicode="&#x30a;" horiz-adv-x="0" d="M-190 1346q0 86 45 137t143 51t144 -51t46 -137t-46 -137.5t-144 -51.5q-100 0 -144 53.5t-44 135.5zM-104 1346q0 -107 102 -107q104 0 104 107q0 106 -104 106q-102 0 -102 -106z" />
+<glyph unicode="&#x30c;" horiz-adv-x="0" d="M-334 1569h150l184 -238l184 238h150l-230 -361h-210z" />
+<glyph unicode="&#x323;" d="M428 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x374;" horiz-adv-x="420" d="M82 1128l65 361h215l-159 -361h-121z" />
+<glyph unicode="&#x375;" horiz-adv-x="420" d="M68 -231l159 360h121l-65 -360h-215z" />
+<glyph unicode="&#x37e;" horiz-adv-x="555" d="M156 98q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -34t27.5 -99q0 -123 -36.5 -223.5t-75.5 -147.5h-105q36 46 60 128t24 151q-59 0 -84.5 26.5t-25.5 85.5zM156 936q0 59 27.5 86t92.5 27q68 0 95.5 -27t27.5 -86q0 -64 -29.5 -88.5t-93.5 -24.5q-71 0 -95.5 30t-24.5 83z " />
+<glyph unicode="&#x384;" horiz-adv-x="414" d="M0 1208l178 361h236l-273 -361h-141z" />
+<glyph unicode="&#x385;" horiz-adv-x="0" d="M242 1300q0 54 21.5 79.5t80.5 25.5t83 -25.5t24 -79.5q0 -57 -25 -78.5t-82 -21.5q-61 0 -81.5 26.5t-20.5 73.5zM535 1208l122 361h230l-213 -361h-139zM862 1300q0 54 21.5 79.5t81.5 25.5q59 0 82.5 -25.5t23.5 -79.5q0 -57 -24.5 -78.5t-81.5 -21.5 q-62 0 -82.5 26.5t-20.5 73.5z" />
+<glyph unicode="&#x386;" horiz-adv-x="1288" d="M41 1024l123 360h237l-213 -360h-147zM51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM414 528h450l-225 674z" />
+<glyph unicode="&#x387;" horiz-adv-x="555" d="M156 745q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5z" />
+<glyph unicode="&#x388;" horiz-adv-x="1393" d="M2 1024l123 360h237l-213 -360h-147zM422 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846z" />
+<glyph unicode="&#x389;" horiz-adv-x="1604" d="M2 1024l123 360h237l-213 -360h-147zM422 0v1384h185v-583h630v583h185v-1384h-185v633h-630v-633h-185z" />
+<glyph unicode="&#x38a;" horiz-adv-x="1059" d="M2 1024l123 360h237l-213 -360h-147zM391 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566z" />
+<glyph unicode="&#x38c;" horiz-adv-x="1554" d="M2 1024l123 360h237l-213 -360h-147zM309 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM503 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135 t-86.5 -422z" />
+<glyph unicode="&#x38e;" horiz-adv-x="1497" d="M2 1024l123 360h237l-213 -360h-147zM391 1384h209l325 -673l332 673h199l-440 -849v-535h-187v526z" />
+<glyph unicode="&#x38f;" horiz-adv-x="1657" d="M2 1024l123 360h237l-213 -360h-147zM301 811q0 183 65 319.5t189.5 209.5t298.5 73q295 0 434 -151.5t139 -450.5q0 -266 -80 -408.5t-241 -183.5v-51h290v-168h-454v322q109 12 170 63.5t91 150t30 261.5q0 239 -91.5 345.5t-287.5 106.5q-180 0 -269.5 -110.5 t-89.5 -341.5q0 -159 26 -251.5t83.5 -144.5t181.5 -79v-322h-454v168h290v51q-164 45 -242.5 186.5t-78.5 405.5z" />
+<glyph unicode="&#x390;" horiz-adv-x="614" d="M-155 1300q0 54 21.5 79.5t80.5 25.5t83 -25.5t24 -79.5q0 -57 -25 -78.5t-82 -21.5q-61 0 -81.5 26.5t-20.5 73.5zM138 1208l122 361h230l-213 -361h-139zM168 301v748h174v-744q0 -106 20.5 -151t88.5 -45q53 0 100 18l41 -135q-78 -23 -172 -23q-140 0 -196 76.5 t-56 255.5zM465 1300q0 54 21.5 79.5t81.5 25.5q59 0 82.5 -25.5t23.5 -79.5q0 -57 -24.5 -78.5t-81.5 -21.5q-62 0 -82.5 26.5t-20.5 73.5z" />
+<glyph unicode="&#x391;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM414 528h450l-225 674z" />
+<glyph unicode="&#x392;" horiz-adv-x="1272" d="M182 0v1384h410q254 0 366.5 -72.5t112.5 -242.5q0 -139 -61.5 -212t-153.5 -101q137 -19 219 -101t82 -249q0 -213 -136 -309.5t-388 -96.5h-451zM367 168h188q176 0 255 23.5t117 77t38 145.5q0 86 -33.5 135.5t-103.5 72.5t-226 23h-235v-477zM367 809h204 q166 0 238 53t72 166q0 106 -66 149.5t-235 43.5h-213v-412z" />
+<glyph unicode="&#x393;" horiz-adv-x="1067" d="M182 0v1384h844v-161h-659v-1223h-185z" />
+<glyph unicode="&#x394;" horiz-adv-x="1260" d="M51 0v88q115 313 231.5 648t233.5 648h234q110 -313 227 -648t231 -648v-88h-1157zM266 160h715l-303 887q-16 46 -53 172h-4l-24 -87l-28 -88z" />
+<glyph unicode="&#x395;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846z" />
+<glyph unicode="&#x396;" horiz-adv-x="1163" d="M92 0v176l729 1041h-698v167h917v-165l-737 -1051h754v-168h-965z" />
+<glyph unicode="&#x397;" horiz-adv-x="1364" d="M182 0v1384h185v-583h630v583h185v-1384h-185v633h-630v-633h-185z" />
+<glyph unicode="&#x398;" horiz-adv-x="1446" d="M119 692q0 370 147 545.5t457 175.5q308 0 456 -175.5t148 -545.5q0 -372 -148 -546.5t-456 -174.5q-305 0 -454.5 175t-149.5 546zM313 692q0 -294 99 -428.5t311 -134.5q211 0 310.5 134.5t99.5 428.5q0 292 -98.5 427.5t-311.5 135.5q-214 0 -312 -135.5t-98 -427.5z M483 618v177h478v-177h-478z" />
+<glyph unicode="&#x399;" horiz-adv-x="770" d="M102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566z" />
+<glyph unicode="&#x39a;" horiz-adv-x="1264" d="M182 0v1384h185v-679l585 679h230l-566 -636l594 -748h-235l-477 614l-131 -147v-467h-185z" />
+<glyph unicode="&#x39b;" horiz-adv-x="1229" d="M51 0l447 1384h237l443 -1384h-193l-373 1204l-374 -1204h-187z" />
+<glyph unicode="&#x39c;" horiz-adv-x="1593" d="M182 0v1384h250l367 -753l370 753h242v-1384h-176v1147l-383 -770h-115l-379 770v-1147h-176z" />
+<glyph unicode="&#x39d;" horiz-adv-x="1386" d="M182 0v1384h271l573 -1087v1087h178v-1384h-219l-625 1188v-1188h-178z" />
+<glyph unicode="&#x39e;" horiz-adv-x="1102" d="M125 0v168h852v-168h-852zM125 1217v167h852v-167h-852zM184 645v168h731v-168h-731z" />
+<glyph unicode="&#x39f;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422z" />
+<glyph unicode="&#x3a0;" horiz-adv-x="1327" d="M182 0v1384h963v-1384h-184v1217h-594v-1217h-185z" />
+<glyph unicode="&#x3a1;" horiz-adv-x="1182" d="M182 0v1384h410q259 0 375 -107t116 -335q0 -250 -117.5 -361.5t-381.5 -111.5h-217v-469h-185zM367 637h178q146 0 213.5 28.5t99 92t31.5 180.5q0 145 -72 212t-246 67h-204v-580z" />
+<glyph unicode="&#x3a3;" horiz-adv-x="1108" d="M74 0v170l512 535l-512 518v161h911v-165h-674l482 -494v-39l-500 -520h723v-166h-942z" />
+<glyph unicode="&#x3a4;" horiz-adv-x="1184" d="M41 1217v167h1102v-167h-459v-1217h-184v1217h-459z" />
+<glyph unicode="&#x3a5;" horiz-adv-x="1147" d="M41 1384h209l325 -673l332 673h199l-440 -849v-535h-187v526z" />
+<glyph unicode="&#x3a6;" horiz-adv-x="1499" d="M119 690q0 293 131 437.5t405 164.5v144h179v-142q280 -18 413 -163.5t133 -440.5t-133 -439.5t-413 -160.5v-139h-179v139q-272 21 -404 165t-132 435zM313 690q0 -201 77 -311.5t265 -132.5v893q-188 -23 -265 -135.5t-77 -313.5zM834 246q192 18 273 130.5t81 313.5 q0 203 -80 316.5t-274 132.5v-893z" />
+<glyph unicode="&#x3a7;" horiz-adv-x="1208" d="M53 0l449 694l-436 690h217l327 -546l338 546h207l-442 -684l442 -700h-217l-336 557l-342 -557h-207z" />
+<glyph unicode="&#x3a8;" horiz-adv-x="1493" d="M131 801v583h184v-563q0 -177 87.5 -282.5t254.5 -124.5v970h179v-970q165 18 254.5 124t89.5 279v567h182v-583q0 -260 -128.5 -391.5t-397.5 -149.5v-305h-179v305q-268 18 -397 150t-129 391z" />
+<glyph unicode="&#x3a9;" horiz-adv-x="1364" d="M119 811q0 183 65 319.5t189.5 209.5t298.5 73q295 0 434 -151.5t139 -450.5q0 -266 -80 -408.5t-241 -183.5v-51h290v-168h-454v322q109 12 170 63.5t91 150t30 261.5q0 239 -91.5 345.5t-287.5 106.5q-180 0 -269.5 -110.5t-89.5 -341.5q0 -159 26 -251.5t83.5 -144.5 t181.5 -79v-322h-454v168h290v51q-164 45 -242.5 186.5t-78.5 405.5z" />
+<glyph unicode="&#x3aa;" horiz-adv-x="770" d="M90 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566zM485 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5 q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x3ab;" horiz-adv-x="1147" d="M41 1384h209l325 -673l332 673h199l-440 -849v-535h-187v526zM275 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM670 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5 q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x3ac;" horiz-adv-x="1219" d="M117 522q0 172 52 297.5t147.5 192.5t220.5 67q84 0 161.5 -28.5t143.5 -108.5q6 82 10 107h174q-32 -224 -39.5 -312t-7.5 -162v-270q0 -116 20 -156t80 -40q43 0 88 18l41 -135q-60 -23 -159 -23q-121 0 -168 65.5t-54 207.5q-41 -142 -127 -207.5t-194 -65.5 q-189 0 -289 143.5t-100 409.5zM297 516q0 -385 227 -385q280 0 307 639q-53 74 -119.5 117t-138.5 43q-276 0 -276 -414zM483 1208l178 361h236l-273 -361h-141z" />
+<glyph unicode="&#x3ad;" horiz-adv-x="1044" d="M129 287q0 88 47 147.5t115 87.5q-68 29 -115 89.5t-47 140.5q0 102 52 175.5t149.5 112.5t218.5 39q141 0 234.5 -47t148.5 -145l-141 -86q-39 61 -94.5 98t-147.5 37q-109 0 -175.5 -47t-66.5 -139q0 -52 26 -82t77 -44t161 -14h222v-143h-232q-131 0 -192.5 -40 t-61.5 -130q0 -88 71.5 -136t186.5 -48q86 0 141.5 34.5t98.5 100.5l141 -86q-49 -84 -138 -138.5t-243 -54.5q-214 0 -325 83t-111 235zM446 1208l178 361h236l-273 -361h-141z" />
+<glyph unicode="&#x3ae;" horiz-adv-x="1169" d="M170 0v1049h174v-158q188 188 350 188q164 0 239 -99t75 -300v-1075h-174v1013q0 116 -16.5 180.5t-52.5 92t-110 27.5q-59 0 -141 -47.5t-170 -127.5v-743h-174zM483 1208l178 361h236l-273 -361h-141z" />
+<glyph unicode="&#x3af;" horiz-adv-x="614" d="M133 1208l178 361h236l-273 -361h-141zM168 301v748h174v-744q0 -106 20.5 -151t88.5 -45q53 0 100 18l41 -135q-78 -23 -172 -23q-140 0 -196 76.5t-56 255.5z" />
+<glyph unicode="&#x3b0;" horiz-adv-x="1143" d="M156 1300q0 54 21.5 79.5t80.5 25.5t83 -25.5t24 -79.5q0 -57 -25 -78.5t-82 -21.5q-61 0 -81.5 26.5t-20.5 73.5zM162 354v695h176v-689q0 -110 65.5 -177.5t171.5 -67.5q121 0 196 99t75 325q0 174 -27.5 303t-52.5 207h184q24 -56 50 -207.5t26 -282.5 q0 -298 -109 -444t-348 -146q-207 0 -307 99t-100 286zM449 1208l122 361h230l-213 -361h-139zM776 1300q0 54 21.5 79.5t81.5 25.5q59 0 82.5 -25.5t23.5 -79.5q0 -57 -24.5 -78.5t-81.5 -21.5q-62 0 -82.5 26.5t-20.5 73.5z" />
+<glyph unicode="&#x3b1;" horiz-adv-x="1219" d="M117 522q0 172 52 297.5t147.5 192.5t220.5 67q84 0 161.5 -28.5t143.5 -108.5q6 82 10 107h174q-32 -224 -39.5 -312t-7.5 -162v-270q0 -116 20 -156t80 -40q43 0 88 18l41 -135q-60 -23 -159 -23q-121 0 -168 65.5t-54 207.5q-41 -142 -127 -207.5t-194 -65.5 q-189 0 -289 143.5t-100 409.5zM297 516q0 -385 227 -385q280 0 307 639q-53 74 -119.5 117t-138.5 43q-276 0 -276 -414z" />
+<glyph unicode="&#x3b2;" horiz-adv-x="1176" d="M162 -397v1431q0 243 105 364.5t306 121.5q175 0 279 -91.5t104 -250.5q0 -140 -73.5 -226t-182.5 -108q166 -17 264.5 -127.5t98.5 -282.5q0 -133 -52 -239t-149 -166t-221 -60q-113 0 -190.5 38t-114.5 69v-473h-174zM336 213q39 -29 117.5 -62.5t183.5 -33.5 q113 0 180.5 90t67.5 235q0 314 -418 314v145q313 0 313 258q0 113 -53 164t-158 51q-120 0 -176.5 -77.5t-56.5 -254.5v-829z" />
+<glyph unicode="&#x3b3;" horiz-adv-x="1065" d="M51 1049h187l280 -848q80 112 145.5 252.5t105.5 286.5t40 274v35h182v-43q0 -152 -59 -332t-153.5 -349.5t-196.5 -285.5v-434h-174v434z" />
+<glyph unicode="&#x3b4;" horiz-adv-x="1200" d="M117 455q0 130 53 239.5t140.5 180.5t193.5 96q-111 74 -154.5 117.5t-66.5 89.5t-23 106q0 105 74 170.5t237 65.5q146 0 245 -28t140 -50l-61 -133q-61 28 -142 54t-186 26q-71 0 -100 -27t-29 -59q0 -49 20.5 -83.5t68.5 -72.5t132 -86q160 -94 244 -176.5t132 -181.5 t48 -220q0 -159 -59 -275t-170.5 -177.5t-255.5 -61.5q-226 0 -353.5 131t-127.5 355zM297 453q0 -156 84 -247t231 -91q127 0 209 96t82 266q0 126 -61.5 225t-210.5 193q-31 -6 -86.5 -29.5t-110.5 -73t-96 -132t-41 -207.5z" />
+<glyph unicode="&#x3b5;" horiz-adv-x="1044" d="M129 287q0 88 47 147.5t115 87.5q-68 29 -115 89.5t-47 140.5q0 102 52 175.5t149.5 112.5t218.5 39q141 0 234.5 -47t148.5 -145l-141 -86q-39 61 -94.5 98t-147.5 37q-109 0 -175.5 -47t-66.5 -139q0 -52 26 -82t77 -44t161 -14h222v-143h-232q-131 0 -192.5 -40 t-61.5 -130q0 -88 71.5 -136t186.5 -48q86 0 141.5 34.5t98.5 100.5l141 -86q-49 -84 -138 -138.5t-243 -54.5q-214 0 -325 83t-111 235z" />
+<glyph unicode="&#x3b6;" horiz-adv-x="909" d="M129 449q0 75 21.5 184.5t76 232.5t143.5 248t224 227h-426v148h657v-125q-139 -92 -256.5 -241t-187.5 -325t-70 -335q0 -100 27 -164.5t77.5 -104t145.5 -63.5l109 -26q100 -24 146 -82.5t46 -161.5q0 -48 -20.5 -120t-46.5 -136h-179q32 63 54 125.5t22 103.5 q0 100 -125 127l-78 19q-146 30 -214 82t-107 145t-39 242z" />
+<glyph unicode="&#x3b7;" horiz-adv-x="1169" d="M170 0v1049h174v-158q188 188 350 188q164 0 239 -99t75 -300v-1075h-174v1013q0 116 -16.5 180.5t-52.5 92t-110 27.5q-59 0 -141 -47.5t-170 -127.5v-743h-174z" />
+<glyph unicode="&#x3b8;" horiz-adv-x="1169" d="M131 748q0 308 45 461.5t143 233t267 79.5q166 0 264 -79t143 -231.5t45 -463.5q0 -333 -44 -479.5t-141 -223t-267 -76.5q-172 0 -269.5 77t-141.5 224.5t-44 477.5zM311 698q0 -247 26 -358t84 -168t161 -57q104 0 163 58.5t86 170t27 354.5h-547zM311 838h547 q-4 229 -31.5 331.5t-84.5 154.5t-156 52q-147 0 -211 -117t-64 -421z" />
+<glyph unicode="&#x3b9;" horiz-adv-x="614" d="M168 301v748h174v-744q0 -106 20.5 -151t88.5 -45q53 0 100 18l41 -135q-78 -23 -172 -23q-140 0 -196 76.5t-56 255.5z" />
+<glyph unicode="&#x3ba;" horiz-adv-x="1057" d="M170 0v1049h174v-504l436 504h207l-412 -461l435 -588h-209l-342 487l-115 -131v-356h-174z" />
+<glyph unicode="&#x3bb;" horiz-adv-x="1092" d="M51 0l422 1055q-45 159 -80 239t-96 80q-41 0 -78 -12t-59 -29l-41 142q33 16 87 31.5t101 15.5q85 0 135 -27.5t86 -93.5t72 -199l256 -915q25 -88 54.5 -121t64.5 -33q27 0 47 8l47 -141q-69 -16 -145 -16q-71 0 -113 31.5t-76.5 104.5t-60.5 187l-131 545l-299 -852 h-193z" />
+<glyph unicode="&#x3bc;" horiz-adv-x="1169" d="M139 -395v1444h174v-793q43 -53 113 -85t143 -32q153 0 273 144v766h176v-1049h-166l-10 119q-60 -76 -123.5 -113t-147.5 -37q-75 0 -132.5 15.5t-125.5 66.5v-446h-174z" />
+<glyph unicode="&#x3bd;" horiz-adv-x="1024" d="M51 1049h189l268 -865q119 190 201 422t82 402v41h182v-35q0 -148 -55.5 -326.5t-156.5 -368.5t-206 -319h-160z" />
+<glyph unicode="&#x3be;" horiz-adv-x="911" d="M129 416q0 135 67.5 227t176.5 133q-72 41 -123 117t-51 184q0 90 40 165t138 112h-234v135h654v-141h-49q-149 0 -224 -25.5t-111 -84.5t-36 -159q0 -97 58 -155t159 -58h176v-145h-197q-100 0 -182 -86.5t-82 -204.5q0 -86 25.5 -137t66.5 -83t93.5 -48.5t105.5 -30.5 q153 -37 208.5 -100t55.5 -170q0 -50 -18.5 -120t-46.5 -136h-168q44 100 57.5 146.5t13.5 82.5q0 58 -41.5 93.5t-152.5 64.5q-62 16 -129.5 38.5t-122.5 66.5t-91 120t-36 199z" />
+<glyph unicode="&#x3bf;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5z" />
+<glyph unicode="&#x3c0;" horiz-adv-x="1331" d="M10 985q45 23 127 43.5t189 20.5h946v-140h-258v-604q0 -106 20.5 -144t89.5 -38q60 0 107 18l43 -135q-80 -22 -174 -22q-102 0 -155.5 29t-79 96t-25.5 192v608h-357v-622q0 -97 -4 -166.5t-20 -120.5h-201q49 142 49 299v610q-41 0 -117 -12.5t-127 -36.5z" />
+<glyph unicode="&#x3c1;" horiz-adv-x="1178" d="M139 -395v930q0 544 463 544q227 0 343 -144t116 -390q0 -182 -52 -312.5t-147.5 -197t-224.5 -66.5q-113 0 -195 45t-129 111v-520h-174zM313 301q52 -78 128.5 -128t162.5 -50q126 0 201.5 104t75.5 299q0 205 -72.5 306.5t-204.5 101.5q-105 0 -165.5 -45.5t-93 -143 t-32.5 -256.5v-188z" />
+<glyph unicode="&#x3c2;" horiz-adv-x="981" d="M117 522q0 557 469 557q258 0 368 -192l-141 -86q-39 63 -92 98t-139 35q-152 0 -218.5 -109.5t-66.5 -302.5q0 -106 27.5 -172.5t71.5 -107.5t99.5 -64.5t110.5 -42.5q117 -38 160.5 -70t68.5 -81t25 -123q0 -50 -18.5 -120t-46.5 -136h-177q38 83 55 135.5t17 93.5 q0 64 -41 94.5t-104 53.5q-66 22 -140.5 47.5t-138 80t-106.5 151.5t-43 261z" />
+<glyph unicode="&#x3c3;" horiz-adv-x="1245" d="M117 492q0 286 118.5 421.5t385.5 135.5h550v-146h-264q82 -74 120 -179.5t38 -223.5q0 -258 -125 -394.5t-356 -136.5q-226 0 -346.5 136.5t-120.5 386.5zM297 485q0 -175 74 -272.5t209 -97.5q151 0 229 97t78 277q0 279 -139 414h-160q-106 0 -169 -43t-92.5 -125.5 t-29.5 -249.5z" />
+<glyph unicode="&#x3c4;" horiz-adv-x="997" d="M18 983q123 66 304 66h622v-144h-362v-600q0 -106 20.5 -144t85.5 -38q55 0 96 18l41 -135q-71 -22 -168 -22q-140 0 -194.5 69.5t-54.5 247.5v604h-97q-141 0 -239 -49z" />
+<glyph unicode="&#x3c5;" horiz-adv-x="1143" d="M162 354v695h176v-689q0 -110 65.5 -177.5t171.5 -67.5q121 0 196 99t75 325q0 174 -27.5 303t-52.5 207h184q24 -56 50 -207.5t26 -282.5q0 -298 -109 -444t-348 -146q-207 0 -307 99t-100 286z" />
+<glyph unicode="&#x3c6;" horiz-adv-x="1366" d="M117 522q0 274 115 405.5t370 147.5v414h168v-414q246 -17 362.5 -148t116.5 -405q0 -271 -115.5 -400.5t-363.5 -148.5v-368h-168v368q-260 19 -372.5 152t-112.5 397zM297 522q0 -201 70.5 -296.5t234.5 -114.5v825q-158 -18 -231.5 -111t-73.5 -303zM770 113 q168 20 234.5 120.5t66.5 288.5q0 189 -66.5 291t-234.5 123v-823z" />
+<glyph unicode="&#x3c7;" horiz-adv-x="1069" d="M55 1049q87 30 135 30q76 0 128.5 -41t93.5 -149l143 -400l238 560h188l-350 -697l168 -401q39 -101 71.5 -148t79.5 -47q18 0 49 13l48 -138q-70 -26 -146 -26q-72 0 -119 40t-94.5 138t-159.5 424l-268 -592h-188l377 731l-196 484q-20 52 -41.5 75t-53.5 23 q-26 0 -60 -13z" />
+<glyph unicode="&#x3c8;" horiz-adv-x="1378" d="M162 416v633h174v-629q0 -127 69.5 -209t210.5 -98v1378h170v-1374q136 22 212.5 131.5t76.5 290.5q0 174 -24.5 302t-46.5 208h184q30 -95 52 -239t22 -251q0 -266 -119 -414t-357 -170v-370h-170v366q-233 13 -343.5 123.5t-110.5 321.5z" />
+<glyph unicode="&#x3c9;" horiz-adv-x="1636" d="M117 395q0 149 57 345.5t137 306.5l187 -35q-86 -120 -139.5 -287t-53.5 -303q0 -305 199 -305q92 0 158.5 100t66.5 318v274h180v-274q0 -201 61 -309.5t163 -108.5q198 0 198 305q0 141 -53.5 304.5t-136.5 285.5l186 35q82 -114 137.5 -298.5t55.5 -347.5 q0 -221 -103.5 -326.5t-273.5 -105.5q-123 0 -207 68.5t-119 189.5q-33 -121 -117 -189.5t-206 -68.5q-170 0 -273.5 103.5t-103.5 322.5z" />
+<glyph unicode="&#x3ca;" horiz-adv-x="614" d="M-69 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM168 301v748h174v-744q0 -106 20.5 -151t88.5 -45q53 0 100 18l41 -135q-78 -23 -172 -23q-140 0 -196 76.5t-56 255.5zM326 1315 q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x3cb;" horiz-adv-x="1143" d="M162 354v695h176v-689q0 -110 65.5 -177.5t171.5 -67.5q121 0 196 99t75 325q0 174 -27.5 303t-52.5 207h184q24 -56 50 -207.5t26 -282.5q0 -298 -109 -444t-348 -146q-207 0 -307 99t-100 286zM242 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5 q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM637 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x3cc;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM483 1208l178 361 h236l-273 -361h-141z" />
+<glyph unicode="&#x3cd;" horiz-adv-x="1143" d="M162 354v695h176v-689q0 -110 65.5 -177.5t171.5 -67.5q121 0 196 99t75 325q0 174 -27.5 303t-52.5 207h184q24 -56 50 -207.5t26 -282.5q0 -298 -109 -444t-348 -146q-207 0 -307 99t-100 286zM444 1208l178 361h236l-273 -361h-141z" />
+<glyph unicode="&#x3ce;" horiz-adv-x="1636" d="M117 395q0 149 57 345.5t137 306.5l187 -35q-86 -120 -139.5 -287t-53.5 -303q0 -305 199 -305q92 0 158.5 100t66.5 318v274h180v-274q0 -201 61 -309.5t163 -108.5q198 0 198 305q0 141 -53.5 304.5t-136.5 285.5l186 35q82 -114 137.5 -298.5t55.5 -347.5 q0 -221 -103.5 -326.5t-273.5 -105.5q-123 0 -207 68.5t-119 189.5q-33 -121 -117 -189.5t-206 -68.5q-170 0 -273.5 103.5t-103.5 322.5zM729 1208l178 361h236l-273 -361h-141z" />
+<glyph unicode="&#x400;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM340 1905h236l178 -361h-141z" />
+<glyph unicode="&#x401;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM287 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM682 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5 q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x402;" horiz-adv-x="1360" d="M16 1229v155h815v-155h-313v-422h211q295 0 424 -96.5t129 -313.5q0 -202 -138.5 -299.5t-438.5 -97.5v154q145 0 226 23.5t118.5 75.5t37.5 148q0 123 -75.5 185.5t-257.5 62.5h-236v-649h-184v1229h-318z" />
+<glyph unicode="&#x403;" horiz-adv-x="1067" d="M182 0v1384h844v-161h-659v-1223h-185zM436 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x404;" horiz-adv-x="1321" d="M129 692q0 361 146.5 541t451.5 180q121 0 216 -30t160.5 -82.5t119.5 -147.5l-152 -100q-44 74 -89 112.5t-108 61t-147 22.5q-201 0 -294 -125t-107 -344h673v-168h-673q12 -235 108 -356t295 -121q118 0 205 46.5t156 160.5l153 -100q-66 -106 -134.5 -160.5 t-159.5 -82.5t-214 -28q-311 0 -458.5 179.5t-147.5 541.5z" />
+<glyph unicode="&#x405;" horiz-adv-x="1227" d="M96 242l150 100q117 -207 362 -207q147 0 231.5 61.5t84.5 168.5q0 61 -27 103t-71 70.5t-101 46t-119 33.5q-102 25 -190 51.5t-152.5 68.5t-101.5 107.5t-37 168.5q0 184 118.5 291.5t354.5 107.5q188 0 300 -69.5t177 -178.5l-147 -104q-54 90 -131.5 139t-198.5 49 q-135 0 -210 -59.5t-75 -159.5q0 -53 22.5 -89t64.5 -60.5t104.5 -42t142.5 -37.5q94 -25 179 -52.5t148.5 -72.5t100.5 -116t37 -181q0 -194 -127.5 -301t-372.5 -107q-187 0 -312 66t-204 205z" />
+<glyph unicode="&#x406;" horiz-adv-x="770" d="M102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566z" />
+<glyph unicode="&#x407;" horiz-adv-x="770" d="M90 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566zM485 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5 q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x408;" horiz-adv-x="885" d="M51 20l68 158q32 -16 92 -30.5t98 -14.5q81 0 125 28t63 92.5t19 199.5v931h184v-1007q0 -203 -89 -305.5t-300 -102.5q-59 0 -133 14.5t-127 36.5z" />
+<glyph unicode="&#x409;" horiz-adv-x="1944" d="M16 4l33 148q22 -9 45 -9q152 0 226.5 277.5t74.5 789.5v174h735v-530h218q276 0 400 -105.5t124 -334.5q0 -217 -132 -315.5t-386 -98.5h-410v1223h-364v-84q0 -528 -116 -841.5t-325 -313.5q-65 0 -123 20zM1130 162h213q158 0 247 58.5t89 197.5q0 104 -34.5 163 t-107 85t-218.5 26h-189v-530z" />
+<glyph unicode="&#x40a;" horiz-adv-x="1978" d="M182 0v1384h185v-550h612v550h186v-550h215q277 0 402 -96.5t125 -323.5q0 -217 -133.5 -315.5t-387.5 -98.5h-407v672h-612v-672h-185zM1165 162h213q158 0 247 58.5t89 197.5t-76 196.5t-284 57.5h-189v-510z" />
+<glyph unicode="&#x40b;" horiz-adv-x="1380" d="M16 1229v155h811v-155h-321v-412q184 62 354 62q215 0 307.5 -108t92.5 -339v-432h-185v348q0 166 -21 239.5t-73 103.5t-176 30q-47 0 -128 -12.5t-171 -38.5v-670h-184v1229h-306z" />
+<glyph unicode="&#x40c;" horiz-adv-x="1247" d="M182 0v1384h185v-600h223q77 0 132.5 61.5t106 192.5t101.5 346h192q-70 -313 -154.5 -473.5t-211.5 -201.5q92 -33 152.5 -88.5t104.5 -139.5t77.5 -202.5t74.5 -278.5h-194q-83 314 -131 420t-110.5 153.5t-158.5 47.5h-204v-621h-185zM526 1544l178 361h236l-272 -361 h-142z" />
+<glyph unicode="&#x40d;" horiz-adv-x="1391" d="M182 0v1384h176v-1142l584 1142h266v-1384h-176v1194l-618 -1194h-232zM420 1905h236l178 -361h-141z" />
+<glyph unicode="&#x40e;" horiz-adv-x="1196" d="M51 1384h199l364 -827l361 827h190l-518 -1167q-55 -127 -142.5 -186.5t-232.5 -59.5q-97 0 -202 35l57 154q31 -15 76 -23t80 -8q145 0 202 143l27 66zM291 1776h158q12 -74 56 -111t110 -37q88 0 125.5 37t48.5 111h157q0 -71 -39.5 -130.5t-113.5 -91.5t-176 -32 q-98 0 -172 33t-114 93t-40 128z" />
+<glyph unicode="&#x40f;" horiz-adv-x="1399" d="M182 0v1384h191v-1216h653v1216h191v-1384h-424v-262h-187v262h-424z" />
+<glyph unicode="&#x410;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM414 528h450l-225 674z" />
+<glyph unicode="&#x411;" horiz-adv-x="1239" d="M182 0v1384h879v-157h-694v-420h254q278 0 401 -92t123 -301q0 -219 -137.5 -316.5t-376.5 -97.5h-449zM367 162h194q160 0 236.5 25t115.5 78.5t39 144.5q0 86 -35.5 139t-103.5 76.5t-213 23.5h-233v-487z" />
+<glyph unicode="&#x412;" horiz-adv-x="1272" d="M182 0v1384h410q254 0 366.5 -72.5t112.5 -242.5q0 -139 -61.5 -212t-153.5 -101q137 -19 219 -101t82 -249q0 -213 -136 -309.5t-388 -96.5h-451zM367 168h188q176 0 255 23.5t117 77t38 145.5q0 86 -33.5 135.5t-103.5 72.5t-226 23h-235v-477zM367 809h204 q166 0 238 53t72 166q0 106 -66 149.5t-235 43.5h-213v-412z" />
+<glyph unicode="&#x413;" horiz-adv-x="1067" d="M182 0v1384h844v-161h-659v-1223h-185z" />
+<glyph unicode="&#x414;" horiz-adv-x="1313" d="M27 162h116q69 132 127.5 333t90.5 423t34 466h723v-1222h168v-424h-180v262h-899v-262h-180v424zM324 162h610v1061h-359q-15 -293 -82.5 -581t-168.5 -480z" />
+<glyph unicode="&#x415;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846z" />
+<glyph unicode="&#x416;" horiz-adv-x="1817" d="M82 0q74 304 123 420t115.5 183.5t171.5 105.5q-129 43 -213 201.5t-154 473.5h194q76 -323 155 -461.5t183 -138.5h160v600h184v-600h160q76 0 130 59.5t104 189t102 351.5h195q-71 -316 -156 -475t-211 -200q92 -33 153.5 -88.5t104.5 -139.5t77 -202.5t75 -278.5h-195 q-83 313 -131.5 419.5t-109.5 154t-156 47.5h-142v-621h-184v621h-141q-103 0 -167.5 -55t-117 -180.5t-115.5 -385.5h-194z" />
+<glyph unicode="&#x417;" horiz-adv-x="1169" d="M45 199l145 106q54 -80 144.5 -128t191.5 -48q336 0 336 270q0 113 -67.5 177.5t-210.5 64.5h-260v160h247q129 0 200 52t71 177q0 111 -72 169t-201 58q-104 0 -193 -28.5t-175 -106.5l-111 142q80 67 191.5 108t293.5 41q219 0 341 -98t122 -285q0 -231 -215 -311 q119 -39 175.5 -133t56.5 -203q0 -116 -63.5 -210.5t-182.5 -148t-285 -53.5q-155 0 -279 55.5t-200 172.5z" />
+<glyph unicode="&#x418;" horiz-adv-x="1391" d="M182 0v1384h176v-1142l584 1142h266v-1384h-176v1194l-618 -1194h-232z" />
+<glyph unicode="&#x419;" horiz-adv-x="1391" d="M182 0v1384h176v-1142l584 1142h266v-1384h-176v1194l-618 -1194h-232zM377 1776h158q12 -74 56 -111t110 -37q88 0 125.5 37t48.5 111h157q0 -71 -39.5 -130.5t-113.5 -91.5t-176 -32q-98 0 -172 33t-114 93t-40 128z" />
+<glyph unicode="&#x41a;" horiz-adv-x="1247" d="M182 0v1384h185v-600h223q77 0 132.5 61.5t106 192.5t101.5 346h192q-70 -313 -154.5 -473.5t-211.5 -201.5q92 -33 152.5 -88.5t104.5 -139.5t77.5 -202.5t74.5 -278.5h-194q-83 314 -131 420t-110.5 153.5t-158.5 47.5h-204v-621h-185z" />
+<glyph unicode="&#x41b;" horiz-adv-x="1337" d="M16 4l33 148q22 -9 45 -9q152 0 226.5 277.5t74.5 789.5v174h760v-1384h-184v1223h-391v-84q0 -528 -116 -841.5t-325 -313.5q-65 0 -123 20z" />
+<glyph unicode="&#x41c;" horiz-adv-x="1593" d="M182 0v1384h250l367 -753l370 753h242v-1384h-176v1147l-383 -770h-115l-379 770v-1147h-176z" />
+<glyph unicode="&#x41d;" horiz-adv-x="1364" d="M182 0v1384h185v-583h630v583h185v-1384h-185v633h-630v-633h-185z" />
+<glyph unicode="&#x41e;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422z" />
+<glyph unicode="&#x41f;" horiz-adv-x="1327" d="M182 0v1384h963v-1384h-184v1217h-594v-1217h-185z" />
+<glyph unicode="&#x420;" horiz-adv-x="1182" d="M182 0v1384h410q259 0 375 -107t116 -335q0 -250 -117.5 -361.5t-381.5 -111.5h-217v-469h-185zM367 637h178q146 0 213.5 28.5t99 92t31.5 180.5q0 145 -72 212t-246 67h-204v-580z" />
+<glyph unicode="&#x421;" horiz-adv-x="1321" d="M129 692q0 361 146.5 541t451.5 180q121 0 216 -30t160.5 -82.5t119.5 -147.5l-152 -100q-44 74 -89 112.5t-108 61t-147 22.5q-208 0 -305.5 -138.5t-97.5 -418.5q0 -276 96 -416.5t309 -140.5q118 0 205 46.5t156 160.5l153 -100q-66 -106 -134.5 -160.5t-159.5 -82.5 t-214 -28q-311 0 -458.5 179.5t-147.5 541.5z" />
+<glyph unicode="&#x422;" horiz-adv-x="1184" d="M41 1217v167h1102v-167h-459v-1217h-184v1217h-459z" />
+<glyph unicode="&#x423;" horiz-adv-x="1196" d="M51 1384h199l364 -827l361 827h190l-518 -1167q-55 -127 -142.5 -186.5t-232.5 -59.5q-97 0 -202 35l57 154q31 -15 76 -23t80 -8q145 0 202 143l27 66z" />
+<glyph unicode="&#x424;" horiz-adv-x="1503" d="M78 694q0 273 147.5 403t446.5 146v191h164v-191q301 -14 445 -144t144 -405q0 -272 -146 -401t-443 -143v-197h-164v197q-301 14 -447.5 143t-146.5 401zM268 694q0 -186 91.5 -282.5t312.5 -108.5v787q-210 -13 -307 -103.5t-97 -292.5zM836 303q217 12 309 108.5 t92 282.5q0 187 -92 284t-309 112v-787z" />
+<glyph unicode="&#x425;" horiz-adv-x="1208" d="M53 0l449 694l-436 690h217l327 -546l338 546h207l-442 -684l442 -700h-217l-336 557l-342 -557h-207z" />
+<glyph unicode="&#x426;" horiz-adv-x="1346" d="M182 0v1384h185v-1216h602v1216h182v-1222h168v-424h-180v262h-957z" />
+<glyph unicode="&#x427;" horiz-adv-x="1253" d="M80 952v432h184v-348q0 -169 21.5 -241.5t73 -102.5t169.5 -30q151 0 357 55v667h186v-1384h-186v563q-242 -59 -402 -59q-211 0 -307 104.5t-96 343.5z" />
+<glyph unicode="&#x428;" horiz-adv-x="1898" d="M182 0v1384h185v-1222h491v1222h182v-1222h492v1222h184v-1384h-1534z" />
+<glyph unicode="&#x429;" horiz-adv-x="1911" d="M182 0v1384h185v-1222h491v1222h182v-1222h492v1222h184v-1222h168v-424h-180v262h-1522z" />
+<glyph unicode="&#x42a;" horiz-adv-x="1434" d="M41 1223v161h567v-530h228q276 0 401 -104.5t125 -333.5q0 -217 -133 -316.5t-387 -99.5h-418v1223h-383zM608 162h223q158 0 247 58.5t89 197.5q0 105 -33 163t-106 84.5t-221 26.5h-199v-530z" />
+<glyph unicode="&#x42b;" horiz-adv-x="1714" d="M182 0v1384h185v-530h227q276 0 401 -104.5t125 -333.5q0 -219 -134 -317.5t-386 -98.5h-418zM367 162h225q158 0 246 58.5t88 197.5q0 105 -33 163t-105.5 84.5t-222.5 26.5h-198v-530zM1348 0v1384h184v-1384h-184z" />
+<glyph unicode="&#x42c;" horiz-adv-x="1192" d="M182 0v1384h185v-530h227q276 0 401 -104.5t125 -333.5q0 -219 -134 -317.5t-386 -98.5h-418zM367 162h225q158 0 246 58.5t88 197.5q0 105 -33 163t-105.5 84.5t-222.5 26.5h-198v-530z" />
+<glyph unicode="&#x42d;" horiz-adv-x="1321" d="M129 242l154 100q64 -109 152 -158t208 -49q199 0 295 121t109 356h-674v168h674q-15 234 -113 351.5t-289 117.5q-81 0 -142.5 -21.5t-106 -57t-95.5 -117.5l-151 100q75 137 199.5 198.5t295.5 61.5q305 0 451.5 -180t146.5 -541q0 -362 -147.5 -541.5t-458.5 -179.5 q-178 0 -301 64t-207 207z" />
+<glyph unicode="&#x42e;" horiz-adv-x="1894" d="M182 0v1384h185v-614h280q13 319 150 481t411 162q293 0 430.5 -176.5t137.5 -544.5q0 -365 -141.5 -543t-426.5 -178q-272 0 -410 159.5t-151 477.5h-280v-608h-185zM840 692q0 -292 90 -427.5t278 -135.5q196 0 285.5 133t89.5 430q0 296 -89 429.5t-286 133.5 q-194 0 -281 -134.5t-87 -428.5z" />
+<glyph unicode="&#x42f;" horiz-adv-x="1237" d="M59 0l375 594q-153 33 -222 132t-69 269q0 198 112 293.5t370 95.5h430v-1384h-185v565h-241l-353 -565h-217zM334 981q0 -146 69.5 -199t235.5 -53h231v492h-243q-154 0 -223.5 -51.5t-69.5 -188.5z" />
+<glyph unicode="&#x430;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM287 299 q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z" />
+<glyph unicode="&#x431;" horiz-adv-x="1114" d="M100 653q0 193 20.5 328t63.5 227t110.5 147.5t163 87.5t220.5 48t283 31v-164q-168 -12 -295 -28.5t-213 -66t-129 -143.5t-43 -258q65 64 157 101.5t191 37.5q405 0 405 -479q0 -258 -115.5 -405.5t-326.5 -147.5q-248 0 -370 175t-122 509zM279 610q0 -239 82.5 -369 t232.5 -130q123 0 192.5 114.5t69.5 288.5q0 172 -63.5 258t-202.5 86q-81 0 -165 -45t-144 -117l-2 -43v-43z" />
+<glyph unicode="&#x432;" horiz-adv-x="1098" d="M170 0v1049h371q226 0 316.5 -55t90.5 -191q0 -183 -162 -248q108 -24 158.5 -80t50.5 -156q0 -169 -114.5 -244t-335.5 -75h-375zM338 137h147q166 0 250 34t84 144q0 91 -59.5 122.5t-204.5 31.5h-217v-332zM338 604h184q254 0 254 172q0 88 -59.5 113.5t-181.5 25.5 h-197v-311z" />
+<glyph unicode="&#x433;" horiz-adv-x="881" d="M170 0v1049h694v-142h-520v-907h-174z" />
+<glyph unicode="&#x434;" horiz-adv-x="1100" d="M23 137h98q96 189 146 430t50 482h592v-912h168v-368h-164v231h-727v-231h-163v368zM287 137h454v774h-262q-12 -214 -60.5 -412.5t-131.5 -361.5z" />
+<glyph unicode="&#x435;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM297 639h512q-2 141 -59.5 219t-186.5 78 q-123 0 -184.5 -70.5t-81.5 -226.5z" />
+<glyph unicode="&#x436;" horiz-adv-x="1493" d="M74 0q56 223 94 316t85 144.5t124 76.5q-63 15 -105 69.5t-83.5 162.5t-79.5 280h174q36 -156 77.5 -257t84 -145.5t100.5 -44.5h117v447h169v-447h117q85 0 143.5 101t118.5 346h172q-37 -169 -78.5 -277.5t-83.5 -163.5t-104 -71q64 -19 107 -58t75.5 -103.5t59 -156.5 t61.5 -219h-174q-35 123 -62.5 209t-60 140t-77 80t-113.5 26h-101v-455h-169v455h-103q-67 0 -111.5 -24.5t-77 -80t-60 -141.5t-62.5 -209h-174z" />
+<glyph unicode="&#x437;" horiz-adv-x="961" d="M51 162l142 86q47 -66 100 -97.5t137 -31.5q113 0 185.5 44t72.5 134q0 180 -215 180h-229v141h219q117 0 172 33t55 107q0 172 -254 172q-86 0 -138 -34t-91 -95l-141 86q110 192 368 192q211 0 317.5 -85t106.5 -230q0 -94 -49 -153.5t-115 -80.5q62 -22 112 -83.5 t50 -167.5q0 -310 -428 -310q-154 0 -241 54.5t-136 138.5z" />
+<glyph unicode="&#x438;" horiz-adv-x="1190" d="M170 0v1049h162v-828l514 828h174v-1049h-162v811l-506 -811h-182z" />
+<glyph unicode="&#x439;" horiz-adv-x="1190" d="M170 0v1049h162v-828l514 828h174v-1049h-162v811l-506 -811h-182zM274 1442h158q12 -74 56 -111t110 -37q88 0 125.5 37t48.5 111h157q0 -72 -40.5 -131.5t-114 -91t-174.5 -31.5q-97 0 -170.5 32t-114.5 92t-41 130z" />
+<glyph unicode="&#x43a;" horiz-adv-x="997" d="M170 0v1049h168v-447h147q59 0 100 42t81.5 141.5t78.5 263.5h175q-38 -171 -80.5 -281t-84 -163t-104.5 -68q75 -22 122 -71t86 -146.5t95 -319.5h-174q-35 123 -62.5 210t-60 141.5t-76.5 79t-112 24.5h-131v-455h-168z" />
+<glyph unicode="&#x43b;" horiz-adv-x="1090" d="M10 2l33 150q37 -7 63 -7q205 0 205 748v156h609v-1049h-168v907h-277v-73q0 -255 -43.5 -451.5t-123 -297.5t-187.5 -101q-25 0 -59.5 6t-51.5 12z" />
+<glyph unicode="&#x43c;" horiz-adv-x="1311" d="M170 0v1049h180l305 -539l308 539h178v-1049h-162v799l-285 -523h-86l-276 523v-799h-162z" />
+<glyph unicode="&#x43d;" horiz-adv-x="1186" d="M170 0v1049h168v-439h510v439h168v-1049h-168v471h-510v-471h-168z" />
+<glyph unicode="&#x43e;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5z" />
+<glyph unicode="&#x43f;" horiz-adv-x="1169" d="M170 0v1049h829v-1049h-172v907h-485v-907h-172z" />
+<glyph unicode="&#x440;" horiz-adv-x="1174" d="M170 -395v1444h172v-105q59 57 142 96t178 39q187 0 291 -141.5t104 -405.5q0 -258 -112.5 -410.5t-309.5 -152.5q-157 0 -293 117v-481h-172zM342 236q134 -113 270 -113q117 0 192 98t75 307q0 398 -250 398q-82 0 -157 -41t-130 -94v-555z" />
+<glyph unicode="&#x441;" horiz-adv-x="1030" d="M117 522q0 274 116 415.5t342 141.5q259 0 369 -192l-141 -86q-39 61 -91.5 95t-138.5 34q-151 0 -214.5 -109.5t-63.5 -302.5q0 -147 30 -229t93.5 -126t161.5 -44q84 0 137 31.5t100 97.5l141 -86q-49 -84 -136 -138.5t-240 -54.5q-231 0 -348 139.5t-117 413.5z" />
+<glyph unicode="&#x442;" horiz-adv-x="872" d="M16 911v138h840v-138h-336v-911h-168v911h-336z" />
+<glyph unicode="&#x443;" horiz-adv-x="1040" d="M-4 -365l43 142q65 -29 151 -29q121 0 205 219l35 90l-383 992h186l289 -768l291 768h180l-448 -1129q-71 -173 -152 -244t-211 -71q-47 0 -100 9t-86 21z" />
+<glyph unicode="&#x444;" horiz-adv-x="1360" d="M117 522q0 274 117 406.5t370 148.5v414h156v-414q250 -17 366.5 -150.5t116.5 -404.5q0 -266 -113 -398t-370 -151v-368h-156v368q-242 13 -364.5 140t-122.5 409zM291 522q0 -190 68.5 -290.5t244.5 -116.5v817q-178 -17 -245.5 -117t-67.5 -293zM760 117 q174 16 241.5 115.5t67.5 289.5q0 193 -67.5 293t-241.5 117v-815z" />
+<glyph unicode="&#x445;" horiz-adv-x="1012" d="M55 0l348 518l-344 531h211l242 -398l248 398h196l-348 -519l348 -530h-215l-241 399l-250 -399h-195z" />
+<glyph unicode="&#x446;" horiz-adv-x="1202" d="M170 0v1049h174v-908h500v908h174v-912h162v-368h-160v231h-850z" />
+<glyph unicode="&#x447;" horiz-adv-x="1059" d="M82 719v330h168v-269q0 -126 15 -190.5t49.5 -90.5t103.5 -26q113 0 303 76v500h168v-1049h-168v401l-83 -30q-159 -60 -257 -60q-155 0 -227 101t-72 307z" />
+<glyph unicode="&#x448;" horiz-adv-x="1618" d="M170 0v1049h168v-912h403v912h168v-912h402v912h168v-1049h-1309z" />
+<glyph unicode="&#x449;" horiz-adv-x="1669" d="M170 0v1049h168v-912h403v912h168v-912h402v912h168v-912h168v-368h-164v231h-1313z" />
+<glyph unicode="&#x44a;" horiz-adv-x="1108" d="M16 911v138h445v-396h164q227 0 327.5 -79.5t100.5 -260.5q0 -178 -109.5 -245.5t-312.5 -67.5h-338v911h-277zM461 137h160q137 0 196.5 41t59.5 137q0 77 -24 120t-79 62t-174 19h-139v-379z" />
+<glyph unicode="&#x44b;" horiz-adv-x="1421" d="M170 0v1049h168v-396h164q227 0 328.5 -79.5t101.5 -260.5q0 -161 -98.5 -237t-325.5 -76h-338zM338 137h164q141 0 197.5 43t56.5 135q0 82 -27 123.5t-86.5 59.5t-165.5 18h-139v-379zM1083 0v1049h168v-1049h-168z" />
+<glyph unicode="&#x44c;" horiz-adv-x="987" d="M170 0v1049h168v-396h164q227 0 328.5 -79.5t101.5 -260.5q0 -161 -98.5 -237t-325.5 -76h-338zM338 137h164q141 0 197.5 43t56.5 135q0 82 -27 123.5t-86.5 59.5t-165.5 18h-139v-379z" />
+<glyph unicode="&#x44d;" horiz-adv-x="1030" d="M72 162l141 86q47 -66 100.5 -97.5t137.5 -31.5q130 0 201 78.5t81 259.5h-512v141h512q-12 158 -76.5 245t-199.5 87q-86 0 -138.5 -34t-91.5 -95l-141 86q111 192 369 192q229 0 343.5 -142.5t114.5 -414.5q0 -274 -117.5 -413.5t-346.5 -139.5q-154 0 -241 54.5 t-136 138.5z" />
+<glyph unicode="&#x44e;" horiz-adv-x="1565" d="M170 0v1049h164v-459h196q31 489 459 489q228 0 343.5 -141.5t115.5 -415.5q0 -268 -115 -410.5t-344 -142.5q-208 0 -326 120t-133 372h-196v-461h-164zM698 522q0 -202 73.5 -307.5t217.5 -105.5q141 0 215 106t74 307q0 203 -71.5 311.5t-217.5 108.5 q-145 0 -218 -107.5t-73 -312.5z" />
+<glyph unicode="&#x44f;" horiz-adv-x="1053" d="M53 0l272 445q-106 29 -162.5 108.5t-56.5 206.5q0 160 97.5 224.5t306.5 64.5h373v-1049h-168v428h-219l-252 -428h-191zM276 750q0 -78 24.5 -115t79.5 -53.5t161 -16.5h174v350h-185q-148 0 -201 -35t-53 -130z" />
+<glyph unicode="&#x450;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM297 639h512q-2 141 -59.5 219t-186.5 78 q-123 0 -184.5 -70.5t-81.5 -226.5zM321 1569h236l178 -361h-141z" />
+<glyph unicode="&#x451;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM258 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5 t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5zM653 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78 z" />
+<glyph unicode="&#x452;" horiz-adv-x="1104" d="M23 1217v133h114v141h172v-141h295v-133h-295v-324q83 83 176 134.5t172 51.5q189 0 277 -139t88 -408q0 -421 -122 -654.5t-347 -264.5l-29 137q122 29 189 108.5t100 229t33 377.5q0 240 -50 344t-173 104q-56 0 -140.5 -46t-173.5 -126v-741h-172v1217h-114z" />
+<glyph unicode="&#x453;" horiz-adv-x="881" d="M170 0v1049h694v-142h-520v-907h-174zM370 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x454;" horiz-adv-x="1030" d="M117 522q0 274 116 415.5t342 141.5q259 0 369 -192l-141 -86q-39 61 -91.5 95t-138.5 34q-135 0 -199.5 -87t-76.5 -245h512v-141h-512q10 -180 80.5 -259t202.5 -79q84 0 137 31.5t100 97.5l141 -86q-49 -84 -136 -138.5t-240 -54.5q-231 0 -348 139.5t-117 413.5z" />
+<glyph unicode="&#x455;" horiz-adv-x="991" d="M100 158l138 84q79 -127 254 -127q114 0 170.5 43.5t56.5 117.5q0 44 -20 71.5t-62 48t-172 55.5q-187 43 -263.5 119t-76.5 202q0 139 100 223t277 84q137 0 230 -54t136 -130l-137 -84q-82 123 -233 123q-86 0 -145.5 -38t-59.5 -118q0 -71 52 -103t163 -59 q178 -46 246 -86t100.5 -98.5t32.5 -148.5q0 -147 -104 -230.5t-296 -83.5q-131 0 -235 49.5t-152 139.5z" />
+<glyph unicode="&#x456;" horiz-adv-x="512" d="M145 1315q0 53 26 77.5t85 24.5q61 0 87 -23.5t26 -78.5q0 -60 -27 -81.5t-86 -21.5q-63 0 -87 27t-24 76zM170 0v1049h172v-1049h-172z" />
+<glyph unicode="&#x457;" horiz-adv-x="512" d="M-63 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM170 0v1049h172v-1049h-172zM332 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29 t-21.5 78z" />
+<glyph unicode="&#x458;" horiz-adv-x="537" d="M-143 -365l43 142q73 -29 151 -29q84 0 109.5 58.5t25.5 168.5v1074h172v-1094q0 -190 -74 -270t-239 -80q-100 0 -188 30zM162 1315q0 53 25.5 77.5t84.5 24.5q62 0 87.5 -23.5t25.5 -78.5q0 -60 -26.5 -81.5t-86.5 -21.5q-63 0 -86.5 27t-23.5 76z" />
+<glyph unicode="&#x459;" horiz-adv-x="1567" d="M10 2l33 150q37 -7 63 -7q205 0 205 748v156h609v-396h161q228 0 329 -79.5t101 -260.5q0 -164 -99 -238.5t-325 -74.5h-335v907h-277v-73q0 -255 -43.5 -451.5t-123 -297.5t-187.5 -101q-25 0 -59.5 6t-51.5 12zM920 137h161q121 0 187.5 36t66.5 142q0 77 -23.5 119.5 t-77 62t-175.5 19.5h-139v-379z" />
+<glyph unicode="&#x45a;" horiz-adv-x="1665" d="M170 0v1049h168v-420h510v420h168v-420h164q227 0 328.5 -75t101.5 -241q0 -163 -99 -238t-325 -75h-338v487h-510v-487h-168zM1016 137h162q137 0 196.5 41t59.5 137q0 99 -57.5 135.5t-221.5 36.5h-139v-350z" />
+<glyph unicode="&#x45b;" horiz-adv-x="1096" d="M16 1217v133h121v139h172v-139h291v-133h-291v-324q73 73 170 129.5t195 56.5q153 0 224 -88.5t71 -290.5v-700h-172v618q0 145 -14.5 197.5t-50 75t-99.5 22.5q-66 0 -154 -50t-170 -122v-741h-172v1217h-121z" />
+<glyph unicode="&#x45c;" horiz-adv-x="997" d="M170 0v1049h168v-447h147q59 0 100 42t81.5 141.5t78.5 263.5h175q-38 -171 -80.5 -281t-84 -163t-104.5 -68q75 -22 122 -71t86 -146.5t95 -319.5h-174q-35 123 -62.5 210t-60 141.5t-76.5 79t-112 24.5h-131v-455h-168zM403 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x45d;" horiz-adv-x="1190" d="M170 0v1049h162v-828l514 828h174v-1049h-162v811l-506 -811h-182zM313 1569h236l178 -361h-141z" />
+<glyph unicode="&#x45e;" horiz-adv-x="1040" d="M-4 -365l43 142q65 -29 151 -29q121 0 205 219l35 90l-383 992h186l289 -768l291 768h180l-448 -1129q-71 -173 -152 -244t-211 -71q-47 0 -100 9t-86 21zM199 1442h158q12 -74 56 -111t110 -37q88 0 125.5 37t48.5 111h157q0 -72 -40.5 -131.5t-114 -91t-174.5 -31.5 q-97 0 -170.5 32t-114.5 92t-41 130z" />
+<glyph unicode="&#x45f;" horiz-adv-x="1128" d="M139 0v1049h174v-908h502v908h174v-1049h-340v-285h-170v285h-340z" />
+<glyph unicode="&#x490;" horiz-adv-x="1055" d="M182 0v1384h652v250h180v-417h-641v-1217h-191z" />
+<glyph unicode="&#x491;" horiz-adv-x="850" d="M139 0v1049h527v307h168v-449h-521v-907h-174z" />
+<glyph unicode="&#x1e80;" horiz-adv-x="1757" d="M68 1384h184l258 -1118l262 1118h209l266 -1126l262 1126h181l-334 -1384h-221l-261 1108l-262 -1108h-217zM590 1905h236l178 -361h-141z" />
+<glyph unicode="&#x1e81;" horiz-adv-x="1475" d="M63 1049h179l178 -799l250 799h143l256 -799l170 799h172l-258 -1049h-160l-256 803l-256 -803h-157zM436 1569h236l178 -361h-141z" />
+<glyph unicode="&#x1e82;" horiz-adv-x="1757" d="M68 1384h184l258 -1118l262 1118h209l266 -1126l262 1126h181l-334 -1384h-221l-261 1108l-262 -1108h-217zM782 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x1e83;" horiz-adv-x="1475" d="M63 1049h179l178 -799l250 799h143l256 -799l170 799h172l-258 -1049h-160l-256 803l-256 -803h-157zM649 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x1e84;" horiz-adv-x="1757" d="M68 1384h184l258 -1118l262 1118h209l266 -1126l262 1126h181l-334 -1384h-221l-261 1108l-262 -1108h-217zM578 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM973 1651q0 53 23.5 79.5t82.5 26.5 q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1e85;" horiz-adv-x="1475" d="M63 1049h179l178 -799l250 799h143l256 -799l170 799h172l-258 -1049h-160l-256 803l-256 -803h-157zM445 1315q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM840 1315q0 53 23.5 79.5t82.5 26.5 q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph unicode="&#x1e9e;" horiz-adv-x="1405" d="M182 0v889q0 268 120 397t380 129q102 0 170 -7t141 -24v-135q-133 0 -198.5 -57t-65.5 -162q0 -95 49.5 -146t171.5 -93q183 -64 270 -160t87 -252q0 -190 -115 -299t-318 -109q-311 0 -423 271l157 86q39 -92 103.5 -142.5t167.5 -50.5q100 0 169.5 56.5t69.5 173.5 q0 90 -55 153.5t-195 110.5q-182 61 -252.5 158.5t-70.5 226.5q0 84 29.5 139t84.5 98q-162 0 -227 -73.5t-65 -266.5v-911h-185z" />
+<glyph unicode="&#x1ea0;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM414 528h450l-225 674zM528 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ea1;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM287 299 q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5zM383 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ea2;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM414 528h450l-225 674zM448 1774q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -138 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ea3;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM287 299 q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5zM350 1438q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ea4;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM311 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM414 528h450l-225 674zM827 1733l123 274h235l-217 -274h-141z" />
+<glyph unicode="&#x1ea5;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM201 1167 l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5zM717 1397l123 274h235l-217 -274h-141z" />
+<glyph unicode="&#x1ea6;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM104 2007h236l122 -274h-141zM311 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM414 528h450l-225 674z" />
+<glyph unicode="&#x1ea7;" horiz-adv-x="1100" d="M-6 1671h236l122 -274h-141zM109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46 q-150 0 -231.5 91.5t-81.5 234.5zM201 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z" />
+<glyph unicode="&#x1ea8;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM311 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM414 528h450l-225 674zM761 1954q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55 q0 27 -15 41.5t-54 14.5q-21 0 -49.5 -8.5t-50.5 -24.5z" />
+<glyph unicode="&#x1ea9;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM201 1167 l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5zM651 1618q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25 q73 0 73 55q0 27 -15 41.5t-54 14.5q-21 0 -49.5 -8.5t-50.5 -24.5z" />
+<glyph unicode="&#x1eaa;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM268 1823q6 104 67.5 162.5t161.5 58.5q47 0 87 -15.5t77 -35t71 -34.5t70 -15q88 0 97 88h121q-19 -222 -232 -222q-59 0 -98 16.5t-71 36t-62.5 36t-71.5 16.5q-51 0 -71.5 -24.5t-24.5 -67.5h-121z M311 1503l229 258h211l228 -258h-150l-184 142l-185 -142h-149zM414 528h450l-225 674z" />
+<glyph unicode="&#x1eab;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM158 1507 q6 105 67.5 163.5t161.5 58.5q47 0 87 -15.5t77 -35t71 -35t70 -15.5q88 0 97 88h121q-19 -221 -232 -221q-59 0 -98 16.5t-71 36t-62.5 35.5t-71.5 16q-51 0 -71.5 -24.5t-24.5 -67.5h-121zM201 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM287 299 q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z" />
+<glyph unicode="&#x1eac;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM311 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149zM414 528h450l-225 674zM528 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31 t-22.5 84z" />
+<glyph unicode="&#x1ead;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM201 1208 l229 361h211l228 -361h-150l-184 238l-185 -238h-149zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5zM383 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5 q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1eae;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM315 1784h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM414 528h450l-225 674zM549 1733l122 274h236l-217 -274h-141z" />
+<glyph unicode="&#x1eaf;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM207 1489 h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5zM441 1438l122 274h236 l-217 -274h-141z" />
+<glyph unicode="&#x1eb0;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM317 1784h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM381 2007h235l123 -274h-141zM414 528h450l-225 674z" />
+<glyph unicode="&#x1eb1;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM207 1489 h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM271 1712h235l123 -274h-141zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z " />
+<glyph unicode="&#x1eb2;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM317 1784h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM414 528h450l-225 674zM450 2015q23 21 70 37t106 16 q90 0 138.5 -37.5t48.5 -99.5q0 -137 -148 -155v-37h-98v112h24q74 0 74 56q0 55 -69 55q-56 0 -101 -33z" />
+<glyph unicode="&#x1eb3;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM207 1489 h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5zM340 1720q23 21 70 37.5 t106 16.5q90 0 138.5 -38t48.5 -100q0 -137 -148 -155v-37h-98v112h24q74 0 74 56q0 55 -69 55q-56 0 -101 -33z" />
+<glyph unicode="&#x1eb4;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM268 1843q6 105 67.5 163t161.5 58q47 0 87 -15t77 -34.5t71 -35t70 -15.5q88 0 97 88h121q-19 -221 -232 -221q-59 0 -98 16.5t-71 36t-62.5 35.5t-71.5 16q-51 0 -71.5 -24.5t-24.5 -67.5h-121z M317 1784h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM414 528h450l-225 674z" />
+<glyph unicode="&#x1eb5;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM158 1548 q6 105 67.5 163t161.5 58q47 0 87 -15t77 -34.5t71 -35t70 -15.5q88 0 97 88h121q-19 -221 -232 -221q-59 0 -98 16.5t-71 36t-62.5 35.5t-71.5 16q-51 0 -71.5 -24.5t-24.5 -67.5h-121zM207 1489h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127 q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5z" />
+<glyph unicode="&#x1eb6;" horiz-adv-x="1288" d="M51 0l473 1384h240l473 -1384h-195l-120 360h-564l-118 -360h-189zM317 1804h127q14 -63 66.5 -94t130.5 -31q102 0 147 31t57 94h127q0 -123 -86.5 -202.5t-242.5 -79.5q-152 0 -239 81t-87 201zM414 528h450l-225 674zM530 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28 t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1eb7;" horiz-adv-x="1100" d="M109 295q0 108 42.5 179.5t123 113t233.5 59.5l258 23v51q0 121 -67.5 165t-186.5 44q-106 0 -163.5 -37t-82.5 -80l-141 86q48 87 146.5 133.5t244.5 46.5q226 0 324 -82t98 -284v-713h-172v131q-80 -70 -161 -116t-183 -46q-150 0 -231.5 91.5t-81.5 234.5zM207 1489 h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM287 299q0 -94 47 -135t141 -41q39 0 77 14.5t75 36t71.5 49t67.5 53.5v256l-168 -16q-171 -15 -241 -66.5t-70 -150.5zM383 -258q0 59 24.5 87 t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1eb8;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM479 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1eb9;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM297 639h512q-2 141 -59.5 219t-186.5 78 q-123 0 -184.5 -70.5t-81.5 -226.5zM448 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1eba;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM426 1774q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -138 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ebb;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM297 639h512q-2 141 -59.5 219t-186.5 78 q-123 0 -184.5 -70.5t-81.5 -226.5zM380 1438q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ebc;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM242 1556q6 125 67.5 194t161.5 69q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -98 h-121z" />
+<glyph unicode="&#x1ebd;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM186 1221q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5 t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121zM297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5z" />
+<glyph unicode="&#x1ebe;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM270 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM786 1733l123 274h235l-217 -274h-141z" />
+<glyph unicode="&#x1ebf;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM240 1167l229 279h211l228 -279h-150l-184 162l-185 -162 h-149zM297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5zM756 1397l123 274h235l-217 -274h-141z" />
+<glyph unicode="&#x1ec0;" horiz-adv-x="1153" d="M63 2007h236l122 -274h-141zM182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM270 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149z" />
+<glyph unicode="&#x1ec1;" horiz-adv-x="1081" d="M33 1671h236l122 -274h-141zM117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM240 1167l229 279h211l228 -279 h-150l-184 162l-185 -162h-149zM297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5z" />
+<glyph unicode="&#x1ec2;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM270 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM720 1954q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41.5t-54 14.5 q-21 0 -49.5 -8.5t-50.5 -24.5z" />
+<glyph unicode="&#x1ec3;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM238 1167l229 279h211l228 -279h-150l-184 162l-185 -162 h-149zM297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5zM688 1618q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41.5t-54 14.5q-21 0 -49.5 -8.5t-50.5 -24.5z" />
+<glyph unicode="&#x1ec4;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM227 1823q6 104 67.5 162.5t161.5 58.5q47 0 87 -15.5t77 -35t71 -34.5t70 -15q88 0 97 88h121q-19 -222 -232 -222q-59 0 -98 16.5t-71 36t-62.5 36t-71.5 16.5q-51 0 -71.5 -24.5t-24.5 -67.5h-121z M270 1503l229 258h211l228 -258h-150l-184 142l-185 -142h-149z" />
+<glyph unicode="&#x1ec5;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM197 1507q6 105 67.5 163.5t161.5 58.5q47 0 87 -15.5 t77 -35t71 -35t70 -15.5q88 0 97 88h121q-19 -221 -232 -221q-59 0 -98 16.5t-71 36t-62.5 35.5t-71.5 16q-51 0 -71.5 -24.5t-24.5 -67.5h-121zM240 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5 t-81.5 -226.5z" />
+<glyph unicode="&#x1ec6;" horiz-adv-x="1153" d="M182 0v1384h846v-167h-661v-404h565v-168h-565v-477h661v-168h-846zM270 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149zM479 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ec7;" horiz-adv-x="1081" d="M117 516q0 288 112.5 425.5t339.5 137.5q204 0 306 -117.5t102 -361.5v-96h-682q0 -208 71 -296.5t228 -88.5q70 0 123 29.5t102 95.5l142 -88q-60 -90 -146 -138.5t-233 -48.5q-234 0 -349.5 136t-115.5 411zM240 1208l229 361h211l228 -361h-150l-184 238l-185 -238 h-149zM297 639h512q-2 141 -59.5 219t-186.5 78q-123 0 -184.5 -70.5t-81.5 -226.5zM459 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ec8;" horiz-adv-x="770" d="M102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566zM206 1774q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -138 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ec9;" horiz-adv-x="512" d="M77 1438q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24zM170 0v1049h172v-1049h-172z" />
+<glyph unicode="&#x1eca;" horiz-adv-x="770" d="M102 0v160h191v1067h-191v157h566v-157h-191v-1067h191v-160h-566zM272 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ecb;" horiz-adv-x="512" d="M143 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84zM145 1315q0 53 26 77.5t85 24.5q61 0 87 -23.5t26 -78.5q0 -60 -27 -81.5t-86 -21.5q-63 0 -87 27t-24 76zM170 0v1049h172v-1049h-172z" />
+<glyph unicode="&#x1ecc;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM565 -258q0 59 24.5 87 t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ecd;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM463 -258 q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ece;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM499 1774q23 20 70 36.5 t107 16.5q90 0 138 -38t48 -99q0 -138 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ecf;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM397 1438 q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ed0;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM342 1503l229 279h211 l228 -279h-150l-184 162l-185 -162h-149zM858 1733l123 274h235l-217 -274h-141z" />
+<glyph unicode="&#x1ed1;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM240 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311 t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM756 1397l123 274h235l-217 -274h-141z" />
+<glyph unicode="&#x1ed2;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM135 2007h236l122 -274h-141zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135 t-86.5 -422zM342 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149z" />
+<glyph unicode="&#x1ed3;" horiz-adv-x="1157" d="M33 1671h236l122 -274h-141zM117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM240 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM295 522q0 -205 67.5 -304t217.5 -99 q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5z" />
+<glyph unicode="&#x1ed4;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM342 1503l229 279h211 l228 -279h-150l-184 162l-185 -162h-149zM792 1954q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41.5t-54 14.5q-21 0 -49.5 -8.5t-50.5 -24.5z" />
+<glyph unicode="&#x1ed5;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM240 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311 t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM690 1618q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41.5t-54 14.5q-21 0 -49.5 -8.5t-50.5 -24.5z" />
+<glyph unicode="&#x1ed6;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM299 1823q6 104 67.5 162.5t161.5 58.5q47 0 87 -15.5t77 -35t71 -34.5t70 -15q88 0 97 88h121q-19 -222 -232 -222q-59 0 -98 16.5t-71 36 t-62.5 36t-71.5 16.5q-51 0 -71.5 -24.5t-24.5 -67.5h-121zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM342 1503l229 258h211l228 -258h-150l-184 142l-185 -142h-149z" />
+<glyph unicode="&#x1ed7;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM197 1507q6 105 67.5 163.5t161.5 58.5q47 0 87 -15.5t77 -35t71 -35t70 -15.5q88 0 97 88h121q-19 -221 -232 -221q-59 0 -98 16.5t-71 36 t-62.5 35.5t-71.5 16q-51 0 -71.5 -24.5t-24.5 -67.5h-121zM240 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5z" />
+<glyph unicode="&#x1ed8;" horiz-adv-x="1364" d="M119 692q0 364 137 542.5t426 178.5q285 0 424 -175t139 -546q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM348 1544l229 361h211 l228 -361h-150l-184 238l-185 -238h-149zM565 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ed9;" horiz-adv-x="1157" d="M117 522q0 281 119.5 419t343.5 138q226 0 343 -140.5t117 -416.5q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM244 1208l229 361h211l228 -361h-150l-184 238l-185 -238h-149zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311 t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM463 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1eda;" horiz-adv-x="1487" d="M119 692q0 364 137 542.5t426 178.5q207 0 329 -87t179 -247h37q71 0 102 41t31 144v182h160v-182q0 -167 -71 -243.5t-212 -76.5h-12q20 -114 20 -252q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134 q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM557 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x1edb;" horiz-adv-x="1249" d="M117 522q0 281 119.5 419t343.5 138q317 0 417 -274q68 2 96.5 44t28.5 140v141h160v-141q0 -305 -252 -319q10 -87 10 -148q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311 t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM460 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x1edc;" horiz-adv-x="1487" d="M119 692q0 364 137 542.5t426 178.5q207 0 329 -87t179 -247h37q71 0 102 41t31 144v182h160v-182q0 -167 -71 -243.5t-212 -76.5h-12q20 -114 20 -252q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134 q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM401 1905h236l178 -361h-141z" />
+<glyph unicode="&#x1edd;" horiz-adv-x="1249" d="M117 522q0 281 119.5 419t343.5 138q317 0 417 -274q68 2 96.5 44t28.5 140v141h160v-141q0 -305 -252 -319q10 -87 10 -148q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311 t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM305 1569h236l178 -361h-141z" />
+<glyph unicode="&#x1ede;" horiz-adv-x="1487" d="M119 692q0 364 137 542.5t426 178.5q207 0 329 -87t179 -247h37q71 0 102 41t31 144v182h160v-182q0 -167 -71 -243.5t-212 -76.5h-12q20 -114 20 -252q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134 q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM516 1774q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -138 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1edf;" horiz-adv-x="1249" d="M117 522q0 281 119.5 419t343.5 138q317 0 417 -274q68 2 96.5 44t28.5 140v141h160v-141q0 -305 -252 -319q10 -87 10 -148q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311 t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM413 1438q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ee0;" horiz-adv-x="1487" d="M119 692q0 364 137 542.5t426 178.5q207 0 329 -87t179 -247h37q71 0 102 41t31 144v182h160v-182q0 -167 -71 -243.5t-212 -76.5h-12q20 -114 20 -252q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM305 1556q6 125 67.5 194t161.5 69q56 0 96.5 -22.5 t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -98h-121zM313 692q0 -289 87.5 -423t281.5 -134q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422z " />
+<glyph unicode="&#x1ee1;" horiz-adv-x="1249" d="M117 522q0 281 119.5 419t343.5 138q317 0 417 -274q68 2 96.5 44t28.5 140v141h160v-141q0 -305 -252 -319q10 -87 10 -148q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM197 1221q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5t75.5 -48.5t66 -48.5 t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311t-211.5 97q-145 0 -215 -97.5t-70 -310.5z" />
+<glyph unicode="&#x1ee2;" horiz-adv-x="1487" d="M119 692q0 364 137 542.5t426 178.5q207 0 329 -87t179 -247h37q71 0 102 41t31 144v182h160v-182q0 -167 -71 -243.5t-212 -76.5h-12q20 -114 20 -252q0 -373 -140.5 -547t-422.5 -174q-286 0 -424.5 177t-138.5 544zM313 692q0 -289 87.5 -423t281.5 -134 q193 0 281 133t88 424q0 287 -86.5 422t-282.5 135t-282.5 -135t-86.5 -422zM565 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ee3;" horiz-adv-x="1249" d="M117 522q0 281 119.5 419t343.5 138q317 0 417 -274q68 2 96.5 44t28.5 140v141h160v-141q0 -305 -252 -319q10 -87 10 -148q0 -273 -117.5 -413t-342.5 -140t-344 138.5t-119 414.5zM295 522q0 -205 67.5 -304t217.5 -99q143 0 212.5 98t69.5 305q0 214 -70.5 311 t-211.5 97q-145 0 -215 -97.5t-70 -310.5zM459 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ee4;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM586 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87 q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ee5;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM432 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5 t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ee6;" horiz-adv-x="1405" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-806q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193t-50.5 355zM520 1774q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99 q0 -138 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ee7;" horiz-adv-x="1163" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-1049h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5zM391 1438q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98 v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ee8;" horiz-adv-x="1524" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-305h41q71 0 102 41t31 144v182h159v-182q0 -170 -71.5 -245t-210.5 -75h-51v-366q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193 t-50.5 355zM583 1544l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x1ee9;" horiz-adv-x="1286" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-244h33q72 0 102.5 41t30.5 143v141h160v-141q0 -166 -69.5 -242.5t-213.5 -76.5h-43v-670h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5z M473 1208l178 361h236l-272 -361h-142z" />
+<glyph unicode="&#x1eea;" horiz-adv-x="1524" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-305h41q71 0 102 41t31 144v182h159v-182q0 -170 -71.5 -245t-210.5 -75h-51v-366q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193 t-50.5 355zM401 1905h236l178 -361h-141z" />
+<glyph unicode="&#x1eeb;" horiz-adv-x="1286" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-244h33q72 0 102.5 41t30.5 143v141h160v-141q0 -166 -69.5 -242.5t-213.5 -76.5h-43v-670h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5z M282 1569h236l178 -361h-141z" />
+<glyph unicode="&#x1eec;" horiz-adv-x="1524" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-305h41q71 0 102 41t31 144v182h159v-182q0 -170 -71.5 -245t-210.5 -75h-51v-366q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193 t-50.5 355zM518 1774q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -138 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1eed;" horiz-adv-x="1286" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-244h33q72 0 102.5 41t30.5 143v141h160v-141q0 -166 -69.5 -242.5t-213.5 -76.5h-43v-670h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5z M395 1438q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1eee;" horiz-adv-x="1524" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-305h41q71 0 102 41t31 144v182h159v-182q0 -170 -71.5 -245t-210.5 -75h-51v-366q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193 t-50.5 355zM340 1556q6 125 67.5 194t161.5 69q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -98h-121z" />
+<glyph unicode="&#x1eef;" horiz-adv-x="1286" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-244h33q72 0 102.5 41t30.5 143v141h160v-141q0 -166 -69.5 -242.5t-213.5 -76.5h-43v-670h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5z M215 1221q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121z" />
+<glyph unicode="&#x1ef0;" horiz-adv-x="1524" d="M182 578v806h185v-786q0 -182 33 -280.5t104.5 -141.5t197.5 -43q127 0 199 42.5t104.5 135.5t32.5 283v790h185v-305h41q71 0 102 41t31 144v182h159v-182q0 -170 -71.5 -245t-210.5 -75h-51v-366q0 -227 -51 -358t-160.5 -191t-306.5 -60q-196 0 -309 61t-163.5 193 t-50.5 355zM582 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ef1;" horiz-adv-x="1286" d="M162 348v701h172v-619q0 -150 15.5 -200t49.5 -72.5t99 -22.5t153 50.5t170 121.5v742h172v-244h33q72 0 102.5 41t30.5 143v141h160v-141q0 -166 -69.5 -242.5t-213.5 -76.5h-43v-670h-172v156q-80 -80 -176 -133.5t-188 -53.5q-105 0 -170.5 39.5t-95 119t-29.5 220.5z M459 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ef2;" horiz-adv-x="1147" d="M41 1384h209l325 -673l332 673h199l-440 -849v-535h-187v526zM305 1905h236l178 -361h-141z" />
+<glyph unicode="&#x1ef3;" horiz-adv-x="1040" d="M-4 -365l43 142q65 -29 151 -29q121 0 205 219l35 90l-383 992h186l289 -768l291 768h180l-448 -1129q-71 -173 -152 -244t-211 -71q-47 0 -100 9t-86 21zM233 1569h236l178 -361h-141z" />
+<glyph unicode="&#x1ef4;" horiz-adv-x="1147" d="M41 1384h209l325 -673l332 673h199l-440 -849v-535h-187v526zM457 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph unicode="&#x1ef5;" horiz-adv-x="1040" d="M-4 -365l43 142q65 -29 151 -29q121 0 205 219l35 90l-383 992h186l289 -768l291 768h180l-448 -1129q-71 -173 -152 -244t-211 -71q-47 0 -100 9t-86 21zM631 -258q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84 z" />
+<glyph unicode="&#x1ef6;" horiz-adv-x="1147" d="M41 1384h209l325 -673l332 673h199l-440 -849v-535h-187v526zM391 1774q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -138 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ef7;" horiz-adv-x="1040" d="M-4 -365l43 142q65 -29 151 -29q121 0 205 219l35 90l-383 992h186l289 -768l291 768h180l-448 -1129q-71 -173 -152 -244t-211 -71q-47 0 -100 9t-86 21zM342 1438q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41 t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph unicode="&#x1ef8;" horiz-adv-x="1147" d="M41 1384h209l325 -673l332 673h199l-440 -849v-535h-187v526zM197 1556q6 125 67.5 194t161.5 69q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -98h-121z " />
+<glyph unicode="&#x1ef9;" horiz-adv-x="1040" d="M-4 -365l43 142q65 -29 151 -29q121 0 205 219l35 90l-383 992h186l289 -768l291 768h180l-448 -1129q-71 -173 -152 -244t-211 -71q-47 0 -100 9t-86 21zM148 1221q6 125 67.5 193.5t161.5 68.5q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121 q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -97h-121z" />
+<glyph unicode="&#x2000;" horiz-adv-x="1034" />
+<glyph unicode="&#x2001;" horiz-adv-x="2068" />
+<glyph unicode="&#x2002;" horiz-adv-x="1034" />
+<glyph unicode="&#x2003;" horiz-adv-x="2068" />
+<glyph unicode="&#x2004;" horiz-adv-x="689" />
+<glyph unicode="&#x2005;" horiz-adv-x="517" />
+<glyph unicode="&#x2006;" horiz-adv-x="344" />
+<glyph unicode="&#x2007;" horiz-adv-x="344" />
+<glyph unicode="&#x2008;" horiz-adv-x="258" />
+<glyph unicode="&#x2009;" horiz-adv-x="413" />
+<glyph unicode="&#x200a;" horiz-adv-x="114" />
<glyph unicode="&#x2010;" horiz-adv-x="827" d="M102 440v172h623v-172h-623z" />
<glyph unicode="&#x2011;" horiz-adv-x="827" d="M102 440v172h623v-172h-623z" />
<glyph unicode="&#x2012;" horiz-adv-x="827" d="M102 440v172h623v-172h-623z" />
-<glyph unicode="&#x2013;" horiz-adv-x="1085" d="M51 455v143h983v-143h-983z" />
+<glyph unicode="&#x2013;" d="M51 455v143h983v-143h-983z" />
<glyph unicode="&#x2014;" horiz-adv-x="2109" d="M51 455v143h2007v-143h-2007z" />
-<glyph unicode="&#x2018;" d="M156 1014q0 106 31.5 208t80.5 162h105q-34 -42 -59 -127.5t-25 -150.5q59 0 84.5 -26.5t25.5 -86.5q0 -55 -27.5 -83.5t-92.5 -28.5q-68 0 -95.5 33.5t-27.5 99.5z" />
-<glyph unicode="&#x2019;" d="M156 1300q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -33.5t27.5 -99.5q0 -123 -36.5 -223.5t-75.5 -147.5h-105q35 44 59.5 130t24.5 149q-59 0 -84.5 26.5t-25.5 85.5z" />
-<glyph unicode="&#x201a;" d="M156 98q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -34t27.5 -99q0 -123 -36.5 -223.5t-75.5 -147.5h-105q35 44 59.5 130t24.5 149q-59 0 -84.5 26.5t-25.5 85.5z" />
+<glyph unicode="&#x2015;" horiz-adv-x="2109" d="M51 455v143h2007v-143h-2007z" />
+<glyph unicode="&#x2017;" horiz-adv-x="1024" d="M-10 -105h1044v-102h-1044v102zM-10 -289h1044v-102h-1044v102z" />
+<glyph unicode="&#x2018;" horiz-adv-x="555" d="M156 1014q0 106 31.5 208t80.5 162h105q-34 -42 -59 -127.5t-25 -150.5q59 0 84.5 -26.5t25.5 -86.5q0 -55 -27.5 -83.5t-92.5 -28.5q-68 0 -95.5 33.5t-27.5 99.5z" />
+<glyph unicode="&#x2019;" horiz-adv-x="555" d="M156 1300q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -33.5t27.5 -99.5q0 -123 -36.5 -223.5t-75.5 -147.5h-105q35 44 59.5 130t24.5 149q-59 0 -84.5 26.5t-25.5 85.5z" />
+<glyph unicode="&#x201a;" horiz-adv-x="555" d="M156 98q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -34t27.5 -99q0 -123 -36.5 -223.5t-75.5 -147.5h-105q35 44 59.5 130t24.5 149q-59 0 -84.5 26.5t-25.5 85.5z" />
+<glyph unicode="&#x201b;" horiz-adv-x="555" d="M156 1280q0 66 27.5 99.5t95.5 33.5q65 0 92.5 -28.5t27.5 -84.5q0 -59 -25.5 -85.5t-84.5 -26.5q0 -65 24.5 -150t59.5 -129h-105q-39 47 -75.5 147.5t-36.5 223.5z" />
<glyph unicode="&#x201c;" horiz-adv-x="965" d="M156 1014q0 106 31.5 208t80.5 162h105q-34 -42 -59 -127.5t-25 -150.5q59 0 84.5 -26.5t25.5 -86.5q0 -55 -27.5 -83.5t-92.5 -28.5q-68 0 -95.5 33.5t-27.5 99.5zM565 1014q0 101 32 207.5t81 162.5h104q-34 -43 -59 -130t-25 -148q60 0 85.5 -26.5t25.5 -86.5 q0 -55 -27.5 -83.5t-93.5 -28.5q-67 0 -95 33.5t-28 99.5z" />
<glyph unicode="&#x201d;" horiz-adv-x="965" d="M156 1300q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -33.5t27.5 -99.5q0 -123 -36.5 -223.5t-75.5 -147.5h-105q35 44 59.5 130t24.5 149q-59 0 -84.5 26.5t-25.5 85.5zM565 1300q0 56 28 84.5t93 28.5q68 0 95.5 -33.5t27.5 -99.5q0 -123 -37 -223.5t-76 -147.5h-104 q33 43 58.5 127.5t25.5 151.5q-60 0 -85.5 26.5t-25.5 85.5z" />
<glyph unicode="&#x201e;" horiz-adv-x="965" d="M156 98q0 56 27.5 84.5t92.5 28.5q68 0 95.5 -34t27.5 -99q0 -123 -36.5 -223.5t-75.5 -147.5h-105q35 44 59.5 130t24.5 149q-59 0 -84.5 26.5t-25.5 85.5zM565 98q0 56 28 84.5t93 28.5q68 0 95.5 -34t27.5 -99q0 -123 -37 -223.5t-76 -147.5h-104q33 43 58.5 127.5 t25.5 151.5q-60 0 -85.5 26.5t-25.5 85.5z" />
+<glyph unicode="&#x2020;" horiz-adv-x="1118" d="M96 842v178l398 -25l-27 525h182l-24 -525l397 25v-178l-397 22l30 -1259h-194l33 1259z" />
+<glyph unicode="&#x2021;" horiz-adv-x="1118" d="M113 51v180l379 -24l-19 354l19 354l-379 -24v180l379 -24l-27 471h186l-26 -471l379 24v-180l-379 24l18 -354l-18 -354l379 24v-180l-379 25l26 -471h-186l27 471z" />
<glyph unicode="&#x2022;" horiz-adv-x="774" d="M129 745q0 109 76 184t182 75q108 0 182 -76t74 -183q0 -104 -76 -180t-180 -76q-106 0 -182 76t-76 180z" />
<glyph unicode="&#x2026;" horiz-adv-x="2109" d="M250 98q0 60 27.5 86.5t93.5 26.5q67 0 95 -26.5t28 -86.5q0 -63 -30 -87.5t-93 -24.5q-72 0 -96.5 29.5t-24.5 82.5zM932 98q0 60 27.5 86.5t93.5 26.5q67 0 95 -26.5t28 -86.5q0 -63 -30 -87.5t-93 -24.5q-72 0 -96.5 29.5t-24.5 82.5zM1614 98q0 60 27.5 86.5 t93.5 26.5q67 0 95 -26.5t28 -86.5q0 -63 -30 -87.5t-93 -24.5q-72 0 -96.5 29.5t-24.5 82.5z" />
-<glyph unicode="&#x202f;" horiz-adv-x="381" />
+<glyph unicode="&#x202f;" horiz-adv-x="413" />
+<glyph unicode="&#x2030;" horiz-adv-x="2765" d="M92 971q0 442 348 442q187 0 269 -119.5t82 -322.5q0 -201 -84 -321t-267 -120q-186 0 -267 119t-81 322zM270 971q0 -173 41.5 -240t128.5 -67q67 0 103 32t52.5 88.5t16.5 186.5q0 119 -17 180t-54 95t-101 34q-65 0 -101.5 -32.5t-52.5 -89.5t-16 -187zM498 -51 l778 1487h158l-781 -1487h-155zM1143 410q0 442 348 442q186 0 268 -120t82 -322q0 -201 -84 -321t-266 -120q-188 0 -268 117t-80 324zM1319 410q0 -123 17.5 -181.5t54 -92.5t100.5 -34q65 0 102 32.5t53.5 88t16.5 187.5q0 119 -16.5 179.5t-54.5 95t-101 34.5 q-67 0 -103.5 -34t-52.5 -91t-16 -184zM1974 410q0 442 348 442q187 0 269 -120t82 -322q0 -201 -84 -321t-267 -120q-188 0 -268 117t-80 324zM2150 410q0 -117 17 -178t53.5 -95.5t101.5 -34.5q66 0 102.5 32.5t53 88.5t16.5 187q0 118 -16 179t-53.5 95.5t-102.5 34.5 q-66 0 -103 -34t-53 -92.5t-16 -182.5z" />
+<glyph unicode="&#x2032;" horiz-adv-x="557" d="M154 834l41 550h208l-122 -550h-127z" />
+<glyph unicode="&#x2033;" horiz-adv-x="1012" d="M154 834l41 550h208l-122 -550h-127zM609 834l41 550h208l-122 -550h-127z" />
<glyph unicode="&#x2039;" horiz-adv-x="735" d="M72 524l393 471h197l-394 -471l394 -471h-197z" />
<glyph unicode="&#x203a;" horiz-adv-x="735" d="M74 53l393 471l-393 471h196l394 -471l-394 -471h-196z" />
-<glyph unicode="&#x205f;" horiz-adv-x="476" />
+<glyph unicode="&#x203c;" horiz-adv-x="1110" d="M156 98q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5t-24.5 82.5zM178 1384h199l-25 -985h-145zM711 98q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5 q-71 0 -95.5 29.5t-24.5 82.5zM733 1384h199l-25 -985h-145z" />
+<glyph unicode="&#x203d;" horiz-adv-x="1049" d="M68 1313q51 92 151 149.5t266 57.5q214 0 334.5 -100t120.5 -281q0 -104 -42 -188t-117 -153.5t-251 -168.5v-230h-174l-16 928q-75 -37 -121 -113zM324 98q0 60 27.5 86.5t92.5 26.5q68 0 95.5 -26.5t27.5 -86.5q0 -63 -29.5 -87.5t-93.5 -24.5q-71 0 -95.5 29.5 t-24.5 82.5zM518 801q94 63 136.5 108.5t66.5 99t24 115.5q0 103 -55 161t-160 69z" />
+<glyph unicode="&#x203e;" horiz-adv-x="1024" d="M-10 1526v102h1044v-102h-1044z" />
+<glyph unicode="&#x2044;" horiz-adv-x="244" d="M-324 -51l779 1487h166l-781 -1487h-164z" />
+<glyph unicode="&#x205f;" horiz-adv-x="517" />
+<glyph unicode="&#x2070;" horiz-adv-x="889" d="M84 1079q0 228 87 334.5t273 106.5q187 0 274 -106.5t87 -332.5q0 -229 -87 -336.5t-274 -107.5q-186 0 -273 106.5t-87 335.5zM256 1079q0 -164 45 -239.5t143 -75.5q99 0 144 75.5t45 241.5q0 160 -45 236t-144 76q-98 0 -143 -76t-45 -238z" />
+<glyph unicode="&#x2074;" horiz-adv-x="889" d="M43 838v125l496 542h141v-542h127v-125h-127v-183h-160v183h-477zM221 963h299v325z" />
+<glyph unicode="&#x2075;" horiz-adv-x="889" d="M90 780l135 76q23 -35 69 -62.5t107 -27.5q95 0 142 45t47 123t-56.5 110.5t-130.5 32.5q-97 0 -167 -43h-86l53 471h524v-131h-385l-23 -188q46 16 121 16q150 0 235 -68t85 -200q0 -135 -88 -216t-266 -81q-115 0 -195 43t-121 100z" />
+<glyph unicode="&#x2076;" horiz-adv-x="889" d="M102 1065q0 218 101 338.5t282 120.5q86 0 149.5 -23.5t119.5 -70.5l-99 -109q-45 35 -84 55.5t-86 20.5q-83 0 -135.5 -59.5t-66.5 -174.5q101 49 196 49q139 0 221 -66.5t82 -207.5q0 -143 -88 -222t-243 -79q-185 0 -267 108.5t-82 319.5zM276 1040q3 -149 46 -212.5 t131 -63.5q163 0 163 170q0 149 -165 149q-86 0 -175 -43z" />
+<glyph unicode="&#x2077;" horiz-adv-x="889" d="M88 1374v131h688v-121l-360 -729h-180l362 719h-510z" />
+<glyph unicode="&#x2078;" horiz-adv-x="889" d="M94 883q0 71 48 128.5t137 96.5q-86 41 -124 85t-38 103q0 109 82 168.5t241 59.5q158 0 240 -57.5t82 -168.5q0 -57 -39 -103t-129 -89q190 -67 190 -223q0 -123 -93 -184.5t-251 -61.5q-172 0 -259 63.5t-87 182.5zM258 883q0 -58 45 -91.5t137 -33.5t136.5 35.5 t44.5 89.5q0 59 -54.5 95t-126.5 64q-107 -40 -144.5 -78t-37.5 -81zM281 1300q0 -34 32.5 -64t128.5 -67q154 43 154 127q0 47 -39 78t-117 31q-84 0 -121.5 -31t-37.5 -74z" />
+<glyph unicode="&#x2079;" horiz-adv-x="889" d="M94 1225q0 141 90 220t244 79q186 0 266 -106.5t80 -309.5q0 -226 -99.5 -348.5t-289.5 -122.5q-162 0 -274 96l98 111q88 -80 176 -80q181 0 209 231q-92 -45 -197 -45q-139 0 -221 66.5t-82 208.5zM258 1229q0 -152 170 -152q47 0 93 14.5t79 36.5q0 269 -172 269 q-82 0 -126 -43t-44 -125z" />
+<glyph unicode="&#x207f;" horiz-adv-x="862" d="M143 668v649h138v-90q47 43 111.5 76.5t129.5 33.5q117 0 161 -61.5t44 -173.5v-434h-139v372q0 99 -17.5 139t-85.5 40q-45 0 -100 -30t-104 -73v-448h-138z" />
+<glyph unicode="&#x2080;" horiz-adv-x="889" d="M84 106q0 228 87 334.5t273 106.5q187 0 274 -106.5t87 -332.5q0 -229 -87 -336.5t-274 -107.5q-186 0 -273 106.5t-87 335.5zM256 106q0 -164 45 -239.5t143 -75.5q99 0 144 75.5t45 241.5q0 160 -45 236t-144 76q-98 0 -143 -76t-45 -238z" />
+<glyph unicode="&#x2081;" horiz-adv-x="889" d="M182 268v107q129 4 182.5 37.5t77.5 119.5h125v-850h-161v586h-224z" />
+<glyph unicode="&#x2082;" horiz-adv-x="889" d="M106 389q106 162 326 162q148 0 230.5 -63.5t82.5 -180.5q0 -85 -38.5 -147t-122.5 -137t-260 -210h450v-131h-659v138q74 52 208.5 161t195 180t56.5 142q0 59 -44 89t-103 30q-108 0 -188 -111z" />
+<glyph unicode="&#x2083;" horiz-adv-x="889" d="M84 -195l133 74q27 -35 73 -60.5t103 -25.5q94 0 137 36t43 109q0 70 -48 100.5t-140 30.5h-90v127h78q86 0 136 32t50 91q0 54 -40 79.5t-105 25.5q-117 0 -187 -99l-133 76q40 56 82.5 85.5t105.5 47t142 17.5q160 0 233.5 -63.5t73.5 -151.5q0 -140 -139 -193 q67 -24 110 -78.5t43 -132.5q0 -133 -92 -200.5t-258 -67.5q-102 0 -186 39t-125 102z" />
+<glyph unicode="&#x2084;" horiz-adv-x="889" d="M43 -10l496 542h141v-542h127v-125h-127v-183h-160v183h-477v125zM221 -10h299v325z" />
+<glyph unicode="&#x2085;" horiz-adv-x="889" d="M90 -193l135 76q23 -35 69 -62.5t107 -27.5q95 0 142 45t47 123t-56.5 110.5t-130.5 32.5q-97 0 -167 -43h-86l53 471h524v-131h-385l-23 -188q46 16 121 16q150 0 235 -68t85 -200q0 -135 -88 -216t-266 -81q-115 0 -195 43t-121 100z" />
+<glyph unicode="&#x2086;" horiz-adv-x="889" d="M102 92q0 218 101 338.5t282 120.5q86 0 149.5 -23.5t119.5 -70.5l-99 -109q-45 35 -84 55.5t-86 20.5q-83 0 -135.5 -59.5t-66.5 -174.5q101 49 196 49q139 0 221 -66.5t82 -207.5q0 -143 -88 -222t-243 -79q-185 0 -267 108.5t-82 319.5zM276 67q3 -149 46 -212.5 t131 -63.5q163 0 163 170q0 149 -165 149q-86 0 -175 -43z" />
+<glyph unicode="&#x2087;" horiz-adv-x="889" d="M88 401v131h688v-121l-360 -729h-180l362 719h-510z" />
+<glyph unicode="&#x2088;" horiz-adv-x="889" d="M94 -90q0 71 48 128.5t137 96.5q-86 41 -124 85t-38 103q0 109 82 168.5t241 59.5q158 0 240 -57.5t82 -168.5q0 -57 -39 -103t-129 -89q190 -67 190 -223q0 -123 -93 -184.5t-251 -61.5q-172 0 -259 63.5t-87 182.5zM258 -90q0 -58 45 -91.5t137 -33.5t136.5 35.5 t44.5 89.5q0 59 -54.5 95t-126.5 64q-107 -40 -144.5 -78t-37.5 -81zM281 327q0 -34 32.5 -64t128.5 -67q154 43 154 127q0 47 -39 78t-117 31q-84 0 -121.5 -31t-37.5 -74z" />
+<glyph unicode="&#x2089;" horiz-adv-x="889" d="M94 252q0 141 90 220t244 79q186 0 266 -106.5t80 -309.5q0 -226 -99.5 -348.5t-289.5 -122.5q-162 0 -274 96l98 111q88 -80 176 -80q181 0 209 231q-92 -45 -197 -45q-139 0 -221 66.5t-82 208.5zM258 256q0 -152 170 -152q47 0 93 14.5t79 36.5q0 269 -172 269 q-82 0 -126 -43t-44 -125z" />
+<glyph unicode="&#x20a3;" horiz-adv-x="1264" d="M92 227v131h172v1026h838v-167h-653v-404h555v-168h-555v-287h350v-131h-350v-227h-185v227h-172z" />
+<glyph unicode="&#x20a4;" horiz-adv-x="1264" d="M113 0v156q80 16 119.5 96t52.5 205h-158v121h166q0 91 -12 149h-154v121h129q-23 108 -23 196q0 173 127 271t342 98q306 0 443 -219l-154 -90q-45 72 -118.5 115t-170.5 43q-135 0 -206.5 -64.5t-71.5 -181.5q0 -78 22 -168h416v-121h-391q12 -87 12 -149h379v-121 h-389q-33 -217 -151 -301h837v-156h-1046z" />
+<glyph unicode="&#x20a7;" horiz-adv-x="2540" d="M182 0v1384h369q211 0 334 -74.5t149 -260.5h160v292h172v-292h246v-144h-246v-555q0 -127 21.5 -182t95.5 -55q61 0 119 28l45 -141q-95 -31 -185 -31q-143 0 -205.5 84t-62.5 264v588h-154q-8 -228 -124 -332t-373 -104h-176v-469h-185zM367 637h137q146 0 213.5 28.5 t99 92t31.5 180.5q0 145 -72 212t-246 67h-163v-580zM1649 158l137 84q80 -127 254 -127q115 0 171 43.5t56 117.5q0 44 -18.5 71t-60.5 48t-175 56q-187 43 -263.5 119t-76.5 202q0 139 100.5 223t276.5 84q137 0 230.5 -54t136.5 -130l-138 -84q-82 123 -233 123 q-86 0 -145.5 -38t-59.5 -118q0 -71 52.5 -103t162.5 -59q180 -47 247.5 -86.5t99.5 -98.5t32 -148q0 -150 -105 -232t-294 -82q-135 0 -238.5 51t-148.5 138z" />
+<glyph unicode="&#x20ab;" horiz-adv-x="1174" d="M117 487q0 159 49.5 279t145 187t227.5 67q158 0 292 -117v219h-301v140h301v122h173v-122h137v-140h-137v-1122h-173v104q-59 -57 -142 -96t-177 -39q-194 0 -294.5 137.5t-100.5 380.5zM158 -152h846v-139h-846v139zM295 492q0 -190 64 -279.5t186 -89.5q82 0 156.5 41 t129.5 94v496q-136 112 -270 112q-117 0 -191.5 -91t-74.5 -283z" />
<glyph unicode="&#x20ac;" horiz-adv-x="1264" d="M31 506l39 119h59v139h-98l37 119h71q35 264 173.5 397t392.5 133q114 0 204.5 -29.5t153 -80.5t119.5 -150l-152 -96q-45 78 -88 116t-101 59t-136 21q-166 0 -254.5 -98t-116.5 -272h592l-37 -119h-565v-139h530l-37 -119h-483q28 -187 118.5 -281t256.5 -94 q113 0 192 49.5t146 173.5l147 -92q-87 -160 -199.5 -225.5t-279.5 -65.5q-508 0 -576 535h-108z" />
+<glyph unicode="&#x20b9;" horiz-adv-x="1264" d="M147 934l84 145h494q-12 84 -60.5 121t-142.5 37h-375l84 147h914l-84 -147h-244q72 -61 84 -158h244l-84 -145h-160q-21 -149 -141 -227.5t-326 -83.5l473 -623h-200l-476 623v151h177q155 0 227 35t88 125h-576z" />
+<glyph unicode="&#x20ba;" horiz-adv-x="1264" d="M158 575v146l178 63v152l-178 -64v142l178 65v305h172v-251l291 108v-145l-291 -107v-151l291 106v-143l-291 -107v-559h27q204 0 300.5 125t96.5 402h168q0 -336 -140.5 -513.5t-449.5 -177.5q-100 0 -174 29v641z" />
+<glyph unicode="&#x2105;" horiz-adv-x="1843" d="M72 1155q0 168 76.5 266.5t254.5 98.5q185 0 265 -136l-117 -65q-55 84 -150 84q-188 0 -188 -248q0 -111 41 -179.5t154 -68.5q84 0 159 62l84 -103q-35 -24 -92 -49.5t-156 -25.5q-331 0 -331 364zM442 -31l801 1520h164l-803 -1520h-162zM1120 328q0 179 83.5 270.5 t242.5 91.5q174 0 250 -100.5t76 -261.5q0 -175 -84 -267t-242 -92q-166 0 -246 94.5t-80 264.5zM1264 328q0 -111 39.5 -177.5t142.5 -66.5q100 0 141 66.5t41 177.5q0 112 -41 178.5t-141 66.5q-103 0 -142.5 -66.5t-39.5 -178.5z" />
+<glyph unicode="&#x2113;" horiz-adv-x="1067" d="M156 459l192 196v449q0 188 74 287.5t205 99.5q67 0 115.5 -29.5t75 -83.5t26.5 -116q0 -132 -64 -263.5t-250 -359.5v-332q0 -104 38 -147t96 -43q57 0 103 32.5t77 65.5l65 -106q-60 -63 -137.5 -100.5t-155.5 -37.5q-129 0 -198.5 84.5t-69.5 239.5v194l-123 -124z M530 819q84 96 134.5 210t50.5 206q0 47 -18.5 79t-57.5 32q-109 0 -109 -220v-307z" />
+<glyph unicode="&#x2116;" horiz-adv-x="2402" d="M164 0v1384h285l651 -1089v1089h182v-1384h-225l-711 1204v-1204h-182zM1516 879q0 193 88.5 294t265.5 101q190 0 273 -108.5t83 -286.5q0 -193 -92.5 -292.5t-263.5 -99.5q-170 0 -262 99t-92 293zM1542 0v172h658v-172h-658zM1698 879q0 -111 38 -181.5t134 -70.5 q98 0 136 70.5t38 181.5q0 112 -38 184t-136 72q-96 0 -134 -72t-38 -184z" />
<glyph unicode="&#x2122;" horiz-adv-x="1608" d="M76 1257v127h581v-127h-219v-587h-141v587h-221zM817 670v714h164l174 -344l180 344h160v-714h-137v483l-160 -301h-88l-156 299v-481h-137z" />
+<glyph unicode="&#x2126;" horiz-adv-x="1364" d="M119 811q0 183 65 319.5t189.5 209.5t298.5 73q295 0 434 -151.5t139 -450.5q0 -266 -80 -408.5t-241 -183.5v-51h290v-168h-454v322q109 12 170 63.5t91 150t30 261.5q0 239 -91.5 345.5t-287.5 106.5q-180 0 -269.5 -110.5t-89.5 -341.5q0 -159 26 -251.5t83.5 -144.5 t181.5 -79v-322h-454v168h290v51q-164 45 -242.5 186.5t-78.5 405.5z" />
+<glyph unicode="&#x212e;" horiz-adv-x="1399" d="M88 623q0 183 76 331.5t216 232t316 83.5q178 0 317 -83.5t216 -230.5t82 -333h-959v-430q144 -140 340 -140q147 0 258 66.5t203 216.5l39 -22l37 -23q-109 -167 -237 -241.5t-300 -74.5q-173 0 -310.5 83.5t-215.5 233.5t-78 331zM352 700h686v351q-65 65 -154 103 t-188 38q-204 0 -344 -139v-353z" />
+<glyph unicode="&#x215b;" horiz-adv-x="1946" d="M182 1126v107q129 4 182.5 37.5t77.5 119.5h125v-850h-161v586h-224zM452 -51l779 1487h166l-781 -1487h-164zM1151 217q0 71 48 128.5t137 96.5q-86 41 -124 85t-38 103q0 109 82 168.5t241 59.5q158 0 240 -57.5t82 -168.5q0 -57 -39 -103t-129 -89q190 -67 190 -223 q0 -123 -93 -184.5t-251 -61.5q-172 0 -259 63.5t-87 182.5zM1315 217q0 -58 45 -91.5t137 -33.5t136.5 35.5t44.5 89.5q0 59 -54.5 95t-126.5 64q-107 -40 -144.5 -78t-37.5 -81zM1338 634q0 -34 32.5 -64t128.5 -67q154 43 154 127q0 47 -39 78t-117 31q-84 0 -121.5 -31 t-37.5 -74z" />
+<glyph unicode="&#x215c;" horiz-adv-x="1946" d="M84 663l133 74q27 -35 73 -60.5t103 -25.5q94 0 137 36t43 109q0 70 -48 100.5t-140 30.5h-90v127h78q86 0 136 32t50 91q0 54 -40 79.5t-105 25.5q-117 0 -187 -99l-133 76q40 56 82.5 85.5t105.5 47t142 17.5q160 0 233.5 -63.5t73.5 -151.5q0 -140 -139 -193 q67 -24 110 -78.5t43 -132.5q0 -133 -92 -200.5t-258 -67.5q-102 0 -186 39t-125 102zM485 -51l779 1487h166l-781 -1487h-164zM1151 217q0 71 48 128.5t137 96.5q-86 41 -124 85t-38 103q0 109 82 168.5t241 59.5q158 0 240 -57.5t82 -168.5q0 -57 -39 -103t-129 -89 q190 -67 190 -223q0 -123 -93 -184.5t-251 -61.5q-172 0 -259 63.5t-87 182.5zM1315 217q0 -58 45 -91.5t137 -33.5t136.5 35.5t44.5 89.5q0 59 -54.5 95t-126.5 64q-107 -40 -144.5 -78t-37.5 -81zM1338 634q0 -34 32.5 -64t128.5 -67q154 43 154 127q0 47 -39 78t-117 31 q-84 0 -121.5 -31t-37.5 -74z" />
+<glyph unicode="&#x215d;" horiz-adv-x="1946" d="M90 665l135 76q23 -35 69 -62.5t107 -27.5q95 0 142 45t47 123t-56.5 110.5t-130.5 32.5q-97 0 -167 -43h-86l53 471h524v-131h-385l-23 -188q46 16 121 16q150 0 235 -68t85 -200q0 -135 -88 -216t-266 -81q-115 0 -195 43t-121 100zM489 -51l779 1487h166l-781 -1487 h-164zM1151 217q0 71 48 128.5t137 96.5q-86 41 -124 85t-38 103q0 109 82 168.5t241 59.5q158 0 240 -57.5t82 -168.5q0 -57 -39 -103t-129 -89q190 -67 190 -223q0 -123 -93 -184.5t-251 -61.5q-172 0 -259 63.5t-87 182.5zM1315 217q0 -58 45 -91.5t137 -33.5t136.5 35.5 t44.5 89.5q0 59 -54.5 95t-126.5 64q-107 -40 -144.5 -78t-37.5 -81zM1338 634q0 -34 32.5 -64t128.5 -67q154 43 154 127q0 47 -39 78t-117 31q-84 0 -121.5 -31t-37.5 -74z" />
+<glyph unicode="&#x215e;" horiz-adv-x="1946" d="M88 1259v131h688v-121l-360 -729h-180l362 719h-510zM452 -51l779 1487h166l-781 -1487h-164zM1151 217q0 71 48 128.5t137 96.5q-86 41 -124 85t-38 103q0 109 82 168.5t241 59.5q158 0 240 -57.5t82 -168.5q0 -57 -39 -103t-129 -89q190 -67 190 -223 q0 -123 -93 -184.5t-251 -61.5q-172 0 -259 63.5t-87 182.5zM1315 217q0 -58 45 -91.5t137 -33.5t136.5 35.5t44.5 89.5q0 59 -54.5 95t-126.5 64q-107 -40 -144.5 -78t-37.5 -81zM1338 634q0 -34 32.5 -64t128.5 -67q154 43 154 127q0 47 -39 78t-117 31q-84 0 -121.5 -31 t-37.5 -74z" />
+<glyph unicode="&#x2190;" horiz-adv-x="2048" d="M190 494v47q80 40 144.5 85.5t129 106t138.5 144.5h78q-76 -157 -168 -273h1346v-176h-1346q57 -69 94.5 -132t73.5 -138h-78q-109 122 -196 193.5t-216 142.5z" />
+<glyph unicode="&#x2191;" horiz-adv-x="1024" d="M154 1178v75q151 140 215 223t120 191h46q63 -121 131 -203t206 -211v-75q-66 29 -128 64.5t-144 100.5v-1343h-174v1343q-70 -52 -120.5 -84.5t-151.5 -80.5z" />
+<glyph unicode="&#x2192;" horiz-adv-x="2048" d="M190 428v176h1344q-70 90 -97.5 139t-68.5 134h76q140 -154 223 -218t191 -120v-45q-121 -64 -221 -146.5t-193 -189.5h-76q49 100 84 157t82 113h-1344z" />
+<glyph unicode="&#x2193;" horiz-adv-x="1024" d="M152 414v75q94 -45 149 -79t123 -86v1343h174v-1343q68 49 120 83.5t152 81.5v-75q-135 -123 -204 -211q-68 -82 -131 -203h-46q-63 121 -131 203t-206 211z" />
+<glyph unicode="&#x2194;" horiz-adv-x="2048" d="M190 494v47q80 40 144.5 85.5t129 106t138.5 144.5h78q-76 -157 -168 -273h1022q-60 78 -73.5 98.5t-39.5 69.5t-53 105h76q140 -154 223 -218t191 -120v-45q-121 -64 -221 -146.5t-193 -189.5h-76q60 122 76 147q30 50 90 123h-1022q57 -69 94.5 -132t73.5 -138h-78 q-109 122 -196 193.5t-216 142.5z" />
+<glyph unicode="&#x2195;" horiz-adv-x="1024" d="M154 414v75q73 -34 135.5 -70t136.5 -95v1019q-53 -43 -106.5 -78t-165.5 -87v75q125 112 197.5 201t137.5 213h46q60 -114 128 -201t209 -213v-75q-116 54 -159 81.5t-113 83.5v-1019l65 48q78 56 207 117v-75q-139 -123 -206 -209t-131 -205h-46q-63 121 -145 220.5 t-190 193.5z" />
+<glyph unicode="&#x21a8;" horiz-adv-x="1024" d="M154 -74h718v-174h-718v174zM154 414v75q62 -29 127 -66.5t145 -98.5v1019q-48 -38 -110 -78t-162 -87v75q141 128 215 226t120 188h46q54 -104 118 -190.5t219 -223.5v-75q-116 54 -159 81.5t-113 83.5v-1019q105 78 152 105t120 60v-75q-80 -69 -135 -126.5 t-104.5 -127t-97.5 -160.5h-46q-63 121 -145 220.5t-190 193.5z" />
+<glyph unicode="&#x2202;" horiz-adv-x="1255" d="M102 381q0 182 74.5 326.5t204 226.5t272.5 82q113 0 186.5 -46t104.5 -104h4q8 58 8 127q0 164 -75.5 255t-216.5 91q-119 0 -211 -59l-50 135q43 29 121 53.5t170 24.5q212 0 334.5 -139.5t122.5 -384.5q0 -266 -87 -501t-235.5 -363t-326.5 -128q-113 0 -205 50.5 t-143.5 144t-51.5 209.5zM301 375q0 -111 56.5 -176.5t150.5 -65.5q142 0 254 156t160 409q-23 72 -81.5 123t-156.5 51q-101 0 -190 -67t-141 -182.5t-52 -247.5z" />
+<glyph unicode="&#x2206;" horiz-adv-x="1260" d="M51 0v88q115 313 231.5 648t233.5 648h234q110 -313 227 -648t231 -648v-88h-1157zM266 160h715l-303 887q-16 46 -53 172h-4l-24 -87l-28 -88z" />
+<glyph unicode="&#x220f;" horiz-adv-x="1571" d="M178 -471v1905h1215v-1905h-203v1731h-811v-1731h-201z" />
+<glyph unicode="&#x2211;" horiz-adv-x="1372" d="M61 -371l693 860l-648 832v113h1154v-164h-887l602 -776l-639 -801h973v-164h-1248v100z" />
+<glyph unicode="&#x2212;" horiz-adv-x="1427" d="M164 514v143h1100v-143h-1100z" />
+<glyph unicode="&#x2215;" horiz-adv-x="991" d="M8 -299l715 1819h168l-717 -1819h-166z" />
+<glyph unicode="&#x2219;" horiz-adv-x="506" d="M125 590q0 63 28.5 91t98.5 28q72 0 100.5 -28t28.5 -91q0 -66 -32 -92.5t-97 -26.5q-74 0 -100.5 30.5t-26.5 88.5z" />
+<glyph unicode="&#x221a;" horiz-adv-x="1153" d="M47 686l264 166l285 -655l362 1296h146l-428 -1518h-156l-295 678l-116 -73z" />
+<glyph unicode="&#x221e;" horiz-adv-x="1718" d="M100 594q0 102 45 184.5t127 127t187 44.5q233 0 397 -233h4q79 114 181 173.5t208 59.5q166 0 266.5 -98.5t100.5 -249.5t-97.5 -254.5t-261.5 -103.5q-127 0 -229 65.5t-168 169.5h-4q-72 -102 -171 -168.5t-222 -66.5q-160 0 -261.5 97.5t-101.5 252.5zM260 594 q0 -92 59.5 -150.5t151.5 -58.5q94 0 172 62.5t135 150.5q-59 94 -140 152.5t-169 58.5q-104 0 -156.5 -63.5t-52.5 -151.5zM936 598q59 -98 138 -155.5t169 -57.5q97 0 154 57t57 158q0 98 -58 153.5t-153 55.5q-98 0 -172 -59.5t-135 -151.5z" />
+<glyph unicode="&#x221f;" horiz-adv-x="2048" d="M123 0v1667h135v-1532h1667v-135h-1802z" />
+<glyph unicode="&#x2229;" horiz-adv-x="1473" d="M158 0v588q0 186 7 307.5t51.5 225.5t123.5 181t182 117.5t215 40.5q137 0 246 -49t182 -137q75 -89 108 -194.5t37.5 -208t4.5 -283.5v-588h-146v596q0 225 -10.5 323t-51.5 177t-95 126.5t-122.5 70t-154.5 22.5q-136 0 -227.5 -56.5t-141.5 -156t-57 -221.5 q-4 -108 -4 -285v-596h-147z" />
+<glyph unicode="&#x222b;" horiz-adv-x="1059" d="M119 -449l41 148q47 -21 100 -21q168 0 168 201v1284q0 172 87 271.5t257 99.5q49 0 97.5 -9t70.5 -22l-41 -145q-40 20 -100 20q-84 0 -127 -51t-43 -147v-1284q0 -177 -89 -275t-253 -98q-41 0 -91.5 8t-76.5 20z" />
+<glyph unicode="&#x2248;" horiz-adv-x="1427" d="M162 643v160q100 80 178 103.5t127 23.5q61 0 125.5 -24.5t129 -54.5t126 -54.5t117.5 -24.5q57 0 123.5 29t119.5 71l54 43v-159q-64 -54 -131.5 -90.5t-161.5 -36.5q-62 0 -130.5 24.5t-136 54t-130 54t-109.5 24.5q-138 0 -301 -143zM164 193v159q100 80 178 103.5 t127 23.5q61 0 125.5 -24.5t129 -54t126 -54t117.5 -24.5q47 0 91.5 15.5t84.5 38t121 89.5v-160q-78 -65 -154 -96t-139 -31q-62 0 -130.5 24.5t-136 54.5t-130 54.5t-109.5 24.5q-129 0 -301 -143z" />
+<glyph unicode="&#x2260;" horiz-adv-x="1427" d="M164 283v143h375l166 317h-541v144h616l217 413h166l-217 -413h318v-144h-394l-165 -317h559v-143h-635l-191 -365h-164l191 365h-301z" />
+<glyph unicode="&#x2261;" horiz-adv-x="1427" d="M164 0v143h1100v-143h-1100zM164 463v143h1100v-143h-1100zM164 926v143h1100v-143h-1100z" />
+<glyph unicode="&#x2264;" horiz-adv-x="1427" d="M164 0v143h1100v-143h-1100zM164 635v125l1100 448v-155l-902 -357l902 -295v-155z" />
+<glyph unicode="&#x2265;" horiz-adv-x="1427" d="M164 0v143h1100v-143h-1100zM164 246v155l901 295l-901 357v155l1100 -448v-125z" />
+<glyph unicode="&#x2302;" horiz-adv-x="1229" d="M154 0v635l460 518l461 -518v-635h-921zM233 82h762v518l-381 426l-381 -426v-518z" />
+<glyph unicode="&#x2310;" horiz-adv-x="1427" d="M164 367v604h1100v-144h-957v-460h-143z" />
+<glyph unicode="&#x2320;" horiz-adv-x="1237" d="M547 -381v1608q0 223 88 329q88 111 203 111q67 0 103 -34t36 -74q0 -37 -25.5 -65t-62.5 -28q-29 0 -52.5 11.5t-48.5 50.5q-22 37 -45 37q-30 0 -43 -27q-10 -31 -10 -152v-1767h-143z" />
+<glyph unicode="&#x2321;" horiz-adv-x="1237" d="M260 -272q0 39 26.5 65.5t61.5 26.5q31 0 53.5 -12.5t47.5 -51.5q22 -35 45 -35q33 0 43 32.5t10 146.5v1767h143v-1608q0 -219 -88 -327q-86 -113 -203 -113q-69 0 -104 33t-35 76z" />
+<glyph unicode="&#x2500;" horiz-adv-x="1450" d="M-23 535v174h1496v-174h-1496z" />
+<glyph unicode="&#x2502;" horiz-adv-x="1450" d="M639 -621v2485h174v-2485h-174z" />
+<glyph unicode="&#x250c;" horiz-adv-x="1450" d="M639 -621v1330h836v-174h-662v-1156h-174z" />
+<glyph unicode="&#x2510;" horiz-adv-x="1450" d="M-23 535v174h834v-1330h-174v1156h-660z" />
+<glyph unicode="&#x2514;" horiz-adv-x="1450" d="M639 535v1329h174v-1155h662v-174h-836z" />
+<glyph unicode="&#x2518;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-1329h-834z" />
+<glyph unicode="&#x251c;" horiz-adv-x="1450" d="M639 -621v2485h174v-1155h662v-174h-662v-1156h-174z" />
+<glyph unicode="&#x2524;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-2485h-174v1156h-660z" />
+<glyph unicode="&#x252c;" horiz-adv-x="1450" d="M-23 535v174h1496v-174h-662v-1156h-174v1156h-660z" />
+<glyph unicode="&#x2534;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-1155h662v-174h-1496z" />
+<glyph unicode="&#x253c;" horiz-adv-x="1450" d="M-23 535v174h660v1155h174v-1155h662v-174h-662v-1156h-174v1156h-660z" />
+<glyph unicode="&#x2550;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-1496zM-23 725v174h1496v-174h-1496z" />
+<glyph unicode="&#x2551;" horiz-adv-x="1450" d="M449 -621v2485h174v-2485h-174zM829 -621v2485h175v-2485h-175z" />
+<glyph unicode="&#x2552;" horiz-adv-x="1450" d="M639 -621v1520h836v-174h-662v-207h662v-174h-662v-965h-174z" />
+<glyph unicode="&#x2553;" horiz-adv-x="1450" d="M449 -621v1330h1026v-174h-471v-1156h-175v1156h-206v-1156h-174z" />
+<glyph unicode="&#x2554;" horiz-adv-x="1450" d="M449 -621v1520h1026v-174h-852v-1346h-174zM829 518h646v-174h-471v-965h-175v1139z" />
+<glyph unicode="&#x2555;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h834v-1520h-174v965h-660z" />
+<glyph unicode="&#x2556;" horiz-adv-x="1450" d="M-23 535v174h1027v-1330h-177v1156h-204v-1156h-174v1156h-472z" />
+<glyph unicode="&#x2557;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h1027v-1520h-177v1346h-850z" />
+<glyph unicode="&#x2558;" horiz-adv-x="1450" d="M639 344v1520h174v-965h662v-174h-662v-207h662v-174h-836z" />
+<glyph unicode="&#x2559;" horiz-adv-x="1450" d="M449 535v1329h174v-1155h206v1155h175v-1155h471v-174h-1026z" />
+<glyph unicode="&#x255a;" horiz-adv-x="1450" d="M449 344v1520h174v-1346h850v-174h-1024zM829 725v1139h175v-965h471v-174h-646z" />
+<glyph unicode="&#x255b;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h660v965h174v-1520h-834z" />
+<glyph unicode="&#x255c;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1329h-1027z" />
+<glyph unicode="&#x255d;" horiz-adv-x="1450" d="M-23 344v174h850v1346h177v-1520h-1027zM-23 725v174h469v965h177v-1139h-646z" />
+<glyph unicode="&#x255e;" horiz-adv-x="1450" d="M639 -621v2485h174v-965h662v-174h-662v-207h662v-174h-662v-965h-174z" />
+<glyph unicode="&#x255f;" horiz-adv-x="1450" d="M449 -621v2485h174v-2485h-174zM829 -621v2485h175v-1155h471v-174h-471v-1156h-175z" />
+<glyph unicode="&#x2560;" horiz-adv-x="1450" d="M449 -621v2485h174v-2485h-174zM829 518h646v-174h-471v-965h-175v1139zM829 725v1139h175v-965h471v-174h-646z" />
+<glyph unicode="&#x2561;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h660v965h174v-2485h-174v965h-660z" />
+<glyph unicode="&#x2562;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-2485h-177l3 1156h-472zM827 -621v2485h177v-2485h-177z" />
+<glyph unicode="&#x2563;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h469v965h177v-1139h-646zM827 -621v2485h177v-2485h-177z" />
+<glyph unicode="&#x2564;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-662v-965h-174v965h-660zM-23 725v174h1496v-174h-1496z" />
+<glyph unicode="&#x2565;" horiz-adv-x="1450" d="M-23 535v174h1496v-174h-469v-1156h-177v1156h-204v-1156h-177v1156h-469z" />
+<glyph unicode="&#x2566;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h1496v-174h-1496zM827 518h646v-174h-469v-965h-177v1139z" />
+<glyph unicode="&#x2567;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-1496zM-23 725v174h660v965h174v-965h662v-174h-1496z" />
+<glyph unicode="&#x2568;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1155h469v-174h-1496z" />
+<glyph unicode="&#x2569;" horiz-adv-x="1450" d="M-23 344v174h1496v-174h-1496zM-23 725v174h469v965h177v-1139h-646zM827 725v1139h177v-965h469v-174h-646z" />
+<glyph unicode="&#x256a;" horiz-adv-x="1450" d="M-23 344v174h660v207h-660v174h660v965h174v-965h662v-174h-662v-207h662v-174h-662v-965h-174v965h-660z" />
+<glyph unicode="&#x256b;" horiz-adv-x="1450" d="M-23 535v174h469v1155h177v-1155h204v1155h177v-1155h469v-174h-469v-1156h-177v1156h-204v-1156h-177v1156h-469z" />
+<glyph unicode="&#x256c;" horiz-adv-x="1450" d="M-23 344v174h646v-1139h-177v965h-469zM-23 725v174h469v965h177v-1139h-646zM827 518h646v-174h-469v-965h-177v1139zM827 725v1139h177v-965h469v-174h-646z" />
+<glyph unicode="&#x2580;" horiz-adv-x="1450" d="M-23 621v1243h1496v-1243h-1496z" />
+<glyph unicode="&#x2584;" horiz-adv-x="1450" d="M-23 -621v1242h1496v-1242h-1496z" />
+<glyph unicode="&#x2588;" horiz-adv-x="1450" d="M-23 -621v2485h1496v-2485h-1496z" />
+<glyph unicode="&#x258c;" horiz-adv-x="1450" d="M-23 -621v2485h748v-2485h-748z" />
+<glyph unicode="&#x2590;" horiz-adv-x="1450" d="M725 -621v2485h750v-2485h-750z" />
+<glyph unicode="&#x2591;" horiz-adv-x="1450" d="M0 -129h121v-127h-121v127zM0 244v125h121v-125h-121zM0 741v125h121v-125h-121zM0 1241v125h121v-125h-121zM0 1739v125h121v-125h-121zM242 -4v125h120v-125h-120zM242 -379h120v-125h-120v125zM242 494v124h120v-124h-120zM242 991v125h120v-125h-120zM242 1491v125 h120v-125h-120zM481 -129h121v-127h-121v127zM481 244v125h121v-125h-121zM481 741v125h121v-125h-121zM481 1241v125h121v-125h-121zM481 1739v125h121v-125h-121zM723 -4v125h121v-125h-121zM723 -379h121v-125h-121v125zM723 494v124h121v-124h-121zM723 991v125h121 v-125h-121zM723 1491v125h121v-125h-121zM965 -129h120v-127h-120v127zM965 244v125h120v-125h-120zM965 741v125h120v-125h-120zM965 1241v125h120v-125h-120zM965 1739v125h120v-125h-120zM1206 -4v125h121v-125h-121zM1206 -379h121v-125h-121v125zM1206 494v124h121 v-124h-121zM1206 991v125h121v-125h-121zM1206 1491v125h121v-125h-121z" />
+<glyph unicode="&#x2592;" horiz-adv-x="1450" d="M0 -4v123h121v-123h-121zM0 -379h121v-125h-121v125zM0 494v124h121v-124h-121zM0 991v125h121v-125h-121zM0 1491v125h121v-125h-121zM121 -129h121v-127h-121v127zM121 244v125h121v-125h-121zM121 741v125h121v-125h-121zM121 1241v125h121v-125h-121zM121 1739v125 h121v-125h-121zM242 -4v123h120v-123h-120zM242 -379h120v-125h-120v125zM242 494v124h120v-124h-120zM242 991v125h120v-125h-120zM242 1491v125h120v-125h-120zM362 -129h119v-127h-119v127zM362 244v125h119v-125h-119zM362 741v125h119v-125h-119zM362 1241v125h119 v-125h-119zM362 1739v125h119v-125h-119zM481 -4v123h121v-123h-121zM481 -379h121v-125h-121v125zM481 494v124h121v-124h-121zM481 991v125h121v-125h-121zM481 1491v125h121v-125h-121zM602 -129h123v-127h-123v127zM602 244v125h123v-125h-123zM602 741v125h123v-125 h-123zM602 1241v125h123v-125h-123zM602 1739v125h123v-125h-123zM725 -4v123h119v-123h-119zM725 -379h119v-125h-119v125zM725 494v124h119v-124h-119zM725 991v125h119v-125h-119zM725 1491v125h119v-125h-119zM844 -129h121v-127h-121v127zM844 244v125h121v-125h-121z M844 741v125h121v-125h-121zM844 1241v125h121v-125h-121zM844 1739v125h121v-125h-121zM965 -4v123h120v-123h-120zM965 -381l120 2v-125h-120v123zM965 494v124h120v-124h-120zM965 991v125h120v-125h-120zM965 1491v125h120v-125h-120zM1085 -129h121v-127h-121v127z M1085 244v125h121v-125h-121zM1085 741v125h121v-125h-121zM1085 1241v125h121v-125h-121zM1085 1739v125h121v-125h-121zM1206 -4v123h121v-123h-121zM1206 -379h121v-125h-121v125zM1206 494v124h121v-124h-121zM1206 991v125h121v-125h-121zM1206 1491v125h121v-125h-121 zM1327 -129h121v-127h-121v127zM1327 244v125h121v-125h-121zM1327 741v125h121v-125h-121zM1327 1241v125h121v-125h-121zM1327 1739v125h121v-125h-121z" />
+<glyph unicode="&#x2593;" horiz-adv-x="1450" d="M0 -129v373h121v125h-121v372h121v125h-121v375h121v125h-121v373h121v125h121v-125h120v125h119v-125h121v125h123v-125h119v125h121v-125h120v125h121v-125h121v125h121v-248h-121v-125h121v-375h-121v-125h121v-373h-121v-124h121v-375h-121v-123h121v-375h-121v-125 h121v-125h-1448v373h121v127h-121zM121 -4h121v123h-121v-123zM121 -379v-125h121v125h-121zM121 494h121v124h-121v-124zM121 991h121v125h-121v-125zM121 1491h121v125h-121v-125zM242 -129v-127h120v127h-120zM242 244h120v125h-120v-125zM242 741h120v125h-120v-125z M242 1241h120v125h-120v-125zM362 -4h119v123h-119v-123zM362 -379v-125h119v125h-119zM362 494h119v124h-119v-124zM362 991h119v125h-119v-125zM362 1491h119v125h-119v-125zM481 -129v-127h121v127h-121zM481 244h121v125h-121v-125zM481 741h121v125h-121v-125z M481 1241h121v125h-121v-125zM602 -4h123v123h-123v-123zM602 -379v-125h123v125h-123zM602 494h123v124h-123v-124zM602 991h123v125h-123v-125zM602 1491h123v125h-123v-125zM725 -129v-127h119v127h-119zM725 244h119v125h-119v-125zM725 741h119v125h-119v-125z M725 1241h119v125h-119v-125zM844 -4h121v123h-121v-123zM844 -379v-125h121v125h-121zM844 494h121v124h-121v-124zM844 991h121v125h-121v-125zM844 1491h121v125h-121v-125zM965 -129v-127h120v127h-120zM965 244h120v125h-120v-125zM965 741h120v125h-120v-125z M965 1241h120v125h-120v-125zM1085 -4h121v123h-121v-123zM1085 -379v-125h121v125h-121zM1085 494h121v124h-121v-124zM1085 991h121v125h-121v-125zM1085 1491h121v125h-121v-125zM1206 -129v-127h121v127h-121zM1206 244h121v125h-121v-125zM1206 741h121v125h-121v-125z M1206 1241h121v125h-121v-125z" />
+<glyph unicode="&#x25a0;" horiz-adv-x="1237" d="M145 0v944h945v-944h-945z" />
+<glyph unicode="&#x25a1;" horiz-adv-x="1237" d="M145 0v944h945v-944h-945zM221 76h793v792h-793v-792z" />
+<glyph unicode="&#x25aa;" horiz-adv-x="725" d="M131 444v463l463 2v-465h-463z" />
+<glyph unicode="&#x25ab;" horiz-adv-x="725" d="M131 444v463h463v-463h-463zM207 520h311v311h-311v-311z" />
+<glyph unicode="&#x25ac;" horiz-adv-x="2048" d="M340 0v385h1368v-385h-1368z" />
+<glyph unicode="&#x25b2;" horiz-adv-x="2028" d="M303 0l711 1419l710 -1419h-1421z" />
+<glyph unicode="&#x25ba;" horiz-adv-x="2028" d="M289 -31v1448l1450 -725z" />
+<glyph unicode="&#x25bc;" horiz-adv-x="2028" d="M303 1389h1421l-710 -1420z" />
+<glyph unicode="&#x25c4;" horiz-adv-x="2028" d="M289 692l1450 725v-1448z" />
+<glyph unicode="&#x25ca;" horiz-adv-x="1229" d="M145 715l451 719h100l453 -717l-453 -717h-100zM307 717l340 -541l338 541l-338 538z" />
+<glyph unicode="&#x25cb;" horiz-adv-x="1237" d="M178 595q0 105 62 205.5t159.5 159t218.5 58.5q120 0 218.5 -58t160.5 -158.5t62 -206.5q0 -139 -58.5 -238.5t-157.5 -159.5t-225 -60q-124 0 -223 59.5t-158 159t-59 239.5zM254 594q0 -117 48 -199.5t130.5 -132t185.5 -49.5q155 0 260 107t105 267q0 87 -47.5 169 t-131 134t-186.5 52q-101 0 -183.5 -50.5t-131.5 -131.5t-49 -166z" />
+<glyph unicode="&#x25cf;" horiz-adv-x="1237" d="M178 595q0 105 62 205.5t159.5 159t218.5 58.5q120 0 218.5 -58t160.5 -158.5t62 -206.5q0 -139 -58.5 -238.5t-157.5 -159.5t-225 -60q-124 0 -223 59.5t-158 159t-59 239.5z" />
+<glyph unicode="&#x25d8;" horiz-adv-x="1237" d="M127 0v981h981v-981h-981zM416 489q0 -84 60.5 -142t141.5 -58t141 59t60 141q0 86 -57 144.5t-144 58.5q-86 0 -144 -58.5t-58 -144.5z" />
+<glyph unicode="&#x25d9;" horiz-adv-x="1237" d="M43 0v1155h1153v-1155h-1153zM178 595q0 -139 58.5 -238.5t158 -159.5t223.5 -60q126 0 225.5 59.5t158.5 159.5t59 239q0 105 -62 205.5t-160 159t-221 58.5q-120 0 -218 -58.5t-160 -159t-62 -205.5zM256 595q0 88 49.5 168.5t132 129.5t183.5 49q97 0 179.5 -48.5 t132.5 -129t50 -169.5q0 -171 -106.5 -276.5t-255.5 -105.5q-104 0 -186.5 49t-130.5 132t-48 201z" />
+<glyph unicode="&#x25e6;" horiz-adv-x="725" d="M113 678q0 106 73 178t176 72q104 0 178 -73t74 -177q0 -105 -73.5 -178.5t-178.5 -73.5q-108 0 -178.5 75t-70.5 177zM188 678q0 -74 51.5 -125t122.5 -51q79 0 128 54.5t49 121.5q0 72 -51.5 123t-125.5 51q-71 0 -122.5 -51t-51.5 -123z" />
<glyph unicode="&#x25fc;" horiz-adv-x="1050" d="M0 0v1050h1050v-1050h-1050z" />
+<glyph unicode="&#x263a;" horiz-adv-x="2048" d="M385 518q0 164 84 316t236 236.5t319 84.5q168 0 321 -86.5t235.5 -237t82.5 -313.5q0 -132 -53 -252t-137 -203t-203 -132.5t-246 -49.5q-165 0 -315.5 83t-237 232.5t-86.5 321.5zM479 518q0 -135 68 -262.5t198.5 -205t278.5 -77.5q145 0 274 74t200 202.5t71 268.5 q0 133 -68 261.5t-200 206t-277 77.5q-136 0 -269 -72.5t-204.5 -204t-71.5 -268.5zM698 649q0 35 23.5 58.5t56.5 23.5q35 0 58.5 -23.5t23.5 -58.5q0 -33 -23.5 -56.5t-58.5 -23.5q-33 0 -56.5 23.5t-23.5 56.5zM729 313l64 35q75 -143 231 -143t231 143l64 -35 q-102 -194 -295 -194t-295 194zM1188 649q0 35 23.5 58.5t56.5 23.5q35 0 58.5 -23.5t23.5 -58.5q0 -33 -23.5 -56.5t-58.5 -23.5q-33 0 -56.5 23.5t-23.5 56.5z" />
+<glyph unicode="&#x263b;" horiz-adv-x="2048" d="M385 518q0 164 84 316t236 236.5t319 84.5q168 0 321 -86.5t235.5 -237t82.5 -313.5q0 -132 -53 -252t-137 -203t-203 -132.5t-246 -49.5q-165 0 -315.5 83t-237 232.5t-86.5 321.5zM698 649q0 -33 23.5 -56.5t56.5 -23.5q35 0 58.5 23.5t23.5 56.5q0 35 -23.5 58.5 t-58.5 23.5q-33 0 -56.5 -23.5t-23.5 -58.5zM729 313q102 -194 295 -194t295 194l-64 35q-75 -143 -231 -143t-231 143zM1188 649q0 -33 23.5 -56.5t56.5 -23.5q35 0 58.5 23.5t23.5 56.5q0 35 -23.5 58.5t-58.5 23.5q-33 0 -56.5 -23.5t-23.5 -58.5z" />
+<glyph unicode="&#x263c;" horiz-adv-x="1878" d="M16 666v67h336q8 107 41 186.5t103 163.5l-283 287l47 57l293 -282q100 69 179 100t169 39v338h78v-338q100 -6 180 -38t168 -103l291 284l51 -53l-287 -287q87 -113 115.5 -196t30.5 -158h334v-67h-334q-23 -197 -144 -353l285 -290l-57 -50l-283 283 q-100 -76 -172 -102q-67 -27 -178 -39v-338h-78v338q-110 14 -187 44.5t-157 92.5l-295 -279l-49 52l285 286q-68 86 -102 167t-44 188h-336zM426 698q0 -124 59.5 -243t183.5 -194t269 -75q131 0 254 68t190.5 189.5t67.5 254.5q0 111 -46 210.5t-119 166t-161 101 t-186 34.5q-122 0 -243.5 -59.5t-195 -184.5t-73.5 -268z" />
+<glyph unicode="&#x2640;" horiz-adv-x="1536" d="M244 983q0 134 68 258t192.5 195t263.5 71q132 0 254 -65.5t195 -189.5t73 -269q0 -214 -147 -364.5t-346 -157.5v-402h458v-59h-458v-381h-60v381h-461v59h461v402q-97 0 -218.5 62t-198 188t-76.5 272zM299 981q0 -195 137 -332t332 -137q132 0 238 63t168.5 169 t62.5 254q0 113 -65.5 220t-170 169.5t-233.5 62.5q-122 0 -232.5 -62t-173.5 -173t-63 -234z" />
+<glyph unicode="&#x2642;" horiz-adv-x="1536" d="M111 262q0 218 154 370t372 152q80 0 166 -26l360 772l-536 -266l-25 53l615 303l34 -16l164 -666l-57 -14l-141 579l-359 -768q148 -73 223.5 -199t75.5 -274q0 -135 -69.5 -259.5t-193 -194.5t-259.5 -70q-131 0 -251 63t-196.5 186.5t-76.5 274.5zM166 262 q0 -196 138.5 -333.5t330.5 -137.5q191 0 330 137t139 334q0 99 -43 193t-108 153t-149 91t-169 32q-117 0 -228 -59t-176 -172.5t-65 -237.5z" />
+<glyph unicode="&#x2660;" horiz-adv-x="1343" d="M186 494q0 87 45.5 157t133.5 142q114 93 175.5 167t89.5 136.5t44 134.5q28 -124 86.5 -207t183.5 -197q146 -133 179.5 -198t33.5 -131q0 -91 -62 -157.5t-155 -66.5q-156 0 -256 191q4 -213 87 -310.5t292 -117.5l6 -37h-793l9 37q186 0 284.5 104.5t98.5 307.5v16 q-90 -191 -262 -191q-90 0 -155 65t-65 155z" />
+<glyph unicode="&#x2663;" horiz-adv-x="1343" d="M55 553q0 116 73 194t167 82q65 -4 166 -53q-25 39 -42.5 75.5t-21.5 54.5t-4 52q0 116 79.5 194.5t197.5 78.5q116 0 196 -80q82 -76 82 -188q0 -91 -69 -187q79 40 103 46.5t58 6.5q102 0 175 -78t73 -194q0 -118 -78.5 -199t-197.5 -86q-78 4 -135.5 34t-108.5 79 q-46 61 -86 127q4 -160 48 -252t136 -154q68 -40 224 -71l8 -35h-848l8 35q123 26 183.5 50t112 86.5t80 139.5t28.5 154l-3 47q-61 -125 -147 -182.5t-178 -57.5q-122 0 -200.5 81.5t-78.5 199.5z" />
+<glyph unicode="&#x2665;" horiz-adv-x="1343" d="M127 969q0 108 73.5 185t180.5 77q99 0 175.5 -63t117.5 -189q38 128 112.5 190t169.5 62q111 0 185 -74t76 -176q0 -86 -39 -179t-174 -265q-155 -199 -240 -340q-59 -111 -90 -222q-32 125 -93.5 231t-218.5 312l-97 132q-72 95 -105 170t-33 149z" />
+<glyph unicode="&#x2666;" horiz-adv-x="1343" d="M213 604q77 88 192 238t169.5 233.5t97.5 159.5q98 -172 247.5 -368t210.5 -263q-54 -59 -208 -260t-250 -369q-52 93 -160 243t-175 232z" />
+<glyph unicode="&#x266a;" horiz-adv-x="1024" d="M37 186q0 113 80.5 180.5t193.5 67.5q76 0 174 -47v977h39q176 0 228 -14q123 -35 179 -128t56 -247v-103h-98v43q0 108 -73 164t-204 56h-26v-836q0 -123 -33 -190t-111.5 -106.5t-169.5 -39.5q-110 0 -172.5 61.5t-62.5 161.5z" />
+<glyph unicode="&#x266b;" horiz-adv-x="1536" d="M86 94q0 67 32 123t97.5 90.5t144.5 34.5q82 0 175 -45v975l794 248v-1108q0 -119 -28 -183t-106.5 -106.5t-172.5 -42.5q-111 0 -175.5 62.5t-64.5 160.5q0 103 76 172q76 74 201 74q47 0 81 -10t89 -33v723l-596 -185v-835q0 -125 -33 -191t-108.5 -106t-169.5 -41 q-111 0 -173.5 62.5t-62.5 160.5z" />
+<glyph unicode="&#xf001;" horiz-adv-x="1143" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM776 1315q0 53 26 77.5t85 24.5q61 0 87 -23.5t26 -78.5q0 -60 -27 -81.5t-86 -21.5q-63 0 -87 27 t-24 76zM801 0v1049h172v-1049h-172z" />
+<glyph unicode="&#xf002;" horiz-adv-x="1159" d="M43 905v144h154v102q0 190 71.5 279.5t251.5 89.5q113 0 203 -39l-47 -148q-29 15 -73 26t-79 11q-87 0 -121 -44.5t-34 -174.5v-102h233v-144h-233v-905h-172v905h-154zM809 0v1489h172v-1489h-172z" />
+<glyph unicode="&#xf6c3;" horiz-adv-x="555" d="M156 -258q0 55 26.5 85t91.5 30q66 0 95.5 -33t29.5 -98q0 -91 -35.5 -151t-72.5 -105h-105q29 38 55.5 79t26.5 82q-59 0 -85.5 26t-26.5 85z" />
+<glyph unicode="&#xfeff;" horiz-adv-x="0" />
+<glyph horiz-adv-x="555" d="M156 1296q0 62 22.5 120.5t85.5 135.5h105q-29 -39 -55.5 -79.5t-26.5 -81.5q59 0 85.5 -26t26.5 -85q0 -55 -26.5 -85t-91.5 -30q-66 0 -95.5 33t-29.5 98z" />
+<glyph horiz-adv-x="414" d="M27 1024l123 360h237l-213 -360h-147z" />
+<glyph horiz-adv-x="889" d="M84 413q0 228 87 334.5t273 106.5q187 0 274 -106.5t87 -332.5q0 -229 -87 -336.5t-274 -107.5q-186 0 -273 106.5t-87 335.5zM256 413q0 -164 45 -239.5t143 -75.5q99 0 144 75.5t45 241.5q0 160 -45 236t-144 76q-98 0 -143 -76t-45 -238z" />
+<glyph horiz-adv-x="889" d="M182 575v107q129 4 182.5 37.5t77.5 119.5h125v-850h-161v586h-224z" />
+<glyph horiz-adv-x="889" d="M106 696q106 162 326 162q148 0 230.5 -63.5t82.5 -180.5q0 -85 -38.5 -147t-122.5 -137t-260 -210h450v-131h-659v138q74 52 208.5 161t195 180t56.5 142q0 59 -44 89t-103 30q-108 0 -188 -111z" />
+<glyph horiz-adv-x="889" d="M84 112l133 74q27 -35 73 -60.5t103 -25.5q94 0 137 36t43 109q0 70 -48 100.5t-140 30.5h-90v127h78q86 0 136 32t50 91q0 54 -40 79.5t-105 25.5q-117 0 -187 -99l-133 76q40 56 82.5 85.5t105.5 47t142 17.5q160 0 233.5 -63.5t73.5 -151.5q0 -140 -139 -193 q67 -24 110 -78.5t43 -132.5q0 -133 -92 -200.5t-258 -67.5q-102 0 -186 39t-125 102z" />
+<glyph horiz-adv-x="889" d="M43 172v125l496 542h141v-542h127v-125h-127v-183h-160v183h-477zM221 297h299v325z" />
+<glyph horiz-adv-x="889" d="M90 114l135 76q23 -35 69 -62.5t107 -27.5q95 0 142 45t47 123t-56.5 110.5t-130.5 32.5q-97 0 -167 -43h-86l53 471h524v-131h-385l-23 -188q46 16 121 16q150 0 235 -68t85 -200q0 -135 -88 -216t-266 -81q-115 0 -195 43t-121 100z" />
+<glyph horiz-adv-x="889" d="M102 399q0 218 101 338.5t282 120.5q86 0 149.5 -23.5t119.5 -70.5l-99 -109q-45 35 -84 55.5t-86 20.5q-83 0 -135.5 -59.5t-66.5 -174.5q101 49 196 49q139 0 221 -66.5t82 -207.5q0 -143 -88 -222t-243 -79q-185 0 -267 108.5t-82 319.5zM276 374q3 -149 46 -212.5 t131 -63.5q163 0 163 170q0 149 -165 149q-86 0 -175 -43z" />
+<glyph horiz-adv-x="889" d="M88 708v131h688v-121l-360 -729h-180l362 719h-510z" />
+<glyph horiz-adv-x="889" d="M94 217q0 71 48 128.5t137 96.5q-86 41 -124 85t-38 103q0 109 82 168.5t241 59.5q158 0 240 -57.5t82 -168.5q0 -57 -39 -103t-129 -89q190 -67 190 -223q0 -123 -93 -184.5t-251 -61.5q-172 0 -259 63.5t-87 182.5zM258 217q0 -58 45 -91.5t137 -33.5t136.5 35.5 t44.5 89.5q0 59 -54.5 95t-126.5 64q-107 -40 -144.5 -78t-37.5 -81zM281 634q0 -34 32.5 -64t128.5 -67q154 43 154 127q0 47 -39 78t-117 31q-84 0 -121.5 -31t-37.5 -74z" />
+<glyph horiz-adv-x="889" d="M94 559q0 141 90 220t244 79q186 0 266 -106.5t80 -309.5q0 -226 -99.5 -348.5t-289.5 -122.5q-162 0 -274 96l98 111q88 -80 176 -80q181 0 209 231q-92 -45 -197 -45q-139 0 -221 66.5t-82 208.5zM258 563q0 -152 170 -152q47 0 93 14.5t79 36.5q0 269 -172 269 q-82 0 -126 -43t-44 -125z" />
+<glyph horiz-adv-x="889" d="M84 964q0 228 87 334.5t273 106.5q187 0 274 -106.5t87 -332.5q0 -229 -87 -336.5t-274 -107.5q-186 0 -273 106.5t-87 335.5zM256 964q0 -164 45 -239.5t143 -75.5q99 0 144 75.5t45 241.5q0 160 -45 236t-144 76q-98 0 -143 -76t-45 -238z" />
+<glyph horiz-adv-x="889" d="M182 1126v107q129 4 182.5 37.5t77.5 119.5h125v-850h-161v586h-224z" />
+<glyph horiz-adv-x="889" d="M106 1247q106 162 326 162q148 0 230.5 -63.5t82.5 -180.5q0 -85 -38.5 -147t-122.5 -137t-260 -210h450v-131h-659v138q74 52 208.5 161t195 180t56.5 142q0 59 -44 89t-103 30q-108 0 -188 -111z" />
+<glyph horiz-adv-x="889" d="M84 663l133 74q27 -35 73 -60.5t103 -25.5q94 0 137 36t43 109q0 70 -48 100.5t-140 30.5h-90v127h78q86 0 136 32t50 91q0 54 -40 79.5t-105 25.5q-117 0 -187 -99l-133 76q40 56 82.5 85.5t105.5 47t142 17.5q160 0 233.5 -63.5t73.5 -151.5q0 -140 -139 -193 q67 -24 110 -78.5t43 -132.5q0 -133 -92 -200.5t-258 -67.5q-102 0 -186 39t-125 102z" />
+<glyph horiz-adv-x="889" d="M43 723v125l496 542h141v-542h127v-125h-127v-183h-160v183h-477zM221 848h299v325z" />
+<glyph horiz-adv-x="889" d="M90 665l135 76q23 -35 69 -62.5t107 -27.5q95 0 142 45t47 123t-56.5 110.5t-130.5 32.5q-97 0 -167 -43h-86l53 471h524v-131h-385l-23 -188q46 16 121 16q150 0 235 -68t85 -200q0 -135 -88 -216t-266 -81q-115 0 -195 43t-121 100z" />
+<glyph horiz-adv-x="889" d="M102 950q0 218 101 338.5t282 120.5q86 0 149.5 -23.5t119.5 -70.5l-99 -109q-45 35 -84 55.5t-86 20.5q-83 0 -135.5 -59.5t-66.5 -174.5q101 49 196 49q139 0 221 -66.5t82 -207.5q0 -143 -88 -222t-243 -79q-185 0 -267 108.5t-82 319.5zM276 925q3 -149 46 -212.5 t131 -63.5q163 0 163 170q0 149 -165 149q-86 0 -175 -43z" />
+<glyph horiz-adv-x="889" d="M88 1259v131h688v-121l-360 -729h-180l362 719h-510z" />
+<glyph horiz-adv-x="889" d="M94 768q0 71 48 128.5t137 96.5q-86 41 -124 85t-38 103q0 109 82 168.5t241 59.5q158 0 240 -57.5t82 -168.5q0 -57 -39 -103t-129 -89q190 -67 190 -223q0 -123 -93 -184.5t-251 -61.5q-172 0 -259 63.5t-87 182.5zM258 768q0 -58 45 -91.5t137 -33.5t136.5 35.5 t44.5 89.5q0 59 -54.5 95t-126.5 64q-107 -40 -144.5 -78t-37.5 -81zM281 1185q0 -34 32.5 -64t128.5 -67q154 43 154 127q0 47 -39 78t-117 31q-84 0 -121.5 -31t-37.5 -74z" />
+<glyph horiz-adv-x="889" d="M94 1110q0 141 90 220t244 79q186 0 266 -106.5t80 -309.5q0 -226 -99.5 -348.5t-289.5 -122.5q-162 0 -274 96l98 111q88 -80 176 -80q181 0 209 231q-92 -45 -197 -45q-139 0 -221 66.5t-82 208.5zM258 1114q0 -152 170 -152q47 0 93 14.5t79 36.5q0 269 -172 269 q-82 0 -126 -43t-44 -125z" />
+<glyph d="M268 1905h236l178 -361h-141z" />
+<glyph d="M481 1544l178 361h236l-272 -361h-142z" />
+<glyph d="M209 1544l229 361h211l228 -361h-150l-184 238l-185 -238h-149z" />
+<glyph d="M209 1905h149l185 -238l184 238h150l-230 -361h-211z" />
+<glyph d="M475 1128l66 361h215l-160 -361h-121z" />
+<glyph d="M166 1556q6 125 67.5 194t161.5 69q56 0 96.5 -22.5t75.5 -48.5t66 -48.5t67 -22.5q88 0 97 129h121q-19 -262 -232 -262q-65 0 -105 22.5t-71 50.5t-58.5 50.5t-68.5 22.5q-51 0 -71.5 -36t-24.5 -98h-121z" />
+<glyph d="M238 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -25 -83.5t-84 -23.5q-63 0 -84.5 29t-21.5 78zM633 1651q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph d="M238 1591v140h610v-140h-610z" />
+<glyph d="M215 1804h127q14 -63 66.5 -94t130.5 -31q102 0 147 31t57 94h127q0 -123 -86.5 -202.5t-242.5 -79.5q-152 0 -239 81t-87 201z" />
+<glyph d="M352 1683q0 86 45 137.5t144 51.5q98 0 144 -51.5t46 -137.5t-46 -137t-144 -51q-101 0 -145 53.5t-44 134.5zM438 1683q0 -106 103 -106q104 0 104 106q0 107 -104 107q-103 0 -103 -107z" />
+<glyph d="M225 1544l178 361h236l-272 -361h-142zM573 1544l179 361h235l-272 -361h-142z" />
+<glyph d="M428 1659q0 59 24.5 87t90.5 28q65 0 90.5 -28t25.5 -87q0 -64 -26.5 -89.5t-89.5 -25.5q-70 0 -92.5 31t-22.5 84z" />
+<glyph d="M209 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM725 1397l123 274h235l-217 -274h-141z" />
+<glyph d="M2 1671h236l122 -274h-141zM209 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149z" />
+<glyph d="M209 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM659 1618q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41.5t-54 14.5q-21 0 -49.5 -8.5t-50.5 -24.5z" />
+<glyph d="M166 1507q6 105 67.5 163.5t161.5 58.5q47 0 87 -15.5t77 -35t71 -35t70 -15.5q88 0 97 88h121q-19 -221 -232 -221q-59 0 -98 16.5t-71 36t-62.5 35.5t-71.5 16q-51 0 -71.5 -24.5t-24.5 -67.5h-121zM209 1167l229 279h211l228 -279h-150l-184 162l-185 -162h-149z" />
+<glyph d="M215 1489h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM449 1438l122 274h236l-217 -274h-141z" />
+<glyph d="M215 1489h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM279 1712h235l123 -274h-141z" />
+<glyph d="M215 1489h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM348 1720q23 21 70 37.5t106 16.5q90 0 138.5 -38t48.5 -100q0 -137 -148 -155v-37h-98v112h24q74 0 74 56q0 55 -69 55q-56 0 -101 -33z " />
+<glyph d="M166 1548q6 105 67.5 163t161.5 58q47 0 87 -15t77 -34.5t71 -35t70 -15.5q88 0 97 88h121q-19 -221 -232 -221q-59 0 -98 16.5t-71 36t-62.5 35.5t-71.5 16q-51 0 -71.5 -24.5t-24.5 -67.5h-121zM215 1489h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5 h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202z" />
+<glyph d="M238 1458v139h610v-139h-610zM242 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM637 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29 t-21.5 78z" />
+<glyph d="M242 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM463 1401l123 311h235l-217 -311h-141zM637 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5 q-63 0 -84.5 29t-21.5 78z" />
+<glyph d="M209 1712h149l185 -172l184 172h150l-230 -289h-211zM242 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM637 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5 t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph d="M242 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM270 1712h236l123 -311h-142zM637 1274q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29 t-21.5 78z" />
+<glyph d="M209 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM725 1733l123 274h235l-217 -274h-141z" />
+<glyph d="M2 2007h236l122 -274h-141zM209 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149z" />
+<glyph d="M209 1503l229 279h211l228 -279h-150l-184 162l-185 -162h-149zM659 1954q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41.5t-54 14.5q-21 0 -49.5 -8.5t-50.5 -24.5z" />
+<glyph d="M166 1823q6 104 67.5 162.5t161.5 58.5q47 0 87 -15.5t77 -35t71 -34.5t70 -15q88 0 97 88h121q-19 -222 -232 -222q-59 0 -98 16.5t-71 36t-62.5 36t-71.5 16.5q-51 0 -71.5 -24.5t-24.5 -67.5h-121zM209 1503l229 258h211l228 -258h-150l-184 142l-185 -142h-149z" />
+<glyph d="M215 1784h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM449 1733l122 274h236l-217 -274h-141z" />
+<glyph d="M215 1784h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM279 2007h235l123 -274h-141z" />
+<glyph d="M215 1784h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202zM348 2015q23 21 70 37t106 16q90 0 138.5 -37.5t48.5 -99.5q0 -137 -148 -155v-37h-98v112h24q74 0 74 56q0 55 -69 55q-56 0 -101 -33z " />
+<glyph d="M166 1843q6 105 67.5 163t161.5 58q47 0 87 -15t77 -34.5t71 -35t70 -15.5q88 0 97 88h121q-19 -221 -232 -221q-59 0 -98 16.5t-71 36t-62.5 35.5t-71.5 16q-51 0 -71.5 -24.5t-24.5 -67.5h-121zM215 1784h127q14 -64 66.5 -94.5t130.5 -30.5q102 0 147 30.5t57 94.5 h127q0 -124 -86 -203.5t-243 -79.5q-152 0 -239 81t-87 202z" />
+<glyph d="M238 1794v139h610v-139h-610zM242 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM637 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29 t-21.5 78z" />
+<glyph d="M242 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM463 1737l123 311h235l-217 -311h-141zM637 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5 q-63 0 -84.5 29t-21.5 78z" />
+<glyph d="M209 2048h149l185 -172l184 172h150l-230 -289h-211zM242 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM637 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5 t-84.5 -23.5q-63 0 -84.5 29t-21.5 78z" />
+<glyph d="M242 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29t-21.5 78zM270 2048h236l123 -311h-142zM637 1610q0 53 23.5 79.5t82.5 26.5q62 0 85.5 -25.5t23.5 -80.5q0 -60 -24.5 -83.5t-84.5 -23.5q-63 0 -84.5 29 t-21.5 78z" />
+<glyph d="M360 1438q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -137 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph d="M360 1774q23 20 70 36.5t107 16.5q90 0 138 -38t48 -99q0 -138 -148 -156v-37h-98v113h25q73 0 73 55q0 27 -15 41t-54 14q-21 0 -49.5 -8t-50.5 -24z" />
+<glyph d="M215 1442h158q12 -74 56 -111t110 -37q88 0 125.5 37t48.5 111h157q0 -72 -40.5 -131.5t-114 -91t-174.5 -31.5q-97 0 -170.5 32t-114.5 92t-41 130z" />
+<glyph d="M215 1776h158q12 -74 56 -111t110 -37q88 0 125.5 37t48.5 111h157q0 -71 -39.5 -130.5t-113.5 -91.5t-176 -32q-98 0 -172 33t-114 93t-40 128z" />
+<hkern u1="&#x28;" u2="&#x458;" k="-123" />
+<hkern u1="&#x28;" u2="&#x3ca;" k="-82" />
+<hkern u1="&#x28;" u2="&#x390;" k="-102" />
<hkern u1="&#x28;" u2="j" k="-123" />
+<hkern u1="&#x2a;" u2="&#x2206;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1eb6;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1eb4;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1eb2;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1eb0;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1eae;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1eac;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1eaa;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1ea8;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1ea6;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1ea4;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1ea2;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1ea0;" k="164" />
+<hkern u1="&#x2a;" u2="&#x459;" k="195" />
+<hkern u1="&#x2a;" u2="&#x457;" k="-41" />
+<hkern u1="&#x2a;" u2="&#x44a;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x442;" k="-41" />
+<hkern u1="&#x2a;" u2="&#x43b;" k="195" />
+<hkern u1="&#x2a;" u2="&#x42a;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x422;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x41b;" k="205" />
+<hkern u1="&#x2a;" u2="&#x414;" k="123" />
+<hkern u1="&#x2a;" u2="&#x410;" k="164" />
+<hkern u1="&#x2a;" u2="&#x40b;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x409;" k="205" />
+<hkern u1="&#x2a;" u2="&#x408;" k="225" />
+<hkern u1="&#x2a;" u2="&#x402;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x3ca;" k="-102" />
+<hkern u1="&#x2a;" u2="&#x3c7;" k="-41" />
+<hkern u1="&#x2a;" u2="&#x3be;" k="-20" />
+<hkern u1="&#x2a;" u2="&#x3a4;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x39b;" k="164" />
+<hkern u1="&#x2a;" u2="&#x394;" k="164" />
+<hkern u1="&#x2a;" u2="&#x391;" k="164" />
+<hkern u1="&#x2a;" u2="&#x38f;" k="-225" />
+<hkern u1="&#x2a;" u2="&#x38e;" k="-225" />
+<hkern u1="&#x2a;" u2="&#x38c;" k="-225" />
+<hkern u1="&#x2a;" u2="&#x38a;" k="-225" />
+<hkern u1="&#x2a;" u2="&#x389;" k="-225" />
+<hkern u1="&#x2a;" u2="&#x388;" k="-225" />
+<hkern u1="&#x2a;" u2="&#x386;" k="-225" />
+<hkern u1="&#x2a;" u2="&#x21a;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x1fa;" k="164" />
+<hkern u1="&#x2a;" u2="&#x1cd;" k="164" />
+<hkern u1="&#x2a;" u2="&#x166;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x164;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x162;" k="-61" />
+<hkern u1="&#x2a;" u2="&#x134;" k="225" />
+<hkern u1="&#x2a;" u2="&#x104;" k="164" />
+<hkern u1="&#x2a;" u2="&#x102;" k="164" />
+<hkern u1="&#x2a;" u2="&#x100;" k="164" />
<hkern u1="&#x2a;" u2="&#xef;" k="-61" />
<hkern u1="&#x2a;" u2="&#xc5;" k="164" />
<hkern u1="&#x2a;" u2="&#xc4;" k="164" />
@@ -253,15 +966,55 @@
<hkern u1="&#x2a;" u2="T" k="-61" />
<hkern u1="&#x2a;" u2="J" k="225" />
<hkern u1="&#x2a;" u2="A" k="164" />
+<hkern u1="&#x2c;" u2="&#x42a;" k="205" />
+<hkern u1="&#x2e;" u2="&#x42a;" k="205" />
+<hkern u1="&#x3a;" u2="&#x42a;" k="143" />
+<hkern u1="&#x3b;" u2="&#x42a;" k="143" />
<hkern u1="A" u2="&#x3f;" k="82" />
<hkern u1="A" u2="&#x2a;" k="164" />
+<hkern u1="F" u2="&#x135;" k="-20" />
+<hkern u1="F" u2="&#x12b;" k="-41" />
+<hkern u1="F" u2="&#x129;" k="-82" />
<hkern u1="F" u2="&#xef;" k="-41" />
<hkern u1="F" u2="&#xee;" k="-20" />
+<hkern u1="K" u2="&#x135;" k="41" />
+<hkern u1="K" u2="&#x12d;" k="20" />
+<hkern u1="K" u2="&#x12b;" k="10" />
+<hkern u1="K" u2="&#x129;" k="-20" />
<hkern u1="K" u2="&#xef;" k="-10" />
<hkern u1="K" u2="&#xee;" k="-10" />
<hkern u1="L" u2="&#xd8;" k="20" />
<hkern u1="L" u2="&#x3f;" k="102" />
<hkern u1="L" u2="&#x2a;" k="287" />
+<hkern u1="T" u2="&#x1ef9;" k="82" />
+<hkern u1="T" u2="&#x1ee1;" k="123" />
+<hkern u1="T" u2="&#x1ed7;" k="174" />
+<hkern u1="T" u2="&#x1ed3;" k="143" />
+<hkern u1="T" u2="&#x1ec5;" k="164" />
+<hkern u1="T" u2="&#x1ec1;" k="143" />
+<hkern u1="T" u2="&#x1ebd;" k="102" />
+<hkern u1="T" u2="&#x1eb7;" k="143" />
+<hkern u1="T" u2="&#x1eb5;" k="143" />
+<hkern u1="T" u2="&#x1eb3;" k="143" />
+<hkern u1="T" u2="&#x1eb1;" k="143" />
+<hkern u1="T" u2="&#x1eaf;" k="143" />
+<hkern u1="T" u2="&#x1ead;" k="123" />
+<hkern u1="T" u2="&#x1eab;" k="123" />
+<hkern u1="T" u2="&#x1ea9;" k="143" />
+<hkern u1="T" u2="&#x1ea7;" k="143" />
+<hkern u1="T" u2="&#x1ea5;" k="143" />
+<hkern u1="T" u2="&#x1e9e;" k="41" />
+<hkern u1="T" u2="&#x1d6;" k="123" />
+<hkern u1="T" u2="&#x1d0;" k="41" />
+<hkern u1="T" u2="&#x161;" k="201" />
+<hkern u1="T" u2="&#x15d;" k="119" />
+<hkern u1="T" u2="&#x159;" k="123" />
+<hkern u1="T" u2="&#x135;" k="-61" />
+<hkern u1="T" u2="&#x12d;" k="-41" />
+<hkern u1="T" u2="&#x12b;" k="-82" />
+<hkern u1="T" u2="&#x129;" k="-143" />
+<hkern u1="T" u2="&#x103;" k="164" />
+<hkern u1="T" u2="&#x101;" k="164" />
<hkern u1="T" u2="&#xef;" k="-102" />
<hkern u1="T" u2="&#xee;" k="-61" />
<hkern u1="T" u2="&#xe4;" k="164" />
@@ -269,32 +1022,110 @@
<hkern u1="T" u2="&#xe2;" k="143" />
<hkern u1="T" u2="&#x3f;" k="20" />
<hkern u1="T" u2="&#x2a;" k="-61" />
+<hkern u1="V" u2="&#x1e9e;" k="20" />
+<hkern u1="V" u2="&#x135;" k="-31" />
+<hkern u1="V" u2="&#x12d;" k="-20" />
+<hkern u1="V" u2="&#x12b;" k="-41" />
+<hkern u1="V" u2="&#x129;" k="-82" />
+<hkern u1="V" u2="&#x127;" k="31" />
<hkern u1="V" u2="&#xef;" k="-61" />
<hkern u1="V" u2="&#xee;" k="-41" />
+<hkern u1="W" u2="&#x1e9e;" k="20" />
+<hkern u1="W" u2="&#x135;" k="-31" />
+<hkern u1="W" u2="&#x12d;" k="-20" />
+<hkern u1="W" u2="&#x12b;" k="-41" />
+<hkern u1="W" u2="&#x129;" k="-82" />
+<hkern u1="W" u2="&#x127;" k="31" />
<hkern u1="W" u2="&#xef;" k="-61" />
<hkern u1="W" u2="&#xee;" k="-41" />
+<hkern u1="X" u2="&#x1e9e;" k="41" />
+<hkern u1="X" u2="&#x12d;" k="-41" />
+<hkern u1="X" u2="&#x12b;" k="-20" />
+<hkern u1="X" u2="&#x129;" k="-82" />
<hkern u1="X" u2="&#xef;" k="-61" />
<hkern u1="X" u2="&#xee;" k="-41" />
+<hkern u1="Y" u2="&#x1ed3;" k="143" />
+<hkern u1="Y" u2="&#x1ebd;" k="143" />
+<hkern u1="Y" u2="&#x1ea7;" k="82" />
+<hkern u1="Y" u2="&#x1e9e;" k="41" />
+<hkern u1="Y" u2="&#x1d0;" k="41" />
+<hkern u1="Y" u2="&#x135;" k="-10" />
+<hkern u1="Y" u2="&#x12d;" k="-20" />
+<hkern u1="Y" u2="&#x12b;" k="-41" />
+<hkern u1="Y" u2="&#x129;" k="-82" />
<hkern u1="Y" u2="&#xef;" k="-61" />
<hkern u1="Y" u2="&#xee;" k="-51" />
+<hkern u1="[" u2="&#x458;" k="-123" />
+<hkern u1="[" u2="&#x3ca;" k="-82" />
+<hkern u1="[" u2="&#x390;" k="-82" />
<hkern u1="[" u2="j" k="-123" />
+<hkern u1="a" u2="&#x167;" k="-10" />
+<hkern u1="f" u2="&#x1eb5;" k="-20" />
+<hkern u1="f" u2="&#x1eb3;" k="-20" />
+<hkern u1="f" u2="&#x1eb1;" k="-20" />
+<hkern u1="f" u2="&#x1eaf;" k="-20" />
+<hkern u1="f" u2="&#x1eab;" k="-31" />
+<hkern u1="f" u2="&#x1ea7;" k="-61" />
+<hkern u1="f" u2="&#x1d0;" k="-164" />
+<hkern u1="f" u2="&#x159;" k="-41" />
+<hkern u1="f" u2="&#x135;" k="-123" />
+<hkern u1="f" u2="&#x12d;" k="-164" />
+<hkern u1="f" u2="&#x12b;" k="-123" />
+<hkern u1="f" u2="&#x129;" k="-225" />
+<hkern u1="f" u2="&#x127;" k="-61" />
<hkern u1="f" u2="&#xef;" k="-123" />
<hkern u1="f" u2="&#xee;" k="-102" />
<hkern u1="f" u2="&#xec;" k="-82" />
<hkern u1="f" u2="&#x3f;" k="-82" />
<hkern u1="f" u2="&#x2a;" k="-82" />
<hkern u1="f" u2="&#x21;" k="-61" />
+<hkern u1="j" u2="&#x1ef9;" k="-31" />
+<hkern u1="j" u2="&#x1ef7;" k="-31" />
+<hkern u1="j" u2="&#x1ef5;" k="-31" />
+<hkern u1="j" u2="&#x1ef3;" k="-31" />
+<hkern u1="j" u2="&#x177;" k="-31" />
<hkern u1="j" u2="&#xff;" k="-31" />
<hkern u1="j" u2="&#xfd;" k="-31" />
<hkern u1="j" u2="y" k="-31" />
+<hkern u1="&#x7b;" u2="&#x458;" k="-123" />
+<hkern u1="&#x7b;" u2="&#x3ca;" k="-82" />
+<hkern u1="&#x7b;" u2="&#x390;" k="-102" />
<hkern u1="&#x7b;" u2="j" k="-123" />
+<hkern u1="&#xa1;" u2="&#x1ef8;" k="113" />
+<hkern u1="&#xa1;" u2="&#x1ef6;" k="113" />
+<hkern u1="&#xa1;" u2="&#x1ef4;" k="113" />
+<hkern u1="&#xa1;" u2="&#x1ef2;" k="113" />
+<hkern u1="&#xa1;" u2="&#x1e84;" k="61" />
+<hkern u1="&#xa1;" u2="&#x1e82;" k="61" />
+<hkern u1="&#xa1;" u2="&#x1e80;" k="61" />
+<hkern u1="&#xa1;" u2="&#x21a;" k="143" />
<hkern u1="&#xa1;" u2="&#x178;" k="113" />
+<hkern u1="&#xa1;" u2="&#x176;" k="113" />
+<hkern u1="&#xa1;" u2="&#x174;" k="61" />
+<hkern u1="&#xa1;" u2="&#x166;" k="143" />
+<hkern u1="&#xa1;" u2="&#x164;" k="143" />
+<hkern u1="&#xa1;" u2="&#x162;" k="143" />
<hkern u1="&#xa1;" u2="&#xdd;" k="113" />
<hkern u1="&#xa1;" u2="Y" k="113" />
<hkern u1="&#xa1;" u2="W" k="61" />
<hkern u1="&#xa1;" u2="V" k="61" />
<hkern u1="&#xa1;" u2="T" k="143" />
+<hkern u1="&#xab;" u2="&#x386;" k="-266" />
+<hkern u1="&#xb5;" u2="&#x3c7;" k="20" />
+<hkern u1="&#xbf;" u2="&#x1ef8;" k="215" />
+<hkern u1="&#xbf;" u2="&#x1ef6;" k="215" />
+<hkern u1="&#xbf;" u2="&#x1ef4;" k="215" />
+<hkern u1="&#xbf;" u2="&#x1ef2;" k="215" />
+<hkern u1="&#xbf;" u2="&#x1e84;" k="123" />
+<hkern u1="&#xbf;" u2="&#x1e82;" k="123" />
+<hkern u1="&#xbf;" u2="&#x1e80;" k="123" />
+<hkern u1="&#xbf;" u2="&#x21a;" k="143" />
<hkern u1="&#xbf;" u2="&#x178;" k="215" />
+<hkern u1="&#xbf;" u2="&#x176;" k="215" />
+<hkern u1="&#xbf;" u2="&#x174;" k="123" />
+<hkern u1="&#xbf;" u2="&#x166;" k="143" />
+<hkern u1="&#xbf;" u2="&#x164;" k="143" />
+<hkern u1="&#xbf;" u2="&#x162;" k="143" />
<hkern u1="&#xbf;" u2="&#xdd;" k="215" />
<hkern u1="&#xbf;" u2="Y" k="215" />
<hkern u1="&#xbf;" u2="W" k="123" />
@@ -312,358 +1143,1729 @@
<hkern u1="&#xc4;" u2="&#x2a;" k="164" />
<hkern u1="&#xc5;" u2="&#x3f;" k="82" />
<hkern u1="&#xc5;" u2="&#x2a;" k="164" />
+<hkern u1="&#xdd;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#xdd;" u2="&#x1ebd;" k="143" />
+<hkern u1="&#xdd;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#xdd;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#xdd;" u2="&#x1d0;" k="41" />
+<hkern u1="&#xdd;" u2="&#x135;" k="-10" />
+<hkern u1="&#xdd;" u2="&#x12d;" k="-20" />
+<hkern u1="&#xdd;" u2="&#x12b;" k="-41" />
+<hkern u1="&#xdd;" u2="&#x129;" k="-82" />
<hkern u1="&#xdd;" u2="&#xef;" k="-61" />
<hkern u1="&#xdd;" u2="&#xee;" k="-51" />
+<hkern u1="&#xde;" u2="&#x1e84;" k="-10" />
+<hkern u1="&#xde;" u2="&#x1e82;" k="-10" />
+<hkern u1="&#xde;" u2="&#x1e80;" k="-10" />
+<hkern u1="&#xde;" u2="&#x21a;" k="20" />
+<hkern u1="&#xde;" u2="&#x174;" k="-10" />
+<hkern u1="&#xde;" u2="&#x166;" k="20" />
+<hkern u1="&#xde;" u2="&#x164;" k="20" />
+<hkern u1="&#xde;" u2="&#x162;" k="20" />
<hkern u1="&#xde;" u2="X" k="41" />
<hkern u1="&#xde;" u2="W" k="-10" />
<hkern u1="&#xde;" u2="V" k="-10" />
<hkern u1="&#xde;" u2="T" k="20" />
+<hkern u1="&#xe0;" u2="&#x167;" k="-10" />
+<hkern u1="&#xe1;" u2="&#x167;" k="-10" />
+<hkern u1="&#xe2;" u2="&#x167;" k="-10" />
+<hkern u1="&#xe3;" u2="&#x167;" k="-10" />
+<hkern u1="&#xe4;" u2="&#x167;" k="-10" />
+<hkern u1="&#xe5;" u2="&#x167;" k="-10" />
<hkern u1="&#xef;" u2="&#xef;" k="-184" />
<hkern u1="&#xef;" u2="&#x2a;" k="-61" />
+<hkern u1="&#x100;" u2="&#x3f;" k="82" />
+<hkern u1="&#x100;" u2="&#x2a;" k="164" />
+<hkern u1="&#x101;" u2="&#x167;" k="-10" />
+<hkern u1="&#x102;" u2="&#x3f;" k="82" />
+<hkern u1="&#x102;" u2="&#x2a;" k="164" />
+<hkern u1="&#x103;" u2="&#x167;" k="-10" />
+<hkern u1="&#x104;" u2="&#x3f;" k="82" />
+<hkern u1="&#x104;" u2="&#x2a;" k="164" />
+<hkern u1="&#x105;" u2="&#x167;" k="-10" />
+<hkern u1="&#x10f;" u2="&#x159;" k="-82" />
+<hkern u1="&#x10f;" u2="&#xe4;" k="20" />
+<hkern u1="&#x10f;" u2="&#x3f;" k="-82" />
+<hkern u1="&#x136;" u2="&#x135;" k="41" />
+<hkern u1="&#x136;" u2="&#x12d;" k="20" />
+<hkern u1="&#x136;" u2="&#x12b;" k="10" />
+<hkern u1="&#x136;" u2="&#x129;" k="-20" />
+<hkern u1="&#x136;" u2="&#xef;" k="-10" />
+<hkern u1="&#x136;" u2="&#xee;" k="-10" />
+<hkern u1="&#x139;" u2="&#xd8;" k="20" />
+<hkern u1="&#x139;" u2="&#x3f;" k="102" />
+<hkern u1="&#x139;" u2="&#x2a;" k="287" />
+<hkern u1="&#x13b;" u2="&#xd8;" k="20" />
+<hkern u1="&#x13b;" u2="&#x3f;" k="102" />
+<hkern u1="&#x13b;" u2="&#x2a;" k="287" />
+<hkern u1="&#x13d;" u2="&#xd8;" k="20" />
+<hkern u1="&#x13d;" u2="&#x3f;" k="102" />
+<hkern u1="&#x13d;" u2="&#x2a;" k="287" />
+<hkern u1="&#x13e;" u2="&#x159;" k="-82" />
+<hkern u1="&#x13e;" u2="&#xe4;" k="20" />
+<hkern u1="&#x13e;" u2="&#x3f;" k="-82" />
+<hkern u1="&#x141;" u2="&#xd8;" k="20" />
+<hkern u1="&#x141;" u2="&#x3f;" k="102" />
+<hkern u1="&#x141;" u2="&#x2a;" k="287" />
+<hkern u1="&#x142;" u2="&#x21b;" k="-20" />
+<hkern u1="&#x142;" u2="&#x167;" k="-20" />
+<hkern u1="&#x142;" u2="&#x165;" k="-20" />
+<hkern u1="&#x142;" u2="&#x163;" k="-20" />
+<hkern u1="&#x142;" u2="t" k="-20" />
+<hkern u1="&#x162;" u2="&#x1ef9;" k="82" />
+<hkern u1="&#x162;" u2="&#x1ee1;" k="123" />
+<hkern u1="&#x162;" u2="&#x1ed7;" k="174" />
+<hkern u1="&#x162;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x162;" u2="&#x1ec5;" k="164" />
+<hkern u1="&#x162;" u2="&#x1ec1;" k="143" />
+<hkern u1="&#x162;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x162;" u2="&#x1eb7;" k="143" />
+<hkern u1="&#x162;" u2="&#x1eb5;" k="143" />
+<hkern u1="&#x162;" u2="&#x1eb3;" k="143" />
+<hkern u1="&#x162;" u2="&#x1eb1;" k="143" />
+<hkern u1="&#x162;" u2="&#x1eaf;" k="143" />
+<hkern u1="&#x162;" u2="&#x1ead;" k="123" />
+<hkern u1="&#x162;" u2="&#x1eab;" k="123" />
+<hkern u1="&#x162;" u2="&#x1ea9;" k="143" />
+<hkern u1="&#x162;" u2="&#x1ea7;" k="143" />
+<hkern u1="&#x162;" u2="&#x1ea5;" k="143" />
+<hkern u1="&#x162;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x162;" u2="&#x1d6;" k="123" />
+<hkern u1="&#x162;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x162;" u2="&#x161;" k="201" />
+<hkern u1="&#x162;" u2="&#x15d;" k="119" />
+<hkern u1="&#x162;" u2="&#x159;" k="123" />
+<hkern u1="&#x162;" u2="&#x135;" k="-61" />
+<hkern u1="&#x162;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x162;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x162;" u2="&#x129;" k="-143" />
+<hkern u1="&#x162;" u2="&#x103;" k="164" />
+<hkern u1="&#x162;" u2="&#x101;" k="164" />
+<hkern u1="&#x162;" u2="&#xef;" k="-102" />
+<hkern u1="&#x162;" u2="&#xee;" k="-61" />
+<hkern u1="&#x162;" u2="&#xe4;" k="164" />
+<hkern u1="&#x162;" u2="&#xe3;" k="102" />
+<hkern u1="&#x162;" u2="&#xe2;" k="143" />
+<hkern u1="&#x162;" u2="&#x3f;" k="20" />
+<hkern u1="&#x162;" u2="&#x2a;" k="-61" />
+<hkern u1="&#x164;" u2="&#x1ef9;" k="82" />
+<hkern u1="&#x164;" u2="&#x1ee1;" k="123" />
+<hkern u1="&#x164;" u2="&#x1ed7;" k="174" />
+<hkern u1="&#x164;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x164;" u2="&#x1ec5;" k="164" />
+<hkern u1="&#x164;" u2="&#x1ec1;" k="143" />
+<hkern u1="&#x164;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x164;" u2="&#x1eb7;" k="143" />
+<hkern u1="&#x164;" u2="&#x1eb5;" k="143" />
+<hkern u1="&#x164;" u2="&#x1eb3;" k="143" />
+<hkern u1="&#x164;" u2="&#x1eb1;" k="143" />
+<hkern u1="&#x164;" u2="&#x1eaf;" k="143" />
+<hkern u1="&#x164;" u2="&#x1ead;" k="123" />
+<hkern u1="&#x164;" u2="&#x1eab;" k="123" />
+<hkern u1="&#x164;" u2="&#x1ea9;" k="143" />
+<hkern u1="&#x164;" u2="&#x1ea7;" k="143" />
+<hkern u1="&#x164;" u2="&#x1ea5;" k="143" />
+<hkern u1="&#x164;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x164;" u2="&#x1d6;" k="123" />
+<hkern u1="&#x164;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x164;" u2="&#x161;" k="201" />
+<hkern u1="&#x164;" u2="&#x15d;" k="119" />
+<hkern u1="&#x164;" u2="&#x159;" k="123" />
+<hkern u1="&#x164;" u2="&#x135;" k="-61" />
+<hkern u1="&#x164;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x164;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x164;" u2="&#x129;" k="-143" />
+<hkern u1="&#x164;" u2="&#x103;" k="164" />
+<hkern u1="&#x164;" u2="&#x101;" k="164" />
+<hkern u1="&#x164;" u2="&#xef;" k="-102" />
+<hkern u1="&#x164;" u2="&#xee;" k="-61" />
+<hkern u1="&#x164;" u2="&#xe4;" k="164" />
+<hkern u1="&#x164;" u2="&#xe3;" k="102" />
+<hkern u1="&#x164;" u2="&#xe2;" k="143" />
+<hkern u1="&#x164;" u2="&#x3f;" k="20" />
+<hkern u1="&#x164;" u2="&#x2a;" k="-61" />
+<hkern u1="&#x166;" u2="&#x1ef9;" k="82" />
+<hkern u1="&#x166;" u2="&#x1ee1;" k="123" />
+<hkern u1="&#x166;" u2="&#x1ed7;" k="174" />
+<hkern u1="&#x166;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x166;" u2="&#x1ec5;" k="164" />
+<hkern u1="&#x166;" u2="&#x1ec1;" k="143" />
+<hkern u1="&#x166;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x166;" u2="&#x1eb7;" k="143" />
+<hkern u1="&#x166;" u2="&#x1eb5;" k="143" />
+<hkern u1="&#x166;" u2="&#x1eb3;" k="143" />
+<hkern u1="&#x166;" u2="&#x1eb1;" k="143" />
+<hkern u1="&#x166;" u2="&#x1eaf;" k="143" />
+<hkern u1="&#x166;" u2="&#x1ead;" k="123" />
+<hkern u1="&#x166;" u2="&#x1eab;" k="123" />
+<hkern u1="&#x166;" u2="&#x1ea9;" k="143" />
+<hkern u1="&#x166;" u2="&#x1ea7;" k="143" />
+<hkern u1="&#x166;" u2="&#x1ea5;" k="143" />
+<hkern u1="&#x166;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x166;" u2="&#x1d6;" k="123" />
+<hkern u1="&#x166;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x166;" u2="&#x161;" k="201" />
+<hkern u1="&#x166;" u2="&#x15d;" k="119" />
+<hkern u1="&#x166;" u2="&#x159;" k="123" />
+<hkern u1="&#x166;" u2="&#x135;" k="-61" />
+<hkern u1="&#x166;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x166;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x166;" u2="&#x129;" k="-143" />
+<hkern u1="&#x166;" u2="&#x103;" k="164" />
+<hkern u1="&#x166;" u2="&#x101;" k="164" />
+<hkern u1="&#x166;" u2="&#xef;" k="-102" />
+<hkern u1="&#x166;" u2="&#xee;" k="-61" />
+<hkern u1="&#x166;" u2="&#xe4;" k="164" />
+<hkern u1="&#x166;" u2="&#xe3;" k="102" />
+<hkern u1="&#x166;" u2="&#xe2;" k="143" />
+<hkern u1="&#x166;" u2="&#x3f;" k="20" />
+<hkern u1="&#x166;" u2="&#x2a;" k="-61" />
+<hkern u1="&#x174;" u2="&#x1e9e;" k="20" />
+<hkern u1="&#x174;" u2="&#x135;" k="-31" />
+<hkern u1="&#x174;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x174;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x174;" u2="&#x129;" k="-82" />
+<hkern u1="&#x174;" u2="&#x127;" k="31" />
+<hkern u1="&#x174;" u2="&#xef;" k="-61" />
+<hkern u1="&#x174;" u2="&#xee;" k="-41" />
+<hkern u1="&#x176;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x176;" u2="&#x1ebd;" k="143" />
+<hkern u1="&#x176;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x176;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x176;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x176;" u2="&#x135;" k="-10" />
+<hkern u1="&#x176;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x176;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x176;" u2="&#x129;" k="-82" />
+<hkern u1="&#x176;" u2="&#xef;" k="-61" />
+<hkern u1="&#x176;" u2="&#xee;" k="-51" />
+<hkern u1="&#x178;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x178;" u2="&#x1ebd;" k="143" />
+<hkern u1="&#x178;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x178;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x178;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x178;" u2="&#x135;" k="-10" />
+<hkern u1="&#x178;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x178;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x178;" u2="&#x129;" k="-82" />
<hkern u1="&#x178;" u2="&#xef;" k="-61" />
<hkern u1="&#x178;" u2="&#xee;" k="-51" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="T" k="164" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="V" k="92" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="W" k="61" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="Y,Yacute,Ydieresis" k="133" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quotedbl,quotesingle" k="123" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="colon,semicolon" k="-41" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="41" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="41" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="t" k="31" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="z" k="-20" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="copyright,registered" k="41" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="trademark" k="205" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quoteleft,quotedblleft" k="184" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="quoteright,quotedblright" k="184" />
-<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="41" />
-<hkern g1="B" g2="J" k="61" />
-<hkern g1="B" g2="T" k="61" />
+<hkern u1="&#x1cd;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1cd;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1ce;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1fa;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1fa;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1fb;" u2="&#x167;" k="-10" />
+<hkern u1="&#x21a;" u2="&#x1ef9;" k="82" />
+<hkern u1="&#x21a;" u2="&#x1ee1;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1ed7;" k="174" />
+<hkern u1="&#x21a;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1ec5;" k="164" />
+<hkern u1="&#x21a;" u2="&#x1ec1;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1ebd;" k="102" />
+<hkern u1="&#x21a;" u2="&#x1eb7;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1eb5;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1eb3;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1eb1;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1eaf;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1ead;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1eab;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1ea9;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1ea7;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1ea5;" k="143" />
+<hkern u1="&#x21a;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x21a;" u2="&#x1d6;" k="123" />
+<hkern u1="&#x21a;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x21a;" u2="&#x161;" k="201" />
+<hkern u1="&#x21a;" u2="&#x15d;" k="119" />
+<hkern u1="&#x21a;" u2="&#x159;" k="123" />
+<hkern u1="&#x21a;" u2="&#x135;" k="-61" />
+<hkern u1="&#x21a;" u2="&#x12d;" k="-41" />
+<hkern u1="&#x21a;" u2="&#x12b;" k="-82" />
+<hkern u1="&#x21a;" u2="&#x129;" k="-143" />
+<hkern u1="&#x21a;" u2="&#x103;" k="164" />
+<hkern u1="&#x21a;" u2="&#x101;" k="164" />
+<hkern u1="&#x21a;" u2="&#xef;" k="-102" />
+<hkern u1="&#x21a;" u2="&#xee;" k="-61" />
+<hkern u1="&#x21a;" u2="&#xe4;" k="164" />
+<hkern u1="&#x21a;" u2="&#xe3;" k="102" />
+<hkern u1="&#x21a;" u2="&#xe2;" k="143" />
+<hkern u1="&#x21a;" u2="&#x3f;" k="20" />
+<hkern u1="&#x21a;" u2="&#x2a;" k="-61" />
+<hkern u1="&#x386;" u2="&#x3f;" k="82" />
+<hkern u1="&#x388;" u2="&#x390;" k="-143" />
+<hkern u1="&#x389;" u2="&#x390;" k="-61" />
+<hkern u1="&#x390;" u2="&#x3be;" k="31" />
+<hkern u1="&#x390;" u2="&#x3b8;" k="20" />
+<hkern u1="&#x390;" u2="&#x3b6;" k="20" />
+<hkern u1="&#x390;" u2="&#x3f;" k="-61" />
+<hkern u1="&#x391;" u2="&#x3f;" k="82" />
+<hkern u1="&#x393;" u2="&#x3cb;" k="164" />
+<hkern u1="&#x393;" u2="&#x3ca;" k="-106" />
+<hkern u1="&#x393;" u2="&#x3b4;" k="195" />
+<hkern u1="&#x393;" u2="&#x3b0;" k="102" />
+<hkern u1="&#x393;" u2="&#x3af;" k="127" />
+<hkern u1="&#x393;" u2="&#x3a6;" k="123" />
+<hkern u1="&#x393;" u2="&#x390;" k="-170" />
+<hkern u1="&#x394;" u2="&#x3f;" k="82" />
+<hkern u1="&#x395;" u2="&#x390;" k="-143" />
+<hkern u1="&#x396;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x396;" u2="&#x390;" k="-123" />
+<hkern u1="&#x397;" u2="&#x390;" k="-61" />
+<hkern u1="&#x39a;" u2="&#x3ca;" k="-41" />
+<hkern u1="&#x39a;" u2="&#x3a6;" k="61" />
+<hkern u1="&#x39a;" u2="&#x390;" k="-102" />
+<hkern u1="&#x39b;" u2="&#x3f;" k="82" />
+<hkern u1="&#x39c;" u2="&#x390;" k="-61" />
+<hkern u1="&#x39d;" u2="&#x390;" k="-61" />
+<hkern u1="&#x39e;" u2="&#x3ca;" k="-41" />
+<hkern u1="&#x39e;" u2="&#x390;" k="-123" />
+<hkern u1="&#x3a0;" u2="&#x390;" k="-61" />
+<hkern u1="&#x3a3;" u2="&#x3ca;" k="-41" />
+<hkern u1="&#x3a3;" u2="&#x390;" k="-123" />
+<hkern u1="&#x3a4;" u2="&#x3cb;" k="143" />
+<hkern u1="&#x3a4;" u2="&#x3ca;" k="-123" />
+<hkern u1="&#x3a4;" u2="&#x3b4;" k="164" />
+<hkern u1="&#x3a4;" u2="&#x3b0;" k="82" />
+<hkern u1="&#x3a4;" u2="&#x3af;" k="82" />
+<hkern u1="&#x3a4;" u2="&#x390;" k="-205" />
+<hkern u1="&#x3a4;" u2="&#x3f;" k="20" />
+<hkern u1="&#x3a4;" u2="&#x2a;" k="61" />
+<hkern u1="&#x3a7;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x3a7;" u2="&#x390;" k="-133" />
+<hkern u1="&#x3a8;" u2="&#x3ca;" k="-20" />
+<hkern u1="&#x3a8;" u2="&#x390;" k="-102" />
+<hkern u1="&#x3b1;" u2="&#x3c4;" k="31" />
+<hkern u1="&#x3b1;" u2="&#x3c0;" k="31" />
+<hkern u1="&#x3b2;" u2="&#x3c4;" k="61" />
+<hkern u1="&#x3b6;" u2="&#x3ca;" k="-61" />
+<hkern u1="&#x3b6;" u2="&#x390;" k="-164" />
+<hkern u1="&#x3bb;" u2="&#x3f;" k="164" />
+<hkern u1="&#x3bb;" u2="&#x2a;" k="164" />
+<hkern u1="&#x3bd;" u2="&#x3c4;" k="-20" />
+<hkern u1="&#x3be;" u2="&#x390;" k="-82" />
+<hkern u1="&#x3be;" u2="&#x2a;" k="-20" />
+<hkern u1="&#x3c7;" u2="&#x3f;" k="143" />
+<hkern u1="&#x3c7;" u2="&#x2a;" k="41" />
+<hkern u1="&#x3c9;" u2="&#x3f;" k="82" />
+<hkern u1="&#x3ca;" u2="&#x3ca;" k="-82" />
+<hkern u1="&#x3ca;" u2="&#x3f;" k="20" />
+<hkern u1="&#x3ce;" u2="&#x3f;" k="82" />
+<hkern u1="&#x403;" u2="&#x45e;" k="287" />
+<hkern u1="&#x403;" u2="&#x458;" k="82" />
+<hkern u1="&#x403;" u2="&#x457;" k="-143" />
+<hkern u1="&#x403;" u2="&#x456;" k="82" />
+<hkern u1="&#x403;" u2="&#x451;" k="307" />
+<hkern u1="&#x403;" u2="&#x424;" k="102" />
+<hkern u1="&#x409;" u2="&#x42a;" k="82" />
+<hkern u1="&#x40a;" u2="&#x42a;" k="82" />
+<hkern u1="&#x40c;" u2="&#x457;" k="-10" />
+<hkern u1="&#x40c;" u2="&#x456;" k="41" />
+<hkern u1="&#x40e;" u2="&#x457;" k="-102" />
+<hkern u1="&#x410;" u2="&#x42a;" k="123" />
+<hkern u1="&#x410;" u2="&#x3f;" k="82" />
+<hkern u1="&#x410;" u2="&#x2a;" k="164" />
+<hkern u1="&#x413;" u2="&#x45e;" k="287" />
+<hkern u1="&#x413;" u2="&#x458;" k="82" />
+<hkern u1="&#x413;" u2="&#x457;" k="-143" />
+<hkern u1="&#x413;" u2="&#x456;" k="82" />
+<hkern u1="&#x413;" u2="&#x451;" k="307" />
+<hkern u1="&#x413;" u2="&#x424;" k="102" />
+<hkern u1="&#x414;" u2="&#x458;" k="-164" />
+<hkern u1="&#x414;" u2="&#x42d;" k="-20" />
+<hkern u1="&#x416;" u2="&#x457;" k="-10" />
+<hkern u1="&#x416;" u2="&#x456;" k="41" />
+<hkern u1="&#x41a;" u2="&#x457;" k="-10" />
+<hkern u1="&#x41a;" u2="&#x456;" k="41" />
+<hkern u1="&#x422;" u2="&#x458;" k="41" />
+<hkern u1="&#x422;" u2="&#x457;" k="-123" />
+<hkern u1="&#x422;" u2="&#x456;" k="41" />
+<hkern u1="&#x422;" u2="&#x451;" k="205" />
+<hkern u1="&#x422;" u2="&#x424;" k="82" />
+<hkern u1="&#x422;" u2="&#x2a;" k="-61" />
+<hkern u1="&#x423;" u2="&#x457;" k="-102" />
+<hkern u1="&#x424;" u2="&#x422;" k="82" />
+<hkern u1="&#x425;" u2="&#x457;" k="-61" />
+<hkern u1="&#x426;" u2="&#x458;" k="-164" />
+<hkern u1="&#x429;" u2="&#x458;" k="-164" />
+<hkern u1="&#x42a;" u2="&#x42a;" k="82" />
+<hkern u1="&#x42c;" u2="&#x42a;" k="82" />
+<hkern u1="&#x434;" u2="&#x458;" k="-20" />
+<hkern u1="&#x442;" u2="&#x2a;" k="-41" />
+<hkern u1="&#x446;" u2="&#x458;" k="-20" />
+<hkern u1="&#x449;" u2="&#x458;" k="-20" />
+<hkern u1="&#x456;" u2="&#x457;" k="-20" />
+<hkern u1="&#x457;" u2="&#x45b;" k="-113" />
+<hkern u1="&#x457;" u2="&#x452;" k="-113" />
+<hkern u1="&#x457;" u2="&#x3f;" k="-41" />
+<hkern u1="&#x457;" u2="&#x2a;" k="-41" />
+<hkern u1="&#x490;" u2="&#x491;" k="307" />
+<hkern u1="&#x490;" u2="&#x45f;" k="307" />
+<hkern u1="&#x490;" u2="&#x45e;" k="82" />
+<hkern u1="&#x490;" u2="&#x45d;" k="307" />
+<hkern u1="&#x490;" u2="&#x45c;" k="307" />
+<hkern u1="&#x490;" u2="&#x45a;" k="307" />
+<hkern u1="&#x490;" u2="&#x458;" k="82" />
+<hkern u1="&#x490;" u2="&#x457;" k="-143" />
+<hkern u1="&#x490;" u2="&#x456;" k="82" />
+<hkern u1="&#x490;" u2="&#x453;" k="307" />
+<hkern u1="&#x490;" u2="&#x451;" k="307" />
+<hkern u1="&#x490;" u2="&#x450;" k="266" />
+<hkern u1="&#x490;" u2="&#x44e;" k="307" />
+<hkern u1="&#x490;" u2="&#x44c;" k="307" />
+<hkern u1="&#x490;" u2="&#x44b;" k="307" />
+<hkern u1="&#x490;" u2="&#x449;" k="307" />
+<hkern u1="&#x490;" u2="&#x448;" k="307" />
+<hkern u1="&#x490;" u2="&#x446;" k="307" />
+<hkern u1="&#x490;" u2="&#x440;" k="307" />
+<hkern u1="&#x490;" u2="&#x43f;" k="307" />
+<hkern u1="&#x490;" u2="&#x43d;" k="307" />
+<hkern u1="&#x490;" u2="&#x43c;" k="307" />
+<hkern u1="&#x490;" u2="&#x43a;" k="307" />
+<hkern u1="&#x490;" u2="&#x439;" k="307" />
+<hkern u1="&#x490;" u2="&#x438;" k="307" />
+<hkern u1="&#x490;" u2="&#x433;" k="307" />
+<hkern u1="&#x490;" u2="&#x432;" k="307" />
+<hkern u1="&#x490;" u2="&#x42d;" k="20" />
+<hkern u1="&#x490;" u2="&#x424;" k="102" />
+<hkern u1="&#x490;" u2="&#x417;" k="20" />
+<hkern u1="&#x491;" u2="&#x45b;" k="-51" />
+<hkern u1="&#x491;" u2="&#x457;" k="-164" />
+<hkern u1="&#x491;" u2="&#x452;" k="-51" />
+<hkern u1="&#x1e80;" u2="&#x1e9e;" k="20" />
+<hkern u1="&#x1e80;" u2="&#x135;" k="-31" />
+<hkern u1="&#x1e80;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x1e80;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x1e80;" u2="&#x129;" k="-82" />
+<hkern u1="&#x1e80;" u2="&#x127;" k="31" />
+<hkern u1="&#x1e80;" u2="&#xef;" k="-61" />
+<hkern u1="&#x1e80;" u2="&#xee;" k="-41" />
+<hkern u1="&#x1e82;" u2="&#x1e9e;" k="20" />
+<hkern u1="&#x1e82;" u2="&#x135;" k="-31" />
+<hkern u1="&#x1e82;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x1e82;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x1e82;" u2="&#x129;" k="-82" />
+<hkern u1="&#x1e82;" u2="&#x127;" k="31" />
+<hkern u1="&#x1e82;" u2="&#xef;" k="-61" />
+<hkern u1="&#x1e82;" u2="&#xee;" k="-41" />
+<hkern u1="&#x1e84;" u2="&#x1e9e;" k="20" />
+<hkern u1="&#x1e84;" u2="&#x135;" k="-31" />
+<hkern u1="&#x1e84;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x1e84;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x1e84;" u2="&#x129;" k="-82" />
+<hkern u1="&#x1e84;" u2="&#x127;" k="31" />
+<hkern u1="&#x1e84;" u2="&#xef;" k="-61" />
+<hkern u1="&#x1e84;" u2="&#xee;" k="-41" />
+<hkern u1="&#x1e9e;" u2="&#x2026;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#x201e;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#x201a;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#x1ef8;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x1ef6;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x1ef4;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x1ef2;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x1eb6;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eb4;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eb2;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eb0;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eae;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eac;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1eaa;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea8;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea6;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea4;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea2;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1ea0;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1e9e;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#x1e84;" k="31" />
+<hkern u1="&#x1e9e;" u2="&#x1e82;" k="31" />
+<hkern u1="&#x1e9e;" u2="&#x1e80;" k="31" />
+<hkern u1="&#x1e9e;" u2="&#x21a;" k="164" />
+<hkern u1="&#x1e9e;" u2="&#x1fc;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#x1fa;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x1cd;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x178;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x176;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#x174;" k="31" />
+<hkern u1="&#x1e9e;" u2="&#x166;" k="164" />
+<hkern u1="&#x1e9e;" u2="&#x164;" k="164" />
+<hkern u1="&#x1e9e;" u2="&#x162;" k="164" />
+<hkern u1="&#x1e9e;" u2="&#x104;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x102;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x100;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xdd;" k="102" />
+<hkern u1="&#x1e9e;" u2="&#xc6;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#xc5;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc4;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc3;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc2;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc1;" k="41" />
+<hkern u1="&#x1e9e;" u2="&#xc0;" k="41" />
+<hkern u1="&#x1e9e;" u2="Y" k="102" />
+<hkern u1="&#x1e9e;" u2="X" k="20" />
+<hkern u1="&#x1e9e;" u2="W" k="31" />
+<hkern u1="&#x1e9e;" u2="V" k="31" />
+<hkern u1="&#x1e9e;" u2="T" k="164" />
+<hkern u1="&#x1e9e;" u2="A" k="41" />
+<hkern u1="&#x1e9e;" u2="&#x2e;" k="61" />
+<hkern u1="&#x1e9e;" u2="&#x2c;" k="61" />
+<hkern u1="&#x1ea0;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1ea0;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1ea1;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1ea2;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1ea2;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1ea3;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1ea4;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1ea4;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1ea5;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1ea6;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1ea6;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1ea7;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1ea8;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1ea8;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1ea9;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1eaa;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1eaa;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1eab;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1eac;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1eac;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1ead;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1eae;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1eae;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1eaf;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1eb0;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1eb0;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1eb1;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1eb2;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1eb2;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1eb3;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1eb4;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1eb4;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1eb5;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1eb6;" u2="&#x3f;" k="82" />
+<hkern u1="&#x1eb6;" u2="&#x2a;" k="164" />
+<hkern u1="&#x1eb7;" u2="&#x167;" k="-10" />
+<hkern u1="&#x1ecb;" u2="j" k="-61" />
+<hkern u1="&#x1ef2;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x1ef2;" u2="&#x1ebd;" k="143" />
+<hkern u1="&#x1ef2;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x1ef2;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x1ef2;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x1ef2;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1ef2;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x1ef2;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x1ef2;" u2="&#x129;" k="-82" />
+<hkern u1="&#x1ef2;" u2="&#xef;" k="-61" />
+<hkern u1="&#x1ef2;" u2="&#xee;" k="-51" />
+<hkern u1="&#x1ef4;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x1ef4;" u2="&#x1ebd;" k="143" />
+<hkern u1="&#x1ef4;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x1ef4;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x1ef4;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x1ef4;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1ef4;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x1ef4;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x1ef4;" u2="&#x129;" k="-82" />
+<hkern u1="&#x1ef4;" u2="&#xef;" k="-61" />
+<hkern u1="&#x1ef4;" u2="&#xee;" k="-51" />
+<hkern u1="&#x1ef6;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x1ef6;" u2="&#x1ebd;" k="143" />
+<hkern u1="&#x1ef6;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x1ef6;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x1ef6;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x1ef6;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1ef6;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x1ef6;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x1ef6;" u2="&#x129;" k="-82" />
+<hkern u1="&#x1ef6;" u2="&#xef;" k="-61" />
+<hkern u1="&#x1ef6;" u2="&#xee;" k="-51" />
+<hkern u1="&#x1ef8;" u2="&#x1ed3;" k="143" />
+<hkern u1="&#x1ef8;" u2="&#x1ebd;" k="143" />
+<hkern u1="&#x1ef8;" u2="&#x1ea7;" k="82" />
+<hkern u1="&#x1ef8;" u2="&#x1e9e;" k="41" />
+<hkern u1="&#x1ef8;" u2="&#x1d0;" k="41" />
+<hkern u1="&#x1ef8;" u2="&#x135;" k="-10" />
+<hkern u1="&#x1ef8;" u2="&#x12d;" k="-20" />
+<hkern u1="&#x1ef8;" u2="&#x12b;" k="-41" />
+<hkern u1="&#x1ef8;" u2="&#x129;" k="-82" />
+<hkern u1="&#x1ef8;" u2="&#xef;" k="-61" />
+<hkern u1="&#x1ef8;" u2="&#xee;" k="-51" />
+<hkern u1="&#x2018;" u2="&#x3ca;" k="-82" />
+<hkern u1="&#x2018;" u2="&#x390;" k="-102" />
+<hkern u1="&#x2018;" u2="&#x38e;" k="-246" />
+<hkern u1="&#x2018;" u2="&#x386;" k="-82" />
+<hkern u1="&#x2019;" u2="&#x3ca;" k="-82" />
+<hkern u1="&#x2019;" u2="&#x390;" k="-123" />
+<hkern u1="&#x2019;" u2="&#x38e;" k="-225" />
+<hkern u1="&#x2019;" u2="&#x386;" k="-123" />
+<hkern u1="&#x201a;" u2="&#x42a;" k="205" />
+<hkern u1="&#x201b;" u2="&#x2206;" k="184" />
+<hkern u1="&#x201b;" u2="&#x2026;" k="164" />
+<hkern u1="&#x201b;" u2="&#x201e;" k="164" />
+<hkern u1="&#x201b;" u2="&#x201b;" k="123" />
+<hkern u1="&#x201b;" u2="&#x201a;" k="164" />
+<hkern u1="&#x201b;" u2="&#x1ee3;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ee1;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1edf;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1edd;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1edb;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ed9;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ed7;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ed5;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ed3;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ed1;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ecf;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ecd;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ec7;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ec5;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ec3;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ec1;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ebf;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ebd;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1ebb;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1eb9;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1eb6;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eb4;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eb2;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eb0;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eae;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eac;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1eaa;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea8;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea6;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea4;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea2;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1ea0;" k="184" />
+<hkern u1="&#x201b;" u2="&#x459;" k="164" />
+<hkern u1="&#x201b;" u2="&#x43b;" k="164" />
+<hkern u1="&#x201b;" u2="&#x42a;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x41b;" k="225" />
+<hkern u1="&#x201b;" u2="&#x414;" k="184" />
+<hkern u1="&#x201b;" u2="&#x410;" k="184" />
+<hkern u1="&#x201b;" u2="&#x40b;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x409;" k="225" />
+<hkern u1="&#x201b;" u2="&#x408;" k="193" />
+<hkern u1="&#x201b;" u2="&#x402;" k="-41" />
+<hkern u1="&#x201b;" u2="&#x3ce;" k="102" />
+<hkern u1="&#x201b;" u2="&#x3cc;" k="82" />
+<hkern u1="&#x201b;" u2="&#x3ca;" k="-82" />
+<hkern u1="&#x201b;" u2="&#x3c9;" k="102" />
+<hkern u1="&#x201b;" u2="&#x3c6;" k="82" />
+<hkern u1="&#x201b;" u2="&#x3c3;" k="82" />
+<hkern u1="&#x201b;" u2="&#x3c2;" k="82" />
+<hkern u1="&#x201b;" u2="&#x3c1;" k="61" />
+<hkern u1="&#x201b;" u2="&#x3bf;" k="82" />
+<hkern u1="&#x201b;" u2="&#x3b4;" k="82" />
+<hkern u1="&#x201b;" u2="&#x3b1;" k="82" />
+<hkern u1="&#x201b;" u2="&#x3ac;" k="82" />
+<hkern u1="&#x201b;" u2="&#x3a4;" k="-61" />
+<hkern u1="&#x201b;" u2="&#x39b;" k="184" />
+<hkern u1="&#x201b;" u2="&#x394;" k="184" />
+<hkern u1="&#x201b;" u2="&#x391;" k="184" />
+<hkern u1="&#x201b;" u2="&#x390;" k="-123" />
+<hkern u1="&#x201b;" u2="&#x38f;" k="-184" />
+<hkern u1="&#x201b;" u2="&#x38e;" k="-225" />
+<hkern u1="&#x201b;" u2="&#x38c;" k="-184" />
+<hkern u1="&#x201b;" u2="&#x38a;" k="-184" />
+<hkern u1="&#x201b;" u2="&#x389;" k="-184" />
+<hkern u1="&#x201b;" u2="&#x388;" k="-184" />
+<hkern u1="&#x201b;" u2="&#x386;" k="-123" />
+<hkern u1="&#x201b;" u2="&#x21a;" k="-61" />
+<hkern u1="&#x201b;" u2="&#x1ff;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1fc;" k="174" />
+<hkern u1="&#x201b;" u2="&#x1fa;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1d2;" k="82" />
+<hkern u1="&#x201b;" u2="&#x1cd;" k="184" />
+<hkern u1="&#x201b;" u2="&#x1a1;" k="82" />
+<hkern u1="&#x201b;" u2="&#x166;" k="-61" />
+<hkern u1="&#x201b;" u2="&#x164;" k="-61" />
+<hkern u1="&#x201b;" u2="&#x162;" k="-61" />
+<hkern u1="&#x201b;" u2="&#x153;" k="82" />
+<hkern u1="&#x201b;" u2="&#x151;" k="82" />
+<hkern u1="&#x201b;" u2="&#x14f;" k="82" />
+<hkern u1="&#x201b;" u2="&#x14d;" k="82" />
+<hkern u1="&#x201b;" u2="&#x134;" k="193" />
+<hkern u1="&#x201b;" u2="&#x123;" k="82" />
+<hkern u1="&#x201b;" u2="&#x121;" k="82" />
+<hkern u1="&#x201b;" u2="&#x11f;" k="82" />
+<hkern u1="&#x201b;" u2="&#x11d;" k="82" />
+<hkern u1="&#x201b;" u2="&#x11b;" k="82" />
+<hkern u1="&#x201b;" u2="&#x119;" k="82" />
+<hkern u1="&#x201b;" u2="&#x117;" k="82" />
+<hkern u1="&#x201b;" u2="&#x115;" k="82" />
+<hkern u1="&#x201b;" u2="&#x113;" k="82" />
+<hkern u1="&#x201b;" u2="&#x111;" k="82" />
+<hkern u1="&#x201b;" u2="&#x10f;" k="82" />
+<hkern u1="&#x201b;" u2="&#x10d;" k="82" />
+<hkern u1="&#x201b;" u2="&#x10b;" k="82" />
+<hkern u1="&#x201b;" u2="&#x109;" k="82" />
+<hkern u1="&#x201b;" u2="&#x107;" k="82" />
+<hkern u1="&#x201b;" u2="&#x104;" k="184" />
+<hkern u1="&#x201b;" u2="&#x102;" k="184" />
+<hkern u1="&#x201b;" u2="&#x100;" k="184" />
+<hkern u1="&#x201b;" u2="&#xf8;" k="82" />
+<hkern u1="&#x201b;" u2="&#xf6;" k="82" />
+<hkern u1="&#x201b;" u2="&#xf5;" k="82" />
+<hkern u1="&#x201b;" u2="&#xf4;" k="82" />
+<hkern u1="&#x201b;" u2="&#xf3;" k="82" />
+<hkern u1="&#x201b;" u2="&#xf2;" k="82" />
+<hkern u1="&#x201b;" u2="&#xf0;" k="82" />
+<hkern u1="&#x201b;" u2="&#xeb;" k="82" />
+<hkern u1="&#x201b;" u2="&#xea;" k="82" />
+<hkern u1="&#x201b;" u2="&#xe9;" k="82" />
+<hkern u1="&#x201b;" u2="&#xe8;" k="82" />
+<hkern u1="&#x201b;" u2="&#xe7;" k="82" />
+<hkern u1="&#x201b;" u2="&#xc6;" k="174" />
+<hkern u1="&#x201b;" u2="&#xc5;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc4;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc3;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc2;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc1;" k="184" />
+<hkern u1="&#x201b;" u2="&#xc0;" k="184" />
+<hkern u1="&#x201b;" u2="q" k="82" />
+<hkern u1="&#x201b;" u2="o" k="82" />
+<hkern u1="&#x201b;" u2="g" k="82" />
+<hkern u1="&#x201b;" u2="e" k="82" />
+<hkern u1="&#x201b;" u2="d" k="82" />
+<hkern u1="&#x201b;" u2="c" k="82" />
+<hkern u1="&#x201b;" u2="T" k="-61" />
+<hkern u1="&#x201b;" u2="J" k="193" />
+<hkern u1="&#x201b;" u2="A" k="184" />
+<hkern u1="&#x201b;" u2="&#x2e;" k="164" />
+<hkern u1="&#x201b;" u2="&#x2c;" k="164" />
+<hkern u1="&#x201c;" u2="&#x3ca;" k="-82" />
+<hkern u1="&#x201c;" u2="&#x390;" k="-102" />
+<hkern u1="&#x201c;" u2="&#x38e;" k="-246" />
+<hkern u1="&#x201c;" u2="&#x386;" k="-82" />
+<hkern u1="&#x201d;" u2="&#x3ca;" k="-82" />
+<hkern u1="&#x201d;" u2="&#x390;" k="-123" />
+<hkern u1="&#x201d;" u2="&#x38e;" k="-225" />
+<hkern u1="&#x201d;" u2="&#x386;" k="-123" />
+<hkern u1="&#x201e;" u2="&#x42a;" k="205" />
+<hkern u1="&#x2026;" u2="&#x42a;" k="205" />
+<hkern u1="&#x2039;" u2="&#x386;" k="-266" />
+<hkern u1="&#x207f;" u2="&#x1e85;" k="14" />
+<hkern u1="&#x207f;" u2="&#x1e83;" k="14" />
+<hkern u1="&#x207f;" u2="&#x1e81;" k="14" />
+<hkern u1="&#x207f;" u2="&#x175;" k="14" />
+<hkern u1="&#x207f;" u2="w" k="14" />
+<hkern u1="&#x207f;" u2="v" k="14" />
+<hkern u1="&#x2206;" u2="&#x3f;" k="82" />
+<hkern g1="f_f" u2="&#x1eb5;" k="-20" />
+<hkern g1="f_f" u2="&#x1eb3;" k="-20" />
+<hkern g1="f_f" u2="&#x1eb1;" k="-20" />
+<hkern g1="f_f" u2="&#x1eaf;" k="-20" />
+<hkern g1="f_f" u2="&#x1eab;" k="-31" />
+<hkern g1="f_f" u2="&#x1ea7;" k="-61" />
+<hkern g1="f_f" u2="&#x1d0;" k="-164" />
+<hkern g1="f_f" u2="&#x159;" k="-41" />
+<hkern g1="f_f" u2="&#x135;" k="-123" />
+<hkern g1="f_f" u2="&#x12d;" k="-164" />
+<hkern g1="f_f" u2="&#x12b;" k="-123" />
+<hkern g1="f_f" u2="&#x129;" k="-225" />
+<hkern g1="f_f" u2="&#x127;" k="-61" />
+<hkern g1="f_f" u2="&#xef;" k="-123" />
+<hkern g1="f_f" u2="&#xee;" k="-102" />
+<hkern g1="f_f" u2="&#xec;" k="-82" />
+<hkern g1="f_f" u2="&#x3f;" k="-82" />
+<hkern g1="f_f" u2="&#x2a;" k="-82" />
+<hkern g1="f_f" u2="&#x21;" k="-61" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="164" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="V" k="92" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="61" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="133" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quotedbl,quotesingle" k="123" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="colon,semicolon" k="-41" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="41" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="41" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="20" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="31" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="z,zacute,zdotaccent,zcaron" k="-20" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="copyright,registered" k="41" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="trademark" k="205" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quoteleft,quotedblleft" k="184" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="quoteright,quotedblright" k="184" />
+<hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="41" />
+<hkern g1="B" g2="J,Jcircumflex" k="61" />
+<hkern g1="B" g2="T,uni0162,Tcaron,Tbar,uni021A" k="61" />
<hkern g1="B" g2="V" k="41" />
-<hkern g1="B" g2="W" k="41" />
-<hkern g1="B" g2="Y,Yacute,Ydieresis" k="51" />
+<hkern g1="B" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="41" />
+<hkern g1="B" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="51" />
<hkern g1="B" g2="trademark" k="61" />
-<hkern g1="C,Ccedilla" g2="J" k="20" />
-<hkern g1="C,Ccedilla" g2="V" k="20" />
-<hkern g1="C,Ccedilla" g2="W" k="20" />
-<hkern g1="C,Ccedilla" g2="X" k="31" />
-<hkern g1="C,Ccedilla" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="E,AE,Egrave,Eacute,Ecircumflex,Edieresis,OE" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="20" />
-<hkern g1="F" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="123" />
-<hkern g1="F" g2="J" k="184" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="J,Jcircumflex" k="20" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="V" k="20" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="X" k="31" />
+<hkern g1="C,Ccedilla,Cacute,Ccircumflex,Cdotaccent,Ccaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="E,AE,Egrave,Eacute,Ecircumflex,Edieresis,Emacron,Ebreve,Edotaccent,Eogonek,Ecaron,OE,AEacute,Edotbelow,Ehookabove,Etilde,Ecircumflexacute,Ecircumflexgrave,Ecircumflexhookabove,Ecircumflextilde,Ecircumflexdotbelow" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="20" />
+<hkern g1="F" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="123" />
+<hkern g1="F" g2="J,Jcircumflex" k="184" />
<hkern g1="F" g2="X" k="61" />
<hkern g1="F" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="246" />
-<hkern g1="F" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="61" />
-<hkern g1="F" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="82" />
-<hkern g1="F" g2="t" k="20" />
-<hkern g1="F" g2="z" k="61" />
+<hkern g1="F" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="61" />
+<hkern g1="F" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="82" />
+<hkern g1="F" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="F" g2="z,zacute,zdotaccent,zcaron" k="61" />
<hkern g1="F" g2="copyright,registered" k="61" />
-<hkern g1="F" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="F" g2="S" k="41" />
-<hkern g1="F" g2="Z" k="41" />
-<hkern g1="F" g2="i,j,igrave,iacute,icircumflex,idieresis" k="41" />
-<hkern g1="F" g2="m,n,p,r,ntilde" k="72" />
-<hkern g1="F" g2="s" k="82" />
-<hkern g1="F" g2="u,ugrave,uacute,ucircumflex,udieresis" k="41" />
+<hkern g1="F" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="F" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="41" />
+<hkern g1="F" g2="Z,Zacute,Zdotaccent,Zcaron" k="41" />
+<hkern g1="F" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="41" />
+<hkern g1="F" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="72" />
+<hkern g1="F" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="82" />
+<hkern g1="F" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="41" />
<hkern g1="F" g2="v" k="41" />
-<hkern g1="F" g2="w" k="41" />
+<hkern g1="F" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="41" />
<hkern g1="F" g2="x" k="82" />
-<hkern g1="F" g2="y,yacute,ydieresis" k="61" />
-<hkern g1="G" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="20" />
-<hkern g1="G" g2="J" k="51" />
-<hkern g1="G" g2="T" k="41" />
-<hkern g1="G" g2="V" k="41" />
-<hkern g1="G" g2="W" k="41" />
-<hkern g1="G" g2="X" k="31" />
-<hkern g1="G" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="G" g2="trademark" k="41" />
-<hkern g1="J" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="41" />
-<hkern g1="J" g2="J" k="61" />
-<hkern g1="J" g2="X" k="20" />
-<hkern g1="J" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
-<hkern g1="J" g2="AE" k="61" />
-<hkern g1="K" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="41" />
-<hkern g1="K" g2="J" k="41" />
-<hkern g1="K" g2="T" k="61" />
-<hkern g1="K" g2="V" k="51" />
-<hkern g1="K" g2="W" k="51" />
-<hkern g1="K" g2="X" k="41" />
-<hkern g1="K" g2="Y,Yacute,Ydieresis" k="82" />
-<hkern g1="K" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="61" />
-<hkern g1="K" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="20" />
-<hkern g1="K" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="61" />
-<hkern g1="K" g2="t" k="61" />
-<hkern g1="K" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="K" g2="S" k="72" />
-<hkern g1="K" g2="i,j,igrave,iacute,icircumflex,idieresis" k="41" />
-<hkern g1="K" g2="m,n,p,r,ntilde" k="41" />
-<hkern g1="K" g2="s" k="61" />
-<hkern g1="K" g2="u,ugrave,uacute,ucircumflex,udieresis" k="61" />
-<hkern g1="K" g2="v" k="51" />
-<hkern g1="K" g2="w" k="51" />
-<hkern g1="K" g2="y,yacute,ydieresis" k="102" />
-<hkern g1="K" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="41" />
-<hkern g1="L" g2="T" k="205" />
-<hkern g1="L" g2="V" k="154" />
-<hkern g1="L" g2="W" k="102" />
-<hkern g1="L" g2="Y,Yacute,Ydieresis" k="164" />
-<hkern g1="L" g2="quotedbl,quotesingle" k="205" />
-<hkern g1="L" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
-<hkern g1="L" g2="colon,semicolon" k="-41" />
-<hkern g1="L" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="61" />
-<hkern g1="L" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="41" />
-<hkern g1="L" g2="t" k="31" />
-<hkern g1="L" g2="copyright,registered" k="102" />
-<hkern g1="L" g2="trademark" k="287" />
-<hkern g1="L" g2="quoteleft,quotedblleft" k="256" />
-<hkern g1="L" g2="quoteright,quotedblright" k="256" />
-<hkern g1="L" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="31" />
-<hkern g1="L" g2="S" k="41" />
-<hkern g1="L" g2="v" k="61" />
-<hkern g1="L" g2="w" k="61" />
-<hkern g1="L" g2="y,yacute,ydieresis" k="102" />
-<hkern g1="P,Thorn" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="102" />
-<hkern g1="P,Thorn" g2="J" k="143" />
-<hkern g1="P,Thorn" g2="T" k="20" />
+<hkern g1="F" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="61" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="20" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="J,Jcircumflex" k="51" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="T,uni0162,Tcaron,Tbar,uni021A" k="41" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="V" k="41" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="41" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="X" k="31" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="G,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent" g2="trademark" k="41" />
+<hkern g1="J,IJ,Jcircumflex" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="41" />
+<hkern g1="J,IJ,Jcircumflex" g2="J,Jcircumflex" k="61" />
+<hkern g1="J,IJ,Jcircumflex" g2="X" k="20" />
+<hkern g1="J,IJ,Jcircumflex" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
+<hkern g1="J,IJ,Jcircumflex" g2="AE,AEacute" k="61" />
+<hkern g1="K,Kcommaaccent" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="41" />
+<hkern g1="K,Kcommaaccent" g2="J,Jcircumflex" k="41" />
+<hkern g1="K,Kcommaaccent" g2="T,uni0162,Tcaron,Tbar,uni021A" k="61" />
+<hkern g1="K,Kcommaaccent" g2="V" k="51" />
+<hkern g1="K,Kcommaaccent" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="51" />
+<hkern g1="K,Kcommaaccent" g2="X" k="41" />
+<hkern g1="K,Kcommaaccent" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="82" />
+<hkern g1="K,Kcommaaccent" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="61" />
+<hkern g1="K,Kcommaaccent" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="20" />
+<hkern g1="K,Kcommaaccent" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="61" />
+<hkern g1="K,Kcommaaccent" g2="t,uni0163,tcaron,tbar,uni021B" k="61" />
+<hkern g1="K,Kcommaaccent" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="K,Kcommaaccent" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="72" />
+<hkern g1="K,Kcommaaccent" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="41" />
+<hkern g1="K,Kcommaaccent" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="41" />
+<hkern g1="K,Kcommaaccent" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="61" />
+<hkern g1="K,Kcommaaccent" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="61" />
+<hkern g1="K,Kcommaaccent" g2="v" k="51" />
+<hkern g1="K,Kcommaaccent" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="51" />
+<hkern g1="K,Kcommaaccent" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="102" />
+<hkern g1="K,Kcommaaccent" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="41" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="T,uni0162,Tcaron,Tbar,uni021A" k="205" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="V" k="154" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="102" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="164" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quotedbl,quotesingle" k="205" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-20" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="colon,semicolon" k="-41" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="61" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="41" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="t,uni0163,tcaron,tbar,uni021B" k="31" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="copyright,registered" k="102" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="trademark" k="287" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quoteleft,quotedblleft" k="256" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="quoteright,quotedblright" k="256" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="31" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="41" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="v" k="61" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="61" />
+<hkern g1="L,Lacute,Lcommaaccent,Lcaron,Lslash" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="102" />
+<hkern g1="P,Thorn" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="102" />
+<hkern g1="P,Thorn" g2="J,Jcircumflex" k="143" />
+<hkern g1="P,Thorn" g2="T,uni0162,Tcaron,Tbar,uni021A" k="20" />
<hkern g1="P,Thorn" g2="V" k="-10" />
-<hkern g1="P,Thorn" g2="W" k="-10" />
+<hkern g1="P,Thorn" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-10" />
<hkern g1="P,Thorn" g2="X" k="41" />
<hkern g1="P,Thorn" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="287" />
-<hkern g1="P,Thorn" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="20" />
-<hkern g1="P,Thorn" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="P,Thorn" g2="S" k="-31" />
-<hkern g1="P,Thorn" g2="Z" k="41" />
-<hkern g1="P,Thorn" g2="AE" k="123" />
-<hkern g1="P,Thorn" g2="I,Igrave,Iacute,Icircumflex,Idieresis" k="41" />
-<hkern g1="R" g2="J" k="41" />
-<hkern g1="R" g2="T" k="41" />
-<hkern g1="R" g2="V" k="41" />
-<hkern g1="R" g2="W" k="41" />
-<hkern g1="R" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="R" g2="z" k="-20" />
-<hkern g1="R" g2="AE" k="61" />
-<hkern g1="S" g2="J" k="61" />
-<hkern g1="S" g2="T" k="41" />
-<hkern g1="S" g2="V" k="31" />
-<hkern g1="S" g2="W" k="31" />
-<hkern g1="S" g2="X" k="20" />
-<hkern g1="S" g2="Y,Yacute,Ydieresis" k="61" />
-<hkern g1="T" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="164" />
-<hkern g1="T" g2="J" k="143" />
-<hkern g1="T" g2="X" k="20" />
-<hkern g1="T" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="225" />
-<hkern g1="T" g2="colon,semicolon" k="143" />
-<hkern g1="T" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="61" />
-<hkern g1="T" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="205" />
-<hkern g1="T" g2="t" k="82" />
-<hkern g1="T" g2="z" k="156" />
-<hkern g1="T" g2="copyright,registered" k="102" />
-<hkern g1="T" g2="trademark" k="-61" />
-<hkern g1="T" g2="quoteleft,quotedblleft" k="-61" />
-<hkern g1="T" g2="quoteright,quotedblright" k="-61" />
-<hkern g1="T" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="205" />
-<hkern g1="T" g2="S" k="41" />
-<hkern g1="T" g2="i,j,igrave,iacute,icircumflex,idieresis" k="41" />
-<hkern g1="T" g2="m,n,p,r,ntilde" k="184" />
-<hkern g1="T" g2="s" k="242" />
-<hkern g1="T" g2="u,ugrave,uacute,ucircumflex,udieresis" k="164" />
-<hkern g1="T" g2="v" k="225" />
-<hkern g1="T" g2="w" k="225" />
-<hkern g1="T" g2="x" k="205" />
-<hkern g1="T" g2="y,yacute,ydieresis" k="143" />
-<hkern g1="T" g2="AE" k="184" />
-<hkern g1="T" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="61" />
-<hkern g1="T" g2="hyphen,endash,emdash" k="102" />
-<hkern g1="T" g2="guillemotleft,guilsinglleft" k="143" />
-<hkern g1="T" g2="guillemotright,guilsinglright" k="123" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="41" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="J" k="51" />
-<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis" g2="X" k="20" />
-<hkern g1="W" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="61" />
-<hkern g1="W" g2="J" k="143" />
-<hkern g1="W" g2="X" k="20" />
-<hkern g1="W" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="W" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
-<hkern g1="W" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="41" />
-<hkern g1="W" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="61" />
-<hkern g1="W" g2="t" k="31" />
-<hkern g1="W" g2="z" k="41" />
-<hkern g1="W" g2="copyright,registered" k="41" />
-<hkern g1="W" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="W" g2="S" k="10" />
-<hkern g1="W" g2="m,n,p,r,ntilde" k="61" />
-<hkern g1="W" g2="s" k="61" />
-<hkern g1="W" g2="u,ugrave,uacute,ucircumflex,udieresis" k="61" />
-<hkern g1="W" g2="x" k="31" />
-<hkern g1="W" g2="y,yacute,ydieresis" k="20" />
-<hkern g1="W" g2="AE" k="82" />
-<hkern g1="W" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
-<hkern g1="W" g2="b,h,k,l,germandbls,thorn" k="31" />
-<hkern g1="X" g2="T" k="20" />
+<hkern g1="P,Thorn" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="20" />
+<hkern g1="P,Thorn" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="P,Thorn" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-31" />
+<hkern g1="P,Thorn" g2="Z,Zacute,Zdotaccent,Zcaron" k="41" />
+<hkern g1="P,Thorn" g2="AE,AEacute" k="123" />
+<hkern g1="P,Thorn" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="J,Jcircumflex" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="T,uni0162,Tcaron,Tbar,uni021A" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="V" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="z,zacute,zdotaccent,zcaron" k="-20" />
+<hkern g1="R,Racute,Rcommaaccent,Rcaron" g2="AE,AEacute" k="61" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="J,Jcircumflex" k="61" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="T,uni0162,Tcaron,Tbar,uni021A" k="41" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="V" k="31" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="31" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="X" k="20" />
+<hkern g1="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent,Eszett" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="61" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="164" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="J,Jcircumflex" k="143" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="X" k="20" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="225" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="colon,semicolon" k="143" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="61" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="205" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="t,uni0163,tcaron,tbar,uni021B" k="82" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="z,zacute,zdotaccent,zcaron" k="156" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="copyright,registered" k="102" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="trademark" k="-61" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="quoteleft,quotedblleft" k="-61" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="quoteright,quotedblright" k="-61" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="205" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="41" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="41" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="184" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="242" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="164" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="v" k="225" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="225" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="x" k="205" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="143" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="AE,AEacute" k="184" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="61" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="hyphen,endash,emdash,afii00208" k="102" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="guillemotleft,guilsinglleft" k="143" />
+<hkern g1="T,uni0162,Tcaron,Tbar,uni021A" g2="guillemotright,guilsinglright" k="123" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="41" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="J,Jcircumflex" k="51" />
+<hkern g1="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove" g2="X" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="J,Jcircumflex" k="143" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="X" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="41" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="t,uni0163,tcaron,tbar,uni021B" k="31" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="z,zacute,zdotaccent,zcaron" k="41" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="copyright,registered" k="41" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="10" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="61" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="x" k="31" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="AE,AEacute" k="82" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
+<hkern g1="W,Wcircumflex,Wgrave,Wacute,Wdieresis" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="31" />
+<hkern g1="X" g2="T,uni0162,Tcaron,Tbar,uni021A" k="20" />
<hkern g1="X" g2="V" k="20" />
-<hkern g1="X" g2="W" k="20" />
-<hkern g1="X" g2="Y,Yacute,Ydieresis" k="41" />
-<hkern g1="X" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="41" />
-<hkern g1="X" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis" k="20" />
+<hkern g1="X" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="20" />
+<hkern g1="X" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
+<hkern g1="X" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="41" />
+<hkern g1="X" g2="U,Ugrave,Uacute,Ucircumflex,Udieresis,Utilde,Umacron,Ubreve,Uring,Uhungarumlaut,Uogonek,Uhorn,Ucaron,Udieresismacron,Udieresisacute,Udieresiscaron,Udieresisgrave,Udotbelow,Uhookabove,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" k="20" />
<hkern g1="X" g2="copyright,registered" k="41" />
-<hkern g1="X" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="X" g2="S" k="20" />
-<hkern g1="X" g2="m,n,p,r,ntilde" k="31" />
-<hkern g1="X" g2="u,ugrave,uacute,ucircumflex,udieresis" k="82" />
+<hkern g1="X" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="X" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="20" />
+<hkern g1="X" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="31" />
+<hkern g1="X" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="82" />
<hkern g1="X" g2="v" k="41" />
-<hkern g1="X" g2="w" k="41" />
-<hkern g1="X" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
+<hkern g1="X" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="41" />
+<hkern g1="X" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
<hkern g1="X" g2="guillemotleft,guilsinglleft" k="61" />
<hkern g1="X" g2="guillemotright,guilsinglright" k="-41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="133" />
-<hkern g1="Y,Yacute,Ydieresis" g2="J" k="184" />
-<hkern g1="Y,Yacute,Ydieresis" g2="V" k="41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="W" k="41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="X" k="41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="164" />
-<hkern g1="Y,Yacute,Ydieresis" g2="colon,semicolon" k="61" />
-<hkern g1="Y,Yacute,Ydieresis" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="61" />
-<hkern g1="Y,Yacute,Ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="123" />
-<hkern g1="Y,Yacute,Ydieresis" g2="t" k="31" />
-<hkern g1="Y,Yacute,Ydieresis" g2="z" k="102" />
-<hkern g1="Y,Yacute,Ydieresis" g2="copyright,registered" k="82" />
-<hkern g1="Y,Yacute,Ydieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="143" />
-<hkern g1="Y,Yacute,Ydieresis" g2="S" k="61" />
-<hkern g1="Y,Yacute,Ydieresis" g2="Z" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="i,j,igrave,iacute,icircumflex,idieresis" k="41" />
-<hkern g1="Y,Yacute,Ydieresis" g2="m,n,p,r,ntilde" k="133" />
-<hkern g1="Y,Yacute,Ydieresis" g2="s" k="123" />
-<hkern g1="Y,Yacute,Ydieresis" g2="u,ugrave,uacute,ucircumflex,udieresis" k="102" />
-<hkern g1="Y,Yacute,Ydieresis" g2="v" k="123" />
-<hkern g1="Y,Yacute,Ydieresis" g2="w" k="123" />
-<hkern g1="Y,Yacute,Ydieresis" g2="x" k="82" />
-<hkern g1="Y,Yacute,Ydieresis" g2="AE" k="113" />
-<hkern g1="Y,Yacute,Ydieresis" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
-<hkern g1="Y,Yacute,Ydieresis" g2="guillemotleft,guilsinglleft" k="102" />
-<hkern g1="Y,Yacute,Ydieresis" g2="b,h,k,l,germandbls,thorn" k="41" />
-<hkern g1="Z" g2="Y,Yacute,Ydieresis" k="31" />
-<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="t" k="20" />
-<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="v" k="31" />
-<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring" g2="w" k="10" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="41" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="quoteleft,quotedblleft" k="82" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="quoteright,quotedblright" k="82" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="v" k="20" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="x" k="20" />
-<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn" g2="y,yacute,ydieresis" k="10" />
-<hkern g1="h,m,n,ntilde" g2="v" k="20" />
-<hkern g1="h,m,n,ntilde" g2="w" k="20" />
-<hkern g1="f" g2="quotedbl,quotesingle" k="-102" />
-<hkern g1="f" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
-<hkern g1="f" g2="trademark" k="-143" />
-<hkern g1="f" g2="quoteleft,quotedblleft" k="-102" />
-<hkern g1="f" g2="quoteright,quotedblright" k="-102" />
-<hkern g1="f" g2="parenright,bracketright,braceright" k="-143" />
-<hkern g1="k" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="31" />
-<hkern g1="k" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="41" />
-<hkern g1="k" g2="s" k="20" />
-<hkern g1="k" g2="v" k="41" />
-<hkern g1="k" g2="guillemotright,guilsinglright" k="-41" />
-<hkern g1="d,l,uniFB02,uniFB04" g2="t" k="20" />
-<hkern g1="r" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="266" />
-<hkern g1="r" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="20" />
-<hkern g1="r" g2="quoteleft,quotedblleft" k="-82" />
-<hkern g1="r" g2="quoteright,quotedblright" k="-82" />
-<hkern g1="r" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="r" g2="s" k="41" />
-<hkern g1="r" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="-20" />
-<hkern g1="r" g2="guillemotright,guilsinglright" k="-82" />
-<hkern g1="s" g2="t" k="20" />
-<hkern g1="s" g2="v" k="41" />
-<hkern g1="s" g2="w" k="41" />
-<hkern g1="s" g2="x" k="20" />
-<hkern g1="t" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="-20" />
-<hkern g1="t" g2="t" k="20" />
-<hkern g1="t" g2="z" k="-31" />
-<hkern g1="t" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="t" g2="u,ugrave,uacute,ucircumflex,udieresis" k="31" />
-<hkern g1="t" g2="v" k="31" />
-<hkern g1="t" g2="w" k="31" />
-<hkern g1="t" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="41" />
-<hkern g1="w" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
-<hkern g1="w" g2="s" k="20" />
-<hkern g1="w" g2="y,yacute,ydieresis" k="10" />
-<hkern g1="x" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="y,yacute,ydieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="123" />
-<hkern g1="y,yacute,ydieresis" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="20" />
-<hkern g1="y,yacute,ydieresis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="41" />
-<hkern g1="y,yacute,ydieresis" g2="s" k="31" />
-<hkern g1="y,yacute,ydieresis" g2="v" k="20" />
-<hkern g1="y,yacute,ydieresis" g2="w" k="20" />
-<hkern g1="y,yacute,ydieresis" g2="x" k="31" />
-<hkern g1="y,yacute,ydieresis" g2="parenright,bracketright,braceright" k="61" />
-<hkern g1="z" g2="z" k="-20" />
-<hkern g1="colon,semicolon" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-41" />
-<hkern g1="colon,semicolon" g2="J" k="-41" />
-<hkern g1="colon,semicolon" g2="T" k="143" />
-<hkern g1="colon,semicolon" g2="Y,Yacute,Ydieresis" k="61" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="-41" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="J" k="-41" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="T" k="225" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="133" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="J,Jcircumflex" k="184" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="V" k="41" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="41" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="X" k="41" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="164" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="colon,semicolon" k="61" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="61" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="123" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="t,uni0163,tcaron,tbar,uni021B" k="31" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="z,zacute,zdotaccent,zcaron" k="102" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="copyright,registered" k="82" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="143" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="61" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="Z,Zacute,Zdotaccent,Zcaron" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="41" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="133" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="123" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="102" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="v" k="123" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="123" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="x" k="82" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="AE,AEacute" k="113" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="guillemotleft,guilsinglleft" k="102" />
+<hkern g1="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="41" />
+<hkern g1="Z,Zacute,Zdotaccent,Zcaron" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="31" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring,amacron,abreve,aogonek,acaron,aringacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring,amacron,abreve,aogonek,acaron,aringacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" g2="v" k="31" />
+<hkern g1="a,agrave,aacute,acircumflex,atilde,adieresis,aring,amacron,abreve,aogonek,acaron,aringacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="10" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="41" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="quoteleft,quotedblleft" k="82" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="quoteright,quotedblright" k="82" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="v" k="20" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="x" k="20" />
+<hkern g1="b,o,p,germandbls,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,thorn,omacron,obreve,ohungarumlaut,ocaron,oslashacute,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="h,m,n,ntilde,hcircumflex,hbar,nacute,ncommaaccent,ncaron,napostrophe,eng" g2="v" k="20" />
+<hkern g1="h,m,n,ntilde,hcircumflex,hbar,nacute,ncommaaccent,ncaron,napostrophe,eng" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
+<hkern g1="f,f_f" g2="quotedbl,quotesingle" k="-102" />
+<hkern g1="f,f_f" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
+<hkern g1="f,f_f" g2="trademark" k="-143" />
+<hkern g1="f,f_f" g2="quoteleft,quotedblleft" k="-102" />
+<hkern g1="f,f_f" g2="quoteright,quotedblright" k="-102" />
+<hkern g1="f,f_f" g2="parenright,bracketright,braceright" k="-143" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="31" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="41" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="20" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="v" k="41" />
+<hkern g1="k,kcommaaccent,kgreenlandic" g2="guillemotright,guilsinglright" k="-41" />
+<hkern g1="d,l,dcroat,lacute,lcommaaccent,lslash,f_l,fl,f_f_l" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="266" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="20" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="quoteleft,quotedblleft" k="-82" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="quoteright,quotedblright" k="-82" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="41" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-20" />
+<hkern g1="r,racute,rcommaaccent,rcaron" g2="guillemotright,guilsinglright" k="-82" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="v" k="41" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="41" />
+<hkern g1="s,sacute,scircumflex,scedilla,scaron,scommaaccent" g2="x" k="20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="-20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="z,zacute,zdotaccent,zcaron" k="-31" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="31" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="v" k="31" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="31" />
+<hkern g1="t,uni0163,tcaron,tbar,uni021B" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="41" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="20" />
+<hkern g1="w,wcircumflex,wgrave,wacute,wdieresis" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="x" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="123" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="20" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="41" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="31" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="v" k="20" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="20" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="x" k="31" />
+<hkern g1="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" g2="parenright,bracketright,braceright" k="61" />
+<hkern g1="z,zacute,zdotaccent,zcaron" g2="z,zacute,zdotaccent,zcaron" k="-20" />
+<hkern g1="colon,semicolon" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="-41" />
+<hkern g1="colon,semicolon" g2="J,Jcircumflex" k="-41" />
+<hkern g1="colon,semicolon" g2="T,uni0162,Tcaron,Tbar,uni021A" k="143" />
+<hkern g1="colon,semicolon" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="61" />
+<hkern g1="colon,semicolon" g2="uni0410" k="-41" />
+<hkern g1="colon,semicolon" g2="uni0409,uni041B" k="-41" />
+<hkern g1="colon,semicolon" g2="uni0422" k="143" />
+<hkern g1="colon,semicolon" g2="uni0408" k="-41" />
+<hkern g1="colon,semicolon" g2="uni0402,uni040B,uni042A" k="82" />
+<hkern g1="colon,semicolon" g2="uni043B,uni0459" k="-41" />
+<hkern g1="colon,semicolon" g2="Alpha,uni0394,Lambda,Delta" k="-41" />
+<hkern g1="colon,semicolon" g2="Tau" k="143" />
+<hkern g1="colon,semicolon" g2="Upsilon,Upsilondieresis" k="61" />
+<hkern g1="colon,semicolon" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-184" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="J,Jcircumflex" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="T,uni0162,Tcaron,Tbar,uni021A" k="225" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="V" k="143" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="W" k="143" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Y,Yacute,Ydieresis" k="164" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="143" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="164" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="quoteleft,quotedblleft" k="184" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="quoteright,quotedblright" k="143" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="41" />
<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="v" k="61" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="w" k="61" />
-<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="AE" k="-61" />
-<hkern g1="guillemotleft,guilsinglleft" g2="T" k="123" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="61" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="AE,AEacute" k="-61" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0410" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0409,uni041B" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0422" k="225" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0408" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0402,uni040B,uni042A" k="102" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni043B,uni0459" k="-20" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Alpha,uni0394,Lambda,Delta" k="-41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Tau" k="225" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Upsilon,Upsilondieresis" k="164" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="pi" k="184" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0427" k="205" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0442" k="143" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni0447" k="102" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="uni044A" k="82" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="Psi" k="143" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="gamma,nu" k="102" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="theta" k="61" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="tau" k="184" />
+<hkern g1="comma,period,quotesinglbase,quotedblbase,ellipsis" g2="chi" k="82" />
+<hkern g1="guillemotleft,guilsinglleft" g2="T,uni0162,Tcaron,Tbar,uni021A" k="123" />
<hkern g1="guillemotleft,guilsinglleft" g2="X" k="-41" />
-<hkern g1="guillemotright,guilsinglright" g2="T" k="143" />
+<hkern g1="guillemotleft,guilsinglleft" g2="uni0422" k="123" />
+<hkern g1="guillemotleft,guilsinglleft" g2="uni0402,uni040B,uni042A" k="61" />
+<hkern g1="guillemotleft,guilsinglleft" g2="Tau" k="123" />
+<hkern g1="guillemotleft,guilsinglleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-266" />
+<hkern g1="guillemotright,guilsinglright" g2="T,uni0162,Tcaron,Tbar,uni021A" k="143" />
<hkern g1="guillemotright,guilsinglright" g2="X" k="61" />
-<hkern g1="guillemotright,guilsinglright" g2="Y,Yacute,Ydieresis" k="102" />
-<hkern g1="hyphen,endash,emdash" g2="T" k="102" />
-<hkern g1="parenleft,bracketleft,braceleft" g2="y,yacute,ydieresis" k="-61" />
-<hkern g1="quoteleft,quotedblleft" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="184" />
-<hkern g1="quoteleft,quotedblleft" g2="J" k="195" />
-<hkern g1="quoteleft,quotedblleft" g2="T" k="-61" />
-<hkern g1="quoteleft,quotedblleft" g2="t" k="-61" />
+<hkern g1="guillemotright,guilsinglright" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="102" />
+<hkern g1="guillemotright,guilsinglright" g2="uni0422" k="143" />
+<hkern g1="guillemotright,guilsinglright" g2="uni0402,uni040B,uni042A" k="61" />
+<hkern g1="guillemotright,guilsinglright" g2="Tau" k="143" />
+<hkern g1="guillemotright,guilsinglright" g2="Upsilon,Upsilondieresis" k="102" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="T,uni0162,Tcaron,Tbar,uni021A" k="102" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="uni0422" k="102" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="Tau" k="102" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="pi" k="61" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="tau" k="61" />
+<hkern g1="hyphen,endash,emdash,afii00208" g2="xi" k="-41" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-61" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-123" />
+<hkern g1="parenleft,bracketleft,braceleft" g2="uni0443,uni045E" k="-61" />
+<hkern g1="parenright,bracketright,braceright" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-184" />
+<hkern g1="quoteleft,quotedblleft" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="184" />
+<hkern g1="quoteleft,quotedblleft" g2="J,Jcircumflex" k="195" />
+<hkern g1="quoteleft,quotedblleft" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-61" />
+<hkern g1="quoteleft,quotedblleft" g2="t,uni0163,tcaron,tbar,uni021B" k="-61" />
<hkern g1="quoteleft,quotedblleft" g2="quoteleft,quotedblleft" k="123" />
-<hkern g1="quoteleft,quotedblleft" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="82" />
-<hkern g1="quoteleft,quotedblleft" g2="AE" k="174" />
-<hkern g1="quoteright,quotedblright" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="184" />
-<hkern g1="quoteright,quotedblright" g2="J" k="193" />
-<hkern g1="quoteright,quotedblright" g2="T" k="-61" />
+<hkern g1="quoteleft,quotedblleft" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="82" />
+<hkern g1="quoteleft,quotedblleft" g2="AE,AEacute" k="174" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0410" k="184" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0409,uni041B" k="225" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0408" k="193" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0402,uni040B,uni042A" k="-41" />
+<hkern g1="quoteleft,quotedblleft" g2="uni043B,uni0459" k="143" />
+<hkern g1="quoteleft,quotedblleft" g2="Alpha,uni0394,Lambda,Delta" k="184" />
+<hkern g1="quoteleft,quotedblleft" g2="Tau" k="-61" />
+<hkern g1="quoteleft,quotedblleft" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-184" />
+<hkern g1="quoteleft,quotedblleft" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="82" />
+<hkern g1="quoteleft,quotedblleft" g2="uni0414" k="164" />
+<hkern g1="quoteleft,quotedblleft" g2="rho" k="61" />
+<hkern g1="quoteleft,quotedblleft" g2="omega,omegatonos" k="102" />
+<hkern g1="quoteright,quotedblright" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="184" />
+<hkern g1="quoteright,quotedblright" g2="J,Jcircumflex" k="193" />
+<hkern g1="quoteright,quotedblright" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-61" />
<hkern g1="quoteright,quotedblright" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="164" />
<hkern g1="quoteright,quotedblright" g2="quoteright,quotedblright" k="123" />
-<hkern g1="quoteright,quotedblright" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="82" />
-<hkern g1="quoteright,quotedblright" g2="AE" k="174" />
-<hkern g1="quotedbl,quotesingle" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="123" />
-<hkern g1="quotedbl,quotesingle" g2="J" k="205" />
-<hkern g1="V" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring" k="92" />
-<hkern g1="V" g2="J" k="143" />
+<hkern g1="quoteright,quotedblright" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="82" />
+<hkern g1="quoteright,quotedblright" g2="AE,AEacute" k="174" />
+<hkern g1="quoteright,quotedblright" g2="uni0410" k="184" />
+<hkern g1="quoteright,quotedblright" g2="uni0409,uni041B" k="225" />
+<hkern g1="quoteright,quotedblright" g2="uni0408" k="193" />
+<hkern g1="quoteright,quotedblright" g2="uni0402,uni040B,uni042A" k="-41" />
+<hkern g1="quoteright,quotedblright" g2="uni043B,uni0459" k="164" />
+<hkern g1="quoteright,quotedblright" g2="Alpha,uni0394,Lambda,Delta" k="184" />
+<hkern g1="quoteright,quotedblright" g2="Tau" k="-61" />
+<hkern g1="quoteright,quotedblright" g2="Alphatonos,Epsilontonos,Etatonos,Iotatonos,Omicrontonos,Upsilontonos,Omegatonos" k="-184" />
+<hkern g1="quoteright,quotedblright" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="82" />
+<hkern g1="quoteright,quotedblright" g2="uni0414" k="184" />
+<hkern g1="quoteright,quotedblright" g2="rho" k="61" />
+<hkern g1="quoteright,quotedblright" g2="omega,omegatonos" k="102" />
+<hkern g1="quotedbl,quotesingle" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="123" />
+<hkern g1="quotedbl,quotesingle" g2="J,Jcircumflex" k="205" />
+<hkern g1="dcaron,lcaron" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="82" />
+<hkern g1="dcaron,lcaron" g2="quoteleft,quotedblleft" k="-82" />
+<hkern g1="dcaron,lcaron" g2="quoteright,quotedblright" k="-61" />
+<hkern g1="dcaron,lcaron" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="82" />
+<hkern g1="dcaron,lcaron" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="82" />
+<hkern g1="dcaron,lcaron" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="82" />
+<hkern g1="dcaron,lcaron" g2="parenright,bracketright,braceright" k="-102" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="colon,semicolon" k="-41" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="quoteleft,quotedblleft" k="184" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="quoteright,quotedblright" k="184" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Tau" k="164" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Upsilon,Upsilondieresis" k="133" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="pi" k="82" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Psi" k="61" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="gamma,nu" k="41" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="theta" k="20" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="tau" k="102" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="Theta,Omicron,Phi" k="41" />
+<hkern g1="Alphatonos,Alpha,uni0394,Lambda,Delta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="41" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Alpha,uni0394,Lambda,Delta" k="41" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Tau" k="61" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Upsilon,Upsilondieresis" k="61" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="Chi" k="41" />
+<hkern g1="Omicrontonos,Theta,Omicron,Phi" g2="lambda" k="20" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="164" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="colon,semicolon" k="61" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="guillemotleft,guilsinglleft" k="102" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Alpha,uni0394,Lambda,Delta" k="133" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="pi" k="92" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="143" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="tau" k="102" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Theta,Omicron,Phi" k="61" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Chi" k="41" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="Zeta" k="20" />
+<hkern g1="Upsilontonos,Upsilon,Upsilondieresis" g2="mu,etatonos,eta,uni03BC" k="133" />
+<hkern g1="Iotatonos,Iota,Iotadieresis" g2="pi" k="20" />
+<hkern g1="Iotatonos,Iota,Iotadieresis" g2="tau" k="41" />
+<hkern g1="Omegatonos,uni03A9,Omega" g2="Tau" k="61" />
+<hkern g1="Omegatonos,uni03A9,Omega" g2="Chi" k="61" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="pi" k="61" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="gamma,nu" k="61" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="tau" k="61" />
+<hkern g1="Epsilontonos,Epsilon,Xi" g2="chi" k="41" />
+<hkern g1="Beta" g2="Tau" k="61" />
+<hkern g1="Beta" g2="Upsilon,Upsilondieresis" k="51" />
+<hkern g1="Beta" g2="pi" k="41" />
+<hkern g1="Beta" g2="gamma,nu" k="41" />
+<hkern g1="Beta" g2="tau" k="41" />
+<hkern g1="Beta" g2="lambda" k="41" />
+<hkern g1="Gamma" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="287" />
+<hkern g1="Gamma" g2="colon,semicolon" k="205" />
+<hkern g1="Gamma" g2="quoteleft,quotedblleft" k="-20" />
+<hkern g1="Gamma" g2="quoteright,quotedblright" k="-20" />
+<hkern g1="Gamma" g2="hyphen,endash,emdash,afii00208" k="297" />
+<hkern g1="Gamma" g2="guillemotleft,guilsinglleft" k="205" />
+<hkern g1="Gamma" g2="guillemotright,guilsinglright" k="205" />
+<hkern g1="Gamma" g2="Alpha,uni0394,Lambda,Delta" k="174" />
+<hkern g1="Gamma" g2="pi" k="236" />
+<hkern g1="Gamma" g2="gamma,nu" k="215" />
+<hkern g1="Gamma" g2="theta" k="41" />
+<hkern g1="Gamma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="307" />
+<hkern g1="Gamma" g2="tau" k="236" />
+<hkern g1="Gamma" g2="chi" k="236" />
+<hkern g1="Gamma" g2="rho" k="297" />
+<hkern g1="Gamma" g2="omega,omegatonos" k="276" />
+<hkern g1="Gamma" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="299" />
+<hkern g1="Gamma" g2="lambda" k="82" />
+<hkern g1="Gamma" g2="mu,etatonos,eta,uni03BC" k="307" />
+<hkern g1="Gamma" g2="uni03A9,Omega" k="61" />
+<hkern g1="Gamma" g2="beta" k="41" />
+<hkern g1="Gamma" g2="epsilontonos,epsilon" k="348" />
+<hkern g1="Gamma" g2="zeta" k="82" />
+<hkern g1="Gamma" g2="kappa" k="307" />
+<hkern g1="Gamma" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="266" />
+<hkern g1="Zeta" g2="Upsilon,Upsilondieresis" k="31" />
+<hkern g1="Zeta" g2="pi" k="82" />
+<hkern g1="Zeta" g2="gamma,nu" k="61" />
+<hkern g1="Zeta" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="Zeta" g2="tau" k="102" />
+<hkern g1="Zeta" g2="chi" k="41" />
+<hkern g1="Zeta" g2="rho" k="20" />
+<hkern g1="Zeta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="82" />
+<hkern g1="Zeta" g2="beta" k="41" />
+<hkern g1="Kappa" g2="Alpha,uni0394,Lambda,Delta" k="41" />
+<hkern g1="Kappa" g2="Tau" k="61" />
+<hkern g1="Kappa" g2="Upsilon,Upsilondieresis" k="82" />
+<hkern g1="Kappa" g2="pi" k="154" />
+<hkern g1="Kappa" g2="Psi" k="51" />
+<hkern g1="Kappa" g2="gamma,nu" k="102" />
+<hkern g1="Kappa" g2="theta" k="82" />
+<hkern g1="Kappa" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="Kappa" g2="tau" k="154" />
+<hkern g1="Kappa" g2="chi" k="102" />
+<hkern g1="Kappa" g2="rho" k="61" />
+<hkern g1="Kappa" g2="omega,omegatonos" k="31" />
+<hkern g1="Kappa" g2="Theta,Omicron,Phi" k="61" />
+<hkern g1="Kappa" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="143" />
+<hkern g1="Kappa" g2="Chi" k="41" />
+<hkern g1="Kappa" g2="lambda" k="61" />
+<hkern g1="Kappa" g2="mu,etatonos,eta,uni03BC" k="41" />
+<hkern g1="Kappa" g2="uni03A9,Omega" k="61" />
+<hkern g1="Kappa" g2="beta" k="61" />
+<hkern g1="Kappa" g2="epsilontonos,epsilon" k="61" />
+<hkern g1="Kappa" g2="zeta" k="61" />
+<hkern g1="Kappa" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="82" />
+<hkern g1="Rho" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="287" />
+<hkern g1="Rho" g2="Alpha,uni0394,Lambda,Delta" k="102" />
+<hkern g1="Rho" g2="Tau" k="20" />
+<hkern g1="Rho" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="Rho" g2="Chi" k="41" />
+<hkern g1="Rho" g2="Zeta" k="41" />
+<hkern g1="Rho" g2="Iota,Iotadieresis" k="41" />
+<hkern g1="Sigma" g2="pi" k="102" />
+<hkern g1="Sigma" g2="gamma,nu" k="61" />
+<hkern g1="Sigma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="Sigma" g2="tau" k="102" />
+<hkern g1="Sigma" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="61" />
+<hkern g1="Tau" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="225" />
+<hkern g1="Tau" g2="colon,semicolon" k="143" />
+<hkern g1="Tau" g2="copyright,registered" k="102" />
+<hkern g1="Tau" g2="quoteleft,quotedblleft" k="-61" />
+<hkern g1="Tau" g2="quoteright,quotedblright" k="-61" />
+<hkern g1="Tau" g2="hyphen,endash,emdash,afii00208" k="82" />
+<hkern g1="Tau" g2="guillemotleft,guilsinglleft" k="143" />
+<hkern g1="Tau" g2="guillemotright,guilsinglright" k="123" />
+<hkern g1="Tau" g2="Alpha,uni0394,Lambda,Delta" k="164" />
+<hkern g1="Tau" g2="pi" k="225" />
+<hkern g1="Tau" g2="gamma,nu" k="184" />
+<hkern g1="Tau" g2="theta" k="61" />
+<hkern g1="Tau" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="205" />
+<hkern g1="Tau" g2="tau" k="225" />
+<hkern g1="Tau" g2="chi" k="215" />
+<hkern g1="Tau" g2="rho" k="174" />
+<hkern g1="Tau" g2="omega,omegatonos" k="164" />
+<hkern g1="Tau" g2="Theta,Omicron,Phi" k="61" />
+<hkern g1="Tau" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="205" />
+<hkern g1="Tau" g2="Chi" k="20" />
+<hkern g1="Tau" g2="lambda" k="82" />
+<hkern g1="Tau" g2="mu,etatonos,eta,uni03BC" k="184" />
+<hkern g1="Tau" g2="uni03A9,Omega" k="61" />
+<hkern g1="Tau" g2="beta" k="82" />
+<hkern g1="Tau" g2="epsilontonos,epsilon" k="215" />
+<hkern g1="Tau" g2="zeta" k="41" />
+<hkern g1="Tau" g2="kappa" k="184" />
+<hkern g1="Tau" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="205" />
+<hkern g1="Chi" g2="Tau" k="20" />
+<hkern g1="Chi" g2="Upsilon,Upsilondieresis" k="41" />
+<hkern g1="Chi" g2="pi" k="113" />
+<hkern g1="Chi" g2="gamma,nu" k="41" />
+<hkern g1="Chi" g2="theta" k="41" />
+<hkern g1="Chi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="Chi" g2="tau" k="143" />
+<hkern g1="Chi" g2="chi" k="41" />
+<hkern g1="Chi" g2="rho" k="41" />
+<hkern g1="Chi" g2="omega,omegatonos" k="41" />
+<hkern g1="Chi" g2="Theta,Omicron,Phi" k="41" />
+<hkern g1="Chi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="82" />
+<hkern g1="Chi" g2="mu,etatonos,eta,uni03BC" k="31" />
+<hkern g1="Chi" g2="uni03A9,Omega" k="61" />
+<hkern g1="Chi" g2="beta" k="20" />
+<hkern g1="Chi" g2="zeta" k="41" />
+<hkern g1="Chi" g2="kappa" k="41" />
+<hkern g1="Chi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="82" />
+<hkern g1="Psi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
+<hkern g1="Psi" g2="Alpha,uni0394,Lambda,Delta" k="61" />
+<hkern g1="Psi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="Psi" g2="lambda" k="41" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="pi" k="41" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="gamma,nu" k="41" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="theta" k="20" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="tau" k="41" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="chi" k="41" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="xi" k="31" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="epsilontonos,epsilon" k="20" />
+<hkern g1="iotadieresistonos,alphatonos,iotatonos,alpha,iota,iotadieresis" g2="zeta" k="20" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="41" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="quoteleft,quotedblleft" k="82" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="quoteright,quotedblright" k="82" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="gamma,nu" k="41" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="tau" k="41" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="chi" k="61" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="xi" k="20" />
+<hkern g1="beta,delta,omicron,rho,phi,omicrontonos" g2="lambda" k="20" />
+<hkern g1="omega,omegatonos" g2="quoteleft,quotedblleft" k="82" />
+<hkern g1="omega,omegatonos" g2="quoteright,quotedblright" k="102" />
+<hkern g1="omega,omegatonos" g2="pi" k="20" />
+<hkern g1="omega,omegatonos" g2="tau" k="41" />
+<hkern g1="omega,omegatonos" g2="chi" k="41" />
+<hkern g1="epsilontonos,epsilon" g2="pi" k="41" />
+<hkern g1="epsilontonos,epsilon" g2="gamma,nu" k="20" />
+<hkern g1="epsilontonos,epsilon" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="epsilontonos,epsilon" g2="chi" k="41" />
+<hkern g1="epsilontonos,epsilon" g2="xi" k="20" />
+<hkern g1="epsilontonos,epsilon" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="20" />
+<hkern g1="epsilontonos,epsilon" g2="lambda" k="20" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="pi" k="41" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="gamma,nu" k="20" />
+<hkern g1="mu,etatonos,eta,uni03BC" g2="tau" k="41" />
+<hkern g1="gamma,nu" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="123" />
+<hkern g1="chi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="chi" g2="quoteleft,quotedblleft" k="82" />
+<hkern g1="chi" g2="quoteright,quotedblright" k="61" />
+<hkern g1="chi" g2="pi" k="20" />
+<hkern g1="chi" g2="gamma,nu" k="41" />
+<hkern g1="chi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="chi" g2="tau" k="41" />
+<hkern g1="chi" g2="xi" k="61" />
+<hkern g1="chi" g2="omega,omegatonos" k="51" />
+<hkern g1="chi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="61" />
+<hkern g1="chi" g2="lambda" k="41" />
+<hkern g1="chi" g2="mu,etatonos,eta,uni03BC" k="20" />
+<hkern g1="chi" g2="epsilontonos,epsilon" k="41" />
+<hkern g1="chi" g2="zeta" k="41" />
+<hkern g1="chi" g2="kappa" k="20" />
+<hkern g1="chi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="41" />
+<hkern g1="zeta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="zeta" g2="hyphen,endash,emdash,afii00208" k="102" />
+<hkern g1="zeta" g2="pi" k="82" />
+<hkern g1="zeta" g2="gamma,nu" k="82" />
+<hkern g1="zeta" g2="theta" k="41" />
+<hkern g1="zeta" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="zeta" g2="tau" k="123" />
+<hkern g1="zeta" g2="omega,omegatonos" k="41" />
+<hkern g1="zeta" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="61" />
+<hkern g1="zeta" g2="epsilontonos,epsilon" k="20" />
+<hkern g1="zeta" g2="kappa" k="41" />
+<hkern g1="zeta" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="41" />
+<hkern g1="theta" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
+<hkern g1="theta" g2="gamma,nu" k="20" />
+<hkern g1="kappa" g2="hyphen,endash,emdash,afii00208" k="61" />
+<hkern g1="kappa" g2="pi" k="31" />
+<hkern g1="kappa" g2="gamma,nu" k="41" />
+<hkern g1="kappa" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="61" />
+<hkern g1="kappa" g2="tau" k="31" />
+<hkern g1="kappa" g2="chi" k="20" />
+<hkern g1="kappa" g2="xi" k="20" />
+<hkern g1="kappa" g2="omega,omegatonos" k="41" />
+<hkern g1="kappa" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="20" />
+<hkern g1="kappa" g2="epsilontonos,epsilon" k="31" />
+<hkern g1="kappa" g2="zeta" k="20" />
+<hkern g1="lambda" g2="quoteleft,quotedblleft" k="164" />
+<hkern g1="lambda" g2="quoteright,quotedblright" k="164" />
+<hkern g1="lambda" g2="pi" k="82" />
+<hkern g1="lambda" g2="gamma,nu" k="41" />
+<hkern g1="lambda" g2="theta" k="31" />
+<hkern g1="lambda" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="31" />
+<hkern g1="lambda" g2="tau" k="133" />
+<hkern g1="lambda" g2="chi" k="61" />
+<hkern g1="lambda" g2="xi" k="41" />
+<hkern g1="lambda" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="51" />
+<hkern g1="lambda" g2="zeta" k="41" />
+<hkern g1="xi" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="xi" g2="hyphen,endash,emdash,afii00208" k="41" />
+<hkern g1="xi" g2="pi" k="20" />
+<hkern g1="xi" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="41" />
+<hkern g1="xi" g2="tau" k="20" />
+<hkern g1="xi" g2="omega,omegatonos" k="20" />
+<hkern g1="xi" g2="iotadieresistonos,iotatonos,iota,iotadieresis" k="41" />
+<hkern g1="xi" g2="epsilontonos,epsilon" k="20" />
+<hkern g1="sigma" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="102" />
+<hkern g1="sigma" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="sigma" g2="xi" k="51" />
+<hkern g1="sigma" g2="omega,omegatonos" k="41" />
+<hkern g1="sigma" g2="lambda" k="41" />
+<hkern g1="sigma" g2="kappa" k="41" />
+<hkern g1="sigma1" g2="pi" k="-41" />
+<hkern g1="sigma1" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="20" />
+<hkern g1="sigma1" g2="tau" k="-20" />
+<hkern g1="sigma1" g2="xi" k="20" />
+<hkern g1="sigma1" g2="omega,omegatonos" k="20" />
+<hkern g1="sigma1" g2="lambda" k="41" />
+<hkern g1="tau" g2="hyphen,endash,emdash,afii00208" k="61" />
+<hkern g1="tau" g2="pi" k="-20" />
+<hkern g1="tau" g2="alphatonos,alpha,delta,omicron,sigma1,sigma,phi,omicrontonos" k="31" />
+<hkern g1="tau" g2="tau" k="-20" />
+<hkern g1="tau" g2="xi" k="20" />
+<hkern g1="tau" g2="omega,omegatonos" k="41" />
+<hkern g1="tau" g2="lambda" k="41" />
+<hkern g1="tau" g2="epsilontonos,epsilon" k="41" />
+<hkern g1="tau" g2="zeta" k="20" />
+<hkern g1="tau" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="20" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0410" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0422" k="61" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0408" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0442" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0443,uni045E" k="61" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0404,uni041E,uni0421,uni0424" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0425" k="41" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0405" k="72" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0430" k="61" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="61" />
+<hkern g1="uni040C,uni0416,uni041A" g2="uni0455" k="61" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="quoteleft,quotedblleft" k="61" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="quoteright,quotedblright" k="41" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="hyphen,endash,emdash,afii00208" k="-82" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0422" k="143" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0402,uni040B,uni042A" k="82" />
+<hkern g1="uni0409,uni040A,uni042A,uni042C" g2="uni0417,uni042D" k="-31" />
+<hkern g1="uni0411,uni0412,uni0417" g2="uni0422" k="61" />
+<hkern g1="uni0411,uni0412,uni0417" g2="uni0408" k="61" />
+<hkern g1="uni0403,uni0413,uni0490" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="410" />
+<hkern g1="uni0403,uni0413,uni0490" g2="colon,semicolon" k="205" />
+<hkern g1="uni0403,uni0413,uni0490" g2="hyphen,endash,emdash,afii00208" k="246" />
+<hkern g1="uni0403,uni0413,uni0490" g2="guillemotleft,guilsinglleft" k="205" />
+<hkern g1="uni0403,uni0413,uni0490" g2="guillemotright,guilsinglright" k="205" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0410" k="174" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0409,uni041B" k="143" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0408" k="205" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0402,uni040B,uni042A" k="-20" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni043B,uni0459" k="307" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0442" k="287" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0447" k="246" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni044A" k="287" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0443,uni045E" k="287" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0414" k="133" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0404,uni041E,uni0421,uni0424" k="82" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0405" k="41" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0430" k="266" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="307" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0455" k="307" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0417,uni042D" k="20" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni042F" k="41" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0431" k="61" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0434" k="328" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0436" k="307" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0437,uni044D" k="266" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="307" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni0445" k="307" />
+<hkern g1="uni0403,uni0413,uni0490" g2="uni044F" k="307" />
+<hkern g1="uni0400,uni0401,uni0415" g2="uni0409,uni041B" k="31" />
+<hkern g1="uni0400,uni0401,uni0415" g2="uni040E,uni0423" k="-31" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0410" k="41" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0409,uni041B" k="51" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0422" k="61" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0408" k="41" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0425" k="41" />
+<hkern g1="uni041E,uni0424,uni042D,uni042E" g2="uni0416" k="41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-61" />
+<hkern g1="uni0414,uni0426,uni0429" g2="colon,semicolon" k="-61" />
+<hkern g1="uni0414,uni0426,uni0429" g2="guillemotright,guilsinglright" k="-61" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0410" k="-61" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0409,uni041B" k="-51" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0408" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni043B,uni0459" k="-61" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0427" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0443,uni045E" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0414" k="-82" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0425" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0417,uni042D" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni042F" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0434" k="-61" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0436" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0437,uni044D" k="-41" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni040E,uni0423" k="-51" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0416" k="-20" />
+<hkern g1="uni0414,uni0426,uni0429" g2="uni0400,uni0401,uni0403,uni040A,uni040C,uni040D,uni040F,uni0411,uni0412,uni0413,uni0415,uni0418,uni0419,uni041A,uni041C,uni041D,uni041F,uni0420,uni0426,uni0428,uni0429,uni042B,uni042C,uni042E,uni0490" k="-20" />
+<hkern g1="uni0404,uni0421" g2="uni0408" k="20" />
+<hkern g1="uni0404,uni0421" g2="uni0414" k="-20" />
+<hkern g1="uni0404,uni0421" g2="uni0425" k="31" />
+<hkern g1="uni040E,uni0423" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="184" />
+<hkern g1="uni040E,uni0423" g2="colon,semicolon" k="123" />
+<hkern g1="uni040E,uni0423" g2="uni0410" k="143" />
+<hkern g1="uni040E,uni0423" g2="uni0409,uni041B" k="184" />
+<hkern g1="uni040E,uni0423" g2="uni0408" k="184" />
+<hkern g1="uni040E,uni0423" g2="uni043B,uni0459" k="184" />
+<hkern g1="uni040E,uni0423" g2="uni0427" k="-41" />
+<hkern g1="uni040E,uni0423" g2="uni0442" k="61" />
+<hkern g1="uni040E,uni0423" g2="uni0447" k="41" />
+<hkern g1="uni040E,uni0423" g2="uni044A" k="82" />
+<hkern g1="uni040E,uni0423" g2="uni0443,uni045E" k="41" />
+<hkern g1="uni040E,uni0423" g2="uni0414" k="123" />
+<hkern g1="uni040E,uni0423" g2="uni0404,uni041E,uni0421,uni0424" k="20" />
+<hkern g1="uni040E,uni0423" g2="uni0425" k="20" />
+<hkern g1="uni040E,uni0423" g2="uni0405" k="20" />
+<hkern g1="uni040E,uni0423" g2="uni0430" k="123" />
+<hkern g1="uni040E,uni0423" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="102" />
+<hkern g1="uni040E,uni0423" g2="uni0455" k="143" />
+<hkern g1="uni040E,uni0423" g2="uni0417,uni042D" k="20" />
+<hkern g1="uni040E,uni0423" g2="uni042F" k="41" />
+<hkern g1="uni040E,uni0423" g2="uni0434" k="164" />
+<hkern g1="uni040E,uni0423" g2="uni0436" k="82" />
+<hkern g1="uni040E,uni0423" g2="uni0437,uni044D" k="102" />
+<hkern g1="uni040E,uni0423" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="82" />
+<hkern g1="uni040E,uni0423" g2="uni0445" k="102" />
+<hkern g1="uni040E,uni0423" g2="uni044F" k="123" />
+<hkern g1="uni040E,uni0423" g2="uni0416" k="61" />
+<hkern g1="uni0410" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="uni0410" g2="colon,semicolon" k="-41" />
+<hkern g1="uni0410" g2="quoteleft,quotedblleft" k="184" />
+<hkern g1="uni0410" g2="quoteright,quotedblright" k="184" />
+<hkern g1="uni0410" g2="uni0422" k="164" />
+<hkern g1="uni0410" g2="uni0402,uni040B,uni042A" k="123" />
+<hkern g1="uni0410" g2="uni0447" k="41" />
+<hkern g1="uni0410" g2="uni044A" k="72" />
+<hkern g1="uni0410" g2="uni0404,uni041E,uni0421,uni0424" k="41" />
+<hkern g1="uni0410" g2="uni0430" k="20" />
+<hkern g1="uni0410" g2="uni0416" k="41" />
+<hkern g1="uni0420" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="287" />
+<hkern g1="uni0420" g2="uni0410" k="102" />
+<hkern g1="uni0420" g2="uni0409,uni041B" k="133" />
+<hkern g1="uni0420" g2="uni0422" k="20" />
+<hkern g1="uni0420" g2="uni0408" k="143" />
+<hkern g1="uni0420" g2="uni043B,uni0459" k="123" />
+<hkern g1="uni0420" g2="uni0427" k="-51" />
+<hkern g1="uni0420" g2="uni0447" k="-41" />
+<hkern g1="uni0420" g2="uni0414" k="102" />
+<hkern g1="uni0420" g2="uni0425" k="41" />
+<hkern g1="uni0420" g2="uni0405" k="-31" />
+<hkern g1="uni0420" g2="uni0430" k="20" />
+<hkern g1="uni0420" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="20" />
+<hkern g1="uni0420" g2="uni0434" k="123" />
+<hkern g1="uni0402,uni040B" g2="quoteleft,quotedblleft" k="143" />
+<hkern g1="uni0402,uni040B" g2="quoteright,quotedblright" k="143" />
+<hkern g1="uni0402,uni040B" g2="hyphen,endash,emdash,afii00208" k="-41" />
+<hkern g1="uni0402,uni040B" g2="parenright,bracketright,braceright" k="20" />
+<hkern g1="uni0402,uni040B" g2="uni0422" k="143" />
+<hkern g1="uni0422" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="225" />
+<hkern g1="uni0422" g2="colon,semicolon" k="143" />
+<hkern g1="uni0422" g2="hyphen,endash,emdash,afii00208" k="102" />
+<hkern g1="uni0422" g2="guillemotleft,guilsinglleft" k="143" />
+<hkern g1="uni0422" g2="guillemotright,guilsinglright" k="123" />
+<hkern g1="uni0422" g2="uni0410" k="164" />
+<hkern g1="uni0422" g2="uni0409,uni041B" k="143" />
+<hkern g1="uni0422" g2="uni0408" k="143" />
+<hkern g1="uni0422" g2="uni043B,uni0459" k="246" />
+<hkern g1="uni0422" g2="uni0427" k="-31" />
+<hkern g1="uni0422" g2="uni0442" k="205" />
+<hkern g1="uni0422" g2="uni0447" k="184" />
+<hkern g1="uni0422" g2="uni044A" k="184" />
+<hkern g1="uni0422" g2="uni0443,uni045E" k="143" />
+<hkern g1="uni0422" g2="uni0414" k="123" />
+<hkern g1="uni0422" g2="uni0404,uni041E,uni0421,uni0424" k="61" />
+<hkern g1="uni0422" g2="uni0425" k="20" />
+<hkern g1="uni0422" g2="uni0405" k="41" />
+<hkern g1="uni0422" g2="uni0430" k="205" />
+<hkern g1="uni0422" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="205" />
+<hkern g1="uni0422" g2="uni0455" k="242" />
+<hkern g1="uni0422" g2="uni042F" k="41" />
+<hkern g1="uni0422" g2="uni0431" k="61" />
+<hkern g1="uni0422" g2="uni0434" k="246" />
+<hkern g1="uni0422" g2="uni0436" k="184" />
+<hkern g1="uni0422" g2="uni0437,uni044D" k="184" />
+<hkern g1="uni0422" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="184" />
+<hkern g1="uni0422" g2="uni0445" k="205" />
+<hkern g1="uni0422" g2="uni044F" k="184" />
+<hkern g1="uni0425" g2="uni0422" k="20" />
+<hkern g1="uni0425" g2="uni0404,uni041E,uni0421,uni0424" k="41" />
+<hkern g1="uni0425" g2="uni0405" k="20" />
+<hkern g1="uni0425" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="61" />
+<hkern g1="uni0425" g2="uni040E,uni0423" k="-20" />
+<hkern g1="uni0405" g2="uni0409,uni041B" k="31" />
+<hkern g1="uni0405" g2="uni0422" k="41" />
+<hkern g1="uni0405" g2="uni0408" k="61" />
+<hkern g1="uni0405" g2="uni0442" k="41" />
+<hkern g1="uni0405" g2="uni0425" k="20" />
+<hkern g1="uni0405" g2="uni0434" k="41" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0442" k="31" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0443,uni045E" k="10" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0434" k="41" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0436" k="20" />
+<hkern g1="uni0431,uni043E,uni0440,uni0444,uni044D,uni044E" g2="uni0445" k="20" />
+<hkern g1="uni0433,uni0453,uni0491" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="205" />
+<hkern g1="uni0433,uni0453,uni0491" g2="colon,semicolon" k="-41" />
+<hkern g1="uni0433,uni0453,uni0491" g2="quoteleft,quotedblleft" k="-41" />
+<hkern g1="uni0433,uni0453,uni0491" g2="quoteright,quotedblright" k="-41" />
+<hkern g1="uni0433,uni0453,uni0491" g2="hyphen,endash,emdash,afii00208" k="143" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni043B,uni0459" k="123" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0442" k="-41" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni044A" k="-51" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0430" k="20" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="20" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni0434" k="123" />
+<hkern g1="uni0433,uni0453,uni0491" g2="uni044F" k="20" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0430" k="31" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="20" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0455" k="20" />
+<hkern g1="uni0436,uni043A,uni045C" g2="uni0431" k="20" />
+<hkern g1="uni0434,uni0446,uni0449" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="-41" />
+<hkern g1="uni0434,uni0446,uni0449" g2="colon,semicolon" k="-41" />
+<hkern g1="uni0434,uni0446,uni0449" g2="guillemotright,guilsinglright" k="-41" />
+<hkern g1="uni0434,uni0446,uni0449" g2="parenright,bracketright,braceright" k="-41" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni043B,uni0459" k="-51" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0443,uni045E" k="-41" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0431" k="-31" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0434" k="-61" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0436" k="-20" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0437,uni044D" k="-20" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0432,uni0433,uni0438,uni0439,uni043A,uni043C,uni043D,uni043F,uni0440,uni0446,uni0448,uni0449,uni044B,uni044C,uni044E,uni0453,uni0456,uni0457,uni0458,uni045A,uni045C,uni045D,uni045F,uni0491" k="-20" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni0445" k="-31" />
+<hkern g1="uni0434,uni0446,uni0449" g2="uni044F" k="-31" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni043B,uni0459" k="-20" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni0442" k="41" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni044A" k="61" />
+<hkern g1="uni044A,uni044C,uni0459,uni045A" g2="uni0434" k="-20" />
+<hkern g1="uni0430" g2="uni0442" k="31" />
+<hkern g1="uni0430" g2="uni044A" k="20" />
+<hkern g1="uni0443,uni045E" g2="parenright,bracketright,braceright" k="61" />
+<hkern g1="uni0443,uni045E" g2="uni043B,uni0459" k="61" />
+<hkern g1="uni0443,uni045E" g2="uni0430" k="20" />
+<hkern g1="uni0443,uni045E" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="41" />
+<hkern g1="uni0443,uni045E" g2="uni0455" k="31" />
+<hkern g1="uni0443,uni045E" g2="uni0434" k="82" />
+<hkern g1="uni0443,uni045E" g2="uni0445" k="31" />
+<hkern g1="uni0443,uni045E" g2="uni044F" k="31" />
+<hkern g1="uni0442" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
+<hkern g1="uni0442" g2="uni043B,uni0459" k="102" />
+<hkern g1="uni0442" g2="uni0442" k="-41" />
+<hkern g1="uni0442" g2="uni0447" k="-20" />
+<hkern g1="uni0442" g2="uni044A" k="-41" />
+<hkern g1="uni0442" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="31" />
+<hkern g1="uni0442" g2="uni0434" k="82" />
+<hkern g1="uni0445" g2="uni0435,uni043E,uni0441,uni0444,uni0450,uni0451,uni0454" k="20" />
+<hkern g1="uni0455" g2="uni0445" k="20" />
+<hkern g1="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" g2="tau" k="20" />
+<hkern g1="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" g2="chi" k="20" />
+<hkern g1="uni0408" g2="uni0410" k="20" />
+<hkern g1="uni0408" g2="uni0409,uni041B" k="41" />
+<hkern g1="uni0408" g2="uni0408" k="61" />
+<hkern g1="uni0408" g2="uni043B,uni0459" k="41" />
+<hkern g1="uni0408" g2="uni0427" k="-41" />
+<hkern g1="uni0408" g2="uni0414" k="102" />
+<hkern g1="uni0408" g2="uni0425" k="20" />
+<hkern g1="uni0408" g2="uni0434" k="41" />
+<hkern g1="V" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="92" />
+<hkern g1="V" g2="J,Jcircumflex" k="143" />
<hkern g1="V" g2="X" k="20" />
-<hkern g1="V" g2="Y,Yacute,Ydieresis" k="41" />
+<hkern g1="V" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="41" />
<hkern g1="V" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="143" />
-<hkern g1="V" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,OE" k="41" />
-<hkern g1="V" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="61" />
-<hkern g1="V" g2="t" k="31" />
-<hkern g1="V" g2="z" k="41" />
+<hkern g1="V" g2="C,G,O,Q,Ccedilla,Ograve,Oacute,Ocircumflex,Otilde,Odieresis,Oslash,Cacute,Ccircumflex,Cdotaccent,Ccaron,Gcircumflex,Gbreve,Gdotaccent,Gcommaaccent,Omacron,Obreve,Ohungarumlaut,OE,Ohorn,Ocaron,Oslashacute,Odotbelow,Ohookabove,Ocircumflexacute,Ocircumflexgrave,Ocircumflexhookabove,Ocircumflextilde,Ocircumflexdotbelow,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" k="41" />
+<hkern g1="V" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="61" />
+<hkern g1="V" g2="t,uni0163,tcaron,tbar,uni021B" k="31" />
+<hkern g1="V" g2="z,zacute,zdotaccent,zcaron" k="41" />
<hkern g1="V" g2="copyright,registered" k="41" />
-<hkern g1="V" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="61" />
-<hkern g1="V" g2="S" k="10" />
-<hkern g1="V" g2="m,n,p,r,ntilde" k="61" />
-<hkern g1="V" g2="s" k="61" />
-<hkern g1="V" g2="u,ugrave,uacute,ucircumflex,udieresis" k="61" />
+<hkern g1="V" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="V" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="10" />
+<hkern g1="V" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="61" />
+<hkern g1="V" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="61" />
+<hkern g1="V" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="61" />
<hkern g1="V" g2="x" k="31" />
-<hkern g1="V" g2="y,yacute,ydieresis" k="20" />
-<hkern g1="V" g2="AE" k="82" />
-<hkern g1="V" g2="f,uniFB01,uniFB02,uniFB03,uniFB04" k="20" />
-<hkern g1="V" g2="b,h,k,l,germandbls,thorn" k="31" />
+<hkern g1="V" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="20" />
+<hkern g1="V" g2="AE,AEacute" k="82" />
+<hkern g1="V" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="20" />
+<hkern g1="V" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="31" />
+<hkern g1="pi" g2="hyphen,endash,emdash,afii00208" k="61" />
+<hkern g1="pi" g2="xi" k="20" />
+<hkern g1="pi" g2="lambda" k="41" />
+<hkern g1="pi" g2="epsilontonos,epsilon" k="41" />
+<hkern g1="pi" g2="zeta" k="20" />
+<hkern g1="pi" g2="upsilondieresistonos,upsilon,psi,upsilondieresis,upsilontonos" k="20" />
<hkern g1="v" g2="comma,period,quotesinglbase,quotedblbase,ellipsis" k="61" />
-<hkern g1="v" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae" k="31" />
-<hkern g1="v" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,oe" k="20" />
-<hkern g1="v" g2="s" k="20" />
+<hkern g1="v" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="31" />
+<hkern g1="v" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="20" />
+<hkern g1="v" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="20" />
<hkern g1="v" g2="v" k="20" />
-<hkern g1="v" g2="y,yacute,ydieresis" k="10" />
+<hkern g1="v" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="10" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="102" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="J,Jcircumflex" k="123" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-102" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="V" k="-61" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-41" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="X" k="-61" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="-82" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="51" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-41" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="Z,Zacute,Zdotaccent,Zcaron" k="-41" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="-61" />
+<hkern g1="Ohorn,Ohornacute,Ohorngrave,Ohornhookabove,Ohorntilde,Ohorndotbelow" g2="B,D,E,F,H,K,L,M,N,P,R,Egrave,Eacute,Ecircumflex,Edieresis,Eth,Ntilde,Thorn,Dcaron,Dcroat,Emacron,Ebreve,Edotaccent,Eogonek,Ecaron,Hcircumflex,Hbar,Kcommaaccent,Lacute,Lcommaaccent,Lcaron,Ldot,Lslash,Nacute,Ncommaaccent,Ncaron,Eng,Racute,Rcommaaccent,Rcaron,Eszett,Edotbelow,Ehookabove,Etilde,Ecircumflexacute,Ecircumflexgrave,Ecircumflexhookabove,Ecircumflextilde,Ecircumflexdotbelow" k="-41" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="-41" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="-102" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="z,zacute,zdotaccent,zcaron" k="-82" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="-41" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="-20" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="-31" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="-31" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="v" k="-41" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="-41" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="x" k="-61" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-61" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-82" />
+<hkern g1="ohorn,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="-41" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Aring,Amacron,Abreve,Aogonek,Acaron,Aringacute,Adotbelow,Ahookabove,Acircumflexacute,Acircumflexgrave,Acircumflexhookabove,Acircumflextilde,Acircumflexdotbelow,Abreveacute,Abrevegrave,Abrevehookabove,Abrevetilde,Abrevedotbelow" k="82" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="J,Jcircumflex" k="143" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="T,uni0162,Tcaron,Tbar,uni021A" k="-82" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="V" k="-82" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="W,Wcircumflex,Wgrave,Wacute,Wdieresis" k="-82" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="X" k="-82" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="Y,Yacute,Ycircumflex,Ydieresis,Ygrave,Ydotbelow,Yhookabove,Ytilde" k="-82" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="61" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="S,Sacute,Scircumflex,Scedilla,Scaron,Scommaaccent" k="-41" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="Z,Zacute,Zdotaccent,Zcaron" k="-41" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="I,Igrave,Iacute,Icircumflex,Idieresis,Itilde,Imacron,Ibreve,Iogonek,Idotaccent,IJ,Icaron,Ihookabove,Idotbelow" k="-82" />
+<hkern g1="Uhorn,Uhornacute,Uhorngrave,Uhornhookabove,Uhorntilde,Uhorndotbelow" g2="B,D,E,F,H,K,L,M,N,P,R,Egrave,Eacute,Ecircumflex,Edieresis,Eth,Ntilde,Thorn,Dcaron,Dcroat,Emacron,Ebreve,Edotaccent,Eogonek,Ecaron,Hcircumflex,Hbar,Kcommaaccent,Lacute,Lcommaaccent,Lcaron,Ldot,Lslash,Nacute,Ncommaaccent,Ncaron,Eng,Racute,Rcommaaccent,Rcaron,Eszett,Edotbelow,Ehookabove,Etilde,Ecircumflexacute,Ecircumflexgrave,Ecircumflexhookabove,Ecircumflextilde,Ecircumflexdotbelow" k="-61" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="t,uni0163,tcaron,tbar,uni021B" k="-82" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="z,zacute,zdotaccent,zcaron" k="-41" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="-41" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="-41" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="u,ugrave,uacute,ucircumflex,udieresis,utilde,umacron,ubreve,uring,uhungarumlaut,uogonek,uhorn,ucaron,udieresismacron,udieresisacute,udieresiscaron,udieresisgrave,udotbelow,uhookabove,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" k="-41" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="v" k="-82" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="w,wcircumflex,wgrave,wacute,wdieresis" k="-61" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="x" k="-61" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="y,yacute,ydieresis,ycircumflex,ygrave,ydotbelow,yhookabove,ytilde" k="-82" />
+<hkern g1="uhorn,uhornacute,uhorngrave,uhornhookabove,uhorntilde,uhorndotbelow" g2="f,longs,f_i,f_l,f_f,fi,fl,f_f_i,f_f_l" k="-82" />
+<hkern g1="longs" g2="a,agrave,aacute,acircumflex,atilde,adieresis,aring,ae,amacron,abreve,aogonek,acaron,aringacute,aeacute,adotbelow,ahookabove,acircumflexacute,acircumflexgrave,acircumflexhookabove,acircumflextilde,acircumflexdotbelow,abreveacute,abrevegrave,abrevehookabove,abrevetilde,abrevedotbelow" k="31" />
+<hkern g1="longs" g2="t,uni0163,tcaron,tbar,uni021B" k="20" />
+<hkern g1="longs" g2="c,d,e,g,o,q,ccedilla,egrave,eacute,ecircumflex,edieresis,eth,ograve,oacute,ocircumflex,otilde,odieresis,oslash,cacute,ccircumflex,cdotaccent,ccaron,dcaron,dcroat,emacron,ebreve,edotaccent,eogonek,ecaron,gcircumflex,gbreve,gdotaccent,gcommaaccent,omacron,obreve,ohungarumlaut,oe,ohorn,ocaron,oslashacute,edotbelow,ehookabove,etilde,ecircumflexacute,ecircumflexgrave,ecircumflexhookabove,ecircumflextilde,ecircumflexdotbelow,odotbelow,ohookabove,ocircumflexacute,ocircumflexgrave,ocircumflexhookabove,ocircumflextilde,ocircumflexdotbelow,ohornacute,ohorngrave,ohornhookabove,ohorntilde,ohorndotbelow" k="31" />
+<hkern g1="longs" g2="i,j,igrave,iacute,icircumflex,idieresis,itilde,imacron,ibreve,iogonek,ij,jcircumflex,icaron,dotlessj,ihookabove,idotbelow" k="-20" />
+<hkern g1="longs" g2="m,n,p,r,ntilde,dotlessi,kgreenlandic,nacute,ncommaaccent,ncaron,eng,racute,rcommaaccent,rcaron" k="31" />
+<hkern g1="longs" g2="s,sacute,scircumflex,scedilla,scaron,scommaaccent" k="20" />
+<hkern g1="longs" g2="b,h,k,l,germandbls,thorn,hcircumflex,hbar,kcommaaccent,lacute,lcommaaccent,lcaron,ldot,lslash" k="-31" />
</font>
</defs></svg> \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.ttf b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.ttf
index 2c7356bc9..434c750d0 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.ttf
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.ttf
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.woff b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.woff
index 9d58858d8..03bd4a337 100755
--- a/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.woff
+++ b/Duplicati/Server/webroot/ngax/fonts/ClearSans-Regular-webfont.woff
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/arrow_collapse_blue.png b/Duplicati/Server/webroot/ngax/img/arrow_collapse_blue.png
new file mode 100644
index 000000000..0bf726599
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/arrow_collapse_blue.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/arrow_collapse_green.png b/Duplicati/Server/webroot/ngax/img/arrow_collapse_green.png
new file mode 100644
index 000000000..8282f154d
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/arrow_collapse_green.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/arrow_expand_blue.png b/Duplicati/Server/webroot/ngax/img/arrow_expand_blue.png
new file mode 100644
index 000000000..5d7e101a2
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/arrow_expand_blue.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/arrow_expand_green.png b/Duplicati/Server/webroot/ngax/img/arrow_expand_green.png
new file mode 100644
index 000000000..370eb5f3d
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/arrow_expand_green.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/backup.png b/Duplicati/Server/webroot/ngax/img/backup.png
index 6cda805a6..157fdb9c3 100755
--- a/Duplicati/Server/webroot/ngax/img/backup.png
+++ b/Duplicati/Server/webroot/ngax/img/backup.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/clippy.png b/Duplicati/Server/webroot/ngax/img/clippy.png
new file mode 100644
index 000000000..0410c163b
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/clippy.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/donate/bitcoin.png b/Duplicati/Server/webroot/ngax/img/donate/bitcoin.png
index 25b9c27de..439758efe 100644
--- a/Duplicati/Server/webroot/ngax/img/donate/bitcoin.png
+++ b/Duplicati/Server/webroot/ngax/img/donate/bitcoin.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/donate/paypal.png b/Duplicati/Server/webroot/ngax/img/donate/paypal.png
index 1567a4c74..96193d2d5 100644
--- a/Duplicati/Server/webroot/ngax/img/donate/paypal.png
+++ b/Duplicati/Server/webroot/ngax/img/donate/paypal.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/about.png b/Duplicati/Server/webroot/ngax/img/mainmenu/about.png
new file mode 100644
index 000000000..34fe4f2c2
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/about.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/add.png b/Duplicati/Server/webroot/ngax/img/mainmenu/add.png
index 26e5c654a..c621caa91 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/add.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/add.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/arrow_down.png b/Duplicati/Server/webroot/ngax/img/mainmenu/arrow_down.png
new file mode 100644
index 000000000..494cff086
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/arrow_down.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/arrow_right.png b/Duplicati/Server/webroot/ngax/img/mainmenu/arrow_right.png
new file mode 100644
index 000000000..4ed6ccd6a
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/arrow_right.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/home.png b/Duplicati/Server/webroot/ngax/img/mainmenu/home.png
new file mode 100644
index 000000000..25a5bec72
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/home.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/log.png b/Duplicati/Server/webroot/ngax/img/mainmenu/log.png
index 87c120b8b..e245b4137 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/log.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/log.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/logout.png b/Duplicati/Server/webroot/ngax/img/mainmenu/logout.png
new file mode 100644
index 000000000..3827da043
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/logout.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/about.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/about.png
new file mode 100644
index 000000000..9e0249e77
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/about.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/add.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/add.png
index b5c07f4e2..1978b1400 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/over/add.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/add.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/arrow_down.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/arrow_down.png
new file mode 100644
index 000000000..6930aca8a
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/arrow_down.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/arrow_right.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/arrow_right.png
new file mode 100644
index 000000000..16810af6f
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/arrow_right.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/home.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/home.png
new file mode 100644
index 000000000..c77fd8910
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/home.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/log.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/log.png
index 87e205939..c4ae7d7b5 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/over/log.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/log.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/logout.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/logout.png
new file mode 100644
index 000000000..64ee4ab65
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/logout.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/pause.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/pause.png
index a7abe60c3..fd8943fa1 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/over/pause.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/pause.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/restore.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/restore.png
index 7240774ea..4d26cd53d 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/over/restore.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/restore.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/resume.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/resume.png
new file mode 100644
index 000000000..0eb5d077b
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/resume.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/over/settings.png b/Duplicati/Server/webroot/ngax/img/mainmenu/over/settings.png
index 9e1834569..d42959aad 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/over/settings.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/over/settings.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/pause.png b/Duplicati/Server/webroot/ngax/img/mainmenu/pause.png
index 3cfa54a69..4af2b2f9b 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/pause.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/pause.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/restore.png b/Duplicati/Server/webroot/ngax/img/mainmenu/restore.png
index ba01a1f19..a356d0982 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/restore.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/restore.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/resume.png b/Duplicati/Server/webroot/ngax/img/mainmenu/resume.png
new file mode 100644
index 000000000..1252a9884
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/resume.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/mainmenu/settings.png b/Duplicati/Server/webroot/ngax/img/mainmenu/settings.png
index ca10ffbde..43f2a5408 100755
--- a/Duplicati/Server/webroot/ngax/img/mainmenu/settings.png
+++ b/Duplicati/Server/webroot/ngax/img/mainmenu/settings.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/menu.png b/Duplicati/Server/webroot/ngax/img/menu.png
index 42b548654..0276764d1 100755
--- a/Duplicati/Server/webroot/ngax/img/menu.png
+++ b/Duplicati/Server/webroot/ngax/img/menu.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/menu_active.png b/Duplicati/Server/webroot/ngax/img/menu_active.png
index 46f9a873a..91af174bd 100755
--- a/Duplicati/Server/webroot/ngax/img/menu_active.png
+++ b/Duplicati/Server/webroot/ngax/img/menu_active.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/pause.png b/Duplicati/Server/webroot/ngax/img/pause.png
new file mode 100755
index 000000000..4af2b2f9b
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/pause.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/progress-resume.png b/Duplicati/Server/webroot/ngax/img/progress-resume.png
new file mode 100644
index 000000000..afd6e9035
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/progress-resume.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/progress-stop.png b/Duplicati/Server/webroot/ngax/img/progress-stop.png
new file mode 100644
index 000000000..2d916ebb8
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/progress-stop.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/resume.png b/Duplicati/Server/webroot/ngax/img/resume.png
new file mode 100644
index 000000000..1252a9884
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/resume.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/social/duplicati.png b/Duplicati/Server/webroot/ngax/img/social/duplicati.png
new file mode 100644
index 000000000..3d8b785c5
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/social/duplicati.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/social/facebook.png b/Duplicati/Server/webroot/ngax/img/social/facebook.png
index 6b0f151a9..57e98ebf0 100755
--- a/Duplicati/Server/webroot/ngax/img/social/facebook.png
+++ b/Duplicati/Server/webroot/ngax/img/social/facebook.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/social/ggroups.png b/Duplicati/Server/webroot/ngax/img/social/ggroups.png
index 174731912..1a976ee76 100644
--- a/Duplicati/Server/webroot/ngax/img/social/ggroups.png
+++ b/Duplicati/Server/webroot/ngax/img/social/ggroups.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/social/github.png b/Duplicati/Server/webroot/ngax/img/social/github.png
index 5cb74a349..8141ba806 100755
--- a/Duplicati/Server/webroot/ngax/img/social/github.png
+++ b/Duplicati/Server/webroot/ngax/img/social/github.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/social/google.png b/Duplicati/Server/webroot/ngax/img/social/google.png
index 4c061b100..6d3355c17 100755
--- a/Duplicati/Server/webroot/ngax/img/social/google.png
+++ b/Duplicati/Server/webroot/ngax/img/social/google.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/steps/line-out.png b/Duplicati/Server/webroot/ngax/img/steps/line-out.png
index 1574b0214..105481955 100755
--- a/Duplicati/Server/webroot/ngax/img/steps/line-out.png
+++ b/Duplicati/Server/webroot/ngax/img/steps/line-out.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/three_dots.png b/Duplicati/Server/webroot/ngax/img/three_dots.png
new file mode 100644
index 000000000..036bc008b
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/three_dots.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/throttle-inactive.png b/Duplicati/Server/webroot/ngax/img/throttle-inactive.png
new file mode 100644
index 000000000..046ada18e
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/throttle-inactive.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/throttle.png b/Duplicati/Server/webroot/ngax/img/throttle.png
new file mode 100644
index 000000000..a87690622
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/img/throttle.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/img/treeicons.png b/Duplicati/Server/webroot/ngax/img/treeicons.png
index 488418292..71110da04 100644
--- a/Duplicati/Server/webroot/ngax/img/treeicons.png
+++ b/Duplicati/Server/webroot/ngax/img/treeicons.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/index.html b/Duplicati/Server/webroot/ngax/index.html
index 572163cce..ca53e89f1 100755
--- a/Duplicati/Server/webroot/ngax/index.html
+++ b/Duplicati/Server/webroot/ngax/index.html
@@ -1,9 +1,9 @@
<!DOCTYPE html>
-<html xmlns:ng="http://angularjs.org" ng-app="backupApp">
+<html xmlns:ng="http://angularjs.org" ng-app="backupApp" ng-controller="AppController">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
- <title>Duplicati</title>
+ <title ng-bind-template="{{systemInfo.MachineName}} - {{brandingService.appName}}"></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
@@ -26,8 +26,8 @@
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" type="text/css" href="styles/smoothness/jquery-ui.min.css">
- <link rel="stylesheet" type="text/css" href="styles/styles2.css">
<link rel="stylesheet" type="text/css" href="styles/style.css">
+ <link rel="stylesheet" type="text/css" href="styles/themes.css">
<link rel="stylesheet" type="text/css" href="../oem/ngax/styles/oem.css" />
<link rel="stylesheet" type="text/css" href="../customized/customized.css" />
@@ -51,6 +51,8 @@
<script type="text/javascript" src="scripts/libs/modal.min.js"></script>
<script type="text/javascript" src="scripts/libs/dxTree.js"></script>
<script type="text/javascript" src="scripts/libs/moment-with-locales.min.js"></script>
+ <script type="text/javascript" src="scripts/libs/clipboard.min.js"></script>
+ <script type="text/javascript" src="scripts/libs/ngclipboard.min.js"></script>
<script type="text/javascript" src="scripts/libs/angular-gettext.min.js"></script>
@@ -70,6 +72,7 @@
<script type="text/javascript" src="scripts/services/NotificationService.js"></script>
<script type="text/javascript" src="scripts/services/DialogService.js"></script>
<script type="text/javascript" src="scripts/services/EditBackupService.js"></script>
+ <script type="text/javascript" src="scripts/services/CaptchaService.js"></script>
<script type="text/javascript" src="scripts/controllers/AppController.js"></script>
<script type="text/javascript" src="scripts/controllers/AboutController.js"></script>
@@ -77,7 +80,6 @@
<script type="text/javascript" src="scripts/controllers/SystemSettingsController.js"></script>
<script type="text/javascript" src="scripts/controllers/HomeController.js"></script>
<script type="text/javascript" src="scripts/controllers/EditBackupController.js"></script>
- <script type="text/javascript" src="scripts/controllers/PauseController.js"></script>
<script type="text/javascript" src="scripts/controllers/RestoreController.js"></script>
<script type="text/javascript" src="scripts/controllers/RestoreDirectController.js"></script>
<script type="text/javascript" src="scripts/controllers/LogController.js"></script>
@@ -86,6 +88,13 @@
<script type="text/javascript" src="scripts/controllers/UpdateChangelogController.js"></script>
<script type="text/javascript" src="scripts/controllers/DialogController.js"></script>
<script type="text/javascript" src="scripts/controllers/LocalDatabaseController.js"></script>
+ <script type="text/javascript" src="scripts/controllers/DeleteController.js"></script>
+ <script type="text/javascript" src="scripts/controllers/CaptchaController.js"></script>
+ <script type="text/javascript" src="scripts/controllers/RestoreWizardController.js"></script>
+ <script type="text/javascript" src="scripts/controllers/AddWizardController.js"></script>
+ <script type="text/javascript" src="scripts/controllers/PauseController.js"></script>
+ <script type="text/javascript" src="scripts/controllers/CommandlineController.js"></script>
+ <script type="text/javascript" src="scripts/controllers/ThrottleController.js"></script>
<script type="text/javascript" src="scripts/filters/timeremaining.js"></script>
<script type="text/javascript" src="scripts/filters/highlight.js"></script>
@@ -105,56 +114,120 @@
<script type="text/javascript" src="scripts/directives/notificationArea.js"></script>
<script type="text/javascript" src="scripts/directives/progressBar.js"></script>
<script type="text/javascript" src="scripts/directives/advancedOptionsEditor.js"></script>
+ <script type="text/javascript" src="scripts/directives/timeFormatFixer.js"></script>
<script type="text/javascript" src="../package/ngax/package.js"></script>
<script type="text/javascript" src="../oem/ngax/scripts/oem.js"></script>
<script type="text/javascript" src="../customized/customized.js"></script>
</head>
-<body ng-controller="AppController">
+<body class="theme-{{active_theme}}">
<div class="container">
<div class="header">
<div class="logo">
- <a href="#/" class="home">{{brandingService.appName}}</a>
- <div class="build-suffix" ng-hide="systemInfo.ServerVersionType == 'stable' || systemInfo.ServerVersionType == ''">{{systemInfo.ServerVersionType}}</div>
- <div class="powered-by">{{brandingService.appSubtitle}}</div>
+ <a href="#/">
+ <img class="mainlogo" ng-src="{{brandingService.appLogoPath}}"/>
+ </a>
+
+ <div class="logotext">
+ <a href="#/" class="home">{{brandingService.appName}}</a>
+ <div class="build-suffix" ng-hide="systemInfo.ServerVersionType == 'stable' || systemInfo.ServerVersionType == ''">{{systemInfo.ServerVersionType}}</div>
+ <div class="powered-by">{{brandingService.appSubtitle}}</div>
+ </div>
</div>
-
+
<div class="donate" ng-hide="systemInfo.SuppressDonationMessages">
<span translate>Donate</span>
<ul>
<li>
- <a href="bitcoin:1L74qa1n5SFKwwyHhECTHBJgcf6WT2rJKf" target="_blank"><img src="img/donate/bitcoin.png" alt="{{'Donate with Bitcoins' | translate}}" /></a>
+ <a href="bitcoin:1L74qa1n5SFKwwyHhECTHBJgcf6WT2rJKf" target="_blank"><img src="img/donate/bitcoin.png" alt="{{'Donate with Bitcoins' | translate}}" title="{{'Donate with Bitcoins' | translate}}" /></a>
</li>
<li>
- <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal%40hexad%2edk&item_name=Duplicati%20Donation&no_shipping=2&no_note=1&tax=0&currency_code=EUR&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=US" target="_blank"><img src="img/donate/paypal.png" alt="{{'Donate with PayPal' | translate}}" /></a>
+ <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal%40hexad%2edk&item_name=Duplicati%20Donation&no_shipping=2&no_note=1&tax=0&currency_code=EUR&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=US" target="_blank"><img src="img/donate/paypal.png" alt="{{'Donate with PayPal' | translate}}" title="{{'Donate with PayPal' | translate}}" /></a>
</li>
</ul>
</div>
-
+
<a href class="menubutton hidden" data-target="mainmenu" translate>Menu</a>
+
+ <div class="action-icons-small">
+ <div class="pause" ng-class="{'active': state.programState != 'Running'}" ng-click="pauseOptions()" title="{{state.programState == 'Running' ? 'Click to see the pause options' : 'Click to resume'}}"></div>
+ <div class="throttle {{throttle_active ? 'active' : 'inactive'}}" ng-click="throttleOptions()" title="{{'Click to set throttle options' | translate}}" alt="{{'Click to set throttle options' | translate}}"></div>
+ </div>
+
+ <div class="statepadding">
+ <div class="state" ng-controller="StateController">
+ <div class="content">
+ <div ng-hide="state.activeTask == null">
+ <span ng-hide="activeBackup == null">
+ <span ng-hide="StopReqId == activeTaskID">
+ <strong>{{activeBackup.Backup.Name}}:</strong> {{StateText}}
+ </span>
+ <span ng-show="StopReqId == activeTaskID">
+ <strong translate>Stopping after upload:</strong> {{activeBackup.Backup.Name}}
+ </span>
+ </span>
+ <span ng-show="activeBackup == null">
+ <strong ng-hide="StopReqId == activeTaskID" translate>Running task:</strong>
+ <strong ng-show="StopReqId == activeTaskID" translate>Stopping task:</strong>
+ {{StateText}}
+ </span>
+
+ </div>
+
+ <div ng-show="state.activeTask == null &amp;&amp; nextTask != null">
+ <strong translate>Next task:</strong> {{nextTask.Backup.Name}}
+ </div>
+
+ <div ng-show="state.activeTask == null &amp;&amp; nextTask == null &amp;&amp; nextScheduledTask != null"><strong translate>Next scheduled task:</strong> {{nextScheduledTask.Backup.Name}} <span title="{{nextScheduledTime | parsetimestamp}}">{{nextScheduledTime | moment: 'calendar'}}</span></div>
+
+ <div ng-show="state.activeTask == null &amp;&amp; nextTask == null &amp;&amp; nextScheduledTask == null" translate>No scheduled tasks</div>
+ </div>
+
+ <div class="buttons">
+ <div ng-hide="state.activeTask == null" class="stop" ng-click="stopDialog()" translate></div>
+ <div ng-hide="state.activeTask != null || state.programState == 'Running'" class="resume" ng-click="sendResume()" translate></div>
+ </div>
+
+ <div class="progress-bar progress-bar-striped" ng-class="{active: Progress < 0}" role="progressbar" aria-valuenow="{{Progress * 100}}" aria-valuemin="0" aria-valuemax="100" style="width:{{Progress * 100}}%"></div>
+
+ </div>
+
+ <div class="action-icons">
+ <div class="pause" ng-class="{'active': state.programState != 'Running'}" ng-click="pauseOptions()" title="{{state.programState == 'Running' ? 'Click to see the pause options' : 'Click to resume'}}"></div>
+ <div class="throttle {{throttle_active ? 'active' : 'inactive'}}" ng-click="throttleOptions()" title="{{'Click to set throttle options' | translate}}" alt="{{'Click to set throttle options' | translate}}"></div>
+ </div>
+ </div>
</div>
<div class="body">
<div class="mainmenu menu" id="mainmenu">
<ul>
<li>
- <a href="#/add" class="add" translate>Add new backup</a>
+ <a href="#/" class="home" ng-class="{active: current_page == 'home'}" translate>Home</a>
</li>
<li>
- <a href="#/restoredirect" class="restore" translate>Restore backup</a>
+ <a class="add" href="#/addstart" ng-class="{active: current_page == 'add'}" translate>Add backup</a>
</li>
<li>
- <a href="#/pause" id="pause" class="pause" translate>Pause</a>
+ <a href="#/restorestart" ng-class="{active: current_page == 'restore'}" class="restore" translate>Restore</a>
+ </li>
+ <li ng-hide="state.programState == 'Running'">
+ <a href ng-click="resume()" id="resume" class="resume" translate>Resume</a>
</li>
<li>
- <a href="#/settings" class="settings">{{'Settings' | translate}}</a>
+ <a href="#/settings" class="settings" ng-class="{active: current_page == 'settings'}" translate>Settings</a>
</li>
<li>
- <a href="#/log" class="log">{{'Show log' | translate}}</a>
+ <a href="#/log" class="log" ng-class="{active: current_page == 'log'}" translate>Show log</a>
+ </li>
+ <li>
+ <a href="#/about" class="about" ng-class="{active: current_page == 'about'}" translate>About</a>
+ </li>
+ <li ng-show="isLoggedIn">
+ <a href ng-click="log_out()" class="logout" translate>Log out</a>
</li>
-
</ul>
</div>
@@ -175,17 +248,20 @@
{{'Visit us on' | translate}}
<ul>
<li>
- <a href="https://groups.google.com/forum/#!forum/duplicati" target="_blank"><img src="img/social/ggroups.png" alt="Google Groups" width="28" /></a>
+ <a href="https://forum.duplicati.com" target="_blank"><img src="img/social/duplicati.png" alt="{{'Duplicati forum' | translate}}" title="{{'Duplicati forum' | translate}}" width="28" /></a>
</li>
<li>
- <a href="https://github.com/duplicati" target="_blank"><img src="img/social/github.png" alt="Github" /></a>
+ <a href="https://github.com/duplicati" target="_blank"><img src="img/social/github.png" alt="Github" title="Github" /></a>
</li>
<li>
- <a href="https://www.facebook.com/pages/Duplicati/105118456272281" target="_blank"><img src="img/social/facebook.png" alt="Facebook" /></a>
+ <a href="https://www.facebook.com/pages/Duplicati/105118456272281" target="_blank"><img src="img/social/facebook.png" alt="Facebook" title="Facebook" /></a>
</li>
<li>
- <a href="https://plus.google.com/105271984558189185842" target="_blank"><img src="img/social/google.png" alt="Google Plus" /></a>
+ <a href="https://plus.google.com/105271984558189185842" target="_blank"><img src="img/social/google.png" alt="Google Plus" title="Google Plus" /></a>
</li>
+ <!-- <li>
+ <a href="http://www.duplicati.com" target="_blank"><img src="img/social/duplicati.png" alt="{{'Duplicati Website' | translate}}" title="{{'Duplicati Website' | translate}}" /></a>
+ </li> -->
</ul>
</div>
@@ -193,10 +269,10 @@
<span translate>Donate</span>
<ul>
<li>
- <a href="bitcoin:1L74qa1n5SFKwwyHhECTHBJgcf6WT2rJKf" target="_blank"><img src="img/donate/bitcoin.png" alt="{{'Donate with Bitcoins' | translate}}" /></a>
+ <a href="bitcoin:1L74qa1n5SFKwwyHhECTHBJgcf6WT2rJKf" target="_blank"><img src="img/donate/bitcoin.png" alt="{{'Donate with Bitcoins' | translate}}" title="{{'Donate with Bitcoins' | translate}}" /></a>
</li>
<li>
- <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal%40hexad%2edk&item_name=Duplicati%20Donation&no_shipping=2&no_note=1&tax=0&currency_code=EUR&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=US" target="_blank"><img src="img/donate/paypal.png" alt="{{'Donate with PayPal' | translate}}" /></a>
+ <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal%40hexad%2edk&item_name=Duplicati%20Donation&no_shipping=2&no_note=1&tax=0&currency_code=EUR&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=US" target="_blank"><img src="img/donate/paypal.png" alt="{{'Donate with PayPal' | translate}}" title="{{'Donate with PayPal' | translate}}" /></a>
</li>
</ul>
</div>
@@ -211,26 +287,33 @@
<div ng-show="state.CurrentItem != null" class="modal-dialog ng-cloak">
<div class="info">
<div class="title">{{state.CurrentItem.title}}</div>
- <div class="content">{{state.CurrentItem.message}}</div>
+ <div class="content" ng-show="state.CurrentItem.message || state.CurrentItem.enableTextarea">
+ {{state.CurrentItem.message}}
+ <form ng-show="state.CurrentItem.enableTextarea">
+ <textarea placeholder="{{state.CurrentItem.placeholder}}" ng-model="state.CurrentItem.textarea" id="copytarget"></textarea>
+ </form>
+ </div>
+ <div class="content" ng-show="state.CurrentItem.htmltemplate" ng-include="state.CurrentItem.htmltemplate"></div>
<div class="content buttons">
<ul>
- <li ng-repeat="btn in state.CurrentItem.buttons track by $index" style="display: inline-block"><a href class="button" ng-click="onButtonClick($index)" >{{btn}}</a></li>
+ <li ng-show="state.CurrentItem.buttonTemplate" ng-include="state.CurrentItem.buttonTemplate" style="display: inline-block"></li>
+ <li ng-repeat="btn in state.CurrentItem.buttons track by $index" style="display: inline-block"><a href class="button" ng-click="onButtonClick($index)">{{btn}}</a></li>
</ul>
</div>
</div>
</div>
</div>
- <div ng-show="state.connectionState != 'connected'" class="blocker" ng-click=""></div>
+ <div id="connection-lost-blocker" ng-show="state.connectionState != 'connected'" class="blocker ng-cloak" ng-click=""></div>
- <div ng-show="state.connectionState != 'connected'" class="connection-lost ng-cloak" >
+ <div id="connection-lost-dialog" ng-show="state.connectionState != 'connected'" class="connection-lost ng-cloak" >
<div class="info">
<div class="title" translate>Connection lost</div>
<div class="content" ng-show="state.connectionState !='connecting'" translate translate-params-time="(state.connectionAttemptTimer + 1000) | timeremaining">
The connection to the server is lost, attempting again in {{time}} ...
</div>
<div class="content" translate ng-hide="state.connectionState !='connecting'">
- Connnecting to server ...
+ Connecting to server ...
</div>
<div class="content buttons">
<a href ng-show="state.connectionState != 'connecting'" ng-click="doReconnect()" class="button" translate>Connect now</a>
diff --git a/Duplicati/Server/webroot/ngax/less/fonts.less b/Duplicati/Server/webroot/ngax/less/fonts.less
index 29f6c7270..8870da65d 100755
--- a/Duplicati/Server/webroot/ngax/less/fonts.less
+++ b/Duplicati/Server/webroot/ngax/less/fonts.less
@@ -1,5 +1,4 @@
-@font-face
-{
+@font-face {
font-family: 'Clear Sans';
src: url('../fonts/ClearSans-Light-webfont.eot');
src: url('../fonts/ClearSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
@@ -10,8 +9,7 @@
font-style: normal;
}
-@font-face
-{
+@font-face {
font-family: 'Clear Sans';
src: url('../fonts/ClearSans-Regular-webfont.eot');
src: url('../fonts/ClearSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
@@ -22,8 +20,7 @@
font-style: normal;
}
-@font-face
-{
+@font-face {
font-family: 'Clear Sans';
src: url('../fonts/ClearSans-Medium-webfont.eot');
src: url('../fonts/ClearSans-Medium-webfont.eot?#iefix') format('embedded-opentype'),
@@ -34,8 +31,7 @@
font-style: normal;
}
-@font-face
-{
+@font-face {
font-family: 'Clear Sans';
src: url('../fonts/ClearSans-Bold-webfont.eot');
src: url('../fonts/ClearSans-Bold-webfont.eot?#iefix') format('embedded-opentype'),
diff --git a/Duplicati/Server/webroot/ngax/less/form.less b/Duplicati/Server/webroot/ngax/less/form.less
index 0e60a58e7..9054d27a4 100755
--- a/Duplicati/Server/webroot/ngax/less/form.less
+++ b/Duplicati/Server/webroot/ngax/less/form.less
@@ -1,19 +1,26 @@
// form.css for duplicati 2.0 | Alex Franzelin 2015
-form.styled
-{
- label
- {
+form.styled {
+ div.leftflush input {
+ width: auto;
+ margin-top: 10px;
+ }
+
+ div.leftflush label {
+ width: auto;
+ min-width: 190px;
+ }
+
+ label {
display: block;
width: 190px;
float: left;
line-height: 37px;
}
-
+
input,
textarea,
- select
- {
+ select {
color: @tColor;
font-size: 16px;
font-weight: 300;
@@ -23,44 +30,37 @@ form.styled
border-radius: 2px;
width: 420px;
}
-
+
input:focus,
textarea:focus,
- select:focus
- {
+ select:focus {
border: 1px darken(@border, 20%) solid;
}
-
-
- .input
- {
+
+
+ .input {
padding-bottom: 18px;
overflow: hidden;
}
-
+
.input.text,
- .input.password
- {
- input
- {
+ .input.password {
+ input {
height: 35px;
line-height: 35px;
padding: 0 12px;
}
}
-
- .input.text.text-browse
- {
- input
- {
+
+ .input.text.text-browse {
+ input {
width: 375px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 0;
}
-
- a.browse
- {
+
+ a.browse {
width: 45px;
display: block;
float: left;
@@ -72,26 +72,21 @@ form.styled
background: @lColor;
line-height: 37px;
}
-
- a.browse:hover
- {
+
+ a.browse:hover {
background: darken(@lColor, 20%);
}
}
-
- .input.textarea
- {
- textarea
- {
+
+ .input.textarea {
+ textarea {
height: 130px;
padding: 10px 12px;
}
}
-
- .input.select
- {
- select
- {
+
+ .input.select {
+ select {
width: 446px;
padding: 0 12px;
-webkit-appearance: menulist-button;
@@ -101,15 +96,13 @@ form.styled
line-height: 38px;
}
}
-
- .buttons
- {
+
+ .buttons {
overflow: hidden;
float: right;
-
+
input,
- a
- {
+ a {
display: block;
background: @lColor;
color: white !important;
@@ -124,28 +117,23 @@ form.styled
font-weight: 300;
border-radius: 0;
}
-
- input
- {
+
+ input {
padding: 4px 15px;
}
-
+
input:hover,
- a:hover
- {
+ a:hover {
background: darken(@lColor, 25%);
}
}
}
-@media(max-width: 480px)
-{
- form.styled
- {
+@media (max-width: 480px) {
+ form.styled {
input,
textarea,
- select
- {
+ select {
font-size: 15px;
}
}
diff --git a/Duplicati/Server/webroot/ngax/less/style.less b/Duplicati/Server/webroot/ngax/less/style.less
index 8483ff30a..304650c1e 100755
--- a/Duplicati/Server/webroot/ngax/less/style.less
+++ b/Duplicati/Server/webroot/ngax/less/style.less
@@ -1,54 +1,62 @@
// duplicati 2.0 less | Alex Franzelin 2015
-
@import 'fonts.less';
@import 'variables.less';
@import 'form.less';
@import 'font-awesome/font-awesome.less';
-*
-{
+// https://css-tricks.com/snippets/css/a-guide-to-flexbox/
+.flexbox() {
+ display: -webkit-box;
+ display: -moz-box;
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+}
+
+.flex(@grow: 0; @shrink: 1; @basis: auto) {
+ -webkit-box-flex: @grow @shrink @basis;
+ -moz-box-flex: @grow @shrink @basis;
+ -webkit-flex: @grow @shrink @basis;
+ -ms-flex: @grow @shrink @basis;
+ flex: @grow @shrink @basis;
+}
+
+* {
font-family: 'Clear Sans', sans-serif;
}
html,
-body
-{
+body {
margin: 0;
padding: 0;
height: 100%;
}
h1,
-h2
-{
+h2 {
font-weight: 300;
color: @hColor;
}
-h1
-{
+h1 {
margin: 10px 0;
}
-h3
-{
+h3 {
font-weight: 400;
}
-a
-{
+a {
text-decoration: none;
}
-ul
-{
+ul {
list-style: none;
margin: 0;
padding: 0;
}
-hr
-{
+hr {
border: none;
border-bottom: 1px #ddd solid;
}
@@ -57,8 +65,7 @@ textarea {
max-width: 94%;
}
-.button
-{
+.button {
display: block;
background: @lColor;
color: white !important;
@@ -74,314 +81,854 @@ textarea {
border-radius: 0;
}
-.button:hover
-{
+.button:hover {
background: darken(@lColor, 10%);
}
+.step3 source-folder-picker, #folder_path_picker, #restore_file_picker {
+ display: block;
+ border: 1px solid lightgray;
+ padding: 2px;
+ height: 100%;
+ overflow: auto;
+}
-body
-{
+.not-clickable {
+ cursor: default !important;
+ > a, span, div {
+ cursor: default !important;
+ }
+}
+
+.ui-match {
+ font-weight: bold;
+ color: darkgreen;
+}
+
+wait-area {
+ min-width: 350px;
+ text-align: center;
+ display: block;
+}
+
+.prewrapped-text {
+ white-space: pre-wrap;
+}
+
+.exceptiontext {
+ background-color: lightgray;
+ color: black;
+}
+
+ul.tabs {
+ margin-bottom: 10px;
+
+ > li {
+ display: inline;
+ margin-right: 10px;
+ border: 1px solid @lColor;
+ padding: 5px;
+
+ &.active {
+ background-color: @lColor;
+ color: white;
+
+ > a {
+ background-color: @lColor;
+ color: white;
+ }
+
+ &.disabled {
+ border: 1px solid lightgray;
+ background-color: lightgray;
+ color: grey;
+ cursor: default;
+
+ > a {
+ background-color: lightgray;
+ color: grey;
+ cursor: default;
+ }
+ }
+ }
+ }
+}
+
+.licenses {
+ > ul {
+ list-style: initial;
+ margin: 10px;
+ margin-left: 20px;
+ }
+
+ li {
+ margin-bottom: 10px;
+ }
+
+ a.itemlink {
+ font-weight: bold;
+ }
+}
+
+.logpage {
+ ul.entries {
+ list-style: initial;
+ margin: 10px;
+ margin-left: 20px;
+ }
+
+ .entries {
+ div.entryline {
+ cursor: pointer;
+ }
+ }
+
+ .entries.livedata {
+ li {
+ height: 1.2em;
+ overflow: hidden;
+ }
+
+ li.expanded {
+ height: auto;
+ overflow: auto;
+ }
+ }
+
+ .button {
+ text-align: center;
+ margin-right: 10px;
+ border: 1px solid @lColor;
+ padding: 5px;
+ background-color: @lColor;
+ color: white;
+ cursor: pointer;
+ }
+}
+
+.exportpage {
+ .checkbox {
+ input {
+ width: auto;
+ margin-top: 10px;
+ }
+ }
+ .commandline {
+ div {
+ background-color: lightgray;
+ color: black;
+ }
+ }
+}
+
+.themelink {
+ margin-left: 20px;
+}
+
+ul.notification {
+ position: fixed;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+ margin: auto;
+ width: 480px;
+}
+
+.notification {
+ .title {
+ border: 1px solid @lColor;
+ background-color: @lColor;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+ border-bottom-left-radius: 0px;
+ border-bottom-right-radius: 0px;
+ padding: 2px;
+ padding-left: 5px;
+ padding-right: 5px;
+ font-weight: bold;
+ color: lightgray;
+ width: 100%;
+ text-align: center;
+ clear: both;
+ }
+
+ .content {
+ background-color: white;
+ border: 1px solid @lColor;
+ border-top-left-radius: 0px;
+ border-top-right-radius: 0px;
+ border-bottom-left-radius: 5px;
+ border-bottom-right-radius: 5px;
+ padding: 2px;
+ padding-left: 5px;
+ padding-right: 5px;
+ width: 100%;
+ }
+
+ .message {
+ width: 100%;
+ color: black;
+ }
+
+ .button {
+ padding: 2px 10px;
+ margin-top: 6px;
+ }
+
+ .clear {
+ clear: right;
+ height: 1px;
+ }
+
+ .error {
+ .title {
+ border-color: red;
+ background-color: red;
+ }
+
+ .content {
+ border-color: red;
+ }
+
+ .button {
+ border-color: red;
+ background-color: red;
+ }
+ }
+
+ .warning {
+ .title {
+ background-color: orange;
+ border-color: orange;
+ }
+
+ .button {
+ background-color: orange;
+ border-color: orange;
+ }
+
+ .content {
+ border-color: orange;
+ }
+ }
+}
+
+.filepicker {
+ height: 200px;
+}
+
+.resizable {
+ margin-bottom: 6px;
+ max-width: 100%;
+}
+
+.advanced-toggle {
+ float: right;
+ margin-right: 25px;
+ line-height: 37px;
+}
+
+.advancedoptions {
+ li {
+ clear: both;
+ margin-bottom: 10px;
+ padding: 10px 0;
+ border-top: 1px lightgray solid;
+ }
+}
+
+.advancedentry {
+ .multiple {
+ display: inline;
+ }
+
+ .shortname {
+ font-weight: bold;
+ }
+
+ input[type="text"] {
+ width: 300px;
+ }
+
+ select {
+ width: 300px;
+ }
+
+ input[type="checkbox"] {
+ margin-top: 13px;
+ width: auto;
+ }
+
+ .longdescription {
+ margin-left: 190px;
+ clear: both;
+ font-style: italic;
+ }
+}
+
+.settings {
+ div.sublabel {
+ clear: both;
+ padding: 0 31px;
+ font-style: italic;
+ }
+}
+
+.logo {
+ img.mainlogo {
+ height: 64px;
+ width: 64px;
+ float: left;
+ padding-right: 8px;
+ padding-top: 2px;
+ }
+
+ div.logotext {
+ float: left;
+ }
+
+ a {
+ float: left;
+ display: block;
+ line-height: normal;
+ }
+
+ div.build-suffix {
+ clear: both;
+ display: inline;
+ float: left;
+ font-size: 16px;
+ line-height: 16px;
+ }
+
+ div.powered-by {
+ font-size: 16px;
+ margin: 0px;
+ line-height: 16px;
+ float: left;
+ padding: 0px;
+ margin-left: 5px;
+ }
+}
+
+.fixed-width-font {
+ font-family: monospace;
+}
+
+.warning {
+ margin: 10px;
+ font-style: italic;
+ color: #f49b42;
+}
+
+div.captcha {
+ .details {
+ padding-top: 10px;
+ margin-left: auto;
+ margin-right: auto;
+ width: 180px;
+ }
+}
+
+.centered-text {
+ text-align: center;
+}
+
+body {
color: @tColor;
-
- .container
- {
+
+ .container {
min-height: 100%;
position: relative;
-
- .header
- {
- height: 70px;
+
+ .header {
line-height: 70px;
background: @headerBg;
overflow: hidden;
-
- a
- {
+ height: 70px;
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+ z-index: 100;
+
+ a {
color: @lColor;
}
-
+
a:hover,
- a.active
- {
+ a.active {
color: darken(@tColor, 25%);
}
-
- .logo
- {
+
+ .logo {
font-size: 30px;
font-weight: 700;
float: left;
- padding-left: 50px;
+ padding-left: 40px;
}
-
- .about-header
- {
+
+ .statepadding {
+ padding-right: 90px;
+ margin-left: 320px;
+ }
+
+ .state {
+ float: left;
+ color: darken(@hColor, 10%);
+ width: 580px;
+ padding: 13px 15px;
+ margin: 10px 20px;
+ border: 1px darken(@hColor, 10%) solid;
+ font-weight: 300;
+ font-size: 18px;
+ overflow: hidden;
+ line-height: normal;
+ display: inline-block;
+ background-color: white;
+ text-overflow: ellipsis;
+ position: relative;
+ height: 25px;
+
+ strong {
+ display: inline;
+ margin-right: 10px;
+ }
+
+ span {
+ display: inline;
+ }
+
+ .button {
+ position: static;
+ margin-top: 70px;
+ }
+
+ .content {
+ position: relative;
+ z-index: 10;
+ margin-right: 40px;
+ display: block;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+
+ .buttons {
+ position: absolute;
+ right: 0px;
+ top: 0px;
+ bottom: 0px;
+ width: 26px;
+ margin: 13px 15px;
+
+ .stop {
+ display: block;
+ width: 26px;
+ height: 26px;
+ background: url('../img/progress-stop.png');
+ background-size: 26px;
+ cursor: pointer;
+ }
+
+ .resume {
+ display: block;
+ width: 26px;
+ height: 26px;
+ background: url('../img/progress-resume.png');
+ background-size: 26px;
+ cursor: pointer;
+ }
+ }
+
+ .progress-bar {
+ position: absolute;
+ top: 0px;
+ bottom: 0px;
+ left: 0px;
+ background: fade(@hColor, 25%);
+ z-index: 5;
+ }
+ }
+
+ .action-icons {
+ display: inline-block;
+ line-height: normal;
+ margin: 10px 0px;
+ padding: 13px 0px;
+ float: left;
+ }
+
+ .action-icons-small {
+ display: none;
+ float: right;
+ margin-top: 21px;
+ line-height: normal;
+ }
+
+ .action-icons,
+ .action-icons-small {
+ > .pause {
+ width: 26px;
+ height: 26px;
+ display: inline-block;
+ cursor: pointer;
+ background: url('../img/pause.png');
+ }
+
+ > .pause.active {
+ background: url('../img/resume.png');
+ }
+
+ > .throttle {
+ width: 26px;
+ height: 26px;
+ display: inline-block;
+ cursor: pointer;
+ background: url('../img/throttle.png');
+ }
+
+ > .throttle.inactive {
+ opacity: 0.5;
+ }
+ }
+
+
+ .about-header {
float: right;
padding-right: 20px;
overflow: hidden;
-
- ul
- {
+
+ ul {
overflow: hidden;
list-style: none;
-
- li
- {
+
+ li {
float: right;
padding-right: 20px;
}
}
}
-
- .donate
- {
- img
- {
+
+ .donate {
+ float: right;
+
+ ul {
+ overflow: hidden;
+ float: right;
+ padding-left: 20px;
+ padding-right: 10px;
+
+ li {
+ float: right;
+ margin-right: 10px;
+ padding-top: 5px;
+ }
+ }
+
+ img {
opacity: 0.6;
}
-
- img:hover
- {
+
+ img:hover {
opacity: 1;
}
}
}
-
- .body
- {
+
+ .body {
width: 100%;
overflow: hidden;
min-height: 500px;
- padding-top: 50px;
+ padding-top: 120px;
padding-bottom: 70px;
-
- a
- {
+
+ a {
color: @lColor;
}
-
- .mainmenu
- {
+
+ .mainmenu {
width: 260px;
padding-left: 40px;
float: left;
-
- ul
- {
- li
- {
+
+ > ul {
+ > li {
position: relative;
-
- a
- {
+
+ > a {
font-size: 22px;
font-weight: 300;
padding: 5px 10px 5px 55px;
display: block;
}
-
- a:hover,
- a.active
- {
+
+ > a:hover {
+ color: white;
+ }
+
+ > a.active {
color: white;
}
-
- a.add
- {
+
+ > a.add {
background: url('../img/mainmenu/add.png') no-repeat 8px 7px;
}
-
- a.restore
- {
+
+ > a.restore {
background: url('../img/mainmenu/restore.png') no-repeat 8px 7px;
}
-
- a.pause
- {
+
+ > a.pause {
background: url('../img/mainmenu/pause.png') no-repeat 8px 7px;
}
-
- a.settings
- {
+
+ > a.resume {
+ background: url('../img/mainmenu/resume.png') no-repeat 8px 7px;
+ }
+
+ > a.settings {
background: url('../img/mainmenu/settings.png') no-repeat 8px 7px;
}
-
- a.log
- {
+
+ > a.log {
background: url('../img/mainmenu/log.png') no-repeat 8px 7px;
}
-
- a.add:hover,
- a.add.active
- {
+
+ > a.logout {
+ background: url('../img/mainmenu/logout.png') no-repeat 8px 7px;
+ }
+
+ > a.home {
+ background: url('../img/mainmenu/home.png') no-repeat 8px 7px;
+ }
+
+ > a.about {
+ background: url('../img/mainmenu/about.png') no-repeat 8px 7px;
+ }
+
+ > a.pause {
+ > span {
+ padding-right: 25px;
+ background: url('../img/mainmenu/arrow_right.png') right center no-repeat;
+ }
+ }
+
+ > a.home.active {
+ background: lighten(@lColor, 15%) url('../img/mainmenu/over/home.png') no-repeat 8px 7px;
+ }
+
+ > a.add.active {
+ background: lighten(@lColor, 15%) url('../img/mainmenu/over/add.png') no-repeat 8px 7px;
+ }
+
+ > a.restore.active {
+ background: lighten(@lColor, 15%) url('../img/mainmenu/over/restore.png') no-repeat 8px 7px;
+ }
+
+ > a.pause.active {
+ background: lighten(@lColor, 15%) url('../img/mainmenu/over/pause.png') no-repeat 8px 7px;
+ }
+
+ > a.resume.active {
+ background: lighten(@lColor, 15%) url('../img/mainmenu/over/resume.png') no-repeat 8px 7px;
+ }
+
+ > a.settings.active {
+ background: lighten(@lColor, 15%) url('../img/mainmenu/over/settings.png') no-repeat 8px 7px;
+ }
+
+ > a.log.active {
+ background: lighten(@lColor, 15%) url('../img/mainmenu/over/log.png') no-repeat 8px 7px;
+ }
+
+ > a.about.active {
+ background: lighten(@lColor, 15%) url('../img/mainmenu/over/about.png') no-repeat 8px 7px;
+ }
+
+ > a.pause.open.active {
+ > span {
+ background: url('../img/mainmenu/over/arrow_down.png') right center no-repeat;
+ }
+ }
+
+ > a.add:hover {
background: @lColor url('../img/mainmenu/over/add.png') no-repeat 8px 7px;
}
-
- a.restore:hover,
- a.restore.active
- {
+
+ > a.restore:hover {
background: @lColor url('../img/mainmenu/over/restore.png') no-repeat 8px 7px;
}
-
- a.pause:hover,
- a.pause.active
- {
+
+ > a.pause:hover {
background: @lColor url('../img/mainmenu/over/pause.png') no-repeat 8px 7px;
}
-
- a.settings:hover,
- a.settings.active
- {
+
+ > a.pause:hover {
+ > span {
+ background: url('../img/mainmenu/over/arrow_right.png') right center no-repeat;
+ }
+ }
+
+ > a.pause.open:hover {
+ > span {
+ background: url('../img/mainmenu/over/arrow_down.png') right center no-repeat;
+ }
+ }
+
+ > a.pause.open {
+ > span {
+ background: url('../img/mainmenu/arrow_down.png') right center no-repeat;
+ }
+ }
+
+ > a.resume:hover {
+ background: @lColor url('../img/mainmenu/over/resume.png') no-repeat 8px 7px;
+ }
+
+ > a.settings:hover {
background: @lColor url('../img/mainmenu/over/settings.png') no-repeat 8px 7px;
}
-
- a.log:hover,
- a.log.active
- {
+
+ > a.log:hover {
background: @lColor url('../img/mainmenu/over/log.png') no-repeat 8px 7px;
}
-
- ul
- {
- position: absolute;
- left: 200px;
- top: 25px;
- background: white;
- border: 1px @headerBg solid;
- box-shadow: 0px 7px 15px rgba(0,0,0,0.2);
- z-index: 200;
-
- li
- {
- a
- {
- color: @tColor;
- font-size: 15px;
- font-weight: 400;
- padding: 0;
- display: block;
- width: 205px;
- padding: 4px 10px;
- }
-
- a:hover,
- a.active
- {
- background: @lColor;
- color: white;
- }
- }
+
+ > a.logout:hover {
+ background: @lColor url('../img/mainmenu/over/logout.png') no-repeat 8px 7px;
+ }
+
+ > a.home:hover {
+ background: @lColor url('../img/mainmenu/over/home.png') no-repeat 8px 7px;
+ }
+
+ > a.about:hover {
+ background: @lColor url('../img/mainmenu/over/about.png') no-repeat 8px 7px;
}
}
-
- li.hr-top
- {
+
+ li.hr-top {
padding-top: 25px;
margin-top: 25px;
border-top: 1px @headerBg solid;
}
}
}
-
- .content
- {
+
+ div.contextmenu_container {
+ position: relative;
+ }
+
+ .contextmenu {
+ display: none;
+ position: absolute;
+ background: white;
+ border: 1px @headerBg solid;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
+ z-index: 200;
+ padding: 5px;
+
+ li {
+
+ a {
+ color: @lColor;
+ font-size: 15px;
+ font-weight: 400;
+ padding: 0;
+ display: block;
+ min-width: 200px;
+ padding: 4px 10px;
+ white-space: nowrap;
+ padding-left: 45px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ a:hover {
+ background: @lColor;
+ color: white;
+ }
+ }
+ }
+
+ .contextmenu.open {
+ display: block;
+ }
+
+ .content {
float: left;
padding-left: 50px;
padding-bottom: 50px;
max-width: 700px;
-
- ul.tabs > li
- {
+
+ ul.tabs > li {
display: inline-block;
}
-
- .state
- {
- color: @hColor;
- width: 575px;
- padding: 13px 15px;
- border: 1px @hColor solid;
- font-weight: 300;
- font-size: 18px;
- overflow: hidden;
-
- strong
- {
- display: inline-block;
- margin-right: 10px;
- }
-
- .button
- {
- position: static;
- margin-top: 70px;
- }
- }
-
- .tasks
- {
- padding-top: 20px;
-
- .tasklist
- {
- .task
- {
+
+ .tasks {
+
+ .tasklist {
+ .task {
border-top: 1px solid #eee;
padding-top: 20px;
margin-bottom: 25px;
}
-
- .task:last-child
- {
+
+ .task:last-child {
border-bottom: 1px solid #eee;
padding-bottom: 20px;
}
-
- a
- {
+
+ .task:first-child {
+ padding-top: 0px;
+ border-top: 0px none;
+ }
+
+ a {
font-size: 30px;
padding-left: 55px;
background: url('../img/backup.png') no-repeat 5px 6px;
font-weight: 300;
display: inline-block;
+
+ &.action-link {
+ font-size: 14px;
+ background: none;
+ padding-left: 0px;
+ }
}
-
- a::after
- {
- content: " >";
- }
-
- dl
- {
+
+ dl {
padding-left: 55px;
overflow: hidden;
font-size: 14px;
-
+
dt,
- dd
- {
+ dd {
display: block;
float: left;
}
-
- dt
- {
+
+ dt {
clear: both;
font-weight: 500;
margin-bottom: 5px;
}
-
- dd
- {
+
+ dd {
margin-left: 10px;
}
}
-
- dl.contextmenu
- {
- dt
- {
+
+ dl.taskmenu {
+ p {
+ display: inline;
+ margin-right: 10px;
+ color: @lColor;
+ cursor: pointer;
+ }
+
+ dt {
float: left;
margin-right: 10px;
margin-bottom: 0;
@@ -390,16 +937,14 @@ body
cursor: pointer;
clear: none;
}
-
+
dt.active,
- dt:hover
- {
+ dt:hover {
//background: @lColor;
//color: white;
}
-
- dd
- {
+
+ dd {
clear: both;
float: none;
padding-bottom: 8px;
@@ -409,24 +954,19 @@ body
}
}
}
-
- div.add
- {
- .steps
- {
+
+ div.add,
+ div.restore {
+ .steps {
width: 100%;
overflow: hidden;
- margin-left: 50px;
-
- .step
- {
+
+ .step {
float: left;
- padding-left: 130px;
background: url('../img/steps/line-out.png') no-repeat top left;
color: #c7e5f6;
-
- span
- {
+
+ span {
display: block;
border: 4px #c7e5f6 solid;
background: white;
@@ -439,57 +979,66 @@ body
cursor: pointer;
}
}
-
- .step.active
- {
+
+ .step.active {
color: @lColor;
-
- span
- {
+
+ span {
border: 4px @lColor solid;
background: @lColor;
color: white;
}
-
- h2
- {
+
+ h2 {
color: @lColor;
}
}
-
- .step:first-child
- {
+
+ .step:first-child {
padding-left: 0;
background: transparent;
}
}
-
- .steps-boxes
- {
+
+ .steps-legend {
+ overflow: hidden;
+ padding-bottom: 50px;
+ list-style: none;
+ margin: 0;
+
+ li {
+ color: #c7e5f6;
+ font-size: 18px;
+ text-align: center;
+ float: left;
+ padding-top: 10px;
+ cursor: pointer;
+ }
+
+ li.active {
+ color: @lColor;
+ }
+ }
+
+ .steps-boxes {
padding-left: 40px;
-
- .step
- {
+
+ .step {
display: none;
}
-
- .step.active
- {
+
+ .step.active {
display: block;
}
-
- .box.browser
- {
- .checklinks
- {
- a
- {
+
+ .box.browser {
+ .checklinks {
+ a {
float: left;
margin-left: 20px;
color: @tColor;
-
- i
- {
+
+ i {
border: 2px solid;
border-color: @tColor;
border-radius: 2px;
@@ -499,53 +1048,43 @@ body
width: 18px;
}
}
-
- a.inactive
- {
+
+ a.inactive {
color: lighten(@tColor, 20%);
cursor: default;
-
- i
- {
+
+ i {
border-color: lighten(@tColor, 20%);
}
}
-
- a:first-child
- {
+
+ a:first-child {
margin-left: 0;
}
}
-
- .input.overlayButton
- {
+
+ .input.overlayButton {
padding-top: 10px;
max-width: 100%;
-
- input#sourcePath
- {
+
+ input#sourcePath {
width: 100%;
box-sizing: border-box;
height: 37px;
}
-
- a.button
- {
+
+ a.button {
top: 10px;
}
}
}
-
- .box.filters
- {
- .input.link
- {
- a
- {
+
+ .box.filters {
+ .input.link {
+ a {
color: @tColor;
-
- i
- {
+
+ i {
border: 2px solid;
border-color: @tColor;
border-radius: 2px;
@@ -556,102 +1095,112 @@ body
}
}
}
-
- ul#simplefilterlist
- {
+
+ ul#simplefilterlist {
overflow: hidden;
padding-bottom: 15px;
-
- li
- {
+
+ li {
overflow: hidden;
clear: both;
padding-bottom: 5px;
-
- select
- {
+
+ select {
width: 200px;
margin-right: 5px;
height: 36px;
line-height: 36px;
}
-
- input
- {
+
+ input {
width: 280px;
padding: 5px;
}
}
}
}
-
- .step4
- {
+
+ .step1 {
+ li.strength.score-0 {
+ color: #ff0000;
+ }
+
+ li.strength.score-1 {
+ color: #ff7700;
+ }
+
+ li.strength.score-2 {
+ color: #aaaa00;
+ }
+
+ li.strength.score-3 {
+ color: #007700;
+ }
+
+ li.strength.score-4 {
+ color: #427e27;
+ }
+
+ li.strength.score-x {
+ color: #ff0000;
+ }
+
+ }
+
+ .step5 {
div.input.maxSize input.number,
- div.input.keepBackups input.number
- {
+ div.input.keepBackups input.number {
width: 60px;
}
-
- .advancedoptions
- {
+
+ .advancedoptions {
padding-top: 15px;
clear: both;
-
- li
- {
+
+ li {
border-top: none;
}
-
- li > a
- {
+
+ li > a {
.button;
}
-
- li.advancedentry
- {
+
+ li.advancedentry {
border-bottom: 1px solid lightgray;
}
-
- li:last-child
- {
+
+ li:last-child {
padding-top: 0;
-
- select
- {
+
+ select {
max-width: 400px;
}
}
-
- label
- {
+
+ label {
line-height: normal;
}
-
+
input,
- select
- {
+ select {
width: auto;
max-width: 100%;
box-sizing: border-box;
}
-
- .longdescription
- {
+
+ .longdescription {
margin-top: 10px;
}
}
-
- .advanced-toggle
- {
+
+ .advanced-toggle {
color: @tColor;
line-height: normal;
margin-top: 16px;
clear: both;
float: left;
-
- i.fa
- {
+
+ i.fa {
border: 2px solid;
border-color: @tColor;
border-radius: 2px;
@@ -661,9 +1210,8 @@ body
width: 18px;
}
}
-
- textarea
- {
+
+ textarea {
box-sizing: border-box;
clear: both;
margin-top: 15px;
@@ -671,198 +1219,252 @@ body
}
}
}
-
- .steps-legend
- {
- overflow: hidden;
- padding-bottom: 50px;
- list-style: none;
- padding-left: 0;
- margin: 0;
-
- li
- {
- color: #c7e5f6;
- font-size: 18px;
- text-align: center;
- float: left;
- width: 175px;
- padding-top: 10px;
- cursor: pointer;
- }
-
- li:first-child
- {
- width: 140px;
- padding-right: 15px;
- }
-
- li.active
- {
- color: @lColor;
- }
- }
-
- form
- {
+
+ form {
padding-bottom: 50px;
overflow: hidden;
-
- .input.password
- {
- .tools
- {
+
+ .input.password {
+ .tools {
clear: both;
padding-left: 190px;
padding-top: 10px;
-
- ul
- {
+
+ ul {
overflow: hidden;
-
- li
- {
+
+ li {
float: left;
padding-right: 7px;
}
-
- li.strength.useless
- {
+
+ li.strength.useless {
color: red;
}
-
- li.strength.average
- {
+
+ li.strength.average {
color: yellow;
}
-
- li.strength.good
- {
+
+ li.strength.good {
color: @lColor;
}
}
}
}
-
- .input.multiple
- {
+
+ .input.multiple {
input,
- select
- {
+ select {
width: auto;
margin-right: 5px;
}
-
- select
- {
+
+ select {
padding: 5px 12px;
}
}
-
- .input.overlayButton
- {
+
+ .input.overlayButton {
overflow: hidden;
position: relative;
max-width: 446px;
-
- input
- {
+
+ input {
width: 347px;
}
-
- a.button
- {
+
+ a.button {
position: absolute;
top: 0;
right: 0;
padding: 7px 12px 8px;
}
}
-
- .input.checkbox.multiple
- {
- strong
- {
+
+ .input.checkbox.multiple {
+ strong {
display: block;
padding-bottom: 5px;
}
-
- label
- {
+
+ label {
display: inline-block;
float: none;
width: auto;
padding-right: 10px;
}
-
- input
- {
+
+ input {
width: auto;
display: inline-block;
float: none;
}
}
-
- .buttons
- {
+
+ .buttons {
float: none;
width: 635px;
padding-top: 30px;
}
}
}
-
- div.settings
- {
+
+ div.add {
+ @legends-steps: 5;
+ @legends-width: 700px;
+ @legends-padding-left: (700px - @legends-width) / 2;
+ @circle-width: 43px;
+ @step-width: @legends-width / @legends-steps;
+
+ .steps {
+ margin-left: (@step-width - @circle-width) / 2 + @legends-padding-left;
+
+ .step {
+ padding-left: @step-width - @circle-width;
+ }
+ }
+
+ .steps-legend {
+ padding-left: @legends-padding-left;
+
+ li {
+ width: @step-width;
+ }
+ }
+ }
+
+ div.restore {
+ @legends-steps: 2;
+ @legends-width: 700px;
+ @legends-padding-left: (700px - @legends-width) / 2;
+ @circle-width: 43px;
+ @step-width: @legends-width / @legends-steps;
+
+ .steps {
+ margin-left: (@step-width - @circle-width) / 2 + @legends-padding-left;
+
+ .step {
+ padding-left: @step-width - @circle-width;
+ }
+ }
+
+ .steps-legend {
+ padding-left: @legends-padding-left;
+
+ li {
+ width: @step-width;
+ }
+ }
+ }
+
+ div.restore.restore-direct {
+ @legends-steps: 4;
+ @legends-width: 700px;
+ @legends-padding-left: (700px - @legends-width) / 2;
+ @circle-width: 43px;
+ @step-width: @legends-width / @legends-steps;
+
+ .steps {
+ margin-left: (@step-width - @circle-width) / 2 + @legends-padding-left;
+
+ .step {
+ padding-left: @step-width - @circle-width;
+ }
+ }
+
+ .steps-legend {
+ padding-left: @legends-padding-left;
+
+ li {
+ width: @step-width;
+ }
+ }
+
+ .step:first-child {
+ padding-left: 0;
+ background: transparent;
+ }
+
+ .steps-legend {
+ padding-left: 20px;
+ }
+ }
+
+
+ div.headerthreedotmenu {
+ margin: 20px 0 20px 0;
+
+ h2 {
+ display: inline;
+ }
+
+ .contextmenu_container {
+ float: right;
+ }
+
+ .contextmenu {
+ left: auto;
+ right: 0;
+ top: auto;
+ }
+ .threedotmenubutton {
+ padding: 5px;
+ }
+ }
+
+ .expandable {
+ margin: 20px 0 20px 0;
+
+ h2 {
+ display: inline;
+ }
+
+ img {
+ padding: 0 6px;
+ }
+ }
+
+ div.settings {
.input.mixed.multiple,
- .input.checkbox
- {
- input.checkbox
- {
+ .input.checkbox {
+ input.checkbox {
width: auto;
}
-
- select
- {
+
+ select {
width: auto;
margin-right: 5px;
}
-
- label
- {
+
+ label {
line-height: normal;
padding: 0 15px;
width: auto;
}
}
}
-
- .logpage
- {
- ul.tabs
- {
+
+ .logpage {
+ ul.tabs {
padding: 15px 0;
}
-
- ul.entries
- {
- li
- {
+
+ ul.entries {
+ li {
padding-top: 15px;
}
}
}
-
- .prewrapped-text
- {
+
+ .prewrapped-text {
white-space: pre-wrap;
overflow-x: auto;
}
}
}
-
- .footer
- {
+
+ .footer {
background: @headerBg;
min-height: 70px;
line-height: 70px;
@@ -870,120 +1472,100 @@ body
position: absolute;
bottom: 0;
width: 100%;
-
- a
- {
+
+ a {
color: @lColor;
}
-
- .about-footer
- {
+
+ .about-footer {
float: left;
overflow: hidden;
padding-right: 20px;
-
- span
- {
+
+ span {
display: block;
float: left;
padding-left: 20px;
}
-
- ul
- {
+
+ ul {
float: left;
}
-
- li
- {
+
+ li {
float: left;
padding-left: 20px;
}
}
-
- .donate
- {
+
+ .donate {
float: right;
padding-right: 40px;
overflow: hidden;
-
- ul
- {
+
+ ul {
overflow: hidden;
float: right;
-
- li
- {
+
+ li {
float: left;
margin-left: 20px;
-
- a
- {
- img
- {
+
+ a {
+ img {
margin-top: 24px;
display: inline-block;
opacity: 0.6;
}
-
- img:hover
- {
+
+ img:hover {
opacity: 1;
}
}
}
}
}
-
- .donate > a
- {
+
+ .donate > a {
float: left;
}
-
- .social
- {
+
+ .social {
float: right;
-
- ul
- {
+
+ ul {
overflow: hidden;
float: right;
padding-left: 20px;
padding-right: 10px;
-
- li
- {
+
+ li {
float: right;
margin-right: 10px;
padding-top: 5px;
-
- img
- {
+
+ img {
opacity: 0.6;
}
-
- img:hover
- {
+
+ img:hover {
opacity: 1;
}
}
}
}
-
- .themelink
- {
+
+ .themelink {
float: right;
padding-right: 20px;
}
}
}
-
- #modal-menu
- {
+
+ #modal-menu {
max-width: 400px;
-
- a
- {
+
+ a {
color: @lColor;
font-size: 20px;
line-height: 40px;
@@ -992,29 +1574,24 @@ body
}
// Modal windows
-.remodal
-{
+.remodal {
padding: 30px;
- box-shadow: 0px 2px 7px rgba(0,0,0,0.3);
+ box-shadow: 0px 2px 7px rgba(0, 0, 0, 0.3);
background: white;
display: none;
-
- form
- {
- .buttons
- {
+
+ form {
+ .buttons {
float: none;
}
}
}
-.remodal-wrapper .remodal
-{
+.remodal-wrapper .remodal {
display: block;
}
-span.info
-{
+span.info {
font-size: 10px;
font-weight: 500;
display: inline-block;
@@ -1029,49 +1606,558 @@ span.info
text-align: center;
}
-.hidden
-{
+.hidden {
display: none;
}
-.clear
-{
+.clear {
clear: both;
}
-.nofloat
-{
+.nofloat {
float: none !important;
}
-div.blocker
-{
+div.blocker,
+div.connection-lost,
+div.modal-dialog {
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+ bottom: 0px;
+ margin: auto;
+}
+
+div.blocker {
z-index: 5000;
+ background-color: #000000;
+ opacity: 0.65;
+}
+
+#connection-lost-blocker {
+ z-index: 5100;
+}
+
+#connection-lost-dialog {
+ z-index: 5200;
}
div.connection-lost,
-div.modal-dialog
-{
+div.modal-dialog {
z-index: 5001;
+ .flexbox;
+
+ -webkit-box-pack: center;
+ -moz-box-pack: center;
+ -ms-flex-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+
+ -webkit-box-align: center;
+ -moz-box-align: center;
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ align-items: center;
+
+ div.info {
+ min-width: 310px;
+ max-width: 650px;
+ margin: 5px;
+ }
+
+ div.title {
+ border: 1px solid #65b1dd;
+ background-color: #65b1dd;
+ border-radius: 5px 5px 0 0;
+ padding: 10px 20px;
+ font-weight: bold;
+ color: lightgray;
+ text-align: center;
+ }
+
+ div.content {
+ background-color: white;
+ border: 1px solid white;
+ padding: 20px;
+ }
+
+ .buttons {
+ border-radius: 0 0 5px 5px;
+ padding-top: 10px;
+ overflow: auto;
+ }
+
+ form {
+ margin-top: 15px;
+
+ textarea {
+ height: 130px;
+ width: 420px;
+ padding: 10px 12px;
+ border: 1px #d8d8d8 solid;
+ border-radius: 2px;
+ color: #8f8f8f;
+ font-size: 16px;
+ font-weight: 300;
+ }
+
+ input {
+ height: 35px;
+ line-height: 35px;
+ padding: 0 12px;
+ }
+ }
+}
+
+div.modal-dialog {
+ .content.buttons {
+ ul {
+ float: right;
+ }
+
+ // tooltipped css taken from: https://github.com/primer/primer-tooltips and https://sachinchoolur.github.io/ngclipboard/
+ .tooltipped {
+ position: relative
+ }
+
+ .tooltipped:after {
+ position: absolute;
+ z-index: 1000000;
+ display: none;
+ padding: 5px 8px;
+ font: normal normal 11px/1.5 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
+ color: #fff;
+ text-align: center;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-wrap: break-word;
+ white-space: pre;
+ pointer-events: none;
+ content: attr(aria-label);
+ background: rgba(0, 0, 0, 0.8);
+ border-radius: 3px;
+ -webkit-font-smoothing: subpixel-antialiased
+ }
+
+ .tooltipped:before {
+ position: absolute;
+ z-index: 1000001;
+ display: none;
+ width: 0;
+ height: 0;
+ color: rgba(0, 0, 0, 0.8);
+ pointer-events: none;
+ content: "";
+ border: 5px solid transparent
+ }
+
+ .tooltipped:hover:before, .tooltipped:hover:after, .tooltipped:active:before, .tooltipped:active:after, .tooltipped:focus:before, .tooltipped:focus:after {
+ display: inline-block;
+ text-decoration: none
+ }
+
+ .tooltipped-w:after {
+ right: 100%;
+ bottom: 50%;
+ margin-right: 5px;
+ -webkit-transform: translateY(50%);
+ -ms-transform: translateY(50%);
+ transform: translateY(50%)
+ }
+
+ .tooltipped-w:before {
+ top: 50%;
+ bottom: 50%;
+ left: -5px;
+ margin-top: -5px;
+ border-left-color: rgba(0, 0, 0, 0.8)
+ }
+ }
}
+.restorewizard,
+.addwizard {
+ form.styled {
+ ul {
+ margin: 20px;
+ margin-left: 0px;
+ }
-// Smaller screen sizes
-@media(max-width: 1100px)
+ input[type="radio"] {
+ width: 20px;
+ margin-left: 5px;
+ margin-right: 5px;
+ }
+
+ label {
+ width: auto;
+ line-height: normal;
+ }
+
+ div.subtext {
+ clear: both;
+ margin-left: 30px;
+ padding-top: 5px;
+ color: lightgray;
+
+ }
+ }
+}
+
+.pauseoptions {
+ form.styled {
+ li {
+ line-height: normal;
+ padding: 0px;
+
+ input {
+ height: auto;
+ margin-top: 8px;
+ margin-right: 8px;
+ width: auto;
+ }
+ }
+ }
+}
+
+/* Progress bar styles from Bootstrap */
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px;
+}
+
+.progress-striped {
+ .progress-bar {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px;
+ }
+}
+
+.progress {
+ position: relative;
+ min-height: 25px;
+
+ > span {
+ position: absolute;
+ vertical-align: middle;
+ display: block;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ z-index: 100;
+ padding-top: 2px;
+ }
+
+ &.active {
+ .progress-bar {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+ }
+ }
+
+ .progress-bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #fff;
+ text-align: center;
+ background-color: #337ab7;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ -webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
+ transition: width .6s ease;
+ height: 100%;
+ position: absolute;
+
+ &.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+ }
+ }
+}
+
+.tree-view {
+ list-style-type: none;
+ margin-left: 10px;
+ padding-bottom: 5px;
+
+ ul {
+ margin-left: 16px;
+ }
+
+ span {
+ &.nodeLabel {
+ cursor: pointer;
+
+ &.selected {
+ border: 1px solid #aaa;
+ background-color: #ddd;
+ padding: 1px 3px;
+ }
+ }
+ }
+
+ li {
+ .node {
+ padding-bottom: 5px;
+ }
+
+ div.selected {
+ border-color: lightblue;
+ background-color: lightblue;
+ }
+
+ > ul {
+ display: none;
+ }
+
+ > ul.expanded {
+ display: block;
+ }
+
+ a {
+ &.nav {
+ cursor: pointer;
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+ vertical-align: middle;
+ background-image: url(../img/treeicons.png);
+ background-repeat: no-repeat;
+ background-position: -80px 0px;
+
+ &.leaf {
+ background: none;
+ }
+
+ &.expanded {
+ background-position: -80px -16px;
+ }
+ }
+
+ &.type {
+ cursor: auto;
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+ vertical-align: middle;
+ background-image: url(../img/treeicons.png);
+ background-repeat: no-repeat;
+ background-position: 0px -16px;
+
+ &.invisible {
+ background-position: 0px -32px;
+ }
+
+ &.loading {
+ cursor: progress;
+ background-image: url(../img/loader-16.gif);
+ background-repeat: no-repeat;
+ background-position: 0px 0px;
+ }
+
+ &.x-tree-icon-drive {
+ background-position: -16px -16px;
+ }
+
+ &.x-tree-icon-leaf {
+ background-position: -32px -16px;
+ }
+
+ &.x-tree-icon-symlink {
+ background-position: -48px -16px;
+ }
+
+ &.x-tree-icon-userdata {
+ background-position: -16px -48px;
+ }
+
+ &.x-tree-icon-locked {
+ background-position: -64px -16px;
+ }
+
+ &.x-tree-icon-broken {
+ background-position: -64px -16px;
+ }
+
+ &.x-tree-icon-computer {
+ background-position: 0px -48px;
+ }
+
+ &.x-tree-icon-hyperv {
+ background-position: -96px -16px;
+ }
+
+ &.x-tree-icon-hypervmachine {
+ background-position: -96px 0px;
+ }
+
+ &.x-tree-icon-mssql {
+ background-position: -96px -32px;
+ }
+
+ &.x-tree-icon-mssqldb {
+ background-position: -80px -32px;
+ }
+
+ &.x-tree-icon-mydocuments {
+ background-position: -32px -48px;
+ }
+
+ &.x-tree-icon-mymusic {
+ background-position: -48px -48px;
+ }
+
+ &.x-tree-icon-mypictures {
+ background-position: -64px -48px;
+ }
+
+ &.x-tree-icon-desktop {
+ background-position: -80px -48px;
+ }
+
+ &.x-tree-icon-home {
+ background-position: -96px -48px;
+ }
+
+ &.x-tree-icon-drive.invisible {
+ background-position: -16px -32px;
+ }
+
+ &.x-tree-icon-leaf.invisible {
+ background-position: -32px -32px;
+ }
+
+ &.x-tree-icon-symlink.invisible {
+ cursor: auto;
+ background-position: -48px -32px;
+ }
+
+ &.x-tree-icon-locked.invisible {
+ background-position: -64px -32px;
+ }
+ }
+
+ &.check {
+ height: 16px;
+ width: 16px;
+ display: inline-block;
+ cursor: pointer;
+ background-image: url(../img/treeicons.png);
+ background-repeat: no-repeat;
+ background-position: 0px 0px;
+ vertical-align: middle;
+ }
+
+ &.partial {
+ background-position: -32px 0px;
+ }
+
+ &.include {
+ background-position: -16px 0px;
+ }
+
+ &.exclude {
+ background-position: -48px 0px;
+ }
+
+ &.root {
+ background: none;
+ display: none;
+ }
+ }
+ }
+}
+
+.throttlesettings
{
- body
- {
- .container
- {
- .header
- {
- .donate
- {
+ div.multiple {
+
+ select {
+ width: auto;
+ margin-right: 5px;
+ }
+
+ input {
+ width: 100px;
+ }
+
+ input.checkbox {
+ width: auto;
+ }
+
+ label {
+ line-height: 35px;
+ padding: 0 15px;
+ width: auto;
+ min-width: 150px;
+ }
+ }
+
+ .disabled {
+ color: lighten(@tColor, 25%);
+ input, select {
+ color: lighten(@tColor, 25%);
+ }
+ }
+
+}
+
+// Smaller screen sizes
+@media (max-width: 1200px) {
+ body {
+ .container {
+ .header {
+ .donate {
+ display: none;
+ }
+ }
+ }
+ }
+}
+
+@media (max-width: 1100px) {
+ body {
+ .container {
+ .header {
+ height: 140px;
+
+ .statepadding {
+ padding-right: 90px;
+ margin-left: 0px;
+ }
+
+ .state {
+ width: 100%;
+ margin: 10px 40px;
+ clear: left;
+ float: left;
+ }
+
+ .action-icons {
display: none;
}
-
- .menubutton
- {
+
+ .action-icons-small {
+ display: inline-block;
+ }
+
+
+ .menubutton {
display: block;
font-size: 18px;
padding-right: 50px;
@@ -1084,96 +2170,83 @@ div.modal-dialog
color: #8f8f8f;
float: right;
top: 10px;
- width: 80px;
+ padding-left: 20px;
text-transform: uppercase;
text-align: right;
}
-
- .menubutton.active
- {
+
+ .menubutton.active {
background-image: url('../img/menu_active.png');
color: @lColor;
}
}
-
- .body
- {
+
+ .body {
position: relative;
- padding-top: 0;
-
- .mainmenu
- {
+ padding-top: 140px;
+
+ .mainmenu {
display: none;
- position: absolute;
+ position: fixed;
background: none repeat scroll 0 0 white;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
left: 10px;
padding: 20px;
top: 60px;
}
-
- .mainmenu.mobile-open
- {
+
+ .mainmenu.mobile-open {
display: block;
left: auto;
right: 0;
top: 0;
z-index: 1000;
}
-
- .content
- {
+
+ .contextmenu {
+ left: 0;
+ top: auto;
+ }
+
+ .content {
float: none;
- padding: 50px 20px;
- margin: 0 auto;
-
- .state
- {
+ padding: 20px 20px;
+ margin: 0px auto 30px auto;
+
+ .state {
width: auto;
}
}
}
-
- .footer
- {
- .donate
- {
+
+ .footer {
+ .donate {
display: block;
}
}
-
- .mobileOpen
- {
+
+ .mobileOpen {
display: block !important;
}
}
}
}
-@media(max-width: 768px)
-{
- body
- {
- .container
- {
- .body
- {
- .content
- {
- .tasks
- {
- .tasklist
- {
- a
- {
+@media (max-width: 768px) {
+ body {
+ .container {
+ .body {
+ .content {
+ .tasks {
+ .tasklist {
+ a {
font-size: 20px;
background-size: 24px;
background-position: 0 4px;
padding-left: 35px;
}
-
- dl
- {
+
+ dl {
padding-left: 35px;
}
}
@@ -1182,96 +2255,93 @@ div.modal-dialog
}
}
}
-
- body
- {
- .container
- {
- .body
- {
- .content
- {
+
+ body {
+ .container {
+
+ .header {
+ .logo {
+ padding-left: 10px;
+ }
+ .statepadding {
+ padding-right: 50px;
+ }
+ .state {
+ margin-left: 10px;
+ }
+ .menubutton {
+ margin-right: 5px;
+ }
+ }
+
+ .body {
+ .content {
div.add,
- div.settings
- {
- .steps
- {
+ div.restore,
+ div.settings {
+ .steps {
display: none;
}
-
- .steps-legend
- {
+
+ .steps-legend {
list-style: decimal;
padding-left: 20px;
border-bottom: 1px solid #eee;
margin-bottom: 30px;
padding-bottom: 20px;
-
- li
- {
+
+ li {
float: none;
font-weight: 500;
width: auto !important;
padding-right: 0 !important;
}
}
-
- .steps-boxes
- {
+
+ .steps-boxes {
padding-left: 0;
}
-
- form.styled
- {
- .input
- {
+
+ form.styled {
+ .input {
input,
select,
- textarea
- {
+ textarea {
max-width: 100%;
box-sizing: border-box;
}
}
-
- .input.select select
- {
+
+ .input.select select {
width: 420px;
}
-
- .buttons
- {
+
+ .buttons {
max-width: 100%;
width: auto;
}
-
- .tools
- {
+
+ .tools {
padding-left: 0 !important;
}
-
- .input.checkbox.multiple
- {
+
+ .input.checkbox.multiple {
padding-bottom: 5px;
-
+
input,
- label
- {
+ label {
display: block !important;
float: left !important;
line-height: normal;
}
-
- input
- {
+
+ input {
clear: both;
}
}
-
- .input.text.multiple
- {
- input
- {
+
+ .input.text.multiple {
+ input {
max-width: 48% !important;
}
}
@@ -1283,125 +2353,99 @@ div.modal-dialog
}
}
-@media(max-width: 640px)
-{
- body
- {
- h2
- {
+@media (max-width: 640px) {
+ body {
+ h2 {
font-size: 20px;
text-align: center;
}
-
- .container
- {
- .body
- {
- padding-bottom: 0;
-
- .content
- {
- div.add
- {
- form
- {
- .input.overlayButton
- {
+
+ .container {
+ .body {
+ padding-bottom: 10px;
+
+ .content {
+ margin: 0px auto;
+
+ div.add,
+ div.restore {
+ form {
+ .input.overlayButton {
padding-top: 8px;
padding-bottom: 30px;
//border-bottom: 1px #ddd solid;
margin-bottom: 10px;
-
- a.button
- {
+
+ a.button {
padding: 7px 10px;
right: 1px;
top: 9px;
}
}
-
- .input.checkbox.multiple
- {
- div
- {
+
+ .input.checkbox.multiple {
+ div {
display: block;
}
}
-
- .input.select.multiple
- {
- input#exclude-larger-than-number
- {
+
+ .input.select.multiple {
+ input#exclude-larger-than-number {
width: 75px;
}
-
- select#exclude-larger-than-multiplier
- {
+
+ select#exclude-larger-than-multiplier {
width: 140px;
}
}
-
- .filters
- {
+
+ .filters {
//border-bottom: 1px #ddd solid;
-
- .input.link
- {
+
+ .input.link {
//padding-bottom: 0;
}
-
- .input.textarea
- {
+
+ .input.textarea {
padding-bottom: 10px;
}
-
- h3
- {
+
+ h3 {
margin: 5px 0;
}
}
-
- .input.text.select.multiple.repeat
- {
- label
- {
+
+ .input.text.select.multiple.repeat {
+ label {
float: none;
}
-
- input#repeatRunNumber
- {
+
+ input#repeatRunNumber {
width: 70px;
}
-
- select#repeatRunMultiplier
- {
+
+ select#repeatRunMultiplier {
width: 100px;
}
}
-
- .input.multiple.text.select.maxSize
- {
- input
- {
+
+ .input.multiple.text.select.maxSize {
+ input {
width: 70px;
}
-
- select
- {
+
+ select {
width: 100px;
}
}
-
- .input.multiple.text.select.keepBackups
- {
- select
- {
+
+ .input.multiple.text.select.keepBackups {
+ select {
width: 85px;
padding: 4px 6px;
}
-
- input
- {
+
+ input {
width: 60px;
}
}
@@ -1409,34 +2453,29 @@ div.modal-dialog
}
}
}
-
- .footer
- {
+
+ .footer {
position: static;
padding: 15px;
line-height: normal;
text-align: left;
box-sizing: border-box;
-
- *
- {
+
+ * {
float: none !important;
text-align: center;
box-sizing: border-box;
}
-
- .about-footer
- {
+
+ .about-footer {
padding-right: 0;
-
- span
- {
+
+ span {
padding-left: 0;
padding-bottom: 5px;
}
-
- li
- {
+
+ li {
padding-left: 0;
float: none;
display: inline-block;
@@ -1444,74 +2483,61 @@ div.modal-dialog
width: 32px;
background-size: 28px !important;
border-bottom: none;
-
- a
- {
+
+ a {
/*color: transparent;
height: 32px;
width: 32px;*/
}
}
-
- li.support
- {
+
+ li.support {
background: url('../img/support.png') no-repeat center center;
}
-
- li.about
- {
+
+ li.about {
background: url('../img/about.png') no-repeat center center;
}
-
- li:first-child
- {
+
+ li:first-child {
padding-bottom: 0;
}
-
- li:last-child
- {
+
+ li:last-child {
padding-bottom: 20px;
}
}
-
+
li,
.donate,
.social,
- .about-footer
- {
+ .about-footer {
padding: 8px 0;
border-bottom: 1px #ddd solid;
}
-
- .donate
- {
- ul
- {
- li
- {
+
+ .donate {
+ ul {
+ li {
display: inline-block;
border: none;
margin: 0 5px;
-
- a img
- {
+
+ a img {
margin-top: 0;
}
}
}
}
-
- .social
- {
- li
- {
+
+ .social {
+ li {
display: inline-block;
border: none;
}
}
-
- .themelink
- {
+
+ .themelink {
padding: 5px 0;
}
}
@@ -1519,85 +2545,86 @@ div.modal-dialog
}
}
-@media(max-width: 480px)
-{
- body
- {
+@media (max-width: 580px) {
+ .advancedentry .longdescription {
+ margin-left: 0;
+ }
+}
+
+@media (max-width: 492px) {
+ ul.notification {
+ width: auto;
+ }
+}
+
+@media (max-width: 480px) {
+ body {
font-size: 15px;
-
- .container
- {
- .header
- {
- .logo
- {
- padding-left: 20px;
+
+ .container {
+ .header {
+ .logo {
+ padding-left: 5px;
}
-
- .menubutton
- {
+
+ .menubutton {
margin-right: 5px;
-
+ }
+
+ .state {
+ margin-left: 5px;
+ }
+
+ .statepadding {
+ padding-right: 40px;
+ }
+
+ .menubutton {
+ padding-left: 10px;
}
}
-
- .body
- {
- .mainmenu
- {
+
+ .body {
+ .mainmenu {
width: 280px;
box-sizing: border-box;
-
- ul
- {
- li
- {
- a
- {
+
+ ul {
+ li {
+ a {
font-size: 22px;
}
}
}
}
-
- .content
- {
- padding: 50px 15px;
-
- div.add
- {
- form
- {
- .input.password
- {
- .tools
- {
- ul li
- {
+
+ .content {
+ padding: 15px;
+
+ div.add,
+ div.restore {
+ form {
+ .input.password {
+ .tools {
+ ul li {
font-size: 14px;
}
}
}
-
- .buttons
- {
- a
- {
+
+ .buttons {
+ a {
float: none;
text-align: center;
margin-bottom: 5px;
}
}
}
-
- .steps-boxes
- {
- .box.browser
- {
- .checklinks
- {
- a
- {
+
+ .steps-boxes {
+ .box.browser {
+ .checklinks {
+ a {
float: none;
margin-bottom: 8px;
display: block;
@@ -1610,4 +2637,60 @@ div.modal-dialog
}
}
}
+}
+
+@media (max-width: 400px) {
+ body {
+ font-size: 15px;
+
+ .container {
+ .header {
+ .menubutton {
+ margin-right: 0px;
+ padding-left: 0px;
+ padding-right: 40px;
+
+ span {
+ display: none;
+ }
+ }
+ }
+ }
+ }
+}
+
+@media (max-width: 325px) {
+ body {
+ font-size: 15px;
+
+ .container {
+ .header {
+ .logo {
+ div {
+ display: none;
+ }
+ }
+ }
+ }
+ }
+}
+
+@media (max-width: 200px) {
+ body {
+ font-size: 15px;
+
+ .container {
+ .header {
+ .menubutton {
+ position: static;
+ margin-top: 0px;
+ }
+
+ .action-icons-small {
+ clear: right;
+ margin-top: 0px;
+ }
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/scripts/angular-gettext-cli_compiled_js_output.js b/Duplicati/Server/webroot/ngax/scripts/angular-gettext-cli_compiled_js_output.js
index aaed35c96..19ba70875 100644
--- a/Duplicati/Server/webroot/ngax/scripts/angular-gettext-cli_compiled_js_output.js
+++ b/Duplicati/Server/webroot/ngax/scripts/angular-gettext-cli_compiled_js_output.js
@@ -1,6 +1,15 @@
angular.module('backupApp').run(['gettextCatalog', function (gettextCatalog) {
/* jshint -W100 */
- gettextCatalog.setStrings('da', {"- pick an option -":"- vælg en indstilling -","Access to user interface":"Adgang til brugerinterface"});
- gettextCatalog.setStrings('de', {"- pick an option -":"- Option auswählen -","...loading...":"...laden...","API Key":"API Schlüssel","AWS Access ID":"AWS Access ID","AWS Access Key":"AWS Access Key","AWS IAM Policy":"AWS IAM Policy","About":"Über","About {{appname}}":"Über {{appname}}","Access Key":"Zugriffsschlüssel","Access to user interface":"Zugriff auf die Benutzeroberfläche","Account name":"Account-Name","Activate":"Aktivieren","Activate failed:":"Aktivierung fehlgeschlagen:","Add advanced option":"Option für Profis hinzufügen","Add filter":"Filter hinzufügen","Add new backup":"Neues Backup hinzufügen","Add path":"Pfad hinzufügen","Adjust bucket name?":"Bucket-Name anpassen?","Adjust path name?":"Pfad anpassen?","Advanced Options":"Optionen für Profis","Advanced options":"Einstellungen für Profis","Advanced:":"Fortgeschritten:","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Alle Nutzungsberichte werden anonym verschickt und enthalten keine personenbezogenen oder personenbeziehbaren Daten. Sie enthalten Daten über Hardware, Betriebssystem, das verwendete Backend, die Backupdauer, die Gesamtgröße des BAckups und ähnliuche Daten. Sie enthalten NICHT Pfade, Dateinamen, benutzernamen, Passwörter oder andere sensible Informationen.","Allow remote access (requires restart)":"Fernzugriff erlauben (Neustart notwendig)","Allowed days":"Erlaubte Tage","An existing file was found at the new location":"An dem angegebenen Ort wurde eine bereits vorhandene Datenbank gefunden.","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"Eine vorhandene Datenbank wurde gefunden.\nSoll diese Datenbank von nun an verwendet werden?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"Eine lokale Datenbank für den Onlinespeicher wurde gefunden.\nMit dieser Datenbank können die GUI und die Kommandozeile auf dem gleichen Onlinespeicher arbeiten.\n\nSoll die lokale Datenbank genutzt werden?","Anonymous usage reports":"Anonyme Nutzungsberichte","As Command-line":"als Befehl für Kommandozeile","AuthID":"AuthID","Authentication password":"Authentifzierungs Passwort","Authentication username":"Authentifzierungs Benutzername","Autogenerated passphrase":"Generiertes Passwort","Automatically run backups.":"Backups automatisch ausführen.","B2 Account ID":"B2 Account ID","B2 Application Key":"B2 Application Key","B2 Cloud Storage Account ID":"B2 Cloud Storage Account ID","B2 Cloud Storage Application Key":"B2 Cloud Storage Application Key","Back":"Zurück","Backend modules:":"Backend-Module:","Backup to &gt;":"Backup nach &gt;","Backup:":"Backup:","Backups are currently paused,":"Backup sind momentan pausiert,","Beta":"Beta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Browse":"Anzeigen","Bucket Name":"Bucket-Name","Bucket name":"Bucket-Name","Building list of files to restore ...":"Dateiliste erstellen...","Building partial temporary database ...":"Temporäre Datenbank wird erstellt...","Canary":"Canary","Cancel":"Abbrechen","Changelog":"Änderungen","Check failed:":"Prüfung fehlgeschlagen:","Check for updates now":"Aktualisierung suchen","Checking for updates ...":"Suche Aktualisierung...","Click the AuthID link to create an AuthID":"Auf AuthID klicken um eine AuthID zu erstellen","Compact now":"Backup komprimieren","Compacting remote data ...":"Backupdaten verkleinern...","Completing backup ...":"Backup fertigstellen...","Completing previous backup ...":"Vorheriges BAckup fertigstellen...","Compression modules:":"Kompression:","Configuration file:":"Konfigurationsdatei:","Configuration:":"Konfiguration:","Confirm delete":"Löschen bestätigen","Confirmation required":"Bestätigung erfolderlich","Connect":"Verbinden","Connect now":"Jetzt verbinden","Connect to &gt;":"Verbinden &gt;","Connecting...":"Verbinden...","Connection lost":"Verbindung verloren","Connnecting to server ...":"Verbinde mit Server...","Container name":"Container-Name","Container region":"Container Region","Continue":"Fortfahren","Continue without encryption":"Ohne Verschlüsselung fortfahren","Core options":"Allgemeine Optionen","Counting ({{files}} files found, {{size}})":"Dateien ermitteln ({{files}} files found, {{size}})","Crashes only":"Nur Abstürze","Create bug report ...":"Fehlerbericht erstellen...","Created new limited user":"Nutzer mit eingeschränkten Rechten anlegen","Creating bug report ...":"Fehlerbericht wird erstellt...","Creating new user with limited access ...":"Nutzer mit eingeschränkten Rechten wird erstellt...","Creating target folders ...":"Zielverzeichnisse erstellen...","Creating temporary backup ...":"Temporäres Backup erstellen...","Creating user...":"Nutzer anlegen...","Current version is {{versionname}} ({{versionnumber}})":"Aktuelle Version: {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"Benutzerdefinierter S3 endpoint","Custom authentication url":"Benutzerdefinierte Authentifizierungs URL","Custom location ({{server}})":"Benutzerdefinierter Standort ({{server}})","Custom region for creating buckets":"Benutzerdefinierte Region um buckets zu erstellen","Custom region value ({{region}})":"Benutzerdefinierter Region Wert ({{region}})","Custom server url ({{server}})":"Benutzerdefinierte Server URL ({{server}})","Custom storage class ({{class}})":"Benutzerdefinierte storage class ({{class}})","Days":"Tage","Default ({{channelname}})":"Standard ({{channelname}})","Default options":"Standard-Optionen","Delete":"Löschen","Deleting unwanted files ...":"Veraltete Daten löschen...","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"Konnten wir Deine Daten retten? Falls ja, würden wir uns über eine angemessen Spende sehr freuen. Wir empfehlen {{smallamount}} für private Daten und {{largeamount}} für geschäftliche Daten.","Disabled":"Deaktiviert","Dismiss":"Verwerfen","Do you really want to delete the backup: {{name}}":"Möchtest du das Backup \"{{name}}\" wirklich löschen?","Do you really want to delete the local database for: {{name}}":"Möchtest du die lokale Datenbank wirklich löschen für: {{name}}","Donate":"Spenden","Donate with Bitcoins":"Spenden per Bitcoin","Donate with PayPal":"Spenden per PayPal","Donation messages":"Spenden-Links","Donation messages are hidden, click to show":"Spenden-Links werden versteckt, klicken um anzuzeigen","Donation messages are visible, click to hide":"Spendenlinks werden angezeigt, klicken zum verstecken","Done":"Fertig","Download":"Herunterladen","Downloading ...":"Herunterladen...","Downloading files ...":"Dateien herunterladen...","Downloading update...":"Update Herunterladen...","Duplicate option {{opt}}":"doppelte Option {{opt}}","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Jedes Backup hat eine lokale Datenbank. Diese Datenbank beschleunigt viele Aktionen und führt dazu, dass weniger Daten heruntergeladen werden müssen.","Edit ...":"Bearbeiten...","Edit as list":"Als Liste bearbeiten","Edit as text":"Als Text bearbeiten","Empty":"Leer","Encrypt file":"Datei verschlüsseln","Encryption":"Verschlüsselung","Encryption changed":"Verschlüsselung geändert","Encryption modules:":"Verschlüsselungen:","Enter a url, or click the &quot;Connect to &gt;&quot; link":"URL eingeben oder auf &quot;Verbinden &gt;&quot; klicken","Enter a url, or click the 'Backup to &gt;' link":"URL eingeben oder auf 'Backup nach &gt;' klicken","Enter access key":"Zugriffsschlüssel angeben","Enter account name":"Account-Name angeben","Enter backup passphrase, if any":"Paswort für Backup","Enter container name":"Container-Name angeben","Enter encryption passphrase":"Verschlüsselungspasswort angeben","Enter expression here":"Ausdruck hier einfügen","Enter folder path name":"Ordnerpfad eingeben","Enter one option per line in command-line format, eg. {0}":"Gib eine Option pro Zeile an im Kommandozeilen-Format, z.B. {0}","Enter the destination path":"Ziel-Pfad angeben","Error":"Fehler","Error!":"Fehler!","Errors and crashes":"Fehler und Abstürze","Exclude":"Ausschließen","Exclude directories whose names contain":"Ordner ausschließen dessen Namen beinhaltet","Exclude file":"Datei ausschließen","Exclude file extension":"Dateiendung ausschließen","Exclude files whose names contain":"Dateien ausschließen dessen Namen beinhaltet","Exclude folder":"Ordner ausschließen","Existing file found":"Vorhandene Datenbank gefunden","Experimental":"Experimental","Export":"Exportieren","Export ...":"Exportieren...","Export backup configuration":"Backup-Konfiguration exportieren","Exporting ...":"Expotieren...","FTP (Alternative)":"FTP (Alternativ)","Failed to build temporary database: {{message}}":"Erstellen der temporären Datenbank fehlgeschlagen: {{message}}","Failed to connect: {{message}}":"Verbindung fehlgeschlagen: {{message}}","Failed to delete:":"Löschen fehlgeschlagen:","Failed to read backup defaults:":"Konnte Standard-Einstellungen nicht lesen:","Failed to restore files: {{message}}":"Wiederherstellung der Dateien fehlgeschlagen: {{message}}","Failed to save:":"Fehler beim Speichern:","Fetching path information ...":"Pfad-Infos werden ermittelt...","Files larger than:":"Dateien größer als:","Filters":"Filter","Finished!":"Fertiggestellt!","Folder path":"Ordnerpfad","Folders":"Ordner","Fri":"Fr","GByte":"GByte","GCS Project ID":"GCS Project ID","General":"Allgemein","General options":"Allgemeine Einstellungen","Generate":"Erzeugen","Hidden files":"Versteckte Dateien","Hide":"Ausblenden","Hide hidden folders":"versteckte Ordner ausblenden","Hours":"Stunden","How do you want to handle existing files?":"Wie sollen bestehende Dateien behandelt werden?","If a date was missed, the job will run as soon as possible.":"Wurde ein Zeitpunkt verpasst, startet das Backup so bald wie möglich.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Wenn lokale Daten und das Backup nicht mehr synchron sind, muss die lokale Datenbank repariert werden.\\nSollte die Reparatur nicht erfolgreich sein, so kann die lokale Datenbank gelöscht und neu erstellt werden.","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Ohne Pfad werden alle Dateien im Login-Verzeichnis gespeichert.\nMöchtest du das?","Import":"Importieren","Import backup configuration":"Konfigurationsdatei importieren","Import configuration from a file ...":"Konfigurationsdatei importieren...","Importing ...":"Importieren...","Individual builds for developers only.":"Individuelle Versionen für Entwickler.","Install":"Installieren","Install failed:":"Installation fehlgeschlagen:","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"Manche FTP-Server erlauben einen Login ohne Passwort.\nBist Du sicher, dass Dein FTP-Server dazu gehört?","KByte":"KByte","Keep backups":"Backups speichern","Language in user interface":"Sprache der Benutzeroberfläche","Last month":"Letzter Monat","Last successful run:":"Letztes erfolgreiches Backup:","Latest":"Neuste","Libraries":"Bibliotheken","Listing backup dates ...":"BAckups werden aufgelistet...","Live":"Live","Load older data":"ältere Einträge laden","Loading ...":"Laden...","Local database for":"Lokale Datenbank für","Local database path:":"Lokale Datenbank:","Local storage":"Lokaler Speicher","Location":"Ort","Log data":"Log-Meldungen","MByte":"MByte","Maintenance":"Wartung","Manage database ...":"Datenbank verwalten...","Manually type path":"Pfad eingeben","Menu":"Menü","Minutes":"Minuten","Missing destination":"Ziel fehlt","Missing name":"Name fehlt","Missing passphrase":"Passwort fehlt","Missing sources":"Quelle fehlt","Mon":"Mo","Months":"Monate","Move existing database":"Datenbank verschieben","My Photos":"Meine Fotos","Name":"Name","Never":"Nie","New update found: {{message}}":"Neues Update verfügbar: {{message}}","Next":"Weiter","Next scheduled run:":"Nächstes Backup geplant:","Next scheduled task:":"Nächste geplante Aufgabe:","Next task:":"Nächste Aufgabe:","Next time":"Nächstes Backup","No":"Nein","No encryption":"Keine Verschlüsselung","No items selected":"Nichts ausgewählt","No items to restore, please select one or more items":"Es wurde nichts für die Wiederherstellung ausgewählt. Wähle eine Datei oder einen Ordner aus.","No passphrase entered":"Kein Passwort angegeben","No scheduled tasks, you can manually start a task":"Kein Backup geplant. Backup von Hand starten.","Non-matching passphrase":"Passwort-Fehler","None / disabled":"Keine / deaktiviert","OK":"OK","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Operation fehlgeschlagen:","Operations:":"Operationen:","Optional authentication password":"Passwort für Anmeldung (optional)","Optional authentication username":"Benutzername für Anmeldung (optional)","Options":"Optionen","Original location":"Ursprünglicher Speicherort","Others":"Weitere","Overwrite":"Überschreiben","Passphrase":"Paswort","Passphrase (if encrypted)":"Passwort (falls verschlüsselt)","Passphrase changed":"Passwort gändert","Passphrases are not matching":"Die Passwörter stimmen nicht überein","Password":"Passwort","Passwords do not match":"Die Passwörter stimmen nicht überein","Patching files with local blocks ...":"Dateien mit vorhandenen Daten aufbauen...","Path not found":"Pfad nicht gefunden","Path or subfolder in the bucket":"Pfad oder Unterverzeichnis im Bucket","Pause":"Pause","Pause after startup or hibernation":"Pause nach dem Aufwachen des PCs","Pause controls":"Pause","Permissions":"Berechtigungen","Pick location":"Speicherort auswählen","Port":"Port","Previous":"Zurück","Proprietary":"Proprietär","Rebuilding local database ...":"Lokale Datenbank wieder aufbauen...","Recreate (delete and repair)":"Wiederherstellen (löschen und reparieren)","Recreating database ...":"Datenbank wird neu erstellt...","Relative paths not allowed":"Relative Pfade sind nicht möglich","Remove":"Entfernen","Remove option":"Option entfernen","Repair":"Reparieren","Reparing ...":"Reparieren...","Repeat Passphrase":"Passwort wiederholen","Reset":"Zurücksetzen","Restore":"Wiederherstellen","Restore backup":"Backup wiederherstellen","Restore files":"Dateien wiederherstellen","Restore files ...":"Dateien wiederherstellen...","Restore from":"Wiederherstellen von","Restore options":"Wiederherstellungsoptionen","Restore read/write permissions":"Scheib- und Leserechter wiederherstellen","Restoring files ...":"Dateien werden wiederhergestellt...","Resume now":"Jetzt starten","Run again every":"Wiederholen alle","Run now":"Jetzt sichern","Running ...":"Läuft...","Running task":"Backup läuft","Running task:":"Backup läuft:","S3 Compatible":"S3 Kompatibel","Same as the base install version: {{channelname}}":"Wie die zuerst installierte Version: {{channelname}}","Sat":"Sa","Save":"Speichern","Save and repair":"Speichern und reparieren","Save different versions with timestamp in file name":"Mehrere Versionen mit Zeitstempel im Dateinamen speichern","Scanning existing files ...":"Vorhandene Dateien scannen...","Scanning for local blocks ...":"Vorhandene Daten scannen...","Schedule":"Zeitplan","Search":"Suche","Search for files":"Dateien suchen","Seconds":"Sekunden","Select a log level and see messages as they happen:":"Wähle ein Log-Level und sehe live die Meldungen:","Server":"Server","Server and port":"Server und Port","Settings":"Einstellungen","Show":"Zeigen","Show advanced editor":"Profi-Modus anzeigen","Show hidden folders":"Zeige versteckte Ordner","Show log":"Logfile anzeigen","Show log ...":"Log-Datei anzeigen...","Source Data":"Quell-Daten","Source folders":"Quell-Verzeichnisse","Source:":"Quelle:","Specific builds for developers only.":"Spezielle Versionen für Entwickler.","Standard protocols":"Standardprotokolle","Starting ...":"Los geht\\'s...","Starting the restore process ...":"Wiederherstellung wird gestartet...","Stop":"Stop","Stored":"Gespeichert","Strong":"Stark","Sun":"So","System files":"Systemdateien","System info":"System-Informationen","System properties":"System-Eigenschaften","TByte":"TByte","Temporary files":"Temporäre Dateien","Test connection":"Verbindung prüfen","Testing ...":"Testen...","Testing permissions ...":"Rechte werden geprüft...","Testing permissions...":"Rechte werden geprüft...","The bucket name should be all lower-case, convert automatically?":"Der Bucket sollte klein geschrieben sein. Jetzt klein schreiben?","The bucket name should start with your username, prepend automatically?":"Der Bucket-Name sollte mit Deinem Benutzernamen beginnen. Benutzername hinzufügen?","The connection to the server is lost, attempting again in {{time}} ...":"Die Verbindung zum Server wurde verloren. Versuch erneut in {{time}}...","The path does not appear to exist, do you want to add it anyway?":"Der Pfad scheint nicht zu existieren. Möchtest Du ihn trotzdem hinzufügen?","The path does not end with a '{0}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"Ohne das abschließende '{0}' fügst du eine Datei hinzu und kein Verzeichnis.\n\nMöchtest du diese Datei hinzufügen?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"Der Pfad muss ein absoluter Pfad sein. Das heißt, er muss mit '/' beginnen","The path should start with \"{{prefix}}\" or \"{{def}}\", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?":"Der Pfad sollte mit \"{{prefix}}\" oder \"{{def}}\" beginnen. Ansonsten wirst du die Dateien nicht auf der HubiC-Webseite sehen können.\n\nSoll das Prefix automatisch hinzugefügt werden?","The storage class affects the availability and price for a stored file":"The storage class affects the availability and price for a stored file","The target folder contains encrypted files, please supply the passphrase":"Das Ziel enthält verschlüsselte Dateien. Wir benötigen ein Passwort!","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"Der Nutzer hat zu viele Rechte. Möchtest Du einen Nutzer mit eingeschränkten Berechtigungen für den gewählten Pfad erstellen?","This month":"Dieser Monat","This week":"Diese Woche","Thu":"Do","To File":"als Datei","To export without a passphrase, uncheck the \"Encrypt file\" box":"Um ohne Passwort zu exprotieren, entferne den Haken für die Verschlüsselung","Today":"Heute","Try out the new features we are working on. Don't use with important data.":"Neue Funktionen ausprobieren! Aber nutze diese Versionen nicht mit wichtigen Backups!","Tue":"Di","Type to highlight files":"Tippen, um Dateien zu markieren","Unknown":"Unbekannt","Update channel":"Update-Kanal","Update failed:":"Update fehlgeschlagen:","Updating with existing database":"Datenbank wird aktualisiert","Upload volume size":"Dateigröße beim Upload","Uploading verification file ...":"Prüfdatei hochladen...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"utzungsberichte helfen und bei der Weiterentwicklung. Wir generieren daraus <a href=\"{{link}}\" target=\"_blank\">öffentliche Nutzungsstatistiken</a>","Usage statistics":"Nutzungsstatistiken","Usage statistics, warnings, errors, and crashes":"Nutzungsberichte, Warnungen, Fehler und Abstürze","Use SSL":"SSL benutzen","Use existing database?":"Bestehende Datenbank nutzen?","Use weak passphrase":"Schwaches Passwort nutzen","Useless":"Nutzlos","User has too many permissions":"Nutzer hat zu viele Rechte","User interface language":"Sprache der Benutzeroberfläche","Username":"Benutzername","VISA, Mastercard, ... via Paypal":"VISA, Mastercard, ... via Paypal","Verify files":"Backup prüfen","Verifying ...":"Prüfen...","Verifying remote data ...":"Backupdaten prüfen...","Verifying restored files ...":"Wiederhergestellte Dateien prüfen...","Very strong":"Sehr stark","Very weak":"Sehr schwach","Visit us on":"Besuche uns auf","Waiting for task to begin":"Warte darauf, loslegen zu können","Waiting for upload ...":"Auf den Upload warten...","Warnings, errors and crashes":"Warnungen, Fehler und Abstürze","We recommend that you encrypt all backups stored outside your system":"Wir empfehlen, alle Backups auf Onlinespiechern zu verschlüsseln.","Weak":"Schwach","Weak passphrase":"Schwaches Passwort","Wed":"Mi","Weeks":"Wochen","Where do you want to restore the files to?":"Wohin sollen die Dateien wiederhergestellt werden?","Years":"Jahre","Yes":"Ja","Yes, I have stored the passphrase safely":"Ja, ich habe das Passwort sicher gespeichert","Yes, I'm brave!":"Ja, ich bin mutig!","Yes, please break my backup!":"Ja, mach das Backup kaputt!","Yesterday":"Gestern","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"Du änderst gerade den Pfad zur lokalen Datenbank.\nWeißt Du, was Du da tust?","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"Du hast die Verschlüsselung geändert. Dadurch kann das bestehende Backup unbenutzbar sein. Erstelle lieber ein neues Backup.","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"Du hast das Passwort geändert. Dadurch kann das bestehende Backup unbenutzbar sein. Erstelle lieber ein neues Backup.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"Alle Backups auf Onlinespeichern sollten verschlüsselt werden.","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"Du hast ein starkes Passwort generiert. Kannst Du Dir das merken? Sonst schreib es lieber auf. Denn ohne Passwort kannst Du Dein Backup nicht wiederherstellen.","You must choose at least one source folder":"Du musst schon ein Quellverzeichnis wählen","You must enter a destination where the backups are stored":"Du musst ein Ziel angeben, in dem das Backup gespeichert ist","You must enter a name for the backup":"Gib einen Namen für das Backup an","You must enter a passphrase or disable encryption":"Gib das Passwort ein, um die Verschlüsselung zu deaktivieren","You must enter a tenant name if you do not provide an API Key":"Gib einen Kundennamen an, wenn Du keinen API-Key hast.","You must enter either a password or an API Key":"Gib einen API-Key oder ein Passwort ein.","You must enter either a password or an API Key, not both":"Gib einen API-Key oder ein Passwort an. Aber nicht beides!","You must fill in the password":"Gib ein Passwort an!","You must fill in the path":"Gib einen Pfad an!","You must fill in the server name or address":"Gib einen Server-Namen oder eine Adresse ein!","You must fill in the username":"Gib einen Benutzernamen an!","You must select or fill in the AuthURI":"AuthURI auswählen oder eintragen","You must select or fill in the server":"Server auswählen oder eintragen","Your files and folders have been restored successfully.":"Dateien und Ordner erfolgreich wiederhergestellt.","Your passphrase is easy to guess. Consider changing passphrase.":"Dein Passwort is leicht zu erraten. Nimm lieber etwas Komplizierteres.","a specific number":"eine Anzahl","byte":"byte","click to resume now":"Jetzt starten","custom":"benutzerdefiniert","for a specific time":"eine Dauer","forever":"immer","resume now":"Jetzt starten","resuming in":"starte in","right click and choose &quot;Save as ...&quot;":"Rechtsklick und &quot;Speichern unter...&quot; auswählen","{{files}} files ({{size}}) to go":"Noch {{files}} Dateien ({{size}})","{{number}} Hour":"{{number}} Stunde","{{number}} Minutes":"{{number}} Minuten","{{time}} (took {{duration}})":"{{time}} (dauerte{{duration}})"});
+ gettextCatalog.setStrings('da', {"- pick an option -":"- vælg indstilling -","...loading...":"...indlæser...","API Key":"API Key","AWS Access ID":"AWS Access ID","AWS Access Key":"AWS Access Key","AWS IAM Policy":"AWS IAM Policy","About":"Om","About {{appname}}":"Om {{appname}}","Access Key":"Access Key","Access denied":"Adgang nægtet","Access to user interface":"Adgang til brugerinterface","Account name":"Konto navn","Activate":"Aktiver","Activate failed:":"Aktivering fejlede:","Add a new backup":"Tilføj en ny backup","Add a path directly":"Tilføj en sti","Add advanced option":"Tilføj en avanceret indstilling","Add backup":"Tilføj backup","Add filter":"Tilføj filter","Add path":"Tilføj sti","Adjust bucket name?":"Tilpas bucket navnet?","Adjust path name?":"Juster stien?","Advanced Options":"Avancerede indstillinger","Advanced options":"Avancerede indstillinger","Advanced:":"Avanceret:","All Hyper-V Machines":"Alle Hyper-V maskiner","All Microsoft SQL Databases":"Alle Microsoft SQL databaser","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Alle brugs rapporter bliver sendt anonymt og indeholder ikke personlige oplysninger. De indeholder oplysninger om hardware, operativsystem, destinationstype, backup varighed, backup størrelse og lignende information. De indeholder ikke stier, filnavne, brugernavne, kodeord eller lignende følsom information.","Allow remote access (requires restart)":"Tillad fjernadgang (kræver genstart)","Allowed days":"Tilladte dage","An existing file was found at the new location":"En eksisterende fil blev fundet på den nye placering","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"En eksisterende fil blev funder på den nye placering.\nEr du sikker på at du vil have databasen til at pege på en eksisterende fil?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"En eksisterende lokal database for destinationen er fundet.\nHvis du genbruger databasen, kan du bruge både kommandolinie og serveren til at arbejde på samme destination.\n\nVil du bruge den eksisterende database?","Anonymous usage reports":"Anonyme brugsstatistiker","As Command-line":"Som kommandolinie","AuthID":"AuthID","Authentication password":"Kodeord til godkendelse","Authentication username":"Brugernavn til godkendelse","Autogenerated passphrase":"Autogenereret kodeord","Automatically run backups.":"Kør backups automatisk","B2 Account ID":"B2 Account ID","B2 Application Key":"B2 Application Key","B2 Cloud Storage Account ID":"B2 Cloud Storage Account ID","B2 Cloud Storage Application Key":"B2 Cloud Storage Application Key","Back":"Tilbage","Backend modules:":"Backend moduler:","Backup destination":"Backup destination","Backup location":"Backup placering","Backup:":"Backup:","Beta":"Beta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Broken access":"Adgang defekt","Browse":"Gennemse","Browser default":"Browser standard","Bucket Name":"Bucket navn","Bucket create location":"Bucket placering ved oprettelse","Bucket create region":"Bucket region ved oprettelse","Bucket name":"Bucket navn","Bucket storage class":"Bucket storage class","Building list of files to restore ...":"Bygger liste af filer til gendannelse ...","Building partial temporary database ...":"Bygger en midlertidig database ...","Busy ...":"Optaget ...","Canary":"Canary","Cancel":"Annuller","Cannot move to existing file":"Kan ikke flytte til eksisterende fil","Changelog":"Ændringslog","Changelog for {{appname}} {{version}}":"Ændringslog for {{appname}} {{version}}","Check failed:":"Kontrol fejlede:","Check for updates now":"Tjek for opdateringer nu","Checking ...":"Kontrollerer ...","Checking for updates ...":"Leder efter opdateringer...","Chose a storage type to get started":"Valgte en destinationstype at komme i gang","Click the AuthID link to create an AuthID":"Click på AuthID linket for at oprettet et AuthID","Click to set throttle options":"Klik for at sætte hastigheds begrænsning","Commandline ...":"Kommandolinie ...","Compact now":"Komprimer nu","Compacting remote data ...":"Komprimerer data på destinationen ...","Completing backup ...":"Fuldfører backup ...","Completing previous backup ...":"Fuldfører forrige backup ...","Compression modules:":"Kompressions moduler:","Computer":"Computer","Configuration file:":"Konfigurationsfil:","Configuration:":"Konfiguration:","Configure a new backup":"Indstil en ny backup","Confirm delete":"Bekræft sletning","Confirmation required":"Bekræftelse kræves","Connect":"Forbind","Connect now":"Forbind nu","Connecting to server ...":"Forbinder til server ...","Connecting to task ....":"Forbinder til opgave ...","Connecting...":"Forbinder ...","Connection lost":"Forbindelse mistet","Connection worked!":"Forbindelsen virkede!","Container name":"Container navn","Container region":"Container region","Continue":"Fortsæt","Continue without encryption":"Fortsæt uden kryptering","Copied!":"Kopieret!","Copy Destination URL to Clipboard":"Kopier URL-destinationsadressen til udklipsholder","Copy failed. Please manually copy the URL":"Kopiering mislykkedes. Kopier venligst URL-adressen manuelt","Core options":"Grund indstillinger","Counting ({{files}} files found, {{size}})":"Tæller ({{files}} filer fundet, {{size}})","Crashes only":"Kun nedbrud","Create bug report ...":"Opret fejlrapport ...","Create folder?":"Opret mappe?","Created new limited user":"Opret en ny begrænset bruger","Creating bug report ...":"Opretter fejlrapport ...","Creating new user with limited access ...":"Opretter en ny bruger med begrænset adgang ...","Creating target folders ...":"Opretter destinations mapper ...","Creating temporary backup ...":"Opretter en midlertidig backup ...","Creating user...":"Opretter bruger ...","Current version is {{versionname}} ({{versionnumber}})":"Nuværende version er {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"Brugerdefineret S3 endpoint","Custom authentication url":"Brugerdefineret godkendelses url","Custom location ({{server}})":"Brugerdefineret placering ({{server}})","Custom region for creating buckets":"Brugerdefineret region for at oprette buckets","Custom region value ({{region}})":"Brugerdefineret regions værdi ({{region}})","Custom server url ({{server}})":"Brugerdefineret server url ({{server}})","Custom storage class ({{class}})":"Brugerdefineret storage class ({{klasse}})","Database ...":"Database ...","Days":"Dage","Default":"Standard","Default ({{channelname}})":"Standard ({{channelname}})","Default options":"Standardindstillinger","Delete":"Slet","Delete ...":"Slet ...","Delete backup":"Slet backup","Delete local database":"Slet lokal database","Delete remote files":"Slette filer fra destinationen","Delete the local database":"Slet den lokale database","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"Slet {{filecount}} filer ({{filesize}}) fra destinationen?","Deleting remote files ...":"Sletter filer fra destinationen ...","Deleting unwanted files ...":"Sletter uønskede filer ...","Desktop":"Skrivebord","Destination":"Destination","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"Hjalp vi med at redde dine filer? Du kan overveje at støtte Duplicati med en donation. Vi foreslår {{smallamount}} ved privat brug og {{largeamount}} ved kommerciel brug.","Direct restore from backup files ...":"Direkte gendannelse fra backup filer ...","Disabled":"Deaktiveret","Dismiss":"Afvis","Display and color theme":"Visning og farvevalg","Do you really want to delete the backup: \"{{name}}\" ?":"Vil du virkelig slette backupen: \"{{name}}\"?","Do you really want to delete the local database for: {{name}}":"Vil du virkelig slette den lokale database for: {{navn}}","Donate":"Donér","Donate with Bitcoins":"Donér med Bitcoins","Donate with PayPal":"Donér med PayPal","Donation messages":"Donations beskeder","Donation messages are hidden, click to show":"Donations beskeder er skjult, klik for at vise","Donation messages are visible, click to hide":"Donation beskeder er synlige, klik for at skjule","Done":"Færdig","Download":"Download","Downloading ...":"Downloader ...","Downloading files ...":"Downloader filer ...","Downloading update...":"Downloader opdatering ...","Duplicate option {{opt}}":"Dublet af indstilling {{opt}}","Duplicati Website":"Duplicati hjemmeside","Duplicati forum":"Duplicati forum","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\n When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.\n If you are using the local database for backups from the commandline, you should keep the database.":"Hver backup har en lokal database tilknyttet, som gemmer information om data på fjerndestinationen lokalt på maskinen.\nNår du sletter en backup kan du også slette den lokale database uden at dette påvirker muligheden for at gendanne filer.\nHvis du bruger den lokale database til at køre backup via kommandolinien skal du beholde databasen.","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Hver backup har en lokal database forbundet, som gemmer oplysninger om destinationens filer på den lokale maskine. \\nDette gør det hurtigere at udføre mange operationer, og reducerer mængden af data, der skal hentes for hver operation.","Edit ...":"Rediger ...","Edit as list":"Rediger som liste","Edit as text":"Rediger som tekst","Encrypt file":"Krypter fil","Encryption":"Kryptering","Encryption changed":"Kryptering ændret","Encryption modules:":"Krypterings moduler:","Enter URL":"Indtast URL","Enter access key":"Indtast adgangsnøgle","Enter account name":"Indtast kontonavn","Enter backup passphrase, if any":"Indtast krypteringssætning, hvis krævet","Enter configuration details":"Indtast konfigurationsdetaljer","Enter container name":"Indtast container navn","Enter encryption passphrase":"Indtast krypteringssætning","Enter expression here":"Indtast udtryk her","Enter folder path name":"indtast mappe navn","Enter one option per line in command-line format, eg. {0}":"Indtast én indstilling per linie i kommandolinieformat, f.eks. {0}","Enter the destination path":"Indtast destinations stien","Error":"Fejl","Error!":"Fejl!","Errors and crashes":"Fejl og nedbrud","Exclude":"Eksludér","Exclude directories whose names contain":"Ekskluder mapper hvor navnet indeholder","Exclude expression":"Excluder udtryk","Exclude file":"Excluder fil","Exclude file extension":"Ekskluder filendelse","Exclude files whose names contain":"Ekskluder filer hvor navnet indeholder","Exclude folder":"Ekskluder mappe","Exclude regular expression":"Ekskluder regulært udtryk","Existing file found":"Eksisterende fil fundet","Experimental":"Eksperimental","Export":"Eksporter","Export ...":"Eksporter ...","Export backup configuration":"Eksporter backup konfiguration","Export configuration":"Eksporter konfiguration","Exporting ...":"Eksporterer ...","FTP (Alternative)":"FTP (alternativ)","Failed to build temporary database: {{message}}":"Kunne ikke bygge midlertidig database: {{message}}","Failed to connect:":"Kunne ikke forbinde:","Failed to connect: {{message}}":"Kunne ikke forbinde: {{message}}","Failed to delete:":"Kunne ikke slette:","Failed to fetch path information: {{message}}":"Kunne ikke hente sti-information: {{message}}","Failed to import:":"Kunne ikke importere:","Failed to read backup defaults:":"Kunne ikke læse backup standardværdier:","Failed to restore files: {{message}}":"Kunne ikke gendanne filer: {{message}}","Failed to save:":"Kunne ikke gemme:","Fetching path information ...":"Henter information om stier ...","File":"Fil","Files larger than:":"Filer større end:","Filters":"Filtre","Finished!":"Færdig!","First run setup":"Førstegangsopsætning","Folder":"Mappe","Folder path":"Mappe sti","Fri":"Fre","GByte":"GByte","GByte/s":"GByte/s","GCS Project ID":"GCS Projekt ID","General":"Generelt","General backup settings":"Generelle backup indstillinger","General options":"Generelle indstillinger","Generate":"Generér","Generate IAM access policy":"Generér IAM access policy","Getting file versions ...":"Henter fil versioner ...","Hidden files":"Skjulte filer","Hide":"Skjul","Hide hidden folders":"Skjul skjulte filer","Home":"Hjem","Hours":"Timer","How do you want to handle existing files?":"Hvordan vil du håndtere eksisterende filer?","Hyper-V Machine":"Hyper-V maskine","Hyper-V Machine:":"Hyper-V maskine:","Hyper-V Machines":"Hyper-V maskiner","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"Hvis der ikke blev kørt på det angivne tidspunkt, vil jobbet køre så hurtigt som muligt.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Hvis backup og data på destinationen ikke er synkroniseret, vil Duplicati kræve at du kører en reparation for at synkronisere databasen.\\nHvis reparationen ikke lykkes kan du slette den lokale database og gendanne den.","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Hvis backup filen ikke blev downloaded automatisk, så <a href=\"{{DownloadURL}}\" target=\"_blank\"> højreklik og vælg &quot;Gem som... &quot;</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Hvis backup filen ikke blev downloaded automatisk, så <a href=\"{{item.DownloadLink}}\" target=\"_blank\"> højreklik og vælg &quot;Gem som... &quot;</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Hvis du ikke indtaster en sti, vil alle filer blive gemt i login mappen.\nEr du sikke på at det er det du vil gøre?","If you do not enter an API Key, the tenant name is required":"Hvis du ikke indtaster en API key, skal du angive tenant navnet","If you want to use the backup later, you can export the configuration before deleting it":"Hvis du vil bruge din backup senere, kan du eksportere konfigurationen før du sletter den","If your machine is in a multi-user environment (i.e. the machine has more than one account), you need to set a password to prevent other users from accessing data on your account.\nDo you want to set a password now?":"Hvis flere personer bruger denne computer (med forskellig brugerkonti) bør du indstille et kodeord for at forhindre andre i at tilgå din data.\nVil du indstille et kodeord nu?","Import":"Importér","Import Destination URL":"Importer destinations URL","Import backup configuration":"Importer backup konfiguration","Import completed, but no certificates were found after the import":"Importen blev færdig, men der blev ikke funder certifikater efter importen","Import failed":"Importen fejlede","Import from a file":"Importer fra en fil","Importing ...":"Importerer ...","Include a file?":"Inkluder en fil?","Include expression":"Inkluder udtryk","Include regular expression":"Inkluder regulært udtryk","Incorrect answer, try again":"Forkert svar, prøv igen","Individual builds for developers only.":"Individuelle versioner for udviklere","Information":"Information","Install":"Installer","Install failed:":"Installationen fejlede:","Invalid retention time":"Ugyldig bevaringstid","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"Det er muligt at oprette forbindelse til nogle FTP servere uden en adgangskode.\nEr du sikker på din FTP-server understøtter password-fri login?","KByte":"KByte","KByte/s":"KByte/s","Keep this number of backups":"Antal backup, der skal beholdes","Language in user interface":"Sprog i brugergrænsefladen","Last month":"Sidste måned","Last successful run:":"Sidste succesfulde kørsel:","Latest":"Nyeste","Libraries":"Biblioteker","Listing backup dates ...":"Henter backup datoer...","Listing remote files ...":"Henter filer fra destinationen ...","Live":"Live","Load a configuration from an exported job or a storage provider":"Indlæs konfiguration fra en eksporteret fil eller en pladsudbyder","Load destination from an exported job or a storage provider":"Indlæs destination fra en eksporteret fil eller en pladsudbyder","Load older data":"Indlæs ældre data","Loading ...":"Indlæser ...","Loading remote storage usage ...":"Indlæser forbrug fra fjerndestinationen ...","Local database for":"Lokal database for","Local database path:":"Lokal database sti:","Local storage":"Local opbevaring","Location":"Placering","Location where buckets are created":"Placering hvor buckets bliver oprettet","Log data for <b>{{Backup.Backup.Name}}</b>":"Logdata for <b>{{Backup.Backup.Name}}</b>","Log data from the server":"Logdata fra serveren","Log out":"Log ud","MByte":"MByte","MByte/s":"MByte/s","Maintenance":"Vedligehold","Manually type path":"Indtast en sti manuelt","Max download speed":"Max downloadhastighed","Max upload speed":"Maks uploadhastighed","Menu":"Menu","Microsoft SQL Database:":"Microsoft SQL Database:","Microsoft SQL Databases":"Microsoft SQL Databaser","Minutes":"Minutter","Missing name":"Navn mangler","Missing passphrase":"Kodesætning mangler","Missing sources":"Kilder mangler","Mon":"Man","Months":"Måneder","Move existing database":"Flyt eksisterende database","Move failed:":"Flytning fejlede:","My Documents":"Mine dokumenter","My Music":"Min musik","My Photos":"Mine foto","My Pictures":"Mine billeder","Name":"Navn","Never":"Aldrig","New update found: {{message}}":"Ny opdatering fundet: {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"Nyt bruger navn er {{user}}.\nLoginoplysninger er opdateret til den nye begrænsede bruger","Next":"Næste","Next scheduled run:":"Næste planlagte kørsel:","Next scheduled task:":"Næste planlagte opgave:","Next task:":"Næste opgave:","Next time":"Næste tidspunkt","No":"Nej","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"Intet certifikat har været anvendt før, kontroller venligst at nøglen er korrekt hos serveradministratoren: {{key}} \n\nVil du godkende den angivne nøgle?","No editor found for the &quot;{{backend}}&quot; storage type":"Ingen editor blev fundet for &quot;{{backend}}&quot; destinationen","No encryption":"Ingen kryptering","No items selected":"Ingen emner valgt","No items to restore, please select one or more items":"Ingen emner er valgt til gendannelse, vælg venligst en eller flere emner","No passphrase entered":"Ingen adgangssætning angivet","No scheduled tasks":"Ingen planlagte opgaver","No, my machine has only a single account":"Nej, min computer har kun en brugerkonto","Non-matching passphrase":"Uoverenstemmelse mellem kodesætninger","None / disabled":"Ingen / deaktiveret","OK":"OK","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Operation fejlede:","Operations:":"Operationer:","Optional authentication password":"Valgfrit kodeord til godkendelse","Optional authentication username":"Valgfrit brugernavn til godkendelse","Options":"Indstillinger","Options added here are applied to all backups, but can be overridden in each individual backup":"Indstilliger tilføjet here bliver anvendt på alle backups, men kan blive overskrevet individuelt på hver backup","Original location":"Oprindelig placering","Others":"Andre","Overwrite":"Overskriv","Passphrase":"Kodesætning","Passphrase (if encrypted)":"Kodesætning (hvis krypteret)","Passphrase changed":"Kodesætning ændret","Passphrases are not matching":"Kodesætninger er ikke ens","Password":"Kodeord","Passwords do not match":"Kodeord er ikke ens","Patching files with local blocks ...":"Opdaterer filer med lokale blokke ...","Path not found":"Stien blev ikke fundet","Path on server":"Sti på server","Path or subfolder in the bucket":"Sti eller undermappe i bucket","Pause":"Pause","Pause after startup or hibernation":"Pause efter start eller dvale","Pause options":"Pause indstillinger","Permissions":"Tilladelser","Pick location":"Vælg placering","Point to your backup files and restore from there":"Udpeg dine backup-filer og gendan fra dem","Port":"Port","Previous":"Forrige","ProjectID is optional if the bucket exist":"ProjectID er valgfrit hvis bucket eksisterer","Proprietary":"Proprietære","Purging files ...":"Fjerner filer ...","Rebuilding local database ...":"Genopbygger lokal database ...","Recreate (delete and repair)":"Gendan (slet og reparer)","Recreating database ...":"Gendanner database ...","Registering temporary backup ...":"Registrerer midlertidig backup ...","Relative paths not allowed":"Relative stier er ikke tilladt","Reload":"Genindlæs","Remote":"Destination","Remove":"Fjern","Remove option":"Fjern indstilling","Repair":"Reparer","Reparing ...":"Reparerer ...","Repeat Passphrase":"Gentag kodesætning","Reporting:":"Rapporterer:","Reset":"Nulstil","Restore":"Gendan","Restore files":"Gendan filer","Restore files ...":"Gendan filer ...","Restore files from {{backupname}}":"Gendan filer fra {{backupname}}","Restore from":"Gendan fra","Restore from backup configuration":"Gendan fra konfiguration i backup","Restore from configuration ...":"Gendan fra konfiguration ...","Restore options":"Indstillinger til gendannelse","Restore read/write permissions":"Gendan læse/skrive tilladelser","Restoring files ...":"Gendanner filer ...","Resume":"Genoptag","Run again every":"Kør igen hver","Run now":"Kør nu","Running ...":"Kører ...","Running ....":"Kører ...","Running commandline entry":"Kører kommandolinie opgave","Running task:":"Kørende opgave:","S3 Compatible":"S3 kompatibel","Same as the base install version: {{channelname}}":"Samme som grundinstallationsversionen: {{channelname}}","Sat":"Lør","Save":"Gem","Save and repair":"Gem og reparer","Save different versions with timestamp in file name":"Gem forskellige versioner med tidstempel i filnavnet","Save immediately":"Gem med det samme","Scanning existing files ...":"Skanner eksisterende filer ...","Scanning for local blocks ...":"Scanner for lokale blokke ...","Schedule":"Planlagt","Search":"Søg","Search for files":"Søg efter filer","Seconds":"Sekunder","Select a log level and see messages as they happen:":"Vælg et log niveau og se beskeder som de kommer:","Select files":"Vælg filer","Server":"Server","Server and port":"Server og port","Server hostname or IP":"Server navn eller IP","Server is currently paused,":"Serveren er sat på pause.","Server is currently paused, do you want to resume now?":"Serveren er sat på pause, vil du genoptage med det samme?","Server paused":"Server på pause","Server state properties":"Egenskaber for serveren","Settings":"Indstillinger","Show":"Vis","Show advanced editor":"Vis avanceret redigering","Show hidden folders":"Vis skjulte mapper","Show log":"Vis log","Show log ...":"Vis log ...","Show treeview":"Vis træstruktur","Some OpenStack providers allow an API key instead of a password and tenant name":"Nogle OpenStack udbydere tillader en API nøgle istedet for et kodeord og et tenant navn","Source Data":"Kilde data","Source data":"Kilde data","Source folders":"Kilde mapper","Source:":"Kilde:","Specific builds for developers only.":"Specielle versioner til udviklere.","Standard protocols":"Standard protokoller","Starting ...":"Starter ...","Starting the restore process ...":"Starter gendannelses processen ...","Stop after the current file":"Stop efter den nuværende fil","Stop after upload":"Stop efter upload","Stop now":"Stop nu","Stop running backup":"Stop den kørende backup","Stop running task":"Stop den kørende opgave","Stopping after upload:":"Stopper efter upload:","Stopping task:":"Stopper opgave:","Storage Type":"Opbevaringstype","Storage class":"Opbevaringsklasse","Storage class for creating a bucket":"Opbevaringsklasse når der oprettes en bucket","Stored":"Gemt","Strong":"Stærk","Success":"Succes","Sun":"Søn","Symbolic link":"Symbolsk kæde","System default ({{levelname}})":"System standard ({{levelname}})","System files":"System filer","System info":"System info","System properties":"System egenskaber","TByte":"TByte","TByte/s":"TByte/s","Task is running":"Opgave kører","Temporary files":"Midlertidige filer","Tenant Name":"Tenant navn","Test connection":"Test forbindelse","Testing ...":"Tester ...","Testing connection ...":"Tester forbindelse ...","Testing permissions ...":"Tester tilladelser ...","Testing permissions...":"Tester tilladelser...","The bucket name should be all lower-case, convert automatically?":"Bucket navnet bør være med små bogstaver, konverter automatisk?","The bucket name should start with your username, prepend automatically?":"Bucket navnet bør starte med dit brugernavn, vil du sætte det foran automatisk?","The connection to the server is lost, attempting again in {{time}} ...":"Forbindelsen til serveren er mistet, forsøger igen om {{time}} ...","The dark theme (by Michal)":"Mørke farver (af Michal)","The default blue on white theme (by Alex)":"Standard blå på hvid (af Alex)","The folder {{folder}} does not exist\nCreate it now?":"Mappen {{folder}} findes ikke\nOpret den nu?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"Nøglen fra værten er ændret, kontroller venligst med server administratoren om dette er korrekt, ellers kan du være offer for et MAN-IN-THE-MIDDLE angreb.\n\nVil du ERSTATTE din NUVÆRENDE værtsnøgle \"{{prev}}\" med den RAPPORTEREDE værtsnøgle: {{key}}?","The path does not appear to exist, do you want to add it anyway?":"Stien ser ikke ud til at findes, vil du tilføje den alligevel?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"Stien slutter ikke med '{{dirsep}}' tegnet, hvilket betyder at du inkluderer en file og ikke en mappe.\n\nVil du inkludere den valgte fil?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"Stien skal være en absolut sti, altså skal den starte med '/'","The path should start with \"{{prefix1}}\" or \"{{prefix2}}\", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?":"Stien bør starte med \"{{præfiks1}}\" eller \"{{præfiks2}}\", ellers vil du ikke kunne se andre filer i HubiC web konsollen\n\nVil du tilføje præfikset til stien automatisk?","The region parameter is only applied when creating a new bucket":"Regionsparameteren anvendes kun når der oprettes en ny bucket","The region parameter is only used when creating a bucket":"Regionsparameteren bruges kun når der oprettes en ny bucket","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"Server certifikatet kunne ikke valideres.\nVil du godkende SSL certifikatet med dette hash: {{hash}}?","The storage class affects the availability and price for a stored file":"Opbevaringsklasen påvirker tilgængeligheden og prisen for en opbevaret fil","The target folder contains encrypted files, please supply the passphrase":"Destinationsmappen indeholder krypterede filer, angiv venligst kodesætningen","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"Brugeren har for mange tilladelser. Vil du oprette en ny begrænset bruger der kun har adgang til den valgte sti?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"Denne backup blev oprettet på et andet operativsystem. Når der gendannes filer uden at angive en destination, kan disse blive oprettet på uventede placeringer. Er du sikker på at du vil fortsætte uden at vælge en destinationsmappe?","This month":"Denne måned","This week":"Denne uge","Thu":"Tor","To File":"Til fil","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"For at bekræfte at du vil slette all fjernfiler til \"{{name}}\", indtast venligst det ord ud ser herunder","To export without a passphrase, uncheck the \"Encrypt file\" box":"For at eksportere uden en adgangsætning, fjern mærket ud for \"Krypter filen\"","Today":"I dag","Trust host certificate?":"Stol på værtscertifikatet?","Trust server certificate?":"Stol på server certifikatet?","Try out the new features we are working on. Don't use with important data.":"Prøv de nye ting vi arbejder på. Undlad at bruge denne med vigtige data.","Tue":"Tir","Type to highlight files":"Skriv for at markere filer","Unknown backup size and versions":"Ukendt backup størrelse og versionsantal","Until resumed":"Indtil genoptaget","Update channel":"Opdateringskanal","Update failed:":"Opdatering fejlede:","Updating with existing database":"Opdaterer med eksisterende database","Upload volume size":"Filstørrelse til upload","Uploading verification file ...":"Uploader verifikationsfil ...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"Brugsrapporter hjælper os med at forbedre brugeroplevelsen og effekten af nye funktioner. Vi bruger den til at generere <a href=\"{{link}}\" target=\"_blank\">offentlige brugsstatistikker</a>","Usage statistics":"Brugsstatistik","Usage statistics, warnings, errors, and crashes":"Brugsstatistik, advarsler, fejl og nedbrud","Use SSL":"Brug SSL","Use existing database?":"Brug eksisterende database?","Use weak passphrase":"Brug svag kodesætning","Useless":"Ubrugelig","User data":"Brugerdata","User has too many permissions":"Brugeren har for mange tilladelser","User interface settings":"Indstillinger til brugergrænseflade","Username":"Brugernavn","VISA, Mastercard, ... via Paypal":"VISA, Mastercard, ... via Paypal","Validating ...":"Validerer ...","Verify files":"Verificer filer","Verifying ...":"Verificerer ...","Verifying answer":"Verificerer svar","Verifying backend data ...":"Verificerer destinationsdata ...","Verifying remote data ...":"Verificerer fjerndata ...","Verifying restored files ...":"Verificerer gendannede filer ...","Very strong":"Meget stærk","Very weak":"Meget svag","Visit us on":"Besøg os på","WARNING: The remote database is found to be in use by the commandline library":"ADVARSEL: Databasen benyttes af kommandolinie programmet","WARNING: This will prevent you from restoring the data in the future.":"ADVARSEL: Dette vil forhindre dig i at gendanne data i fremtiden.","Waiting for task to begin":"Venter på at opgaven starter","Waiting for task to start ....":"Venter på at opgaven starter ...","Waiting for upload ...":"Venter på upload ...","Warnings, errors and crashes":"Advarsler, fejl og nedbrud","We recommend that you encrypt all backups stored outside your system":"Vi anbefaler at du krypterer alle backups der er gemt uden for dit system","Weak":"Svag","Weak passphrase":"Svag kodesætning","Wed":"Ons","Weeks":"Uger","Where do you want to restore from?":"Hvor vil du gerne gendanne fra?","Where do you want to restore the files to?":"Hvor vil du gendanne filerne til?","Years":"År","Yes":"Ja","Yes, I have stored the passphrase safely":"Ja, jeg har opbevaret kodesætningen sikkert","Yes, I'm brave!":"Ja, jeg er modig!","Yes, please break my backup!":"Ja, ødelæg venligst min backup!","Yesterday":"I går","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"Det ser ud til at du kører Mono uden nogen SSL certifikater.\nVil du importere listen af certifikater som Mozilla bruger?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"Du er ved at ændre database stien væk fra en eksisterende database.\nEr du sikker på at det er det du vil?","You are currently running {{appname}} {{version}}":"Du kører med {{appname}} {{version}}","You can stop the backup immediately, or stop after the current file has been uploaded.":"Du kan stoppe backup'en med det samme, eller stoppe efter den nuværende fil er uploaded.","You can stop the task immediately, or allow the process to continue its current file and the stop.":"Du kan stoppe opgaven med det samme, eller lade den afslutte den nuværende fil og så stoppe.","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"Du har skiftet krypteringsmetode. Dette kan ødelægge ting. Du opfordres til at oprette en ny backup i stedet.","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"Du har skiftet kodesætningen, hvilket ikke understøttes. Du opfordres til at oprette en ny backup i stedet.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"Du har valgt at undlade at kryptere din backup. Kryptering anbefales for alt data der gemmes på en fjerndestination.","You have chosen to restore to a new location, but not entered one":"Du har valgt at gendanne til en ny placering, men ikke angivet en","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"Du har dannet et stærk kodesætning. Du skal sikre dig at du har en kopi af kodesætningen, for dine data kan ikke gendannes hvis du mister denne.","You must choose at least one source folder":"Du skal vælge mindst en kilde mappe","You must enter a name for the backup":"Du skal angive et navn for denne backup","You must enter a passphrase or disable encryption":"Du skal indtaste en kodesætning eller fravælge kryptering","You must enter a positive number of backups to keep":"Du skal indtaste et positivt antal backups der skal bevares","You must enter a tenant name if you do not provide an API Key":"Du skal angive et tenant navn hvis du ikke angiver en API nøgle","You must enter a valid duration for the time to keep backups":"Du skal angive en gyldig periode som backups gemmes i","You must enter either a password or an API Key":"Du skal angive enten et kodeord eller en API nøgle","You must enter either a password or an API Key, not both":"Du skal angive enten et kodeord eller en API nøgle, men ikke begge","You must fill in the password":"Du skal angive et kodeord","You must fill in the server name or address":"Du skal angive server navnet eller adressen","You must fill in the username":"Du skal angive et brugernavn","You must fill in {{field}}":"Du skal udfylde {{field}}","You must select or fill in the AuthURI":"Du skal vælge eller udfylde AuthURI","You must select or fill in the server":"Du skal vælge eller indtaste server navnet","You must specify a path":"Du skal angive en sti","Your files and folders have been restored successfully.":"Dine filer og mapper blev gendannet korrekt.","Your passphrase is easy to guess. Consider changing passphrase.":"Din kodesætning er let at gætte. Overvej at skifte den.","a specific number":"et specifikt tal","bucket/folder/subfolder":"buvket/mappe/undermappe","byte":"byte","byte/s":"byte/s","custom":"tilpasset","resume now":"genoptag nu","unlimited":"ubegrænset","until they are older than":"Indtil de er ældre end","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} er primært udviklet af <a href=\"{{mail1}}\">{{dev1}}</a> og <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} kan downloades fra <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} er licenseret med <a href=\"{{licenselink}}\">{{licensename}}</a>.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":["{{item.Backup.Metadata.TargetSizeString}} / {{$count}} version","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} versioner"],"{{number}} Hour":"{{number}} Timer","{{number}} Minutes":"{{number}} Minutter","{{time}} (took {{duration}})":"{{time}} (varighed: {{duration}})"});
+ gettextCatalog.setStrings('de', {"- pick an option -":"- Option auswählen -","...loading...":"...laden...","API Key":"API-Schlüssel","AWS Access ID":"AWS Access ID","AWS Access Key":"AWS Access Key","AWS IAM Policy":"AWS IAM Policy","About":"Über","About {{appname}}":"Über {{appname}}","Access Key":"Zugriffsschlüssel","Access denied":"Zugriff verweigert","Access to user interface":"Zugriff auf die Benutzeroberfläche","Account name":"Kontoname","Activate":"Aktivieren","Activate failed:":"Aktivierung fehlgeschlagen:","Add a new backup":"Neues Backup hinzufügen","Add a path directly":"Direkten Pfad eingeben","Add advanced option":"Option für Profis hinzufügen","Add backup":"Sicherung hinzufügen","Add filter":"Filter hinzufügen","Add path":"Pfad hinzufügen","Adjust bucket name?":"Bucket-Name anpassen?","Adjust path name?":"Pfad anpassen?","Advanced Options":"Optionen für Profis","Advanced options":"Optionen für Profis","Advanced:":"Für Profis:","All Hyper-V Machines":"Alle Hyper-V Maschinen","All Microsoft SQL Databases":"Alle Microsoft SQL-Datenbanken","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Alle Nutzungsberichte werden anonym verschickt und enthalten keine personenbezogenen oder personenbeziehbare Daten. Sie enthalten Daten über Hardware, Betriebssystem, das verwendete Backend, die Sicherungsdauer, die Gesamtgröße der Sicherungen und ähnliche Daten. Sie enthalten NICHT Pfade, Dateinamen, Benutzernamen, Passwörter oder andere sensible Informationen.","Allow remote access (requires restart)":"Fernzugriff erlauben (Neustart notwendig)","Allowed days":"Erlaubte Tage","An existing file was found at the new location":"An dem angegebenen Ort wurde eine bereits vorhandene Datenbank gefunden.","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"Eine vorhandene Datenbank wurde gefunden.\nSoll diese Datenbank von nun an verwendet werden?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"Eine lokale Datenbank für den Onlinespeicher wurde gefunden.\nMit dieser Datenbank können GUI und Kommandozeile auf dem gleichen Onlinespeicher arbeiten.\n\nSoll die lokale Datenbank genutzt werden?","Anonymous usage reports":"Anonyme Nutzungsberichte","As Command-line":"als Befehl für Kommandozeile","AuthID":"AuthID","Authentication password":"Passwort für Anmeldung","Authentication username":"Benutzername für Anmeldung","Autogenerated passphrase":"Automatisch generierte Passphrase","Automatically run backups.":"Sicherungen automatisch ausführen.","B2 Account ID":"B2 Account ID","B2 Application Key":"B2 Application Key","B2 Cloud Storage Account ID":"B2 Cloud Storage Account ID","B2 Cloud Storage Application Key":"B2 Cloud Storage Application Key","Back":"Zurück","Backend modules:":"Backend-Module:","Backup destination":"Sicherungsziel","Backup location":"Sicherungsort","Backup:":"Sicherung:","Beta":"Beta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Broken access":"Defekter Zugriff","Browse":"Anzeigen","Browser default":"Standard Browser","Bucket Name":"Bucket-Name","Bucket create location":"Bucket-Speicherort","Bucket create region":"Bucket Bereich erstellen","Bucket name":"Bucket-Name","Bucket storage class":"Bucket Speicherklasse","Building list of files to restore ...":"Dateiliste erstellen...","Building partial temporary database ...":"Temporäre Datenbank wird erstellt...","Busy ...":"Beschäftigt...","Canary":"Canary","Cancel":"Abbrechen","Cannot move to existing file":"Verschieben auf bereits existierende Datei nicht möglich","Changelog":"Änderungen","Changelog for {{appname}} {{version}}":"Changelog für {{appname}} {{version}}","Check failed:":"Prüfung fehlgeschlagen:","Check for updates now":"Aktualisierung suchen","Checking ...":"Überprüfen...","Checking for updates ...":"Suche Aktualisierung...","Chose a storage type to get started":"Wähle einen Speichertypen zum Starten","Click the AuthID link to create an AuthID":"Auf AuthID klicken um eine AuthID zu erstellen","Click to set throttle options":"Klicken, um die Drosseloptionen einzustellen","Commandline ...":"Kommandozeile","Compact now":"Sicherung komprimieren","Compacting remote data ...":"Remotedaten verkleinern...","Completing backup ...":"Sicherung fertigstellen...","Completing previous backup ...":"Vorherige Sicherung fertigstellen...","Compression modules:":"Kompression:","Computer":"Computer","Configuration file:":"Konfigurationsdatei:","Configuration:":"Konfiguration:","Configure a new backup":"Neues Backup konfigurieren","Confirm delete":"Löschen bestätigen","Confirmation required":"Bestätigung erfolderlich","Connect":"Verbinden","Connect now":"Jetzt verbinden","Connecting to server ...":"Verbindung zum Server herstellen ...","Connecting to task ....":"Verbinde mit Aufgabe...","Connecting...":"Verbinden...","Connection lost":"Verbindung verloren","Connection worked!":"Verbindung erfolgreich!","Container name":"Container-Name","Container region":"Container-Region","Continue":"Fortfahren","Continue without encryption":"Ohne Verschlüsselung fortfahren","Copied!":"Kopiert!","Copy Destination URL to Clipboard":"Kopiere Ziel-URL in Zwischenablage","Copy failed. Please manually copy the URL":"Kopie fehlgeschlagen. Bitte kopiere die URL manuell","Core options":"Allgemeine Optionen","Counting ({{files}} files found, {{size}})":"Dateien ermitteln ({{files}} files found, {{size}})","Crashes only":"Nur Abstürze","Create bug report ...":"Fehlerbericht erstellen...","Create folder?":"Ordner erstellen?","Created new limited user":"Nutzer mit eingeschränkten Rechten anlegen","Creating bug report ...":"Fehlerbericht wird erstellt...","Creating new user with limited access ...":"Nutzer mit eingeschränkten Rechten wird erstellt...","Creating target folders ...":"Zielverzeichnisse erstellen...","Creating temporary backup ...":"Temporäre Sicherung erstellen...","Creating user...":"Nutzer anlegen...","Current version is {{versionname}} ({{versionnumber}})":"Aktuelle Version: {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"Benutzerdefinierter S3 endpoint","Custom authentication url":"Benutzerdefinierte URL für Authentifizierung","Custom location ({{server}})":"Benutzerdefinierter Standort ({{server}})","Custom region for creating buckets":"Benutzerdefinierte Region, um Buckets zu erstellen","Custom region value ({{region}})":"Benutzerdefinierter Wert für Region ({{region}})","Custom server url ({{server}})":"Benutzerdefinierte Server-URL ({{server}})","Custom storage class ({{class}})":"Benutzerdefinierte Speicher-Klasse ({{class}})","Database ...":"Datenbank ...","Days":"Tage","Default":"Standard","Default ({{channelname}})":"Standard ({{channelname}})","Default options":"Standard-Optionen","Delete":"Löschen","Delete ...":"Löschen...","Delete backup":"Sicherung löschen","Delete local database":"Lokale Datenbank löschen","Delete remote files":"Remote-Dateien löschen","Delete the local database":"Die lokale Datenbank löschen","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"{{filecount}} Dateien ({{filesize}}) vom Remote-Speicher löschen?","Deleting remote files ...":"Remote-Dateien löschen...","Deleting unwanted files ...":"Veraltete Daten löschen...","Desktop":"Desktop","Destination":"Ziel","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"Konnten wir Deine Daten retten? Falls ja, würden wir uns über eine angemessene Spende sehr freuen. Wir empfehlen {{smallamount}} bei privater Nutzung und {{largeamount}} bei geschäftlicher Nutzung.","Direct restore from backup files ...":"Direkte Wiederherstellung von Sicherungsdateien","Disabled":"Deaktiviert","Dismiss":"Verwerfen","Display and color theme":"Anzeige und Farbthema","Do you really want to delete the backup: \"{{name}}\" ?":"Möchtest Du die Sicherung wirklich löschen: \"{{name}}\" ?","Do you really want to delete the local database for: {{name}}":"Möchtest du die lokale Datenbank wirklich löschen für: {{name}}","Donate":"Spenden","Donate with Bitcoins":"Spenden per Bitcoin","Donate with PayPal":"Spenden per PayPal","Donation messages":"Spenden-Links","Donation messages are hidden, click to show":"Spenden-Links werden versteckt (jetzt anzeigen)","Donation messages are visible, click to hide":"Spendenlinks werden angezeigt (jetzt ausblenden)","Done":"Fertig","Download":"Herunterladen","Downloading ...":"Herunterladen...","Downloading files ...":"Dateien herunterladen...","Downloading update...":"Update Herunterladen...","Duplicate option {{opt}}":"doppelte Option {{opt}}","Duplicati Website":"Duplicati Website","Duplicati forum":"Duplicati Forum","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\n When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.\n If you are using the local database for backups from the commandline, you should keep the database.":"Jedes Backup hat eine lokale Datenbank.\nBeim Löschen des Backups kann die lokale Datenbank, ohne die Wiederherstellung der Remote-Dateien zu beeinträchtigen.\nWenn Sie die lokale Datenbank für Backups von der Befehlszeile aus verwenden, sollten Sie die Datenbank behalten.","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Jede Sicherung hat eine lokale Datenbank. Diese Datenbank beschleunigt viele Aktionen und führt dazu, dass weniger Daten heruntergeladen werden müssen.","Edit ...":"Bearbeiten...","Edit as list":"Als Liste bearbeiten","Edit as text":"Als Text bearbeiten","Encrypt file":"Datei verschlüsseln","Encryption":"Verschlüsselung","Encryption changed":"Verschlüsselung geändert","Encryption modules:":"Verschlüsselungen:","Enter URL":"URL eingeben","Enter access key":"Zugriffsschlüssel angeben","Enter account name":"Account-Name angeben","Enter backup passphrase, if any":"Sicherungspassphrase eingeben, wenn nötig","Enter configuration details":"Konfigurationsdetails eingeben","Enter container name":"Container-Name angeben","Enter encryption passphrase":"Verschlüsselungpassphrase eingeben","Enter expression here":"Ausdruck hier eingeben","Enter folder path name":"Ordnerpfad eingeben","Enter one option per line in command-line format, eg. {0}":"Gib eine Option pro Zeile an im Kommandozeilen-Format, z.B. {0}","Enter the destination path":"Ziel-Pfad angeben","Error":"Fehler","Error!":"Fehler!","Errors and crashes":"Fehler und Abstürze","Exclude":"Ausschließen","Exclude directories whose names contain":"Ordner ausschließen dessen Namen beinhaltet","Exclude expression":"Filter (ausschließen)","Exclude file":"Datei ausschließen","Exclude file extension":"Dateiendung ausschließen","Exclude files whose names contain":"Dateien ausschließen dessen Namen beinhaltet","Exclude folder":"Ordner ausschließen","Exclude regular expression":"Regulären Ausdruck (ausschließen)","Existing file found":"Vorhandene Datenbank gefunden","Experimental":"Experimental","Export":"Exportieren","Export ...":"Exportieren...","Export backup configuration":"Sicherungskonfiguration exportieren","Export configuration":"Konfiguration exportieren","Exporting ...":"Exportieren...","FTP (Alternative)":"FTP (Alternativ)","Failed to build temporary database: {{message}}":"Erstellen der temporären Datenbank fehlgeschlagen: {{message}}","Failed to connect:":"Verbindung fehlgeschlagen:","Failed to connect: {{message}}":"Verbindung fehlgeschlagen: {{message}}","Failed to delete:":"Löschen fehlgeschlagen:","Failed to fetch path information: {{message}}":"Konnte Pfadangaben nicht abrufen: {{message}}","Failed to import:":"Import fehlgeschlagen:","Failed to read backup defaults:":"Konnte Sicherungsstandardeinstellungen nicht lesen:","Failed to restore files: {{message}}":"Wiederherstellung der Dateien fehlgeschlagen: {{message}}","Failed to save:":"Fehler beim Speichern:","Fetching path information ...":"Pfad-Infos werden ermittelt...","File":"Datei","Files larger than:":"Dateien größer als:","Filters":"Filter","Finished!":"Fertiggestellt!","Folder":"Ordner","Folder path":"Ordnerpfad","Fri":"Fr","GByte":"GByte","GByte/s":"GByte/s","GCS Project ID":"GCS Project ID","General":"Allgemein","General backup settings":"Allgemeine Sicherungseinstellungen","General options":"Allgemeine Einstellungen","Generate":"Erzeugen","Generate IAM access policy":"Generieren IAM Zugriffsrichtlinie","Getting file versions ...":"Erhalte Dateiversionen ...","Hidden files":"Versteckte Dateien","Hide":"Ausblenden","Hide hidden folders":"versteckte Ordner ausblenden","Home":"Home","Hours":"Stunden","How do you want to handle existing files?":"Wie sollen bestehende Dateien behandelt werden?","Hyper-V Machine":"Hyper-V-Maschine","Hyper-V Machine:":"Hyper-V-Maschine:","Hyper-V Machines":"Hyper-V-Maschinen","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"Wurde ein Zeitpunkt verpasst, startet die Sicherung so bald wie möglich.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Wenn lokale Daten und die Sicherung nicht mehr synchron sind, muss die lokale Datenbank repariert werden.\\nSollte die Reparatur nicht erfolgreich sein, so kann die lokale Datenbank gelöscht und neu erstellt werden.","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Wenn die Sicherungsdatei nicht automatisch heruntergeladen wurde, <a href=\"{{DownloadURL}}\" target=\"_blank\">klickst Du mit der rechten Maustaste und wählst \"Speichern unter...\" aus</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Wenn die Sicherungsdatei nicht automatisch heruntergeladen wurde, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">klickst De mit der rechten Maustaste und wählst \"Speichern unter...\" aus</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Ohne Pfad werden alle Dateien im Login-Verzeichnis gespeichert.\nMöchtest du das?","If you do not enter an API Key, the tenant name is required":"Wenn kein API Schlüssel angegeben wurde, ist der Tenant-Name erforderlich.","If you want to use the backup later, you can export the configuration before deleting it":"Wenn Du die Sicherung später verwenden möchtest, kann die Konfiguration vor dem Löschen exportiert werden","Import":"Importieren","Import Destination URL":"Ziel-URL importieren","Import backup configuration":"Sicherungskonfiguration importieren","Import completed, but no certificates were found after the import":"Import abgeschlossen, aber es wurde kein Zertifikat nach dem Import gefunden","Import failed":"Import fehlgeschlagen","Import from a file":"Von einer Datei importieren","Importing ...":"Importieren...","Include a file?":"Datei einfügen?","Include expression":"Filter (einschließen)","Include regular expression":"Regulären Ausdruck (einschließen)","Incorrect answer, try again":"Fehlerhafte Antwort, versuche es erneut","Individual builds for developers only.":"Individuelle Versionen für Entwickler.","Information":"Information","Install":"Installieren","Install failed:":"Installation fehlgeschlagen:","Invalid retention time":"Ungültige Aufbewahrungszeit","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"Manche FTP-Server erlauben einen Login ohne Passwort.\nBist Du sicher, dass Dein FTP-Server dazu gehört?","KByte":"KByte","KByte/s":"KByte/s","Keep this number of backups":"Behalte diese Anzahl von Backups","Language in user interface":"Sprache der Benutzeroberfläche","Last month":"Letzter Monat","Last successful run:":"Letzte erfolgreiche Sicherung:","Latest":"Neuste","Libraries":"Bibliotheken","Listing backup dates ...":"Sicherungsdaten werden aufgelistet...","Listing remote files ...":"Auflisten von Remote-Dateien...","Live":"Live","Load a configuration from an exported job or a storage provider":"Konfiguration aus einem exportierten Job oder Speicheranbieter laden","Load destination from an exported job or a storage provider":"Ziel aus einem exportierten Job oder Speicheranbieter laden","Load older data":"ältere Einträge laden","Loading ...":"Laden...","Loading remote storage usage ...":"Remote-Speicherplatznutzung abfragen...","Local database for":"Lokale Datenbank für","Local database path:":"Lokale Datenbank:","Local storage":"Lokaler Speicher","Location":"Ort","Location where buckets are created":"Speicherort, wo die Buckets erstellt werden","Log data for <b>{{Backup.Backup.Name}}</b>":"Logdaten für <b>{{Backup.Backup.Name}}</b>","Log data from the server":"Logdaten vom Server","Log out":"Abmelden","MByte":"MByte","MByte/s":"MByte/s","Maintenance":"Wartung","Manually type path":"Pfad eingeben","Max download speed":"Max. Downloadgeschwindigkeit","Max upload speed":"Max. Upload-Geschwindigkeit","Menu":"Menü","Microsoft SQL Database:":"Microsoft SQL Datenbank:","Microsoft SQL Databases":"Microsoft SQL Datenbanken","Minutes":"Minuten","Missing name":"Name fehlt","Missing passphrase":"Passphrase fehlt","Missing sources":"Quelle fehlt","Mon":"Mo","Months":"Monate","Move existing database":"Datenbank verschieben","Move failed:":"Verschieben fehlgeschlagen:","My Documents":"Dokumente","My Music":"Musik","My Photos":"Meine Fotos","My Pictures":"Bilder","Name":"Name","Never":"Nie","New update found: {{message}}":"Neues Update verfügbar: {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"Neuer Benutzername ist {{user}}.\nZugangsdaten für eingeschränken Benutzer verwendet","Next":"Weiter","Next scheduled run:":"Nächste geplante Ausführung:","Next scheduled task:":"Nächste geplante Aufgabe:","Next task:":"Nächste Aufgabe:","Next time":"Nächstes Mal","No":"Nein","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"Es wurde kein Zertifikat angegeben, mit dem der Serveradministrator prüft, ob der Schlüssel korrekt ist: {{key}}\n\nMöchtest Du den gemeldeten Host-Schlüssel freigeben?","No editor found for the &quot;{{backend}}&quot; storage type":"Kein Editor für den &quot;{{backend}}&quot; Speichertyp gefunden","No encryption":"Keine Verschlüsselung","No items selected":"Nichts ausgewählt","No items to restore, please select one or more items":"Es wurden keine Daten für die Wiederherstellung ausgewählt. Wähle eine Datei oder einen Ordner aus.","No passphrase entered":"Keine Passphrase eingegeben","No scheduled tasks":"Keine geplanten Aufgaben","Non-matching passphrase":"Nicht übereinstimmende Passphrase","None / disabled":"Keine / deaktiviert","OK":"OK","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Operation fehlgeschlagen:","Operations:":"Operationen:","Optional authentication password":"Passwort für Anmeldung (optional)","Optional authentication username":"Benutzername für Anmeldung (optional)","Options":"Optionen","Options added here are applied to all backups, but can be overridden in each individual backup":"Optionen, die hier gesetzt werden, werden auf alle Backups angewandt, können aber in jedem einzelnen Backup überschrieben werden","Original location":"Ursprünglicher Speicherort","Others":"Weitere","Overwrite":"Überschreiben","Passphrase":"Passphrase","Passphrase (if encrypted)":"Passphrase (falls verschlüsselt)","Passphrase changed":"Passphrase gändert","Passphrases are not matching":"Passphrasen stimmen nicht überein","Password":"Passwort","Passwords do not match":"Die Passwörter stimmen nicht überein","Patching files with local blocks ...":"Dateien mit vorhandenen Daten aufbauen...","Path not found":"Pfad nicht gefunden","Path on server":"Pfad auf Server","Path or subfolder in the bucket":"Pfad oder Unterverzeichnis im Bucket","Pause":"Pause","Pause after startup or hibernation":"Pause nach dem Aufwachen des PCs","Pause options":"Anhalten Optionen","Permissions":"Berechtigungen","Pick location":"Speicherort auswählen","Point to your backup files and restore from there":"Sicherungsdateien auswählen und wiederherstellen","Port":"Port","Previous":"Zurück","ProjectID is optional if the bucket exist":"Die Projekt-ID ist optional, wenn der Bucket existiert","Proprietary":"Proprietär","Purging files ...":"Lösche Dateien ...","Rebuilding local database ...":"Lokale Datenbank wieder aufbauen...","Recreate (delete and repair)":"Wiederherstellen (löschen und reparieren)","Recreating database ...":"Datenbank wird neu erstellt...","Registering temporary backup ...":"Temporäre Sicherung registrieren...","Relative paths not allowed":"Relative Pfade sind nicht möglich","Reload":"Neu laden","Remote":"Remote","Remove":"Entfernen","Remove option":"Option entfernen","Repair":"Reparieren","Reparing ...":"Reparieren...","Repeat Passphrase":"Passphrase wiederholen","Reporting:":"Bericht:","Reset":"Zurücksetzen","Restore":"Wiederherstellen","Restore files":"Dateien wiederherstellen","Restore files ...":"Dateien wiederherstellen...","Restore files from {{backupname}}":"Stelle Dateien von {{backupname}} wieder her","Restore from":"Wiederherstellen von","Restore from backup configuration":"Aus Sicherungskonfiguration wiederherstellen","Restore from configuration ...":"Aus Konfiguration wiederherstellen...","Restore options":"Wiederherstellungsoptionen","Restore read/write permissions":"Schreib- und Leserechte wiederherstellen","Restoring files ...":"Dateien werden wiederhergestellt...","Resume":"Fortsetzen","Run again every":"Wiederholen alle","Run now":"Jetzt sichern","Running ...":"Läuft...","Running ....":"Läuft ....","Running commandline entry":"Führe Kommandozeilenbefehl aus","Running task:":"Laufende Aufgabe:","S3 Compatible":"S3 Kompatibel","Same as the base install version: {{channelname}}":"Wie die zuerst installierte Version: {{channelname}}","Sat":"Sa","Save":"Speichern","Save and repair":"Speichern und reparieren","Save different versions with timestamp in file name":"Mehrere Versionen mit Zeitstempel im Dateinamen speichern","Save immediately":"Sofort speichern","Scanning existing files ...":"Vorhandene Dateien scannen...","Scanning for local blocks ...":"Vorhandene Daten scannen...","Schedule":"Zeitplan","Search":"Suche","Search for files":"Dateien suchen","Seconds":"Sekunden","Select a log level and see messages as they happen:":"Wähle ein Log-Level und sehe live die Meldungen:","Select files":"Wähle Dateien","Server":"Server","Server and port":"Server und Port","Server hostname or IP":"Server-Hostname oder IP","Server is currently paused,":"Server ist pausiert,","Server is currently paused, do you want to resume now?":"Server ist zurzeit pausiert, Server starten?","Server paused":"Server pausiert","Server state properties":"Server Zustandseigenschaften","Settings":"Einstellungen","Show":"Zeigen","Show advanced editor":"Profi-Modus anzeigen","Show hidden folders":"Zeige versteckte Ordner","Show log":"Logfile anzeigen","Show log ...":"Log-Datei anzeigen...","Show treeview":"Zeige Baumansicht","Some OpenStack providers allow an API key instead of a password and tenant name":"Einige OpenStack Anbieter erlauben einen API Schlüssel anstelle eines Passwortes und Tenant Namen","Source Data":"Quell-Daten","Source data":"Quell-Daten","Source folders":"Quell-Verzeichnisse","Source:":"Quelle:","Specific builds for developers only.":"Spezielle Versionen für Entwickler.","Standard protocols":"Standardprotokolle","Starting ...":"Los geht's...","Starting the restore process ...":"Wiederherstellung wird gestartet...","Stop after the current file":"Beende nach aktueller Datei","Stop after upload":"Beende nach Hochladen","Stop now":"Beenden","Stop running backup":"Beende laufende Sicherung","Stop running task":"Beende laufenden Vorgang","Stopping after upload:":"Beende nach Hochladen","Stopping task:":"Beende Vorgang","Storage Type":"Speichertyp","Storage class":"Speicherklasse","Storage class for creating a bucket":"Speicherklasse zum Erstellen eines Bucket","Stored":"Gespeichert","Strong":"Stark","Success":"Erfolgreich","Sun":"So","Symbolic link":"Symbolischer Link","System default ({{levelname}})":"System-Standard ({{levelname}})","System files":"Systemdateien","System info":"System-Informationen","System properties":"System-Eigenschaften","TByte":"TByte","TByte/s":"TByte/s","Task is running":"Aufgabe wird ausgeführt","Temporary files":"Temporäre Dateien","Tenant Name":"Tenant-Name","Test connection":"Verbindung prüfen","Testing ...":"Testen...","Testing connection ...":"Teste Verbindung...","Testing permissions ...":"Rechte werden geprüft...","Testing permissions...":"Rechte werden geprüft...","The bucket name should be all lower-case, convert automatically?":"Der Bucket sollte klein geschrieben sein. Jetzt klein schreiben?","The bucket name should start with your username, prepend automatically?":"Der Bucket-Name sollte mit Deinem Benutzernamen beginnen. Benutzername hinzufügen?","The connection to the server is lost, attempting again in {{time}} ...":"Die Verbindung zum Server wurde verloren. Versuch erneut in {{time}}...","The dark theme (by Michal)":"Dunkles Thema (von Michal)","The default blue on white theme (by Alex)":"Blau-auf-Weiß Thema (von Alex)","The folder {{folder}} does not exist\nCreate it now?":"Der Ordner {{folder}} existiert nicht\nJetzt erstellen?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"Der Host-Schlüssel wurde geändert, bitte prüfe mit dem Server Administrator ob dieser korrekt ist, ansonsten könntest Du ein Opfer eines MAN-IN-THE-MIDDLE-Angriffs sein.\n\nMöchtest du den AKTUELLEN Host-Schüssel \"{{prev}}\" mit dem GEMELDETEN Host-Schüssel {{key}} ERSETZEN?","The path does not appear to exist, do you want to add it anyway?":"Der Pfad scheint nicht zu existieren. Möchtest Du ihn trotzdem hinzufügen?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"Ohne das abschließende '{{dirsep}}' fügst du eine Datei hinzu und kein Verzeichnis.\n\nMöchtest du diese Datei hinzufügen?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"Der Pfad muss ein absoluter Pfad sein. Das heißt, er muss mit '/' beginnen","The path should start with \"{{prefix1}}\" or \"{{prefix2}}\", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?":"Der Pfad sollte mit \"{{prefix1}}\" oder \"{{prefix2}}\" beginnen. Ansonsten wirst du die Dateien nicht auf der HubiC-Webseite sehen können.\n\nSoll das Präfix automatisch hinzugefügt werden?","The region parameter is only applied when creating a new bucket":"Der Bereich Parameter wird nur angewendet, wenn ein neuer Bucket erzeugt wird","The region parameter is only used when creating a bucket":"Der Bereich Parameter wird nur angewendet, wenn ein Bucket erzeugt wird","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"Das Server Zertifikat könnte nicht validiert werden.\nMöchtest du das SSL-Zertifikat mit dem folgenden Hash freigeben: {{hash}}?","The storage class affects the availability and price for a stored file":"Die Speicherklasse wirkt sich auf die Verfügbarkeit und den Preis einer gespeicherten Datei aus","The target folder contains encrypted files, please supply the passphrase":"Das Ziel enthält verschlüsselte Dateien. Wir benötigen ein Passwort!","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"Der Nutzer hat zu viele Rechte. Möchtest Du einen Nutzer mit eingeschränkten Berechtigungen für den gewählten Pfad erstellen?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"Dieses Backup wurde mit einem anderen Betriebssystem erstellt. Die Wiederherstellung von Dateien ohne Angabe eines Zielverzeichnisses, kann dazu führen das diese an ungewünschten Stellen wiederhergestellt werden. Bist du dir sicher fortzufahren ohne ein Zielverzeichnis zu wählen?","This month":"Dieser Monat","This week":"Diese Woche","Throttle settings":"Drosseleinstellungen","Thu":"Do","To File":"als Datei","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"Zum Bestätigen für das Löschen der Remote-Dateien für \"{{name}}\", bitte das unten angegebene Wort eingeben","To export without a passphrase, uncheck the \"Encrypt file\" box":"Entferne den Haken für die Verschlüsselung, um ohne Passwort zu exportieren","Today":"Heute","Trust host certificate?":"Host Zertifikat vertrauen?","Trust server certificate?":"Server Zertifikat vertrauen?","Try out the new features we are working on. Don't use with important data.":"Neue Funktionen ausprobieren. Nutze diese Versionen nicht mit wichtigen Daten!","Tue":"Di","Type to highlight files":"Tippen, um Dateien zu markieren","Unknown backup size and versions":"Unbekannte Backupgröße und -versionen","Until resumed":"Bis zur Wiederaufnahme","Update channel":"Update-Kanal","Update failed:":"Update fehlgeschlagen:","Updating with existing database":"Datenbank wird aktualisiert","Upload volume size":"Dateigröße beim Upload","Uploading verification file ...":"Prüfdatei hochladen...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"Nutzungsberichte helfen uns bei der Weiterentwicklung. Wir generieren daraus <a href=\"{{link}}\" target=\"_blank\">öffentliche Nutzungsstatistiken</a>","Usage statistics":"Nutzungsstatistiken","Usage statistics, warnings, errors, and crashes":"Nutzungsberichte, Warnungen, Fehler und Abstürze","Use SSL":"SSL benutzen","Use existing database?":"Bestehende Datenbank nutzen?","Use weak passphrase":"Schwache Passphrase verwenden","Useless":"Nutzlos","User data":"Benutzer Daten","User has too many permissions":"Nutzer hat zu viele Rechte","User interface settings":"Einstellungen der Benutzeroberfläche","Username":"Benutzername","VISA, Mastercard, ... via Paypal":"VISA, Mastercard, ... via Paypal","Validating ...":"Validieren...","Verify files":"Dateien prüfen","Verifying ...":"Prüfen...","Verifying answer":"Antwort verifizieren","Verifying backend data ...":"Verifiziere Backend-Daten...","Verifying remote data ...":"Remotedaten prüfen ...","Verifying restored files ...":"Wiederhergestellte Dateien prüfen...","Very strong":"Sehr stark","Very weak":"Sehr schwach","Visit us on":"Besuche uns auf","WARNING: The remote database is found to be in use by the commandline library":"WARNUNG: Die Remote-Datenbank wird bereits von der Kommandozeilen Bibliothek verwendet","WARNING: This will prevent you from restoring the data in the future.":"WARNUNG: Dadurch kannst Du die Daten in Zukunft nicht wiederherstellen.","Waiting for task to begin":"Warte darauf, loslegen zu können","Waiting for task to start ....":"Warte auf Aufgabenstart","Waiting for upload ...":"Auf den Upload warten...","Warnings, errors and crashes":"Warnungen, Fehler und Abstürze","We recommend that you encrypt all backups stored outside your system":"Wir empfehlen, alle Sicherungen außerhalb Deines Systems zu verschlüsseln","Weak":"Schwach","Weak passphrase":"Schwache Passphrase","Wed":"Mi","Weeks":"Wochen","Where do you want to restore from?":"Von wo wollen Sie wiederherstellen?","Where do you want to restore the files to?":"Wohin sollen die Dateien wiederhergestellt werden?","Years":"Jahre","Yes":"Ja","Yes, I have stored the passphrase safely":"Ja, ich habe die Passphrase sicher gespeichert","Yes, I'm brave!":"Ja, ich bin mutig!","Yes, please break my backup!":"Ja, mach meine Sicherung kaputt!","Yesterday":"Gestern","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"Mono scheint ohne geladenen SSL-Zertifikate zu laufen.\nMöchtest du die Liste von vertrauenswürdigen Zertifikate von Mozilla importieren?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"Du änderst gerade den Pfad zur lokalen Datenbank.\nWeißt Du, was Du da tust?","You are currently running {{appname}} {{version}}":"Aktuell wird {{appname}} {{version}} verwendet","You can stop the backup immediately, or stop after the current file has been uploaded.":"Das Backup kann sofort angehalten werden, oder nachdem die aktuelle Datei hochgeladen wurde.","You can stop the task immediately, or allow the process to continue its current file and the stop.":"Die Aufgabe kann sofort angehalten werden, oder nachdem der Prozess die aktuelle Datei abgeschlossen hat.","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"Du hast die Verschlüsselung geändert. Dadurch kann die bestehende Sicherung unbenutzbar sein. Erstelle lieber eine neue Sicherung.","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"Du hast die Passphrase geändert. Dadurch kann die bestehende Sicherung unbenutzbar sein. Erstelle lieber eine neue Sicherung.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"Du hast gewählt, die Sicherung nicht zu verschlüsseln. Die Verschlüsselung wird für alle auf einem Remoteserver gespeicherten Daten empfohlen.","You have chosen to restore to a new location, but not entered one":"Wiederherstellen an einen neuen Ort wurde gewählt, aber kein Ort angegeben","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"Du hast eine starke Passphrase generiert. Stelle sicher, dass Du eine sichere Kopie der Passphrase gemacht hast, da die Daten nicht wiederhergestellt werden können, wenn Du die Passphrase verlierst.","You must choose at least one source folder":"Du musst schon ein Quellverzeichnis wählen","You must enter a name for the backup":"Du musst einen Namen für die Sicherung eingeben","You must enter a passphrase or disable encryption":"Du musst eine Passphrase eingeben oder die Verschlüsselung deaktivieren","You must enter a positive number of backups to keep":"Du musst eine positive Nummer der zu behaltenden Sicherungen eingeben","You must enter a tenant name if you do not provide an API Key":"Gib einen Kundennamen an, wenn Du keinen API-Key hast.","You must enter a valid duration for the time to keep backups":"Du musst einen gültigen Zeitraum der zu behaltenden Sicherungen eingeben","You must enter either a password or an API Key":"Gib einen API-Key oder ein Passwort ein.","You must enter either a password or an API Key, not both":"Gib einen API-Key oder ein Passwort an. Aber nicht beides!","You must fill in the password":"Du musst ein Passwort eintragen!","You must fill in the server name or address":"Du musst einen Servernamen oder eine Adresse eintragen!","You must fill in the username":"Du musst einen Benutzernamen eintragen!","You must fill in {{field}}":"{{field}} muss ausgefüllt sein","You must select or fill in the AuthURI":"Du musst die AuthURI auswählen oder eintragen","You must select or fill in the server":"Du musst den Server auswählen oder eintragen","You must specify a path":"Du musst einen Pfad angeben","Your files and folders have been restored successfully.":"Dateien und Ordner erfolgreich wiederhergestellt.","Your passphrase is easy to guess. Consider changing passphrase.":"Deine Passphrase ist leicht zu erraten. Nimm lieber etwas Komplizierteres.","a specific number":"eine Anzahl","bucket/folder/subfolder":"Bucket/Ordner/Unterordner","byte":"Byte","byte/s":"Byte/s","custom":"benutzerdefiniert","resume now":"Jetzt starten","unlimited":"unbegrenzt","until they are older than":"Bis sie älter sind als","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} wurde hauptsächlich von <a href=\"{{mail1}}\">{{dev1}}</a> und <a href=\"{{mail2}}\">{{dev2}}</a> entwickelt. {{appname}} kann unter folgender Adresse heruntergeladen werden: <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} ist unter <a href=\"{{licenselink}}\">{{licensename}}</a> lizenziert.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":["{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versionen"],"{{number}} Hour":"{{number}} Stunde","{{number}} Minutes":"{{number}} Minuten","{{time}} (took {{duration}})":"{{time}} (dauerte {{duration}})"});
+ gettextCatalog.setStrings('es', {"- pick an option -":"- escoja una opción -","...loading...":"...cargando...","API Key":"Clave API","AWS Access ID":"AWS Acceso ID","AWS Access Key":"AWS Clave de aceso","AWS IAM Policy":"AWS IAM Política","About":"Acerca de","About {{appname}}":"Acerca de {{appname}}","Access Key":"Clave de acceso","Access denied":"Acceso denegado","Access to user interface":"Acceso a la interfaz de usuario","Account name":"Nombre de la cuenta","Activate":"Activar","Activate failed:":"Activar fallido:","Add a new backup":"Añadir nueva copia de seguridad","Add advanced option":"Añadir opción avanzada","Add backup":"Añadir copia de seguridad","Add filter":"Añadir filtro","Add path":"Añadir ruta","Adjust bucket name?":"¿Ajustar el nombre del deposito?","Adjust path name?":"¿Ajustar el nombre de la ruta?","Advanced Options":"Opciones Avanzadas","Advanced options":"Opciones avanzadas","Advanced:":"Avanzado:","All Hyper-V Machines":"Todas las máquinas de Hyper-V","All Microsoft SQL Databases":"Las bases de datos de Microsoft SQL","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Todos los informes de uso son enviados anónimamente y no contienen ninguna información personal. Contiene información sobre hardware y sistema operativo, el tipo de respaldo, duración de copia de seguridad, tamaño de fuente de datos y similares. No contiene rutas, nombres de archivos, nombres de usuarios, contraseñas o información sensible similar.","Allow remote access (requires restart)":"Permitir el acceso remoto (requiere reiniciar)","Allowed days":"Días permitidos","An existing file was found at the new location":"Se encontró un archivo existente en la nueva ubicación","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"Se encontró un archivo existente en la nueva ubicación\n¿Está seguro que desea que la base de datos apunte a un archivo existente?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"Se ha encontrado una base de datos local existente para el almacenamiento.\nVolver a utilizar la base de datos permitirá a las instancias de línea de comandos y al servidor trabajar con el mismo almacenamiento remoto.\n\n¿Desea utilizar la base de datos existente?","Anonymous usage reports":"Informes de uso anónimos","As Command-line":"Como Línea de comandos","AuthID":"AuthID","Authentication password":"Contraseña de autenticación","Authentication username":"Nombre de usuario de autenticación","Autogenerated passphrase":"Autogenerar frase de seguridad","Automatically run backups.":"Ejecutar automáticamente las copias de seguridad.","B2 Account ID":"B2 Cuenta ID","B2 Application Key":"B2 clave de aplicación","B2 Cloud Storage Account ID":"B2 Cuenta Cloud Storage ID","B2 Cloud Storage Application Key":"B2 Clave de aplicación de Cloud Storage","Back":"Volver","Backend modules:":"Módulos de respaldo:","Backup destination":"Destino de la copia de seguridad","Backup location":"Ubicación de la copia de seguridad","Backup:":"Copia de seguridad:","Beta":"Beta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Broken access":"Acceso roto","Browse":"Navega","Browser default":"Navegador por defecto","Bucket Name":"Nombre del depósito","Bucket create location":"Crear la ubicación del depósito","Bucket create region":"Crear región en depósito","Bucket name":"Nombre del depósito","Bucket storage class":"Categoría de almacenamiento del depósito","Building list of files to restore ...":"Construir lista de archivos a restaurar ...","Building partial temporary database ...":"Construcción parcial de la base de datos temporal ...","Busy ...":"Ocupado ...","Canary":"Experimental e inestable (Canary)","Cancel":"Cancelar","Cannot move to existing file":"No se puede mover al archivo existente","Changelog":"Registro de cambios","Changelog for {{appname}} {{version}}":"Registro de cambios para {{appname}} {{version}}","Check failed:":"Error en chequeo:","Check for updates now":"Comprobar actualizaciones ahora","Checking ...":"Comprobando ...","Checking for updates ...":"Comprobando actualizaciones ...","Chose a storage type to get started":"Elija un tipo de almacenamiento para empezar","Click the AuthID link to create an AuthID":"Haga clic en el enlace de AuthID para crear una AuthID","Compact now":"Compactar ahora","Compacting remote data ...":"Compactando datos remotos ...","Completing backup ...":"Completando copia de seguridad ...","Completing previous backup ...":"Completando copia de seguridad anterior ...","Compression modules:":"Módulos de compresión:","Computer":"Ordenador","Configuration file:":"Archivo de configuración:","Configuration:":"Configuración:","Configure a new backup":"Configurar nueva copia de seguridad","Confirm delete":"Confirmar borrado","Confirmation required":"Confirmación necesaria","Connect":"Conectar","Connect now":"Conectar ahora","Connecting...":"Conectando...","Connection lost":"Conexión perdida","Connection worked!":"¡La conexión funcionó!","Container name":"Nombre del contenedor","Container region":"Contenedor de región","Continue":"Continuar","Continue without encryption":"Continuar sin cifrado","Copied!":"¡Copiado!","Copy Destination URL to Clipboard":"Copiar la URL de destino al portapapeles","Copy failed. Please manually copy the URL":"Copía fallida. Por favor, copia manualmente la dirección URL","Core options":"Opciones de base","Counting ({{files}} files found, {{size}})":"Contando ({{files}} archivos encontrados, {{size}})","Crashes only":"Sólo bloqueos","Create bug report ...":"Crear informe de error ...","Create folder?":"¿Crear carpeta?","Created new limited user":"Creó un nuevo usuario limitado","Creating bug report ...":"Creando un informe de error ...","Creating new user with limited access ...":"Crear nuevo usuario con acceso limitado ...","Creating target folders ...":"Creando las carpetas de destino ...","Creating temporary backup ...":"Creando una copia de seguridad temporal ...","Creating user...":"Creando usuario...","Current version is {{versionname}} ({{versionnumber}})":"La versión actual es {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"Personalizada S3 endpoint","Custom authentication url":"Url de autenticación personalizada","Custom location ({{server}})":"Ubicación personalizada ({{server}})","Custom region for creating buckets":"Región personalizada para la creación de depósitos","Custom region value ({{region}})":"Personalizar el valor de la región ({{region}})","Custom server url ({{server}})":"Url del servidor personalizada ({{server}})","Custom storage class ({{class}})":"Categoría de almacenamiento personalizado ({{class}})","Days":"Días","Default":"Por defecto","Default ({{channelname}})":"({{channelname}}) por defecto","Default options":"Opciones por defecto","Delete":"Eliminar","Delete ...":"Eliminar ...","Delete backup":"Eliminar copia de seguridad","Delete local database":"Eliminar base de datos local","Delete remote files":"Eliminar archivos remotos","Delete the local database":"Eliminar la base de datos local","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"¿Eliminar {{filecount}} archivos con ({{filesize}}) del almacenamiento remoto?","Deleting remote files ...":"Eliminando archivos remotos ...","Deleting unwanted files ...":"Eliminando archivos no deseados ...","Desktop":"Escritorio","Destination":"Destino","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"¿Le hemos ayudado a guardar sus archivos? Si es así, por favor considere apoyar a Duplicati con una donación. Le sugerimos {{smallamount}} para uso privado y {{largeamount}} para uso comercial.","Direct restore from backup files ...":"Restaurar directamente desde ficheros de copia de seguridad...","Disabled":"Desactivar","Dismiss":"Descartar","Do you really want to delete the backup: \"{{name}}\" ?":"¿Realmente desea eliminar la copia de seguridad: \"{{name}}\"?","Do you really want to delete the local database for: {{name}}":"Realmente desea eliminar la base de datos local: {{name}}","Donate":"Donar","Donate with Bitcoins":"Donar con Bitcoins","Donate with PayPal":"Donar con PayPal","Donation messages":"Mensajes de donación","Donation messages are hidden, click to show":"El mensaje de donación está oculto, haga clic para mostrar","Donation messages are visible, click to hide":"El mensaje de donación está visible, haga clic para ocultar","Done":"Hecho","Download":"Descargar","Downloading ...":"Descargando ...","Downloading files ...":"Descargando archivos ...","Downloading update...":"Descargando actualizaciones...","Duplicate option {{opt}}":"Opciones de duplicado {{opt}}","Duplicati Website":"Sitio Web Duplicati","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\n When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.\n If you are using the local database for backups from the commandline, you should keep the database.":"Cada copia tiene una base de datos local asociada que almacena información sobre la copia de seguridad remota en la máquina local.\nAl eliminar una copia de seguridad, también puede borrar la base de datos local sin afectar a la habilidad de restaurar los archivos remotos.\nSi está utilizando la base de datos local para copias de seguridad desde la línea de comandos, debe mantener la base de datos.","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Cada copia de seguridad tiene una base de datos local asociado a él, esta almacena información acerca de la copia de seguridad remota en el equipo local.\\nEsto hace más rápido realizar muchas operaciones y reduce la cantidad de datos que necesita descargarse para cada operación.","Edit ...":"Editar ...","Edit as list":"Editar lista","Edit as text":"Editar como texto","Encrypt file":"Cifrar archivo","Encryption":"Cifrado","Encryption changed":"Cambios de cifrado","Encryption modules:":"Módulos de cifrado:","Enter URL":"Introduzca URL","Enter access key":"Introduzca la clave de acceso","Enter account name":"Introduce el nombre de la cuenta","Enter backup passphrase, if any":"Introduzca la frase de seguridad, si la hay","Enter configuration details":"Introduzca los detalles de configuración","Enter container name":"Introduce el nombre de contenedor","Enter encryption passphrase":"Introduzca la frase de seguridad","Enter expression here":"Introduzca aquí la expresión","Enter folder path name":"Introduzca nombre de ruta de la carpeta","Enter one option per line in command-line format, eg. {0}":"Introduzca una opción por línea, en formato de línea de comandos, por ejemplo: {0}","Enter the destination path":"Introduzca la ruta de destino","Error":"Error","Error!":"¡Error!","Errors and crashes":"Errores y bloqueos","Exclude":"Excluir","Exclude directories whose names contain":"Excluir directorios cuyos nombres contienen","Exclude expression":"Excluir expresión","Exclude file":"Excluir archivos","Exclude file extension":"Excluir extensión de archivo","Exclude files whose names contain":"Excluir archivos cuyos nombres contengan","Exclude folder":"Excluir la carpeta","Exclude regular expression":"Excluir la expresión regular","Existing file found":"Archivo existente encontrado","Experimental":"Experimental","Export":"Exportar","Export ...":"Exportar ...","Export backup configuration":"Exportar configuración de copia de seguridad","Export configuration":"Exportar configuración","Exporting ...":"Exportando ...","FTP (Alternative)":"FTP (Alternativa)","Failed to build temporary database: {{message}}":"Error al crear base de datos temporal: {{message}}","Failed to connect:":"Fallo al conectar:","Failed to connect: {{message}}":"No se pudo conectar: {{message}}","Failed to delete:":"Error al eliminar:","Failed to fetch path information: {{message}}":"Error al recuperar información de la ruta: {{message}}","Failed to import:":"Fallo al importar:","Failed to read backup defaults:":"Error al leer los valores predeterminados de copia de seguridad:","Failed to restore files: {{message}}":"Fallo al restaurar archivos: {{message}}","Failed to save:":"Error al guardar:","Fetching path information ...":"Obteniendo información de ruta ...","File":"Archivo","Files larger than:":"Archivos que superen:","Filters":"Filtros","Finished!":"¡Terminado!","Folder":"Carpeta","Folder path":"Ruta de la carpeta","Fri":"Vie","GByte":"GByte","GByte/s":"GByte/s","GCS Project ID":"GCS Proyecto ID","General":"General","General backup settings":"Configuración general de la copia de seguridad","General options":"Opciones generales","Generate":"Generar","Generate IAM access policy":"Generar política de acceso IAM","Getting file versions ...":"Recuperando versiones de ficheros...","Hidden files":"Archivos ocultos","Hide":"Ocultar","Hide hidden folders":"Ocultar carpetas ocultas","Home":"Inicio","Hours":"Horas","How do you want to handle existing files?":"¿Cómo desea manejar los archivos existentes?","Hyper-V Machine":"Máquina Hyper-V","Hyper-V Machine:":"Máquina Hyper-V:","Hyper-V Machines":"Máquinas Hyper-V","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"Si la fecha se paso, se ejecutará el trabajo tan pronto como sea posible.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Si la copia de seguridad y el almacenamiento remoto están fuera de sincronización, Duplicati requerirá que realice una operación de reparación para sincronizar la base de datos. \\nSi la reparación fracasa, puede eliminar la base de datos local y volver a generarla.","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Si el archivo de copia de seguridad no se descarga automáticamente, <a href=\"{{DownloadURL}}\" target=\"_blank\">haga click derecho y elija &quot;Guardar como ...&quot;</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Si el archivo de copia de seguridad no se descarga automáticamente, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">haga click derecho y elija &quot;Guardar como ...&quot;</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Si no introduce una ruta, todos los archivos se almacenarán en la carpeta de inicio de sesión.\n¿Está seguro que es lo que quiere?","If you do not enter an API Key, the tenant name is required":"Si no introduce una clave API, requerirá el nombre de cliente","If you want to use the backup later, you can export the configuration before deleting it":"Si desea utilizar la copia de seguridad más adelante, puede exportar la configuración antes de eliminarla","Import":"Importar","Import Destination URL":"Importar Destino URL","Import backup configuration":"Importar configuración de copias de seguridad","Import completed, but no certificates were found after the import":"Importación completada, pero no se han encontrado certificados despues de la importación","Import failed":"Importación fallida","Importing ...":"Importando ...","Include a file?":"¿Incluir un archivo?","Include expression":"Incluir una expresión","Include regular expression":"Incluir una expresión regular","Incorrect answer, try again":"Respuesta incorrecta, intente de nuevo","Individual builds for developers only.":"Compilación individual sólo para desarrolladores.","Information":"Información","Install":"Instalar","Install failed:":"Error de instalación:","Invalid retention time":"Tiempo de retención no válido","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"Es posible conectar a un FTP sin contraseña.\n¿Está seguro que su servidor FTP admite los inicios de sesión sin contraseña?","KByte":"KByte","KByte/s":"KByte/s","Language in user interface":"Idioma de interfaz de usuario","Last month":"Mes pasado","Last successful run:":"Última ejecución exitosa:","Latest":"Más reciente","Libraries":"Librerías","Listing backup dates ...":"Listado de fechas de copia de seguridad ...","Listing remote files ...":"Listado de archivos remotos ...","Live":"En vivo","Load a configuration from an exported job or a storage provider":"Cargar una configuración desde un trabajo exportado o un proveedor de almacenamiento","Load destination from an exported job or a storage provider":"Cargar un destino desde un trabajo exportado o un proveedor de almacenamiento","Load older data":"Cargar datos anteriores","Loading ...":"Cargando ...","Loading remote storage usage ...":"Cargando el uso del almacenamiento remoto ...","Local database for":"Base de datos local para","Local database path:":"Ruta de la base de datos local:","Local storage":"Almacenamiento local","Location":"Localización","Location where buckets are created":"La ubicación donde se crean los depósitos","Log data for <b>{{Backup.Backup.Name}}</b>":"Registrar datos para <b>{{Backup.Backup.Name}}</b>","Log data from the server":"Registrar datos desde el servidor","Log out":"Desconectar","MByte":"MByte","MByte/s":"MByte/s","Maintenance":"Mantenimiento","Manually type path":"Escribir manualmente la ruta","Menu":"Menú","Microsoft SQL Database:":"Base de datos Microsoft SQL:","Microsoft SQL Databases":"Bases de datos Microsoft SQL:","Minutes":"Minutos","Missing name":"Falta el nombre","Missing passphrase":"Falta la frase de seguridad","Missing sources":"Faltan las fuentes","Mon":"Lun","Months":"Meses","Move existing database":"Mover base de datos existente","Move failed:":"Fallos al mover:","My Documents":"Mis Documentos","My Music":"Mi Música","My Photos":"Mis Fotos","My Pictures":"Mis Imágenes","Name":"Nombre","Never":"Nunca","New update found: {{message}}":"Nueva actualización encontrada: {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"El nuevo nombre de usuario es {{user}}.\nCredenciales actualizadas para el nuevo usuario restringido","Next":"Siguiente","Next scheduled run:":"Siguiente ejecución programada:","Next scheduled task:":"Siguiente tarea programada:","Next task:":"Siguiente tarea:","Next time":"La próxima vez","No":"No","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"No se especificó previamente un certificado, por favor verifica con el administrador del servidor que la llave es correcta: {{key}}\n\n¿Desea aprobar la llave del host reportada?","No editor found for the &quot;{{backend}}&quot; storage type":"Ningún editor para el &quot;{{backend}}&quot; tipo de almacenamiento","No encryption":"Sin cifrado","No items selected":"No hay artículos seleccionados","No items to restore, please select one or more items":"No hay artículos para restaurar, seleccione uno o más elementos","No passphrase entered":"No se introdujo clave de seguridad","No scheduled tasks":"No hay tareas programadas","Non-matching passphrase":"No coincide la frase de seguridad","None / disabled":"Ninguno / desactivado","OK":"OK","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Operación fallida:","Operations:":"Operaciones:","Optional authentication password":"Contraseña de autentificación opcional","Optional authentication username":"Nombre de usuario para autentificación opcional","Options":"Opciones","Original location":"Localización original","Others":"Otros","Overwrite":"Sobrescribir","Passphrase":"Frase de seguridad","Passphrase (if encrypted)":"Frase de seguridad (con cifrado)","Passphrase changed":"Frase de seguridad cambiada","Passphrases are not matching":"Las frases de seguridad no coinciden","Password":"Contraseña","Passwords do not match":"La contraseña no coincide","Patching files with local blocks ...":"Arreglar los archivos con bloques locales ...","Path not found":"Ruta no encontrada","Path on server":"Ruta del servidor","Path or subfolder in the bucket":"Ruta o subcarpeta en el depósito","Pause":"Pausa","Pause after startup or hibernation":"Pausar después del arranque o de hibernación","Pause options":"Opciones de pausa","Permissions":"Permisos","Pick location":"Elegir ubicación","Point to your backup files and restore from there":"Indique sus ficheros de copia de seguridad y restáurelos desde allí","Port":"Puerto","Previous":"Anterior","ProjectID is optional if the bucket exist":"ProjectID es opcional si el depósito existe","Proprietary":"Propietario","Purging files ...":"Purgando ficheros...","Rebuilding local database ...":"Reconstruyendo la base de datos local ...","Recreate (delete and repair)":"Recrear (borrar y reparar)","Recreating database ...":"Recreando base de datos ...","Registering temporary backup ...":"Registrando copia de seguridad temporal …","Relative paths not allowed":"No se permiten rutas relativas","Reload":"Recargar","Remote":"Remoto","Remove":"Quitar","Remove option":"Quitar opción","Repair":"Reparar","Reparing ...":"Reparando ...","Repeat Passphrase":"Repita la frase de seguridad","Reporting:":"Reportando:","Reset":"Resetear","Restore":"Restaurar","Restore files":"Restaurar archivos","Restore files ...":"Restaurar archivos ...","Restore files from {{backupname}}":"Restaurar ficheros desde {{backupname}}","Restore from":"Restaurar desde","Restore from backup configuration":"Restaurar desde una configuración de copia de seguridad","Restore from configuration ...":"Restaurar desde una configuración...","Restore options":"Opciones de restauración","Restore read/write permissions":"Restaurar permisos de lectura/escritura","Restoring files ...":"Restaurando archivos ...","Resume":"Resumir","Run again every":"Volver a ejecutar cada","Run now":"Ejecutar ahora","Running ...":"Ejecutando ...","Running task:":"Ejecutando tarea:","S3 Compatible":"S3 Compatible","Same as the base install version: {{channelname}}":"Igual que la versión base instalada: {{channelname}}","Sat":"Sab","Save":"Guardar","Save and repair":"Guardar y reparar","Save different versions with timestamp in file name":"Guardar diferentes versiones con fecha y hora en el nombre de archivo","Save immediately":"Guardar inmediatamente","Scanning existing files ...":"Analizando los archivos existentes ...","Scanning for local blocks ...":"Analizando bloques locales ...","Schedule":"Horario","Search":"Buscar","Search for files":"Buscar archivos","Seconds":"Segundos","Select a log level and see messages as they happen:":"Seleccione un nivel de registro y vea los mensajes a medida que ocurren:","Select files":"Seleccionar ficheros","Server":"Servidor","Server and port":"Servidor y puerto","Server hostname or IP":"Nombre del servidor o IP","Server is currently paused,":"El servidor se encuentra en pausa,","Server is currently paused, do you want to resume now?":"El servidor se encuentra en pausa, ¿quiere reanudar ahora?","Server paused":"Servidor pausado","Server state properties":"Propiedades del estado del servidor","Settings":"Configuraciones","Show":"Mostrar","Show advanced editor":"Mostrar el editor avanzado","Show hidden folders":"Mostrar carpetas ocultas","Show log":"Mostrar registro","Show log ...":"Mostrar registro ...","Show treeview":"Mostrar vista de árbol","Some OpenStack providers allow an API key instead of a password and tenant name":"Algunos proveedores de OpenStack permiten una clave API en lugar de un nombre del cliente y contraseña","Source Data":"Datos de Origen","Source data":"Datos de origen","Source folders":"Carpetas de origen","Source:":"Origen:","Specific builds for developers only.":"Compilación específica solo para desarrolladores.","Standard protocols":"Protocolos estándar","Starting ...":"Iniciando ...","Starting the restore process ...":"Iniciando el proceso de restauración ...","Storage Type":"Tipo de Almacenamiento","Storage class":"Categoría de almacenamiento","Storage class for creating a bucket":"Categoría de almacenamiento para la creación de un depósito","Stored":"Almacenados","Strong":"Fuerte","Success":"Éxito","Sun":"Dom","Symbolic link":"Enlace simbólico","System default ({{levelname}})":"Sistema por defecto ({{levelname}})","System files":"Archivos de sistema","System info":"Información del sistema","System properties":"Propiedades del sistema","TByte":"TByte","TByte/s":"TByte/s","Task is running":"La tarea está ejecutandose","Temporary files":"Archivos temporales","Tenant Name":"Nombre del Cliente","Test connection":"Conexión de prueba","Testing ...":"Probando …","Testing connection ...":"Probando la conexión ...","Testing permissions ...":"Probando permisos …","Testing permissions...":"Probando permisos…","The bucket name should be all lower-case, convert automatically?":"El nombre del depósito debe ser todo en minúsculas, ¿convertir automáticamente?","The bucket name should start with your username, prepend automatically?":"El nombre del depósito debe empezar con su nombre de usuario, ¿anteponer automáticamente?","The connection to the server is lost, attempting again in {{time}} ...":"La conexión al servidor se perdió, intentar otra vez en {{time}} ...","The folder {{folder}} does not exist\nCreate it now?":"La carpeta {{folder}} no existe\n¿Crearla ahora?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"La clave de host fue cambiada, compruebe con el administrador del servidor si esto es correcto, de lo contrario usted podría ser víctima de un ataque MAN-IN-THE-MIDDLE.\n\n¿Desea REMPALAZAR su ACTUAL clave de host \"{{prev}}\" con la clave del host REGISTRADA: {{key}}?","The path does not appear to exist, do you want to add it anyway?":"La ruta parece que no existe, ¿desea agregar de todos modos?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"La ruta no termina con un carácter '{{dirsep}}', que significa que incluye un archivo, no una carpeta.\n\n¿Desea incluir el archivo especificado?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"La ruta debe ser una ruta absoluta, es decir, debe comenzar con una barra '/'","The region parameter is only applied when creating a new bucket":"El parámetro de la región sólo se aplica al crear un nuevo depósito","The region parameter is only used when creating a bucket":"El parámetro de la región sólo se utiliza al crear un depósito","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"El certificado del servidor no puede ser validado.\n¿Quieres aprobar el certificado SSL con el hash: {{hash}}?","The storage class affects the availability and price for a stored file":"La categoría de almacenamiento afecta la disponibilidad y precio de un archivo almacenado","The target folder contains encrypted files, please supply the passphrase":"La carpeta de destino contiene archivos encriptados, por favor suministra la frase de seguridad","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"El usuario tiene demasiados permisos. ¿Quieres crear un usuario nuevo, con sólo permisos para la ruta seleccionada?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"Esta copia de seguridad fue creada en otro sistema operativo. Restaurar estos ficheros sin indicar una carpeta de destino puede provocar que sean restaurados en ubicaciones imprevistas ¿Está seguro de que quiere continuar sin elegir una carpeta de destino?","This month":"Este mes","This week":"Esta semana","Thu":"Jue","To File":"A archivo","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"Para confirmar que desea eliminar todos los archivos remotos \"{{name}}\", por favor ingrese la palabra que ves abajo","To export without a passphrase, uncheck the \"Encrypt file\" box":"Para exportar sin una frase de seguridad, desactive la casilla \"Cifrar el archivo\"","Today":"Hoy","Trust host certificate?":"¿Confiar en el certificado del host?","Trust server certificate?":"¿Confiar en el certificado del servidor?","Try out the new features we are working on. Don't use with important data.":"Pruebe las nuevas funciones en las que estamos trabajando. No utilizar con datos importantes.","Tue":"Mar","Type to highlight files":"Tipo para seleccionar archivos","Unknown backup size and versions":"Tamaño y versiones de la copia de seguridad desconocidas","Until resumed":"Hasta reanudar","Update channel":"Canal de actualización","Update failed:":"Error de actualización:","Updating with existing database":"Actualizando la base de datos existente","Upload volume size":"Tamaño del volumen de subida","Uploading verification file ...":"Cargar archivo de verificación ...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"Los informes de uso nos ayudan a mejorar la experiencia del usuario y evaluar el impacto de nuevas características. Podemos usarlos para generar <a href=\"{{link}}\" target=\"_blank\">estadísticas de uso público</a>.","Usage statistics":"Estadísticas de uso","Usage statistics, warnings, errors, and crashes":"Estadísticas de uso, advertencias, errores y bloqueos","Use SSL":"Usar SSL","Use existing database?":"¿Usar base de datos existente?","Use weak passphrase":"Uso de frase de seguridad débil","Useless":"Inútil","User data":"Datos de usuario","User has too many permissions":"El usuario tiene demasiados permisos","Username":"Nombre de usuario","VISA, Mastercard, ... via Paypal":"VISA, Mastercard,... a través de Paypal","Validating ...":"Validando …","Verify files":"Verificar archivos","Verifying ...":"Verificando ...","Verifying answer":"Verificando respuesta","Verifying backend data ...":"Verificando datos de respaldo ...","Verifying remote data ...":"Verificando datos remotos ...","Verifying restored files ...":"Verificando archivos restaurados ...","Very strong":"Muy fuerte","Very weak":"Muy débil","Visit us on":"Visítenos en","WARNING: The remote database is found to be in use by the commandline library":"ADVERTENCIA: La base de datos remota se encuentre en uso por la biblioteca de la línea de comandos","WARNING: This will prevent you from restoring the data in the future.":"ADVERTENCIA: Esto le impedirá restaurar los datos en el futuro.","Waiting for task to begin":"Esperando que se inicie la tarea","Waiting for upload ...":"Esperando la subida ...","Warnings, errors and crashes":"Advertencias, errores y bloqueos","We recommend that you encrypt all backups stored outside your system":"Recomendamos cifrar todas las copias de seguridad almacenadas fuera de su sistema","Weak":"Débil","Weak passphrase":"Frase de seguridad débil","Wed":"Mié","Weeks":"Semanas","Where do you want to restore from?":"¿Desde dónde quiere restaurar?","Where do you want to restore the files to?":"¿Dónde desea restaurar los archivos?","Years":"Años","Yes":"Sí","Yes, I have stored the passphrase safely":"Sí, he guardado la frase de seguridad de forma segura","Yes, I'm brave!":"Sí, ¡soy valiente!","Yes, please break my backup!":"Sí, por favor, ¡rompe mi copia de seguridad!","Yesterday":"Ayer","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"Parece estar ejecutando Mono sin certificados SSL cargados.\n¿Desea importar la lista de certificados de confianza de Mozilla?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"Está cambiando la ruta de la base de datos de una base de datos existente.\n¿Realmente es lo que quieres?","You are currently running {{appname}} {{version}}":"Actualmente está ejecutando {{appname}} {{version}}","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"Ha cambiado el modo de encriptación. Esto puede quebrar cosas. Le animamos a crear una nueva copia de seguridad en su lugar","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"Ha cambiado la frase de seguridad, la cual no es compatible. Le animamos a crear una nueva copia de seguridad en su lugar.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"Ha optado por no cifrar la copia de seguridad. El cifrado se recomienda para todos los datos almacenados en un servidor remoto.","You have chosen to restore to a new location, but not entered one":"Ha elegido restaurar a una nueva ubicación, pero no la ha indicado","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"Ha generado una frase de seguridad fuerte. Asegúrese de que usted ha hecho una copia de seguridad de la frase de seguridad, los datos no se pueden recuperar si se pierde la contraseña.","You must choose at least one source folder":"Debe seleccionar al menos una carpeta de origen","You must enter a name for the backup":"Debe introducir un nombre para la copia de seguridad","You must enter a passphrase or disable encryption":"Debe ingresar una frase de seguridad o deshabilitar el cifrado","You must enter a positive number of backups to keep":"Debe especificar un número positivo de copias de seguridad a guardar","You must enter a tenant name if you do not provide an API Key":"Debe introducir un nombre de cliente si no proporciona una clave API","You must enter a valid duration for the time to keep backups":"Debe introducir una duración válida para el tiempo de retención de las copias de seguridad","You must enter either a password or an API Key":"Debe introducir una contraseña o una clave API","You must enter either a password or an API Key, not both":"Debe introducir una contraseña o una clave API, no ambos","You must fill in the password":"Debe rellenar la contraseña","You must fill in the server name or address":"Debe introducir el nombre del servidor o la dirección","You must fill in the username":"Debe rellenar el nombre de usuario","You must fill in {{field}}":"Debe rellenar el {{field}}","You must select or fill in the AuthURI":"Debe seleccionar o rellenar la AuthURI","You must select or fill in the server":"Debe seleccionar o rellenar en el servidor","You must specify a path":"Debe especificar una ruta de acceso","Your files and folders have been restored successfully.":"Los archivos y carpetas han sido restaurados con éxito.","Your passphrase is easy to guess. Consider changing passphrase.":"Tu frase de seguridad es fácil de adivinar. Considere cambiarla.","a specific number":"un número específico","bucket/folder/subfolder":"depósito/carpeta/subcarpeta","byte":"byte","byte/s":"byte/s","custom":"Personalizar","resume now":"reanudar ahora","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} fue desarrollado principalmente por <a href=\"{{mail1}}\">{{dev1}}</a> y <a href=\"{{mail2}}\">{{dev2}}</a>. Puede descargarse {{appname}} desde <a href=\"{{websitelink}}\"> {{websitename}}</a>. {{appname}} está licenciado bajo <a href=\"{{licenselink}}\"> {{licensename}}</a>.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":["{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versión","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versiones"],"{{number}} Hour":"{{number}} Hora","{{number}} Minutes":"{{number}} Minutos","{{time}} (took {{duration}})":"{{time}} (llevó {{duration}})"});
+ gettextCatalog.setStrings('fi', {"- pick an option -":"- Valitse jokin vaihtoehto -","...loading...":"...ladataan...","API Key":"API-avain","AWS Access ID":"Tunniste \"Access Key ID\" palveluun AWS","AWS Access Key":"Tunniste \"Access Key ID\" palveluun AWS","AWS IAM Policy":"Palvelun AWS IAM-asetukset","About":"Tietoja","About {{appname}}":"Tietoja sovelluksesta {{appname}}","Access Key":"Pääsyavain","Access denied":"Pääsy evätty","Access to user interface":"Käyttöoikeus käyttöliittymään","Account name":"Käyttäjätunnus","Activate":"Aktivoi","Activate failed:":"Aktivointi epäonnistui","Add a new backup":"Lisää uusi varmuuskopio","Add advanced option":"Anna harvoin tarvittava valitsin","Add backup":"Lisää varmuuskopio","Add filter":"Lisää suodatin","Add path":"Lisää polku","Adjust bucket name?":"Muuta ämpärin nimeä?","Adjust path name?":"Muuta polkua?","Advanced Options":"Harvoin tarvittavat valitsimet","Advanced options":"Harvoin tarvittavat valitsimet","Advanced:":"Harvoin tarvittavat asetukset","All Hyper-V Machines":"Kaikki Hyper-V-virtuaalikoneet","All Microsoft SQL Databases":"Kaikki Microsoft SQL -tietokannat","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Kaikki käyttöraportit lähetetään anonyymisti. Ne eivät sisällä mitään henkilökohtaisia tietoja. Raportit sisältävät tietoja laitteistosta ja käyttöjärjestelmästä, käytetystä etäpalvelusta, varmuuskopion kestosta, varmuuskopioitavan datan määrästä yms.Raportit eivät sisällä polkuja, tiedostonimiä, käyttäjätunnuksia, salasanoja tai vastaavia tietoja.","Allow remote access (requires restart)":"Salli etäyhteydet (Vaatii Duplicatin uudeleenkäynnistämisen)","Allowed days":"Sallitut päivät","An existing file was found at the new location":"Olemassaoleva tiedosto löydettiin uudesta paikasta","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"Annettu tietokanta on jo olemassa.\nOletko varma, että haluat käyttää olemassaolevaa tietokantaa?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"Löydettiin olemassaoleva paikallinen tietokanta tälle varmuuskopiolle.\nSaman tietokannan käyttäminen mahdollistaa kometorivi-ohjelman ja palvelimen käyttämisen saman varmuuskopion kanssa.\n\nHaluatko käyttää samaa tietokantaa?","Anonymous usage reports":"Anonyymit käyttöraportit","As Command-line":"Komentona","AuthID":"AuthID","Authentication password":"Kirjautumissalasana","Authentication username":"Käyttäjätunnus","Autogenerated passphrase":"Automaattisesti luoto salauslause","Automatically run backups.":"Tee varmuuskopiot automaattisesti","B2 Account ID":"B2-tilin ID","B2 Application Key":"B2 Application Key","B2 Cloud Storage Account ID":"Tunnus B2 Cloud Storage Account ID","B2 Cloud Storage Application Key":"B2 Cloud Storage Application Key","Back":"Palaa","Backend modules:":"Etäpalvelinmoduulit:","Backup destination":"Sijainti, johon varmuuskopio tehdään","Backup location":"Varmuuskopion sijainti","Backup:":"Varmuuskopio:","Beta":"Beta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Broken access":"Pääsy epäonnistui","Browse":"Selaa","Browser default":"Selaimen oletusasetus","Bucket Name":"Ämpärin nimi","Bucket create location":"Luo ämpäri sijaintiin","Bucket create region":"Luo ämpäri alueelle","Bucket name":"Ämpärin nimi","Bucket storage class":"Ämpärin tallennusluokka","Building list of files to restore ...":"Kootaan listaa palautettavista tiedostoista ...","Building partial temporary database ...":"Koostan osittaista tilapäistä tietokantaa ...","Busy ...":"Työskentelen ...","Canary":"Canary","Cancel":"Peruuta","Cannot move to existing file":"Ei voida korvata olemassaolevaa tiedostoa","Changelog":"Muutokset","Changelog for {{appname}} {{version}}":"Muutokset versiossa {{appname}} {{version}}","Check failed:":"Päivitysten haku epäonnistui:","Check for updates now":"Hae päivityksiä nyt","Checking ...":"Haetaan ...","Checking for updates ...":"Haetaan päivityksiä ...","Chose a storage type to get started":"Valitseensin tallennustyyppi","Click the AuthID link to create an AuthID":"Klikkaa AuthID-linkkiä luodaksesi AuthID-tunnisteen","Compact now":"Tiivistä nyt","Compacting remote data ...":"Tiivistän varmuuskopiota etäpalvelimella ...","Completing backup ...":"Viimeistelen varmuuskopiota ...","Completing previous backup ...":"Viimeistelen edellistä varmuuskopiota ...","Compression modules:":"Pakkausmoduulit","Computer":"Tietokone","Configuration file:":"Asetustiedosto","Configuration:":"Asetukset:","Configure a new backup":"Määrittele uusi varmuuskopio","Confirm delete":"Vahvista poistaminen","Confirmation required":"Tarvitsen vahvistuksen","Connect":"Yhdistä","Connect now":"Yhdistä nyt","Connecting...":"Yhdistän ...","Connection lost":"Yhteys katkesi","Connection worked!":"Yhteys toimi!","Container name":"Kontin nimi","Container region":"Kontin alue","Continue":"Jatka","Continue without encryption":"Jatka salaamatta","Copied!":"Kopioitu!","Copy Destination URL to Clipboard":"Kopio etäpalvelimen osoite leikepöydälle","Copy failed. Please manually copy the URL":"Kopionti epäonnistui. Kopio osoite käsin","Core options":"Ydinasetukset","Counting ({{files}} files found, {{size}})":"Lasketaan tiedostoja. (Löydetty {{files}} tiedostoa, {{size}})","Crashes only":"Vain kaatumiset","Create bug report ...":"Luo ilmoitus ohjelmistovirheestä ...","Create folder?":"Luo kansio?","Created new limited user":"Luotiin uusi rajoitettu käyttäjä","Creating bug report ...":"Luodaan ilmoitusta ohjelmistovirheestä ...","Creating new user with limited access ...":"Luon uutta rajoitettua käyttäjää ...","Creating target folders ...":"Luon kohdekansioita","Creating temporary backup ...":"Luon tilapäistä varmuuskopiota ...","Creating user...":"Luon käyttäjää ...","Current version is {{versionname}} ({{versionnumber}})":"Nykyinen versio on {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"Vaihtoehtoinen S3 päätepiste","Custom authentication url":"Vaihtoehtoinen autentikointiosoite","Custom location ({{server}})":"Vaihtoehtoinen sijainti ({{server}})","Custom region for creating buckets":"Vaihtoehtoinen alue ämpärin luomista varten","Custom region value ({{region}})":"Vaihtoehtoinen alue ({{region}})","Custom server url ({{server}})":"Vaihtoehtoisen palvelimen osoite ({{server}})","Custom storage class ({{class}})":"Vaihtoehtoinen tallennusluokka ({{class}})","Days":"Päivää","Default":"Oletus","Default ({{channelname}})":"Oletus ({{channelname}})","Default options":"Oletusasetukset","Delete":"Poista","Delete ...":"Poistan ...","Delete backup":"Poista varmuuskopio","Delete local database":"Poista paikallinen tietokanta","Delete remote files":"Poista tiedostot etäpalvelimelta","Delete the local database":"Poista paikallinen tietokanta","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"Poistetaanko {{filecount}} tiedostoa ({{filesize}}) etäpalvelimelta","Deleting remote files ...":"Poistan tiedostoja etäpalvelimelta ...","Deleting unwanted files ...":"Poistan tiedotoja ...","Desktop":"Työpöytä","Destination":"Kohde","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"Autoimmeko me pelastamaan tiedostosi? Jos autoimme, harkitse Duplicatin tukemista pienellä lahjoituksella. Suossitamme {{smallamount}} kotikäytössä ja {{largeamount}} yrityskäytössä.","Disabled":"Positetteu käytöstä","Dismiss":"Ohita","Do you really want to delete the backup: \"{{name}}\" ?":"Haluatko varmasti poistaa varmuuskopion \"{{name}}\"?","Do you really want to delete the local database for: {{name}}":"Haluatko varmasti poistaa varmuuskopion {{name}} paikallisen tietokannan?","Donate":"Lahjoita","Donate with Bitcoins":"Lahjoita Bitcoineja","Donate with PayPal":"Lahjoita PayPal:n kautta","Donation messages":"Lahjoituskehoitukset","Donation messages are hidden, click to show":"Lahjoituskehoitukset on poistettu käytöstä. Klikkaa ottaaksesi ne käyttöön.","Donation messages are visible, click to hide":"Lahjoituskehoitukset ovat käytössä. Klikkaa poistaaksesi ne käytöstä.","Done":"Valmis","Download":"Lataa","Downloading ...":"Lataan ...","Downloading files ...":"Lataan tiedostoja ...","Downloading update...":"Lataan päivitystä ...","Duplicate option {{opt}}":"Sama valitsin {{opt}} annettiin kahdesti","Duplicati Website":"Duplicatin verkkosivu","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Jokaisella varmuuskopiolla on oma paikallinen tietokanta, joka sisältää tiedot etäpalvelimella olevista varmuuskopioista.\\nTämä nopeuttaa monia toimenpiteitä ja vähentää etäpalvelimelta ladattavan datan määrää.","Edit ...":"Muokkaa ...","Edit as list":"Muokkaa listana","Edit as text":"Muokkaa tekstinä","Encrypt file":"Salaa tiedosto","Encryption":"Salaus","Encryption changed":"Salausasetukset ovat muuttuneet","Encryption modules:":"Saluasmoduulit:","Enter URL":"Anna URL","Enter access key":"Anna pääsyavain","Enter account name":"Anna käyttäjätunnus","Enter backup passphrase, if any":"Anna varmuuskopion salauslause, jos käytät salausta.","Enter container name":"Anna kontin nimi","Enter encryption passphrase":"Anna salauslause","Enter expression here":"Anna ilmaisu","Enter folder path name":"Anna kansion polku","Enter one option per line in command-line format, eg. {0}":"Syötä valitsimet yksi kullekin riville. Esim: {0}","Enter the destination path":"Anna kohdekansion polku","Error":"Virhe","Error!":"Virhe!","Errors and crashes":"Virheet ja kaatumiset","Exclude":"Ohita","Exclude directories whose names contain":"Ohita kansiot, joiden nimessä on","Exclude expression":"Ohita ilmaisu","Exclude file":"Ohita tiedosto","Exclude file extension":"Ohita tämän tyyppiset tiedostot","Exclude files whose names contain":"Ohita tiedostot, joiden nimessä on","Exclude folder":"Ohita kansio","Exclude regular expression":"Ohita säännöllistä ilmaisua vastaavat kohteet","Existing file found":"Löydettiin olemassaoleva tiedosto","Experimental":"Experimental","Export":"Vie","Export ...":" Vien ...","Export backup configuration":"Vie varmuuskopion asetukset","Export configuration":"Vie asetukset","Exporting ...":"Vien ...","FTP (Alternative)":"FTP (vaihtoehtoinen)","Failed to build temporary database: {{message}}":"Tilapäisen tietokannan luominen epäonnistui. Virhe: {{message}}","Failed to connect:":"Yhteyden muodostaminen epäonnistui:","Failed to connect: {{message}}":"Yhteyden muodostaminen epäonnistui: {{message}}","Failed to delete:":"Poistaminen epäonnistui:","Failed to fetch path information: {{message}}":"Polkutietojen noutaminen epäonnistui: {{message}}","Failed to import:":"Tuominen epäonnistui:","Failed to read backup defaults:":"Varmuuskopion oletusasetusten lukeminen epäonnistui:","Failed to restore files: {{message}}":"Tiedostojen palauttaminen epäonnistui: {{message}}","Failed to save:":"Tallennus epäonnistui:","Fetching path information ...":"Haen tietoja poluista ...","File":"Tiedosto","Files larger than:":"Tiedostot, joiden koko on suurempi kuin:","Filters":"Suodattimet","Finished!":"Valmis!","Folder":"Kansio","Folder path":"Kansion polku","Fri":"Pe","GByte":"GT","GByte/s":"GT/s","GCS Project ID":"GCS Projektin ID","General":"Yleinen","General backup settings":"Yleiset varmuuskopioasetukset","General options":"Yleiset asetukset","Generate":"Luo","Generate IAM access policy":"Luo Amazon IAM access policy","Getting file versions ...":"Haetaan tiedostojen versioita ...","Hidden files":"Piilotetut tiedostot","Hide":"Piilota","Hide hidden folders":"Älä näytä piilotettuja kansioita","Home":"Etusivu","Hours":"tuntia","How do you want to handle existing files?":"Mitä tehdään olemassa oleville tiedostoille?","Hyper-V Machine":"Hyper-V-virtuaalikone","Hyper-V Machine:":"Hyper-V-virtuaalikone:","Hyper-V Machines":"Hyper-V-virtuaalikoneet","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"Jos ajastettu varmuuskopio jää tekemättä, se tehdään niin pian kuin mahdollista.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Jos etäpalvelimella oleva varmuuskopio ja paikallinen tietokanta eivät ole synkronoituja, Duplicati vaatii tietokannan korjauksen.\\nJos korjaus ei onnistu voit poistaa luoda uudelleen paikallisen tietokannan.","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Jos varmuuskopiotiedosto ei latautunut automaattisesti, <a href=\"{{DownloadURL}}\" target=\"_blank\">klikkaa oikealla näppäimellä ja valitse &quot;Tallenna nimellä ...&quot;</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Jos varmuuskopiotiedosto ei latautunut automaattisesti, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">klikkaa oikealla näppäimellä ja valitse &quot;Tallenna nimellä ...&quot;</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Jos et anna polkua, kaikki tiedostot tallennetaan kirjautumiskansioon.\nOletko varma, että haluat tätä?","If you do not enter an API Key, the tenant name is required":"Jos et anna tunnistetta API key, on tunniste \"tenant name\" pakollinen","If you want to use the backup later, you can export the configuration before deleting it":"Jos haluat luoda varmuuskopion myöhemmin uudelleen, voit viedä tiedostoon ennen poistamista.","Import":"Tuo","Import Destination URL":"Tuo etäpalvelimen osoite","Import backup configuration":"Tuo varmuuskopion asetukset","Import completed, but no certificates were found after the import":"Tuominen valmistui, mutta yhtään sertifikaattia ei löytynyt sen jälkeen","Import failed":"Tuominen epäonnistui","Importing ...":"Tuon ...","Include a file?":"Sisällytä tiedosto?","Include expression":"Sisällytä ilmaisua vastaavat kohteet","Include regular expression":"Sisällytä säännöllistä ilmaisua vastaavat kohteet","Incorrect answer, try again":"Virheellinen vastaus. Yritä uudelleen.","Individual builds for developers only.":"Kehittäjille tarkoitetut testiversiot","Information":"Informaatio","Install":"Asenna","Install failed:":"Asennus epäonnistui:","Invalid retention time":"Epäkelpo säilytysaika","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"JOtkut FTP-palvelimet sallivat yhteyden muodostamisen ilman salasanaa.\nOleko varma, että käyttämäsi FTP-palvelin sallii anonyymit kirjautumiset?","KByte":"KB","KByte/s":"KB/s","Language in user interface":"Käytettävä kieli","Last month":"Viime kuussa","Last successful run:":"Edellinen onnistunut varmuuskopio:","Latest":"Viimesin","Libraries":"Kirjastot","Listing backup dates ...":"Listaan varmuuskopioiden ajankohtia ...","Listing remote files ...":"Listaan etäpalvelimen tiedostoja ...","Live":"Live","Load older data":"Lataa vanhoja tietoja","Loading ...":"Lataan ...","Loading remote storage usage ...":"Haetaan tietoja etäpalvelimen tilankäytöstä ...","Local database for":"Paikallinen tietoknata varmuuskopiolle","Local database path:":"Paikallisen tietokannan sijainti:","Local storage":"Paikallinen tilankäyttö","Location":"Sijainti","Location where buckets are created":"Alue, jolle ämpärit luodaan","Log data for <b>{{Backup.Backup.Name}}</b>":"Varmuuskopion <b>{{Backup.Backup.Name}}</b> lokitiedot","Log data from the server":"Palvelimen lokitiedot","Log out":"Kirjaudu ulos","MByte":"MB","MByte/s":"MB/s","Maintenance":"Ylläpito","Manually type path":"Anna polku","Menu":"Valikko","Microsoft SQL Database:":"Microsoft SQL-tietokanta:","Microsoft SQL Databases":"Microsoft SQL -tietokannat","Minutes":"Minuuttia","Missing name":"Et antanut nimeä","Missing passphrase":"Salasana puuttuuEt antanut salasanaa","Missing sources":"Et valinnut varmuuskopioitavia tietostoja","Mon":"ma","Months":"Kuukautta","Move existing database":"Siirrä olemassa oleva tietokanta","Move failed:":"Siirto epäonnistui:","My Documents":"Tiedostot","My Music":"Musiikki","My Photos":"Kuvat","My Pictures":"Kuvat","Name":"Nimi","Never":"Ei koskaan","New update found: {{message}}":"Uusi päivitys on ladattavissa: {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"Uusi käyttäjätunnus on {{user}}.\nPäivitä tunnukset käyttääksesi uutta rajoitettua käyttäjää.","Next":"Seuraava","Next scheduled run:":"Seuraava varmuuskopio tehdään:","Next scheduled task:":"Seuraava ajoitettu tehtävä:","Next task:":"Seuraava tehtävä:","Next time":"Seuraavalla kerralla","No":"Ei","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"Sertifikaattia ei ole määritelty aikaisemmin. Varmista palvelimen ylläpitäjältä, että avain onn oikea: {{key}}\n\nHaluatko hyväksyä tämän avaimen?","No editor found for the &quot;{{backend}}&quot; storage type":"Etäpalvelimelle &quot;{{backend}}&quot; ei löytynyt editoria.","No encryption":"Ei salausta","No items selected":"Et valinnut yhtään kohdetta","No items to restore, please select one or more items":"Et valinnut yhtään tiedostoa palautettavaksi. Valitse yksi tai useampi tiedosto.","No passphrase entered":"Et antanut salasanaa","No scheduled tasks":"Ei ajastettuja tehtäviä","Non-matching passphrase":"Salasanat eivät ole samat","None / disabled":"Ei mitään/poistettu käytöstä","OK":"OK","OpenStack AuthURI":"Openstack autentikointiosoite","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Toimenpide epäonnistui","Operations:":"Toimenpiteet:","Optional authentication password":"Salasana (ei välttämätön)","Optional authentication username":"Käyttäjätunnus (ei välttämätön)","Options":"Valitsimet","Original location":"Alkuperäinen sijainti","Others":"Muut","Overwrite":"Korvaa","Passphrase":"Salauslause","Passphrase (if encrypted)":"Salauslause (jos varmuuskopio on salattu)","Passphrase changed":"Salauslause vaihdettiin","Passphrases are not matching":"Salauslauseet eivät täsmää","Password":"Salasana","Passwords do not match":"Salasanat eivät täsmää","Patching files with local blocks ...":"Käytän paikallisia tiedostoja apuna ...","Path not found":"Polkua ei löydy","Path on server":"Polku etäpalvelimella","Path or subfolder in the bucket":"Ämpärin polku tai alikansio","Pause":"Tauko","Pause after startup or hibernation":"Tauko käynnistyksen tai lepotilasta heräämisen jälkeen","Permissions":"Oikeudet","Pick location":"Valitse sijainti","Port":"Portti","Previous":"Edellinen","ProjectID is optional if the bucket exist":"Tunniste ProjectID on valinnainen, jos ämpäri on jo olemassa","Proprietary":"Suljettu","Purging files ...":"Poistetaan tiedostoja ...","Rebuilding local database ...":"Luon paikallista tietokantaa uudelleen ...","Recreate (delete and repair)":"Luo uudelleen (poista ja korjaa)","Recreating database ...":"Luon tietokantaa uudelleen ...","Registering temporary backup ...":"Rekisteroin tilapäisen varmuuskopion ...","Relative paths not allowed":"Suhteelliset polut eivät ole sallittuja","Reload":"Lataa uudelleen","Remote":"Etäpalvelimella","Remove":"Poista","Remove option":"Poisto-asetukset","Repair":"Korjaa","Reparing ...":"Korjaan ...","Repeat Passphrase":"Toista salauslause","Reporting:":"Raportoin:","Reset":"Palauta edelliset asetukset","Restore":"Palauta","Restore files":"Palauta tiedostoja","Restore files ...":"Palautan tiedostoja ...","Restore from":"Palauta etäpalvelimelta","Restore options":"Palautusasetukset","Restore read/write permissions":"Palauta luku- ja kirjoitusoikeudet","Restoring files ...":"Palautan tiedostoja ...","Resume":"Jatka","Run again every":"Suorita uudelleen joka","Run now":"Suorita nyt","Running ...":"Teen varmuuskopiota ...","Running task:":"Suoritettava tehtävä:","S3 Compatible":"S3-yhteensopiva","Same as the base install version: {{channelname}}":"Sama kuin asennettu versio: {{channelname}}","Sat":"La","Save":"Tallenna","Save and repair":"Tallenna ja korjaa","Save different versions with timestamp in file name":"Tallenna eri versiot aikaleima tiedoston nimessä","Save immediately":"Tallenna heti","Scanning existing files ...":"Luen olemassa olevia tiedostoja","Scanning for local blocks ...":"Etsin paikallisia lohkoja ...","Schedule":"Aikataulu","Search":"Etsi","Search for files":"Etsi tiedostoja","Seconds":"Sekuntia","Select a log level and see messages as they happen:":"Valitse lokitiedot ja näe ne heti, kun ne ilmoitetaan lokiin:","Select files":"Valitse tiedostot","Server":"Palvelin","Server and port":"Palvelin ja portti:","Server hostname or IP":"Palvelimen nimi ja IP-osoite","Server is currently paused,":"Palvelin on pysäytetty,","Server is currently paused, do you want to resume now?":"Palvelin on pysäytetty, haluatko aktivoida sen nyt?","Server paused":"Palvelin on pysäytetty","Server state properties":"Palvelimen tila","Settings":"Asetukset","Show":"Näytä","Show advanced editor":"Näytä asetusten muokkain","Show hidden folders":"Näytä piilotetut tiedostot","Show log":"Näytä loki","Show log ...":"Lataan lokitietoja ...","Show treeview":"Näytä puunäkymä","Some OpenStack providers allow an API key instead of a password and tenant name":"Jotkin OpenStack-palveluntarjoajat sallivat API-avaimen käytön salasanan ja käyttäjätunnuksen sijaan","Source Data":"Lähdetiedostot","Source data":"Lähdetiedostot","Source folders":"Lähekansiot","Source:":"Varmuuskopioitavat tiedostot:","Specific builds for developers only.":"Testiversiot kehittäjille.","Standard protocols":"Standardinmukaiset protokollat","Starting ...":"Käynnistän ...","Starting the restore process ...":"Aloitan tiedostojen palauttamisen ...","Storage Type":"Tallennustyyppi","Storage class":"Tallennusluokka","Storage class for creating a bucket":"Tallennusluokka ämpärin luomista varten","Stored":"Tallennettu","Strong":"Vahva","Success":"Onnistui","Sun":"Su","Symbolic link":"Symbolinen linkki","System default ({{levelname}})":"Järjestelmän oletus ({{levelname}})","System files":"Järjestelmätiedostot","System info":"Järjestelmän tiedot","System properties":"Järjestelmän ominaisuudet","TByte":"TB","TByte/s":"TB/s","Task is running":"Tehtävää suoritetaan","Temporary files":"Tilapäistiedostot","Tenant Name":"Vuokralaisen nimi","Test connection":"Kokeile yhteysasetuksia","Testing ...":"Yhdistän ...","Testing connection ...":"Testaan yhteyttä ...","Testing permissions ...":"Testaan oikeuksia ...","Testing permissions...":"Testaan oikeuksia ...","The bucket name should be all lower-case, convert automatically?":"Bucketin nimen pitää olla kirjoitettu pienillä kirjaimilla. Muuta automaattisesti?","The bucket name should start with your username, prepend automatically?":"Bucketin nimen pitäisi alkaa käyttäjätunnuksellasi. Haluatko liittää tunnuksesi nimen alkuun automaattisesti?","The connection to the server is lost, attempting again in {{time}} ...":"Yhteys palvelimeen katkesi, yritetään uudelleen {{time}} kuluttua ...","The folder {{folder}} does not exist\nCreate it now?":"Hakemistoa {{folder}} ei ole olemassa. Luodaanko se nyt?","The path does not appear to exist, do you want to add it anyway?":"Polku ei vaikuta olevan olemassa, haluatko lisätä sen silti?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"Polku ei pääty '{{dirsep}}' -merkkiin, eli olet lisäämässä tiedoston etkä kansiota. Haluatko lisätä määritellyn tiedoston?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"Polun pitää olla absoluuttinen, eli sen tulee alkaa vinoviivalla \"/\"","The region parameter is only applied when creating a new bucket":"Alue -parametria käytetään vain bucketia luodessa.","The region parameter is only used when creating a bucket":"Alue -parametria käytetään vain bucketia luodessa.","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"Palvelimen varmennetta ei pystytty todentamaan. Haluatko hyväksyä SSL-varmenteen, jonka tiiviste on {{hash}}?","The storage class affects the availability and price for a stored file":"Tietovaraston tyyppi vaikuttaa talennetun tiedoston saatavuuteen ja hintaan.","The target folder contains encrypted files, please supply the passphrase":"Kohdekansio sisältää salattuja tiedostoja. Anna salasana","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"Käyttäjällä on liikaa oikeuksia. Haluatko luoda uuden rajoitetun käyttäjän, jolla on käyttöoikeus vain valittuun polkuun?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"Tämä varmuuskopio on luotu toisessa käyttöjärjestelmässä. Tiedostojen palauttaminen ilman kohdekansion määrittelyä voi johtaa tiedostojen palauttamiseen odottamattomiin paikkoihin. Haluatko varmasti jatkaa määrittelemättä kohdekansiota?","This month":"Tässä kuussa","This week":"Tällä viikolla","Thu":"To","To File":"Tiedostoon","To export without a passphrase, uncheck the \"Encrypt file\" box":"Viedäksesi ilmaan salasanaa poista rasti \"Salaa tiedosto\" -valinnasta","Today":"Tänään","Trust host certificate?":"Luota palvelimen varmenteeseen?","Trust server certificate?":"Luota palvelimen varmenteeseen?","Try out the new features we are working on. Don't use with important data.":"Kokeile uusia ominaisuuksia, jotka ovat kehityksessä. Älä käytä tätä tärkeiden tietojen kanssa.","Tue":"ti","Type to highlight files":"Kirjoita korostaaksesi tiedostoja","Until resumed":"Toistaiseksi","Update channel":"Päivityskanava","Update failed:":"Päivitys epäonnistui:","Upload volume size":"Lähetettävän datatiedoston koko","Uploading verification file ...":"Lähetetään varmennustiedostoa ...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"Käyttöraportit auttavat meitä kehittämään käyttäjäkokemusta ja arvioimaan uusia ominaisuuksia. Käytämme raportteja <a href=\"{{link}}\" target=\"_blank\">julkisten käyttötilastojen</a> luomiseen.","Usage statistics":"Käyttötilastot","Usage statistics, warnings, errors, and crashes":"Käyttötilastot, varoitukset, virheet ja kaatumiset","Use SSL":"Käytä SSL:ää","Use existing database?":"Käytä olemassaolevaa tietokantaa?","Use weak passphrase":"Käytä heikkoa salasanaa","Useless":"Hyödytön","User has too many permissions":"Käyttäjällä on liikaa oikeuksia","Username":"Käyttäjätunnus","VISA, Mastercard, ... via Paypal":"VISA, Mastercard, ... Paypal","Validating ...":"tarkistetaan ...","Verify files":"Tarkista tiedostot","Verifying ...":"Tarkistetaan ...","Verifying answer":"Tarkistetaan vastausta","Verifying backend data ...":"Tarkistetaan taustajärjestelmän tietoja ...","Verifying remote data ...":"Vahvistetaan taustajärjestelmän dataa ...","Verifying restored files ...":"Tarkistetaan palautetut tiedostot ...","Very strong":"Hyvin vahva","Very weak":"Hyvin heikko","Visit us on":"Tutustu meihin","WARNING: The remote database is found to be in use by the commandline library":"VAROITUS: etätietokanta on komentorivikirjaston käytössä.","WARNING: This will prevent you from restoring the data in the future.":"VAROITUS: Tämä estää tietojen palauttamisen tulevaisuudessa","Waiting for task to begin":"Odotetaan tehtävän alkamista","Waiting for upload ...":"Odotetaan lähetystä ...","Warnings, errors and crashes":"Varoitukset, virheet ja kaatumiset","We recommend that you encrypt all backups stored outside your system":"Suosittelemme salausta varmuuskopioihin, jotka säilötään oman tietokoneesi ulkopuolelle.","Weak":"Heikko","Weak passphrase":"Heikko salasana","Wed":"ke","Weeks":"Viikkoa","Where do you want to restore from?":"Mistä haluat palauttaa?","Where do you want to restore the files to?":"Mihin tiedostot palautetaan?","Years":"Vuotta","Yes":"Kyllä","Yes, I have stored the passphrase safely":"Kyllä, olen tallentanut salasanan turvallisesti","Yes, I'm brave!":"Kyllä, olen rohkea!","Yes, please break my backup!":"Kyllä, riko varmuuskopioni!","Yesterday":"Eilen","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"Käytät Mono:a ilman SSL-varmenteita. Haluatko tuoda luotetut varmenteet Mozillasta?","You are currently running {{appname}} {{version}}":"Käytössä oleva versio: {{appname}} {{version}}","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"Vaihdoit salausmenetelmää, ja se saattaa rikkoa asioita. Harkitse kokonaan uuden varmuuskopion luomista sen sijaan.","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"Vaihdoit salasanaa, mutta tätä toiminnallisuutta ei tueta. Luo sen sijaan kokonaan uusi varmuuskopio.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"Valitsit salaamattoman varmuuskopioinnin. Salaaminen on suositeltua kaikella datalle, joka säilötään etäpalvelimelle.","You have chosen to restore to a new location, but not entered one":"Valitsit palautuksen uuteen sijaintiin, mutta et antanut sijaintia.","You must choose at least one source folder":"Vähintään yksi lähdekansio pitää valita","You must enter a name for the backup":"Varmuuskopiolle pitää antaa nimi","You must enter a passphrase or disable encryption":"Anna salasana tai poista salaus käytöstä","You must enter a positive number of backups to keep":"Syötä säilytettävien varmuuskopioiden määrä (positiivinen kokonaisluku)","You must enter a valid duration for the time to keep backups":"Syötä sallittu varmuuskopioiden säilytysaika","You must enter either a password or an API Key":"Syötä salasana tai API-avain","You must enter either a password or an API Key, not both":"Syötä joko salasana tai API-avain, ei molempia","You must fill in the password":"Täytä salasana","You must fill in the server name or address":"Täytä palvelimen nimi tai osoite","You must fill in the username":"Täytä käyttäjätunnus","You must fill in {{field}}":"Täytä kenttä {{field}}","You must select or fill in the AuthURI":"Valitse tai syötä AuthURI","You must select or fill in the server":"Valitse tai syötä palvelin","You must specify a path":"Määritä polku","Your files and folders have been restored successfully.":"Tiedostot ja kansiot palautettiin onnistuneesti.","Your passphrase is easy to guess. Consider changing passphrase.":"Salasanasi on helppo arvata. Harkitse salasanan vaihtamista.","a specific number":"Määritelty kappalemäärä","bucket/folder/subfolder":"bucket/kansio/alikansio","byte":"tavu","byte/s":"tavua/s","custom":"mukautettu","resume now":"jatka nyt","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}}n on pääasiallisesti kehittänyt <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}}n voi ladata osoitteesta <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} on lisensoitu <a href=\"{{licenselink}}\">{{licensename}}</a> -lisenssillä.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":["{{item.Backup.Metadata.TargetSizeString}} / {{$count}} versio","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} versiota"],"{{number}} Hour":"{{number}} tuntia","{{number}} Minutes":"{{number}} minuuttia","{{time}} (took {{duration}})":"{{time}} (kesto: {{duration}})"});
+ gettextCatalog.setStrings('fr', {"- pick an option -":"- Choisissez une option -","...loading...":"...chargement...","API Key":"Clé API","AWS Access ID":"AWS Access ID","AWS Access Key":"AWS Access Key","AWS IAM Policy":"AWS IAM Policy","About":"À propos","About {{appname}}":"À propos de {{appname}}","Access Key":"Clé d'accès","Access denied":"Accès refusé","Access to user interface":"Accès à l'interface utilisateur","Account name":"Nom du compte","Activate":"Activer","Activate failed:":"Echec d'activation:","Add a new backup":"Ajouter une nouvelle sauvegarde","Add a path directly":"Ajouter un répertoire directement","Add advanced option":"Ajouter une option avancée","Add backup":"Ajouter sauvegarde","Add filter":"Ajouter un filtre","Add path":"Ajouter un chemin","Adjust bucket name?":"Ajuster le nom du bucket","Adjust path name?":"Adapter le nom du chemin ?","Advanced Options":"Options avancées","Advanced options":"options avancées","Advanced:":"Avancé :","All Hyper-V Machines":"Toutes les machines Hyper-V","All Microsoft SQL Databases":"Toutes les bases de données Microsoft SQL","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Tous les rapports d'utilisation sont envoyés de manière anonyme et ne contiennent aucune information personnelle. Ils contiennent des informations sur le matériel et le système d'exploitation, sur le type d'infrastructure, la durée de la sauvegarde, la taille générale des fichiers sources et d'autres données similaires. Ils ne contiennent pas de chemin d'accès, noms de fichiers, noms d'utilisateurs, mots de passe ou des informations sensibles de ce type.","Allow remote access (requires restart)":"Autoriser l'accès à distance (nécessite un redémarrage)","Allowed days":"Jours autorisés","An existing file was found at the new location":"Un fichier existant a été trouvé au nouvel endroit","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"Un fichier existant a été trouvé au nouvel endroit.\nÊtes-vous sûr de vouloir faire pointer la base de données vers un fichier existant ?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"Une base de données locale pour le stockage a été trouvée.\nRéutiliser la base de données va permettre la ligne de commande et les instances serveur de travailler sur le même stockage à distance.\n\nVoulez-vous utiliser la base de donnée existante ?","Anonymous usage reports":"Rapports d'utilisation anonyme","As Command-line":"Comme ligne de commande","AuthID":"AuthID","Authentication password":"Mot de passe d'identification","Authentication username":"Nom d'utilisateur d'identification","Autogenerated passphrase":"Phrase secrète auto-générée","Automatically run backups.":"Lancer des sauvegardes automatiques.","B2 Account ID":"B2 Account ID","B2 Application Key":"B2 Application Key","B2 Cloud Storage Account ID":"B2 Cloud Storage Account ID","B2 Cloud Storage Application Key":"B2 Cloud Storage Application Key","Back":"Retour","Backend modules:":"Modules back-end :","Backup destination":"Destination de sauvegarde","Backup location":"Emplacement de la sauvegarde","Backup:":"Sauvegarde :","Beta":"Béta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Broken access":"Accès rompu","Browse":"Parcourir","Browser default":"Paramètre par défaut du navigateur","Bucket Name":"Nom du bucket","Bucket create location":"Emplacement de la création du bucket","Bucket create region":"Région de création du bucket","Bucket name":"nom du bucket","Bucket storage class":"Classe de stockage du bucket","Building list of files to restore ...":"Construction d'une liste de fichiers à restaurer","Building partial temporary database ...":"Construction d'une base de données temporaire partielle","Busy ...":"Occupé ...","Canary":"Canary","Cancel":"Annuler","Cannot move to existing file":"Impossible de déplacer vers un fichier existant","Changelog":"Journal des modifications","Changelog for {{appname}} {{version}}":"Journal des modifications pour {{appname}} {{version}}","Check failed:":"Vérification échouée :","Check for updates now":"Vérifier les mise à jour maintenant","Checking ...":"Vérification ...","Checking for updates ...":"Vérification des mises à jour ...","Chose a storage type to get started":"Sélectionnez un type de stockage pour commencer","Click the AuthID link to create an AuthID":"Cliquez sur le lien AuthID pour créer un AuthID","Click to set throttle options":"Cliquez pour définir les options d'accélération","Commandline ...":"Ligne de commande","Compact now":"Compacter maintenant","Compacting remote data ...":"Compactage des données distantes ...","Completing backup ...":"Finalisation de la sauvegarde ...","Completing previous backup ...":"Finalisation de la précédente sauvegarde ...","Compression modules:":"Modules de compression :","Computer":"Ordinateur","Configuration file:":"Fichier de configuration :","Configuration:":"Configuration :","Configure a new backup":"Configurer une nouvelle sauvegarde","Confirm delete":"Confirmer suppression","Confirmation required":"Confirmation nécessaire","Connect":"Connecter","Connect now":"Connecter maintenant","Connecting to server ...":"Connexion au serveur ...","Connecting to task ....":"Connexion à la tâche ...","Connecting...":"Connexion ...","Connection lost":"Connexion perdue","Connection worked!":"Connection fonctionnelle !","Container name":"Nom du conteneur","Container region":"Région du conteneur","Continue":"Continuer","Continue without encryption":"Continuer sans chiffrement","Copied!":"Copié !","Copy Destination URL to Clipboard":"Copier l'URL de destination dans le presse-papier","Copy failed. Please manually copy the URL":"Copie échouée. Veuillez copier manuellement l'URL","Core options":"Options du noyau","Counting ({{files}} files found, {{size}})":"Comptage ({{files}} fichiers trouvés, {{size}})","Crashes only":"Uniquement les accidents","Create bug report ...":"Crée un rapport d'erreur ...","Create folder?":"Créer un dossier ?","Created new limited user":"Nouvel utilisateur limité créé","Creating bug report ...":"Création d'un rapport d'erreur ...","Creating new user with limited access ...":"Création d'un nouvel utilisateur avec un accès limité ...","Creating target folders ...":"Création des répertoires de destination ...","Creating temporary backup ...":"Création d'une sauvegarde temporaire ...","Creating user...":"Création d'un utilisateur ...","Current version is {{versionname}} ({{versionnumber}})":"La version actuelle est {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"S3 endpoint personnalisé","Custom authentication url":"URL d'authentification personnalisée","Custom location ({{server}})":"Emplacement personnalisé ({{server)}}","Custom region for creating buckets":"Région personnalisée pour la créations de buckets","Custom region value ({{region}})":"Valeur personnalisée de région ({{region}})","Custom server url ({{server}})":"URL serveur personnalisée ({{server}})","Custom storage class ({{class}})":"Classe de stockage personnalisée ({{class}})","Database ...":"Base de donnée","Days":"Jours","Default":"Défaut","Default ({{channelname}})":"({{channelname}}) par défaut","Default options":"Options par défaut","Delete":"Supprimer","Delete ...":"Suppression ...","Delete backup":"Supprimer sauvegarde","Delete local database":"Supprimer base de données locale","Delete remote files":"Supprimer les fichiers distants","Delete the local database":"Supprimer la base de données locale","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"Supprimer {{filecount}} fichiers ({{filesize}}) du stockage distant ?","Deleting remote files ...":"Suppression des fichiers distants ...","Deleting unwanted files ...":"Suppression des fichiers non désirés ...","Desktop":"Bureau","Destination":"Destination","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"Nous vous avons aidé à sauvegarder vos fichiers ? Dans ce cas, songez à supporter Duplicati avec une donation. Nous vous suggérons {{smallamount}} pour un usage privé et {{largeamount}} pour un usage commercial.","Direct restore from backup files ...":"Restauration directe depuis les fichiers de sauvegarde","Disabled":"Désactivé","Dismiss":"Rejeter","Display and color theme":"Affichage et couleur","Do you really want to delete the backup: \"{{name}}\" ?":"Voulez-vous vraiment supprimer la sauvegarde : \"{{name}}\" ?","Do you really want to delete the local database for: {{name}}":"Voulez-vous vraiment supprimer la base de données locale pour : {{name}} ?","Donate":"Faire un don","Donate with Bitcoins":"Faire un don en Bitcoins","Donate with PayPal":"Faire un don avec PayPal","Donation messages":"Messages de donation","Donation messages are hidden, click to show":"Les messages de donation sont cachés, cliquez ici pour les afficher","Donation messages are visible, click to hide":"Les messages de donation sont affichés, cliquez ici pour les cacher","Done":"Fait","Download":"Téléchargement","Downloading ...":"Téléchargement ...","Downloading files ...":"Téléchargement des fichiers ...","Downloading update...":"Téléchargement de mise à jour ...","Duplicate option {{opt}}":"Option de duplication {{opt}}","Duplicati Website":"Site internet de Duplicati","Duplicati forum":"Forum de Duplicati","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\n When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.\n If you are using the local database for backups from the commandline, you should keep the database.":"Chaque sauvegarde a une base de données locale associée à elle, elle stocke des informations localement à propos de la sauvegarde distante.\nQuand vous supprimez une sauvegarde, vous pouvez aussi supprimer la base de données locale sans affecter votre capacité à restaurer vos fichiers distants.\nSi vous utilisez la base de données locale pour vos sauvegardes à partir de la ligne de commande, vous devez conserver la base de données.","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Chaque sauvegarde a une base de données locale associée à elle, elle enregistre localement les informations à propos de la sauvegarde distante. \\nCela rend la réalisation de beaucoup d'opérations plus rapide et réduit la quantité de données qui doit être téléchargé pour chaque opération.","Edit ...":"Éditer ...","Edit as list":"Éditer en tant que liste","Edit as text":"Éditer en tant que texte","Encrypt file":"Chiffrement de fichier","Encryption":"Chiffrement","Encryption changed":"Chiffrement changé","Encryption modules:":"Modules de Chiffrement :","Enter URL":"Entrer l'URL","Enter access key":"Entrez clé d'accès","Enter account name":"Entrez nom du compte","Enter backup passphrase, if any":"Entrez la phrase secrète de sauvegarde, si présente","Enter configuration details":"Entrer les détails de configuration","Enter container name":"Entrez le nom du conteneur","Enter encryption passphrase":"Entrez la phrase secrète de chiffrement","Enter expression here":"Entrez l'expression ici","Enter folder path name":"Entrez le nom du chemin du répertoire","Enter one option per line in command-line format, eg. {0}":"Entrez une option par ligne dans le format ligne de commande, ex : {0}","Enter the destination path":"Entrez le chemin de destination","Error":"Erreur","Error!":"Erreur !","Errors and crashes":"Erreurs et accidents","Exclude":"Exclure","Exclude directories whose names contain":"Exclure répertoires dont le nom contient","Exclude expression":"Exclure expression","Exclude file":"Exclure fichier","Exclude file extension":"Exclure extension de fichier","Exclude files whose names contain":"Exclure fichiers dont le nom contient","Exclude folder":"Exclure dossier","Exclude regular expression":"Exclure expression régulière","Existing file found":"Fichier existant trouvé","Experimental":"Expérimental","Export":"Exporter","Export ...":"Exportation ...","Export backup configuration":"Exporter la configuration de sauvegarde","Export configuration":"Exporter la configuration","Exporting ...":"Exportation ...","FTP (Alternative)":"FTP (Alternatif)","Failed to build temporary database: {{message}}":"Échec de la construction de la base de données temporaire : {{message}}","Failed to connect:":"Échec de la connexion :","Failed to connect: {{message}}":"Échec de la connexion : {{message}}","Failed to delete:":"Échec de la suppression :","Failed to fetch path information: {{message}}":"Échec de la récupération des information du chemin : {{message}}","Failed to import:":"Échec de l'import :","Failed to read backup defaults:":"Échec de la lecture des paramètres par défaut de la sauvegarde :","Failed to restore files: {{message}}":"Échec de la restauration des fichiers : {{message}}","Failed to save:":"Échec d'enregistrement :","Fetching path information ...":"Récupération des informations du chemin ...","File":"Fichier","Files larger than:":"Fichiers plus gros que :","Filters":"Filtres","Finished!":"Terminé !","First run setup":"Première mise en route","Folder":"Dossier","Folder path":"Chemin du dossier","Fri":"Ven.","GByte":"GByte","GByte/s":"GByte/s","GCS Project ID":"GCS Project ID","General":"Général","General backup settings":"Paramètres généraux de sauvegarde","General options":"Options générales","Generate":"Générer","Generate IAM access policy":"Générer IAM access policy","Getting file versions ...":"Récupération des versions des fichiers…","Hidden files":"Fichiers cachés","Hide":"Cacher","Hide hidden folders":"Masquer les dossiers cachés","Home":"Poste de travail","Hours":"Heures","How do you want to handle existing files?":"Comment voulez-vous traiter les fichiers existants ?","Hyper-V Machine":"Machine Hyper-V","Hyper-V Machine:":"Machine Hyper-V :","Hyper-V Machines":"Machines Hyper-V","ID:":"ID :","If a date was missed, the job will run as soon as possible.":"Si une date a été manquée, le travail démarrera dès que possible.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Si la sauvegarde et le stockage distant ne sont plus synchronisés, Duplicati demandera d'effectuer une opération de réparation pour synchroniser la base de données. \\n Si la réparation ne réussit pas, vous pouvez supprimer la base de données locale et la régénérer.","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Si les fichiers de sauvegarde n'ont pas été téléchargés automatiquement, <a href=\"{{DownloadURL}}\" target=\"_blank\">cliquez bouton-droit et choisissez &quot;Sauvegarder sous ...&quot;</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Si les fichiers de sauvegarde n'ont pas été téléchargés automatiquement, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">cliquez bouton-droit et choisissez \"Sauvegarder sous ...\"</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Si vous n'entrez pas de chemin, tous les fichiers seront stockés dans le dossier de connexion.\nÊtes-vous sûr que c'est ce que vous voulez ?","If you do not enter an API Key, the tenant name is required":"Si vous n'entrez pas de clé API, le nom de l'entité est requis","If you want to use the backup later, you can export the configuration before deleting it":"Si vous voulez utiliser la sauvegarde plus tard, vous pouvez exporter la configuration avant de la supprimer","If your machine is in a multi-user environment (i.e. the machine has more than one account), you need to set a password to prevent other users from accessing data on your account.\nDo you want to set a password now?":"Si votre machine est dans un environnement multi-utilisateur (votre machine a plus d'un compte), vous avez besoin de définir un mot de passe pour éviter que les autres utilisateurs puissent accéder à vos données sur votre compte.\nVoulez-vous définir un mot de passe maintenant ?","Import":"Importer","Import Destination URL":"Importer l'URL de destination","Import backup configuration":"Importer la configuration de sauvegarde","Import completed, but no certificates were found after the import":"Import terminé, mais aucun certificat n'a été trouvé après l'import","Import failed":"Échec de l'import","Import from a file":"Importer depuis un fichier","Importing ...":"Importation ...","Include a file?":"Inclure un fichier ?","Include expression":"Inclure expression","Include regular expression":"Inclure expression régulière","Incorrect answer, try again":"Réponse incorrecte, essayez encore","Individual builds for developers only.":"Compilations individuelles pour les developpeurs uniquement.","Information":"Information","Install":"Installer","Install failed:":"Échec d'installation :","Invalid retention time":"Temps de rétention invalide","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"Il est possible de se connecter à certains FTP sans mot de passe.\nÊtes-vous sûr que votre serveur FTP prend en charge l'identification sans mot de passe ?","KByte":"KByte","KByte/s":"KByte/s","Keep this number of backups":"Garder ce nombre de sauvegardes","Language in user interface":"Langue dans l'interface utilisateur","Last month":"Mois dernier","Last successful run:":"Dernière exécution réussie :","Latest":"Dernière","Libraries":"Librairies","Listing backup dates ...":"Listing des dates de sauvegardes ...","Listing remote files ...":"Listing des fichiers distants ...","Live":"Direct","Load a configuration from an exported job or a storage provider":"Charger une configuration depuis un export ou un opérateur de stockage","Load destination from an exported job or a storage provider":"Charger la destination depuis un export ou un opérateur de stockage","Load older data":"Charger des données plus anciennes","Loading ...":"Chargement ...","Loading remote storage usage ...":"Chargement de l'utilisation du stockage distant ...","Local database for":"Base de données locale pour","Local database path:":"Chemin de la base de données locale :","Local storage":"Stockage local","Location":"Emplacement","Location where buckets are created":"Emplacement ou les buckets sont créés","Log data for <b>{{Backup.Backup.Name}}</b>":"Historique pour <b>{{Backup.Backup.Name}}</b>","Log data from the server":"Données d'historique du serveur","Log out":"Déconnexion","MByte":"MByte","MByte/s":"MByte/s","Maintenance":"Maintenance","Manually type path":"Entrée manuelle du chemin","Max download speed":"Vitesse maximum de téléchargement","Max upload speed":"Vitesse maximum de téléversement","Menu":"Menu","Microsoft SQL Database:":"Base de données Microsoft SQL :","Microsoft SQL Databases":"Bases de données Microsoft SQL","Minutes":"Minutes","Missing name":"Nom manquant","Missing passphrase":"Phrase secrète manquante","Missing sources":"Sources manquantes","Mon":"Lun.","Months":"Mois","Move existing database":"Déplacer base de données existante","Move failed:":"Échec de déplacement :","My Documents":"Mes documents","My Music":"Ma musique","My Photos":"Mes photos","My Pictures":"Mes photos","Name":"Nom","Never":"Jamais","New update found: {{message}}":"Nouvelle mise à jour trouvée : {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"Le nouveau nom d'utilisateur est {{user}}.\nMise à jour des accès pour le nouvel utilisateur limité","Next":"Suivant","Next scheduled run:":"Prochaine exécution programmée :","Next scheduled task:":"Prochaine tâche planifiée :","Next task:":"Prochaine tâche :","Next time":"Prochaine fois","No":"Non","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"Aucun certificat n'a été spécifié auparavant, veuillez vérifier que la clé est correcte auprès de votre administrateur système : {{key}}\n\nVoulez-vous approuver la clé de l'hôte mentionné ?","No editor found for the &quot;{{backend}}&quot; storage type":"Aucun éditeur trouvé pour le &quot;{{backend}}&quot; type de stockage","No encryption":"Pas de chiffrement","No items selected":"Aucun élément sélectionné","No items to restore, please select one or more items":"Aucun élément à restaurer, merci de sélectionner un ou plusieurs éléments","No passphrase entered":"Aucune phrase secrète entrée","No scheduled tasks":"Pas de tâche planifié","No, my machine has only a single account":"Non, ma machine n'a qu'un seul compte","Non-matching passphrase":"La phrase secrète ne correspond pas","None / disabled":"Aucun / Désactivé","OK":"Ok","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Échec de l'opération :","Operations:":"Opérations :","Optional authentication password":"Mot de passe d'identification optionel","Optional authentication username":"Nom d'utilisateur d'identification optionel","Options":"Options","Options added here are applied to all backups, but can be overridden in each individual backup":"Les options ajoutées ici sont appliquées pour toutes les sauvegardes, mais elles peuvent être outrepassées pour chaque sauvegarde","Original location":"Emplacement d'origine","Others":"Autres","Overwrite":"Écraser","Passphrase":"Phrase secrète","Passphrase (if encrypted)":"Phrase secrète (si chiffré)","Passphrase changed":"Phrase secrète changée","Passphrases are not matching":"Les phrases secrètes ne correspondent pas","Password":"Mot de passe","Passwords do not match":"Les mots de passe ne correspondent pas","Patching files with local blocks ...":"Correction des fichiers avec les blocs locaux ...","Path not found":"Chemin non trouvé","Path on server":"Chemin sur le serveur","Path or subfolder in the bucket":"Chemin ou sous-dossier dans le bucket","Pause":"Pause","Pause after startup or hibernation":"Pause après le démarrage ou l'hibernation","Pause options":"Options de pause","Permissions":"Permissions","Pick location":"Choisir emplacement","Point to your backup files and restore from there":"Donner votre fichier de sauvegarde et restaurer depuis celui-ci ","Port":"Port","Previous":"Précédent","ProjectID is optional if the bucket exist":"Le ProjectID est optionel si le bucket existe","Proprietary":"Propriétaire","Purging files ...":"Nettoyage des fichiers…","Rebuilding local database ...":"Reconstruction de la base de données locale","Recreate (delete and repair)":"Récrée (suppression et réparation)","Recreating database ...":"Recréation de la base de données ...","Registering temporary backup ...":"Enregistrement de la sauvegarde temporaire ..","Relative paths not allowed":"Les chemins relatifs ne sont pas autorisés","Reload":"Recharger","Remote":"Distant","Remove":"Retirer","Remove option":"Option de retrait","Repair":"Réparer","Reparing ...":"Réparation ....","Repeat Passphrase":"Répeter la phrase secrète","Reporting:":"Communication de données :","Reset":"Réinitialiser","Restore":"Restaurer","Restore files":"Restaurer fichiers","Restore files ...":"Restaurer fichier ...","Restore files from {{backupname}}":"Restaurer les fichiers depuis {{backupname}}","Restore from":"Restaurer depuis","Restore from backup configuration":"Restaurer depuis une sauvegarde de configuration","Restore from configuration ...":"Restaurer depuis une configuration","Restore options":"Options de restauration","Restore read/write permissions":"Autorisations de lecture/écriture de restauration","Restoring files ...":"Restauration des fichiers ...","Resume":"Reprendre","Run again every":"Relancer tous les","Run now":"Démarrer maintenant","Running ...":"En cours d'exécution ...","Running ....":"En cour ...","Running commandline entry":"Execution d'une ligne de commnde","Running task:":"Tâche en cours :","S3 Compatible":"Compatible S3","Same as the base install version: {{channelname}}":"Identique à la version de base installée : {{channelname}}","Sat":"Sam.","Save":"Enregistrer","Save and repair":"Enregistrer et réparer","Save different versions with timestamp in file name":"Enregistrer des versions différentes avec l'horodatage dans le nom du fichier","Save immediately":"Sauver immédiatement ","Scanning existing files ...":"Scannage des fichiers existants ...","Scanning for local blocks ...":"Scannage de blocs locaux ...","Schedule":"Planifier","Search":"Recherche","Search for files":"Recherche de fichiers","Seconds":"Secondes","Select a log level and see messages as they happen:":"Sélectionner un niveau d'historique et voyez les messages quand ils apparaissent :","Select files":"Sélectionner les fichiers","Server":"Serveur","Server and port":"Serveur et port","Server hostname or IP":"Nom d'hôte du serveur ou IP","Server is currently paused,":"Le serveur est actuellement en pause,","Server is currently paused, do you want to resume now?":"Le serveur est actuellement en pause, voulez-vous reprendre maintenant ?","Server paused":"Serveur en pause","Server state properties":"Propriétés du statut serveur","Settings":"Paramètres","Show":"Montrer","Show advanced editor":"Montrer l'éditeur avancé","Show hidden folders":"Montrer les dossiers cachés","Show log":"Montrer l'historique","Show log ...":"Montrer l'historique ...","Show treeview":"Afficher l'arborescence","Some OpenStack providers allow an API key instead of a password and tenant name":"Certains fournisseurs OpenStack autorisent une clé API à la place d'un mot de passe et d'un nom d'entité","Source Data":"Données source","Source data":"Données source","Source folders":"Dossiers source","Source:":"Source :","Specific builds for developers only.":"Compilations spécifiques pour développeurs uniquement.","Standard protocols":"Protocoles standards","Starting ...":"Démarrage ...","Starting the restore process ...":"Démarrage du processus de restauration ...","Stop after the current file":"Stopper après le fichier en cour","Stop after upload":"Stopper après le transfert","Stop now":"Stopper maintenant","Stop running backup":"Stopper la sauvegarde en cour","Stop running task":"Stopper la tâche en cour","Stopping after upload:":"Arrêter après transfert","Stopping task:":"Arrêt de la tâche","Storage Type":"Type de stockage","Storage class":"Classe de stockage","Storage class for creating a bucket":"Classe de stockage pour la création d'un bucket","Stored":"Stocké","Strong":"Fort","Success":"Succès","Sun":"Dim.","Symbolic link":"Lien symbolique","System default ({{levelname}})":"Paramètre par défaut du système ({{levelname}})","System files":"Fichiers système","System info":"Info système","System properties":"Propriétés système","TByte":"TByte","TByte/s":"TByte/s","Task is running":"La tâche est en cours","Temporary files":"Fichiers temporaires","Tenant Name":"Nom d'entité","Test connection":"Tester la connexion","Testing ...":"Test ...","Testing connection ...":"Essai de connexion ...","Testing permissions ...":"Test des permissions ...","Testing permissions...":"Test des permissions ...","The bucket name should be all lower-case, convert automatically?":"Le nom du bucket devrait être entièrement en minuscule, convertir automatiquement ?","The bucket name should start with your username, prepend automatically?":"Le nom du bucket devrait commencer par votre nom d'utilisateur, l'ajouter automatiquement ?","The connection to the server is lost, attempting again in {{time}} ...":"La connexion au serveur a été perdue, nouvelle tentative dans {{time}} ...","The dark theme (by Michal)":"Le thème sombre (de Michal)","The default blue on white theme (by Alex)":"Thème par défaut bleu sur fond blanc (by Alex)","The folder {{folder}} does not exist\nCreate it now?":"Le dossier {{folder}} n'existe pas\nVoulez-vous le créer ?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"La clé de l'hôte a changé, veuillez vérifier avec l'administrateur du serveur si cela est correcte, car il pourrait s'agir d'une attaque de type \"intermédiaire\".\n\nVoulez-vous REMPLACER votre clé d'hôte COURANTE \"{{prev}}\" par la clé MENTIONNÉE : {{key}} ?","The path does not appear to exist, do you want to add it anyway?":"Le chemin ne semble pas exister, voulez-vous l'ajouter quand même ?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"Le répertoire ne se termine pas par un caractère '{{dirsep}}', ce qui signifie que vous sélectionnez un fichier et non un dossier.\n\nVoulez-vous inclure le fichier spécifié ?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"Le chemin doit être un chemin absolu, c.-à-d. Il doit commencer par un slash avant '/'","The path should start with \"{{prefix1}}\" or \"{{prefix2}}\", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?":"Le chemin d'accès doit commencer par \"{{prefix1}}\" ou \"{{prefix2}}\", sinon vous ne pourrez pas voir les fichiers dans l'interface web d'HubiC.\n\nVoulez-vous automatiquement ajouter le préfixe au chemin ?","The region parameter is only applied when creating a new bucket":"Le paramètre régional n'est appliqué qu'à la création d'un nouveau bucket","The region parameter is only used when creating a bucket":"Le paramètre régional n'est utilisé qu'à la création d'un bucket","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"Le certificat du serveur n'a pas pu être validé.\nVoulez-vous approuver le certificat SSL avec la somme de contrôle : {{hash}} ?","The storage class affects the availability and price for a stored file":"La classe de stockage affecte la disponibilité et le prix d'un fichier stocké","The target folder contains encrypted files, please supply the passphrase":"Le fichier cible contient des fichiers chiffrés, merci de fournir la phrase secrète","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"L'utilisateur à trop d'autorisations. Voulez-vous créer un nouvel utilisateur limité avec uniquement les autorisations pour les chemins sélectionnés ?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"Cette sauvegarde a été créée sur un autre système d’exploitation. Restaurer les fichiers sans préciser un dossier de destination peut créer des fichiers à des endroits inattendus. Êtes-vous surs de vouloir poursuivre sans choisir de dossier de destination ?","This month":"Ce mois","This week":"Cette semaine","Throttle settings":"Options d'accélération","Thu":"Jeu.","To File":"Vers fichier","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"Pour confirmer que vous souhaitez supprimer tous les fichiers distants pour \"{{name}}\", veuillez entrer le mot situé ci-dessous","To export without a passphrase, uncheck the \"Encrypt file\" box":"Pour exporter sans phrase secrète, décochez la case \"Chiffrer fichier\"","Today":"Aujourd'hui","Trust host certificate?":"Faire confiance au certificat de l'hôte ?","Trust server certificate?":"Faire confiance au certificat du serveur ?","Try out the new features we are working on. Don't use with important data.":"Essayez les nouvelles fonctions sur lesquelles nous travaillons. Ne l'utilisez pas avec des données importantes.","Tue":"Mar.","Type to highlight files":"Tapez pour mettre en surbrillance les fichiers","Unknown backup size and versions":"Taille et version de sauvegarde inconnue","Until resumed":"Jusqu'à la reprise","Update channel":"Canal de mise à jour","Update failed:":"Échec de mise à jour","Updating with existing database":"Mettre à jour avec une base de données existante","Upload volume size":"Taille du volume téléversé","Uploading verification file ...":"Téléversement du fichier de vérification ...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"Les rapports d'utilisation nous aident à améliorer l'expérience utilisateur et à évaluer l'impacte des nouvelles fonctions. Nous les utilisons pour générer des <a href=\"{{link}}\" target=\"_blank\">statistiques d'utilisation publiques</a>","Usage statistics":"Statistiques d'utilisation","Usage statistics, warnings, errors, and crashes":"Statistiques d'utilisation, avertissements, erreurs et accidents","Use SSL":"Utiliser SSL","Use existing database?":"Utiliser une base de données existante ?","Use weak passphrase":"Utiliser une phrase secrète faible","Useless":"Inutile","User data":"Données utilisateur","User has too many permissions":"L'utilisateur à trop d'autorisations","User interface settings":"Réglages interface utilisateur","Username":"Nom d'utilisateur","VISA, Mastercard, ... via Paypal":"VISA, Mastercard, ... par Paypal","Validating ...":"Validation ...","Verify files":"Vérifier fichier","Verifying ...":"Vérification ...","Verifying answer":"Vérification de la réponse","Verifying backend data ...":"Vérification des données back-end","Verifying remote data ...":"Vérifications des données distantes","Verifying restored files ...":"Vérification des fichiers restaurés","Very strong":"Très fort","Very weak":"Très faible","Visit us on":"Rendez nous visite sur","WARNING: The remote database is found to be in use by the commandline library":"ATTENTION : La base de données locale est rapportée comme étant utilisée par la librairie de ligne de commande","WARNING: This will prevent you from restoring the data in the future.":"ATTENTION : Cela va vous empêcher de restaurer vos données dans le futur.","Waiting for task to begin":"En attente du début de la tâche","Waiting for task to start ....":"En attente du début de la tâche","Waiting for upload ...":"En attente du téléversement ...","Warnings, errors and crashes":"Avertissements, erreurs et accidents","We recommend that you encrypt all backups stored outside your system":"Nous vous recommandons de chiffrer toutes les sauvegardes stockées en dehors de votre système","Weak":"Faible","Weak passphrase":"Phrase secrète faible","Wed":"Mer.","Weeks":"Semaines","Where do you want to restore from?":"Ou voulez-vous restaurer vos fichiers ?","Where do you want to restore the files to?":"Ou voulez-vous restaurer vos fichiers ?","Years":"Années","Yes":"Oui","Yes, I have stored the passphrase safely":"Oui, j'ai conservé ma phrase secrète en sécurité","Yes, I'm brave!":"Oui, je suis courageux !","Yes, please break my backup!":"Oui, s'il vous plait cassez ma sauvegarde","Yesterday":"Hier","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"Mono semble fonctionner sans certificat SSL chargé.\nVoulez-vous importer la liste de certificats de confiance depuis Mozilla ?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"Vous êtes en train de changer le chemin de la base de données depuis une base de donnée existante.\nÊtes-vous sûr que c'est ce que vous voulez ?","You are currently running {{appname}} {{version}}":"Vous êtes actuellement en train d'utiliser {{appname}} {{version}}","You can stop the backup immediately, or stop after the current file has been uploaded.":"Vous pouvez arrêter la sauvegarde immédiatement, ou stopper après télé-versement du fichier courant","You can stop the task immediately, or allow the process to continue its current file and the stop.":"Vous pouvez stopper la tâche immédiatement, ou autoriser le processus en cour et stopper ensuite","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"Vous avez changé la méthode de chiffrement. Ceci peut endommager certaines choses. Nous vous encourageons à créer une nouvelle sauvegarde à la place.","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"Vous avez changé la phrase secrète, ce qui n'est pas pris en charge. Nous vous encourageons à créer une nouvelle sauvegarde à la place.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"Vous avez choisi de ne pas chiffrer votre sauvegarde. Le chiffrement est recommandé pour toutes les données stockées sur un serveur distant.","You have chosen to restore to a new location, but not entered one":"Vous avez demandé à restaurer vers un nouveau dossier, mais sans indiquer son chemin","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"Vous avez généré une phrase secrète forte. Assurez-vous d'avoir placé une copie de cette phrase secrète en sécurité, car les données ne peuvent être récupérées si vous perdez la phrase secrète.","You must choose at least one source folder":"Vous devez choisir au moins un dossier source","You must enter a name for the backup":"Vous devez entrer un nom pour votre sauvegarde","You must enter a passphrase or disable encryption":"Vous devez entrer une phrase secrète ou désactiver le chiffrement","You must enter a positive number of backups to keep":"Vous devez entrer un nombre positif de sauvegarde à conserver","You must enter a tenant name if you do not provide an API Key":"Vous devez entrer un nom d'entité si vous ne fournissez pas une clé API","You must enter a valid duration for the time to keep backups":"Vous devez entrer une valeur correcte pour la durée de conservation de vos sauvegardes","You must enter either a password or an API Key":"Vous devez entrer soit un mot de passe, soit une clé API","You must enter either a password or an API Key, not both":"Vous devez entrer soit un mot de passe, soit une clé API, mais pas les deux","You must fill in the password":"Vous devez renseigner le mot de passe","You must fill in the server name or address":"Vous devez renseigner le nom du serveur ou l'adresse","You must fill in the username":"Vous devez renseigner le nom d'utilisateur","You must fill in {{field}}":"Vous devez renseigner le champ : {{field}}","You must select or fill in the AuthURI":"Vous devez sélectionner ou renseigner l'AuthURI","You must select or fill in the server":"Vous devez sélectionner ou renseigner le serveur","You must specify a path":"Vous devez spécifier un chemin.","Your files and folders have been restored successfully.":"Vos fichiers et dossiers ont été restaurés avec succès.","Your passphrase is easy to guess. Consider changing passphrase.":"Votre phrase secrète est facile à deviner. Songez à la changer.","a specific number":"un nombre spécifique","bucket/folder/subfolder":"bucket/dossier/sous-dossier","byte":"byte","byte/s":"byte/s","custom":"personnalisé ","resume now":"reprendre maintenant","unlimited":"illimité","until they are older than":"jusqu'à ce qu'ils soient plus vieux que","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} a été principalement développée par <a href=\"{{mail1}}\">{{dev1}}</a> et <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} peut être téléchargée depuis <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} est sous licence <a href=\"{{licenselink}}\">{{licensename}}</a>.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":["{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versions"],"{{number}} Hour":"{{number}} Heure","{{number}} Minutes":"{{number}} Minutes","{{time}} (took {{duration}})":"{{time}} (durée {{duration}})"});
+ gettextCatalog.setStrings('it', {"- pick an option -":"- seleziona un'opzione -","...loading...":"... caricamento in corso ...","API Key":"Chiave API","AWS Access ID":"ID di accesso AWS","AWS Access Key":"Chiave di accesso AWS","AWS IAM Policy":"Noerme AWS IAM","About":"Informazioni","About {{appname}}":"Informazioni {{appname}}","Access Key":"Chiave di accesso","Access denied":"Accesso negato","Access to user interface":"Accesso all'interfaccia utente","Account name":"Nome account","Activate":"Attivazione","Activate failed:":"Attivazione fallita:","Add a new backup":"Aggiungi un nuovo backup","Add a path directly":"Aggiungi direttamente un percorso","Add advanced option":"Aggiungi opzione avanzata","Add backup":"Aggiungi backup","Add filter":"Aggiungi filtro","Add path":"Aggiungi percorso","Adjust bucket name?":"Sistemare il nome bucket?","Adjust path name?":"Sistemare il nome del percorso?","Advanced Options":"Opzioni Avanzate","Advanced options":"Opzioni avanzate","Advanced:":"Avanzate:","All Hyper-V Machines":"Tutte le Macchine Hyper-V","All Microsoft SQL Databases":"Tutti i database Microsoft SQL","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Tutti i report sono inviati in modo anonimo e non contengono informazioni personali. Contengono informazioni sull'hardware, sul sistema operativo, il tipo di backend, la durata del backup, la dimensione complessiva dei dati sorgente ed dati simili. Non contengono i percorsi, nomi dei file, nomi utente, password o altre informazioni sensibili.","Allow remote access (requires restart)":"Consenti accesso remoto (richiede il riavvio)","Allowed days":"Giorni consentiti","An existing file was found at the new location":"Un file esistente è stato trovato nella nuova posizione","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"Un file esistente è stato trovato nella nuova posizione.\nSei sicuro di volere che il database punti ad un file esistente?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"Un database locale esistente per l'archiviazione è stato trovato.\nIl riutilizzo del database consentirà alle istanze da riga di comando e dal server di lavorare sullo stesso archivio remoto.\n\nVuoi usare il database esistente?","Anonymous usage reports":"Report di utilizzo anonimi","As Command-line":"Come riga di comando","AuthID":"AuthID","Authentication password":"Password di autenticazione","Authentication username":"Nome utente di autenticazione","Autogenerated passphrase":"Genera automaticamente passphrase","Automatically run backups.":"Esegui automaticamente backups","B2 Account ID":"ID Account B2","B2 Application Key":"Chiave Applicazione B2","B2 Cloud Storage Account ID":"ID Account Cloud B2 Storage","B2 Cloud Storage Application Key":"Chiave applicazione Archiviazione Cloud B2","Back":"Indietro","Backend modules:":"Moduli backend:","Backup destination":"Destinazione backup","Backup location":"Posizione Backup","Backup:":"Backup:","Beta":"Beta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Broken access":"Accesso non riuscito","Browse":"Browse","Browser default":"Browser predefinito","Bucket Name":"Nome Bucket","Bucket create location":"Crea posizione bucket","Bucket create region":"Crea area bucket","Bucket name":"Nome bucket","Bucket storage class":"Classe bucket","Building list of files to restore ...":"Creazione della lista dei file da ripristinare...","Building partial temporary database ...":"Creazione di un database parziale temporaneo...","Busy ...":"Occupato...","Canary":"Canary","Cancel":"Annulla","Cannot move to existing file":"Non puoi spostare in un file esistente","Changelog":"Registro modifiche","Changelog for {{appname}} {{version}}":"Registro modifiche di {{appname}} {{version}}","Check failed:":"Controllo fallito:","Check for updates now":"Controlla aggiornamenti ora","Checking ...":"Controllo...","Checking for updates ...":"Controllo aggiornamenti...","Chose a storage type to get started":"Scegliere un tipo di archiviazione per iniziare","Click the AuthID link to create an AuthID":"Clicca sul link AuthID per creare un nuovo AuthID","Click to set throttle options":"Clicca per impostare le opzioni di limitazione","Commandline ...":"Riga di comando...","Compact now":"Comprimi ora","Compacting remote data ...":"Comprimi dati remoti...","Completing backup ...":"Completamento backup...","Completing previous backup ...":"Completamento backup precedente...","Compression modules:":"Moduli di compressione:","Computer":"Computer","Configuration file:":"File di configurazione:","Configuration:":"Configurazione: ","Configure a new backup":"Configura un nuovo backup","Confirm delete":"Conferma cancellazione","Confirmation required":"Conferma richiesta","Connect":"Connetti","Connect now":"Connetti ora","Connecting to server ...":"Connessione al server...","Connecting to task ....":"Connessione all'attività...","Connecting...":"Connessione...","Connection lost":"Connessione persa","Connection worked!":"Connessione funzionante!","Container name":"Nome contenitore","Container region":"Area contenitore","Continue":"Continua","Continue without encryption":"Continua senza criptazione","Copied!":"Copiato!","Copy Destination URL to Clipboard":"Copia URL Destinazione negli Appunti","Copy failed. Please manually copy the URL":"Copia non riuscita. Per favore copia manualmente l'URL","Core options":"Opzioni base","Counting ({{files}} files found, {{size}})":"Conteggio ({{files}} file trovati, {{size}})","Crashes only":"Solo arresti anomali","Create bug report ...":"Crea rapporto bug...","Create folder?":"Creare cartella?","Created new limited user":"Creato nuovo utente limitato","Creating bug report ...":"Creazione rapporto bug...","Creating new user with limited access ...":"Creazione nuovo utente con accesso limitato...","Creating target folders ...":"Creazione cartelle di destinazione...","Creating temporary backup ...":"Creazione backup temporaneo...","Creating user...":"Creazione utente...","Current version is {{versionname}} ({{versionnumber}})":"La versione attuale è {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"End point S3 personalizzato","Custom authentication url":"URL di autenticazione personalizzato","Custom location ({{server}})":"Posizione personalizzata ({{server}})","Custom region for creating buckets":"Area personalizzata per la creazione bucket","Custom region value ({{region}})":"Valore area personalizzata ({{region}})","Custom server url ({{server}})":"URL del server personalizzato ({{server}})","Custom storage class ({{class}})":"Classe di archiviazione personalizzata ({{class}})","Database ...":"Database...","Days":"Giorni","Default":"Predefinito","Default ({{channelname}})":"Predefinito ({{channelname}})","Default options":"Opzioni predefinite","Delete":"Cancella","Delete ...":"Cancella...","Delete backup":"Cancella backup","Delete local database":"Cancella database locale","Delete remote files":"Cancella file remoti","Delete the local database":"Cancella il database locale","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"Cancella {{filecount}} file ({{filesize}}) dall'archivio remoto?","Deleting remote files ...":"Cancellazione file remoti...","Deleting unwanted files ...":"Cancellazione file indesiderati...","Desktop":"Desktop","Destination":"Destinazione","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"Ti abbiamo aiutato a salvare i tuoi file? Se è così, per favore considera di supportare Duplicati con una donazione. Suggeriamo {{smallamount}} per uso privato e {{largeamount}} per uso commerciale.","Direct restore from backup files ...":"Ripristino diretto da file di backup...","Disabled":"Disattivato","Dismiss":"Abbandona","Display and color theme":"Schermo e colore tema","Do you really want to delete the backup: \"{{name}}\" ?":"Vuoi veramente cancellare il backup: \"{{name}}\" ?","Do you really want to delete the local database for: {{name}}":"Vuoi veramente cancellare il database locale per: {{name}} ?","Donate":"Donazione","Donate with Bitcoins":"Donazione con Bitcoin","Donate with PayPal":"Donazione con PayPal","Donation messages":"Messaggio donazione","Donation messages are hidden, click to show":"Messaggio donazione è nascosto, clicca per mostrarlo","Donation messages are visible, click to hide":"Messaggio donazione è visibile, clicca per nasconderlo","Done":"Fatto","Download":"Scarica","Downloading ...":"Sto scaricando...","Downloading files ...":"Sto scaricando i file...","Downloading update...":"Sto scaricando l'aggiornamento...","Duplicate option {{opt}}":"Opzione duplicata {{opt}}","Duplicati Website":"Sito web di Duplicati","Duplicati forum":"Forum Duplicati","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\n When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.\n If you are using the local database for backups from the commandline, you should keep the database.":"Ogni backup dispone di un database locale associato, che archivia le informazioni del backup remoto sul computer locale.\nQuando si cancella un backup, è anche possibile cancellare il database locale senza influire sulla possibilità di ripristinare i file remoti.\nSe si utilizza il database locale per i backup dalla riga di comando, è necessario mantenere il database.","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Ogni backup dispone di un database locale associato, che archivia le informazioni del backup remoto sul computer locale.\nIn questo modo è più veloce eseguire molte operazioni e riduce la quantità di dati che devono essere scaricati per ogni operazione.","Edit ...":"Modifica...","Edit as list":"Modifica come elenco","Edit as text":"Modifica come testo","Encrypt file":"Cripta file","Encryption":"Criptazione","Encryption changed":"Criptazione cambiata","Encryption modules:":"Moduli criptazione:","Enter URL":"Inserisci URL","Enter access key":"Inserisci chiave di accesso","Enter account name":"Inserisci nome account","Enter backup passphrase, if any":"Inserisci la passphrase del backup, se presente","Enter configuration details":"Inserisci dettagli configurazione","Enter container name":"Inserire nome contenitore","Enter encryption passphrase":"Inserisci passphrase criptazione","Enter expression here":"Inserisci qui espressione","Enter folder path name":"Inserire il nome del percorso della cartella","Enter one option per line in command-line format, eg. {0}":"Inserire un'opzione per riga in formato riga di comando, ad es. {0}","Enter the destination path":"Inserisci percorso destinazione","Error":"Errore","Error!":"Errore!","Errors and crashes":"Errori e arresti anomali","Exclude":"Escludi","Exclude directories whose names contain":"Escludi cartelle il cui nome contiene","Exclude expression":"Escludi espressione","Exclude file":"Escludi file","Exclude file extension":"Escludi estensione del file","Exclude files whose names contain":"Escludi file il cui nome contiene","Exclude folder":"Escludi cartella","Exclude regular expression":"Escludi espressione regolare","Existing file found":"Trovato file esistente","Experimental":"Sperimentale","Export":"Esporta","Export ...":"Esporta...","Export backup configuration":"Esporta configurazione backup","Export configuration":"Esporta configurazione","Exporting ...":"Esportazione...","FTP (Alternative)":"FTP (Alternativo)","Failed to build temporary database: {{message}}":"Fallita creazione del database temporaneo: {{message}}","Failed to connect:":"Connessione fallita:","Failed to connect: {{message}}":"Connessione fallita: {{message}}","Failed to delete:":"Cancellazione fallita: ","Failed to fetch path information: {{message}}":"Recupero informazioni sul percorso fallito: {{message}}","Failed to import:":"Importazione fallita:","Failed to read backup defaults:":"Lettura impostazioni predefinite backup fallita:","Failed to restore files: {{message}}":"Ripristino dei file fallito: {{message}}","Failed to save:":"Salvataggio fallito:","Fetching path information ...":"Recupero informazioni percorso...","File":"File","Files larger than:":"File più grandi di:","Filters":"Filtri","Finished!":"Finito!","First run setup":"Impostazione prima esecuzione","Folder":"Cartella","Folder path":"Percorso cartella","Fri":"Ven","GByte":"GByte","GByte/s":"GByte/s","GCS Project ID":"ID Progetto GCS","General":"Generale","General backup settings":"Impostazioni generali backup","General options":"Opzioni generali","Generate":"Genera","Generate IAM access policy":"Genera criteri di accesso IAM","Getting file versions ...":"Ottenimento versione file...","Hidden files":"File nascosti","Hide":"Nascondi","Hide hidden folders":"Nascondi cartelle nascoste","Home":"Home","Hours":"Ore","How do you want to handle existing files?":"Come vuoi gestire i file esistenti?","Hyper-V Machine":"Sitema Hyper-V","Hyper-V Machine:":"Sistema Hyper-V:","Hyper-V Machines":"Sistemi Hyper-V","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"Se una data è stata persa, il lavoro sarà eseguito il più presto possibile.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Se il backup e l'archivio remoto non sono sincronizzati, Duplicati sarà necessario eseguire un'operazione di ripristino per sincronizzare il database.\nSe la riparazione non è riuscita, è possibile cancellare il database locale e rigenerarlo.","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Se il file di backup non è scaricato automaticamente, <a href=\"{{DownloadURL}}\" target=\"_blank\">fai clic con il tasto desto e seleziona &quot;Salva come...&quot;</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Se il file di backup non è scaricato automaticamente,<a href=\"{{item.DownloadLink}}\" target=\"_blank\">fai clic con il tasto desto e seleziona &quot;Salva come...&quot;</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Se non inserisci un percorso, tutti i file saranno salvati nella cartella di accesso.\nSei sicuro che questo è quello che vuoi?","If you do not enter an API Key, the tenant name is required":"Se non inserisci una Chiave API, è richiesto il nome dell'inquilino","If you want to use the backup later, you can export the configuration before deleting it":"Se desideri utilizzare il backup in un secondo momento, è possibile esportare la configurazione prima di cancellarla","If your machine is in a multi-user environment (i.e. the machine has more than one account), you need to set a password to prevent other users from accessing data on your account.\nDo you want to set a password now?":"Se la tua macchina è in un ambiente multi-utente (cioè la macchina ha più di un account), è necessario impostare una password per impedire ad altri utenti di accedere ai dati del tuo account. \nVuoi impostare una password ora?","Import":"Importa","Import Destination URL":"Importa URL Destinazione","Import backup configuration":"Importa configurazione backup","Import completed, but no certificates were found after the import":"Importazione completata, ma non sono stati trovati certificati dopo l'importazione","Import failed":"Importazione fallita","Import from a file":"Importa da un file","Importing ...":"Importazione...","Include a file?":"Includi un file?","Include expression":"Includi espressione","Include regular expression":"Includi espressione regolare","Incorrect answer, try again":"Risposta errata, riprova","Individual builds for developers only.":"Versioni particolari solo per gli sviluppatori.","Information":"Informazioni","Install":"Installa","Install failed:":"Installazione fallita:","Invalid retention time":"Tempo ritenzione non valido","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"È possibile connettersi ad alcuni FTP senza una password.\nSei sicuro che il tuo server FTP supporta gli accessi senza password?","KByte":"KByte","KByte/s":"KByte/s","Keep this number of backups":"Manteni questo numero di backup","Language in user interface":"Lingua nell'interfaccia utente","Last month":"Lo scorso mese","Last successful run:":"Ultima esecuzione corretta:","Latest":"Più recente","Libraries":"Librerie","Listing backup dates ...":"Creazione elenco date backup...","Listing remote files ...":"Creazione elenco file remoti...","Live":"In tempo reale","Load a configuration from an exported job or a storage provider":"Carica una configurazione da un lavoro esportato o da un provider di archiviazione","Load destination from an exported job or a storage provider":"Carica una destinazione da un lavoro esportato o da un provider di archiviazione","Load older data":"Carica dati precedenti","Loading ...":"Caricamento...","Loading remote storage usage ...":"Caricamento dell'archivio remoto utilizzato ...","Local database for":"Database locale per ","Local database path:":"Percorso database locale:","Local storage":"Archivio locale","Location":"Posizione","Location where buckets are created":"Posizione in cui sono creati i bucket","Log data for <b>{{Backup.Backup.Name}}</b>":"Dati di registro per <b>{{Backup.Backup.Name}}</b>","Log data from the server":"Dati di registro dal server","Log out":"Log out","MByte":"MByte","MByte/s":"MByte/s","Maintenance":"Manutenzione","Manually type path":"Digita manualmente il percorso","Max download speed":"Velocità massima per scaricare","Max upload speed":"Velocità massima per il caricamento","Menu":"Menu","Microsoft SQL Database:":"Microsoft SQL Database:","Microsoft SQL Databases":"Microsoft SQL Database","Minutes":"Minuti","Missing name":"Nome mancante","Missing passphrase":"Passphrase mancante","Missing sources":"Sorgente mancante","Mon":"Lun","Months":"Mesi","Move existing database":"Sposta database esistente","Move failed:":"Spostamento fallito:","My Documents":"Documenti","My Music":"Musica","My Photos":"Foto","My Pictures":"Immagini","Name":"Nome","Never":"Mai","New update found: {{message}}":"Nuovo aggiornamento trovato: {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"Il nuovo nome utente è {{user}}.\nCredenziali aggiornate per utilizzare il nuovo utente limitato","Next":"Avanti","Next scheduled run:":"Prossima esecuzione pianificata: ","Next scheduled task:":"Prossima attività pianificata:","Next task:":"Prossima attività:","Next time":"Prossima volta","No":"No","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"Nessun certificato è stato specificato in precedenza, per favore verifica con l'amministratore del server che la chiave è corretta: {{key}}\n\nVuoi approvare la chiave host riportata?","No editor found for the &quot;{{backend}}&quot; storage type":"Nessun editor trovato per il &quot;{{backend}}&quot; tipo archivio","No encryption":"Nessuna criptazione","No items selected":"Nessun elemento selezionato","No items to restore, please select one or more items":"Nessun elemento da ripristinare, seleziona uno o più elementi","No passphrase entered":"Nessuna passphrase inserita","No scheduled tasks":"Nessuna attività pianificata","No, my machine has only a single account":"No, la mia macchina ha solo un singolo account","Non-matching passphrase":"Passphrase non corrispondente","None / disabled":"Nessuno / disattivato","OK":"OK","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Operazione fallita:","Operations:":"Operazioni:","Optional authentication password":"Password opzionale per l'autenticazione","Optional authentication username":"Nome utente opzionale per l'autenticazione","Options":"Opzioni","Options added here are applied to all backups, but can be overridden in each individual backup":"Le opzioni aggiunte qui sono applicate a tutti i backup, ma possono essere ignorate in ogni singolo backup","Original location":"Percorso originale","Others":"Altri","Overwrite":"Sovrascrivi","Passphrase":"Passphrase","Passphrase (if encrypted)":"Passphrase (se criptato)","Passphrase changed":"Passphrase modificata","Passphrases are not matching":"Passphrase non corrispondenti","Password":"Password","Passwords do not match":"Password non corrispondenti","Patching files with local blocks ...":"Sistemazione file con blocchi locali...","Path not found":"Percorso non trovato","Path on server":"Percorso sul server","Path or subfolder in the bucket":"Percorso o sottocartella bucket","Pause":"Pausa","Pause after startup or hibernation":"Pausa dopo avvio o ibernazione","Pause options":"Opzioni pausa","Permissions":"Autorizzazioni","Pick location":"Scegli posizione","Point to your backup files and restore from there":"Puntare ai file di backup e ripristinare da lì","Port":"Porta","Previous":"Precedente","ProjectID is optional if the bucket exist":"ID Progetto è opzionale se esiste un bucket","Proprietary":"Proprietario","Purging files ...":"Cancellazione dei file...","Rebuilding local database ...":"Ricostruzione database locale...","Recreate (delete and repair)":"Ricrea (cancella e ripara)","Recreating database ...":"Ricreazione database...","Registering temporary backup ...":"Registrazione backup temporaneo...","Relative paths not allowed":"Percorsi relativi non consentiti","Reload":"Ricarica","Remote":"Remoto","Remove":"Rimuovi","Remove option":"Rimuovi opzione","Repair":"Ripara","Reparing ...":"Riparazione...","Repeat Passphrase":"Ripeti Passphrase","Reporting:":"Segnalazione:","Reset":"Reset","Restore":"Ripristina","Restore files":"Ripristina file","Restore files ...":"Ripristina file...","Restore files from {{backupname}}":"Ripristina file da {{backupname}}","Restore from":"Ripristina da","Restore from backup configuration":"Ripristino dalla configurazione backup","Restore from configuration ...":"Ripristino dalla configurazione...","Restore options":"Opzioni di ripristino","Restore read/write permissions":"Ripristina autorizzazioni lettura/scrittura","Restoring files ...":"Ripristino file...","Resume":"Riprendi","Run again every":"Eseguire di nuovo ogni","Run now":"Esegui ora","Running ...":"Esecuzione...","Running ....":"Esecuzione...","Running commandline entry":"Riga di comando in esecuzione","Running task:":"Attività in esecuzione:","S3 Compatible":"Compatibile S3","Same as the base install version: {{channelname}}":"Come la versione di base installata: {{channelname}}","Sat":"Sab","Save":"Salva","Save and repair":"Salva e ripara","Save different versions with timestamp in file name":"Salva versioni diverse con timestamp nel nome del file","Save immediately":"Salva immediatamente","Scanning existing files ...":"Scansione file esistenti...","Scanning for local blocks ...":"Scansione dei blocchi locali...","Schedule":"Pianificazione","Search":"Cerca","Search for files":"Cerca per file","Seconds":"Secondi","Select a log level and see messages as they happen:":"Selezionare un livello di registro e visiona i messaggi che avvengono:","Select files":"Seleziona file","Server":"Server","Server and port":"Server e porta","Server hostname or IP":"Nome host o IP del server","Server is currently paused,":"Server è attualmente in pausa,","Server is currently paused, do you want to resume now?":"Server attualmente in pausa, vuoi riprendere ora?","Server paused":"Server in pausa","Server state properties":"Proprietà stato del server","Settings":"Impostazioni","Show":"Mostra","Show advanced editor":"Mostra editor avanzato","Show hidden folders":"Mostra cartelle nascoste","Show log":"Mostra registro modifiche","Show log ...":"Mostra registro modifiche...","Show treeview":"Visualizza ad albero","Some OpenStack providers allow an API key instead of a password and tenant name":"Alcuni provider OpenStack consentono una chiave API anziché una password e un nome inquilino","Source Data":"Dati Sorgente","Source data":"Dati sorgente","Source folders":"Cartella sorgente","Source:":"Sorgente:","Specific builds for developers only.":"Versioni specifiche solo per sviluppatori.","Standard protocols":"Protocolli standard","Starting ...":"Avvio....","Starting the restore process ...":"Avvio del processo di ripristino...","Stop after the current file":"Ferma dopo il file corrente","Stop after upload":"Ferma dopo caricamento","Stop now":"Ferma adesso","Stop running backup":"Ferma esecuzione backup","Stop running task":"Ferma esecuzione attività","Stopping after upload:":"Ferma dopo caricamento:","Stopping task:":"Ferma attività:","Storage Type":"Tipo archivio","Storage class":"Classe archivio","Storage class for creating a bucket":"Classe di archiviazione per la creazione di un bucket","Stored":"Archivia","Strong":"Forte","Success":"Successo","Sun":"Dom","Symbolic link":"Link simbolico","System default ({{levelname}})":"Sistema predefinito ({{levelname}})","System files":"Fila di sistema","System info":"Informazioni di sistema","System properties":"Proprietà di sistema","TByte":"TByte","TByte/s":"TByte/s","Task is running":"Attività in esecuzione","Temporary files":"File temporanei","Tenant Name":"Nome Inquilino","Test connection":"Prova connessione","Testing ...":"Test in corso...","Testing connection ...":"Prova connessione...","Testing permissions ...":"Prova autorizzazioni...","Testing permissions...":"Prova autorizzazioni...","The bucket name should be all lower-case, convert automatically?":"Il nome del bucket dovrebbe essere tutto minuscolo, convertirlo automaticamente?","The bucket name should start with your username, prepend automatically?":"Il nome del bucket dovrebbe iniziare con il tuo nome utente, anteporlo automaticamente?","The connection to the server is lost, attempting again in {{time}} ...":"Connessione al server persa, nuovo tentativo in {{time}}...","The dark theme (by Michal)":"Il tema scuro (da Michal)","The default blue on white theme (by Alex)":"Il blu predefinito sul tema bianco (da Alex)","The folder {{folder}} does not exist\nCreate it now?":"La cartella {{folder}} non esiste\nCrearla ora?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"La chiave host è cambiata, per favore consulta l'amministratore del server se questa è corretta, altrimenti potresti essere la vittima di un attacco UOMO-NEL-MEZZO.\n\nVuoi SOSTITUIRE la chiave host CORRENTE \"{{prev}}\" con la chiave host SEGNALATA: {{key}}?","The path does not appear to exist, do you want to add it anyway?":"Il percorso sembra non esistere, vuoi aggiungerlo comunque?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"Il percorso non termina con un carattere '{{dirsep}}', il che significa che si include un file, non una cartella.\n\nVuoi includere il file specificato?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"Il percorso deve essere un percorso assoluto, cioè deve iniziare con una barra '/'","The path should start with \"{{prefix1}}\" or \"{{prefix2}}\", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?":"Il percorso deve iniziare con \"{{prefix1}}\" o \"{{prefix2}}\", altrimenti non sarà possibile visualizzare i file nell'interfaccia Web di HubiC.\n\nVuoi aggiungere automaticamente il prefisso al percorso?","The region parameter is only applied when creating a new bucket":"Il parametro area è applicato solo quando si crea un nuovo bucket","The region parameter is only used when creating a bucket":"Il parametro area è utilizzato solo quando si crea un bucket","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"Il certificato del server non può essere convalidato.\n\nVuoi approvare il certificato SSL con l'hash: {{hash}}?","The storage class affects the availability and price for a stored file":"La classe di archiviazione influisce sulla disponibilità e sul prezzo per un file archiviato","The target folder contains encrypted files, please supply the passphrase":"La cartella di destinazione contiene file criptati, per favore fornisci la passphrase","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"L'utente dispone di troppe autorizzazioni. Vuoi creare un nuovo utente limitato, con solo autorizzazioni per il percorso selezionato?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"Questo backup è stato creato su un altro sistema operativo. Il ripristino dei file senza specificare una cartella di destinazione può causare il ripristino di file in luoghi imprevisti. Sei sicuro di voler continuare senza scegliere una cartella di destinazione?","This month":"Questo mese","This week":"Questa settimana","Throttle settings":"Impostazioni limitazione","Thu":"Mar","To File":"Al File","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"Per confermare che vuoi cancellare tutti i file remoti che contengono \"{{name}}\", digita la parla che vedi di seguito","To export without a passphrase, uncheck the \"Encrypt file\" box":"Per esportare senza una passphrase, deselezionare la casella \"Cripta file\"","Today":"Oggi","Trust host certificate?":"Certificato host affidabile?","Trust server certificate?":"Certificato server affidabile?","Try out the new features we are working on. Don't use with important data.":"Prova le nuove funzioni su cui stiamo lavorando. Non usare con dati importanti.","Tue":"Gio","Type to highlight files":"Digitare per evidenziare i file","Unknown backup size and versions":"Dimensione e versione backup sconosciute","Until resumed":"Finché non riprende","Update channel":"Aggiorna canale","Update failed:":"Aggiornamento fallito:","Updating with existing database":"Aggiornamento con database esistente","Upload volume size":"Dimensione file caricati","Uploading verification file ...":"Caricamento file di verifica...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"I rapporti sull'utilizzo ci aiutano a migliorare l'esperienza dell'utente e a valutare l'impatto delle nuove funzionalità. Li usiamo per generare <a href=\"{{link}}\" target=\"_blank\">statistiche di utilizzo pubblico</a>","Usage statistics":"Statistiche di utilizzo","Usage statistics, warnings, errors, and crashes":"Statistiche di utilizzo, avvisi, errori e arresti anomali","Use SSL":"Usa SSL","Use existing database?":"Usare database esistente?","Use weak passphrase":"Usa passphrase debole","Useless":"Inutile","User data":"Dati utente","User has too many permissions":"L'utente ha troppe autorizzazioni","User interface settings":"Impostazioni interfaccia utente","Username":"Nome utente","VISA, Mastercard, ... via Paypal":"VISA, Mastercard, ... via Paypal","Validating ...":"Convalida...","Verify files":"Verifica file","Verifying ...":"Verifica...","Verifying answer":"Verifica risposta","Verifying backend data ...":"Verifica dati backend...","Verifying remote data ...":"Verifica dati remoti...","Verifying restored files ...":"Verifica file ripristinati...","Very strong":"Molto forte","Very weak":"Molto debole","Visit us on":"Venite a trovarci su","WARNING: The remote database is found to be in use by the commandline library":"ATTENZIONE: Il database remoto si trova in uso dalla libreria riga di comando","WARNING: This will prevent you from restoring the data in the future.":"ATTENZIONE: Questo ti impedirà di ripristinare i dati in futuro.","Waiting for task to begin":"In attesa dell'attività per iniziare","Waiting for task to start ....":"In attesa dell'attività per iniziare...","Waiting for upload ...":"In attesa del caricamento...","Warnings, errors and crashes":"Avvisi, errori e arresti anomali","We recommend that you encrypt all backups stored outside your system":"Ti consigliamo di criptare tutti i backup archiviati al di fuori del tuo sistema","Weak":"Debole","Weak passphrase":"Passphrase debole","Wed":"Mer","Weeks":"Settimane","Where do you want to restore from?":"Da dove vuoi ripristinare?","Where do you want to restore the files to?":"Dove vuoi ripristinare i files?","Years":"Anni","Yes":"Si","Yes, I have stored the passphrase safely":"Si, ho archiviato la passphrase in modo sicuro","Yes, I'm brave!":"Sì, sono coraggioso!","Yes, please break my backup!":"Sì, per favore rompi il mio backup!","Yesterday":"Ieri","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"Sembra che tu sia in esecuzione Mono senza certificati SSL caricati.\nVuoi importare l'elenco dei certificati attendibili da Mozilla?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"Stai cambiando il percorso di un database esistente.\nSei sicuro che questo è ciò che vuoi?","You are currently running {{appname}} {{version}}":"Attualmente stai eseguendo {{appname}} {{version}}","You can stop the backup immediately, or stop after the current file has been uploaded.":"È possibile fermare immediatamente il backup o fermarlo dopo che il file corrente è stato caricato.","You can stop the task immediately, or allow the process to continue its current file and the stop.":"Puoi arrestare immediatamente l'attività o consentire al processo di continuare il file in corso e fermarlo.","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"Hai modificato l'algoritmo di criptazione. Questa azione potrebbe corrompere i dati. Ti consigliamo di creare un nuovo backup.","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"Hai modificato la passphrase ma questo non è supportato. Ti consigliamo di creare un nuovo backup.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"Hai scelto di non criptare il backup. È consigliabile criptare tutti i dati custoditi su server remoti.","You have chosen to restore to a new location, but not entered one":"Si è scelto di ripristinare in una nuova posizione, ma non ne è stata inserita una","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"Hai generato una passphrase forte. Assicurati di aver fatto una copia sicura della passphrase, in quanto i dati non possono essere recuperati se perdi la passphrase.","You must choose at least one source folder":"Devi scegliere almeno una cartella sorgente","You must enter a name for the backup":"Devi inserire un nome un nome per il backup","You must enter a passphrase or disable encryption":"Devi inserire una passphrase o disattiva la criptazione","You must enter a positive number of backups to keep":"Devi inserire un numero positivo di backup da mantenere","You must enter a tenant name if you do not provide an API Key":"Devi inserire il nome di un inquilino se non fornisci una Chiave API","You must enter a valid duration for the time to keep backups":"Devi inserire un periodo di tempo valido in cui mantenere i backup","You must enter either a password or an API Key":"Devi inserire una password o una Chiave API","You must enter either a password or an API Key, not both":"Devi inserire una password o una Chiave API, non entrambe","You must fill in the password":"Devi compilare in password","You must fill in the server name or address":"Devi compilare in nome del server o indirizzo","You must fill in the username":"Devi compilare in nome utente","You must fill in {{field}}":"Devi compilare in {{field}}","You must select or fill in the AuthURI":"Devi selezionare o compilare in AuthURI","You must select or fill in the server":"Devi selezionare o compilare in server","You must specify a path":"Devi specificare un percorso","Your files and folders have been restored successfully.":"I tuoi file e cartelle sono stati ripristinati correttamente.","Your passphrase is easy to guess. Consider changing passphrase.":"La tua passphrase è facile da indovinare. Considera l'idea di cambiarla.","a specific number":"un numero specifico","bucket/folder/subfolder":"bucket/cartella/sottocartella","byte":"byte","byte/s":"byte/s","custom":"personalizzato","resume now":"riprendi ora","unlimited":"illimitato","until they are older than":"finché non sono più vecchi di","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} è stato sviluppato principalmente da <a href=\"{{mail1}}\">{{dev1}}</a> e <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} può essere scaricato da <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} è sotto la licenza <a href=\"{{licenselink}}\">{{licensename}}</a>.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":["{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versione","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versioni"],"{{number}} Hour":"{{number}} Ore","{{number}} Minutes":"{{number}} Minuti","{{time}} (took {{duration}})":"{{time}} (took {{duration}})"});
+ gettextCatalog.setStrings('nl_NL', {"- pick an option -":" - kies een optie -","...loading...":"...laden...","API Key":"API sleutel","AWS Access ID":"AWS Toegangs ID","AWS Access Key":"AWS Toegangssleutel","AWS IAM Policy":"AWS IAM Beleid","About":"Over","About {{appname}}":"Over {{appname}}","Access Key":"Toegangssleutel","Access denied":"Toegang geweigerd","Access to user interface":"Toegang tot gebruikersinterface","Account name":"Accountnaam","Activate":"Activeren","Activate failed:":"Activeren mislukt","Add a new backup":"Nieuwe back-up toevoegen","Add a path directly":"Voeg een pad rechtstreeks toe","Add advanced option":"Voeg geavanceerde optie toe","Add backup":"Back-up toevoegen","Add filter":"Voeg filter toe","Add path":"Voeg pad toe","Adjust bucket name?":"Bucket naam aanpassen?","Adjust path name?":"Padnaam aanpassen?","Advanced Options":"Geavanceerde Opties","Advanced options":"Geavanceerde opties","Advanced:":"Geavanceerd:","All Hyper-V Machines":"Alle Hyper-V Machines","All Microsoft SQL Databases":"Alle Microsoft SQL Databases","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Alle gebruiksrapporten worden anoniem verstuurd en bevatten geen enkele persoonlijke informatie. Ze bevatten informatie over hardware en besturingssysteem, het type backend, back-up tijdsduur, totale grootte van brongegevens en soortgelijke gegevens. Ze bevatten geen paden, bestandsnamen, gebruikersnamen, wachtwoorden of soortgelijke gevoelige informatie.","Allow remote access (requires restart)":"Remote toegang toestaan (herstart vereist)","Allowed days":"Alleen op deze dagen","An existing file was found at the new location":"Een bestaand bestand was gevonden op de nieuwe locatie","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"Een bestaand bestand was gevonden op de nieuwe locatie. Weet u zeker dat de database moet verwijzen naar een bestaand bestand?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"Een bestaande lokale database voor de opslag is gevonden.\nHergebruik van de database zal toestaan dat de opdrachtregel- en server instances werken op dezelfde remote opslag.\n\nWilt u de bestaande database gebruiken?","Anonymous usage reports":"Anonieme gebruiksrapporten","As Command-line":"Als Opdrachtregel","AuthID":"AuthID","Authentication password":"Authenticatie wachtwoord","Authentication username":"Authenticatie gebruikersnaam","Autogenerated passphrase":"Automatisch gegenereerde wachtwoordzin","Automatically run backups.":"Automatisch back-ups uitvoeren","B2 Account ID":"B2 Account ID","B2 Application Key":"B2 Applicatiesleutel","B2 Cloud Storage Account ID":"B2 Cloud Storage Account ID","B2 Cloud Storage Application Key":"B2 Cloud Storage Applicatiesleutel","Back":"Vorige","Backend modules:":"Backend modules:","Backup destination":"Back-updoel","Backup location":"Back-up locatie","Backup:":"Back-up:","Beta":"Beta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Broken access":"Verbroken toegang","Browse":"Bladeren","Browser default":"Browser standaard","Bucket Name":"Bucket Naam","Bucket create location":"Bucket aanmaaklocatie","Bucket create region":"Bucket aanmaakregio","Bucket name":"Bucketnaam","Bucket storage class":"Bucket opslagklasse","Building list of files to restore ...":"Lijst samenstellen met te herstellen bestanden ...","Building partial temporary database ...":"Gedeeltelijke tijdelijke database samenstellen ...","Busy ...":"Bezig ...","Canary":"Canary","Cancel":"Annuleren","Cannot move to existing file":"Kan niet verplaatsen naar bestaand bestand","Changelog":"Aanpassingen-log","Changelog for {{appname}} {{version}}":"Aanpassingen-log voor {{appname}} {{version}}","Check failed:":"Controle mislukt:","Check for updates now":"Controleer nu op updates","Checking ...":"Controleren ...","Checking for updates ...":"Controleren op updates ...","Chose a storage type to get started":"Kies een opslagtype om aan de slag te gaan","Click the AuthID link to create an AuthID":"Klik op de AuthID link om een AuthID aan te maken","Click to set throttle options":"Klik om bandbreedte-opties in te stellen","Commandline ...":"Opdrachtregel ...","Compact now":"Nu opruimen","Compacting remote data ...":"Opruimen van remote gegevens ...","Completing backup ...":"Back-up wordt voltooid ...","Completing previous backup ...":"Vorige back-up wordt voltooid ...","Compression modules:":"Compressiemodules:","Computer":"Computer","Configuration file:":"Configuratiebestand","Configuration:":"Configuratie:","Configure a new backup":"Een nieuwe back-up instellen","Confirm delete":"Bevestig verwijderen","Confirmation required":"Bevestiging vereist","Connect":"Verbind","Connect now":"Verbind nu","Connecting to server ...":"Verbinden met server ...","Connecting to task ....":"Verbinding maken met taak ...","Connecting...":"Verbinden...","Connection lost":"Verbinding verbroken","Connection worked!":"Verbinding werkt!","Container name":"Containernaam","Container region":"Container-regio","Continue":"Volgende","Continue without encryption":"Ga verder zonder versleuteling","Copied!":"Gekopieerd!","Copy Destination URL to Clipboard":"Kopieer doel URL naar Klembord","Copy failed. Please manually copy the URL":"Kopiëren mislukt. Kopieer de URL handmatig","Core options":"Kern-opties","Counting ({{files}} files found, {{size}})":"Tellen ({{files}} bestanden gevonden, {{size}})","Crashes only":"Alleen crashes","Create bug report ...":"Bug rapport maken ...","Create folder?":"Folder aanmaken?","Created new limited user":"Nieuwe beperkte gebruiker aangemaakt","Creating bug report ...":"Bug rapport aanmaken ...","Creating new user with limited access ...":"Nieuwe gebruiker met beperkte toegang aanmaken ...","Creating target folders ...":"Doelmappen aanmaken ...","Creating temporary backup ...":"Tijdelijke back-up aanmaken ...","Creating user...":"Gebruiker aanmaken ...","Current version is {{versionname}} ({{versionnumber}})":"Huidige versie is {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"Aangepaste S3 endpoint","Custom authentication url":"Aangepaste authenticatie url","Custom location ({{server}})":"Aangepaste locatie ({{server}})","Custom region for creating buckets":"Aangepaste regio voor het aanmaken van buckets","Custom region value ({{region}})":"Aangepaste regio waarde ({{region}})","Custom server url ({{server}})":"Aangepaste server url ({{server}})","Custom storage class ({{class}})":"Aangepaste opslagklasse ({{class}})","Database ...":"Database ...","Days":"Dagen","Default":"Standaard","Default ({{channelname}})":"Standaard ({{channelname}})","Default options":"Standaard opties","Delete":"Verwijderen","Delete ...":"Verwijderen ...","Delete backup":"Verwijder back-up","Delete local database":"Verwijder lokale database","Delete remote files":"Verwijder remote bestanden","Delete the local database":"Verwijder de lokale database","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"{{filecount}} bestanden ({{filesize}}) van de remote opslag verwijderen?","Deleting remote files ...":"Remote bestanden verwijderen ...","Deleting unwanted files ...":"Onnodige bestanden verwijderen ...","Desktop":"Desktop","Destination":"Doel","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"Hebben we geholpen uw bestanden veilig te stellen? Overweeg in dat geval Duplicati te ondersteunen met een donatie. We raden {{smallamount}} aan voor persoonlijk gebruik en {{largeamount}} voor bedrijfsmatig gebruik.","Direct restore from backup files ...":"Rechtstreeks herstellen vanuit back-up bestanden ...","Disabled":"Uitgeschakeld","Dismiss":"Afwijzen","Display and color theme":"Weergave en kleurenschema","Do you really want to delete the backup: \"{{name}}\" ?":"Wilt u de back-up \"{{name}}\" echt verwijderen?","Do you really want to delete the local database for: {{name}}":"Wilt u de lokale database voor: {{name}} echt verwijderen?","Donate":"Doneren","Donate with Bitcoins":"Doneer met Bitcoins","Donate with PayPal":"Doneer met PayPal","Donation messages":"Doneer-berichten","Donation messages are hidden, click to show":"Doneer-berichten zijn verborgen, klik om ze weer te geven","Donation messages are visible, click to hide":"Doneer-berichten zijn zichtbaar, klik om ze te verbergen","Done":"Klaar","Download":"Download","Downloading ...":"Downloaden ...","Downloading files ...":"Bestanden downloaden ...","Downloading update...":"Update downloaden ...","Duplicate option {{opt}}":"Dupliceer optie {{opt}}","Duplicati Website":"Duplicati Website","Duplicati forum":"Duplicati forum","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\n When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.\n If you are using the local database for backups from the commandline, you should keep the database.":"Iedere back-up heeft een lokale database waarmee het geassocieerd is, die informatie opslaat over de remote back-up op de lokale machine.\nBij het verwijderen van een back-up kan eveneens de lokale database verwijderd worden, zonder dat dit invloed heeft op de mogelijkheid van het terugzetten van de remote bestanden.\nAls de lokale database gebruikt wordt voor back-ups vanaf de opdrachtregel, moet de database behouden blijven.","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Iedere back-up heeft een lokale database waarmee het geassocieerd is, die informatie opslaat over de remote back-up op de lokale machine.\nDit maakt het sneller bij het uitvoeren van veel bewerkingen, en reduceert de hoeveelheid gegevens die gedownload moeten worden voor iedere bewerking.","Edit ...":"Bewerken ...","Edit as list":"Bewerk als lijst","Edit as text":"Bewerk als tekst","Encrypt file":"Versleutel bestand","Encryption":"Versleuteling","Encryption changed":"Versleuteling aangepast","Encryption modules:":"Versleutelingsmodules:","Enter URL":"Geef URL in","Enter access key":"Geef toegangscode in","Enter account name":"Geef accountnaam in","Enter backup passphrase, if any":"Geef eventueel back-up wachtwoordzin in","Enter configuration details":"Voer configuratie-details in","Enter container name":"Geef containernaam in","Enter encryption passphrase":"Geef een wachtwoordzin in voor versleuteling","Enter expression here":"Geef uitdrukking hier in","Enter folder path name":"Geef padnaam van de map in","Enter one option per line in command-line format, eg. {0}":"Geef één optie per regel in opdracht-prompt indeling, bijvoorbeeld {0}","Enter the destination path":"Geef het doelpad in","Error":"Fout","Error!":"Fout!","Errors and crashes":"Fouten en crashes","Exclude":"Uitsluiten","Exclude directories whose names contain":"Sluit mappen uit waarvan de naam bevat:","Exclude expression":"Sluit uitdrukking uit","Exclude file":"Sluit bestand uit","Exclude file extension":"Sluit bestandsextensie uit","Exclude files whose names contain":"Sluit bestanden uit waarvan de naam bevat:","Exclude folder":"Sluit map uit","Exclude regular expression":"Sluit reguliere expressie uit","Existing file found":"Bestaand bestand gevonden","Experimental":"Experimenteel","Export":"Exporteer","Export ...":"Exporteren ...","Export backup configuration":"Exporteer back-upconfiguratie","Export configuration":"Exporteer configuratie","Exporting ...":"Exporteren ...","FTP (Alternative)":"FTP (Alternatief)","Failed to build temporary database: {{message}}":"Opbouwen tijdelijke database mislukt: {{message}}","Failed to connect:":"Verbinden mislukt:","Failed to connect: {{message}}":"Verbinden mislukt: {{message}}","Failed to delete:":"Verwijderen mislukt:","Failed to fetch path information: {{message}}":"Ophalen pad-informatie mislukt: {{message}}","Failed to import:":"Importeren mislukt:","Failed to read backup defaults:":"Standaard instellingen voor back-up inlezen mislukt:","Failed to restore files: {{message}}":"Herstellen bestanden mislukt: {{message}}","Failed to save:":"Opslaan mislukt:","Fetching path information ...":"Ophalen pad-informatie ...","File":"Bestand","Files larger than:":"Bestanden groter dan:","Filters":"Filters","Finished!":"Klaar!","First run setup":"Instellen voor eerste gebruik","Folder":"Map","Folder path":"Map-pad","Fri":"Vrijdag","GByte":"GByte","GByte/s":"GByte/s","GCS Project ID":"GCS Project ID","General":"Algemeen","General backup settings":"Algemene back-upinstellingen","General options":"Algemene opties","Generate":"Genereer","Generate IAM access policy":"Genereer IAM toegangsbeleid","Getting file versions ...":"Bestandsversies ophalen ...","Hidden files":"Verborgen bestanden","Hide":"Verberg","Hide hidden folders":"Verberg verborgen bestanden","Home":"Start","Hours":"Uur","How do you want to handle existing files?":"Hoe wilt u omgaan met bestaande bestanden?","Hyper-V Machine":"Hyper-V Machine","Hyper-V Machine:":"Hyper-V Machine:","Hyper-V Machines":"Hyper-V Machines","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"Als een geplande taak werd overgeslagen, zal de taak zo snel mogelijk na het geplande tijdstip starten.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Als de back-up en de remote opslag niet gesynchroniseerd zijn, zal Duplicati vereisen dat u een repareer-bewerking uitvoert om de database te synchroniseren.\nAls het repareren niet succesvol was, kunt u de lokale database verwijderen en opnieuw samenstellen.","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Als het back-upbestand niet automatisch is gedownload, <a href=\"{{DownloadURL}}\" target=\"_blank\">klik met rechts en kies &quot;Opslaan als ...&quot;</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Als het back-upbestand niet automatisch is gedownload, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">klik met rechts en kies &quot;Opslaan als ...&quot;</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Als u geen pad ingeeft, zullen alle bestanden opgeslagen worden in de login map.\nWeet u zeker dat dit is wat u wilt?","If you do not enter an API Key, the tenant name is required":"Als u geen API sleutel ingeeft, is een tenant naam vereist","If you want to use the backup later, you can export the configuration before deleting it":"Als u de back-up later wilt gebruiken, kunt u de configuratie exporteren alvorens hem te verwijderen","If your machine is in a multi-user environment (i.e. the machine has more than one account), you need to set a password to prevent other users from accessing data on your account.\nDo you want to set a password now?":"Als uw machine zich in een multi-user omgeving bevindt (bijvoorbeeld als op de machine met meer dan één account kan worden aangemeld), moet een wachtwoord worden ingesteld om te voorkomen dat andere gebruikers togang kunnen krijgen tot gegevens behorend bij uw account.\nWilt u nu een wachtwoord instellen?","Import":"Importeer","Import Destination URL":"Importeer Doel URL","Import backup configuration":"Importeer back-upconfiguratie","Import completed, but no certificates were found after the import":"Importeren voltooid, maar na het importeren zijn geen certificaten gevonden","Import failed":"Importeren mislukt","Import from a file":"Importeer vanuit een bestand","Importing ...":"Importeren ...","Include a file?":"Een bestand opnemen?","Include expression":"Uitdrukking opnemen","Include regular expression":"Reguliere expressie opnemen","Incorrect answer, try again":"Incorrect antwoord, probeer opnieuw","Individual builds for developers only.":"Individuele builds alleen voor ontwikkelaars.","Information":"Informatie","Install":"Installeren","Install failed:":"Installeren mislukt","Invalid retention time":"Ongeldige retentietijd","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"Het is mogelijk te verbinden met sommige FTP servers zonder een wachtwoord.\nWeet u zeker dat uw FTP server aanmelden zonder wachtwoord ondersteunt?","KByte":"KByte","KByte/s":"KByte/s","Keep this number of backups":"Bewaar dit aantal back-ups","Language in user interface":"Taal in gebruikersinterface","Last month":"Vorige maand","Last successful run:":"Laatste succesvolle uitvoering","Latest":"Laatste","Libraries":"Bibliotheken","Listing backup dates ...":"Back-updata weergeven ...","Listing remote files ...":"Remote bestanden weergeven ...","Live":"Live","Load a configuration from an exported job or a storage provider":"Laad een configuratie vanuit een geëxporteerde taak of een opslagprovider","Load destination from an exported job or a storage provider":"Laad doel vanuit een geëxporteerde taak of een opslagprovider","Load older data":"Laad oudere gegevens","Loading ...":"Laden ...","Loading remote storage usage ...":"Laden van remote opslaggebruik ...","Local database for":"Lokale database voor","Local database path:":"Lokaal database-pad:","Local storage":"Lokale opslag","Location":"Locatie","Location where buckets are created":"Locatie waar buckets gemaakt worden","Log data for <b>{{Backup.Backup.Name}}</b>":"Log gegevens voor <b>{{Backup.Backup.Name}}</b>","Log data from the server":"Log gegevens van de server","Log out":"Uitloggen","MByte":"MByte","MByte/s":"MByte/s","Maintenance":"Onderhoud","Manually type path":"Voer pad handmatig in","Max download speed":"Max downloadsnelheid","Max upload speed":"Max Uploadsnelheid","Menu":"Menu","Microsoft SQL Database:":"Microsoft SQL Database","Microsoft SQL Databases":"Microsoft SQL Databases","Minutes":"Minuten","Missing name":"Ontbrekende naam","Missing passphrase":"Ontbrekende wachtwoordzin","Missing sources":"Ontbrekende bronnen","Mon":"Maandag","Months":"Maanden","Move existing database":"Verplaats bestaande database","Move failed:":"Verplaatsen mislukt:","My Documents":"Mijn Documenten","My Music":"Mijn Muziek","My Photos":"Mijn Foto's","My Pictures":"Mijn Afbeeldingen","Name":"Naam","Never":"Nooit","New update found: {{message}}":"Nieuwe update gevonden: {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"Nieuwe gebruikersnaam is {{user}}.\nGebruikersreferenties bijgewerkt om de nieuwe beperkte gebruiker te gebruiken","Next":"Volgende","Next scheduled run:":"Volgende geplande uitvoering:","Next scheduled task:":"Volgende geplande taak:","Next task:":"Volgende taak:","Next time":"Volgende keer","No":"Nee","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"Er is eerder geen certificaat opgegeven, controleer svp met de serverbeheerder of de sleutel correct is: {{key}}\n\nWilt u de gerapporteerde host-sleutel goedkeuren?","No editor found for the &quot;{{backend}}&quot; storage type":"Geen bewerkingsprogramma gevonden voor het &quot;{{backend}}&quot; opslagtype","No encryption":"Geen versleuteling","No items selected":"Geen items geselecteerd","No items to restore, please select one or more items":"Geen items om te herstellen, selecteer één of meer items","No passphrase entered":"Geen wachtwoordzin ingegeven","No scheduled tasks":"Geen geplande taken","No, my machine has only a single account":"Nee, mijn machine heeft slechts een enkele account","Non-matching passphrase":"Niet-bijbehorende wachtwoordzin","None / disabled":"Geen / uitgeschakeld","OK":"OK","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Bewerking mislukt:","Operations:":"Bewerkingen:","Optional authentication password":"Optioneel authenticatie wachtwoord","Optional authentication username":"Optionele authenticatie gebruikersnaam","Options":"Opties","Options added here are applied to all backups, but can be overridden in each individual backup":"Opties die hier worden toegevoegd, worden toegepast op alle back-ups, maar kunnen worden overschreven in iedere afzonderlijke back-up","Original location":"Originele locatie","Others":"Anderen","Overwrite":"Overschrijven","Passphrase":"Wachtwoordzin","Passphrase (if encrypted)":"Wachtwoordzin (indien versleuteld)","Passphrase changed":"Wachtwoordzin veranderd","Passphrases are not matching":"Wachtwoordzinnen komen niet overeen","Password":"Wachtwoord","Passwords do not match":"Wachtwoorden komen niet overeen","Patching files with local blocks ...":"Bestanden bijwerken met lokale blokken ...","Path not found":"Pad niet gevonden","Path on server":"Pad op server","Path or subfolder in the bucket":"Pad of submap in de bucket","Pause":"Pauze","Pause after startup or hibernation":"Pauzeer na opstarten of slaapmodus","Pause options":"Pauzeer-opties","Permissions":"Permissies","Pick location":"Kies locatie","Point to your backup files and restore from there":"Verwijs naar de back-up bestanden en herstel daar vandaan","Port":"Poort","Previous":"Vorige","ProjectID is optional if the bucket exist":"ProjectID is optioneel als de bucket bestaat","Proprietary":"Fabrikantgebonden","Purging files ...":"Bestanden wissen ...","Rebuilding local database ...":"Opnieuw opbouwen van lokale database ...","Recreate (delete and repair)":"Opnieuw aanmaken (verwijderen en repareren)","Recreating database ...":"Opnieuw opbouwen van de database ...","Registering temporary backup ...":"Registreren tijdelijke back-up ...","Relative paths not allowed":"Relatieve paden zijn niet toegestaan","Reload":"Andere code","Remote":"Remote","Remove":"Verwijderen","Remove option":"Verwijder optie","Repair":"Repareer","Reparing ...":"Repareren ...","Repeat Passphrase":"Herhaal wachtwoordzin","Reporting:":"Rapportage:","Reset":"Reset","Restore":"Herstellen","Restore files":"Herstel bestanden","Restore files ...":"Bestanden herstellen ...","Restore files from {{backupname}}":"Herstel bestanden vanuit {{backupname}}","Restore from":"Herstellen vanaf","Restore from backup configuration":"Herstel vanuit back-up configuratie","Restore from configuration ...":"Herstel vanuit configuratie...","Restore options":"Herstelopties","Restore read/write permissions":"Herstel lees/schrijfpermissies","Restoring files ...":"Bestanden worden hersteld ...","Resume":"Hervat","Run again every":"Voer opnieuw uit iedere","Run now":"Nu uitvoeren","Running ...":"In uitvoering ...","Running ....":"Uitvoeren ...","Running commandline entry":"Opdrachtregelinvoer in uitvoering","Running task:":"Taak in uitvoering:","S3 Compatible":"S3 Compatible","Same as the base install version: {{channelname}}":"Zelfde als de basis installatie versie: {{channelname}}","Sat":"Zaterdag","Save":"Opslaan","Save and repair":"Opslaan en repareren","Save different versions with timestamp in file name":"Sla verschillende versies op met tijdstempel in de bestandsnaam","Save immediately":"Onmiddellijk opslaan","Scanning existing files ...":"Scannen bestaande bestanden ...","Scanning for local blocks ...":"Scannen op lokale blokken ...","Schedule":"Planning","Search":"Zoek","Search for files":"Zoek bestanden","Seconds":"Seconden","Select a log level and see messages as they happen:":"Selecteer een logniveau en bekijk meldingen zodra ze zich voordoen:","Select files":"Selecteer bestanden","Server":"Server","Server and port":"Server en poort","Server hostname or IP":"Server hostnaam of IP","Server is currently paused,":"Server is momenteel gepauzeerd,","Server is currently paused, do you want to resume now?":"Server is momenteel gepauzeerd, wilt u nu hervatten?","Server paused":"Server gepauzeerd","Server state properties":"Server status eigenschappen","Settings":"Instellingen","Show":"Tonen","Show advanced editor":"Toon geavanceerde editor","Show hidden folders":"Toon verborgen mappen","Show log":"Log weergeven","Show log ...":"Log weergeven ...","Show treeview":"Toon boomstructuur","Some OpenStack providers allow an API key instead of a password and tenant name":"Sommige OpenStack providers staan een API key toe in plaats van een wachtwoord en tenant naam","Source Data":"Bron","Source data":"Brongegevens","Source folders":"Bronmappen","Source:":"Bron:","Specific builds for developers only.":"Specifieke builds alleen voor ontwikkelaars.","Standard protocols":"Standaard protocollen","Starting ...":"Starten ...","Starting the restore process ...":"Starten van het herstelproces ...","Stop after the current file":"Stop na het huidige bestand","Stop after upload":"Stop na de upload","Stop now":"Nu stoppen","Stop running backup":"Stop de back-up in uitvoering","Stop running task":"Stop de taak in uitvoering","Stopping after upload:":"Stop na de upload:","Stopping task:":"Taak wordt gestopt:","Storage Type":"Opslagtype","Storage class":"Opslagklasse","Storage class for creating a bucket":"Opslagklasse voor het aanmaken van een bucket","Stored":"Opgeslagen","Strong":"Sterk","Success":"Succes","Sun":"Zondag","Symbolic link":"Symbolische link","System default ({{levelname}})":"Systeem standaard ({{levelname}})","System files":"Systeembestanden","System info":"Systeeminformatie","System properties":"Systeemeigenschappen","TByte":"TByte","TByte/s":"TByte/s","Task is running":"Taak is in uitvoering","Temporary files":"Tijdelijke bestanden","Tenant Name":"Tenant naam","Test connection":"Test verbinding","Testing ...":"Testen ...","Testing connection ...":"Testen van de verbinding ...","Testing permissions ...":"Testen van de permissies ...","Testing permissions...":"Testen van de permissies ...","The bucket name should be all lower-case, convert automatically?":"De bucket-naam hoort in kleine letters te zijn, automatisch converteren?","The bucket name should start with your username, prepend automatically?":"De bucket naam hoort te beginnen met uw gebruikersnaam, automatisch voorvoegen?","The connection to the server is lost, attempting again in {{time}} ...":"De verbinding met de server is verbroken, opnieuw proberen over {{time}} ...","The dark theme (by Michal)":"Het donkere thema (door Michal)","The default blue on white theme (by Alex)":"Het standaard blauw op wit thema (door Alex)","The folder {{folder}} does not exist\nCreate it now?":"De map {{folder}} bestaat niet. Nu aanmaken?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"De host sleutel is veranderd, controleer met uw server beheerder of dit correct is, in het andere geval zou u het slachtoffer kunnen zijn van een MAN-IN-THE-MIDDLE aanval.\n\nWilt u de HUIDIGE host sleutel \"{prev}\" VERVANGEN door de GERAPPORTEERDE host sleutel: {{key}}?","The path does not appear to exist, do you want to add it anyway?":"Het pad lijkt niet te bestaan, wilt u het desondanks toevoegen?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"Het pad eindigt niet met een '{{dirsep}}' teken, wat betekent dat u een bestand opneemt, niet een map.\n\nWilt u het aangegeven bestand opnemen?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"Het pad moet een absoluut pad zijn, bijvoorbeeld het moet beginnen met een forward slash '/'","The path should start with \"{{prefix1}}\" or \"{{prefix2}}\", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?":"Het pad moet beginnen met \"{{prefix1}}\" of \"{{prefix2}}\", anders zullen bestanden in de HubiC web interface niet zichtbaar zijn.","The region parameter is only applied when creating a new bucket":"De regio parameter wordt alleen toegepast bij het aanmaken van een bucket","The region parameter is only used when creating a bucket":"De regio parameter wordt alleen gebruikt bij het aanmaken van een bucket","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"Het servercertificaat kon niet gevalideerd worden.\nWilt u het certificaat goedkeuren met deze hash: {{hash}}?","The storage class affects the availability and price for a stored file":"De opslagklasse beïnvloedt de beschikbaarheid en prijs van een opgeslagen bestand","The target folder contains encrypted files, please supply the passphrase":"De doelmap bevat versleutelde bestanden, geef alstublieft de wachtwoordzin","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"De gebruiker heeft teveel permmissies. Wilt u een nieuwe beperkte gebruiker aanmaken, met enkel permissies tot het aangegeven pad?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"De back-up werd aangemaakt op een ander besturingssysteem. Bestanden terugzetten zonder een doelmap op te geven kan tot gevolg hebben dat bestanden worden teruggezet naar onverwachte plaatsen. Bent u er zeker van dat u wilt doorgaan zonder een doelmap te kiezen?","This month":"Deze maand","This week":"Deze wek","Throttle settings":"Bandbreedte-instellingen","Thu":"Donderdag","To File":"Naar Bestand","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"Om te bevestigen dat u alle remote bestanden wilt verwijderen voor \"{{name}}\", geef svp het woord in dat u hieronder ziet","To export without a passphrase, uncheck the \"Encrypt file\" box":"Om te exporteren zonder een wachtwoordzin, deselecteer het \"Versleutel bestand\" vakje","Today":"Vandaag","Trust host certificate?":"Vertrouw host certificaat?","Trust server certificate?":"Vertrouw server certificaat?","Try out the new features we are working on. Don't use with important data.":"Probeer nieuwe mogelijkheden uit waar we aan werken. Niet gebruiken met belangrijke gegevens.","Tue":"Dinsdag","Type to highlight files":"Typ om bestanden uit te lichten","Unknown backup size and versions":"Onbekende back-up grootte en versies","Until resumed":"Tot hervatting","Update channel":"Updatekanaal","Update failed:":"Update mislukt:","Updating with existing database":"Updaten met bestaande database","Upload volume size":"Upload volumegrootte","Uploading verification file ...":"Uploaden controlebestand ...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"Gebruiksrapporten helpen ons de gebruikerservaring te verbeteren en de impact van nieuwe mogelijkheden te evalueren. We gebruiken ze om <a href=\"{{link}}\" target=\"_blank\">openbare gebruikstatistieken</a> te genereren.","Usage statistics":"Gebruikstatistieken","Usage statistics, warnings, errors, and crashes":"Gebruikstatistieken, waarschuwingen, fouten en crashes","Use SSL":"Gebruik SSL","Use existing database?":"Gebruik bestaande database?","Use weak passphrase":"Gebruik zwakke wachtwoordzin","Useless":"Waardeloos","User data":"Gebruikersgegevens","User has too many permissions":"Gebruiker heeft teveel permissies","User interface settings":"Gebruikersinterface instellingen","Username":"Gebruikersnaam","VISA, Mastercard, ... via Paypal":"VISA, Mastercard, ... via PayPal","Validating ...":"Valideren ...","Verify files":"Bestanden controleren","Verifying ...":"Controleren ...","Verifying answer":"Antwoord controleren","Verifying backend data ...":"Controleren van backend gegevens ...","Verifying remote data ...":"Controleren van remote gegevens ...","Verifying restored files ...":"Controleren van herstelde bestanden ...","Very strong":"Erg sterk","Very weak":"Erg zwak","Visit us on":"Bezoek ons op","WARNING: The remote database is found to be in use by the commandline library":"WAARSCHUWING: De remote database blijkt in gebruik te zijn door de opdrachtregel bibliotheek","WARNING: This will prevent you from restoring the data in the future.":"WAARSCHUWING: Dit zal het onmogelijk maken om in de toekomst bestanden te herstellen.","Waiting for task to begin":"Wachten op het starten van de taak","Waiting for task to start ....":"Wachten op het starten van de taak ...","Waiting for upload ...":"Wachten op upload ...","Warnings, errors and crashes":"Waarschuwingen, fouten en crashes","We recommend that you encrypt all backups stored outside your system":"We raden aan dat u alle back-ups die buiten uw systeem worden opgeslagen versleutelt","Weak":"Zwak","Weak passphrase":"Zwakke wachtwoordzin","Wed":"Woensdag","Weeks":"Weken","Where do you want to restore from?":"Waar vandaan wilt u herstellen?","Where do you want to restore the files to?":"Waarheen wilt u de bestanden herstellen?","Years":"Jaren","Yes":"Ja","Yes, I have stored the passphrase safely":"Ja, ik heb de wachtwoordzin op een veilige plaats opgeborgen","Yes, I'm brave!":"Ja, ik ben dapper!","Yes, please break my backup!":"Ja, help mijn back-up om zeep!","Yesterday":"Gisteren","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"Het lijkt er op dat u Mono gebruikt zonder dat SSL certificaten geladen zijn.\nWilt u de lijst met vertrouwde certificaten importeren van Mozilla?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"U verandert het database pad weg van een bestaande database.\nWeet u zeker dat dit is wat u wilt?","You are currently running {{appname}} {{version}}":"U werkt momenteel met {{appname}} {{version}}","You can stop the backup immediately, or stop after the current file has been uploaded.":"De back-up kan onmiddellijk worden gestopt, of stoppen nadat het huidige bestand is geüpload.","You can stop the task immediately, or allow the process to continue its current file and the stop.":"De taak kan onmiddellijk worden gestopt, of het proces toestaan om door te gaan met het huidige bestand en dan stoppen.","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"U hebt de versleutelingsmodus veranderd. Dit kan dingen kapotmaken. U wordt daarom aangemoedigd een nieuwe back-up aan te maken","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"U hebt de wachtwoordzin aangepast, wat niet wordt ondersteund. U wordt daarom aangemoedigd een nieuwe back-up aan te maken.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"U hebt ervoor gekozen de back-up niet te versleutelen. Encryptie is aanbevolen voor alle gegevens die worden opgeslagen op een remote server.","You have chosen to restore to a new location, but not entered one":"U koos voor terugzetten naar een nieuwe locatie, maar hebt geen locatie opgegeven","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"U hebt een sterke wachtwoordzin gegenereerd. Verzeker u ervan dat u een veilige kopie heeft van de wachtwoordzin, omdat de gegevens niet hersteld kunnen worden als u de wachtwoordzin verliest.","You must choose at least one source folder":"U moet tenminste één bronmap kiezen","You must enter a name for the backup":"U moet een naam ingeven voor de back-up","You must enter a passphrase or disable encryption":"U moet een wachtwoordzin ingeven of versleuteling uitschakelen","You must enter a positive number of backups to keep":"U moet een positief getal opgeven voor de hoeveelheid te bewaren back-ups","You must enter a tenant name if you do not provide an API Key":"U moet een tenant naam ingeven als u de API sleutel niet verstrekt","You must enter a valid duration for the time to keep backups":"U moet een geldige tijdsduur ingeven voor de tijd dat back-ups bewaard moeten worden","You must enter either a password or an API Key":"U moet òf een wachtwoord, òf een API sleutel ingeven","You must enter either a password or an API Key, not both":"U moet òf een wachtwoord, òf een API sleutel ingeven, niet beide","You must fill in the password":"U moet het wachtwoord invullen","You must fill in the server name or address":"U moet de servernaam of -adres invullen","You must fill in the username":"U moet de gebruikersnaam invullen","You must fill in {{field}}":"U moet {{field}} invullen","You must select or fill in the AuthURI":"U moet de AuthURI selecteren of invullen","You must select or fill in the server":"U moet de server selecteren of invullen","You must specify a path":"U moet een pad opgeven","Your files and folders have been restored successfully.":"Uw bestanden en mappen zijn succesvol hersteld","Your passphrase is easy to guess. Consider changing passphrase.":"Uw wachtwoordzin is eenvoudig te raden. Overweeg de wachtwoordzin te veranderen.","a specific number":"een bepaald aantal","bucket/folder/subfolder":"bucket/map/submap","byte":"byte","byte/s":"byte/s","custom":"aangepast","resume now":"nu hervatten","unlimited":"onbeperkt","until they are older than":"totdat ze ouder zijn dan","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} werd in eerste instantie ontwikkeld door <a href=\"{{mail1}}\">{{dev1}}</a> en <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} kan gedownload worden van <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is gelicenseerd onder de <a href=\"{{licenselink}}\">{{licensename}}</a>.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":["{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versie","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versies"],"{{number}} Hour":"{{number}} Uur","{{number}} Minutes":"{{number}} Minuten","{{time}} (took {{duration}})":"{{time}} (duurde {{duration}})"});
+ gettextCatalog.setStrings('pl', {"- pick an option -":"- wybierz opcję -","...loading...":"...ładowanie...","API Key":"Klucz API","AWS Access ID":"Identyfikator dostępu AWS","AWS Access Key":"Klucz dostepu AWS","AWS IAM Policy":"Polisa AWS IAM","About":"O programie","About {{appname}}":"O programie {{appname}}","Access Key":"Klucz dostępu","Access denied":"Dostęp zabroniony","Access to user interface":"Dostęp do interface użytkownika","Account name":"Nazwa konta","Activate":"Aktywuj","Activate failed:":"Niepowodzenie aktywacji:","Add a new backup":"Dodaj nową kopię","Add a path directly":"Dodaj ścieżkę bezpośrednio","Add advanced option":"Dodaj opcję zaawansowaną","Add backup":"Dodaj kopię","Add filter":"Dodaj filtr","Add path":"Dodaj ścieżkę","Adjust bucket name?":"Poprawić nazwę zasobnika?","Adjust path name?":"Poprawić nazwę ścieżki?","Advanced Options":"Opcje Zaawansowane","Advanced options":"Opcje zaawansowane","Advanced:":"Zaawansowane:","All Hyper-V Machines":"Wszystkie Maszyny Hyper-V","All Microsoft SQL Databases":"Wszystkie Bazy Danych Microsoft SQL","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Wszystkie raporty użycia są wysyłane anonimowo i nie zawierają żadnych danych osobistych. Raporty zawierają informacje o sprzęcie i systemie operacyjnym, rodzaju kopii zapasowej, czasie trwania, ogólnej ilości danych źródłowych i tym podobne. Raporty nie zawierają ścieżek, nazw plików, nazw użytkowników, haseł i tym podobnych danych wrażliwych.","Allow remote access (requires restart)":"Zezwalaj na dostęp zdalny (wymaga restartu)","Allowed days":"Dozwolone dni","An existing file was found at the new location":"Znaleziono istniejący plik w nowym położeniu","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"Istniejący plik został znaleziony w nowej lokalizacji\nCzy na pewno chcesz skierować bazę danych do istniejącego pliku?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"Znaleziono istniejącą, lokalną bazę danych dla magazynu.\nPonowne użycie tej bazy pozwoli pracować instancji wiersza poleceń oraz serwerowej z tym samym zdalnym magazynem.\n\nCzy chcesz użyć istniejącej bazy danych?","Anonymous usage reports":"Anonimowy raport użycia","As Command-line":"Jako Linia poleceń","AuthID":"AuthID","Authentication password":"Hasło uwierzytenienia","Authentication username":"Nazwa uwierzytelnienia","Autogenerated passphrase":"Automatycznie wygenerowane długie hasło","Automatically run backups.":"Automatycznie uruchamiaj kopie.","B2 Account ID":"ID Konta B2","B2 Application Key":"Klucz Aplikacji B2","B2 Cloud Storage Account ID":"B2 Cloud Storage Account ID","B2 Cloud Storage Application Key":"B2 Cloud Storage Application Key","Back":"Wstecz","Backend modules:":"Moduły zaplecza:","Backup destination":"Miejsce docelowe kopii","Backup location":"Lokalizacja kopii","Backup:":"Kopia:","Beta":"Beta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Broken access":"Przerwany dostęp","Browse":"Przeglądaj","Browser default":"Domyślna przeglądarka","Bucket Name":"Nazwa Zasobnika","Bucket create location":"Miejsce tworzenia zasobnika","Bucket create region":"Region tworzenia zasobnika","Bucket name":"Nazwa zasobnika","Bucket storage class":"Klasa przechowywania zasobnika","Building list of files to restore ...":"Tworzenie listy plików do odzyskania ...","Building partial temporary database ...":"Tworzenie tymczasowej częściowej bazy danych ...","Busy ...":"Zajęty ...","Canary":"Robocze","Cancel":"Anuluj","Cannot move to existing file":"Nie można przenieść do istniejącego plku","Changelog":"Lista zmian","Changelog for {{appname}} {{version}}":"Lista zmian dla {{appname}} {{version}}","Check failed:":"Sprawdzenie nieudane:","Check for updates now":"Sprawdź uaktualnienia ","Checking ...":"Sprawdzanie...","Checking for updates ...":"Sprawdzanie uaktualnień ...","Chose a storage type to get started":"Wybierz typ magazynu by rozpocząć","Click the AuthID link to create an AuthID":"Kliknij link AuthID by utworzyć AuthID","Click to set throttle options":"Kliknij, aby ustawić limity prędkości","Commandline ...":"Linia poleceń ...","Compact now":"Kompaktuj teraz","Compacting remote data ...":"Kompaktowanie zdalnych danych","Completing backup ...":"Kończenie kopii...","Completing previous backup ...":"Kończenie poprzedniej kopii...","Compression modules:":"Moduły kompresji:","Computer":"Komputer","Configuration file:":"Plik konfiguracyjny:","Configuration:":"Konfiguracja:","Configure a new backup":"Skonfiguruj nową kopię","Confirm delete":"Potwierdź usunięcie","Confirmation required":"Potwierdzenie wymagane","Connect":"Połącz","Connect now":"Połącz teraz","Connecting to server ...":"Łączenie z serwerem ...","Connecting to task ....":"Łączenie z zadaniem ...","Connecting...":"Łączenie ...","Connection lost":"Utracono połączenie","Connection worked!":"Połączenie działa!","Container name":"Nazwa zasobnika","Container region":"Region zasobnika","Continue":"Kontynuuj","Continue without encryption":"Kontynuuj bez szyfrowania","Copied!":"Skopiowane!","Copy Destination URL to Clipboard":"Kopiuj Docelowy URL do Schowka","Copy failed. Please manually copy the URL":"Niepowodzenie kopiowania. Proszę skopiować URL ręcznie","Core options":"Opcje podstawowe","Counting ({{files}} files found, {{size}})":"Liczenie ({{files}} znaleziono plików, {{size}})","Crashes only":"Tylko awarie","Create bug report ...":"Tworzenie raportu błędów ...","Create folder?":"Utworzyć folder","Created new limited user":"Utwórz nowego użytkownika z ograniczeniami","Creating bug report ...":"Tworzenie raportu błędów ...","Creating new user with limited access ...":"Tworzenie nowego użytkownika z ograniczeniami ...","Creating target folders ...":"Tworzenie folderów docelowych ...","Creating temporary backup ...":"Tworzenie kopii tymczasowej ...","Creating user...":"Tworzenie użytkownika ...","Current version is {{versionname}} ({{versionnumber}})":"Bieżąca wersja to {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"Niestandardowy węzeł końcowy S3","Custom authentication url":"Niestandardowy URL uwierzytelniania","Custom location ({{server}})":"Niestandardowa lokalizacja ({{serwer}})","Custom region for creating buckets":"Niestandardowy region do tworzenia zasobników","Custom region value ({{region}})":"Niestandardowa wartość regionu ({{region}})","Custom server url ({{server}})":"Niestandardowy adres url serwera ({{serwer}})","Custom storage class ({{class}})":"Niestandardowa klasa magazynu ({{Klasa}})","Database ...":"Baza danych ...","Days":"Dni","Default":"Domyślny","Default ({{channelname}})":"Domyślny ({{channelname}})","Default options":"Opcje domyślne","Delete":"Usuń","Delete ...":"Usuń ...","Delete backup":"Usuń kopię","Delete local database":"Usuń lokalną bazę danych","Delete remote files":"Usuń zdalne pliki","Delete the local database":"Usuń lokalną bazę danych","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"Usunąć {{filecount}} plików ({{filesize}}) ze zdalnego magazynu?","Deleting remote files ...":"Usuwanie zdalnych plików ...","Deleting unwanted files ...":"Usuwanie niepotrzebnych plików","Desktop":"Pulpit","Destination":"Lokalizacja docelowa","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"Czy pomogliśmy zabezpieczyć Twoje pliki? Jeśli tal, to rozważ proszę wsparcie programu Duplicati dotacją w wysokości {{smallamount}} dla użytku prywatnego i {{largeamount}} - dla użytku firmowego.","Direct restore from backup files ...":"Odtwórz bezpośrednio z plików kopii ...","Disabled":"Wyłączone","Dismiss":"Ukryj","Display and color theme":"Schemat ekranu i kolorystyki","Do you really want to delete the backup: \"{{name}}\" ?":"Naprawdę chcesz usunąć kopię: \"{{name}}\" ?","Do you really want to delete the local database for: {{name}}":"Czy naprawdę chcesz usunąć lokalna bazę danych: {{name}}","Donate":"Wesprzyj","Donate with Bitcoins":"Wesprzyj przez Bitcoins","Donate with PayPal":"Wesprzyj przez PayPal","Donation messages":"Komunikaty o wsparcie","Donation messages are hidden, click to show":"Komunikaty o wsparcie są ukryte, kliknij by przywrócić","Donation messages are visible, click to hide":"Komunikaty o wsparcie są widoczne kliknij by ukryć","Done":"Wykonane","Download":"Pobranie","Downloading ...":"Pobieranie ...","Downloading files ...":"Pobieranie plików ...","Downloading update...":"Pobieranie uaktualnienia ...","Duplicate option {{opt}}":"Powielenie opcji {{opt}}","Duplicati Website":"Strona Duplicati","Duplicati forum":"Forum Duplicati","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\n When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.\n If you are using the local database for backups from the commandline, you should keep the database.":"Każdy skonfigurowany backup posiada powiązaną z nim lokalną bazę danych, w której przechowuje na komputerze lokalnym informacje o zdalnej kopii zapasowej.\rKiedy konfiguracja backup'u jest usuwana, można również usunąć lokalną bazę danych bez wpływu na możliwość odtworzenia plików zdalnych.\rJeśli używasz lokalnej bazy danych do kopii zapasowych z wiersza poleceń, należy zachować bazę danych.","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Każda kopia zapasowa ma powiązaną z nią lokalną bazę danych, w której na lokalnym komputerze przechowywane są informacje o zdalnej kopii zapasowej. \\nTo sprawia, że można szybciej wykonywać wiele operacji i zmniejsza ilość danych, które muszą być pobrane dla każdej operacji.","Edit ...":"Edycja ...","Edit as list":"Edytuj jako listę","Edit as text":"Edytuj jako tekst","Encrypt file":"Zaszyfruj plik","Encryption":"Szyfrowanie","Encryption changed":"Szyfrowanie zmienione","Encryption modules:":"Moduły szyfrujące:","Enter URL":"Podaj URL","Enter access key":"Podaj klucz dostępu","Enter account name":"Podaj nazwę konta","Enter backup passphrase, if any":"Podaj długie hasło, jeśli jest","Enter configuration details":"Wprowadź szczegóły konfiguracji","Enter container name":"Podaj nazwę zasobnika","Enter encryption passphrase":"Podaj długie hasło szyfrowania","Enter expression here":"Tutaj wprowadź wyrażenie","Enter folder path name":"Wprowadź nazwę ścieżki dostępu","Enter one option per line in command-line format, eg. {0}":"Wprowadź po jednej opcji w wierszu w formacie wiersza poleceń, np. \n{0}","Enter the destination path":"Wprowadź ścieżkę docelową","Error":"Błąd","Error!":"Błąd!","Errors and crashes":"Błędy i awarie","Exclude":"Wyłącz","Exclude directories whose names contain":"Wyłącz katalogi z nazwą zawierającą","Exclude expression":"Wyłącz wyrażenie","Exclude file":"Wyłącz plik","Exclude file extension":"Wyłącz rozszerzenie pliku","Exclude files whose names contain":"Wyłącz pliki z nazwą zawierającą","Exclude folder":"Wyłącz folder","Exclude regular expression":"Wyłącz wyrażenie regularne","Existing file found":"Znaleziono istniejący plik","Experimental":"Eksperymentalne","Export":"Eksport","Export ...":"Eksportowanie ...","Export backup configuration":"Eksportuj konfigurację kopii","Export configuration":"Eksportuj konfigurację","Exporting ...":"Eksportowanie ...","FTP (Alternative)":"FTP (Alternatywny)","Failed to build temporary database: {{message}}":"Nie udało się utworzyć tymczasowej bazy danych: {{message}}","Failed to connect:":"Nie udało się połączyć:","Failed to connect: {{message}}":"Nie udało się połączyć: {{message}}","Failed to delete:":"Nie udało się usunąć:","Failed to fetch path information: {{message}}":"Nie udało się pobrać informacji o ścieżce: {{message}}","Failed to import:":"Nie udało się zaimportować:","Failed to read backup defaults:":"Nie udało się odczytać domyślnych danych kopii:","Failed to restore files: {{message}}":"Nie udało się odtworzyć plików: {{message}}","Failed to save:":"Nie udało się zapisać:","Fetching path information ...":"Pobieranie informacji o ścieżce ...","File":"Plik","Files larger than:":"Pliki większe niż:","Filters":"Filtry","Finished!":"Zakończono!","First run setup":"Konfiguracja początkowa","Folder":"Katalog","Folder path":"Ścieżka katalogu","Fri":"Pt","GByte":"GBajt","GByte/s":"GBajt/s","GCS Project ID":"GCS Project ID","General":"Ogólne","General backup settings":"Ogólne ustawienia kopii","General options":"Opcje ogólne","Generate":"Generuj","Generate IAM access policy":"Wygeneruj politykę dostępu IAM","Getting file versions ...":"Pobieranie wersji plików ...","Hidden files":"Ukryte pliki","Hide":"Ukryj","Hide hidden folders":"Ukryj ukryte foldery","Home":"Domowa","Hours":"Godziny","How do you want to handle existing files?":"Jak chcesz potraktować istniejące pliki?","Hyper-V Machine":"Maszyna Hyper-V","Hyper-V Machine:":"Maszyna Hyper-V:","Hyper-V Machines":"Maszyny Hyper-V","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"Jeśli brak daty, zadanie zostanie uruchomione najwcześniej gdy to możliwe.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Jeśli kopia zapasowa i zdalny magazyn nie są zsynchronizowane, Duplicati będzie wymagać wykonania operacji naprawy aby zsynchronizować bazy danych. \\nJeśli naprawa się nie powiedzie, można usunąć lokalną bazę danych i ją ponownie wygenerować.","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Jeśli plik kopia zapasowa nie została pobrana automatycznie, <a href=\"{{DownloadURL}}\" target=\"_blank\"> kliknij prawym przyciskiem myszy i wybierz &quot;Zapisz jako ...&quot;</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Jeśli plik kopia zapasowa nie została pobrana automatycznie, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">kliknij prawym przyciskiem myszy i wybierz &quot;Zapisz jako ...&quot;</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Jeśli ścieżka nie zostanie wprowadzona, to wszystkie pliki będą przechowywane w katalogu logowania. Czy na pewno tak właśnie ma być?","If you do not enter an API Key, the tenant name is required":"Jeśli nie podasz Klucza API, nawa dzierżawcy jest wymagana","If you want to use the backup later, you can export the configuration before deleting it":"Jeśli chcesz użyć kopii później, możesz wyeksportować konfigurację przed jej usunięciem","If your machine is in a multi-user environment (i.e. the machine has more than one account), you need to set a password to prevent other users from accessing data on your account.\nDo you want to set a password now?":"Jeśli twoje urządzenie działa w środowisku wielodostępowym (np. w komputerze jest więcej niż jedno konto), musisz ustawić hasło, aby uniemożliwić innym użytkownikom dostęp do danych na swoim koncie.\nCzy chcesz teraz ustawić hasło?","Import":"Import","Import Destination URL":"Import Docelowego URL","Import backup configuration":"Importuj konfigurację kopii","Import completed, but no certificates were found after the import":"Import zakończony, ale nie znaleziono certyfikatów po imporcie","Import failed":"Nie udało się zaimportować","Import from a file":"Zaimportuj z pliku","Importing ...":"Importowanie ...","Include a file?":"Dołaczyć plik?","Include expression":"Dołącz wyrażenie","Include regular expression":"Dołącz wyrażenie regularne","Incorrect answer, try again":"Nieprawidłowa odpowiedź, spróbuj ponownie","Individual builds for developers only.":"Indywidualne kompilacje tylko dla developerów","Information":"Informacja","Install":"Instalacja","Install failed:":"Nie udało się zainstalować:","Invalid retention time":"Nieprawidłowy czas przechowywania","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"Do niektórych serwerów FTP można łączyć się bez hasła.\nCzy na pewno Twój serwer FTP obsługuje logowanie bez hasła?","KByte":"KBajty","KByte/s":"KBajty/s","Keep this number of backups":"Zachowaj tę ilość kopii zapasowych","Language in user interface":"Język w interfejsie użytkownika","Last month":"Ostatni miesiąc","Last successful run:":"Ostatnie prawidłowe wykonanie:","Latest":"Ostatni","Libraries":"Biblioteki","Listing backup dates ...":"Szukanie dat kopii ...","Listing remote files ...":"Szukanie plików zdalnych","Live":"Aktywne","Load a configuration from an exported job or a storage provider":"Wczytaj konfigurację z wyeksportowanego zadania lub magazynu","Load destination from an exported job or a storage provider":"Wczytaj miejsce docelowe z wyeksportowanego zadania lub magazynu","Load older data":"Załaduj starsze dane","Loading ...":"Ładowanie ...","Loading remote storage usage ...":"Ładowanie użycia magazynu zdalnego ...","Local database for":"Lokalna baza danych dla","Local database path:":"Ścieżka lokalnej bazy danych:","Local storage":"Magazyn lokalny","Location":"Położenie","Location where buckets are created":"Położenie, gdzie będą utworzone zasobniki","Log data for <b>{{Backup.Backup.Name}}</b>":"Loguj dane dla <b>{{Backup.Backup.Name}}</b>","Log data from the server":"Loguj dane z serwera","Log out":"Wyloguj","MByte":"MBajt","MByte/s":"MBajty/s","Maintenance":"Konserwacja","Manually type path":"Podaj ścieżkę ręcznie ","Max download speed":"Maksymalna szybkość pobierania","Max upload speed":"Maksymalna szybkość wysyłania","Menu":"Menu","Microsoft SQL Database:":"Baza danych Microsoft SQL:","Microsoft SQL Databases":"Bazy danych Microsoft SQL:","Minutes":"Minuty","Missing name":"Brak nazwy","Missing passphrase":"Brak długiego hasła","Missing sources":"Brak źródła","Mon":"Pn","Months":"Miesiące","Move existing database":"Przenieś istniejącą bazę danych","Move failed:":"Nie udało się przenieść:","My Documents":"Moje Dokumenty","My Music":"Moja Muzyka","My Photos":"Moje Zdjęcia","My Pictures":"Moje Obrazy","Name":"Nazwa","Never":"Nigdy","New update found: {{message}}":"Znaleziono nowe uaktualnienie: {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"Nowa nazwa użytkownika to {{user}}.\nUaktualniono uwierzytelnienia dla użytkownika o ograniczonym dostępie","Next":"Następny","Next scheduled run:":"Następne zaplanowane uruchomienie:","Next scheduled task:":"Następne zaplanowane zadanie:","Next task:":"Następne zadanie","Next time":"Następny raz","No":"Nie","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"Certyfikat nie został wcześniej określony, należy sprawdzić u administratora serwera czy klucz jest poprawny: {{key}} \n\nCzy akceptujesz podany klucz?","No editor found for the &quot;{{backend}}&quot; storage type":"Nie znaleziono edytora dla magazynu typu &quot;{{backend}}&quot;","No encryption":"Bez szyfrowania","No items selected":"Nie wybrano pozycji","No items to restore, please select one or more items":"Brak pozycji do odtworzenia, proszę wybrać jedną lub więcej pozycji.","No passphrase entered":"Nie wprowadzono długiego hasła","No scheduled tasks":"Brak zaplanowanych zadań","No, my machine has only a single account":"Nie, moje urządzenie ma tylko jedno konto","Non-matching passphrase":"Niepasujące długie hasła","None / disabled":"Żaden / wyłączone","OK":"OK","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Nie udało się wykonać operacji:","Operations:":"Operacje:","Optional authentication password":"Opcjonalne hasło uwierzytelnienia","Optional authentication username":"Opcjonalny użytkownik uwierzytelnienia","Options":"Opcje","Options added here are applied to all backups, but can be overridden in each individual backup":"Opcje dodane tutaj stosowane są do wszystkich kopii zapasowych, ale można je zmodyfikować w każdej indywidualnej kopii zapasowej","Original location":"Położenie oryginalne","Others":"Inne","Overwrite":"Nadpisz","Passphrase":"Długie hasło","Passphrase (if encrypted)":"Długie hasło (jeśli zaszyfrowane)","Passphrase changed":"Zmieniono długie hasło","Passphrases are not matching":"Długie hasła różnią się od siebie","Password":"Hasło","Passwords do not match":"Hasła różnią się od siebie","Patching files with local blocks ...":"Uzupełnianie plików z bloków lokalnych ...","Path not found":"Ścieżka nie znaleziona","Path on server":"Ścieżka na serwerze","Path or subfolder in the bucket":"Ścieżka lub podkatalog w zasobniku","Pause":"Wstrzymaj","Pause after startup or hibernation":"Wstrzymaj po uruchomieniu lub hibernacji","Pause options":"Opcje wstrzymania","Permissions":"Uprawnienia","Pick location":"Wybierz położenie","Point to your backup files and restore from there":"Wskaż pliki kopii zapasowej i odtwórz z nich","Port":"Port","Previous":"Poprzedni","ProjectID is optional if the bucket exist":"ProjectID jest opcjonalne jeśli zasobnik istnieje","Proprietary":"Własny","Purging files ...":"Czyszczenie plików ...","Rebuilding local database ...":"Przebudowywanie lokalnej bazy danych ...","Recreate (delete and repair)":"Odtworzenie (usunięcie i naprawienie)","Recreating database ...":"Odtwarzanie bazy danych ...","Registering temporary backup ...":"Rejestrowanie tymczasowej kopii ...","Relative paths not allowed":"Ścieżki względne nie są dopuszczalne","Reload":"Przeładuj","Remote":"Zdalny","Remove":"Usuń","Remove option":"Usuń opcję","Repair":"Napraw","Reparing ...":"Naprawianie ...","Repeat Passphrase":"Powtórz długie hasło","Reporting:":"Raportowanie:","Reset":"Resetuj","Restore":"Odtwórz","Restore files":"Odtwórz pliki","Restore files ...":"Odtwórz pliki ...","Restore files from {{backupname}}":"Odtwórz pliki z {{backupname}}","Restore from":"Odtwórz z","Restore from backup configuration":"Odtwórz z konfiguracji kopii","Restore from configuration ...":"Odtwórz z konfiguracji ...","Restore options":"Opcje odtwarzania","Restore read/write permissions":"Odtwórz uprawnienia odczytu/zapisu","Restoring files ...":"Odtwarzanie plików","Resume":"Wznów","Run again every":"Uruchom ponownie co","Run now":"Uruchom teraz","Running ...":"Uruchamianie ...","Running ....":"Uruchamianie ...","Running commandline entry":"Uruchamianie komend z linii poleceń","Running task:":"Uruchamianie zadania:","S3 Compatible":"Kompatybilny z S3","Same as the base install version: {{channelname}}":"Zgodny z bazową wersją instalacji: {{channelname}}","Sat":"So","Save":"Zapisz","Save and repair":"Zapisz i napraw","Save different versions with timestamp in file name":"Zapisz różne wersje z sygnaturą czasową w nazwie","Save immediately":"Zapisz niezwłocznie","Scanning existing files ...":"Przeglądanie istniejących plików ...","Scanning for local blocks ...":"Szukanie lokalnych bloków","Schedule":"Harmonogram","Search":"Szukaj","Search for files":"Szukaj plików","Seconds":"Sekundy","Select a log level and see messages as they happen:":"Wybierz zakres dziennika i zobacz co się wydarzyło:","Select files":"Wybierz pliki","Server":"Serwer","Server and port":"Serwer and port","Server hostname or IP":"Nazwa serwera lub IP","Server is currently paused,":"Serwer jest obecnie wstrzymany,","Server is currently paused, do you want to resume now?":"Serwer jest obecnie wstrzymany, czy chcesz teraz wznowić jego pracę?","Server paused":"Serwer wstrzymany","Server state properties":"Właściwości stanu serwera","Settings":"Ustawienia","Show":"Pokaż","Show advanced editor":"Pokaż edytor zaawansowany","Show hidden folders":"Pokaż ukryte foldery","Show log":"Pokaż dziennik","Show log ...":"Pokaż dziennik ...","Show treeview":"Pokaż drzewo widoku","Some OpenStack providers allow an API key instead of a password and tenant name":"Niektórzy dostawcy OpenStack dopuszczają klucz API zamiast hasła i nazwy najemcy","Source Data":"Dane Źródłowe","Source data":"Dane źródłowe","Source folders":"Foldery źródłowe","Source:":"Źródło:","Specific builds for developers only.":"Specjalne kompilacje tylko dla developerów","Standard protocols":"Protokoły standardowe","Starting ...":"Uruchamianie ...","Starting the restore process ...":"Uruchamianie procesu odtwarzania ...","Stop after the current file":"Zatrzymaj po bieżącym pliku","Stop after upload":"Zatrzymaj po przesłaniu pliku","Stop now":"Zatrzymaj teraz","Stop running backup":"Zatrzymaj wykonywaną kopię","Stop running task":"Zatrzymaj wykonywane zadanie","Stopping after upload:":"Zatrzymaj po przesłaniu:","Stopping task:":"Zatrzymywanie zadania:","Storage Type":"Typ Magazynu","Storage class":"Klasa magazynu","Storage class for creating a bucket":"Klasa magazynu dla utworzenia zasobnika","Stored":"Zachowane","Strong":"Silne","Success":"Powodzenie","Sun":"Nie","Symbolic link":"Link symboliczny","System default ({{levelname}})":"System domyślny ({{levelname}})","System files":"Pliki systemowe","System info":"Informacja systemowa","System properties":"Właściwości systemowe","TByte":"TBajty","TByte/s":"TBajty/s","Task is running":"Zadanie jest wykonywane","Temporary files":"Pliki tymczasowe","Tenant Name":"Nazwa Dzierżawcy","Test connection":"Sprawdź połączenie","Testing ...":"Sprawdzanie ...","Testing connection ...":"Sprawdzanie połączenia ...","Testing permissions ...":"Sprawdzanie uprawnień ...","Testing permissions...":"Sprawdzanie uprawnień ...","The bucket name should be all lower-case, convert automatically?":"Nazwa zasobnika powinna być pisana wersalikami, zmienić automatycznie ?","The bucket name should start with your username, prepend automatically?":"Nazwa zasobnika powinna zaczynać się od nazwy użytkownika, dodać automatycznie ?","The connection to the server is lost, attempting again in {{time}} ...":"Utracono połączenie z serwerem, ponowna próba za {{time}} ...","The dark theme (by Michal)":"Ciemny schemat (wyk. Michal)","The default blue on white theme (by Alex)":"Domyślny schemat niebieski na białym (wyk. Alex)","The folder {{folder}} does not exist\nCreate it now?":"Certyfikat zaufanego hosta?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"Klucz komputera został zmieniony, proszę sprawdzić z administratorem serwera czy jest to poprawne, w przeciwnym razie możesz zostać ofiarą ataku typu MAN-IN--MIDDLE.\n\nCzy chcesz ZASTĄPIĆ twój BIEŻĄCY klucz komputera \"{{prev}}\" na PODANY klucz: {{klucz}}?","The path does not appear to exist, do you want to add it anyway?":"Wygląda, że ścieżka nie istnieje, czy mimo to chcesz ją dodać?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"Ścieżka nie kończy się znakiem \"{{dirsep}}\", co oznacza, że dołączasz plik, a nie folder.\n\nCzy chcesz dołączyć określony plik?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"Ścieżka musi być ścieżką bezwzględną, tzn. musi rozpoczynać się prawym ukośnikiem '/'","The path should start with \"{{prefix1}}\" or \"{{prefix2}}\", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?":"Ścieżka powinna zaczynać się od \"{{prefix1}}\" lub \"{{prefix2}}\", w przeciwnym razie nie będzie widać plików w interfejsie internetowym HubiC.\n\nCzy chcesz dodać prefiks do ścieżki automatycznie?","The region parameter is only applied when creating a new bucket":"Parametr regionu jest stosowany tylko podczas tworzenia nowego zasobnika","The region parameter is only used when creating a bucket":"Parametr regionu jest używany tylko podczas tworzenia zasobnika","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"Certyfikat serwera nie może być zweryfikowany.\nCzy aprobujesz certyfikat SSL z sygnaturą: {{hash}}?","The storage class affects the availability and price for a stored file":"Klasa magazynu danych ma wpływ na dostępność i cenę za przechowywany plik","The target folder contains encrypted files, please supply the passphrase":"Docelowy folder zawiera zaszyfrowane pliki, proszę podać długie hasło","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"Użytkownik ma za duże uprawnienia. Czy chcesz stworzyć nowego użytkownika z uprawnieniami ograniczonymi do wybranej ścieżki?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"Ta kopia zapasowa została utworzona na innym systemie operacyjnym. Odzyskiwanie plików bez określania folderu docelowego może spowodować, że pliki zostaną przywrócone w nieoczekiwanych miejscach. Czy na pewno chcesz kontynuować bez wyboru folderu docelowego?","This month":"Bieżący miesiąc","This week":"Bieżący tydzień","Throttle settings":"Limity prędkości","Thu":"Czw","To File":"Do Pliku","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"Aby potwierdzić, że chcesz skasować wszystkie zdalne pliki dla \"{{name}}\", proszę wprowadzić słowo zamieszczone poniżej","To export without a passphrase, uncheck the \"Encrypt file\" box":"Aby wyeksportować bez hasła, odznacz pole \"Szyfruj plik\"","Today":"Dzisiaj","Trust host certificate?":"Certyfikat zaufanego hosta?","Trust server certificate?":"Certyfikat zaufanego serwera?","Try out the new features we are working on. Don't use with important data.":"Wypróbuj nowe funkcjonalności nad którymi pracujemy. Nie używaj z ważnymi danymi.","Tue":"Wt","Type to highlight files":"Napisz by podświetlić pliki","Unknown backup size and versions":"Nieznany rozmiar kopii i wersje","Until resumed":"Do wznowienia","Update channel":"Kanał uaktualnień","Update failed:":"Nie udało się uaktualnić","Updating with existing database":"Uaktualnij z istniejącą bazą danych","Upload volume size":"Rozmiar przesłanych danych","Uploading verification file ...":"Przesyłanie pliku weryfikującego ...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"Raporty użytkowania pomagają nam poprawić wrażenia użytkownika i ocenić wpływ nowych funkcji. Używamy ich do generowania <a href=\"{{link}}\" target=\"_blank\"> publicznych statystyk użytkowania</a>","Usage statistics":"Statystyki użycia","Usage statistics, warnings, errors, and crashes":"Statystyki użycia , ostrzeżenia, błędy i awarie","Use SSL":"Użyj SSL","Use existing database?":"Użyj istniejącej bazy danych","Use weak passphrase":"Użyj słabego długiego hasła","Useless":"Bezużyteczne","User data":"Dane użytkownika","User has too many permissions":"Użytkownik ma za duże uprawnienia","User interface settings":"Ustawienia interfejsu użytkownika","Username":"Nazwa użytkownika","VISA, Mastercard, ... via Paypal":"VISA, Mastercard, ... przez Paypal","Validating ...":"Potwierdzanie ...","Verify files":"Sprawdź pliki","Verifying ...":"Weryfikowanie ...","Verifying answer":"Weryfikacja odpowiedzi","Verifying backend data ...":"Weryfikowanie danych silnika ...","Verifying remote data ...":"Weryfikacja zdalnych danych ...","Verifying restored files ...":"Weryfikacja odtworzonych plików ...","Very strong":"Bardzo silne","Very weak":"Bardzo słabe","Visit us on":"Odwiedź nas na","WARNING: The remote database is found to be in use by the commandline library":"UWAGA: Wykryto, że zdalna baza danych jest używana przez bibliotekę wiersza poleceń.","WARNING: This will prevent you from restoring the data in the future.":"UWAGA: To uniemożliwi odtworzenie danych w przyszłości.","Waiting for task to begin":"Oczekiwanie na rozpoczęcie zadania","Waiting for task to start ....":"Oczekiwanie na uruchomienie zadania ...","Waiting for upload ...":"Oczekiwanie na przesłanie ...","Warnings, errors and crashes":"Ostrzeżenia, błędy i awarie","We recommend that you encrypt all backups stored outside your system":"Zalecamy szyfrowanie wszystkich kopii przechowywanych poza twoim systemem","Weak":"Słabe","Weak passphrase":"Słabe długie hasło","Wed":"Śr","Weeks":"Tygodnie","Where do you want to restore from?":"Gdzie chcesz odtworzyć?","Where do you want to restore the files to?":"Gdzie chcesz odtworzyć pliki?","Years":"Lata","Yes":"Tak","Yes, I have stored the passphrase safely":"Tak, długie hasło zostało bezpiecznie zachowane.","Yes, I'm brave!":"Tak. Jestem dzielny!","Yes, please break my backup!":"Tak, proszę zepsuj moją kopię!","Yesterday":"Wczoraj","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"Wygląda na to, że uruchamiasz Mono bez załadowanego certyfikatu SSL.\nCzy chcesz zaimportować listę zaufanych certyfikatów z Mozilli?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"Zmieniłeś ścieżkę na nie prowadzącą do istniejącej bazy danych.\nCzy jesteś pewny, że takie było twoje rzeczywiste zamierzenie?","You are currently running {{appname}} {{version}}":"Aktualnie używasz {{appname}} {{version}}","You can stop the backup immediately, or stop after the current file has been uploaded.":"Możesz natychmiast przerwać tworzenie kopii zapasowej lub przerwać po przesłaniu bieżącego pliku.","You can stop the task immediately, or allow the process to continue its current file and the stop.":"Możesz natychmiast przerwać wykonywane zadanie lub przerwać po zakończeniu bieżącego pliku. ","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"Zmieniłeś tryb szyfrowania. Może to spowodować uszkodzenie zawartości. Zamiast tego zachęcamy do utworzenia nowej kopii zapasowej.","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"Zmieniono hasło - zmiana hasła nie jest obsługiwana. Zachęcamy Cię zamiast tego do utworzenia nowej kopii zapasowej.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"Wybrałeś opcję nieszyfrowania kopii zapasowej. Szyfrowanie jest zalecane dla wszystkich danych przechowywanych na serwerze zdalnym.","You have chosen to restore to a new location, but not entered one":"Możesz wybrać odtworzenie do nowej lokalizacji, ale nie tej wprowadzonej","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"Wygenerowano silne hasło. Upewnij się, że masz bezpieczną kopię tego hasła, bo danych nie będzie można odzyskać, jeśli utracisz hasło.","You must choose at least one source folder":"Musisz wybrać co najmniej jeden folder źródłowy","You must enter a name for the backup":"Musisz podać nazwę kopii zapasowej","You must enter a passphrase or disable encryption":"Musisz podać długie hasło lub wyłączyć szyfrowanie","You must enter a positive number of backups to keep":"Musisz podać dodatnią liczbę kopii do zachowania","You must enter a tenant name if you do not provide an API Key":"Musisz podać nazwę dzierżawcy jeśli nie podano Klucza API","You must enter a valid duration for the time to keep backups":"Musisz podać prawidłowy okres przechowywania kopii zapasowych","You must enter either a password or an API Key":"Musisz podać hasło lub Klucz API ","You must enter either a password or an API Key, not both":"Musisz podać jedno z dwóch hasło lub Klucz API, ale nie oba","You must fill in the password":"Musisz wypełnić pole hasło","You must fill in the server name or address":"Musisz wypełnić pole nazwa serwera lub adres","You must fill in the username":"Musisz wypełnić pole użytkownik","You must fill in {{field}}":"Musisz wypełnić pole {{field}}","You must select or fill in the AuthURI":"Musisz wybrać lub wypełnić pole AuthURI","You must select or fill in the server":"Musisz wybrać lub wypełnić pole serwer","You must specify a path":"Musisz podać ścieżkę","Your files and folders have been restored successfully.":"Twoje pliki i foldery zostały pomyślnie odtworzone.","Your passphrase is easy to guess. Consider changing passphrase.":"Twoje długie hasło jest łatwe do odgadnięcia. Rozważ zmianę długiego hasła.","a specific number":"określoną liczbę","bucket/folder/subfolder":"zasobnik/folder/podfolder","byte":"bajtów","byte/s":"bajtów/s","custom":"dostosowany","resume now":"wznów teraz","unlimited":"bez ograniczeń","until they are older than":"dopóki nie są starsze niż","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} zostało opracowane głównie przez <a href=\"{{mail1}}\">{{dev1}}</a> i <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} można pobrać z <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} podlega licencji <a href=\"{{licenselink}}\">{{licensename}}</a>.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":["{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Wersja","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Wersji","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Wersji","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Wersji"],"{{number}} Hour":"{{number}} Godzin","{{number}} Minutes":"{{number}} Minut","{{time}} (took {{duration}})":"{{time}} (trwało {{duration}})"});
+ gettextCatalog.setStrings('ru', {"- pick an option -":"- выберите параметр -","...loading...":"...загрузка...","API Key":"Ключ API","AWS Access ID":"AWS Access ID","AWS Access Key":"AWS Access Key","AWS IAM Policy":"AWS IAM Policy","About":"О программе","About {{appname}}":"О {{appname}}","Access Key":"Ключ доступа","Access denied":"Доступ запрещен","Access to user interface":"Доступ в пользовательский интерфейс","Account name":"Имя учётной записи","Activate":"Активировать","Activate failed:":"Активация не удалась:","Add a new backup":"Создать новую резервную копию","Add a path directly":"Добавить путь непосредственно","Add advanced option":"Добавить расширенный параметр","Add backup":"Добавить резервную копию","Add filter":"Добавить фильтр","Add path":"Добавить путь","Adjust bucket name?":"Изменить имя блока?","Adjust path name?":"Изменить имя пути?","Advanced Options":"Расширенные параметры","Advanced options":"Расширенные параметры","Advanced:":"Дополнительно:","All Hyper-V Machines":"Все виртуальные машины Hyper-V","All Microsoft SQL Databases":"Все базы данных Microsoft SQL","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"Все отчеты об использовании отправляются анонимно и не содержат каких-либо персональных данных. Они содержат информацию об аппаратной конфигурации и операционной системе, тип бэкэнда, продолжительность резервного копирования, общий размер исходных данных и подобные данные. Они не содержат пути, имена файлов, имена пользователей, пароли или любую другую конфиденциальную информацию.","Allow remote access (requires restart)":"Разрешить удалённый доступ (потребуется перезапуск)","Allowed days":"Разрешенные дни","An existing file was found at the new location":"Существующий файл был найден по новому пути","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"Существующий файл был найден по новому пути\nВы точно хотите, чтобы база данных указывала на существующий файл?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"Была обнаружена локальная база данных для хранилища.\nПовторное использование базы данных позволит экземплярам командной строки и сервера работать на одном и том же удаленном хранилище.\n\n Вы хотите использовать существующую базу данных?","Anonymous usage reports":"Анонимные отчёты об использовании","As Command-line":"Как командная строка","AuthID":"AuthID","Authentication password":"Пароль для аутентификации","Authentication username":"Имя пользователя для аутентификации","Autogenerated passphrase":"Сгенерированный пароль","Automatically run backups.":"Запускать резервное копирование автоматически","B2 Account ID":"B2 Account ID","B2 Application Key":"B2 Application Key","B2 Cloud Storage Account ID":"B2 Cloud Storage Account ID","B2 Cloud Storage Application Key":"B2 Cloud Storage Application Key","Back":"Назад","Backend modules:":"Модули бэкенда:","Backup destination":"Хранение резервной копии","Backup location":"Расположение резервной копии","Backup:":"Резервная копия:","Beta":"Beta","Bitcoin: {{bitcoinaddr}}":"Bitcoin: {{bitcoinaddr}}","Broken access":"Битый доступ","Browse":"Обзор","Browser default":"Браузер по-умолчанию","Bucket Name":"Имя блока","Bucket create location":"Место создания блока","Bucket create region":"Регион создания блока","Bucket name":"Имя блока","Bucket storage class":"Класс хранения блока","Building list of files to restore ...":"Создание списка файлов для восстановления ...","Building partial temporary database ...":"Создание частичной временной базы данных ...","Busy ...":"Занят ...","Canary":"Canary","Cancel":"Отмена","Cannot move to existing file":"Не могу переместить в существующий файл","Changelog":"История изменений","Changelog for {{appname}} {{version}}":"Список изменений для {{appname}} {{version}}","Check failed:":"Проверка не удалась:","Check for updates now":"Проверить наличие обновлений","Checking ...":"Проверка","Checking for updates ...":"Проверка обновлений ...","Chose a storage type to get started":"Для начала выберите тип хранилища","Click the AuthID link to create an AuthID":"Нажмите на ссылку AuthID для создания AuthID","Commandline ...":"Командная строка...","Compact now":"Уплотнить сейчас","Compacting remote data ...":"Уплотнение удаленных данных ...","Completing backup ...":"Завершение резервного копирования ...","Completing previous backup ...":"Завершение предыдущего резервного копирования ...","Compression modules:":"Модули сжатия:","Computer":"Компьютер","Configuration file:":"Файл конфигурации:","Configuration:":"Настройка:","Configure a new backup":"Настройка новой резервной копии","Confirm delete":"Подтвердите удаление","Confirmation required":"Необходимо подтверждение","Connect":"Подключение","Connect now":"Подключиться сейчас","Connecting to server ...":"Подключение к серверу ...","Connecting to task ....":"Подключение к задаче...","Connecting...":"Подключение...","Connection lost":"Потеряно соединение","Connection worked!":"Подключение работает!","Container name":"Имя контейнера","Container region":"Регион контейнера","Continue":"Продолжить","Continue without encryption":"Продолжить без шифрования","Copied!":"Скопировано!","Copy Destination URL to Clipboard":"Скопировать URL-адрес назначения в буфер обмена","Copy failed. Please manually copy the URL":"Копирование не удалось. Скопируйте URL-адрес вручную","Core options":"Основные параметры","Counting ({{files}} files found, {{size}})":"Подсчёт ({{files}} файлов найдено, {{size}})","Crashes only":"Только падения","Create bug report ...":"Создать отчет об ошибке...","Create folder?":"Создать папку?","Created new limited user":"Создан новый ограниченный пользователь","Creating bug report ...":"Создание отчета об ошибке...","Creating new user with limited access ...":"Создание нового пользователя с ограниченным доступом...","Creating target folders ...":"Создание целевых папок...","Creating temporary backup ...":"Создание временной резервной копии...","Creating user...":"Создание пользователя...","Current version is {{versionname}} ({{versionnumber}})":"Текущая версия — {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"Пользовательский S3 endpoint","Custom authentication url":"Пользовательский URL-адрес аутентификации","Custom location ({{server}})":"Пользовательское местоположение ({{server}})","Custom region for creating buckets":"Пользовательский регион для создания buckets","Custom region value ({{region}})":"Пользовательское значение региона ({{region}})","Custom server url ({{server}})":"Пользовательский URL-адрес сервера ({{server}})","Custom storage class ({{class}})":"Пользовательский класс хранения ({{class}})","Database ...":"База данных...","Days":"Дней","Default":"По умолчанию","Default ({{channelname}})":"По умолчанию ({{channelname}})","Default options":"Параметры по умолчанию","Delete":"Удалить","Delete ...":"Удалить...","Delete backup":"Удалить резервную копию","Delete local database":"Удалить локальную базу данных","Delete remote files":"Удалить удаленные файлы","Delete the local database":"Удалить локальную базу данных","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"Удалить {{filecount}} файлов ({{filesize}}) из удаленного хранилища?","Deleting remote files ...":"Удаление удаленных файлов...","Deleting unwanted files ...":"Удаление нежелательных файлов ...","Desktop":"Рабочий стол","Destination":"Хранение","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"Мы помогли спасти ваши файлы? Если да, пожалуйста, подумайте о поддержке Duplicati пожертвованием. Мы предлагаем {{smallamount}} за частное использование и {{largeamount}} за коммерческое использование.","Direct restore from backup files ...":"Прямое восстановление из резервной копии...","Disabled":"Отключено","Dismiss":"Скрыть","Display and color theme":"Отображение и цветовая тема","Do you really want to delete the backup: \"{{name}}\" ?":"Вы действительно хотите удалить резервную копию: «{{name}}» ?","Do you really want to delete the local database for: {{name}}":"Вы действительно хотите удалить локальную базу данных для: {{name}}","Donate":"Пожертвовать","Donate with Bitcoins":"Пожертвовать через Bitcoin","Donate with PayPal":"Пожертвовать через PayPal","Donation messages":"Напоминания о пожертвовании","Donation messages are hidden, click to show":"Напоминания о пожертвовании отключены, нажмите, чтобы показывать","Donation messages are visible, click to hide":"Напоминания о пожертвовании включены, нажмите, чтобы скрыть","Done":"Готово","Download":"Скачать","Downloading ...":"Загрузка ...","Downloading files ...":"Загрузка файлов ...","Downloading update...":"Загрузка обновления...","Duplicate option {{opt}}":"Дублировать параметр {{opt}}","Duplicati Website":"Сайт Duplicati ","Duplicati forum":"Форум Duplicati","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\n When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.\n If you are using the local database for backups from the commandline, you should keep the database.":"Для каждой резервной копии существует связанная с ней локальная база данных, которая хранит на локальной машине информацию об удаленной резервной копии.\nПри удалении резервной копии вы можете также удалить и локальную базу данных, никак не влияя на возможность восстановления удалённых файлов.\nЕсли вы используете локальную базу данных для резервного копирования из командной строки, то вы должны сохранить базу данных.","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Каждая резервная копия имеет локальную базу данных, связанную с ним, со сведениями об удаленной резервной копировании на местном компьютере. \\nЭто позволяет быстрее выполнять множество операций и уменьшает объем данных, который необходимо загрузить для каждой операции.","Edit ...":"Изменить...","Edit as list":"Редактировать как список","Edit as text":"Редактировать как текст","Encrypt file":"Шифровать файл","Encryption":"Шифрование","Encryption changed":"Шифрование изменено","Encryption modules:":"Модули шифрования:","Enter URL":"Введите URL-адрес","Enter access key":"Введите ключ доступа","Enter account name":"Введите имя учетной записи","Enter backup passphrase, if any":"Введите пароль резервной копии, если таковой имеется","Enter configuration details":"Ввод сведений конфигурации","Enter container name":"Введите имя контейнера","Enter encryption passphrase":"Введите пароль шифрования","Enter expression here":"Введите выражение здесь","Enter folder path name":"Введите путь папки","Enter one option per line in command-line format, eg. {0}":"Введите по одному параметру в строке в формате командной строки, например {0}","Enter the destination path":"Введите путь назначения","Error":"Ошибка","Error!":"Ошибка!","Errors and crashes":"Ошибки и падения","Exclude":"Исключить","Exclude directories whose names contain":"Исключить каталоги, имена которых содержат","Exclude expression":"Выражение для исключения","Exclude file":"Исключить файл","Exclude file extension":"Исключить файловое расширение","Exclude files whose names contain":"Исключить файлы, имена которых содержат","Exclude folder":"Исключить папку","Exclude regular expression":"Регулярное выражение для исключения","Existing file found":"Найден существующий файл","Experimental":"Experimental","Export":"Экспорт","Export ...":"Экспортировать...","Export backup configuration":"Экспорт конфигурации резервного копирования","Export configuration":"Экспорт конфигурации","Exporting ...":"Экспортирование ...","FTP (Alternative)":"FTP (Альтернативный)","Failed to build temporary database: {{message}}":"Не удалось построить временную базу данных: {{message}}","Failed to connect:":"Не удается подключиться:","Failed to connect: {{message}}":"Не удается подключиться: {{message}}","Failed to delete:":"Не удалось удалить:","Failed to fetch path information: {{message}}":"Не удалось получить сведения о пути: {{message}}","Failed to import:":"Не удалось импортировать:","Failed to read backup defaults:":"Не удалось прочитать настройки по умолчанию для резервной копии:","Failed to restore files: {{message}}":"Не удалось восстановить файлы: {{message}}","Failed to save:":"Не удалось сохранить:","Fetching path information ...":"Получение сведений о пути ...","File":"Файл","Files larger than:":"Файлы размером более:","Filters":"Фильтры","Finished!":"Готово!","First run setup":"Настройка при первом запуске","Folder":"Папка","Folder path":"Путь к папке","Fri":"Пт","GByte":"ГБ","GByte/s":"ГБ/сек","GCS Project ID":"GCS Project ID","General":"Общие","General backup settings":"Общие параметры резервного копирования","General options":"Основные параметры","Generate":"Сгенерировать","Generate IAM access policy":"Сгенерировать политики доступа IAM","Getting file versions ...":"Получение версий файлов ...","Hidden files":"Скрытые файлы","Hide":"Скрыть","Hide hidden folders":"Скрыть скрытые папки","Home":"Главная","Hours":"часов","How do you want to handle existing files?":"Как вы хотите обрабатывать существующие файлы?","Hyper-V Machine":"Hyper-V Машина","Hyper-V Machine:":"Hyper-V Машина:","Hyper-V Machines":"Hyper-V Машины","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"Если дата была пропущена, задание будет выполнено как можно скорее.","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"Если резервное копирование и внешнее хранилище не синхронизированы, Duplicati потребует выполнения операции исправления для синхронизации базы данных. \\nЕсли исправление не удастся, вы можете удалить локальную базу данных для повторного создания.","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Если файл резервной копии не загружаются автоматически, <a href=\"{{DownloadURL}}\" target=\"_blank\"> нажмите правой кнопкой мыши и выберите &quot;Сохранить как ...&quot;</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"Если файл резервной копии не загрузится автоматически, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">нажмите правой кнопкой мыши и выберите &quot;Сохранить как ...&quot;</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"Если вы не введете путь, все файлы будут храниться в папке логина.\nВы уверены, что это то, что вы хотите?","If you do not enter an API Key, the tenant name is required":"Если вы не вводите ключ API, требуется имя арендатора","If you want to use the backup later, you can export the configuration before deleting it":"Если вы хотите использовать резервное копирование позже, вы можете экспортировать конфигурацию перед ее удалением","If your machine is in a multi-user environment (i.e. the machine has more than one account), you need to set a password to prevent other users from accessing data on your account.\nDo you want to set a password now?":"Если ваш компьютер находится в многопользовательской среде (например, на компьютере имеется несколько учетных записей), вам необходимо установить пароль, чтобы другие пользователи не могли получать доступ к данным вашей учетной записи.\nВы хотите установить пароль сейчас?","Import":"Импорт","Import Destination URL":"Импортировать URL-адрес назначения","Import backup configuration":"Импорт настройки резервной копии","Import completed, but no certificates were found after the import":"Импорт завершен, но после импорта не были найдены сертификаты","Import failed":"Ошибка импорта","Import from a file":"Импортировать из файла","Importing ...":"Импортирование ...","Include a file?":"Включить файл?","Include expression":"Выражение для включения","Include regular expression":"Регулярное выражение для включения","Incorrect answer, try again":"Неправильный ответ, попробуйте еще раз","Individual builds for developers only.":"Индивидуальные сборки только для разработчиков.","Information":"Информация","Install":"Установить","Install failed:":"Установка не удалась:","Invalid retention time":"Недопустимое время хранения","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"К некоторым FTP возможно подключиться без пароля.\nВы уверены, что ваш FTP-сервер поддерживает вход без пароля?","KByte":"КБайт","KByte/s":"КБ/сек","Keep this number of backups":"Хранить данное количество резервных копий","Language in user interface":"Язык пользовательского интерфейса","Last month":"Последний месяц","Last successful run:":"Последний успешный запуск:","Latest":"Последнее","Libraries":"Библиотеки","Listing backup dates ...":"Список дат резервного копирования ...","Listing remote files ...":"Список удаленных файлов...","Live":"Текущие","Load a configuration from an exported job or a storage provider":"Загрузить настройки из экспортированного задания или поставщика хранилища","Load destination from an exported job or a storage provider":"Загрузить назначение из экспортированного задания или поставщика хранилища","Load older data":"Загрузить старые данные","Loading ...":"Загрузка ...","Loading remote storage usage ...":"Загрузка использования удаленного хранилища ...","Local database for":"Локальная база данных для","Local database path:":"Путь локальной базы данных:","Local storage":"Локальное хранилище","Location":"Местоположение","Location where buckets are created":"Место где создаются buckets","Log data for <b>{{Backup.Backup.Name}}</b>":"Данные журнала для <b>{{Backup.Backup.Name}}</b>","Log data from the server":"Сообщения журнала сервера","Log out":"Выход","MByte":"Мбайт","MByte/s":"Мбайт/с","Maintenance":"Техническое обслуживание","Manually type path":"Ввести путь вручную","Max download speed":"Максимальная скорость загрузки","Max upload speed":"Максимальная скорость выгрузки","Menu":"Меню","Microsoft SQL Database:":"База данных Microsoft SQL:","Microsoft SQL Databases":"Баз данных Microsoft SQL","Minutes":"минут","Missing name":"Отсутствует имя","Missing passphrase":"Отсутствующие парольная фраза","Missing sources":"Отсутствуют источники","Mon":"Пн","Months":"Месяцев","Move existing database":"Перемещение существующей базы данных","Move failed:":"Перемещение не удалось:","My Documents":"Мои документы","My Music":"Моя музыка","My Photos":"Мои фотографии","My Pictures":"Мои Картинки","Name":"Имя","Never":"Никогда","New update found: {{message}}":"Найдено новое обновление: {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"Новое имя пользователя — {{user}}.\nОбновлены учетные данные для использования нового пользователя с ограниченными правами","Next":"Далее","Next scheduled run:":"Следующий запланированный запуск:","Next scheduled task:":"Следующее запланированное задание:","Next task:":"Следующая задача:","Next time":"В следующий раз","No":"Нет","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"Сертификат не был указан ранее, пожалуйста проверьте с администратором сервера ключ: {{key}} \n\nВы хотите утвердить полученный ключ сервера?","No editor found for the &quot;{{backend}}&quot; storage type":"Не найден редактор для хранилища типа &quot;{{backend}}&quot;","No encryption":"Без шифрования","No items selected":"Элементы не выбраны","No items to restore, please select one or more items":"Нет элементов для восстановления, выберите один или несколько элементов","No passphrase entered":"Не введена кодовая фраза","No scheduled tasks":"Нет запланированных задач","No, my machine has only a single account":"Нет, мой компьютер имеет единственную учётную запись","Non-matching passphrase":"Кодовые фразы не совпадают","None / disabled":"Нет / отключено","OK":"OK","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"Операция не удалась:","Operations:":"Операции:","Optional authentication password":"Необязательный пароль аутентификации","Optional authentication username":"Необязательное имя пользователя","Options":"Параметры","Options added here are applied to all backups, but can be overridden in each individual backup":"Опции, добавленные здесь применяются ко всем резервным копиям, но могут быть переопределены для каждой резервной копии индивидуально","Original location":"Исходное местоположение","Others":"Другие","Overwrite":"Перезаписать","Passphrase":"Кодовая фраза","Passphrase (if encrypted)":"Кодовая фраза (если зашифрован)","Passphrase changed":"Кодовая фраза изменена","Passphrases are not matching":"Кодовые фразы не совпадают","Password":"Пароль","Passwords do not match":"Пароли не совпадают","Patching files with local blocks ...":"Исправление файлов локальными блоками ...","Path not found":"Путь не найден","Path on server":"Путь на сервере","Path or subfolder in the bucket":"Путь или подпапка в bucket","Pause":"Пауза","Pause after startup or hibernation":"Пауза после запуска или спящего режима","Pause options":"Параметры паузы","Permissions":"Разрешения","Pick location":"Выберете местоположение","Point to your backup files and restore from there":"Укажите вашу резервную копию и восстановите данные из неё","Port":"Порт","Previous":"Назад","ProjectID is optional if the bucket exist":"ProjectID необязателен, если существует bucket","Proprietary":"Проприетарное","Purging files ...":"Очистка файлов ...","Rebuilding local database ...":"Пересборка локальной базы данных ...","Recreate (delete and repair)":"Пересоздать (удалить и исправить)","Recreating database ...":"Пересоздание базы данных ...","Registering temporary backup ...":"Регистрация временной резервной копии ...","Relative paths not allowed":"Относительные пути не допускаются","Reload":"Перезагрузить","Remote":"Удаленный","Remove":"Удалить","Remove option":"Удалить параметр","Repair":"Исправить","Reparing ...":"Починка ...","Repeat Passphrase":"Повторить кодовую фразу","Reporting:":"Отчетность:","Reset":"Сбросить","Restore":"Восстановление","Restore files":"Восстановить файлы","Restore files ...":"Восстановить файлы...","Restore files from {{backupname}}":"Восстановить файлы из {{backupname}}","Restore from":"Восстановить из","Restore from backup configuration":"Восстановить из конфигурации резервной копии","Restore from configuration ...":"Восстановление из конфигурации ...","Restore options":"Параметры восстановления","Restore read/write permissions":"Восстановить разрешения чтения/записи","Restoring files ...":"Восстановление файлов ...","Resume":"Продолжить","Run again every":"Запускать каждый","Run now":"Запустить сейчас","Running ...":"Запуск ...","Running ....":"Выполнение...","Running commandline entry":"Выполнение записи командной строки","Running task:":"Выполняемая задача:","S3 Compatible":"S3 совместимый","Same as the base install version: {{channelname}}":"Такой же как в базовой версии: {{channelname}}","Sat":"Сб","Save":"Сохранить","Save and repair":"Сохранить и исправить","Save different versions with timestamp in file name":"Сохранить различные версии с отметкой времени в имени файла","Save immediately":"Немедленно сохранить","Scanning existing files ...":"Сканирование существующих файлов ...","Scanning for local blocks ...":"Сканирование локальных блоков ...","Schedule":"Расписание","Search":"Поиск","Search for files":"Поиск файлов","Seconds":"Секунд","Select a log level and see messages as they happen:":"Выберите уровень ведения журнала и смотрите сообщения по мере прихода:","Select files":"Выбор файлов","Server":"Сервер","Server and port":"Сервер и порт","Server hostname or IP":"Имя сервера или IP","Server is currently paused,":"Сервер приостановлен,","Server is currently paused, do you want to resume now?":"Сервер в настоящее время приостановлен, вы хотите возобновить сейчас?","Server paused":"Сервер приостановлен","Server state properties":"Свойства состояния сервера","Settings":"Настройки","Show":"Показать","Show advanced editor":"Текстовое отображение","Show hidden folders":"Показать скрытые папки","Show log":"Журнал","Show log ...":"Показать журнал ...","Show treeview":"Древовидное отображение","Some OpenStack providers allow an API key instead of a password and tenant name":"Некоторые провайдеры OpenStack позволяют использовать ключ API вместо имени клиента и пароля","Source Data":"Исходные данные","Source data":"Данные для резервирования","Source folders":"Исходные папки","Source:":"Источник:","Specific builds for developers only.":"Особые сборки только для разработчиков.","Standard protocols":"Стандартные протоколы","Starting ...":"Начинаю ...","Starting the restore process ...":"Запуск процесса восстановления ...","Stop after the current file":"Остановиться после текущего файла","Stop after upload":"Остановить после выгрузки","Stop now":"Остановить сейчас","Stop running backup":"Остановить резервное копирование","Stop running task":"Остановить задачу","Stopping after upload:":"Остановка после выгрузки:","Stopping task:":"Остановка задачи:","Storage Type":"Тип хранилища","Storage class":"Класс хранилища","Storage class for creating a bucket":"Класс хранения для создания bucket","Stored":"Сохраненные","Strong":"Сильный","Success":"Успех","Sun":"Вс","Symbolic link":"Символическая ссылка","System default ({{levelname}})":"По умолчанию ({{levelname}})","System files":"Системные файлы","System info":"Информация о системе","System properties":"Свойства системы","TByte":"ТБайт","TByte/s":"ТБайт/s","Task is running":"Выполняется задача","Temporary files":"Временные файлы","Tenant Name":"Имя клиента","Test connection":"Проверить доступ","Testing ...":"Проверка ...","Testing connection ...":"Проверка соединения...","Testing permissions ...":"Проверка разрешений ...","Testing permissions...":"Проверка разрешений...","The bucket name should be all lower-case, convert automatically?":"Имя bucket должно быть строчным, преобразовать автоматически?","The bucket name should start with your username, prepend automatically?":"Имя bucket следует начинать с вашего имени пользователя, вставить автоматически?","The connection to the server is lost, attempting again in {{time}} ...":"Потеряно соединение с сервером, повторная попытка через {{time}} ...","The dark theme (by Michal)":"Тёмная тема (от Michael)","The default blue on white theme (by Alex)":"Стандартная тема синий на белом (от Alex)","The folder {{folder}} does not exist\nCreate it now?":"Папка {{folder}} не существует\nСоздать её?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"Ключ узла изменился, пожалуйста, проверьте у администратора сервера так ли это, в противном случае вы можете быть жертвой атаки MAN-IN-THE-MIDDLE.\n\nВы хотите ЗАМЕНИТЬ ваш ТЕКУЩИЙ ключ узла «{{prev}}» ПОЛУЧЕННЫМ ключом хоста: {{key}}?","The path does not appear to exist, do you want to add it anyway?":"Путь, по-видимому, не существует, вы всё равно хотите его добавить?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"Путь не заканчивается символом «{{dirsep}}», что означает, что вы включаете файл, а не папку.\n\nВы хотите включить указанный файл?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"Путь должен быть абсолютным, то есть он должен начинаться с косой черты «/»","The path should start with \"{{prefix1}}\" or \"{{prefix2}}\", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?":"Путь должен начинаться с «{{prefix1}}\" или \"{{prefix2}}\", иначе вы не сможете увидеть файлы через веб-интерфейс HubiC.\n\nВы хотите, чтобы префикс был добавлен в путь автоматически?","The region parameter is only applied when creating a new bucket":"Параметр «регион» применяется только при создании нового bucket","The region parameter is only used when creating a bucket":"Параметр «регион» используется только при создании bucket","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"Не удалось проверить сертификат сервера.\nВы хотите утвердить SSL-сертификат с хэшом: {{hash}}?","The storage class affects the availability and price for a stored file":"Класс хранилища влияет на доступность и цену сохраненного файла","The target folder contains encrypted files, please supply the passphrase":"Целевая папка содержит зашифрованные файлы, пожалуйста, укажите кодовую фразу","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"Пользователь имеет слишком много прав. Вы хотите создать нового пользователя с ограниченными правами, с разрешениями только на выбранный путь?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"Эта резервная копия была создана в другой операционной системе. Восстановление файлов без указания папки назначения может повлечь восстановление файлов в неожиданных местах. Вы уверены, что вы хотите продолжить без выбора папки назначения?","This month":"В этом месяце","This week":"На этой неделе","Thu":"Чт","To File":"В файл","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"Чтобы подтвердить, что вы хотите удалить все дистанционные файлы для «{{name}}», введите слово, которое вы видите ниже","To export without a passphrase, uncheck the \"Encrypt file\" box":"Чтобы экспортировать без кодовой фразы, снимите флажок «Зашифровать файл»","Today":"Сегодня","Trust host certificate?":"Доверять сертификату хоста?","Trust server certificate?":"Доверять сертификату сервера?","Try out the new features we are working on. Don't use with important data.":"Попробуйте новые возможности, находящиеся в разработке. Не используйте с важными данными.","Tue":"Вт","Type to highlight files":"Напишите для выделения файлов","Unknown backup size and versions":"Неизвестные размер резервной копии и версии","Until resumed":"До возобновления","Update channel":"Канал обновлений","Update failed:":"Обновление не удалось:","Updating with existing database":"Обновление с существующей базой данных","Upload volume size":"Размер выгружаемых томов","Uploading verification file ...":"Выгрузка файла проверки ...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"Отчёты об использовании помогают нам улучшить пользовательский интерфейс и оценить влияние новых функций. Мы используем отчёты для генерации <a href=\"{{link}}\" target=\"_blank\">публичной статистики использования</a>","Usage statistics":"Статистика использования","Usage statistics, warnings, errors, and crashes":"Статистика использования, предупреждения, ошибки и падения","Use SSL":"Использовать SSL","Use existing database?":"Использовать существующую базу данных?","Use weak passphrase":"Использовать слабую кодовую фразу","Useless":"Бесполезно","User data":"Данные пользователя","User has too many permissions":"Пользователь имеет слишком много разрешений","User interface settings":"Настройки интерфейса","Username":"Имя пользователя","VISA, Mastercard, ... via Paypal":"VISA, Mastercard, ... через Paypal","Validating ...":"Проверка ...","Verify files":"Проверить файлы","Verifying ...":"Проверка ...","Verifying answer":"Проверка ответа","Verifying backend data ...":"Проверка данных бэкенда ...","Verifying remote data ...":"Проверка дистанционных данных ...","Verifying restored files ...":"Проверка восстановленных файлов ...","Very strong":"Очень надёжный","Very weak":"Очень слабый","Visit us on":"Посетите нас на","WARNING: The remote database is found to be in use by the commandline library":"ВНИМАНИЕ: Удаленная база данных используется библиотекой командной строки","WARNING: This will prevent you from restoring the data in the future.":"ВНИМАНИЕ: В будущем это не позволит вам восстановить данные.","Waiting for task to begin":"Ожидание начала задачи","Waiting for task to start ....":"Ожидание запуска задачи...","Waiting for upload ...":"Ожидание выгрузки ...","Warnings, errors and crashes":"Предупреждения, ошибки и падения","We recommend that you encrypt all backups stored outside your system":"Мы рекомендуем зашифровать все резервные копии, хранящиеся вне вашей системы","Weak":"Слабый","Weak passphrase":"Слабая кодовая фраза","Wed":"Ср","Weeks":"Недель","Where do you want to restore from?":"Откуда вы хотите восстановить данные?","Where do you want to restore the files to?":"Куда вы хотите восстановить файлы?","Years":"Лет","Yes":"Да","Yes, I have stored the passphrase safely":"Да, я надёжно сохранил кодовую фразу","Yes, I'm brave!":"Да, я смелый!","Yes, please break my backup!":"Да, пожалуйста, сломайте мою резервную копию!","Yesterday":"Вчера","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"Вы используете Mono без загруженных SSL-сертификатов.\nВы хотите импортировать список доверенных сертификатов от Mozilla?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"Вы меняете путь базы данных отличный от существующей базы данных.\nВы уверены, что это то, что вы хотите?","You are currently running {{appname}} {{version}}":"Вы используете {{appname}} {{version}}","You can stop the backup immediately, or stop after the current file has been uploaded.":"Вы можете остановить резервное копирование немедленно или после завершения выгрузки текущего файла.","You can stop the task immediately, or allow the process to continue its current file and the stop.":"Вы можете завершить задачу немедленно или позволить процессу продолжить текущий файл и остановиться.","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"Вы изменили режим шифрования. Это может что-нибудь сломать. Вместо этого вам лучше создать новую резервную копию","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"Вы изменили кодовую фразу, но это не поддерживается. Вместо этого вам стоит создать новую резервную копию.","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"Вы выбрали не шифровать резервную копию. Шифрование рекомендовано для всех данных, хранящихся на удаленном сервере.","You have chosen to restore to a new location, but not entered one":"Вы выбрали новое место для восстановления, но не ввели его","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"Вы задали сложную кодовую фразу. Убедитесь, что вы надёжно сохранили кодовую фразу, поскольку данные не могут быть восстановлены без неё.","You must choose at least one source folder":"Вы должны выбрать по крайней мере одну исходную папку","You must enter a name for the backup":"Вам необходимо ввести имя резервной копии","You must enter a passphrase or disable encryption":"Вы должны ввести кодовую фразу или отключить шифрование","You must enter a positive number of backups to keep":"Необходимо ввести положительное число резервных копий для хранения","You must enter a tenant name if you do not provide an API Key":"Вам необходимо ввести имя арендатора, если вы не предоставите ключ API","You must enter a valid duration for the time to keep backups":"Необходимо ввести допустимый срок времени хранения резервных копий","You must enter either a password or an API Key":"Вы должны ввести пароль или ключ API","You must enter either a password or an API Key, not both":"Вы должны ввести либо пароль, либо ключ API, но не оба","You must fill in the password":"Вы должны заполнить пароль","You must fill in the server name or address":"Вы должны заполнить имя сервера или адрес","You must fill in the username":"Вы должны заполнить имя пользователя","You must fill in {{field}}":"Вы должны заполнить {{field}}","You must select or fill in the AuthURI":"Вы должны выбрать или заполнить AuthURI","You must select or fill in the server":"Вы должны выбрать или заполнить сервер","You must specify a path":"Вы должны указать путь","Your files and folders have been restored successfully.":"Ваши файлы и папки были восстановлены успешно.","Your passphrase is easy to guess. Consider changing passphrase.":"Вашу кодовую фразу легко отгадать. Подумайте об изменении кодовой фразы.","a specific number":"пользовательский","bucket/folder/subfolder":"bucket/папка/подпапка","byte":"байт","byte/s":"байт/сек","custom":"пользовательские","resume now":"возобновить сейчас","unlimited":"неограниченный","until they are older than":"пока они старее, чем","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} был разработан преимущественно <a href=\"{{mail1}}\">{{dev1}}</a> и <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} может быть загружен с веб-сайта <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} лицензируется под <a href=\"{{licenselink}}\">{{licensename}}</a>.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":["{{item.Backup.Metadata.TargetSizeString}} / {{$count}} версия","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} версии","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} версий","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} версий"],"{{number}} Hour":"{{number}} Часов","{{number}} Minutes":"{{number}} минут","{{time}} (took {{duration}})":"{{time}} (заняло {{duration}})"});
+ gettextCatalog.setStrings('zh_CN', {"- pick an option -":"- 选择一个选项 -","...loading...":"…载入中…","API Key":"API 密钥","AWS Access ID":"AWS 访问 ID","AWS Access Key":"AWS 访问密钥","AWS IAM Policy":"AWS IAM 策略","About":"关于","About {{appname}}":"关于 {{appname}}","Access Key":"访问密钥","Access denied":"访问被拒绝","Access to user interface":"访问控制","Account name":"帐户名","Activate":"激活","Activate failed:":"激活失败:","Add a new backup":"添加新备份","Add a path directly":"直接添加路径","Add advanced option":"添加高级选项","Add backup":"新增备份","Add filter":"添加过滤条件","Add path":"添加路径","Adjust bucket name?":"调整 bucket 名称?","Adjust path name?":"调整路径名称?","Advanced Options":"高级选项","Advanced options":"高级选项","Advanced:":"高级:","All Hyper-V Machines":"所有 Hyper-V 机器","All Microsoft SQL Databases":"所有 Microsoft SQL 数据库","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"所有的使用情况报告都是匿名发送,不含任何个人信息。 其中包括硬件,操作系统,后端类型,备份时长,备份源大小以及类似数据,但不包括路径,文件名,用户名,密码或类似的敏感信息。","Allow remote access (requires restart)":"允许远程访问 (需要重启)","Allowed days":"日期规划","An existing file was found at the new location":"新位置已有文件","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"新位置已有文件\n你确定要将数据库指向已存在的文件?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"发现此存储在本地已存在数据库\n重新使用该数据库将使用命令行或服务器实例工作在相同的存储\n你希望使用已有的数据库吗?","Anonymous usage reports":"使用情况报告级别","As Command-line":"导出为命令行","AuthID":"授权 ID","Authentication password":"认证密码","Authentication username":"认证用户名","Autogenerated passphrase":"自动生成的密码","Automatically run backups.":"自动运行备份","B2 Account ID":"B2 帐户 ID","B2 Application Key":"B2 应用密钥","B2 Cloud Storage Account ID":"B2 云存储帐户 ID","B2 Cloud Storage Application Key":"B2 云存储应用密钥","Back":"返回","Backend modules:":"后端模块:","Backup destination":"备份保存位置","Backup location":"备份位置","Backup:":"备份数据:","Beta":" Beta","Bitcoin: {{bitcoinaddr}}":"比特币:{{bitcoinaddr}}","Broken access":"访问错误","Browse":"浏览","Browser default":"浏览器默认语言","Bucket Name":"Bucket 名称","Bucket create location":"Bucket 创建区域","Bucket create region":"Bucket 创建区域","Bucket name":"Bucket 名称","Bucket storage class":"Bucket 存储类型","Building list of files to restore ...":"正在构建文件还原列表…","Building partial temporary database ...":"正在构建局部临时数据库…","Busy ...":"忙碌中…","Canary":"Canary","Cancel":"取消","Cannot move to existing file":"不能移动到已有文件","Changelog":"更新日志","Changelog for {{appname}} {{version}}":"{{appname}} {{version}} 更新日志","Check failed:":"检查失败:","Check for updates now":"立即检查更新","Checking ...":"正在检查…","Checking for updates ...":"正在检查更新…","Chose a storage type to get started":"选择存储类型以开始","Click the AuthID link to create an AuthID":"点击\"授权 ID\"链接来创建一个授权 ID","Click to set throttle options":"点击配置限流","Commandline ...":"命令行...","Compact now":"立即压实","Compacting remote data ...":"正在压实远程数据…","Completing backup ...":"即将完成备份…","Completing previous backup ...":"即将完成前一备份…","Compression modules:":"压缩模块:","Computer":"计算机","Configuration file:":"配置文件:","Configuration:":"配置:","Configure a new backup":"配置新备份","Confirm delete":"确认删除","Confirmation required":"需要确认","Connect":"连接","Connect now":"立即连接","Connecting to server ...":"正在连接服务器…","Connecting to task ....":"正在连接至任务...","Connecting...":"正在连接…","Connection lost":"连接中断","Connection worked!":"连接正常!","Container name":"容器名称","Container region":"容器区域","Continue":"继续","Continue without encryption":"继续且不启用加密","Copied!":"已复制!","Copy Destination URL to Clipboard":"复制地址到剪贴板","Copy failed. Please manually copy the URL":"复制失败,请手动复制此地址","Core options":"核心选项","Counting ({{files}} files found, {{size}})":"正在计算 (已找到 {{files}} 个文件,{{size}})","Crashes only":"仅崩溃","Create bug report ...":"创建 bug 报告…","Create folder?":"创建文件夹?","Created new limited user":"受限用户已创建","Creating bug report ...":"正在创建 bug 报告…","Creating new user with limited access ...":"正在创建受限用户…","Creating target folders ...":"正在创建目标文件夹…","Creating temporary backup ...":"正在创建临时备份…","Creating user...":"正在创建用户…","Current version is {{versionname}} ({{versionnumber}})":"当前版本为 {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"自定义 S3 端点","Custom authentication url":"自定义认证地址","Custom location ({{server}})":"自定义区域 ({{server}})","Custom region for creating buckets":"自定义创建 Bucket 的地区","Custom region value ({{region}})":"自定义地区 ({{region}})","Custom server url ({{server}})":"自定义服务器地址 ({{server}})","Custom storage class ({{class}})":"自定义存储类别 ({{class}})","Database ...":"数据库...","Days":"天","Default":"默认","Default ({{channelname}})":"默认 ({{channelname}})","Default options":"默认选项","Delete":"删除","Delete ...":"删除…","Delete backup":"删除备份","Delete local database":"删除本地数据库","Delete remote files":"删除远程文件","Delete the local database":"删除本地数据库","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"从远程存储中删除 {{filecount}} 个文件 ({{filesize}}) ?","Deleting remote files ...":"正在删除远程文件…","Deleting unwanted files ...":"正在删除多余文件…","Desktop":"桌面","Destination":"保存位置","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"若 Duplicati 对你有所帮助,请考虑捐赠来支持我们。个人用途,建议捐赠 {{smallamount}},商业用途,建议捐赠 {{largeamount}}。","Direct restore from backup files ...":"直接从备份文件中恢复...","Disabled":"已禁用","Dismiss":"忽略","Display and color theme":"显示和颜色主题","Do you really want to delete the backup: \"{{name}}\" ?":"你确定要删除备份:\"{{name}}\"吗 ?","Do you really want to delete the local database for: {{name}}":"你确定要删除 \"{{name}}\" 的本地数据库吗 ?","Donate":"捐赠","Donate with Bitcoins":"通过比特币捐赠","Donate with PayPal":"通过 Paypal 捐赠","Donation messages":"捐赠信息","Donation messages are hidden, click to show":"捐赠信息已隐藏,点击显示","Donation messages are visible, click to hide":"捐赠消息已显示,点击隐藏","Done":"完成","Download":"下载","Downloading ...":"正在下载…","Downloading files ...":"正在下载文件……","Downloading update...":"正在下载更新…","Duplicate option {{opt}}":"Duplicati 选项 {{opt}}","Duplicati Website":"Duplicati 网站","Duplicati forum":"Duplicati 论坛","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\n When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.\n If you are using the local database for backups from the commandline, you should keep the database.":"每个备份都有一个关联的本地数据库,用来存储远程备份相关的信息。\n删除一个备份时,你也可以删除其本地数据库,这不会影响从远程文件中恢复数据。\n但如果你通过命令行进行备份,你应当保留此数据库。","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"每个备份都有一个关联的本地数据库,用来存储远程备份相关的信息。\\n这将加快许多操作的执行时间并减少操作时需要下载的数据量。","Edit ...":"编辑…","Edit as list":"以列表形式编辑","Edit as text":"以文本形式编辑","Encrypt file":"加密文件","Encryption":"加密方式","Encryption changed":"加密方式已更改","Encryption modules:":"加密模块:","Enter URL":"输入地址","Enter access key":"输入访问密钥","Enter account name":"输入帐户名称","Enter backup passphrase, if any":"输入备份密码 (若存在)","Enter configuration details":"进入详细配置","Enter container name":"输入容器名称","Enter encryption passphrase":"输入加密密码","Enter expression here":"在此输入表达式","Enter folder path name":"输入文件夹路径名","Enter one option per line in command-line format, eg. {0}":"以命令行格式,一行一个参数,例如 {0}","Enter the destination path":"输入目标路径","Error":"错误","Error!":"错误!","Errors and crashes":"错误,崩溃","Exclude":"排除","Exclude directories whose names contain":"排除文件夹,名称包括","Exclude expression":"排除表达式","Exclude file":"排除文件","Exclude file extension":"排除文件后缀","Exclude files whose names contain":"排除文件,名称包括","Exclude folder":"排除文件夹","Exclude regular expression":"排除正则表达式","Existing file found":"发现已存在文件","Experimental":"Experimental","Export":"导出","Export ...":"导出…","Export backup configuration":"导出备份配置","Export configuration":"导出配置","Exporting ...":"正在导出…","FTP (Alternative)":"FTP (备选)","Failed to build temporary database: {{message}}":"构建临时数据库失败: {{message}}","Failed to connect:":"连接失败:","Failed to connect: {{message}}":"连接失败:{{message}}","Failed to delete:":"删除失败:","Failed to fetch path information: {{message}}":"获取路径信息失败: {{message}}","Failed to import:":"导入失败:","Failed to read backup defaults:":"读取备份默认设置失败:","Failed to restore files: {{message}}":"恢复文件失败: {{message}}","Failed to save:":"保存失败:","Fetching path information ...":"获取路径信息…","File":"文件","Files larger than:":"文件大于","Filters":"过滤条件","Finished!":"已完成!","First run setup":"初始配置","Folder":"文件夹","Folder path":"文件夹路径","Fri":"周五","GByte":"GB","GByte/s":"GB/s","GCS Project ID":"GCS 项目 ID","General":"常规","General backup settings":"常规备份设置","General options":"常规选项","Generate":"生成","Generate IAM access policy":"生成 IAM 访问策略","Getting file versions ...":"正在读取文件版本...","Hidden files":"隐藏文件","Hide":"隐藏","Hide hidden folders":"隐藏被隐藏的文件夹","Home":"首页","Hours":"小时","How do you want to handle existing files?":"你想要怎样处理已存在的文件?","Hyper-V Machine":"Hyper-V 虚拟机","Hyper-V Machine:":"Hyper-V 虚拟机:","Hyper-V Machines":"Hyper-V 虚拟机","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"如果时间错过,任务将尽快运行。","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"如果备份和远程存储不同步,Duplicati 需要你执行修复操作来同步数据库。\\n如果修复失败,你可以删除本地数据库并重新生成。","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"如果备份文件没有自动下载,<a href=\"{{DownloadURL}}\" target=\"_blank\">右键单击并选择 &quot;另存为…&quot; </a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"如果备份文件没有自动下载,<a href=\"{{item.DownloadLink}}\" target=\"_blank\">右键单击并选择 &quot;另存为…&quot; </a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"如果你不输入路径,所有文件将存储在登录时的默认文件夹。\n你确定这是你想要的吗?","If you do not enter an API Key, the tenant name is required":"如果你不输入 API 密钥,则需要输入租户名称","If you want to use the backup later, you can export the configuration before deleting it":"如果你需要之后使用备份,你可以在删除它之前导出配置","If your machine is in a multi-user environment (i.e. the machine has more than one account), you need to set a password to prevent other users from accessing data on your account.\nDo you want to set a password now?":"如果你的机器处于多用户环境(比如机器上有多个帐户),你需要设定一个密码来防止其他帐户访问你的数据。\n你要现在设定密码吗?","Import":"导入","Import Destination URL":"导入地址","Import backup configuration":"导入备份配置","Import completed, but no certificates were found after the import":"导入完成,但是未能找到证书","Import failed":"导入失败","Import from a file":"从文件导入","Importing ...":"正在导入…","Include a file?":"包含一个文件?","Include expression":"包含表达式","Include regular expression":"包含正则表达式","Incorrect answer, try again":"验证失败,请重试","Individual builds for developers only.":"面向开发者的个人构建","Information":"信息","Install":"安装","Install failed:":"安装失败:","Invalid retention time":"无效的保留时间","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"某些 FTP 不需要密码\n你确定你的 FTP 服务器支持无密码登陆吗?","KByte":"KB","KByte/s":"KB/s","Keep this number of backups":"保留备份","Language in user interface":"界面语言","Last month":"上月","Last successful run:":"上一次成功运行于:","Latest":"最新","Libraries":"第三方库","Listing backup dates ...":"正在列举备份日期…","Listing remote files ...":"正在列举远程文件…","Live":"实时","Load a configuration from an exported job or a storage provider":"从已导出的任务文件或者存储提供商处载入配置","Load destination from an exported job or a storage provider":"从已导出的任务文件或存储提供商处载入目标位置","Load older data":"载入之前的数据","Loading ...":"载入中…","Loading remote storage usage ...":"正在载入远程存储使用量…","Local database for":"本地数据库","Local database path:":"本地数据库路径:","Local storage":"本地存储","Location":"位置","Location where buckets are created":"请指定 Bucket 创建区域","Log data for <b>{{Backup.Backup.Name}}</b>":"<b>{{Backup.Backup.Name}}</b> 的日志","Log data from the server":"Duplicati 服务器日志","Log out":"登出","MByte":"MB","MByte/s":"MB/s","Maintenance":"维护","Manually type path":"手动输入路径…","Max download speed":"最大下载速度","Max upload speed":"最大上传速度","Menu":"菜单","Microsoft SQL Database:":"Microsoft SQL 数据库:","Microsoft SQL Databases":"Microsoft SQL 数据库","Minutes":"分钟","Missing name":"缺少名称","Missing passphrase":"缺少密码","Missing sources":"缺少源数据","Mon":"周一","Months":"月","Move existing database":"移动已有数据库","Move failed:":"移动失败:","My Documents":"我的文档","My Music":"我的音乐","My Photos":"我的照片","My Pictures":"我的图片","Name":"名称","Never":"从不","New update found: {{message}}":"发现新版本: {{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"新用户名为 {{user}}\n已为新的受限用户更新证书","Next":"下一步","Next scheduled run:":"下一次计划运行于:","Next scheduled task:":"下一次计划任务:","Next task:":"下一次任务:","Next time":"下一次运行时间:","No":"否","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"未预先指定证书,请与服务器管理员确认密钥 {{key}} 是否正确\n\n你想要允许此主机密钥吗?","No editor found for the &quot;{{backend}}&quot; storage type":"未找到 &quot;{{backend}}&quot; 存储类型的编辑器","No encryption":"无加密","No items selected":"未选中项目","No items to restore, please select one or more items":"未恢复项目,请至少选择一项","No passphrase entered":"未输入密码","No scheduled tasks":"暂无计划任务","No, my machine has only a single account":"否,我的机器只有一个帐户","Non-matching passphrase":"密码不匹配","None / disabled":"无 / 禁用","OK":"确定","OpenStack AuthURI":"OpenStack 认证地址","OpenStack Object Storage / Swift":"OpenStack 对象存储 / Swift","Operation failed:":"操作失败:","Operations:":"操作:","Optional authentication password":"如果需要,请输入认证密码","Optional authentication username":"如果需要,请输入认证用户名","Options":"选项","Options added here are applied to all backups, but can be overridden in each individual backup":"此处选项将对所有备份生效,但你可以单独设置备份来覆盖它","Original location":"原位置","Others":"其它","Overwrite":"覆盖","Passphrase":"密码","Passphrase (if encrypted)":"密码 (若启用加密)","Passphrase changed":"密码已更改","Passphrases are not matching":"密码不匹配","Password":"密码","Passwords do not match":"密码不匹配","Patching files with local blocks ...":"正在使用本地块修补文件…","Path not found":"路径未找到","Path on server":"服务器上路径","Path or subfolder in the bucket":" Bucket 中路径或子文件夹","Pause":"暂停","Pause after startup or hibernation":"开机或唤醒后暂缓","Pause options":"暂停选项","Permissions":"权限","Pick location":"选择位置","Point to your backup files and restore from there":"指向你的备份文件,将从中恢复","Port":"端口","Previous":"上一步","ProjectID is optional if the bucket exist":"若 Bucket 存在, 则项目ID 可选","Proprietary":"专有","Purging files ...":"正在清除文件...","Rebuilding local database ...":"正在重新构建本地数据库…","Recreate (delete and repair)":"重建 (删除并修复)","Recreating database ...":"正在重建数据库…","Registering temporary backup ...":"正在注册临时备份…","Relative paths not allowed":"不允许相对路径","Reload":"重新载入","Remote":"远程","Remove":"移除","Remove option":"移除选项","Repair":"修复","Reparing ...":"正在修复…","Repeat Passphrase":"重复密码","Reporting:":"报告:","Reset":"重置","Restore":"恢复文件","Restore files":"恢复文件","Restore files ...":"恢复文件…","Restore files from {{backupname}}":"从 {{backupname}} 恢复文件","Restore from":"恢复自","Restore from backup configuration":"从备份配置中恢复","Restore from configuration ...":"从配置中恢复...","Restore options":"恢复选项","Restore read/write permissions":"恢复读写权限","Restoring files ...":"正在恢复文件…","Resume":"恢复运行","Run again every":"重复运行每","Run now":"立即运行","Running ...":"正在运行…","Running ....":"正在运行...","Running commandline entry":"正在运行命令行","Running task:":"运行中的任务:","S3 Compatible":"S3 兼容","Same as the base install version: {{channelname}}":"与当前安装版本一致:{{channelname}}","Sat":"周六","Save":"保存","Save and repair":"保存并修复","Save different versions with timestamp in file name":"保存不同版本 (文件名中添加时间戳)","Save immediately":"立即保存","Scanning existing files ...":"正在扫描存在的文件…","Scanning for local blocks ...":"正在扫描本地文件块…","Schedule":"计划","Search":"搜索","Search for files":"搜索文件","Seconds":"秒","Select a log level and see messages as they happen:":"选择日志级别并实时查看","Select files":"选择文件","Server":"服务器","Server and port":"服务器与端口","Server hostname or IP":"服务器主机名或 IP","Server is currently paused,":"服务器暂停中,","Server is currently paused, do you want to resume now?":"Duplicati 服务器暂停中,你想要立即恢复运行吗?","Server paused":"服务器已暂停","Server state properties":"Duplicati 服务器状态","Settings":"设置","Show":"查看","Show advanced editor":"显示高级编辑器","Show hidden folders":"显示隐藏文件夹","Show log":"日志","Show log ...":"查看日志…","Show treeview":"显示树状视图","Some OpenStack providers allow an API key instead of a password and tenant name":"一些 OpenStack 提供商使用 API 密钥,而不是租户名称和密码","Source Data":"源数据","Source data":"源数据","Source folders":"源文件夹","Source:":"源数据:","Specific builds for developers only.":"面向开发者的特定构建","Standard protocols":"标准协议","Starting ...":"准备开始…","Starting the restore process ...":"正在开始恢复操作…","Stop after the current file":"当前文件完成后停止","Stop after upload":"上传完成后停止","Stop now":"立即停止","Stop running backup":"停止正在运行的备份","Stop running task":"停止正在运行的任务","Stopping after upload:":"于此完成后停止:","Stopping task:":"正在停止任务:","Storage Type":"存储类型","Storage class":"存储类别","Storage class for creating a bucket":"创建 Bucket 的存储类别","Stored":"存档","Strong":"强度高","Success":"成功","Sun":"周日","Symbolic link":"符号链接","System default ({{levelname}})":"默认 ({{levelname}})","System files":"系统文件","System info":"系统信息","System properties":"系统属性","TByte":"TB","TByte/s":"TB/s","Task is running":"任务正在运行中","Temporary files":"临时文件","Tenant Name":"租户名称","Test connection":"测试连接","Testing ...":"正在测试…","Testing connection ...":"正在测试连接…","Testing permissions ...":"正在测试权限…","Testing permissions...":"正在测试权限…","The bucket name should be all lower-case, convert automatically?":"Bucket 名称应当是全小写,自动转换?","The bucket name should start with your username, prepend automatically?":"Bucket 名称应该以你的用户名开头,自动加上?","The connection to the server is lost, attempting again in {{time}} ...":"服务器连接中断,将在 {{time}} 后重新连接…","The dark theme (by Michal)":"黑色主题 (by Michal)","The default blue on white theme (by Alex)":"默认蓝白主题 (by Alex)","The folder {{folder}} does not exist\nCreate it now?":"文件夹 {{folder}} 不存在\n现在创建它吗?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"主机密钥已更改,请与服务器管理员确认其是否正确,否则你可能正在被中间人攻击。\n\n你想要把现有密钥 \"{{prev}}\" 替换为 {{key}} 吗?","The path does not appear to exist, do you want to add it anyway?":"路径似乎不存在,你确定要添加它吗?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"路径不应该以 '{{dirsep}}' 字符结尾,这意味你想要包含一个文件而不是文件夹。\n你想要包含指定文件吗?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"路径必须为绝对路径,也就是以斜杠 '/' 开头","The path should start with \"{{prefix1}}\" or \"{{prefix2}}\", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?":"路径应当以 \"{{prefix1}}\" 或 \"{{prefix2}}\" 开头,否则你不会在 HubiC 网页界面上看到文件。\n你需要自动给路径添加上前缀吗?","The region parameter is only applied when creating a new bucket":"\"地区\"参数只在创建新 Bucket 时生效","The region parameter is only used when creating a bucket":"\"参数只在创建新 Bucket 时使用","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"服务器证书验证失败\n你想要允许此 SSL证书吗?其哈希值为 {{hash}}","The storage class affects the availability and price for a stored file":"存储类别影响文件可用性和价格","The target folder contains encrypted files, please supply the passphrase":"目标文件夹包含加密文件,请提供密码","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"此用户权限太多,你想要创建一个只能访问所选路径的受限用户吗?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"此备份创建于其他操作系统上。恢复时不指定目标文件夹可能会使文件恢复到未知的位置。你确定要继续吗?","This month":"本月","This week":"本周","Throttle settings":"限流设置","Thu":"周四","To File":"导出为文件","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"为确认你想要删除 \"{{name}}\" 的所有远程文件,请输入以下单词","To export without a passphrase, uncheck the \"Encrypt file\" box":"如果不想使用密码加密导出的文件,请去除勾选\"加密文件\"","Today":"今天","Trust host certificate?":"信任主机证书?","Trust server certificate?":"信任服务器证书?","Try out the new features we are working on. Don't use with important data.":"尝试我们开发的新特性,注意不要使用在重要数据上","Tue":"周二","Type to highlight files":"输入以高亮文件","Unknown backup size and versions":"未知的备份大小和版本","Until resumed":"直到手动恢复运行","Update channel":"更新分支","Update failed:":"更新失败:","Updating with existing database":"正在更新存在的数据库","Upload volume size":"上传分卷大小","Uploading verification file ...":"正在上传校验文件…","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"使用情况报告帮助我们提升用户体验,评估新特性的影响,我们用它们生成 <a href=\"{{link}}\" target=\"_blank\">公共使用统计</a>","Usage statistics":"使用情况统计","Usage statistics, warnings, errors, and crashes":"使用情况统计,警告,错误,崩溃","Use SSL":"启用 SSL","Use existing database?":"使用已存在的数据库?","Use weak passphrase":"确定使用弱密码","Useless":"无用","User data":"用户数据","User has too many permissions":"用户权限太多","User interface settings":"界面设置","Username":"用户名","VISA, Mastercard, ... via Paypal":" Paypal:VISA, Mastercard, ... ","Validating ...":"正在验证…","Verify files":"校验文件","Verifying ...":"正在校验…","Verifying answer":"正在验证","Verifying backend data ...":"正在校验后端数据…","Verifying remote data ...":"正在校验远程数据…","Verifying restored files ...":"正在校验恢复出的文件…","Very strong":"强度非常高","Very weak":"强度非常低","Visit us on":"了解我们","WARNING: The remote database is found to be in use by the commandline library":"警告:远程数据库正在被命令行库使用","WARNING: This will prevent you from restoring the data in the future.":"警告:这将使你以后不再能恢复数据","Waiting for task to begin":"等待任务开始…","Waiting for task to start ....":"正在等待任务开始...","Waiting for upload ...":"等待上传完成…","Warnings, errors and crashes":"警告,错误,崩溃","We recommend that you encrypt all backups stored outside your system":"我们推荐加密所有保存在第三方系统中的数据","Weak":"强度低","Weak passphrase":"弱密码","Wed":"周三","Weeks":"周","Where do you want to restore from?":"你想从哪里恢复呢?","Where do you want to restore the files to?":"你想把文件恢复到哪里?","Years":"年","Yes":"是","Yes, I have stored the passphrase safely":"是,我已将密码安全保存","Yes, I'm brave!":"是,我无所谓","Yes, please break my backup!":"是,请清除我的备份","Yesterday":"昨天","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"看起来 Mono 当前没有载入 SSL 证书。\n你想要从 Mozilla 导入可信任的证书吗?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"你正在改变数据库路径。\n你确定想要这么做吗?","You are currently running {{appname}} {{version}}":"当前正在运行 {{appname}} {{version}}","You can stop the backup immediately, or stop after the current file has been uploaded.":"你可以立即停止备份,也可以在当前文件完成上传后停止。","You can stop the task immediately, or allow the process to continue its current file and the stop.":"你可以立即停止任务,也可以在当前文件处理完成后停止。","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"你已经更改了加密方式,这可能破坏备份。你更应当创建新备份。","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"你已经更改密码,这是不支持的操作。你更应当创建新备份。","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"你已选择不加密备份,推荐加密所有存储在远程服务器上的数据。","You have chosen to restore to a new location, but not entered one":"你选择了恢复到新位置,却没有指定具体位置","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"你已经生成了一个强密码,确保你安全记录下了此密码,否则万一你丢失密码,数据将不能恢复。","You must choose at least one source folder":"你必须选择至少一个源文件夹","You must enter a name for the backup":"你必须输入备份名称","You must enter a passphrase or disable encryption":"你必须输入加密密码或禁用加密","You must enter a positive number of backups to keep":"你输入要保留的版本数必须为正","You must enter a tenant name if you do not provide an API Key":"如果你没有提供 API 密钥,你必须输入租户名称","You must enter a valid duration for the time to keep backups":"你必须输入有效的保留时长","You must enter either a password or an API Key":"你必须输入一个密码或 API 密钥","You must enter either a password or an API Key, not both":"你必须只输入一个密码或 API 密钥,而不是两者同时","You must fill in the password":"你必须填写密码","You must fill in the server name or address":"你必须填写服务器主机名或地址","You must fill in the username":"你必须填写用户名","You must fill in {{field}}":"你必须填写 {{field}}","You must select or fill in the AuthURI":"你必须选择或填写认证地址","You must select or fill in the server":"你必须选择或填写服务器","You must specify a path":"你必须指定路径","Your files and folders have been restored successfully.":"文件恢复成功!","Your passphrase is easy to guess. Consider changing passphrase.":"你的密码很容易被破解,请考虑更换一个强密码","a specific number":"指定版本数","bucket/folder/subfolder":"Bucket / 文件夹 / 子文件夹","byte":"B","byte/s":"B/s","custom":"自定义","resume now":"立即恢复运行","unlimited":"永久","until they are older than":"指定时长","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} 主要由 <a href=\"{{mail1}}\">{{dev1}}</a> 和 <a href=\"{{mail2}}\">{{dev2}}</a> 开发. {{appname}} 可以从 <a href=\"{{websitelink}}\">{{websitename}}</a> 下载. {{appname}} 采用 <a href=\"{{licenselink}}\">{{licensename}}</a> 授权.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":"{{item.Backup.Metadata.TargetSizeString}} / {{$count}} 个版本","{{number}} Hour":"{{number}} 小时","{{number}} Minutes":"{{number}} 分钟","{{time}} (took {{duration}})":"{{time}} (耗时 {{duration}})"});
+ gettextCatalog.setStrings('zh_TW', {"- pick an option -":"選擇一個選項","...loading...":"...載入中...","API Key":"API Key","AWS Access ID":"AWS Access ID","AWS Access Key":"AWS Access Key","AWS IAM Policy":"AWS IAM Policy","About":"關於","About {{appname}}":"關於 {{appname}}","Access Key":"Access Key","Access denied":"拒絕存取","Access to user interface":"進入使用者介面","Account name":"帳號名稱","Activate":"啟用","Activate failed:":"啟用失敗","Add a new backup":"新增備份","Add advanced option":"加入進階選項","Add backup":"加入備份","Add filter":"加入篩選條件","Add path":"加入路徑","Adjust bucket name?":"調整 bucket 名稱?","Adjust path name?":"調整 path 名稱?","Advanced Options":"進階選項","Advanced options":"進階選項","Advanced:":"進階","All Hyper-V Machines":"全部 Hyper-V 主機","All Microsoft SQL Databases":"全部 Microsoft SQL 資料庫","All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.":"All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.","Allow remote access (requires restart)":"允許遠端存取(需要重新啟動)","Allowed days":"允許天數","An existing file was found at the new location":"新的位置發現已既有檔案存在","An existing file was found at the new location\nAre you sure you want the database to point to an existing file?":"新的位置發現已既有檔案存在,您要將資料庫指向其中一個既有檔案嗎?","An existing local database for the storage has been found.\nRe-using the database will allow the command-line and server instances to work on the same remote storage.\n\n Do you wish to use the existing database?":"儲存區發現既有的的本機資料庫已存在。\n重新使用資料庫將可以讓您使用命令列和伺服器服務用在同樣的遠端儲存區。\n\n您希望使用既有的資料庫嗎?","Anonymous usage reports":"匿名使用報告","As Command-line":"如同 Command-Line","AuthID":"AuthID","Authentication password":"認證密碼","Authentication username":"認證名稱","Autogenerated passphrase":"自動產生密碼","Automatically run backups.":"自動執行備份","B2 Account ID":"B2 帳號 ID","B2 Application Key":"B2 Application Key","B2 Cloud Storage Account ID":"B2 Cloud Storage 帳號 ID","B2 Cloud Storage Application Key":"B2 Cloud Storage Application Key","Back":"返回","Backend modules:":"Backend 模組:","Backup destination":"備份目的地","Backup location":"備份位置","Backup:":"備份:","Beta":"測試版 (Beta)","Bitcoin: {{bitcoinaddr}}":"比特幣:{{bitcoinaddr}}","Broken access":"故障連線","Browse":"瀏覽","Browser default":"瀏覽器預設","Bucket Name":"Bucket 名稱","Bucket create location":"Bucket 建立位置","Bucket create region":"Bucket 建立區域","Bucket name":"Bucket 名稱","Bucket storage class":"Bucket 儲存等級","Building list of files to restore ...":"正在建立還原的檔案清單 ...","Building partial temporary database ...":"正在建立部份暫存資料庫 ...","Busy ...":"忙碌 ...","Canary":"Canary","Cancel":"取消","Cannot move to existing file":"無法搬移已存在檔案","Changelog":"更新記錄","Changelog for {{appname}} {{version}}":"更新記錄:{{appname}} {{version}}","Check failed:":"檢查失敗:","Check for updates now":"現在檢查更新","Checking ...":"檢查中 ...","Checking for updates ...":"檢查更新中 ...","Chose a storage type to get started":"選擇儲存區類型,然後開始","Click the AuthID link to create an AuthID":"按下 AuthID 連結來建立一組 AuthID","Compact now":"立即緊密壓縮","Compacting remote data ...":"正在緊密壓縮遠端資料 ...","Completing backup ...":"正在完成備份 ...","Completing previous backup ...":"正在完成上一次備份 ...","Compression modules:":"壓縮模組:","Computer":"電腦","Configuration file:":"設定檔:","Configuration:":"設定:","Configure a new backup":"設定一個新備份","Confirm delete":"確認刪除","Confirmation required":"需要確認","Connect":"連線","Connect now":"立即連線","Connecting...":"連線中...","Connection lost":"連線失敗","Connection worked!":"連線已建立!","Container name":"容器名稱","Container region":"容器區域","Continue":"繼續","Continue without encryption":"不加密並繼續","Copied!":"已複製","Copy Destination URL to Clipboard":"複製目標 URL 至剪貼簿","Copy failed. Please manually copy the URL":"複製失敗。請手動複製 URL","Core options":"核心選項","Counting ({{files}} files found, {{size}})":"正在計算 ({{files}} 個檔案, {{size}})","Crashes only":"只有當機","Create bug report ...":"建立問題報告","Create folder?":"建立資料夾?","Created new limited user":"建立新的受限使用者","Creating bug report ...":"正在建立問題報告 ...","Creating new user with limited access ...":"正在建立有限制存取的新使用者 ...","Creating target folders ...":"正在建立目標資料夾 ...","Creating temporary backup ...":"正在建立暫存備份 ...","Creating user...":"正在建立使用者 ...","Current version is {{versionname}} ({{versionnumber}})":"目前版本 {{versionname}} ({{versionnumber}})","Custom S3 endpoint":"自訂 S3 進入點","Custom authentication url":"自訂授權 URL","Custom location ({{server}})":"自訂位置 ({{server}})","Custom region for creating buckets":"自定區域以建立 Bucket ","Custom region value ({{region}})":"自訂區域 Value ({{region}})","Custom server url ({{server}})":"自訂伺服器 URL ({{server}})","Custom storage class ({{class}})":"自訂儲存等級 ({{class}})","Days":"日","Default":"預設","Default ({{channelname}})":"預設 ({{channelname}})","Default options":"預設選項","Delete":"刪除","Delete ...":"刪除 ...","Delete backup":"刪除備份","Delete local database":"刪除本機資料庫","Delete remote files":"刪除遠端檔案","Delete the local database":"刪除本機資料庫","Delete {{filecount}} files ({{filesize}}) from the remote storage?":"刪除遠端儲存區的 {{filecount}} 個檔案 ({{filesize}}) 嗎?","Deleting remote files ...":"正在刪除遠端檔案 ...","Deleting unwanted files ...":"正在刪除不需要的檔案 ...","Desktop":"桌面","Destination":"目的地","Did we help save your files? If so, please consider supporting Duplicati with a donation. We suggest {{smallamount}} for private use and {{largeamount}} for commercial use.":"我們協助您保護您的檔案了嗎?如果是這樣,請考慮贊助支援 Duplicati。我們建議私人 {{smallamount}} 以及 {{largeamount}} 進行商業用途。","Direct restore from backup files ...":"直接從備份檔還原 ...","Disabled":"取消","Dismiss":"忽略","Do you really want to delete the backup: \"{{name}}\" ?":"您真的要刪除 \"{{name}}\" 這個備份?","Do you really want to delete the local database for: {{name}}":"您真的要刪除 {{name}} 這個本機資料庫?","Donate":"贊助","Donate with Bitcoins":"以比特幣贊助","Donate with PayPal":"以 Paypal 贊助","Donation messages":"贊助資訊","Donation messages are hidden, click to show":"贊助資訊已隱藏,點選以顯示","Donation messages are visible, click to hide":"贊助資資已顯示,點選以隱藏","Done":"完成","Download":"下載","Downloading ...":"下載中 ...","Downloading files ...":"正在下載檔案 ...","Downloading update...":"正在下載更新 ...","Duplicate option {{opt}}":"重複選項 {{opt}}","Duplicati Website":"Duplicati 官方網站","Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.":"Each backup has a local database associated with it, which stores information about the remote backup on the local machine.\\nThis makes it faster to perform many operations, and reduces the amount of data that needs to be downloaded for each operation.","Edit ...":"編輯 ...","Edit as list":"編輯清單","Edit as text":"編輯文字內容","Encrypt file":"加密檔案","Encryption":"加密方式","Encryption changed":"加密方式已變更","Encryption modules:":"加密模組:","Enter URL":"輸入 URL","Enter access key":"輸入 access key","Enter account name":"輸入帳號名稱","Enter backup passphrase, if any":"輸入備份密碼,如果有的話","Enter configuration details":"進入設定細節","Enter container name":"輸入容器名稱","Enter encryption passphrase":"輸入加密密碼","Enter expression here":"在這裡輸入運算式","Enter folder path name":"輸入資料夾路徑名稱","Enter one option per line in command-line format, eg. {0}":"請輸入選項,每一行一個,如。{0}","Enter the destination path":"輸入目的地路徑","Error":"錯誤","Error!":"錯誤!","Errors and crashes":"錯誤與當機","Exclude":"例外","Exclude directories whose names contain":"排除目錄名稱含有","Exclude expression":"排除表示式","Exclude file":"例外檔案","Exclude file extension":"例外副檔名","Exclude files whose names contain":"排除檔案名稱包含有","Exclude folder":"例外資料夾","Exclude regular expression":"排除的正規表示式","Existing file found":"檔案已存在","Experimental":"實驗版 (Experimental)","Export":"匯出","Export ...":"匯出 ...","Export backup configuration":"匯出備份設定","Export configuration":"匯出設定","Exporting ...":"正在匯出 ...","FTP (Alternative)":"FTP (替代)","Failed to build temporary database: {{message}}":"建立暫存資料庫失敗:{{message}}","Failed to connect:":"連線失敗:","Failed to connect: {{message}}":"連線失敗:{{message}}","Failed to delete:":"刪除失敗:","Failed to fetch path information: {{message}}":"列取路徑資訊失敗: {{message}}","Failed to import:":"匯入失敗:","Failed to read backup defaults:":"讀取備份預設值失敗︰","Failed to restore files: {{message}}":"還原檔案失敗:{{message}}","Failed to save:":"儲存失敗:","Fetching path information ...":"正在列舉路徑資訊 ...","File":"檔案","Files larger than:":"檔案大小超過:","Filters":"篩選","Finished!":"已完成!","Folder":"資料夾","Folder path":"資料夾路徑","Fri":"週五","GByte":"GByte","GByte/s":"GByte/s","GCS Project ID":"GCS Project ID","General":"一般","General backup settings":"一般備份設定","General options":"一般選項","Generate":"產生","Generate IAM access policy":"產生 IAM access policy","Getting file versions ...":"正在取得檔案版本 ...","Hidden files":"隱藏檔","Hide":"隱藏","Hide hidden folders":"隱藏目錄","Home":"首頁","Hours":"小時","How do you want to handle existing files?":"您如何處理既有檔案?","Hyper-V Machine":"Hyper-V 主機","Hyper-V Machine:":"Hyper-V 主機:","Hyper-V Machines":"Hyper-V 主機","ID:":"ID:","If a date was missed, the job will run as soon as possible.":"如果已錯過時間,將儘可能快速進行這個工作。","If the backup and the remote storage is out of sync, Duplicati will require that you perform a repair operation to synchronize the database.\\nIf the repair is unsuccesful, you can delete the local database and re-generate.":"如果備份與遠端儲存區不同步,Duplicati 需要您執行修復操作以讓資料庫重新同步。 \\n 如果修復不成功,您可以刪除本機資料庫並重新產生之。","If the backup file was not downloaded automatically, <a href=\"{{DownloadURL}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"如果備份檔案沒有自動下載,<a href=\"{{DownloadURL}}\" target=\"_blank\">右鍵點選這裡 &quot;另存 ...&quot;</a>","If the backup file was not downloaded automatically, <a href=\"{{item.DownloadLink}}\" target=\"_blank\">right click and choose &quot;Save as ...&quot;</a>":"如果備份檔案沒有自動下載,<a href=\"{{item.DownloadLink}}\" target=\"_blank\">右鍵點選這裡 &quot;另存 ...&quot;</a>","If you do not enter a path, all files will be stored in the login folder.\nAre you sure this is what you want?":"如果沒有輸入路徑,將會儲存所有檔案在登入資料夾。\n確定這是您要的嗎?","If you do not enter an API Key, the tenant name is required":"If you do not enter an API Key, the tenant name is required","If you want to use the backup later, you can export the configuration before deleting it":"如果您以後還想要使用此備份,您可以在刪除之前先將設定匯出","Import":"匯入","Import Destination URL":"匯入目的地 URL","Import backup configuration":"匯入備份設定","Import completed, but no certificates were found after the import":"匯入完成,但沒有在匯入時找到憑證","Import failed":"匯入失敗","Importing ...":"正在匯入 ...","Include a file?":"包含檔案?","Include expression":"包含表示式","Include regular expression":"包含正則表示式","Incorrect answer, try again":"回應不正確,請重試一次","Individual builds for developers only.":"Individual builds for developers only.","Information":"資訊","Install":"安裝","Install failed:":"安裝失敗:","Invalid retention time":"保留時間無效","It is possible to connect to some FTP without a password.\nAre you sure your FTP server supports password-less logins?":"可以在無密碼的情況下連接到 FTP。\n您確定您的 FTP 伺服器支援無密碼登錄嗎?","KByte":"KByte","KByte/s":"KByte/s","Language in user interface":"使用者介面語言","Last month":"上個月","Last successful run:":"上一次成功執行","Latest":"最新","Libraries":"Libraries","Listing backup dates ...":"正在列出備份日期 ...","Listing remote files ...":"正在列出遠端檔案 ...","Live":"即時","Load a configuration from an exported job or a storage provider":"Load a configuration from an exported job or a storage provider","Load destination from an exported job or a storage provider":"Load destination from an exported job or a storage provider","Load older data":"載入較舊的資料","Loading ...":"載入中 ...","Loading remote storage usage ...":"正在載入遠端儲存區使用資訊 ...","Local database for":"本機資料庫","Local database path:":"本機資料庫路徑:","Local storage":"本機儲存區","Location":"位置","Location where buckets are created":"建立 Buckets 的位置","Log data for <b>{{Backup.Backup.Name}}</b>":"<b>{{Backup.Backup.Name}}</b> 的記錄資料","Log data from the server":"伺服器上的記錄","Log out":"登出","MByte":"MByte","MByte/s":"MByte/s","Maintenance":"維護","Manually type path":"手動輸入路徑","Menu":"功能","Microsoft SQL Database:":"Microsoft SQL 資料庫:","Microsoft SQL Databases":"Microsoft SQL 資料庫","Minutes":"分鐘","Missing name":"遺失名稱","Missing passphrase":"遺失密碼","Missing sources":"遺失來源","Mon":"週一","Months":"月","Move existing database":"搬移已存在資料庫","Move failed:":"搬移失敗:","My Documents":"My Documents","My Music":"My Music","My Photos":"My Photos","My Pictures":"My Pictures","Name":"名稱","Never":"從未","New update found: {{message}}":"發現最新版本:{{message}}","New user name is {{user}}.\nUpdated credentials to use the new limited user":"新使用者名稱是 {{user}}.\n更新憑證以使用新的受限使用者帳號","Next":"下一","Next scheduled run:":"下一次排程執行時間:","Next scheduled task:":"下一個排程工作:","Next task:":"下一個工作:","Next time":"下一次","No":"否","No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?":"No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?","No editor found for the &quot;{{backend}}&quot; storage type":"找不到 &quot;{{backend}}&quot; 儲存區類型","No encryption":"不加密","No items selected":"沒有選擇","No items to restore, please select one or more items":"沒有要還原的項目,請至少選擇一個項目","No passphrase entered":"沒有輸入密碼","No scheduled tasks":"沒有排程工作","Non-matching passphrase":"密碼不相符","None / disabled":"無 / 取消","OK":"好","OpenStack AuthURI":"OpenStack AuthURI","OpenStack Object Storage / Swift":"OpenStack Object Storage / Swift","Operation failed:":"操作失敗:","Operations:":"操作:","Optional authentication password":"(非必要)認證密碼","Optional authentication username":"(非必要)認證帳號","Options":"選項","Original location":"原始位置","Others":"其它","Overwrite":"覆寫","Passphrase":"密碼","Passphrase (if encrypted)":"密碼 (如果已加密)","Passphrase changed":"密碼已變更","Passphrases are not matching":"密碼不相符","Password":"密碼","Passwords do not match":"密碼不符","Patching files with local blocks ...":"使用本機區塊修復檔案中 ...","Path not found":"找不到路徑","Path on server":"伺服器路徑","Path or subfolder in the bucket":"Bucket 裡的路徑或子資料夾","Pause":"暫停","Pause after startup or hibernation":"當啟動或休眠後暫停","Pause options":"暫停選項","Permissions":"權限","Pick location":"選擇位置","Point to your backup files and restore from there":"指向您的備份檔案,將會由此還原","Port":"連接埠","Previous":"上一頁","ProjectID is optional if the bucket exist":"ProjectID is optional if the bucket exist","Proprietary":"所有權","Purging files ...":"清理檔案 ...","Rebuilding local database ...":"正在重建本機資料庫 ...","Recreate (delete and repair)":"重新建立(刪除並修復)","Recreating database ...":"正在重建資料庫 ...","Registering temporary backup ...":"正在註冊暫時備份 ...","Relative paths not allowed":"不允許使用相對路徑","Reload":"重新載入","Remote":"入遠端","Remove":"移除","Remove option":"移除選項","Repair":"修復","Reparing ...":"正在修復 ...","Repeat Passphrase":"重複密碼","Reporting:":"報告︰","Reset":"重置","Restore":"還原","Restore files":"還原檔案","Restore files ...":"還原檔案 ...","Restore files from {{backupname}}":"從 {{backupname}} 還原檔案","Restore from":"還原檔案從 ","Restore from backup configuration":"從備份設定檔還原","Restore from configuration ...":"從設定檔還原 ...","Restore options":"還原選項","Restore read/write permissions":"還原讀/寫權限","Restoring files ...":"正在還原檔案 ...","Resume":"繼續","Run again every":"重複執行於每","Run now":"立即執行","Running ...":"正在執行 ...","Running task:":"正在執行工作:","S3 Compatible":"S3 相容","Same as the base install version: {{channelname}}":"Same as the base install version: {{channelname}}","Sat":"週六","Save":"儲存","Save and repair":"儲存並修復","Save different versions with timestamp in file name":"在檔案名稱中儲存不同版本的時間戳記","Save immediately":"立即儲存","Scanning existing files ...":"正在掃描已存在檔案 ...","Scanning for local blocks ...":"正在掃描本機區塊 ...","Schedule":"排程","Search":"搜尋","Search for files":"搜尋檔案","Seconds":"秒","Select a log level and see messages as they happen:":"選擇一個記錄等級以查看訊息︰","Select files":"選擇檔案","Server":"伺服器","Server and port":"伺服器與連接埠","Server hostname or IP":"伺服器名稱或 IP","Server is currently paused,":"伺服器目前已暫停,","Server is currently paused, do you want to resume now?":"伺服器目前已暫停,請問您現在要繼續嗎?","Server paused":"伺服器目前已暫停","Server state properties":"伺服器狀態屬性","Settings":"設定","Show":"顯示","Show advanced editor":"顯示進階編輯器","Show hidden folders":"顯示隱藏資料夾","Show log":"顯示記錄","Show log ...":"顯示記錄 ...","Show treeview":"顯示樹狀清單","Some OpenStack providers allow an API key instead of a password and tenant name":"某些 OpenStack 供應商允許 API Key 而不用密碼與 Tenant 名稱","Source Data":"來源資料","Source data":"來源資料","Source folders":"來源資料夾","Source:":"來源:","Specific builds for developers only.":"Specific builds for developers only.","Standard protocols":"標準通訊協定","Starting ...":"正在開始 ...","Starting the restore process ...":"正在開始還原程序 ...","Storage Type":"儲存區類型","Storage class":"儲存區等級","Storage class for creating a bucket":"建立 Bucket 的儲存類型","Stored":"儲存","Strong":"強","Success":"成功","Sun":"週日","Symbolic link":"符號連結","System default ({{levelname}})":"系統預設 ({{levelname}})","System files":"系統檔案","System info":"系統資訊","System properties":"系統屬性","TByte":"TByte","TByte/s":"TByte/s","Task is running":"工作正在執行","Temporary files":"暫存檔案","Tenant Name":"Tenant 名稱","Test connection":"測試連線","Testing ...":"測試中 ...","Testing connection ...":"正在測試連線 ...","Testing permissions ...":"正在測試權限 ...","Testing permissions...":"正在測試權限 ...","The bucket name should be all lower-case, convert automatically?":"Bucket 名稱應該全部小寫,要自動轉換嗎?","The bucket name should start with your username, prepend automatically?":"Bucket 名稱應該以您的使用者名稱開頭,要自動加入嗎?","The connection to the server is lost, attempting again in {{time}} ...":"連接伺服器的失敗,再次嘗試 {{}}......","The folder {{folder}} does not exist\nCreate it now?":"找不到資料夾 {{folder}} ,是否立即建立?","The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key \"{{prev}}\" with the REPORTED host key: {{key}}?":"主機金鑰已變更,如果是正確的請您與伺服器管理員聯繫,否則您可能已遭受中間人攻擊。\n\n你想要更換原先的主機金鑰 \"{{prev}}\" 到 {{key}} 嗎?","The path does not appear to exist, do you want to add it anyway?":"路徑似乎不存在,無論如何你都要加入嗎?","The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?":"The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?","The path must be an absolute path, i.e. it must start with a forward slash '/'":"必須是絕對路徑,也就是說必須以斜線開頭 '/'","The region parameter is only applied when creating a new bucket":"區域參數只有在建立新 Bucket 時套用","The region parameter is only used when creating a bucket":"區域參數只使用在在建立新 Bucket 時","The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?":"伺服器無法驗證。\n您要使用這個 SSL 憑證 {{hash}} 嗎?","The storage class affects the availability and price for a stored file":"儲存區類型會影響到可用性以及... 價格","The target folder contains encrypted files, please supply the passphrase":"目的資料夾中包含加密檔案,請提供密碼","The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?":"The user has too many permissions. Do you want to create a new limited user, with only permissions to the selected path?","This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?":"This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?","This month":"本月","This week":"本週","Thu":"週四","To File":"到檔案","To confirm you want to delete all remote files for \"{{name}}\", please enter the word you see below":"確認要刪除所有的遠端檔案 \"{{name}}\",請輸入下面的單字","To export without a passphrase, uncheck the \"Encrypt file\" box":"若要無密碼匯出,請不要勾選\"加密檔案\"核取方塊","Today":"今天","Trust host certificate?":"信任主機憑證?","Trust server certificate?":"信任伺服器憑證?","Try out the new features we are working on. Don't use with important data.":"試試我們正在進行的新功能。不要使用在重要的資料上。","Tue":"週二","Type to highlight files":"Type to highlight files","Unknown backup size and versions":"未知的備份大小與版本","Until resumed":"直到恢復","Update channel":"更新分支","Update failed:":"更新失敗:","Updating with existing database":"正在更新已存在資料庫 ...","Upload volume size":"上傳區塊大小","Uploading verification file ...":"正在上傳驗證檔案 ...","Usage reports help us improve the user experience and evaluate impact of new features. We use them to generate <a href=\"{{link}}\" target=\"_blank\">public usage statistics</a>":"使用報告可以協助改善使用者體驗,並用以評估新功能。我們靠他來產生 <a href=\"{{link}}\" target=\"_blank\">公開使用統計</a>","Usage statistics":"使用統計","Usage statistics, warnings, errors, and crashes":"使用統計、警告、錯誤與當機","Use SSL":"使用 SSL","Use existing database?":"使用已存在資料庫?","Use weak passphrase":"使用低強度密碼","Useless":"不使用","User data":"使用者資料","User has too many permissions":"使用者有太多權限","Username":"使用者","VISA, Mastercard, ... via Paypal":"VISA、Mastercard、 ... 透過 Paypal","Validating ...":"確認中 ...","Verify files":"驗證檔案","Verifying ...":"驗證中 ...","Verifying answer":"驗證答案","Verifying backend data ...":"正在驗證後端資料 ...","Verifying remote data ...":"正在驗證遠端資料 ...","Verifying restored files ...":"正在驗證已還原檔案 ...","Very strong":"非常強","Very weak":"非常弱","Visit us on":"拜訪我們","WARNING: The remote database is found to be in use by the commandline library":"WARNING: The remote database is found to be in use by the commandline library","WARNING: This will prevent you from restoring the data in the future.":"警告︰ 這將會阻止您日後還原資料。","Waiting for task to begin":"正在等待工作開始","Waiting for upload ...":"正在等待上傳 ...","Warnings, errors and crashes":"警告、錯誤與當機","We recommend that you encrypt all backups stored outside your system":"我們建議您加密在您的系統以外的所有備份儲存","Weak":"弱","Weak passphrase":"弱密碼","Wed":"週三","Weeks":"週","Where do you want to restore from?":"您要從那裡還原?","Where do you want to restore the files to?":"您要還原檔案到哪裡?","Years":"年","Yes":"是","Yes, I have stored the passphrase safely":"是,我已安全的儲存密碼","Yes, I'm brave!":"是的,我敢!","Yes, please break my backup!":"是,請中斷我的備份!","Yesterday":"昨天","You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?":"您正在運行 Mono 似乎沒有載入 SSL 相關憑證。\n要從 Mozilla 匯入受信任的憑證清單嗎?","You are changing the database path away from an existing database.\nAre you sure this is what you want?":"您正在變更現有資料庫的路徑。\n您確定這是您想要的嗎?","You are currently running {{appname}} {{version}}":"您正在執行 {{appname}} {{version}}","You have changed the encryption mode. This may break stuff. You are encouraged to create a new backup instead":"您已變更加密模式。這可能導致資料損毀。我們建議您建立一個新的備份","You have changed the passphrase, which is not supported. You are encouraged to create a new backup instead.":"您變更加密密碼,這個動作不被支援。我們建議您建立一個新的備份。","You have chosen not to encrypt the backup. Encryption is recommended for all data stored on a remote server.":"您已選擇備份不加密。建議將存在遠端伺服器上的資料予以加密。","You have chosen to restore to a new location, but not entered one":"You have chosen to restore to a new location, but not entered one","You have generated a strong passphrase. Make sure you have made a safe copy of the passphrase, as the data cannot be recovered if you loose the passphrase.":"您有產生高強度的密碼,請確認您已經另外保存好這個密碼,若遺失這個密碼,您的資料將無法恢復。","You must choose at least one source folder":"您至少要選擇一個來源資料夾","You must enter a name for the backup":"您必須輸入備份名稱","You must enter a passphrase or disable encryption":"您必須輸入密碼或取消加密","You must enter a positive number of backups to keep":"您必須輸入正數,備份才能保存","You must enter a tenant name if you do not provide an API Key":"如果您不提供 API Key,您必須輸入 Tenant 名稱","You must enter a valid duration for the time to keep backups":"您必須輸入有效的起迄時間來保留備份","You must enter either a password or an API Key":"您必須輸入密碼或 API Key","You must enter either a password or an API Key, not both":"您必須輸入密碼或者 API Key,二擇一","You must fill in the password":"您必須輸入密碼","You must fill in the server name or address":"您必須填寫伺服器名稱或位址","You must fill in the username":"您必須填寫使用者名稱","You must fill in {{field}}":"您必須填寫 {{field}}","You must select or fill in the AuthURI":"您必須選擇或填寫 AuthURI","You must select or fill in the server":"您必須選擇或填寫伺服器","You must specify a path":"您必須指定一個路徑","Your files and folders have been restored successfully.":"您的檔案與資料夾已成功還原。","Your passphrase is easy to guess. Consider changing passphrase.":"您的密碼很容易被猜到。請考慮變更密碼。","a specific number":"指定數目","bucket/folder/subfolder":"bucket/folder/subfolder","byte":"byte","byte/s":"byte/s","custom":"自訂","resume now":"立即繼續","{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.":"{{appname}} was primarily developed by <a href=\"{{mail1}}\">{{dev1}}</a> and <a href=\"{{mail2}}\">{{dev2}}</a>. {{appname}} can be downloaded from <a href=\"{{websitelink}}\">{{websitename}}</a>. {{appname}} is licensed under the <a href=\"{{licenselink}}\">{{licensename}}</a>.","{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version":"{{item.Backup.Metadata.TargetSizeString}} / {{$count}} 個版本","{{number}} Hour":"{{number}} 小時","{{number}} Minutes":"{{number}} 分鐘","{{time}} (took {{duration}})":"{{time}} (花費 {{duration}})"});
/* jshint +W100 */
}]); \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/scripts/app.js b/Duplicati/Server/webroot/ngax/scripts/app.js
index 1099329b8..6f6a05cb0 100644
--- a/Duplicati/Server/webroot/ngax/scripts/app.js
+++ b/Duplicati/Server/webroot/ngax/scripts/app.js
@@ -5,7 +5,8 @@ var backupApp = angular.module(
'dotjem.angular.tree',
'ngCookies',
'ngSanitize',
- 'gettext'
+ 'gettext',
+ 'ngclipboard'
]
);
@@ -22,12 +23,24 @@ backupApp.config(['$routeProvider',
when('/add', {
templateUrl: 'templates/addoredit.html'
}).
+ when('/add-import', {
+ templateUrl: 'templates/addoredit.html'
+ }).
+ when('/restorestart', {
+ templateUrl: 'templates/restorewizard.html'
+ }).
+ when('/addstart', {
+ templateUrl: 'templates/addwizard.html'
+ }).
when('/edit/:backupid', {
templateUrl: 'templates/addoredit.html'
}).
when('/restoredirect', {
templateUrl: 'templates/restoredirect.html'
}).
+ when('/restoredirect-import', {
+ templateUrl: 'templates/restoredirect.html'
+ }).
when('/restore/:backupid', {
templateUrl: 'templates/restore.html'
}).
@@ -37,6 +50,9 @@ backupApp.config(['$routeProvider',
when('/about', {
templateUrl: 'templates/about.html'
}).
+ when('/delete/:backupid', {
+ templateUrl: 'templates/delete.html'
+ }).
when('/log/:backupid', {
templateUrl: 'templates/log.html'
}).
@@ -52,11 +68,20 @@ backupApp.config(['$routeProvider',
when('/import', {
templateUrl: 'templates/import.html'
}).
+ when('/restore-import', {
+ templateUrl: 'templates/import.html'
+ }).
when('/localdb/:backupid', {
templateUrl: 'templates/localdatabase.html'
}).
- when('/pause', {
- templateUrl: 'templates/pause.html'
+ when('/commandline', {
+ templateUrl: 'templates/commandline.html'
+ }).
+ when('/commandline/:backupid', {
+ templateUrl: 'templates/commandline.html'
+ }).
+ when('/commandline/view/:viewid', {
+ templateUrl: 'templates/commandline.html'
}).
otherwise({
templateUrl: 'templates/home.html'
@@ -75,3 +100,25 @@ backupApp.run(function($injector) {
$injector.get('ProxyService');
} catch(e) {}
});
+
+// Registers a global parseInt function
+angular.module('backupApp').run(function($rootScope){
+ $rootScope.parseInt = function(str) {
+ return parseInt(str);
+ };
+});
+
+// Register a global back function
+/*backupApp.run(function ($rootScope, $location) {
+
+ var history = [];
+ $rootScope.$on('$routeChangeSuccess', function() {
+ history.push($location.$$path);
+ });
+
+ $rootScope.back = function () {
+ var prevUrl = history.length > 1 ? history.splice(-2)[0] : "/home";
+ $location.path(prevUrl);
+ };
+
+});*/
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/AddWizardController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/AddWizardController.js
new file mode 100644
index 000000000..b2e36f08a
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/AddWizardController.js
@@ -0,0 +1,13 @@
+backupApp.controller('AddWizardController', function($scope, $location, gettextCatalog) {
+
+ $scope.selection = {
+ style: 'blank'
+ };
+
+ $scope.nextPage = function() {
+ if ($scope.selection.style == 'blank')
+ $location.path('/add');
+ else
+ $location.path('/import');
+ };
+});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js
index 355055802..9d93e9aad 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js
@@ -1,11 +1,183 @@
-backupApp.controller('AppController', function($scope, BrandingService, ServerStatus, SystemInfo) {
+backupApp.controller('AppController', function($scope, $cookies, $location, AppService, BrandingService, ServerStatus, SystemInfo, AppUtils, DialogService, gettextCatalog) {
$scope.brandingService = BrandingService.watch($scope);
$scope.state = ServerStatus.watch($scope);
$scope.systemInfo = SystemInfo.watch($scope);
-
+
$scope.localized = {};
+ $scope.location = $location;
+ $scope.saved_theme = $scope.active_theme = $cookies.get('current-theme') || 'default';
+ $scope.throttle_active = false;
+
+ // If we want the theme settings
+ // to be persisted on the server,
+ // set to "true" here
+ var save_theme_on_server = false;
$scope.doReconnect = function() {
ServerStatus.reconnect();
};
+
+ $scope.resume = function() {
+ ServerStatus.resume().then(function() {}, AppUtils.connectionError);
+ };
+
+ $scope.pause = function(duration) {
+ ServerStatus.pause(duration).then(function() {}, AppUtils.connectionError);
+ };
+
+ $scope.isLoggedIn = $cookies.get('session-auth') != null && $cookies.get('session-auth') != '';
+
+ $scope.log_out = function() {
+ AppService.log_out().then(function() {
+ $cookies.remove('session-auth', { path: '/' });
+ location.reload(true);
+ }, AppUtils.connectionError);
+ };
+
+ $scope.pauseOptions = function() {
+ if ($scope.state.programState != 'Running') {
+ $scope.resume();
+ } else {
+ DialogService.htmlDialog(
+ gettextCatalog.getString('Pause options'),
+ 'templates/pause.html',
+ [gettextCatalog.getString('OK'), gettextCatalog.getString('Cancel')],
+ function(index, text, cur) {
+ if (index == 0 && cur != null && cur.time != null) {
+ var time = cur.time;
+ $scope.pause(time == 'infinite' ? '' : time);
+ }
+ }
+ );
+ }
+ };
+
+ $scope.throttleOptions = function() {
+ DialogService.htmlDialog(
+ gettextCatalog.getString('Throttle settings'),
+ 'templates/throttle.html',
+ [gettextCatalog.getString('OK'), gettextCatalog.getString('Cancel')],
+ function(index, text, cur) {
+ if (index == 0 && cur != null && cur.uploadspeed != null && cur.downloadspeed != null) {
+ var patchdata = {
+ 'max-download-speed': cur.downloadthrottleenabled ? cur.downloadspeed : '',
+ 'max-upload-speed': cur.uploadthrottleenabled ? cur.uploadspeed : '',
+ };
+
+ AppService.patch('/serversettings', patchdata, {headers: {'Content-Type': 'application/json; charset=utf-8'}}).then(function(data) {
+ $scope.throttle_active = cur.downloadthrottleenabled || cur.uploadthrottleenabled;
+ }, AppUtils.connectionError);
+ }
+ }
+ );
+ };
+
+ function updateCurrentPage() {
+
+ $scope.active_theme = $scope.saved_theme;
+
+ if ($location.$$path == '/' || $location.$$path == '')
+ $scope.current_page = 'home';
+ else if ($location.$$path == '/addstart' || $location.$$path == '/add' || $location.$$path == '/import')
+ $scope.current_page = 'add';
+ else if ($location.$$path == '/restorestart' || $location.$$path == '/restore' || $location.$$path == '/restoredirect' || $location.$$path.indexOf('/restore/') == 0)
+ $scope.current_page = 'restore';
+ else if ($location.$$path == '/settings')
+ $scope.current_page = 'settings';
+ else if ($location.$$path == '/log')
+ $scope.current_page = 'log';
+ else if ($location.$$path == '/about')
+ $scope.current_page = 'about';
+ else
+ $scope.current_page = '';
+ };
+
+ $scope.$on('serverstatechanged', function() {
+ // Unwanted jQuery interference, but the menu is built with this
+ if (ServerStatus.state.programState == 'Paused') {
+ $('#contextmenu_pause').removeClass('open');
+ $('#contextmenulink_pause').removeClass('open');
+ }
+ });
+
+ //$scope.$on('$routeUpdate', updateCurrentPage);
+ $scope.$watch('location.$$path', updateCurrentPage);
+ updateCurrentPage();
+
+ function loadCurrentTheme() {
+ if (save_theme_on_server) {
+ AppService.get('/uisettings/ngax').then(
+ function(data) {
+ var theme = 'default';
+ if (data.data != null && (data.data['theme'] || '').trim().length > 0)
+ theme = data.data['theme'];
+
+ var now = new Date();
+ var exp = new Date(now.getFullYear()+10, now.getMonth(), now.getDate());
+ $cookies.put('current-theme', theme, { expires: exp });
+ $scope.saved_theme = $scope.active_theme = theme;
+ }, function() {}
+ );
+ }
+ };
+
+ // In case the cookie is out-of-sync
+ loadCurrentTheme();
+
+ $scope.$on('update_theme', function(event, args) {
+ var theme = 'default';
+ if (args != null && (args.theme || '').trim().length != 0)
+ theme = args.theme;
+
+ if (save_theme_on_server) {
+ // Set it here to avoid flickering when the page changes
+ $scope.saved_theme = $scope.active_theme = theme;
+
+ AppService.patch('/uisettings/ngax', { 'theme': theme }, {'headers': {'Content-Type': 'application/json'}}).then(
+ function(data) {
+ var now = new Date();
+ var exp = new Date(now.getFullYear()+10, now.getMonth(), now.getDate());
+ $cookies.put('current-theme', theme, { expires: exp });
+ $scope.saved_theme = $scope.active_theme = theme;
+ }, function() {}
+ );
+ } else {
+ var now = new Date();
+ var exp = new Date(now.getFullYear()+10, now.getMonth(), now.getDate());
+ $cookies.put('current-theme', theme, { expires: exp });
+ $scope.saved_theme = $scope.active_theme = theme;
+ }
+
+ loadCurrentTheme();
+ });
+
+ $scope.$on('preview_theme', function(event, args) {
+ if (args == null || (args.theme + '').trim().length == 0)
+ $scope.active_theme = $scope.saved_theme;
+ else
+ $scope.active_theme = args.theme || '';
+ });
+
+ AppService.get('/serversettings').then(function(data) {
+ var ut = data.data['max-upload-speed'];
+ var dt = data.data['max-download-speed'];
+ $scope.throttle_active = (ut != null && ut.trim().length != 0) || (dt != null && dt.trim().length != 0);
+
+ var firstpw = data.data['has-asked-for-password-protection'];
+ var haspw = data.data['server-passphrase'];
+ if (!firstpw && haspw == '') {
+ DialogService.dialog(
+ gettextCatalog.getString('First run setup'),
+ gettextCatalog.getString('If your machine is in a multi-user environment (i.e. the machine has more than one account), you need to set a password to prevent other users from accessing data on your account.\nDo you want to set a password now?'),
+ [gettextCatalog.getString('No, my machine has only a single account'), gettextCatalog.getString('Yes')],
+ function(btn) {
+ AppService.patch('/serversettings', { 'has-asked-for-password-protection': 'true'}, {'headers': {'Content-Type': 'application/json'}});
+ if (btn == 1) {
+ $location.path('/settings');
+ }
+ }
+ );
+ }
+
+ }, AppUtils.connectionError);
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/CaptchaController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/CaptchaController.js
new file mode 100644
index 000000000..2238e66ff
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/CaptchaController.js
@@ -0,0 +1,21 @@
+backupApp.controller('CaptchaController', function($scope, CaptchaService, DialogService, AppService, AppUtils) {
+ var entry = $scope.entry = CaptchaService.active;
+
+ function refreshImage() {
+ entry.imageurl = null;
+
+ AppService.post('/captcha', { 'target': entry.target}).then(function(resp) {
+ entry.token = resp.data.token;
+ entry.imageurl = AppService.apiurl + '/captcha/' + entry.token;
+
+ }, function(err) {
+ DialogService.dismissCurrent();
+ AppUtils.connectionError(err);
+ });
+ };
+
+ if (entry.token == null)
+ refreshImage();
+
+ $scope.reload = refreshImage;
+});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/CommandlineController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/CommandlineController.js
new file mode 100644
index 000000000..c9df0ea1d
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/CommandlineController.js
@@ -0,0 +1,174 @@
+backupApp.controller('CommandlineController', function($scope, $routeParams, $location, $timeout, SystemInfo, ServerStatus, AppUtils, AppService, DialogService, gettextCatalog) {
+ $scope.SystemInfo = SystemInfo.watch($scope);
+ $scope.ServerStatus = ServerStatus;
+ $scope.serverstate = ServerStatus.watch($scope);
+
+ $scope.ExtendedOptions = [];
+ $scope.Arguments = [];
+ $scope.Running = false;
+ $scope.Mode = 'submit';
+ $scope.ViewLines = [];
+ $scope.Started = null;
+ $scope.Finished = false;
+ $scope.RawFinished = false;
+
+ var viewid = null;
+ var view_offset = 0;
+ var view_refreshing = false;
+ var view_timer = null;
+ var scope = $scope;
+
+ function reloadOptionsList()
+ {
+ var opts = AppUtils.parseOptionStrings($scope.ExtendedOptions || []);
+
+ var encmodule = opts['encryption-module'] || opts['--encryption-module'] || '';
+ var compmodule = opts['compression-module'] || opts['--compression-module'] || 'zip';
+ var backmodule = $scope.TargetURL || '';
+ var ix = backmodule.indexOf(':');
+ if (ix > 0)
+ backmodule = backmodule.substr(0, ix);
+
+ $scope.ExtendedOptionList = AppUtils.buildOptionList($scope.SystemInfo, encmodule, compmodule, backmodule);
+ };
+
+ $scope.$watchCollection("ExtendedOptions", reloadOptionsList);
+ $scope.$watch("TargetURL", reloadOptionsList);
+ $scope.$on('systeminfochanged', reloadOptionsList);
+
+ reloadOptionsList();
+
+ var scope = $scope;
+
+ $scope.HideEditUri = function() {
+ scope.EditUriState = false;
+ };
+
+ $scope.run = function() {
+
+ var opts = AppUtils.parseOptionStrings($scope.ExtendedOptions || []);
+ var combined = angular.copy($scope.Arguments || []);
+
+ if (($scope.TargetURL || '').trim().length != 0)
+ combined.unshift($scope.TargetURL);
+
+ combined.unshift($scope.Command);
+
+ for(n in opts) {
+ if (opts[n] == null)
+ combined.push(n);
+ else
+ combined.push(n + '=' + opts[n]);
+ }
+
+ options = {
+ headers: {'Content-Type': 'application/json; charset=utf-8'},
+ responseType: 'text'
+ };
+
+ AppService.post('/commandline', combined, options).then(
+ function(resp) {
+ $location.path('/commandline/view/' + resp.data.ID);
+ },
+ function(resp) {
+ DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
+ }
+ );
+ };
+
+ $scope.Abort = function()
+ {
+ AppService.post('/commandline/' + viewid + '/abort' ).then(function(resp) {
+
+ }, function() {
+ AppUtils.connectionError.apply(AppUtils, arguments);
+ });
+
+ };
+
+ function FetchOutputLines()
+ {
+ if (view_refreshing)
+ return;
+
+ view_refreshing = true;
+ if (view_timer != null) {
+ $timeout.cancel(view_timer);
+ view_timer = null;
+ }
+
+ AppService.get('/commandline/' + viewid + '?pagesize=100&offset=' + view_offset).then(function(resp) {
+ $scope.ViewLines.push.apply($scope.ViewLines, resp.data.Items);
+ view_offset = view_offset + resp.data.Items.length;
+
+ while ($scope.ViewLines.length > 2000)
+ $scope.ViewLines.shift();
+
+ $scope.Started = resp.data.Started;
+ $scope.Finished = resp.data.Finished && view_offset == resp.data.Count;
+ $scope.RawFinished = resp.data.Finished;
+
+ view_refreshing = false;
+ var wait_time = 2000;
+
+ // Fetch more as we are not empty
+ if (resp.data.Items.length != 0)
+ wait_time = 100;
+ // All done, slowly keep the data alive
+ else if (resp.data.Finished)
+ wait_time = 10000;
+
+ view_timer = $timeout(FetchOutputLines, wait_time);
+
+ }, function(resp) {
+ $scope.Started = true;
+ if (resp.status == 404) {
+ $scope.ViewLines.push('Connection lost, data has expired ...');
+ $scope.Finished = true;
+ } else {
+ $scope.ViewLines.push('Connection error, retry in 2 sec ...');
+ view_refreshing = false;
+ view_timer = $timeout(FetchOutputLines, 2000);
+ }
+ });
+ };
+
+ AppService.get('/commandline').then(function(resp) {
+ var cmds = [];
+ for (var i = resp.data.length - 1; i >= 0; i--)
+ cmds.push(resp.data[i]);
+
+ $scope.SupportedCommands = cmds;
+ $scope.Command = 'help';
+
+ }, function() {
+ AppUtils.connectionError.apply(AppUtils, arguments);
+ $location.path('/');
+ });
+
+ if ($routeParams.viewid != null) {
+ $scope.Mode = 'view';
+ viewid = $routeParams.viewid;
+ view_offset = 0;
+
+ FetchOutputLines();
+ }
+
+ if ($routeParams.backupid != null) {
+ AppService.get('/backup/' + $routeParams.backupid + '/export?argsonly=true').then(
+ function(resp) {
+ $scope.TargetURL = resp.data.Backend;
+ $scope.Arguments = resp.data.Arguments;
+ $scope.ExtendedOptions = resp.data.Options;
+ $scope.Command = 'backup';
+ },
+ function(resp) {
+ var message = resp.statusText;
+ if (resp.data != null && resp.data.Message != null)
+ message = resp.data.Message;
+
+ DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
+ }
+ );
+ }
+}); \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/DeleteController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/DeleteController.js
new file mode 100644
index 000000000..c7729edb5
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/DeleteController.js
@@ -0,0 +1,91 @@
+backupApp.controller('DeleteController', function($scope, $routeParams, $location, gettextCatalog, CaptchaService, DialogService, ServerStatus, SystemInfo, BackupList, AppService, AppUtils) {
+ $scope.BackupID = $routeParams.backupid;
+ $scope.DeleteLocalDatabase = true;
+ $scope.DeleteRemoteFiles = false;
+
+ function resetBackupItem(force) {
+ var prev = $scope.DBPath;
+
+ $scope.Backup = BackupList.lookup[$scope.BackupID];
+ $scope.DBPath = null;
+
+ if ($scope.Backup == null || $scope.Backup.Backup == null) {
+ $scope.NoLocalDB = true;
+ $scope.DbUsedElsewhere = false;
+ } else {
+ $scope.DBPath = $scope.Backup.Backup.DBPath;
+
+ if ($scope.DBPath != prev || force)
+ AppService.post('/filesystem/validate', {path: $scope.DBPath}).then(function(resp) {
+ $scope.NoLocalDB = false;
+ }, function() {
+ $scope.NoLocalDB = true;
+ });
+
+ if ($scope.DBPath != prev || force)
+ AppService.get('/backup/' + $scope.BackupID + '/isdbusedelsewhere', {path: $scope.DBPath}).then(function(resp) {
+ $scope.DbUsedElsewhere = resp.data.inuse;
+ // Default to not delete the db if others use it
+ if (resp.data.inuse)
+ $scope.DeleteLocalDatabase = false;
+
+ }, function() {
+ $scope.DbUsedElsewhere = true;
+ });
+ }
+
+ if ($scope.Backup != null && !$scope.hasRefreshedRemoteSize && ($scope.Backup.Backup.Metadata.TargetFilesCount == null || $scope.Backup.Backup.Metadata.TargetFilesCount <= 0))
+ {
+ $scope.hasRefreshedRemoteSize = true;
+ AppService.post('/backup/' + $scope.BackupID + '/report-remote-size').then(
+ function(resp) {
+
+ var taskid = resp.data.ID;
+ $scope.list_files_taskid = taskid;
+
+ ServerStatus.callWhenTaskCompletes(taskid, function() {
+
+ });
+ }, AppUtils.connectionError);
+ }
+
+ };
+
+ $scope.$on('backuplistchanged', resetBackupItem);
+ resetBackupItem();
+
+ $scope.doExport = function() {
+ $location.path('/export/' + $scope.BackupID);
+ };
+
+ $scope.doDelete = function() {
+ if ($scope.DeleteRemoteFiles)
+ {
+ CaptchaService.Authorize(
+ gettextCatalog.getString('Confirm delete'),
+ gettextCatalog.getString('To confirm you want to delete all remote files for "{{name}}", please enter the word you see below', {name: $scope.Backup.Backup.Name}),
+ 'DELETE /backup/' + $scope.BackupID,
+ function(token, answer) {
+ AppService.delete('/backup/' + $scope.BackupID + '?delete-local-db=' + $scope.DeleteLocalDatabase + '&delete-remote-files=' + $scope.DeleteRemoteFiles + '&captcha-token=' + token + '&captcha-answer=' + answer).then(function() {
+ $location.path('/');
+ }, AppUtils.connectionError);
+ }
+ );
+ }
+ else
+ {
+ DialogService.dialog(gettextCatalog.getString('Confirm delete'), gettextCatalog.getString('Do you really want to delete the backup: "{{name}}" ?', {name: $scope.Backup.Backup.Name}), [gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
+ if (ix == 1) {
+ AppService.delete('/backup/' + $scope.BackupID + '?delete-local-db=' + $scope.DeleteLocalDatabase + '&delete-remote-files=' + $scope.DeleteRemoteFiles).then(function() {
+ $location.path('/');
+ }, AppUtils.connectionError);
+ }
+ });
+ }
+ };
+
+ $scope.goBack = function() {
+ $location.path('/');
+ };
+
+});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/DialogController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/DialogController.js
index ec45eaa5f..9b471600d 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/DialogController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/DialogController.js
@@ -1,12 +1,32 @@
-backupApp.controller('DialogController', function($scope, DialogService) {
+backupApp.controller('DialogController', function($scope, DialogService, gettextCatalog) {
$scope.state = DialogService.watch($scope);
+ function showTooltip(elem, msg) {
+ elem.addEventListener('mouseleave', function(e) {
+ e.currentTarget.setAttribute('class', 'button');
+ e.currentTarget.removeAttribute('aria-label');
+ });
+
+ elem.setAttribute('class', 'button tooltipped tooltipped-w');
+ elem.setAttribute('aria-label', msg);
+ }
+
+ $scope.onCopySuccess = function(e) {
+ e.clearSelection();
+ showTooltip(e.trigger, gettextCatalog.getString('Copied!'));
+ };
+
+ $scope.onCopyError = function(e) {
+ showTooltip(e.trigger, gettextCatalog.getString('Copy failed. Please manually copy the URL'));
+ };
+
$scope.onButtonClick = function(index) {
- var cur = $scope.state.CurrentItem;
+ var cur = $scope.state.CurrentItem;
+ var input = cur.textarea;
DialogService.dismissCurrent();
if (cur.callback)
- cur.callback(index);
+ cur.callback(index, input, cur);
};
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/EditBackupController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/EditBackupController.js
index 8e9f31e25..5ee523386 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/EditBackupController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/EditBackupController.js
@@ -1,4 +1,4 @@
-backupApp.controller('EditBackupController', function ($scope, $routeParams, $location, $timeout, AppService, AppUtils, SystemInfo, DialogService, EditBackupService, gettext, gettextCatalog) {
+backupApp.controller('EditBackupController', function ($rootScope, $scope, $routeParams, $location, $timeout, AppService, AppUtils, SystemInfo, DialogService, EditBackupService, gettext, gettextCatalog) {
$scope.SystemInfo = SystemInfo.watch($scope);
$scope.AppUtils = AppUtils;
@@ -6,14 +6,22 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
$scope.RepeatPasshrase = null;
$scope.PasswordStrength = 'unknown';
$scope.CurrentStep = 0;
- $scope.EditUriState = false;
$scope.showhiddenfolders = false;
$scope.EditSourceAdvanced = false;
$scope.EditFilterAdvanced = false;
+ $scope.DefaultFilters = [];
$scope.ExcludeAttributes = [];
$scope.ExcludeLargeFiles = false;
+ $scope.defaultFilterSetAll = 'All';
+ $scope.defaultFilterSets = [
+ { 'name': gettextCatalog.getString('Windows'), 'value': 'Windows' },
+ { 'name': gettextCatalog.getString('OSX'), 'value': 'OSX' },
+ { 'name': gettextCatalog.getString('Linux'), 'value': 'Linux' },
+ { 'name': gettextCatalog.getString('All'), 'value': $scope.defaultFilterSetAll },
+ ];
+
$scope.fileAttributes = [
{'name': gettextCatalog.getString('Hidden files'), 'value': 'hidden'},
{'name': gettextCatalog.getString('System files'), 'value': 'system'},
@@ -25,7 +33,6 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
function computePassPhraseStrength() {
var strengthMap = {
- '': gettextCatalog.getString("Empty"),
'x': gettextCatalog.getString("Passwords do not match"),
0: gettextCatalog.getString("Useless"),
1: gettextCatalog.getString("Very weak"),
@@ -43,7 +50,7 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
else
scope.PassphraseScore = (zxcvbn(passphrase) || {'score': -1}).score;
- scope.PassphraseScoreString = strengthMap[scope.PassphraseScore] || gettextCatalog.getString('Unknown');
+ scope.PassphraseScoreString = strengthMap[scope.PassphraseScore];
}
$scope.$watch('Options["passphrase"]', computePassPhraseStrength);
@@ -56,20 +63,32 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
};
$scope.togglePassphraseVisibility = function() {
- this.ShowPassphrase = !this.ShowPassphrase;;
+ this.ShowPassphrase = !this.ShowPassphrase;
};
$scope.nextPage = function() {
- $scope.CurrentStep = Math.min(3, $scope.CurrentStep + 1);
+ $scope.CurrentStep = Math.min(4, $scope.CurrentStep + 1);
};
$scope.prevPage = function() {
$scope.CurrentStep = Math.max(0, $scope.CurrentStep - 1);
+ };
+ $scope.setBuilduriFn = function(builduriFn) {
+ $scope.builduri = builduriFn;
};
- $scope.HideEditUri = function() {
- scope.EditUriState = false;
+ $scope.importUrl = function () {
+ DialogService.textareaDialog('Import URL', 'Enter a Backup destination URL:', null, gettextCatalog.getString('Enter URL'), [gettextCatalog.getString('Cancel'), gettextCatalog.getString('OK')], null, function(btn, input) {
+ if (btn == 1)
+ scope.Backup.TargetURL = input;
+ });
+ };
+
+ $scope.copyUrlToClipboard = function () {
+ $scope.builduri(function(res) {
+ DialogService.textareaDialog('Copy URL', null, null, res, [gettextCatalog.getString('OK')], 'templates/copy_clipboard_buttons.html');
+ });
};
var oldSchedule = null;
@@ -125,23 +144,19 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
}
});
});
- };
+ }
if (scope.manualSourcePath.substr(scope.manualSourcePath.length - 1, 1) != dirsep) {
- DialogService.dialog(gettextCatalog.getString('Include a file?'), gettextCatalog.getString("The path does not end with a '{0}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?", dirsep), [gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
+ DialogService.dialog(gettextCatalog.getString('Include a file?'), gettextCatalog.getString("The path does not end with a '{{dirsep}}' character, which means that you include a file, not a folder.\n\nDo you want to include the specified file?", {dirsep: dirsep}), [gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
if (ix == 1)
continuation();
});
} else {
continuation();
}
-
-
-
-
};
- $scope.toggleArraySelection = function (lst, value) {
+ function toggleArraySelection(lst, value) {
var ix = lst.indexOf(value);
if (ix > -1)
@@ -150,6 +165,61 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
lst.push(value);
};
+ $scope.toggleAllowedDays = function(value) {
+ if ($scope.Schedule.AllowedDays == null)
+ $scope.Schedule.AllowedDays = [];
+ toggleArraySelection($scope.Schedule.AllowedDays, value);
+ };
+
+ $scope.isDefaultFilterSetEnabled = function (value) {
+ if ($scope.DefaultFilters == null)
+ $scope.DefaultFilters = [];
+ if (value != $scope.defaultFilterSetAll && $scope.isDefaultFilterSetEnabled($scope.defaultFilterSetAll))
+ {
+ return true;
+ }
+
+ return $scope.DefaultFilters.indexOf(value) > -1;
+ };
+
+ $scope.toggleDefaultFilters = function (value) {
+ if ($scope.DefaultFilters == null)
+ $scope.DefaultFilters = [];
+ if (value == $scope.defaultFilterSetAll)
+ {
+ var wasAllEnabled = $scope.isDefaultFilterSetEnabled($scope.defaultFilterSetAll);
+ $scope.DefaultFilters = [];
+ if (!wasAllEnabled)
+ {
+ for (var index = 0; index < $scope.defaultFilterSets.length; index++)
+ {
+ $scope.DefaultFilters.push($scope.defaultFilterSets[index].value);
+ }
+ }
+ }
+ else
+ {
+ if ($scope.isDefaultFilterSetEnabled($scope.defaultFilterSetAll))
+ {
+ toggleArraySelection($scope.DefaultFilters, $scope.defaultFilterSetAll);
+ }
+
+ toggleArraySelection($scope.DefaultFilters, value);
+
+ // If everything but the 'all' group is enabled, enable it
+ if ($scope.DefaultFilters.length >= $scope.defaultFilterSets.length - 1)
+ {
+ toggleArraySelection($scope.DefaultFilters, $scope.defaultFilterSetAll);
+ }
+ }
+ };
+
+ $scope.toggleExcludeAttributes = function(value) {
+ if ($scope.ExcludeAttributes == null)
+ $scope.ExcludeAttributes = [];
+ toggleArraySelection($scope.ExcludeAttributes, value);
+ };
+
$scope.save = function() {
if (!EditBackupService.preValidate($scope))
@@ -160,7 +230,7 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
Schedule: angular.copy($scope.Schedule)
};
- var opts = angular.copy($scope.Options);
+ var opts = angular.copy($scope.Options, opts);
if (!$scope.ExcludeLargeFiles)
delete opts['--skip-files-larger-than'];
@@ -174,6 +244,30 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
if (!AppUtils.parse_extra_options(scope.ExtendedOptions, opts))
return false;
+ for (var n in $scope.servermodulesettings)
+ opts['--' + n] = $scope.servermodulesettings[n];
+
+ var defaultFilters = ($scope.DefaultFilters || []).concat((opts['--default-filters'] || '').split(/[,;\|]+/));
+ var filterMap = { '': true };
+
+ // Remove duplicates
+ for (var i = defaultFilters.length - 1; i >= 0; i--) {
+ defaultFilters[i] = (defaultFilters[i] || '').trim();
+ var cmp = defaultFilters[i].toLowerCase();
+ if (filterMap[cmp])
+ defaultFilters.splice(i, 1);
+ else
+ filterMap[cmp] = true;
+ }
+
+ if (defaultFilters.length == 0)
+ delete opts['--default-filters'];
+ else
+ if (filterMap[$scope.defaultFilterSetAll.toLowerCase()])
+ opts['--default-filters'] = $scope.defaultFilterSetAll;
+ else
+ opts['--default-filters'] = defaultFilters.join(',');
+
var exclattr = ($scope.ExcludeAttributes || []).concat((opts['--exclude-files-attributes'] || '').split(','));
var exclmap = { '': true };
@@ -190,7 +284,7 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
if (exclattr.length == 0)
delete opts['--exclude-files-attributes'];
else
- opts['--exclude-files-attributes'] = exclattr.join(',')
+ opts['--exclude-files-attributes'] = exclattr.join(',');
if (($scope.Backup.Name || '').trim().length == 0) {
DialogService.dialog(gettextCatalog.getString('Missing name'), gettextCatalog.getString('You must enter a name for the backup'));
@@ -213,15 +307,9 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
}
}
- if (($scope.Backup.TargetURL || '').trim().length == 0) {
- DialogService.dialog(gettextCatalog.getString('Missing destination'), gettextCatalog.getString('You must enter a destination where the backups are stored'));
- $scope.CurrentStep = 0;
- return;
- }
-
if ($scope.Backup.Sources == null || $scope.Backup.Sources.length == 0) {
DialogService.dialog(gettextCatalog.getString('Missing sources'), gettextCatalog.getString('You must choose at least one source folder'));
- $scope.CurrentStep = 1;
+ $scope.CurrentStep = 2;
return;
}
@@ -230,6 +318,21 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
if ($scope.KeepType == 'versions' || $scope.KeepType == '')
delete opts['keep-time'];
+ if ($scope.KeepType == 'time' && (opts['keep-time'] || '').trim().length == 0)
+ {
+ DialogService.dialog(gettextCatalog.getString('Invalid retention time'), gettextCatalog.getString('You must enter a valid duration for the time to keep backups'));
+ $scope.CurrentStep = 4;
+ return;
+ }
+
+ if ($scope.KeepType == 'versions' && (parseInt(opts['keep-versions']) <= 0 || isNaN(parseInt(opts['keep-versions']))))
+ {
+ DialogService.dialog(gettextCatalog.getString('Invalid retention time'), gettextCatalog.getString('You must enter a positive number of backups to keep'));
+ $scope.CurrentStep = 4;
+ return;
+ }
+
+
result.Backup.Settings = [];
for(var k in opts) {
var origfilter = "";
@@ -328,6 +431,19 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
};
+ function checkForValidBackupDestination(continuation) {
+ var success = false;
+ $scope.builduri(function(res) {
+ result.Backup.TargetURL = res;
+ $scope.Backup.TargetURL = res;
+ success = true;
+ continuation();
+ });
+
+ if (!success)
+ $scope.CurrentStep = 1;
+ }
+
function checkForDisabledEncryption(continuation) {
if (encryptionEnabled || $scope.Backup.TargetURL.indexOf('file://') == 0 || $scope.SystemInfo.EncryptionModules.length == 0)
continuation();
@@ -370,10 +486,12 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
// Chain calls
checkForGeneratedPassphrase(function() {
- checkForDisabledEncryption(function() {
- warnWeakPassphrase(function() {
- checkForExistingDb(function() {
- EditBackupService.postValidate($scope, postDb);
+ checkForValidBackupDestination(function() {
+ checkForDisabledEncryption(function() {
+ warnWeakPassphrase(function() {
+ checkForExistingDb(function () {
+ EditBackupService.postValidate($scope, postDb);
+ });
});
});
});
@@ -386,9 +504,11 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
AppService.put('/backup/' + $routeParams.backupid, result, {'headers': {'Content-Type': 'application/json'}}).then(function() {
$location.path('/');
}, AppUtils.connectionError);
- };
+ }
- checkForChangedPassphrase(putDb);
+ checkForChangedPassphrase(function() {
+ checkForValidBackupDestination(putDb);
+ });
}
};
@@ -420,6 +540,38 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
if ($scope.ExcludeLargeFiles)
$scope.Options['--skip-files-larger-than'] = extopts['--skip-files-larger-than'];
+ var defaultFilters = (extopts['--default-filters'] || '').split(/[,;\|]+/);
+ var defaultFiltersActive = [];
+ var filterMap = {};
+
+ for (var i = defaultFilters.length - 1; i >= 0; i--) {
+ var cmp = (defaultFilters[i] || '').trim().toLowerCase();
+
+ // Remove empty entries
+ if (cmp.length == 0) {
+ defaultFilters.splice(i, 1);
+ continue;
+ }
+
+ for (var j = scope.defaultFilterSets.length - 1; j >= 0; j--) {
+ if (scope.defaultFilterSets[j].value.toLowerCase() == cmp) {
+ // Remote duplicates
+ if (filterMap[cmp] == null) {
+ defaultFiltersActive.push(scope.defaultFilterSets[j].value);
+ filterMap[cmp] = true;
+ }
+ defaultFilters.splice(i, 1);
+ break;
+ }
+ }
+ }
+
+ $scope.DefaultFilters = defaultFiltersActive;
+ if (defaultFilters.length == 0)
+ delete extopts['--default-filters'];
+ else
+ extopts['--default-filters'] = defaultFilters.join(',');
+
var exclattr = (extopts['--exclude-files-attributes'] || '').split(',');
var dispattr = [];
var dispmap = {};
@@ -465,11 +617,16 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
$scope.KeepType = 'versions';
}
- var delopts = ['--skip-files-larger-than', '--no-encryption']
+ var delopts = ['--skip-files-larger-than', '--no-encryption'];
for(var n in delopts)
delete extopts[delopts[n]];
$scope.ExtendedOptions = AppUtils.serializeAdvancedOptionsToArray(extopts);
+
+ $scope.servermodulesettings = {};
+ AppUtils.extractServerModuleOptions($scope.ExtendedOptions, $scope.ServerModules, $scope.servermodulesettings, 'SupportedLocalCommands');
+
+ $scope.showAdvanced = $scope.ExtendedOptions.length > 0;
var now = new Date();
if ($scope.Schedule != null) {
@@ -502,6 +659,20 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
}
}
+ function setupServerModules()
+ {
+ var mods = [];
+ if ($scope.SystemInfo.ServerModules != null)
+ for(var ix in $scope.SystemInfo.ServerModules)
+ {
+ var m = $scope.SystemInfo.ServerModules[ix];
+ if (m.SupportedLocalCommands != null && m.SupportedLocalCommands.length > 0)
+ mods.push(m);
+ }
+
+ $scope.ServerModules = mods;
+ };
+
function reloadOptionsList()
{
if ($scope.Options == null)
@@ -514,9 +685,32 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
if (ix > 0)
backmodule = backmodule.substr(0, ix);
- $scope.ExtendedOptionList = AppUtils.buildOptionList($scope.SystemInfo, encmodule, compmodule, backmodule);
+ $scope.ExtendedOptionList = AppUtils.buildOptionList($scope.SystemInfo, encmodule, compmodule, backmodule);
+ setupServerModules();
+
+ AppUtils.extractServerModuleOptions($scope.ExtendedOptions, $scope.ServerModules, $scope.servermodulesettings, 'SupportedLocalCommands');
+ };
+
+ function checkAllowedDaysConfig()
+ {
+ if ($scope.Schedule == null || $scope.Schedule.AllowedDays == null)
+ return;
+
+ // Remove invalid values
+ var alldays = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];
+ for (var i = $scope.Schedule.AllowedDays.length - 1; i >= 0; i--)
+ if (alldays.indexOf($scope.Schedule.AllowedDays[i]) < 0)
+ $scope.Schedule.AllowedDays.splice(i, 1);
+
+ // Empty and all are the same, but the UI confuses if no days are selected
+ if ($scope.Schedule.AllowedDays.length == 0)
+ $timeout(function() {
+ $scope.Schedule.AllowedDays = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];
+ });
};
+ setupServerModules();
+
$scope.$watch("Options['encryption-module']", reloadOptionsList);
$scope.$watch("Options['compression-module']", reloadOptionsList);
$scope.$watch("Options['--compression-module']", reloadOptionsList);
@@ -526,19 +720,23 @@ backupApp.controller('EditBackupController', function ($scope, $routeParams, $lo
if ($scope.Options != null && $scope.Options['--skip-files-larger-than'] == null)
$scope.Options['--skip-files-larger-than'] = '100MB';
});
+ $scope.$watch("Schedule.AllowedDays", checkAllowedDaysConfig, true);
if ($routeParams.backupid == null) {
AppService.get('/backupdefaults').then(function(data) {
$scope.rawddata = data.data.data;
+
+ if ($location.$$path.indexOf('/add-import') == 0 && $rootScope.importConfig != null)
+ angular.merge($scope.rawddata, $rootScope.importConfig);
+
setupScope($scope.rawddata);
}, function(data) {
AppUtils.connectionError(gettextCatalog.getString('Failed to read backup defaults:') + ' ', data);
$location.path('/');
});
-
} else {
AppService.get('/backup/' + $routeParams.backupid).then(function(data) {
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/ExportController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/ExportController.js
index f1812bb3a..0dd6550a6 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/ExportController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/ExportController.js
@@ -29,7 +29,7 @@ backupApp.controller('ExportController', function($scope, $routeParams, AppServi
}
);
} else {
- $scope.DownloadURL = AppService.get_export_url($scope.BackupID, $scope.Passphrase);
+ $scope.DownloadURL = AppService.get_export_url($scope.BackupID, $scope.UseEncryption ? $scope.Passphrase : null);
$scope.Completed = true;
}
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/HomeController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/HomeController.js
index 062e64a46..ee52e45a3 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/HomeController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/HomeController.js
@@ -30,10 +30,7 @@ backupApp.controller('HomeController', function ($scope, $location, ServerStatus
};
$scope.doDelete = function(id, name) {
- DialogService.dialog(gettextCatalog.getString('Confirm delete'), gettextCatalog.getString('Do you really want to delete the backup: {{name}}', {name: name}), [gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
- if (ix == 1)
- AppService.delete('/backup/' + id);
- });
+ $location.path('/delete/' + id);
};
$scope.doLocalDb = function(id) {
@@ -52,6 +49,10 @@ backupApp.controller('HomeController', function ($scope, $location, ServerStatus
$location.path('/log/' + id);
};
+ $scope.doCommandLine = function(id, name) {
+ $location.path('/commandline/' + id);
+ };
+
$scope.doCreateBugReport = function(id, name) {
AppService.post('/backup/' + id + '/createreport');
};
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/ImportController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/ImportController.js
index d07257572..8f2557785 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/ImportController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/ImportController.js
@@ -1,21 +1,41 @@
-backupApp.controller('ImportController', function($scope, $routeParams, $location, AppService, DialogService) {
+backupApp.controller('ImportController', function($rootScope, $scope, $timeout, $location, AppService, DialogService) {
$scope.Connecting = false;
$scope.Completed = false;
$scope.ImportURL = AppService.get_import_url();
+ $scope.restoremode = $location.$$path.indexOf('/restore-import') == 0;
+
// Ugly, but we need to communicate across the iframe load
$scope.CallbackMethod = 'callback-' + Math.random();
- window[$scope.CallbackMethod] = function(message) {
- $scope.Connecting = false;
- $scope.Completed = true;
- if (message == 'OK')
- $location.path('/');
- else
- DialogService.dialog('Error', message);
+ window[$scope.CallbackMethod] = function(message, jobdefinition) {
+ // The delay fixes an issue with Ghostery
+ // failing somewhere
+ $timeout(function() {
+
+ $scope.Connecting = false;
+ $scope.Completed = true;
+
+ if (message == 'OK')
+ $location.path('/');
+ else if (jobdefinition != null && typeof(jobdefinition) != typeof(''))
+ {
+ // Use the root scope to pass the imported job
+ $rootScope.importConfig = jobdefinition;
+
+ if ($scope.restoremode)
+ $location.path('/restoredirect-import');
+ else
+ $location.path('/add-import');
+ }
+ else
+ DialogService.dialog('Error', message);
+
+ }, 100);
};
$scope.doSubmit = function() {
// TODO: Ugly non-angular way
+ $scope.Connecting = true;
document.getElementById('import-form').submit();
};
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/LogController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/LogController.js
index 69a4ee57f..168e7c5b4 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/LogController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/LogController.js
@@ -1,4 +1,4 @@
-backupApp.controller('LogController', function($scope, $routeParams, SystemInfo, ServerStatus, AppService, DialogService, gettextCatalog) {
+backupApp.controller('LogController', function($scope, $routeParams, $timeout, SystemInfo, ServerStatus, AppService, DialogService, BackupList, gettextCatalog) {
$scope.state = ServerStatus.watch($scope);
$scope.BackupID = $routeParams.backupid;
$scope.SystemInfo = SystemInfo.watch($scope);
@@ -13,7 +13,7 @@ backupApp.controller('LogController', function($scope, $routeParams, SystemInfo,
}
if (liveRefreshTimer != null) {
- clearTimeout(liveRefreshTimer);
+ $timeout.cancel(liveRefreshTimer);
liveRefreshTimer = null;
}
@@ -39,11 +39,11 @@ backupApp.controller('LogController', function($scope, $routeParams, SystemInfo,
updateLivePoll();
else
if ($scope.Page == 'live' && $scope.LiveLogLevel != '')
- liveRefreshTimer = setTimeout(updateLivePoll, 3000);
+ liveRefreshTimer = $timeout(updateLivePoll, 3000);
}, function(resp) {
if ($scope.Page == 'live' && $scope.LiveLogLevel != '')
- liveRefreshTimer = setTimeout(updateLivePoll, 3000);
+ liveRefreshTimer = $timeout(updateLivePoll, 3000);
}
);
@@ -65,6 +65,9 @@ backupApp.controller('LogController', function($scope, $routeParams, SystemInfo,
$scope[key].push.apply($scope[key], resp.data);
$scope.LoadingData = false;
$scope[key + 'Complete'] = resp.data.length < PAGE_SIZE;
+ if ($scope.BackupID != null)
+ $scope.Backup = BackupList.lookup[$scope.BackupID];
+
}, function(resp) {
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
@@ -93,12 +96,13 @@ backupApp.controller('LogController', function($scope, $routeParams, SystemInfo,
$scope.LoadMoreStoredData = function() { LoadMoreData('/logdata/log', 'LogData', 'Timestamp'); };
$scope.LoadMoreStoredData();
} else {
- $scope.Page = 'general';
+ $scope.Page = 'general';
$scope.LoadMoreGeneralData = function() { LoadMoreData('/backup/' + $scope.BackupID + '/log', 'GeneralData', 'ID'); };
$scope.LoadMoreRemoteData = function() { LoadMoreData('/backup/' + $scope.BackupID + '/remotelog', 'RemoteData', 'ID'); };
$scope.LoadMoreGeneralData();
+ $scope.Backup = BackupList.lookup[$scope.BackupID];
}
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/PauseController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/PauseController.js
index 1b1f8a8b8..58c02482e 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/PauseController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/PauseController.js
@@ -1,15 +1,5 @@
-backupApp.controller('PauseController', function ($scope, $location, AppService, AppUtils, ServerStatus) {
- $scope.state = ServerStatus.watch($scope);
+backupApp.controller('PauseController', function($scope, $location, gettextCatalog) {
+ $scope.selection = $scope.$parent.state.CurrentItem;
- $scope.pause = function(duration) {
- ServerStatus.pause(duration).then(function() {
- $location.path('/');
- }, AppUtils.connectionError);
- };
-
- $scope.resume = function() {
- ServerStatus.resume().then(function() {
- $location.path('/');
- }, AppUtils.connectionError);
- };
+ $scope.selection.time = 'infinite';
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreController.js
index 00956fd57..3988b5295 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreController.js
@@ -1,4 +1,4 @@
-backupApp.controller('RestoreController', function ($rootScope, $scope, $routeParams, $location, AppService, AppUtils, SystemInfo, ServerStatus, DialogService, gettextCatalog) {
+backupApp.controller('RestoreController', function ($rootScope, $scope, $routeParams, $location, AppService, AppUtils, SystemInfo, ServerStatus, DialogService, BackupList, gettextCatalog) {
$scope.SystemInfo = SystemInfo.watch($scope);
$scope.AppUtils = AppUtils;
@@ -13,6 +13,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
var filesetsRepaired = {};
var filesetStamps = {};
var inProgress = {};
+ var dirsep = $scope.SystemInfo.DirectorySeparator || '/';
$scope.filesetStamps = filesetStamps;
$scope.treedata = {};
@@ -62,6 +63,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
$scope.fetchBackupTimes = function() {
$scope.connecting = true;
+ $scope.ConnectionProgress = gettextCatalog.getString('Getting file versions ...');
var qp = '';
if ($scope.IsBackupTemporary)
@@ -70,6 +72,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
AppService.get('/backup/' + $scope.BackupID + '/filesets' + qp).then(
function(resp) {
$scope.connecting = false;
+ $scope.ConnectionProgress = '';
$scope.Filesets = resp.data;
$scope.parseBackupTimesData();
$scope.fetchPathInformation();
@@ -164,6 +167,9 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
filesetsBuilt[version] = resp.data.Files;
$scope.Paths = filesetsBuilt[version];
+
+ dirsep = resp.data.Files[0].Path[0] == '/' ? '/' : '\\';
+
}, handleError);
}
} else {
@@ -217,7 +223,6 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
function(resp) {
$scope.Searching = false;
var searchNodes = [];
- var dirsep = $scope.SystemInfo.DirectorySeparator || '/';
function compareablePath(path) {
return $scope.SystemInfo.CaseSensitiveFilesystem ? path : path.toLowerCase();
@@ -289,16 +294,38 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
};
$scope.onStartRestore = function() {
+ if ($scope.RestoreLocation == 'custom' && ($scope.RestorePath || '').trim().length == 0)
+ {
+ DialogService.alert(gettextCatalog.getString('You have chosen to restore to a new location, but not entered one'));
+ return;
+ }
+
+ if ($scope.RestoreLocation != 'custom' && dirsep != $scope.SystemInfo.DirectorySeparator)
+ {
+ DialogService.confirm(gettextCatalog.getString('This backup was created on another operating system. Restoring files without specifying a destination folder can cause files to be restored in unexpected places. Are you sure you want to continue without choosing a destination folder?'), function(ix) {
+ if (ix == 1)
+ $scope.onStartRestoreProcess();
+ });
+ }
+ else
+ {
+ $scope.onStartRestoreProcess();
+ }
+ }
+
+ $scope.onStartRestoreProcess = function() {
+
var version = $scope.RestoreVersion + '';
var stamp = filesetStamps[version];
- var dirsep = $scope.SystemInfo.DirectorySeparator || '/';
- var pathSep = $scope.SystemInfo.PathSeparator || ':';
+
+ $scope.restore_step = 2;
function handleError(resp) {
var message = resp.statusText;
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
+ $scope.restore_step = 1;
$scope.connecting = false;
$scope.ConnectionProgress = '';
DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
@@ -351,6 +378,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to build temporary database: {{message}}', { message: resp.data.ErrorMessage }));
$scope.connecting = false;
$scope.ConnectionProgress = '';
+ $scope.restore_step = 1;
}
}, handleError);
});
@@ -376,7 +404,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
if (resp.data.Status == 'Completed')
{
- $scope.restore_step = 2;
+ $scope.restore_step = 3;
}
else
{
@@ -387,6 +415,7 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
if (resp.data != null && resp.data.Message != null)
message = resp.data.Message;
+ $scope.restore_step = 1;
$scope.connecting = false;
$scope.ConnectionProgress = '';
DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
@@ -395,11 +424,21 @@ backupApp.controller('RestoreController', function ($rootScope, $scope, $routePa
$scope.onClickComplete = function () {
$location.path('/');
- }
+ };
+
+ $scope.trySetStep = function(pg) {
+ if ($scope.restore_step < 2)
+ $scope.restore_step = pg;
+ };
$scope.BackupID = $routeParams.backupid;
$scope.IsBackupTemporary = parseInt($scope.BackupID) != $scope.BackupID;
+ if (!$scope.IsBackupTemporary) {
+ $scope.$on('backuplistchanged', function() { $scope.Backup = BackupList.lookup[$scope.BackupID]; });
+ $scope.Backup = BackupList.lookup[$scope.BackupID];
+ }
+
// We pass in the filelist through a global variable
// ... bit ugly, but we do not want to do two remote queries,
// ... nor do we want to pass the information through the url
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreDirectController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreDirectController.js
index f16da89a7..3381921f7 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreDirectController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreDirectController.js
@@ -5,51 +5,86 @@ backupApp.controller('RestoreDirectController', function ($rootScope, $scope, $l
$scope.ServerStatus = ServerStatus;
$scope.serverstate = ServerStatus.watch($scope);
+ $scope.CurrentStep = 0;
$scope.connecting = false;
- $scope.HideEditUri = function() {
- $scope.EditUriState = false;
+ $scope.nextPage = function() {
+ $scope.CurrentStep = Math.min(1, $scope.CurrentStep + 1);
};
- $scope.doConnect = function() {
- $scope.connecting = true;
- $scope.ConnectionProgress = gettextCatalog.getString('Registering temporary backup ...');
+ $scope.prevPage = function() {
+ $scope.CurrentStep = Math.max(0, $scope.CurrentStep - 1);
+ };
- var opts = {};
- var obj = {'Backup': {'TargetURL': $scope.TargetURL } };
+ $scope.setBuilduriFn = function(builduriFn) {
+ $scope.builduri = builduriFn;
+ };
- if (($scope.EncryptionPassphrase || '') == '')
- opts['--no-encryption'] = 'true';
- else
- opts['passphrase'] = $scope.EncryptionPassphrase;
+ $scope.importUrl = function () {
+ DialogService.textareaDialog('Import URL', 'Enter a Backup destination URL:', null, gettextCatalog.getString('Enter URL'), [gettextCatalog.getString('Cancel'), gettextCatalog.getString('OK')], null, function(btn, input) {
+ if (btn == 1) {
+ $scope.TargetURL = input;
+ }
+ });
+ };
- if (!AppUtils.parse_extra_options($scope.ExtendedOptions, opts))
- return false;
+ $scope.copyUrlToClipboard = function () {
+ $scope.builduri(function(res) {
+ DialogService.textareaDialog('Copy URL', null, null, res, [gettextCatalog.getString('OK')], 'templates/copy_clipboard_buttons.html');
+ });
+ };
- obj.Backup.Settings = [];
- for(var k in opts) {
- obj.Backup.Settings.push({
- Name: k,
- Value: opts[k]
- });
- }
+ $scope.doConnect = function() {
+ function connect() {
+ $scope.connecting = true;
+ $scope.ConnectionProgress = gettextCatalog.getString('Registering temporary backup ...');
- AppService.post('/backups?temporary=true', obj, {'headers': {'Content-Type': 'application/json'}}).then(
- function(resp) {
+ var opts = {};
+ var obj = {'Backup': {'TargetURL': $scope.TargetURL } };
- $scope.ConnectionProgress = gettextCatalog.getString('Listing backup dates ...');
- $scope.BackupID = resp.data.ID;
- $scope.fetchBackupTimes();
- }, function(resp) {
- var message = resp.statusText;
- if (resp.data != null && resp.data.Message != null)
- message = resp.data.Message;
+ if (($scope.EncryptionPassphrase || '') == '')
+ opts['--no-encryption'] = 'true';
+ else
+ opts['passphrase'] = $scope.EncryptionPassphrase;
- $scope.connecting = false;
- $scope.ConnectionProgress = '';
- DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
+ if (!AppUtils.parse_extra_options($scope.ExtendedOptions, opts))
+ return false;
+
+ obj.Backup.Settings = [];
+ for(var k in opts) {
+ obj.Backup.Settings.push({
+ Name: k,
+ Value: opts[k]
+ });
}
- );
+
+ AppService.post('/backups?temporary=true', obj, {'headers': {'Content-Type': 'application/json'}}).then(
+ function(resp) {
+
+ $scope.ConnectionProgress = gettextCatalog.getString('Listing backup dates ...');
+ $scope.BackupID = resp.data.ID;
+ $scope.fetchBackupTimes();
+ }, function(resp) {
+ var message = resp.statusText;
+ if (resp.data != null && resp.data.Message != null)
+ message = resp.data.Message;
+
+ $scope.connecting = false;
+ $scope.ConnectionProgress = '';
+ DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
+ }
+ );
+ }
+
+ function checkForValidBackupDestination(continuation) {
+ $scope.builduri(function(res) {
+ $scope.TargetURL = res;
+ continuation();
+ });
+ $scope.CurrentStep = 0;
+ }
+
+ checkForValidBackupDestination(connect);
};
$scope.fetchBackupTimes = function() {
@@ -76,4 +111,24 @@ backupApp.controller('RestoreDirectController', function ($rootScope, $scope, $l
}
);
};
+
+ if ($location.$$path.indexOf('/restoredirect-import') == 0 && $rootScope.importConfig != null)
+ {
+ $scope.TargetURL = $rootScope.importConfig.Backup.TargetURL;
+
+ var tmpsettings = angular.copy($rootScope.importConfig.Backup.Settings);
+ var res = {};
+ for (var i = tmpsettings.length - 1; i >= 0; i--) {
+ if (tmpsettings[i].Name == 'passphrase') {
+ $scope.EncryptionPassphrase = tmpsettings[i].Value;
+ tmpsettings.splice(i, 1);
+ } else {
+ res['--' + tmpsettings[i].Name] = tmpsettings[i].Value;
+ }
+ }
+
+ $scope.showAdvanced = true;
+ $scope.ExtendedOptions = AppUtils.serializeAdvancedOptions(res);
+ }
+
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreWizardController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreWizardController.js
new file mode 100644
index 000000000..702ab8985
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/RestoreWizardController.js
@@ -0,0 +1,16 @@
+backupApp.controller('RestoreWizardController', function($scope, $location, BackupList, gettextCatalog) {
+ $scope.backups = BackupList.watch($scope);
+
+ $scope.selection = {
+ backupid: '-1'
+ };
+
+ $scope.nextPage = function() {
+ if ($scope.selection.backupid == 'direct')
+ $location.path('/restoredirect');
+ else if ($scope.selection.backupid == 'import')
+ $location.path('/restore-import');
+ else
+ $location.path('/restore/' + $scope.selection.backupid);
+ };
+});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/StateController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/StateController.js
index c8c0980ff..19b6fb208 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/StateController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/StateController.js
@@ -1,4 +1,4 @@
-backupApp.controller('StateController', function($scope, $timeout, ServerStatus, BackupList, AppService, AppUtils, gettextCatalog) {
+backupApp.controller('StateController', function($scope, $timeout, ServerStatus, BackupList, AppService, AppUtils, DialogService, gettextCatalog) {
$scope.state = ServerStatus.watch($scope);
$scope.backups = BackupList.watch($scope);
$scope.ServerStatus = ServerStatus;
@@ -6,6 +6,7 @@ backupApp.controller('StateController', function($scope, $timeout, ServerStatus,
$scope.activeTask = null;
var updateActiveTask = function() {
+ $scope.activeTaskID = $scope.state.activeTask == null ? null : $scope.state.activeTask.Item1;
$scope.activeBackup = $scope.state.activeTask == null ? null : BackupList.lookup[$scope.state.activeTask.Item2];
$scope.nextTask = ($scope.state.schedulerQueueIds == null || $scope.state.schedulerQueueIds.length == 0) ? null : BackupList.lookup[$scope.state.schedulerQueueIds[0].Item2];
$scope.nextScheduledTask = ($scope.state.proposedSchedule == null || $scope.state.proposedSchedule.length == 0) ? null : BackupList.lookup[$scope.state.proposedSchedule[0].Item1];
@@ -23,7 +24,7 @@ backupApp.controller('StateController', function($scope, $timeout, ServerStatus,
function updateStateDisplay() {
var text = gettextCatalog.getString('Running ...');
var pg = -1;
- if ($scope.state.lastPgEvent != null)
+ if ($scope.state.lastPgEvent != null && $scope.state.activeTask != null)
{
text = ServerStatus.progress_state_text[$scope.state.lastPgEvent.Phase || ''] || $scope.state.lastPgEvent.Phase;
@@ -34,15 +35,19 @@ backupApp.controller('StateController', function($scope, $timeout, ServerStatus,
pg = 0;
} else {
var filesleft = $scope.state.lastPgEvent.TotalFileCount - $scope.state.lastPgEvent.ProcessedFileCount;
- var sizeleft = $scope.state.lastPgEvent.TotalFileSize - $scope.state.lastPgEvent.ProcessedFileSize;
- pg = $scope.state.lastPgEvent.ProcessedFileSize / $scope.state.lastPgEvent.TotalFileSize;
+ var sizeleft = $scope.state.lastPgEvent.TotalFileSize - $scope.state.lastPgEvent.ProcessedFileSize - $scope.state.lastPgEvent.CurrentFileoffset;
+ pg = ($scope.state.lastPgEvent.ProcessedFileSize + $scope.state.lastPgEvent.CurrentFileoffset) / $scope.state.lastPgEvent.TotalFileSize;
if ($scope.state.lastPgEvent.ProcessedFileCount == 0)
pg = 0;
else if (pg >= 0.90)
pg = 0.90;
-
- text = gettextCatalog.getString('{{files}} files ({{size}}) to go', { files: filesleft, size: AppUtils.formatSizeString(sizeleft) });
+
+ // If we have a speed append it
+ var speed_txt = ($scope.state.lastPgEvent.BackendSpeed < 0) ? "" : " at "+AppUtils.formatSizeString($scope.state.lastPgEvent.BackendSpeed)+"/s";
+
+ // Finally construct the whole text
+ text = gettextCatalog.getString('{{files}} files ({{size}}) to go {{speed_txt}}', { files: filesleft, size: AppUtils.formatSizeString(sizeleft), speed_txt: speed_txt});
}
}
else if ($scope.state.lastPgEvent.Phase == 'Backup_Finalize' || $scope.state.lastPgEvent.Phase == 'Backup_WaitForUpload')
@@ -71,20 +76,45 @@ backupApp.controller('StateController', function($scope, $timeout, ServerStatus,
};
$scope.$watch('state.lastPgEvent', updateStateDisplay, true);
+ $scope.$on('serverstatechanged', updateStateDisplay);
- $scope.stopTask = function() {
- var taskId = $scope.state.activeTask.Item1;
- if ($scope.StopReqId == taskId) {
- AppService.post('/task/' + taskId + '/abort');
- } else {
- AppService.post('/task/' + taskId + '/stop');
- }
+ $scope.stopDialog = function() {
+ if ($scope.activeTaskID == null)
+ return;
+
+ var taskId = $scope.activeTaskID;
+ var txt = $scope.state.lastPgEvent == null ? '' : ($scope.state.lastPgEvent.Phase || '');
+
+ function handleClick(ix) {
+ if (ix == 0)
+ {
+ AppService.post('/task/' + taskId + '/stop');
+ $scope.StopReqId = taskId;
+ }
+ else if (ix == 1)
+ AppService.post('/task/' + taskId + '/abort');
+ };
- $scope.StopReqId = taskId;
+ if (txt.indexOf('Backup_') == 0)
+ {
+ DialogService.dialog(
+ gettextCatalog.getString('Stop running backup'),
+ gettextCatalog.getString('You can stop the backup immediately, or stop after the current file has been uploaded.'),
+ [gettextCatalog.getString('Stop after upload'), gettextCatalog.getString('Stop now'), gettextCatalog.getString('Cancel')],
+ handleClick
+ );
+ }
+ else
+ {
+ DialogService.dialog(
+ gettextCatalog.getString('Stop running task'),
+ gettextCatalog.getString('You can stop the task immediately, or allow the process to continue its current file and the stop.'),
+ [gettextCatalog.getString('Stop after the current file'), gettextCatalog.getString('Stop now'), gettextCatalog.getString('Cancel')],
+ handleClick
+ );
+ }
};
updateStateDisplay();
updateActiveTask();
-
-
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/SystemSettingsController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/SystemSettingsController.js
index 21c3f70ce..4ea0a37f9 100644
--- a/Duplicati/Server/webroot/ngax/scripts/controllers/SystemSettingsController.js
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/SystemSettingsController.js
@@ -1,15 +1,34 @@
backupApp.controller('SystemSettingsController', function($rootScope, $scope, $location, $cookies, AppService, AppUtils, SystemInfo, gettextCatalog) {
- $scope.SystemInfo = SystemInfo.watch($scope);
+ $scope.SystemInfo = SystemInfo.watch($scope);
+ $scope.theme = $scope.$parent.$parent.saved_theme;
+ if (($scope.theme || '').trim().length == 0)
+ $scope.theme = 'default';
+
+ $scope.usageReporterLevel = '';
function reloadOptionsList() {
$scope.advancedOptionList = AppUtils.buildOptionList($scope.SystemInfo, false, false, false);
- }
+ var mods = [];
+ if ($scope.SystemInfo.ServerModules != null)
+ for(var ix in $scope.SystemInfo.ServerModules)
+ {
+ var m = $scope.SystemInfo.ServerModules[ix];
+ if (m.SupportedGlobalCommands != null && m.SupportedGlobalCommands.length > 0)
+ mods.push(m);
+ }
- reloadOptionsList();
+ $scope.ServerModules = mods;
+ AppUtils.extractServerModuleOptions($scope.advancedOptions, $scope.ServerModules, $scope.servermodulesettings, 'SupportedGlobalCommands');
+ };
+ reloadOptionsList();
$scope.$on('systeminfochanged', reloadOptionsList);
+ $scope.$watch('theme', function() {
+ $rootScope.$broadcast('preview_theme', { theme: $scope.theme });
+ });
+
$scope.uiLanguage = $cookies.get('ui-locale');
$scope.lang_browser_default = gettextCatalog.getString('Browser default');
$scope.lang_default = gettextCatalog.getString('Default');
@@ -19,33 +38,39 @@ backupApp.controller('SystemSettingsController', function($rootScope, $scope, $l
$cookies.remove('ui-locale');
gettextCatalog.setCurrentLanguage($scope.SystemInfo.BrowserLocale.Code.replace("-", "_"));
} else {
- $cookies.put('ui-locale', $scope.uiLanguage);
- gettextCatalog.setCurrentLanguage($scope.uiLanguage);
+ var now = new Date();
+ var exp = new Date(now.getFullYear()+10, now.getMonth(), now.getDate());
+ $cookies.put('ui-locale', $scope.uiLanguage, { expires: exp });
+
+ gettextCatalog.setCurrentLanguage($scope.uiLanguage.replace("-", "_"));
}
$rootScope.$broadcast('ui_language_changed');
- }
+ };
AppService.get('/serversettings').then(function(data) {
$scope.rawdata = data.data;
- $scope.requireRemotePassword = data.data[''] != null && data.data.WebserverPassword != '';
- $scope.remotePassword = data.data.WebserverPassword;
+ $scope.requireRemotePassword = data.data['server-passphrase'] != null && data.data['server-passphrase'] != '';
+ $scope.remotePassword = data.data['server-passphrase'];
$scope.allowRemoteAccess = data.data['server-listen-interface'] != 'loopback';
- $scope.startupDelayDurationValue = data.data['startup-delay'].substr(0, data.data['startup-delay'].length - 1);
- $scope.startupDelayDurationMultiplier = data.data['startup-delay'].substr(-1);
+ $scope.startupDelayDurationValue = data.data['startup-delay'].substr(0, data.data['startup-delay'].length - 1) == "" ? "0" : data.data['startup-delay'].substr(0, data.data['startup-delay'].length - 1);
+ $scope.startupDelayDurationMultiplier = data.data['startup-delay'].substr(-1) == "" ? "s" : data.data['startup-delay'].substr(-1);
$scope.updateChannel = data.data['update-channel'];
$scope.originalUpdateChannel = data.data['update-channel'];
$scope.usageReporterLevel = data.data['usage-reporter-level'];
$scope.advancedOptions = AppUtils.serializeAdvancedOptionsToArray(data.data);
+ $scope.servermodulesettings = {};
+ AppUtils.extractServerModuleOptions($scope.advancedOptions, $scope.ServerModules, $scope.servermodulesettings, 'SupportedGlobalCommands');
+
}, AppUtils.connectionError);
$scope.save = function() {
if ($scope.requireRemotePassword && $scope.remotePassword.trim().length == 0)
- return AppUtil.notifyInputError('Cannot use empty password');
+ return AppUtils.notifyInputError('Cannot use empty password');
var patchdata = {
'server-passphrase': $scope.requireRemotePassword ? $scope.remotePassword : '',
@@ -56,7 +81,6 @@ backupApp.controller('SystemSettingsController', function($rootScope, $scope, $l
'usage-reporter-level': $scope.usageReporterLevel
};
-
if ($scope.requireRemotePassword) {
if ($scope.rawdata['server-passphrase'] != $scope.remotePassword) {
patchdata['server-passphrase-salt'] = CryptoJS.lib.WordArray.random(256/8).toString(CryptoJS.enc.Base64);
@@ -68,6 +92,10 @@ backupApp.controller('SystemSettingsController', function($rootScope, $scope, $l
}
AppUtils.mergeAdvancedOptions($scope.advancedOptions, patchdata, $scope.rawdata);
+ for(var n in $scope.servermodulesettings)
+ patchdata['--' + n] = $scope.servermodulesettings[n];
+
+ $rootScope.$broadcast('update_theme', { theme: $scope.theme } );
AppService.patch('/serversettings', patchdata, {headers: {'Content-Type': 'application/json; charset=utf-8'}}).then(
function() {
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/ThrottleController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/ThrottleController.js
new file mode 100644
index 000000000..f24583cf8
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/controllers/ThrottleController.js
@@ -0,0 +1,22 @@
+backupApp.controller('ThrottleController', function($scope, AppService, ServerStatus, SystemInfo, AppUtils) {
+ $scope.speedMultipliers = AppUtils.speedMultipliers;
+
+ $scope.selection = $scope.$parent.state.CurrentItem;
+
+ AppService.get('/serversettings').then(function(data) {
+
+ $scope.selection.uploadspeed = data.data['max-upload-speed'];
+ $scope.selection.downloadspeed = data.data['max-download-speed'];
+
+ $scope.selection.uploadthrottleenabled = ($scope.selection.uploadspeed != '');
+ $scope.selection.downloadthrottleenabled = ($scope.selection.downloadspeed != '');
+
+ // Nicer looking UI
+ if (!$scope.selection.uploadthrottleenabled)
+ $scope.selection.uploadspeed = "10MB";
+ if (!$scope.selection.downloadthrottleenabled)
+ $scope.selection.downloadspeed = "10MB";
+
+ }, AppUtils.connectionError);
+
+});
diff --git a/Duplicati/Server/webroot/ngax/scripts/directives/advancedOptionsEditor.js b/Duplicati/Server/webroot/ngax/scripts/directives/advancedOptionsEditor.js
index f8edc0d2f..6a88a562d 100644
--- a/Duplicati/Server/webroot/ngax/scripts/directives/advancedOptionsEditor.js
+++ b/Duplicati/Server/webroot/ngax/scripts/directives/advancedOptionsEditor.js
@@ -10,12 +10,27 @@ backupApp.directive('advancedOptionsEditor', function() {
$scope.NewItem = null;
$scope.fileSizeMultipliers = AppUtils.fileSizeMultipliers;
$scope.timerangeMultipliers = AppUtils.timerangeMultipliers;
+ $scope.speedMultipliers = AppUtils.speedMultipliers;
+ $scope.shorttimerangeMultipliers = AppUtils.shorttimerangeMultipliers;
AppUtils.watch($scope, function() {
$scope.fileSizeMultipliers = AppUtils.fileSizeMultipliers;
$scope.timerangeMultipliers = AppUtils.timerangeMultipliers;
+ $scope.speedMultipliers = AppUtils.speedMultipliers;
+ $scope.shorttimerangeMultipliers = AppUtils.shorttimerangeMultipliers;
});
+ // Overrides to display a custom layout for a specific option
+ var overrides = {
+ 'throttle-upload': 'speed',
+ 'throttle-download': 'speed',
+
+ 'retry-delay': 'shorttimespan',
+ 'amzcd-consistency-delay': 'shorttimespan',
+ 'web-timeout': 'shorttimespan',
+ 'run-script-timeout': 'shorttimespan'
+ };
+
var optionmap = null;
function rebuildOptionMap() {
@@ -59,6 +74,9 @@ backupApp.directive('advancedOptionsEditor', function() {
if (item == null)
return 'text';
+ if (overrides[item.Name])
+ return overrides[item.Name];
+
if (item.Type == 'Enumeration')
return 'enum';
if (item.Type == 'Flags')
diff --git a/Duplicati/Server/webroot/ngax/scripts/directives/backupEditUri.js b/Duplicati/Server/webroot/ngax/scripts/directives/backupEditUri.js
index a7b07821e..c3ba70f97 100644
--- a/Duplicati/Server/webroot/ngax/scripts/directives/backupEditUri.js
+++ b/Duplicati/Server/webroot/ngax/scripts/directives/backupEditUri.js
@@ -1,9 +1,9 @@
-backupApp.directive('backupEditUri', function() {
+backupApp.directive('backupEditUri', function(gettextCatalog) {
return {
restrict: 'E',
scope: {
uri: '=uri',
- hide: '=hide'
+ setBuilduriFn: '&'
},
templateUrl: 'templates/edituri.html',
controller: function($scope, AppService, AppUtils, SystemInfo, EditUriBackendConfig, DialogService, EditUriBuiltins) {
@@ -18,13 +18,15 @@ backupApp.directive('backupEditUri', function() {
callback(EditUriBackendConfig.defaultbuilder(scope));
else
callback(EditUriBackendConfig.builders[scope.Backend.Key](scope));
- };
+ }
if (EditUriBackendConfig.validaters[scope.Backend.Key] == null)
EditUriBackendConfig.defaultvalidater(scope, validationCompleted);
else
EditUriBackendConfig.validaters[scope.Backend.Key](scope, validationCompleted);
- }
+ };
+
+ $scope.setBuilduriFn({ builduriFn: builduri });
function performConnectionTest(uri) {
@@ -39,17 +41,17 @@ backupApp.directive('backupEditUri', function() {
if (dlg != null)
dlg.dismiss();
- dlg = DialogService.dialog('Testing ...', 'Testing connection ...', [], null, function() {
+ dlg = DialogService.dialog(gettextCatalog.getString('Testing ...'), gettextCatalog.getString('Testing connection ...'), [], null, function() {
AppService.post('/remoteoperation/test', uri).then(function() {
scope.Testing = false;
dlg.dismiss();
if (EditUriBackendConfig.testers[scope.Backend.Key] != null)
EditUriBackendConfig.testers[scope.Backend.Key](scope, function() {
- DialogService.dialog('Success', 'Connection worked!');
+ DialogService.dialog(gettextCatalog.getString('Success'), gettextCatalog.getString('Connection worked!'));
});
else
- DialogService.dialog('Success', 'Connection worked!');
+ DialogService.dialog(gettextCatalog.getString('Success'), gettextCatalog.getString('Connection worked!'));
}, handleError);
});
@@ -79,10 +81,10 @@ backupApp.directive('backupEditUri', function() {
}
scope.AdvancedOptions.push('--accept-specified-ssl-hash=' + hash);
- }
+ };
var askApproveCert = function(hash) {
- DialogService.dialog('Trust server certificate?', 'The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: ' + hash + '?', ['No', 'Yes'], function(ix) {
+ DialogService.dialog(gettextCatalog.getString('Trust server certificate?'), gettextCatalog.getString('The server certificate could not be validated.\nDo you want to approve the SSL certificate with the hash: {{hash}}?', { hash: hash }), [gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
if (ix == 1) {
appendApprovedCert(hash);
builduri(function(res) {
@@ -108,7 +110,7 @@ backupApp.directive('backupEditUri', function() {
}
return false;
- }
+ };
var handleError = function(data) {
@@ -126,7 +128,7 @@ backupApp.directive('backupEditUri', function() {
if ((folder || "") == "")
folder = '';
- DialogService.dialog('Create folder?', 'The folder ' + folder + ' does not exist\nCreate it now?', ['No', 'Yes'], function(ix) {
+ DialogService.dialog(gettextCatalog.getString('Create folder?'), gettextCatalog.getString('The folder {{folder}} does not exist\nCreate it now?', { folder: folder }), [gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
if (ix == 1)
createFolder();
});
@@ -138,7 +140,7 @@ backupApp.directive('backupEditUri', function() {
if (data.data != null && data.data.Message != null)
message = data.data.Message;
- DialogService.dialog('Error', 'Failed to connect: ' + message);
+ DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: ') + message);
return;
}
@@ -148,13 +150,13 @@ backupApp.directive('backupEditUri', function() {
AppService.post('/webmodule/check-mono-ssl', {'mono-ssl-config': 'List'}).then(function(data) {
if (data.data.Result.count == 0) {
- if (confirm('You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?'))
+ if (confirm(gettextCatalog.getString('You appear to be running Mono with no SSL certificates loaded.\nDo you want to import the list of trusted certificates from Mozilla?')))
{
scope.Testing = true;
AppService.post('/webmodule/check-mono-ssl', {'mono-ssl-config': 'Install'}).then(function(data) {
scope.Testing = false;
if (data.data.Result.count == 0) {
- DialogService.dialog('Import failed', 'Import completed, but no certificates were found after the import');
+ DialogService.dialog(gettextCatalog.getString('Import failed'), gettextCatalog.getString('Import completed, but no certificates were found after the import'));
} else {
testConnection();
}
@@ -165,7 +167,7 @@ backupApp.directive('backupEditUri', function() {
if (data.data != null && data.data.Message != null)
message = data.data.Message;
- DialogService.dialog('Error', 'Failed to import: ' + message);
+ DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to import: ') + message);
});
}
@@ -200,16 +202,16 @@ backupApp.directive('backupEditUri', function() {
if (data.data != null && data.data.Message != null)
message = data.data.Message;
- DialogService.dialog('Error', 'Failed to connect: ' + message);
+ DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: ') + message);
}
else
{
var message = ((prev || '').trim().length == 0) ?
- ('No certificate was specified previously, please verify with the server administrator that the key is correct: ' + key + ' \n\nDo you want to approve the reported host key?')
+ (gettextCatalog.getString('No certificate was specified previously, please verify with the server administrator that the key is correct: {{key}} \n\nDo you want to approve the reported host key?', { key: key }))
:
- ('The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key "' + prev + '" with the REPORTED host key: ' + key + '?');
+ (gettextCatalog.getString('The host key has changed, please check with the server administrator if this is correct, otherwise you could be the victim of a MAN-IN-THE-MIDDLE attack.\n\nDo you want to REPLACE your CURRENT host key "{{prev}}" with the REPORTED host key: {{key}}?', { prev: pref, key: key }));
- DialogService.dialog('Trust host certificate?', message, ['No', 'Yes'], function(ix) {
+ DialogService.dialog(gettextCatalog.getString('Trust host certificate?'), message, [gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
if (ix == 1) {
hasTriedHostkey = true;
for(var n in scope.AdvancedOptions) {
@@ -234,24 +236,17 @@ backupApp.directive('backupEditUri', function() {
if (data.data != null && data.data.Message != null)
message = data.data.Message;
- DialogService.dialog('Error', 'Failed to connect: ' + message);
+ DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: ') + message);
}
- }
+ };
testConnection();
- };
+ }
$scope.testConnection = function() {
builduri(performConnectionTest);
};
- $scope.save = function() {
- builduri(function(res) {
- scope.uri = res;
- scope.hide();
- });
- };
-
$scope.contains_value = AppUtils.contains_value;
$scope.$watch('Backend', function() {
diff --git a/Duplicati/Server/webroot/ngax/scripts/directives/parseAdvancedOption.js b/Duplicati/Server/webroot/ngax/scripts/directives/parseAdvancedOption.js
index fde2b57af..7e41f3835 100644
--- a/Duplicati/Server/webroot/ngax/scripts/directives/parseAdvancedOption.js
+++ b/Duplicati/Server/webroot/ngax/scripts/directives/parseAdvancedOption.js
@@ -179,7 +179,7 @@ backupApp.directive('parseAdvancedOptionSizeNumber', function(AppUtils) {
if (name == null)
return null;
- return name + '=' + txt + multiplier;
+ return name + '=' + (txt || '0') + (multiplier || '');
});
ctrl[0].$formatters.push(function(src) {
@@ -231,7 +231,7 @@ backupApp.directive('parseAdvancedOptionSizeMultiplier', function(AppUtils) {
if (name == null)
return null;
- return name + '=' + (number || '') + txt;
+ return name + '=' + (number || '0') + (txt || '');
});
ctrl[0].$formatters.push(function(src) {
diff --git a/Duplicati/Server/webroot/ngax/scripts/directives/parseSizeNumber.js b/Duplicati/Server/webroot/ngax/scripts/directives/parseSizeNumber.js
index 05f6b7466..708a210f7 100644
--- a/Duplicati/Server/webroot/ngax/scripts/directives/parseSizeNumber.js
+++ b/Duplicati/Server/webroot/ngax/scripts/directives/parseSizeNumber.js
@@ -9,8 +9,7 @@ backupApp.directive('parseSizeNumber', function(AppUtils) {
var multiplier = null;
ctrl[0].$parsers.push(function(txt) {
- txt = txt || '0';
- return txt + (multiplier || '');
+ return (txt || '0') + (multiplier || '');
});
ctrl[0].$formatters.push(function(src) {
diff --git a/Duplicati/Server/webroot/ngax/scripts/directives/restoreFilePicker.js b/Duplicati/Server/webroot/ngax/scripts/directives/restoreFilePicker.js
index 100d362ab..ef142f6bc 100644
--- a/Duplicati/Server/webroot/ngax/scripts/directives/restoreFilePicker.js
+++ b/Duplicati/Server/webroot/ngax/scripts/directives/restoreFilePicker.js
@@ -17,6 +17,8 @@ backupApp.directive('restoreFilePicker', function() {
controller: function($scope, $timeout, SystemInfo, AppService, AppUtils) {
var scope = $scope;
+ var dirsep = '/';
+
$scope.systeminfo = SystemInfo.watch($scope);
$scope.treedata = [];
@@ -35,7 +37,6 @@ backupApp.directive('restoreFilePicker', function() {
AppService.get('/backup/' + $scope.ngBackupId + '/files/' + encodeURIComponent(node.id) + '?prefix-only=false&folder-contents=true&time=' + encodeURIComponent($scope.ngTimestamp) + '&filter=' + encodeURIComponent(node.id)).then(function(data) {
var children = []
- var dirsep = scope.systeminfo.DirectorySeparator || '/';
for(var n in data.data.Files)
{
@@ -51,6 +52,7 @@ backupApp.directive('restoreFilePicker', function() {
id: data.data.Files[n].Path,
size: data.data.Files[n].Sizes[0],
iconCls: leaf ? 'x-tree-icon-leaf' : '',
+ entrytype: AppUtils.getEntryTypeFromIconCls(leaf ? 'x-tree-icon-leaf' : ''),
leaf: leaf
});
}
@@ -94,7 +96,6 @@ backupApp.directive('restoreFilePicker', function() {
};
function findParent(node) {
- var dirsep = scope.systeminfo.DirectorySeparator || '/';
var e = [];
e.push.apply(e, $scope.treedata.children);
var p = compareablePath(node.id);
@@ -151,7 +152,6 @@ backupApp.directive('restoreFilePicker', function() {
};
function buildPartialMap() {
- var dirsep = scope.systeminfo.DirectorySeparator || '/';
var map = {};
for (var i = $scope.ngSelected.length - 1; i >= 0; i--) {
var is_dir = $scope.ngSelected[i].substr($scope.ngSelected[i].length - 1, 1) == dirsep;
@@ -179,7 +179,6 @@ backupApp.directive('restoreFilePicker', function() {
};
$scope.toggleCheck = function(node) {
- var dirsep = scope.systeminfo.DirectorySeparator || '/';
if (node.include != '+') {
var p = findParent(node) || node;
@@ -280,7 +279,6 @@ backupApp.directive('restoreFilePicker', function() {
var buildnodes = function(items, parentpath) {
var res = [];
- var dirsep = scope.systeminfo.DirectorySeparator || '/';
parentpath = parentpath || '';
@@ -294,7 +292,8 @@ backupApp.directive('restoreFilePicker', function() {
expanded: items[n].expanded,
iconCls: items[n].iconCls,
leaf: items[n].leaf,
- id: items[n].Path
+ id: items[n].Path,
+ entrytype: AppUtils.getEntryTypeFromIconCls(items[n].iconCls)
};
if (items[n].Children) {
@@ -310,7 +309,12 @@ backupApp.directive('restoreFilePicker', function() {
var updateRoots = function()
{
- var roots = buildnodes($scope.ngSources) ;
+ if ($scope.ngSources == null || $scope.ngSources.length == 0)
+ dirsep = scope.systeminfo.DirectorySeparator || '/';
+ else
+ dirsep = $scope.ngSources[0].Path[0] == '/' ? '/' : '\\';
+
+ var roots = buildnodes($scope.ngSources);
$scope.treedata = $scope.treedata || {};
diff --git a/Duplicati/Server/webroot/ngax/scripts/directives/sourceFolderPicker.js b/Duplicati/Server/webroot/ngax/scripts/directives/sourceFolderPicker.js
index 6ffb6a9de..27b77a6bd 100644
--- a/Duplicati/Server/webroot/ngax/scripts/directives/sourceFolderPicker.js
+++ b/Duplicati/Server/webroot/ngax/scripts/directives/sourceFolderPicker.js
@@ -9,10 +9,11 @@ backupApp.directive('sourceFolderPicker', function() {
},
templateUrl: 'templates/sourcefolderpicker.html',
- controller: function($scope, $timeout, SystemInfo, AppService, AppUtils) {
+ controller: function($scope, $timeout, SystemInfo, AppService, AppUtils, gettextCatalog) {
var scope = $scope;
scope.systeminfo = SystemInfo.watch($scope);
+ var sourceNodeChildren = null;
$scope.treedata = { };
@@ -30,7 +31,12 @@ backupApp.directive('sourceFolderPicker', function() {
path += dirsep;
return scope.systeminfo.CaseSensitiveFilesystem ? path : path.toLowerCase();
- };
+ }
+
+ function setEntryType(n)
+ {
+ n.entrytype = AppUtils.getEntryTypeFromIconCls(n.iconCls);
+ }
function setIconCls(n) {
var cp = compareablePath(n.id);
@@ -45,10 +51,24 @@ backupApp.directive('sourceFolderPicker', function() {
n.iconCls = 'x-tree-icon-desktop';
else if (cp == compareablePath('%HOME%'))
n.iconCls = 'x-tree-icon-home';
+ else if (n.id.substr(0, 9) == "%HYPERV%\\" && n.id.length >= 10) {
+ n.iconCls = 'x-tree-icon-hypervmachine';
+ n.tooltip = gettextCatalog.getString("ID:") + " " + n.id.substring(9, n.id.length);
+ }
+ else if (n.id.substr(0, 8) == "%HYPERV%")
+ n.iconCls = 'x-tree-icon-hyperv';
+ else if (n.id.substr(0, 8) == "%MSSQL%\\" && n.id.length >= 9) {
+ n.iconCls = 'x-tree-icon-mssqldb';
+ n.tooltip = gettextCatalog.getString("ID:") + " " + n.id.substring(8, n.id.length);
+ }
+ else if (n.id.substr(0, 7) == "%MSSQL%")
+ n.iconCls = 'x-tree-icon-mssql';
else if (defunctmap[cp])
n.iconCls = 'x-tree-icon-broken';
else if (cp.substr(cp.length - 1, 1) != dirsep)
n.iconCls = 'x-tree-icon-leaf';
+
+ setEntryType(n);
}
function indexOfPathInArray(array, item) {
@@ -59,7 +79,7 @@ backupApp.directive('sourceFolderPicker', function() {
return -1;
- };
+ }
function removePathFromArray(array, item) {
var ix = indexOfPathInArray(array, item);
@@ -69,7 +89,7 @@ backupApp.directive('sourceFolderPicker', function() {
}
return false;
- };
+ }
function traversenodes(m, start) {
var root = (start || scope.treedata);
@@ -94,7 +114,7 @@ backupApp.directive('sourceFolderPicker', function() {
work.push([x[1], x[1].children[v]]);
}
}
- };
+ }
function buildidlookup(sources, map) {
var dirsep = scope.systeminfo.DirectorySeparator || '/';
@@ -116,7 +136,7 @@ backupApp.directive('sourceFolderPicker', function() {
}
return map;
- };
+ }
function updateIncludeFlags(root, parentFlag) {
if (root != null)
@@ -141,10 +161,10 @@ backupApp.directive('sourceFolderPicker', function() {
else
n.include = null;
}, root);
- };
+ }
function syncTreeWithLists() {
- if (scope.ngSources == null || scope.treedata.children == null)
+ if (scope.ngSources == null || sourceNodeChildren == null)
return;
dirsep = scope.systeminfo.DirectorySeparator || '/';
@@ -170,8 +190,7 @@ backupApp.directive('sourceFolderPicker', function() {
if (anySpecials)
filterList = AppUtils.filterListToRegexps(scope.ngFilters, scope.systeminfo.CaseSensitiveFilesystem);
- var sources = scope.treedata.children[2].children;
- sources.length = 0;
+ sourceNodeChildren.length = 0;
function findInList(lst, path) {
for(var x in lst)
@@ -179,7 +198,7 @@ backupApp.directive('sourceFolderPicker', function() {
return x;
return false;
- };
+ }
for(var i = 0; i < scope.ngSources.length; i++) {
var k = compareablePath(scope.ngSources[i]);
@@ -193,7 +212,7 @@ backupApp.directive('sourceFolderPicker', function() {
var nx = k.substr(1).indexOf('%') + 2;
if (nx > 1) {
var key = compareablePath(k.substr(0, nx));
- txt = (displayMap[compareablePath(key)] || key) + txt.substr(nx);
+ txt = displayMap[compareablePath(k)] || ((displayMap[compareablePath(key)] || key) + txt.substr(nx));
}
}
@@ -207,9 +226,9 @@ backupApp.directive('sourceFolderPicker', function() {
setIconCls(n);
- sources.push(n);
+ sourceNodeChildren.push(n);
- if (defunctmap[k] == null) {
+ if (defunctmap[k] == null && n.iconCls != "x-tree-icon-hyperv" && n.iconCls != "x-tree-icon-hypervmachine" && n.iconCls != "x-tree-icon-mssql" && n.iconCls != "x-tree-icon-mssqldb") {
defunctmap[k] = true;
var p = scope.ngSources[i];
@@ -221,9 +240,11 @@ backupApp.directive('sourceFolderPicker', function() {
}, function(data) {
var p = data.config.data.path;
- var ix = findInList(sources, compareablePath(p));
- if (ix != null && sources[ix].id == p)
- sources[ix].iconCls = 'x-tree-icon-broken';
+ var ix = findInList(sourceNodeChildren, compareablePath(p));
+ if (ix != null && sourceNodeChildren[ix].id == p) {
+ sourceNodeChildren[ix].iconCls = 'x-tree-icon-broken';
+ setEntryType(sourceNodeChildren[ix]);
+ }
});
}
}
@@ -306,12 +327,14 @@ backupApp.directive('sourceFolderPicker', function() {
} else if (node.include == '-') {
removePathFromArray(scope.ngFilters, '-' + node.id);
}
- }
+ };
$scope.toggleExpanded = function(node) {
node.expanded = !node.expanded;
- if (node.root || node.iconCls == 'x-tree-icon-leaf' || node.iconCls == 'x-tree-icon-locked')
+ if (node.root || node.iconCls == 'x-tree-icon-leaf' || node.iconCls == 'x-tree-icon-locked'
+ || node.iconCls == 'x-tree-icon-hyperv' || node.iconCls == 'x-tree-icon-hypervmachine'
+ || node.iconCls == 'x-tree-icon-mssql' || node.iconCls == 'x-tree-icon-mssqldb')
return;
if (!node.children && !node.loading) {
@@ -320,6 +343,10 @@ backupApp.directive('sourceFolderPicker', function() {
AppService.post('/filesystem?onlyfolders=false&showhidden=true', {path: node.id}).then(function(data) {
node.children = data.data;
node.loading = false;
+
+ if (node.children != null)
+ for(var i in node.children)
+ setEntryType(node.children[i]);
updateIncludeFlags(node, node.include);
@@ -338,37 +365,35 @@ backupApp.directive('sourceFolderPicker', function() {
scope.selectednode = node;
scope.selectednode.selected = true;
};
-
+
+ scope.treedata.children = [];
+
AppService.post('/filesystem?onlyfolders=false&showhidden=true', {path: '/'}).then(function(data) {
var usernode = {
- text: 'User data',
+ text: gettextCatalog.getString('User data'),
root: true,
iconCls: 'x-tree-icon-userdata',
expanded: true,
children: []
};
var systemnode = {
- text: 'Computer',
+ text: gettextCatalog.getString('Computer'),
root: true,
iconCls: 'x-tree-icon-computer',
children: []
};
var sourcenode = {
- text: 'Source data',
+ text: gettextCatalog.getString('Source data'),
root: true,
iconCls: 'x-tree-icon-others',
expanded: true,
- children: []
+ children: [],
+ isSourcenode: true
};
- scope.treedata.children = [
- usernode,
- systemnode,
- sourcenode
- ];
-
- displayMap = {};
+ sourceNodeChildren = sourcenode.children;
+ scope.treedata.children.push(usernode, systemnode, sourcenode);
for(var i = 0; i < data.data.length; i++) {
if (data.data[i].id.indexOf('%') == 0) {
@@ -385,6 +410,71 @@ backupApp.directive('sourceFolderPicker', function() {
syncTreeWithLists();
}, AppUtils.connectionError);
+
+ AppService.get('/hyperv', {path: '/'}).then(function(data) {
+ if (data.data != null && data.data.length > 0) {
+ var hypervnode = {
+ text: gettextCatalog.getString('Hyper-V Machines'),
+ id: "%HYPERV%",
+ children: []
+ };
+ setIconCls(hypervnode);
+ var cp = compareablePath(hypervnode.id);
+ displayMap[cp] = gettextCatalog.getString('All Hyper-V Machines');
+
+ // add HyperV at the beginning
+ if (scope.treedata.children.length < 1)
+ scope.treedata.children.push(hypervnode);
+ else
+ scope.treedata.children = [hypervnode].concat(scope.treedata.children);
+
+ for (var i = 0; i < data.data.length; i++) {
+ var node = {
+ leaf: true,
+ id: "%HYPERV%\\" + data.data[i].id,
+ text: data.data[i].name};
+
+ cp = compareablePath(node.id);
+ displayMap[cp] = gettextCatalog.getString('Hyper-V Machine:') + " " + node.text;
+ setIconCls(node);
+ hypervnode.children.push(node);
+ }
+ syncTreeWithLists();
+ }
+ }, AppUtils.connectionError);
+
+ AppService.get('/mssql', { path: '/' }).then(function (data) {
+ if (data.data != null && data.data.length > 0) {
+ var mssqlnode = {
+ text: gettextCatalog.getString('Microsoft SQL Databases'),
+ id: "%MSSQL%",
+ children: []
+ };
+ setIconCls(mssqlnode);
+ var cp = compareablePath(mssqlnode.id);
+ displayMap[cp] = gettextCatalog.getString('All Microsoft SQL Databases');
+
+ // add MS SQL DB at the beginning
+ if (scope.treedata.children.length < 1)
+ scope.treedata.children.push(mssqlnode);
+ else
+ scope.treedata.children = [mssqlnode].concat(scope.treedata.children);
+
+ for (var i = 0; i < data.data.length; i++) {
+ var node = {
+ leaf: true,
+ id: "%MSSQL%\\" + data.data[i].id,
+ text: data.data[i].name
+ };
+
+ cp = compareablePath(node.id);
+ displayMap[cp] = gettextCatalog.getString('Microsoft SQL Database:') + " " + node.text;
+ setIconCls(node);
+ mssqlnode.children.push(node);
+ }
+ syncTreeWithLists();
+ }
+ }, AppUtils.connectionError);
}
}
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/directives/targetFolderPicker.js b/Duplicati/Server/webroot/ngax/scripts/directives/targetFolderPicker.js
index 595bdec62..bee49af6a 100644
--- a/Duplicati/Server/webroot/ngax/scripts/directives/targetFolderPicker.js
+++ b/Duplicati/Server/webroot/ngax/scripts/directives/targetFolderPicker.js
@@ -26,6 +26,11 @@ backupApp.directive('destinationFolderPicker', function() {
return scope.systeminfo.CaseSensitiveFilesystem ? path : path.toLowerCase();
};
+ function setEntryType(n)
+ {
+ n.entrytype = AppUtils.getEntryTypeFromIconCls(n.iconCls);
+ }
+
function setIconCls(n) {
var cp = compareablePath(n.id);
var dirsep = scope.systeminfo.DirectorySeparator || '/';
@@ -42,6 +47,8 @@ backupApp.directive('destinationFolderPicker', function() {
n.iconCls = 'x-tree-icon-home';
else if (cp.substr(cp.length - 1, 1) != dirsep)
n.iconCls = 'x-tree-icon-leaf';
+
+ setEntryType(n);
}
$scope.toggleExpanded = function(node) {
@@ -59,6 +66,10 @@ backupApp.directive('destinationFolderPicker', function() {
AppService.post('/filesystem?onlyfolders=true&showhidden=true', {path: node.id}).then(function(data) {
node.children = data.data;
node.loading = false;
+
+ if (node.children != null)
+ for(var i in node.children)
+ setEntryType(node.children[i]);
}, function() {
node.loading = false;
@@ -118,7 +129,10 @@ backupApp.directive('destinationFolderPicker', function() {
usernode.children.push(data.data[i]);
}
else
- systemnode.children.push(data.data[i]);
+ {
+ setEntryType(data.data[i]);
+ systemnode.children.push(data.data[i]);
+ }
}
updateHideUserNode();
diff --git a/Duplicati/Server/webroot/ngax/scripts/directives/timeFormatFixer.js b/Duplicati/Server/webroot/ngax/scripts/directives/timeFormatFixer.js
new file mode 100644
index 000000000..56c69bd10
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/directives/timeFormatFixer.js
@@ -0,0 +1,16 @@
+// From: https://mark.zealey.org/2015/01/08/formatting-time-inputs-nicely-with-angularjs
+backupApp.directive('ngModel', function( $filter ) {
+ return {
+ require: '?ngModel',
+ link: function(scope, elem, attr, ngModel) {
+ if( !ngModel )
+ return;
+ if( attr.type !== 'time' )
+ return;
+
+ ngModel.$formatters.unshift(function(value) {
+ return value.replace(/:00\.000$/, '')
+ });
+ }
+ }
+}); \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/scripts/libs/clipboard.min.js b/Duplicati/Server/webroot/ngax/scripts/libs/clipboard.min.js
new file mode 100644
index 000000000..dac064248
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/libs/clipboard.min.js
@@ -0,0 +1,7 @@
+/*!
+ * clipboard.js v1.5.13
+ * https://zenorocha.github.io/clipboard.js
+ *
+ * Licensed MIT © Zeno Rocha
+ */
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function r(c,a){if(!n[c]){if(!e[c]){var l="function"==typeof require&&require;if(!a&&l)return l(c,!0);if(i)return i(c,!0);var s=new Error("Cannot find module '"+c+"'");throw s.code="MODULE_NOT_FOUND",s}var u=n[c]={exports:{}};e[c][0].call(u.exports,function(t){var n=e[c][1][t];return r(n?n:t)},u,u.exports,t,e,n,o)}return n[c].exports}for(var i="function"==typeof require&&require,c=0;c<o.length;c++)r(o[c]);return r}({1:[function(t,e,n){function o(t,e,n){for(n=n||document.documentElement;t&&t!==n;){if(r(t,e))return t;t=t.parentNode}return r(t,e)?t:null}try{var r=t("matches-selector")}catch(e){var r=t("component-matches-selector")}e.exports=o},{"component-matches-selector":2,"matches-selector":2}],2:[function(t,e,n){function o(t,e){if(!t||1!==t.nodeType)return!1;if(c)return c.call(t,e);for(var n=r.all(e,t.parentNode),o=0;o<n.length;++o)if(n[o]==t)return!0;return!1}try{var r=t("query")}catch(e){var r=t("component-query")}var i=Element.prototype,c=i.matches||i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector;e.exports=o},{"component-query":3,query:3}],3:[function(t,e,n){function o(t,e){return e.querySelector(t)}n=e.exports=function(t,e){return e=e||document,o(t,e)},n.all=function(t,e){return e=e||document,e.querySelectorAll(t)},n.engine=function(t){if(!t.one)throw new Error(".one callback required");if(!t.all)throw new Error(".all callback required");return o=t.one,n.all=t.all,n}},{}],4:[function(t,e,n){function o(t,e,n,o,i){var c=r.apply(this,arguments);return t.addEventListener(n,c,i),{destroy:function(){t.removeEventListener(n,c,i)}}}function r(t,e,n,o){return function(n){n.delegateTarget=i(n.target,e,!0),n.delegateTarget&&o.call(t,n)}}var i=t("component-closest");e.exports=o},{"component-closest":1}],5:[function(t,e,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){var e=Object.prototype.toString.call(t);return"[object Function]"===e}},{}],6:[function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!a.string(e))throw new TypeError("Second argument must be a String");if(!a.fn(n))throw new TypeError("Third argument must be a Function");if(a.node(t))return r(t,e,n);if(a.nodeList(t))return i(t,e,n);if(a.string(t))return c(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function r(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function i(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function c(t,e,n){return l(document.body,t,e,n)}var a=t("./is"),l=t("delegate");e.exports=o},{"./is":5,delegate:4}],7:[function(t,e,n){function o(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName)t.focus(),t.setSelectionRange(0,t.value.length),e=t.value;else{t.hasAttribute("contenteditable")&&t.focus();var n=window.getSelection(),o=document.createRange();o.selectNodeContents(t),n.removeAllRanges(),n.addRange(o),e=n.toString()}return e}e.exports=o},{}],8:[function(t,e,n){function o(){}o.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){r.off(t,o),e.apply(n,arguments)}var r=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;for(o;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,c=o.length;i<c;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},e.exports=o},{}],9:[function(e,n,o){!function(r,i){if("function"==typeof t&&t.amd)t(["module","select"],i);else if("undefined"!=typeof o)i(n,e("select"));else{var c={exports:{}};i(c,r.select),r.clipboardAction=c.exports}}(this,function(t,e){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var r=n(e),i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},c=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),a=function(){function t(e){o(this,t),this.resolveOptions(e),this.initSelection()}return t.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action=e.action,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""},t.prototype.initSelection=function t(){this.text?this.selectFake():this.target&&this.selectTarget()},t.prototype.selectFake=function t(){var e=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=document.body.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px";var o=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.addEventListener("focus",window.scrollTo(0,o)),this.fakeElem.style.top=o+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=(0,r.default)(this.fakeElem),this.copyText()},t.prototype.removeFake=function t(){this.fakeHandler&&(document.body.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)},t.prototype.selectTarget=function t(){this.selectedText=(0,r.default)(this.target),this.copyText()},t.prototype.copyText=function t(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)},t.prototype.handleResult=function t(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})},t.prototype.clearSelection=function t(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()},t.prototype.destroy=function t(){this.removeFake()},c(t,[{key:"action",set:function t(){var e=arguments.length<=0||void 0===arguments[0]?"copy":arguments[0];if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function t(){return this._action}},{key:"target",set:function t(e){if(void 0!==e){if(!e||"object"!==("undefined"==typeof e?"undefined":i(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function t(){return this._target}}]),t}();t.exports=a})},{select:7}],10:[function(e,n,o){!function(r,i){if("function"==typeof t&&t.amd)t(["module","./clipboard-action","tiny-emitter","good-listener"],i);else if("undefined"!=typeof o)i(n,e("./clipboard-action"),e("tiny-emitter"),e("good-listener"));else{var c={exports:{}};i(c,r.clipboardAction,r.tinyEmitter,r.goodListener),r.clipboard=c.exports}}(this,function(t,e,n,o){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function c(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function l(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}var s=r(e),u=r(n),f=r(o),d=function(t){function e(n,o){i(this,e);var r=c(this,t.call(this));return r.resolveOptions(o),r.listenClick(n),r}return a(e,t),e.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText},e.prototype.listenClick=function t(e){var n=this;this.listener=(0,f.default)(e,"click",function(t){return n.onClick(t)})},e.prototype.onClick=function t(e){var n=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new s.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})},e.prototype.defaultAction=function t(e){return l("action",e)},e.prototype.defaultTarget=function t(e){var n=l("target",e);if(n)return document.querySelector(n)},e.prototype.defaultText=function t(e){return l("text",e)},e.prototype.destroy=function t(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)},e}(u.default);t.exports=d})},{"./clipboard-action":9,"good-listener":6,"tiny-emitter":8}]},{},[10])(10)}); \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/scripts/libs/ngclipboard.min.js b/Duplicati/Server/webroot/ngax/scripts/libs/ngclipboard.min.js
new file mode 100644
index 000000000..a43bb6bcd
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/libs/ngclipboard.min.js
@@ -0,0 +1,4 @@
+/*! ngclipboard - v1.1.1 - 2016-02-26
+* https://github.com/sachinchoolur/ngclipboard
+* Copyright (c) 2016 Sachin; Licensed MIT */
+!function(){"use strict";var a,b,c="ngclipboard";"object"==typeof module&&module.exports?(a=require("angular"),b=require("clipboard"),module.exports=c):(a=window.angular,b=window.Clipboard),a.module(c,[]).directive("ngclipboard",function(){return{restrict:"A",scope:{ngclipboardSuccess:"&",ngclipboardError:"&"},link:function(a,c){var d=new b(c[0]);d.on("success",function(b){a.$apply(function(){a.ngclipboardSuccess({e:b})})}),d.on("error",function(b){a.$apply(function(){a.ngclipboardError({e:b})})})}}})}(); \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/scripts/menu.js b/Duplicati/Server/webroot/ngax/scripts/menu.js
index f6f0e016f..0d2daa686 100755
--- a/Duplicati/Server/webroot/ngax/scripts/menu.js
+++ b/Duplicati/Server/webroot/ngax/scripts/menu.js
@@ -1,6 +1,11 @@
$(document).ready(function() {
$('html').on('click', function(e) {
$('#mainmenu').removeClass('mobile-open');
+ $('#threedotmenu_add_destination').removeClass('open');
+ $('#threedotmenu_add_destination_adv').removeClass('open');
+ $('#threedotmenu_add_source_folders').removeClass('open');
+ $('#threedotmenu_add_source_filters').removeClass('open');
+ $('#threedotmenu_add_options_adv').removeClass('open');
});
$('body').on('click', '.menubutton', function(e) {
@@ -8,4 +13,35 @@ $(document).ready(function() {
e.preventDefault();
$('#mainmenu').toggleClass('mobile-open');
});
+
+ $('body').on('click', '#threedotmenubutton_add_destination', function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ $('#threedotmenu_add_destination').toggleClass('open');
+ });
+
+ $('body').on('click', '#threedotmenubutton_add_destination_adv', function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ $('#threedotmenu_add_destination_adv').toggleClass('open');
+ });
+
+ $('body').on('click', '#threedotmenubutton_add_source_folders', function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ $('#threedotmenu_add_source_folders').toggleClass('open');
+ });
+
+ $('body').on('click', '#threedotmenubutton_add_source_filters', function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ $('#threedotmenu_add_source_filters').toggleClass('open');
+ });
+
+ $('body').on('click', '#threedotmenubutton_add_options_adv', function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ $('#threedotmenu_add_options_adv').toggleClass('open');
+ });
+
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/AppService.js b/Duplicati/Server/webroot/ngax/scripts/services/AppService.js
index 24d539134..54ffbd112 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/AppService.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/AppService.js
@@ -1,5 +1,5 @@
backupApp.service('AppService', function($http, $cookies, $q, $cookies, DialogService, appConfig) {
- this.apiurl = '/api/v1';
+ this.apiurl = '../api/v1';
this.proxy_url = null;
var self = this;
@@ -116,4 +116,10 @@ backupApp.service('AppService', function($http, $cookies, $q, $cookies, DialogSe
return rurl;
};
+
+ this.log_out = function() {
+ var rurl = '/logout.cgi';
+
+ return installResponseHook($http.get(this.proxy_url == null ? rurl : this.proxy_url, setupConfig('GET', {}, null, rurl)));
+ };
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/AppUtils.js b/Duplicati/Server/webroot/ngax/scripts/services/AppUtils.js
index ef1f2b33c..180e86f27 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/AppUtils.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/AppUtils.js
@@ -1,17 +1,20 @@
-backupApp.service('AppUtils', function($rootScope, $timeout, DialogService, gettextCatalog) {
+backupApp.service('AppUtils', function($rootScope, $timeout, $cookies, DialogService, gettextCatalog) {
var apputils = this;
this.exampleOptionString = '--dblock-size=100MB';
- try {
- moment.locale(
- navigator.languages
- ? navigator.languages[0]
- : (navigator.language || navigator.userLanguage)
- );
- } catch (e) {
- }
+ function setMomentLocale() {
+ try {
+ var browser_lang = navigator.languages ?
+ navigator.languages[0] :
+ (navigator.language || navigator.userLanguage);
+ moment.locale($cookies.get('ui-locale') ? $cookies.get('ui-locale') : browser_lang);
+ } catch (e) {
+ }
+ }
+ setMomentLocale();
+ $rootScope.$on('ui_language_changed', setMomentLocale);
this.formatSizes = ['TB', 'GB', 'MB', 'KB'];
this.formatSizeString = function(val) {
@@ -38,6 +41,40 @@ backupApp.service('AppUtils', function($rootScope, $timeout, DialogService, gett
if (m) $timeout(m);
};
+ this.getEntryTypeFromIconCls = function(cls)
+ {
+ // Entry type is used in as the ALT entry,
+ // to guide screen reading software for visually
+ // impaired users
+
+ var res = gettextCatalog.getString('Folder');
+
+ if (cls == 'x-tree-icon-mydocuments')
+ res = gettextCatalog.getString('My Documents');
+ else if (cls == 'x-tree-icon-mymusic')
+ res = gettextCatalog.getString('My Music');
+ else if (cls == 'x-tree-icon-mypictures')
+ res = gettextCatalog.getString('My Pictures');
+ else if (cls == 'x-tree-icon-desktop')
+ res = gettextCatalog.getString('Desktop');
+ else if (cls == 'x-tree-icon-home')
+ res = gettextCatalog.getString('Home');
+ else if (cls == 'x-tree-icon-hypervmachine')
+ res = gettextCatalog.getString('Hyper-V Machine');
+ else if (cls == 'x-tree-icon-hyperv')
+ res = gettextCatalog.getString('Hyper-V Machines');
+ else if (cls == 'x-tree-icon-broken')
+ res = gettextCatalog.getString('Broken access');
+ else if (cls == 'x-tree-icon-locked')
+ res = gettextCatalog.getString('Access denied');
+ else if (cls == 'x-tree-icon-symlink')
+ res = gettextCatalog.getString('Symbolic link');
+ else if (cls == 'x-tree-icon-leaf')
+ res = gettextCatalog.getString('File');
+
+ return res;
+ };
+
function reloadTexts() {
apputils.fileSizeMultipliers = [
{name: gettextCatalog.getString('byte'), value: ''},
@@ -56,6 +93,12 @@ backupApp.service('AppUtils', function($rootScope, $timeout, DialogService, gett
{name: gettextCatalog.getString('Years'), value: 'Y'}
];
+ apputils.shorttimerangeMultipliers = [
+ {name: gettextCatalog.getString('Seconds'), value: 's'},
+ {name: gettextCatalog.getString('Minutes'), value: 'm'},
+ {name: gettextCatalog.getString('Hours'), value: 'h'}
+ ];
+
apputils.daysOfWeek = [
{name: gettextCatalog.getString('Mon'), value: 'mon'},
{name: gettextCatalog.getString('Tue'), value: 'tue'},
@@ -66,6 +109,15 @@ backupApp.service('AppUtils', function($rootScope, $timeout, DialogService, gett
{name: gettextCatalog.getString('Sun'), value: 'sun'}
];
+ apputils.speedMultipliers = [
+ {name: gettextCatalog.getString('byte/s'), value: ''},
+ {name: gettextCatalog.getString('KByte/s'), value: 'KB'},
+ {name: gettextCatalog.getString('MByte/s'), value: 'MB'},
+ {name: gettextCatalog.getString('GByte/s'), value: 'GB'},
+ {name: gettextCatalog.getString('TByte/s'), value: 'TB'}
+ ];
+
+
apputils.exampleOptionString = gettextCatalog.getString('Enter one option per line in command-line format, eg. {0}');
apputils.filterClasses = [{
@@ -388,7 +440,7 @@ backupApp.service('AppUtils', function($rootScope, $timeout, DialogService, gett
res.querystring.replace(QUERY_REGEXP, function(str, key, val) {
if (key)
- res['--' + key] = decodeURIComponent(val);
+ res['--' + key] = decodeURIComponent((val || '').replace(/\+/g, '%20'));
});
var backends = {};
@@ -551,6 +603,9 @@ backupApp.service('AppUtils', function($rootScope, $timeout, DialogService, gett
items[n].Category = gettextCatalog.getString('Core options');
function copyToList(lst, key) {
+ if (key != null && typeof(key) != typeof(''))
+ key = null;
+
for(var n in lst)
{
if (key == null || key.toLowerCase() == lst[n].Key.toLowerCase())
@@ -576,4 +631,23 @@ backupApp.service('AppUtils', function($rootScope, $timeout, DialogService, gett
return items;
};
+ this.extractServerModuleOptions = function(advOptionsList, servermodulelist, servermodulesettings, optionlistname) {
+ if (optionlistname == null)
+ optionlistname = 'SupportedCommands';
+
+ for(var mix in servermodulelist) {
+ var mod = servermodulelist[mix];
+ for(var oix in mod[optionlistname]) {
+ var opt = mod[optionlistname][oix];
+ var prefixstr = '--' + opt.Name + '=';
+ for (var i = advOptionsList.length - 1; i >= 0; i--) {
+ if (advOptionsList[i].indexOf(prefixstr) == 0) {
+ servermodulesettings[opt.Name] = advOptionsList[i].substr(prefixstr.length);
+ advOptionsList.splice(i, 1);
+ }
+ }
+ }
+ }
+ };
+
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/BrandingService.js b/Duplicati/Server/webroot/ngax/scripts/services/BrandingService.js
index eaa177b1c..b991ecd40 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/BrandingService.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/BrandingService.js
@@ -1,6 +1,10 @@
backupApp.service('BrandingService', function() {
- var state = { 'appName': 'Duplicati', 'appSubtitle': null };
+ var state = {
+ 'appName': 'Duplicati',
+ 'appSubtitle': null,
+ 'appLogoPath': '../img/logo.png'
+ };
this.state = state;
this.watch = function(scope, m) {
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/CaptchaService.js b/Duplicati/Server/webroot/ngax/scripts/services/CaptchaService.js
new file mode 100644
index 000000000..413b1ae95
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/scripts/services/CaptchaService.js
@@ -0,0 +1,55 @@
+backupApp.service('CaptchaService', function(DialogService, AppService, AppUtils, gettextCatalog) {
+ this.active = null;
+ var self = this;
+
+ this.Authorize = function(title, message, target, callback) {
+
+ var cb = self.active = {
+ 'message': message,
+ 'target': target,
+ 'callback': callback,
+ 'attempts': 0,
+ 'hasfailed': false,
+ 'verifying': false
+ };
+
+ self.attemptSolve = function() {
+ if (cb.attempts >= 3) {
+ cb.attempts = 0;
+ cb.token = null;
+ }
+
+ DialogService.htmlDialog(title, 'templates/captcha.html', [gettextCatalog.getString('Cancel'), gettextCatalog.getString('OK')], function(btn) {
+ if (btn != 1) {
+ self.active = null;
+ return;
+ }
+
+ cb.attempts += 1;
+ cb.verifying = true;
+
+
+ DialogService.dialog(gettextCatalog.getString('Verifying answer'), gettextCatalog.getString('Verifying ...'), [], function() {}, function() {
+
+ AppService.post('/captcha/' + encodeURIComponent(cb.token), {'answer': cb.answer, 'target': cb.target}).then(function(resp) {
+ DialogService.dismissCurrent();
+ self.active = null;
+ cb.callback(cb.token, cb.answer);
+ }, function(err) {
+
+ DialogService.dismissCurrent();
+ cb.verifying = false;
+ cb.hasfailed = true;
+ if (err.status == 400)
+ self.attemptSolve();
+ else
+ AppUtils.connectionError(err);
+ });
+
+ });
+ });
+ };
+
+ self.attemptSolve();
+ };
+}); \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/DialogService.js b/Duplicati/Server/webroot/ngax/scripts/services/DialogService.js
index 7be415ce1..d5ab6e5d6 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/DialogService.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/DialogService.js
@@ -1,4 +1,4 @@
-backupApp.service('DialogService', function() {
+backupApp.service('DialogService', function(gettextCatalog) {
var state = this.state = {
CurrentItem: null,
Queue: []
@@ -21,11 +21,11 @@ backupApp.service('DialogService', function() {
this.enqueueDialog = function(config) {
- if (config == null || config.message == null)
+ if (config == null || (config.message == null && config.htmltemplate == null && config.enableTextarea == null))
return;
- config.title = config.title || 'Information';
- config.buttons = config.buttons || ['OK'];
+ config.title = config.title || gettextCatalog.getString('Information');
+ config.buttons = config.buttons || [gettextCatalog.getString('OK')];
state.Queue.push(config);
if (state.CurrentItem == null)
@@ -47,7 +47,7 @@ backupApp.service('DialogService', function() {
return this.enqueueDialog({
'message': message,
'callback': callback,
- 'buttons': ['Cancel', 'OK']
+ 'buttons': [gettextCatalog.getString('Cancel'), gettextCatalog.getString('OK')]
});
};
@@ -55,7 +55,7 @@ backupApp.service('DialogService', function() {
return this.enqueueDialog({
'message': message,
'callback': callback,
- 'buttons': ['OK']
+ 'buttons': [gettextCatalog.getString('OK')]
});
};
@@ -69,6 +69,30 @@ backupApp.service('DialogService', function() {
});
};
+ this.htmlDialog = function(title, htmltemplate, buttons, callback, onshow) {
+ return this.enqueueDialog({
+ 'htmltemplate': htmltemplate,
+ 'title': title,
+ 'callback': callback,
+ 'buttons': buttons,
+ 'onshow': onshow
+ });
+ };
+
+ this.textareaDialog = function(title, message, placeholder, textarea, buttons, buttonTemplate, callback, onshow) {
+ return this.enqueueDialog({
+ 'enableTextarea': true,
+ 'title': title,
+ 'message': message,
+ 'placeholder': placeholder,
+ 'textarea': textarea,
+ 'callback': callback,
+ 'buttons': buttons,
+ 'buttonTemplate': buttonTemplate,
+ 'onshow': onshow
+ });
+ };
+
this.dismissCurrent = function() {
if (state.CurrentItem != null) {
if (state.CurrentItem.ondismiss)
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBackendConfig.js b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBackendConfig.js
index 8a2d27cc5..69f30a1d0 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBackendConfig.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBackendConfig.js
@@ -60,14 +60,14 @@ backupApp.service('EditUriBackendConfig', function(AppService, AppUtils, SystemI
this.show_error_dialog = function(msg) {
DialogService.dialog('Error', msg);
return false;
- }
+ };
this.show_warning_dialog = function(msg, continuation) {
DialogService.dialog(gettextCatalog.getString('Confirmation required'), msg, [gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
if (ix == 1)
continuation();
});
- }
+ };
this.defaultvalidater = function(scope, continuation) {
continuation();
@@ -89,7 +89,7 @@ backupApp.service('EditUriBackendConfig', function(AppService, AppUtils, SystemI
this.require_path = function(scope) {
if ((scope.Path || '').trim().length == 0)
- return self.show_error_dialog(gettextCatalog.getString('You must fill in the path'));
+ return self.show_error_dialog(gettextCatalog.getString('You must specify a path'));
return true;
};
@@ -110,4 +110,11 @@ backupApp.service('EditUriBackendConfig', function(AppService, AppUtils, SystemI
return true;
};
+ this.require_username = function(scope) {
+ if ((scope.Username || '').trim().length == 0)
+ return self.show_error_dialog(gettextCatalog.getString('You must fill in the username'));
+
+ return true;
+ };
+
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js
index 2f3642d56..882e4766b 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js
@@ -23,8 +23,10 @@ backupApp.service('EditUriBuiltins', function(AppService, AppUtils, SystemInfo,
EditUriBackendConfig.templates['gcs'] = 'templates/backends/gcs.html';
EditUriBackendConfig.templates['b2'] = 'templates/backends/b2.html';
EditUriBackendConfig.templates['mega'] = 'templates/backends/mega.html';
+ EditUriBackendConfig.templates['jottacloud'] = 'templates/backends/jottacloud.html';
EditUriBackendConfig.templates['box'] = 'templates/backends/oauth.html';
- EditUriBackendConfig.templates['dropbox'] = 'templates/backends/oauth.html';
+ EditUriBackendConfig.templates['dropbox'] = 'templates/backends/oauth.html';
+ EditUriBackendConfig.templates['sia'] = 'templates/backends/sia.html';
EditUriBackendConfig.testers['s3'] = function(scope, callback) {
@@ -355,6 +357,23 @@ backupApp.service('EditUriBuiltins', function(AppService, AppUtils, SystemInfo,
EditUriBackendConfig.mergeServerAndPath(scope);
};
+ EditUriBackendConfig.parsers['jottacloud'] = function(scope, module, server, port, path, options) {
+ EditUriBackendConfig.mergeServerAndPath(scope);
+ };
+
+ EditUriBackendConfig.parsers['sia'] = function (scope, module, server, port, path, options) {
+ if (options['--sia-targetpath'])
+ scope.sia_targetpath = options['--sia-targetpath'];
+ if (options['--sia-redundancy'])
+ scope.sia_redundancy = options['--sia-redundancy'];
+ if (options['--sia-password'])
+ scope.sia_password = options['--sia-password'];
+
+ var nukeopts = ['--sia-targetpath', '--sia-redundancy', '--sia-password'];
+ for (var x in nukeopts)
+ delete options[nukeopts[x]];
+ };
+
// Builders take the scope and produce the uri output
EditUriBackendConfig.builders['s3'] = function(scope) {
var opts = {
@@ -519,6 +538,42 @@ backupApp.service('EditUriBuiltins', function(AppService, AppUtils, SystemInfo,
return url;
};
+ EditUriBackendConfig.builders['sia'] = function (scope) {
+ var opts = {
+ 'sia-password': scope.sia_password,
+ 'sia-targetpath': scope.sia_targetpath,
+ 'sia-redundancy': scope.sia_redundancy
+ };
+
+ EditUriBackendConfig.merge_in_advanced_options(scope, opts);
+
+ var url = AppUtils.format('{0}://{1}/{2}{3}',
+ scope.Backend.Key,
+ scope.Server || '',
+ scope.sia_targetpath || '',
+ AppUtils.encodeDictAsUrl(opts)
+ );
+
+ return url;
+ }
+
+ EditUriBackendConfig.builders['jottacloud'] = function (scope) {
+ var opts = { };
+
+ EditUriBackendConfig.merge_in_advanced_options(scope, opts);
+
+ // Slightly better error message
+ scope.Folder = scope.Path;
+
+ var url = AppUtils.format('{0}://{1}{2}',
+ scope.Backend.Key,
+ scope.Path,
+ AppUtils.encodeDictAsUrl(opts)
+ );
+
+ return url;
+ };
+
EditUriBackendConfig.validaters['file'] = function(scope, continuation) {
if (EditUriBackendConfig.require_path(scope))
continuation();
@@ -543,7 +598,7 @@ backupApp.service('EditUriBuiltins', function(AppService, AppUtils, SystemInfo,
EditUriBackendConfig.validaters['ssh'] = function(scope, continuation) {
var res =
EditUriBackendConfig.require_server(scope) &&
- EditUriBackendConfig.require_username_and_password(scope);
+ EditUriBackendConfig.require_username(scope);
if (res)
EditUriBackendConfig.recommend_path(scope, continuation);
@@ -564,19 +619,20 @@ backupApp.service('EditUriBuiltins', function(AppService, AppUtils, SystemInfo,
EditUriBackendConfig.validaters['hubic'] = function(scope, continuation) {
- var prefix = 'HubiC-DeskBackup_Duplicati/';
+ var prefix1 = 'HubiC-DeskBackup_Duplicati/';
+ var prefix2 = 'default/'
EditUriBackendConfig.validaters['onedrive'](scope, function() {
var p = (scope.Path || '').trim();
- if (p.length > 0 && p.indexOf('default/') != 0 && p.indexOf(prefix) != 0) {
- DialogService.dialog(gettextCatalog.getString('Adjust path name?'), gettextCatalog.getString('The path should start with "{{prefix}}" or "{{def}}", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?', {prefix: prefix, def: 'default' }), [gettextCatalog.getString('Cancel'), gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
+ if (p.length > 0 && p.indexOf(prefix2) != 0 && p.indexOf(prefix1) != 0) {
+ DialogService.dialog(gettextCatalog.getString('Adjust path name?'), gettextCatalog.getString('The path should start with "{{prefix1}}" or "{{prefix2}}", otherwise you will not be able to see the files in the HubiC web interface.\n\nDo you want to add the prefix to the path automatically?', {prefix1: prefix1, prefix2: prefix2 }), [gettextCatalog.getString('Cancel'), gettextCatalog.getString('No'), gettextCatalog.getString('Yes')], function(ix) {
if (ix == 2) {
while (p.indexOf('/') == 0)
p = p.substr(1);
- scope.Path = prefix + p;
+ scope.Path = prefix2 + p;
}
if (ix == 1 || ix == 2)
continuation();
@@ -589,7 +645,6 @@ backupApp.service('EditUriBuiltins', function(AppService, AppUtils, SystemInfo,
};
EditUriBackendConfig.validaters['googledrive'] = EditUriBackendConfig.validaters['onedrive'];
- EditUriBackendConfig.validaters['hubic'] = EditUriBackendConfig.validaters['onedrive'];
EditUriBackendConfig.validaters['gcs'] = EditUriBackendConfig.validaters['onedrive'];
EditUriBackendConfig.validaters['amzcd'] = EditUriBackendConfig.validaters['onedrive'];
EditUriBackendConfig.validaters['box'] = EditUriBackendConfig.validaters['onedrive'];
@@ -697,5 +752,31 @@ backupApp.service('EditUriBuiltins', function(AppService, AppUtils, SystemInfo,
continuation();
};
+ EditUriBackendConfig.validaters['jottacloud'] = function(scope, continuation) {
+ scope.Path = scope.Path || '';
+ var res =
+ EditUriBackendConfig.require_field(scope, 'Username', gettextCatalog.getString('Username')) &&
+ EditUriBackendConfig.require_field(scope, 'Password', gettextCatalog.getString('Password'));
+
+ if (res)
+ continuation();
+ };
+
+ EditUriBackendConfig.validaters['sia'] = function (scope, continuation) {
+ var res =
+ EditUriBackendConfig.require_field(scope, 'Server', gettextCatalog.getString('Server'));
+
+ var re = new RegExp('^(([a-zA-Z0-9-])|(\/(?!\/)))*$');
+ if (res && !re.test(scope['sia_targetpath'])) {
+ res = EditUriBackendConfig.show_error_dialog(gettextCatalog.getString('Invalid characters in path'));
+ }
+
+ if (res && (scope['sia_redundancy'] || '').trim().length == 0 || parseFloat(scope['sia_redundancy']) < 1.0)
+ res = EditUriBackendConfig.show_error_dialog(gettextCatalog.getString('Minimum redundancy is 1.0'));
+
+ if (res)
+ continuation();
+ };
+
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js b/Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js
index bc54e6946..f50360039 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js
@@ -57,6 +57,12 @@ backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, App
'Repair_Running': gettextCatalog.getString('Reparing ...'),
'Verify_Running': gettextCatalog.getString('Verifying ...'),
'BugReport_Running': gettextCatalog.getString('Creating bug report ...'),
+ 'Delete_Listing': gettextCatalog.getString('Listing remote files ...'),
+ 'Delete_Deleting': gettextCatalog.getString('Deleting remote files ...'),
+ 'PurgeFiles_Begin,': gettextCatalog.getString('Listing remote files ...'),
+ 'PurgeFiles_Process,': gettextCatalog.getString('Purging files ...'),
+ 'PurgeFiles_Compact,': gettextCatalog.getString('Compacting remote data ...'),
+ 'PurgeFiles_Complete,': gettextCatalog.getString('Finished!'),
'Error': gettextCatalog.getString('Error!')
};
};
@@ -188,7 +194,7 @@ backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, App
return false;
}
- var longpoll = function() {
+ var longpoll = function(fastcall) {
if (longPollRetryTimer != null) {
window.clearInterval(longPollRetryTimer);
longPollRetryTimer = null;
@@ -199,7 +205,7 @@ backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, App
$rootScope.$broadcast('serverstatechanged');
}
- var url = '/serverstate/?lasteventid=' + parseInt(state.lastEventId) + '&longpoll=' + (state.lastEventId > 0 ? 'true' : 'false') + '&duration=' + parseInt((longpolltime-1000) / 1000) + 's';
+ var url = '/serverstate/?lasteventid=' + parseInt(state.lastEventId) + '&longpoll=' + (((!fastcall) && (state.lastEventId > 0)) ? 'true' : 'false') + '&duration=' + parseInt((longpolltime-1000) / 1000) + 's';
AppService.get(url, {timeout: state.lastEventId > 0 ? longpolltime : 5000}).then(
function (response) {
var oldEventId = state.lastEventId;
@@ -209,7 +215,7 @@ backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, App
notifyIfChanged(response.data, 'LastNotificationUpdateID', 'lastNotificationUpdateId') |
notifyIfChanged(response.data, 'ActiveTask', 'activeTask') |
notifyIfChanged(response.data, 'ProgramState', 'programState') |
- notifyIfChanged(response.data, 'EstimatedPauseEnd', 'estimatedPauseEnd')
+ notifyIfChanged(response.data, 'EstimatedPauseEnd', 'estimatedPauseEnd') |
notifyIfChanged(response.data, 'UpdaterState', 'updaterState') |
notifyIfChanged(response.data, 'UpdateReady', 'updateReady') |
notifyIfChanged(response.data, 'UpdatedVersion', 'updatedVersion')|
@@ -253,7 +259,7 @@ backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, App
startUpdateProgressPoll();
- longpoll();
+ longpoll(false);
},
function(response) {
@@ -266,17 +272,17 @@ backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, App
if (state.connectionState == 'connected' && state.failedConnectionAttempts == 1) {
// Try again
- longpoll();
+ longpoll(true);
} else {
state.connectionState = 'disconnected';
//If we got a new XSRF token this time, quickly retry
if (state.xsfrerror && !oldxsfrstate) {
- longpoll();
+ longpoll(true);
} else {
// Otherwise, start countdown to next try
- countdownForForReLongPoll(longpoll);
+ countdownForForReLongPoll(function() { longpoll(true); });
}
}
@@ -287,7 +293,7 @@ backupApp.service('ServerStatus', function($rootScope, $timeout, AppService, App
);
};
- this.reconnect = longpoll;
+ this.reconnect = function() { longpoll(true); };
- longpoll();
+ longpoll(true);
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js b/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js
index 2eb31e08b..4e1bfb741 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js
@@ -67,7 +67,9 @@ backupApp.service('SystemInfo', function($rootScope, $timeout, $cookies, AppServ
'box': null,
'od4b': null,
'mssp': null,
- 'dropbox': null
+ 'dropbox': null,
+ 'sia': null,
+ 'jottacloud': null
}
};
@@ -117,7 +119,7 @@ backupApp.service('SystemInfo', function($rootScope, $timeout, $cookies, AppServ
if ((uiLanguage || '').trim().length == 0) {
gettextCatalog.setCurrentLanguage(state.BrowserLocale.Code.replace("-", "_"));
} else {
- gettextCatalog.setCurrentLanguage(uiLanguage);
+ gettextCatalog.setCurrentLanguage(uiLanguage.replace("-", "_"));
}
}
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
index c09235f60..a2e6bfc08 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
index d29011d2a..e36540bbf 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
index 1558bea51..294b563cb 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
index 0359b121f..3e56dbdca 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_dadada_1x400.png
index 4fce6c462..6b8b33a18 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_dadada_1x400.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_dadada_1x400.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
index 5299b5a0b..8cc46b392 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
index 398c56a9c..c02d12430 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
index d819aa58a..ae3ccae06 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_222222_256x240.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_222222_256x240.png
index c1cb1170c..474de8f3a 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_222222_256x240.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_222222_256x240.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_2e83ff_256x240.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_2e83ff_256x240.png
index 84b601bf0..ef2de6a3f 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_2e83ff_256x240.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_454545_256x240.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_454545_256x240.png
index b6db1acdd..474b1a4c6 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_454545_256x240.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_454545_256x240.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_888888_256x240.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_888888_256x240.png
index feea0e202..1f9ef5692 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_888888_256x240.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_888888_256x240.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_cd0a0a_256x240.png b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_cd0a0a_256x240.png
index ed5b6b093..fe8dbf10f 100755
--- a/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_cd0a0a_256x240.png
+++ b/Duplicati/Server/webroot/ngax/styles/smoothness/images/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/Duplicati/Server/webroot/ngax/styles/style.css b/Duplicati/Server/webroot/ngax/styles/style.css
index 432dd1fdf..e8018d31e 100755..100644
--- a/Duplicati/Server/webroot/ngax/styles/style.css
+++ b/Duplicati/Server/webroot/ngax/styles/style.css
@@ -1,4 +1,4 @@
-@font-face{font-family:'Clear Sans';src:url(../fonts/ClearSans-Light-webfont.eot);src:url(../fonts/ClearSans-Light-webfont.eot?#iefix) format('embedded-opentype'),url(../fonts/ClearSans-Light-webfont.woff) format('woff'),url(../fonts/ClearSans-Light-webfont.ttf) format('truetype'),url(../fonts/ClearSans-Light-webfont.svg#clear_sans_lightregular) format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Clear Sans';src:url(../fonts/ClearSans-Regular-webfont.eot);src:url(../fonts/ClearSans-Regular-webfont.eot?#iefix) format('embedded-opentype'),url(../fonts/ClearSans-Regular-webfont.woff) format('woff'),url(../fonts/ClearSans-Regular-webfont.ttf) format('truetype'),url(../fonts/ClearSans-Regular-webfont.svg#clear_sansregular) format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Clear Sans';src:url(../fonts/ClearSans-Medium-webfont.eot);src:url(../fonts/ClearSans-Medium-webfont.eot?#iefix) format('embedded-opentype'),url(../fonts/ClearSans-Medium-webfont.woff) format('woff'),url(../fonts/ClearSans-Medium-webfont.ttf) format('truetype'),url(../fonts/ClearSans-Medium-webfont.svg#clear_sans_mediumregular) format('svg');font-weight:500;font-style:normal}@font-face{font-family:'Clear Sans';src:url(../fonts/ClearSans-Bold-webfont.eot);src:url(../fonts/ClearSans-Bold-webfont.eot?#iefix) format('embedded-opentype'),url(../fonts/ClearSans-Bold-webfont.woff) format('woff'),url(../fonts/ClearSans-Bold-webfont.ttf) format('truetype'),url(../fonts/ClearSans-Bold-webfont.svg#clear_sansbold) format('svg');font-weight:700;font-style:normal}form.styled label{display:block;width:190px;float:left;line-height:37px}form.styled input,form.styled select,form.styled textarea{color:#8f8f8f;font-size:16px;font-weight:300;float:left;display:block;border:1px #d8d8d8 solid;border-radius:2px;width:420px}form.styled input:focus,form.styled select:focus,form.styled textarea:focus{border:1px #a5a5a5 solid}form.styled .input{padding-bottom:18px;overflow:hidden}form.styled .input.password input,form.styled .input.text input{height:35px;line-height:35px;padding:0 12px}form.styled .input.text.text-browse input{width:375px;border-top-right-radius:0;border-bottom-right-radius:0;border-right:0}form.styled .input.text.text-browse a.browse{width:45px;display:block;float:left;height:37px;border-radius:2px;border-top-left-radius:0;border-bottom-left-radius:0;color:#fff;background:#65b1dd;line-height:37px}form.styled .input.text.text-browse a.browse:hover{background:#2881b4}form.styled .input.textarea textarea{height:130px;padding:10px 12px}form.styled .input.select select{width:446px;padding:0 12px;-webkit-appearance:menulist-button;background:#fff;border-radius:2px;height:38px;line-height:38px}form.styled .buttons{overflow:hidden;float:right}form.styled .buttons a,form.styled .buttons input{display:block;background:#65b1dd;color:#fff!important;padding:5px 15px;float:right;margin-left:10px;cursor:pointer;width:auto;border:none;font-family:'Clear Sans',sans-serif;font-size:16px;font-weight:300;border-radius:0}form.styled .buttons input{padding:4px 15px}form.styled .buttons a:hover,form.styled .buttons input:hover{background:#23729f}@media (max-width:480px){form.styled input,form.styled select,form.styled textarea{font-size:15px}}/*!
+@font-face{font-family:'Clear Sans';src:url(../fonts/ClearSans-Light-webfont.eot);src:url(../fonts/ClearSans-Light-webfont.eot?#iefix) format('embedded-opentype'),url(../fonts/ClearSans-Light-webfont.woff) format('woff'),url(../fonts/ClearSans-Light-webfont.ttf) format('truetype'),url(../fonts/ClearSans-Light-webfont.svg#clear_sans_lightregular) format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Clear Sans';src:url(../fonts/ClearSans-Regular-webfont.eot);src:url(../fonts/ClearSans-Regular-webfont.eot?#iefix) format('embedded-opentype'),url(../fonts/ClearSans-Regular-webfont.woff) format('woff'),url(../fonts/ClearSans-Regular-webfont.ttf) format('truetype'),url(../fonts/ClearSans-Regular-webfont.svg#clear_sansregular) format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Clear Sans';src:url(../fonts/ClearSans-Medium-webfont.eot);src:url(../fonts/ClearSans-Medium-webfont.eot?#iefix) format('embedded-opentype'),url(../fonts/ClearSans-Medium-webfont.woff) format('woff'),url(../fonts/ClearSans-Medium-webfont.ttf) format('truetype'),url(../fonts/ClearSans-Medium-webfont.svg#clear_sans_mediumregular) format('svg');font-weight:500;font-style:normal}@font-face{font-family:'Clear Sans';src:url(../fonts/ClearSans-Bold-webfont.eot);src:url(../fonts/ClearSans-Bold-webfont.eot?#iefix) format('embedded-opentype'),url(../fonts/ClearSans-Bold-webfont.woff) format('woff'),url(../fonts/ClearSans-Bold-webfont.ttf) format('truetype'),url(../fonts/ClearSans-Bold-webfont.svg#clear_sansbold) format('svg');font-weight:700;font-style:normal}form.styled div.leftflush input{width:auto;margin-top:10px}form.styled div.leftflush label{width:auto;min-width:190px}form.styled label{display:block;width:190px;float:left;line-height:37px}form.styled input,form.styled select,form.styled textarea{color:#8f8f8f;font-size:16px;font-weight:300;float:left;display:block;border:1px #d8d8d8 solid;border-radius:2px;width:420px}form.styled input:focus,form.styled select:focus,form.styled textarea:focus{border:1px #a5a5a5 solid}form.styled .input{padding-bottom:18px;overflow:hidden}form.styled .input.password input,form.styled .input.text input{height:35px;line-height:35px;padding:0 12px}form.styled .input.text.text-browse input{width:375px;border-top-right-radius:0;border-bottom-right-radius:0;border-right:0}form.styled .input.text.text-browse a.browse{width:45px;display:block;float:left;height:37px;border-radius:2px;border-top-left-radius:0;border-bottom-left-radius:0;color:#fff;background:#65b1dd;line-height:37px}form.styled .input.text.text-browse a.browse:hover{background:#2881b4}form.styled .input.textarea textarea{height:130px;padding:10px 12px}form.styled .input.select select{width:446px;padding:0 12px;-webkit-appearance:menulist-button;background:#fff;border-radius:2px;height:38px;line-height:38px}form.styled .buttons{overflow:hidden;float:right}form.styled .buttons a,form.styled .buttons input{display:block;background:#65b1dd;color:#fff!important;padding:5px 15px;float:right;margin-left:10px;cursor:pointer;width:auto;border:none;font-family:'Clear Sans',sans-serif;font-size:16px;font-weight:300;border-radius:0}form.styled .buttons input{padding:4px 15px}form.styled .buttons a:hover,form.styled .buttons input:hover{background:#23729f}@media (max-width:480px){form.styled input,form.styled select,form.styled textarea{font-size:15px}}/*!
* Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.5.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0) format('embedded-opentype'),url(../fonts/fontawesome-webfont.woff2?v=4.5.0) format('woff2'),url(../fonts/fontawesome-webfont.woff?v=4.5.0) format('woff'),url(../fonts/fontawesome-webfont.ttf?v=4.5.0) format('truetype'),url(../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}*{font-family:'Clear Sans',sans-serif}body,html{margin:0;padding:0;height:100%}h1,h2{font-weight:300;color:#81c401}h1{margin:10px 0}h3{font-weight:400}a{text-decoration:none}ul{list-style:none;margin:0;padding:0}hr{border:none;border-bottom:1px #ddd solid}textarea{max-width:94%}.button{display:block;background:#65b1dd;color:#fff!important;padding:5px 15px;float:right;margin-left:10px;cursor:pointer;width:auto;border:none;font-family:'Clear Sans',sans-serif;font-size:16px;font-weight:300;border-radius:0}.button:hover{background:#3b9cd4}body{color:#8f8f8f}body .container{min-height:100%;position:relative}body .container .header{height:70px;line-height:70px;background:#ededed;overflow:hidden}body .container .header a{color:#65b1dd}body .container .header a.active,body .container .header a:hover{color:#4f4f4f}body .container .header .logo{font-size:30px;font-weight:700;float:left;padding-left:50px}body .container .header .about-header{float:right;padding-right:20px;overflow:hidden}body .container .header .about-header ul{overflow:hidden;list-style:none}body .container .header .about-header ul li{float:right;padding-right:20px}body .container .header .donate img{opacity:.6}body .container .header .donate img:hover{opacity:1}body .container .body{width:100%;overflow:hidden;min-height:500px;padding-top:50px;padding-bottom:70px}body .container .body a{color:#65b1dd}body .container .body .mainmenu{width:260px;padding-left:40px;float:left}body .container .body .mainmenu ul li{position:relative}body .container .body .mainmenu ul li a{font-size:22px;font-weight:300;padding:5px 10px 5px 55px;display:block}body .container .body .mainmenu ul li a.active,body .container .body .mainmenu ul li a:hover{color:#fff}body .container .body .mainmenu ul li a.add{background:url(../img/mainmenu/add.png) no-repeat 8px 7px}body .container .body .mainmenu ul li a.restore{background:url(../img/mainmenu/restore.png) no-repeat 8px 7px}body .container .body .mainmenu ul li a.pause{background:url(../img/mainmenu/pause.png) no-repeat 8px 7px}body .container .body .mainmenu ul li a.settings{background:url(../img/mainmenu/settings.png) no-repeat 8px 7px}body .container .body .mainmenu ul li a.log{background:url(../img/mainmenu/log.png) no-repeat 8px 7px}body .container .body .mainmenu ul li a.add.active,body .container .body .mainmenu ul li a.add:hover{background:#65b1dd url(../img/mainmenu/over/add.png) no-repeat 8px 7px}body .container .body .mainmenu ul li a.restore.active,body .container .body .mainmenu ul li a.restore:hover{background:#65b1dd url(../img/mainmenu/over/restore.png) no-repeat 8px 7px}body .container .body .mainmenu ul li a.pause.active,body .container .body .mainmenu ul li a.pause:hover{background:#65b1dd url(../img/mainmenu/over/pause.png) no-repeat 8px 7px}body .container .body .mainmenu ul li a.settings.active,body .container .body .mainmenu ul li a.settings:hover{background:#65b1dd url(../img/mainmenu/over/settings.png) no-repeat 8px 7px}body .container .body .mainmenu ul li a.log.active,body .container .body .mainmenu ul li a.log:hover{background:#65b1dd url(../img/mainmenu/over/log.png) no-repeat 8px 7px}body .container .body .mainmenu ul li ul{position:absolute;left:200px;top:25px;background:#fff;border:1px #ededed solid;box-shadow:0 7px 15px rgba(0,0,0,.2);z-index:200}body .container .body .mainmenu ul li ul li a{color:#8f8f8f;font-size:15px;font-weight:400;padding:0;display:block;width:205px;padding:4px 10px}body .container .body .mainmenu ul li ul li a.active,body .container .body .mainmenu ul li ul li a:hover{background:#65b1dd;color:#fff}body .container .body .mainmenu ul li.hr-top{padding-top:25px;margin-top:25px;border-top:1px #ededed solid}body .container .body .content{float:left;padding-left:50px;padding-bottom:50px;max-width:700px}body .container .body .content ul.tabs>li{display:inline-block}body .container .body .content .state{color:#81c401;width:575px;padding:13px 15px;border:1px #81c401 solid;font-weight:300;font-size:18px;overflow:hidden}body .container .body .content .state strong{display:inline-block;margin-right:10px}body .container .body .content .state .button{position:static;margin-top:70px}body .container .body .content .tasks{padding-top:20px}body .container .body .content .tasks .tasklist .task{border-top:1px solid #eee;padding-top:20px;margin-bottom:25px}body .container .body .content .tasks .tasklist .task:last-child{border-bottom:1px solid #eee;padding-bottom:20px}body .container .body .content .tasks .tasklist a{font-size:30px;padding-left:55px;background:url(../img/backup.png) no-repeat 5px 6px;font-weight:300;display:inline-block}body .container .body .content .tasks .tasklist a::after{content:" >"}body .container .body .content .tasks .tasklist dl{padding-left:55px;overflow:hidden;font-size:14px}body .container .body .content .tasks .tasklist dl dd,body .container .body .content .tasks .tasklist dl dt{display:block;float:left}body .container .body .content .tasks .tasklist dl dt{clear:both;font-weight:500;margin-bottom:5px}body .container .body .content .tasks .tasklist dl dd{margin-left:10px}body .container .body .content .tasks .tasklist dl.contextmenu dt{float:left;margin-right:10px;margin-bottom:0;padding:5px 8px;color:#8f8f8f;cursor:pointer;clear:none}body .container .body .content .tasks .tasklist dl.contextmenu dd{clear:both;float:none;padding-bottom:8px;border-bottom:1px #ddd solid;margin-bottom:5px}body .container .body .content div.add .steps{width:100%;overflow:hidden;margin-left:50px}body .container .body .content div.add .steps .step{float:left;padding-left:130px;background:url(../img/steps/line-out.png) no-repeat top left;color:#c7e5f6}body .container .body .content div.add .steps .step span{display:block;border:4px #c7e5f6 solid;background:#fff;border-radius:50%;width:35px;height:35px;text-align:center;font-size:22px;line-height:35px;cursor:pointer}body .container .body .content div.add .steps .step.active{color:#65b1dd}body .container .body .content div.add .steps .step.active span{border:4px #65b1dd solid;background:#65b1dd;color:#fff}body .container .body .content div.add .steps .step.active h2{color:#65b1dd}body .container .body .content div.add .steps .step:first-child{padding-left:0;background:0 0}body .container .body .content div.add .steps-boxes{padding-left:40px}body .container .body .content div.add .steps-boxes .step{display:none}body .container .body .content div.add .steps-boxes .step.active{display:block}body .container .body .content div.add .steps-boxes .box.browser .checklinks a{float:left;margin-left:20px;color:#8f8f8f}body .container .body .content div.add .steps-boxes .box.browser .checklinks a i{border:2px solid;border-color:#8f8f8f;border-radius:2px;font-size:18px;height:18px;vertical-align:top;width:18px}body .container .body .content div.add .steps-boxes .box.browser .checklinks a.inactive{color:#c2c2c2;cursor:default}body .container .body .content div.add .steps-boxes .box.browser .checklinks a.inactive i{border-color:#c2c2c2}body .container .body .content div.add .steps-boxes .box.browser .checklinks a:first-child{margin-left:0}body .container .body .content div.add .steps-boxes .box.browser .input.overlayButton{padding-top:10px;max-width:100%}body .container .body .content div.add .steps-boxes .box.browser .input.overlayButton input#sourcePath{width:100%;box-sizing:border-box;height:37px}body .container .body .content div.add .steps-boxes .box.browser .input.overlayButton a.button{top:10px}body .container .body .content div.add .steps-boxes .box.filters .input.link a{color:#8f8f8f}body .container .body .content div.add .steps-boxes .box.filters .input.link a i{border:2px solid;border-color:#8f8f8f;border-radius:2px;font-size:18px;height:18px;vertical-align:top;width:18px}body .container .body .content div.add .steps-boxes .box.filters ul#simplefilterlist{overflow:hidden;padding-bottom:15px}body .container .body .content div.add .steps-boxes .box.filters ul#simplefilterlist li{overflow:hidden;clear:both;padding-bottom:5px}body .container .body .content div.add .steps-boxes .box.filters ul#simplefilterlist li select{width:200px;margin-right:5px;height:36px;line-height:36px}body .container .body .content div.add .steps-boxes .box.filters ul#simplefilterlist li input{width:280px;padding:5px}body .container .body .content div.add .steps-boxes .step4 div.input.keepBackups input.number,body .container .body .content div.add .steps-boxes .step4 div.input.maxSize input.number{width:60px}body .container .body .content div.add .steps-boxes .step4 .advancedoptions{padding-top:15px;clear:both}body .container .body .content div.add .steps-boxes .step4 .advancedoptions li{border-top:none}body .container .body .content div.add .steps-boxes .step4 .advancedoptions li>a{display:block;background:#65b1dd;color:#fff!important;padding:5px 15px;float:right;margin-left:10px;cursor:pointer;width:auto;border:none;font-family:'Clear Sans',sans-serif;font-size:16px;font-weight:300;border-radius:0}body .container .body .content div.add .steps-boxes .step4 .advancedoptions li.advancedentry{border-bottom:1px solid #d3d3d3}body .container .body .content div.add .steps-boxes .step4 .advancedoptions li:last-child{padding-top:0}body .container .body .content div.add .steps-boxes .step4 .advancedoptions li:last-child select{max-width:400px}body .container .body .content div.add .steps-boxes .step4 .advancedoptions label{line-height:normal}body .container .body .content div.add .steps-boxes .step4 .advancedoptions input,body .container .body .content div.add .steps-boxes .step4 .advancedoptions select{width:auto;max-width:100%;box-sizing:border-box}body .container .body .content div.add .steps-boxes .step4 .advancedoptions .longdescription{margin-top:10px}body .container .body .content div.add .steps-boxes .step4 .advanced-toggle{color:#8f8f8f;line-height:normal;margin-top:16px;clear:both;float:left}body .container .body .content div.add .steps-boxes .step4 .advanced-toggle i.fa{border:2px solid;border-color:#8f8f8f;border-radius:2px;font-size:18px;height:18px;vertical-align:top;width:18px}body .container .body .content div.add .steps-boxes .step4 textarea{box-sizing:border-box;clear:both;margin-top:15px;width:100%}body .container .body .content div.add .steps-legend{overflow:hidden;padding-bottom:50px;list-style:none;padding-left:0;margin:0}body .container .body .content div.add .steps-legend li{color:#c7e5f6;font-size:18px;text-align:center;float:left;width:175px;padding-top:10px;cursor:pointer}body .container .body .content div.add .steps-legend li:first-child{width:140px;padding-right:15px}body .container .body .content div.add .steps-legend li.active{color:#65b1dd}body .container .body .content div.add form{padding-bottom:50px;overflow:hidden}body .container .body .content div.add form .input.password .tools{clear:both;padding-left:190px;padding-top:10px}body .container .body .content div.add form .input.password .tools ul{overflow:hidden}body .container .body .content div.add form .input.password .tools ul li{float:left;padding-right:7px}body .container .body .content div.add form .input.password .tools ul li.strength.useless{color:red}body .container .body .content div.add form .input.password .tools ul li.strength.average{color:#ff0}body .container .body .content div.add form .input.password .tools ul li.strength.good{color:#65b1dd}body .container .body .content div.add form .input.multiple input,body .container .body .content div.add form .input.multiple select{width:auto;margin-right:5px}body .container .body .content div.add form .input.multiple select{padding:5px 12px}body .container .body .content div.add form .input.overlayButton{overflow:hidden;position:relative;max-width:446px}body .container .body .content div.add form .input.overlayButton input{width:347px}body .container .body .content div.add form .input.overlayButton a.button{position:absolute;top:0;right:0;padding:7px 12px 8px}body .container .body .content div.add form .input.checkbox.multiple strong{display:block;padding-bottom:5px}body .container .body .content div.add form .input.checkbox.multiple label{display:inline-block;float:none;width:auto;padding-right:10px}body .container .body .content div.add form .input.checkbox.multiple input{width:auto;display:inline-block;float:none}body .container .body .content div.add form .buttons{float:none;width:635px;padding-top:30px}body .container .body .content div.settings .input.checkbox input.checkbox,body .container .body .content div.settings .input.mixed.multiple input.checkbox{width:auto}body .container .body .content div.settings .input.checkbox select,body .container .body .content div.settings .input.mixed.multiple select{width:auto;margin-right:5px}body .container .body .content div.settings .input.checkbox label,body .container .body .content div.settings .input.mixed.multiple label{line-height:normal;padding:0 15px;width:auto}body .container .body .content .logpage ul.tabs{padding:15px 0}body .container .body .content .logpage ul.entries li{padding-top:15px}body .container .body .content .prewrapped-text{white-space:pre-wrap;overflow-x:auto}body .container .footer{background:#ededed;min-height:70px;line-height:70px;overflow:hidden;position:absolute;bottom:0;width:100%}body .container .footer a{color:#65b1dd}body .container .footer .about-footer{float:left;overflow:hidden;padding-right:20px}body .container .footer .about-footer span{display:block;float:left;padding-left:20px}body .container .footer .about-footer ul{float:left}body .container .footer .about-footer li{float:left;padding-left:20px}body .container .footer .donate{float:right;padding-right:40px;overflow:hidden}body .container .footer .donate ul{overflow:hidden;float:right}body .container .footer .donate ul li{float:left;margin-left:20px}body .container .footer .donate ul li a img{margin-top:24px;display:inline-block;opacity:.6}body .container .footer .donate ul li a img:hover{opacity:1}body .container .footer .donate>a{float:left}body .container .footer .social{float:right}body .container .footer .social ul{overflow:hidden;float:right;padding-left:20px;padding-right:10px}body .container .footer .social ul li{float:right;margin-right:10px;padding-top:5px}body .container .footer .social ul li img{opacity:.6}body .container .footer .social ul li img:hover{opacity:1}body .container .footer .themelink{float:right;padding-right:20px}body #modal-menu{max-width:400px}body #modal-menu a{color:#65b1dd;font-size:20px;line-height:40px}.remodal{padding:30px;box-shadow:0 2px 7px rgba(0,0,0,.3);background:#fff;display:none}.remodal form .buttons{float:none}.remodal-wrapper .remodal{display:block}span.info{font-size:10px;font-weight:500;display:inline-block;background:#65b1dd;border-radius:50%;width:15px;height:15px;vertical-align:super;color:#fff;line-height:15px;margin-left:5px;text-align:center}.hidden{display:none}.clear{clear:both}.nofloat{float:none!important}div.blocker{z-index:5000}div.connection-lost,div.modal-dialog{z-index:5001}@media (max-width:1100px){body .container .header .donate{display:none}body .container .header .menubutton{display:block;font-size:18px;padding-right:50px;margin-top:5px;margin-right:15px;background:url(../img/menu.png) no-repeat right top;position:relative;height:40px;line-height:40px;color:#8f8f8f;float:right;top:10px;width:80px;text-transform:uppercase;text-align:right}body .container .header .menubutton.active{background-image:url(../img/menu_active.png);color:#65b1dd}body .container .body{position:relative;padding-top:0}body .container .body .mainmenu{display:none;position:absolute;background:none repeat scroll 0 0 #fff;box-shadow:0 4px 8px rgba(0,0,0,.3);left:10px;padding:20px;top:60px}body .container .body .mainmenu.mobile-open{display:block;left:auto;right:0;top:0;z-index:1000}body .container .body .content{float:none;padding:50px 20px;margin:0 auto}body .container .body .content .state{width:auto}body .container .footer .donate{display:block}body .container .mobileOpen{display:block!important}}@media (max-width:768px){body .container .body .content .tasks .tasklist a{font-size:20px;background-size:24px;background-position:0 4px;padding-left:35px}body .container .body .content .tasks .tasklist dl{padding-left:35px}body .container .body .content div.add .steps,body .container .body .content div.settings .steps{display:none}body .container .body .content div.add .steps-legend,body .container .body .content div.settings .steps-legend{list-style:decimal;padding-left:20px;border-bottom:1px solid #eee;margin-bottom:30px;padding-bottom:20px}body .container .body .content div.add .steps-legend li,body .container .body .content div.settings .steps-legend li{float:none;font-weight:500;width:auto!important;padding-right:0!important}body .container .body .content div.add .steps-boxes,body .container .body .content div.settings .steps-boxes{padding-left:0}body .container .body .content div.add form.styled .input input,body .container .body .content div.add form.styled .input select,body .container .body .content div.add form.styled .input textarea,body .container .body .content div.settings form.styled .input input,body .container .body .content div.settings form.styled .input select,body .container .body .content div.settings form.styled .input textarea{max-width:100%;box-sizing:border-box}body .container .body .content div.add form.styled .input.select select,body .container .body .content div.settings form.styled .input.select select{width:420px}body .container .body .content div.add form.styled .buttons,body .container .body .content div.settings form.styled .buttons{max-width:100%;width:auto}body .container .body .content div.add form.styled .tools,body .container .body .content div.settings form.styled .tools{padding-left:0!important}body .container .body .content div.add form.styled .input.checkbox.multiple,body .container .body .content div.settings form.styled .input.checkbox.multiple{padding-bottom:5px}body .container .body .content div.add form.styled .input.checkbox.multiple input,body .container .body .content div.add form.styled .input.checkbox.multiple label,body .container .body .content div.settings form.styled .input.checkbox.multiple input,body .container .body .content div.settings form.styled .input.checkbox.multiple label{display:block!important;float:left!important;line-height:normal}body .container .body .content div.add form.styled .input.checkbox.multiple input,body .container .body .content div.settings form.styled .input.checkbox.multiple input{clear:both}body .container .body .content div.add form.styled .input.text.multiple input,body .container .body .content div.settings form.styled .input.text.multiple input{max-width:48%!important}}@media (max-width:640px){body h2{font-size:20px;text-align:center}body .container .body{padding-bottom:0}body .container .body .content div.add form .input.overlayButton{padding-top:8px;padding-bottom:30px;margin-bottom:10px}body .container .body .content div.add form .input.overlayButton a.button{padding:7px 10px;right:1px;top:9px}body .container .body .content div.add form .input.checkbox.multiple div{display:block}body .container .body .content div.add form .input.select.multiple input#exclude-larger-than-number{width:75px}body .container .body .content div.add form .input.select.multiple select#exclude-larger-than-multiplier{width:140px}body .container .body .content div.add form .filters .input.textarea{padding-bottom:10px}body .container .body .content div.add form .filters h3{margin:5px 0}body .container .body .content div.add form .input.text.select.multiple.repeat label{float:none}body .container .body .content div.add form .input.text.select.multiple.repeat input#repeatRunNumber{width:70px}body .container .body .content div.add form .input.text.select.multiple.repeat select#repeatRunMultiplier{width:100px}body .container .body .content div.add form .input.multiple.text.select.maxSize input{width:70px}body .container .body .content div.add form .input.multiple.text.select.maxSize select{width:100px}body .container .body .content div.add form .input.multiple.text.select.keepBackups select{width:85px;padding:4px 6px}body .container .body .content div.add form .input.multiple.text.select.keepBackups input{width:60px}body .container .footer{position:static;padding:15px;line-height:normal;text-align:left;box-sizing:border-box}body .container .footer *{float:none!important;text-align:center;box-sizing:border-box}body .container .footer .about-footer{padding-right:0}body .container .footer .about-footer span{padding-left:0;padding-bottom:5px}body .container .footer .about-footer li{padding-left:0;float:none;display:inline-block;height:32px;width:32px;background-size:28px!important;border-bottom:none}body .container .footer .about-footer li.support{background:url(../img/support.png) no-repeat center center}body .container .footer .about-footer li.about{background:url(../img/about.png) no-repeat center center}body .container .footer .about-footer li:first-child{padding-bottom:0}body .container .footer .about-footer li:last-child{padding-bottom:20px}body .container .footer .about-footer,body .container .footer .donate,body .container .footer .social,body .container .footer li{padding:8px 0;border-bottom:1px #ddd solid}body .container .footer .donate ul li{display:inline-block;border:none;margin:0 5px}body .container .footer .donate ul li a img{margin-top:0}body .container .footer .social li{display:inline-block;border:none}body .container .footer .themelink{padding:5px 0}}@media (max-width:480px){body{font-size:15px}body .container .header .logo{padding-left:20px}body .container .header .menubutton{margin-right:5px}body .container .body .mainmenu{width:280px;box-sizing:border-box}body .container .body .mainmenu ul li a{font-size:22px}body .container .body .content{padding:50px 15px}body .container .body .content div.add form .input.password .tools ul li{font-size:14px}body .container .body .content div.add form .buttons a{float:none;text-align:center;margin-bottom:5px}body .container .body .content div.add .steps-boxes .box.browser .checklinks a{float:none;margin-bottom:8px;display:block}} \ No newline at end of file
+ */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.5.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0) format('embedded-opentype'),url(../fonts/fontawesome-webfont.woff2?v=4.5.0) format('woff2'),url(../fonts/fontawesome-webfont.woff?v=4.5.0) format('woff'),url(../fonts/fontawesome-webfont.ttf?v=4.5.0) format('truetype'),url(../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}*{font-family:'Clear Sans',sans-serif}body,html{margin:0;padding:0;height:100%}h1,h2{font-weight:300;color:#81c401}h1{margin:10px 0}h3{font-weight:400}a{text-decoration:none}ul{list-style:none;margin:0;padding:0}hr{border:none;border-bottom:1px #ddd solid}textarea{max-width:94%}.button{display:block;background:#65b1dd;color:#fff!important;padding:5px 15px;float:right;margin-left:10px;cursor:pointer;width:auto;border:none;font-family:'Clear Sans',sans-serif;font-size:16px;font-weight:300;border-radius:0}.button:hover{background:#3b9cd4}#folder_path_picker,#restore_file_picker,.step3 source-folder-picker{display:block;border:1px solid #d3d3d3;padding:2px;height:100%;overflow:auto}.not-clickable{cursor:default!important}.not-clickable div,.not-clickable span,.not-clickable>a{cursor:default!important}.ui-match{font-weight:700;color:#006400}wait-area{min-width:350px;text-align:center;display:block}.prewrapped-text{white-space:pre-wrap}.exceptiontext{background-color:#d3d3d3;color:#000}ul.tabs{margin-bottom:10px}ul.tabs>li{display:inline;margin-right:10px;border:1px solid #65b1dd;padding:5px}ul.tabs>li.active{background-color:#65b1dd;color:#fff}ul.tabs>li.active>a{background-color:#65b1dd;color:#fff}ul.tabs>li.active.disabled{border:1px solid #d3d3d3;background-color:#d3d3d3;color:grey;cursor:default}ul.tabs>li.active.disabled>a{background-color:#d3d3d3;color:grey;cursor:default}.licenses>ul{list-style:initial;margin:10px;margin-left:20px}.licenses li{margin-bottom:10px}.licenses a.itemlink{font-weight:700}.logpage ul.entries{list-style:initial;margin:10px;margin-left:20px}.logpage .entries div.entryline{cursor:pointer}.logpage .entries.livedata li{height:1.2em;overflow:hidden}.logpage .entries.livedata li.expanded{height:auto;overflow:auto}.logpage .button{text-align:center;margin-right:10px;border:1px solid #65b1dd;padding:5px;background-color:#65b1dd;color:#fff;cursor:pointer}.exportpage .checkbox input{width:auto;margin-top:10px}.exportpage .commandline div{background-color:#d3d3d3;color:#000}.themelink{margin-left:20px}ul.notification{position:fixed;bottom:0;left:0;right:0;margin:auto;width:480px}.notification .title{border:1px solid #65b1dd;background-color:#65b1dd;border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-left-radius:0;border-bottom-right-radius:0;padding:2px;padding-left:5px;padding-right:5px;font-weight:700;color:#d3d3d3;width:100%;text-align:center;clear:both}.notification .content{background-color:#fff;border:1px solid #65b1dd;border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding:2px;padding-left:5px;padding-right:5px;width:100%}.notification .message{width:100%;color:#000}.notification .button{padding:2px 10px;margin-top:6px}.notification .clear{clear:right;height:1px}.notification .error .title{border-color:red;background-color:red}.notification .error .content{border-color:red}.notification .error .button{border-color:red;background-color:red}.notification .warning .title{background-color:orange;border-color:orange}.notification .warning .button{background-color:orange;border-color:orange}.notification .warning .content{border-color:orange}.filepicker{height:200px}.resizable{margin-bottom:6px;max-width:100%}.advanced-toggle{float:right;margin-right:25px;line-height:37px}.advancedoptions li{clear:both;margin-bottom:10px;padding:10px 0;border-top:1px #d3d3d3 solid}.advancedentry .multiple{display:inline}.advancedentry .shortname{font-weight:700}.advancedentry input[type=text]{width:300px}.advancedentry select{width:300px}.advancedentry input[type=checkbox]{margin-top:13px;width:auto}.advancedentry .longdescription{margin-left:190px;clear:both;font-style:italic}.settings div.sublabel{clear:both;padding:0 31px;font-style:italic}.logo img.mainlogo{height:64px;width:64px;float:left;padding-right:8px;padding-top:2px}.logo div.logotext{float:left}.logo a{float:left;display:block;line-height:normal}.logo div.build-suffix{clear:both;display:inline;float:left;font-size:16px;line-height:16px}.logo div.powered-by{font-size:16px;margin:0;line-height:16px;float:left;padding:0;margin-left:5px}.fixed-width-font{font-family:monospace}.warning{margin:10px;font-style:italic;color:#f49b42}div.captcha .details{padding-top:10px;margin-left:auto;margin-right:auto;width:180px}.centered-text{text-align:center}body{color:#8f8f8f}body .container{min-height:100%;position:relative}body .container .header{line-height:70px;background:#ededed;overflow:hidden;height:70px;position:fixed;top:0;left:0;right:0;z-index:100}body .container .header a{color:#65b1dd}body .container .header a.active,body .container .header a:hover{color:#4f4f4f}body .container .header .logo{font-size:30px;font-weight:700;float:left;padding-left:40px}body .container .header .statepadding{padding-right:90px;margin-left:320px}body .container .header .state{float:left;color:#609101;width:580px;padding:13px 15px;margin:10px 20px;border:1px #609101 solid;font-weight:300;font-size:18px;overflow:hidden;line-height:normal;display:inline-block;background-color:#fff;text-overflow:ellipsis;position:relative;height:25px}body .container .header .state strong{display:inline;margin-right:10px}body .container .header .state span{display:inline}body .container .header .state .button{position:static;margin-top:70px}body .container .header .state .content{position:relative;z-index:10;margin-right:40px;display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}body .container .header .state .buttons{position:absolute;right:0;top:0;bottom:0;width:26px;margin:13px 15px}body .container .header .state .buttons .stop{display:block;width:26px;height:26px;background:url(../img/progress-stop.png);background-size:26px;cursor:pointer}body .container .header .state .buttons .resume{display:block;width:26px;height:26px;background:url(../img/progress-resume.png);background-size:26px;cursor:pointer}body .container .header .state .progress-bar{position:absolute;top:0;bottom:0;left:0;background:rgba(129,196,1,.25);z-index:5}body .container .header .action-icons{display:inline-block;line-height:normal;margin:10px 0;padding:13px 0;float:left}body .container .header .action-icons-small{display:none;float:right;margin-top:21px;line-height:normal}body .container .header .action-icons-small>.pause,body .container .header .action-icons>.pause{width:26px;height:26px;display:inline-block;cursor:pointer;background:url(../img/pause.png)}body .container .header .action-icons-small>.pause.active,body .container .header .action-icons>.pause.active{background:url(../img/resume.png)}body .container .header .action-icons-small>.throttle,body .container .header .action-icons>.throttle{width:26px;height:26px;display:inline-block;cursor:pointer;background:url(../img/throttle.png)}body .container .header .action-icons-small>.throttle.inactive,body .container .header .action-icons>.throttle.inactive{opacity:.5}body .container .header .about-header{float:right;padding-right:20px;overflow:hidden}body .container .header .about-header ul{overflow:hidden;list-style:none}body .container .header .about-header ul li{float:right;padding-right:20px}body .container .header .donate{float:right}body .container .header .donate ul{overflow:hidden;float:right;padding-left:20px;padding-right:10px}body .container .header .donate ul li{float:right;margin-right:10px;padding-top:5px}body .container .header .donate img{opacity:.6}body .container .header .donate img:hover{opacity:1}body .container .body{width:100%;overflow:hidden;min-height:500px;padding-top:120px;padding-bottom:70px}body .container .body a{color:#65b1dd}body .container .body .mainmenu{width:260px;padding-left:40px;float:left}body .container .body .mainmenu>ul>li{position:relative}body .container .body .mainmenu>ul>li>a{font-size:22px;font-weight:300;padding:5px 10px 5px 55px;display:block}body .container .body .mainmenu>ul>li>a:hover{color:#fff}body .container .body .mainmenu>ul>li>a.active{color:#fff}body .container .body .mainmenu>ul>li>a.add{background:url(../img/mainmenu/add.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.restore{background:url(../img/mainmenu/restore.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.pause{background:url(../img/mainmenu/pause.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.resume{background:url(../img/mainmenu/resume.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.settings{background:url(../img/mainmenu/settings.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.log{background:url(../img/mainmenu/log.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.logout{background:url(../img/mainmenu/logout.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.home{background:url(../img/mainmenu/home.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.about{background:url(../img/mainmenu/about.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.pause>span{padding-right:25px;background:url(../img/mainmenu/arrow_right.png) right center no-repeat}body .container .body .mainmenu>ul>li>a.home.active{background:#a4d1eb url(../img/mainmenu/over/home.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.add.active{background:#a4d1eb url(../img/mainmenu/over/add.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.restore.active{background:#a4d1eb url(../img/mainmenu/over/restore.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.pause.active{background:#a4d1eb url(../img/mainmenu/over/pause.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.resume.active{background:#a4d1eb url(../img/mainmenu/over/resume.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.settings.active{background:#a4d1eb url(../img/mainmenu/over/settings.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.log.active{background:#a4d1eb url(../img/mainmenu/over/log.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.about.active{background:#a4d1eb url(../img/mainmenu/over/about.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.pause.open.active>span{background:url(../img/mainmenu/over/arrow_down.png) right center no-repeat}body .container .body .mainmenu>ul>li>a.add:hover{background:#65b1dd url(../img/mainmenu/over/add.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.restore:hover{background:#65b1dd url(../img/mainmenu/over/restore.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.pause:hover{background:#65b1dd url(../img/mainmenu/over/pause.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.pause:hover>span{background:url(../img/mainmenu/over/arrow_right.png) right center no-repeat}body .container .body .mainmenu>ul>li>a.pause.open:hover>span{background:url(../img/mainmenu/over/arrow_down.png) right center no-repeat}body .container .body .mainmenu>ul>li>a.pause.open>span{background:url(../img/mainmenu/arrow_down.png) right center no-repeat}body .container .body .mainmenu>ul>li>a.resume:hover{background:#65b1dd url(../img/mainmenu/over/resume.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.settings:hover{background:#65b1dd url(../img/mainmenu/over/settings.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.log:hover{background:#65b1dd url(../img/mainmenu/over/log.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.logout:hover{background:#65b1dd url(../img/mainmenu/over/logout.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.home:hover{background:#65b1dd url(../img/mainmenu/over/home.png) no-repeat 8px 7px}body .container .body .mainmenu>ul>li>a.about:hover{background:#65b1dd url(../img/mainmenu/over/about.png) no-repeat 8px 7px}body .container .body .mainmenu>ul li.hr-top{padding-top:25px;margin-top:25px;border-top:1px #ededed solid}body .container .body div.contextmenu_container{position:relative}body .container .body .contextmenu{display:none;position:absolute;background:#fff;border:1px #ededed solid;box-shadow:0 4px 8px rgba(0,0,0,.3);z-index:200;padding:5px}body .container .body .contextmenu li a{color:#65b1dd;font-size:15px;font-weight:400;padding:0;display:block;min-width:200px;padding:4px 10px;white-space:nowrap;padding-left:45px;overflow:hidden;text-overflow:ellipsis}body .container .body .contextmenu li a:hover{background:#65b1dd;color:#fff}body .container .body .contextmenu.open{display:block}body .container .body .content{float:left;padding-left:50px;padding-bottom:50px;max-width:700px}body .container .body .content ul.tabs>li{display:inline-block}body .container .body .content .tasks .tasklist .task{border-top:1px solid #eee;padding-top:20px;margin-bottom:25px}body .container .body .content .tasks .tasklist .task:last-child{border-bottom:1px solid #eee;padding-bottom:20px}body .container .body .content .tasks .tasklist .task:first-child{padding-top:0;border-top:0 none}body .container .body .content .tasks .tasklist a{font-size:30px;padding-left:55px;background:url(../img/backup.png) no-repeat 5px 6px;font-weight:300;display:inline-block}body .container .body .content .tasks .tasklist a.action-link{font-size:14px;background:0 0;padding-left:0}body .container .body .content .tasks .tasklist dl{padding-left:55px;overflow:hidden;font-size:14px}body .container .body .content .tasks .tasklist dl dd,body .container .body .content .tasks .tasklist dl dt{display:block;float:left}body .container .body .content .tasks .tasklist dl dt{clear:both;font-weight:500;margin-bottom:5px}body .container .body .content .tasks .tasklist dl dd{margin-left:10px}body .container .body .content .tasks .tasklist dl.taskmenu p{display:inline;margin-right:10px;color:#65b1dd;cursor:pointer}body .container .body .content .tasks .tasklist dl.taskmenu dt{float:left;margin-right:10px;margin-bottom:0;padding:5px 8px;color:#8f8f8f;cursor:pointer;clear:none}body .container .body .content .tasks .tasklist dl.taskmenu dd{clear:both;float:none;padding-bottom:8px;border-bottom:1px #ddd solid;margin-bottom:5px}body .container .body .content div.add .steps,body .container .body .content div.restore .steps{width:100%;overflow:hidden}body .container .body .content div.add .steps .step,body .container .body .content div.restore .steps .step{float:left;background:url(../img/steps/line-out.png) no-repeat top left;color:#c7e5f6}body .container .body .content div.add .steps .step span,body .container .body .content div.restore .steps .step span{display:block;border:4px #c7e5f6 solid;background:#fff;border-radius:50%;width:35px;height:35px;text-align:center;font-size:22px;line-height:35px;cursor:pointer}body .container .body .content div.add .steps .step.active,body .container .body .content div.restore .steps .step.active{color:#65b1dd}body .container .body .content div.add .steps .step.active span,body .container .body .content div.restore .steps .step.active span{border:4px #65b1dd solid;background:#65b1dd;color:#fff}body .container .body .content div.add .steps .step.active h2,body .container .body .content div.restore .steps .step.active h2{color:#65b1dd}body .container .body .content div.add .steps .step:first-child,body .container .body .content div.restore .steps .step:first-child{padding-left:0;background:0 0}body .container .body .content div.add .steps-legend,body .container .body .content div.restore .steps-legend{overflow:hidden;padding-bottom:50px;list-style:none;margin:0}body .container .body .content div.add .steps-legend li,body .container .body .content div.restore .steps-legend li{color:#c7e5f6;font-size:18px;text-align:center;float:left;padding-top:10px;cursor:pointer}body .container .body .content div.add .steps-legend li.active,body .container .body .content div.restore .steps-legend li.active{color:#65b1dd}body .container .body .content div.add .steps-boxes,body .container .body .content div.restore .steps-boxes{padding-left:40px}body .container .body .content div.add .steps-boxes .step,body .container .body .content div.restore .steps-boxes .step{display:none}body .container .body .content div.add .steps-boxes .step.active,body .container .body .content div.restore .steps-boxes .step.active{display:block}body .container .body .content div.add .steps-boxes .box.browser .checklinks a,body .container .body .content div.restore .steps-boxes .box.browser .checklinks a{float:left;margin-left:20px;color:#8f8f8f}body .container .body .content div.add .steps-boxes .box.browser .checklinks a i,body .container .body .content div.restore .steps-boxes .box.browser .checklinks a i{border:2px solid;border-color:#8f8f8f;border-radius:2px;font-size:18px;height:18px;vertical-align:top;width:18px}body .container .body .content div.add .steps-boxes .box.browser .checklinks a.inactive,body .container .body .content div.restore .steps-boxes .box.browser .checklinks a.inactive{color:#c2c2c2;cursor:default}body .container .body .content div.add .steps-boxes .box.browser .checklinks a.inactive i,body .container .body .content div.restore .steps-boxes .box.browser .checklinks a.inactive i{border-color:#c2c2c2}body .container .body .content div.add .steps-boxes .box.browser .checklinks a:first-child,body .container .body .content div.restore .steps-boxes .box.browser .checklinks a:first-child{margin-left:0}body .container .body .content div.add .steps-boxes .box.browser .input.overlayButton,body .container .body .content div.restore .steps-boxes .box.browser .input.overlayButton{padding-top:10px;max-width:100%}body .container .body .content div.add .steps-boxes .box.browser .input.overlayButton input#sourcePath,body .container .body .content div.restore .steps-boxes .box.browser .input.overlayButton input#sourcePath{width:100%;box-sizing:border-box;height:37px}body .container .body .content div.add .steps-boxes .box.browser .input.overlayButton a.button,body .container .body .content div.restore .steps-boxes .box.browser .input.overlayButton a.button{top:10px}body .container .body .content div.add .steps-boxes .box.filters .input.link a,body .container .body .content div.restore .steps-boxes .box.filters .input.link a{color:#8f8f8f}body .container .body .content div.add .steps-boxes .box.filters .input.link a i,body .container .body .content div.restore .steps-boxes .box.filters .input.link a i{border:2px solid;border-color:#8f8f8f;border-radius:2px;font-size:18px;height:18px;vertical-align:top;width:18px}body .container .body .content div.add .steps-boxes .box.filters ul#simplefilterlist,body .container .body .content div.restore .steps-boxes .box.filters ul#simplefilterlist{overflow:hidden;padding-bottom:15px}body .container .body .content div.add .steps-boxes .box.filters ul#simplefilterlist li,body .container .body .content div.restore .steps-boxes .box.filters ul#simplefilterlist li{overflow:hidden;clear:both;padding-bottom:5px}body .container .body .content div.add .steps-boxes .box.filters ul#simplefilterlist li select,body .container .body .content div.restore .steps-boxes .box.filters ul#simplefilterlist li select{width:200px;margin-right:5px;height:36px;line-height:36px}body .container .body .content div.add .steps-boxes .box.filters ul#simplefilterlist li input,body .container .body .content div.restore .steps-boxes .box.filters ul#simplefilterlist li input{width:280px;padding:5px}body .container .body .content div.add .steps-boxes .step1 li.strength.score-0,body .container .body .content div.restore .steps-boxes .step1 li.strength.score-0{color:red}body .container .body .content div.add .steps-boxes .step1 li.strength.score-1,body .container .body .content div.restore .steps-boxes .step1 li.strength.score-1{color:#f70}body .container .body .content div.add .steps-boxes .step1 li.strength.score-2,body .container .body .content div.restore .steps-boxes .step1 li.strength.score-2{color:#aa0}body .container .body .content div.add .steps-boxes .step1 li.strength.score-3,body .container .body .content div.restore .steps-boxes .step1 li.strength.score-3{color:#070}body .container .body .content div.add .steps-boxes .step1 li.strength.score-4,body .container .body .content div.restore .steps-boxes .step1 li.strength.score-4{color:#427e27}body .container .body .content div.add .steps-boxes .step1 li.strength.score-x,body .container .body .content div.restore .steps-boxes .step1 li.strength.score-x{color:red}body .container .body .content div.add .steps-boxes .step5 div.input.keepBackups input.number,body .container .body .content div.add .steps-boxes .step5 div.input.maxSize input.number,body .container .body .content div.restore .steps-boxes .step5 div.input.keepBackups input.number,body .container .body .content div.restore .steps-boxes .step5 div.input.maxSize input.number{width:60px}body .container .body .content div.add .steps-boxes .step5 .advancedoptions,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions{padding-top:15px;clear:both}body .container .body .content div.add .steps-boxes .step5 .advancedoptions li,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions li{border-top:none}body .container .body .content div.add .steps-boxes .step5 .advancedoptions li>a,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions li>a{display:block;background:#65b1dd;color:#fff!important;padding:5px 15px;float:right;margin-left:10px;cursor:pointer;width:auto;border:none;font-family:'Clear Sans',sans-serif;font-size:16px;font-weight:300;border-radius:0}body .container .body .content div.add .steps-boxes .step5 .advancedoptions li.advancedentry,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions li.advancedentry{border-bottom:1px solid #d3d3d3}body .container .body .content div.add .steps-boxes .step5 .advancedoptions li:last-child,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions li:last-child{padding-top:0}body .container .body .content div.add .steps-boxes .step5 .advancedoptions li:last-child select,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions li:last-child select{max-width:400px}body .container .body .content div.add .steps-boxes .step5 .advancedoptions label,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions label{line-height:normal}body .container .body .content div.add .steps-boxes .step5 .advancedoptions input,body .container .body .content div.add .steps-boxes .step5 .advancedoptions select,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions input,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions select{width:auto;max-width:100%;box-sizing:border-box}body .container .body .content div.add .steps-boxes .step5 .advancedoptions .longdescription,body .container .body .content div.restore .steps-boxes .step5 .advancedoptions .longdescription{margin-top:10px}body .container .body .content div.add .steps-boxes .step5 .advanced-toggle,body .container .body .content div.restore .steps-boxes .step5 .advanced-toggle{color:#8f8f8f;line-height:normal;margin-top:16px;clear:both;float:left}body .container .body .content div.add .steps-boxes .step5 .advanced-toggle i.fa,body .container .body .content div.restore .steps-boxes .step5 .advanced-toggle i.fa{border:2px solid;border-color:#8f8f8f;border-radius:2px;font-size:18px;height:18px;vertical-align:top;width:18px}body .container .body .content div.add .steps-boxes .step5 textarea,body .container .body .content div.restore .steps-boxes .step5 textarea{box-sizing:border-box;clear:both;margin-top:15px;width:100%}body .container .body .content div.add form,body .container .body .content div.restore form{padding-bottom:50px;overflow:hidden}body .container .body .content div.add form .input.password .tools,body .container .body .content div.restore form .input.password .tools{clear:both;padding-left:190px;padding-top:10px}body .container .body .content div.add form .input.password .tools ul,body .container .body .content div.restore form .input.password .tools ul{overflow:hidden}body .container .body .content div.add form .input.password .tools ul li,body .container .body .content div.restore form .input.password .tools ul li{float:left;padding-right:7px}body .container .body .content div.add form .input.password .tools ul li.strength.useless,body .container .body .content div.restore form .input.password .tools ul li.strength.useless{color:red}body .container .body .content div.add form .input.password .tools ul li.strength.average,body .container .body .content div.restore form .input.password .tools ul li.strength.average{color:#ff0}body .container .body .content div.add form .input.password .tools ul li.strength.good,body .container .body .content div.restore form .input.password .tools ul li.strength.good{color:#65b1dd}body .container .body .content div.add form .input.multiple input,body .container .body .content div.add form .input.multiple select,body .container .body .content div.restore form .input.multiple input,body .container .body .content div.restore form .input.multiple select{width:auto;margin-right:5px}body .container .body .content div.add form .input.multiple select,body .container .body .content div.restore form .input.multiple select{padding:5px 12px}body .container .body .content div.add form .input.overlayButton,body .container .body .content div.restore form .input.overlayButton{overflow:hidden;position:relative;max-width:446px}body .container .body .content div.add form .input.overlayButton input,body .container .body .content div.restore form .input.overlayButton input{width:347px}body .container .body .content div.add form .input.overlayButton a.button,body .container .body .content div.restore form .input.overlayButton a.button{position:absolute;top:0;right:0;padding:7px 12px 8px}body .container .body .content div.add form .input.checkbox.multiple strong,body .container .body .content div.restore form .input.checkbox.multiple strong{display:block;padding-bottom:5px}body .container .body .content div.add form .input.checkbox.multiple label,body .container .body .content div.restore form .input.checkbox.multiple label{display:inline-block;float:none;width:auto;padding-right:10px}body .container .body .content div.add form .input.checkbox.multiple input,body .container .body .content div.restore form .input.checkbox.multiple input{width:auto;display:inline-block;float:none}body .container .body .content div.add form .buttons,body .container .body .content div.restore form .buttons{float:none;width:635px;padding-top:30px}body .container .body .content div.add .steps{margin-left:48.5px}body .container .body .content div.add .steps .step{padding-left:97px}body .container .body .content div.add .steps-legend{padding-left:0}body .container .body .content div.add .steps-legend li{width:140px}body .container .body .content div.restore .steps{margin-left:153.5px}body .container .body .content div.restore .steps .step{padding-left:307px}body .container .body .content div.restore .steps-legend{padding-left:0}body .container .body .content div.restore .steps-legend li{width:350px}body .container .body .content div.restore.restore-direct .steps{margin-left:66px}body .container .body .content div.restore.restore-direct .steps .step{padding-left:132px}body .container .body .content div.restore.restore-direct .steps-legend{padding-left:0}body .container .body .content div.restore.restore-direct .steps-legend li{width:175px}body .container .body .content div.restore.restore-direct .step:first-child{padding-left:0;background:0 0}body .container .body .content div.restore.restore-direct .steps-legend{padding-left:20px}body .container .body .content div.headerthreedotmenu{margin:20px 0 20px 0}body .container .body .content div.headerthreedotmenu h2{display:inline}body .container .body .content div.headerthreedotmenu .contextmenu_container{float:right}body .container .body .content div.headerthreedotmenu .contextmenu{left:auto;right:0;top:auto}body .container .body .content div.headerthreedotmenu .threedotmenubutton{padding:5px}body .container .body .content .expandable{margin:20px 0 20px 0}body .container .body .content .expandable h2{display:inline}body .container .body .content .expandable img{padding:0 6px}body .container .body .content div.settings .input.checkbox input.checkbox,body .container .body .content div.settings .input.mixed.multiple input.checkbox{width:auto}body .container .body .content div.settings .input.checkbox select,body .container .body .content div.settings .input.mixed.multiple select{width:auto;margin-right:5px}body .container .body .content div.settings .input.checkbox label,body .container .body .content div.settings .input.mixed.multiple label{line-height:normal;padding:0 15px;width:auto}body .container .body .content .logpage ul.tabs{padding:15px 0}body .container .body .content .logpage ul.entries li{padding-top:15px}body .container .body .content .prewrapped-text{white-space:pre-wrap;overflow-x:auto}body .container .footer{background:#ededed;min-height:70px;line-height:70px;overflow:hidden;position:absolute;bottom:0;width:100%}body .container .footer a{color:#65b1dd}body .container .footer .about-footer{float:left;overflow:hidden;padding-right:20px}body .container .footer .about-footer span{display:block;float:left;padding-left:20px}body .container .footer .about-footer ul{float:left}body .container .footer .about-footer li{float:left;padding-left:20px}body .container .footer .donate{float:right;padding-right:40px;overflow:hidden}body .container .footer .donate ul{overflow:hidden;float:right}body .container .footer .donate ul li{float:left;margin-left:20px}body .container .footer .donate ul li a img{margin-top:24px;display:inline-block;opacity:.6}body .container .footer .donate ul li a img:hover{opacity:1}body .container .footer .donate>a{float:left}body .container .footer .social{float:right}body .container .footer .social ul{overflow:hidden;float:right;padding-left:20px;padding-right:10px}body .container .footer .social ul li{float:right;margin-right:10px;padding-top:5px}body .container .footer .social ul li img{opacity:.6}body .container .footer .social ul li img:hover{opacity:1}body .container .footer .themelink{float:right;padding-right:20px}body #modal-menu{max-width:400px}body #modal-menu a{color:#65b1dd;font-size:20px;line-height:40px}.remodal{padding:30px;box-shadow:0 2px 7px rgba(0,0,0,.3);background:#fff;display:none}.remodal form .buttons{float:none}.remodal-wrapper .remodal{display:block}span.info{font-size:10px;font-weight:500;display:inline-block;background:#65b1dd;border-radius:50%;width:15px;height:15px;vertical-align:super;color:#fff;line-height:15px;margin-left:5px;text-align:center}.hidden{display:none}.clear{clear:both}.nofloat{float:none!important}div.blocker,div.connection-lost,div.modal-dialog{position:fixed;top:0;left:0;right:0;bottom:0;margin:auto}div.blocker{z-index:5000;background-color:#000;opacity:.65}#connection-lost-blocker{z-index:5100}#connection-lost-dialog{z-index:5200}div.connection-lost,div.modal-dialog{z-index:5001;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-box-pack:center;-moz-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-moz-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center}div.connection-lost div.info,div.modal-dialog div.info{min-width:310px;max-width:650px;margin:5px}div.connection-lost div.title,div.modal-dialog div.title{border:1px solid #65b1dd;background-color:#65b1dd;border-radius:5px 5px 0 0;padding:10px 20px;font-weight:700;color:#d3d3d3;text-align:center}div.connection-lost div.content,div.modal-dialog div.content{background-color:#fff;border:1px solid #fff;padding:20px}div.connection-lost .buttons,div.modal-dialog .buttons{border-radius:0 0 5px 5px;padding-top:10px;overflow:auto}div.connection-lost form,div.modal-dialog form{margin-top:15px}div.connection-lost form textarea,div.modal-dialog form textarea{height:130px;width:420px;padding:10px 12px;border:1px #d8d8d8 solid;border-radius:2px;color:#8f8f8f;font-size:16px;font-weight:300}div.connection-lost form input,div.modal-dialog form input{height:35px;line-height:35px;padding:0 12px}div.modal-dialog .content.buttons ul{float:right}div.modal-dialog .content.buttons .tooltipped{position:relative}div.modal-dialog .content.buttons .tooltipped:after{position:absolute;z-index:1000000;display:none;padding:5px 8px;font:normal normal 11px/1.5 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol";color:#fff;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:rgba(0,0,0,.8);border-radius:3px;-webkit-font-smoothing:subpixel-antialiased}div.modal-dialog .content.buttons .tooltipped:before{position:absolute;z-index:1000001;display:none;width:0;height:0;color:rgba(0,0,0,.8);pointer-events:none;content:"";border:5px solid transparent}div.modal-dialog .content.buttons .tooltipped:active:after,div.modal-dialog .content.buttons .tooltipped:active:before,div.modal-dialog .content.buttons .tooltipped:focus:after,div.modal-dialog .content.buttons .tooltipped:focus:before,div.modal-dialog .content.buttons .tooltipped:hover:after,div.modal-dialog .content.buttons .tooltipped:hover:before{display:inline-block;text-decoration:none}div.modal-dialog .content.buttons .tooltipped-w:after{right:100%;bottom:50%;margin-right:5px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%)}div.modal-dialog .content.buttons .tooltipped-w:before{top:50%;bottom:50%;left:-5px;margin-top:-5px;border-left-color:rgba(0,0,0,.8)}.addwizard form.styled ul,.restorewizard form.styled ul{margin:20px;margin-left:0}.addwizard form.styled input[type=radio],.restorewizard form.styled input[type=radio]{width:20px;margin-left:5px;margin-right:5px}.addwizard form.styled label,.restorewizard form.styled label{width:auto;line-height:normal}.addwizard form.styled div.subtext,.restorewizard form.styled div.subtext{clear:both;margin-left:30px;padding-top:5px;color:#d3d3d3}.pauseoptions form.styled li{line-height:normal;padding:0}.pauseoptions form.styled li input{height:auto;margin-top:8px;margin-right:8px;width:auto}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress{position:relative;min-height:25px}.progress>span{position:absolute;vertical-align:middle;display:block;width:100%;height:100%;text-align:center;z-index:100;padding-top:2px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress .progress-bar{float:left;width:0;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease;height:100%;position:absolute}.progress .progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.tree-view{list-style-type:none;margin-left:10px;padding-bottom:5px}.tree-view ul{margin-left:16px}.tree-view span.nodeLabel{cursor:pointer}.tree-view span.nodeLabel.selected{border:1px solid #aaa;background-color:#ddd;padding:1px 3px}.tree-view li .node{padding-bottom:5px}.tree-view li div.selected{border-color:#add8e6;background-color:#add8e6}.tree-view li>ul{display:none}.tree-view li>ul.expanded{display:block}.tree-view li a.nav{cursor:pointer;display:inline-block;width:16px;height:16px;vertical-align:middle;background-image:url(../img/treeicons.png);background-repeat:no-repeat;background-position:-80px 0}.tree-view li a.nav.leaf{background:0 0}.tree-view li a.nav.expanded{background-position:-80px -16px}.tree-view li a.type{cursor:auto;display:inline-block;width:16px;height:16px;vertical-align:middle;background-image:url(../img/treeicons.png);background-repeat:no-repeat;background-position:0 -16px}.tree-view li a.type.invisible{background-position:0 -32px}.tree-view li a.type.loading{cursor:progress;background-image:url(../img/loader-16.gif);background-repeat:no-repeat;background-position:0 0}.tree-view li a.type.x-tree-icon-drive{background-position:-16px -16px}.tree-view li a.type.x-tree-icon-leaf{background-position:-32px -16px}.tree-view li a.type.x-tree-icon-symlink{background-position:-48px -16px}.tree-view li a.type.x-tree-icon-userdata{background-position:-16px -48px}.tree-view li a.type.x-tree-icon-locked{background-position:-64px -16px}.tree-view li a.type.x-tree-icon-broken{background-position:-64px -16px}.tree-view li a.type.x-tree-icon-computer{background-position:0 -48px}.tree-view li a.type.x-tree-icon-hyperv{background-position:-96px -16px}.tree-view li a.type.x-tree-icon-hypervmachine{background-position:-96px 0}.tree-view li a.type.x-tree-icon-mssql{background-position:-96px -32px}.tree-view li a.type.x-tree-icon-mssqldb{background-position:-80px -32px}.tree-view li a.type.x-tree-icon-mydocuments{background-position:-32px -48px}.tree-view li a.type.x-tree-icon-mymusic{background-position:-48px -48px}.tree-view li a.type.x-tree-icon-mypictures{background-position:-64px -48px}.tree-view li a.type.x-tree-icon-desktop{background-position:-80px -48px}.tree-view li a.type.x-tree-icon-home{background-position:-96px -48px}.tree-view li a.type.x-tree-icon-drive.invisible{background-position:-16px -32px}.tree-view li a.type.x-tree-icon-leaf.invisible{background-position:-32px -32px}.tree-view li a.type.x-tree-icon-symlink.invisible{cursor:auto;background-position:-48px -32px}.tree-view li a.type.x-tree-icon-locked.invisible{background-position:-64px -32px}.tree-view li a.check{height:16px;width:16px;display:inline-block;cursor:pointer;background-image:url(../img/treeicons.png);background-repeat:no-repeat;background-position:0 0;vertical-align:middle}.tree-view li a.partial{background-position:-32px 0}.tree-view li a.include{background-position:-16px 0}.tree-view li a.exclude{background-position:-48px 0}.tree-view li a.root{background:0 0;display:none}.throttlesettings div.multiple select{width:auto;margin-right:5px}.throttlesettings div.multiple input{width:100px}.throttlesettings div.multiple input.checkbox{width:auto}.throttlesettings div.multiple label{line-height:35px;padding:0 15px;width:auto;min-width:150px}.throttlesettings .disabled{color:#cfcfcf}.throttlesettings .disabled input,.throttlesettings .disabled select{color:#cfcfcf}@media (max-width:1200px){body .container .header .donate{display:none}}@media (max-width:1100px){body .container .header{height:140px}body .container .header .statepadding{padding-right:90px;margin-left:0}body .container .header .state{width:100%;margin:10px 40px;clear:left;float:left}body .container .header .action-icons{display:none}body .container .header .action-icons-small{display:inline-block}body .container .header .menubutton{display:block;font-size:18px;padding-right:50px;margin-top:5px;margin-right:15px;background:url(../img/menu.png) no-repeat right top;position:relative;height:40px;line-height:40px;color:#8f8f8f;float:right;top:10px;padding-left:20px;text-transform:uppercase;text-align:right}body .container .header .menubutton.active{background-image:url(../img/menu_active.png);color:#65b1dd}body .container .body{position:relative;padding-top:140px}body .container .body .mainmenu{display:none;position:fixed;background:none repeat scroll 0 0 #fff;box-shadow:0 4px 8px rgba(0,0,0,.3);left:10px;padding:20px;top:60px}body .container .body .mainmenu.mobile-open{display:block;left:auto;right:0;top:0;z-index:1000}body .container .body .contextmenu{left:0;top:auto}body .container .body .content{float:none;padding:20px 20px;margin:0 auto 30px auto}body .container .body .content .state{width:auto}body .container .footer .donate{display:block}body .container .mobileOpen{display:block!important}}@media (max-width:768px){body .container .body .content .tasks .tasklist a{font-size:20px;background-size:24px;background-position:0 4px;padding-left:35px}body .container .body .content .tasks .tasklist dl{padding-left:35px}body .container .header .logo{padding-left:10px}body .container .header .statepadding{padding-right:50px}body .container .header .state{margin-left:10px}body .container .header .menubutton{margin-right:5px}body .container .body .content div.add .steps,body .container .body .content div.restore .steps,body .container .body .content div.settings .steps{display:none}body .container .body .content div.add .steps-legend,body .container .body .content div.restore .steps-legend,body .container .body .content div.settings .steps-legend{list-style:decimal;padding-left:20px;border-bottom:1px solid #eee;margin-bottom:30px;padding-bottom:20px}body .container .body .content div.add .steps-legend li,body .container .body .content div.restore .steps-legend li,body .container .body .content div.settings .steps-legend li{float:none;font-weight:500;width:auto!important;padding-right:0!important}body .container .body .content div.add .steps-boxes,body .container .body .content div.restore .steps-boxes,body .container .body .content div.settings .steps-boxes{padding-left:0}body .container .body .content div.add form.styled .input input,body .container .body .content div.add form.styled .input select,body .container .body .content div.add form.styled .input textarea,body .container .body .content div.restore form.styled .input input,body .container .body .content div.restore form.styled .input select,body .container .body .content div.restore form.styled .input textarea,body .container .body .content div.settings form.styled .input input,body .container .body .content div.settings form.styled .input select,body .container .body .content div.settings form.styled .input textarea{max-width:100%;box-sizing:border-box}body .container .body .content div.add form.styled .input.select select,body .container .body .content div.restore form.styled .input.select select,body .container .body .content div.settings form.styled .input.select select{width:420px}body .container .body .content div.add form.styled .buttons,body .container .body .content div.restore form.styled .buttons,body .container .body .content div.settings form.styled .buttons{max-width:100%;width:auto}body .container .body .content div.add form.styled .tools,body .container .body .content div.restore form.styled .tools,body .container .body .content div.settings form.styled .tools{padding-left:0!important}body .container .body .content div.add form.styled .input.checkbox.multiple,body .container .body .content div.restore form.styled .input.checkbox.multiple,body .container .body .content div.settings form.styled .input.checkbox.multiple{padding-bottom:5px}body .container .body .content div.add form.styled .input.checkbox.multiple input,body .container .body .content div.add form.styled .input.checkbox.multiple label,body .container .body .content div.restore form.styled .input.checkbox.multiple input,body .container .body .content div.restore form.styled .input.checkbox.multiple label,body .container .body .content div.settings form.styled .input.checkbox.multiple input,body .container .body .content div.settings form.styled .input.checkbox.multiple label{display:block!important;float:left!important;line-height:normal}body .container .body .content div.add form.styled .input.checkbox.multiple input,body .container .body .content div.restore form.styled .input.checkbox.multiple input,body .container .body .content div.settings form.styled .input.checkbox.multiple input{clear:both}body .container .body .content div.add form.styled .input.text.multiple input,body .container .body .content div.restore form.styled .input.text.multiple input,body .container .body .content div.settings form.styled .input.text.multiple input{max-width:48%!important}}@media (max-width:640px){body h2{font-size:20px;text-align:center}body .container .body{padding-bottom:10px}body .container .body .content{margin:0 auto}body .container .body .content div.add form .input.overlayButton,body .container .body .content div.restore form .input.overlayButton{padding-top:8px;padding-bottom:30px;margin-bottom:10px}body .container .body .content div.add form .input.overlayButton a.button,body .container .body .content div.restore form .input.overlayButton a.button{padding:7px 10px;right:1px;top:9px}body .container .body .content div.add form .input.checkbox.multiple div,body .container .body .content div.restore form .input.checkbox.multiple div{display:block}body .container .body .content div.add form .input.select.multiple input#exclude-larger-than-number,body .container .body .content div.restore form .input.select.multiple input#exclude-larger-than-number{width:75px}body .container .body .content div.add form .input.select.multiple select#exclude-larger-than-multiplier,body .container .body .content div.restore form .input.select.multiple select#exclude-larger-than-multiplier{width:140px}body .container .body .content div.add form .filters .input.textarea,body .container .body .content div.restore form .filters .input.textarea{padding-bottom:10px}body .container .body .content div.add form .filters h3,body .container .body .content div.restore form .filters h3{margin:5px 0}body .container .body .content div.add form .input.text.select.multiple.repeat label,body .container .body .content div.restore form .input.text.select.multiple.repeat label{float:none}body .container .body .content div.add form .input.text.select.multiple.repeat input#repeatRunNumber,body .container .body .content div.restore form .input.text.select.multiple.repeat input#repeatRunNumber{width:70px}body .container .body .content div.add form .input.text.select.multiple.repeat select#repeatRunMultiplier,body .container .body .content div.restore form .input.text.select.multiple.repeat select#repeatRunMultiplier{width:100px}body .container .body .content div.add form .input.multiple.text.select.maxSize input,body .container .body .content div.restore form .input.multiple.text.select.maxSize input{width:70px}body .container .body .content div.add form .input.multiple.text.select.maxSize select,body .container .body .content div.restore form .input.multiple.text.select.maxSize select{width:100px}body .container .body .content div.add form .input.multiple.text.select.keepBackups select,body .container .body .content div.restore form .input.multiple.text.select.keepBackups select{width:85px;padding:4px 6px}body .container .body .content div.add form .input.multiple.text.select.keepBackups input,body .container .body .content div.restore form .input.multiple.text.select.keepBackups input{width:60px}body .container .footer{position:static;padding:15px;line-height:normal;text-align:left;box-sizing:border-box}body .container .footer *{float:none!important;text-align:center;box-sizing:border-box}body .container .footer .about-footer{padding-right:0}body .container .footer .about-footer span{padding-left:0;padding-bottom:5px}body .container .footer .about-footer li{padding-left:0;float:none;display:inline-block;height:32px;width:32px;background-size:28px!important;border-bottom:none}body .container .footer .about-footer li.support{background:url(../img/support.png) no-repeat center center}body .container .footer .about-footer li.about{background:url(../img/about.png) no-repeat center center}body .container .footer .about-footer li:first-child{padding-bottom:0}body .container .footer .about-footer li:last-child{padding-bottom:20px}body .container .footer .about-footer,body .container .footer .donate,body .container .footer .social,body .container .footer li{padding:8px 0;border-bottom:1px #ddd solid}body .container .footer .donate ul li{display:inline-block;border:none;margin:0 5px}body .container .footer .donate ul li a img{margin-top:0}body .container .footer .social li{display:inline-block;border:none}body .container .footer .themelink{padding:5px 0}}@media (max-width:580px){.advancedentry .longdescription{margin-left:0}}@media (max-width:492px){ul.notification{width:auto}}@media (max-width:480px){body{font-size:15px}body .container .header .logo{padding-left:5px}body .container .header .menubutton{margin-right:5px}body .container .header .state{margin-left:5px}body .container .header .statepadding{padding-right:40px}body .container .header .menubutton{padding-left:10px}body .container .body .mainmenu{width:280px;box-sizing:border-box}body .container .body .mainmenu ul li a{font-size:22px}body .container .body .content{padding:15px}body .container .body .content div.add form .input.password .tools ul li,body .container .body .content div.restore form .input.password .tools ul li{font-size:14px}body .container .body .content div.add form .buttons a,body .container .body .content div.restore form .buttons a{float:none;text-align:center;margin-bottom:5px}body .container .body .content div.add .steps-boxes .box.browser .checklinks a,body .container .body .content div.restore .steps-boxes .box.browser .checklinks a{float:none;margin-bottom:8px;display:block}}@media (max-width:400px){body{font-size:15px}body .container .header .menubutton{margin-right:0;padding-left:0;padding-right:40px}body .container .header .menubutton span{display:none}}@media (max-width:325px){body{font-size:15px}body .container .header .logo div{display:none}}@media (max-width:200px){body{font-size:15px}body .container .header .menubutton{position:static;margin-top:0}body .container .header .action-icons-small{clear:right;margin-top:0}} \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/styles/styles2.css b/Duplicati/Server/webroot/ngax/styles/styles2.css
deleted file mode 100644
index d9d480a79..000000000
--- a/Duplicati/Server/webroot/ngax/styles/styles2.css
+++ /dev/null
@@ -1,625 +0,0 @@
-/* tree */
-.tree-view {
- list-style-type: none;
- margin-left: 10px;
- padding-bottom: 5px;
-}
-
-.tree-view ul {
- margin-left: 16px;
-}
-
-.tree-view li .node {
- padding-bottom: 5px;
-}
-.tree-view span.nodeLabel {
- cursor: pointer;
-}
-.tree-view span.nodeLabel.selected {
- border: 1px solid #aaa;
- background-color: #ddd;
- padding: 1px 3px;
-}
-
-.tree-view li div.selected {
- border-color: lightblue;
- background-color: lightblue;
-}
-
-
-.tree-view li a.nav {
- cursor: pointer;
- display: inline-block;
- width: 16px;
- height: 16px;
- vertical-align: middle;
- background-image: url(../img/treeicons.png);
- background-repeat: no-repeat;
- background-position: -80px 0px;
-}
-
-.tree-view a.nav.expanded {
- background-position: -80px -16px;
-}
-
-.tree-view a.nav.leaf {
- background: none;
-}
-
-.tree-view li a.type {
- cursor: auto;
- display: inline-block;
- width: 16px;
- height: 16px;
- vertical-align: middle;
- background-image: url(../img/treeicons.png);
- background-repeat: no-repeat;
- background-position: 0px -16px;
-}
-
-.tree-view a.type.x-tree-icon-drive {
- background-position: -16px -16px;
-}
-
-.tree-view a.type.x-tree-icon-leaf {
- background-position: -32px -16px;
-}
-
-.tree-view a.type.x-tree-icon-symlink {
- background-position: -48px -16px;
-}
-
-.tree-view a.type.x-tree-icon-userdata {
- background-position: -16px -48px;
-}
-
-.tree-view a.type.x-tree-icon-locked {
- background-position: -64px -16px;
-}
-
-.tree-view a.type.x-tree-icon-broken {
- background-position: -64px -16px;
-}
-
-.tree-view a.type.x-tree-icon-computer {
- background-position: 0px -48px;
-}
-
-.tree-view a.type.x-tree-icon-mydocuments {
- background-position: -32px -48px;
-}
-
-.tree-view a.type.x-tree-icon-mymusic {
- background-position: -48px -48px;
-}
-
-.tree-view a.type.x-tree-icon-mypictures {
- background-position: -64px -48px;
-}
-
-.tree-view a.type.x-tree-icon-desktop {
- background-position: -80px -48px;
-}
-
-.tree-view a.type.x-tree-icon-home {
- background-position: -96px -48px;
-}
-
-
-.tree-view li a.type.invisible {
- background-position: 0px -32px;
-}
-
-.tree-view a.type.x-tree-icon-drive.invisible {
- background-position: -16px -32px;
-}
-
-
-.tree-view a.type.x-tree-icon-leaf.invisible {
- background-position: -32px -32px;
-}
-
-.tree-view a.type.x-tree-icon-symlink.invisible {
- cursor: auto;
- background-position: -48px -32px;
-}
-
-.tree-view a.type.x-tree-icon-locked.invisible {
- background-position: -64px -32px;
-}
-
-
-.tree-view a.type.loading {
- cursor: progress;
- background-image: url(../img/loader-16.gif);
- background-repeat: no-repeat;
- background-position: 0px 0px;
-}
-
-.tree-view li a.check {
- height: 16px;
- width: 16px;
- display: inline-block;
- cursor: pointer;
- background-image: url(../img/treeicons.png);
- background-repeat: no-repeat;
- background-position: 0px 0px;
- vertical-align: middle;
-}
-
-.tree-view li a.check.partial {
- background-position: -32px 0px;
-}
-
-.tree-view li a.check.include {
- background-position: -16px 0px;
-}
-
-.tree-view li a.check.exclude {
- background-position: -48px 0px;
-}
-
-.tree-view li a.check.root {
- background: none;
- display: none;
-}
-
-.tree-view li > ul {
- display: none;
-}
-
-.tree-view li > ul.expanded {
- display: block;
-}
-
-.step2 source-folder-picker, #folder_path_picker, #restore_file_picker {
- overflow: auto;
- display: block;
- border: 1px solid lightgray;
- padding: 2px;
- height: 100%;
- overflow: auto;
-}
-
-.step1 li.strength.score-0 {
- color: #ff0000;
-}
-
-.step1 li.strength.score-1 {
- color: #ff7700;
-}
-
-.step1 li.strength.score-2 {
- color: #aaaa00;
-}
-
-.step1 li.strength.score-3 {
- color: #007700;
-}
-
-.step1 li.strength.score-4 {
- color: #427e27;
-}
-
-.step1 li.strength.score-x {
- color: #ff0000;
-}
-
-.pause a {
- margin-top: 20px;
- margin-bottom: 20px;
- display: block;
- font-weight: 300;
- font-size: 24px;
-}
-
-body .container .body .content .tasks .tasklist a.action-link {
- font-size: 14px;
- background: none;
- padding-left: 0px;
-}
-
-
-/* Progress bar styles from Bootstrap */
-.progress-bar {
- float: left;
- width: 0;
- height: 100%;
- font-size: 12px;
- line-height: 20px;
- color: #fff;
- text-align: center;
- background-color: #337ab7;
- -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
- box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
- -webkit-transition: width .6s ease;
- -o-transition: width .6s ease;
- transition: width .6s ease;
- height: 100%;
- position: absolute;
-}
-
-.progress-bar-striped, .progress-striped .progress-bar {
- background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);
- background-image: -o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);
- background-image: linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);
- -webkit-background-size: 40px 40px;
- background-size: 40px 40px;
-}
-
-.progress-bar.active, .progress.active .progress-bar {
- -webkit-animation: progress-bar-stripes 2s linear infinite;
- -o-animation: progress-bar-stripes 2s linear infinite;
- animation: progress-bar-stripes 2s linear infinite;
-}
-
-.progress {
- position: relative;
- min-height: 25px;
-}
-.progress > span {
- position: absolute;
- vertical-align: middle;
- display: block;
- width: 100%;
- height: 100%;
- text-align: center;
- z-index: 100;
- padding-top: 2px;
-}
-
-.ui-match {
- font-weight: bold;
- color: darkgreen;
-}
-
-
-form.styled div.leftflush input {
- width: auto;
- margin-top: 10px;
-}
-
-form.styled div.leftflush label {
- width: auto;
- min-width: 190px;
-}
-
-wait-area {
- min-width: 350px;
- text-align: center;
- display: block;
-}
-
-.contextmenu p {
- display: inline;
- margin-right: 10px;
- color: #65b1dd;
- cursor: pointer;
-}
-
-.prewrapped-text {
- white-space: pre-wrap;
-}
-
-.exceptiontext {
- background-color: lightgray;
- color: black;
-}
-
-
-ul.tabs {
- margin-bottom: 10px;
-}
-
-ul.tabs > li {
- display: inline;
- margin-right: 10px;
- border: 1px solid #65b1dd;
- padding: 5px;
-}
-
-ul.tabs > li.active, ul.tabs > li.active > a {
- background-color: #65b1dd;
- color: white;
-
-}
-
-ul.tabs > li.active.disabled {
- border: 1px solid lightgray;
-}
-
-ul.tabs > li.active.disabled, ul.tabs > li.active.disabled > a {
- background-color: lightgray;
- color: grey;
- cursor: default;
-
-}
-
-.licenses > ul {
- list-style: initial;
- margin: 10px;
- margin-left: 20px;
-}
-
-.licenses li {
- margin-bottom: 10px;
-}
-
-.licenses a.itemlink {
- font-weight: bold;
-}
-
-.logpage ul.entries {
- list-style: initial;
- margin: 10px;
- margin-left: 20px;
-}
-
-.logpage .entries div.entryline {
- cursor: pointer;
-}
-
-.logpage .entries.livedata li {
- height: 1.2em;
- overflow: hidden;
-}
-
-.logpage .entries.livedata li.expanded {
- height: auto;
- overflow: auto;
-}
-
-.logpage .button {
- text-align: center;
- margin-right: 10px;
- border: 1px solid #65b1dd;
- padding: 5px;
- background-color: #65b1dd;
- color: white;
- cursor: pointer;
-}
-
-.exportpage .checkbox input {
- width: auto;
- margin-top: 10px;
-}
-
-.exportpage .commandline div {
- background-color: lightgray;
- color: black;
-}
-
-div.connection-lost, div.blocker, div.modal-dialog {
- position: fixed;
- top: 0px;
- left: 0px;
- right: 0px;
- bottom: 0px;
- margin: auto;
-}
-
-div.connection-lost {
- width: 250px;
- height: 200px;
-}
-
-div.modal-dialog {
- width: 350px;
- height: 250px;
-}
-
-div.blocker {
- background-color: #000000;
- opacity: 0.65;
-}
-
-.connection-lost div.info, .modal-dialog div.info {
- display: inline-block;
-}
-
-.connection-lost div.title, .modal-dialog div.title {
- border: 1px solid #65b1dd;
- background-color: #65b1dd;
- border-top-left-radius: 5px;
- border-top-right-radius: 5px;
- border-bottom-left-radius: 0px;
- border-bottom-right-radius: 0px;
- padding: 10px;
- padding-left: 20px;
- padding-right: 20px;
- font-weight: bold;
- color: lightgray;
- width: 100%;
- text-align: center;
-}
-
-.connection-lost div.content, .modal-dialog div.content {
- background-color: white;
- border: 1px solid white;
- padding: 20px;
- width: 100%;
- min-width: 250px;
-}
-
-.connection-lost div.content.buttons, .modal-dialog div.content.buttons {
- border-top-left-radius: 0px;
- border-top-right-radius: 0px;
- border-bottom-left-radius: 5px;
- border-bottom-right-radius: 5px;
- overflow: auto;
-}
-
-.modal-dialog .content.buttons ul {
- float: right;
-}
-
-.themelink {
- margin-left: 20px;
-}
-
-body .container .header .donate ul {
- overflow: hidden;
- float: right;
- padding-left: 20px;
- padding-right: 10px;
-}
-
-body .container .header .donate ul li {
- float: right;
- margin-right: 10px;
- padding-top: 5px;
- }
-
-.header .donate {
- float: right;
-}
-
-ul.notification {
- position: fixed;
- bottom: 0px;
- left: 0px;
- right: 0px;
- margin: auto;
- width: 300px;
-}
-
-.notification .title {
- border: 1px solid #65b1dd;
- background-color: #65b1dd;
- border-top-left-radius: 5px;
- border-top-right-radius: 5px;
- border-bottom-left-radius: 0px;
- border-bottom-right-radius: 0px;
- padding: 2px;
- padding-left: 5px;
- padding-right: 5px;
- font-weight: bold;
- color: lightgray;
- width: 100%;
- text-align: center;
- clear: both;
-}
-
-.notification .content {
- background-color: white;
- border: 1px solid #65b1dd;
- border-top-left-radius: 0px;
- border-top-right-radius: 0px;
- border-bottom-left-radius: 5px;
- border-bottom-right-radius: 5px;
- padding: 2px;
- padding-left: 5px;
- padding-right: 5px;
- padding-bottom: 30px;
- width: 100%;
-}
-
-.notification .message {
- width: 100%;
- color: black;
-}
-
-.notification .buttons {
- padding-top: 6px;
-}
-
-.notification .button {
- padding: 2px 10px;
-}
-
-
-.notification .error .title, .notification .error .content, .notification .error .button {
- border-color: red;
-}
-
-.notification .error .title, .notification .error .button {
- background-color: red;
-}
-
-.notification .warning .title, .notification .warning .button {
- background-color: orange;
-}
-
-.notification .warning .title, .notification .warning .content, .notification .warning .button {
- border-color: orange;
-}
-
-.filepicker {
- height: 200px;
-}
-
-.resizable {
- margin-bottom: 6px;
- max-width: 100%;
-}
-
-.advanced-toggle {
- float: right;
- margin-right: 25px;
- line-height: 37px;
-}
-
-.advancedoptions li {
- clear: both;
- margin-bottom: 10px;
- padding: 10px 0;
- border-top: 1px lightgray solid;
-}
-
-.advancedentry .multiple {
- display: inline;
-}
-
-.advancedentry .shortname {
- font-weight: bold;
-}
-
-.advancedentry input[type="text"],
-.advancedentry select
-{
- width: 300px;
-}
-
-.advancedentry input[type="checkbox"]
-{
- margin-top: 13px;
- width: auto;
-}
-
-.advancedentry .longdescription {
- margin-left: 190px;
- clear: both;
- font-style: italic;
-}
-
-.settings div.sublabel {
- clear: both;
- padding: 0 31px;
- font-style: italic;
-}
-
-.logo div.build-suffix {
- display: inline;
- font-size: 16px;
-}
-
-.logo div.powered-by {
- font-size: 16px;
- margin: 0px;
- line-height: 16px;
- padding: 0px;
- margin-top: -25px;
- margin-left: 10px
-}
-
-.fixed-width-font {
- font-family: monospace;
-}
-
-@media(max-width: 580px)
-{
- .advancedentry .longdescription
- {
- margin-left: 0;
- }
-}
diff --git a/Duplicati/Server/webroot/ngax/styles/themes.css b/Duplicati/Server/webroot/ngax/styles/themes.css
new file mode 100644
index 000000000..ae3ce5c60
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/styles/themes.css
@@ -0,0 +1,59 @@
+body.theme-dark
+{
+ background-color: #1a1a1a !important;
+}
+
+body.theme-dark .footer
+{
+ background-color: #333333 !important;
+}
+
+body.theme-dark .header
+{
+ background-color: #333333 !important;
+}
+
+body.theme-dark .state
+{
+ background-color: #1a1a1a !important;
+}
+
+body.theme-dark form.styled .buttons input, body.theme-dark form.styled .buttons a
+{
+ background: #4a5879;
+}
+
+body.theme-dark form.styled .buttons input:hover, body.theme-dark form.styled .buttons a:hover
+{
+ background: #6089b5;
+}
+
+body.theme-dark .button
+{
+ background: #4a5879;
+}
+
+body.theme-dark .button:hover
+{
+ background: #6089b5;
+}
+
+body.theme-dark .container .body .mainmenu>ul>li>a.active
+{
+ color: black;
+}
+
+body.theme-dark .container .body .content div.add .steps .step, body.theme-dark .container .body .content div.restore .steps .step
+{
+ color: #2780b3;
+}
+
+body.theme-dark .step3 source-folder-picker, body.theme-dark #folder_path_picker, body.theme-dark #restore_file_picker
+{
+ background-color: #ffffff;
+}
+
+body.theme-dark form.styled input, body.theme-dark form.styled textarea, body.theme-dark form.styled select
+{
+ color: #000000;
+} \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/templates/about.html b/Duplicati/Server/webroot/ngax/templates/about.html
index 3e4088152..948c42bf1 100644
--- a/Duplicati/Server/webroot/ngax/templates/about.html
+++ b/Duplicati/Server/webroot/ngax/templates/about.html
@@ -19,7 +19,7 @@
translate-params-licensename="'GNU Lesser General Public License'"
translate-params-licenselink="'https://www.gnu.org/licenses/lgpl.html'"
>
- {{appname}} was primarily developed by <a href="mail1">{{dev1}}</a> and <a href="mail2">{{dev2}}</a>. {{appname}} can be downloaded from <a href="{websitelink}">{{websitename}}</a>. {{appname}} is licensed under the <a href="{{licenselink}}">{{licensename}}</a>.
+ {{appname}} was primarily developed by <a href="{{mail1}}">{{dev1}}</a> and <a href="{{mail2}}">{{dev2}}</a>. {{appname}} can be downloaded from <a href="{{websitelink}}">{{websitename}}</a>. {{appname}} is licensed under the <a href="{{licenselink}}">{{licensename}}</a>.
</div>
<div>&nbsp;</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/addoredit.html b/Duplicati/Server/webroot/ngax/templates/addoredit.html
index fa93f6dc1..50b50a905 100755
--- a/Duplicati/Server/webroot/ngax/templates/addoredit.html
+++ b/Duplicati/Server/webroot/ngax/templates/addoredit.html
@@ -14,14 +14,18 @@
<div class="step step4" ng-class="{active: CurrentStep == 3}" ng-click="CurrentStep = 3">
<span>4</span>
</div>
+ <div class="step step5" ng-class="{active: CurrentStep == 4}" ng-click="CurrentStep = 4">
+ <span>5</span>
+ </div>
</div>
<!-- .steps -->
<ol class="steps-legend">
<li ng-class="{active: CurrentStep == 0}" class="step1" ng-click="CurrentStep = 0" translate>General</li>
- <li ng-class="{active: CurrentStep == 1}" class="step2" ng-click="CurrentStep = 1" translate>Source Data</li>
- <li ng-class="{active: CurrentStep == 2}" class="step3" ng-click="CurrentStep = 2" translate>Schedule</li>
- <li ng-class="{active: CurrentStep == 3}" class="step4" ng-click="CurrentStep = 3" translate>Options</li>
+ <li ng-class="{active: CurrentStep == 1}" class="step2" ng-click="CurrentStep = 1" translate>Destination</li>
+ <li ng-class="{active: CurrentStep == 2}" class="step3" ng-click="CurrentStep = 2" translate>Source Data</li>
+ <li ng-class="{active: CurrentStep == 3}" class="step4" ng-click="CurrentStep = 3" translate>Schedule</li>
+ <li ng-class="{active: CurrentStep == 4}" class="step5" ng-click="CurrentStep = 4" translate>Options</li>
</ol>
<!-- .steps-legend -->
@@ -29,83 +33,120 @@
<div class="step step1" ng-class="{active: CurrentStep == 0}">
<div class="form">
<form class="styled">
- <backup-edit-uri uri="Backup.TargetURL" hide="HideEditUri" ng-show="EditUriState"></backup-edit-uri>
+ <h2 translate>General backup settings</h2>
- <div ng-hide="EditUriState">
- <div class="input text linklabel">
- <label for="importlink">&nbsp;</label>
- <a href="#import" translate>Import configuration from a file ...</a>
- </div>
-
- <div class="input text">
- <label for="name" translate>Name</label>
- <input type="text" name="name" id="name" ng-model="Backup.Name" placeholder="{{'My Photos' | translate}}"/>
- </div>
- <div class="input textarea linklabel">
- <label for="target"><a href class="target" ng-click="EditUriState = true" translate>Backup to &gt;</a></label>
- <textarea name="target" id="target" ng-model="Backup.TargetURL" placeholder="{{'Enter a url, or click the \'Backup to &gt;\' link' | translate }}"></textarea>
- </div>
- <div class="input select" ng-hide="SystemInfo.EncryptionModules.length == 0">
- <label for="encryption" translate>Encryption</label>
- <select name="encryption" id="encryption" ng-model="Options['encryption-module']" ng-options="module.Key as module.DisplayName for module in SystemInfo.EncryptionModules">
- <option value="" translate>No encryption</option>
- </select>
- </div>
+ <div class="input text">
+ <label for="name" translate>Name</label>
+ <input type="text" name="name" id="name" ng-model="Backup.Name" placeholder="{{'My Photos' | translate}}"/>
+ </div>
+ <div class="input select" ng-hide="SystemInfo.EncryptionModules.length == 0">
+ <label for="encryption" translate>Encryption</label>
+ <select name="encryption" id="encryption" ng-model="Options['encryption-module']" ng-options="module.Key as module.DisplayName for module in SystemInfo.EncryptionModules">
+ <option value="" translate>No encryption</option>
+ </select>
+ </div>
- <div class="input encryptionhint" ng-show="(Options['encryption-module'] || '').length == 0">
- <h3 class="warning" translate>We recommend that you encrypt all backups stored outside your system</h3>
- </div>
+ <div class="input encryptionhint" ng-show="(Options['encryption-module'] || '').length == 0">
+ <h3 class="warning" translate>We recommend that you encrypt all backups stored outside your system</h3>
+ </div>
- <div class="input password" ng-hide="(Options['encryption-module'] || '').length == 0">
- <label for="passphrase" translate>Passphrase</label>
- <input type="{{ShowPassphrase ? 'text' : 'password'}}" name="passphrase" id="passphrase" ng-model="Options['passphrase']" />
- </div>
- <div class="input password" ng-hide="(Options['encryption-module'] || '').length == 0">
- <label for="repeat-passphrase" translate>Repeat Passphrase</label>
- <input type="{{ShowPassphrase ? 'text' : 'password'}}" name="repeat-passphrase" id="repeat-passphrase" ng-model="RepeatPasshrase"/>
-
- <div class="tools">
- <ul>
- <li>
- <a href ng-click="togglePassphraseVisibility()" ng-show="ShowPassphrase" translate>Hide</a>
- <a href ng-click="togglePassphraseVisibility()" ng-hide="ShowPassphrase" translate>Show</a>
- </li>
- <li>|</li>
- <li>
- <a href ng-click="generatePassphrase()" translate>Generate</a>
- </li>
- <li>|</li>
- <li class="strength score-{{PassphraseScore}}">{{PassphraseScore != 'x' ? 'Strength: ' : ''}} {{PassphraseScoreString}}</li>
- </ul>
- </div>
- </div>
-
- <div class="buttons">
- <input class="submit next" type="button" id="nextStep1" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
+ <div class="input password" ng-hide="(Options['encryption-module'] || '').length == 0">
+ <label for="passphrase" translate>Passphrase</label>
+ <input type="{{ShowPassphrase ? 'text' : 'password'}}" name="passphrase" id="passphrase" ng-model="Options['passphrase']" />
+ </div>
+ <div class="input password" ng-hide="(Options['encryption-module'] || '').length == 0">
+ <label for="repeat-passphrase" translate>Repeat Passphrase</label>
+ <input type="{{ShowPassphrase ? 'text' : 'password'}}" name="repeat-passphrase" id="repeat-passphrase" ng-model="RepeatPasshrase"/>
+
+ <div class="tools">
+ <ul>
+ <li>
+ <a href ng-click="togglePassphraseVisibility()" ng-show="ShowPassphrase" translate>Hide</a>
+ <a href ng-click="togglePassphraseVisibility()" ng-hide="ShowPassphrase" translate>Show</a>
+ </li>
+ <li>|</li>
+ <li>
+ <a href ng-click="generatePassphrase()" translate>Generate</a>
+ </li>
+ <li ng-show="PassphraseScoreString">|</li>
+ <li class="strength score-{{PassphraseScore}}" ng-show="PassphraseScoreString">{{PassphraseScore != 'x' ? 'Strength: ' : ''}} {{PassphraseScoreString}}</li>
+ </ul>
</div>
</div>
+
+ <div class="buttons">
+ <input class="submit next" type="button" id="nextStep1" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
+ </div>
</form>
</div>
</div>
<!-- .step1 -->
-
+
<div class="step step2" ng-class="{active: CurrentStep == 1}">
<form class="styled">
+ <div class="headerthreedotmenu">
+ <h2 translate>Backup destination</h2>
+
+ <div class="contextmenu_container">
+ <a href title="{{'Menu' | translate}}"><img src="img/three_dots.png" id="threedotmenubutton_add_destination" class="threedotmenubutton"/></a>
+
+ <div class="contextmenu" id="threedotmenu_add_destination">
+ <ul>
+ <li>
+ <a href ng-click="importUrl()" translate>Import Destination URL</a>
+ </li>
+ <li>
+ <a href ng-click="copyUrlToClipboard()" translate>Copy Destination URL to Clipboard</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <backup-edit-uri uri="Backup.TargetURL" set-builduri-fn="setBuilduriFn(builduriFn)"></backup-edit-uri>
+
+ <div class="buttons">
+ <input class="submit next" type="button" id="nextStep2" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
+ <input class="submit prev" type="button" id="prevStep2" ng-click="prevPage()" value="&lt; {{'Previous' | translate}}" />
+ </div>
+ </form>
+ </div>
+ <!-- .step2 -->
+
+ <div class="step step3" ng-class="{active: CurrentStep == 2}">
+ <form class="styled">
<div class="box browser">
- <h2 translate>Folders</h2>
+ <div class="headerthreedotmenu">
+ <h2 translate>Source data</h2>
+
+ <div class="contextmenu_container">
+ <a href title="{{'Menu' | translate}}"><img src="img/three_dots.png" id="threedotmenubutton_add_source_folders" class="threedotmenubutton"/></a>
+
+ <div class="contextmenu" id="threedotmenu_add_source_folders">
+ <ul>
+ <li ng-hide="EditSourceAdvanced">
+ <a href ng-click="EditSourceAdvanced = true" translate>Show advanced editor</a>
+ </li>
+ <li ng-show="EditSourceAdvanced">
+ <a href ng-click="EditSourceAdvanced = false" translate>Show treeview</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
<div class="input checklinks">
<a href class="{{EditSourceAdvanced ? 'inactive' : ''}}" ng-click="showhiddenfolders = !showhiddenfolders"><i class="fa {{showhiddenfolders ? 'fa-check' : ''}}"></i> {{'Show hidden folders' | translate}}</a>
- <a href ng-click="EditSourceAdvanced = !EditSourceAdvanced"><i class="fa {{EditSourceAdvanced ? 'fa-check' : ''}}"></i> {{'Show advanced editor' | translate}}</a>
</div>
- <div class="resizable filepicker" ng-hide="EditSourceAdvanced" ng-show-hidden="showhiddenfolders">
- <source-folder-picker ng-sources="Backup.Sources" ng-filters="Backup.Filters"></source-folder-picker>
+ <div class="resizable filepicker" ng-hide="EditSourceAdvanced">
+ <source-folder-picker ng-sources="Backup.Sources" ng-filters="Backup.Filters" ng-show-hidden="showhiddenfolders"></source-folder-picker>
</div>
<div class="input textarea" ng-show="EditSourceAdvanced">
<label for="SourcePathList" translate>Source folders</label>
<textarea id="SourcePathList" string-array-as-text ng-model="Backup.Sources" ng-model-options="{updateOn: 'blur'}"></textarea>
</div>
<div class="input text overlayButton">
- <input type="text" name="sourcePath" id="sourcePath" placeholder="Add a path directly" ng-model="manualSourcePath" ng-disabled="validatingSourcePath" />
+ <input type="text" name="sourcePath" id="sourcePath" placeholder="{{'Add a path directly' | translate}}" ng-model="manualSourcePath" ng-disabled="validatingSourcePath" />
<a href id="sourceFolderPathAdd" class="button" ng-disabled="validatingSourcePath || manualSourcePath == null || manualSourcePath == ''" ng-click="addManualSourcePath()">
<span ng-show="validatingSourcePath" translate>Validating ...</span>
<span ng-hide="validatingSourcePath" translate>Add path</span>
@@ -113,64 +154,109 @@
</div>
</div>
<div class="box filters">
- <h2 translate>Filters</h2>
- <div class="input link">
- <a href ng-click="EditFilterAdvanced = !EditFilterAdvanced"><i class="fa {{EditFilterAdvanced ? 'fa-check' : ''}}"></i> {{'Show advanced editor' | translate}}</a>
- </div>
- <div class="input textarea" ng-show="EditFilterAdvanced">
- <!--<label for="FilterList">Filters <span class="info">i</span></label>-->
- <textarea id="FilterList" string-array-as-text ng-model="Backup.Filters" ng-model-options="{updateOn: 'blur'}"></textarea>
+ <div class="headerthreedotmenu">
+ <a href ng-click="showFilter = !showFilter" class="expandable">
+ <h2 translate>Filters</h2>
+ <img ng-show="showFilter" src="img/arrow_collapse_green.png">
+ <img ng-hide="showFilter" src="img/arrow_expand_green.png">
+ </a>
+
+ <div class="contextmenu_container" ng-show="showFilter">
+ <a href title="{{'Menu' | translate}}"><img src="img/three_dots.png" id="threedotmenubutton_add_source_filters" class="threedotmenubutton" title="{{'Menu' | translate}}"/></a>
+
+ <div class="contextmenu" id="threedotmenu_add_source_filters">
+ <ul>
+ <li>
+ <a href ng-show="EditFilterAdvanced" ng-click="EditFilterAdvanced = false" translate>Edit as list</a>
+ </li>
+ <li>
+ <a href ng-hide="EditFilterAdvanced" ng-click="EditFilterAdvanced = true" translate>Edit as text</a>
+ </li>
+ </ul>
+ </div>
+ </div>
</div>
- <div class="input textarea" ng-hide="EditFilterAdvanced">
- <ul id="simplefilterlist">
- <li ng-repeat="f in Backup.Filters track by $index">
- <select parse-filter-type ng-model="Backup.Filters[$index]" ng-options="item.key as item.name for item in AppUtils.filterClasses">
- </select>
-
- <input type="text" parse-filter-content ng-model="Backup.Filters[$index]" ng-model-options="{updateOn: 'blur'}" placeholder="{{'Enter expression here' | translate}}"/>
-
- <a class="button" href title="{{'Remove' | translate}}" ng-click="Backup.Filters.splice($index, 1)">X</a>
- </li>
-
- </ul>
- <a href ng-click="Backup.Filters.push('-*')" translate>Add filter</a>
+
+ <div ng-show="showFilter">
+ <div class="input textarea" ng-show="EditFilterAdvanced">
+ <!--<label for="FilterList">Filters <span class="info">i</span></label>-->
+ <textarea id="FilterList" string-array-as-text ng-model="Backup.Filters" ng-model-options="{updateOn: 'blur'}"></textarea>
+ </div>
+ <div class="input textarea" ng-hide="EditFilterAdvanced">
+ <ul id="simplefilterlist">
+ <li ng-repeat="f in Backup.Filters track by $index">
+ <select parse-filter-type ng-model="Backup.Filters[$index]" ng-options="item.key as item.name for item in AppUtils.filterClasses">
+ </select>
+
+ <input type="text" parse-filter-content ng-model="Backup.Filters[$index]" ng-model-options="{updateOn: 'blur'}" placeholder="{{'Enter expression here' | translate}}"/>
+
+ <a class="button" href title="{{'Remove' | translate}}" ng-click="Backup.Filters.splice($index, 1)">X</a>
+ </li>
+
+ </ul>
+ <a href ng-click="Backup.Filters.push('-*')" translate>Add filter</a>
+ </div>
+
+ <div class="input checkbox multiple">
+ <strong translate>Default Filters</strong>
+
+ <div ng-repeat="filterSet in defaultFilterSets">
+ <input id="filterSet_{{filterSet.value}}"
+ type="checkbox"
+ name="filterSet_{{filterSet.value}}"
+ value="{{filterSet.value}}"
+ ng-checked="isDefaultFilterSetEnabled(filterSet.value)"
+ ng-click="toggleDefaultFilters(filterSet.value)" />
+ <label for="filterSet_{{filterSet.value}}">{{filterSet.name}}</label>
+ </div>
+ </div>
</div>
</div>
<div class="box exclude">
- <h2 translate>Exclude</h2>
- <div class="input checkbox multiple">
- <div ng-repeat="attr in fileAttributes">
- <input
- id="fileattr_{{attr.value}}"
- type="checkbox"
- name="fileattr_{{attr.value}}"
- value="{{attr.value}}"
- ng-checked="ExcludeAttributes.indexOf(attr.value) > -1"
- ng-click="toggleArraySelection(ExcludeAttributes, attr.value)"
- />
- <label for="fileattr_{{attr.value}}">{{attr.name}}</label>
- </div>
+ <div class="expandable">
+ <a href ng-click="showExclude = !showExclude">
+ <h2 translate>Exclude</h2>
+ <img ng-show="showExclude" src="img/arrow_collapse_green.png">
+ <img ng-hide="showExclude" src="img/arrow_expand_green.png">
+ </a>
</div>
-
- <div class="input text select multiple">
- <input id="exclude-large-files" type="checkbox" class="simple-checkbox" ng-model="ExcludeLargeFiles" />
- <label for="exclude-large-files" translate>Files larger than:</label>
-
- <input type="number" parse-size-number="uppercase" ng-model="Options['--skip-files-larger-than']" id="exclude-larger-than-number" ng-disabled="!ExcludeLargeFiles" value="1" />
- <select parse-size-multiplier="uppercase" id="exclude-larger-than-multiplier" ng-model="Options['--skip-files-larger-than']" ng-disabled="!ExcludeLargeFiles" ng-options="item.value as item.name for item in AppUtils.fileSizeMultipliers">
- </select>
+
+ <div ng-show="showExclude">
+ <div class="input checkbox multiple">
+ <div ng-repeat="attr in fileAttributes">
+ <input
+ id="fileattr_{{attr.value}}"
+ type="checkbox"
+ name="fileattr_{{attr.value}}"
+ value="{{attr.value}}"
+ ng-checked="ExcludeAttributes.indexOf(attr.value) > -1"
+ ng-click="toggleExcludeAttributes(attr.value)"
+ />
+ <label for="fileattr_{{attr.value}}">{{attr.name}}</label>
+ </div>
+ </div>
+
+ <div class="input text select multiple">
+ <input id="exclude-large-files" type="checkbox" class="simple-checkbox" ng-model="ExcludeLargeFiles" />
+ <label for="exclude-large-files" translate>Files larger than:</label>
+
+ <input type="number" parse-size-number="uppercase" ng-model="Options['--skip-files-larger-than']" id="exclude-larger-than-number" ng-disabled="!ExcludeLargeFiles" value="1" />
+ <select parse-size-multiplier="uppercase" id="exclude-larger-than-multiplier" ng-model="Options['--skip-files-larger-than']" ng-disabled="!ExcludeLargeFiles" ng-options="item.value as item.name for item in AppUtils.fileSizeMultipliers">
+ </select>
+ </div>
</div>
</div>
<div class="buttons">
- <input class="submit next" type="button" id="nextStep2" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
- <input class="submit prev" type="button" id="prevStep2" ng-click="prevPage()" value="&lt; {{'Previous' | translate}}" />
+ <input class="submit next" type="button" id="nextStep3" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
+ <input class="submit prev" type="button" id="prevStep3" ng-click="prevPage()" value="&lt; {{'Previous' | translate}}" />
</div>
</form>
</div>
- <!-- .step2 -->
+ <!-- .step3 -->
- <div class="step step3" ng-class="{active: CurrentStep == 2}">
+ <div class="step step4" ng-class="{active: CurrentStep == 3}">
<form class="styled">
+ <h2 translate>Schedule</h2>
<div class="input checkbox multiple">
<input type="checkbox" id="useScheduleRun" ng-checked="Schedule != null" ng-click="toggleSchedule()" />
<label for="useScheduleRun" translate>Automatically run backups.</label>
@@ -203,7 +289,7 @@
name="dayofweek_{{day.value}}"
value="{{day.value}}"
ng-checked="Schedule.AllowedDays.indexOf(day.value) > -1"
- ng-click="toggleArraySelection(Schedule.AllowedDays, day.value)"
+ ng-click="toggleAllowedDays(day.value)"
/>
<label for="dayofweek_{{day.value}}">{{day.name}}</label>
</div>
@@ -211,14 +297,14 @@
</div>
<div class="buttons">
- <input class="submit next" type="button" id="nextStep3" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
- <input class="submit prev" type="button" id="prevStep3" ng-click="prevPage()" value="&lt; {{'Previous' | translate}}" />
+ <input class="submit next" type="button" id="nextStep4" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
+ <input class="submit prev" type="button" id="prevStep4" ng-click="prevPage()" value="&lt; {{'Previous' | translate}}" />
</div>
</form>
</div>
- <!-- .step3 -->
+ <!-- .step4 -->
- <div class="step step4" ng-class="{active: CurrentStep == 3}">
+ <div class="step step5" ng-class="{active: CurrentStep == 4}">
<form class="styled">
<h2 translate>General options</h2>
<div class="input multiple text select maxSize">
@@ -228,16 +314,16 @@
</select>
</div>
<div class="input multiple text select keepBackups">
- <label for="keepTimeType" translate>Keep backups</label>
+ <label for="keepTimeType" translate>Keep this number of backups</label>
<select id="keepTimeType" ng-model="KeepType">
- <option value="" translate>forever</option>
- <option value="time" translate>for a specific time</option>
+ <option value="" translate>unlimited</option>
+ <option value="time" translate>until they are older than</option>
<option value="versions" translate>a specific number</option>
</select>
- <input type="number" ng-model="Options['keep-versions']" ng-show="KeepType == 'versions'" />
+ <input type="number" ng-model="Options['keep-versions']" ng-show="KeepType == 'versions'" min="1" />
<div ng-show="KeepType == 'time'">
- <input type="number" class="number" parse-size-number ng-model="Options['keep-time']" />
+ <input type="text" class="number" parse-size-number ng-model="Options['keep-time']" />
<select parse-size-multiplier ng-model="Options['keep-time']" >
<option value="D" translate>Days</option>
<option value="W" translate>Weeks</option>
@@ -247,25 +333,56 @@
</select>
</div>
</div>
- <div class="input textarea" ng-show="ShowAdvancedTextArea">
- <h2 translate>Advanced options</h2>
- <a href ng-click="ShowAdvancedTextArea = false" class="advanced-toggle"><i class="fa fa-check"></i> <span translate>Edit as text</span></a>
- <textarea id="backupOptions" ng-model="ExtendedOptions" string-array-as-text placeholder="{{AppUtils.format(AppUtils.exampleOptionString, '--dblock-size=100MB')}}"></textarea>
+
+ <div ng-repeat="module in ServerModules">
+ <h2 title="{{module.Description}}">{{module.DisplayName}}</h2>
+
+ <div class="input" ng-repeat="opt in module.SupportedLocalCommands">
+ <label for="{{module.Key}}-{{opt.Name}}" title="{{opt.LongDescription}}">{{opt.ShortDescription}}</label>
+ <input type="text" title="{{opt.LongDescription}}" name="{{module.Key}}-{{opt.Name}}" id="{{module.Key}}-{{opt.Name}}" ng-model="servermodulesettings[opt.Name]" />
+ </div>
</div>
-
- <div class="input" ng-hide="ShowAdvancedTextArea">
- <h2 translate>Advanced options</h2>
- <a href ng-click="ShowAdvancedTextArea = true" class="advanced-toggle"><i class="fa"></i> {{'Edit as text' | translate}}</a>
- <advanced-options-editor ng-option-list="ExtendedOptionList" ng-model="ExtendedOptions"></advanced-options-editor>
+
+ <div class="headerthreedotmenu">
+ <a href ng-click="showAdvanced = !showAdvanced" class="expandable">
+ <h2 translate>Advanced options</h2>
+ <img ng-show="showAdvanced" src="img/arrow_collapse_green.png">
+ <img ng-hide="showAdvanced" src="img/arrow_expand_green.png">
+ </a>
+
+ <div class="contextmenu_container" ng-show="showAdvanced">
+ <a href title="{{'Menu' | translate}}"><img src="img/three_dots.png" id="threedotmenubutton_add_options_adv" class="threedotmenubutton" title="{{'Menu' | translate}}"/></a>
+
+ <div class="contextmenu" id="threedotmenu_add_options_adv">
+ <ul>
+ <li>
+ <a href ng-show="ShowAdvancedTextArea" ng-click="ShowAdvancedTextArea = false" translate>Edit as list</a>
+ </li>
+ <li>
+ <a href ng-hide="ShowAdvancedTextArea" ng-click="ShowAdvancedTextArea = true" translate>Edit as text</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div ng-show="showAdvanced">
+ <div class="input textarea" ng-show="ShowAdvancedTextArea">
+ <textarea id="backupOptions" ng-model="ExtendedOptions" string-array-as-text placeholder="{{AppUtils.format(AppUtils.exampleOptionString, '--dblock-size=100MB')}}"></textarea>
+ </div>
+
+ <div class="input" ng-hide="ShowAdvancedTextArea">
+ <advanced-options-editor ng-option-list="ExtendedOptionList" ng-model="ExtendedOptions"></advanced-options-editor>
+ </div>
</div>
<div class="buttons">
<input class="submit save" type="submit" id="save" ng-click="save()" value="{{'Save' | translate}}" />
- <input class="submit prev" type="button" id="prevStep4" ng-click="prevPage()" value="&lt; {{'Previous' | translate}}" />
+ <input class="submit prev" type="button" id="prevStep5" ng-click="prevPage()" value="&lt; {{'Previous' | translate}}" />
</div>
</form>
</div>
- <!-- .step4 -->
+ <!-- .step5 -->
</div>
<!-- .steps-boxes -->
</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/addwizard.html b/Duplicati/Server/webroot/ngax/templates/addwizard.html
new file mode 100644
index 000000000..2eab6263d
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/addwizard.html
@@ -0,0 +1,31 @@
+<div ng-controller="AddWizardController" class="addwizard">
+
+ <h1><div translate>Add a new backup</div></h1>
+
+ <form class="styled">
+ <ul>
+ <li class="input" ng-click="selection.style = 'blank'">
+ <input type="radio" name="blank" id="blank" ng-model="selection.style" value="blank">
+ <label for="direct" translate>Configure a new backup</label>
+ <div class="subtext" translate>Enter configuration details</div>
+ </li>
+
+ <li class="input" ng-click="selection.style = 'importfile'">
+ <input type="radio" name="blank" id="blank" ng-model="selection.style" value="importfile">
+ <label for="direct" translate>Import from a file</label>
+ <div class="subtext" translate>Load a configuration from an exported job or a storage provider</div>
+ </li>
+
+ <!--<li class="input" ng-click="selection.style = 'importremote'">
+ <input type="radio" name="blank" id="blank" ng-model="selection.style" value="importremote">
+ <label for="direct">From a remote backup</label>
+ <div class="subtext">Import configuration from a backup folder</div>
+ </li> -->
+
+ </ul>
+
+ <div class="buttons">
+ <input class="submit next" type="button" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
+ </div>
+ </form>
+</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/advancedoptionseditor.html b/Duplicati/Server/webroot/ngax/templates/advancedoptionseditor.html
index 6f20cb2f9..d71db8d88 100644
--- a/Duplicati/Server/webroot/ngax/templates/advancedoptionseditor.html
+++ b/Duplicati/Server/webroot/ngax/templates/advancedoptionseditor.html
@@ -16,6 +16,12 @@
</select>
</div>
+ <div ng-if="getInputType(item) == 'speed'" class="input type multiple">
+ <input type="number" parse-advanced-option-size-number="uppercase" ng-model="$parent.ngModel[$index]" />
+ <select parse-advanced-option-size-multiplier="uppercase" ng-model="$parent.ngModel[$index]" ng-options="item.value as item.name for item in speedMultipliers">
+ </select>
+ </div>
+
<div ng-if="getInputType(item) == 'timespan'" class="input type multiple">
<input parse-advanced-option-size-number type="number" ng-model="$parent.ngModel[$index]" />
<select parse-advanced-option-size-multiplier ng-model="$parent.ngModel[$index]" ng-options="item.value as item.name for item in timerangeMultipliers">
@@ -23,6 +29,12 @@
</select>
</div>
+ <div ng-if="getInputType(item) == 'shorttimespan'" class="input type multiple">
+ <input parse-advanced-option-size-number type="number" ng-model="$parent.ngModel[$index]" />
+ <select parse-advanced-option-size-multiplier ng-model="$parent.ngModel[$index]" ng-options="item.value as item.name for item in shorttimerangeMultipliers">
+ <option value="" translate>custom</option>
+ </select>
+ </div>
</div>
<a href ng-click="deleteItem(item)" title="{{'Remove option' | translate}}">x</a>
diff --git a/Duplicati/Server/webroot/ngax/templates/backends/jottacloud.html b/Duplicati/Server/webroot/ngax/templates/backends/jottacloud.html
new file mode 100644
index 000000000..40d523ec0
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/backends/jottacloud.html
@@ -0,0 +1,13 @@
+<div class="input text">
+ <label for="jottacloud_path" translate>Folder path</label>
+ <input type="text" name="jottacloud_path" id="jottacloud_path" ng-model="$parent.Path" placeholder="{{'Enter folder path name' | translate}}" />
+</div>
+
+<div class="input text">
+ <label for="jottacloud_username" translate>Username</label>
+ <input type="text" name="jottacloud_username" id="jottacloud_username" ng-model="$parent.Username" placeholder="{{'Username' | translate}}" />
+</div>
+<div class="input password">
+ <label for="jottacloud_password" translate>Password</label>
+ <input type="password" name="jottacloud_password" id="jottacloud_password" ng-model="$parent.Password" placeholder="{{'Password' | translate}}" />
+</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/backends/sia.html b/Duplicati/Server/webroot/ngax/templates/backends/sia.html
new file mode 100644
index 000000000..e5c937f2e
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/backends/sia.html
@@ -0,0 +1,17 @@
+<div class="input text">
+ <label for="sia_server" translate>Server</label>
+ <input type="text" id="sia_server" ng-model="$parent.Server" placeholder="{{'127.0.0.1:9980'}}" />
+</div>
+<div class="input text">
+ <label for="sia_path" translate>Folder path</label>
+ <input type="text" name="sia_targetpath" id="sia_targetpath" ng-model="$parent.sia_targetpath" placeholder="{{'Target path, ie /backup' | translate}}" />
+</div>
+<div class="input password">
+ <label for="sia_password" translate>Server password</label>
+ <input type="password" name="sia_password" id="sia_password" ng-model="$parent.sia_password" placeholder="{{'Sia server password' | translate}}" />
+</div>
+<div class="input text">
+ <label for="sia_redundancy" translate>Minimum redundancy</label>
+ <input type="text" name="sia_redundancy" id="sia_redundancy" ng-model="$parent.sia_redundancy" placeholder="{{'1.5'}}" />
+</div>
+<div>Choose 1.0 for fast backup, 1.5 for decent reliability, 2.0 for safer upload but slow backup.<br /><b>Note:</b>Sia will still boost redundancy later as long as you're connected to your hosts.</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/captcha.html b/Duplicati/Server/webroot/ngax/templates/captcha.html
new file mode 100644
index 000000000..7effca3b1
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/captcha.html
@@ -0,0 +1,15 @@
+<div class="captcha" ng-controller="CaptchaController">
+ <div ng-show="entry.imageurl">
+ <div>{{entry.message}}</div>
+ <div class="details">
+ <img src="{{entry.imageurl}}" />
+ <input type="text" ng-model="entry.answer" />
+ <input type="button" value="{{'Reload' | translate}}" ng-click="reload()" />
+ </div>
+
+ <div class="centered-text" ng-show="entry.verifying" translate>Checking ...</div>
+ <div class="centered-text warning" ng-show="!entry.verifying && entry.hasfailed" translate>Incorrect answer, try again</div>
+
+ </div>
+ <div ng-hide="entry.imageurl" translate>Loading ...</div>
+</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/commandline.html b/Duplicati/Server/webroot/ngax/templates/commandline.html
new file mode 100644
index 000000000..4c6f7ee51
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/commandline.html
@@ -0,0 +1,70 @@
+<div class="commandline form" ng-controller="CommandlineController">
+ <form class="styled" ng-hide="Mode == 'view'">
+ <backup-edit-uri uri="TargetURL" hide="HideEditUri" ng-show="EditUriState"></backup-edit-uri>
+
+ <div ng-hide="EditUriState">
+
+ <div class="input mixed">
+ <label for="command">Command</label>
+ <select name="command" id="command" ng-model="Command" ng-options="item for item in SupportedCommands">
+ </select>
+ <div style="float: left">{{CommandHelp[Command]}}</div>
+ </div>
+
+
+ <div class="input textarea linklabel">
+ <label for="target"><a href class="target" ng-click="EditUriState = true">Target URL &gt;</a></label>
+ <textarea name="target" id="target" ng-model="TargetURL" placeholder="Enter a url, or click the 'Target URL &gt;' link"></textarea>
+ </div>
+
+ <div class="input textarea">
+ <label for="arguments">Commandline arguments</label>
+ <textarea id="arguments" ng-model="Arguments" string-array-as-text placeholder="Enter one argument per line without quotes, e.g. *.txt"></textarea>
+ </div>
+
+ <div class="input textarea" ng-show="ShowAdvancedTextArea">
+ <label for="backupOptions">Advanced options</label>
+ <div>
+ <a href ng-click="ShowAdvancedTextArea = false" class="advanced-toggle"><i class="fa fa-check"></i> Edit as text</a>
+ <textarea id="backupOptions" ng-model="ExtendedOptions" string-array-as-text placeholder="Enter one option per line in command-line format, eg. --dblock-size=100MB"></textarea>
+ </div>
+ </div>
+
+ <div class="input" ng-hide="ShowAdvancedTextArea">
+ <label for="backupOptions">Advanced options</label>
+ <a href ng-click="ShowAdvancedTextArea = true" class="advanced-toggle"><i class="fa"></i> Edit as text</a>
+ <advanced-options-editor ng-option-list="ExtendedOptionList" ng-model="ExtendedOptions"></advanced-options-editor>
+ </div>
+
+ <div class="buttons">
+ <input class="submit run" type="submit" id="run" ng-click="run()" value="Run &quot;{{Command}}&quot; command now" />
+ </div>
+
+ </div>
+ </form>
+
+ <div ng-show="Mode == 'view'">
+ <h2 translate>Running commandline entry</h2>
+ <div ng-show="serverstate.programState == 'Paused' &amp;&amp; Started != true">
+ {{'Server is currently paused,' | translate}} <a ng-click="ServerStatus.resume()" translate>resume now</a>
+ </div>
+ <div ng-show="serverstate.programState != 'Paused' &amp;&amp; Started == null" translate="">
+ Connecting to task ....
+ </div>
+ <div ng-show="serverstate.programState != 'Paused' &amp;&amp; Started == false" translate="">
+ Waiting for task to start ....
+ </div>
+ <div ng-show="Started == true &amp;&amp; Finished == false">
+ <span translate>Running ....</span> <a href ng-click="Abort()" ng-hide="RawFinished">stop now</a>
+ </div>
+ <div ng-show="Started == true &amp;&amp; Finished == true" translate>
+ Finished!
+ </div>
+
+ <div ng-show="Started == true" class="prewrapped-text" style="overflow-x: auto;">
+ <div class="fixed-width-font" style="white-space: pre" ng-repeat="line in ViewLines track by $index">{{line}}</div>
+ </div>
+
+ </div>
+
+</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/copy_clipboard_buttons.html b/Duplicati/Server/webroot/ngax/templates/copy_clipboard_buttons.html
new file mode 100644
index 000000000..69659ead3
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/copy_clipboard_buttons.html
@@ -0,0 +1,4 @@
+<a href class="button" ngclipboard ngclipboard-success="onCopySuccess(e);" ngclipboard-error="onCopyError(e);" data-clipboard-action="copy" data-clipboard-target="#copytarget">
+ <img src="img/clippy.png" style="vertical-align: middle;"/>
+ <span style="vertical-align: middle;">Copy</span>
+</a>
diff --git a/Duplicati/Server/webroot/ngax/templates/delete.html b/Duplicati/Server/webroot/ngax/templates/delete.html
new file mode 100644
index 000000000..60a66329e
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/delete.html
@@ -0,0 +1,59 @@
+<div ng-controller="DeleteController">
+ <form class="styled">
+
+ <h1>
+ <span translate>Delete backup</span>
+ <b>
+ <span translate ng-hide="Backup.Backup.Name">...loading...</span>
+ <span ng-show="Backup.Backup.Name">{{Backup.Backup.Name}}</span>
+ </b>
+ </h1>
+
+ <div ng-hide="NoLocalDB">
+ <h2 translate>Delete local database</h2>
+
+ <div translate>
+ Each backup has a local database associated with it, which stores information about the remote backup on the local machine.
+ When deleting a backup, you can also delete the local database without affecting the ability to restore the remote files.
+ If you are using the local database for backups from the commandline, you should keep the database.
+ </div>
+
+ <div class="warning" translate ng-show="DeleteLocalDatabase && DbUsedElsewhere">
+ WARNING: The remote database is found to be in use by the commandline library
+ </div>
+
+ <div class="input checkbox multiple">
+ <label for="deleteLocalDB" translate>Delete the local database</label>
+ <input type="checkbox" id="deleteLocalDB" ng-model="DeleteLocalDatabase" />
+ </div>
+ </div>
+
+ <h2 translate>Export configuration</h2>
+ <div translate>If you want to use the backup later, you can export the configuration before deleting it</div>
+ <div class="buttons">
+ <input class="submit" type="button" ng-click="doExport()" value="{{'Export configuration' | translate}} &gt;" />
+ </div>
+
+ <div ng-hide="NoLocalDB">
+ <h2 translate>Delete remote files</h2>
+
+ <div ng-show="Backup.Backup.Metadata.TargetFilesCount == null" translate>Loading remote storage usage ...</div>
+ <div ng-show="Backup.Backup.Metadata.TargetFilesCount != null" translate translate-params-filecount="Backup.Backup.Metadata.TargetFilesCount" translate-params-filesize="Backup.Backup.Metadata.TargetSizeString">
+ Delete {{filecount}} files ({{filesize}}) from the remote storage?
+ </div>
+ <div class="warning" translate ng-show="DeleteRemoteFiles">WARNING: This will prevent you from restoring the data in the future.</div>
+
+ <div class="input checkbox multiple">
+ <label for="deleteRemoteFiles" translate>Delete remote files</label>
+ <input type="checkbox" id="deleteRemoteFiles" ng-model="DeleteRemoteFiles" />
+ </div>
+ </div>
+
+ <div class="buttons">
+ <input class="submit" type="button" ng-click="doDelete()" value="{{'Delete backup' | translate}} &gt;" />
+ <input class="cancel" type="button" ng-click="goBack()" value="{{'Cancel' | translate}}" />
+ </div>
+
+ </form>
+
+</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/edituri.html b/Duplicati/Server/webroot/ngax/templates/edituri.html
index 3ff832c00..221efcc69 100644
--- a/Duplicati/Server/webroot/ngax/templates/edituri.html
+++ b/Duplicati/Server/webroot/ngax/templates/edituri.html
@@ -1,40 +1,57 @@
-<a href ng-click="hide()" ng-hide="Testing">&lt; {{'Back' | translate}}</a>
-
-<div class="input select">
- <label for="type" translate>Storage Type</label>
- <select name="type" id="type" ng-model="Backend" ng-options="backend.DisplayName group by backend.GroupType for backend in SystemInfo.GroupedBackendModules | orderBy: ['OrderKey', 'GroupType', 'DisplayName'] track by backend.Key">
- </select>
-</div>
-
-<div ng-include="TemplateUrl">
-</div>
-
-<div ng-show="TemplateUrl == null &amp;&amp; Backend != null">
- <h3 translate translate-params-backend="Backend.DisplayName">No editor found for the &quot;{{backend}}&quot; storage type</h3>
-</div>
-
-<div ng-show="Backend == null">
- <h3 translate>Chose a storage type to get started</h3>
-</div>
-
-<div class="input textarea" ng-show="ShowAdvancedTextArea">
- <label for="targetOptions" translate>Options</label>
- <a href ng-click="ShowAdvancedTextArea = false" class="advanced-toggle" translate>Edit as list</a>
- <textarea id="targetOptions" name="targetOptions" string-array-as-text placeholder="{{AppUtils.format(AppUtils.exampleOptionString, '--use-ssl=true')}}" ng-model="AdvancedOptions"></textarea>
-</div>
-
-<div class="input" ng-hide="ShowAdvancedTextArea">
- <label for="backupOptions" translate>Options</label>
- <a href ng-click="ShowAdvancedTextArea = true" class="advanced-toggle" translate>Edit as text</a>
- <advanced-options-editor ng-option-list="AdvanceOptionList" ng-model="AdvancedOptions"></advanced-options-editor>
-</div>
-
-<div class="buttons" ng-hide="Testing">
- <a href ng-click="save()" class="save" translate>OK</a>
- <a href ng-click="testConnection()" class="test-connection" translate>Test connection</a>
- <a href ng-click="hide()" class="warning cancel" translate>Cancel</a>
-</div>
-
-<div class="button testmessage" ng-show="Testing">
- <h3 translate>Testing ...</h3>
+<div>
+ <div class="input select">
+ <label for="type" translate>Storage Type</label>
+ <select name="type" id="type" ng-model="Backend" ng-options="backend.DisplayName group by backend.GroupType for backend in SystemInfo.GroupedBackendModules | orderBy: ['OrderKey', 'GroupType', 'DisplayName'] track by backend.Key">
+ </select>
+ </div>
+
+ <div ng-include="TemplateUrl">
+ </div>
+
+ <div ng-show="TemplateUrl == null &amp;&amp; Backend != null">
+ <h3 translate translate-params-backend="Backend.DisplayName">No editor found for the &quot;{{backend}}&quot; storage type</h3>
+ </div>
+
+ <div ng-show="Backend == null">
+ <h3 translate>Chose a storage type to get started</h3>
+ </div>
+</div>
+
+<div class="buttons">
+ <a href ng-hide="Testing" class="test-connection" ng-click="testConnection()" translate>Test connection</a>
+ <a href ng-show="Testing" class="test-connection" translate>Testing ...</a>
+</div>
+
+<div class="input textarea">
+ <div class="headerthreedotmenu">
+ <a href ng-click="showAdvanced = !showAdvanced" class="expandable">
+ <h2 translate>Advanced options</h2>
+ <img ng-show="showAdvanced" src="img/arrow_collapse_green.png">
+ <img ng-hide="showAdvanced" src="img/arrow_expand_green.png">
+ </a>
+
+ <div class="contextmenu_container" ng-show="showAdvanced">
+ <a href title="{{'Menu' | translate}}"><img src="img/three_dots.png" id="threedotmenubutton_add_destination_adv" class="threedotmenubutton" title="{{'Menu' | translate}}"/></a>
+
+ <div class="contextmenu" id="threedotmenu_add_destination_adv">
+ <ul>
+ <li>
+ <a href ng-show="ShowAdvancedTextArea" ng-click="ShowAdvancedTextArea = false" translate>Edit as list</a>
+ </li>
+ <li>
+ <a href ng-hide="ShowAdvancedTextArea" ng-click="ShowAdvancedTextArea = true" translate>Edit as text</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div ng-show="showAdvanced">
+ <div ng-show="ShowAdvancedTextArea">
+ <label for="targetOptions" translate>Options</label>
+ <textarea id="targetOptions" name="targetOptions" string-array-as-text placeholder="{{AppUtils.format(AppUtils.exampleOptionString, '--use-ssl=true')}}" ng-model="AdvancedOptions"></textarea>
+ </div>
+
+ <advanced-options-editor ng-hide="ShowAdvancedTextArea" ng-option-list="AdvanceOptionList" ng-model="AdvancedOptions"></advanced-options-editor>
+ </div>
</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/export.html b/Duplicati/Server/webroot/ngax/templates/export.html
index 83f5d37d4..d9caf839b 100644
--- a/Duplicati/Server/webroot/ngax/templates/export.html
+++ b/Duplicati/Server/webroot/ngax/templates/export.html
@@ -38,10 +38,7 @@
</div>
<div ng-show="DownloadURL != null">
- <div translate>If the backup file was not downloaded automatically,</div>
- <div>
- <a href="{{DownloadURL}}" target="_blank" translate>right click and choose &quot;Save as ...&quot;</a>
- </div>
+ <div translate>If the backup file was not downloaded automatically, <a href="{{DownloadURL}}" target="_blank">right click and choose &quot;Save as ...&quot;</a></div>
</div>
<div class="buttons">
diff --git a/Duplicati/Server/webroot/ngax/templates/home.html b/Duplicati/Server/webroot/ngax/templates/home.html
index 60ba81db0..2875e76e9 100644
--- a/Duplicati/Server/webroot/ngax/templates/home.html
+++ b/Duplicati/Server/webroot/ngax/templates/home.html
@@ -1,47 +1,13 @@
<div class="home">
- <div class="state" ng-controller="StateController">
-
- <div ng-hide="state.programState == 'Running'">
- <strong style="margin-right: 0px;" translate>Backups are currently paused,</strong>
- <div style="display: inline" ng-show="state.pauseTimeRemain > 0">{{'resuming in' | translate}} {{state.pauseTimeRemain | timeremaining}}</div>
- <a href ng-click="sendResume()" translate>click to resume now</a>
- </div>
-
- <div ng-hide="activeBackup == null">
- <strong>{{'Running task:' | translate}} </strong>
- {{activeBackup.Backup.Name}}
-
- <a class="button" ng-click="stopTask()" ng-show="StopReqId == state.activeTask.Item1" translate>Force stop</a>
- <a class="button" ng-click="stopTask()" ng-hide="StopReqId == state.activeTask.Item1" translate>Stop</a>
-
- <progress-bar ng-text="StateText" ng-progress="Progress"></progress-bar>
-
- </div>
-
- <div ng-show="activeBackup == null &amp;&amp; state.activeTask != null">
- <strong translate>Running task</strong>
-
- <a class="button" ng-click="stopTask()" ng-show="StopReqId == state.activeTask.Item1" translate>Force stop</a>
- <a class="button" ng-click="stopTask()" ng-hide="StopReqId == state.activeTask.Item1" translate>Stop</a>
- </div>
-
- <div ng-show="state.activeTask == null &amp;&amp; nextTask != null">
- <strong>{{'Next task:' | translate}} </strong>
- {{nextTask.Backup.Name}}
- </div>
-
- <div ng-show="state.activeTask == null &amp;&amp; nextTask == null &amp;&amp; nextScheduledTask != null"><strong translate>Next scheduled task:</strong> {{nextScheduledTask.Backup.Name}} <span title="{{nextScheduledTime | parsetimestamp}}">{{nextScheduledTime | moment: 'calendar'}}</span></div>
-
- <div ng-show="state.activeTask == null &amp;&amp; nextTask == null &amp;&amp; nextScheduledTask == null" translate>No scheduled tasks, you can manually start a task</div>
-
- </div>
-
<div class="tasks" ng-controller="HomeController">
<div class="tasklist">
<div ng-repeat="item in backups" class="task">
- <a href ng-click="$parent.ContextMenuID == item.Backup.ID ? $parent.ContextMenuID = null : $parent.ContextMenuID = item.Backup.ID">{{item.Backup.Name}}</a>
+ <a href ng-click="$parent.TaskMenuID == item.Backup.ID ? $parent.TaskMenuID = null : $parent.TaskMenuID = item.Backup.ID">{{item.Backup.Name}}
+ <img ng-show="$parent.TaskMenuID == item.Backup.ID" src="img/arrow_collapse_blue.png">
+ <img ng-show="$parent.TaskMenuID != item.Backup.ID" src="img/arrow_expand_blue.png">
+ </a>
- <dl class="contextmenu" ng-show="$parent.ContextMenuID == item.Backup.ID">
+ <dl class="taskmenu" ng-show="$parent.TaskMenuID == item.Backup.ID">
<dt translate>Operations:</dt>
<dd>
<p ng-click="doRun(item.Backup.ID)" translate>Run now</p>
@@ -52,15 +18,16 @@
<dd>
<p ng-click="doEdit(item.Backup.ID)" translate>Edit ...</p>
<p ng-click="doExport(item.Backup.ID)" translate>Export ...</p>
- <p ng-click="doDelete(item.Backup.ID, item.Backup.Name)" translate>Delete</p>
+ <p ng-click="doDelete(item.Backup.ID, item.Backup.Name)" translate>Delete ...</p>
</dd>
<dt translate>Advanced:</dt>
<dd>
- <p ng-click="doLocalDb(item.Backup.ID)" translate>Manage database ...</p>
+ <p ng-click="doLocalDb(item.Backup.ID)" translate>Database ...</p>
<p ng-click="doVerifyRemote(item.Backup.ID)" translate>Verify files</p>
<p ng-click="doCompact(item.Backup.ID)" translate>Compact now</p>
+ <p ng-click="doCommandLine(item.Backup.ID)" translate>Commandline ...</p>
</dd>
<dt translate>Reporting:</dt>
@@ -72,9 +39,12 @@
<dl>
<dt translate>Last successful run:</dt>
- <dd ng-hide="item.Backup.Metadata == null || item.Backup.Metadata.LastBackupFinished == null" title="{{item.Backup.Metadata.LastBackupFinished | parsetimestamp }}" translate translate translate-params-time="item.Backup.Metadata.LastBackupFinished | moment: 'calendar'" translate-params-duration="formatDuration(item.Backup.Metadata.LastDuration)">{{time}} (took {{duration}})</dd>
- <dd ng-show="item.Backup.Metadata == null || item.Backup.Metadata.LastBackupFinished == null">
- {{'Never' | translate}} - <a href class="action-link" ng-click="doRun(item.Backup.ID)" translate>Run now</a>
+ <dd ng-hide="item.Backup.Metadata == null || item.Backup.Metadata.LastBackupFinished == null"
+ title="{{item.Backup.Metadata.LastBackupFinished | parsetimestamp }}"
+ translate translate-params-time="item.Backup.Metadata.LastBackupFinished | moment: 'calendar'"
+ translate-params-duration="formatDuration(item.Backup.Metadata.LastDuration)">{{time}} (took {{duration}})</dd>
+ <dd>
+ <span ng-show="item.Backup.Metadata == null || item.Backup.Metadata.LastBackupFinished == null">{{'Never' | translate}} - </span><a href class="action-link" ng-click="doRun(item.Backup.ID)" translate>Run now</a>
</dd>
<div ng-hide="item.Backup.Metadata == null || item.Backup.Metadata.NextScheduledRun == null">
@@ -88,7 +58,7 @@
</div>
<div ng-hide="item.Backup.Metadata.TargetSizeString == null">
<dt translate>Backup:</dt>
- <dd>{{item.Backup.Metadata.TargetSizeString}}</dd>
+ <dd translate translate-n="parseInt(item.Backup.Metadata.BackupListCount)" translate-plural="{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versions">{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version</dd>
</div>
</div>
</dl>
diff --git a/Duplicati/Server/webroot/ngax/templates/import.html b/Duplicati/Server/webroot/ngax/templates/import.html
index db8bbeba4..f95a4613c 100644
--- a/Duplicati/Server/webroot/ngax/templates/import.html
+++ b/Duplicati/Server/webroot/ngax/templates/import.html
@@ -1,5 +1,8 @@
<div ng-controller="ImportController" class="importpage">
- <h1 translate>Import backup configuration</h1>
+
+ <h1 ng-hide="restoremode" translate>Import backup configuration</h1>
+ <h1 ng-show="restoremode" translate>Restore from backup configuration</h1>
+
<form enctype="multipart/form-data" id="import-form" class="styled" method="POST" action="{{ImportURL}}" target="submit-target">
<div class="input text">
@@ -7,15 +10,19 @@
<input type="file" name="config" id="file" />
</div>
- <div class="input text">
+ <div class="input text">
<label for="passphrase" translate>Passphrase (if encrypted)</label>
- <input type="password" name="passphrase" id="passphrase" placeholder="{{'Enter encryption passphrase' | translate}}" >
+ <input type="password" name="passphrase" id="passphrase" placeholder="{{'Enter encryption passphrase' | translate}}" />
+ </div>
+
+ <div class="input checkbox" ng-hide="restoremode">
+ <label for="direct" translate>Save immediately</label>
+ <input type="checkbox" name="direct" id="direct" value="true" />
</div>
- <input type="hidden" name="callback" value="{{CallbackMethod}}">
+ <input type="hidden" name="callback" value="{{CallbackMethod}}" />
<div class="buttons" ng-hide="Connecting">
- <a href="#" class="submit" translate>Cancel</a>
<a href ng-click="doSubmit()" translate>Import</a>
</div>
@@ -26,4 +33,4 @@
<iframe style="display:none" id="submit-target" name="submit-target"></iframe>
-<div>
+</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/log.html b/Duplicati/Server/webroot/ngax/templates/log.html
index a0e772c61..6b3d13bd1 100644
--- a/Duplicati/Server/webroot/ngax/templates/log.html
+++ b/Duplicati/Server/webroot/ngax/templates/log.html
@@ -1,6 +1,7 @@
<div ng-controller="LogController" class="logpage">
- <h1 translate>Log data</h1>
+ <h1 ng-show="BackupID == null" translate>Log data from the server</h1>
+ <h1 ng-show="BackupID != null" translate>Log data for <b>{{Backup.Backup.Name}}</b></h1>
<ul class="tabs">
<li ng-show="BackupID == null" ng-class="{active: Page=='stored'}"><a href ng-click="Page='stored'" translate>Stored</a></li>
diff --git a/Duplicati/Server/webroot/ngax/templates/notificationarea.html b/Duplicati/Server/webroot/ngax/templates/notificationarea.html
index ca9841623..1bcfdb3b1 100644
--- a/Duplicati/Server/webroot/ngax/templates/notificationarea.html
+++ b/Duplicati/Server/webroot/ngax/templates/notificationarea.html
@@ -4,10 +4,7 @@
<div class="content">
<div ng-if="item.Action != 'update:new'" class="message">{{item.Message}}</div>
<div ng-show="item.DownloadLink != null">
- <div translate>If the backup file was not downloaded automatically,</div>
- <div>
- <a href="{{item.DownloadLink}}" target="_blank" translate>right click and choose &quot;Save as ...&quot;</a>
- </div>
+ <div translate>If the backup file was not downloaded automatically, <a href="{{item.DownloadLink}}" target="_blank">right click and choose &quot;Save as ...&quot;</a></div>
</div>
<div ng-if="item.Action != 'update:new'" class="buttons">
<a href ng-click="doDismiss(item.ID)" class="button dismiss" translate>Dismiss</a>
@@ -15,6 +12,7 @@
<a href ng-show="item.Action == 'backup:show-log'" ng-click="doShowLog(item.BackupID)" class="button showlog" translate>Show</a>
<a href ng-show="item.Action.indexOf('bug-report:created:') == 0 &amp;&amp; item.DownloadLink == null" ng-click="doDownloadBugreport(item)" class="button downloadbugreport" translate>Download</a>
+ <div class="clear"></div>
</div>
@@ -30,6 +28,7 @@
<a href ng-show="state.updaterState == 'Downloading'" class="button" ng-disabled="true" ng-click="" translate>Downloading ...</a>
<a href ng-show="state.updaterState == 'Checking'" class="button" ng-disabled="true" ng-click="" translate>Verifying ...</a>
<a href ng-click="doShowUpdate()" class="button showupdate" translate>Show</a>
+ <div class="clear"></div>
</div>
</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/pause.html b/Duplicati/Server/webroot/ngax/templates/pause.html
index fff9a93b6..c709054dc 100644
--- a/Duplicati/Server/webroot/ngax/templates/pause.html
+++ b/Duplicati/Server/webroot/ngax/templates/pause.html
@@ -1,31 +1,36 @@
-<div class="pause" ng-controller="PauseController">
- <h1 translate>Pause controls</h1>
-
+<div ng-controller="PauseController" class="pauseoptions">
<form class="styled">
+ <ul>
+ <li class="input" ng-click="selection.time = '5m'">
+ <input type="radio" name="fivemin" id="fivemin" ng-model="selection.time" value="5m">
+ <label for="fivemin" class="pause-5" translate translate-params-number="5">{{number}} Minutes</label>
+ </li>
- <ul>
- <li ng-show="state.programState != 'Running'">
- <a href ng-click="resume()" class="resume" translate>Resume now</a>
- </li>
+ <li class="input" ng-click="selection.time = '10m'">
+ <input type="radio" name="tenmin" id="tenmin" ng-model="selection.time" value="10m">
+ <label for="tenmin" class="pause-10" translate translate-params-number="10">{{number}} Minutes</label>
+ </li>
- <li>
- <a href ng-click="pause('5m')" class="pause-5" translate translate-params-number="5">{{number}} Minutes</a>
- </li>
- <li>
- <a href ng-click="pause('10m')" class="pause-10" translate translate-params-number="10">{{number}} Minutes</a>
- </li>
- <li>
- <a href ng-click="pause('15m')" class="pause-15" translate translate-params-number="15">{{number}} Minutes</a>
- </li>
- <li>
- <a href ng-click="pause('30m')" class="pause-30" translate translate-params-number="30">{{number}} Minutes</a>
- </li>
- <li>
- <a href ng-click="pause('1h')" class="pause-60" translate translate-params-number="1">{{number}} Hour</a>
- </li>
- <li>
- <a href ng-click="pause()" class="pause-x" translate>Until resumed</a>
- </li>
- </ul>
- </form>
-</div>
+ <li class="input" ng-click="selection.time = '15m'">
+ <input type="radio" name="fifteenmin" id="fifteenmin" ng-model="selection.time" value="15m">
+ <label for="fifteenmin" class="pause-15" translate translate-params-number="15">{{number}} Minutes</label>
+ </li>
+
+ <li class="input" ng-click="selection.time = '30m'">
+ <input type="radio" name="thirtymin" id="thirtymin" ng-model="selection.time" value="30m">
+ <label for="thirtymin" class="pause-30" translate translate-params-number="30">{{number}} Minutes</label>
+ </li>
+
+ <li class="input" ng-click="selection.time = '1h'">
+ <input type="radio" name="onehour" id="onehour" ng-model="selection.time" value="1h">
+ <label for="onehour" class="pause-60" translate translate-params-number="1">{{number}} Hour</label>
+ </li>
+
+ <li class="input" ng-click="selection.time = 'infinite'">
+ <input type="radio" name="infinite" id="infinite" ng-model="selection.time" value="infinite">
+ <label for="infinite" class="pause-x" translate>Until resumed</label>
+ </li>
+ </ul>
+ </form>
+
+</div> \ No newline at end of file
diff --git a/Duplicati/Server/webroot/ngax/templates/restore.html b/Duplicati/Server/webroot/ngax/templates/restore.html
index 69351118f..44e23e7dd 100644
--- a/Duplicati/Server/webroot/ngax/templates/restore.html
+++ b/Duplicati/Server/webroot/ngax/templates/restore.html
@@ -1,10 +1,49 @@
<script>$(function() { $( ".resizable" ).resizable(); });</script>
-<div class="restore" ng-controller="RestoreController">
+<div class="restore" ng-class="{'restore-direct': IsBackupTemporary}" ng-controller="RestoreController">
+
+ <div class="steps" ng-show="IsBackupTemporary &amp;&amp; restore_step &lt; 2">
+ <div class="step step1 not-clickable">
+ <span>1</span>
+ </div>
+ <div class="step step2 not-clickable">
+ <span>2</span>
+ </div>
+ <div class="step step3" ng-class="{active: restore_step == 0}" ng-click="trySetStep(0)">
+ <span>3</span>
+ </div>
+ <div class="step step4" ng-class="{active: restore_step == 1}" ng-click="trySetStep(1)">
+ <span>4</span>
+ </div>
+ </div>
+
+ <ol class="steps-legend" ng-show="IsBackupTemporary &amp;&amp; restore_step &lt; 2">
+ <li class="step1 not-clickable" translate>Backup location</li>
+ <li class="step2 not-clickable" translate>Encryption</li>
+ <li ng-class="{active: restore_step == 0}" class="step3" ng-click="trySetStep(0)" translate>Select files</li>
+ <li ng-class="{active: restore_step == 1}" class="step4" ng-click="trySetStep(1)" translate>Restore options</li>
+ </ol>
+
+
+ <div class="steps" ng-hide="IsBackupTemporary || restore_step &gt; 1">
+ <div class="step step1" ng-class="{active: restore_step == 0}" ng-click="trySetStep(0)">
+ <span>1</span>
+ </div>
+ <div class="step step2" ng-class="{active: restore_step == 1}" ng-click="trySetStep(1)">
+ <span>2</span>
+ </div>
+ </div>
+
+ <ol class="steps-legend" ng-hide="IsBackupTemporary || restore_step &gt; 1">
+ <li ng-class="{active: restore_step == 0}" class="step1" ng-click="trySetStep(0)" translate>Select files</li>
+ <li ng-class="{active: restore_step == 1}" class="step2" ng-click="trySetStep(1)" translate>Restore options</li>
+ </ol>
+
<form id="restore" class="styled">
<div ng-show="restore_step == 0 &amp;&amp; connecting == false">
- <h1 translate>Restore files</h1>
+ <h1 ng-show="IsBackupTemporary" translate>Restore files</h1>
+ <h1 ng-hide="IsBackupTemporary" translate translate-params-backupname="Backup.Backup.Name">Restore files from {{backupname}}</h1>
<div class="input timestamp">
<label for="restoreversion" translate>Restore from</label>
@@ -95,7 +134,7 @@
</div>
- <div ng-show="restore_step == 2 &amp;&amp; connecting == false">
+ <div ng-show="restore_step == 3 &amp;&amp; connecting == false">
<h3>
<div class="hint-text" translate>Your files and folders have been restored successfully.</div>
<div ng-hide="SystemInfo.SuppressDonationMessages">
diff --git a/Duplicati/Server/webroot/ngax/templates/restoredirect.html b/Duplicati/Server/webroot/ngax/templates/restoredirect.html
index 92b3cd4a3..281853de2 100644
--- a/Duplicati/Server/webroot/ngax/templates/restoredirect.html
+++ b/Duplicati/Server/webroot/ngax/templates/restoredirect.html
@@ -1,31 +1,92 @@
-<div class="restore" ng-controller="RestoreDirectController">
+<div class="restore restore-direct" ng-controller="RestoreDirectController">
<form id="restore" class="styled">
-
<div ng-show="!connecting">
- <backup-edit-uri uri="TargetURL" hide="HideEditUri" ng-show="EditUriState"></backup-edit-uri>
-
- <div ng-hide="EditUriState">
- <h1 translate>Restore files</h1>
- <div class="input textarea linklabel">
- <label for="target"><a href class="target" ng-click="EditUriState = true" translate>Connect to &gt;</a></label>
- <textarea name="target" id="target" ng-model="TargetURL" placeholder="{{'Enter a url, or click the &quot;Connect to &gt;&quot; link' | translate}}"></textarea>
+ <div class="steps">
+ <div class="step step1" ng-class="{active: CurrentStep == 0}" ng-click="CurrentStep = 0">
+ <span>1</span>
</div>
- <div class="input password">
- <label for="password" translate>Passphrase</label>
- <input type="password" id="password" name="password" ng-model="EncryptionPassphrase" placeholder="{{'Enter backup passphrase, if any' | translate}}" />
+ <div class="step step2" ng-class="{active: CurrentStep == 1}" ng-click="CurrentStep = 1">
+ <span>2</span>
</div>
- <div class="input textarea">
- <label for="options">{{'Advanced Options' | translate}}<span class="info">i</span></label>
- <textarea id="options" name="options" ng-model="ExtendedOptions" placeholder="{{AppUtils.format(AppUtils.exampleOptionString, '--backup-prefix')}}"></textarea>
+ <div class="step step3 not-clickable">
+ <span>3</span>
</div>
- <div class="buttons" ng-hide="connecting">
- <a href="#" class="submit" translate>Cancel</a>
- <a href ng-click="doConnect()" translate>Connect</a>
+ <div class="step step4 not-clickable">
+ <span>4</span>
+ </div>
+ </div>
+ <!-- .steps -->
+
+ <ol class="steps-legend">
+ <li ng-class="{active: CurrentStep == 0}" class="step1" ng-click="CurrentStep = 0" translate>Backup location</li>
+ <li ng-class="{active: CurrentStep == 1}" class="step2" ng-click="CurrentStep = 1" translate>Encryption</li>
+ <li class="step3 not-clickable" translate>Select files</li>
+ <li class="step4 not-clickable" translate>Restore options</li>
+ </ol>
+ <!-- .steps-legend -->
+
+ <div class="steps-boxes">
+ <div class="step step1" ng-class="{active: CurrentStep == 0}">
+ <div class="headerthreedotmenu">
+ <h2 translate>Backup location</h2>
+
+ <div class="contextmenu_container">
+ <a href title="{{'Menu' | translate}}"><img src="img/three_dots.png" id="threedotmenubutton_add_destination" class="threedotmenubutton"/></a>
+
+ <div class="contextmenu" id="threedotmenu_add_destination">
+ <ul>
+ <li>
+ <a href ng-click="importUrl()" translate>Import Destination URL</a>
+ </li>
+ <li>
+ <a href ng-click="copyUrlToClipboard()" translate>Copy Destination URL to Clipboard</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <backup-edit-uri uri="TargetURL" set-builduri-fn="setBuilduriFn(builduriFn)"></backup-edit-uri>
+
+ <div class="buttons">
+ <input class="submit next" type="button" id="nextStep1" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
+ </div>
</div>
- <div ng-show="connecting">
- {{ConnectionProgress}}
+ <!-- .step1 -->
+
+ <div class="step step2" ng-class="{active: CurrentStep == 1}">
+ <h2 translate>Encryption</h2>
+ <div class="input password">
+ <label for="password" translate>Passphrase</label>
+ <input type="password" id="password" name="password" ng-model="EncryptionPassphrase" placeholder="{{'Enter backup passphrase, if any' | translate}}" />
+ </div>
+
+ <div class="expandable">
+ <a href ng-click="showAdvanced = !showAdvanced">
+ <h2 translate>Advanced Options</h2>
+ <img ng-show="showAdvanced" src="img/arrow_collapse_green.png">
+ <img ng-hide="showAdvanced" src="img/arrow_expand_green.png">
+ </a>
+ </div>
+
+ <div ng-show="showAdvanced">
+ <div class="input textarea">
+ <label for="options">{{'Advanced Options' | translate}}<span class="info">i</span></label>
+ <textarea id="options" name="options" ng-model="ExtendedOptions" placeholder="{{AppUtils.format(AppUtils.exampleOptionString, '--prefix')}}"></textarea>
+ </div>
+ </div>
+
+ <div class="buttons" ng-hide="connecting">
+ <input class="submit" type="button" id="connect" ng-click="doConnect()" value="{{'Connect' | translate}}" />
+ <input class="submit prev" type="button" id="prevStep2" ng-click="prevPage()" value="&lt; {{'Previous' | translate}}" />
+ </div>
+ <div ng-show="connecting">
+ {{ConnectionProgress}}
+ </div>
</div>
+ <!-- .step2 -->
</div>
+ <!-- .steps-boxes -->
</div>
<div ng-show="connecting == true &amp;&amp; taskid == null">
diff --git a/Duplicati/Server/webroot/ngax/templates/restorefilepicker.html b/Duplicati/Server/webroot/ngax/templates/restorefilepicker.html
index e46fd5c1c..d23d0466e 100644
--- a/Duplicati/Server/webroot/ngax/templates/restorefilepicker.html
+++ b/Duplicati/Server/webroot/ngax/templates/restorefilepicker.html
@@ -1,12 +1,12 @@
<ul dx-start-with="treedata" class="tree-view">
<li ng-repeat="node in $dxPrior.children" ng-class="{hidden: node.invisible || (node.hidden &amp;&amp; !ngShowHidden)}">
- <div ng-class="{selected: node.selected}">
- <a class="nav" ng-click="toggleExpanded(node)" ng-class="{expanded: node.expanded, leaf: node.leaf}"></a>
- <a class="check" ng-click="toggleCheck(node)" ng-class="{include: node.include == '+', exclude: node.include == '-', partial: node.include == ' ', root: node.root}"></a>
- <a class="type {{node.iconCls}}" ng-class="{invisible: node.hidden, loading: node.loading}"></a>
+ <div ng-class="{selected: node.selected}" alt="{{node.selected ? 'selected' : 'not selected'}}">
+ <a class="nav" ng-click="toggleExpanded(node)" ng-class="{expanded: node.expanded, leaf: node.leaf}" alt="{{node.expanded ? 'expanded' : 'contracted'}}"></a>
+ <a class="check" ng-click="toggleCheck(node)" ng-class="{include: node.include == '+', exclude: node.include == '-', partial: node.include == ' ', root: node.root}" alt="{{node.include == ' ' ? 'partially included' : (node.include == '-' ? 'excluded' : (node.include == '+' ? 'included' : 'not checked'))}}"></a>
+ <a class="type {{node.iconCls}}" alt="{{loading ? 'loading' : node.entrytype}}" ng-class="{invisible: node.hidden, loading: node.loading}"></a>
<span ng-click="toggleSelected(node)" ng-bind-html="node.text | highlight:ngSearchFilter"></span>
</div>
- <ul ng-class="{expanded: node.expanded}" dx-connect="node"/>
+ <ul ng-class="{expanded: node.expanded}" dx-connect="node" alt="{{node.expanded ? 'expanded' : 'contracted'}}"/>
</li>
</ul>
diff --git a/Duplicati/Server/webroot/ngax/templates/restorewizard.html b/Duplicati/Server/webroot/ngax/templates/restorewizard.html
new file mode 100644
index 000000000..e3a7c22a7
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/restorewizard.html
@@ -0,0 +1,33 @@
+<div ng-controller="RestoreWizardController" class="restorewizard">
+
+ <h1><div translate>Where do you want to restore from?</div></h1>
+
+ <form class="styled">
+ <ul>
+ <li class="input" ng-click="selection.backupid = 'direct'">
+ <input type="radio" name="direct" id="direct" ng-model="selection.backupid" value="direct">
+ <label for="direct" translate>Direct restore from backup files ...</label>
+ <div class="subtext" translate>Point to your backup files and restore from there</div>
+ </li>
+
+ <li class="input" ng-click="selection.backupid = 'import'">
+ <input type="radio" name="import" id="import" ng-model="selection.backupid" value="import">
+ <label for="import" translate>Restore from configuration ...</label>
+ <div class="subtext" translate>Load destination from an exported job or a storage provider</div>
+ </li>
+
+ <li class="input" ng-repeat="item in backups" ng-click="selection.backupid = item.Backup.ID" >
+ <input type="radio" name="direct" id="backup-{{item.Backup.ID}}" ng-model="selection.backupid" value="{{item.Backup.ID}}">
+ <label for="backup-{{item.Backup.ID}}">{{item.Backup.Name}}</label>
+
+ <div ng-hide="item.Backup.Metadata == null || item.Backup.Metadata.TargetSizeString == null" class="subtext" translate translate-n="parseInt(item.Backup.Metadata.BackupListCount)" translate-plural="{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Versions">{{item.Backup.Metadata.TargetSizeString}} / {{$count}} Version</div>
+
+ <div ng-show="item.Backup.Metadata == null || item.Backup.Metadata.TargetSizeString == null" class="subtext" translate>Unknown backup size and versions</div>
+ </li>
+ </ul>
+
+ <div class="buttons">
+ <input class="submit next" type="button" ng-click="nextPage()" value="{{'Next' | translate}} &gt;" />
+ </div>
+ </form>
+</div>
diff --git a/Duplicati/Server/webroot/ngax/templates/settings.html b/Duplicati/Server/webroot/ngax/templates/settings.html
index 93339ca05..d363e3b82 100644
--- a/Duplicati/Server/webroot/ngax/templates/settings.html
+++ b/Duplicati/Server/webroot/ngax/templates/settings.html
@@ -17,6 +17,7 @@
<div class="input mixed multiple">
<label for="pauseTime" translate>Pause</label>
<select id="pauseTime" name="pauseTime" ng-model="startupDelayDurationValue">
+ <option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
@@ -34,7 +35,7 @@
</select>
</div>
- <h2 translate>User interface language</h2>
+ <h2 translate>User interface settings</h2>
<div class="input mixed multiple">
<label for="userinterfacelanguage" translate>Language in user interface</label>
@@ -45,6 +46,14 @@
</select>
</div>
+ <div class="input mixed multiple">
+ <label for="themedisplay" translate>Display and color theme</label>
+
+ <select id="themedisplay" ng-model="theme">
+ <option value="default" translate>The default blue on white theme (by Alex)</option>
+ <option value="dark" translate>The dark theme (by Michal)</option>
+ </select>
+ </div>
<h2 translate>Donation messages</h2>
<div class="input checkbox">
@@ -90,10 +99,11 @@
</div>
-->
- <h2 translate>Usage statistics</h2>
- <div class="input mixed multiple">
+ <h2 ng-if="SystemInfo.DefaultUsageReportLevel != 'Disabled'" translate>Usage statistics</h2>
+ <div ng-if="SystemInfo.DefaultUsageReportLevel != 'Disabled'" class="input mixed multiple">
<label for="usagereporterlevel" translate>Anonymous usage reports</label>
- <select id="usagereporterlevel" ng-model="usageReporterLevel">
+
+ <select id="usagereporterlevel" ng-model="$parent.usageReporterLevel">
<option value="" translate translate-params-levelname="SystemInfo.DefaultUsageReportLevel">System default ({{levelname}})</option>
<option value="information" translate>Usage statistics, warnings, errors, and crashes</option>
<option value="warning" translate>Warnings, errors and crashes</option>
@@ -106,8 +116,20 @@
<p translate>All usage reports are sent anonymously and do not contain any personal information. They contain information about hardware and operating system, the type of backend, backup duration, overall size of source data and similar data. They do not contain paths, filenames, usernames, passwords or similar sensitive information.</p></div>
</div>
+ <div ng-repeat="module in ServerModules">
+ <h2>{{module.DisplayName}}</h2>
+
+ <p ng-show="(module.ServiceLink || '').length > 0"><a href="{{module.ServiceLink}}" target="_blank">{{module.Description}}</a></p>
+ <p ng-show="(module.ServiceLink || '').length == 0">{{module.Description}}</p>
+
+ <div class="input" ng-repeat="opt in module.SupportedGlobalCommands">
+ <label for="{{module.Key}}-{{opt.Name}}" title="{{opt.LongDescription}}">{{opt.ShortDescription}}</label>
+ <input type="text" title="{{opt.LongDescription}}" name="{{module.Key}}-{{opt.Name}}" id="{{module.Key}}-{{opt.Name}}" ng-model="servermodulesettings[opt.Name]" />
+ </div>
+ </div>
<h2 translate>Default options</h2>
+ <div class="sublabel"><p translate>Options added here are applied to all backups, but can be overridden in each individual backup</p></div>
<div class="input textarea" ng-show="ShowAdvancedTextArea">
<label for="backupOptions" translate>Options</label>
<a href ng-click="ShowAdvancedTextArea = false" class="advanced-toggle" translate>Edit as list</a>
diff --git a/Duplicati/Server/webroot/ngax/templates/sourcefolderpicker.html b/Duplicati/Server/webroot/ngax/templates/sourcefolderpicker.html
index 1220ac2e6..5ea095042 100644
--- a/Duplicati/Server/webroot/ngax/templates/sourcefolderpicker.html
+++ b/Duplicati/Server/webroot/ngax/templates/sourcefolderpicker.html
@@ -1,12 +1,12 @@
<ul dx-start-with="treedata" class="tree-view">
<li ng-repeat="node in $dxPrior.children" ng-class="{hidden: (node.hidden &amp;&amp; !ngShowHidden)}">
- <div ng-class="{selected: node.selected}">
- <a class="nav" ng-click="toggleExpanded(node)" ng-class="{expanded: node.expanded, leaf: node.leaf}"></a>
- <a class="check" ng-click="toggleCheck(node)" ng-class="{include: node.include == '+', exclude: node.include == '-', partial: node.include == ' ', root: node.root}"></a>
- <a class="type {{node.iconCls}}" ng-class="{invisible: node.hidden, loading: node.loading}"></a>
+ <div ng-class="{selected: node.selected}" alt="{{node.selected ? 'selected' : 'not selected'}}">
+ <a class="nav" ng-click="toggleExpanded(node)" alt="{{node.expanded ? 'expanded' : 'contracted'}}" ng-class="{expanded: node.expanded, leaf: node.leaf}"></a>
+ <a class="check" ng-click="toggleCheck(node)" alt="{{node.include == ' ' ? 'partially included' : (node.include == '-' ? 'excluded' : (node.include == '+' ? 'included' : 'not checked'))}}" ng-class="{include: node.include == '+', exclude: node.include == '-', partial: node.include == ' ', root: node.root}"></a>
+ <a class="type {{node.iconCls}}" alt="{{loading ? 'loading' : node.entrytype}}" ng-class="{invisible: node.hidden, loading: node.loading}"></a>
- <span ng-click="toggleSelected(node)">{{ node.text }}</span>
+ <span ng-click="toggleSelected(node)" title="{{ node.tooltip }}">{{ node.text }}</span>
</div>
- <ul ng-class="{expanded: node.expanded, include: node.include, exclude: node.exclude}" dx-connect="node"/>
+ <ul ng-class="{expanded: node.expanded, include: node.include, exclude: node.exclude}" alt="{{node.include == '+' ? 'included' : (node.include == '-' ? 'excluded' : 'partially included')}}" dx-connect="node"/>
</li>
</ul>
diff --git a/Duplicati/Server/webroot/ngax/templates/targetfolderpicker.html b/Duplicati/Server/webroot/ngax/templates/targetfolderpicker.html
index 4bb2fbba6..eae9bb1ff 100644
--- a/Duplicati/Server/webroot/ngax/templates/targetfolderpicker.html
+++ b/Duplicati/Server/webroot/ngax/templates/targetfolderpicker.html
@@ -1,11 +1,11 @@
<ul dx-start-with="treedata" class="tree-view">
<li ng-repeat="node in $dxPrior.children" ng-class="{hidden: node.invisible || (node.hidden &amp;&amp; !ngShowHidden)}">
- <div ng-class="{selected: node.selected}">
- <a class="nav" ng-click="toggleExpanded(node)" ng-class="{expanded: node.expanded, leaf: node.leaf}"></a>
- <a class="type {{node.iconCls}}" ng-class="{invisible: node.hidden, loading: node.loading}"></a>
+ <div ng-class="{selected: node.selected}" alt="{{node.selected ? 'selected' : 'not selected'}}">
+ <a class="nav" ng-click="toggleExpanded(node)" ng-class="{expanded: node.expanded, leaf: node.leaf}" alt="{{node.expanded ? 'expanded' : 'contracted'}}"></a>
+ <a class="type {{node.iconCls}}" alt="{{loading ? 'loading' : node.entrytype}}" ng-class="{invisible: node.hidden, loading: node.loading}"></a>
<span ng-click="toggleSelected(node)">{{ node.text }}</span>
</div>
- <ul ng-class="{expanded: node.expanded}" dx-connect="node"/>
+ <ul ng-class="{expanded: node.expanded}" alt="{{node.expanded ? 'expanded' : 'contracted'}}" dx-connect="node"/>
</li>
</ul>
diff --git a/Duplicati/Server/webroot/ngax/templates/throttle.html b/Duplicati/Server/webroot/ngax/templates/throttle.html
new file mode 100644
index 000000000..0fd093b14
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/throttle.html
@@ -0,0 +1,27 @@
+<div ng-controller="ThrottleController" class="throttlesettings">
+ <form class="styled">
+ <div class="input mixed multiple" ng-class="selection.uploadthrottleenabled ? '' : 'disabled'">
+ <input type="checkbox" class="checkbox" name="uploadthrottleenabled" ng-model="selection.uploadthrottleenabled">
+ <label ng-click="selection.uploadthrottleenabled = !selection.uploadthrottleenabled" for="uploadspeed" translate>Max upload speed</label>
+
+ <input ng-disabled="!selection.uploadthrottleenabled" type="number" id="uploadspeed" name="uploadspeed" parse-size-number="uppercase" ng-model="selection.uploadspeed" />
+ <select ng-disabled="!selection.uploadthrottleenabled" parse-size-multiplier="uppercase" ng-model="selection.uploadspeed" ng-options="item.value as item.name for item in speedMultipliers">
+ </select>
+ </div>
+
+ <div class="input mixed multiple" ng-class="selection.downloadthrottleenabled ? '' : 'disabled'">
+ <input type="checkbox" class="checkbox" name="downloadthrottleenabled" ng-model="selection.downloadthrottleenabled">
+
+ <label ng-click="selection.downloadthrottleenabled = !selection.downloadthrottleenabled" for="downloadspeed" translate>Max download speed</label>
+
+ <input ng-disabled="!selection.downloadthrottleenabled" type="number" id="downloadspeed" name="downloadspeed" parse-size-number="uppercase" ng-model="selection.downloadspeed" />
+ <select ng-disabled="!selection.downloadthrottleenabled" parse-size-multiplier="uppercase" ng-model="selection.downloadspeed" ng-options="item.value as item.name for item in speedMultipliers">
+ </select>
+ </div>
+
+ <div>
+ Note that speeds are entered in bytes, and line speeds are typically reported in bits. Use a factor of 8 to convert, such that an 8 mbit/s line is equivalent to 1 MByte/s.
+ <div>
+ </form>
+
+</div> \ No newline at end of file
diff --git a/Duplicati/Server/webroot/oem/greeno/scripts/oem.js b/Duplicati/Server/webroot/oem/greeno/scripts/oem.js
deleted file mode 100644
index 2ff600ec0..000000000
--- a/Duplicati/Server/webroot/oem/greeno/scripts/oem.js
+++ /dev/null
@@ -1 +0,0 @@
-/* Placeholder for OEM branding */
diff --git a/Duplicati/Server/webroot/oem/greeno/stylesheets/oem.css b/Duplicati/Server/webroot/oem/greeno/stylesheets/oem.css
deleted file mode 100644
index 2ff600ec0..000000000
--- a/Duplicati/Server/webroot/oem/greeno/stylesheets/oem.css
+++ /dev/null
@@ -1 +0,0 @@
-/* Placeholder for OEM branding */
diff --git a/Duplicati/Server/webroot/theme.html b/Duplicati/Server/webroot/theme.html
index 98a53d542..ebd2c131c 100644
--- a/Duplicati/Server/webroot/theme.html
+++ b/Duplicati/Server/webroot/theme.html
@@ -49,7 +49,7 @@
function updateToCurrentTheme() {
var theme = parseCookies()['default-theme'];
- var themes = ['greeno', 'ngax'];
+ var themes = ['ngax'];
for(var k in themes) {
var el = document.getElementById(themes[k]);
el.className = "button" + (theme == themes[k] ? " disabled" : "");
@@ -78,19 +78,19 @@
<h2>Duplicati theme</h2>
<ul>
<li class="theme-item">
- <h3 class="title">NgAx - The new responsive theme</h3>
+ <h3 class="title">NgAx - The responsive theme</h3>
<div class="buttons">
<div class="button" id="ngax" onclick="setDefault('ngax')">Use as default</div>
<div class="button" onclick="setView('ngax')">View now</div>
</div>
</li>
- <li class="theme-item">
+ <!--<li class="theme-item">
<h3 class="title">Greeno - Your friendly green theme</h3>
<div class="buttons">
<div class="button" id="greeno" onclick="setDefault('greeno')">Use as default</div>
<div class="button" onclick="setView('greeno')">View now</div>
</div>
- </li>
+ </li>-->
</ul>
<script type="text/javascript">updateToCurrentTheme();</script>
diff --git a/Duplicati/Service/Duplicati.Service.csproj b/Duplicati/Service/Duplicati.Service.csproj
index 9f3a85209..20b63ea2d 100644
--- a/Duplicati/Service/Duplicati.Service.csproj
+++ b/Duplicati/Service/Duplicati.Service.csproj
@@ -5,11 +5,13 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E93F3DE2-FF3A-4709-96A3-8190AA14FA25}</ProjectGuid>
<OutputType>Exe</OutputType>
+ <Prefer32Bit>False</Prefer32Bit>
<RootNamespace>Duplicati.Service</RootNamespace>
<AssemblyName>Duplicati.Service</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<SignAssembly>true</SignAssembly>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/Duplicati/Tools/Duplicati.Tools.csproj b/Duplicati/Tools/Duplicati.Tools.csproj
index c97a4506f..efe428109 100644
--- a/Duplicati/Tools/Duplicati.Tools.csproj
+++ b/Duplicati/Tools/Duplicati.Tools.csproj
@@ -8,6 +8,7 @@
<RootNamespace>Duplicati.Tools</RootNamespace>
<AssemblyName>Duplicati.Tools</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -77,9 +78,22 @@
<Link>win-tools\zlib1.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="..\..\thirdparty\mozroots\mozroots.exe">
+ <Link>utility-scripts\mozroots.exe</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\thirdparty\TlsTest\TlsTest.exe">
+ <Link>utility-scripts\TlsTest.exe</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\Tools\Commandline\pause-resume.py">
+ <Link>utility-scripts\pause-resume.py</Link>
+ </None>
+ </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/Duplicati/UnitTest/BasicSetupHelper.cs b/Duplicati/UnitTest/BasicSetupHelper.cs
index eb2128858..ce045a3da 100644
--- a/Duplicati/UnitTest/BasicSetupHelper.cs
+++ b/Duplicati/UnitTest/BasicSetupHelper.cs
@@ -62,7 +62,7 @@ namespace Duplicati.UnitTest
/// </summary>
public static readonly bool DEBUG_OUTPUT =
new[] { "1", "true", "on", "yes" }
- .Contains(Environment.GetEnvironmentVariable("DEBUG_OUTPUT") ?? "", StringComparer.InvariantCultureIgnoreCase);
+ .Contains(Environment.GetEnvironmentVariable("DEBUG_OUTPUT") ?? "", StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Writes a message to TestContext.Progress and Console.Out
diff --git a/Duplicati/UnitTest/BorderTests.cs b/Duplicati/UnitTest/BorderTests.cs
index ac7ed0380..74a5c0e1e 100644
--- a/Duplicati/UnitTest/BorderTests.cs
+++ b/Duplicati/UnitTest/BorderTests.cs
@@ -43,6 +43,16 @@ namespace Duplicati.UnitTest
[Test]
[Category("Border")]
+ public void Run10mb()
+ {
+ PrepareSourceData();
+ RunCommands(1024 * 10, modifyOptions: opts => {
+ opts["blocksize"] = "10mb";
+ });
+ }
+
+ [Test]
+ [Category("Border")]
public void Run100k()
{
PrepareSourceData();
@@ -67,6 +77,17 @@ namespace Duplicati.UnitTest
[Test]
[Category("Border")]
+ public void RunNoMetadata()
+ {
+ PrepareSourceData();
+ RunCommands(1024 * 10, modifyOptions: opts => {
+ opts["skip-metadata"] = "true";
+ });
+ }
+
+
+ [Test]
+ [Category("Border")]
public void RunMD5()
{
PrepareSourceData();
@@ -87,7 +108,7 @@ namespace Duplicati.UnitTest
});
}
- //[Test]
+ [Test]
[Category("Border")]
public void RunMixedBlockFile_1()
{
@@ -98,7 +119,7 @@ namespace Duplicati.UnitTest
});
}
- //[Test]
+ [Test]
[Category("Border")]
public void RunMixedBlockFile_2()
{
@@ -129,14 +150,18 @@ namespace Duplicati.UnitTest
});
}
- private void RunCommands(int blocksize, int basedatasize = 0, Action<Dictionary<string, string>> modifyOptions = null)
+ [Test]
+ [Category("Border")]
+ public void RunQuickTimestamps()
+ {
+ PrepareSourceData();
+ RunCommands(1024 * 10, modifyOptions: opts =>
+ {
+ opts["check-filetime-only"] = "true";
+ });
+ }
+ public static Dictionary<string, int> WriteTestFilesToFolder(string targetfolder, int blocksize, int basedatasize = 0)
{
- var testopts = TestOptions;
- testopts["verbose"] = "true";
- testopts["blocksize"] = blocksize.ToString() + "b";
- if (modifyOptions != null)
- modifyOptions(testopts);
-
if (basedatasize <= 0)
basedatasize = blocksize * 1024;
@@ -163,8 +188,21 @@ namespace Duplicati.UnitTest
var data = new byte[filenames.Select(x => x.Value).Max()];
- foreach(var k in filenames)
- File.WriteAllBytes(Path.Combine(DATAFOLDER, "a" + k.Key), data.Take(k.Value).ToArray());
+ foreach (var k in filenames)
+ File.WriteAllBytes(Path.Combine(targetfolder, "a" + k.Key), data.Take(k.Value).ToArray());
+
+ return filenames;
+ }
+
+ private void RunCommands(int blocksize, int basedatasize = 0, Action<Dictionary<string, string>> modifyOptions = null)
+ {
+ var testopts = TestOptions;
+ testopts["verbose"] = "true";
+ testopts["blocksize"] = blocksize.ToString() + "b";
+ if (modifyOptions != null)
+ modifyOptions(testopts);
+
+ var filenames = WriteTestFilesToFolder(DATAFOLDER, blocksize, basedatasize);
using(var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
c.Backup(new string[] { DATAFOLDER });
@@ -181,6 +219,7 @@ namespace Duplicati.UnitTest
//Console.WriteLine(string.Join(Environment.NewLine, r.Files.Select(x => x.Path)));
}
+ var data = new byte[filenames.Select(x => x.Value).Max()];
new Random().NextBytes(data);
foreach(var k in filenames)
File.WriteAllBytes(Path.Combine(DATAFOLDER, "b" + k.Key), data.Take(k.Value).ToArray());
@@ -261,7 +300,7 @@ namespace Duplicati.UnitTest
Assert.AreEqual(filenames.Count * 3, r.FilesRestored);
}
- TestUtils.VerifyDir(DATAFOLDER, RESTOREFOLDER, true);
+ TestUtils.VerifyDir(DATAFOLDER, RESTOREFOLDER, !Library.Utility.Utility.ParseBoolOption(testopts, "skip-metadata"));
using(var tf = new Library.Utility.TempFolder())
{
diff --git a/Duplicati/UnitTest/CommandLineOperationsTests.cs b/Duplicati/UnitTest/CommandLineOperationsTests.cs
index 51f5935fc..323ff15a5 100644
--- a/Duplicati/UnitTest/CommandLineOperationsTests.cs
+++ b/Duplicati/UnitTest/CommandLineOperationsTests.cs
@@ -42,7 +42,7 @@ namespace Duplicati.UnitTest
}
}
- [TestFixtureSetUp()]
+ [OneTimeSetUp]
public override void PrepareSourceData()
{
base.PrepareSourceData();
@@ -187,8 +187,9 @@ namespace Duplicati.UnitTest
TestUtils.VerifyDir(s, Path.Combine(RESTOREFOLDER, Path.GetFileName(s)), true);
ProgressWriteLine("Testing data ...");
- using(new Library.Logging.Timer("Test remote data"))
- Duplicati.CommandLine.Program.RealMain((new string[] { "test", target, "all" }.Union(opts)).ToArray());
+ using (new Library.Logging.Timer("Test remote data"))
+ if (Duplicati.CommandLine.Program.RealMain((new string[] { "test", target, "all" }.Union(opts)).ToArray()) != 0)
+ throw new Exception("Failed during final remote verification");
}
diff --git a/Duplicati/UnitTest/CompressionTests.cs b/Duplicati/UnitTest/CompressionTests.cs
new file mode 100644
index 000000000..7ed414d9e
--- /dev/null
+++ b/Duplicati/UnitTest/CompressionTests.cs
@@ -0,0 +1,68 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using System.IO;
+using NUnit.Framework;
+
+namespace Duplicati.UnitTest
+{
+ [TestFixture]
+ [Category("Compression")]
+ public class CompressionTests
+ {
+ [Test]
+ public void TestZipCompressionHints()
+ {
+ TestCompressionHints("zip");
+ }
+
+ [Test]
+ public void Test7zCompressionHints()
+ {
+ TestCompressionHints("7z");
+ }
+
+ public void TestCompressionHints(string module)
+ {
+ const int TESTSIZE = 1024 * 1024;
+
+ using (var tf0 = new Library.Utility.TempFile())
+ using (var tf1 = new Library.Utility.TempFile())
+ {
+ var opts = new Dictionary<string, string>();
+ opts["zip-compression-level"] = "9";
+
+ using (var z0 = Library.DynamicLoader.CompressionLoader.GetModule(module, tf0, opts))
+ using (var fs0 = z0.CreateFile("sample", Library.Interface.CompressionHint.Noncompressible, DateTime.Now))
+ fs0.Write(new byte[TESTSIZE], 0, TESTSIZE);
+
+ using (var z1 = Library.DynamicLoader.CompressionLoader.GetModule(module, tf1, opts))
+ using (var fs1 = z1.CreateFile("sample", Library.Interface.CompressionHint.Compressible, DateTime.Now))
+ fs1.Write(new byte[TESTSIZE], 0, TESTSIZE);
+
+
+ if (new FileInfo(tf0).Length < TESTSIZE)
+ throw new Exception("Compression hint non-compressible is not honored");
+
+ if (new FileInfo(tf1).Length > new FileInfo(tf0).Length * 0.25)
+ throw new Exception("Compression is not applied");
+ }
+ }
+
+ }
+}
diff --git a/Duplicati/UnitTest/Duplicati.UnitTest.csproj b/Duplicati/UnitTest/Duplicati.UnitTest.csproj
index 8522c5e41..f698d9ff3 100644
--- a/Duplicati/UnitTest/Duplicati.UnitTest.csproj
+++ b/Duplicati/UnitTest/Duplicati.UnitTest.csproj
@@ -8,6 +8,7 @@
<RootNamespace>Duplicati.UnitTest</RootNamespace>
<AssemblyName>Duplicati.UnitTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -30,7 +31,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="nunit.framework">
- <HintPath>..\..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath>
+ <HintPath>..\..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -44,6 +45,9 @@
<Compile Include="SizeOmittingBackend.cs" />
<Compile Include="BorderTests.cs" />
<Compile Include="Issue1723.cs" />
+ <Compile Include="PurgeTesting.cs" />
+ <Compile Include="CompressionTests.cs" />
+ <Compile Include="UtilityTests.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
diff --git a/Duplicati/UnitTest/PurgeTesting.cs b/Duplicati/UnitTest/PurgeTesting.cs
new file mode 100644
index 000000000..c26cb4601
--- /dev/null
+++ b/Duplicati/UnitTest/PurgeTesting.cs
@@ -0,0 +1,252 @@
+// Copyright (C) 2016, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using NUnit.Framework;
+
+namespace Duplicati.UnitTest
+{
+ [TestFixture]
+ public class PurgeTesting : BasicSetupHelper
+ {
+ public override void PrepareSourceData()
+ {
+ base.PrepareSourceData();
+
+ Directory.CreateDirectory(DATAFOLDER);
+ Directory.CreateDirectory(TARGETFOLDER);
+ }
+
+ [Test]
+ [Category("Purge")]
+ public void PurgeTest()
+ {
+ PrepareSourceData();
+
+ var blocksize = 1024 * 10;
+ var basedatasize = 0;
+
+ var testopts = TestOptions;
+ testopts["verbose"] = "true";
+ testopts["blocksize"] = blocksize.ToString() + "b";
+
+ var filenames = BorderTests.WriteTestFilesToFolder(DATAFOLDER, blocksize, basedatasize).Select(x => "a" + x.Key).ToList();
+
+ var round1 = filenames.Take(filenames.Count / 3).ToArray();
+ var round2 = filenames.Take((filenames.Count / 3) * 2).ToArray();
+ var round3 = filenames;
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var res = c.Backup(new string[] { DATAFOLDER }, new Library.Utility.FilterExpression(round1.Select(x => "*" + Path.DirectorySeparatorChar + x)));
+ Assert.AreEqual(res.AddedFiles, round1.Length);
+ }
+
+ System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var res = c.Backup(new string[] { DATAFOLDER }, new Library.Utility.FilterExpression(round2.Select(x => "*" + Path.DirectorySeparatorChar + x)));
+ Assert.AreEqual(res.AddedFiles, round2.Length - round1.Length);
+ }
+
+ System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var res = c.Backup(new string[] { DATAFOLDER });
+ Assert.AreEqual(res.AddedFiles, filenames.Count - round2.Length);
+ }
+
+ System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
+ var last_ts = DateTime.Now;
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts.Expand(new { list_sets_only = true }), null))
+ {
+ var inf = c.List();
+ var filesets = inf.Filesets.Count();
+ Assert.AreEqual(3, filesets, "Incorrect number of initial filesets");
+ }
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var filecount = c.List("*").Files.Count();
+ Assert.AreEqual(filenames.Count + 1, filecount, "Incorrect number of initial files");
+ }
+
+ var allversion_candidate = round1.First();
+ var single_version_candidate = round1.Skip(1).First();
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var res = c.PurgeFiles(new Library.Utility.FilterExpression("*" + Path.DirectorySeparatorChar + allversion_candidate));
+ Assert.AreEqual(3, res.RewrittenFileLists, "Incorrect number of rewritten filesets after all-versions purge");
+ Assert.AreEqual(3, res.RemovedFileCount, "Incorrect number of removed files after all-versions purge");
+ }
+
+ for (var i = 0; i < 3; i++)
+ {
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts.Expand(new { version = i }), null))
+ {
+ var res = c.PurgeFiles(new Library.Utility.FilterExpression("*" + Path.DirectorySeparatorChar + single_version_candidate));
+ Assert.AreEqual(1, res.RewrittenFileLists, "Incorrect number of rewritten filesets after single-versions purge");
+ Assert.AreEqual(1, res.RemovedFileCount, "Incorrect number of removed files after single-versions purge");
+ }
+ }
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var res = c.PurgeFiles(new Library.Utility.FilterExpression(round2.Skip(round1.Length).Take(2).Select(x => "*" + Path.DirectorySeparatorChar + x)));
+ Assert.AreEqual(2, res.RewrittenFileLists, "Incorrect number of rewritten filesets after 2-versions purge");
+ Assert.AreEqual(4, res.RemovedFileCount, "Incorrect number of removed files after 2-versions purge");
+ }
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var res = c.PurgeFiles(new Library.Utility.FilterExpression(round3.Skip(round2.Length).Take(2).Select(x => "*" + Path.DirectorySeparatorChar + x)));
+ Assert.AreEqual(1, res.RewrittenFileLists, "Incorrect number of rewritten filesets after 1-versions purge");
+ Assert.AreEqual(2, res.RemovedFileCount, "Incorrect number of removed files after 1-versions purge");
+ }
+
+ // Since we make the operations back-to-back, the purge timestamp can drift beyond the current time
+ var wait_target = last_ts.AddSeconds(10) - DateTime.Now;
+ if (wait_target.TotalMilliseconds > 0)
+ System.Threading.Thread.Sleep(wait_target);
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var listinfo = c.List("*");
+ var filecount = listinfo.Files.Count();
+ listinfo = c.List();
+ var filesets = listinfo.Filesets.Count();
+
+ Assert.AreEqual(3, filesets, "Incorrect number of filesets after purge");
+ Assert.AreEqual(filenames.Count - 6 + 1, filecount, "Incorrect number of files after purge");
+ }
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ c.Backup(new string[] { DATAFOLDER });
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var listinfo = c.List("*");
+ var files = listinfo.Files.ToArray();
+ var filecount = files.Length;
+ listinfo = c.List();
+ var filesets = listinfo.Filesets.ToArray();
+
+ Console.WriteLine("Listing final version information");
+
+ Console.WriteLine("Versions:");
+ Console.WriteLine(" " + string.Join(Environment.NewLine + " ", filesets.Select(x => string.Format("{0}: {1}, {2} {3}", x.Version, x.Time, x.FileCount, x.FileSizes))));
+ Console.WriteLine("Files:");
+ Console.WriteLine(" " + string.Join(Environment.NewLine + " ", files.Select(x => string.Format("{0}: {1}", x.Path, string.Join(" - ", x.Sizes.Select(y => y.ToString()))))));
+
+ Assert.AreEqual(4, filesets.Length, "Incorrect number of filesets after final backup");
+ Assert.AreEqual(filenames.Count + 1, filecount, "Incorrect number of files after final backup");
+ }
+ }
+
+ [Test]
+ [Category("Purge")]
+ public void PurgeBrokenFilesTest()
+ {
+ PrepareSourceData();
+
+ var blocksize = 1024 * 10;
+ var basedatasize = 0;
+
+ var testopts = TestOptions;
+ testopts["verbose"] = "true";
+ testopts["blocksize"] = blocksize.ToString() + "b";
+
+ var filenames = BorderTests.WriteTestFilesToFolder(DATAFOLDER, blocksize, basedatasize).Select(x => "a" + x.Key).ToList();
+
+ var round1 = filenames.Take(filenames.Count / 3).ToArray();
+ var round2 = filenames.Take((filenames.Count / 3) * 2).ToArray();
+ var round3 = filenames;
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var res = c.Backup(new string[] { DATAFOLDER }, new Library.Utility.FilterExpression(round1.Select(x => "*" + Path.DirectorySeparatorChar + x)));
+ Assert.AreEqual(res.AddedFiles, round1.Length);
+ }
+
+ var dblock_file = Directory
+ .GetFiles(TARGETFOLDER, "*.dblock.zip.aes")
+ .Select(x => new FileInfo(x))
+ .OrderBy(x => x.LastWriteTimeUtc)
+ .Select(x => x.FullName)
+ .First();
+
+ System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var res = c.Backup(new string[] { DATAFOLDER }, new Library.Utility.FilterExpression(round2.Select(x => "*" + Path.DirectorySeparatorChar + x)));
+ Assert.AreEqual(round2.Length - round1.Length, res.AddedFiles);
+ }
+
+ System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var res = c.Backup(new string[] { DATAFOLDER });
+ Assert.AreEqual(filenames.Count - round2.Length, res.AddedFiles);
+ }
+
+ var last_ts = DateTime.Now;
+
+ File.Delete(dblock_file);
+
+ long[] affectedfiles;
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var brk = c.ListBrokenFiles(null);
+ var sets = brk.BrokenFiles.Count();
+ var files = brk.BrokenFiles.Sum(x => x.Item3.Count());
+ Assert.AreEqual(3, sets);
+ Assert.True(files > 0);
+
+ affectedfiles = brk.BrokenFiles.OrderBy(x => x.Item1).Select(x => x.Item3.LongCount()).ToArray();
+ }
+
+ for (var i = 0; i < 3; i++)
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts.Expand(new { version = i }), null))
+ {
+ var brk = c.ListBrokenFiles(null);
+ var sets = brk.BrokenFiles.Count();
+ var files = brk.BrokenFiles.Sum(x => x.Item3.Count());
+ Assert.AreEqual(1, sets);
+ Assert.AreEqual(affectedfiles[i], files);
+ }
+
+ using (var c = new Library.Main.Controller("file://" + TARGETFOLDER, testopts, null))
+ {
+ var brk = c.PurgeBrokenFiles(null);
+
+ var modFilesets = 0L;
+ if (brk.DeleteResults != null)
+ modFilesets += brk.DeleteResults.DeletedSets.Count();
+ if (brk.PurgeResults != null)
+ modFilesets += brk.PurgeResults.RewrittenFileLists;
+
+ Assert.AreEqual(3, modFilesets);
+ }
+ }
+
+ }
+}
diff --git a/Duplicati/UnitTest/RandomErrorBackend.cs b/Duplicati/UnitTest/RandomErrorBackend.cs
index 6f14115c5..4151a8622 100644
--- a/Duplicati/UnitTest/RandomErrorBackend.cs
+++ b/Duplicati/UnitTest/RandomErrorBackend.cs
@@ -23,6 +23,6 @@ namespace Duplicati.UnitTest
public RandomErrorBackend()
{
} public RandomErrorBackend(string url, Dictionary<string, string> options) { var u = new Library.Utility.Uri(url).SetScheme(WrappedBackend).ToString(); m_backend = (IStreamingBackend)Library.DynamicLoader.BackendLoader.GetBackend(u, options); } private void ThrowErrorRandom() { if (random.NextDouble() > 0.90) throw new Exception("Random upload failure"); }
- #region IStreamingBackend implementation public void Put(string remotename, Stream stream) { var uploadError = random.NextDouble() > 0.9; using(var f = new Library.Utility.ProgressReportingStream(stream, stream.Length, x => { if (uploadError && stream.Position > stream.Length / 2) throw new Exception("Random upload failure"); })) m_backend.Put(remotename, f); ThrowErrorRandom(); } public void Get(string remotename, Stream stream) { ThrowErrorRandom(); m_backend.Get(remotename, stream); ThrowErrorRandom(); } #endregion #region IBackend implementation public List<IFileEntry> List() { return m_backend.List(); } public void Put(string remotename, string filename) { ThrowErrorRandom(); m_backend.Put(remotename, filename); ThrowErrorRandom(); } public void Get(string remotename, string filename) { ThrowErrorRandom(); m_backend.Get(remotename, filename); ThrowErrorRandom(); } public void Delete(string remotename) { ThrowErrorRandom(); m_backend.Delete(remotename); ThrowErrorRandom(); } public void Test() { m_backend.Test(); } public void CreateFolder() { m_backend.CreateFolder(); } public string DisplayName { get { return "Random Error Backend"; } } public string ProtocolKey { get { return "randomerror"; } } public IList<ICommandLineArgument> SupportedCommands { get { if (m_backend == null) try { return Duplicati.Library.DynamicLoader.BackendLoader.GetSupportedCommands(WrappedBackend + "://"); } catch { } return m_backend.SupportedCommands; } } public string Description { get { return "A testing backend that randomly fails"; } } #endregion #region IDisposable implementation public void Dispose() { if (m_backend != null) try { m_backend.Dispose(); } finally { m_backend = null; } } #endregion }
+ #region IStreamingBackend implementation public void Put(string remotename, Stream stream) { var uploadError = random.NextDouble() > 0.9; using(var f = new Library.Utility.ProgressReportingStream(stream, stream.Length, x => { if (uploadError && stream.Position > stream.Length / 2) throw new Exception("Random upload failure"); })) m_backend.Put(remotename, f); ThrowErrorRandom(); } public void Get(string remotename, Stream stream) { ThrowErrorRandom(); m_backend.Get(remotename, stream); ThrowErrorRandom(); } #endregion #region IBackend implementation public IEnumerable<IFileEntry> List() { return m_backend.List(); } public void Put(string remotename, string filename) { ThrowErrorRandom(); m_backend.Put(remotename, filename); ThrowErrorRandom(); } public void Get(string remotename, string filename) { ThrowErrorRandom(); m_backend.Get(remotename, filename); ThrowErrorRandom(); } public void Delete(string remotename) { ThrowErrorRandom(); m_backend.Delete(remotename); ThrowErrorRandom(); } public void Test() { m_backend.Test(); } public void CreateFolder() { m_backend.CreateFolder(); } public string DisplayName { get { return "Random Error Backend"; } } public string ProtocolKey { get { return "randomerror"; } } public IList<ICommandLineArgument> SupportedCommands { get { if (m_backend == null) try { return Duplicati.Library.DynamicLoader.BackendLoader.GetSupportedCommands(WrappedBackend + "://"); } catch { } return m_backend.SupportedCommands; } } public string Description { get { return "A testing backend that randomly fails"; } } #endregion #region IDisposable implementation public void Dispose() { if (m_backend != null) try { m_backend.Dispose(); } finally { m_backend = null; } } #endregion }
}
diff --git a/Duplicati/UnitTest/SVNCheckoutsTest.cs b/Duplicati/UnitTest/SVNCheckoutsTest.cs
index 2cc3682d4..74107abf4 100644
--- a/Duplicati/UnitTest/SVNCheckoutsTest.cs
+++ b/Duplicati/UnitTest/SVNCheckoutsTest.cs
@@ -74,32 +74,8 @@ namespace Duplicati.UnitTest
/// <param name="target">The target destination for the backups</param>
public static void RunTest(string[] folders, Dictionary<string, string> options, string target)
{
- var oldlog = Log.CurrentLog as IDisposable;
- Log.CurrentLog = null;
- if (oldlog != null)
- try { oldlog.Dispose(); }
- catch { }
-
- LogHelper log = new LogHelper(string.Format("unittest-{0}.log", Library.Utility.Utility.SerializeDateTime(DateTime.Now)));
- Log.CurrentLog = log;
- Log.LogLevel = Duplicati.Library.Logging.LogMessageType.Profiling;
-
string tempdir = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "tempdir");
-
- //Filter empty entries, commonly occuring with copy/paste and newlines
- folders = (from x in folders
- where !string.IsNullOrWhiteSpace(x)
- select Library.Utility.Utility.ExpandEnvironmentVariables(x)).ToArray();
-
- //Expand the tilde to home folder on Linux/OSX
- if (Utility.IsClientLinux)
- folders = (from x in folders
- select x.Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.Personal))).ToArray();
-
- foreach(var f in folders)
- foreach(var n in f.Split(new char[] {System.IO.Path.PathSeparator}, StringSplitOptions.RemoveEmptyEntries))
- if (!System.IO.Directory.Exists(n))
- throw new Exception(string.Format("Missing source folder: {0}", n));
+ string logfilename = System.IO.Path.Combine(tempdir, string.Format("unittest-{0}.log", Library.Utility.Utility.SerializeDateTime(DateTime.Now)));
try
{
@@ -108,289 +84,310 @@ namespace Duplicati.UnitTest
System.IO.Directory.CreateDirectory(tempdir);
}
- catch(Exception ex)
+ catch (Exception ex)
{
- Log.WriteMessage("Failed to clean tempdir", LogMessageType.Error, ex);
+ Console.WriteLine("Failed to clean tempdir: {0}", ex);
}
- Duplicati.Library.Utility.TempFolder.SystemTempPath = tempdir;
+ using (var log = new LogHelper(logfilename))
+ using (Log.StartScope(log))
+ {
+ Log.LogLevel = Duplicati.Library.Logging.LogMessageType.Profiling;
- //Set some defaults
- if (!options.ContainsKey("passphrase"))
- options["passphrase"] = "secret password!";
+ //Filter empty entries, commonly occuring with copy/paste and newlines
+ folders = (from x in folders
+ where !string.IsNullOrWhiteSpace(x)
+ select Library.Utility.Utility.ExpandEnvironmentVariables(x)).ToArray();
- if (!options.ContainsKey("prefix"))
- options["prefix"] = "duplicati_unittest";
+ //Expand the tilde to home folder on Linux/OSX
+ if (Utility.IsClientLinux)
+ folders = (from x in folders
+ select x.Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.Personal))).ToArray();
- //We want all messages in the log
- options["log-level"] = LogMessageType.Profiling.ToString();
- //We cannot rely on USN numbering, but we can use USN enumeration
- //options["disable-usn-diff-check"] = "true";
-
- //We use precise times
- options["disable-time-tolerance"] = "true";
+ foreach (var f in folders)
+ foreach (var n in f.Split(new char[] { System.IO.Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries))
+ if (!System.IO.Directory.Exists(n))
+ throw new Exception(string.Format("Missing source folder: {0}", n));
- //We need all sets, even if they are unchanged
- options["upload-unchanged-backups"] = "true";
-
- bool skipfullrestore = false;
- bool skippartialrestore = false;
- bool skipverify = false;
-
- if (Utility.ParseBoolOption(options, "unittest-backuponly"))
- {
- skipfullrestore = true;
- skippartialrestore = true;
- options.Remove("unittest-backuponly");
- }
-
- if (Utility.ParseBoolOption(options, "unittest-skip-partial-restore"))
- {
- skippartialrestore = true;
- options.Remove("unittest-skip-partial-restore");
- }
-
- if (Utility.ParseBoolOption(options, "unittest-skip-full-restore"))
- {
- skipfullrestore = true;
- options.Remove("unittest-skip-full-restore");
- }
-
- if (Utility.ParseBoolOption(options, "unittest-skip-verify"))
- {
- skipverify = true;
- options.Remove("unittest-skip-verify");
- }
- var verifymetadata = !Utility.ParseBoolOption(options, "skip-metadata");
-
- using(new Timer("Total unittest"))
- using(TempFolder tf = new TempFolder())
- {
- options["dbpath"] = System.IO.Path.Combine(tempdir, "unittest.sqlite");
- if (System.IO.File.Exists(options["dbpath"]))
- System.IO.File.Delete(options["dbpath"]);
+ Duplicati.Library.Utility.TempFolder.SystemTempPath = tempdir;
+
+ //Set some defaults
+ if (!options.ContainsKey("passphrase"))
+ options["passphrase"] = "secret password!";
+
+ if (!options.ContainsKey("prefix"))
+ options["prefix"] = "duplicati_unittest";
+
+ //We want all messages in the log
+ options["log-level"] = LogMessageType.Profiling.ToString();
+ //We cannot rely on USN numbering, but we can use USN enumeration
+ //options["disable-usn-diff-check"] = "true";
+
+ //We use precise times
+ options["disable-time-tolerance"] = "true";
- if (string.IsNullOrEmpty(target))
+ //We need all sets, even if they are unchanged
+ options["upload-unchanged-backups"] = "true";
+
+ bool skipfullrestore = false;
+ bool skippartialrestore = false;
+ bool skipverify = false;
+
+ if (Utility.ParseBoolOption(options, "unittest-backuponly"))
{
- target = "file://" + tf;
+ skipfullrestore = true;
+ skippartialrestore = true;
+ options.Remove("unittest-backuponly");
}
- else
+
+ if (Utility.ParseBoolOption(options, "unittest-skip-partial-restore"))
{
- BasicSetupHelper.ProgressWriteLine("Removing old backups");
- Dictionary<string, string> tmp = new Dictionary<string, string>(options);
- tmp["keep-versions"] = "0";
- tmp["force"] = "";
- tmp["allow-full-removal"] = "";
-
- using(new Timer("Cleaning up any existing backups"))
- try
- {
- using(var bk = Duplicati.Library.DynamicLoader.BackendLoader.GetBackend(target, options))
- foreach(var f in bk.List())
- if (!f.IsFolder)
- bk.Delete(f.Name);
- }
- catch(Duplicati.Library.Interface.FolderMissingException)
- {
- }
+ skippartialrestore = true;
+ options.Remove("unittest-skip-partial-restore");
}
- log.Backupset = "Backup " + folders[0];
- string fhtempsource = null;
-
- bool usingFHWithRestore = (!skipfullrestore || !skippartialrestore);
+ if (Utility.ParseBoolOption(options, "unittest-skip-full-restore"))
+ {
+ skipfullrestore = true;
+ options.Remove("unittest-skip-full-restore");
+ }
- using(var fhsourcefolder = usingFHWithRestore ? new Library.Utility.TempFolder() : null)
+ if (Utility.ParseBoolOption(options, "unittest-skip-verify"))
{
- if (usingFHWithRestore)
+ skipverify = true;
+ options.Remove("unittest-skip-verify");
+ }
+
+ var verifymetadata = !Utility.ParseBoolOption(options, "skip-metadata");
+
+ using (new Timer("Total unittest"))
+ using (TempFolder tf = new TempFolder())
+ {
+ options["dbpath"] = System.IO.Path.Combine(tempdir, "unittest.sqlite");
+ if (System.IO.File.Exists(options["dbpath"]))
+ System.IO.File.Delete(options["dbpath"]);
+
+ if (string.IsNullOrEmpty(target))
{
- fhtempsource = fhsourcefolder;
- TestUtils.CopyDirectoryRecursive(folders[0], fhsourcefolder);
+ target = "file://" + tf;
+ }
+ else
+ {
+ BasicSetupHelper.ProgressWriteLine("Removing old backups");
+ Dictionary<string, string> tmp = new Dictionary<string, string>(options);
+ tmp["keep-versions"] = "0";
+ tmp["force"] = "";
+ tmp["allow-full-removal"] = "";
+
+ using (new Timer("Cleaning up any existing backups"))
+ try
+ {
+ using (var bk = Duplicati.Library.DynamicLoader.BackendLoader.GetBackend(target, options))
+ foreach (var f in bk.List())
+ if (!f.IsFolder)
+ bk.Delete(f.Name);
+ }
+ catch (Duplicati.Library.Interface.FolderMissingException)
+ {
+ }
}
- RunBackup(usingFHWithRestore ? (string)fhsourcefolder : folders[0], target, options, folders[0]);
-
- for (int i = 1; i < folders.Length; i++)
+ log.Backupset = "Backup " + folders[0];
+ string fhtempsource = null;
+
+ bool usingFHWithRestore = (!skipfullrestore || !skippartialrestore);
+
+ using (var fhsourcefolder = usingFHWithRestore ? new Library.Utility.TempFolder() : null)
{
- //options["passphrase"] = "bad password";
- //If the backups are too close, we can't pick the right one :(
- System.Threading.Thread.Sleep(1000 * 5);
- log.Backupset = "Backup " + folders[i];
-
if (usingFHWithRestore)
{
- System.IO.Directory.Delete(fhsourcefolder, true);
- TestUtils.CopyDirectoryRecursive(folders[i], fhsourcefolder);
+ fhtempsource = fhsourcefolder;
+ TestUtils.CopyDirectoryRecursive(folders[0], fhsourcefolder);
}
-
- //Call function to simplify profiling
- RunBackup(usingFHWithRestore ? (string)fhsourcefolder : folders[i], target, options, folders[i]);
- }
- }
- Duplicati.Library.Main.Options opts = new Duplicati.Library.Main.Options(options);
- using (Duplicati.Library.Interface.IBackend bk = Duplicati.Library.DynamicLoader.BackendLoader.GetBackend(target, options))
- foreach (Duplicati.Library.Interface.IFileEntry fe in bk.List())
- if (fe.Size > opts.VolumeSize)
+ RunBackup(usingFHWithRestore ? (string)fhsourcefolder : folders[0], target, options, folders[0]);
+
+ for (int i = 1; i < folders.Length; i++)
{
- string msg = string.Format("The file {0} is {1} bytes larger than allowed", fe.Name, fe.Size - opts.VolumeSize);
- BasicSetupHelper.ProgressWriteLine(msg);
- Log.WriteMessage(msg, LogMessageType.Error);
+ //options["passphrase"] = "bad password";
+ //If the backups are too close, we can't pick the right one :(
+ System.Threading.Thread.Sleep(1000 * 5);
+ log.Backupset = "Backup " + folders[i];
+
+ if (usingFHWithRestore)
+ {
+ System.IO.Directory.Delete(fhsourcefolder, true);
+ TestUtils.CopyDirectoryRecursive(folders[i], fhsourcefolder);
+ }
+
+ //Call function to simplify profiling
+ RunBackup(usingFHWithRestore ? (string)fhsourcefolder : folders[i], target, options, folders[i]);
}
+ }
- IList<DateTime> entries;
- using(var i = new Duplicati.Library.Main.Controller(target, options, new CommandLine.ConsoleOutput(options)))
- entries = (from n in i.List().Filesets select n.Time.ToLocalTime()).ToList();
+ Duplicati.Library.Main.Options opts = new Duplicati.Library.Main.Options(options);
+ using (Duplicati.Library.Interface.IBackend bk = Duplicati.Library.DynamicLoader.BackendLoader.GetBackend(target, options))
+ foreach (Duplicati.Library.Interface.IFileEntry fe in bk.List())
+ if (fe.Size > opts.VolumeSize)
+ {
+ string msg = string.Format("The file {0} is {1} bytes larger than allowed", fe.Name, fe.Size - opts.VolumeSize);
+ BasicSetupHelper.ProgressWriteLine(msg);
+ Log.WriteMessage(msg, LogMessageType.Error);
+ }
- if (entries.Count != folders.Length)
- {
- StringBuilder sb = new StringBuilder();
- sb.AppendLine("Entry count: " + entries.Count.ToString());
- sb.Append(string.Format("Found {0} filelists but there were {1} source folders", entries.Count, folders.Length));
- throw new Exception("Filename parsing problem, or corrupt storage: " + sb.ToString());
- }
+ IList<DateTime> entries;
+ using (var i = new Duplicati.Library.Main.Controller(target, options, new CommandLine.ConsoleOutput(Console.Out, options)))
+ entries = (from n in i.List().Filesets select n.Time.ToLocalTime()).ToList();
- if (!skipfullrestore || !skippartialrestore)
- {
- for (int i = 0; i < entries.Count; i++)
+ if (entries.Count != folders.Length)
{
- using (TempFolder ttf = new TempFolder())
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine("Entry count: " + entries.Count.ToString());
+ sb.Append(string.Format("Found {0} filelists but there were {1} source folders", entries.Count, folders.Length));
+ throw new Exception("Filename parsing problem, or corrupt storage: " + sb.ToString());
+ }
+
+ if (!skipfullrestore || !skippartialrestore)
+ {
+ for (int i = 0; i < entries.Count; i++)
{
- log.Backupset = "Restore " + folders[i];
- BasicSetupHelper.ProgressWriteLine("Restoring the copy: " + folders[i]);
-
- options["time"] = entries[entries.Count - i - 1].ToString();
-
- string[] actualfolders = folders[i].Split(System.IO.Path.PathSeparator);
- if (!skippartialrestore)
+ using (TempFolder ttf = new TempFolder())
{
- BasicSetupHelper.ProgressWriteLine("Partial restore of: " + folders[i]);
- using (TempFolder ptf = new TempFolder())
+ log.Backupset = "Restore " + folders[i];
+ BasicSetupHelper.ProgressWriteLine("Restoring the copy: " + folders[i]);
+
+ options["time"] = entries[entries.Count - i - 1].ToString();
+
+ string[] actualfolders = folders[i].Split(System.IO.Path.PathSeparator);
+ if (!skippartialrestore)
{
- List<string> testfiles = new List<string>();
- using (new Timer("Extract list of files from" + folders[i]))
+ BasicSetupHelper.ProgressWriteLine("Partial restore of: " + folders[i]);
+ using (TempFolder ptf = new TempFolder())
{
- List<string> sourcefiles;
- using(var inst = new Library.Main.Controller(target, options, new CommandLine.ConsoleOutput(options)))
- sourcefiles = (from n in inst.List("*").Files select n.Path).ToList();
-
- //Remove all folders from list
- for (int j = 0; j < sourcefiles.Count; j++)
- if (sourcefiles[j].EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
+ List<string> testfiles = new List<string>();
+ using (new Timer("Extract list of files from" + folders[i]))
+ {
+ List<string> sourcefiles;
+ using (var inst = new Library.Main.Controller(target, options, new CommandLine.ConsoleOutput(Console.Out, options)))
+ sourcefiles = (from n in inst.List("*").Files select n.Path).ToList();
+
+ //Remove all folders from list
+ for (int j = 0; j < sourcefiles.Count; j++)
+ if (sourcefiles[j].EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
+ {
+ sourcefiles.RemoveAt(j);
+ j--;
+ }
+
+
+ int testfilecount = 15;
+ Random r = new Random();
+ while (testfilecount-- > 0 && sourcefiles.Count > 0)
{
- sourcefiles.RemoveAt(j);
- j--;
+ int rn = r.Next(0, sourcefiles.Count);
+ testfiles.Add(sourcefiles[rn]);
+ sourcefiles.RemoveAt(rn);
}
-
-
- int testfilecount = 15;
- Random r = new Random();
- while (testfilecount-- > 0 && sourcefiles.Count > 0)
+
+ }
+
+
+ //Add all folders to avoid warnings in restore log
+ int c = testfiles.Count;
+ Dictionary<string, string> partialFolders = new Dictionary<string, string>(Utility.ClientFilenameStringComparer);
+
+ for (int j = 0; j < c; j++)
{
- int rn = r.Next(0, sourcefiles.Count);
- testfiles.Add(sourcefiles[rn]);
- sourcefiles.RemoveAt(rn);
+ string f = testfiles[j];
+
+ if (!f.StartsWith(usingFHWithRestore ? fhtempsource : folders[i], Utility.ClientFilenameStringComparision))
+ throw new Exception(string.Format("Unexpected file found: {0}, path is not a subfolder for {1}", f, folders[i]));
+
+ f = f.Substring(Utility.AppendDirSeparator(usingFHWithRestore ? fhtempsource : folders[i]).Length);
+
+ do
+ {
+ f = System.IO.Path.GetDirectoryName(f);
+ partialFolders[Utility.AppendDirSeparator(f)] = null;
+ } while (f.IndexOf(System.IO.Path.DirectorySeparatorChar) > 0);
}
-
- }
-
-
- //Add all folders to avoid warnings in restore log
- int c = testfiles.Count;
- Dictionary<string, string> partialFolders = new Dictionary<string, string>(Utility.ClientFilenameStringComparer);
-
- for (int j = 0; j < c; j++)
- {
- string f = testfiles[j];
-
- if (!f.StartsWith(usingFHWithRestore ? fhtempsource : folders[i], Utility.ClientFilenameStringComparision))
- throw new Exception(string.Format("Unexpected file found: {0}, path is not a subfolder for {1}", f, folders[i]));
-
- f = f.Substring(Utility.AppendDirSeparator(usingFHWithRestore ? fhtempsource : folders[i]).Length);
-
- do
+
+ if (partialFolders.ContainsKey(""))
+ partialFolders.Remove("");
+ if (partialFolders.ContainsKey(System.IO.Path.DirectorySeparatorChar.ToString()))
+ partialFolders.Remove(System.IO.Path.DirectorySeparatorChar.ToString());
+
+ List<string> filterlist;
+
+ var tfe = Utility.AppendDirSeparator(usingFHWithRestore ? fhtempsource : folders[i]);
+
+ filterlist = (from n in partialFolders.Keys
+ where !string.IsNullOrWhiteSpace(n) && n != System.IO.Path.DirectorySeparatorChar.ToString()
+ select Utility.AppendDirSeparator(System.IO.Path.Combine(tfe, n)))
+ .Union(testfiles) //Add files with full path
+ .Union(new string[] { tfe }) //Ensure root folder is included
+ .Distinct()
+ .ToList();
+
+ testfiles = (from n in testfiles select n.Substring(tfe.Length)).ToList();
+
+ //Call function to simplify profiling
+ RunPartialRestore(folders[i], target, ptf, options, filterlist.ToArray());
+
+ if (!skipverify)
{
- f = System.IO.Path.GetDirectoryName(f);
- partialFolders[Utility.AppendDirSeparator(f)] = null;
- } while (f.IndexOf(System.IO.Path.DirectorySeparatorChar) > 0);
+ //Call function to simplify profiling
+ BasicSetupHelper.ProgressWriteLine("Verifying partial restore of: " + folders[i]);
+ VerifyPartialRestore(folders[i], testfiles, actualfolders, ptf, folders[0], verifymetadata);
+ }
}
-
- if (partialFolders.ContainsKey(""))
- partialFolders.Remove("");
- if (partialFolders.ContainsKey(System.IO.Path.DirectorySeparatorChar.ToString()))
- partialFolders.Remove(System.IO.Path.DirectorySeparatorChar.ToString());
-
- List<string> filterlist;
-
- var tfe = Utility.AppendDirSeparator(usingFHWithRestore ? fhtempsource : folders[i]);
-
- filterlist = (from n in partialFolders.Keys
- where !string.IsNullOrWhiteSpace(n) && n != System.IO.Path.DirectorySeparatorChar.ToString()
- select Utility.AppendDirSeparator(System.IO.Path.Combine(tfe, n)))
- .Union(testfiles) //Add files with full path
- .Union(new string[] { tfe }) //Ensure root folder is included
- .Distinct()
- .ToList();
-
- testfiles = (from n in testfiles select n.Substring(tfe.Length)).ToList();
-
+ }
+
+ if (!skipfullrestore)
+ {
//Call function to simplify profiling
- RunPartialRestore(folders[i], target, ptf, options, filterlist.ToArray());
-
+ RunRestore(folders[i], target, ttf, options);
+
if (!skipverify)
{
//Call function to simplify profiling
- BasicSetupHelper.ProgressWriteLine("Verifying partial restore of: " + folders[i]);
- VerifyPartialRestore(folders[i], testfiles, actualfolders, ptf, folders[0], verifymetadata);
+ BasicSetupHelper.ProgressWriteLine("Verifying the copy: " + folders[i]);
+ VerifyFullRestore(folders[i], actualfolders, new string[] { ttf }, verifymetadata);
}
}
}
-
- if (!skipfullrestore)
- {
- //Call function to simplify profiling
- RunRestore(folders[i], target, ttf, options);
-
- if (!skipverify)
- {
- //Call function to simplify profiling
- BasicSetupHelper.ProgressWriteLine("Verifying the copy: " + folders[i]);
- VerifyFullRestore(folders[i], actualfolders, new string[] { ttf }, verifymetadata);
- }
- }
}
}
- }
-
- foreach(string s in Utility.EnumerateFiles(tempdir))
- {
- if (s == options["dbpath"])
- continue;
- if (s.StartsWith(Utility.AppendDirSeparator(tf)))
- continue;
-
- Log.WriteMessage(string.Format("Found left-over temp file: {0}", s.Substring(tempdir.Length)), LogMessageType.Warning);
- BasicSetupHelper.ProgressWriteLine("Found left-over temp file: {0} -> {1}", s.Substring(tempdir.Length),
+
+ foreach (string s in Utility.EnumerateFiles(tempdir))
+ {
+ if (s == options["dbpath"])
+ continue;
+ if (s == logfilename)
+ continue;
+ if (s.StartsWith(Utility.AppendDirSeparator(tf)))
+ continue;
+
+ Log.WriteMessage(string.Format("Found left-over temp file: {0}", s.Substring(tempdir.Length)), LogMessageType.Warning);
+ BasicSetupHelper.ProgressWriteLine("Found left-over temp file: {0} -> {1}", s.Substring(tempdir.Length),
#if DEBUG
TempFile.GetStackTraceForTempFile(System.IO.Path.GetFileName(s))
#else
System.IO.Path.GetFileName(s)
#endif
);
- }
-
- foreach(string s in Utility.EnumerateFolders(tempdir))
- if (!s.StartsWith(Utility.AppendDirSeparator(tf)) && Utility.AppendDirSeparator(s) != Utility.AppendDirSeparator(tf) && Utility.AppendDirSeparator(s) != Utility.AppendDirSeparator(tempdir))
- {
- Log.WriteMessage(string.Format("Found left-over temp folder: {0}", s.Substring(tempdir.Length)), LogMessageType.Warning);
- BasicSetupHelper.ProgressWriteLine("Found left-over temp folder: {0}", s.Substring(tempdir.Length));
}
+
+ foreach (string s in Utility.EnumerateFolders(tempdir))
+ if (!s.StartsWith(Utility.AppendDirSeparator(tf)) && Utility.AppendDirSeparator(s) != Utility.AppendDirSeparator(tf) && Utility.AppendDirSeparator(s) != Utility.AppendDirSeparator(tempdir))
+ {
+ Log.WriteMessage(string.Format("Found left-over temp folder: {0}", s.Substring(tempdir.Length)), LogMessageType.Warning);
+ BasicSetupHelper.ProgressWriteLine("Found left-over temp folder: {0}", s.Substring(tempdir.Length));
+ }
+ }
}
- (Log.CurrentLog as StreamLog).Dispose();
- Log.CurrentLog = null;
-
if (LogHelper.ErrorCount > 0)
BasicSetupHelper.ProgressWriteLine("Unittest completed, but with {0} errors, see logfile for details", LogHelper.ErrorCount);
else if (LogHelper.WarningCount > 0)
@@ -457,7 +454,7 @@ namespace Duplicati.UnitTest
{
BasicSetupHelper.ProgressWriteLine("Backing up the copy: " + sourcename);
using (new Timer("Backup of " + sourcename))
- using(var i = new Duplicati.Library.Main.Controller(target, options, new CommandLine.ConsoleOutput(options)))
+ using(var i = new Duplicati.Library.Main.Controller(target, options, new CommandLine.ConsoleOutput(Console.Out, options)))
Log.WriteMessage(i.Backup(source.Split(System.IO.Path.PathSeparator)).ToString(), LogMessageType.Information);
}
@@ -466,7 +463,7 @@ namespace Duplicati.UnitTest
var tops = new Dictionary<string, string>(options);
tops["restore-path"] = tempfolder;
using (new Timer("Restore of " + source))
- using(var i = new Duplicati.Library.Main.Controller(target, tops, new CommandLine.ConsoleOutput(options)))
+ using(var i = new Duplicati.Library.Main.Controller(target, tops, new CommandLine.ConsoleOutput(Console.Out, options)))
Log.WriteMessage(i.Restore(null).ToString(), LogMessageType.Information);
}
@@ -475,7 +472,7 @@ namespace Duplicati.UnitTest
var tops = new Dictionary<string, string>(options);
tops["restore-path"] = tempfolder;
using (new Timer("Partial restore of " + source))
- using(var i = new Duplicati.Library.Main.Controller(target, tops, new CommandLine.ConsoleOutput(options)))
+ using(var i = new Duplicati.Library.Main.Controller(target, tops, new CommandLine.ConsoleOutput(Console.Out, options)))
Log.WriteMessage(i.Restore(files).ToString(), LogMessageType.Information);
}
}
diff --git a/Duplicati/UnitTest/SizeOmittingBackend.cs b/Duplicati/UnitTest/SizeOmittingBackend.cs
index 57541f28c..baba42555 100644
--- a/Duplicati/UnitTest/SizeOmittingBackend.cs
+++ b/Duplicati/UnitTest/SizeOmittingBackend.cs
@@ -51,13 +51,12 @@ namespace Duplicati.UnitTest
#endregion
#region IBackend implementation
- public List<IFileEntry> List()
+ public IEnumerable<IFileEntry> List()
{
- return (
+ return
from n in m_backend.List()
where !n.IsFolder
- select new Library.Interface.FileEntry(n.Name)
- ).Cast<Library.Interface.IFileEntry>().ToList();
+ select new Library.Interface.FileEntry(n.Name);
}
public void Put(string remotename, string filename)
{
diff --git a/Duplicati/UnitTest/UtilityTests.cs b/Duplicati/UnitTest/UtilityTests.cs
new file mode 100644
index 000000000..18ddbd7ee
--- /dev/null
+++ b/Duplicati/UnitTest/UtilityTests.cs
@@ -0,0 +1,61 @@
+// Copyright (C) 2017, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using Duplicati.Library.Utility;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+
+namespace Duplicati.UnitTest
+{
+ [TestFixture]
+ public class UtilityTests
+ {
+ [Test]
+ [Category("Utility")]
+ public void GetUniqueItems()
+ {
+ string[] collection = { "A", "a", "A", "b", "c", "c" };
+ string[] uniqueItems = { "A", "a", "b", "c" };
+ string[] duplicateItems = { "A", "c" };
+
+ // Test with default comparer.
+ ISet<string> actualDuplicateItems;
+ ISet<string> actualUniqueItems = Utility.GetUniqueItems(collection, out actualDuplicateItems);
+
+ CollectionAssert.AreEquivalent(uniqueItems, actualUniqueItems);
+ CollectionAssert.AreEquivalent(duplicateItems, actualDuplicateItems);
+
+ // Test with custom comparer.
+ IEqualityComparer<string> comparer = StringComparer.OrdinalIgnoreCase;
+ uniqueItems = new string[] {"a", "b", "c"};
+ duplicateItems = new string[] { "a", "c" };
+
+ actualDuplicateItems = null;
+ actualUniqueItems = Utility.GetUniqueItems(collection, comparer, out actualDuplicateItems);
+
+ Assert.That(actualUniqueItems, Is.EquivalentTo(uniqueItems).Using(comparer));
+ Assert.That(actualDuplicateItems, Is.EquivalentTo(duplicateItems).Using(comparer));
+
+ // Test with empty collection.
+ actualDuplicateItems = null;
+ actualUniqueItems = Utility.GetUniqueItems(new string[0], out actualDuplicateItems);
+
+ Assert.IsNotNull(actualUniqueItems);
+ Assert.IsNotNull(actualDuplicateItems);
+ }
+ }
+}
diff --git a/Duplicati/UnitTest/packages.config b/Duplicati/UnitTest/packages.config
index f2fd55af4..c108d442f 100644
--- a/Duplicati/UnitTest/packages.config
+++ b/Duplicati/UnitTest/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="NUnit" version="3.4.1" targetFramework="net45" />
+ <package id="NUnit" version="3.5.0" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/Duplicati/WindowsService/ServiceControl.cs b/Duplicati/WindowsService/ServiceControl.cs
index 5395d12f4..f2f96b204 100644
--- a/Duplicati/WindowsService/ServiceControl.cs
+++ b/Duplicati/WindowsService/ServiceControl.cs
@@ -67,7 +67,7 @@ namespace Duplicati.WindowsService
var sv = new ServiceStatus()
{
dwCurrentState = ServiceState.SERVICE_START_PENDING,
- dwWaitHint = (int)TimeSpan.FromSeconds(30).TotalMilliseconds
+ dwWaitHint = (uint)TimeSpan.FromSeconds(30).TotalMilliseconds
};
SetServiceStatus(this.ServiceHandle, ref sv);
@@ -120,7 +120,7 @@ namespace Duplicati.WindowsService
var sv = new ServiceStatus()
{
dwCurrentState = ServiceState.SERVICE_STOP_PENDING,
- dwWaitHint = (int)TimeSpan.FromSeconds(5).TotalMilliseconds
+ dwWaitHint = (uint)TimeSpan.FromSeconds(5).TotalMilliseconds
};
SetServiceStatus(this.ServiceHandle, ref sv);
@@ -131,7 +131,7 @@ namespace Duplicati.WindowsService
}
- private enum ServiceState
+ private enum ServiceState : uint
{
SERVICE_STOPPED = 0x00000001,
SERVICE_START_PENDING = 0x00000002,
@@ -145,13 +145,13 @@ namespace Duplicati.WindowsService
[StructLayout(LayoutKind.Sequential)]
private struct ServiceStatus
{
- public long dwServiceType;
+ public uint dwServiceType;
public ServiceState dwCurrentState;
- public long dwControlsAccepted;
- public long dwWin32ExitCode;
- public long dwServiceSpecificExitCode;
- public long dwCheckPoint;
- public long dwWaitHint;
+ public uint dwControlsAccepted;
+ public uint dwWin32ExitCode;
+ public uint dwServiceSpecificExitCode;
+ public uint dwCheckPoint;
+ public uint dwWaitHint;
};
[DllImport("advapi32.dll", SetLastError = true)]
diff --git a/Duplicati/WindowsService/WindowsService.csproj b/Duplicati/WindowsService/WindowsService.csproj
index 0d0b15a46..33a467803 100644
--- a/Duplicati/WindowsService/WindowsService.csproj
+++ b/Duplicati/WindowsService/WindowsService.csproj
@@ -6,6 +6,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BEF7AF9A-3978-4F90-8592-198BF6EA6C6B}</ProjectGuid>
<OutputType>Exe</OutputType>
+ <Prefer32Bit>False</Prefer32Bit>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Duplicati.WindowsService</RootNamespace>
<AssemblyName>Duplicati.WindowsService</AssemblyName>
@@ -14,6 +15,7 @@
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
<SignAssembly>true</SignAssembly>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>