diff --git a/README.md b/README.md index e2d1c28..8459615 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@

Build Status (Travis-CI) -Buitld Status (AppVeyor) +Build Status (AppVeyor) Open Issues Codecov MIT License Join the chat at https://gitter.im/MatthiWare/UpdateLib

-# UpdateLib v0.4.4 +# UpdateLib v0.5.0-alpha A .Net auto update library made in C# ### Disclaimer @@ -16,14 +16,13 @@ UpdateLib should only be used for testing purposes untill the first stable relea Use UpdateLib at your own risk while it is still in development. ## Features -- Generator for the update file with GUI -- Updating files -- Updating registry -- Fail-safe rollback feature -- Caching system -- FluentAPI to configure the client-side application +- GUI for update generation +- Updating files and registry +- Extensive Fail-safe rollback feature +- FluentAPI to configure the client-side application (minimal configuration needed) +- Minimize network overhead by making use of binary patches ## Future -- Creation of binary patches -- Rework update generator -- Extend rollback feature +- Make UpdateLib more generic and configurable +- Bugfixes +- None planned at the moment diff --git a/UpdateLib/.shared/SharedAssemblyInfo.cs b/UpdateLib/.shared/SharedAssemblyInfo.cs new file mode 100644 index 0000000..fb349eb --- /dev/null +++ b/UpdateLib/.shared/SharedAssemblyInfo.cs @@ -0,0 +1,11 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyCompany("MatthiWare")] +[assembly: AssemblyProduct("UpdateLib")] +[assembly: AssemblyCopyright("Copyright © MatthiWare 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: AssemblyVersion("0.5.0.0")] +[assembly: AssemblyFileVersion("0.5.0.0")] diff --git a/UpdateLib/TestApp/Form1.Designer.cs b/UpdateLib/TestApp/Form1.Designer.cs index a13e970..2bf95e8 100644 --- a/UpdateLib/TestApp/Form1.Designer.cs +++ b/UpdateLib/TestApp/Form1.Designer.cs @@ -28,373 +28,12 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); - this.menuStrip1 = new System.Windows.Forms.MenuStrip(); - this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); - this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.printToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.printPreviewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.undoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.redoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); - this.cutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.pasteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); - this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.customizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.indexToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); - this.checkForUpdatesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.label1 = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.menuStrip1.SuspendLayout(); - this.SuspendLayout(); - // - // menuStrip1 - // - this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.fileToolStripMenuItem, - this.editToolStripMenuItem, - this.toolsToolStripMenuItem, - this.helpToolStripMenuItem}); - this.menuStrip1.Location = new System.Drawing.Point(0, 0); - this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(490, 24); - this.menuStrip1.TabIndex = 0; - this.menuStrip1.Text = "menuStrip1"; - // - // fileToolStripMenuItem - // - this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.newToolStripMenuItem, - this.openToolStripMenuItem, - this.toolStripSeparator, - this.saveToolStripMenuItem, - this.saveAsToolStripMenuItem, - this.toolStripSeparator1, - this.printToolStripMenuItem, - this.printPreviewToolStripMenuItem, - this.toolStripSeparator2, - this.exitToolStripMenuItem}); - this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; - this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); - this.fileToolStripMenuItem.Text = "&File"; - // - // newToolStripMenuItem - // - this.newToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("newToolStripMenuItem.Image"))); - this.newToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.newToolStripMenuItem.Name = "newToolStripMenuItem"; - this.newToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N))); - this.newToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.newToolStripMenuItem.Text = "&New"; - // - // openToolStripMenuItem - // - this.openToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripMenuItem.Image"))); - this.openToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.openToolStripMenuItem.Name = "openToolStripMenuItem"; - this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); - this.openToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.openToolStripMenuItem.Text = "&Open"; - // - // toolStripSeparator - // - this.toolStripSeparator.Name = "toolStripSeparator"; - this.toolStripSeparator.Size = new System.Drawing.Size(143, 6); - // - // saveToolStripMenuItem - // - this.saveToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image"))); - this.saveToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); - this.saveToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.saveToolStripMenuItem.Text = "&Save"; - // - // saveAsToolStripMenuItem - // - this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; - this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.saveAsToolStripMenuItem.Text = "Save &As"; - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(143, 6); - // - // printToolStripMenuItem - // - this.printToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("printToolStripMenuItem.Image"))); - this.printToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.printToolStripMenuItem.Name = "printToolStripMenuItem"; - this.printToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.P))); - this.printToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.printToolStripMenuItem.Text = "&Print"; - // - // printPreviewToolStripMenuItem - // - this.printPreviewToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("printPreviewToolStripMenuItem.Image"))); - this.printPreviewToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.printPreviewToolStripMenuItem.Name = "printPreviewToolStripMenuItem"; - this.printPreviewToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.printPreviewToolStripMenuItem.Text = "Print Pre&view"; - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(143, 6); - // - // exitToolStripMenuItem - // - this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - this.exitToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.exitToolStripMenuItem.Text = "E&xit"; - // - // editToolStripMenuItem - // - this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.undoToolStripMenuItem, - this.redoToolStripMenuItem, - this.toolStripSeparator3, - this.cutToolStripMenuItem, - this.copyToolStripMenuItem, - this.pasteToolStripMenuItem, - this.toolStripSeparator4, - this.selectAllToolStripMenuItem}); - this.editToolStripMenuItem.Name = "editToolStripMenuItem"; - this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20); - this.editToolStripMenuItem.Text = "&Edit"; - // - // undoToolStripMenuItem - // - this.undoToolStripMenuItem.Name = "undoToolStripMenuItem"; - this.undoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); - this.undoToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.undoToolStripMenuItem.Text = "&Undo"; - // - // redoToolStripMenuItem - // - this.redoToolStripMenuItem.Name = "redoToolStripMenuItem"; - this.redoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); - this.redoToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.redoToolStripMenuItem.Text = "&Redo"; - // - // toolStripSeparator3 - // - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size(141, 6); - // - // cutToolStripMenuItem - // - this.cutToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("cutToolStripMenuItem.Image"))); - this.cutToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.cutToolStripMenuItem.Name = "cutToolStripMenuItem"; - this.cutToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); - this.cutToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.cutToolStripMenuItem.Text = "Cu&t"; - // - // copyToolStripMenuItem - // - this.copyToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("copyToolStripMenuItem.Image"))); - this.copyToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.copyToolStripMenuItem.Name = "copyToolStripMenuItem"; - this.copyToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); - this.copyToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.copyToolStripMenuItem.Text = "&Copy"; - // - // pasteToolStripMenuItem - // - this.pasteToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("pasteToolStripMenuItem.Image"))); - this.pasteToolStripMenuItem.ImageTransparentColor = System.Drawing.Color.Magenta; - this.pasteToolStripMenuItem.Name = "pasteToolStripMenuItem"; - this.pasteToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); - this.pasteToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.pasteToolStripMenuItem.Text = "&Paste"; - // - // toolStripSeparator4 - // - this.toolStripSeparator4.Name = "toolStripSeparator4"; - this.toolStripSeparator4.Size = new System.Drawing.Size(141, 6); - // - // selectAllToolStripMenuItem - // - this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem"; - this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(144, 22); - this.selectAllToolStripMenuItem.Text = "Select &All"; - // - // toolsToolStripMenuItem - // - this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.customizeToolStripMenuItem, - this.optionsToolStripMenuItem}); - this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; - this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 20); - this.toolsToolStripMenuItem.Text = "&Tools"; - // - // customizeToolStripMenuItem - // - this.customizeToolStripMenuItem.Name = "customizeToolStripMenuItem"; - this.customizeToolStripMenuItem.Size = new System.Drawing.Size(130, 22); - this.customizeToolStripMenuItem.Text = "&Customize"; - // - // optionsToolStripMenuItem - // - this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; - this.optionsToolStripMenuItem.Size = new System.Drawing.Size(130, 22); - this.optionsToolStripMenuItem.Text = "&Options"; - // - // helpToolStripMenuItem - // - this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.contentsToolStripMenuItem, - this.indexToolStripMenuItem, - this.searchToolStripMenuItem, - this.toolStripSeparator5, - this.checkForUpdatesToolStripMenuItem, - this.aboutToolStripMenuItem}); - this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); - this.helpToolStripMenuItem.Text = "&Help"; - // - // contentsToolStripMenuItem - // - this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; - this.contentsToolStripMenuItem.Size = new System.Drawing.Size(173, 22); - this.contentsToolStripMenuItem.Text = "&Contents"; - // - // indexToolStripMenuItem - // - this.indexToolStripMenuItem.Name = "indexToolStripMenuItem"; - this.indexToolStripMenuItem.Size = new System.Drawing.Size(173, 22); - this.indexToolStripMenuItem.Text = "&Index"; - // - // searchToolStripMenuItem - // - this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; - this.searchToolStripMenuItem.Size = new System.Drawing.Size(173, 22); - this.searchToolStripMenuItem.Text = "&Search"; - // - // toolStripSeparator5 - // - this.toolStripSeparator5.Name = "toolStripSeparator5"; - this.toolStripSeparator5.Size = new System.Drawing.Size(170, 6); - // - // checkForUpdatesToolStripMenuItem - // - this.checkForUpdatesToolStripMenuItem.Name = "checkForUpdatesToolStripMenuItem"; - this.checkForUpdatesToolStripMenuItem.Size = new System.Drawing.Size(173, 22); - this.checkForUpdatesToolStripMenuItem.Text = "Check For &Updates"; - this.checkForUpdatesToolStripMenuItem.Click += new System.EventHandler(this.checkForUpdatesToolStripMenuItem_Click); - // - // aboutToolStripMenuItem - // - this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; - this.aboutToolStripMenuItem.Size = new System.Drawing.Size(173, 22); - this.aboutToolStripMenuItem.Text = "&About..."; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(24, 53); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(45, 16); - this.label1.TabIndex = 1; - this.label1.Text = "label1"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label2.Location = new System.Drawing.Point(24, 105); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(45, 16); - this.label2.TabIndex = 2; - this.label2.Text = "label2"; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label3.Location = new System.Drawing.Point(27, 161); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(45, 16); - this.label3.TabIndex = 3; - this.label3.Text = "label3"; - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.components = new System.ComponentModel.Container(); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(490, 266); - this.Controls.Add(this.label3); - this.Controls.Add(this.label2); - this.Controls.Add(this.label1); - this.Controls.Add(this.menuStrip1); - this.MainMenuStrip = this.menuStrip1; - this.Name = "Form1"; - this.Text = "Test app - Not updated"; - this.Load += new System.EventHandler(this.Form1_Load); - this.menuStrip1.ResumeLayout(false); - this.menuStrip1.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "Form1"; } #endregion - - private System.Windows.Forms.MenuStrip menuStrip1; - private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator; - private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripMenuItem printToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem printPreviewToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; - private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem undoToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem redoToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; - private System.Windows.Forms.ToolStripMenuItem cutToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem copyToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem pasteToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; - private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem customizeToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem indexToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem searchToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; - private System.Windows.Forms.ToolStripMenuItem checkForUpdatesToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label label3; } -} - +} \ No newline at end of file diff --git a/UpdateLib/TestApp/Form1.cs b/UpdateLib/TestApp/Form1.cs index eb7d94c..ab38765 100644 --- a/UpdateLib/TestApp/Form1.cs +++ b/UpdateLib/TestApp/Form1.cs @@ -1,24 +1,11 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib; -using MatthiWare.UpdateLib.Tasks; -using System; -using System.IO; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; using System.Windows.Forms; namespace TestApp @@ -28,84 +15,6 @@ public partial class Form1 : Form public Form1() { InitializeComponent(); - - Updater.Instance.CheckForUpdatesCompleted += Instance_CheckForUpdatesCompleted; - } - - private void Instance_CheckForUpdatesCompleted(object sender, CheckForUpdatesCompletedEventArgs e) - { - checkForUpdatesToolStripMenuItem.Enabled = true; - - //if (e.Cancelled || e.Error != null) - //{ - // this.InvokeOnUI(() => MessageDialog.Show( - // this, - // "Updater", - // e.Cancelled ? "Cancelled" : "Error", - // e.Cancelled ? "Update got cancelled" : "Please check the logs for more information.", - // e.Cancelled ? SystemIcons.Warning : SystemIcons.Error, - // MessageBoxButtons.OK)); - - // return; - //} - - //if (!e.UpdateAvailable) - //{ - // this.InvokeOnUI(() => - // MessageDialog.Show( - // this, - // "Updater", - // "No update available!", - // $"You already have the latest version ({e.LatestVersion}).", - // SystemIcons.Information, - // MessageBoxButtons.OK)); - - // return; - //} - } - - private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e) - { - checkForUpdatesToolStripMenuItem.Enabled = false; - - AsyncTask task = Updater.Instance.CheckForUpdatesAsync(); - //task.Cancel(); - } - - private void Form1_Load(object sender, EventArgs e) - { - label1.Text = ReadFile("data/testfile1.txt"); - label2.Text = ReadFile("data/testfile2.txt"); - label3.Text = ReadFileAndKeepStreamOpen("data/testfile3.txt"); - } - - private string ReadFile(string file) - { - if (!File.Exists(file)) - return "ERROR: File doesn't exist.."; - - string[] lines = File.ReadAllLines(file); - - return string.Join(", ", lines); - } - - FileStream fs; - /// - /// Bad code that keeps the file open & locked - /// Purpose: to demonstrate the updater still works on locked files. - /// - /// - /// - private string ReadFileAndKeepStreamOpen(string file) - { - if (!File.Exists(file)) - return "ERROR: File doesn't exist.."; - - fs = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None); - StreamReader sr = new StreamReader(fs); - string text = sr.ReadToEnd(); - - return text; } } } diff --git a/UpdateLib/TestApp/Form1.resx b/UpdateLib/TestApp/Form1.resx deleted file mode 100644 index dbd0356..0000000 --- a/UpdateLib/TestApp/Form1.resx +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAERSURBVDhPrZDbSgJRGIXnpewd6jXsjSQvIrwoI0RQMChU - 0iiDPCGiE3ZCRkvR8VzTeBhnyR5/ccaZNnPhB4t9sdf6Ln5hb8QeathNJFVFKF5C8DqL4ksDVHWGDf7j - LHyPg6NjviSaFqlu5yQYR+KpupaIkrMknCxT3Y7v/NYYb0ITK1c3BarbWWhLQ7IR0cTKReyZ6lZ0XYei - ztHpK4bAc+h1FgQijzSxMptrGIxVSO0xX3AaStFki7bUMVFmaMm/eJMGfIH/MkGzLep0AXn4h/r3CJV3 - mS9gn2bY4UY/UzQ7E9TqfeTFtnuB+XAfzSHKr11kSl/uBebDiZ89ZCst3OUkdwL28sIVsE83ock+EIQV - 2Mz2wxeg6/UAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJHSURBVDhPxZBdSNNhFMb/F110ZZEVhVBgeeHNICiiuggp - olAUyyxI0oSaH1QYC3N+tKnp5ubm1JUua5uuqdNKMwr7kApFItTUkWZqVhSVYmao5Nevvy7UoYR3HXh4 - 4XCe33nOKyy3lAY7l9RWMo0O/raWXxEyo5spVYTNvOGyfIRPfW+ptOkXqaPl6T83hcRmExSdgzAz3NVm - YWyoYla/B+1M9JtxWLPpaH22JORIjI6gKAMB0jyEimIdo4OlbuaprwVMOOMovammpDADc34qppwUrmnl - 5Kni3aFlFg2j3y1z5mnRTJccnNIltQhwq0jFry+mOXNtpWZWDx1Z1NhV3C3JwGFOw25SYjVe5oYhiUKd - HKMmwQUrMWUw/CF3NnZvvYKqUh1TvUroS3fXe7HXkwidMngTS2t5KLbregSzMY2f3Wr4qKW6LJvGR1rX - 0MLor8OhKYTJBn/GHvvxrliCTBrsOqXIoOBHh5K+hmSq7FqmexTQHuUytkaKxuNMNgYyVneA4Qd7GKjc - hjLaRzxH7gIU6JIZaEvgtk1D8wsxSWecCDgNzWFMvwxm/PkhRmr3Mli1nW9lvjRdWc0Jf+/5jzRmyWmv - S+GOLQu6U6BFjPvqKOP1AYw88WOoZif9DgmfLVtxaj1RSLdwNvrkPCA3M54KqxrnvRia9MKcGrUrqFOt - 5H7qKsqT1mGO9+Lqhc2ELdw+U/r0i+gVZ8hMiCDx3DHORwZyKnQ/hw/uYt9uCTskPvh6e7Fp41rWr/Fg - g6eHO+A/lyD8ARfG3mk9fv1YAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIySURBVDhPrZLfS5NRGMfff6H7boIuuq2pMZyL1eAt11CW - DcOKsB9vpFmaLtNExco0av6CbIVLJ61Wk3BSkT/AFCkRZSpZmrmiJQ41xSaCwdfznL15XEUX0Reem5f3 - 8znnec4j/Zc8fxYGla91CS3eRTx0z6OpMYS7jmnU1X6B/VYA18snUVoyjsKCt8jLHcH5c36ouCQR2NUJ - 1Nas4G9ZXlmFKbULh1Kf8lJxSfI+WeCCyopv6q+/h+DQ/DJ2WV5Ao1FgPegRAveDOS4oLfmq/h6dn/DH - 4AJizD4UXJrCAUuzEDgbZrjgou2DiohshIcnQtgme5GTPYbkJKcQ1N8OckHW2REVi+RXuM8fxGaDG4oy - ALPZIQQ11Z+5QDk1oKJ/hjv7P2FTfCMOH3mFxMQ6IbhROYWOdrCnBI4dfwPr0V4+bRoY9UzXppMjcDdS - rC8hy3YhuFI2gTYf2A4Aza4f7N2/o/zaLB8qDYx6zszwr8P7k1thNFYIweXCMXgeAfedq2xxwjClZUeV - Jd2GtDNFETiJwfs8MBjKhMCWN8pgoLoqzE8miH1GjE7G4PsZjE7OQsm9ij2mFg7rdrug1xcJAa2l4w7W - r00Cgk/n38S7wBwC04u4UGxHrMHF4CbEJtyDLj5fCDIzhljfSxzeavRgyw4Zj9t64GvvQ0d3P3pfD2Kv - 2QqNvgFxDN6urYdWmyMElJMnevh60obRktA701PRtGlg1DOdSkXwzrisaMG/RZLWAE60OMW5fNhvAAAA - AElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIpSURBVDhPtZL/T1JRGMb5p1itrVZbbRpqZbawnBENV1I0 - jGlByTSyJTXJwq2oKZQb1KAv6JCYWSxvBrkkZUq4CeQEiRABFeLL072Xa0zRra31bO8v57zP5znnPYf1 - X+TxhWF6O7VtGYcnwbSWijKPOLzYrPSvLPwLS3huGUMlT7o9wGD9grVUBj+icdid03S9tDmgNxNwTgVQ - J+rA8XNtWwM+uuZATMwxmQVRycuJFNyzIRitDlScugKzjSgFRGJJaIwEsrk8AsHIhnSL/Ssck37UNipQ - I5DjtuYV7uksRYhr2kebhx2eP6nrycFIEh5fBA/1Nvru8q5+PDaOovK0rABwfwugWzcErfkzHhjsePL6 - E7q1VrTdNUDcrgGvSYlDZHN5XTNOnL8BVe8AJAoNDtZfLgDu9L1BPJmikzcrk81hlRwodZJwdBXziwnI - OrVoaOkiT8C8hKLHBPO7CbywOaE1jeC+bhAd6meQdvZC1KoG/5IS3MZ2HObLUHZSggvkWq3wOvbWiAqA - VpWeyStVfCUNf3AZ4zNhfHCFMEDMgye+hYr6FrDLzxQAUuVTpr0ocn74mchg5vsKRt1RcHp2Qv9+kZ78 - UcE17KkWFgHNN/uQzgBkGKLJPBZiecyGchjzrmFwPIF++xJUbDbUQzEacIArLpopSRSP4CUN1Obf1Abz - uqob5KjiXwWH/GVl5HPt5zZh37GL2H1EiF1VZ7GDI6CNW5r/TSzWbwHYL0mKJ5czAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGCSURBVDhPnZK9S0JRGMb9F1xb2gqaq6mhwCGDtvYIIyLI - cJOE1paoIYpMKUjFRDH87lpoakGlIZF9DA2hZJEQhJXl1xPn3HPV29WQfvBwOfA+P95zuDJ39A6/4wyl - YOOSMHvOcHGThuwvSKEVRvsR+pQqWD3R1pK98DUbl7Jm5hA8SfESd6S5xH5wycalrO4E0D8yWQuriLH6 - E2xcSqlcoRJBxCpiTO5TNi4m/ZgDF4nDsOulsfujyGRzUsmWM8YqdcggKbveS3A88bEkslRye58RSzZt - IVarY/FFaPmlwp+fUaESYRNW5Vm3BPmpBpZNvppACDmTLbS6FbGAPFAj5OGI4PALOK/yZfIlAlk4j7n5 - xdaCarWKj0KRXmE2+UklJEJZZ/RCPTPdWvBdLOP1rYD41QNcgRiVkKJQ1mjGsa2VNxeQb2OWDC7sh47p - ddQLeoyOTSFiVAAFvVhChsmv2k6Uvd3Icx1UolMNiDdpl4nhLiohW/xb0tMph2JwCJxjAz9A30JI8zYA - tAAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGDSURBVDhPrZFNSwJRGIX9NYGbFoUlFElY1EJQKEYhCJsi - LaVsERnRF5iCaSZJO1toCDVGFkgoFpWQWWRR2aIvUxm1BKN1wSnHCFw4TOCzue+9nPNw4eVVnav4Izzb - QfxeGZ5TWaxT/rK3irzmC7CsusvC1G4IkbNLboIiDieF4GGUKeTeClDpppF8eeEu2PIfwfrzizSdw3Hk - EnKlFpkMzV2wH77AosOFTV8A+vkl9CiHuJeLJNNZjM8tYWB0FkTvMAwmy/8ERTR6CwjlGAi1Ccence6C - 1NsXzN4PKIxJLLgeIJ2MoXvmFraNBKK3eXZRIveJPvs7FIYniEkXZENOdE+GIZ2Ko10TwLK7tJmKmL0F - EEYarYM+NMnt0C1sQzpx/lcSEnZ2gcKY/gs0dlmZuWvmjjmpwA1qxVp2AWFIMAF/OAGBzMjMI7ZrtJCb - 4Df3o4Zfxy7QrdxDRFKol5khkpR2H4qmIOzUQNBGwrsXYxccnNOQqNbQ0KGGZ+eEPVwdeLxvqqrf4wGh - TNAAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHkSURBVDhPvZHfS1NhHIf3p5QypLr2D4goMwoMCi/qIugH - Xe1Cr7qKDIMkZixwNhfWLGWbnuki0kXKzLU023KubBNPJrbRdOzocm6e2dPOO21mMS+CHvjcvOf9PF++ - 79H9M+7RT2iRRsIi9sEAXe43yAvf2LpSHq28G9uAnytNT4jMLewtcQ2Ht2pF8ps/aOt+gccX5lxD694S - +1BQFD1RkN5DSFa4Z3uONKbgHE3h8KZ4OJTC1J8UiSzmfhd2uf1CoJHbyKOsZokl0kKwm+aeJaov+wjO - rpQkVqdXfOz0bWAcVLghfaXxkUz3y2VxvpMGSwL3uMKh+gHezSSLEnNhX23vtYzKUirDfGyFj/Iy1mdx - UWqR8iKhwtQLxjgH659y4EwvVXWPiwJt3/Ws+muywRrlqvkDdx3zQrCN8l1ldnEd3/QqFmkS/akHJYGS - zjLzOUEwEsMf+sLI2zmaOou/93pPGoM5zvk7UU7fnBKxSBPoT7SXBNW1F/9Io2lKCNTCeomUyrS8xnBA - wfUqyf1eP5U1ptJD/o1LzeNCsHPydtqdr6k4aiwvOHvNSya3ibU/QIdrEkvfhJislc32MfYfuV1eUGPw - FF7bIVJVZ0N/soPK421UHGstlFvYd/hWecF/Qqf7CR0A5wwgSQA2AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJSSURBVDhPtZJrSJNRGMdf6IN9KbpQn/pUEH2JIoLqQ0Zh - FqYZRmJG1iKmUqKyLB2pqSm6vC1Nm5GXoeatEsVJ0RASR3eNzegikRq5lrV3857Fr/d9ddlICoL+8OfA - Oef/e57zcIT/os7WLMw302muSGJ2689qqi7A44q8IzjtNYzarzHQm8tZtT8FmRqu6LToMxN+B8qhCbGR - KVcDE85ajKUaxoaryEuL4UVXIudPB5Ko2oy98xjDptXERuz3hsgAOTzlqqMk6yjdllzE90UM9Wp5azlB - S1kwkeG+1CSv4mmBQPThfd6Ahqq8GYB4A11yBKmaMLQxoZyLDkGjDiZOFUhUuB+FsWsUQFiArzegtlzH - pFjPpMPA2GA2jucx2KqWK7ZWLqO7dBGP9D5KWLbfto3eAKMhi3FHBeP9GYy9PMXos4OIrYvJrzSRbWjm - wuV6EnVG4tLLiEzSExGf4w0oL05nZEDPaK+akceBuO9v4uPtFUrYo6npbzhdE/QPOQmNSiPouHYOUpaf - gvgqA/dDf9wd63G1r2SgUlAqyyq/1anYUGfG2mdXwne7bOwJUc1AinOS+NxzBpd5HWLbUhyNPvRdF5S2 - v05/54tbqvzBifWNHUvPOwLC4/CXwrv2HsB3+w6EwosJOB5ESeElfGpayGD1AmwlArHSm+W2PR1clToo - MrbT0mFTVtlbN6xFuJQar3wQz5Q9VksD+7XyPctrJdx4p5s605M5gKz8lJPSDwtGFbKboJ1blAN52vKb - PdXm80/AfDokTVu+8DfPXv9XCcIPTvjvLQ8YoakAAAAASUVORK5CYII= - - - \ No newline at end of file diff --git a/UpdateLib/TestApp/Program.cs b/UpdateLib/TestApp/Program.cs index bcb50b3..e97ee9e 100644 --- a/UpdateLib/TestApp/Program.cs +++ b/UpdateLib/TestApp/Program.cs @@ -15,13 +15,10 @@ * along with this program. If not, see . */ -using MatthiWare.UpdateLib; -using MatthiWare.UpdateLib.Common; -using MatthiWare.UpdateLib.Logging; -using MatthiWare.UpdateLib.Logging.Writers; using System; -using System.Text; using System.Windows.Forms; +using MatthiWare.UpdateLib; +using MatthiWare.UpdateLib.Common; namespace TestApp { @@ -33,27 +30,33 @@ static class Program [STAThread] static void Main() { - Console.WriteLine(Environment.CommandLine); - foreach (var s in Environment.GetCommandLineArgs()) - Console.WriteLine(s); + // UpdateVersion v1 = new UpdateVersion(1, 2, 3, VersionLabel.Alpha); + // XmlSerializer xml = new XmlSerializer(typeof(UpdateVersion)); + // xml.Serialize(Console.Out, v1); + + // Console.WriteLine(Environment.CommandLine); + // foreach (var s in Environment.GetCommandLineArgs()) + // Console.WriteLine(s); - // Environment.Exit(0); + //Environment.Exit(0); // we still want our updater to have visual styles in case of update cmd argument switch Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Updater.Instance - //.ConfigureUpdateUrl("https://raw.githubusercontent.com/MatthiWare/UpdateLib.TestApp.UpdateExample/master/Dev/updatefile.xml") - .ConfigureUpdateUrl("http://matthiware.dev/UpdateLib/Dev/updatefile.xml") - .ConfigureLogger((logger) => logger.LogLevel = LoggingLevel.Debug) - .ConfigureLogger((logger) => logger.Writers.Add(new ConsoleLogWriter())) - .ConfigureLogger((logger) => logger.Writers.Add(new FileLogWriter())) - .ConfigureUnsafeConnections(true) - .ConfigureCacheInvalidation(TimeSpan.FromSeconds(30)) - .ConfigureNeedsRestartBeforeUpdate(true) - .ConfigureInstallationMode(InstallationMode.Shared) - .Initialize(); + Updater.GetBuilder().Build().InitializeAsync().Wait(); + + //Updater.Instance + // //.ConfigureUpdateUrl("https://raw.githubusercontent.com/MatthiWare/UpdateLib.TestApp.UpdateExample/master/Dev/updatefile.xml") + // .ConfigureAddUpdateUri("http://matthiware.dev/UpdateLib/Dev/updatefile.xml") + // .ConfigureLogger((logger) => logger.LogLevel = LoggingLevel.Debug) + // .ConfigureLogger((logger) => logger.Writers.Add(new ConsoleLogWriter())) + // .ConfigureLogger((logger) => logger.Writers.Add(new FileLogWriter())) + // .ConfigureAllowUnsafeConnections(true) + // .ConfigureCacheInvalidation(TimeSpan.FromSeconds(30)) + // .ConfigureNeedsRestartBeforeUpdate(true) + // .ConfigureInstallationMode(InstallationMode.Shared) + // .Initialize(); Application.Run(new Form1()); diff --git a/UpdateLib/TestApp/Properties/AssemblyInfo.cs b/UpdateLib/TestApp/Properties/AssemblyInfo.cs index acc0ca6..ef6ceff 100644 --- a/UpdateLib/TestApp/Properties/AssemblyInfo.cs +++ b/UpdateLib/TestApp/Properties/AssemblyInfo.cs @@ -1,36 +1,10 @@ using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; + +using MatthiWare.UpdateLib.Common; // 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("TestApp")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TestApp")] -[assembly: AssemblyCopyright("Copyright © 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("7c3c0345-6d01-40a6-9f01-60d8d6451fb1")] - -// 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 Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.4.3.0")] -[assembly: AssemblyFileVersion("0.4.3.0")] +[assembly: AssemblyDescription("Test App for UpdateLib")] +[assembly: ApplicationVersion("0.5.0-alpha")] diff --git a/UpdateLib/TestApp/Properties/Resources.Designer.cs b/UpdateLib/TestApp/Properties/Resources.Designer.cs deleted file mode 100644 index 08bc180..0000000 --- a/UpdateLib/TestApp/Properties/Resources.Designer.cs +++ /dev/null @@ -1,71 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace TestApp.Properties -{ - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // 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() - { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TestApp.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [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/UpdateLib/TestApp/Properties/Resources.resx b/UpdateLib/TestApp/Properties/Resources.resx deleted file mode 100644 index af7dbeb..0000000 --- a/UpdateLib/TestApp/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/UpdateLib/TestApp/Properties/Settings.Designer.cs b/UpdateLib/TestApp/Properties/Settings.Designer.cs deleted file mode 100644 index 361ead0..0000000 --- a/UpdateLib/TestApp/Properties/Settings.Designer.cs +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace TestApp.Properties -{ - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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/UpdateLib/TestApp/Properties/Settings.settings b/UpdateLib/TestApp/Properties/Settings.settings deleted file mode 100644 index 3964565..0000000 --- a/UpdateLib/TestApp/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/UpdateLib/TestApp/TestApp.csproj b/UpdateLib/TestApp/TestApp.csproj index 91f86a9..1e541fb 100644 --- a/UpdateLib/TestApp/TestApp.csproj +++ b/UpdateLib/TestApp/TestApp.csproj @@ -1,99 +1,35 @@ - - - + - Debug - AnyCPU - {7C3C0345-6D01-40A6-9F01-60D8D6451FB1} + net472 WinExe - Properties - TestApp - TestApp - v3.5 - 512 + false - AnyCPU - true full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 + bin\$(Configuration)\ Auto - - + - AnyCPU pdbonly - true - bin\Release\ - TRACE - prompt - 4 + bin\$(Configuration)\ - + {7C3C0345-6D01-40A6-9F01-60D8D6451FB1} TestApp.Program - - app.manifest + 7.1 - - - + + + - - - - - - - Form - - - Form1.cs - - - - - - Form1.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - - - Designer - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - {4394be57-95e2-45b1-a968-1404b0590b35} - UpdateLib - + Always @@ -104,12 +40,4 @@ Always - - \ No newline at end of file diff --git a/UpdateLib/TestApp/Testing/DummyTask.cs b/UpdateLib/TestApp/Testing/DummyTask.cs deleted file mode 100644 index 8a8c447..0000000 --- a/UpdateLib/TestApp/Testing/DummyTask.cs +++ /dev/null @@ -1,48 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib; -using MatthiWare.UpdateLib.Tasks; -using System; -using System.Threading; - -namespace TestApp.Testing -{ - public class DummyTask : AsyncTask - { - protected override void DoWork() - { - for (int i = 0; i < 10; i++) - { - Enqueue(new Action(ChildWorkStuff), i); - } - } - - Random rnd = new Random(DateTime.Now.Millisecond); - - private void ChildWorkStuff(int id) - { - int waitTime = rnd.Next(1000, 5000); - - Thread.Sleep(waitTime); - - Updater.Instance.Logger.Debug(nameof(ChildWorkStuff), string.Empty, $"Task[{id.ToString("X2")}] Completed"); - } - - - } -} diff --git a/UpdateLib/TestApp/app.manifest b/UpdateLib/TestApp/app.manifest deleted file mode 100644 index a6b46bb..0000000 --- a/UpdateLib/TestApp/app.manifest +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/UpdateLib/UpdateLib.Generator/Abstractions/IPatchBuilderTask.cs b/UpdateLib/UpdateLib.Generator/Abstractions/IPatchBuilderTask.cs new file mode 100644 index 0000000..62eb8f8 --- /dev/null +++ b/UpdateLib/UpdateLib.Generator/Abstractions/IPatchBuilderTask.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace MatthiWare.UpdateLib.Generator.Abstractions +{ + public interface IPatchBuilderTask + { + Task Execute(); + } +} diff --git a/UpdateLib/UpdateLib.Generator/Core/DeltaTask.cs b/UpdateLib/UpdateLib.Generator/Core/DeltaTask.cs new file mode 100644 index 0000000..a6438e6 --- /dev/null +++ b/UpdateLib/UpdateLib.Generator/Core/DeltaTask.cs @@ -0,0 +1,28 @@ +using MatthiWare.UpdateLib.Generator.Abstractions; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace MatthiWare.UpdateLib.Generator.Core +{ + public class DeltaTask : IPatchBuilderTask + { + private readonly string CurrentFilePath; + private readonly string OldFilepath; + private readonly PatchBuilder patchBuilder; + + public DeltaTask(PatchBuilder builder, string curr, string old) + { + patchBuilder = builder; + CurrentFilePath = curr; + OldFilepath = old; + } + + public async Task Execute() + { + await Task.Delay(50); + return Task.FromResult(0); + } + } +} diff --git a/UpdateLib/UpdateLib.Generator/Data/FilesPage/GenFile.cs b/UpdateLib/UpdateLib.Generator/Data/FilesPage/GenFile.cs deleted file mode 100644 index 14edd17..0000000 --- a/UpdateLib/UpdateLib.Generator/Data/FilesPage/GenFile.cs +++ /dev/null @@ -1,68 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.IO; - -namespace MatthiWare.UpdateLib.Generator.Data.FilesPage -{ - public class GenFile : IGenItem - { - public event EventHandler Changed; - - private FileInfo m_fileInfo; - public FileInfo FileInfo - { - get { return m_fileInfo; } - set { m_fileInfo = value; Changed?.Invoke(this, EventArgs.Empty); } - } - - public string Name { get { return FileInfo?.Name ?? string.Empty; } set { Changed?.Invoke(this, EventArgs.Empty); } } - public string RealPath { get { return FileInfo?.FullName ?? string.Empty; } } - public string Extension { get { return FileInfo?.Extension ?? string.Empty; } } - public string Size { get { return ConvertBytesToSizeString(FileInfo?.Length ?? 0); } } - - public GenFolder Parent { get; set; } - - public ListViewGenItem View { get; set; } - - public GenFile(FileInfo file) - { - FileInfo = file; - - View = new ListViewGenItem(this); - } - - private static string ConvertBytesToSizeString(long size) - { - size = Math.Max(0, size); - - double kb = Math.Ceiling(size / 1024.0); - - return $"{kb.ToString("N0")} kB"; - } - - public string[] GetListViewItems() - { - return new string[] { Name, "File", FileInfo.LastWriteTime.ToString(), Size }; - } - public string GetListViewImageKey() - { - return Extension; - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/Data/FilesPage/GenFolder.cs b/UpdateLib/UpdateLib.Generator/Data/FilesPage/GenFolder.cs deleted file mode 100644 index 63ebf75..0000000 --- a/UpdateLib/UpdateLib.Generator/Data/FilesPage/GenFolder.cs +++ /dev/null @@ -1,83 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System.Collections.Generic; -using System.Linq; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.Data.FilesPage -{ - public class GenFolder - { - public string Name { get; set; } - public string PathVariable { get; set; } - public List Items { get; private set; } = new List(); - public List Directories { get; private set; } = new List(); - public GenFolder ParentFolder { get; set; } - public bool IsRoot { get { return ParentFolder == null; } } - public bool ProtectedFolder { get; set; } = false; - - public ListViewFolder FolderListView { get; set; } - public TreeViewFolderNode FolderTreeView { get; set; } - - public int Count - { - get - { - return Items.Count + Directories.Sum(d => d.Count); - } - } - - public GenFolder(string name, ContextMenuStrip menu) - { - Name = name; - - FolderListView = new ListViewFolder(name, this); - FolderTreeView = new TreeViewFolderNode(name, this); - - FolderTreeView.ContextMenuStrip = menu; - - } - - public void Add(IGenItem item) - { - item.Parent = this; - Items.Add(item); - } - - public void Add(GenFolder folder) - { - folder.ParentFolder = this; - Directories.Add(folder); - FolderTreeView.Nodes.Add(folder.FolderTreeView); - } - - public void Remove(IGenItem item) - { - Items.Remove(item); - item.View.Remove(); - } - - public void Remove(GenFolder folder) - { - Directories.Remove(folder); - FolderTreeView.Nodes.Remove(folder.FolderTreeView); - folder.FolderListView.Remove(); - } - - } -} diff --git a/UpdateLib/UpdateLib.Generator/Data/FilesPage/GenReg.cs b/UpdateLib/UpdateLib.Generator/Data/FilesPage/GenReg.cs deleted file mode 100644 index 8fb2602..0000000 --- a/UpdateLib/UpdateLib.Generator/Data/FilesPage/GenReg.cs +++ /dev/null @@ -1,118 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using Microsoft.Win32; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace MatthiWare.UpdateLib.Generator.Data.FilesPage -{ - public class GenReg : IGenItem - { - public event EventHandler Changed; - - private RegistryValueKind m_type; - public RegistryValueKind Type - { - get { return m_type; } - set - { - m_type = value; - Changed?.Invoke(this, EventArgs.Empty); - } - } - - private string m_name; - public string Name - { - get { return m_name; } - set - { - m_name = value; - Changed?.Invoke(this, EventArgs.Empty); - } - } - - private object m_value; - public object Value - { - get { return m_value; } - set - { - m_value = value; - Changed?.Invoke(this, EventArgs.Empty); - } - } - - public GenFolder Parent { get; set; } - public ListViewGenItem View { get; set; } - - public GenReg(string name, RegistryValueKind kind = RegistryValueKind.String) - { - Name = name; - Type = kind; - - View = new ListViewGenItem(this); - } - - public string[] GetListViewItems() - { - return new string[] { Name, GetTypeName(), Value?.ToString() ?? string.Empty }; - } - - private string GetTypeName() - { - switch (Type) - { - case RegistryValueKind.ExpandString: - return "REG_EXPANDED_SZ"; - case RegistryValueKind.MultiString: - return "REG_MULTI_SZ"; - case RegistryValueKind.Binary: - return "REG_BINARY"; - case RegistryValueKind.DWord: - return "REG_DWORD"; - case RegistryValueKind.QWord: - return "REG_QWORD"; - case RegistryValueKind.String: - case RegistryValueKind.Unknown: - default: - return "REG_SZ"; - } - } - - public string GetListViewImageKey() - { - switch (Type) - { - case RegistryValueKind.String: - case RegistryValueKind.ExpandString: - case RegistryValueKind.MultiString: - return "REG_SZ"; - case RegistryValueKind.Binary: - case RegistryValueKind.DWord: - case RegistryValueKind.QWord: - case RegistryValueKind.Unknown: - default: - return "REG_BIN"; - } - } - - } -} diff --git a/UpdateLib/UpdateLib.Generator/Data/FilesPage/IGenItem.cs b/UpdateLib/UpdateLib.Generator/Data/FilesPage/IGenItem.cs deleted file mode 100644 index 5ad1db5..0000000 --- a/UpdateLib/UpdateLib.Generator/Data/FilesPage/IGenItem.cs +++ /dev/null @@ -1,34 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; - -namespace MatthiWare.UpdateLib.Generator.Data.FilesPage -{ - public interface IGenItem - { - event EventHandler Changed; - - string Name { get; set; } - GenFolder Parent { get; set; } - ListViewGenItem View { get; set; } - - string[] GetListViewItems(); - string GetListViewImageKey(); - - } -} diff --git a/UpdateLib/UpdateLib.Generator/Data/ListViewFolder.cs b/UpdateLib/UpdateLib.Generator/Data/ListViewFolder.cs deleted file mode 100644 index 8acfcd9..0000000 --- a/UpdateLib/UpdateLib.Generator/Data/ListViewFolder.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Generator.Data.FilesPage; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.Data -{ - public class ListViewFolder : ListViewItem - { - internal const string FOLDER_KEY = "folderimagekey"; - - public GenFolder Folder { get; set; } - - private ListViewFolder(string[] items, string imageKey) - : base(items, imageKey) - { } - - public ListViewFolder(string folderName, GenFolder folder) - : this(new string[] { folderName, "Folder", string.Empty, string.Empty }, FOLDER_KEY) - { - Folder = folder; - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/Data/ListViewGenItem.cs b/UpdateLib/UpdateLib.Generator/Data/ListViewGenItem.cs deleted file mode 100644 index dc4d66f..0000000 --- a/UpdateLib/UpdateLib.Generator/Data/ListViewGenItem.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Generator.Data.FilesPage; -using System; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.Data -{ - public class ListViewGenItem : ListViewItem - { - public IGenItem Item { get; set; } - - public ListViewGenItem(IGenItem item) - : base(item.GetListViewItems(), item.GetListViewImageKey()) - { - Item = item; - Item.Changed += Item_Changed; - } - - private void Item_Changed(object sender, EventArgs e) - { - string[] items = Item.GetListViewItems(); - - for (int i = 0; i < items.Length; i++) - SubItems[i].Text = items[i]; - - ImageKey = Item.GetListViewImageKey(); - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/Data/TreeViewFolderNode.cs b/UpdateLib/UpdateLib.Generator/Data/TreeViewFolderNode.cs deleted file mode 100644 index 231418e..0000000 --- a/UpdateLib/UpdateLib.Generator/Data/TreeViewFolderNode.cs +++ /dev/null @@ -1,40 +0,0 @@ -using MatthiWare.UpdateLib.Generator.Data.FilesPage; -using System; -using System.Collections.Generic; -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.Data -{ - public class TreeViewFolderNode : TreeNode - { - internal const string FOLDER_KEY = "folderimagekey"; - - public GenFolder Folder { get; set; } - - public TreeViewFolderNode(string folderName, GenFolder folder, string imageKey = FOLDER_KEY) - { - Text = folderName; - ImageKey = imageKey; - SelectedImageKey = imageKey; - Folder = folder; - } - - } -} diff --git a/UpdateLib/UpdateLib.Generator/Generator_logo.ico b/UpdateLib/UpdateLib.Generator/Generator_logo.ico deleted file mode 100644 index e51a992..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Generator_logo.ico and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/MainForm.Designer.cs b/UpdateLib/UpdateLib.Generator/MainForm.Designer.cs deleted file mode 100644 index d874028..0000000 --- a/UpdateLib/UpdateLib.Generator/MainForm.Designer.cs +++ /dev/null @@ -1,330 +0,0 @@ -namespace MatthiWare.UpdateLib.Generator -{ - partial class MainForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("General Information"); - System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Files"); - System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("Registry"); - System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("Project", new System.Windows.Forms.TreeNode[] { - treeNode1, - treeNode2, - treeNode3}); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.splitContainer = new System.Windows.Forms.SplitContainer(); - this.tvProject = new System.Windows.Forms.TreeView(); - this.lvItems = new System.Windows.Forms.ListView(); - this.clmnName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnDate = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnPath = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.menuStrip = new System.Windows.Forms.MenuStrip(); - this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.statusStrip = new System.Windows.Forms.StatusStrip(); - this.lblStatus = new System.Windows.Forms.ToolStripStatusLabel(); - this.progressBar = new System.Windows.Forms.ToolStripProgressBar(); - this.toolStrip = new System.Windows.Forms.ToolStrip(); - this.newToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.openToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.saveToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); - this.buildToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.splitContainer.Panel1.SuspendLayout(); - this.splitContainer.Panel2.SuspendLayout(); - this.splitContainer.SuspendLayout(); - this.menuStrip.SuspendLayout(); - this.statusStrip.SuspendLayout(); - this.toolStrip.SuspendLayout(); - this.SuspendLayout(); - // - // splitContainer - // - this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.splitContainer.Location = new System.Drawing.Point(0, 52); - this.splitContainer.Name = "splitContainer"; - // - // splitContainer.Panel1 - // - this.splitContainer.Panel1.Controls.Add(this.tvProject); - // - // splitContainer.Panel2 - // - this.splitContainer.Panel2.Controls.Add(this.lvItems); - this.splitContainer.Size = new System.Drawing.Size(968, 308); - this.splitContainer.SplitterDistance = 352; - this.splitContainer.TabIndex = 0; - // - // tvProject - // - this.tvProject.Dock = System.Windows.Forms.DockStyle.Fill; - this.tvProject.Location = new System.Drawing.Point(0, 0); - this.tvProject.Name = "tvProject"; - treeNode1.Name = "nodeInfo"; - treeNode1.Text = "General Information"; - treeNode2.Name = "nodeFiles"; - treeNode2.Text = "Files"; - treeNode3.Name = "nodeRegistry"; - treeNode3.Text = "Registry"; - treeNode4.Name = "root"; - treeNode4.Text = "Project"; - this.tvProject.Nodes.AddRange(new System.Windows.Forms.TreeNode[] { - treeNode4}); - this.tvProject.Size = new System.Drawing.Size(352, 308); - this.tvProject.TabIndex = 0; - this.tvProject.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvProject_AfterSelect); - // - // lvItems - // - this.lvItems.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.clmnName, - this.clmnDate, - this.clmnPath}); - this.lvItems.Dock = System.Windows.Forms.DockStyle.Fill; - this.lvItems.FullRowSelect = true; - this.lvItems.Location = new System.Drawing.Point(0, 0); - this.lvItems.MultiSelect = false; - this.lvItems.Name = "lvItems"; - this.lvItems.Size = new System.Drawing.Size(612, 308); - this.lvItems.TabIndex = 0; - this.lvItems.UseCompatibleStateImageBehavior = false; - this.lvItems.View = System.Windows.Forms.View.Details; - this.lvItems.DoubleClick += new System.EventHandler(this.lvItems_DoubleClick); - // - // clmnName - // - this.clmnName.Text = "Name"; - this.clmnName.Width = 139; - // - // clmnPath - // - this.clmnPath.Text = "Path"; - // - // menuStrip - // - this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.fileToolStripMenuItem, - this.helpToolStripMenuItem}); - this.menuStrip.Location = new System.Drawing.Point(0, 0); - this.menuStrip.Name = "menuStrip"; - this.menuStrip.Size = new System.Drawing.Size(968, 24); - this.menuStrip.TabIndex = 1; - this.menuStrip.Text = "menuStrip1"; - // - // fileToolStripMenuItem - // - this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.newToolStripMenuItem, - this.openToolStripMenuItem, - this.saveToolStripMenuItem, - this.toolStripSeparator1, - this.exitToolStripMenuItem}); - this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; - this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); - this.fileToolStripMenuItem.Text = "File"; - // - // newToolStripMenuItem - // - this.newToolStripMenuItem.Name = "newToolStripMenuItem"; - this.newToolStripMenuItem.Size = new System.Drawing.Size(103, 22); - this.newToolStripMenuItem.Text = "New"; - // - // openToolStripMenuItem - // - this.openToolStripMenuItem.Name = "openToolStripMenuItem"; - this.openToolStripMenuItem.Size = new System.Drawing.Size(103, 22); - this.openToolStripMenuItem.Text = "Open"; - // - // saveToolStripMenuItem - // - this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - this.saveToolStripMenuItem.Size = new System.Drawing.Size(103, 22); - this.saveToolStripMenuItem.Text = "Save"; - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(100, 6); - // - // exitToolStripMenuItem - // - this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - this.exitToolStripMenuItem.Size = new System.Drawing.Size(103, 22); - this.exitToolStripMenuItem.Text = "Exit"; - // - // helpToolStripMenuItem - // - this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); - this.helpToolStripMenuItem.Text = "Help"; - // - // statusStrip - // - this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.lblStatus, - this.progressBar}); - this.statusStrip.Location = new System.Drawing.Point(0, 363); - this.statusStrip.Name = "statusStrip"; - this.statusStrip.Size = new System.Drawing.Size(968, 22); - this.statusStrip.TabIndex = 2; - this.statusStrip.Text = "statusStrip1"; - // - // lblStatus - // - this.lblStatus.Name = "lblStatus"; - this.lblStatus.Size = new System.Drawing.Size(39, 17); - this.lblStatus.Text = "Ready"; - // - // progressBar - // - this.progressBar.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; - this.progressBar.Maximum = 110; - this.progressBar.Name = "progressBar"; - this.progressBar.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.progressBar.Size = new System.Drawing.Size(100, 16); - // - // toolStrip - // - this.toolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; - this.toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.newToolStripButton, - this.openToolStripButton, - this.saveToolStripButton, - this.toolStripSeparator, - this.buildToolStripButton}); - this.toolStrip.Location = new System.Drawing.Point(0, 24); - this.toolStrip.Name = "toolStrip"; - this.toolStrip.Size = new System.Drawing.Size(968, 25); - this.toolStrip.TabIndex = 3; - this.toolStrip.Text = "toolStrip1"; - // - // newToolStripButton - // - this.newToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.newToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("newToolStripButton.Image"))); - this.newToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.newToolStripButton.Name = "newToolStripButton"; - this.newToolStripButton.Size = new System.Drawing.Size(23, 22); - this.newToolStripButton.Text = "&New"; - // - // openToolStripButton - // - this.openToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.openToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripButton.Image"))); - this.openToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.openToolStripButton.Name = "openToolStripButton"; - this.openToolStripButton.Size = new System.Drawing.Size(23, 22); - this.openToolStripButton.Text = "&Open"; - // - // saveToolStripButton - // - this.saveToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.saveToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripButton.Image"))); - this.saveToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.saveToolStripButton.Name = "saveToolStripButton"; - this.saveToolStripButton.Size = new System.Drawing.Size(23, 22); - this.saveToolStripButton.Text = "&Save"; - // - // toolStripSeparator - // - this.toolStripSeparator.Name = "toolStripSeparator"; - this.toolStripSeparator.Size = new System.Drawing.Size(6, 25); - // - // buildToolStripButton - // - this.buildToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buildToolStripButton.Image = global::MatthiWare.UpdateLib.Generator.Properties.Resources.gears; - this.buildToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buildToolStripButton.Name = "buildToolStripButton"; - this.buildToolStripButton.Size = new System.Drawing.Size(23, 22); - this.buildToolStripButton.Text = "C&ut"; - this.buildToolStripButton.Click += new System.EventHandler(this.buildToolStripButton_Click); - // - // MainForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(968, 385); - this.Controls.Add(this.toolStrip); - this.Controls.Add(this.statusStrip); - this.Controls.Add(this.splitContainer); - this.Controls.Add(this.menuStrip); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.Name = "MainForm"; - this.Text = "Update Generator"; - this.Load += new System.EventHandler(this.MainForm_Load); - this.splitContainer.Panel1.ResumeLayout(false); - this.splitContainer.Panel2.ResumeLayout(false); - this.splitContainer.ResumeLayout(false); - this.menuStrip.ResumeLayout(false); - this.menuStrip.PerformLayout(); - this.statusStrip.ResumeLayout(false); - this.statusStrip.PerformLayout(); - this.toolStrip.ResumeLayout(false); - this.toolStrip.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.SplitContainer splitContainer; - private System.Windows.Forms.MenuStrip menuStrip; - private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; - private System.Windows.Forms.StatusStrip statusStrip; - private System.Windows.Forms.ToolStripStatusLabel lblStatus; - private System.Windows.Forms.ToolStrip toolStrip; - private System.Windows.Forms.ToolStripButton newToolStripButton; - private System.Windows.Forms.ToolStripButton openToolStripButton; - private System.Windows.Forms.ToolStripButton saveToolStripButton; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator; - private System.Windows.Forms.ToolStripButton buildToolStripButton; - private System.Windows.Forms.TreeView tvProject; - private System.Windows.Forms.ToolStripProgressBar progressBar; - private System.Windows.Forms.ListView lvItems; - private System.Windows.Forms.ColumnHeader clmnName; - private System.Windows.Forms.ColumnHeader clmnDate; - private System.Windows.Forms.ColumnHeader clmnPath; - } -} - diff --git a/UpdateLib/UpdateLib.Generator/MainForm.cs b/UpdateLib/UpdateLib.Generator/MainForm.cs deleted file mode 100644 index 3722220..0000000 --- a/UpdateLib/UpdateLib.Generator/MainForm.cs +++ /dev/null @@ -1,170 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.ComponentModel; -using System.Drawing; -using System.IO; -using System.Windows.Forms; -using MatthiWare.UpdateLib.Generator.Tasks; -using MatthiWare.UpdateLib.UI; - -namespace MatthiWare.UpdateLib.Generator -{ - public partial class MainForm : Form - { - - private DirectoryInfo applicationFolder = new DirectoryInfo("./ApplicationFolder"); - private DirectoryInfo outputFolder = new DirectoryInfo("./Output"); - - private ImageList iconList; - - public MainForm() - { - InitializeComponent(); - - if (!applicationFolder.Exists) - applicationFolder.Create(); - - if (!outputFolder.Exists) - outputFolder.Create(); - - iconList = new ImageList(); - iconList.ImageSize = new Size(24, 24); - lvItems.SmallImageList = iconList; - - LoadFolder(applicationFolder); - } - - private LoadDirectoryTask LoadFolder(DirectoryInfo path) - { - if (path == null) throw new ArgumentNullException(nameof(path)); - if (!path.Exists) throw new DirectoryNotFoundException($"The directory '{path.FullName}' was not found."); - - LoadDirectoryTask task = new LoadDirectoryTask(lvItems, iconList, path); - task.Start(); - - return task; - } - - private void Generate() - { - - UpdateGeneratorTask generator = new UpdateGeneratorTask(null, null, null); - - generator.TaskCompleted += Generator_TaskCompleted; - generator.TaskProgressChanged += Generator_TaskProgressChanged; - - SetProgressBarValue(0); - SetProgressBarVisible(true); - SetWaitCursor(true); - - SetStatusMessage("Generating..."); - - generator.Start(); - } - - private void SetWaitCursor(bool val) - { - this.InvokeOnUI(() => UseWaitCursor = val); - } - - private void SetProgressBarVisible(bool val) - { - this.InvokeOnUI(() => progressBar.Visible = val); - } - - private void SetProgressBarValue(int val) - { - this.InvokeOnUI(() => progressBar.Value = val); - } - - private void SetStatusMessage(string msg) - { - this.InvokeOnUI(() => lblStatus.Text = msg); - } - - private void Generator_TaskProgressChanged(object sender, ProgressChangedEventArgs e) - { - SetStatusMessage($"Generating {e.ProgressPercentage}%"); - SetProgressBarValue(e.ProgressPercentage); - } - - private void Generator_TaskCompleted(object sender, AsyncCompletedEventArgs e) - { - string filePath = string.Concat(outputFolder.FullName, "\\", "updatefile.xml"); - - UpdateGeneratorTask gen = (UpdateGeneratorTask)sender; - - gen.Result.Save(filePath); - - SetProgressBarValue(110); - - SetStatusMessage("Build completed"); - } - - private void MainForm_Load(object sender, EventArgs e) - { - tvProject.ExpandAll(); - tvProject.SelectedNode = tvProject.Nodes["root"].Nodes["nodeInfo"]; - } - - private void tvProject_AfterSelect(object sender, TreeViewEventArgs e) - { - switch (e.Node.Name) - { - case "nodeInfo": - default: - - break; - case "nodeFiles": - - break; - case "nodeRegistry": - - break; - } - } - - private void buildToolStripButton_Click(object sender, EventArgs e) - { - Action generateAction = new Action(Generate); - - generateAction.BeginInvoke(new AsyncCallback(r => - { - SetWaitCursor(false); - //SetProgressBarVisible(false); - generateAction.EndInvoke(r); - }), null); - } - - private void lvItems_DoubleClick(object sender, EventArgs e) - { - if (lvItems.SelectedItems.Count == 0) - return; - - ListViewItem item = lvItems.SelectedItems[0]; - - DirectoryInfo dir = item.Tag as DirectoryInfo; - - if (dir == null) - return; - - LoadFolder(dir); - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/MainForm.resx b/UpdateLib/UpdateLib.Generator/MainForm.resx deleted file mode 100644 index f650a4c..0000000 --- a/UpdateLib/UpdateLib.Generator/MainForm.resx +++ /dev/null @@ -1,2964 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 132, 17 - - - 248, 17 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAERSURBVDhPrZDbSgJRGIXnpewd6jXsjSQvIrwoI0RQMChU - 0iiDPCGiE3ZCRkvR8VzTeBhnyR5/ccaZNnPhB4t9sdf6Ln5hb8QeathNJFVFKF5C8DqL4ksDVHWGDf7j - LHyPg6NjviSaFqlu5yQYR+KpupaIkrMknCxT3Y7v/NYYb0ITK1c3BarbWWhLQ7IR0cTKReyZ6lZ0XYei - ztHpK4bAc+h1FgQijzSxMptrGIxVSO0xX3AaStFki7bUMVFmaMm/eJMGfIH/MkGzLep0AXn4h/r3CJV3 - mS9gn2bY4UY/UzQ7E9TqfeTFtnuB+XAfzSHKr11kSl/uBebDiZ89ZCst3OUkdwL28sIVsE83ock+EIQV - 2Mz2wxeg6/UAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJHSURBVDhPxZBdSNNhFMb/F110ZZEVhVBgeeHNICiiuggp - olAUyyxI0oSaH1QYC3N+tKnp5ubm1JUua5uuqdNKMwr7kApFItTUkWZqVhSVYmao5Nevvy7UoYR3HXh4 - 4XCe33nOKyy3lAY7l9RWMo0O/raWXxEyo5spVYTNvOGyfIRPfW+ptOkXqaPl6T83hcRmExSdgzAz3NVm - YWyoYla/B+1M9JtxWLPpaH22JORIjI6gKAMB0jyEimIdo4OlbuaprwVMOOMovammpDADc34qppwUrmnl - 5Kni3aFlFg2j3y1z5mnRTJccnNIltQhwq0jFry+mOXNtpWZWDx1Z1NhV3C3JwGFOw25SYjVe5oYhiUKd - HKMmwQUrMWUw/CF3NnZvvYKqUh1TvUroS3fXe7HXkwidMngTS2t5KLbregSzMY2f3Wr4qKW6LJvGR1rX - 0MLor8OhKYTJBn/GHvvxrliCTBrsOqXIoOBHh5K+hmSq7FqmexTQHuUytkaKxuNMNgYyVneA4Qd7GKjc - hjLaRzxH7gIU6JIZaEvgtk1D8wsxSWecCDgNzWFMvwxm/PkhRmr3Mli1nW9lvjRdWc0Jf+/5jzRmyWmv - S+GOLQu6U6BFjPvqKOP1AYw88WOoZif9DgmfLVtxaj1RSLdwNvrkPCA3M54KqxrnvRia9MKcGrUrqFOt - 5H7qKsqT1mGO9+Lqhc2ELdw+U/r0i+gVZ8hMiCDx3DHORwZyKnQ/hw/uYt9uCTskPvh6e7Fp41rWr/Fg - g6eHO+A/lyD8ARfG3mk9fv1YAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIySURBVDhPrZLfS5NRGMfff6H7boIuuq2pMZyL1eAt11CW - DcOKsB9vpFmaLtNExco0av6CbIVLJ61Wk3BSkT/AFCkRZSpZmrmiJQ41xSaCwdfznL15XEUX0Reem5f3 - 8znnec4j/Zc8fxYGla91CS3eRTx0z6OpMYS7jmnU1X6B/VYA18snUVoyjsKCt8jLHcH5c36ouCQR2NUJ - 1Nas4G9ZXlmFKbULh1Kf8lJxSfI+WeCCyopv6q+/h+DQ/DJ2WV5Ao1FgPegRAveDOS4oLfmq/h6dn/DH - 4AJizD4UXJrCAUuzEDgbZrjgou2DiohshIcnQtgme5GTPYbkJKcQ1N8OckHW2REVi+RXuM8fxGaDG4oy - ALPZIQQ11Z+5QDk1oKJ/hjv7P2FTfCMOH3mFxMQ6IbhROYWOdrCnBI4dfwPr0V4+bRoY9UzXppMjcDdS - rC8hy3YhuFI2gTYf2A4Aza4f7N2/o/zaLB8qDYx6zszwr8P7k1thNFYIweXCMXgeAfedq2xxwjClZUeV - Jd2GtDNFETiJwfs8MBjKhMCWN8pgoLoqzE8miH1GjE7G4PsZjE7OQsm9ij2mFg7rdrug1xcJAa2l4w7W - r00Cgk/n38S7wBwC04u4UGxHrMHF4CbEJtyDLj5fCDIzhljfSxzeavRgyw4Zj9t64GvvQ0d3P3pfD2Kv - 2QqNvgFxDN6urYdWmyMElJMnevh60obRktA701PRtGlg1DOdSkXwzrisaMG/RZLWAE60OMW5fNhvAAAA - AElFTkSuQmCC - - - - - AAABAA0AAAAAAAEAIADedwAA1gAAAICAAAABACAAKAgBALR4AACAgAAAAQAIAChMAADcgAEAQEAAAAEA - IAAoQgAABM0BAEBAAAABAAgAKBYAACwPAgAwMAAAAQAgAKglAABUJQIAMDAAAAEACACoDgAA/EoCACAg - AAABACAAqBAAAKRZAgAgIAAAAQAIAKgIAABMagIAGBgAAAEAIACICQAA9HICABgYAAABAAgAyAYAAHx8 - AgAQEAAAAQAgAGgEAABEgwIAEBAAAAEACABoBQAArIcCAIlQTkcNChoKAAAADUlIRFIAAAEAAAABAAgG - AAAAXHKoZgAAAAFzUkdCAK7OHOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA7DAAAOwwHHb6hkAAB3 - c0lEQVR4Xu2dBVhW2faHv3unx8BOQro7xcCgEbu7UClpkBKxW8QWGxNFsVvsbkWxO8accRxnDFj/vTYc - Z3vu8htn7vxn4M5Zz/M+IiUzfO/vrB1nH5VSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSiml - lFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSiml - 1H9f/8rKyvps06ZNX50+fbrM9u3bNdasWVNBoWQxf/78D5g0aVKF0aNHa4wZM6Zc165dy3h7e3/Ffpef - M/6Nv1P8xSql1G8Wyj9r1qxvWQBU3b9/v/6RI0fMd+zYYbVlyxZrZMOGDTYKfx1MdhL2e+IsX77cetGi - RdYLFiywmj59ugULAOOgoCAdFgBVzczMyrJf6ZeMz/gvVymlfqvY1eRr9sKrcerUKZvr16+3uHXrVs9r - 1671zs/P74tcuHAhQOGv4/z58x9w5syZAPa7CTh+/HgAC2ek78GDB/vu27ev99atW3uuXbu205IlS/xZ - GDSIj483adeuXY3iIMBuQOkElFJf7OpSgb2gLK9evdrx6dOnk3744YdV7M/VjDXI8+fPcxT+Otj/c86T - J09yHj16lPPdd9/l3L9/P+fOnTs5t2/fzmHhvAZh4Zx99uzZlceOHcs8cODA9M2bNyezEOgYERHhwroB - Tfar/ZahhIBSautf2Pqzq0l9duWPfPHixdbXr19f++WXX67/9NNPN5Cff/75psJfx8uXLzk//vjjTfb7 - 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 - +1jzWexrJ3iMNY9tPFq/Pf4b+G/hv2nJrvZ8TV8Z4yul1N9e/27HWu9ms4yqeM+wMfOdatvQd7JNC990 - 656+adYRPmnWqYzJPpOsFvim2azxnmi93meCdbbvJKslPhOt53hPtJrinWYz1meS9RDvydZxvlNsQ30m - 2/T1Tbfp1Gyarb/vVCtn36lmNfDfwH+r6J9USimlSk6xK3G7LLMvvScblG82y74K7lHwmmRdxy/NxtBr - orW57yRrGya5IwsGVyZ9Pa9JFnVZADj7TLRw8B5vZeudZmHlPdnGzGuSpbHnVFsDj3QrXc9p5lpeM+1q - ek4wq+SWoqNc7ZVSSimllFJKKaWUUkoppZRSSimllFJKqZJaKtX/Aeh2VQku+EUoAAAAAElFTkSuQmCC - KAAAAIAAAAAAAQAAAQAgAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKpRVDDGYTUgxkkt2MJJLojCQSc0wkEr0MI9K4y+QSsswkEqy - MJJKmTGTS4Aylk1fKpRVDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIIhLROBMZoggjz2 - K4NC/ymCQP8mgj//JYVA/yWJQP8lh0D/JYdA/yaEQP8mgj//KIE//yqDQf8ggjz2E4MzmQCFIiwAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAHofURN9MMcbezb/JH48/yGFPP8lj0P/PKBW/1SsbP9ntn3/cryH/2m2fv9itHr/ - WrFy/1Stbf9NqWb/NphR/yWGQP8mfz3/G3s2/xF9L8cLgypbAH8qBgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8mFBN/MK4ZdzT/In06/x6GOv9MqGP/ - iMaZ/6XUsv+cz6r/lMuk/43Hnf+JxJn/hMKU/4DAkv99vo3/ebyL/3a7if90u4f/abd//0+pZf8zkE3/ - JX49/yd8Pv8fgjrTD4suIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAxlEuLAH8kDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAl/KlQcfTbuIXc4/yOJP/9itnr/ntCr/6XTsv+Zzaf/kMig/4rFmv+Gw5f/gsGT/36/j/96vYz/ - druI/3K5hf9ut4L/arV+/2aze/9ksnn/YrJ4/2Gzd/9asHL/OphT/yd7Pv8dezbzBoEoSwAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2GRf8dfDfu - FYc1aQB/AAIAAAAAAAAAAAAAAAAAAAAAAAAAAACqAAMTfjGhF3Iv/x56Nv8+nlj/otOv/6fUs/+bzan/ - k8mi/47Hnv+LxZr/iMSZ/4bDlv+DwZX/gMCT/3y+jv92u4r/cbiE/2u2f/9ms3v/YrF3/16vdP9arXD/ - Vqtt/1SqbP9Tq2v/QqJb/yd9Pv8adDP9FYIwgwD/AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALIRE/yd3PP8mdjv/HH031AeBK0EAAAAAAAAAAAAAAAAAfz8E - HoM6ryFyNv8fgzr/b7uD/6/au/+i0bD/mM2m/5TLo/+QyKD/kcig/5LJof+FwpX/c7mG/2OxeP9Tqmr/ - Uqlo/1uucv9jsnn/aLV+/2q1ff9isXj/XK5x/1arbf9SqWr/Tqdm/0ulZP9Jp2L/QaJd/y2GRv8ndTv/ - H4I5ug+PLxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgkP+ - LIlG/zuXVv8YbS7/FW0s/w95LbMPjy8gM5kzBR+BOrMebzT/KodC/57Sq/+s1rj/n8+s/5jMpf+XzKX/ - mM2m/5TKo/9ntHz/OZ5V/yWUQ/8plkb/K5dI/y2YSv8tmEr/LZhK/yyXSf8rl0j/K5ZJ/0KjXf9YrW7/ - Vqtt/0+oZ/9KpWP/RqRf/0KiXP8/oln/PaNY/y6NSf8mczv/HX44xwB/PwQAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACuBQf0yiEn/8v70/3/Dkf8bfTb/GWov/yR0O/srgkLT - HWsy/yeHQ/+k1rL/qta2/5zNqv+Zzab/ms6o/5jNp/9XrG//J5RE/yqWR/8wmUz/M5tP/zSbUP80m1D/ - NJtQ/zSbUP80m1D/NJtQ/zSbUP8zm0//MZpN/y6YS/8+n1j/SaVj/0elYP9Colz/PqBY/zqeVf82nVL/ - NZ9S/y+PSv8lbjn/En0vlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - Kn5A/SyDRf/f8+T/y+fS/8Hjyv9XrG7/FXQw/xNiKP8phkL/p9az/6rWtv+dz6r/nM6p/57Qq/9+wJH/ - MplP/yuXSP8xmk7/NJtQ/zScUP81nVH/NZ5R/zagU/82olP/NqNU/zajVP82olP/NqBS/zWeUf80nFD/ - M5tP/zKaTv8zm1D/QKFb/z+hWf86nlX/NZxS/zObT/80nFD/NqBT/yyERP8XaC7/CH4mXQAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqfT/8LoNF/9Xu3f+53MP/u97F/8Hiyv+g067/ - Q6Fc/6TWsv+q1rb/nc+q/5zOqv+i0a//V61v/yaURP8vmUz/M5tP/zScUP81nVH/NqBT/zSdUf8wkUr/ - K4BD/yVvOf8jaTb/JW44/yZ0O/8qfkH/MZVN/zaiVP81n1L/NJxQ/zObT/8ymk7/O59W/zecUv8zm0// - NJtQ/zSbUP81nVH/NaBS/yZ1Pf8YbDD5C4UsLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAACh7QPsxgkj/0OzY/7Tav/+w2Lv/r9e6/7HYuv+u1rn/ptSz/53Pqv+dzqr/n9Ct/02oZv8plkb/ - MZpO/zSbUP80nFD/NZ9S/zWeUf8qfED/IWQz/yJnNf8YbzH5DXEpvwFtH5oBah6xDm0nyBltL/ogZTT/ - JXA6/y+PSv82oVP/NZ1R/zSbUP8zm1D/M5tQ/zSbUP80m1D/NJtQ/zSbUP81nlH/NJ1R/yRsN/8acjLj - EYgzDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKHk++zGBSf/L6tX/sNi7/63WuP+p1LT/ - pdKx/6HQrv+dzqr/ns6r/57Oq/9GpF//KpZH/zKaTv80nFD/NZ1R/zahU/8xlEz/Imo2/xdjLP0ReS2d - C4svQAB/KgYAAAAAAAAAAAAAAAAAAAAAAI0qEhN/L3YZbjDfIWEz/yuBQv81oVL/NZ5R/zScUP80m1D/ - NJtQ/zSbUP80m1D/NJxQ/zWdUf83pFX/MJFK/yJkNP8cdzS8AP8AAQAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAE - AAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAH - AAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAH - AAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAH - AAAABwAAAAcneD76NYJJ/8jo0f+t1rj/qdS0/6XSsf+h0K7/nc6q/5vNqf+i0K7/T6dn/yqWR/8ym0// - NJtQ/zWeUf81n1L/Kn9B/yBgMv8ZbzDnB3spRAAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAG - AAAAAwB/HwgQcyyoFFwn/yZyOv80nVH/NZ5R/zSbUP80m1D/NJtQ/zScUf82n1L/NaFT/yyERP8gYzL/ - F2Ur+hF4LYEAfwAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAADwAAACUAAAA1AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4 - AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4 - AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4 - AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOCV1O/s2gUr/w+fO/6nVtf+l07L/ - odCu/53Oqv+azKj/ns6r/3C5hP8nlUX/MppO/zSbUP80m1D/NZ5R/yd0O/8fXC//J3Q8/RpmL3UAAAA4 - AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAANwAAAC8AAAAbAAAABwAAAAAGdSNzFF8o/SRuOf81olP/ - NZ1R/zScUP81nlL/N6JU/zCSS/8jZzX/Elkm/w1vKb4Afx4iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOlpaVE - 1NTUtMfHx77GxsbBxsbGwcbGxsHExMTBxMTEwcTExMHExMTBw8PDwcPDw8HDw8PBw8PDwcPDw8HDw8PB - w8PDwcPDw8HDw8PBw8PDwcPDw8HCwsLBwsLCwcLCwsHCwsLBwMDAwcDAwMHAwMDBwMDAwb+/v8G/v7/B - v7+/wb+/v8G/v7/Bv7+/wb+/v8G/v7/Bv7+/wb+/v8G/v7/Bv7+/wb6+vsG+vr7Bvr6+wb6+vsG+vr7B - vLy8wby8vMG8vLzBKXY+/jd/S/++5Mj/pdOy/6HRrv+dz6v/mc6n/5zNqP+KxZr/KJVF/zCZTf80m1D/ - NJtQ/zSbUP81nVH/NqJU/y2JRv8gYDL/E1om/zaBS+2csaLJurq6wbq6usG5ubnAurq6wbq6usG5ubnA - vLy8uQ8PD0QAAAASAAAAAQAAAAAEdSRvEVYj/yt+Qf83o1T/NqJT/zSeUf8mdDv/HVgt/xhqLesFfCZW - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLu7u2L39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/ - 9fX1//X19f/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/ - 8fHx//Dw8P/w8PD/8PDw//Dw8P/v7+//7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/7u7u/+7u7v/t7e3/ - 7e3t/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6/8qdT//OH5M/7nixf+h0a7/ - nc+r/5nNp/+Zzaj/m8yo/zSbUP8umEv/NJtQ/zSbUP80m1D/NJtQ/zSbUP81nVH/NqBS/zaiU/8pfUD/ - HVku/xhiK/9vqH7/3eLe/+fn5//n5+f/5+fn/+fn5//j4+P8ExMTXQAAABoAAAACAAAAAAAAAAAObyiw - HFUt/zGSS/8thkX/H1ou/xNaJ/0RdSyUAIsuCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF - ubm5Y/f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0//T09P/09PT/ - 9PT0//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/ - 8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+zs7P/s7Oz/ - 7Ozs/+zs7P/r6+v/6+vr/yt1P/85fkv/tODA/53Pq/+Zzaf/l82m/53Pq/9Mp2T/K5dI/zObT/80m1D/ - NJtQ/zSbUP80m1D/NJtQ/zSbUP80nFD/NqFT/zmpWP8vj0n/Hlgt/w9QIP9RmmX/5ubm/+fn5//n5+f/ - 5+fn/+Pj4/wSEhJiAAAAGwAAAAIAAAAAAAAAAAB/KgwWZy3iHVQr/xxWLf8YbTDNC4UsLgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAZA8hK4JCpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW5ublj9/f3//f39//39/f/9vb2//b29v/29vb/ - 9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/ - 8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/ - 7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/KnM+/zp8Sv+x3r3/ - ms2o/5bMpf+azqj/a7Z//yiVRv8ymk7/NJtQ/zSbUP80m1D/NJtQ/zSbUP80nFD/NZ5R/zeiVP80m0// - JGs2/xpQKP8tdED/nsSp/+fn5//n5+f/5+fn/+fn5//n5+f/4+Pj/BISEmIAAAAbAAAAAgAAAAAAAAAA - AAAAAAV/Ji4IYSDnE30xaAD/AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXx8ID3MohBt3Nfgqf0Hy - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAABbm5uWP4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//X19f/19fX/9fX1//X19f/09PT/ - 9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/ - 8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/ - 7e3t/+zs7P/s7Oz/7Ozs/+zs7P8rcj7/OntL/6zcuf+Wy6X/l8ul/4zHm/8mlUX/MJpN/zSbUP80m1D/ - NJtQ/zSbUP80m1D/NZ1R/zahU/81oVP/J3c+/xlMJ/8YXCv/fK+K/+Ll4//o6Oj/6Ojo/+fn5//n5+f/ - 5+fn/+fn5//j4+P8EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAB/AAIAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAGkbVRR0LeQvgEb/JXk7/yh7QPMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFubm5Y/j4+P/4+Pj/9/f3//f39//39/f/ - 9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/8/Pz//Pz8//z8/P/ - 8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+// - 7+/v/+7u7v/u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/7Ozs/ytxPv86eUz/ - p9q2/5PKov+Zzaj/SaZi/y2YSv80m1D/NJtQ/zSbUP80m1D/NJxR/zagUv84plb/K4RE/xtRKv8PTSD/ - VJNl/9Lf1f/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+fn5//n5+f/5+fn/+Pj4/wSEhJiAAAAGwAAAAIAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGMSKQZuIr4JbCT/X5Nv/4K0kP8jejz/ - J3k99AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAW5ublj+Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/ - 9fX1//X19f/19fX/9PT0//T09P/09PT/9PT0//Pz8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/ - 8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/ - 7u7u/+3t7f/t7e3/7e3t/+3t7f/s7Oz/K289/zl3Sv+j2LH/k8qj/4PCk/8mlET/MppO/zSbUP80m1D/ - NJxQ/zWfUv83pVX/MJFL/x5aLf8YSSb/O31N/7nTwP/p6en/6enp/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/ - 6Ojo/+fn5//n5+f/4+Pj/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AGITDQxxJZAPcSn8LHtB/5a1nv/a69//OaVX/yR3Ov8mdjz0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABby8vGP4+Pj/+Pj4//j4+P/4+Pj/ - 9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0//T09P/09PT/ - 9PT0//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/ - 8PDw/+/v7//v7+//7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/7u7u/+3t7f/t7e3/7e3t/+3t7f8qbz3/ - OnZL/5/Wr/+Wy6T/QKBa/y6YS/80m1D/NJxQ/zWeUf83o1T/NJ1R/yNmNf8VQiH/H2My/5W/oP/o6Oj/ - 6enp/+np6f/p6en/6enp/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/+fn5//j4+P8EhISYgAAABsAAAAC - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqHGITcyzrF3Ix/2OYcv+/18f/0ezX/4vHm/8mmkb/ - JnQ8/yZzO/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAFvLy8Y/n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/ - 9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0//T09P/09PT/9PT0//Pz8//z8/P/8/Pz//Pz8//y8vL/ - 8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/ - 7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/7e3t/y1vP/87dkz/oNiv/3i9iv8olUX/M5tP/zWdUf82oVP/ - N6NT/yd3Pf8WRSP/EVEj/2ylfP/f5eH/6urq/+np6f/p6en/6enp/+np6f/p6en/6Ojo/+jo6P/o6Oj/ - 6Ojo/+jo6P/o6Oj/6Ojo/+Pj4/wSEhJiAAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAABmEzQIbiTI - Cmwl/zeBS/+oxa//yejR/77ix//D4sv/MZpO/zCfTv8mczv/JW849wAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW8vLxj+fn5//n5+f/5+fn/ - +Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/9vb2//b29v/29vb/9fX1//X19f/19fX/ - 9PT0//T09P/09PT/9PT0//Pz8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/ - 8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+7u7v/u7u7/7e3t/+3t7f/t7e3/ - LXA//z12Tf+i2bL/OJxU/y+aTP82oFL/OKZV/y2GRf8ZTij/C0Ub/0WIWP/K3M//6urq/+rq6v/q6ur/ - 6urq/+np6f/p6en/6enp/+np6f/p6en/6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/5OTk/BISEmIAAAAb - AAAAAgAAAAAAAAAAAAAAAABdDRMMcSidEG8r/RxzM/94p4X/y+XQ/8Diyf+z277/ttvA/36/j/8llEP/ - NqJT/yVvOf8kbTf3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAABby8vGP5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/ - 9/f3//f39//29vb/9vb2//b29v/29vb/9fX1//X19f/19fX/9fX1//T09P/09PT/9PT0//Pz8//z8/P/ - 8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/v7+// - 7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/7u7u/+3t7f8ucUD/QXdR/3rEj/8qmUj/NqRU/zGWTf8eXC// - FkQj/zBzQv+rzLT/6+vr/+vr6//q6ur/6urq/+rq6v/q6ur/6urq/+np6f/p6en/6enp/+np6f/p6en/ - 6enp/+np6f/o6Oj/6Ojo/+jo6P/k5OT8EhISYgAAABsAAAACAAAAAAB/AAINcyluFnQu8RZyL/9Ji1r/ - uNXB/8jn0f+33cL/rdi6/63Wt/+v17n/LJhI/y+ZTP83o1T/JG04/yJpNvgAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvLy8Y/r6+v/5+fn/ - +fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/9vb2//b29v/29vb/ - 9fX1//X19f/19fX/9fX1//T09P/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/ - 8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/v7+//7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/ - 7u7u/y5xQf9JfVX/Qq9f/zGdT/8kazf/FkIh/xpcK/+Ht5T/6Ono/+vr6//r6+v/6+vr/+vr6//q6ur/ - 6urq/+rq6v/q6ur/6urq/+rq6v/p6en/6enp/+np6f/p6en/6enp/+np6f/o6Oj/6Ojo/+Tk5PwSEhJi - AAAAGwAAAAIAaRw/GHQw0ht0M/8jdjn/kLuc/83q1P+838X/r9i6/6rVtv+l07P/rNW4/2Syef8plkb/ - M5tQ/zekVP8jazf/IWc1+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAW8vLxj+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/ - +Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/9fX1//X19f/19fX/9fX1//T09P/09PT/ - 9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/ - 8PDw//Dw8P/v7+//7+/v/+/v7//v7+//7u7u/+7u7v/u7u7/L3JB/zBzQf8ngED/F0ck/w9MH/9emm7/ - 2+Xe/+zs7P/s7Oz/7Ozs/+vr6//r6+v/6+vr/+vr6//q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/p6en/ - 6enp/+np6f/p6en/6enp/+jo6P/o6Oj/5OTk/BISEmIAMgozDHAoqhJwLP4Vby7/XJtt/8fjz//B48z/ - tNu//6vVtv+m07L/odGu/6LRr/+bzqn/JpRD/zCaTf80m1D/N6RV/yNnNv8gYzP5AAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABby8vGP6+vr/ - +vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/ - 9vb2//b29v/29vb/9fX1//X19f/19fX/9fX1//T09P/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/ - 8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw//Dw8P/v7+//7+/v/+/v7//v7+// - 7u7u/+7u7v8vckL/F0gk/wtEG/84fkv/wtnI/+3t7f/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+vr6//p6un/ - 6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+np6f/p6en/6enp/+np6f/p6en/6enp/+jo6P/f4d/8 - EFYjrhZyL/caczL/Ln9F/6nOs//I59D/uN3C/67Xuf+o1LT/o9Gw/57Pq/+azqj/odCt/0umZf8sl0n/ - NJtQ/zSbUP83pVX/ImUz/x9gMfkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvLy8Y/r6+v/6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/ - +fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/ - 9fX1//X19f/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/ - 8fHx//Hx8f/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/zBzQv8mazn/ncWn/+7u7v/t7e3/ - 7e3t/+3t7f/t7e3/7Ozs/+zs7P/s7Oz/qM2y/zWaUP+ozLL/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/ - 6urq/+rq6v/p6en/6enp/+np6f/p6en/pcSt/zaHTP8heTn/GnMy/3Wvhf/M6dT/veDH/6/Zu/+p1LT/ - pdKx/6DQrf+bzan/lsul/5fMpf9/wJH/JpRE/zKaTv80m1D/NJtQ/zilVf8gYjL/Hlwv+gAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW8vLxj - +/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/ - 9/f3//f39//39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/ - 8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw8P/w8PD/ - 7+/v/+/v7//v7+//nMWn/+bq5//u7u7/7u7u/+7u7v/t7e3/7e3t/+3t7f/t7e3/0N/U/1mrb/8hkj// - L5ZK/yySSP/O3dL/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6enp/2qgdP8bdzT/ - KXw//zOCSP/L6dT/zuzW/7bcwf+q1bb/pdOy/6HQrv+czqn/mMym/5PKov+QyKD/lsqk/zacUv8vmUv/ - NJtQ/zSbUP80m1D/OKZV/x9fMf8eWi37AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABby8vGP7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/ - +fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/ - 9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/ - 8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+7u7v/u7u7/ - 7u7u/+7u7v/t7e3/6evp/4vBmv8nlET/H408/zCUTP9drHL/IIo9/0ibX//l6Ob/6+vr/+vr6//r6+v/ - 6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/5ebl/4Owj/8jdjr/HXA0/zR9SP+ZxaX/uODD/6jWtf+e0Kz/ - mcyn/5TKo/+PyJ7/jMac/43Gnf9isnj/KpZH/zObT/80m1D/NJtQ/zSbUP84plb/H10w/x1XLPsAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF - vLy8Y/v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/ - +Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/9fX1//X19f/19fX/9fX1//T09P/09PT/ - 9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/ - 8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/7nWwf9Go1//JZJD/xOHNP+Hwpf/ - //////////8tkUj/I4Y+/2qpe//r6+v/6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+rq6v/p6en/ - 6enp/9LZ0/wKVh7GEGMn/RNlKv9Lhlr/nMuo/53Trf+SyaH/jMac/4fEmP+FwpX/hMKU/yuXSf8xmk3/ - NJtQ/zSbUP80m1D/NJtQ/zinVv8eWi7/HVcs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW8vLxj+/v7//v7+//7+/v/+/v7//r6+v/6+vr/ - +vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/ - 9vb2//b29v/29vb/9vb2//X19f/19fX/9fX1//T09P/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/ - 8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+// - 7+/v/9zl3v9rs3//I5JC/x+NPv9RpGb/8vn1///////8/v3//////9fs3f8UfS//GHwz/2+pf//p6un/ - 6+vr/+vr6//r6+v/6urq/+rq6v/q6ur/6urq/+rq6v/p6en/5eXl/BISEmITUiZQIWs19BNgKP8RViT/ - f7KO/4rFmv+EwpX/gMGS/4HBlP9LpmT/LZhK/zSbUP80m1D/NJtQ/zSbUP80m1D/OKdW/x5aL/8dViv8 - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAABby8vGP8/Pz//Pz8//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/ - +fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/ - 9fX1//X19f/19fX/9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/ - 8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/7+/v/+/v7/+SxJ//MppO/zOYTv8wlUz/RqJg//////////// - 8vj0/+v17v/q9Oz/9fr2/63Vuf8ZfTT/IX06/1CWY//Z4dv/6+vr/+vr6//r6+v/6+vr/+rq6v/q6ur/ - 6urq/+rq6v/m5ub8Cy8TgBJiKdsaYy3/I2g1/3ezif+OzJ//gsOT/3y+jv97vo7/bbaB/yqWR/8ym0// - NJtQ/zSbUP80m1D/NJtQ/zSbUP84plb/Hlwv/x1WK/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvLy8Y/z8/P/8/Pz//Pz8//v7+//7+/v/ - +/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/ - 9/f3//f39//39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/ - 8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/ - 8PDw/3Czgv8yl07/MpZN/zOcUP8fkT7/lMqj///////s9u7/4/Hn/9/v4//e7uL/5vTq/7/hyP8hgTv/ - HXY1/yl9QP90qIP/z9rR/+vr6//r6+v/6+vr/+rq6v/n5+f/rsa0/2SXcv4QWyT9FFwp/0aDVv+UzqT/ - i8ib/3/Akf95vYv/d7uJ/3K6h/8ymk7/MJpN/zSbUP80m1D/NJtQ/zSbUP80m1D/NJtQ/zimVv8eXC// - HVUs/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAW8vLxj/Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/ - +fn5//n5+f/5+fn/+fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/ - 9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/ - 8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/6+3r/06gZf8xkUv/MpZN/y6aS/8ckDz/ - u97E//P69P/f7+P/1+vc/9Lp2P/P59b/1ezc/8no0f9RmmT/Emss/xtvMv8WbCz/NHxH/0GDUv9Tj2H/ - RYdW/xxpMP8dZTH/Fl4p/x5hMP9xq4D/kc+i/4LDlf96vYz/dbuI/3O6hf9zuYb/PZ9Y/y+ZTP80m1D/ - NZ1R/zWeUf81nlH/NJxQ/zSbUP80m1D/OKZW/x5cL/8dVSz9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP8/Pz//Pz8//z8/P/8/Pz/ - +/v7//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/ - +Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/09PT/ - 9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/ - 8PDw//Dw8P/w8PD/0N/V/yyMR/8ujEj/MplP/yyZSv8bjjr/o9Gw/+jz6v/U6tn/yuXR/8Xizf/B4Mr/ - xOPM/8vo0v+y2r7/T5tk/x9wNP8OXyX/EWAn/xNfJ/8QXCX/F2Is/z2BTv9uqH3/jsef/4fImv99wI// - druJ/3K5hf9vuIL/braC/0unZf8umEv/M5tP/zWeUv82o1P/KXw//zWhUv82olT/NZ5R/zScUP84plb/ - Hlwu/x1VLP0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAFvr6+Y/39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/ - +vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/ - 9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0//T09P/09PT/9PT0//Pz8//z8/P/ - 8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/ocer/yCBOv8tiUX/ - NJxR/y6aS/8dkDz/hMKV/9vt4P/L5tH/v9/H/7jcwv+02r7/stm9/7LZvP+13cD/uOHD/7DbvP+UyqL/ - gryR/5THo/+e1q7/k8+k/4nImf9/wZD/eb2M/3O6hv9uuIL/bLZ//2u2f/9GpF//LphL/zObT/81nlL/ - NqRU/yRqNv8XSCX/Gk8p/yt/Qf83pFX/NqFT/zioV/8eXDD/HVYs/gAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j/f39//39/f/8/Pz/ - /Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/ - +fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/ - 9fX1//X19f/19fX/9PT0//T09P/09PT/9PT0//Pz8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/ - 8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/aqh7/yuDRP8shkX/NJ1R/zCbTf8jk0L/QqFc/7fcwf/E4cv/ - tdu//63XuP+n07P/o9Gw/57Pq/+Zzaf/l8ul/5TLov+Pyp//iMWa/4PClP9+v4//eb2L/3S6h/9vuIP/ - bLaB/2m2ff9ntH3/P6Ba/y6ZS/8zm0//NZ9S/zalVP8kajf/GUwn/xxWK+kaUin5GEwn/x1XLf8vjEj/ - O7Bb/x9gMv8cViz+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAABb6+vmP9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/ - +/v7//v7+//7+/v/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/ - +Pj4//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0//T09P/09PT/ - 9PT0//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/q7Or/ - XZ5u/yp8QP8rgEH/M5tQ/zOdUP8ql0j/IpJC/2u3gP+v2Lr/sdm7/6TRsP+bzqn/lsul/5HJoP+Nxpz/ - iMSY/4PClP9+v5D/er2M/3a7iP9xuYT/bbaA/2m1fv9ntXz/V61v/zWbUf8wmUz/M5tP/zafUv83pFX/ - Imo1/xlMJ/8NTSDdClseGQBPDyABSxS3DEQb/hhLJv8jajb/IF0w/xxWLP4AAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/39/f/9/f3/ - /f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/ - +vr6//n5+f/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/ - 9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0//T09P/09PT/9PT0//Pz8//z8/P/8/Pz//Pz8//y8vL/ - 8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/v7+//ZZ92/xpxMv8peD3/MplO/zWfUv8wmk3/ - KZZG/yOSQf9ZrnH/l8ul/6HRrv+XzKb/j8if/4jFmf+BwJL/e76N/3a7if9zuYj/cbiF/263gf9rtX// - W65x/zqdVP8umEr/MZpO/zSdUf82olP/NJ1R/yFkM/8ZTCf/EE8f2ABMDBQAAAAAAAAAAAAAAAAAQwNE - AUQR1wtHHP8bUyr/HFYs/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j/f39//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz/ - /Pz8//z8/P/7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/ - +Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/9vb2//b29v/29vb/9fX1//X19f/19fX/ - 9fX1//T09P/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/ - 8fHx//Dw8P/w8PD/daiC/xdrL/8lcjr/L4pI/zWhUv81n1L/MZtO/yuXSf8klEP/MZlO/1GpaP9rtn// - er6L/3q+jP97vo3/eL6L/2u1f/9YrG//R6Rg/zmeU/8tmEr/MZpN/zScUP81n1L/OKVV/yyGRf8aUCn/ - CkQa/wFFE80APwAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEcNbg5OH+4cViz/AAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP+/v7/ - /f39//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/ - +vr6//r6+v/6+vr/+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/ - 9/f3//f39//29vb/9vb2//b29v/29vb/9fX1//X19f/19fX/9fX1//T09P/09PT/9PT0//Pz8//z8/P/ - 8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/jbSW/xppMP8jajf/ - JXE6/zCSS/83o1T/NZ9S/zScUP8xmk7/LphL/yqWSP8olUb/KJVG/yiVRv8plkb/K5dI/y2YSv8wmUz/ - MppO/zScUP82oFL/N6VV/zWfUP8iZjT/GEsm/wxHG/oAQwmFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAD8ADCFiM5kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/7+/v/+/v7//f39//39/f/9/f3//f39//39/f/8/Pz/ - /Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/5+fn/ - +fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/9vb2//b29v/29vb/ - 9fX1//X19f/19fX/9fX1//T09P/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/ - 8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/z9rQ/0yHW/8UXSf/IGEy/yd1Pf8xlUz/NqVU/zejVP82oFL/ - NZ1R/zScUP80m1D/NJtQ/zSbUP80nFD/NZ5R/zagUv83o1T/OKhW/y+PSf8iZjT/GUkl/xlQKf8PUSHW - AEsKLwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j - /v7+//7+/v/+/v7//f39//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/ - +/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/ - +Pj4//f39//39/f/9/f3//f39//39/f/9vb2//b29v/29vb/9fX1//X19f/19fX/9fX1//T09P/09PT/ - 9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/ - 8PDw/67Fs/82ckf/Hlsw/x5aLv8fWy//JnE7/y2KSP82oVP/OalX/zioV/84qFb/OKhX/zeoVv8zmk// - LolG/yh3Pf8dVSz/GEom/wpEGv8AQhDjAEkLgAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3/ - /f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/+/v7//r6+v/6+vr/ - +vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/ - 9vb2//b29v/29vb/9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/ - 8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw/+/v7/+SsZj/Rn5W/xhXKf8bVCv/ - GlAp/xhLJv8YSSb/Gk0n/xtTKv8dWC3/GEom/xdJJf8YSib/GE0n/wxFHP0BShbAAEEAUgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF - vr6+Y/7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz/ - /Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/ - +fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/ - 9fX1//X19f/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/ - 8fHx//Hx8f/w8PD/8PDw//Dw8P/v7+//6+3s/6/Ftf9pk3T/RHdS/zluSP8xZ0D/KGA3/yJcMv82bEX/ - VINg/3Saf/4cRiagEzUdNAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j/v7+//7+/v/+/v7//v7+//7+/v/+/v7/ - /v7+//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/ - +/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/ - 9/f3//f39//39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/ - 8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw8P/w8PD/ - 7+/v/+/v7//v7+//7+/v/+7u7v/u7u7/7u7u/+7u7v/t7e3/6enp/BISEmIAAAAbAAAAAgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAABb6+vmP//////v7+//7+/v/+/v7//v7+//7+/v/+/v7//f39//39/f/9/f3//f39//39/f/9/f3/ - /f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/5+fn/ - +fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/ - 9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/ - 8vLy//Hx8f/x8fH/8fHx//Hx8f/w8PD/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+7u7v/u7u7/ - 7u7u/+7u7v/p6en8EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////////////7+/v/+/v7/ - /v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/ - +/v7//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/ - +Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/09PT/ - 9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx8f/w8PD/ - 8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+/v7//u7u7/7u7u/+rq6vwSEhJiAAAAGwAAAAIAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAW+vr5j/////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3/ - /f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/+/v7//v7+//6+vr/ - +vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/ - 9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0//T09P/09PT/8/Pz//Pz8//z8/P/ - 8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+// - 7+/v/+7u7v/u7u7/6urq/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////// - //////7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz/ - /Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/ - +fn5//j4+P/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/ - 9fX1//X19f/19fX/9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/ - 8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/7+/v/+/v7//v7+//7+/v/+7u7v/q6ur8EhISYgAAABsAAAAC - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAFvr6+Y/////////////////////////////////7+/v/+/v7//v7+//7+/v/+/v7/ - /v7+//39/f/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/ - +/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/ - 9/f3//f39//39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/ - 8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/ - 8PDw/+/v7//v7+//7+/v/+rq6vwSEhJiAAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////// - //////////////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//f39//39/f/9/f3/ - /f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/ - +vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/ - 9vb2//b29v/29vb/9fX1//X19f/19fX/9PT0//T09P/09PT/9PT0//Pz8//z8/P/8/Pz//Pz8//y8vL/ - 8vLy//Ly8v/x8fH/8fHx//Hx8f/x8fH/8PDw//Dw8P/w8PD/8PDw/+/v7//v7+//6+vr/BISEmIAAAAb - AAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////////////////////////////7+/v/+/v7/ - /v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz/ - /Pz8//v7+//7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/5+fn/ - +Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/9vb2//b29v/29vb/9fX1//X19f/19fX/ - 9fX1//T09P/09PT/9PT0//Pz8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/ - 8PDw//Dw8P/w8PD/8PDw/+/v7//r6+v8EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////// - ///////////////////////////////////////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3/ - /f39//39/f/9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//6+vr/ - +vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/ - 9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0//T09P/09PT/9PT0//Pz8//z8/P/ - 8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/8PDw/+vr6/wSEhJi - AAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////////////////////////////////////// - ///////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3//f39//39/f/8/Pz/ - /Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/ - +fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/ - 9fX1//X19f/19fX/9PT0//T09P/09PT/9PT0//Pz8//z8/P/8/Pz//Ly8v/y8vL/8vLy//Ly8v/x8fH/ - 8fHx//Hx8f/x8fH/8fHx//Dw8P/w8PD/6+vr/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///// - ///////////////////////////////////////////////////////////+/v7//v7+//7+/v/+/v7/ - /v7+//7+/v/+/v7//f39//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/ - +/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/ - +Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/9fX1//X19f/19fX/9fX1//T09P/09PT/ - 9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8vLy//Ly8v/y8vL/8fHx//Hx8f/x8fH/8fHx//Dw8P/r6+v8 - EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////////////////////////////////////// - ///////////////////////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//f39//39/f/9/f3/ - /f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/ - +vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/ - 9vb2//b29v/29vb/9fX1//X19f/19fX/9fX1//T09P/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/ - 8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/8fHx/+vr6/wSEhJiAAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j - ///////////////////////////////////////////////////////////////////////////+/v7/ - /v7+//7+/v/+/v7//v7+//7+/v/+/v7//f39//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz/ - /Pz8//v7+//7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/ - +Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/9vb2//b29v/29vb/9fX1//X19f/19fX/ - 9fX1//T09P/09PT/9PT0//Pz8//z8/P/8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8vLy//Hx8f/x8fH/ - 7Ozs/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////////////////////// - ///////////////////////////////////////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/ - /f39//39/f/9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/ - +/v7//r6+v/6+vr/+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/ - 9/f3//f39//29vb/9vb2//b29v/29vb/9fX1//X19f/19fX/9fX1//T09P/09PT/9PT0//T09P/z8/P/ - 8/Pz//Pz8//y8vL/8vLy//Ly8v/y8vL/8fHx//Hx8f/s7Oz8EhISYgAAABsAAAACAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF - vr6+Y/////////////////////////////////////////////////////////////////////////// - /////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3/ - /f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/ - +fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/ - 9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/ - 8vLy/+zs7PwSEhJiAAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////////////////////// - /////////////////////////////////////////////////////////////////v7+//7+/v/+/v7/ - /v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/7+/v/ - +/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/ - +Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/9fX1//T09P/09PT/ - 9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8/Pz//Ly8v/y8vL/7e3t/BISEmIAAAAbAAAAAgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAABb6+vmP///////////////////////////////////////////////////////////////////// - /////////////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3/ - /f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/+/v7//r6+v/6+vr/ - +vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/ - 9vb2//b29v/29vb/9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/ - 8vLy//Ly8v/t7e38EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz/ - /Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/ - +fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/ - 9fX1//X19f/09PT/9PT0//T09P/z8/P/8/Pz//Pz8//z8/P/8vLy/+3t7fwSEhJiAAAAGwAAAAIAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAW+vr5j//////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7/ - /v7+//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/ - +/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/ - 9/f3//f39//39/f/9vb2//b29v/29vb/9vb2//X19f/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/ - 8/Pz//Pz8//z8/P/7u7u/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3/ - /f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/ - +vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/ - 9vb2//b29v/19fX/9fX1//X19f/09PT/9PT0//T09P/09PT/8/Pz//Pz8//u7u78EhISYgAAABsAAAAC - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAFvr6+Y/////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////v7+//7+/v/+/v7/ - /v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/ - +/v7//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/ - +Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/19fX/ - 9PT0//T09P/09PT/8/Pz/+7u7vwSEhJiAAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3/ - /f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//6+vr/ - +vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/ - 9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0//T09P/09PT/7+/v/BISEmIAAAAb - AAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz/ - /Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/ - +fn5//j4+P/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/19fX/ - 9fX1//X19f/19fX/9PT0//T09P/v7+/8EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////7+/v/+/v7//v7+//7+/v/+/v7/ - /v7+//7+/v/+/v7//f39//39/f/9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/ - +/v7//v7+//7+/v/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/ - +Pj4//f39//39/f/9/f3//f39//29vb/9vb2//b29v/19fX/9fX1//X19f/19fX/9PT0/+/v7/wSEhJi - AAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3/ - /f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/ - +vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/ - 9vb2//b29v/29vb/9fX1//X19f/19fX/7+/v/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////7+/v/+/v7/ - /v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz/ - /Pz8//v7+//7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/ - +Pj4//j4+P/4+Pj/9/f3//f39//39/f/9/f3//b29v/29vb/9vb2//b29v/29vb/9fX1//X19f/w8PD8 - EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3/ - /f39//39/f/9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//6+vr/ - +vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//n5+f/4+Pj/+Pj4//j4+P/4+Pj/9/f3//f39//39/f/ - 9/f3//b29v/29vb/9vb2//b29v/19fX/9fX1//Dw8PwSEhJiAAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3/ - /Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/5+fn/ - +fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//f39//39/f/9vb2//b29v/29vb/ - 8PDw/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////+/v7//v7+//7+/v/+/v7/ - /v7+//7+/v/+/v7//f39//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/ - +/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/ - +Pj4//f39//39/f/9/f3//f39//39/f/9vb2//b29v/x8fH8EhISYgAAABsAAAACAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF - vr6+Y/////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//f39//39/f/9/f3/ - /f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/ - +vr6//r6+v/5+fn/+fn5//n5+f/5+fn/+Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/ - 9vb2//Hx8fwSEhJiAAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /v7+//7+/v/+/v7//v7+//7+/v/+/v7//f39//39/f/9/f3//f39//39/f/9/f3//Pz8//z8/P/8/Pz/ - /Pz8//z8/P/7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/+vr6//r6+v/5+fn/+fn5//n5+f/5+fn/ - +Pj4//j4+P/4+Pj/+Pj4//f39//39/f/9/f3//f39//29vb/8fHx/BISEmIAAAAbAAAAAgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAABb6+vmP///////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7/ - /v7+//39/f/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/ - +/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/4+Pj/ - 9/f3//f39//y8vL8EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3/ - /f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/5+fn/ - +fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/39/f/9/f3//Ly8vwSEhJiAAAAGwAAAAIAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAW+vr5j//////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////v7+//7+/v/+/v7/ - /v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/7+/v/ - +/v7//v7+//7+/v/+/v7//r6+v/6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/ - +Pj4//j4+P/39/f/8vLy/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3/ - /f39//39/f/9/f3//Pz8//z8/P/8/Pz//Pz8//z8/P/7+/v/+/v7//v7+//7+/v/+/v7//r6+v/6+vr/ - +vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//j4+P/4+Pj/+Pj4//j4+P/z8/P8EhISYgAAABsAAAAC - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAFvr6+Y/////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////7+/v/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz/ - /Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/ - +fn5//n5+f/4+Pj/+Pj4//Pz8/wSEhJiAAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////7+/v/+/v7//v7+//7+/v/+/v7/ - /v7+//7+/v/9/f3//f39//39/f/9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/ - +/v7//v7+//6+vr/+vr6//r6+v/6+vr/+fn5//n5+f/5+fn/+fn5//n5+f/4+Pj/8/Pz/BISEmIAAAAb - AAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3/ - /f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/+/v7//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/ - +vr6//n5+f/5+fn/+fn5//n5+f/z8/P8EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////v7+//7+/v/+/v7/ - /v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3//f39//z8/P/8/Pz//Pz8//z8/P/8/Pz/ - +/v7//v7+//7+/v/+/v7//v7+//6+vr/+vr6//r6+v/6+vr/+vr6//n5+f/5+fn/+fn5//T09PwSEhJi - AAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3/ - /f39//39/f/9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//7+/v/ - +vr6//r6+v/6+vr/+vr6//n5+f/5+fn/8/Pz/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/9/f3//f39//39/f/8/Pz/ - /Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//7+/v/+vr6//r6+v/6+vr/+fn5//j4+P/w8PD8 - EhISYgAAABsAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////7+/v/+/v7//v7+//7+/v/+/v7/ - /v7+//7+/v/+/v7//f39//39/f/9/f3//f39//39/f/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/ - +/v7//v7+//7+/v/+vr6//r6+v/4+Pj/9fX1/+vr6/wSEhJiAAAAGwAAAAIAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////7+/v/+/v7//v7+//7+/v/9/f3//Pz8//v7+//7+/v/+vr6//r6+v/6+vr/ - +/v7//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//v7+//7+/v/+/v7//v7+//6+vr/+Pj4//T09P/u7u7/ - 5eXl/BISEmIAAAAbAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /f39//z8/P/6+vr/+Pj4//T09P/z8/P/8vLy//Ly8v/09PT/9vb2//j4+P/5+fn/+Pj4//j4+P/4+Pj/ - +Pj4//j4+P/39/f/9vb2//Pz8//v7+//6enp/+Tk5P/b29v8Dw8PYAAAABoAAAABAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF - vr6+Y/////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////+/v7//Pz8//f39//x8fH/6urq/+Xl5f/j4+P/ - 4+Pj/+Xl5f/o6Oj/6urq/+zs7P/t7e3/7e3t/+7u7v/t7e3/7Ozs/+vr6//o6Oj/4+Pj/97e3v/a2tr/ - 19fX/8zMzPQSEhJRAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////7+/v/7+/v/9PT0/+3t7f/n5+f/29vb/9DQ0P/MzMz/z8/P/9PT0//W1tb/2NjY/9ra2v/b29v/ - 29vb/9ra2v/Z2dn/1tbW/9LS0v/Nzc3/ycnJ/8rKyv/Pz8//srKywRAQEC8AAAAIAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAABb6+vmP///////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////v7+//z8/P/z8/P/6Ojo/+7u7v/r6+v/ - 5ubm/9zc3P/S0tL/ysrK/8fHx//Dw8P/wsLC/8HBwf/BwcH/wsLC/8TExP/ExMT/xsbG/8vLy//Q0ND/ - 1dXV/8bGxtB5eXlQAAAADwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////+/v7//Pz8//T09P/l5eX/6enp/+/v7//w8PD/8PDw//Hx8f/x8fH/8fHx//Hx8f/y8vL/ - 8vLy//Ly8v/y8vL/7u7u/+rq6v/l5eX/4ODg/9zc3P/Pz8/gbGxsUgAAAA0AAAACAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAW+vr5j//////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////7+/v/8/Pz/9fX1/+fn5//e3t7/ - 7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/8fHx//Ly8v/x8fH/8fHx/+7u7v/p6en/5eXl/+Dg4P/c3Nz/ - 0NDQ64eHh3EAAAAUAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////7+/v/39/f/6urq/9vb2//s7Oz/7+/v/+/v7//w8PD/8PDw//Dw8P/x8fH/ - 8fHx//Dw8P/t7e3/6enp/+Tk5P/f39//3Nzc/8fHx+N+fn5xAAAAGgAAAAUAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAFvr6+Y/////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////v7+//n5+f/t7e3/ - 3d3d/+fn5//u7u7/7+/v/+/v7//v7+//8PDw//Dw8P/w8PD/7Ozs/+jo6P/j4+P/3t7e/9vb2//Gxsbj - fn5+bwAAABgAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////+/v7/+vr6//Hx8f/g4OD/4uLi/+7u7v/u7u7/7+/v/+/v7//v7+// - 7+/v/+vr6//n5+f/4uLi/93d3f/a2tr/zc3N7Hl5eXMAAAAYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////8/Pz/ - 8vLy/+Li4v/g4OD/7e3t/+3t7f/u7u7/7u7u/+3t7f/q6ur/5ubm/+Hh4f/d3d3/2dnZ/8zMzO2BgYF8 - AAAAGwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////z8/P/z8/P/5OTk/9/f3//t7e3/7e3t/+3t7f/s7Oz/ - 6urq/+bm5v/g4OD/3Nzc/9nZ2f/FxcXleXl5dgAAABsAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /f39//T09P/k5OT/3d3d/+zs7P/s7Oz/7Ozs/+np6f/k5OT/4ODg/9vb2//Y2Nj/wsLC5Xl5eXEAAAAZ - AAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////9/f3/9fX1/+Xl5f/d3d3/7Ozs/+vr6//o6Oj/ - 5OTk/97e3v/a2tr/19fX/8fHx+x3d3d1AAAAGQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////39/f/19fX/5OTk/9zc3P/q6ur/5+fn/+Pj4//e3t7/2tra/9bW1v/Jycnufn5+fwAAABsAAAAF - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////f39//T09P/k5OT/29vb/+bm5v/i4uL/ - 3d3d/9nZ2f/W1tb/wcHB53Z2dnsAAAAcAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb6+vmP///////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////8/Pz/8/Pz/+Li4v/Z2dn/4eHh/9zc3P/Y2Nj/1NTU/729veZ2dnZ0AAAAGgAAAAUAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF - vr6+Y/////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////v7+//x8fH/3d3d/9XV1f/b29v/ - 19fX/9TU1P/CwsLscnJyeAkJCRsAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW+vr5j//////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////+/v7/+fn5/+zs7P/Z2dn/09PT/9fX1//T09P/xsbG7nh4eIEAAAAcAAAABQAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAABb6+vmP///////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////v7+//39/f/19fX/5ubm/9TU1P/S0tL/ - 0tLS/7+/v+l2dnZ/AAAAHQAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvr6+Y/////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////+/v7/+fn5//Dw8P/i4uL/09PT/9HR0f+/v7/kdXV1dQAAABsAAAAGAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAW+vr5j//////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////v7+//r6+v/09PT/6urq/9/f3//T09P/ - w8PD5n19fWwKCgoYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMTExGD///////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /v7+//7+/v/6+vr/9fX1/+/v7//n5+f/3Nzc/crKyuNzc3NjAAAAEwAAAAIAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAACy8vLSvb29tL09PTV9PT01vT09Nb09PTW9PT01vT09Nb09PTW9PT01vT09Nb09PTW - 9PT01vT09Nb09PTW9PT01vT09Nb09PTW9PT01vT09Nb09PTW9PT01vT09Nb09PTW9PT01vT09Nb09PTW - 9PT01vT09Nb09PTW9PT01vT09Nb09PTW9PT01vT09Nb09PTW9PT01vT09Nb09PTW9PT01vT09Nb09PTW - 9PT01vT09Nb09PTW9PT01vT09Nb09PTW9PT01vT09Nbz8/PW7+/v1urq6tbl5eXW4eHh1dbW1tDGxsa1 - goKCWgAAABIAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACurq4Tzc3NObq6uj+3t7dA - t7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dA - t7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dA - t7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dAt7e3QLe3t0C3t7dA - t7e3QLOzs0Czs7NAr6+vQKurq0ClpaU/lZWVOlxcXCQAAAAKAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAB - AAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAB - AAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAB - AAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAC - AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///// - //////////////////////////////////////////////////////////////////////////4B//// - ///////////////gAD//////////////////gAAP/////////////////gAAA///////////////3/wA - AAH//////////////8/wAAAAf//////////////D4AAAAD//////////////wMAAAAAf//////////// - /8AAAAAAD//////////////AAAAAAA//////////////wAAAAAAH/////////////8AAAAAAA/////// - ///////AAAH+AAH/////////////wAAH/wAB/////////////8AAD//AB//////AAAAAAAAAAAAD4B// - ////wAAAAAAAAAAAA+A//////8AAAAAAAAAAAAPw/7/////AAAAAAAAAAAAD+/4/////wAAAAAAAAAAA - A//8P////8AAAAAAAAAAAAP/8D/////AAAAAAAAAAAAD/8A/////wAAAAAAAAAAAA/+AP////8AAAAAA - AAAAAAP+AD/////AAAAAAAAAAAAD+AA/////wAAAAAAAAAAAA/AAP////8AAAAAAAAAAAAPAAD/////A - AAAAAAAAAAADAAA/////wAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA/ - ////wAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAADAAA/////wAAAAAAAAAAA - AAAAP////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////8AAAAAA - AAAAAAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAwP////8AAAAAAAAAAAAAAfD/////A - AAAAAAAAAAAAAP8/////wAAAAAAAAAAAAAH/v////8AAAAAAAAAAAAAH///////AAAAAAAAAAAAAD/// - ////wAAAAAAAAAAAAH///////8AAAAAAAAAAAAH////////AAAAAAAAAAAAD////////wAAAAAAAAAAA - A////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAA - AAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////A - AAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD//// - ////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAA - A////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAA - AAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////A - AAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD//// - ////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAA - A////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAA - AAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////A - AAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD//// - ////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAA - B////////8AAAAAAAAAAAA/////////AAAAAAAAAAAAf////////wAAAAAAAAAAAP////////8AAAAAA - AAAAAH/////////AAAAAAAAAAAD/////////wAAAAAAAAAAB/////////8AAAAAAAAAAA//////////A - AAAAAAAAAAf/////////wAAAAAAAAAAP/////////8AAAAAAAAAAH//////////AAAAAAAAAAD////// - ////wAAAAAAAAAB//////////8AAAAAAAAAA///////////AAAAAAAAAAP//////////wAAAAAAAAAP/ - /////////8AAAAAAAAAH///////////AAAAAAAAAD///////////wAAAAAAAAB///////////8AAAAAA - AAA///////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////ygAAACAAAAAAAEAAAEACAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BAQE/woKCv8NDQ3/ - ABgA/xISEv8APwD/ADMJ/wsvFP8SOB3/AEMB/wBDCv8ASgz/AEQS/wFKFf8LRRv/D00f/wBQEf8KVh// - B1sd/wBjEf8AaBX/AGoc/wB8F/8AfRv/Dk0g/xZEIv8cRif/FUoj/xhLJv8ZTij/D1Ag/w5fJf8RVCP/ - Elsm/xtUK/8VXSn/HVot/x5cMP8hXDH/CWEg/wRuIf8JbST/Dm4o/xBiJ/8UYir/GWQt/xVrLf8Yay7/ - A3Yi/wxxJv8HfSf/CH0m/w1xKf8Jeij/E3It/xF6Lf8eYjH/Gmww/xZzMP8aczL/E34w/xt7Nf8efTj/ - IWMz/yhgN/8jajb/JG04/ytvPf8hcjb/JXQ7/ypzPv8kfDz/KHk+/zFnQP82bEX/OW5I/y5yQP8qfUD/ - MXJD/zR8R/86dkv/NX5J/zl8S/9eXl7/QndR/0Z+Vv9JfVX/bm5u/3V1df97e3v/AIQj/wCIJf8Jgir/ - DYsv/w6OMP8UhDP/HoM6/x2NPP8ckTz/IYI8/yiBP/8hiT7/IZI//yWFQP8rg0P/JYxB/yyJRv8ujUj/ - NIJJ/z2BTv8yiEn/JZND/yiVRv8mmkb/K5ZI/y2YSv8wkkv/MZpO/zuXVv80m1D/OZ1U/z2eWP82olP/ - OKVV/zeoVv84qFb/PqFY/zmpWP87sFv/RIRU/0uGWv9FiFj/SYta/0ibX/9Colz/Qq9f/1SDYP9Tj2H/ - T5tk/1KUZP9RmmT/X5Nv/12bbf9pk3T/ZJpz/3Sbf/9Go2D/S6Vk/02oZf9RpGb/VKts/1isbv9brXH/ - WrBy/2qgdP9spXz/bKh8/2Gyd/9ks3r/arV+/3inhf9zqoL/fK+K/222gf9uuIL/cLOC/3K5hf93s4n/ - f7KO/3W6iP96vYz/fr+Q/3vCj/9+wJD/gYGB/4iIiP+Wlpb/g7CP/4S1kv+NtJb/gryR/5Szm/+Qu5z/ - nLKi/5W/oP+lpaX/q6ur/6+vr/+ysrL/tra2/7q6uv++vr7/g8GU/4fEmP+KxZr/h8ia/43Jnf+SxJ// - lMej/5vFpv+UyqP/mMym/57Eqf+czan/ntKs/6PFrP+oxa//odCu/6DYr/+uxbT/qcyy/6TSsf+p1bX/ - pNmz/63WuP+u2br/stm8/7rVwv+23MD/ut3E/7TgwP+64cX/vuLI/8PDw//Jycn/zc3N/8LZyP/K3M// - ztvR/9PT0//R3dT/29vb/8Liy//K5tH/yunT/9Hs1//b493/1Ova/9rr3//f5eH/3e7i/9/z5P/k5OT/ - 5enm/+zs7P/j8ef/5vTq/+r07P/x8fH/9fX1//L69P/5+fn//v7+/wAAAP8AAAD//f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f12dXV1dWxsdXN1dXV4/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f1bYGRpZWhoampm - aWRlZWRgW/39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f0YPT5I - ZHB8l5+qoJ+Zl5R5aGU+OF1b/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f1bYD5IYpXE1M3JxcPBwa2rq6eglnVISWRf/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/XVb - /f39/f39/f39Nj9GZp/Q1MzGw8HBrquqp6Wgn56enpp5SD9d/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39az9gW/39/f39Wzg7PnzU1MnJw8PDw7W1q6umoJ+enpiXl5eHSDxgW/39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f1pRkY+Xf39/V9hRWGl2NTMycnJx8Gnn5eXmJ+goJ+amJeWlJSHaUdhXv39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/WlsejovOF9jYUJrzdfQycnNyZ98cHNzc3R2c3Rzh5eXlZSHh4d8 - bEZIW/39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39aW/7rmEwRmk6atTVzMrNyZdwdHV2eHh4eHZ2eHZ2 - doeUk4eHfHl7b0Y4/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f1OafLq6Zc3LGvU1c3MzcF4dHZ4eHx4 - fHx4fHx7e3h4dnaHh3l4eHh8aToz/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/U5p7tzc6dCH1NfNzNSX - cHR4eHh8eHVORkJGRk51e3h2dnZ8eXZ4eHh4Rjpd/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39Tm3s29nZ - 2dfVzczNlXF2eHh7eE5AQDw1KRYrOkBHc3t5dnh4eHh4eHt7Qjxf/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f1IUuvY19XU1MzMzJNzeHh4e3VCLThfW/39/f1cPS8naXh7eHh4eHh4eHt1QDxb/f39/f39/f39/f39 - /f39/f39/f0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAE5t6tjV1NDMytSVc3h4e3hOQDw2AAAAAAAAAAAAMzgiRnl2eHh4eHh7aUAuOBj9/f39 - /f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAARm3r1dTMzMrQpXF4eHh4RydGLgAAAAAAAAAAAAAAADItQ3t2eHt7dUIi - NVv9/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAArrm4eDh4eDg4ODg4ODg4ODg4ODg4ODg - 4ODg4ODgwODg4ODgwODgwODAwODA4MDAwL9OUt/Uzc3NzMNzdHh4eHh8aycibri/vr+/v7/ABQAAADEh - aXx8eEYlMDb9/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAACwPr6+vr6+vr6+vr6+vn6 - +vn5+fr5+fn5+fn1+fn59fn19fX59fX19fX19fX19fX19UZu3c3MzMnMdnR4eHh4eHh7fGkjLp3t9PXz - 9PMFAAAAADUjdWkmIjdc/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAAO//Pr8+vr6 - +vr6+vr6+vr6+vr6+fn5+fn5+fn5+fn59fn5+fX1+fn1+fX19fX19fX1TVPdzM3JzZR0eHh4eHh4eHh4 - gHUlHI/z9PP18wUAAAAAXC4jIzpeAAD9/f39/RRp/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAA - Ar/6/Pr6+vr8+vr6+vr6+fn5+fn5+fr5+fn5+fn1+fn59fn1+fn19fn19fX59fX19fVHU93Nycqlcnh4 - eHh4eHh7e3hCHk/L8/Tz9fPzBQAAAAAAXShgWwAAAP39/RU3Pmn9/f39/f39/f39/f39/f39/f0AAAAA - AAAAAAAAAAACv/z6/Pz8/Pr8+vr6+vn6+vr6+vr6+fr5+fn5+fn59fn59fn59fX59fX59fX19fX19U1T - 2MnKxXB2eHh4eHh4fHhHHiOj8/P18/Tz9fMFAAAAAAAAGAAAAAAA/f0WN2lGSf39/f39/f39/f39/f39 - /f39/QAAAAAAAAAAAAAAAAO//Pz6+vr6+vr6+vr6+vr6+vn5+fn5+fn5+fn5+fX5+fX59fX5+fX59fX1 - 9fX19fX1RFPWycmUdHh4eHh4e4BpIxCK5/P18/Xz9fPz8wUAAAAAAAAAAAAAAAAUKiqOs0hJ/f39/f39 - /f39/f39/f39/f39AAAAAAAAAAAAAAAAAr/6/Pz8/Pz8+vr6+vr6+vr6+vr6+vr5+vn5+vn5+fn5+fn5 - +fX1+fX59fn59fX19fVEUdTJwXB2eHh4e3tvJR5R2vX19fP18/Xz9fTzBQAAAAAAAAAAAAAUMjdOtu98 - SEb9/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAACv/z8/Pz6+vr8+vz6+vr6+vr6+vr6+fr5+vn5 - +fn5+fn5+fn5+fn1+fX59fX19fX19URR0cmHdnh4eHx4Qxont/P18/Xz9fP18/Xz8/MFAAAAAAAAAAAA - Fjc3jtzsxXJGR/39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAAO//Pz8+vz8/Pr8+vz6/Pr6+vr6 - +vn6+fr5+vn6+fn5+fn1+fX59fn1+fX1+fn1+fX5RFHRrXF2eHt7RhoZm/D19fX19PXz9fP18/X18wUA - AAAAAAAAFDIqbdLr6el2dkdG/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAr/8/Pz8/Pz6/Pr8 - +vr6+vr6+vr5+vr6+fr5+vn6+vn5+fn5+fn5+fn1+fn19fn19fVNUdF4dHt9aR4PguX19fX08/P18/Xz - 9fP18/PzBQAAAAAAFDU3PKHq39vZrXB7Q0P9/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAACwPz8 - /Pz8+vz6/Pr8/Pr6+vr6+vr6+vr6+fr5+fn5+vn5+fn59fn59fn19fn19fX59URWrXR7diUbTdP19fX0 - 9PX19fXz9fP19fP19fMFAAAAWzc3O4Xa6tzZ1dl0dnxDQv39/f39/f39/f39/f39/f39/QAAAAAAAAAA - AAAAAAO//Pz8/Pz8/Pz8/Pr6/Pz8+vr6+vr6+vr6+vr6+fn5+fn5+fn59fn5+fn59fn59fX4T1eIeEIa - JbX19fXz9fX19fXz9fP19fP19fPz8wUAABY9PEi369zZ1dTXnnN4e0NA/f39/f39/f39/f39/f39/f39 - AAAAAAAAAAAAAAAAAsD8/Pz8/Pz8/Pr6/Pz6+vr6+vr6+vr6+vr5+fn6+vn5+vr5+fn69fn5+fX5+fX5 - +fVNTWkcHI/w9fX19fX19fTz9fX19fXz9fP19fTzBQc1Ly+P6enb1dTN0Mxxdnh8QkD9/f39/f39/f39 - /f39/f39/f0AAAAAAAAAAAAAAAACv/38/Pz8/Pz8/Pz8+vz8/Pz8+vz6+vr6+fr6+vn5+vr5+fn5+fn5 - +fX5+fX5+fX1+U8aD1Pj9fX19fX19fT19fX09PX18/X19PXz9PMhPDxt1erc19XQzczNlHN4eHtAOf39 - /f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAAPA/Pz8/Pz8/Pz8/Pr8+vr6+vr6+vr6+vr6+vr6+vr5 - +fn5+fr6+fn5+vX5+fX1+fn1TUTI9fX19fX19fXTedP19fX19fP18/Xz9fXPb0g8ouvc2dTUzM3JysFw - dnh4fDkn/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAr/8/fz8/Pz8/Pz8/Pz8/Pz8/Pz6/Pr6 - +vr6+vr6+fr6+vr5+fn5+fn5+fn5+fn1+fnL9PX59fX19fXnmXB1ceX19fX19fX19fXzmzxJUuvs29XU - 1M3MycbJeHZ4eHh8QCb9/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAADwP38/f38/Pz8/Pz8/Pz8 - +vr6+vz6+vr6+vr6+vr6+vr5+fr5+fn6+fn5+fn5+fn1+fX5+fX1+fX1w3Bic5lmi/T19PX19PP19PXz - skg8Usfc1czMycXDxZ5zeHh4eHwnI/39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAAK//Pz8/Pz9 - /Pz8/Pz8/Pr8/Pz8+vr8+vr6+vr6+fr6+fr6+fr6+fn5+fn5+fn5+fn1+fX59fn12odwYMP9/XNknfX1 - 9PX19fT19fT15hIsLYPMzcXDw8HBdHZ4eHh4fiUl/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAA - AsD8/fz8/fz8/Pz8/Pz8/Pz8+vr8/Pr8+vz6+vr6+vn6+vn6+fn6+fn5+fn5+fn1+fn1+fX57aRwapb7 - /f397z09nfX19PX09fX09fT0BSFCLCKzw8GuwZR0eHh4eHh8JyP9/f39/f39/f39/f39/f39/f0AAAAA - AAAAAAAAAAADwP38/f38/P38/Pz8/Pz8/Pr8/Pr6/Pr8+vz6+vr6+vr5+vr6+vn6+fn6+fn5+fn5+fn1 - +cZ2dXaH/f37+Pj71T5Ije319fX19PX19fMILS5CpsXBrquldHh4eHh4eIAmI/39/f39/f39/f39/f39 - /f39/QAAAAAAAAAAAAAAAALA/f38/Pz9/Pz9/Pz8/Pz8/Pz8/Pz6/Pr6+vr6+vr6+vr6+fn5+vn6+fn5 - +fn5+fn5+fn5pnh2eHDJ/fj29PH36WQ8ZaHl9fX19fTSkSIsgsrFwa2qqnZ2eHh2eHh4eyYl/f39/f39 - /f39/f39/f39/f39AAAAAAAAAAAAAAAAAr/8/f38/fz8/fz8/fz8/Pz8/Pz8/Pz6/Pz6/Pr8+vr6+vn6 - +vr5+vn6+fn5+fn5+fn1+fn1lG91dGPc+/Hu7u7u640vPDBSgoqCOjkuOaLJwaunp6d/dnh2eHt4eHiA - JiP9/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAADwP38/f38/P38/P38/Pz8/Pz8/Pz6/Pz6+vz6 - /Pr6/Pr6+vr6+vr5+vn6+vn5+fn5+fn59fnnbGx4dGPU+O7q6enp69mNPCgsIiAtbp3FxK2qp6WmlXR4 - eHxOeHx4dnwlI/39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALA/f38/f39/Pz9/Pz8/Pz8/Pz8 - /Pz6/Pz8+vz6+vr6+vr6+vr5+vr6+vn5+vn5+vn5+fn59fnOYWt4dmPB8erc3NnZ2dne2cmsx9HJxK6r - p6WgoId0eHh7QxwjTnx7fiYl/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAsD8/f38/P39/fz8 - /f38/fz8/Pz8/Pz6/Pr8+vz8+vr8+vr6+vr5+vn6+vr5+vn5+fn5+fn6+fidaWt4dnCH2+nZ2NTQ0MrK - ycnEwa6rqqeloKCHdnh4e0McJSMeJW+BJyP9/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAADwP38 - /f39/P38/P38/P38/Pz8/Pz8/Pz8/Pz8+vr8+vr8/Pr6+vr5+vn5+fr5+fn5+fn5+fn1+fWPSU52eHNw - pdfZ1M3JycPDwbWrqqegoKCXeHZ2e3xCHRwTEQ4PHkMnI/39/f39/f39/f39/f39/f39/QAAAAAAAAAA - AAAAAALA/f38/f39/P39/Pz8/Pz9/fz8+vz8/Pz8+vz8/Pr8+vr6+vr6+vr6+vr6+fr6+vr6+fn5+fn5 - +fWcPEl2e3RzcJnK0MnFwrWrp6qnpKCaeXZ2eHx4QB4hEQD9/QoNDyMl/f39/f39/f39/f39/f39/f39 - AAAAAAAAAAAAAAAAAsD9/f38/P39/f39/f38/fz8/Pz9/Pz8/Pz8+vz6/Pr8+vr6+vz6+vr6+vr6+vn5 - +fn6+fr5+fn5+fWiOkZveHh4c3B1l6CtrautoJeUeXR0eHt8aR4PDgoAAP39/f0MECP9/f39/f39/f39 - /f39/f39/f0AAAAAAAAAAAAAAAADwP39/f39/P38/Pz9/P38/Pz9/Pz8/Pz8/Pz8+vz8/Pr8/Pz6+vz6 - +vr6+fr5+vr6+vn5+fn5+fn5+fm0LkJHc3x7dnZ2dHBxcnB0dHV2eHt+eEAdEAsAAAAA/f39/f0KQP39 - /f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALA/f39/f39/P39/fz9/Pz9/fz9/P38/Pz8/Pz8/Pr8 - /Pr6+vz6+vz6+vr6+vr6+fn5+fr5+fr5+fn59fnlhSJARnV9fHh4eHh4eHh7fHx8b0AdIyEMAAAAAAD9 - /f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAsD9/f39/f39/f39/f39/fz8/Pz8/P38 - /Pz8/Pz8/Pr8/Pz8+vz6+vr6+vr6+vn6+vr6+fr6+fn5+fn5+fn50ksnJSVGbHt/fnyAf3hpSSMeDw0M - BAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAADwP39/f39/f38/Pz9/P39 - /fz9/P38/P38/Pz8/Pz8/Pr8+vr8+vz6+vr6+vr6+vr6+fn6+fn5+vn5+fn5+fX5+bRWIyMjHRwdIyUc - HRwcEA4KAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALg/f39/f39 - /f39/fz9/Pz8/fz9/P38/Pz8/Pz8/Pz8/Pr8/Pr8+vz8/Pr8+vr6+vn6+vn6+vr5+fn5+fn5+fn5+fn1 - 0pBVTEtBJ0uJkhsJAAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAA - AsD9/f39/f39/f39/f39/f39/fz9/P38/fz9/Pz8/Pz8/Pz8/Pr8+vr6/Pr6+vr6+vr6+vn5+fn5+fr6 - +fn5+fX59fn19fn59fn1+fX1BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAA - AAAAAAAAAAADwP39/f39/f39/f39/P39/fz9/fz8/P38/fz9/Pr8/Pz8/Pr8/Pr8/Pr6+vr6+vr6+vr6 - +vr6+vr6+fn5+fn5+fn5+fn5+fX59fX19fUFAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39 - /f39/QAAAAAAAAAAAAAAAALA/f39/f39/f39/f39/Pz8/fz9/f38/Pz8/Pz9/fz8/Pz8/Pr8/Pr6/Pr8 - +vr8+vr6+vn6+vn5+fn5+fn5+vn5+fn5+fn1+fX5+fn19QUAAAAAAAAAAAAAAAD9/f39/f39/f39/f39 - /f39/f39/f39/f39AAAAAAAAAAAAAAAAAuD9/f39/f39/f39/f39/f39/fz8/f38/fz9/Pz8/Pz8/Pz8 - /Pr8/Pz6/Pr8/Pr6/Pr6+vr5+vr6+vr6+fn5+fn5+fn59fn5+fX59fn1BQAAAAAAAAAAAAAAAP39/f39 - /f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAACwP39/f39/f39/f39/f39/fz9/f38/f38/fz9 - /Pz9/fz8/Pz8/Pr8/Pz6/Pr6+vz6+vr6+vr6+vr5+fn6+vn6+vn5+fn5+fX5+fX59fUFAAAAAAAAAAAA - AAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAAPA/f39/f39/f39/f39/f39/fz9 - /f38/f38/Pz9/Pz8/fz8/Pz8/Pz6/Pz6/Pz6+vr6+vr6+vr6+fr6+vn5+fn5+fn5+fn1+fn1+fX59QUA - AAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAsD9/f39/f39/f39 - /f39/f39/fz8/f38/f39/Pz9/Pz8/Pz8/Pz8/Pz8/Pz8+vz6/Pz6/Pr6+vr6+vr5+vr6+fn5+fn5+fn5 - +fn5+fX1BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAAC4P39 - /f39/f39/f39/f39/f39/f38/f38/P39/Pz9/fz9/P39/Pz8/Pz6/Pr8+vz6+vr6+vz6+vr6+fr6+fn6 - +vr5+fn5+fn1+fn1+fkFAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAA - AAAAAALA/f39/f39/f39/f39/f39/f39/f38/f39/P39/fz8/fz8/Pz8/Pz8/Pz6/Pz8+vz8+vr8+vr6 - +vr6+vn6+vn5+fr5+fr5+fn59fn19QUAAAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39 - AAAAAAAAAAAAAAAAA8D9/f39/f39/f39/f39/f39/f39/f38/f39/P38/Pz8/P38/Pz8/Pz8/Pz8+vz8 - +vr8+vr6+vr6+vr6+vr6+vr6+fr5+fn5+fn5+fn1BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39 - /f39/f39/f0AAAAAAAAAAAAAAAACwP39/f39/f39/f39/f39/f39/f39/f38/P39/P39/fz9/Pz8/fz8 - /Pz8/Pz8+vz8/Pr8+vz6+vr6+vr6+fn6+fn5+fr5+vn5+fn5+fUFAAAAAAAAAAAAAAAA/f39/f39/f39 - /f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALg/f39/f39/f39/f39/f39/f39/f39/f39/P39/P39 - /fz8/f38/fz9/Pz8/Pz8+vz8/Pr8+vr6/Pr6+vr6+vn6+vr6+fr5+vr5+fn59QUAAAAAAAAAAAAAAAD9 - /f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAsD9/f39/f39/f39/f39/f39/f39/f39 - /f39/P39/Pz9/P38/Pz8/Pz8/Pz8/Pz8+vr8/Pr8/Pr6+vr6+vr6+vr6+fn6+fn5+fn6+fn1BQAAAAAA - AAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAADwP39/f39/f39/f39/f39 - /f39/f39/f39/f39/P39/fz9/P39/fz9/Pz8/Pz8/Pz8/Pr8/Pr6/Pr6/Pr6+vr6+vn6+vn6+vn5+vn5 - +fkFAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALA/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/P39/f39/Pz8/fz8/f38/Pz8/Pz8/Pr8/Pz6/Pz6+vr8+vr6+vr6 - +vn5+vr5+fn59QUAAAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAA - AuD9/f39/f39/f39/f39/f39/f39/f39/f39/f39/Pz9/P39/fz8/P38/P38/fz8/Pz8/Pr8/Pz6+vr6 - /Pr6+vr6+vn6+vr5+fr6+vr1BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAA - AAAAAAAAAAACwP39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fz9/Pz8/fz9/Pz8/Pz8/Pz8/Pz8 - /Pr6/Pz8/Pz6+vz6+vr6+vr6+fr6+fn5+fkFAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39 - /f39/QAAAAAAAAAAAAAAAAPA/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fz9/f38 - /fz9/Pz8/Pz8/Pz6+vr6+vr6+vz6+vr6+vr6+fn6+vn59QUAAAAAAAAAAAAAAAD9/f39/f39/f39/f39 - /f39/f39/f39/f39AAAAAAAAAAAAAAAAAsD9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/P39 - /fz9/fz8/P38/Pz9/Pz8/Pz8/Pz8/Pz8/Pz6+vr8+vr6+vr6+vn5+vr5BQAAAAAAAAAAAAAAAP39/f39 - /f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAAC4P39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/Pz8/fz9/f38/Pz9/Pz9/Pz8/Pz8/Pz8/Pz6+vz6+vr6/Pr6+vr6+vr5+fkFAAAAAAAAAAAA - AAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALA/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/fz8/P38/fz9/Pz9/Pz8/Pz8/Pz6+vz8+vz8+vr6+vr6+vr6+vr69QUA - AAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAA8D9/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/fz9/f39/f38/fz9/Pz9/fz8/Pz8/Pz8/Pz8+vr8+vr6+vr6 - +vr5+vn5BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAACwP39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fz9/f38/f38/Pz9/Pz8/fz8/Pz8/Pz8+vr8 - /Pr8+vr6+vr6+vr6+vkFAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAA - AAAAAALg/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fz8/P38/f39/Pz9/Pz8/fz8 - /Pr8/Pz8/Pz8/Pr8/Pr6+vr6+vr6+QUAAAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39 - AAAAAAAAAAAAAAAAAsD9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f38/P39 - /Pz9/fz8/Pz8/fz8/Pz8+vr6/Pr6/Pz6+vr6+vr5BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39 - /f39/f39/f0AAAAAAAAAAAAAAAADwP39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f38/f39/P39/Pz8/fz8/fz8/Pz8/Pz8/Pz6/Pz6+vz6+vz6+vkFAAAAAAAAAAAAAAAA/f39/f39/f39 - /f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALA/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f38/f39/P39/Pz8/f38/Pz8/Pr8/Pz8/Pz6+vz6+vr8+vr6+QUAAAAAAAAAAAAAAAD9 - /f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAuD9/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f38/P39/P39/fz8/Pz9/Pz8/fz8/Pz8/Pz8/Pz6/Pr6+vr5BQAAAAAA - AAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAACwP39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/P39/P39/fz8/fz9/Pz8/Pz8/Pz8/Pz6+vz6/Pz6 - +voFAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAAPA/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/P39/Pz9/f38/fz9/Pz8/Pz8/Pz8 - /Pz8+vz6+vr8+QUAAAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAA - AsD9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/P39/fz9/Pz8/Pz9 - /P38/Pz8/Pz6/Pz8+vz8/Pr5BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAA - AAAAAAAAAAAC4P39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/P39 - /fz9/f39/Pz9/Pz8/Pz8/Pz8/Pz8+vr6+voFAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39 - /f39/QAAAAAAAAAAAAAAAALA/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/Pz9/f39/Pz9/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8+gUAAAAAAAAAAAAAAAD9/f39/f39/f39/f39 - /f39/f39/f39/f39AAAAAAAAAAAAAAAAA8D9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/fz9/Pz9/fz9/P39/fz8/Pz8/Pz8/Pz8/Pr5BQAAAAAAAAAAAAAAAP39/f39 - /f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAACwP39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/fz9/fz9/fz9/Pz8/f38/Pz8/Pz8/Pz6/PoFAAAAAAAAAAAA - AAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALg/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fz8/fz9/fz8/Pz8/fz8/Pz8/Pz8+gUA - AAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAsD9/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/Pz9/f38/fz8/fz8/fz8/Pz6 - /Pz8/Pz6BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAADwP39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f38 - /f38/fz8/P38/Pz8/PoFAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAA - AAAAAALA/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /P38/fz9/P38/Pz8/P38/Pz8+vz8+gUAAAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39 - AAAAAAAAAAAAAAAAAuD9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/P38/fz9/P39/f39/P38/Pz9/Pz6BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39 - /f39/f39/f0AAAAAAAAAAAAAAAACwP39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/fz9/Pz8/Pz8/Pz8/Pz8+vUFAAAAAAAAAAAAAAAA/f39/f39/f39 - /f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAAPA/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f38/f38/Pz69QUAAAAAAAAAAAAAAAD9 - /f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAsD9/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fz9/fz8/Pz9/P39/fz8/P38/P38+vX1BQAAAAAA - AAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAAC4P39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fz6+vr5+fn6+vr6/Pz8+vz8+fnz - 8+gFAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALA/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39+vn18/Pz8/X19fX1 - 9fX19fPz6Ojo4QUAAAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAA - A8D9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fz69fPo - 4uLm5ubo6Ojo6Ojm5uLi4uK9BQAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAA - AAAAAAAAAAACwP39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/fr1+fX16Obh4eDg4ODg4ODg4eLm4VoBAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39 - /f39/QAAAAAAAAAAAAAAAALg/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f38+vPz9fn1+fn5+fn5+vn19fPz6OJYAAAAAAAAAAAAAAAAAAD9/f39/f39/f39/f39 - /f39/f39/f39/f39AAAAAAAAAAAAAAAAAsD9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f368/P59fn1+fn5+vn19fXz8+jmsAAAAAAAAAAAAAAAAAAAAP39/f39 - /f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAADwP39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/fr16PX5+fn5+fn5+fX18/Po4a8AAAAAAAAAAAAAAAAA - AAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALA/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/PXo8/X5+fX1+fX19fPo6OFaAAAAAAAA - AAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAAuD9/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f389fPz9fX1+fn19fPz6Oji - WgAAAAAAAAAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAACwP39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f368+j59fn1 - 9fX18+jo4q8AAAAAAAAAAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAA - AAAAAAPA/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /fnz8/X59fX18+jo5uBaAAAAAAAAAAAAAAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39 - AAAAAAAAAAAAAAAAAsD9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f38+vPo9fX19fPz6OjgWgAAAAAAAAAAAAAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39 - /f39/f39/f0AAAAAAAAAAAAAAAAC4P39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f368+j19fPz6Ojo4FoBAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f39/f39/f39 - /f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALA/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/frz6PXz8+jo5uCvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD9 - /f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAAA8D9/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39+vPo8/Po6ObgWgAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAACwP39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fz58+jz6OjmwFkAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAALg/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fno5ujm5uBZAwAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAA - AsD9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f389ejm - 5ubhWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAA - AAAAAAAAAAADwP39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/frz5uLm4FkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39 - /f39/QAAAAAAAAAAAAAAAALA/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f389fPm5uBZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD9/f39/f39/f39/f39 - /f39/f39/f39/f39AAAAAAAAAAAAAAAAA+D9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/Pr18+bgWgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP39/f39 - /f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAAC4P39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/fz69fPo4VkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAA/f39/f39/f39/f39/f39/f39/f39/f39/QAAAAAAAAAAAAAAAAPh+vr5+fn5+fn5+fn5+fn5+fn5 - +fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+vn59fPz6OGvAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAD9/f39/f39/f39/f39/f39/f39/f39/f39AAAAAAAAAAAAAAAABb3iv7+/v7+/v7+/ - v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7++vr29vLqxVAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAP39/f39/f39/f39/f39/f39/f39/f39/f0AAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 - /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f////////// - /////////////////////////////////////////////////////////////////////gH///////// - /////////+AAP/////////////////+AAA/////////////////+AAAD///////////////f/AAAAf// - ////////////z/AAAAB//////////////8PgAAAAP//////////////AwAAAAB//////////////wAAA - AAAP/////////////8AAAAAAD//////////////AAAAAAAf/////////////wAAAAAAD//////////// - /8AAAf4AAf/////////////AAAf/AAH/////////////wAAP/8AH/////8AAAAAAAAAAAAPgH//////A - AAAAAAAAAAAD4D//////wAAAAAAAAAAAA/D/v////8AAAAAAAAAAAAP7/j/////AAAAAAAAAAAAD//w/ - ////wAAAAAAAAAAAA//wP////8AAAAAAAAAAAAP/wD/////AAAAAAAAAAAAD/4A/////wAAAAAAAAAAA - A/4AP////8AAAAAAAAAAAAP4AD/////AAAAAAAAAAAAD8AA/////wAAAAAAAAAAAA8AAP////8AAAAAA - AAAAAAMAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAD/////A - AAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAMAAD/////AAAAAAAAAAAAAAAA/ - ////wAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAA - AAAAP////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAADA/////wAAAAAAAAAAAAAB8P////8AAAAAA - AAAAAAAA/z/////AAAAAAAAAAAAAAf+/////wAAAAAAAAAAAAAf//////8AAAAAAAAAAAAAP///////A - AAAAAAAAAAAAf///////wAAAAAAAAAAAAf///////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD//// - ////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAA - A////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAA - AAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////A - AAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD//// - ////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAA - A////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAA - AAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////A - AAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD//// - ////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAA - A////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAA - AAAAAAP////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////A - AAAAAAAAAAAD////////wAAAAAAAAAAAA////////8AAAAAAAAAAAAP////////AAAAAAAAAAAAH//// - ////wAAAAAAAAAAAD////////8AAAAAAAAAAAB/////////AAAAAAAAAAAA/////////wAAAAAAAAAAA - f////////8AAAAAAAAAAAP/////////AAAAAAAAAAAH/////////wAAAAAAAAAAD/////////8AAAAAA - AAAAB//////////AAAAAAAAAAA//////////wAAAAAAAAAAf/////////8AAAAAAAAAAP//////////A - AAAAAAAAAH//////////wAAAAAAAAAD//////////8AAAAAAAAAA///////////AAAAAAAAAA/////// - ////wAAAAAAAAAf//////////8AAAAAAAAAP///////////AAAAAAAAAH///////////wAAAAAAAAD// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - KAAAAEAAAACAAAAAAQAgAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - MJFIFS+RSEYvj0hwL45Jay6SSlIylEo3AFVVAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAKeytGGH01sSSFPfw3lFD/SKBh/0WeXv8+mVf/NZFN/x+CO+MUezF8Cn8qGAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAok0Mm - AAAAAAAAAAAAAAAAAAAAAAB5JBUZejSrL4xJ/2u0fv+Vy6T/kMif/4XClv99vo7/dbqH/263gv9fsXX/ - RJxc/yiCQPQXfjFXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAJX8/+h57N48Afx8QAAAAAByCOC0aeDLnXqtz/6DRrv+UyqP/jsee/4HAkv9utoL/ - Z7N8/2m1fv9lsnn/Wq1w/1Kpav9KpmP/K4VE/iB8N48AfwAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2DRP5wsYL/FXIu7CV7PXwgdjjshcGV/5/Prf+YzKb/ - arV+/z6gWP8tmEn/MJlM/zCZTf8vmUz/NJtQ/0ajX/9KpWP/QqJb/zufVf8ui0j/HHY2lwAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArgEH9zunV/6XTsf9Cklj/ - h8KX/5/Qrf+Mx5z/QaFc/zCZTf80nFH/M5pP/y+MSP8th0X/L41I/zOcUP8zm0//NZxR/zqeVf8zm0// - NJ1Q/yeAQP8SdC1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - LHxC/b/iyf+t1rj/qdS0/5/PrP+IxJj/NJtQ/zObT/8zm1D/JXk8/hxtMrYScCtvAGwfUhNsK3UbbTLU - LIRE/zSdUP8zm1D/NJtQ/zSbUP81nlL/InQ4+Bl6MjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABkAAAAfAAAAHwAAAB8AAAAf - AAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAf - AAAAHwAAAB8AAAAfAAAAHyx8Qfy43sL/pdKx/53Oqv+SyKH/NJpQ/zObT/8xk0v/JGs3/hNiKXUAAAAf - AAAAHwAAAB8AAAAcABcACw9oJoYkdjr+NJ1R/zScUP80m1D/JXk8/xZnK7YPcyYhAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKurqyvk5OTc - 4eHh4ODg4ODg4ODg39/f4N/f3+Dc3Nzg3Nzc4Nzc3ODc3Nzg29vb4Nra2uDa2trg2dnZ4NnZ2eDZ2dng - 2dnZ4NnZ2eDZ2dng2dnZ4NjY2ODY2Njg19fX4NfX1+AweUT+r9q7/53Pqv+azKf/RaNe/zOaT/80m1D/ - NJ1R/y6KR/8ibDf6bpl54tHS0d/S0tLg1NTU3AoKCjMAAAAADWQjhyuBQ/8tiEX/GGUv4xJvK1IAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAACwsLA09/f3//b29v/29vb/9fX1//X19f/09PT/9PT0//Pz8//z8/P/8vLy//Ly8v/x8fH/ - 8fHx//Dw8P/w8PD/7+/v/+/v7//u7u7/7u7u/+3t7f/t7e3/7Ozs/+zs7P/r6+v/MnhE/6bWs/+Yzab/ - XrB0/zGZTf80m1D/NJtQ/zScUP81nlH/KXw//z14Tf/B08b/5+fn/+Tk5P0MDAw+AAAAAQBVAAMRXie9 - GWUvjQCLLgsAAAAAAAAAAA5tJCMiejqrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsLCwNPf39//39/f/9vb2//b29v/19fX/9fX1//T09P/09PT/ - 8/Pz//Pz8//y8vL/8fHx//Hx8f/w8PD/8PDw/+/v7//v7+//7u7u/+7u7v/u7u7/7e3t/+3t7f/s7Oz/ - 7Ozs/zJ1RP+f0q3/gcGS/y2YS/80m1D/NJtQ/zWfUv8shUX/KGg6/5O0nP/m5+b/5+fn/+fn5//k5OT9 - DAwMPgAAAAEAAAAAAAAAAAAAAAAAAAAAAGYACgVsIIRKjVz4JHg8+QAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCwsDT4+Pj/9/f3//f39//29vb/ - 9vb2//X19f/19fX/9PT0//T09P/z8/P/8/Pz//Ly8v/y8vL/8fHx//Hx8f/w8PD/8PDw/+/v7//v7+// - 7u7u/+7u7v/t7e3/7e3t/+zs7P8yckP/mtCp/0WjXv8zmk//NZ1R/zCRS/8gYzL/c5t+/93j3v/o6Oj/ - 6Ojo/+jo6P/n5+f/5OTk/QwMDD4AAAABAAAAAAAAAAAAAAAAC20mVid8P+KUvJ//cLyF/yNzO/kAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwsLA0 - +fn5//j4+P/4+Pj/9/f3//f39//29vb/9fX1//X19f/09PT/9PT0//Pz8//z8/P/8vLy//Ly8v/x8fH/ - 8fHx//Dw8P/w8PD/7+/v/+/v7//u7u7/7u7u/+3t7f/t7e3/NHJF/3zCj/8vmkz/M5pP/yBrNP9Nflv/ - x9fM/+np6f/p6en/6enp/+jo6P/o6Oj/6Ojo/+Tk5P0MDAw+AAAAAQAAAAALbiIsEG8pvmCecf+42sH/ - rde4/y6bTP8jbTf7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAsLCwNPn5+f/5+fn/+Pj4//j4+P/39/f/9/f3//b29v/29vb/9fX1//X19f/09PT/ - 8/Pz//Pz8//y8vL/8vLy//Hx8f/x8fH/8PDw//Dw8P/v7+//7+/v/+7u7v/u7u7/7e3t/zl1Sf9FqmH/ - KHk+/zVsRP+rxLL/6+vr/+rq6v/q6ur/6enp/+np6f/p6en/6enp/+jo6P/l5eX9DAwMPgBfDxAXcy+Q - NoZM+6LKrP+13MD/qtW2/1mtb/80nlH/IWk0+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCwsDT6+vr/+fn5//n5+f/4+Pj/+Pj4//f39//39/f/ - 9vb2//b29v/19fX/9fX1//T09P/09PT/8/Pz//Pz8//y8vL/8fHx//Hx8f/w8PD/8PDw/+/v7//v7+// - 7u7u/+7u7v8pZzr/IGIy/4arkP/n6uj/7Ozs/+vr6//q6ur/6urq/+rq6v/q6ur/6enp/+np6f/o6Oj/ - 4+Tj/RBSIo4adTPpeK+H/7vexf+q1bb/n9Cs/4rFmv8tmEr/NZ9S/yBjMfwAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwsLA0+vr6//r6+v/5+fn/ - +fn5//j4+P/4+Pj/9/f3//f39//29vb/9vb2//X19f/19fX/9PT0//T09P/z8/P/8/Pz//Ly8v/y8vL/ - 8fHx//Hx8f/w8PD/8PDw/+/v7//v7+//dqOC/9nj3P/t7e3/7e3t/+Xp5v+DvZP/TaNl/+Pn5P/q6ur/ - 6urq/+rq6v/p6en/ydbL/0ePWv9OlWH/sdi7/67Yuv+i0a7/mcyn/5TKo/9Colz/M5pP/zagUv8eXi78 - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - sLCwNPv7+//6+vr/+vr6//n5+f/5+fn/+Pj4//j4+P/39/f/9/f3//b29v/29vb/9fX1//X19f/09PT/ - 9PT0//Pz8//z8/P/8vLy//Ly8v/x8fH/8fHx//Dw8P/w8PD/7+/v/+/v7//u7u7/7u7u/7XUvf86m1X/ - dbiH/2qxff9urH//6+vr/+rq6v/q6ur/6urq/+jo6P+WuJ/+Gmov8Guje/+f0a3/ksmh/4nFmf9ntHz/ - MJlM/zSbUP82oFP/HVct/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALCwsDT7+/v/+/v7//r6+v/6+vr/+fn5//n5+f/4+Pj/+Pj4//f39//39/f/ - 9vb2//b29v/19fX/9fX1//T09P/09PT/8/Pz//Pz8//y8vL/8vLy//Hx8f/x8fH/8PDw//Dw8P/v7+// - 1+Tb/2qyfv8ulUv/0ObW//X69//t9u//PJJT/3Kpgf/m6Of/6urq/+rq6v/q6ur/5ubm/Q9EH4MbZS78 - ZaF2/4PBk/96vY3/NZtR/zSbUP80m1D/NqBT/x1WLf0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwsLA0/Pz8//v7+//7+/v/+vr6//r6+v/5+fn/ - +fn5//j4+P/4+Pj/9/f3//f39//29vb/9vb2//X19f/19fX/9PT0//T09P/z8/P/8/Pz//Ly8v/y8vL/ - 8fHx//Hx8f/w8PD/8PDw/87f0/84l1L/LJdJ/5rNqP/o8+r/2eze/9Lp2f9Wnmn/Mn9I/4Gri/+auqL/ - jLCV/1GGYP4scD/+e7iM/37AkP91uof/RKNe/zObT/80nFD/NJtQ/zagU/8dWC3+AAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbW1NPz8/P/8/Pz/ - +/v7//v7+//6+vr/+vr6//r6+v/5+fn/+fn5//j4+P/4+Pj/9/f3//f39//29vb/9vb2//X19f/09PT/ - 9PT0//Pz8//z8/P/8vLy//Ly8v/x8fH/8fHx//Dw8P/w8PD/o8it/yuLRf8ql0j/isWa/9Ho1v+/38f/ - vd/G/5nKp/9lonX/TpFg/1aWaP9xr4H/g8OV/3S7iP9tt4H/S6Zk/zKaTv8xk0v/I2w3/zOYTv82olT/ - HVgt/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALW1tTT9/f3//Pz8//z8/P/7+/v/+/v7//v7+//6+vr/+vr6//n5+f/5+fn/+Pj4//j4+P/39/f/ - 9/f3//b29v/29vb/9fX1//X19f/09PT/9PT0//Pz8//z8/P/8vLy//Ly8v/x8fH/8fHx//Dw8P92rYX/ - LYdF/y6ZS/9RqWn/pNKx/6rVtf+czqr/k8mi/4vGm/+AwJL/d7yJ/263gv9ks3r/QqJc/zKbTv8wlEz/ - F1Ip9hhTJoYRSyHsKXw//x1aLv4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU0/f39//39/f/8/Pz//Pz8//v7+//7+/v/+/v7//r6+v/6+vr/ - +fn5//n5+f/4+Pj/+Pj4//f39//39/f/9vb2//b29v/19fX/9fX1//T09P/09PT/8/Pz//Pz8//y8vL/ - 8fHx//Hx8f/w8PD/7+/v/3iqhv8lezz/MphO/yyYSf9PqGj/breC/37AkP98vo3/crmG/1+vdf9LpmP/ - M5pO/zSeUf8shUT/EE8h8gxMHD8AAAAAADwAEQVEFZEYUSb6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbW1NP39/f/9/f3//f39//z8/P/8/Pz/ - /Pz8//v7+//7+/v/+vr6//r6+v/5+fn/+fn5//j4+P/4+Pj/9/f3//f39//29vb/9vb2//X19f/19fX/ - 9PT0//T09P/z8/P/8/Pz//Ly8v/y8vL/8fHx//Hx8f/w8PD/mbmh/ypvPP8rgkP/M51Q/zKdT/8umEv/ - LphL/y+YS/8xm07/NaBS/y+OSP8iZzT/EEkdvwA9ByEAAAAAAAAAAAAAAAAAAAAAH10rKQAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW1tTT+/v7/ - /f39//39/f/9/f3//Pz8//z8/P/8/Pz/+/v7//v7+//6+vr/+vr6//n5+f/5+fn/+Pj4//j4+P/39/f/ - 9/f3//f39//29vb/9fX1//X19f/09PT/9PT0//Pz8//z8/P/8vLy//Ly8v/x8fH/8fHx//Dw8P/f5eD/ - dZt//yZiNv8hZzX/J3c9/yl8P/8ofD//I203/xpXKv4KRhrEAEUOWAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAC1tbU0/v7+//7+/v/+/v7//f39//39/f/8/Pz//Pz8//z8/P/7+/v/+/v7//r6+v/6+vr/ - +vr6//n5+f/5+fn/+Pj4//j4+P/39/f/9/f3//b29v/29vb/9fX1//X19f/09PT/8/Pz//Pz8//y8vL/ - 8vLy//Hx8f/x8fH/8PDw//Dw8P/u7+7/vc3B/5awnv+NqJT/jamU/6i9rf0VLRtUAAAAAQAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbW1NP7+/v/+/v7//v7+//39/f/9/f3//f39//39/f/8/Pz/ - /Pz8//v7+//7+/v/+vr6//r6+v/5+fn/+fn5//n5+f/4+Pj/+Pj4//f39//39/f/9vb2//b29v/19fX/ - 9fX1//T09P/09PT/8/Pz//Ly8v/y8vL/8fHx//Hx8f/w8PD/8PDw/+/v7//v7+//7u7u/+7u7v/q6ur9 - DAwMPgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW1tTT//////v7+//7+/v/+/v7/ - /v7+//39/f/9/f3//f39//z8/P/8/Pz/+/v7//v7+//7+/v/+vr6//r6+v/5+fn/+fn5//j4+P/4+Pj/ - 9/f3//f39//29vb/9vb2//X19f/19fX/9PT0//T09P/z8/P/8/Pz//Ly8v/y8vL/8fHx//Hx8f/w8PD/ - 7+/v/+/v7//u7u7/6+vr/QwMDD4AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU0 - /////////////////v7+//7+/v/+/v7//f39//39/f/9/f3//Pz8//z8/P/7+/v/+/v7//v7+//6+vr/ - +vr6//n5+f/5+fn/+Pj4//j4+P/39/f/9/f3//b29v/29vb/9fX1//X19f/09PT/9PT0//Pz8//z8/P/ - 8vLy//Ly8v/x8fH/8fHx//Dw8P/w8PD/7+/v/+vr6/0MDAw+AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAtbW1NP/////////////////////+/v7//v7+//7+/v/9/f3//f39//39/f/8/Pz/ - /Pz8//z8/P/7+/v/+/v7//r6+v/6+vr/+fn5//n5+f/5+fn/+Pj4//j4+P/39/f/9/f3//b29v/29vb/ - 9fX1//X19f/09PT/8/Pz//Pz8//y8vL/8vLy//Hx8f/x8fH/8PDw//Dw8P/s7Oz9DAwMPgAAAAEAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW1tTT///////////////////////////7+/v/+/v7/ - /v7+//39/f/9/f3//f39//z8/P/8/Pz//Pz8//v7+//7+/v/+vr6//r6+v/5+fn/+fn5//j4+P/4+Pj/ - 9/f3//f39//29vb/9vb2//X19f/19fX/9PT0//T09P/z8/P/8/Pz//Ly8v/y8vL/8fHx//Hx8f/w8PD/ - 7Ozs/QwMDD4AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU0//////////////// - /////////////////v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//z8/P/8/Pz/+/v7//v7+//6+vr/ - +vr6//r6+v/5+fn/+fn5//j4+P/4+Pj/9/f3//f39//29vb/9vb2//X19f/19fX/9PT0//T09P/z8/P/ - 8/Pz//Ly8v/y8vL/8fHx/+3t7f0MDAw+AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - tbW1NP/////////////////////////////////////+/v7//v7+//7+/v/+/v7//f39//39/f/8/Pz/ - /Pz8//z8/P/7+/v/+/v7//v7+//6+vr/+vr6//n5+f/5+fn/+Pj4//j4+P/39/f/9/f3//b29v/29vb/ - 9fX1//X19f/09PT/9PT0//Pz8//y8vL/8vLy//Hx8f/t7e39DAwMPgAAAAEAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALW1tTT////////////////////////////////////////////////+/v7/ - /v7+//7+/v/9/f3//f39//39/f/8/Pz//Pz8//v7+//7+/v/+/v7//r6+v/6+vr/+fn5//n5+f/4+Pj/ - +Pj4//f39//39/f/9vb2//b29v/19fX/9fX1//T09P/09PT/8/Pz//Pz8//y8vL/7u7u/QwMDD4AAAAB - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU0//////////////////////////////// - //////////////////////7+/v/+/v7//v7+//39/f/9/f3//f39//z8/P/8/Pz//Pz8//v7+//7+/v/ - +vr6//r6+v/5+fn/+fn5//j4+P/4+Pj/9/f3//f39//29vb/9vb2//X19f/19fX/9PT0//T09P/z8/P/ - 8/Pz/+7u7v0MDAw+AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbW1NP////////// - /////////////////////////////////////////////////v7+//7+/v/+/v7//v7+//39/f/9/f3/ - /Pz8//z8/P/8/Pz/+/v7//v7+//6+vr/+vr6//r6+v/5+fn/+fn5//j4+P/4+Pj/9/f3//f39//29vb/ - 9vb2//X19f/09PT/9PT0//Pz8//v7+/9DAwMPgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALW1tTT////////////////////////////////////////////////////////////////+/v7/ - /v7+//7+/v/9/f3//f39//39/f/8/Pz//Pz8//z8/P/7+/v/+/v7//r6+v/6+vr/+vr6//n5+f/5+fn/ - +Pj4//j4+P/39/f/9/f3//b29v/29vb/9fX1//X19f/09PT/8PDw/QwMDD4AAAABAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU0//////////////////////////////////////////////// - //////////////////////7+/v/+/v7//v7+//7+/v/9/f3//f39//39/f/8/Pz//Pz8//v7+//7+/v/ - +/v7//r6+v/6+vr/+fn5//n5+f/4+Pj/+Pj4//f39//39/f/9vb2//b29v/19fX/9fX1//Dw8P0MDAw+ - AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbW1NP////////////////////////// - /////////////////////////////////////////////////v7+//7+/v/+/v7//v7+//39/f/9/f3/ - /f39//z8/P/8/Pz/+/v7//v7+//7+/v/+vr6//r6+v/5+fn/+fn5//j4+P/4+Pj/9/f3//f39//29vb/ - 9vb2//X19f/x8fH9DAwMPgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW1tTT///// - //////////////////////////////////////////////////////////////////////////////// - /v7+//7+/v/+/v7//v7+//39/f/9/f3//Pz8//z8/P/8/Pz/+/v7//v7+//6+vr/+vr6//n5+f/5+fn/ - +fn5//j4+P/4+Pj/9/f3//f39//29vb/8vLy/QwMDD4AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAC1tbU0//////////////////////////////////////////////////////////////// - ///////////////////////////+/v7//v7+//7+/v/9/f3//f39//39/f/8/Pz//Pz8//z8/P/7+/v/ - +/v7//r6+v/6+vr/+fn5//n5+f/4+Pj/+Pj4//f39//39/f/9vb2//Ly8v0MDAw+AAAAAQAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbW1NP////////////////////////////////////////// - //////////////////////////////////////////////////////7+/v/+/v7//v7+//7+/v/9/f3/ - /f39//39/f/8/Pz//Pz8//v7+//7+/v/+/v7//r6+v/6+vr/+fn5//n5+f/4+Pj/+Pj4//f39//z8/P9 - DAwMPgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW1tTT///////////////////// - //////////////////////////////////////////////////////////////////////////////// - /v7+//7+/v/+/v7//v7+//39/f/9/f3//f39//z8/P/8/Pz/+/v7//v7+//6+vr/+vr6//r6+v/5+fn/ - +fn5//j4+P/4+Pj/8/Pz/QwMDD4AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU0 - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////v7+//7+/v/+/v7//f39//39/f/9/f3//Pz8//z8/P/8/Pz/ - +/v7//v7+//6+vr/+vr6//n5+f/5+fn/+Pj4//T09P0MDAw+AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAtbW1NP////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////+/v7//v7+//7+/v/9/f3/ - /f39//39/f/8/Pz//Pz8//v7+//7+/v/+/v7//r6+v/6+vr/+fn5//n5+f/19fX9DAwMPgAAAAEAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW1tTT///////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////7+/v/+/v7//v7+//39/f/9/f3//f39//z8/P/8/Pz//Pz8//v7+//7+/v/+vr6//r6+v/5+fn/ - 9PT0/QwMDD4AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU0//////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////v7+//7+/v/9/f3//Pz8//v7+//7+/v/+/v7//z8/P/8/Pz/ - +/v7//v7+//6+vr/9/f3/+vr6/0MDAw+AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - tbW1NP////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////Pz8//b29v/t7e3/ - 6urq/+3t7f/x8fH/8vLy//Ly8v/x8fH/7Ozs/+Tk5P/Y2Nj7DQ0NNwAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALW1tTT///////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////z8/P/u7u7/5ubm/9fX1//Pz8//zs7O/83Nzf/Nzc3/zc3N/8vLy//Nzc3/u7u7uAAAABEAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU0//////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////9/f3/7e3t/+np6f/v7+//8PDw//Hx8f/x8fH/8PDw/+np6f/g4OD/ - yMjIzkZGRh0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbW1NP////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////v7+//Hx8f/i4uL/7u7u/+/v7//w8PD/ - 7+/v/+jo6P/e3t7/w8PDzVdXVykAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALW1tTT///////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////7+/v/29vb/ - 4eHh/+3t7f/u7u7/7e3t/+bm5v/d3d3/xsbG1E5OTioAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU0//////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ////////////////9/f3/+Dg4P/s7Oz/6+vr/+Xl5f/b29v/vr6+zlNTUysAAAABAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbW1NP////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////n5+f/g4OD/6enp/+Pj4//a2tr/wMDA1U1NTSsAAAAB - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW1tTT///// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////39/f/3t7e/+Hh4f/Y2Nj/ - u7u70E9PTy0AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAC1tbU0//////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////+/v7/ - 9PT0/9fX1//X19f/vb291ktLSywAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtbW1NP////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////Pz8/+vr6//S0tL/urq60EtLSy8AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALm5uTP///////////////////// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////////////+/v7//f39//T09P/h4eH+vr6+yldXVyYAAAABAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8vLwX - 6urqh+Xl5Yvl5eWL5eXli+Xl5Yvl5eWL5eXli+Xl5Yvl5eWL5eXli+Xl5Yvl5eWL5eXli+Xl5Yvl5eWL - 5eXli+Xl5Yvl5eWL5eXli+Xl5Yvl5eWL5eXli+Xl5Yvl5eWL4+Pji9zc3IvW1taKv7+/eF1dXR4AAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////// - ///////4B////////+AB///////5wAB///////iAAD//////+AAAP//////4AOAf//////gD8B//+AAA - AAAYf//4AAAAABz3//gAAAAAH8f/+AAAAAAfh//4AAAAAB4H//gAAAAAGAf/+AAAAAAAB//4AAAAAAAH - //gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAAf/+AAAAAAAB//4AAAAAADn//gAAAAAAf//+AAA - AAAH///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB// - //gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAH///+AAA - AAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB// - //gAAAAAH///+AAAAAAf///4AAAAAD////gAAAAAf///+AAAAAD////4AAAAAf////gAAAAD////+AAA - AAf////4AAAAD/////gAAAAf////+AAAAD/////4AAAA//////////////////////////////////// - /////////////////////ygAAABAAAAAgAAAAAEACAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ - Dg4O/wAVBv8AGAD/FS8c/wBDAv8AQwr/AEUP/wVHFf8LRxr/Dk4d/xFFH/8AYxH/AWUc/wFsH/8Afhj/ - EEsg/xJOIv8SVCP/GVMo/xlUKf8aWCv/Hlku/x9eMP8NZCX/B2wi/xRhKP8fYC//GmUv/xNqK/8McCb/ - DnIo/w59LP8RcCr/FHAt/xN0Lf8QeCz/HGYw/xxrMv8cbTL/Hm80/xdzMP8YdDH/G3U0/x53Nv8WfjL/ - G3s1/yBiM/8hZDP/J2M3/yJpNf8kbDf/JG04/yloOv8lcDn/JXU6/ypwPf8tcT//IXk6/yB8OP8meT3/ - Jnw9/yh5Pv8ofT//NW1E/yl8QP8ufEP/LX5E/zJzRP81c0b/M3ZF/zF5Rf86dkr/PnhO/05OTv9RUVH/ - VVVV/1paWv9Of1v/YWFh/wGJJv8Jgir/DYwv/x6DOv8ihT3/KIBA/yyBQ/8qhUP/LINE/yyFRf8tiUb/ - K4xG/y6MSP8zgEj/OIZN/zCOSf8tk0j/KpdI/y2WSv8tmEr/LplM/y+cTf8wkUr/NZFO/zGUTP8xmU3/ - NJpP/zKcTv84lFD/PZNU/zObUP80m1D/M51Q/zSdUf85mFP/O51V/z+ZWP81oFL/N6NU/zugVv8/oFn/ - So9e/0OTWf9IkFv/RZ1d/0KiXP9Eo17/RqRf/1GIYP9PkWD/TpZi/1aXaf9Wnmn/YZ5x/3Cae/90m3// - R6Rg/0mgYf9KpmP/S6Zk/06kZf9GqmH/Ualp/1+rc/9arXD/X7B1/2Widv9spHv/YLB1/2Wzev9ltHr/ - arJ+/2m0fv91m4D/b62A/3ajgv9yqoH/d62G/3mqh/9ut4L/b7iC/3Gwgv9zuof/cbyG/3mwiP91uoj/ - eLyK/3u5jP96vo3/fL+O/37BkP+Bq4z/h6uR/42plf+NsJb/hL6T/5exnv+UtZ3/lb2f/5m6of+srKz/ - qL2t/7Kysv+1tbX/urq6/729vf+BwZP/g8KU/4bClf+Iwpf/icWa/4zHm/+Ox53/ksmh/5TKov+VyqT/ - lsyl/5jNpv+ay6j/ms2o/53Oqv+b0ar/n9Ou/6PJrf+g0K3/rMWy/6XSsf+l1LL/p9e0/6rVtv+t1rj/ - rtm6/7XUvv+x2Lz/vs7C/7bcwf+528L/uN/D/7zfxv+/38j/veDG/8HBwf/FxcX/ysrK/83Nzf/B1Mb/ - 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 - /v7+/v3+/v3+/f39/f39+/v9/fv7+/v6+vr6+vr6+vf69/cBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - t/7+/v7+/v7+/f3+/f79/f39/f39+/v9+/v7+/v6+vv6+vf69/r3AQAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALj+/v7+/v7+/v7+/f79/v79/f39/f39+/v7+/v6+/v6+vr6+vr39wEAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAC3/v7+/v7+/v7+/v79/v39/v79/f39+/39+/v7+/v6+/v6+/r6+voBAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAt/7+/v7+/v7+/v7+/v3+/v39/f39/f37+/39+/v7+/r6+vr6+vr3AQAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALf+/v7+/v7+/v7+/v7+/f3+/f79/f39/f37+/39+/v7+/v6+vr6+gEAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAC3/v7+/v7+/v7+/v7+/v7+/f79/v39/f39/f37+/v7+/v7+/v7+vcB - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuP7+/v7+/v7+/v7+/v7+/v7+/v3+/f79/f39/f39/fv7+/v6 - +vv6AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALf+/v7+/v7+/v7+/v7+/v7+/f3+/f79/f39/f37+/v9 - +/v7+/v6+gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3/v7+/v7+/v7+/v7+/v7+/v7+/f79/f79/f39 - /f39+/37+/v7+/oBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt/7+/v7+/v7+/v7+/v7+/v7+/v79/v79 - /v39+/39+/37+/v7+/v7AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALf+/v7+/v7+/v7+/v7+/v7+/v7+ - /v3+/v3+/f79/f37/f39+/v7+gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4/v7+/v7+/v7+/v7+/v7+ - /v7+/v7+/f3+/f79/f39/f37+/v7+/sBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt/7+/v7+/v7+/v7+ - /v7+/v7+/v7+/v7+/f79/f79/v39/f39/fv7AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALf+/v7+/v7+ - /v7+/v7+/v7+/v7+/v7+/v79/v79/f39+/39/fv9+wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3/v7+ - /v7+/v7+/v7+/v7+/v7+/v7+/v7+/v39/v39/f79/fv9+/sBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - t/7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v3+/v79/f39/f37AQAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALj+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/f39/f39/fv9+wEAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAC3/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v79/v7+/v7+/f3+/f0BAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAt/7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v39/f3+/f37AQAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALf+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/f3+/v7+/f399wEAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAC3/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7++/r39/r6+vv39OYB - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuP7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vr05uTg4OTg - 4OC4AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALf+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v739vf6 - +vv69vLfSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+ - +vT6+vr39PLeTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt/7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+ - /v7+/vvy9/f39OfeSwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALf+/v7+/v7+/v7+/v7+/v7+/v7+ - /v7+/v7+/v798vf39OfdSwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4/v7+/v7+/v7+/v7+/v7+ - /v7+/v7+/v7+/v7+/fL29ObdSwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt/7+/v7+/v7+/v7+ - /v7+/v7+/v7+/v7+/v7+/v3n8ua5SwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALf+/v7+/v7+ - /v7+/v7+/v7+/v7+/v7+/v7+/v765ua5SgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3/v7+ - /v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+9+S4SgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - uf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7++/LdTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAN329PT09PT09PT09PT09PT09PT09PT09PT05+XdTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAP////////////////////////////gH////////4AH///////nAAH////// - +IAAP//////4AAA///////gA4B//////+APwH//4AAAAABh///gAAAAAHPf/+AAAAAAfx//4AAAAAB+H - //gAAAAAHgf/+AAAAAAYB//4AAAAAAAH//gAAAAAAAf/+AAAAAAAB//4AAAAAAAH//gAAAAAAAf/+AAA - AAAAB//4AAAAAAAH//gAAAAAAOf/+AAAAAAB///4AAAAAAf///gAAAAAH///+AAAAAAf///4AAAAAB// - //gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAH///+AAA - AAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB// - //gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAP///+AAA - AAB////4AAAAAP////gAAAAB////+AAAAAP////4AAAAB/////gAAAAP////+AAAAB/////4AAAAP/// - //gAAAD/////////////////////////////////////////////////////////KAAAADAAAABgAAAA - AQAgAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZgjdm - KYdDvimKQ/YpiELeK4VCvRWBM1UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA - E3ouTSmDQf9yuoT/l8ym/4fDl/98vo3/crmG/1Wsa/8rg0P/EX8wOgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAidjrx - AHwnLQAAAAAddzXAarV+/5vNqP+QyKD/gsCS/1yucv9hsHf/Z7N7/1erbf9NpmX/OJZU/h58OKgAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAACKvZf/Zal3/x1wMeyGwpf/m82p/2q1gP8tl0n/NJxQ/zWeUf81nlH/M5tP/zabUf9BoVv/ - NptS/zKYTv8Scy18AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAB+tY7/rta5/6vUt/+dzqr/QqJb/zOaT/8ymE7/HmQw6wxxKaYGaiCc - Hmcz6jKXTf8zm1D/NJtQ/zSbUP8th0X/DngxJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAuAAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAALwAAAC8AAAAv - AAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAALwAAAC97s4v/pNKx/5rMqP9Sqmr/M5tP/yqAQf8fbTTC - AAAALwAAAC8AAAAvAAAAEwhuInYtikb/NJtQ/zGVTP8TZSnjD3gtEQAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALe3t1L29vb/9fX1//X19f/09PT/8/Pz//Pz8//y8vL/ - 8fHx//Dw8P/w8PD/7+/v/+7u7v/u7u7/7e3t/+3t7f/s7Oz/6+vr/+vr6/92rob/mc2n/3m8i/8xmk7/ - NJtQ/zSbUP8zmU//IGEw/9jf2v/n5+f/Dw8PVAAAAAASXymmIGs3+g9vKlUAAAAAAAAAACeBQEcAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW1tVP39/f/9vb2//b29v/19fX/ - 9PT0//T09P/z8/P/8vLy//Hx8f/x8fH/8PDw/+/v7//v7+//7u7u/+7u7v/t7e3/7Ozs/+zs7P9xqoD/ - k8mh/y6ZS/80m1D/NJtQ/zCUTP8sYzv/4+Xj/+fn5//n5+f/Dg4OVgAAAAAAAAAAAAAAAAAAAAAAaxoT - JHo76yZ4PfUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALW1tVP4+Pj/ - 9/f3//b29v/29vb/9fX1//T09P/09PT/8/Pz//Ly8v/y8vL/8fHx//Dw8P/v7+//7+/v/+7u7v/u7u7/ - 7e3t/+zs7P9spXz/RaJe/zOaT/80n1H/GVEo/77Pwv/p6en/6Ojo/+jo6P/n5+f/Dg4OVgAAAAAAAAAA - AAAAAA5yKbJ9q4n+hcSW/yVzO/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALi4uFP5+fn/+Pj4//f39//39/f/9vb2//X19f/09PT/9PT0//Pz8//y8vL/8fHx//Hx8f/w8PD/ - 7+/v/+/v7//u7u7/7e3t/+3t7f9loXb/Mp1P/yJpNf95oIT/6urq/+rq6v/p6en/6Ojo/+jo6P/o6Oj/ - Dg4OVgAAAAAQcSlcNoJL/rrcw/+w2Lr/K5hJ/yFpNvgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALi4uFP5+fn/+fn5//j4+P/4+Pj/9/f3//b29v/19fX/9fX1//T09P/z8/P/ - 8/Pz//Ly8v/x8fH/8PDw//Dw8P/v7+//7u7u/+7u7v8mcDr/OG5G/+nq6f/r6+v/6urq/+rq6v/q6ur/ - 6enp/+np6f/o6Oj/DikVaRVyLvGYxKT/sNi7/5/QrP9ZrXD/NJxQ/x5hMPoAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALi4uFP6+vr/+fn5//n5+f/4+Pj/9/f3//f39//29vb/ - 9fX1//X19f/09PT/8/Pz//Pz8//y8vL/8fHx//Hx8f/w8PD/7+/v/+/v7//S3dX/7e3t/+3t7f+iy63/ - MpdM/+bo5v/q6ur/6urq/+np6f9Xl2f/Q41X/7rexP+k0bH/mMum/5TJo/8wmEz/NJxQ/x1aLPoAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALi4uFP7+/v/+vr6//n5+f/5+fn/ - +Pj4//j4+P/39/f/9vb2//X19f/19fX/9PT0//Pz8//z8/P/8vLy//Hx8f/x8fH/8PDw/+/v7//v7+// - 2+Td/zubVv+iz6//6vPs/zqPUP/p6un/6urq/+rq6v/p6en/CkIblipvPP2NxJz/gsGU/zWbUf80m1D/ - NJxQ/x1WKvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALi4uFP8/Pz/ - +/v7//r6+v/6+vr/+fn5//j4+P/4+Pj/9/f3//b29v/29vb/9fX1//T09P/09PT/8/Pz//Ly8v/y8vL/ - 8fHx//Dw8P/w8PD/NZdQ/ySTQv/v9/H/3O3g/8flz/8kejz/s8m5/9Db0/+sw7L/FF0o/YXBlv96vYz/ - X7B2/zOaT/80m1D/NJxQ/x1VLP0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALu7u1P8/Pz/+/v7//v7+//6+vr/+vr6//n5+f/4+Pj/+Pj4//f39//29vb/9vb2//X19f/09PT/ - 8/Pz//Pz8//y8vL/8fHx//Hx8f/w8PD/2+Xd/yuJRP8umUv/1+rc/7rcw/+z2r3/nM2p/3Kugf+Fwpf/ - gMGR/2+4g/9brnL/MppO/yl6Pv8lbzj/NaFS/x1VLP0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALu7u1P9/f3//Pz8//z8/P/7+/v/+vr6//r6+v/5+fn/+Pj4//j4+P/39/f/ - 9vb2//b29v/19fX/9PT0//T09P/z8/P/8vLy//Ly8v/x8fH/8PDw/7HNuP8ngD//LppM/2OxeP+czar/ - jsee/3+/kP90uYf/abN9/0SiXf8ynE//KHw//wtLHYoASQ40DEoe7RtVK/4AAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P9/f3//f39//z8/P/8/Pz/+/v7//v7+//6+vr/ - +fn5//n5+f/4+Pj/9/f3//f39//29vb/9fX1//X19f/09PT/8/Pz//Pz8//y8vL/8fHx//Hx8f/G18r/ - KG47/zKYTv8ynE//KpZI/yqWR/8sl0n/MptP/zKaT/8bVir7AEIIXAAAAAAAAAAAAAAAAB5fL2sAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P+/v7//f39//39/f/8/Pz/ - /Pz8//v7+//7+/v/+vr6//n5+f/5+fn/+Pj4//f39//39/f/9vb2//X19f/19fX/9PT0//Pz8//z8/P/ - 8vLy//Hx8f/w8PD/7u7u/4yrk/8aVyr/HFgt/x5fMP8bVyz/GFEo/gJDDH0AMwAKAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P+/v7/ - /v7+//39/f/9/f3//Pz8//z8/P/7+/v/+/v7//r6+v/6+vr/+fn5//j4+P/4+Pj/9/f3//b29v/29vb/ - 9fX1//T09P/09PT/8/Pz//Ly8v/x8fH/8fHx//Dw8P/v7+//7+/v/+7u7v/t7e3/Dg4OVgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALu7u1P//////v7+//7+/v/+/v7//f39//39/f/8/Pz/+/v7//v7+//6+vr/+vr6//n5+f/5+fn/ - +Pj4//f39//39/f/9vb2//X19f/19fX/9PT0//Pz8//y8vL/8vLy//Hx8f/w8PD/7+/v/+/v7//u7u7/ - Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALu7u1P///////////7+/v/+/v7//f39//39/f/8/Pz//Pz8//v7+//7+/v/ - +vr6//r6+v/5+fn/+Pj4//j4+P/39/f/9vb2//b29v/19fX/9PT0//T09P/z8/P/8vLy//Ly8v/x8fH/ - 8PDw//Dw8P/v7+//Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P////////////////+/v7//v7+//7+/v/9/f3/ - /f39//z8/P/8/Pz/+/v7//r6+v/6+vr/+fn5//n5+f/4+Pj/9/f3//f39//29vb/9fX1//X19f/09PT/ - 8/Pz//Pz8//y8vL/8fHx//Hx8f/w8PD/Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////// - /v7+//7+/v/+/v7//f39//39/f/8/Pz//Pz8//v7+//7+/v/+vr6//r6+v/5+fn/+Pj4//j4+P/39/f/ - 9vb2//b29v/19fX/9PT0//T09P/z8/P/8vLy//Ly8v/x8fH/Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///// - //////////////////////7+/v/+/v7//v7+//39/f/9/f3//Pz8//z8/P/7+/v/+/v7//r6+v/5+fn/ - +fn5//j4+P/39/f/9/f3//b29v/19fX/9fX1//T09P/z8/P/8vLy//Ly8v/x8fH/Dg4OVgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALu7u1P//////////////////////////////////////v7+//7+/v/9/f3//f39//z8/P/8/Pz/ - +/v7//v7+//6+vr/+vr6//n5+f/4+Pj/+Pj4//f39//29vb/9vb2//X19f/09PT/8/Pz//Pz8//y8vL/ - Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////////////////////////////7+/v/+/v7/ - /v7+//39/f/9/f3//Pz8//z8/P/7+/v/+vr6//r6+v/5+fn/+fn5//j4+P/39/f/9/f3//b29v/19fX/ - 9PT0//T09P/z8/P/Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////////////////////// - ///////////+/v7//v7+//39/f/9/f3//Pz8//z8/P/8/Pz/+/v7//r6+v/6+vr/+fn5//n5+f/4+Pj/ - 9/f3//f39//29vb/9fX1//X19f/09PT/Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////// - /////////////////////////////////v7+//7+/v/+/v7//f39//39/f/8/Pz//Pz8//v7+//7+/v/ - +vr6//r6+v/5+fn/+Pj4//j4+P/39/f/9vb2//b29v/19fX/Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///// - ///////////////////////////////////////////////////////////+/v7//v7+//7+/v/9/f3/ - /Pz8//z8/P/7+/v/+/v7//r6+v/6+vr/+fn5//n5+f/4+Pj/9/f3//f39//29vb/Dg4OVgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALu7u1P////////////////////////////////////////////////////////////////+/v7/ - /v7+//7+/v/9/f3//f39//z8/P/8/Pz/+/v7//v7+//6+vr/+fn5//n5+f/4+Pj/9/f3//f39//29vb/ - Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////////////////////////////////////// - //////////////////////7+/v/+/v7//f39//39/f/9/f3//Pz8//z8/P/7+/v/+vr6//r6+v/5+fn/ - +Pj4//j4+P/39/f/Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////////////////////// - ///////////////////////////////////////////+/v7//v7+//7+/v/9/f3//f39//z8/P/8/Pz/ - +/v7//v7+//6+vr/+fn5//n5+f/4+Pj/Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////// - /////////////////////////////////////////////////////////////////v7+//7+/v/+/v7/ - /f39//39/f/8/Pz/+/v7//v7+//6+vr/+vr6//n5+f/5+fn/Dg4OVgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///// - //////////////////////////////////////////////////////////////////////////////// - ///////////+/v7//v7+//39/f/9/f3//Pz8//z8/P/7+/v/+/v7//r6+v/29vb/Dg4OVgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALu7u1P///////////////////////////////////////////////////////////////////// - /////////////////////////////////Pz8//b29v/v7+//8fHx//X19f/29vb/9PT0//Dw8P/j4+P/ - Dw8PUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////////////////////////////////////// - /////////////////////////////////////////////////f39/+np6f/k5OT/z8/P/8bGxv/FxcX/ - x8fH/8rKyv/MzMzqAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////////////////////// - /////////////////////////////////////////////////////////////////f39/+rq6v/t7e3/ - 8PDw//Dw8P/v7+//5eXl/9PT0/JZWVkoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////// - //////////////////////////////////////////////////////////////////////////////// - /v7+//Ly8v/m5ub/7u7u/+7u7v/j4+P/1dXV9TY2NiEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////T09P/k5OT/6+vr/+Dg4P/Nzc30NDQ0IgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAALu7u1P///////////////////////////////////////////////////////////////////// - //////////////////////////////////////X19f/g4OD/3t7e/8zMzPRTU1MuAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////////////////////////////////////// - /////////////////////////////////////////////////v7+//Hx8f/W1tb/zs7O9TExMSQAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u1P///////////////////////////////////// - /////////////////////////////////////////////////////////////////f39/+Tk5P/Jycnz - Nzc3JQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMTExEb5+fnp+Pj46vj4+Or4+Pjq - +Pj46vj4+Or4+Pjq+Pj46vj4+Or4+Pjq+Pj46vj4+Or4+Pjq+Pj46vj4+Or4+Pjq+Pj46vj4+Or39/fq - 7e3t6dbW1tpLS0siAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAP///////wAA/////+H/AAD/////gH8AAP////YAHwAA////8AAfAAD////wAA8AAP////AfDwAA - /8AAAAM/AAD/wAAAA/MAAP/AAAADwwAA/8AAAAODAAD/wAAAAgMAAP/AAAAAAwAA/8AAAAADAAD/wAAA - AAMAAP/AAAAAAwAA/8AAAAATAAD/wAAAAH8AAP/AAAAB/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA - /8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAA - A/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA/8AAAAP/AAD/wAAAA/8AAP/AAAAD/wAA - /8AAAAf/AAD/wAAAD/8AAP/AAAAf/wAA/8AAAD//AAD/wAAAf/8AAP/AAAD//wAA/8AAAf//AAD///// - //8AAP///////wAA////////AAD///////8AACgAAAAwAAAAYAAAAAEACAAAAAAAABIAAAAAAAAAAAAA - AAAAAAAAAAAAAAD/AgIC/wkJCf8ARAH/AEcO/wBJDf8JRhj/DU0d/wNhHv8VUCX/FVgm/xlXKf8cVyz/ - Hlku/x5aLv8fXTD/Il4z/wZsIP8JbSP/DW0m/w9qKP8Uaiv/E28r/xZoLP8Xby//DnIo/w91Kv8VdS// - EH4u/xppMP8faTP/HG8z/xtyM/8bdTP/G3Yz/xxxNP8afDT/HX83/yBmM/8iZTT/JG04/yluPP8kczn/ - JnQ7/yd3Pf8qdj7/I3o7/yN8O/8kejz/J3o9/yN+PP8lfz3/LnZC/yl8QP8qf0L/MntG/zh2Sf86eEr/ - O3tM/0pOS/9Kflj/UHtc/1l0YP9zc3P/dHR0/3t7e/98fHz/fn5+/wCDI/8JgCn/CYQr/xuBN/8dgzn/ - G4Q4/yCDO/8ngD//K4BC/yyAQ/8rhUT/LIVE/yuIRP8tiUb/LoxI/y+OSf85gEz/M4pK/zCNSf8wjkn/ - Mo5L/yaQQv8wkEr/MpBM/zSRTv8xlEz/MpZN/zKYTv8ymk//OodQ/z+KU/80m1D/M51Q/zScUP80nlH/ - Np9S/zmeVP89oFf/PKJX/z6hWf9BglL/ToBc/06IXv9AoVv/QaJb/0WjXv9FpF//XI1p/06TYf9NlGD/ - V5tq/1+fcf9niXD/RqRg/0yiY/9No2X/Tadm/1Olaf9aoW3/U6pr/1SrbP9XrG7/WKxu/1mtcP9arXH/ - XK5z/2Ctdf9jrHf/aaR5/2mre/9qqnz/bqh+/2Cwdv9ksnn/arJ+/2i1ff9zrIP/dqyF/36jiP9ut4L/ - eLCH/3C5hP9yuob/dLqH/3iyiP98tIz/d7yK/3q4i/98v47/fr+Q/37AkP+AgID/goKC/4GHgv+EhIT/ - hoaG/4iIiP+NjY3/jo6O/5CQkP+SkpL/h6iQ/4W5k/+PsZj/j7eZ/5G1mv+mpqb/r6+v/6O7qf+zs7P/ - tra2/7+/v/+BwZL/hMKV/4nBmP+LxZv/i8ab/4zGnP+Ox57/mMak/5jMpv+bzan/m86p/53Pqv+ezqv/ - pcau/6HNrf+jza7/o9Kv/67GtP+wybf/tsq8/7jKvf+5zr7/pdKx/6/Xuv+w2Lv/sdm8/7LZvf+8zcD/ - vc7C/77Pw/+93sb/xsbG/8rKyv/MzMz/y9fO/8Xay//B38n/zNjP/9HR0f/T09P/1tbW/9bd2P/V39j/ - 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 - qamprwAAAAAMZyRUAAAAAAxvJlAofD95AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAObm5rH39/f/ - 9vb2//X19f/09PT/8/Pz//Ly8v/x8fH/8PDw/+/v7//u7u7/7e3t/4yulf9dr3P/NZ9R/y1nPf/o6Oj/ - 6Ojo/+jo6P+pqamvAAAAAABiEw1CiVX6lMui/yVvN3sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - 5ubmsfn5+f/4+Pj/9/f3//b29v/19fX/9PT0//Ly8v/x8fH/8PDw/+/v7//u7u7/jq+X/x5mMv/R3tX/ - 6+vr/+rq6v/p6en/6enp/6mpqa8ScCzDtNi+/6TSsf8wmUz/IGQzfAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAADp6emx+vr6//n5+f/4+Pj/9/f3//b29v/19fX/9PT0//Pz8//y8vL/8fHx//Dw8P/a5N3/ - 7u7u/9Ph1/83mlH/6erp/+rq6v/p6en/J3k9/7DZu/+Vy6P/Vqtt/zSbUP8cVyx9AAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAOnp6bH7+/v/+vr6//n5+f/4+Pj/9/f3//b29v/19fX/9PT0//Pz8//y8vL/ - 8fHx//Dw8P9Zqm//fb6P/+Xy6f9Gl1z/xtbK/+rq6v9kjG7dbqx//3e8i/8zm0//NJtQ/xxUKn4AAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6enpsfz8/P/7+/v/+vr6//n5+f/4+Pj/9/f3//b29v/19fX/ - 9PT0//Pz8//y8vL/8fHx//Dw8P8ti0f/cLiE/7Pavf+o1rX/i8Sb/32/jv9qtn7/MptO/xpTK/kuiUf/ - HFYsfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADp6emx/f39//z8/P/7+/v/+vr6//n5+f/4+Pj/ - 9/f3//b29v/19fX/9PT0//Pz8//y8vL/8fHx//Dw8P8kczr/Mp1P/0WjXv9QqWn/OJ1T/zWfUf8MSBvf - AAAAAAAAAAAeWi1lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOzs7LH+/v7//f39//z8/P/7+/v/ - +vr6//r6+v/5+fn/+Pj4//f39//29vb/9fX1//Pz8//y8vL/8fHx//Dw8P+tw7P/N2lF/yBZL/8wYDzn - AD8AFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7Ozssf7+/v/+/v7/ - /f39//z8/P/7+/v/+/v7//r6+v/5+fn/+Pj4//f39//29vb/9fX1//T09P/z8/P/8vLy//Dw8P/v7+// - 7+/v/62tra8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs7Oyx - //////7+/v/+/v7//f39//z8/P/8/Pz/+/v7//r6+v/5+fn/+Pj4//f39//29vb/9fX1//T09P/z8/P/ - 8vLy//Hx8f/w8PD/ra2trwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAOzs7LH///////////7+/v/+/v7//f39//39/f/8/Pz/+/v7//r6+v/5+fn/+Pj4//f39//29vb/ - 9fX1//T09P/z8/P/8vLy//Hx8f+tra2vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAA7Ozssf/////////////////////+/v7//f39//39/f/8/Pz/+/v7//r6+v/5+fn/ - +Pj4//f39//29vb/9fX1//T09P/z8/P/8vLy/62tra8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAADs7Oyx///////////////////////////+/v7//f39//39/f/8/Pz/ - +/v7//r6+v/5+fn/+Pj4//f39//29vb/9fX1//T09P/z8/P/sLCwrwAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOzs7LH////////////////////////////////+/v7/ - /f39//39/f/8/Pz/+/v7//r6+v/5+fn/+Pj4//j4+P/39/f/9vb2//X19f+wsLCvAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7Ozssf////////////////////////// - ///////////+/v7//v7+//39/f/8/Pz/+/v7//r6+v/6+vr/+fn5//j4+P/39/f/9vb2/7CwsK8AAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs7Oyx//////////////// - ///////////////////////////+/v7//v7+//39/f/8/Pz//Pz8//v7+//6+vr/+fn5//j4+P/39/f/ - s7OzrwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOzs7LH///// - ///////////////////////////////////////////+/v7//v7+//39/f/8/Pz//Pz8//v7+//6+vr/ - +fn5//j4+P+0tLSvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - 7Ozssf/////////////////////////////////////////////////////+/v7//v7+//39/f/9/f3/ - /Pz8//v7+//6+vr/+fn5/7S0tK8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAADs7Oyx//////////////////////////////////////////////////////////////// - /v7+//j4+P/29vb/+vr6//n5+f/19fX/p6enrgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAOzs7LH///////////////////////////////////////////////////// - ///////////+/v7/6enp/+Pj4//Z2dn/2dnZ/9XV1f9UVFQbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7Ozssf////////////////////////////////////////// - ///////////////////////////m5ub/7u7u/+7u7v/d3d3/UlJSKAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs7Oyx//////////////////////////////// - /////////////////////////////////////+zs7P/q6ur/2tra/1BQUCkAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOzs7LH///////////////////// - ////////////////////////////////////////////////6Ojo/9fX1/9NTU0rAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7Ozssf////////// - //////////////////////////////////////////////////////39/f/Z2dn/TU1NKwAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7u7sT - t7e3ILe3tyC3t7cgt7e3ILe3tyC3t7cgt7e3ILe3tyC3t7cgt7e3ILe3tyC3t7cgp6enIEVFRQsAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///// - ///8H///6Af//+AH///A5/wAAD/8AAAz/AAAA/wAAAP8AAAD/AAAA/wAAA/8AAA//AAAP/wAAD/8AAA/ - /AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAB//AAA//wAAf/8AAP//AAH//////////// - /////ygAAAAgAAAAQAAAAAEACAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ABgA/wVGE/8IRhf/ - Dk4d/wFSF/8Fdh//GlUp/x5ZLv8eWi7/Hlwv/xZjK/8aYS3/Fmst/xBwKv8ZbzD/H3U2/xl8NP8iZzX/ - I243/yVyOv8iezv/JXs8/yV+Pf8sf0P/O3VL/0d5Vf8jgz3/JYI+/yaCP/8qgkL/KIZC/yyKRf8uikf/ - LoxH/zCCRv8wikj/L5BJ/y2TSP8wkEr/MZFL/zGTTP8xlEz/MZZN/zOXTv8+i1P/PI5S/zyVVP88l1X/ - PpZW/zeYUv80m1D/NJxQ/zacUf81nlH/OJxT/z2cVv88n1f/PKFX/0WMWf9HkFr/RKVe/1OTZf9ak2n/ - W5Nq/1+Rbf9ok3T/aJd1/02nZf9Op2b/T6hn/1anbP9Tqmv/VKxs/1+gcf9cr3L/X7B1/2Sjdf9hrHX/ - aq98/2ysfv9jsnj/ZLB5/2O0ef9ss3//eKSE/263gv92sYb/cbiF/3e6if93vIr/eLuK/3q+jf+YmZj/ - m5ub/5ycnP+fn5//kK6Y/4W+lP+PsZj/kLCZ/5+3pf+jo6P/rKys/6m2rP+4ubj/u7u7/729vf++vr7/ - v7+//4TClf+MwZr/jsie/5DBnv+TxKD/lsul/5jOp/+byaj/ocCp/63Cs/+j0rD/qte3/7HRuv+z2r3/ - v9DD/7jdwv/AwMD/wcHB/8LCwv/Dw8P/xMTE/8XFxf/Gxsb/x8fH/8jIyP/J1Mz/ytrP/9HR0f/U1NT/ - 0dzU/9Pf1v/Y2Nj/2tra/9vb2//e3t7/3uLf/93m4P/g4OD/4uLi/+Hl4v/k5OT/5eXl/+jo6P/p6en/ - 6evp/+rq6v/r6+v/7Ozs/+3t7f/s7u3/7u7u/+/v7//p9Oz/8PDw//Hx8f/y8vL/8/Pz//T09P/19fX/ - 9vb2//f39//4+Pj/+fn5//r6+v/7+/v//Pz8//39/f/+/v7//////wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - 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 - //////////////////////////////////////7+/v/9/f3//Pz8//v7+//6+vr/+fn5//f39/8AAAAO - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC//////////////////////////////// - ///////////+/v7//f39//z8/P/7+/v/+vr6//n5+f8AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAC/////////////////////////////////////////////////v7+//r6+v/8/Pz/ - +/v7//f39/8AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC//////////////// - /////////////////////////////////////+fn5//w8PD/8fHx/9fX1/MAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC//////////////////////////////////////////////// - /////+Li4v/r6+v/z8/P8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC - /////////////////////////////////////////////////////+Dg4P/Jycn0AAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//////////////////////////////// - /////////////////f39/83NzfIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAP///wD//wcA//wDAPgAEwD4AB0A+AARAPgAAQD4AAEA+AAFAPgAHwD4AB8A+AAfAPgAHwD4AB8A - +AAfAPgAHwD4AB8A+AAfAPgAHwD4AD8A+AB/APgA/wD///8A////ACgAAAAYAAAAMAAAAAEACAAAAAAA - gAQAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AEcO/xJPIv8YVyj/Cm0k/xB9Lv8Qfy//HHIz/xt2M/8yYT// - I3s7/yV4O/8ifjv/I347/yp+Qf8yekb/R3JT/21tbf9ycnL/eHh4/35+fv8jgDz/K4FC/ymDQv8sgkP/ - LYdF/ymJQ/8pikT/L4lH/y6LR/8tjkf/MZJL/zORTf8zmE7/OZZS/zieVP9Ei1f/RJFZ/0GXWf9EoV3/ - U4Rh/0+VYv9PlmP/YJtw/0umZP9YrW//Waxv/16pc/9dr3P/Zad3/22vf/9isnj/Y7N4/2exe/9ms3v/ - arV+/3awhv96t4r/eLyL/4ODg/+IiIj/ioqK/4yMjP+NjY3/jo6O/4+Pj/+QkJD/kZGR/4Kqjf+CsI7/ - gbSP/4S7k/+Lv5n/kLCZ/5q4ov+rq6v/s7Oz/7S0tP+xv7X/v7+//5DBnf+TyKH/nsKo/5/Lq/+1ybr/ - vNfD/7zdxf/Dx8T/ycnJ/8vLy//Q0ND/0dHR/9LS0v/T09P/1NTU/9XV1f/W1tb/0dzT/9Td1v/W3tj/ - 2NjY/9ra2v/d3d3/39/f/9bh2f/g4OD/4eHh/+Li4v/j4+P/5OTk/+fn5//m6Of/6Ojo/+np6f/q6ur/ - 6ezq/+zs7P/u7u7/7+/v//Dw8P/x8fH/8vLy//Pz8//09PT/9fX1//b29v/39/f/+Pj4//n5+f/6+vr/ - +/v7//z8/P/9/f3//v7+//////8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAUaIBoGAAAAAAAAAAAAAAAAAAAA - ABkMFS86Ny4iDQAAAAAAAAAAAAAAAAAAAA5HOTMfGx8jHgcAAAAAAFllZGBfXl1cW05INiEPVxAXCggA - AAAAAGZ+fXt6eXd2dWIyISpUbjwEKSUAAAAAAGeAf318enl4dmMkSm9xcCg4URwAAAAAAGmBgH99fHt5 - eHNoU1BvYStRLBgAAAAAAGqDgoB/fnx7enhVNVZGRTEtHRYAAAAAAGuEg4KBf359e3p4UiY0MCcLAgMA - AAAAAGyFhIOCgX9+fXt6eWJJRAkBAAAAAAAAAGyGhYSDgoGAf318enl4dj4AAAAAAAAAAGyGhoWEg4KB - gH99fHt5eD8AAAAAAAAAAGyGhoaFhYSDgYB/fnx7eUAAAAAAAAAAAGyGhoaGhYWEg4KAf359e0EAAAAA - AAAAAGyGhoaGhoaFhIOCgX9+fUIAAAAAAAAAAGyGhoaGhoaGhYSDgoGAfkMAAAAAAAAAAGyGhoaGhoaG - hoWEg4KBgEMAAAAAAAAAAGyGhoaGhoaGhoaFf35/eD0AAAAAAAAAAGyGhoaGhoaGhoaFcm1pWBIAAAAA - AAAAAGyGhoaGhoaGhoaGdHJaFAAAAAAAAAAAAGyGhoaGhoaGhoaGblk7AAAAAAAAAAAAAG2Dg4ODg4OD - g4N/WhMAAAAAAAAAAAAAAE9NTExMTExMTExLEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - ////AP//BwD//AMA+AATAPgAHQD4ABEA+AABAPgAAQD4AAUA+AAfAPgAHwD4AB8A+AAfAPgAHwD4AB8A - +AAfAPgAHwD4AB8A+AAfAPgAPwD4AH8A+AD/AP///wD///8AKAAAABAAAAAgAAAAAQAgAAAAAAAACAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - G4A4ZymIQt4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLv5n/ - hsKX/y2XSv81nlH/QaJc/xJzLXwAAAAAAAAAAAAAAAAAAAAA9vb2//T09P/y8vL/8PDw/+7u7v/s7Oz/ - d6+G/zKaTv8zmk//5+fn/xVjKqcAAAAAAAAAAAAAAAAAAAAAAAAAAPn5+f/39/f/9PT0//Ly8v/w8PD/ - 7u7u/2aid/95oIT/6enp/+jo6P8QcSlcsdi7/wAAAAAAAAAAAAAAAAAAAAD7+/v/+fn5//f39//19fX/ - 8/Pz//Hx8f/v7+//otCv/+rq6v/p6en/jcSd/zSbUP8AAAAAAAAAAAAAAAAAAAAA/f39//v7+//5+fn/ - 9/f3//X19f/z8/P/8fHx/yiAP/+dzqr/dbqI/zOcT/8ATBM1AAAAAAAAAAAAAAAAAAAAAP7+/v/9/f3/ - +/v7//r6+v/4+Pj/9vb2//T09P/x8fH/7+/v/+3t7f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///// - /v7+//39/f/8/Pz/+vr6//j4+P/29vb/9PT0//Ly8v/w8PD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - /////////////////f39//z8/P/6+vr/+Pj4//b29v/09PT/8vLy/wAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAP/////////////////////+/v7//Pz8//v7+//5+fn/9/f3//X19f8AAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAD///////////////////////////7+/v/9/f3/+/v7//n5+f/39/f/AAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAA/////////////////////////////////v7+//39/f/7+/v/9/f3/wAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAP/////////////////////////////////////u7u7/7+/v/19fXygAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////4eHh/1FRUS8AAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Pj46vn5+er5+fnq+fn56vn5+er5+fnq+Pj46lJSUiIAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAA/4MAAOADAADgBQAA4AEAAOADAADgBwAA4AcAAOAHAADgBwAA - 4AcAAOAHAADgDwAA4B8AAOA/AAD//wAAKAAAABAAAAAgAAAAAQAIAAAAAAAAAgAAAAAAAAAAAAAAAAAA - AAAAAAAAAP8IRhf/HFgs/x5aLv8ZfDT/JG04/yNzOf8lezz/JXw9/yV/Pv8qikT/LZNI/zWRTv87klP/ - PZhW/z2eV/8+oVn/RY5Z/0qmY/9PoWb/Vahr/1aobP9frXT/ZKV2/2Wnd/9yqIH/brKA/2+1gv90sIT/ - criF/3+7kP+Tr5v/iLSU/4+8m/+ZuKH/nsyq/7PNuv+6zL//wMDA/8HBwf/ExsX/yMjI/8/f0//S1dP/ - 3d3d/9/f3//h4eH/4uLi/+Pj4//h5OL/5OTk/+Xl5f/q6ur/7e/t/+/v7//x8fH/8vLy//Pz8//09PT/ - 9fX1//b29v/39/f/+Pj4//n5+f/6+vr/+/v7//z8/P/9/f3//v7+//////8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ - AAAA/wAAAP8AAAAAAAAAAAALBBMVDAAAAAAAAAAAAAAAGBoUDg8KAAAAADIzMC4tLCESESgJCAcAAAA6 - PTs5NzYZIDErFxsFAAAAPD89Ozk3KiMkIh4QAwAAAD5BPz47OTUcHRYNBgIAAABAQ0JAPjw6NyUfAQAA - AAAAQERDQkA+PDo4LQAAAAAAAEBFRURCQD89Oy4AAAAAAABARUVFREJBPz0wAAAAAAAAQEVFRUVEQ0E/ - MwAAAAAAAEBFRUVFRUQ/Py8AAAAAAABARUVFRUVFNC4mAAAAAAAAQEVFRUVFRTMnAAAAAAAAADw/Pz8/ - Pz0pAAAAAAAAAAAAAAAAAAAAAAAAAAAA//cAAP+DAADgAwAA4AUAAOABAADgAwAA4AcAAOAHAADgBwAA - 4AcAAOAHAADgBwAA4A8AAOAfAADgPwAA//8AAA== - - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/PatchBuilder.cs b/UpdateLib/UpdateLib.Generator/PatchBuilder.cs new file mode 100644 index 0000000..7c7d719 --- /dev/null +++ b/UpdateLib/UpdateLib.Generator/PatchBuilder.cs @@ -0,0 +1,52 @@ +using MatthiWare.UpdateLib.Generator.Abstractions; +using MatthiWare.UpdateLib.Generator.Core; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MatthiWare.UpdateLib.Utils; + +namespace MatthiWare.UpdateLib.Generator +{ + public class PatchBuilder + { + private readonly string previousVersionFolder, currentVersionFolder, tempFolder, outputFolder; + private int currProgress, totalprogress; + private readonly IList tasks; + + public PatchBuilder(string prev, string curr, string output) + { + previousVersionFolder = prev; + currentVersionFolder = curr; + tempFolder = $@"{System.IO.Path.GetTempPath()}UpdateLib.Generator\{Guid.NewGuid().ToString()}\"; + outputFolder = output; + tasks = new List(); + } + + public async Task CreatePatch(Action progress, CancellationToken cancellation = default) + { + DirectoryInfo dirCurrVersion = new DirectoryInfo(currentVersionFolder); + + var files = dirCurrVersion.GetFiles("*", SearchOption.AllDirectories); + + foreach (var fi in files) + tasks.Add(new DeltaTask(this, fi.FullName, fi.FullName)); + + totalprogress = tasks.Count; + + Action reportTaskCompleted = new Action(() => + { + currProgress += 1; + + progress(currProgress / totalprogress); + }); + + await tasks.ForEachAsync(task => task.Execute().ContinueWith(x => reportTaskCompleted()), Environment.ProcessorCount, cancellation); + + + return await Task.FromResult(0); + } + } +} diff --git a/UpdateLib/UpdateLib.Generator/Program.cs b/UpdateLib/UpdateLib.Generator/Program.cs index 456755c..f013d39 100644 --- a/UpdateLib/UpdateLib.Generator/Program.cs +++ b/UpdateLib/UpdateLib.Generator/Program.cs @@ -15,25 +15,49 @@ * along with this program. If not, see . */ -using MatthiWare.UpdateLib.Logging.Writers; +using McMaster.Extensions.CommandLineUtils; using System; -using System.Windows.Forms; +using System.ComponentModel.DataAnnotations; namespace MatthiWare.UpdateLib.Generator { - static class Program + class Program { /// /// The main entry point for the application. /// [STAThread] - static void Main() + static void Main(string[] args) { - Updater.Instance.ConfigureLogger((logger) => logger.Writers.Add(new ConsoleLogWriter())); + CommandLineApplication.Execute(args); - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new TestForm()); +#if DEBUG + Console.ReadKey(); +#endif } + + [Required] + [DirectoryExists] + [Option("--from ", Description = "Required. 'Old' program directory")] + private string PreviousVersionDir { get; } + + [Required] + [DirectoryExists] + [Option("--to ", Description = "Required. 'new' program directory")] + private string CurrentVersionDirectory { get; } + + [Required] + [DirectoryExists] + [Option("--output ", Description = "Required. Delta output directory")] + private string OutputDirectory { get; } + + private async void OnExecuteAsync() + { + var patchBuilder = new PatchBuilder(PreviousVersionDir, CurrentVersionDirectory, OutputDirectory); + + await patchBuilder.CreatePatch((progress) => Console.WriteLine($"Progress: {progress}")); + } + + } } diff --git a/UpdateLib/UpdateLib.Generator/Properties/AssemblyInfo.cs b/UpdateLib/UpdateLib.Generator/Properties/AssemblyInfo.cs index 0e3eea2..d459ada 100644 --- a/UpdateLib/UpdateLib.Generator/Properties/AssemblyInfo.cs +++ b/UpdateLib/UpdateLib.Generator/Properties/AssemblyInfo.cs @@ -1,36 +1,7 @@ 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("UpdateLib Generator")] -[assembly: AssemblyDescription("Update Generator")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("MatthiWare")] -[assembly: AssemblyProduct("UpdateLib")] -[assembly: AssemblyCopyright("Copyright © MatthiWare 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("5194ff71-49f6-4adb-9b0e-4beb418dc6f3")] - -// 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 Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyDescription("Update Generator for UpdateLib")] diff --git a/UpdateLib/UpdateLib.Generator/Properties/Resources.Designer.cs b/UpdateLib/UpdateLib.Generator/Properties/Resources.Designer.cs deleted file mode 100644 index 017ea70..0000000 --- a/UpdateLib/UpdateLib.Generator/Properties/Resources.Designer.cs +++ /dev/null @@ -1,163 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MatthiWare.UpdateLib.Generator.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // 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() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [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("MatthiWare.UpdateLib.Generator.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap cross { - get { - object obj = ResourceManager.GetObject("cross", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap folder_transparent_16px { - get { - object obj = ResourceManager.GetObject("folder_transparent_16px", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap gears { - get { - object obj = ResourceManager.GetObject("gears", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap image_transparent_16px { - get { - object obj = ResourceManager.GetObject("image_transparent_16px", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap loading { - get { - object obj = ResourceManager.GetObject("loading", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap loading_gear { - get { - object obj = ResourceManager.GetObject("loading_gear", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap project_16px { - get { - object obj = ResourceManager.GetObject("project_16px", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap reg_bin_16px { - get { - object obj = ResourceManager.GetObject("reg_bin_16px", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap reg_string_16px { - get { - object obj = ResourceManager.GetObject("reg_string_16px", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap Registry_Editor_32px { - get { - object obj = ResourceManager.GetObject("Registry_Editor_32px", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/Properties/Resources.resx b/UpdateLib/UpdateLib.Generator/Properties/Resources.resx deleted file mode 100644 index d5f13cd..0000000 --- a/UpdateLib/UpdateLib.Generator/Properties/Resources.resx +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\loading.gif;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\gears.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\folder_transparent_16px.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\loading_gear.gif;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\image_transparent_16px.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\cross.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\project_16px.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\reg_bin_16px.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\reg_string_16px.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Registry Editor_32px.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/Properties/Settings.Designer.cs b/UpdateLib/UpdateLib.Generator/Properties/Settings.Designer.cs deleted file mode 100644 index 58bfc72..0000000 --- a/UpdateLib/UpdateLib.Generator/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MatthiWare.UpdateLib.Generator.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.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/UpdateLib/UpdateLib.Generator/Properties/Settings.settings b/UpdateLib/UpdateLib.Generator/Properties/Settings.settings deleted file mode 100644 index 3964565..0000000 --- a/UpdateLib/UpdateLib.Generator/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/UpdateLib/UpdateLib.Generator/Properties/launchSettings.json b/UpdateLib/UpdateLib.Generator/Properties/launchSettings.json new file mode 100644 index 0000000..b585fc6 --- /dev/null +++ b/UpdateLib/UpdateLib.Generator/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "UpdateLib.Generator": { + "commandName": "Project", + "commandLineArgs": "--from C:\\temp --to C:\\temp\\OUTPUT_TESTING --output C:\\temp\\Editor_CLI_2_XML_debug" + } + } +} \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/Resources/Registry Editor_16px.png b/UpdateLib/UpdateLib.Generator/Resources/Registry Editor_16px.png deleted file mode 100644 index c98ba68..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/Registry Editor_16px.png and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/Registry Editor_32px.png b/UpdateLib/UpdateLib.Generator/Resources/Registry Editor_32px.png deleted file mode 100644 index edcd6f8..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/Registry Editor_32px.png and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/cross.png b/UpdateLib/UpdateLib.Generator/Resources/cross.png deleted file mode 100644 index ecbd604..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/cross.png and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/folder_transparent_16px.png b/UpdateLib/UpdateLib.Generator/Resources/folder_transparent_16px.png deleted file mode 100644 index e7d89f4..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/folder_transparent_16px.png and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/gears.png b/UpdateLib/UpdateLib.Generator/Resources/gears.png deleted file mode 100644 index f0fc216..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/gears.png and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/image_transparent_16px.png b/UpdateLib/UpdateLib.Generator/Resources/image_transparent_16px.png deleted file mode 100644 index 3e26c14..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/image_transparent_16px.png and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/loading.gif b/UpdateLib/UpdateLib.Generator/Resources/loading.gif deleted file mode 100644 index 62d8e4e..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/loading.gif and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/loading_gear.gif b/UpdateLib/UpdateLib.Generator/Resources/loading_gear.gif deleted file mode 100644 index fef4ec0..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/loading_gear.gif and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/project_16px.png b/UpdateLib/UpdateLib.Generator/Resources/project_16px.png deleted file mode 100644 index 25fe536..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/project_16px.png and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/reg_bin_16px.png b/UpdateLib/UpdateLib.Generator/Resources/reg_bin_16px.png deleted file mode 100644 index f79d30a..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/reg_bin_16px.png and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Resources/reg_string_16px.png b/UpdateLib/UpdateLib.Generator/Resources/reg_string_16px.png deleted file mode 100644 index 7959155..0000000 Binary files a/UpdateLib/UpdateLib.Generator/Resources/reg_string_16px.png and /dev/null differ diff --git a/UpdateLib/UpdateLib.Generator/Tasks/LoadDirectoryTask.cs b/UpdateLib/UpdateLib.Generator/Tasks/LoadDirectoryTask.cs deleted file mode 100644 index 003555c..0000000 --- a/UpdateLib/UpdateLib.Generator/Tasks/LoadDirectoryTask.cs +++ /dev/null @@ -1,106 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Tasks; -using MatthiWare.UpdateLib.UI; -using System; -using System.Drawing; -using System.IO; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.Tasks -{ - public class LoadDirectoryTask : AsyncTask - { - public ListView ItemsListView { get; set; } - public ImageList IconList { get; set; } - public DirectoryInfo DirectoryPath { get; set; } - - public LoadDirectoryTask(ListView lv, ImageList iconCache, DirectoryInfo dirPath) - { - if (lv == null) throw new ArgumentNullException(nameof(lv)); - if (iconCache == null) throw new ArgumentNullException(nameof(iconCache)); - if (dirPath == null) throw new ArgumentNullException(nameof(dirPath)); - if (!dirPath.Exists) throw new DirectoryNotFoundException($"The directory '{dirPath.FullName}' was not found."); - - ItemsListView = lv; - IconList = iconCache; - DirectoryPath = dirPath; - } - - protected override void DoWork() - { - BeginUpdate(); - - Clear(); - - foreach (DirectoryInfo subDir in DirectoryPath.GetDirectories()) - { - ListViewItem item = new ListViewItem(new string[] { subDir.Name, subDir.LastWriteTimeUtc.ToString(), subDir.FullName }); - item.Tag = subDir; - item.ImageKey = "folder"; - - AddItem(item); - } - - foreach (FileInfo file in DirectoryPath.GetFiles()) - { - ListViewItem item = new ListViewItem(new string[] { file.Name, file.LastWriteTimeUtc.ToString(), file.FullName }); - item.Tag = file; - - if (!IconList.Images.ContainsKey(file.Extension)) - IconList.Images.Add(file.Extension, Icon.ExtractAssociatedIcon(file.FullName)); - - item.ImageKey = file.Extension; - - AddItem(item); - } - - SetColumnAutoSize(0); - SetColumnAutoSize(1); - SetColumnAutoSize(2); - - EndUpdate(); - - } - - private void SetColumnAutoSize(int clmn) - { - ItemsListView.InvokeOnUI(() => ItemsListView.Columns[clmn].Width = -1); - } - - private void EndUpdate() - { - ItemsListView.InvokeOnUI(() => ItemsListView.EndUpdate()); - } - - private void BeginUpdate() - { - ItemsListView.InvokeOnUI(() => ItemsListView.BeginUpdate()); - } - - private void Clear() - { - ItemsListView.InvokeOnUI(() => ItemsListView.Items.Clear()); - } - - private void AddItem(ListViewItem item) - { - ItemsListView.InvokeOnUI(() => ItemsListView.Items.Add(item)); - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/Tasks/UpdateGeneratorTask.cs b/UpdateLib/UpdateLib.Generator/Tasks/UpdateGeneratorTask.cs deleted file mode 100644 index 53c5771..0000000 --- a/UpdateLib/UpdateLib.Generator/Tasks/UpdateGeneratorTask.cs +++ /dev/null @@ -1,159 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Security; -using System; -using System.Linq; -using System.Threading; -using System.IO; -using MatthiWare.UpdateLib.Tasks; -using MatthiWare.UpdateLib.Generator.Data.FilesPage; -using System.Collections.Generic; -using MatthiWare.UpdateLib.Generator.UI.Pages; - -namespace MatthiWare.UpdateLib.Generator.Tasks -{ - public class UpdateGeneratorTask : AsyncTask - { - private delegate void AddDirRecursiveDelegate(GenFolder dir, DirectoryEntry entry); - - private GenFolder baseDir; - - private int total; - private int done = 0; - - private InformationPage infoPage; - - private IList registryFolders; - - public UpdateGeneratorTask(GenFolder dir, InformationPage info, IList registry) - { - if (dir == null) - throw new ArgumentNullException("dir", "The directory cannot be null"); - - Result = new UpdateFile(); - - baseDir = dir; - registryFolders = registry; - - total = dir.Count + registry.Sum(g => g.Count); - - infoPage = info; - } - - protected override void DoWork() - { - foreach (GenFolder subfolder in baseDir.Directories) - { - if (subfolder.Count == 0) - return; - - DirectoryEntry entry = new DirectoryEntry(string.IsNullOrEmpty(subfolder.PathVariable) ? subfolder.Name : subfolder.PathVariable); - - Result.Folders.Add(entry); - - AddDirRecursive(subfolder, entry); - } - - Enqueue(new Action(AddRegistryItems), null); - - Result.ApplicationName = infoPage.ApplicationName; - Result.VersionString = infoPage.ApplicationVersion; - } - - private void AddRegistryItems() - { - foreach (GenFolder registry in registryFolders) - { - if (registry.Count == 0) - continue; - - DirectoryEntry dir = new DirectoryEntry(registry.Name); - - Result.Registry.Add(dir); - - AddRegistryRecursive(registry, dir); - } - } - - private void AddRegistryRecursive(GenFolder dir, DirectoryEntry entry) - { - List keys = dir.Items; - foreach (GenReg key in keys) - { - entry.Add(new RegistryKeyEntry(key.Name, key.Type, key.Value)); - - Interlocked.Increment(ref done); - } - - if (keys.Count > 0) - OnTaskProgressChanged(done, total); - - IEnumerable dirsLeft = dir.Directories.Where(g => g.Count > 0); - int left = dirsLeft.Count(); - - foreach (GenFolder subDir in dirsLeft) - { - DirectoryEntry dirEntry = new DirectoryEntry(subDir.Name); - entry.Add(dirEntry); - - left--; - - if (left == 0) - AddRegistryRecursive(subDir, dirEntry); - else - Enqueue(new Action(AddRegistryRecursive), subDir, dirEntry); - } - - } - - private void AddDirRecursive(GenFolder dir, DirectoryEntry entry) - { - List files = dir.Items; - foreach (GenFile genFile in files) - { - FileInfo fi = genFile.FileInfo; - FileEntry newEntry = new FileEntry(fi.Name); - newEntry.Hash = HashUtil.GetHash(fi.FullName); - - entry.Add(newEntry); - - Interlocked.Increment(ref done); - } - - if (files.Count > 0) - OnTaskProgressChanged(done, total); - - IEnumerable dirsLeft = dir.Directories.Where(g => g.Count > 0); - int left = dirsLeft.Count(); - - foreach (GenFolder subDir in dirsLeft) - { - DirectoryEntry dirEntry = new DirectoryEntry(string.IsNullOrEmpty(subDir.PathVariable) ? subDir.Name : subDir.PathVariable); - entry.Add(dirEntry); - - left--; - - if (left == 0) - AddDirRecursive(subDir, dirEntry); - else - Enqueue(new Action(AddDirRecursive), subDir, dirEntry); - } - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/TestForm.Designer.cs b/UpdateLib/UpdateLib.Generator/TestForm.Designer.cs deleted file mode 100644 index 09ee13c..0000000 --- a/UpdateLib/UpdateLib.Generator/TestForm.Designer.cs +++ /dev/null @@ -1,264 +0,0 @@ -namespace MatthiWare.UpdateLib.Generator -{ - partial class TestForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TestForm)); - this.SidebarPanel = new System.Windows.Forms.Panel(); - this.ContentPanel = new System.Windows.Forms.Panel(); - this.btnTabBuild = new MatthiWare.UpdateLib.Generator.UI.FlatButton(); - this.btnTabRegistry = new MatthiWare.UpdateLib.Generator.UI.FlatButton(); - this.btnTabFiles = new MatthiWare.UpdateLib.Generator.UI.FlatButton(); - this.btnTabInformation = new MatthiWare.UpdateLib.Generator.UI.FlatButton(); - this.HeaderPanel = new MatthiWare.UpdateLib.Generator.UI.MoveablePanel(); - this.pbMinimize = new MatthiWare.UpdateLib.Generator.UI.HoverPictureBox(); - this.pbMaximize = new MatthiWare.UpdateLib.Generator.UI.HoverPictureBox(); - this.pbClose = new MatthiWare.UpdateLib.Generator.UI.HoverPictureBox(); - this.pbIcon = new System.Windows.Forms.PictureBox(); - this.lblTitle = new System.Windows.Forms.Label(); - this.elipseComponent1 = new MatthiWare.UpdateLib.Generator.UI.ElipseComponent(this.components); - this.SidebarPanel.SuspendLayout(); - this.HeaderPanel.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pbMinimize)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pbMaximize)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pbClose)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pbIcon)).BeginInit(); - this.SuspendLayout(); - // - // SidebarPanel - // - this.SidebarPanel.BackColor = System.Drawing.Color.DarkGray; - this.SidebarPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.SidebarPanel.Controls.Add(this.btnTabBuild); - this.SidebarPanel.Controls.Add(this.btnTabRegistry); - this.SidebarPanel.Controls.Add(this.btnTabFiles); - this.SidebarPanel.Controls.Add(this.btnTabInformation); - this.SidebarPanel.Dock = System.Windows.Forms.DockStyle.Left; - this.SidebarPanel.Location = new System.Drawing.Point(0, 33); - this.SidebarPanel.Name = "SidebarPanel"; - this.SidebarPanel.Size = new System.Drawing.Size(233, 505); - this.SidebarPanel.TabIndex = 1; - // - // ContentPanel - // - this.ContentPanel.AutoScroll = true; - this.ContentPanel.BackColor = System.Drawing.SystemColors.Control; - this.ContentPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.ContentPanel.Dock = System.Windows.Forms.DockStyle.Fill; - this.ContentPanel.Location = new System.Drawing.Point(233, 33); - this.ContentPanel.Name = "ContentPanel"; - this.ContentPanel.Size = new System.Drawing.Size(806, 505); - this.ContentPanel.TabIndex = 2; - // - // btnTabBuild - // - this.btnTabBuild.ActiveItem = false; - this.btnTabBuild.BackHoverColor = System.Drawing.Color.LightGray; - this.btnTabBuild.BackSelectedColor = System.Drawing.Color.DimGray; - this.btnTabBuild.Dock = System.Windows.Forms.DockStyle.Top; - this.btnTabBuild.Font = new System.Drawing.Font("Century Gothic", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnTabBuild.InfoImage = ((System.Drawing.Image)(resources.GetObject("btnTabBuild.InfoImage"))); - this.btnTabBuild.Location = new System.Drawing.Point(0, 189); - this.btnTabBuild.Name = "btnTabBuild"; - this.btnTabBuild.Size = new System.Drawing.Size(231, 63); - this.btnTabBuild.TabIndex = 3; - this.btnTabBuild.Text = "Build"; - this.btnTabBuild.Click += new System.EventHandler(this.btnTabBuild_Click); - // - // btnTabRegistry - // - this.btnTabRegistry.ActiveItem = false; - this.btnTabRegistry.BackHoverColor = System.Drawing.Color.LightGray; - this.btnTabRegistry.BackSelectedColor = System.Drawing.Color.DimGray; - this.btnTabRegistry.Dock = System.Windows.Forms.DockStyle.Top; - this.btnTabRegistry.Font = new System.Drawing.Font("Century Gothic", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnTabRegistry.InfoImage = global::MatthiWare.UpdateLib.Generator.Properties.Resources.Registry_Editor_32px; - this.btnTabRegistry.Location = new System.Drawing.Point(0, 126); - this.btnTabRegistry.Name = "btnTabRegistry"; - this.btnTabRegistry.Size = new System.Drawing.Size(231, 63); - this.btnTabRegistry.TabIndex = 2; - this.btnTabRegistry.Text = "Registry"; - this.btnTabRegistry.Click += new System.EventHandler(this.btnTabRegistry_Click); - // - // btnTabFiles - // - this.btnTabFiles.ActiveItem = false; - this.btnTabFiles.BackHoverColor = System.Drawing.Color.LightGray; - this.btnTabFiles.BackSelectedColor = System.Drawing.Color.DimGray; - this.btnTabFiles.Dock = System.Windows.Forms.DockStyle.Top; - this.btnTabFiles.Font = new System.Drawing.Font("Century Gothic", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnTabFiles.InfoImage = ((System.Drawing.Image)(resources.GetObject("btnTabFiles.InfoImage"))); - this.btnTabFiles.Location = new System.Drawing.Point(0, 63); - this.btnTabFiles.Name = "btnTabFiles"; - this.btnTabFiles.Size = new System.Drawing.Size(231, 63); - this.btnTabFiles.TabIndex = 1; - this.btnTabFiles.Text = "Files"; - this.btnTabFiles.Click += new System.EventHandler(this.flatButton2_Click); - // - // btnTabInformation - // - this.btnTabInformation.ActiveItem = false; - this.btnTabInformation.BackHoverColor = System.Drawing.Color.LightGray; - this.btnTabInformation.BackSelectedColor = System.Drawing.Color.DimGray; - this.btnTabInformation.Dock = System.Windows.Forms.DockStyle.Top; - this.btnTabInformation.Font = new System.Drawing.Font("Century Gothic", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnTabInformation.InfoImage = ((System.Drawing.Image)(resources.GetObject("btnTabInformation.InfoImage"))); - this.btnTabInformation.Location = new System.Drawing.Point(0, 0); - this.btnTabInformation.Name = "btnTabInformation"; - this.btnTabInformation.Size = new System.Drawing.Size(231, 63); - this.btnTabInformation.TabIndex = 0; - this.btnTabInformation.Text = "Update Information"; - this.btnTabInformation.Click += new System.EventHandler(this.flatButton1_Click); - // - // HeaderPanel - // - this.HeaderPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(78)))), ((int)(((byte)(99)))), ((int)(((byte)(133))))); - this.HeaderPanel.Controls.Add(this.pbMinimize); - this.HeaderPanel.Controls.Add(this.pbMaximize); - this.HeaderPanel.Controls.Add(this.pbClose); - this.HeaderPanel.Controls.Add(this.pbIcon); - this.HeaderPanel.Controls.Add(this.lblTitle); - this.HeaderPanel.Dock = System.Windows.Forms.DockStyle.Top; - this.HeaderPanel.Location = new System.Drawing.Point(0, 0); - this.HeaderPanel.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.HeaderPanel.Name = "HeaderPanel"; - this.HeaderPanel.ParentForm = this; - this.HeaderPanel.Size = new System.Drawing.Size(1039, 33); - this.HeaderPanel.TabIndex = 1; - // - // pbMinimize - // - this.pbMinimize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.pbMinimize.Image = ((System.Drawing.Image)(resources.GetObject("pbMinimize.Image"))); - this.pbMinimize.Location = new System.Drawing.Point(965, 5); - this.pbMinimize.Name = "pbMinimize"; - this.pbMinimize.Size = new System.Drawing.Size(24, 24); - this.pbMinimize.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.pbMinimize.TabIndex = 4; - this.pbMinimize.TabStop = false; - this.pbMinimize.Click += new System.EventHandler(this.pbMinimize_Click); - // - // pbMaximize - // - this.pbMaximize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.pbMaximize.BackColor = System.Drawing.Color.Transparent; - this.pbMaximize.Image = ((System.Drawing.Image)(resources.GetObject("pbMaximize.Image"))); - this.pbMaximize.Location = new System.Drawing.Point(988, 5); - this.pbMaximize.Name = "pbMaximize"; - this.pbMaximize.Size = new System.Drawing.Size(24, 24); - this.pbMaximize.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.pbMaximize.TabIndex = 3; - this.pbMaximize.TabStop = false; - this.pbMaximize.Click += new System.EventHandler(this.pbMaximize_Click); - // - // pbClose - // - this.pbClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.pbClose.Image = ((System.Drawing.Image)(resources.GetObject("pbClose.Image"))); - this.pbClose.Location = new System.Drawing.Point(1011, 5); - this.pbClose.Name = "pbClose"; - this.pbClose.Size = new System.Drawing.Size(24, 24); - this.pbClose.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.pbClose.TabIndex = 2; - this.pbClose.TabStop = false; - this.pbClose.Click += new System.EventHandler(this.pbClose_Click); - // - // pbIcon - // - this.pbIcon.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pbIcon.BackgroundImage"))); - this.pbIcon.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; - this.pbIcon.Location = new System.Drawing.Point(5, 5); - this.pbIcon.Name = "pbIcon"; - this.pbIcon.Size = new System.Drawing.Size(24, 24); - this.pbIcon.TabIndex = 1; - this.pbIcon.TabStop = false; - // - // lblTitle - // - this.lblTitle.AutoSize = true; - this.lblTitle.BackColor = System.Drawing.Color.Transparent; - this.lblTitle.Font = new System.Drawing.Font("Century Gothic", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblTitle.ForeColor = System.Drawing.Color.WhiteSmoke; - this.lblTitle.Location = new System.Drawing.Point(31, 6); - this.lblTitle.Name = "lblTitle"; - this.lblTitle.Size = new System.Drawing.Size(157, 21); - this.lblTitle.TabIndex = 0; - this.lblTitle.Text = "Update Generator"; - // - // elipseComponent1 - // - this.elipseComponent1.Control = this; - this.elipseComponent1.Radius = 5; - // - // TestForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoSize = true; - this.BackColor = System.Drawing.SystemColors.ControlLight; - this.ClientSize = new System.Drawing.Size(1039, 538); - this.Controls.Add(this.ContentPanel); - this.Controls.Add(this.SidebarPanel); - this.Controls.Add(this.HeaderPanel); - this.DoubleBuffered = true; - this.Font = new System.Drawing.Font("Century Gothic", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.Name = "TestForm"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "TestForm"; - this.Click += new System.EventHandler(this.TestForm_Click); - this.SidebarPanel.ResumeLayout(false); - this.HeaderPanel.ResumeLayout(false); - this.HeaderPanel.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pbMinimize)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pbMaximize)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pbClose)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pbIcon)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private UI.ElipseComponent elipseComponent1; - private System.Windows.Forms.Label lblTitle; - private System.Windows.Forms.Panel SidebarPanel; - private UI.MoveablePanel HeaderPanel; - private System.Windows.Forms.PictureBox pbIcon; - private UI.HoverPictureBox pbClose; - private UI.HoverPictureBox pbMinimize; - private UI.HoverPictureBox pbMaximize; - private UI.FlatButton btnTabInformation; - private UI.FlatButton btnTabFiles; - private UI.FlatButton btnTabBuild; - internal System.Windows.Forms.Panel ContentPanel; - private UI.FlatButton btnTabRegistry; - } -} \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/TestForm.cs b/UpdateLib/UpdateLib.Generator/TestForm.cs deleted file mode 100644 index 5752676..0000000 --- a/UpdateLib/UpdateLib.Generator/TestForm.cs +++ /dev/null @@ -1,218 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Collections.Generic; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Windows.Forms; -using MatthiWare.UpdateLib.Generator.UI; -using MatthiWare.UpdateLib.Generator.UI.Pages; -using MatthiWare.UpdateLib.Tasks; -using MatthiWare.UpdateLib.UI; - -namespace MatthiWare.UpdateLib.Generator -{ - public partial class TestForm : Form - { - private Dictionary pageCache; - private AsyncTask loadTask; - private bool shouldShowNewPage = false; - - public TestForm() - { - InitializeComponent(); - - pageCache = new Dictionary(); - - LoadPagesTask().Start(); - } - - public bool TryGetPage(string key, out PageControlBase page) - { - return pageCache.TryGetValue(key, out page); - } - - private AsyncTask LoadPagesTask() - { - if (loadTask == null) - { - LoaderControl.Show(ContentPanel); - - Action loadAction = new Action(() => - { - var pageType = typeof(PageControlBase); - var types = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(asm => asm.GetTypes()) - .Where(type => pageType.IsAssignableFrom(type) && !type.IsAbstract && type.IsClass && pageType != type); - - foreach (Type type in types) - { - var name = type.Name; - - PageControlBase page = Activator.CreateInstance(type) as PageControlBase; - page.TestForm = this; - - pageCache.Add(name, page); - } - }); - - loadTask = AsyncTaskFactory.From(loadAction, null); - - loadTask.TaskCompleted += (o, e) => - { - LoaderControl.Hide(ContentPanel); - - btnTabInformation.PerformClick(); - }; - } - - return loadTask; - } - - private void TestForm_Click(object sender, EventArgs e) - { - WindowState = (WindowState == FormWindowState.Maximized) ? FormWindowState.Normal : FormWindowState.Maximized; - } - - private void pbMinimize_Click(object sender, EventArgs e) - { - WindowState = FormWindowState.Minimized; - } - - private void pbMaximize_Click(object sender, EventArgs e) - { - MaximumSize = Screen.FromControl(this).WorkingArea.Size; - WindowState = (WindowState == FormWindowState.Normal ? FormWindowState.Maximized : FormWindowState.Normal); - } - - private void pbClose_Click(object sender, EventArgs e) - { - Close(); - } - - private void flatButton1_Click(object sender, EventArgs e) - { - LoadPage(nameof(InformationPage)); - } - - private void flatButton2_Click(object sender, EventArgs e) - { - LoadPage(nameof(FilesPage)); - } - - private bool LoadPage(string pageName) - { - loadTask.AwaitTask(); - - PageControlBase page = null; - bool success = TryGetPage(pageName, out page); - - if (success) - { - shouldShowNewPage = true; - - if (page.IsPageInitialized) - { - AddControlToContentPanel(page); - } - else - { - AddControlToContentPanel(null); - - LoaderControl.Show(ContentPanel); - - page.InitializePage((o, e) => - { - LoaderControl.Hide(ContentPanel); - - if (e.Cancelled) - { - ShowMessageBox( - "Page Load", - "Task cancelled", - "The loading of the page got cancelled.", - SystemIcons.Warning, - MessageBoxButtons.OK); - - return; - } - - if (e.Error != null) - { - ShowMessageBox( - "Page Load", - "Error occured when loading the page", - "Check the log files for more information!", - SystemIcons.Error, - MessageBoxButtons.OK); - - return; - } - - AddControlToContentPanel(page); - }); - } - } - - return success; - } - - private void ShowMessageBox(string title, string header, string desc, Icon icon, MessageBoxButtons buttons = MessageBoxButtons.YesNo) - { - MessageDialog.Show( - this, - title, - header, - desc, - icon, - buttons); - } - - private void AddControlToContentPanel(Control toAdd) - { - if (!shouldShowNewPage) - return; - - ContentPanel.SuspendLayout(); - - ContentPanel.Controls.Clear(); - - if (toAdd != null) - { - toAdd.Dock = DockStyle.Fill; - ContentPanel.Controls.Add(toAdd); - - shouldShowNewPage = false; - } - - ContentPanel.ResumeLayout(); - - } - - private void btnTabBuild_Click(object sender, EventArgs e) - { - LoadPage(nameof(BuilderPage)); - } - - private void btnTabRegistry_Click(object sender, EventArgs e) - { - LoadPage(nameof(RegistryPage)); - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/TestForm.resx b/UpdateLib/UpdateLib.Generator/TestForm.resx deleted file mode 100644 index f6759bb..0000000 --- a/UpdateLib/UpdateLib.Generator/TestForm.resx +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAfpJREFUWEft - 1ctLFVEAx/GJjB5UZGkPopAWYYG1cO+/oP4BbiMkLagEV27qP+gPyb3to8iKSlFX4kIUNTUz6KXf7zgH - LsPcuo8zBHF/8GFmzpw758ycx01a+d9yAt0Hp2mu4vDBafm5hc/4lF4lySHMYAnXLSg7bVjFd2xmfmEZ - pX6F27CBCdjgXo5lIziCHkRNJ77BN/+dnT/ARVzGY/zED6xjA8cRLb2YhY37tsPI5ym8ZyecEzcQNY69 - b6mjFuTSBTvgXCglf+vAFdiBlfQqcm5iDs58GxlCPk/gPYdpEs6bhuODFOKEcmLJ8m04D47hFMbg2LsS - 7OQial6SPiDf23wHTB/O4hnC/bxxXIJ1a8o5TGMe1/AI7xDG+i0ewglmnTdwt/Mtd+Fy9Oj1GpwndcU3 - /wB7/yU7FtnJjnbO8bfh5wj5CLdnt+m6cwFbsAEn2gA6MoNYgPescx7GofCrhPjH5B9UQ7kHG3CjOWNB - Lu2wY9a5b0HsvIIP70+viuOXsM7L9CpSfKCcbB5dDdVyGtYJW7GaTnhQ6MBJVEspHQj5Z0MQUs8kHLUg - dlxObiY2EJah88HPXrkMXfuVSy9KXOvvYQNhsynyNTta199Ei5vHC7yGm8zd7NzJJs/vwB3T8yk0vOFU - S61/Rtb501KNmqIOtNJKE0mSfboRqJMj/kopAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAUhJREFUWEft - lj1KA1EUhUdJb6VuwEpBXIOlK7ASCwsLtbVzBVZWbkG0cwVWbkAlZdogWFjY+fOd4l2GcS5zr7wEBT/4 - irycc3hMYEjzz2/lc0aG6SvXMEwpHOIVTltnRZ1d4zEOUTphuoUF3MAjvMFnLJnIcDRnDBV0oU2MDkdz - Ru3haM6oPRzNGbWHozmj9nA0Z9QcXsHonhEtDOVW8QGVedRBlFoXeEJ9r0voMmGiF/hA5by3YdnRz5Ai - eoF9fEdlT3XQIbrzjUzxBJXV0+gylwsIL5/dMbJFL5/dMbJFL5/dMbJFL5/dMbJFL5/dMbJFL5/dMbJF - L5/dMbJFL5/dMUrxFs9wB5fRo+Q907xg39AE9adUr91tXELRl237I9ZwF8/xDl+xO6zX77j1eaYs4jru - 4QXe4xu2LzR3RriFB3ipgz9G03wB6snjVo1zIMAAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAL9JREFUWEft - k0sOwjAMRHMPfoLDl88a7sMCyga4AsyEIFlWoiJUuxs/6UmxNzPpJwXBnyzhHp6LPC+gCwx/wpfyAV1K - 7CADj3ANN/BUdh005woZJm+7gtxd8mTMDTJslqcPLMNdnydjtpBhfAUsQXnmzuUV8Lb84Bgo5W4OXeCf - cID3Is9uv+Gk6MeuNacWKjWnFeReQAfq2QwZLgP1bE4UiAKTFfgG6cDWfnRaQa396AwFuBUY0oxaWM0g - +JGU3jM+gGF3vCP8AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAHhJREFUSEtj - GAUkgffv3wt8/vzZgRIMMgNqHCYAKfj69et/SjDIDKhxmABmwbdv3wpgLiIWg/QQbQFeRTgAUXpHLRi1 - AC8YgRZ8//7dDsQmBgPVO5FjgTyQ3UAMBqpVJNkCqBDRgCQLaF7YUYLxWkDzCmcUYAIGBgDTAbB9WZmz - lgAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAN9JREFUSEvt - VTkOwjAQzA/gBRQ8hOs/CERDm5Jn8MK4sBO7g11pLY20TrSO24w08ioz40mR2N2GKjjn9jHGcwuHYdjJ - dhre+9s4jr8WUslJttPIBdM0PWi+1pAyL3PBomkGpiyaUkpHequPheytLqD5wrOF7F1dwKvICujBrMga - aMrhEMKX1r5E0doKLGwq4FVkBfRgVmQNNGFYZAX0YFZkDTRhWGQF9GBWZA005bCFqwqIB/pK3hayt7pA - HplRVUC//52MxeN4jpR5mgtauFjAFw6VFI9jKxcvnA0aXfcH9fiuLoI2qioAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAATNJREFUSEvt - lc1qwkAUhVO79ocudOOzVPR9SqWbbtNi60YUXLizLvs6voHbQkhCyN8yPXc4EUJimMxs/eDg3Js75zhR - EudOJ8IwHOV5PrNREARD2tWJ43iRpmlhI4Q8065OGZBl2SvW8y7CnjftgNahG2jtbRryfX/AZYWiKB48 - z+uzNAtAPUZ9gVw1QMQcvT10LkOMT4B6JT3c443UMO+hPkoP+lRDwDhAQO9L+kmSbPFZmn/wssIqQED/ - m8Y1c8EqgLflh+bqJLx0xTiA5ieau5A6CUJ2HFEYBcD8EUa/NHxXQwA/+LoMkX+U9IwCYDRF/SeGaoCI - KfoH6BJF0ZP0jAIEfMsJlxUkBPNjluYBunQKwC15wWDj4/iWsGepHWCj1gB54SCk8XGsq9YXzp06jvMP - ywAf8wYrhBkAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAmxJREFUWEft - ljuLFEEUhUdUWNBATXzjnzEUFMUHJiImq4hipIIogomKGomYmGhiJLK+138giOIDVxE0E9dlHjuzMz06 - e/2qOdXWzmxPVycLwhw4dPetc+6tqa7pupURRiiDVss21jt2rNax5/AjnK61bYbrl2rHJmqJnZ2Zs62S - D4DxM7otB5Juocht2IVWwN/VxO5Ot2yT7CmIX3bjeowHyXZjbCq5Zwe+hi/hJKvwimsCQ03DeV0O7q/4 - eJo0FizrKUzz3gzfsYz7f5qtliSDmY3VEzuI50Og7/HKXgTP8RNg9jtdAhl77v1RZLmGc4FmJRM5j+eP - vAso2XD8mrPNiBsyueJ7NBQNJvHYFw2p4eGg4B1vINE5haPBsl8Li4aUJB/Vtm1D6JdviiVdoaEoUPy6 - L7YYJcsHCU54MZM5pHAhmOgyvDfCYotR8nwgeipxt2q2RuFC/DBbhWd7ESXPB6Ip6CbwRqGlBYVnNYEn - Cv3/4Mf419pQaGlB4beawCeF8sE3YG8hzdZKXoi62ToKp4cYn+lHCudDM81nYqcljQJ/5cOBf1zhfATi - QZYs7s4FfJ/l77p+QkP5yIr1s2RxB379xSDHTYWHIzD8Y9vuazgaeI7g9Ud5rdm0DRoajqzoQs6T8FLM - uYBmDP3VwNtrdGyHhosRGI1v+0OuWUPC83tOxwOuiOQZtNvH4Xevhz12/klJ4pCZ9c657uPZfx09E7Vh - k9C1Za496+8XZ2lqdqVJyyA1920415Syoe4xFtOUOs0t19TIXg4s8QXdDoCNtJ7XcJwCD+A36BpR16B+ - hc/g0ejNNsIIKSqVv+0vKJgA+u+XAAAAAElFTkSuQmCC - - - - 17, 17 - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/UI/ElipseComponent.cs b/UpdateLib/UpdateLib.Generator/UI/ElipseComponent.cs deleted file mode 100644 index 938db33..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/ElipseComponent.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.ComponentModel; -using System.ComponentModel.Design; -using System.Drawing; -using System.Runtime.InteropServices; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.UI -{ - public class ElipseComponent : Component - { - #region PInvoke CreateRoundRectRgn - - [DllImport("gdi32.dll", EntryPoint = "CreateRoundRectRgn")] - private static extern IntPtr CreateRoundRectRgn(int x, int y, int width, int height, int curveX, int curveY); - - private static void MakeRound(Form form, int elipse) - { - if (form == null) - return; - - form.FormBorderStyle = FormBorderStyle.None; - Region region = Region.FromHrgn(CreateRoundRectRgn(0, 0, form.Width, form.Height, elipse, elipse)); - form.Region = region; - } - - #endregion - - private int m_radius; - - public int Radius - { - get { return m_radius; } - set - { - m_radius = value; - ApplyRadius(); - } - } - - private ContainerControl m_control; - - public ContainerControl Control - { - get { return m_control; } - set - { - if (m_control != null && m_control is Form) - { - m_control.Resize -= M_control_Resize; - } - - m_control = value; - - m_control.Resize += M_control_Resize; - - ApplyRadius(); - } - } - - private void M_control_Resize(object sender, EventArgs e) - { - ApplyRadius(); - } - - public ElipseComponent() - { - m_radius = 5; - } - - public ElipseComponent(IContainer container) - : this() - { - container.Add(this); - } - - public void ApplyRadius() - { - if (Control == null) - return; - - if (!(Control is Form)) - return; - - MakeRound(Control as Form, Radius); - } - - public override ISite Site - { - get - { - return base.Site; - } - - set - { - base.Site = value; - - if (value == null) - return; - - IComponent rootComponent; - Type serviceType = typeof(IDesignerHost); - IDesignerHost service = Site.GetService(serviceType) as IDesignerHost; - - if (service == null) - return; - - rootComponent = service.RootComponent; - - if (!(rootComponent is ContainerControl)) - return; - - Control = rootComponent as ContainerControl; - } - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/FlatButton.cs b/UpdateLib/UpdateLib.Generator/UI/FlatButton.cs deleted file mode 100644 index 5f10eba..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/FlatButton.cs +++ /dev/null @@ -1,205 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.ComponentModel; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Drawing.Text; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.UI -{ - [DefaultEvent(nameof(Click))] - public class FlatButton : Control - { - private const float PADDING_WIDTH = 0.0625f; - private const float PADDING_HEIGHT = 0.25f; - private const float IMG_SIZE_WIDTH = 0.125f; - private const float IMG_SIZE_HEIGHT = 0.5f; - private const float TEXT_SIZE_WIDTH = 1f - (PADDING_WIDTH * 3) - IMG_SIZE_WIDTH; - private const float TEXT_SIZE_HEIGHT = 1f - (PADDING_HEIGHT * 2); - - private bool mouseInside = false; - - private Bitmap buffer; - - private bool m_activeItem; - - private Color m_backColor; - - public bool ActiveItem - { - get { return m_activeItem; } - set { m_activeItem = value; UpdateBackgroundColor(); } - } - - private Color m_hoveColor; - - public Color BackHoverColor - { - get { return m_hoveColor; } - set { m_hoveColor = value; } - } - - private Color m_selectedColor; - - public Color BackSelectedColor - { - get { return m_selectedColor; } - set { m_selectedColor = value; } - } - - private Image m_infoImage; - - public Image InfoImage - { - get { return m_infoImage; } - set - { - m_infoImage = value; - - Rectangle rect = new Rectangle( - (int)(Width * PADDING_WIDTH), - (int)(Height * PADDING_HEIGHT), - (int)(Width * IMG_SIZE_WIDTH), - (int)(Height * IMG_SIZE_HEIGHT)); - - Invalidate(rect); - } - } - - - public FlatButton() - : base() - { - SetStyle(ControlStyles.AllPaintingInWmPaint - | ControlStyles.UserPaint - | ControlStyles.ResizeRedraw - | ControlStyles.OptimizedDoubleBuffer - | ControlStyles.SupportsTransparentBackColor, true); - - DoubleBuffered = true; - } - - public void PerformClick() - { - OnClick(EventArgs.Empty); - } - - protected override void OnClick(EventArgs e) - { - ActiveItem = true; - - foreach (Control c in Parent.Controls) - { - FlatButton button = c as FlatButton; - - if (button == null || button == this) - continue; - - button.ActiveItem = false; - } - - base.OnClick(e); - } - - protected override void OnMouseEnter(EventArgs e) - { - base.OnMouseEnter(e); - - if (!mouseInside) - { - mouseInside = true; - UpdateBackgroundColor(); - } - } - - protected override void OnMouseLeave(EventArgs e) - { - base.OnMouseLeave(e); - - if (mouseInside) - { - mouseInside = false; - UpdateBackgroundColor(); - } - } - - private void UpdateBackgroundColor() - { - m_backColor = (m_activeItem ? m_selectedColor : BackColor); - m_backColor = (mouseInside ? m_hoveColor : m_backColor); - - - Invalidate(); - } - - protected override void OnResize(EventArgs e) - { - base.OnResize(e); - - buffer = new Bitmap(Width, Height); - } - - protected override void OnPaint(PaintEventArgs e) - { - Rectangle rect = new Rectangle(0, 0, Width, Height); - - buffer = buffer ?? new Bitmap(Width, Height); - - using (Graphics g = Graphics.FromImage(buffer)) - { - g.SmoothingMode = SmoothingMode.HighQuality; - g.PixelOffsetMode = PixelOffsetMode.HighQuality; - g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; - - g.Clear(Color.White); - - g.FillRectangle(new SolidBrush(m_backColor), rect); - - float imgSize = Math.Min(Width * IMG_SIZE_WIDTH, Height * IMG_SIZE_HEIGHT); - - RectangleF imgRect = new RectangleF( - Width * PADDING_WIDTH, - Height * PADDING_HEIGHT, - imgSize, - imgSize); - - if (InfoImage != null) - g.DrawImage(InfoImage, imgRect); - - SizeF textSize = g.MeasureString(Text, Font, (int)(Width * TEXT_SIZE_WIDTH)); - - float offsetX = ((Width * PADDING_WIDTH) * 2) + imgRect.Width; - float offsetY = imgRect.Y; - - float availableTextWidth = Width - offsetX - (Width * PADDING_WIDTH); - float availableTextHeight = Height - (offsetY * 2); - - float x = offsetX + (availableTextWidth / 2) - (textSize.Width / 2); - float y = offsetY + (availableTextHeight / 2) - (textSize.Height / 2); - - g.DrawString(Text, Font, new SolidBrush(ForeColor), x, y); - - base.OnPaint(e); - e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; - e.Graphics.DrawImageUnscaled(buffer, 0, 0); - } - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/GradientPanel.cs b/UpdateLib/UpdateLib.Generator/UI/GradientPanel.cs deleted file mode 100644 index c74349a..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/GradientPanel.cs +++ /dev/null @@ -1,134 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Drawing; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.UI -{ - public class GradientPanel : Panel - { - - public GradientPanel() - : base() - { - - } - - private int m_quality = 100; - - public int Quality - { - get { return m_quality; } - set { m_quality = value; SetGradient(); } - } - - - private Color m_gradientTopRight = SystemColors.Control; - - public Color GradientTopRight - { - get { return m_gradientTopRight; } - set { m_gradientTopRight = value; SetGradient(); } - } - - private Color m_gradientTopLeft = SystemColors.Control; - - public Color GradientTopLeft - { - get { return m_gradientTopLeft; } - set { m_gradientTopLeft = value; SetGradient(); } - } - - private Color m_gradientBottomLeft = SystemColors.Control; - - public Color GradientBottomLeft - { - get { return m_gradientBottomLeft; } - set { m_gradientBottomLeft = value; SetGradient(); } - } - - private Color m_gradientBottomRight = SystemColors.Control; - - public Color GradientBottomRight - { - get { return m_gradientBottomRight; } - set { m_gradientBottomRight = value; SetGradient(); } - } - - protected override void OnResize(EventArgs eventargs) - { - base.OnResize(eventargs); - - SetGradient(); - } - - private void SetGradient() - { - Bitmap buffer = new Bitmap(Quality, Quality); - for (int x = 0; x < Quality; x++) - { - int percentX = (int)(((double)x / Width) * 100); - - Color c1 = GetColorScale(percentX, GradientTopLeft, GradientTopRight); - - for (int y = 0; y < Quality; y++) - { - int percentY = (int)(((double)y / Height) * 100); - - Color c2 = GetColorScale(percentY, GradientTopLeft, GradientTopRight); - - buffer.SetPixel(x, y, DiffuseColors(c1, c2)); - } - } - - if (BackgroundImageLayout != ImageLayout.Stretch) - BackgroundImageLayout = ImageLayout.Stretch; - - SuspendLayout(); - - BackgroundImage = buffer; - - ResumeLayout(true); - } - - private Color GetColorScale(int percentage, Color start, Color end) - { - byte red = GetByte(percentage, start.R, end.R); - byte green = GetByte(percentage, start.G, end.G); - byte blue = GetByte(percentage, start.B, end.B); - - return Color.FromArgb(red, green, blue); - } - - private byte GetByte(int percentage, byte begin, byte end) - { - return (byte)(Math.Round((begin + ((end - begin) * percentage) * 0.01), 0)); - } - - private Color DiffuseColors(Color a, Color b) - { - int red = (a.R + b.R) / 2; - int green = (a.G + b.G) / 2; - int blue = (a.B + b.B) / 2; - return Color.FromArgb(red, green, blue); - } - - - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/HoverPictureBox.cs b/UpdateLib/UpdateLib.Generator/UI/HoverPictureBox.cs deleted file mode 100644 index 08cfd31..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/HoverPictureBox.cs +++ /dev/null @@ -1,104 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Drawing; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.UI -{ - public class HoverPictureBox : PictureBox - { - private int alpha = 255; - private bool mouseInBox = false; - private bool mouseDown = false; - - protected override void OnMouseEnter(EventArgs e) - { - base.OnMouseEnter(e); - - if (!mouseInBox) - { - mouseInBox = true; - SwitchBackgroundColor(); - } - } - - private void SwitchBackgroundColor() - { - alpha = (mouseInBox ? 100 : 0); - alpha = (mouseDown ? 150 : alpha); - BackColor = Color.FromArgb(alpha, Color.WhiteSmoke); - } - - protected override void OnMouseHover(EventArgs e) - { - base.OnMouseHover(e); - - if (!mouseInBox) - { - mouseInBox = true; - SwitchBackgroundColor(); - } - } - - protected override void OnMouseLeave(EventArgs e) - { - base.OnMouseLeave(e); - - if (mouseInBox) - { - mouseInBox = false; - SwitchBackgroundColor(); - } - } - - protected override void OnMouseMove(MouseEventArgs e) - { - base.OnMouseMove(e); - - if (!mouseInBox) - { - mouseInBox = true; - SwitchBackgroundColor(); - } - } - - protected override void OnMouseDown(MouseEventArgs e) - { - base.OnMouseDown(e); - - if (!mouseDown) - { - mouseDown = true; - SwitchBackgroundColor(); - } - } - - protected override void OnMouseUp(MouseEventArgs e) - { - base.OnMouseUp(e); - - if (mouseDown) - { - mouseDown = false; - SwitchBackgroundColor(); - } - } - - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/InputDialog.Designer.cs b/UpdateLib/UpdateLib.Generator/UI/InputDialog.Designer.cs deleted file mode 100644 index 709c5a0..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/InputDialog.Designer.cs +++ /dev/null @@ -1,138 +0,0 @@ -namespace MatthiWare.UpdateLib.Generator.UI -{ - partial class InputDialog - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InputDialog)); - this.panel1 = new System.Windows.Forms.Panel(); - this.btn2 = new System.Windows.Forms.Button(); - this.btn1 = new System.Windows.Forms.Button(); - this.btn3 = new System.Windows.Forms.Button(); - this.lblHeader = new System.Windows.Forms.Label(); - this.txtInput = new System.Windows.Forms.TextBox(); - this.panel1.SuspendLayout(); - this.SuspendLayout(); - // - // panel1 - // - this.panel1.BackColor = System.Drawing.SystemColors.Control; - this.panel1.Controls.Add(this.btn2); - this.panel1.Controls.Add(this.btn1); - this.panel1.Controls.Add(this.btn3); - this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.panel1.Location = new System.Drawing.Point(0, 100); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(401, 46); - this.panel1.TabIndex = 0; - // - // btn2 - // - this.btn2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btn2.Location = new System.Drawing.Point(227, 11); - this.btn2.Name = "btn2"; - this.btn2.Size = new System.Drawing.Size(75, 23); - this.btn2.TabIndex = 2; - this.btn2.UseVisualStyleBackColor = true; - this.btn2.Visible = false; - // - // btn1 - // - this.btn1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btn1.Location = new System.Drawing.Point(146, 11); - this.btn1.Name = "btn1"; - this.btn1.Size = new System.Drawing.Size(75, 23); - this.btn1.TabIndex = 1; - this.btn1.UseVisualStyleBackColor = true; - this.btn1.Visible = false; - // - // btn3 - // - this.btn3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btn3.Location = new System.Drawing.Point(308, 11); - this.btn3.Name = "btn3"; - this.btn3.Size = new System.Drawing.Size(75, 23); - this.btn3.TabIndex = 3; - this.btn3.UseVisualStyleBackColor = true; - this.btn3.Visible = false; - // - // lblHeader - // - this.lblHeader.AutoSize = true; - this.lblHeader.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblHeader.ForeColor = System.Drawing.Color.MidnightBlue; - this.lblHeader.Location = new System.Drawing.Point(12, 9); - this.lblHeader.Name = "lblHeader"; - this.lblHeader.Size = new System.Drawing.Size(212, 25); - this.lblHeader.TabIndex = 2; - this.lblHeader.Text = "Version 1.0.0.0 available"; - // - // txtInput - // - this.txtInput.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.txtInput.Location = new System.Drawing.Point(17, 52); - this.txtInput.Name = "txtInput"; - this.txtInput.Size = new System.Drawing.Size(366, 22); - this.txtInput.TabIndex = 0; - this.txtInput.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtInput_KeyDown); - // - // InputDialog - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoSize = true; - this.BackColor = System.Drawing.SystemColors.Window; - this.ClientSize = new System.Drawing.Size(401, 146); - this.Controls.Add(this.txtInput); - this.Controls.Add(this.lblHeader); - this.Controls.Add(this.panel1); - this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "InputDialog"; - this.ShowIcon = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Message Dialog"; - this.panel1.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Panel panel1; - private System.Windows.Forms.Button btn3; - private System.Windows.Forms.Label lblHeader; - private System.Windows.Forms.Button btn1; - private System.Windows.Forms.Button btn2; - private System.Windows.Forms.TextBox txtInput; - } -} \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/UI/InputDialog.cs b/UpdateLib/UpdateLib.Generator/UI/InputDialog.cs deleted file mode 100644 index 9610f66..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/InputDialog.cs +++ /dev/null @@ -1,108 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.UI -{ - public partial class InputDialog : Form - { - public string Header - { - get { return this.lblHeader.Text; } - set { this.lblHeader.Text = value; } - } - - public string Input - { - get { return this.txtInput.Text; } - set { this.txtInput.Text = value; } - } - - public InputDialog() - { - InitializeComponent(); - } - - public InputDialog(string title, string header, MessageBoxButtons buttons = MessageBoxButtons.YesNo) - : this() - { - Header = header; - Text = title; - - SetUpButtons(buttons); - - txtInput.Focus(); - } - - private void SetUpButtons(MessageBoxButtons buttons) - { - switch (buttons) - { - case MessageBoxButtons.OK: - default: - SetUpButton(btn3, "OK", DialogResult.OK, true); - break; - case MessageBoxButtons.OKCancel: - SetUpButton(btn2, "OK", DialogResult.OK, true); - SetUpButton(btn3, "Cancel", DialogResult.Cancel); - break; - case MessageBoxButtons.AbortRetryIgnore: - SetUpButton(btn3, "Ignore", DialogResult.Ignore); - SetUpButton(btn2, "Retry", DialogResult.Retry); - SetUpButton(btn1, "Abort", DialogResult.Abort, true); - break; - case MessageBoxButtons.YesNoCancel: - SetUpButton(btn3, "Cancel", DialogResult.Cancel); - SetUpButton(btn2, "No", DialogResult.No); - SetUpButton(btn1, "Yes", DialogResult.Yes, true); - break; - case MessageBoxButtons.YesNo: - SetUpButton(btn3, "No", DialogResult.No); - SetUpButton(btn2, "Yes", DialogResult.Yes, true); - break; - case MessageBoxButtons.RetryCancel: - SetUpButton(btn3, "Cancel", DialogResult.Cancel); - SetUpButton(btn2, "Retry", DialogResult.Retry, true); - break; - } - } - - private void SetUpButton(Button button, string text, DialogResult result, bool defaultButton = false) - { - button.Text = text; - button.DialogResult = result; - button.Visible = true; - - if (defaultButton) - button.TabIndex = 0; - } - - private void txtInput_KeyDown(object sender, KeyEventArgs e) - { - if (e.KeyCode == Keys.Enter) - { - if (btn1.Visible) - btn1.PerformClick(); - else if (btn2.Visible) - btn2.PerformClick(); - else if (btn3.Visible) - btn3.PerformClick(); - } - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/InputDialog.resx b/UpdateLib/UpdateLib.Generator/UI/InputDialog.resx deleted file mode 100644 index 9fe1da0..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/InputDialog.resx +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - AAABAAIAMDAAAAEAIACoJQAAJgAAABAQAAABACAAaAQAAM4lAAAoAAAAMAAAAGAAAAABACAAAAAAAAAk - AAASCwAAEgsAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8ANJtQDDOYTkgxlEx2MZJLojCQSs0wkEr0MJBK4zCR - SsswkUuyMZJLmTGTTIAylk1fNJtQDP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AACEIy0UgTKaIIM89iuDQv8pgkD/JoI//yWF - QP8liUD/JYdA/yWHQP8mhED/JoI//yiBP/8qg0H/IIM89hSDM5kAhCMs////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAfB9RE30xxxt7Nv8kfjz/IYU8/yWP - Q/88oFb/VKxs/2e2ff9yvIf/abZ+/2K0ev9asXL/VK1t/02pZv82mFH/JYZA/yZ/Pf8bezb/En0wxwqD - K1sAgyMG////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAIUjFBN/Ma4ZdzT/In06/x6G - Ov9MqGP/iMaZ/6XUsv+cz6r/lMuk/43Hnf+JxJn/hMKU/4DAkv99vo3/ebyL/3a7if90u4f/abd//0+p - Zf8zkE3/JX49/yd8Pv8ggzrTDYsvIf///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8AMZRMiwCEIw7///8A////AP///wD///8A////AP///wD///8A////AP///wAJgClUHX037iF3 - OP8jiT//YrZ6/57Qq/+l07L/mc2n/5DIoP+KxZr/hsOX/4LBk/9+v4//er2M/3a7iP9yuYX/breC/2q1 - fv9ms3v/ZLJ5/2KyeP9hs3f/WrBy/zqYU/8nez7/HXw38wiCKUv///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8ALYZF/x58OO4WhzVpAIUkAv///wD///8A////AP///wD///8AAIQjAxN/ - MaEXci//Hno2/z6eWP+i06//p9Sz/5vNqf+TyaL/jsee/4vFmv+IxJn/hsOW/4PBlf+AwJP/fL6O/3a7 - iv9xuIT/a7Z//2aze/9isXf/Xq90/1qtcP9Wq23/VKps/1Ora/9Colv/J30+/xp1M/0VgjGDAIQjAf// - /wD///8A////AP///wD///8A////AP///wD///8ALIRE/yd3PP8mdjv/HX031AmBKkH///8A////AP// - /wANiy8EH4M7ryFyNv8fgzr/b7uD/6/au/+i0bD/mM2m/5TLo/+QyKD/kcig/5LJof+FwpX/c7mG/2Ox - eP9Tqmr/Uqlo/1uucv9jsnn/aLV+/2q1ff9isXj/XK5x/1arbf9SqWr/Tqdm/0ulZP9Jp2L/QaJd/y2G - Rv8ndTv/III6ug2MLxD///8A////AP///wD///8A////AP///wD///8ALIND/iyJRv87l1b/GG0u/xVt - LP8QeS2zDo4wIBuVPAUfgTqzHm80/yqHQv+e0qv/rNa4/5/PrP+YzKX/l8yl/5jNpv+UyqP/Z7R8/zme - Vf8llEP/KZZG/yuXSP8tmEr/LZhK/y2YSv8sl0n/K5dI/yuWSf9Co13/WK1u/1arbf9PqGf/SqVj/0ak - X/9Colz/P6JZ/z2jWP8ujUn/JnM7/x5/OccAhSQE////AP///wD///8A////AP///wD///8AK4FC/TKI - Sf/y/vT/f8OR/xt9Nv8Zai//JXU8+yuCQ9MdazL/J4dD/6TWsv+q1rb/nM2q/5nNpv+azqj/mM2n/1es - b/8nlET/KpZH/zCZTP8zm0//NJtQ/zSbUP80m1D/NJtQ/zSbUP80m1D/NJtQ/zObT/8xmk3/LphL/z6f - WP9JpWP/R6Vg/0KiXP8+oFj/Op5V/zadUv81n1L/L49K/yVuOf8SfS+W////AP///wD///8A////AP// - /wD///8AKn9B/SyDRf/f8+T/y+fS/8Hjyv9XrG7/FXQw/xNiKP8phkL/p9az/6rWtv+dz6r/nM6p/57Q - q/9+wJH/MplP/yuXSP8xmk7/NJtQ/zScUP81nVH/NZ5R/zagU/82olP/NqNU/zajVP82olP/NqBS/zWe - Uf80nFD/M5tP/zKaTv8zm1D/QKFb/z+hWf86nlX/NZxS/zObT/80nFD/NqBT/yyERP8XaC7/CH0mXf// - /wD///8A////AP///wD///8AKn1A/C6DRf/V7t3/udzD/7vexf/B4sr/oNOu/0OhXP+k1rL/qta2/53P - qv+czqr/otGv/1etb/8mlET/L5lM/zObT/80nFD/NZ1R/zagU/80nVH/MJFK/yuAQ/8lbzn/I2k2/yVu - OP8mdDv/Kn5B/zGVTf82olT/NZ9S/zScUP8zm0//MppO/zufVv83nFL/M5tP/zSbUP80m1D/NZ1R/zWg - Uv8mdT3/GW0w+QmEKy7///8A////AP///wD///8AKXxA+zGCSP/Q7Nj/tNq//7DYu/+v17r/sdi6/67W - uf+m1LP/nc+q/53Oqv+f0K3/Tahm/ymWRv8xmk7/NJtQ/zScUP81n1L/NZ5R/yp8QP8hZDP/Imc1/xlw - MfkOcSq/Am4gmgFrHrEObijIGW0w+iBlNP8lcDr/L49K/zahU/81nVH/NJtQ/zObUP8zm1D/NJtQ/zSb - UP80m1D/NJtQ/zWeUf80nVH/JGw3/xtzM+MOjjAP////AP///wD///8AKXo/+zGBSf/L6tX/sNi7/63W - uP+p1LT/pdKx/6HQrv+dzqr/ns6r/57Oq/9GpF//KpZH/zKaTv80nFD/NZ1R/zahU/8xlEz/Imo2/xdk - LP0Sei2dDYsvQACHJQb///8A////AP///wD///8AAIglEhN/MHYZbzDfIWEz/yuBQv81oVL/NZ5R/zSc - UP80m1D/NJtQ/zSbUP80m1D/NJxQ/zWdUf83pFX/MJFK/yJkNP8ceDW8AIMjAf///wD///8AKHg++jWC - Sf/I6NH/rda4/6nUtP+l0rH/odCu/53Oqv+bzan/otCu/0+nZ/8qlkf/MptP/zSbUP81nlH/NZ9S/yp/ - Qf8gYDL/GnEy5gqELD////8A////AP///wD///8A////AP///wD///8A////AP///wAAiCUHEHQsqBRc - J/8mcjr/NJ1R/zWeUf80m1D/NJtQ/zSbUP80nFH/Np9S/zWhU/8shET/IGMy/xdmLPoReC2BAHwXBP// - /wD///8AJ3c9+jaBSv/D587/qdW1/6XTsv+h0K7/nc6q/5rMqP+ezqv/cLmE/yeVRf8ymk7/NJtQ/zSb - UP81nlH/J3Q7/x9cL/8ndTz9KZtHTv///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AAZ2I3MUYCj9JG45/zWiU/81nVH/NJxQ/zWeUv83olT/MJJL/yNnNf8SWSb/DXApvgCB - ISL///8A////AP///wD///8AJ3U8+jd/S/++5Mj/pdOy/6HRrv+dz6v/mc6n/5zNqP+KxZr/KJVF/zCZ - Tf80m1D/NJtQ/zSbUP81nVH/NqJU/y2JRv8gYDL/E1om/w9wKbUBiiYg////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wAEdSRvEVYj/yt+Qf83o1T/NqJT/zSeUf8mdDv/HVgt/xlq - LusHfSdW////AP///wD///8A////AP///wD///8AJnM7+Th+TP+54sX/odGu/53Pq/+Zzaf/mc2o/5vM - qP80m1D/LphL/zSbUP80m1D/NJtQ/zSbUP80m1D/NZ1R/zagUv82olP/KX1A/x1ZLv8VYCn7EHcsjgCG - JAv///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ADm8osBxVLf8xkkv/LYZF/x9a - Lv8TWyf9EXUslACJJQv///8A////AP///wD///8A////AP///wD///8AJnI7+Dl+S/+04MD/nc+r/5nN - p/+Xzab/nc+r/0ynZP8rl0j/M5tP/zSbUP80m1D/NJtQ/zSbUP80m1D/NJtQ/zScUP82oVP/OalY/y+P - Sf8eWC3/D1Ag/wRzIqgAdAoB////AP///wD///8A////AP///wD///8A////AP///wD///8AAYkmDBdo - LeIdVCv/HFYt/xltMM0Khywu////AP///wD///8A////AP///wD///8A////AABiEiErgkOkJXA6+Dp8 - Sv+x3r3/ms2o/5bMpf+azqj/a7Z//yiVRv8ymk7/NJtQ/zSbUP80m1D/NJtQ/zSbUP80nFD/NZ5R/zei - VP80m0//JGs2/xpQKP8YZy7lB30oUv///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AAiAKC4JYSDnFH4waACIJQH///8A////AP///wD///8A////AP///wAAaBUID3MphBx3 - Nfgqf0HyJW859zp7S/+s3Ln/lsul/5fLpf+Mx5v/JpVF/zCaTf80m1D/NJtQ/zSbUP80m1D/NJtQ/zWd - Uf82oVP/NaFT/yd3Pv8ZTCf/E1km+BF4LYABiSYG////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wAAfhgC////AP///wD///8A////AP///wD///8A////AABp - GlUUdC7kL4BG/yV5O/8pfEDzJG049jp5TP+n2rb/k8qi/5nNqP9JpmL/LZhK/zSbUP80m1D/NJtQ/zSb - UP80nFH/NqBS/zimVv8rhET/G1Eq/w9NIP4NaiasAYsnGP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wAAYxEpB24jvglsJP9fk2//grSQ/yN6PP8oeT70JGs39jl3Sv+j2LH/k8qj/4PCk/8mlET/MppO/zSb - UP80m1D/NJxQ/zWfUv83pVX/MJFL/x5aLf8YSSb/FmYs0guGLDf///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8AAGIQDQxxJpAPcSn8LHtB/5a1nv/a69//OaVX/yR3Ov8ndj30I2o29Tp2S/+f1q//lsuk/0Cg - Wv8umEv/NJtQ/zScUP81nlH/N6NU/zSdUf8jZjX/FUIh/xJaJu8TfjBkAYkmAf///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wAAahxiE3Mt6xdyMf9jmHL/v9fH/9Hs1/+Lx5v/JppG/yZ0PP8mczv2I2k28jt2 - TP+g2K//eL2K/yiVRf8zm0//NZ1R/zahU/83o1P/J3c9/xZFI/8PUCH8DnIpkQGLJwv///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8AAGcTNAlvJcgKbCX/N4FL/6jFr//J6NH/vuLH/8Piy/8xmk7/MJ9O/yZz - O/8lcDn3I2o28j12Tf+i2bL/OJxU/y+aTP82oFL/OKZV/y2GRf8ZTij/C0Ub/wplJLwAhSMi////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AABhERMNciidEHAr/RxzM/94p4X/y+XQ/8Diyf+z277/ttvA/36/ - j/8llEP/NqJT/yVvOf8kbTj3I2o28UF3Uf96xI//KplI/zakVP8xlk3/Hlwv/xZEI/8VYireCH8pR/// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wAAhyQCD3MqbhZ0L/EWci//SYta/7jVwf/I59H/t93C/63Y - uv+t1rf/r9e5/yyYSP8vmUz/N6NU/yRtOP8jajb4I2o38El9Vf9Cr1//MZ1P/yRrN/8WQiH/Elck9RF5 - LXUBiiYD////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AAFrHj8YdTHSG3Qz/yN2Of+Qu5z/zerU/7zf - xf+v2Lr/qtW2/6XTs/+s1bj/ZLJ5/ymWRv8zm1D/N6RU/yNrN/8iZzX5I2o27zBzQf8ngED/F0ck/w5L - Hv0NbCaiAYwnEv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAYhIbDXEpqRJwLP4Vby7/XJtt/8fj - z//B48z/tNu//6vVtv+m07L/odGu/6LRr/+bzqn/JpRD/zCaTf80m1D/N6RV/yNnNv8hYzP5I2o37xdI - JP8LRBv/CWEhygCDIi7///8A////AP///wD///8A////AP///wD///8AAHoVAv///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAFcMBRB1K3sYdDD2GnMy/y5/ - Rf+pzrP/yOfQ/7jdwv+u17n/qNS0/6PRsP+ez6v/ms6o/6HQrf9LpmX/LJdJ/zSbUP80m1D/N6VV/yJl - M/8gYDH5JGs37xRfKOkHeiVZ////AP///wD///8A////AP///wD///8A////AP///wALhy1NGY453QqD - Kkv///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wACbR9LHHk23iF5 - Of8aczL/da+F/8zp1P+94Mf/r9m7/6nUtP+l0rH/oNCt/5vNqf+Wy6X/l8yl/3/Akf8mlET/MppO/zSb - UP80m1D/OKVV/yBiMv8fXTD6MI9KbgCIJQj///8A////AP///wD///8A////AP///wD///8AAIEhHhiO - OLAhkj//L5ZK/yGNPvAJgSkg////AP///wD///8A////AP///wD///8A////AP///wD///8A////AABj - EYobdzT/KXw//zOCSP/L6dT/zuzW/7bcwf+q1bb/pdOy/6HQrv+czqn/mMym/5PKov+QyKD/lsqk/zac - Uv8vmUv/NJtQ/zSbUP80m1D/OKZV/x9fMf8eWi77////AP///wD///8A////AP///wD///8A////AACB - IQQZjjl1IZI/9x+NPP8wlEz/Xaxy/yCKPf8giD3MAIMjBv///wD///8A////AP///wD///8A////AP// - /wD///8A////AABDAAQNbyh2GXEx8h1wNP80fUj/mcWl/7jgw/+o1rX/ntCs/5nMp/+UyqP/j8ie/4zG - nP+Nxp3/YrJ4/yqWR/8zm0//NJtQ/zSbUP80m1D/OKZW/x9dMP8dVy37////AP///wD///8A////AP// - /wD///8AC4gtOySUQtMlkkP/E4c0/4fCl////////////y2RSP8jhj7/E30wmP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8AAFsNFQlmI6IQZCf9E2Uq/0uGWv+cy6j/ndOt/5LJ - of+Mxpz/h8SY/4XClf+EwpT/K5dJ/zGaTf80m1D/NJtQ/zSbUP80m1D/OKdW/x5aLv8dVy38////AP// - /wD///8A////AACBIRMZjjmcI5JC/h+NPv9RpGb/8vn1///////8/v3//////9fs3f8UfS//GHwz/xB3 - LJAAhiQC////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAacTM7IWw19BNg - KP8RViT/f7KO/4rFmv+EwpX/gMGS/4HBlP9LpmT/LZhK/zSbUP80m1D/NJtQ/zSbUP80m1D/OKdW/x5a - L/8dViz8////AP///wD///8AAIEhYyWUQ+4zmE7/MJVM/0aiYP////////////L49P/r9e7/6vTs//X6 - 9v+t1bn/GX00/yF9Ov8deja/AGgcE////wD///8A////AP///wD///8A////AP///wD///8A////AABf - GTEUZSvXGmMt/yNoNf93s4n/jsyf/4LDk/98vo7/e76O/222gf8qlkf/MptP/zSbUP80m1D/NJtQ/zSb - UP80m1D/OKZW/x5cL/8dViz8////AP///wD///8ACoMqjTKXTv8ylk3/M5xQ/x+RPv+UyqP//////+z2 - 7v/j8ef/3+/j/97u4v/m9Or/v+HI/yGBO/8ddjX/GHQx6g1vKIgAYRAe////AP///wD///8A////AAA7 - AAMAXxdBCWEhlRBdJfsUXCn/RoNW/5TOpP+LyJv/f8CR/3m9i/93u4n/crqH/zKaTv8wmk3/NJtQ/zSb - UP80m1D/NJtQ/zSbUP80m1D/OKZW/x5cL/8dViz9////AP///wD///8AAIIiBSOMQMkxkUv/MpZN/y6a - S/8ckDz/u97E//P69P/f7+P/1+vc/9Lp2P/P59b/1ezc/8no0f9RmmT/Emss/xtvMv8Vayv9C2Qi0ABb - F7gAXBWkCWMhuxRkKfUdZTH/Fl4p/x5hMP9xq4D/kc+i/4LDlf96vYz/dbuI/3O6hf9zuYb/PZ9Y/y+Z - TP80m1D/NZ1R/zWeUf81nlH/NJxQ/zSbUP80m1D/OKZW/x5cL/8dViz9////AP///wD///8A////AAZ6 - JyEihz7yLoxI/zKZT/8smUr/G446/6PRsP/o8+r/1OrZ/8rl0f/F4s3/weDK/8TjzP/L6NL/stq+/0+b - ZP8fcDT/Dl8l/xFgJ/8TXyf/EFwl/xdiLP89gU7/bqh9/47Hn/+HyJr/fcCP/3a7if9yuYX/b7iC/262 - gv9Lp2X/LphL/zObT/81nlL/NqNT/yl8P/81oVL/NqJU/zWeUf80nFD/OKZW/x5cLv8dViz9////AP// - /wD///8A////AP///wAFdSNVIIE6/y2JRf80nFH/LppL/x2QPP+EwpX/2+3g/8vm0f+/38f/uNzC/7Ta - vv+y2b3/stm8/7XdwP+44cP/sNu8/5TKov+CvJH/lMej/57Wrv+Tz6T/iciZ/3/BkP95vYz/c7qG/264 - gv9stn//a7Z//0akX/8umEv/M5tP/zWeUv82pFT/JGo2/xdIJf8aTyn/K39B/zekVf82oVP/OKhX/x5c - MP8dViz+////AP///wD///8A////AP///wD///8AEXgtmSuDRP8shkX/NJ1R/zCbTf8jk0L/QqFc/7fc - wf/E4cv/tdu//63XuP+n07P/o9Gw/57Pq/+Zzaf/l8ul/5TLov+Pyp//iMWa/4PClP9+v4//eb2L/3S6 - h/9vuIP/bLaB/2m2ff9ntH3/P6Ba/y6ZS/8zm0//NZ9S/zalVP8kajf/GUwn/x1XLOkbUyr5GEwn/x1X - Lf8vjEj/O7Bb/x9gMv8cViz+////AP///wD///8A////AP///wD///8AAF0OBh17NrEqfED/K4BB/zOb - UP8znVD/KpdI/yKSQv9rt4D/r9i6/7HZu/+k0bD/m86p/5bLpf+RyaD/jcac/4jEmP+DwpT/fr+Q/3q9 - jP92u4j/cbmE/222gP9ptX7/Z7V8/1etb/81m1H/MJlM/zObT/82n1L/N6RV/yJqNf8ZTCf/Dk0g3Qdb - HRkAUBEgAksVtwxEG/4YSyb/I2o2/yBdMP8cViz+////AP///wD///8A////AP///wD///8A////AACH - JAEMbCibGnEy/yl4Pf8ymU7/NZ9S/zCaTf8plkb/I5JB/1mucf+Xy6X/odGu/5fMpv+PyJ//iMWZ/4HA - kv97vo3/druJ/3O5iP9xuIX/breB/2u1f/9brnH/Op1U/y6YSv8xmk7/NJ1R/zaiU/80nVH/IWQz/xlM - J/8QTyDYAFERFP///wD///8A////AABDAkQBRRLXC0cc/xtTKv8cViz/////AP///wD///8A////AP// - /wD///8A////AP///wD///8AAGQaghdrL/4lcjr/L4pI/zWhUv81n1L/MZtO/yuXSf8klEP/MZlO/1Gp - aP9rtn//er6L/3q+jP97vo3/eL6L/2u1f/9YrG//R6Rg/zmeU/8tmEr/MZpN/zScUP81n1L/OKVV/yyG - Rf8aUCn/CkQa/wFGFM0ARAEQ////AP///wD///8A////AP///wD///8AAEkNbg9OH+4cViz/////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AABfF2kWZy36I2o3/yVxOv8wkkv/N6NU/zWf - Uv80nFD/MZpO/y6YS/8qlkj/KJVG/yiVRv8olUb/KZZG/yuXSP8tmEr/MJlM/zKaTv80nFD/NqBS/zel - Vf81n1D/ImY0/xhLJv8MRxz6AEMKhf///wD///8A////AP///wD///8A////AP///wD///8A////AAA/ - AAwhYzOZ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAVAkjCV0ftRRd - J/4gYTL/J3U9/zGVTP82pVT/N6NU/zagUv81nVH/NJxQ/zSbUP80m1D/NJtQ/zScUP81nlH/NqBS/zej - VP84qFb/L49J/yJmNP8ZSSX/GVAp/xBRIdYATA0v////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AABWE0YTWyfWHlsw/x5aLv8fWy//JnE7/y2KSP82oVP/OalX/zioV/84qFb/OKhX/zeo - Vv8zmk//LolG/yh3Pf8dVSz/GEom/wpEGv8AQhHjAEoMgAAYAAL///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wACjSgBAE8PYwRSGrcQUSH1G1Qr/xpQKf8YSyb/GEkm/xpN - J/8bUyr/HVgt/xhKJv8XSSX/GEom/xhNJ/8MRhz9AUoWwABCAVL///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAndDwEI2o2TyFi - MqUfXTDRHlsv3R5aLucdWC3xHVgt+B5bL+EgXzG+IWMzlCJmNGQjaTYc////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A///AAf// - AAD//wAAf/8AAP/8AAAP/wAA//AAAAf/AAA/4AAAA/8AAA+AAAAA/wAABwAAAAB/AAAAAAAAAD8AAAAA - AAAAPwAAAAAAAAAfAAAAAAAAAA8AAAAAAAAABwAAAAAB4AADAAAAAA/4AAMAAAAAH/4ADwAAAAAH/wA/ - AAAAAAH/gH8AAAAAAP+B/AAAAAAD/8PwAAAAAAf/7+AAAAAAH///gAAAAAB///4AAAAAAP///AAAAAAD - ///wAAAAAA///8AAAAAAP///AAAAAAB///4AAAAAAf//+AAAAAAH9//gAAAAAB/j/8AAAAAAP4H/gAAA - AAD+AP+AAAAAAPwA/+AAAAAA8AA/+AAAAADgAB/wAAAAAOAAB4AAAAAA4AAAAAAAAADwAAAAAAAAAPgA - AAAAAAAA/AAAAAAAAAD8AAAAAAAAAP4AAAAA4AAA/4AAAAH4AAD/wAAAB/wAAP/gAAAP/wAA//gAAB// - AAD//AAA//8AAP//gAP//wAAKAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEgsAABILAAAAAAAAAAAAAP// - /wD///8A////AP///wA0m1AIMpJMbDOTTt0/mlj4Qpta+TuYVPUyk0zDMJFLIv///wD///8A////AP// - /wAvjEhW////AP///wAAbhkgJIU99Hu4jP+q17b/sdq8/6DRrv+PyZ//cbmF/zOPTf4FeCSi////AP// - /wD///8AQpFY/BB3K+4AbRp8LodG/MHgyf+j1LH/abZ+/0KkW/9BpFz/Wa9w/2W0ev9fsXX/NJVP/wZ0 - I83///8A////AGamd/3h9ef/cbCC/8rn0v9+wpD/I5ZD/yaNQf8mgT77J4FA+yeJQv8smUr/R6dh/0Kk - XP8giDz/AG0alP///wBionP91O3b/77fx/9otn7/JZVD/yV7PP4vhUahKZxJChuVPAQLaSU/G3Qz+DOf - Uf81oVL/IIU8/wJoHd7///8AX51w/cbn0P+ZzKf/I5JB/zKdT/8yl03/KHU8+Q1qJkz///8A////AABi - GiYccjP6Kn1B+R54N3j///8ALIVFFlqZa/3B5cr/O59W/y6bS/81n1H/G3Uz/RBtKb4AZwwK////AP// - /wD///8AAGEYJCCIPAsMXCIEKotEpTKDR/hVlGb9fseR/ymcSP8bdjT/DGIi5ABbDSH///8A////AP// - /wD///8A////AP///wARfS5ZU5Zk96zTtv8sg0T8SY5c/SyOSP8hbDb1GmwwVP///wD///8A////AP// - /wD///8A////AABfCSEQdCvjfrCL/9Lr2f9Wsm//Kn5B/SVuOfYabDGZJptFASOXQwgIiCsg////AP// - /wD///8AAF8HCA14KbdUmWf+weDL/7new/+MyJz/JppF/yl4Pv00m1AM////ABqTO2BLpGP4OplV+wB0 - GS7///8A////AA1uJ0A2hUv4nsiq/6vZt/+WzKX/NpxS/zGgT/8nczv9////AAqHLM9IoWD///////3/ - /v8efzb6AGYaTAFeGgkRaykKGHIwmjR3Rv6Mx5z/V65u/yyYSf83pVT/JnI7/f///wAAeR5jDn8s/ozJ - nf/t+PD/zufV/3ywi/9Bh1T9Sodb/XCqf/+Myp7/XrV1/yudSv8pfj//N6ZW/yZyO/3///8A////AAJy - IIgPeyv/QKRb/5jQqP+y3L3/otWx/5DNoP9zvof/TKtk/yycS/8SXCb9B1QbjghYHfAgYjL9////AP// - /wD///8ABGwfoBRwLfshij7/KZxJ/zmkVf85pFf/K5tJ/ymFQf8TWyX4AEgNNP///wD///8AImU0Zv// - /wD///8A////AP///wAlcDoLKXY+mSdyO/Umcjv7JnE7+ydwO+cmbzqHI2k2EP///wD///8A////AP// - /wDwDwAAYAcAAAADAAAAAQAAAAEAAADCAAAA4AAAA/AAAA/AAAAHAAAAQwAAAIAAAACAAAAAwAAAAOAG - AADwDwAA - - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/UI/LoaderControl.Designer.cs b/UpdateLib/UpdateLib.Generator/UI/LoaderControl.Designer.cs deleted file mode 100644 index 6b90a43..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/LoaderControl.Designer.cs +++ /dev/null @@ -1,64 +0,0 @@ -namespace MatthiWare.UpdateLib.Generator.UI -{ - partial class LoaderControl - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.pbLoader = new System.Windows.Forms.PictureBox(); - ((System.ComponentModel.ISupportInitialize)(this.pbLoader)).BeginInit(); - this.SuspendLayout(); - // - // pbLoader - // - this.pbLoader.Anchor = System.Windows.Forms.AnchorStyles.None; - this.pbLoader.BackColor = System.Drawing.Color.Transparent; - this.pbLoader.Image = global::MatthiWare.UpdateLib.Generator.Properties.Resources.loading_gear; - this.pbLoader.Location = new System.Drawing.Point(0, 0); - this.pbLoader.Name = "pbLoader"; - this.pbLoader.Size = new System.Drawing.Size(150, 150); - this.pbLoader.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.pbLoader.TabIndex = 0; - this.pbLoader.TabStop = false; - // - // LoaderControl - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(249)))), ((int)(((byte)(249))))); - this.Controls.Add(this.pbLoader); - this.MinimumSize = new System.Drawing.Size(150, 150); - this.Name = "LoaderControl"; - ((System.ComponentModel.ISupportInitialize)(this.pbLoader)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.PictureBox pbLoader; - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/LoaderControl.cs b/UpdateLib/UpdateLib.Generator/UI/LoaderControl.cs deleted file mode 100644 index 8cbf791..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/LoaderControl.cs +++ /dev/null @@ -1,144 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Windows.Forms; -using MatthiWare.UpdateLib.UI; - -namespace MatthiWare.UpdateLib.Generator.UI -{ - public partial class LoaderControl : UserControl - { - private static Dictionary loaders = new Dictionary(); - - private const int WS_EX_TRANSPARENT = 0x20; - - private int m_opacity = 100; - - public int Opacity - { - get - { - return m_opacity; - } - set - { - m_opacity = value; - - if (m_opacity > 100) - m_opacity = 100; - - if (m_opacity < 0) - m_opacity = 1; - - var alpha = (m_opacity * 255) / 100; - BackColor = Color.FromArgb(alpha, BackColor); - Invalidate(); - } - } - - - public LoaderControl() - { - InitializeComponent(); - - SetStyle(ControlStyles.SupportsTransparentBackColor, true); - //SetStyle(ControlStyles.Opaque, true); - DoubleBuffered = true; - } - - protected override CreateParams CreateParams - { - get - { - CreateParams cp = base.CreateParams; - cp.ExStyle |= WS_EX_TRANSPARENT; - return cp; - } - } - - public static void Show(Control parent) - { - if (parent == null) - return; - - if (!loaders.ContainsKey(parent)) - loaders.Add(parent, new LoaderControl()); - - loaders[parent].ShowLoader(parent); - } - - public void ShowLoader(Control parent) - { - Parent.InvokeOnUI(() => - { - parent.SuspendLayout(); - - Opacity = 100; - - Size = parent.Size; - //parent.Size = Size; - Location = new Point(0, 0); - - parent.Resize += ParentResize; - - parent.Controls.Add(this); - - BringToFront(); - - parent.ResumeLayout(); - }); - } - - private void ParentResize(object sender, EventArgs e) - { - Control parent = sender as Control; - - if (parent == null) - return; - - Size = parent.Size; - } - - public static void Hide(Control parent) - { - if (parent == null) - return; - - if (!loaders.ContainsKey(parent)) - return; - - loaders[parent].HideLoader(parent); - } - - public void HideLoader(Control parent) - { - Parent.InvokeOnUI(() => - { - parent.SuspendLayout(); - - parent.Resize -= ParentResize; - - parent.Controls.Remove(this); - - parent.ResumeLayout(); - }); - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/LoaderControl.resx b/UpdateLib/UpdateLib.Generator/UI/LoaderControl.resx deleted file mode 100644 index 750e8d2..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/LoaderControl.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - True - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/UI/MoveablePanel.cs b/UpdateLib/UpdateLib.Generator/UI/MoveablePanel.cs deleted file mode 100644 index 5e57ec8..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/MoveablePanel.cs +++ /dev/null @@ -1,71 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Runtime.InteropServices; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.UI -{ - public class MoveablePanel : Panel - { - public Form ParentForm { get; set; } - - private const int WM_NCLBUTTONDOWN = 0xA1; - private const int HT_CAPTION = 0x2; - - [DllImport("user32.dll")] - private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); - - [DllImport("user32.dll")] - private static extern bool ReleaseCapture(); - - protected override void OnMouseMove(MouseEventArgs e) - { - base.OnMouseMove(e); - - MoveParentForm(this, e); - } - - private void MoveParentForm(object sender, MouseEventArgs e) - { - if (ParentForm != null) - { - ReleaseCapture(); - SendMessage(this.ParentForm.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); - } - } - - protected override void OnControlAdded(ControlEventArgs e) - { - base.OnControlAdded(e); - - if (typeof(HoverPictureBox) == e.Control.GetType()) - return; - - e.Control.MouseMove += MoveParentForm; - } - - protected override void OnControlRemoved(ControlEventArgs e) - { - base.OnControlRemoved(e); - - e.Control.MouseMove -= MoveParentForm; - } - - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/BuilderPage.Designer.cs b/UpdateLib/UpdateLib.Generator/UI/Pages/BuilderPage.Designer.cs deleted file mode 100644 index 1a33f59..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/BuilderPage.Designer.cs +++ /dev/null @@ -1,133 +0,0 @@ -namespace MatthiWare.UpdateLib.Generator.UI.Pages -{ - partial class BuilderPage - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.label1 = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.btnBuild = new System.Windows.Forms.Button(); - this.lblProgress = new System.Windows.Forms.Label(); - this.pbProgress = new System.Windows.Forms.ProgressBar(); - this.lblStatus = new System.Windows.Forms.Label(); - this.saveFileDialog = new System.Windows.Forms.SaveFileDialog(); - this.SuspendLayout(); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Century Gothic", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(14, 16); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(143, 20); - this.label1.TabIndex = 1; - this.label1.Text = "Update generator"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(15, 59); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(121, 17); - this.label2.TabIndex = 2; - this.label2.Text = "Make new version: "; - // - // btnBuild - // - this.btnBuild.Location = new System.Drawing.Point(142, 56); - this.btnBuild.Name = "btnBuild"; - this.btnBuild.Size = new System.Drawing.Size(75, 23); - this.btnBuild.TabIndex = 3; - this.btnBuild.Text = "Build"; - this.btnBuild.UseVisualStyleBackColor = true; - this.btnBuild.Click += new System.EventHandler(this.btnBuild_Click); - // - // lblProgress - // - this.lblProgress.AutoSize = true; - this.lblProgress.Location = new System.Drawing.Point(139, 100); - this.lblProgress.Name = "lblProgress"; - this.lblProgress.Size = new System.Drawing.Size(79, 17); - this.lblProgress.TabIndex = 4; - this.lblProgress.Text = "Progress: 0%"; - // - // pbProgress - // - this.pbProgress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.pbProgress.Location = new System.Drawing.Point(17, 139); - this.pbProgress.Name = "pbProgress"; - this.pbProgress.Size = new System.Drawing.Size(593, 23); - this.pbProgress.TabIndex = 5; - // - // lblStatus - // - this.lblStatus.AutoSize = true; - this.lblStatus.Location = new System.Drawing.Point(14, 100); - this.lblStatus.Name = "lblStatus"; - this.lblStatus.Size = new System.Drawing.Size(104, 17); - this.lblStatus.TabIndex = 6; - this.lblStatus.Text = "Status: Waiting.."; - // - // saveFileDialog - // - this.saveFileDialog.FileName = "updatefile"; - this.saveFileDialog.Filter = "Update files (.xml)|*.xml"; - this.saveFileDialog.Title = "Save location"; - // - // BuilderPage - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.lblStatus); - this.Controls.Add(this.pbProgress); - this.Controls.Add(this.lblProgress); - this.Controls.Add(this.btnBuild); - this.Controls.Add(this.label2); - this.Controls.Add(this.label1); - this.DoubleBuffered = true; - this.Font = new System.Drawing.Font("Century Gothic", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.MinimumSize = new System.Drawing.Size(239, 104); - this.Name = "BuilderPage"; - this.Size = new System.Drawing.Size(629, 182); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Button btnBuild; - private System.Windows.Forms.Label lblProgress; - private System.Windows.Forms.ProgressBar pbProgress; - private System.Windows.Forms.Label lblStatus; - private System.Windows.Forms.SaveFileDialog saveFileDialog; - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/BuilderPage.cs b/UpdateLib/UpdateLib.Generator/UI/Pages/BuilderPage.cs deleted file mode 100644 index 6b5ab27..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/BuilderPage.cs +++ /dev/null @@ -1,158 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Windows.Forms; -using System.IO; -using MatthiWare.UpdateLib.UI; -using MatthiWare.UpdateLib.Tasks; -using MatthiWare.UpdateLib.Generator.Tasks; -using MatthiWare.UpdateLib.Files; -using System.Diagnostics; - -namespace MatthiWare.UpdateLib.Generator.UI.Pages -{ - public partial class BuilderPage : PageControlBase - { - private FilesPage filesPage; - private InformationPage infoPage; - private RegistryPage registryPage; - - public BuilderPage() - { - InitializeComponent(); - } - - protected override void OnPageInitialize() - { - saveFileDialog.InitialDirectory = new DirectoryInfo("./Output").FullName; - - PageControlBase page; - if (!TestForm.TryGetPage(nameof(FilesPage), out page)) - { - throw new KeyNotFoundException($"Unable to get {nameof(FilesPage)}"); - } - - filesPage = page as FilesPage; - - if (!TestForm.TryGetPage(nameof(InformationPage), out page)) - { - throw new KeyNotFoundException($"Unable to get {nameof(InformationPage)}"); - } - - infoPage = page as InformationPage; - - if (!TestForm.TryGetPage(nameof(RegistryPage), out page)) - { - throw new KeyNotFoundException($"Unable to get {nameof(RegistryPage)}"); - } - - registryPage = page as RegistryPage; - - if (!filesPage.IsPageInitialized) - filesPage.InitializePage(null); - - if (!infoPage.IsPageInitialized) - infoPage.InitializePage(null); - - if (!registryPage.IsPageInitialized) - registryPage.InitializePage(null); - } - - private void btnBuild_Click(object sender, EventArgs e) - { - if (saveFileDialog.ShowDialog(ParentForm) != DialogResult.OK) - return; - - pbProgress.Value = 0; - lblProgress.Text = "Progress: 0%"; - - Build(saveFileDialog.OpenFile()); - } - - Stopwatch sw = new Stopwatch(); - - private AsyncTask Build(Stream s) - { - UpdateGeneratorTask task = new UpdateGeneratorTask(filesPage.Root, infoPage,registryPage.Folders); - - btnBuild.Enabled = false; - - task.TaskProgressChanged += (o, e) => - { - lblProgress.Text = $"Progress: {e.ProgressPercentage}%"; - pbProgress.Value = e.ProgressPercentage; - - }; - - task.TaskCompleted += (o, e) => - { - sw.Stop(); - - Updater.Instance.Logger.Debug(nameof(BuilderPage), nameof(Build), $"File generation completed in {sw.ElapsedMilliseconds} ms."); - - - - btnBuild.Enabled = true; - - if (e.Cancelled) - { - lblStatus.Text = $"Status: Cancelled"; - return; - } - - if (e.Error != null) - { - lblStatus.Text = $"Status: Error"; - - MessageDialog.Show( - ParentForm, - "Builder", - "Build error", - "Check the logs for more information", - SystemIcons.Error, - MessageBoxButtons.OK); - - return; - } - - using (s) - task.Result.Save(s); - - lblStatus.Text = $"Status: Completed"; - - MessageDialog.Show( - ParentForm, - "Builder", - "Build completed", - "The update file has been succesfully generated!\n" + - $"File generation completed in {sw.ElapsedMilliseconds} ms.", - SystemIcons.Information, - MessageBoxButtons.OK); - }; - - lblStatus.Text = "Status: Building.."; - - sw.Reset(); - sw.Start(); - - return task.Start(); - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/BuilderPage.resx b/UpdateLib/UpdateLib.Generator/UI/Pages/BuilderPage.resx deleted file mode 100644 index ff68a6a..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/BuilderPage.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/FilesPage.Designer.cs b/UpdateLib/UpdateLib.Generator/UI/Pages/FilesPage.Designer.cs deleted file mode 100644 index b5cbc01..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/FilesPage.Designer.cs +++ /dev/null @@ -1,232 +0,0 @@ -namespace MatthiWare.UpdateLib.Generator.UI.Pages -{ - partial class FilesPage - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.label1 = new System.Windows.Forms.Label(); - this.tvFolders = new System.Windows.Forms.TreeView(); - this.ilIcons = new System.Windows.Forms.ImageList(this.components); - this.contextMenuRightClick = new System.Windows.Forms.ContextMenuStrip(this.components); - this.menuAddFiles = new System.Windows.Forms.ToolStripMenuItem(); - this.menuAddFolder = new System.Windows.Forms.ToolStripMenuItem(); - this.newFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.existingFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.lvFiles = new System.Windows.Forms.ListView(); - this.clmnName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnDate = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnSize = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); - this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); - this.contextMenuRightClick.SuspendLayout(); - this.SuspendLayout(); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Century Gothic", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(14, 16); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(128, 20); - this.label1.TabIndex = 1; - this.label1.Text = " Files and folders"; - // - // tvFolders - // - this.tvFolders.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); - this.tvFolders.ImageIndex = 0; - this.tvFolders.ImageList = this.ilIcons; - this.tvFolders.Location = new System.Drawing.Point(18, 53); - this.tvFolders.Name = "tvFolders"; - this.tvFolders.SelectedImageIndex = 0; - this.tvFolders.Size = new System.Drawing.Size(191, 332); - this.tvFolders.TabIndex = 2; - this.tvFolders.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.tvFolders_NodeMouseClick); - // - // ilIcons - // - this.ilIcons.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; - this.ilIcons.ImageSize = new System.Drawing.Size(16, 16); - this.ilIcons.TransparentColor = System.Drawing.Color.Transparent; - // - // contextMenuRightClick - // - this.contextMenuRightClick.Font = new System.Drawing.Font("Century Gothic", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.contextMenuRightClick.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.menuAddFiles, - this.menuAddFolder, - this.toolStripSeparator1, - this.deleteToolStripMenuItem}); - this.contextMenuRightClick.Name = "menuTV"; - this.contextMenuRightClick.Size = new System.Drawing.Size(142, 76); - // - // menuAddFiles - // - this.menuAddFiles.Image = global::MatthiWare.UpdateLib.Generator.Properties.Resources.image_transparent_16px; - this.menuAddFiles.Name = "menuAddFiles"; - this.menuAddFiles.Size = new System.Drawing.Size(141, 22); - this.menuAddFiles.Text = "Add File(s)"; - this.menuAddFiles.Click += new System.EventHandler(this.menuAddFiles_Click); - // - // menuAddFolder - // - this.menuAddFolder.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.newFolderToolStripMenuItem, - this.existingFolderToolStripMenuItem}); - this.menuAddFolder.Image = global::MatthiWare.UpdateLib.Generator.Properties.Resources.folder_transparent_16px; - this.menuAddFolder.Name = "menuAddFolder"; - this.menuAddFolder.Size = new System.Drawing.Size(141, 22); - this.menuAddFolder.Text = "Add Folder"; - // - // newFolderToolStripMenuItem - // - this.newFolderToolStripMenuItem.Name = "newFolderToolStripMenuItem"; - this.newFolderToolStripMenuItem.Size = new System.Drawing.Size(159, 22); - this.newFolderToolStripMenuItem.Text = "New Folder"; - this.newFolderToolStripMenuItem.Click += new System.EventHandler(this.newFolderToolStripMenuItem_Click); - // - // existingFolderToolStripMenuItem - // - this.existingFolderToolStripMenuItem.Name = "existingFolderToolStripMenuItem"; - this.existingFolderToolStripMenuItem.Size = new System.Drawing.Size(159, 22); - this.existingFolderToolStripMenuItem.Text = "Existing Folder"; - this.existingFolderToolStripMenuItem.Click += new System.EventHandler(this.existingFolderToolStripMenuItem_Click); - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(138, 6); - // - // deleteToolStripMenuItem - // - this.deleteToolStripMenuItem.Enabled = false; - this.deleteToolStripMenuItem.Image = global::MatthiWare.UpdateLib.Generator.Properties.Resources.cross; - this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; - this.deleteToolStripMenuItem.Size = new System.Drawing.Size(141, 22); - this.deleteToolStripMenuItem.Text = "Delete"; - this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click); - // - // lvFiles - // - this.lvFiles.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.lvFiles.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.clmnName, - this.clmnType, - this.clmnDate, - this.clmnSize}); - this.lvFiles.ContextMenuStrip = this.contextMenuRightClick; - this.lvFiles.FullRowSelect = true; - this.lvFiles.Location = new System.Drawing.Point(215, 53); - this.lvFiles.MultiSelect = false; - this.lvFiles.Name = "lvFiles"; - this.lvFiles.Size = new System.Drawing.Size(577, 332); - this.lvFiles.SmallImageList = this.ilIcons; - this.lvFiles.TabIndex = 3; - this.lvFiles.UseCompatibleStateImageBehavior = false; - this.lvFiles.View = System.Windows.Forms.View.Details; - this.lvFiles.SelectedIndexChanged += new System.EventHandler(this.lvFiles_SelectedIndexChanged); - this.lvFiles.DoubleClick += new System.EventHandler(this.lvFiles_DoubleClick); - // - // clmnName - // - this.clmnName.Text = "Name"; - this.clmnName.Width = 109; - // - // clmnDate - // - this.clmnDate.DisplayIndex = 1; - this.clmnDate.Text = "Last Modified"; - this.clmnDate.Width = 147; - // - // clmnType - // - this.clmnType.DisplayIndex = 2; - this.clmnType.Text = "Type"; - this.clmnType.Width = 93; - // - // clmnSize - // - this.clmnSize.Text = "Size"; - this.clmnSize.Width = 71; - // - // folderBrowserDialog - // - this.folderBrowserDialog.ShowNewFolderButton = false; - // - // openFileDialog - // - this.openFileDialog.Multiselect = true; - this.openFileDialog.ReadOnlyChecked = true; - this.openFileDialog.Title = "Add files to be included in the updater"; - // - // FilesPage - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.lvFiles); - this.Controls.Add(this.tvFolders); - this.Controls.Add(this.label1); - this.DoubleBuffered = true; - this.Font = new System.Drawing.Font("Century Gothic", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.MinimumSize = new System.Drawing.Size(589, 233); - this.Name = "FilesPage"; - this.Size = new System.Drawing.Size(810, 403); - this.contextMenuRightClick.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label label1; - private System.Windows.Forms.TreeView tvFolders; - private System.Windows.Forms.ListView lvFiles; - private System.Windows.Forms.ColumnHeader clmnName; - private System.Windows.Forms.ColumnHeader clmnDate; - private System.Windows.Forms.ColumnHeader clmnType; - private System.Windows.Forms.ColumnHeader clmnSize; - private System.Windows.Forms.ImageList ilIcons; - private System.Windows.Forms.ContextMenuStrip contextMenuRightClick; - private System.Windows.Forms.ToolStripMenuItem menuAddFiles; - private System.Windows.Forms.ToolStripMenuItem menuAddFolder; - private System.Windows.Forms.ToolStripMenuItem newFolderToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem existingFolderToolStripMenuItem; - private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog; - private System.Windows.Forms.OpenFileDialog openFileDialog; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem; - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/FilesPage.cs b/UpdateLib/UpdateLib.Generator/UI/Pages/FilesPage.cs deleted file mode 100644 index 526cbba..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/FilesPage.cs +++ /dev/null @@ -1,310 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Data; -using System.Linq; -using System.Windows.Forms; -using MatthiWare.UpdateLib.Tasks; -using MatthiWare.UpdateLib.Generator.Data; -using System.IO; -using MatthiWare.UpdateLib.UI; -using MatthiWare.UpdateLib.Generator.Data.FilesPage; - -namespace MatthiWare.UpdateLib.Generator.UI.Pages -{ - public partial class FilesPage : PageControlBase - { - private const string PROJECT_IMAGE_KEY = "project_key"; - - public GenFolder Root { get; set; } - - private GenFile _selectedFile; - private GenFile SelectedFile - { - get { return _selectedFile; } - set - { - _selectedFile = value; - if (value != null && !deleteToolStripMenuItem.Enabled) - deleteToolStripMenuItem.Enabled = true; - } - } - private GenFolder _selectedFolder; - private GenFolder SelectedFolder - { - get { return _selectedFolder; } - set - { - _selectedFolder = value; - if (value != null && !deleteToolStripMenuItem.Enabled) - deleteToolStripMenuItem.Enabled = true; - } - } - - public FilesPage() - { - InitializeComponent(); - } - - protected override void OnPageInitialize() - { - SuspendLayout(); - - ilIcons.Images.Add(TreeViewFolderNode.FOLDER_KEY, Properties.Resources.folder_transparent_16px); - ilIcons.Images.Add(PROJECT_IMAGE_KEY, Properties.Resources.project_16px); - - Root = new GenFolder("Update Project", contextMenuRightClick); - Root.ProtectedFolder = true; - Root.FolderTreeView.SelectedImageKey = PROJECT_IMAGE_KEY; - Root.FolderTreeView.ImageKey = PROJECT_IMAGE_KEY; - - GenFolder appFolder = new GenFolder("Application Folder", contextMenuRightClick); - appFolder.ProtectedFolder = true; - appFolder.PathVariable = "%appdir%"; - - Root.Add(appFolder); - - tvFolders.Nodes.Add(Root.FolderTreeView); - - folderBrowserDialog.Description = "Please select the folder to import"; - - UpdateSelectedFolder(Root); - - ResumeLayout(); - } - - private void menuAddFiles_Click(object sender, EventArgs e) - { - if (openFileDialog.ShowDialog(ParentForm) != DialogResult.OK) - return; - - if (SelectedFolder == Root) - return; - - AddExistingFileAsync(openFileDialog.FileNames.Select(file => new FileInfo(file))); - } - - private void existingFolderToolStripMenuItem_Click(object sender, EventArgs e) - { - if (folderBrowserDialog.ShowDialog(ParentForm) != DialogResult.OK) - return; - - if (SelectedFolder == Root) - return; - - AddExistingFolderAsync(new DirectoryInfo(folderBrowserDialog.SelectedPath)); - } - - private AsyncTask AddExistingFolderAsync(DirectoryInfo dir) - { - ShowLoader(); - - AsyncTask task = AsyncTaskFactory.From(new Action(() => - { - this.InvokeOnUI(() => SuspendLayout()); - - AddExistingFolder(dir, SelectedFolder, true); - - this.InvokeOnUI(() => - { - Root.FolderTreeView.Expand(); - ResumeLayout(); - }); - }), null); - - task.TaskCompleted += (o, e) => { HideLoader(); }; - - return task.Start(); - } - - private void AddExistingFolder(DirectoryInfo dir, GenFolder parentFolder, bool addToUI = false) - { - GenFolder folder = new GenFolder(dir.Name, contextMenuRightClick); - - if (addToUI) - this.InvokeOnUI(() => lvFiles.Items.Add(folder.FolderListView)); - - foreach (DirectoryInfo subDir in dir.GetDirectories()) - AddExistingFolder(subDir, folder); - - foreach (FileInfo f in dir.GetFiles()) - AddExistingFile(f, folder); - - this.InvokeOnUI(() => parentFolder.Add(folder)); - } - - private AsyncTask AddExistingFileAsync(IEnumerable files) - { - return AsyncTaskFactory.StartNew(new Action(() => - { - GenFolder s = SelectedFolder; - - foreach (FileInfo file in files) - AddExistingFile(file, s, true); - - }), null); - } - - private void AddExistingFile(FileInfo f, GenFolder folder, bool addToUI = false) - { - GenFile file = new GenFile(f); - - EnsureExtensionIconExists(f); - - folder.Add(file); - - if (addToUI) - this.InvokeOnUI(() => lvFiles.Items.Add(file.View)); - - } - - private void EnsureExtensionIconExists(FileInfo file) - { - if (ilIcons.Images.ContainsKey(file.Extension)) - return; - - Icon extensionIcon = Icon.ExtractAssociatedIcon(file.FullName); - - this.InvokeOnUI(() => ilIcons.Images.Add(file.Extension, extensionIcon)); - } - - private void UpdateSelectedFolder(GenFolder folder) - { - if (folder == null || folder == SelectedFolder) - return; - - SelectedFolder = folder; - SelectedFile = null; - - if (SelectedFolder == Root) - { - deleteToolStripMenuItem.Enabled = false; - menuAddFiles.Enabled = false; - menuAddFolder.Enabled = false; - } - else - { - menuAddFiles.Enabled = true; - menuAddFolder.Enabled = true; - } - - lvFiles.SuspendLayout(); - - lvFiles.Items.Clear(); - - foreach (GenFolder subFolder in folder.Directories) - lvFiles.Items.Add(subFolder.FolderListView); - - foreach (GenFile subFile in folder.Items) - lvFiles.Items.Add(subFile.View); - - lvFiles.ResumeLayout(); - - tvFolders.SelectedNode = folder.FolderTreeView; - folder.FolderTreeView.Expand(); - } - - private void lvFiles_DoubleClick(object sender, EventArgs e) - { - if (lvFiles.SelectedItems.Count == 0) - return; - - ListViewFolder item = lvFiles.SelectedItems[0] as ListViewFolder; - if (item == null) - return; - - UpdateSelectedFolder(item?.Folder); - - } - - private void newFolderToolStripMenuItem_Click(object sender, EventArgs e) - { - if (SelectedFolder == null || SelectedFolder == Root) - return; - - InputDialog inputDlg = new InputDialog("New folder", "Please enter the folder name: ", MessageBoxButtons.OKCancel); - - if (inputDlg.ShowDialog(ParentForm) != DialogResult.OK && SelectedFolder != null) - return; - - var name = inputDlg.Input; - - GenFolder folder = new GenFolder(name, contextMenuRightClick); - - this.InvokeOnUI(() => - { - SelectedFolder.Add(folder); - lvFiles.Items.Add(folder.FolderListView); - }); - } - - private void lvFiles_SelectedIndexChanged(object sender, EventArgs e) - { - if (lvFiles.SelectedItems.Count == 0) - return; - - ListViewItem item = lvFiles.SelectedItems[0]; - - if (item == null) - return; - - if (item is ListViewGenItem) - SelectedFile = (item as ListViewGenItem).Item as GenFile; - else if (item is ListViewFolder) - SelectedFolder = (item as ListViewFolder).Folder; - } - - private void deleteToolStripMenuItem_Click(object sender, EventArgs e) - { - SuspendLayout(); - - deleteToolStripMenuItem.Enabled = false; - - if (SelectedFile != null) - { - SelectedFile.Parent.Remove(SelectedFile); - SelectedFile = null; - } - else if (SelectedFolder != null && SelectedFolder != Root && !SelectedFolder.ProtectedFolder) - { - SelectedFolder.ParentFolder.Remove(SelectedFolder); - - lvFiles.Items.Clear(); - - GenFolder temp = SelectedFolder; - - UpdateSelectedFolder(SelectedFolder.ParentFolder); - - temp = null; - } - ResumeLayout(); - } - - private void tvFolders_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) - { - TreeViewFolderNode node = e.Node as TreeViewFolderNode; - - if (node == null) - return; - - UpdateSelectedFolder(node?.Folder); - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/FilesPage.resx b/UpdateLib/UpdateLib.Generator/UI/Pages/FilesPage.resx deleted file mode 100644 index 11876ac..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/FilesPage.resx +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 103, 17 - - - 281, 17 - - - 444, 17 - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/InformationPage.Designer.cs b/UpdateLib/UpdateLib.Generator/UI/Pages/InformationPage.Designer.cs deleted file mode 100644 index 4b10891..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/InformationPage.Designer.cs +++ /dev/null @@ -1,113 +0,0 @@ -namespace MatthiWare.UpdateLib.Generator.UI.Pages -{ - partial class InformationPage - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.label1 = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.txtAppName = new System.Windows.Forms.TextBox(); - this.label3 = new System.Windows.Forms.Label(); - this.txtAppVersion = new System.Windows.Forms.TextBox(); - this.SuspendLayout(); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Century Gothic", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(14, 16); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(153, 20); - this.label1.TabIndex = 0; - this.label1.Text = "Update Information"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(15, 59); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(121, 17); - this.label2.TabIndex = 1; - this.label2.Text = "Application name: "; - // - // txtAppName - // - this.txtAppName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.txtAppName.Location = new System.Drawing.Point(160, 56); - this.txtAppName.Name = "txtAppName"; - this.txtAppName.Size = new System.Drawing.Size(212, 22); - this.txtAppName.TabIndex = 3; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(15, 97); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(130, 17); - this.label3.TabIndex = 4; - this.label3.Text = "Application version: "; - // - // txtAppVersion - // - this.txtAppVersion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.txtAppVersion.Location = new System.Drawing.Point(160, 94); - this.txtAppVersion.Name = "txtAppVersion"; - this.txtAppVersion.Size = new System.Drawing.Size(212, 22); - this.txtAppVersion.TabIndex = 5; - // - // InformationPage - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.Control; - this.Controls.Add(this.txtAppVersion); - this.Controls.Add(this.label3); - this.Controls.Add(this.txtAppName); - this.Controls.Add(this.label2); - this.Controls.Add(this.label1); - this.DoubleBuffered = true; - this.Font = new System.Drawing.Font("Century Gothic", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.MinimumSize = new System.Drawing.Size(396, 144); - this.Name = "InformationPage"; - this.Size = new System.Drawing.Size(396, 144); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.TextBox txtAppName; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.TextBox txtAppVersion; - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/InformationPage.cs b/UpdateLib/UpdateLib.Generator/UI/Pages/InformationPage.cs deleted file mode 100644 index 390ecfd..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/InformationPage.cs +++ /dev/null @@ -1,57 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -namespace MatthiWare.UpdateLib.Generator.UI.Pages -{ - public partial class InformationPage : PageControlBase - { - - public string ApplicationName - { - get - { - return txtAppName.Text; - } - set - { - txtAppName.Text = value; - } - } - - public string ApplicationVersion - { - get - { - return txtAppVersion.Text; - } - set - { - txtAppVersion.Text = value; - } - } - - public InformationPage() - { - InitializeComponent(); - } - - protected override void OnPageInitialize() - { - - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/InformationPage.resx b/UpdateLib/UpdateLib.Generator/UI/Pages/InformationPage.resx deleted file mode 100644 index 7080a7d..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/InformationPage.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/PageControlBase.cs b/UpdateLib/UpdateLib.Generator/UI/Pages/PageControlBase.cs deleted file mode 100644 index f39b9f4..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/PageControlBase.cs +++ /dev/null @@ -1,79 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Tasks; -using System; -using System.ComponentModel; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.Generator.UI.Pages -{ - public class PageControlBase : UserControl - { - internal TestForm TestForm { get; set; } - - public PageControlBase() - { - - } - - public void ShowLoader() - { - LoaderControl.Show(TestForm?.ContentPanel); - } - - public void HideLoader() - { - LoaderControl.Hide(TestForm?.ContentPanel); - } - - public bool IsPageInitialized { get; private set; } = false; - - private AsyncTask taskInitialize; - - public AsyncTask InitializePage(EventHandler callBack) - { - if (IsPageInitialized || (taskInitialize != null && taskInitialize.IsRunning)) - return taskInitialize; - - taskInitialize = AsyncTaskFactory.From(new Action(OnPageInitialize), null); - - taskInitialize.TaskCompleted += (o, e) => - { - IsPageInitialized = !e.Cancelled && e.Error == null; - - callBack?.Invoke(this, e); - }; - - return taskInitialize.Start(); - } - - protected virtual void OnPageInitialize() { } - - private void InitializeComponent() - { - this.SuspendLayout(); - // - // PageControlBase - // - this.DoubleBuffered = true; - this.Name = "PageControlBase"; - this.ResumeLayout(false); - - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/PageControlBase.resx b/UpdateLib/UpdateLib.Generator/UI/Pages/PageControlBase.resx deleted file mode 100644 index 7080a7d..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/PageControlBase.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/RegistryPage.Designer.cs b/UpdateLib/UpdateLib.Generator/UI/Pages/RegistryPage.Designer.cs deleted file mode 100644 index 33f3ba0..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/RegistryPage.Designer.cs +++ /dev/null @@ -1,255 +0,0 @@ -namespace MatthiWare.UpdateLib.Generator.UI.Pages -{ - partial class RegistryPage - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RegistryPage)); - this.label1 = new System.Windows.Forms.Label(); - this.tvFolders = new System.Windows.Forms.TreeView(); - this.ilIcons = new System.Windows.Forms.ImageList(this.components); - this.contextMenuRightClick = new System.Windows.Forms.ContextMenuStrip(this.components); - this.menuAddFiles = new System.Windows.Forms.ToolStripMenuItem(); - this.menuAddFolder = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.lvRegistry = new System.Windows.Forms.ListView(); - this.clmnName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnValue = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.stringValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.binaryValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.dWORDValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.qWORDValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.multiStringValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.expandableStringValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.contextMenuRightClick.SuspendLayout(); - this.SuspendLayout(); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Century Gothic", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(14, 16); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(65, 20); - this.label1.TabIndex = 1; - this.label1.Text = "Registry"; - // - // tvFolders - // - this.tvFolders.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); - this.tvFolders.ImageIndex = 0; - this.tvFolders.ImageList = this.ilIcons; - this.tvFolders.Location = new System.Drawing.Point(18, 53); - this.tvFolders.Name = "tvFolders"; - this.tvFolders.SelectedImageIndex = 0; - this.tvFolders.Size = new System.Drawing.Size(191, 332); - this.tvFolders.TabIndex = 2; - this.tvFolders.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.tvFolders_NodeMouseClick); - // - // ilIcons - // - this.ilIcons.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; - this.ilIcons.ImageSize = new System.Drawing.Size(16, 16); - this.ilIcons.TransparentColor = System.Drawing.Color.Transparent; - // - // contextMenuRightClick - // - this.contextMenuRightClick.Font = new System.Drawing.Font("Century Gothic", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.contextMenuRightClick.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.menuAddFiles, - this.menuAddFolder, - this.toolStripSeparator1, - this.deleteToolStripMenuItem}); - this.contextMenuRightClick.Name = "menuTV"; - this.contextMenuRightClick.Size = new System.Drawing.Size(153, 98); - // - // menuAddFiles - // - this.menuAddFiles.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.stringValueToolStripMenuItem, - this.binaryValueToolStripMenuItem, - this.dWORDValueToolStripMenuItem, - this.qWORDValueToolStripMenuItem, - this.multiStringValueToolStripMenuItem, - this.expandableStringValueToolStripMenuItem}); - this.menuAddFiles.Image = global::MatthiWare.UpdateLib.Generator.Properties.Resources.image_transparent_16px; - this.menuAddFiles.Name = "menuAddFiles"; - this.menuAddFiles.Size = new System.Drawing.Size(152, 22); - this.menuAddFiles.Text = "Add Value"; - // - // menuAddFolder - // - this.menuAddFolder.Image = global::MatthiWare.UpdateLib.Generator.Properties.Resources.folder_transparent_16px; - this.menuAddFolder.Name = "menuAddFolder"; - this.menuAddFolder.Size = new System.Drawing.Size(152, 22); - this.menuAddFolder.Text = "Add Key"; - this.menuAddFolder.Click += new System.EventHandler(this.menuAddFolder_Click); - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(149, 6); - // - // deleteToolStripMenuItem - // - this.deleteToolStripMenuItem.Enabled = false; - this.deleteToolStripMenuItem.Image = global::MatthiWare.UpdateLib.Generator.Properties.Resources.cross; - this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; - this.deleteToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.deleteToolStripMenuItem.Text = "Delete"; - this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click); - // - // lvRegistry - // - this.lvRegistry.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.lvRegistry.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.clmnName, - this.clmnType, - this.clmnValue}); - this.lvRegistry.ContextMenuStrip = this.contextMenuRightClick; - this.lvRegistry.FullRowSelect = true; - this.lvRegistry.Location = new System.Drawing.Point(215, 53); - this.lvRegistry.MultiSelect = false; - this.lvRegistry.Name = "lvRegistry"; - this.lvRegistry.Size = new System.Drawing.Size(577, 332); - this.lvRegistry.SmallImageList = this.ilIcons; - this.lvRegistry.TabIndex = 3; - this.lvRegistry.UseCompatibleStateImageBehavior = false; - this.lvRegistry.View = System.Windows.Forms.View.Details; - this.lvRegistry.SelectedIndexChanged += new System.EventHandler(this.lvFiles_SelectedIndexChanged); - this.lvRegistry.DoubleClick += new System.EventHandler(this.lvFiles_DoubleClick); - // - // clmnName - // - this.clmnName.Text = "Name"; - this.clmnName.Width = 150; - // - // clmnType - // - this.clmnType.Text = "Type"; - this.clmnType.Width = 93; - // - // clmnValue - // - this.clmnValue.Text = "Value"; - this.clmnValue.Width = 250; - // - // stringValueToolStripMenuItem - // - this.stringValueToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("stringValueToolStripMenuItem.Image"))); - this.stringValueToolStripMenuItem.Name = "stringValueToolStripMenuItem"; - this.stringValueToolStripMenuItem.Size = new System.Drawing.Size(221, 22); - this.stringValueToolStripMenuItem.Text = "String Value"; - this.stringValueToolStripMenuItem.Click += new System.EventHandler(this.stringValueToolStripMenuItem_Click); - // - // binaryValueToolStripMenuItem - // - this.binaryValueToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("binaryValueToolStripMenuItem.Image"))); - this.binaryValueToolStripMenuItem.Name = "binaryValueToolStripMenuItem"; - this.binaryValueToolStripMenuItem.Size = new System.Drawing.Size(221, 22); - this.binaryValueToolStripMenuItem.Text = "Binary Value"; - this.binaryValueToolStripMenuItem.Click += new System.EventHandler(this.binaryValueToolStripMenuItem_Click); - // - // dWORDValueToolStripMenuItem - // - this.dWORDValueToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("dWORDValueToolStripMenuItem.Image"))); - this.dWORDValueToolStripMenuItem.Name = "dWORDValueToolStripMenuItem"; - this.dWORDValueToolStripMenuItem.Size = new System.Drawing.Size(221, 22); - this.dWORDValueToolStripMenuItem.Text = "DWORD (32-bit) Value"; - this.dWORDValueToolStripMenuItem.Click += new System.EventHandler(this.dWORDValueToolStripMenuItem_Click); - // - // qWORDValueToolStripMenuItem - // - this.qWORDValueToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("qWORDValueToolStripMenuItem.Image"))); - this.qWORDValueToolStripMenuItem.Name = "qWORDValueToolStripMenuItem"; - this.qWORDValueToolStripMenuItem.Size = new System.Drawing.Size(221, 22); - this.qWORDValueToolStripMenuItem.Text = "QWORD (64-bit) Value"; - this.qWORDValueToolStripMenuItem.Click += new System.EventHandler(this.qWORDValueToolStripMenuItem_Click); - // - // multiStringValueToolStripMenuItem - // - this.multiStringValueToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("multiStringValueToolStripMenuItem.Image"))); - this.multiStringValueToolStripMenuItem.Name = "multiStringValueToolStripMenuItem"; - this.multiStringValueToolStripMenuItem.Size = new System.Drawing.Size(221, 22); - this.multiStringValueToolStripMenuItem.Text = "Multi String Value"; - this.multiStringValueToolStripMenuItem.Click += new System.EventHandler(this.multiStringValueToolStripMenuItem_Click); - // - // expandableStringValueToolStripMenuItem - // - this.expandableStringValueToolStripMenuItem.Image = global::MatthiWare.UpdateLib.Generator.Properties.Resources.reg_string_16px; - this.expandableStringValueToolStripMenuItem.Name = "expandableStringValueToolStripMenuItem"; - this.expandableStringValueToolStripMenuItem.Size = new System.Drawing.Size(221, 22); - this.expandableStringValueToolStripMenuItem.Text = "Expandable String Value"; - this.expandableStringValueToolStripMenuItem.Click += new System.EventHandler(this.expandableStringValueToolStripMenuItem_Click); - // - // RegistryPage - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.lvRegistry); - this.Controls.Add(this.tvFolders); - this.Controls.Add(this.label1); - this.DoubleBuffered = true; - this.Font = new System.Drawing.Font("Century Gothic", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.MinimumSize = new System.Drawing.Size(589, 233); - this.Name = "RegistryPage"; - this.Size = new System.Drawing.Size(810, 403); - this.contextMenuRightClick.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label label1; - private System.Windows.Forms.TreeView tvFolders; - private System.Windows.Forms.ListView lvRegistry; - private System.Windows.Forms.ColumnHeader clmnName; - private System.Windows.Forms.ColumnHeader clmnType; - private System.Windows.Forms.ColumnHeader clmnValue; - private System.Windows.Forms.ImageList ilIcons; - private System.Windows.Forms.ContextMenuStrip contextMenuRightClick; - private System.Windows.Forms.ToolStripMenuItem menuAddFiles; - private System.Windows.Forms.ToolStripMenuItem menuAddFolder; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem stringValueToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem binaryValueToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem dWORDValueToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem qWORDValueToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem multiStringValueToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem expandableStringValueToolStripMenuItem; - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/RegistryPage.cs b/UpdateLib/UpdateLib.Generator/UI/Pages/RegistryPage.cs deleted file mode 100644 index 8aae329..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/RegistryPage.cs +++ /dev/null @@ -1,256 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Collections.Generic; -using System.Windows.Forms; -using MatthiWare.UpdateLib.Generator.Data; -using MatthiWare.UpdateLib.UI; -using MatthiWare.UpdateLib.Generator.Data.FilesPage; -using Microsoft.Win32; - -namespace MatthiWare.UpdateLib.Generator.UI.Pages -{ - public partial class RegistryPage : PageControlBase - { - private const string PROJECT_IMAGE_KEY = "project_key"; - - private GenReg m_selectedRegEntry; - private GenReg SelectedRegEntry - { - get { return m_selectedRegEntry; } - set - { - m_selectedRegEntry = value; - if (value != null && !deleteToolStripMenuItem.Enabled) - deleteToolStripMenuItem.Enabled = true; - } - } - private GenFolder _selectedFolder; - private GenFolder SelectedFolder - { - get { return _selectedFolder; } - set - { - _selectedFolder = value; - if (value != null && !deleteToolStripMenuItem.Enabled) - deleteToolStripMenuItem.Enabled = true; - } - } - - public IList Folders { get; set; } - - public RegistryPage() - { - InitializeComponent(); - } - - protected override void OnPageInitialize() - { - SuspendLayout(); - - Folders = new List(); - - ilIcons.Images.Add("REG_BIN", Properties.Resources.reg_bin_16px); - ilIcons.Images.Add("REG_SZ", Properties.Resources.reg_string_16px); - ilIcons.Images.Add(TreeViewFolderNode.FOLDER_KEY, Properties.Resources.folder_transparent_16px); - - GenFolder hkey_classes_root = new GenFolder("HKEY_CLASSES_ROOT", contextMenuRightClick); - GenFolder hkey_current_user = new GenFolder("HKEY_CURRENT_USER", contextMenuRightClick); - GenFolder hkey_local_machine = new GenFolder("HKEY_LOCAL_MACHINE", contextMenuRightClick); - GenFolder hkey_users = new GenFolder("HKEY_USERS", contextMenuRightClick); - GenFolder hkey_current_config = new GenFolder("HKEY_CURRENT_CONFIG", contextMenuRightClick); - - tvFolders.Nodes.Add(hkey_classes_root.FolderTreeView); - tvFolders.Nodes.Add(hkey_current_user.FolderTreeView); - tvFolders.Nodes.Add(hkey_local_machine.FolderTreeView); - tvFolders.Nodes.Add(hkey_users.FolderTreeView); - tvFolders.Nodes.Add(hkey_current_config.FolderTreeView); - - Folders.Add(hkey_classes_root); - Folders.Add(hkey_current_user); - Folders.Add(hkey_local_machine); - Folders.Add(hkey_users); - Folders.Add(hkey_current_config); - - UpdateSelectedFolder(hkey_classes_root); - - ResumeLayout(); - } - - private void UpdateSelectedFolder(GenFolder folder) - { - if (folder == null || folder == SelectedFolder) - return; - - SelectedFolder = folder; - SelectedRegEntry = null; - - if (SelectedFolder.IsRoot) - deleteToolStripMenuItem.Enabled = false; - - lvRegistry.SuspendLayout(); - - lvRegistry.Items.Clear(); - - foreach (GenFolder subFolder in folder.Directories) - lvRegistry.Items.Add(subFolder.FolderListView); - - foreach (IGenItem subFile in folder.Items) - lvRegistry.Items.Add(subFile.View); - - lvRegistry.ResumeLayout(); - - tvFolders.SelectedNode = folder.FolderTreeView; - folder.FolderTreeView.Expand(); - } - - private void lvFiles_DoubleClick(object sender, EventArgs e) - { - if (lvRegistry.SelectedItems.Count == 0) - return; - - ListViewFolder item = lvRegistry.SelectedItems[0] as ListViewFolder; - if (item == null) - return; - - UpdateSelectedFolder(item?.Folder); - - } - - private void lvFiles_SelectedIndexChanged(object sender, EventArgs e) - { - if (lvRegistry.SelectedItems.Count == 0) - return; - - ListViewItem item = lvRegistry.SelectedItems[0]; - - if (item == null) - return; - - if (item is ListViewGenItem) - SelectedRegEntry = (item as ListViewGenItem).Item as GenReg; - else if (item is ListViewFolder) - SelectedFolder = (item as ListViewFolder).Folder; - } - - private void deleteToolStripMenuItem_Click(object sender, EventArgs e) - { - SuspendLayout(); - - deleteToolStripMenuItem.Enabled = false; - - if (SelectedRegEntry != null) - { - SelectedRegEntry.Parent.Remove(SelectedRegEntry); - lvRegistry.Items.Remove(SelectedRegEntry.View); - SelectedRegEntry = null; - } - else if (SelectedFolder != null && !SelectedFolder.IsRoot) - { - SelectedFolder.ParentFolder.Remove(SelectedFolder); - - lvRegistry.Items.Clear(); - - GenFolder temp = SelectedFolder; - - UpdateSelectedFolder(SelectedFolder.ParentFolder); - - temp = null; - } - - ResumeLayout(); - } - - private void tvFolders_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) - { - TreeViewFolderNode node = e.Node as TreeViewFolderNode; - - if (node == null) - return; - - UpdateSelectedFolder(node?.Folder); - } - - private void menuAddFolder_Click(object sender, EventArgs e) - { - if (SelectedFolder == null) - return; - - InputDialog inputDlg = new InputDialog("New folder", "Please enter the folder name: ", MessageBoxButtons.OKCancel); - - if (inputDlg.ShowDialog(ParentForm) != DialogResult.OK && SelectedFolder != null) - return; - - var name = inputDlg.Input; - - GenFolder folder = new GenFolder(name, contextMenuRightClick); - - this.InvokeOnUI(() => - { - SelectedFolder.Add(folder); - SelectedFolder.FolderTreeView.Expand(); - lvRegistry.Items.Add(folder.FolderListView); - }); - } - - private void stringValueToolStripMenuItem_Click(object sender, EventArgs e) - { - MakeNewEntry(RegistryValueKind.String); - } - - private void binaryValueToolStripMenuItem_Click(object sender, EventArgs e) - { - MakeNewEntry(RegistryValueKind.Binary); - } - - private void dWORDValueToolStripMenuItem_Click(object sender, EventArgs e) - { - MakeNewEntry(RegistryValueKind.DWord); - } - - private void qWORDValueToolStripMenuItem_Click(object sender, EventArgs e) - { - MakeNewEntry(RegistryValueKind.QWord); - } - - private void multiStringValueToolStripMenuItem_Click(object sender, EventArgs e) - { - MakeNewEntry(RegistryValueKind.MultiString); - } - - private void expandableStringValueToolStripMenuItem_Click(object sender, EventArgs e) - { - MakeNewEntry(RegistryValueKind.ExpandString); - } - - private void MakeNewEntry(RegistryValueKind type) - { - if (SelectedFolder == null) - return; - - GenReg item = new GenReg("New Item", type); - item.Value = "Test"; - - this.InvokeOnUI(() => - { - SelectedFolder.Add(item); - lvRegistry.Items.Add(item.View); - }); - } - } -} diff --git a/UpdateLib/UpdateLib.Generator/UI/Pages/RegistryPage.resx b/UpdateLib/UpdateLib.Generator/UI/Pages/RegistryPage.resx deleted file mode 100644 index a8e58e9..0000000 --- a/UpdateLib/UpdateLib.Generator/UI/Pages/RegistryPage.resx +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 103, 17 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - wwAADsMBx2+oZAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xNkRpr/UAAADHSURBVDhPnZNN - DoMgEIU5US/Tk7nkGp4FXPQSNi5q+VHKjH04jZKqL/kSeEw+NqCMMekMTdOkHAVU13VUHMowDKlt2x+J - stbS5nBIkKMgYcE8z1Ue9xuDkACQ5LQAefb9VoBhYq9DP00TUwQoAIZr6xiFwGRBjIHBwDq4dnKNi74C - Ux2srUMIzCLIjyMEXw4lez11oAi895cQAncJFmitEyCZc+4wLMhvogCRc2+GIi+QZ8RGQODHAdrLM5KM - 44vZFfwDkgWdPgHhXeaPOieBAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - wwAADsMBx2+oZAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xNkRpr/UAAADJSURBVDhPpZLL - DcIwDEAzEcswWY5Zo7OkObBEUQ+U/IkNTp2AIBWWnuRfn3uI0FrnI0gpcwlBCGMMNIZiXdc8TVMjEfM8 - QzEcICghSIKClBJyOl8qfY9yEBAgqYJ+8VseY8zXZflPAFQBNWiBL/Ga8hCYQBdBCP4QJH8JdB3sF9qc - 14D3HnkKyuPw3iH7wlheBc45hIajORNYZB+2Oa95DwVKqUyAzFo7DArgORIksvZe4Qf62ZsAgL/gH0Dd - z7bthnwU/KI9oPIDaOlC7DAsnWYAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - wwAADsMBx2+oZAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xNkRpr/UAAADJSURBVDhPpZLL - DcIwDEAzEcswWY5Zo7OkObBEUQ+U/IkNTp2AIBWWnuRfn3uI0FrnI0gpcwlBCGMMNIZiXdc8TVMjEfM8 - QzEcICghSIKClBJyOl8qfY9yEBAgqYJ+8VseY8zXZflPAFQBNWiBL/Ga8hCYQBdBCP4QJH8JdB3sF9qc - 14D3HnkKyuPw3iH7wlheBc45hIajORNYZB+2Oa95DwVKqUyAzFo7DArgORIksvZe4Qf62ZsAgL/gH0Dd - z7bthnwU/KI9oPIDaOlC7DAsnWYAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - wwAADsMBx2+oZAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xNkRpr/UAAADJSURBVDhPpZLL - DcIwDEAzEcswWY5Zo7OkObBEUQ+U/IkNTp2AIBWWnuRfn3uI0FrnI0gpcwlBCGMMNIZiXdc8TVMjEfM8 - QzEcICghSIKClBJyOl8qfY9yEBAgqYJ+8VseY8zXZflPAFQBNWiBL/Ga8hCYQBdBCP4QJH8JdB3sF9qc - 14D3HnkKyuPw3iH7wlheBc45hIajORNYZB+2Oa95DwVKqUyAzFo7DArgORIksvZe4Qf62ZsAgL/gH0Dd - z7bthnwU/KI9oPIDaOlC7DAsnWYAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - wwAADsMBx2+oZAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xNkRpr/UAAADHSURBVDhPnZNN - DoMgEIU5US/Tk7nkGp4FXPQSNi5q+VHKjH04jZKqL/kSeEw+NqCMMekMTdOkHAVU13VUHMowDKlt2x+J - stbS5nBIkKMgYcE8z1Ue9xuDkACQ5LQAefb9VoBhYq9DP00TUwQoAIZr6xiFwGRBjIHBwDq4dnKNi74C - Ux2srUMIzCLIjyMEXw4lez11oAi895cQAncJFmitEyCZc+4wLMhvogCRc2+GIi+QZ8RGQODHAdrLM5KM - 44vZFfwDkgWdPgHhXeaPOieBAAAAAElFTkSuQmCC - - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Generator/UpdateLib.Generator.csproj b/UpdateLib/UpdateLib.Generator/UpdateLib.Generator.csproj index 15f5262..ae5c30e 100644 --- a/UpdateLib/UpdateLib.Generator/UpdateLib.Generator.csproj +++ b/UpdateLib/UpdateLib.Generator/UpdateLib.Generator.csproj @@ -1,206 +1,15 @@ - - - + - Debug - AnyCPU - {5194FF71-49F6-4ADB-9B0E-4BEB418DC6F3} - WinExe - Properties + netcoreapp2.1 MatthiWare.UpdateLib.Generator - UpdateLib.Generator - v3.5 - 512 + Exe + false + 7.1 - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - Generator_logo.ico - - - MatthiWare.UpdateLib.Generator.Program - - - - - - - - - - - - - - - - - - - - - - - Form - - - MainForm.cs - - - - - - - Form - - - TestForm.cs - - - Component - - - Component - - - Component - - - Component - - - UserControl - - - LoaderControl.cs - - - Form - - - InputDialog.cs - - - Component - - - UserControl - - - BuilderPage.cs - - - UserControl - - - RegistryPage.cs - - - UserControl - - - FilesPage.cs - - - UserControl - - - InformationPage.cs - - - UserControl - - - MainForm.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - TestForm.cs - - - LoaderControl.cs - - - InputDialog.cs - - - BuilderPage.cs - - - RegistryPage.cs - - - FilesPage.cs - - - InformationPage.cs - - - PageControlBase.cs - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - {4394be57-95e2-45b1-a968-1404b0590b35} - UpdateLib - + - - - - - - - - - - - - + - - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Tests/Common/UpdateInfoTests.cs b/UpdateLib/UpdateLib.Tests/Common/UpdateInfoTests.cs new file mode 100644 index 0000000..afb8c9b --- /dev/null +++ b/UpdateLib/UpdateLib.Tests/Common/UpdateInfoTests.cs @@ -0,0 +1,35 @@ +using System; + +using MatthiWare.UpdateLib.Common; + +using NUnit.Framework; + +namespace UpdateLib.Tests.Common +{ + [TestFixture] + public class UpdateInfoTests + { + + [Test] + public void ConstructInvalidCatalogEntryThrowsCorrectExceotion() + { + Assert.Catch(() => new UpdateInfo(null, null, null, null)); + Assert.Catch(() => new UpdateInfo("1.0.0", "0.5.0", null, null)); + Assert.Catch(() => new UpdateInfo("1.0.0", "0.5.0", "test", null)); + + Assert.Catch(() => new UpdateInfo("1.0.0", "1.5.0", "test", null)); + } + + [Test] + public void TestIsPatchProperty() + { + var catalogEntry = new UpdateInfo("1.0", null, "test", "test"); + + Assert.IsFalse(catalogEntry.IsPatch); + + catalogEntry = new UpdateInfo("1.0", "0.9", "test", "test"); + + Assert.IsTrue(catalogEntry.IsPatch); + } + } +} diff --git a/UpdateLib/UpdateLib.Tests/Common/UpdateVersionTests.cs b/UpdateLib/UpdateLib.Tests/Common/UpdateVersionTests.cs new file mode 100644 index 0000000..7602633 --- /dev/null +++ b/UpdateLib/UpdateLib.Tests/Common/UpdateVersionTests.cs @@ -0,0 +1,110 @@ +using System; + +using MatthiWare.UpdateLib.Common; + +using NUnit.Framework; + +namespace UpdateLib.Tests.Common +{ + [TestFixture] + public class UpdateVersionTests + { + + [Test] + public void TestTryParseGood() + { + string input = "1.2.3-beta"; + + var v = new UpdateVersion(input); + + Assert.AreEqual(1, v.Major); + Assert.AreEqual(2, v.Minor); + Assert.AreEqual(3, v.Patch); + Assert.AreEqual(VersionLabel.Beta, v.Label); + } + + [Test] + public void TestTryParseGood2() + { + string input = "1.2"; + + var v = new UpdateVersion(input); + + Assert.AreEqual(1, v.Major); + Assert.AreEqual(2, v.Minor); + Assert.AreEqual(0, v.Patch); + Assert.AreEqual(VersionLabel.None, v.Label); + } + + [Test] + public void TestTryParseReturnsFalseInBadCase() + { + string input = "1.2.3.beta"; + + UpdateVersion v; + Assert.IsFalse(UpdateVersion.TryParse(input, out v)); + } + + [Test] + public void TestStringValue() + { + var v = new UpdateVersion(1, 2, 3, VersionLabel.RC); + + Assert.AreEqual("1.2.3-rc", v.Value); + + v.Value = "3.1.2"; + + Assert.AreEqual(3, v.Major); + Assert.AreEqual(1, v.Minor); + Assert.AreEqual(2, v.Patch); + Assert.AreEqual(VersionLabel.None, v.Label); + } + + [Test] + public void ConstructorThrowsException() + { + Assert.Catch(() => new UpdateVersion(-1)); + Assert.Catch(() => new UpdateVersion(1, -1)); + Assert.Catch(() => new UpdateVersion(1, 1, -1)); + Assert.Catch(() => new UpdateVersion("blabla")); + } + + [Test] + public void TestOperators() + { + UpdateVersion v1 = new UpdateVersion(1); + UpdateVersion v2 = new UpdateVersion(1); + UpdateVersion v3 = new UpdateVersion(1, 1); + UpdateVersion v4 = new UpdateVersion(1, 1, 1); + UpdateVersion v5 = new UpdateVersion(1, 1, 1, VersionLabel.Alpha); + UpdateVersion v6 = new UpdateVersion(1, 1, 1, VersionLabel.Beta); + UpdateVersion v7 = new UpdateVersion(1, 1, 1, VersionLabel.RC); + + Assert.IsTrue(v1 == v2, "v1 == v2"); + Assert.IsTrue(v1 != v3, "v1 != v3"); + + Assert.IsTrue(v3 > v1, "v3 > v1"); + Assert.IsFalse(v4 < v3, "v4 < v3"); + + Assert.IsTrue(v7 > v6, "v7 > v6"); + Assert.IsTrue(v6 > v5, "v6 > v5"); + } + + [Test] + public void TestConversion() + { + string input = "1.1.1-rc"; + + UpdateVersion v = input; + + Assert.AreEqual(1, v.Major); + Assert.AreEqual(1, v.Minor); + Assert.AreEqual(1, v.Patch); + Assert.AreEqual(VersionLabel.RC, v.Label); + + string output = v; + + Assert.AreEqual(input, output); + } + } +} diff --git a/UpdateLib/UpdateLib.Tests/Files/DirectoryEntryTest.cs b/UpdateLib/UpdateLib.Tests/Files/DirectoryEntryTest.cs index 146d7dc..792af2e 100644 --- a/UpdateLib/UpdateLib.Tests/Files/DirectoryEntryTest.cs +++ b/UpdateLib/UpdateLib.Tests/Files/DirectoryEntryTest.cs @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -using MatthiWare.UpdateLib.Files; +using MatthiWare.UpdateLib.Common; using NUnit.Framework; using System; using System.Linq; diff --git a/UpdateLib/UpdateLib.Tests/Files/FileEntryTest.cs b/UpdateLib/UpdateLib.Tests/Files/FileEntryTest.cs index 5fde225..7347289 100644 --- a/UpdateLib/UpdateLib.Tests/Files/FileEntryTest.cs +++ b/UpdateLib/UpdateLib.Tests/Files/FileEntryTest.cs @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -using MatthiWare.UpdateLib.Files; +using MatthiWare.UpdateLib.Common; using NUnit.Framework; namespace UpdateLib.Tests.Files diff --git a/UpdateLib/UpdateLib.Tests/Files/HashCacheEntryTest.cs b/UpdateLib/UpdateLib.Tests/Files/HashCacheEntryTest.cs index 2eae599..2fb8ef8 100644 --- a/UpdateLib/UpdateLib.Tests/Files/HashCacheEntryTest.cs +++ b/UpdateLib/UpdateLib.Tests/Files/HashCacheEntryTest.cs @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -using MatthiWare.UpdateLib.Files; +using MatthiWare.UpdateLib.Common; using NUnit.Framework; using System; using System.IO; diff --git a/UpdateLib/UpdateLib.Tests/Files/HashCacheFileTest.cs b/UpdateLib/UpdateLib.Tests/Files/HashCacheFileTest.cs index 8ce9748..4e76b66 100644 --- a/UpdateLib/UpdateLib.Tests/Files/HashCacheFileTest.cs +++ b/UpdateLib/UpdateLib.Tests/Files/HashCacheFileTest.cs @@ -1,5 +1,4 @@ -using MatthiWare.UpdateLib.Files; -/* UpdateLib - .Net auto update library +/* UpdateLib - .Net auto update library * Copyright (C) 2016 - MatthiWare (Matthias Beerens) * * This program is free software: you can redistribute it and/or modify @@ -16,12 +15,16 @@ * along with this program. If not, see . */ -using NUnit.Framework; using System; using System.IO; using System.Linq; using System.Text; +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Files; + +using NUnit.Framework; + namespace UpdateLib.Tests.Files { [TestFixture] @@ -35,25 +38,24 @@ public void Before() { var path = Path.GetTempPath(); - m_path = $@"{path}\{HashCacheFile.CACHE_FOLDER_NAME}_{Guid.NewGuid().ToString()}\{HashCacheFile.FILE_NAME}"; + m_path = $@"{path}\\Cache_{Guid.NewGuid().ToString()}\\{HashCacheFile.FILE_NAME}"; m_tempFile = Path.GetTempPath() + Guid.NewGuid().ToString() + "hash_cache_file_test.tmp"; - using (StreamWriter sw = new StreamWriter(File.Open(m_tempFile, FileMode.OpenOrCreate, FileAccess.Write), Encoding.Default)) - { + + using (var sw = new StreamWriter(File.Open(m_tempFile, FileMode.OpenOrCreate, FileAccess.Write), Encoding.Default)) sw.WriteLine("This is a test"); - } } [Test] public void TestLoadAndSaving() { - HashCacheFile file = new HashCacheFile(); + var file = new HashCacheFile(); file.Items.Add(new HashCacheEntry(m_tempFile)); file.Save(m_path); - HashCacheFile loadedFile = HashCacheFile.Load(m_path); + var loadedFile = FileManager.LoadFile(m_path); CheckEntries(file.Items.FirstOrDefault(), loadedFile.Items.FirstOrDefault()); } @@ -88,12 +90,8 @@ private void CheckEntries(HashCacheEntry expected, HashCacheEntry actual) private void EditFile() { - using (StreamWriter sw = new StreamWriter(File.Open(m_tempFile, FileMode.OpenOrCreate, FileAccess.Write), Encoding.Default)) - { + using (var sw = new StreamWriter(File.Open(m_tempFile, FileMode.OpenOrCreate, FileAccess.Write), Encoding.Default)) sw.WriteLine("edited"); - - sw.Flush(); - } } [TearDown] diff --git a/UpdateLib/UpdateLib.Tests/Files/PathVariableConverterTest.cs b/UpdateLib/UpdateLib.Tests/Files/PathVariableConverterTest.cs index 2956a7d..28677b2 100644 --- a/UpdateLib/UpdateLib.Tests/Files/PathVariableConverterTest.cs +++ b/UpdateLib/UpdateLib.Tests/Files/PathVariableConverterTest.cs @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -using MatthiWare.UpdateLib.Files; +using MatthiWare.UpdateLib.Common; using NUnit.Framework; using System; using System.IO; diff --git a/UpdateLib/UpdateLib.Tests/Files/UpdateCatalogFileTests.cs b/UpdateLib/UpdateLib.Tests/Files/UpdateCatalogFileTests.cs new file mode 100644 index 0000000..d17a773 --- /dev/null +++ b/UpdateLib/UpdateLib.Tests/Files/UpdateCatalogFileTests.cs @@ -0,0 +1,63 @@ +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Files; + +using NUnit.Framework; + +namespace UpdateLib.Tests.Files +{ + [TestFixture] + public class UpdateCatalogFileTests + { + + [Test] + public void TestTryGetLatestVersionGood() + { + var file = GenerateCatalogFile(); + + var latest = file.GetLatestUpdateForVersion("0.1"); + + Assert.IsNotNull(latest); + + Assert.AreEqual(latest.FileName, "version_1.0-full"); + } + + [Test] + public void TestTryGetLatestVersionGood2() + { + var file = GenerateCatalogFile(); + + var latest = file.GetLatestUpdateForVersion("0.4"); + + Assert.IsNotNull(latest); + + Assert.AreEqual(latest.FileName, "version_0.4-1.0"); + } + + [Test] + public void TestTryGetLatestVersionEmptryFileReturnsFalse() + { + var file = GenerateCatalogFile(true); + + Assert.IsNull(file.GetLatestUpdateForVersion("0.1")); + } + + + private UpdateCatalogFile GenerateCatalogFile(bool empty = false) + { + UpdateCatalogFile file = new UpdateCatalogFile(); + + if (!empty) + { + file.Catalog.Add(new UpdateInfo("1.0", "0.4", "version_0.4-1.0", "0x0")); + file.Catalog.Add(new UpdateInfo("0.7", "0.1", "version_0.1-0.7", "0x0")); + file.Catalog.Add(new UpdateInfo("0.8", "0.7", "version_0.7-0.8", "0x0")); + file.Catalog.Add(new UpdateInfo("0.9", "0.8", "version_0.8-0.9", "0x0")); + file.Catalog.Add(new UpdateInfo("1.0", null, "version_1.0-full", "0x0")); + file.Catalog.Add(new UpdateInfo("1.0", "0.5", "version_0.5-1.0", "0x0")); + + } + + return file; + } + } +} diff --git a/UpdateLib/UpdateLib.Tests/Files/UpdateFileTest.cs b/UpdateLib/UpdateLib.Tests/Files/UpdateFileTest.cs index 038fa91..3d47991 100644 --- a/UpdateLib/UpdateLib.Tests/Files/UpdateFileTest.cs +++ b/UpdateLib/UpdateLib.Tests/Files/UpdateFileTest.cs @@ -1,7 +1,4 @@ -using MatthiWare.UpdateLib.Files; -using Moq; -using NUnit.Framework; -/* UpdateLib - .Net auto update library +/* UpdateLib - .Net auto update library * Copyright (C) 2016 - MatthiWare (Matthias Beerens) * * This program is free software: you can redistribute it and/or modify @@ -21,6 +18,14 @@ using System; using System.IO; +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Common.Abstraction; +using MatthiWare.UpdateLib.Files; + +using Moq; + +using NUnit.Framework; + namespace UpdateLib.Tests.Files { [TestFixture] @@ -36,14 +41,14 @@ public void Before() [Test] public void SaveAndLoadUpdateFileShouldBeTheSame() { - UpdateFile file = MakeUpdateFile(); + var file = MakeUpdateFile(); file.Save(temp_file); - UpdateFile loadedFile = UpdateFile.Load(temp_file); + var updateFile = FileManager.LoadFile(temp_file); - Assert.AreEqual(file.ApplicationName, loadedFile.ApplicationName); - Assert.AreEqual(file.VersionString, loadedFile.VersionString); - Assert.AreEqual(file.FileCount, loadedFile.FileCount); + ////Assert.AreEqual(file.ApplicationName, updateFile.ApplicationName); + //Assert.AreEqual(file.Version, updateFile.Version); + //Assert.AreEqual(file.FileCount, updateFile.FileCount); } [Test] @@ -51,7 +56,7 @@ public void SaveInvalidParamterShouldThrowExceptions() { Stream nullStream = null; - UpdateFile file = new UpdateFile(); + var file = new UpdateMetadataFile(); Assert.Catch(() => { file.Save(nullStream); }); Assert.Catch(() => { file.Save(string.Empty); }); @@ -67,25 +72,24 @@ public void LoadInvalidParameterShouldThrowExceptions() { Stream nullStream = null; - Assert.Catch(() => { UpdateFile.Load(nullStream); }); - Assert.Catch(() => { UpdateFile.Load(string.Empty); }); + Assert.Catch(() => { FileManager.LoadFile(nullStream); }); + Assert.Catch(() => { FileManager.LoadFile(string.Empty); }); CleanUp(); - Assert.Catch(() => { UpdateFile.Load(temp_file); }); + Assert.Catch(() => { FileManager.LoadFile(temp_file); }); Mock unreadableStream = new Mock(); unreadableStream.SetupGet(s => s.CanRead).Returns(false); - Assert.Catch(() => { UpdateFile.Load(unreadableStream.Object); }); + Assert.Catch(() => { FileManager.LoadFile(unreadableStream.Object); }); } - private UpdateFile MakeUpdateFile() + private UpdateMetadataFile MakeUpdateFile() { - UpdateFile file = new UpdateFile(); + var file = new UpdateMetadataFile(); - file.ApplicationName = nameof(UpdateFileTest); - file.VersionString = "9.9.9.9"; + var info = new UpdateMetadataFile { }; DirectoryEntry appSubFolder = new DirectoryEntry("AppSubFolder"); DirectoryEntry otherSubFolder = new DirectoryEntry("OtherSubFolder"); @@ -107,19 +111,10 @@ private UpdateFile MakeUpdateFile() appSubFolder.Add(appFile); otherSubFolder.Add(otherFile); - file.Folders.Add(appSubFolder); - file.Folders.Add(otherSubFolder); - - DirectoryEntry regDir = new DirectoryEntry("HKEY_LOCAL_MACHINE"); - - EntryBase regEntry = new RegistryKeyEntry("test", Microsoft.Win32.RegistryValueKind.String, null); - - regDir.Add(regEntry); - - file.Registry.Add(regDir); + info.Folders.Add(appSubFolder); + info.Folders.Add(otherSubFolder); - Assert.AreEqual(2, file.FileCount); - Assert.AreEqual(1, file.RegistryKeyCount); + Assert.AreEqual(2, info.FileCount); return file; } diff --git a/UpdateLib/UpdateLib.Tests/Logging/LoggingTests.cs b/UpdateLib/UpdateLib.Tests/Logging/LoggingTests.cs deleted file mode 100644 index 377e853..0000000 --- a/UpdateLib/UpdateLib.Tests/Logging/LoggingTests.cs +++ /dev/null @@ -1,108 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Logging; -using NUnit.Framework; -using Moq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using MatthiWare.UpdateLib.Logging.Writers; -using MatthiWare.UpdateLib.Common; - -namespace UpdateLib.Tests.Logging -{ - [TestFixture] - public class LoggingTests - { - private Logger logger; - - [SetUp] - public void Setup() - { - logger = new Logger(); - } - - [Test] - public void ErrorLogLevelShouldNotLogWhenDebugLog() - { - logger.LogLevel = LoggingLevel.Error; - Mock writer = SetUpWriter(LoggingLevel.Debug); - - logger.Writers.Add(writer.Object); - - logger.Debug(nameof(LoggingTests), nameof(ErrorLogLevelShouldNotLogWhenDebugLog), "This is my log msg"); - - writer.Verify(mock => mock.Log(It.IsAny()), Times.Never); - } - - [Test] - public void DebugLogLevelShouldLogErrorLog() - { - logger.LogLevel = LoggingLevel.Debug; - Mock writer = SetUpWriter(LoggingLevel.Error); - - logger.Writers.Add(writer.Object); - - logger.Error(nameof(LoggingTests), nameof(DebugLogLevelShouldLogErrorLog), "This is my log msg"); - - writer.Verify(mock => mock.Log(It.IsAny()), Times.Once); - } - - [Test] - public void ErrorLogLevelShouldNotLogAnyLowerLevel() - { - logger.LogLevel = LoggingLevel.Error; - - Mock info = SetUpWriter(LoggingLevel.Info); - - Mock warn = SetUpWriter(LoggingLevel.Warn); - - Mock debug = SetUpWriter(LoggingLevel.Debug); - - logger.Writers.Add(info.Object); - logger.Writers.Add(warn.Object); - logger.Writers.Add(debug.Object); - - logger.Error(string.Empty, string.Empty, string.Empty); - logger.Warn(string.Empty, string.Empty, string.Empty); - logger.Info(string.Empty, string.Empty, string.Empty); - logger.Debug(string.Empty, string.Empty, string.Empty); - - info.Verify(mock => mock.Log(It.IsAny()), Times.Never); - warn.Verify(mock => mock.Log(It.IsAny()), Times.Never); - debug.Verify(mock => mock.Log(It.IsAny()), Times.Never); - } - - private Mock SetUpWriter(LoggingLevel level) - { - Mock writer = new Mock(); - writer.SetupGet(w => w.LoggingLevel).Returns(level); - - return writer; - } - - [TearDown] - public void CleanUp() - { - logger.Writers.Clear(); - } - - } -} diff --git a/UpdateLib/UpdateLib.Tests/Properties/AssemblyInfo.cs b/UpdateLib/UpdateLib.Tests/Properties/AssemblyInfo.cs index 412603d..3388a78 100644 --- a/UpdateLib/UpdateLib.Tests/Properties/AssemblyInfo.cs +++ b/UpdateLib/UpdateLib.Tests/Properties/AssemblyInfo.cs @@ -1,36 +1,7 @@ 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("UpdateLib.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("UpdateLib.Tests")] -[assembly: AssemblyCopyright("Copyright © 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("c47b8cc3-abab-4f56-8ca2-1323f902d1c3")] - -// 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 Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyDescription("Unit Tests For UpdateLib")] diff --git a/UpdateLib/UpdateLib.Tests/Tasks/AsyncTaskTest.cs b/UpdateLib/UpdateLib.Tests/Tasks/AsyncTaskTest.cs deleted file mode 100644 index 1e32116..0000000 --- a/UpdateLib/UpdateLib.Tests/Tasks/AsyncTaskTest.cs +++ /dev/null @@ -1,209 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Tasks; -using NUnit.Framework; -using System; -using System.Threading; -using System.Runtime.Serialization; - -namespace UpdateLib.Tests.Tasks -{ - [TestFixture] - public class AsyncTaskTest - { - - [Test, Parallelizable] - public void CancelledTaskIsCancelled() - { - TestTask task = new TestTask(1000); - task.TaskCompleted += (o, e) => - { - Assert.True(e.Cancelled, "The task did not cancel!"); - }; - task.Start(); - task.Cancel(); - task.AwaitTask(); - - Assert.True(task.IsCancelled, "Task did not cancel"); - } - - [Test, Parallelizable] - public void FaultyTaskReturnsException() - { - ErrorTask task = new ErrorTask(); - //ManualResetEvent wait = new ManualResetEvent(false); - - task.TaskCompleted += (o, e) => - { - Assert.False(e.Cancelled, "The task got cancelled"); - Assert.NotNull(e.Error, "The error object is null"); - Assert.IsInstanceOf(e.Error, $"{e.Error} is not an instance of {nameof(AsyncTaskTestException)}"); - // wait.Set(); - }; - task.Start(); - task.AwaitTask(); - //wait.WaitOne(); - } - - [Test, Parallelizable] - public void TestMethod() - { - object o = new object(); - ResultTask task = new ResultTask(o); - task.Start(); - Assert.AreEqual(o, task.AwaitTask().Result); - } - - [Test, Parallelizable] - public void TestResultReturnsCorrectObject() - { - TestResultTask(false); - TestResultTask(19951); - TestResultTask(new object()); - } - - private void TestResultTask(T input) - { - ResultTask task = new ResultTask(input); - task.TaskCompleted += (o, e) => - { - Assert.False(e.Cancelled, "Task got cancelled"); - Assert.IsNull(e.Error, "There was an error"); - - Assert.AreEqual(input, task.Result); - }; - task.Start(); - - Assert.AreEqual(input, task.AwaitTask().Result); - } - - [Test, Parallelizable] - public void CheckDoubleWait() - { - TestTask task = new TestTask(100); - task.Start(); - task.AwaitTask(); - task.AwaitTask(); - } - - [Test, Parallelizable] - public void TestAwaitWorker() - { - WorkerTestTask task = new WorkerTestTask(); - task.TaskCompleted += (o, e) => - { - Assert.IsFalse(e.Cancelled, "The task got cancelled??"); - Assert.IsNull(e.Error, "there was an error"); - }; - task.Start(); - task.AwaitTask(); - } - - private class WorkerTestTask : AsyncTask - { - protected override void DoWork() - { - bool value = false; - - Action simulation = new Action(() => - { - Thread.Sleep(1000); - value = true; - }); - - Assert.IsFalse(value); - - Enqueue(simulation); - - AwaitWorkers(); - - Assert.IsTrue(value); - } - } - - private class TestTask : AsyncTask - { - public int Sleep { get; set; } - public TestTask(int sleep) - { - Sleep = sleep; - } - - protected override void DoWork() - { - Thread.Sleep(Sleep); - } - } - - private class ErrorTask : AsyncTask - { - protected override void DoWork() - { - Action a = new Action(() => { Thread.Sleep(1000); throw new AsyncTaskTestException(); }); - - Enqueue(a); - - //throw new InvalidOperationException(); - - AwaitWorkers(); - } - } - - private class ResultTask : AsyncTask - { - private T returnObj; - - public ResultTask(T returnObj) - { - this.returnObj = returnObj; - } - - protected override void DoWork() - { - Action call = new Action((x) => - { - Thread.Sleep(x); - Result = returnObj; - }); - - Enqueue(call, 50); - } - } - - private class AsyncTaskTestException : Exception - { - public AsyncTaskTestException() : base("Test Exception") - { - } - - public AsyncTaskTestException(string message) : base(message) - { - } - - public AsyncTaskTestException(string message, Exception innerException) : base(message, innerException) - { - } - - protected AsyncTaskTestException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - } - } - - -} diff --git a/UpdateLib/UpdateLib.Tests/Tasks/CleanUpTaskTest.cs b/UpdateLib/UpdateLib.Tests/Tasks/CleanUpTaskTest.cs deleted file mode 100644 index 5cb0d5f..0000000 --- a/UpdateLib/UpdateLib.Tests/Tasks/CleanUpTaskTest.cs +++ /dev/null @@ -1,64 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Tasks; -using NUnit.Framework; -using System; -using System.IO; - -namespace UpdateLib.Tests.Tasks -{ - [TestFixture] - public class CleanUpTaskTest - { - - private string m_folder, m_file; - - [SetUp] - public void Before() - { - m_folder = $"{Path.GetTempPath()}test_{Guid.NewGuid().ToString()}"; - m_file = $"{m_folder}\\test.old.tmp"; - - if (!Directory.Exists(m_folder)) - Directory.CreateDirectory(m_folder); - - if (!File.Exists(m_file)) - File.Open(m_file, FileMode.OpenOrCreate).Dispose(); - } - - [Test] - public void TestCleanUp() - { - Assert.IsTrue(File.Exists(m_file)); - - CleanUpTask task = new CleanUpTask(m_folder); - task.ConfigureAwait(false); - task.Start().AwaitTask(); - - Assert.IsFalse(File.Exists(m_file)); - } - - [TearDown] - public void CleanUp() - { - if (Directory.Exists(m_folder)) - Directory.Delete(m_folder); - } - - } -} diff --git a/UpdateLib/UpdateLib.Tests/Tasks/DownloadManagerTests.cs b/UpdateLib/UpdateLib.Tests/Tasks/DownloadManagerTests.cs deleted file mode 100644 index 22f45d2..0000000 --- a/UpdateLib/UpdateLib.Tests/Tasks/DownloadManagerTests.cs +++ /dev/null @@ -1,91 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib; -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Security; -using MatthiWare.UpdateLib.Tasks; -using NUnit.Framework; -using System; -using System.IO; -using System.Threading; - -namespace UpdateLib.Tests.Tasks -{ - [TestFixture] - public class DownloadManagerTests - { - - private string m_path, m_file; - - [SetUp] - public void Before() - { - m_path = string.Concat(Path.GetTempPath(), Guid.NewGuid().ToString(), "\\updater"); - - m_file = string.Concat(m_path, "\\testfile.txt").Replace("//", "\\"); - - if (!Directory.Exists(m_path)) - Directory.CreateDirectory(m_path); - - using (StreamWriter sw = new StreamWriter(File.Open(m_file, FileMode.OpenOrCreate, FileAccess.Write))) - { - sw.Write("test"); - } - - Updater.Instance.ConfigurePathConverter(c => c["appdir"] = $@"{Path.GetTempPath()}dl_test"); - Updater.Instance.ConfigureUpdateUrl(m_path + "\\update.xml"); - - Updater.Instance.Initialize(); - } - - [Test] - public void TestDownloadManager() - { - - - UpdateFile file = new UpdateFile(); - - DirectoryEntry dir = new DirectoryEntry("%appdir%"); - FileEntry entry_file = new FileEntry("testfile.txt"); - entry_file.Hash = HashUtil.GetHash(m_file); - dir.Add(entry_file); - - file.Folders.Add(dir); - - ManualResetEvent wait = new ManualResetEvent(false); - DownloadManager manager = new DownloadManager(file); - manager.Completed += (o, e) => wait.Set(); - manager.Update(); - - Assert.IsTrue(wait.WaitOne(TimeSpan.FromSeconds(20)), "The async download timed-out after 10 seconds"); - - string localFile = Updater.Instance.Converter.Convert("%appdir%/testfile.txt"); - Assert.IsTrue(File.Exists(localFile), "File didn't exist"); - - using (StreamReader sr = new StreamReader(File.Open(localFile, FileMode.Open, FileAccess.Read))) - { - var data = sr.ReadToEnd(); - - Assert.AreEqual("test", data); - } - - } - - - } -} diff --git a/UpdateLib/UpdateLib.Tests/Tasks/DownloadTaskTest.cs b/UpdateLib/UpdateLib.Tests/Tasks/DownloadTaskTest.cs deleted file mode 100644 index a6ef8b3..0000000 --- a/UpdateLib/UpdateLib.Tests/Tasks/DownloadTaskTest.cs +++ /dev/null @@ -1,61 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib; -using MatthiWare.UpdateLib.Common; -using MatthiWare.UpdateLib.Files; -using System.IO; - -namespace UpdateLib.Tests.Tasks -{ - //[TestFixture] - public class DownloadTaskTest - { - - // [OneTimeSetUp] - public void Before() - { - var path = new DirectoryInfo(".").FullName; - - Updater.Instance - .ConfigureUpdateUrl($@"file:///{path}") - .ConfigureInstallationMode(InstallationMode.Local) - .ConfigureUnsafeConnections(true) - .Initialize(); - } - - // [Test] - public void TestDownload() - { - FileEntry fe = MakeFileEntry(); - - var s = fe.DestinationLocation; - } - - private FileEntry MakeFileEntry() - { - DirectoryEntry appDir = new DirectoryEntry("%appdir%"); - FileEntry file = new FileEntry("testFile"); - - - appDir.Add(file); - - return file; - } - - } -} diff --git a/UpdateLib/UpdateLib.Tests/UI/WizardPageCollectionTest.cs b/UpdateLib/UpdateLib.Tests/UI/WizardPageCollectionTest.cs deleted file mode 100644 index ae4c37f..0000000 --- a/UpdateLib/UpdateLib.Tests/UI/WizardPageCollectionTest.cs +++ /dev/null @@ -1,268 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using NUnit.Framework; -using MatthiWare.UpdateLib.UI; -using Moq; -using System.Windows.Forms; - -namespace UpdateLib.Tests.UI -{ - [TestFixture] - public class WizardPageCollectionTest - { - private WizardPageCollection wizard; - - [SetUp] - public void Before() - { - wizard = new WizardPageCollection(); - } - - [Test] - public void CorrectPageCount() - { - Mock page1 = new Mock(); - page1.SetupGet(p => p.IsBusy).Returns(false); - page1.SetupGet(p => p.IsDone).Returns(true); - page1.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page2 = new Mock(); - page2.SetupGet(p => p.IsBusy).Returns(false); - page2.SetupGet(p => p.IsDone).Returns(true); - page2.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page3 = new Mock(); - page3.SetupGet(p => p.IsBusy).Returns(false); - page3.SetupGet(p => p.IsDone).Returns(true); - page3.SetupGet(p => p.Conent).Returns(new UserControl()); - - wizard.Add(page1.Object); - wizard.Add(page2.Object); - wizard.Add(page3.Object); - - - Assert.AreEqual(3, wizard.Count); - } - - [Test] - public void CorrectFirstPageAndLastPage() - { - Mock page1 = new Mock(); - page1.SetupGet(p => p.IsBusy).Returns(false); - page1.SetupGet(p => p.IsDone).Returns(true); - page1.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page2 = new Mock(); - page2.SetupGet(p => p.IsBusy).Returns(false); - page2.SetupGet(p => p.IsDone).Returns(true); - page2.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page3 = new Mock(); - page3.SetupGet(p => p.IsBusy).Returns(false); - page3.SetupGet(p => p.IsDone).Returns(true); - page3.SetupGet(p => p.Conent).Returns(new UserControl()); - - wizard.Add(page1.Object); - wizard.Add(page2.Object); - wizard.Add(page3.Object); - - Assert.AreEqual(page1.Object, wizard.FirstPage); - Assert.AreEqual(page3.Object, wizard.LastPage); - } - - [Test] - public void AddNullPageShouldThrowArgumentNullException() - { - Assert.Throws(() => { wizard.Add(null); }); - } - - [Test] - public void ClearingTheWizardShouldReturnCountOfZero() - { - Mock page1 = new Mock(); - page1.SetupGet(p => p.IsBusy).Returns(false); - page1.SetupGet(p => p.IsDone).Returns(true); - page1.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page2 = new Mock(); - page2.SetupGet(p => p.IsBusy).Returns(false); - page2.SetupGet(p => p.IsDone).Returns(true); - page2.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page3 = new Mock(); - page3.SetupGet(p => p.IsBusy).Returns(false); - page3.SetupGet(p => p.IsDone).Returns(true); - page3.SetupGet(p => p.Conent).Returns(new UserControl()); - - wizard.Add(page1.Object); - wizard.Add(page2.Object); - wizard.Add(page3.Object); - - wizard.Clear(); - - Assert.AreEqual(0, wizard.Count); - } - - [Test] - public void NextShouldReturnTheCorrectPage() - { - Mock page1 = new Mock(); - page1.SetupGet(p => p.IsBusy).Returns(false); - page1.SetupGet(p => p.IsDone).Returns(true); - page1.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page2 = new Mock(); - page2.SetupGet(p => p.IsBusy).Returns(false); - page2.SetupGet(p => p.IsDone).Returns(true); - page2.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page3 = new Mock(); - page3.SetupGet(p => p.IsBusy).Returns(false); - page3.SetupGet(p => p.IsDone).Returns(true); - page3.SetupGet(p => p.Conent).Returns(new UserControl()); - - wizard.Add(page1.Object); - wizard.Add(page2.Object); - wizard.Add(page3.Object); - - Assert.AreEqual(wizard.FirstPage, wizard.CurrentPage); - - IWizardPage page = wizard.Next(); - - Assert.AreEqual(page2.Object, page); - - page = wizard.Next(); - - Assert.AreEqual(page3.Object, page); - Assert.AreEqual(wizard.LastPage, page); - - page = wizard.Next(); - - Assert.AreEqual(null, page); - - } - - [Test] - public void PreviousShouldReturnTheCorrectPage() - { - Mock page1 = new Mock(); - page1.SetupGet(p => p.IsBusy).Returns(false); - page1.SetupGet(p => p.IsDone).Returns(true); - page1.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page2 = new Mock(); - page2.SetupGet(p => p.IsBusy).Returns(false); - page2.SetupGet(p => p.IsDone).Returns(true); - page2.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page3 = new Mock(); - page3.SetupGet(p => p.IsBusy).Returns(false); - page3.SetupGet(p => p.IsDone).Returns(true); - page3.SetupGet(p => p.Conent).Returns(new UserControl()); - - wizard.Add(page1.Object); - wizard.Add(page2.Object); - wizard.Add(page3.Object); - - IWizardPage page = wizard.Next(); - page = wizard.Next(); - - Assert.AreEqual(page3.Object, page); - - page = wizard.Previous(); - Assert.AreEqual(page2.Object, page); - - page = wizard.Previous(); - Assert.AreEqual(page1.Object, page); - - page = wizard.Previous(); - Assert.AreEqual(null, page); - } - - [Test] - public void AllDoneShouldReturnTrueWhenAllPagesAreDone() - { - Mock page1 = new Mock(); - page1.SetupGet(p => p.IsDone).Returns(true); - page1.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page2 = new Mock(); - page2.SetupGet(p => p.IsDone).Returns(true); - page2.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page3 = new Mock(); - page3.SetupGet(p => p.IsDone).Returns(true); - page3.SetupGet(p => p.Conent).Returns(new UserControl()); - - wizard.Add(page1.Object); - wizard.Add(page2.Object); - wizard.Add(page3.Object); - - Assert.IsTrue(wizard.AllDone()); - } - - [Test] - public void AllDoneShouldReturnFalseWhenSomePagesAreNotDone() - { - Mock page1 = new Mock(); - page1.SetupGet(p => p.IsDone).Returns(true); - page1.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page2 = new Mock(); - page2.SetupGet(p => p.IsDone).Returns(false); - page2.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page3 = new Mock(); - page3.SetupGet(p => p.IsDone).Returns(true); - page3.SetupGet(p => p.Conent).Returns(new UserControl()); - - wizard.Add(page1.Object); - wizard.Add(page2.Object); - wizard.Add(page3.Object); - - Assert.IsFalse(wizard.AllDone()); - } - - - [Test] - public void CheckIfWizardContainsPage() - { - Mock page1 = new Mock(); - page1.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page2 = new Mock(); - page2.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock page3 = new Mock(); - page3.SetupGet(p => p.Conent).Returns(new UserControl()); - - Mock pageNotAdded = new Mock(); - - wizard.Add(page1.Object); - wizard.Add(page2.Object); - wizard.Add(page3.Object); - - Assert.IsTrue(wizard.Contains(page1.Object)); - Assert.IsTrue(wizard.Contains(page2.Object)); - Assert.IsTrue(wizard.Contains(page3.Object)); - Assert.IsFalse(wizard.Contains(pageNotAdded.Object)); - } - - } -} diff --git a/UpdateLib/UpdateLib.Tests/UpdateLib.Tests.csproj b/UpdateLib/UpdateLib.Tests/UpdateLib.Tests.csproj index f1fd1b1..05c2eb5 100644 --- a/UpdateLib/UpdateLib.Tests/UpdateLib.Tests.csproj +++ b/UpdateLib/UpdateLib.Tests/UpdateLib.Tests.csproj @@ -1,101 +1,27 @@ - - - + - Debug - AnyCPU - {C47B8CC3-ABAB-4F56-8CA2-1323F902D1C3} - Library - Properties - UpdateLib.Tests - UpdateLib.Tests - v4.5 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false + netcoreapp2.1 + false - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false + + {C47B8CC3-ABAB-4F56-8CA2-1323F902D1C3} + 7.1 - - ..\packages\Castle.Core.4.0.0\lib\net45\Castle.Core.dll - True - - - ..\packages\Moq.4.7.1\lib\net45\Moq.dll - True - - - ..\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + + + + + - - {4394be57-95e2-45b1-a968-1404b0590b35} - UpdateLib - + - + - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Tests/UpdaterTest.cs b/UpdateLib/UpdateLib.Tests/UpdaterTest.cs index c402ffd..ae5d383 100644 --- a/UpdateLib/UpdateLib.Tests/UpdaterTest.cs +++ b/UpdateLib/UpdateLib.Tests/UpdaterTest.cs @@ -16,7 +16,6 @@ */ using MatthiWare.UpdateLib; -using MatthiWare.UpdateLib.Tasks; using NUnit.Framework; using System; using System.Linq; @@ -29,40 +28,13 @@ public class UpdaterTest [Test] public void EnsureMultithreadedAccessWorks() { - int samples = 10; - - AsyncTask[] tasks = new AsyncTask[samples]; - Updater[] updaters = new Updater[samples]; - - Func getUpdaterAction = new Func(() => Updater.Instance); - - for (int i = 0; i < samples; i++) - tasks[i] = AsyncTaskFactory.StartNew(getUpdaterAction, null); - - AsyncTask.WaitAll(tasks); - - for (int i = 0; i < samples; i++) - updaters[i] = tasks[i].Result; - - int amountOfDistinctUpdaters = updaters.Distinct().Count(); - - Assert.AreEqual(1, amountOfDistinctUpdaters); + } [Test] public void TestInitializationActuallyInitializes() { - Updater u = Updater.Instance; - - u.Initialize(); - - Assert.IsTrue(u.IsInitialized); - - AsyncTask task = u.CleanUpTask.AwaitTask(); - AsyncTask task2 = u.UpdateCacheTask.AwaitTask(); - - Assert.IsTrue(task.IsRunning || task.IsCompleted); - Assert.IsTrue(task2.IsRunning || task2.IsCompleted); + } } } diff --git a/UpdateLib/UpdateLib.Tests/Util/CmdLineParserTest.cs b/UpdateLib/UpdateLib.Tests/Util/CmdLineParserTest.cs index 5837a50..60ab3d5 100644 --- a/UpdateLib/UpdateLib.Tests/Util/CmdLineParserTest.cs +++ b/UpdateLib/UpdateLib.Tests/Util/CmdLineParserTest.cs @@ -15,23 +15,32 @@ * along with this program. If not, see . */ +using System; using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Core; +using MatthiWare.UpdateLib.Core.Internal.CommandLine; using MatthiWare.UpdateLib.Utils; +using Microsoft.Extensions.Options; +using Moq; using NUnit.Framework; -using System; namespace UpdateLib.Tests.Util { [TestFixture] public class CmdLineParserTest { + OptionsWrapper optionsFactory = new OptionsWrapper( + new UpdateLibOptions + { + CommandLineArgumentPrefix = "--" + }); CmdLineParser cmd; [SetUp] public void Setup() { - cmd = new CmdLineParser(); + cmd = new CmdLineParser(optionsFactory); } [Test] @@ -54,22 +63,22 @@ public void GoodArgsAreAllParsedCorrectly() int[] ints = { 5, 10, 15, 20 }; - cmd.AddParameter("silent", ParamMandatoryType.Required, ParamValueType.None); - cmd.AddParameter("wait", ParamMandatoryType.Required, ParamValueType.Int); - cmd.AddParameter("update", ParamMandatoryType.Required, ParamValueType.None); - cmd.AddParameter("text", ParamMandatoryType.Required, ParamValueType.String); - cmd.AddParameter("ints", ParamMandatoryType.Required, ParamValueType.MultipleInts); + cmd.AddParameter("silent", ParamMandatoryType.Required); + cmd.AddParameter("wait", ParamMandatoryType.Required, ParamValueType.Required, new IntArgumentResolver()); + cmd.AddParameter("update", ParamMandatoryType.Required); + cmd.AddParameter("text", ParamMandatoryType.Required, ParamValueType.Required, new StringArgumentResolver(optionsFactory)); + cmd.AddParameter("ints", ParamMandatoryType.Required, ParamValueType.Required, new MultipleIntArgumentResolver()); cmd.Parse(args); - Assert.IsTrue(cmd["silent"]?.IsFound); - Assert.IsTrue(cmd["wait"]?.IsFound); - Assert.AreEqual(9999, cmd["wait"]?.Value); - Assert.IsTrue(cmd["update"]?.IsFound); - Assert.IsTrue(cmd["text"]?.IsFound); - Assert.AreEqual("this is my text message", cmd["text"]?.Value); - Assert.IsTrue(cmd["ints"]?.IsFound); - Assert.AreEqual(ints, cmd["ints"]?.Value); + Assert.IsTrue(cmd.Get("silent")?.IsFound ?? false); + Assert.IsTrue(cmd.Get("wait")?.IsFound ?? false); + Assert.AreEqual(9999, cmd.Get("wait")?.Value ?? -1); + Assert.IsTrue(cmd.Get("update")?.IsFound ?? false); + Assert.IsTrue(cmd.Get("text")?.IsFound ?? false); + Assert.AreEqual("this is my text message", cmd.Get("text")?.Value); + Assert.IsTrue(cmd.Get("ints")?.IsFound ?? false); + Assert.AreEqual(ints, cmd.Get("ints")?.Value); } [Test] @@ -80,15 +89,32 @@ public void OptionalArgumentIsNotMandatory() "--silent" }; - int[] ints = { 5, 10, 15, 20 }; + cmd.AddParameter("wait"); - cmd.AddParameter("silent", ParamMandatoryType.Required, ParamValueType.None); - cmd.AddParameter("wait", ParamMandatoryType.Optional, ParamValueType.Int); + cmd.Parse(args); + + Assert.IsFalse(cmd.Get("wait").IsFound); + } + + [Test] + public void OptionalValueTypeTest() + { + string[] args = { + @"C:\Dev\TestApp.exe", + "--wait", + "--otherParam" + }; + + cmd.AddParameter("wait", ParamMandatoryType.Required, ParamValueType.Optional, new IntArgumentResolver()); + cmd.AddParameter("otherParam", ParamMandatoryType.Required, ParamValueType.Optional, new StringArgumentResolver(optionsFactory)); cmd.Parse(args); - Assert.IsTrue(cmd["silent"]?.IsFound); - Assert.IsFalse(cmd["wait"]?.IsFound); + Assert.IsTrue(cmd.Get("wait").IsFound); + Assert.AreEqual(default(int), cmd.Get("wait").Value); + + Assert.IsTrue(cmd.Get("otherParam").IsFound); + Assert.AreEqual(default(string), cmd.Get("otherParam").Value); } [Test] @@ -102,15 +128,15 @@ public void TestOptionalParamValues() "10" }; - cmd.AddParameter("test", ParamMandatoryType.Required, ParamValueType.OptionalInt); - cmd.AddParameter("test2", ParamMandatoryType.Required, ParamValueType.OptionalInt); + cmd.AddParameter("test", ParamMandatoryType.Required, ParamValueType.Optional, new StringArgumentResolver(optionsFactory)); + cmd.AddParameter("test2", ParamMandatoryType.Required, ParamValueType.Optional, new IntArgumentResolver()); cmd.Parse(args); - Assert.IsTrue(cmd["test"].IsFound); - Assert.IsTrue(cmd["test2"].IsFound); - Assert.AreEqual(null, cmd["test"].Value); - Assert.AreEqual(10, cmd["test2"].Value); + Assert.IsTrue(cmd.Get("test").IsFound); + Assert.IsTrue(cmd.Get("test2").IsFound); + Assert.AreEqual("random", cmd.Get("test").Value); + Assert.AreEqual(10, cmd.Get("test2").Value); } [Test] @@ -123,14 +149,14 @@ public void TestDoubleParse() "--test2" }; - cmd.AddParameter("test1", ParamMandatoryType.Required, ParamValueType.Int); + cmd.AddParameter("test1", ParamMandatoryType.Required, ParamValueType.Required, new IntArgumentResolver()); cmd.AddParameter("test2", ParamMandatoryType.Optional, ParamValueType.None); cmd.Parse(args); - Assert.IsTrue(cmd["test1"].IsFound); - Assert.AreEqual(10, cmd["test1"].Value); - Assert.IsTrue(cmd["test2"].IsFound); + Assert.IsTrue(cmd.Get("test1").IsFound); + Assert.AreEqual(10, cmd.Get("test1").Value); + Assert.IsTrue(cmd.Get("test2").IsFound); args[2] = "11"; @@ -138,18 +164,17 @@ public void TestDoubleParse() cmd.Parse(args); - Assert.IsTrue(cmd["test1"].IsFound); - Assert.AreEqual(11, cmd["test1"].Value); - Assert.IsFalse(cmd["test2"].IsFound); + Assert.IsTrue(cmd.Get("test1").IsFound); + Assert.AreEqual(11, cmd.Get("test1").Value); + Assert.IsFalse(cmd.Get("test2").IsFound); } [Test] public void AddingFaultyParameterThrowsException() { - cmd.ParameterPrefix = string.Empty; Assert.Catch(() => cmd.AddParameter(null)); + Assert.Catch(() => cmd.AddParameter("")); Assert.Catch(() => cmd.AddParameter("test 123")); - Assert.Catch(() => cmd.Parse()); } [Test] diff --git a/UpdateLib/UpdateLib.Tests/Util/ExtensionMethodsTest.cs b/UpdateLib/UpdateLib.Tests/Util/ExtensionMethodsTest.cs index 974fecb..02ba698 100644 --- a/UpdateLib/UpdateLib.Tests/Util/ExtensionMethodsTest.cs +++ b/UpdateLib/UpdateLib.Tests/Util/ExtensionMethodsTest.cs @@ -15,12 +15,17 @@ * along with this program. If not, see . */ -using NUnit.Framework; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; + +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Files; using MatthiWare.UpdateLib.Utils; + using Moq; -using System.Diagnostics; + +using NUnit.Framework; namespace UpdateLib.Tests.Util { @@ -48,6 +53,37 @@ public void TestNotEmpty() Assert.AreEqual(4, test.Split('/').NotEmpty().Count()); } + [Test] + public void TestMax() + { + UpdateMetadataFile v1 = MakeUpdateFile("1"); + UpdateMetadataFile v2 = MakeUpdateFile("2"); + UpdateMetadataFile v3 = MakeUpdateFile("2.1"); + UpdateMetadataFile v4 = MakeUpdateFile("2.1.1"); + UpdateMetadataFile v5 = MakeUpdateFile("2.1.1-beta"); + UpdateMetadataFile v6 = MakeUpdateFile("2.1.1-rc"); + UpdateMetadataFile v7 = MakeUpdateFile("2.1.2"); + + var versions = new List(new UpdateMetadataFile[] + { + v1,v2,v3,v4,v5,v6,v7 + }); + + //var max = versions.MaxOrDefault(u => u.Version); + + //Assert.AreEqual(v7, max); + } + + private UpdateMetadataFile MakeUpdateFile(UpdateVersion version) + { + return new UpdateMetadataFile() + { + //Version = version + }; + } + + + [Test] public void TestForEach() { @@ -77,37 +113,6 @@ public void TestNotNullMethod() Assert.AreEqual(3, objs.NotNull().Count()); } - [Test] - public void TestSkipLast0Items() - { - IEnumerable items = Enumerable.Range(1, 20).SkipLast(0); - Assert.AreEqual(20, items.Count()); - - Assert.AreEqual(20, items.Reverse().First()); - - - } - - [Test] - public void TestSkipLast1Items() - { - IEnumerable items = Enumerable.Range(1, 20).SkipLast(1); - Assert.AreEqual(19, items.Count()); - - Assert.AreEqual(19, items.Reverse().First()); - } - - [Test] - public void TestSkipLast2Items() - { - IEnumerable items = Enumerable.Range(1, 20).SkipLast(2); - Assert.AreEqual(18, items.Count()); - - Assert.AreEqual(18, items.Reverse().First()); - - Assert.AreEqual("1234567", Enumerable.Range(1, 10).SkipLast(3).AppendAll(string.Empty)); - } - [DebuggerDisplay("{Id}")] public class TestObject { diff --git a/UpdateLib/UpdateLib.Tests/Util/GuardTests.cs b/UpdateLib/UpdateLib.Tests/Util/GuardTests.cs new file mode 100644 index 0000000..abb0d7b --- /dev/null +++ b/UpdateLib/UpdateLib.Tests/Util/GuardTests.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MatthiWare.UpdateLib.Utils; +using NUnit.Framework; + +namespace UpdateLib.Tests.Util +{ + [TestFixture] + public class GuardTests + { + [Test] + public void TestNotNullThrowsExceptionWhenNull() + { + Assert.That(() => Guard.NotNull(null, "null"), Throws.TypeOf()); + } + + [Test] + public void TestNotNullOrEmptyThrowsExceptionWhenNullOrEmpty() + { + Assert.That(() => Guard.NotNullOrEmpty(null, "null"), Throws.TypeOf()); + Assert.That(() => Guard.NotNullOrEmpty("", "null"), Throws.TypeOf()); + } + + } +} diff --git a/UpdateLib/UpdateLib.Tests/Util/IOUtilsTest.cs b/UpdateLib/UpdateLib.Tests/Util/IOUtilsTest.cs index 6174607..0160504 100644 --- a/UpdateLib/UpdateLib.Tests/Util/IOUtilsTest.cs +++ b/UpdateLib/UpdateLib.Tests/Util/IOUtilsTest.cs @@ -15,11 +15,11 @@ * along with this program. If not, see . */ +using System; using MatthiWare.UpdateLib; using MatthiWare.UpdateLib.Common; using MatthiWare.UpdateLib.Utils; using NUnit.Framework; -using System; namespace UpdateLib.Tests.Util { @@ -32,27 +32,27 @@ public class IOUtilsTest [SetUp] public void Setup() { - instance = Updater.Instance; + //instance = Updater.Instance; } [Test] public void TestAppDataPathLocal() { - instance.ConfigureInstallationMode(InstallationMode.Local); + //instance.ConfigureInstallationMode(InstallationMode.Local); - string path = IOUtils.AppDataPath; + //string path = IOUtils.AppDataPath; - Assert.IsTrue(path.Contains("Local"), $"Path: '{path}' didn't contain 'Local'"); + //Assert.IsTrue(path.Contains("Local"), $"Path: '{path}' didn't contain 'Local'"); } [Test] public void TestAppDataPathRoaming() { - instance.ConfigureInstallationMode(InstallationMode.Shared); + //instance.ConfigureInstallationMode(InstallationMode.Shared); - string path = IOUtils.AppDataPath; + //string path = IOUtils.AppDataPath; - Assert.IsTrue(path.Contains("Roaming"), $"Path: '{path}' didn't contain 'Roaming'"); + //Assert.IsTrue(path.Contains("Roaming"), $"Path: '{path}' didn't contain 'Roaming'"); } [Test] diff --git a/UpdateLib/UpdateLib.Tests/Util/LazyTests.cs b/UpdateLib/UpdateLib.Tests/Util/LazyTests.cs deleted file mode 100644 index c3f191c..0000000 --- a/UpdateLib/UpdateLib.Tests/Util/LazyTests.cs +++ /dev/null @@ -1,76 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using NUnit.Framework; - -namespace UpdateLib.Tests.Util -{ - [TestFixture] - public class LazyTests - { - - [Test] - public void TestLazyInitializesCorreclty() - { - MatthiWare.UpdateLib.Utils.Lazy myObject = new MatthiWare.UpdateLib.Utils.Lazy(() => "test"); - - Assert.AreEqual("test", myObject.Value); - } - - [Test] - public void TestLaszySet() - { - MatthiWare.UpdateLib.Utils.Lazy myObj = new MatthiWare.UpdateLib.Utils.Lazy(() => "test"); - myObj.Value = "new"; - - Assert.AreEqual("new", myObj.Value); - } - - [Test] - public void TestLazyReset() - { - SwitchObject switcher = new SwitchObject(); - - MatthiWare.UpdateLib.Utils.Lazy myLazy = new MatthiWare.UpdateLib.Utils.Lazy(switcher.Get); - - Assert.AreEqual(switcher.Get(), myLazy.Value); - - switcher.Toggle(); - - Assert.AreNotEqual(switcher.Get(), myLazy.Value); - - myLazy.Reset(); - - Assert.AreEqual(switcher.Get(), myLazy.Value); - } - - private class SwitchObject - { - private bool m_state = false; - - public void Toggle() - { - m_state = !m_state; - } - - public string Get() - { - return m_state ? "true" : "false"; - } - } - } -} diff --git a/UpdateLib/UpdateLib.Tests/Util/RegistryHelperTest.cs b/UpdateLib/UpdateLib.Tests/Util/RegistryHelperTest.cs deleted file mode 100644 index 367c6b9..0000000 --- a/UpdateLib/UpdateLib.Tests/Util/RegistryHelperTest.cs +++ /dev/null @@ -1,46 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Utils; -using NUnit.Framework; -using System; - -namespace UpdateLib.Tests.Util -{ - [TestFixture] - public class RegistryHelperTest - { - [Test] - public void TestNotExistingRootKey() - { - RegistryKeyEntry regKey = new RegistryKeyEntry("unexisting key", Microsoft.Win32.RegistryValueKind.Unknown, null); - regKey.Parent = new DirectoryEntry("not existing"); - - Assert.AreEqual(null, RegistryHelper.GetOrMakeKey(regKey)); - } - - [Test] - public void GetOrMakeKeyThrowsException() - { - RegistryKeyEntry key = null; - Assert.Throws(() => RegistryHelper.GetOrMakeKey(key)); - Assert.Throws(() => RegistryHelper.GetOrMakeKey(string.Empty)); - } - - } -} diff --git a/UpdateLib/UpdateLib.Tests/app.config b/UpdateLib/UpdateLib.Tests/app.config deleted file mode 100644 index 8ed398d..0000000 --- a/UpdateLib/UpdateLib.Tests/app.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.Tests/packages.config b/UpdateLib/UpdateLib.Tests/packages.config deleted file mode 100644 index 9f7b212..0000000 --- a/UpdateLib/UpdateLib.Tests/packages.config +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib.sln b/UpdateLib/UpdateLib.sln index 135c16a..2957dee 100644 --- a/UpdateLib/UpdateLib.sln +++ b/UpdateLib/UpdateLib.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2010 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateLib", "UpdateLib\UpdateLib.csproj", "{4394BE57-95E2-45B1-A968-1404B0590B35}" EndProject @@ -13,6 +13,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateLib.Tests", "UpdateLi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateLib.Generator", "UpdateLib.Generator\UpdateLib.Generator.csproj", "{5194FF71-49F6-4ADB-9B0E-4BEB418DC6F3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CDD5CD43-2D33-4654-8680-2352806AE394}" + ProjectSection(SolutionItems) = preProject + .shared\SharedAssemblyInfo.cs = .shared\SharedAssemblyInfo.cs + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -42,4 +47,7 @@ Global GlobalSection(NestedProjects) = preSolution {C47B8CC3-ABAB-4F56-8CA2-1323F902D1C3} = {4FDF7C41-4B30-4153-A06A-6DE8989B4EFF} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {95EA950A-A44A-4CF2-BEF3-CE45E2B42596} + EndGlobalSection EndGlobal diff --git a/UpdateLib/UpdateLib/Abstractions/ICheckForUpdatesMiddleware.cs b/UpdateLib/UpdateLib/Abstractions/ICheckForUpdatesMiddleware.cs new file mode 100644 index 0000000..3834a6d --- /dev/null +++ b/UpdateLib/UpdateLib/Abstractions/ICheckForUpdatesMiddleware.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace MatthiWare.UpdateLib.Abstractions +{ + public interface ICheckForUpdatesMiddleware + { + void BeforeCheckForUpdates(CancellationToken cancellation); + + void OnCheckForUpdates(CancellationToken cancellation); + + void PostCheckForUpdates(CancellationToken cancellation); + } +} diff --git a/UpdateLib/UpdateLib/Abstractions/ICommandLineArgumentResolver.cs b/UpdateLib/UpdateLib/Abstractions/ICommandLineArgumentResolver.cs new file mode 100644 index 0000000..0291a4e --- /dev/null +++ b/UpdateLib/UpdateLib/Abstractions/ICommandLineArgumentResolver.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MatthiWare.UpdateLib.Abstractions +{ + public interface ICommandLineArgumentResolver + { + bool CanResolve(ref string[] data, ref int index); + + object Resolve(ref string[] data, ref int index); + } + + public interface ICommandLineArgumentResolver : ICommandLineArgumentResolver + { + new TOutput Resolve(ref string[] data, ref int index); + } +} diff --git a/UpdateLib/UpdateLib/Abstractions/ICommandLineParser.cs b/UpdateLib/UpdateLib/Abstractions/ICommandLineParser.cs new file mode 100644 index 0000000..983a3b4 --- /dev/null +++ b/UpdateLib/UpdateLib/Abstractions/ICommandLineParser.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MatthiWare.UpdateLib.Common; + +namespace MatthiWare.UpdateLib.Abstractions +{ + public interface ICommandLineParser + { + void AddParameter(string paramName, ParamMandatoryType mandatoryType = ParamMandatoryType.Optional, ParamValueType valueType = ParamValueType.None); + + void AddParameter(string paramName, ParamMandatoryType mandatoryType, ParamValueType valueType, ICommandLineArgumentResolver resolver); + + void Parse(); + + IParameterDefinition Get(string name); + + IParameterDefinition Get(string name); + + } +} diff --git a/UpdateLib/UpdateLib/Abstractions/IParameterDefinition.cs b/UpdateLib/UpdateLib/Abstractions/IParameterDefinition.cs new file mode 100644 index 0000000..b140611 --- /dev/null +++ b/UpdateLib/UpdateLib/Abstractions/IParameterDefinition.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MatthiWare.UpdateLib.Common; + +namespace MatthiWare.UpdateLib.Abstractions +{ + public interface IParameterDefinition + { + string Name { get; } + ParamValueType ValueType { get; } + ParamMandatoryType MandatoryType { get; } + int Count { get; set; } + bool IsFound { get; } + void Reset(); + void Resolve(ref string[] args, ref int index); + bool CanResolve(ref string[] args, ref int index); + } + + public interface IParameterDefinition : IParameterDefinition + { + T Value { get; } + } +} diff --git a/UpdateLib/UpdateLib/Abstractions/IUpdater.cs b/UpdateLib/UpdateLib/Abstractions/IUpdater.cs new file mode 100644 index 0000000..9cdf2dd --- /dev/null +++ b/UpdateLib/UpdateLib/Abstractions/IUpdater.cs @@ -0,0 +1,14 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using MatthiWare.UpdateLib.Core; + +namespace MatthiWare.UpdateLib.Abstractions +{ + public interface IUpdater : IDisposable + { + Task InitializeAsync(CancellationToken cancellation = default); + + Task CheckForUpdatesAsync(CancellationToken cancellation = default); + } +} diff --git a/UpdateLib/UpdateLib/Abstractions/IValueResolver.cs b/UpdateLib/UpdateLib/Abstractions/IValueResolver.cs new file mode 100644 index 0000000..17ae8d0 --- /dev/null +++ b/UpdateLib/UpdateLib/Abstractions/IValueResolver.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MatthiWare.UpdateLib.Common; + +namespace MatthiWare.UpdateLib.Abstractions +{ + public interface IValueResolver + { + T Resolve(); + + } +} diff --git a/UpdateLib/UpdateLib/Abstractions/Internal/IUpdateManager.cs b/UpdateLib/UpdateLib/Abstractions/Internal/IUpdateManager.cs new file mode 100644 index 0000000..7abc9cf --- /dev/null +++ b/UpdateLib/UpdateLib/Abstractions/Internal/IUpdateManager.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MatthiWare.UpdateLib.Core; + +namespace MatthiWare.UpdateLib.Abstractions.Internal +{ + public interface IUpdateManager + { + Task CheckForUpdatesAsync(CancellationToken cancellation); + + Task UpdateAsync(CancellationToken cancellation); + } +} diff --git a/UpdateLib/UpdateLib/Common/Enums.cs b/UpdateLib/UpdateLib/Common/Enums.cs deleted file mode 100644 index ce760c5..0000000 --- a/UpdateLib/UpdateLib/Common/Enums.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace MatthiWare.UpdateLib.Common -{ - /// - /// Indicates the how the underlaying application is installed. - /// - public enum InstallationMode - { - /// - /// Shared installation we will use the roaming folder - /// - Shared = 0, - - /// - /// Single user installation we will use the local folder - /// - Local = 1 - } - - public enum ParamValueType - { - None, - String, - OptionalString, - Int, - OptionalInt, - Bool, - OptionalBool, - MultipleInts - } - - public enum ParamMandatoryType - { - Optional, - Required - } - - public enum TOKEN_INFORMATION_CLASS - { - TokenUser = 1, - TokenGroups, - TokenPrivileges, - TokenOwner, - TokenPrimaryGroup, - TokenDefaultDacl, - TokenSource, - TokenType, - TokenImpersonationLevel, - TokenStatistics, - TokenRestrictedSids, - TokenSessionId, - TokenGroupsAndPrivileges, - TokenSessionReference, - TokenSandBoxInert, - TokenAuditPolicy, - TokenOrigin, - TokenElevationType, - TokenLinkedToken, - TokenElevation, - TokenHasRestrictions, - TokenAccessInformation, - TokenVirtualizationAllowed, - TokenVirtualizationEnabled, - TokenIntegrityLevel, - TokenUIAccess, - TokenMandatoryPolicy, - TokenLogonSid, - MaxTokenInfoClass - } - - public enum TOKEN_ELEVATION_TYPE - { - TokenElevationTypeDefault = 1, - TokenElevationTypeFull, - TokenElevationTypeLimited - } - - public enum LoggingLevel - { - Debug = 0, - Info = 1, - Warn = 2, - Error = 3 - } -} diff --git a/UpdateLib/UpdateLib/Common/ParameterDefinition.cs b/UpdateLib/UpdateLib/Common/ParameterDefinition.cs deleted file mode 100644 index a746dde..0000000 --- a/UpdateLib/UpdateLib/Common/ParameterDefinition.cs +++ /dev/null @@ -1,33 +0,0 @@ -using MatthiWare.UpdateLib.Utils; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace MatthiWare.UpdateLib.Common -{ - public class ParameterDefinition - { - public string ParameterName { get; private set; } - public ParamMandatoryType MandatoryType { get; private set; } - public ParamValueType ValueType { get; private set; } - public object Value { get; internal set; } - - public int Count { get; internal set; } - - public bool IsFound { get { return Count > 0; } } - - public ParameterDefinition(string paramName, ParamMandatoryType mandatoryType = ParamMandatoryType.Optional, ParamValueType valueType = ParamValueType.None) - { - ParameterName = paramName; - MandatoryType = mandatoryType; - ValueType = valueType; - } - - internal void Reset() - { - Value = null; - Count = 0; - } - } -} diff --git a/UpdateLib/UpdateLib/Controls/UpdaterControl.Designer.cs b/UpdateLib/UpdateLib/Controls/UpdaterControl.Designer.cs deleted file mode 100644 index 46bf967..0000000 --- a/UpdateLib/UpdateLib/Controls/UpdaterControl.Designer.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace MatthiWare.UpdateLib.Controls -{ - partial class UpdaterControl - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.SuspendLayout(); - // - // UpdaterControl - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.Color.Transparent; - this.DoubleBuffered = true; - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.Name = "UpdaterControl"; - this.Size = new System.Drawing.Size(369, 77); - this.ResumeLayout(false); - - } - - #endregion - } -} diff --git a/UpdateLib/UpdateLib/Controls/UpdaterControl.cs b/UpdateLib/UpdateLib/Controls/UpdaterControl.cs deleted file mode 100644 index 39fcebf..0000000 --- a/UpdateLib/UpdateLib/Controls/UpdaterControl.cs +++ /dev/null @@ -1,287 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Windows.Forms; -using MatthiWare.UpdateLib.Properties; - -namespace MatthiWare.UpdateLib.Controls -{ - [ToolboxBitmap(typeof(UpdaterControl), "UpdaterControl.bmp")] - public partial class UpdaterControl : UserControl - { - private const int ICON_SIZE = 16; - private const int XY_OFFSET = 2; - private const int PROGRESS_SPEED = 200; - - private Brush brush; - private float x_text, y_text; - - private const string CHECK_FOR_UPDATES = "Please check for updates"; - - private Point oldLocation; - private ToolTip tooltip = new ToolTip(); - - private Dictionary cachedMeasure = new Dictionary(); - private string _text = CHECK_FOR_UPDATES; - public override string Text - { - get { return _text; } - set - { - if (_text != value) - { - _text = value; - Invalidate(); - } - - } - } - - private int progressIndex = 0; - private Bitmap[] progressImages = new Bitmap[50]; - - private Dictionary cachedImages = new Dictionary(); - - private Timer timer; - - private UpdaterIcon _icon = UpdaterIcon.Info; - private UpdaterIcon Icon - { - get { return _icon; } - set - { - if (_icon != value) - { - _icon = value; - Invalidate(); - } - - } - } - - public enum UpdaterIcon : byte - { - Info = 0, - Error = 1, - Done = 2, - Update = 3, - Progress = 4 - } - - public UpdaterControl() - { - InitializeComponent(); - - SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true); - SetStyle(ControlStyles.ContainerControl, false); - - Size = new Size(XY_OFFSET * 2 + ICON_SIZE, XY_OFFSET * 2 + ICON_SIZE); - timer = new Timer(); - timer.Interval = PROGRESS_SPEED; - timer.Tick += update_progress; - - // caching - LoadImages(); - MakeBrushFromForeColor(); - CalcFont(); - - } - - private void update_progress(object sender, EventArgs e) - { - Invalidate(); - if (++progressIndex >= progressImages.Length) - progressIndex = 0; - } - - private void StartProgress() - { - progressIndex = 0; - timer.Start(); - } - - private void StopProgress() - { - timer.Stop(); - } - - public override Font Font - { - get - { - return base.Font; - } - - set - { - base.Font = value; - // invalidate the cache - cachedMeasure.Clear(); - CalcFont(); - } - } - - private void CalcFont() - { - SizeF size = GetAndCacheSize(); - - int height = XY_OFFSET * 2 + ICON_SIZE; - - x_text = XY_OFFSET * 2 + ICON_SIZE; - y_text = (height / 2) - (size.Height / 2); - } - - private SizeF GetAndCacheSize() - { - if (!cachedMeasure.ContainsKey(Text)) - { - Graphics g = Graphics.FromImage(new Bitmap(1,1)); - SizeF size = g.MeasureString(Text, base.Font); - - cachedMeasure.Add(Text, size); - } - - return cachedMeasure[Text]; - } - - public override Color ForeColor - { - get - { - return base.ForeColor; - } - - set - { - base.ForeColor = value; - MakeBrushFromForeColor(); - } - } - - private void MakeBrushFromForeColor() - { - brush = new SolidBrush(base.ForeColor); - } - - private void LoadImages() - { - Resources.status_download.RotateFlip(RotateFlipType.RotateNoneFlipY); - cachedImages.Add(UpdaterIcon.Info, Resources.status_info); - cachedImages.Add(UpdaterIcon.Error, Resources.status_error); - cachedImages.Add(UpdaterIcon.Done, Resources.status_done); - cachedImages.Add(UpdaterIcon.Update, Resources.status_update); - - Bitmap spritesheet = Resources.status_working; - - int i = 0; - for (int x = 0; x < 10; x++) - { - for (int y = 0; y < 5; y++) - { - Bitmap bmp = new Bitmap(16, 16); - Graphics g = Graphics.FromImage(bmp); - - Rectangle dest = new Rectangle(0, 0, 16, 16); - Rectangle src = new Rectangle(x * 16, y * 16, 16, 16); - - g.DrawImage(spritesheet, dest, src, GraphicsUnit.Pixel); - - g.Dispose(); - - progressImages[i++] = bmp; - } - } - - } - - protected override void OnPaint(PaintEventArgs e) - { - base.OnPaint(e); - - DrawIcon(e.Graphics); - DrawText(e.Graphics); - } - - private void DrawIcon(Graphics g) - { - g.DrawImage((Icon == UpdaterIcon.Progress) ? progressImages[progressIndex] : cachedImages[Icon], - XY_OFFSET, - XY_OFFSET, - ICON_SIZE, - ICON_SIZE); - } - - private void DrawText(Graphics g) - { - g.DrawString(Text, Font, brush, x_text, y_text); - } - - protected override void OnMouseEnter(EventArgs e) - { - base.OnMouseEnter(e); - - oldLocation = Location; - int newWidth = CalcNewWidth(); - Width = newWidth; - - if (Location.X + newWidth > ParentForm.Width) - { - int amountToRemove = ParentForm.Width - (Location.X + newWidth) - (XY_OFFSET * 2 + ICON_SIZE); - Point x = Location; - x.X += amountToRemove; - Location = x; - } - } - - protected override void OnMouseLeave(EventArgs e) - { - base.OnMouseLeave(e); - - Location = oldLocation; - Width = XY_OFFSET * 2 + ICON_SIZE; - - tooltip.Active = false; - } - - protected override void OnMouseHover(EventArgs e) - { - base.OnMouseHover(e); - - - tooltip.ToolTipIcon = ToolTipIcon.Info; - tooltip.ToolTipTitle = Text; - tooltip.UseAnimation = true; - tooltip.Active = true; - tooltip.Show("Please click here to start checking for updates", Parent, Location.X + Width + (ICON_SIZE), Location.Y + Height); - - } - - protected override void OnClick(EventArgs e) - { - base.OnClick(e); - - Text = "Checking for updates.."; - Icon = UpdaterIcon.Progress; - - int currWidth = Width; - int newWidth = CalcNewWidth(); - - int offset = currWidth - newWidth; - Point x = Location; - x.X += offset; - Location = x; - Width = newWidth; - - StartProgress(); - - - } - - private int CalcNewWidth() - { - SizeF size = GetAndCacheSize(); - return (int)size.Width + (XY_OFFSET * 2 + ICON_SIZE); - } - - } -} diff --git a/UpdateLib/UpdateLib/Controls/UpdaterControl.resx b/UpdateLib/UpdateLib/Controls/UpdaterControl.resx deleted file mode 100644 index 7080a7d..0000000 --- a/UpdateLib/UpdateLib/Controls/UpdaterControl.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib/Files/EntryBase.cs b/UpdateLib/UpdateLib/Core/Abstraction/EntryBase.cs similarity index 97% rename from UpdateLib/UpdateLib/Files/EntryBase.cs rename to UpdateLib/UpdateLib/Core/Abstraction/EntryBase.cs index 74cc5af..cdb7cde 100644 --- a/UpdateLib/UpdateLib/Files/EntryBase.cs +++ b/UpdateLib/UpdateLib/Core/Abstraction/EntryBase.cs @@ -19,7 +19,7 @@ using System.Text; using System.Xml.Serialization; -namespace MatthiWare.UpdateLib.Files +namespace MatthiWare.UpdateLib.Common.Abstraction { [Serializable] public abstract class EntryBase diff --git a/UpdateLib/UpdateLib/Core/Abstraction/FileBase.cs b/UpdateLib/UpdateLib/Core/Abstraction/FileBase.cs new file mode 100644 index 0000000..c05a02e --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Abstraction/FileBase.cs @@ -0,0 +1,108 @@ +/* UpdateLib - .Net auto update library + * Copyright (C) 2016 - MatthiWare (Matthias Beerens) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System; +using System.IO; +using System.Xml.Serialization; + +namespace MatthiWare.UpdateLib.Common.Abstraction +{ + /// + /// The base class for all the files that need to be able to save/load from disk. + /// + /// Serializable file class + [Serializable] + public abstract class FileBase where T : new() + { + /// + /// Default ctor needed for serialization + /// + protected FileBase() { } + + /// + /// Saves the file using the default path + /// + public abstract void Save(); + + /// + /// Saves the file using a specified path + /// + /// The path to save the file to + public virtual void Save(string path) + { + if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); + + var fi = new FileInfo(path); + + if (!fi.Directory.Exists) + fi.Directory.Create(); + + using (var stream = fi.Open(FileMode.Create, FileAccess.Write)) + Save(stream); + } + + /// + /// Saves the file using a specified stream + /// + /// The stream to save the file to. + public virtual void Save(Stream stream) + { + if (stream == null) throw new ArgumentNullException(nameof(stream)); + if (!stream.CanWrite) throw new ArgumentException("Unwritable stream", nameof(stream)); + + XmlSerializer serializer = new XmlSerializer(typeof(T)); + serializer.Serialize(stream, this); + } + + /// + /// Loads the file from the default path + /// + /// A loaded instance of the file. + public abstract T Load(); + + /// + /// Loads the file from a specified path + /// + /// The path to load the file from + /// A loaded instance of the file. + public virtual T Load(string path) + { + if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); + + var fi = new FileInfo(path); + + if (!fi.Exists) throw new FileNotFoundException("File does not exist", path); + + using (var stream = fi.Open(FileMode.Open, FileAccess.Read)) + return Load(stream); + } + + /// + /// Loads the file from a specified stream + /// + /// + /// A loaded instance of the file. + public virtual T Load(Stream stream) + { + if (stream == null) throw new ArgumentNullException(nameof(stream)); + if (!stream.CanRead) throw new ArgumentException("Unreadable stream", nameof(stream)); + + XmlSerializer serializer = new XmlSerializer(typeof(T)); + return (T)serializer.Deserialize(stream); + } + } +} diff --git a/UpdateLib/UpdateLib/Core/Attributes.cs b/UpdateLib/UpdateLib/Core/Attributes.cs new file mode 100644 index 0000000..509dabe --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Attributes.cs @@ -0,0 +1,19 @@ +using System; + +namespace MatthiWare.UpdateLib.Common +{ + /// + /// The application version that the uses to know what the current version is. + /// This attribute should be incremented with each new release, patch, ... + /// + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = true)] + public sealed class ApplicationVersionAttribute : Attribute + { + public UpdateVersion Version { get; private set; } + + public ApplicationVersionAttribute(string version) + { + Version = version; + } + } +} diff --git a/UpdateLib/UpdateLib/Core/CheckForUpdatesResult.cs b/UpdateLib/UpdateLib/Core/CheckForUpdatesResult.cs new file mode 100644 index 0000000..61fad9b --- /dev/null +++ b/UpdateLib/UpdateLib/Core/CheckForUpdatesResult.cs @@ -0,0 +1,12 @@ +using MatthiWare.UpdateLib.Common; + +namespace MatthiWare.UpdateLib.Core +{ + public class CheckForUpdatesResult + { + public UpdateVersion Version { get { return UpdateInfo.Version; } } + public bool UpdateAvailable => UpdateInfo != null; + public UpdateInfo UpdateInfo { get; internal set; } + public bool AdminRightsNeeded { get; internal set; } + } +} \ No newline at end of file diff --git a/UpdateLib/UpdateLib/Core/Delegates.cs b/UpdateLib/UpdateLib/Core/Delegates.cs new file mode 100644 index 0000000..6b97523 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Delegates.cs @@ -0,0 +1,9 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace MatthiWare.UpdateLib.Common +{ + public delegate void ProgressChangedHandler(bool completed, double progress); +} diff --git a/UpdateLib/UpdateLib/Files/DirectoryEntry.cs b/UpdateLib/UpdateLib/Core/DirectoryEntry.cs similarity index 88% rename from UpdateLib/UpdateLib/Files/DirectoryEntry.cs rename to UpdateLib/UpdateLib/Core/DirectoryEntry.cs index 023824c..cdfc04c 100644 --- a/UpdateLib/UpdateLib/Files/DirectoryEntry.cs +++ b/UpdateLib/UpdateLib/Core/DirectoryEntry.cs @@ -17,12 +17,14 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Text; using System.Xml.Serialization; -using System.Linq; -using System.Diagnostics; -namespace MatthiWare.UpdateLib.Files +using MatthiWare.UpdateLib.Common.Abstraction; + +namespace MatthiWare.UpdateLib.Common { /// /// Represents a directory in the update file. @@ -42,34 +44,23 @@ public class DirectoryEntry /// /// Gets how many files there are in this directory and its subdirectories. /// - public int Count - { - get - { - return Items.Count + Directories.Sum(d => d.Count); - } - } + public int Count => Items.Count + Directories.Sum(dir => dir.Count); /// /// Gets the list of subdirectories. /// - [XmlArray("Directories"), XmlArrayItem("Directory")] public List Directories { get; set; } = new List(); /// /// Gets the list of files in this directory. /// - [XmlElement(typeof(FileEntry))] - [XmlElement(typeof(RegistryKeyEntry))] public List Items { get; set; } = new List(); /// /// Gets or Sets the Parent of this Directory /// - [XmlIgnore] public DirectoryEntry Parent { get; set; } - [XmlIgnore] public string SourceLocation { get @@ -152,9 +143,6 @@ public bool Remove(EntryBase file) /// Gets all the items including the items of childs /// /// A list of items - public IEnumerable GetItems() - { - return Items.Concat(Directories.SelectMany(d => d.GetItems())); - } + public IEnumerable GetItems() => Items.Concat(Directories.SelectMany(d => d.GetItems())); } } diff --git a/UpdateLib/UpdateLib/Core/Enums.cs b/UpdateLib/UpdateLib/Core/Enums.cs new file mode 100644 index 0000000..0402427 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Enums.cs @@ -0,0 +1,47 @@ +namespace MatthiWare.UpdateLib.Common +{ + /// + /// Indicates the how the underlaying application is installed. + /// + public enum InstallationMode + { + /// + /// Shared installation we will use the roaming folder + /// + Shared = 0, + + /// + /// Single user installation we will use the local folder + /// + Local = 1 + } + + public enum ParamValueType + { + None, + Optional, + Required + } + + public enum ParamMandatoryType + { + Optional, + Required + } + + public enum VersionLabel : byte + { + Alpha = 0, + Beta = 1, + RC = 2, + None = 3 + } + + internal enum InstructionType : byte + { + NoOp = 0, + Add = 1, + Run = 2, + Copy = 3 + } +} diff --git a/UpdateLib/UpdateLib/Security/InvalidHashException.cs b/UpdateLib/UpdateLib/Core/Exceptions/InvalidHashException.cs similarity index 96% rename from UpdateLib/UpdateLib/Security/InvalidHashException.cs rename to UpdateLib/UpdateLib/Core/Exceptions/InvalidHashException.cs index 9647bdb..fceb24a 100644 --- a/UpdateLib/UpdateLib/Security/InvalidHashException.cs +++ b/UpdateLib/UpdateLib/Core/Exceptions/InvalidHashException.cs @@ -18,7 +18,7 @@ using System; using System.Runtime.Serialization; -namespace MatthiWare.UpdateLib.Security +namespace MatthiWare.UpdateLib.Common.Exceptions { [Serializable] public class InvalidHashException : Exception diff --git a/UpdateLib/UpdateLib/Core/Exceptions/InvalidUpdateServerException.cs b/UpdateLib/UpdateLib/Core/Exceptions/InvalidUpdateServerException.cs new file mode 100644 index 0000000..a12fa51 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Exceptions/InvalidUpdateServerException.cs @@ -0,0 +1,40 @@ +/* Copyright + * + * UpdateLib - .Net auto update library + * + * File: NoVersionSpecifiedException.cs v0.5 + * + * Author: Matthias Beerens + * + * Copyright (C) 2017 - MatthiWare + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System; + +namespace MatthiWare.UpdateLib.Common.Exceptions +{ + + [Serializable] + public class InvalidUpdateServerException : Exception + { + public InvalidUpdateServerException() { } + public InvalidUpdateServerException(string message) : base(message) { } + public InvalidUpdateServerException(string message, Exception inner) : base(message, inner) { } + protected InvalidUpdateServerException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } +} diff --git a/UpdateLib/UpdateLib.Generator/Files/ProjectFile.cs b/UpdateLib/UpdateLib/Core/Exceptions/NoInternetException.cs similarity index 55% rename from UpdateLib/UpdateLib.Generator/Files/ProjectFile.cs rename to UpdateLib/UpdateLib/Core/Exceptions/NoInternetException.cs index e28bc23..b9b34b8 100644 --- a/UpdateLib/UpdateLib.Generator/Files/ProjectFile.cs +++ b/UpdateLib/UpdateLib/Core/Exceptions/NoInternetException.cs @@ -1,5 +1,10 @@ /* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) + * + * File: NoInternetException.cs + * + * Author: Matthias Beerens + * + * Copyright (C) 2016 - MatthiWare * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published @@ -16,24 +21,18 @@ */ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace MatthiWare.UpdateLib.Generator.Files +namespace MatthiWare.UpdateLib.Common.Exceptions { + [Serializable] - public class ProjectFile + public class NoInternetException : Exception { - - #region General Info - #endregion - - #region Files - #endregion - - #region Registry - #endregion - + public NoInternetException() { } + public NoInternetException(string message) : base(message) { } + public NoInternetException(string message, Exception inner) : base(message, inner) { } + protected NoInternetException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } } } diff --git a/UpdateLib/UpdateLib/Core/Exceptions/UnableToDownloadUpdateException.cs b/UpdateLib/UpdateLib/Core/Exceptions/UnableToDownloadUpdateException.cs new file mode 100644 index 0000000..3904c5f --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Exceptions/UnableToDownloadUpdateException.cs @@ -0,0 +1,16 @@ +using System; + +namespace MatthiWare.UpdateLib.Common.Exceptions +{ + + [Serializable] + public class UnableToDownloadUpdateException : Exception + { + public UnableToDownloadUpdateException() { } + public UnableToDownloadUpdateException(string message) : base(message) { } + public UnableToDownloadUpdateException(string message, Exception inner) : base(message, inner) { } + protected UnableToDownloadUpdateException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } +} diff --git a/UpdateLib/UpdateLib/Files/FileEntry.cs b/UpdateLib/UpdateLib/Core/FileEntry.cs similarity index 93% rename from UpdateLib/UpdateLib/Files/FileEntry.cs rename to UpdateLib/UpdateLib/Core/FileEntry.cs index 7b1a221..cfcefe6 100644 --- a/UpdateLib/UpdateLib/Files/FileEntry.cs +++ b/UpdateLib/UpdateLib/Core/FileEntry.cs @@ -15,10 +15,11 @@ * along with this program. If not, see . */ +using MatthiWare.UpdateLib.Common.Abstraction; using System; using System.Xml.Serialization; -namespace MatthiWare.UpdateLib.Files +namespace MatthiWare.UpdateLib.Common { [Serializable] public class FileEntry : EntryBase diff --git a/UpdateLib/UpdateLib/Core/FileManager.cs b/UpdateLib/UpdateLib/Core/FileManager.cs new file mode 100644 index 0000000..06c4cd0 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/FileManager.cs @@ -0,0 +1,41 @@ +/* Copyright + * + * UpdateLib - .Net auto update library + * + * File: FileManager.cs v0.5 + * + * Author: Matthias Beerens + * + * Copyright (C) 2017 - MatthiWare + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System.IO; +using MatthiWare.UpdateLib.Common.Abstraction; + +namespace MatthiWare.UpdateLib.Common +{ + public static class FileManager + { + public static T LoadFile() where T : FileBase, new() + => new T().Load(); + + public static T LoadFile(string path) where T : FileBase, new() + => new T().Load(path); + + public static T LoadFile(Stream stream) where T : FileBase, new() + => new T().Load(stream); + } +} diff --git a/UpdateLib/UpdateLib/Files/HashCacheEntry.cs b/UpdateLib/UpdateLib/Core/HashCacheEntry.cs similarity index 76% rename from UpdateLib/UpdateLib/Files/HashCacheEntry.cs rename to UpdateLib/UpdateLib/Core/HashCacheEntry.cs index 18c1380..0de28ff 100644 --- a/UpdateLib/UpdateLib/Files/HashCacheEntry.cs +++ b/UpdateLib/UpdateLib/Core/HashCacheEntry.cs @@ -15,12 +15,13 @@ * along with this program. If not, see . */ -using MatthiWare.UpdateLib.Security; using System; using System.IO; using System.Xml.Serialization; -namespace MatthiWare.UpdateLib.Files +using MatthiWare.UpdateLib.Security; + +namespace MatthiWare.UpdateLib.Common { [Serializable] public class HashCacheEntry @@ -55,22 +56,21 @@ public void Recalculate(string hash = "") { try { - long tick = File.GetLastWriteTime(FilePath).Ticks; + var tick = File.GetLastWriteTime(FilePath).Ticks; + + if (Ticks != -1 && tick == Ticks) return; - if (Ticks == -1 || tick != Ticks) - { - Hash = string.IsNullOrEmpty(hash) ? HashUtil.GetHash(FilePath) : hash; - Ticks = tick; + Hash = string.IsNullOrEmpty(hash) ? HashUtil.GetHash(FilePath) : hash; + Ticks = tick; - Updater.Instance.Logger.Debug(nameof(HashCacheEntry), nameof(Recalculate), $"Recalculated Time: {DateTime.FromBinary(Ticks).ToString()} Name: {FilePath} Hash: {Hash}"); - } + //Updater.Instance.Logger.Debug(nameof(HashCacheEntry), nameof(Recalculate), $"Recalculated Time: {DateTime.FromBinary(Ticks).ToString()} Name: {FilePath} Hash: {Hash}"); } catch (Exception ex) // file might no longer exist or is in use { Hash = string.Empty; Ticks = -1; - Updater.Instance.Logger.Error(nameof(HashCacheEntry), nameof(Recalculate), ex); + //Updater.Instance.Logger.Error(nameof(HashCacheEntry), nameof(Recalculate), ex); } } diff --git a/UpdateLib/UpdateLib/Core/Internal/CommandLine/IntArgumentResolver.cs b/UpdateLib/UpdateLib/Core/Internal/CommandLine/IntArgumentResolver.cs new file mode 100644 index 0000000..9bbf49e --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Internal/CommandLine/IntArgumentResolver.cs @@ -0,0 +1,18 @@ +using MatthiWare.UpdateLib.Abstractions; + +namespace MatthiWare.UpdateLib.Core.Internal.CommandLine +{ + public class IntArgumentResolver : ICommandLineArgumentResolver + { + private int value; + + public bool CanResolve(ref string[] data, ref int index) + => int.TryParse(data[index], out value); + + public int Resolve(ref string[] data, ref int index) + => value; + + object ICommandLineArgumentResolver.Resolve(ref string[] data, ref int index) + => Resolve(ref data, ref index); + } +} diff --git a/UpdateLib/UpdateLib/Core/Internal/CommandLine/MultipleIntArgumentResolver.cs b/UpdateLib/UpdateLib/Core/Internal/CommandLine/MultipleIntArgumentResolver.cs new file mode 100644 index 0000000..2d2b076 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Internal/CommandLine/MultipleIntArgumentResolver.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; +using MatthiWare.UpdateLib.Abstractions; + +namespace MatthiWare.UpdateLib.Core.Internal.CommandLine +{ + public class MultipleIntArgumentResolver : ICommandLineArgumentResolver + { + private IList ints = new List(); + + public bool CanResolve(ref string[] data, ref int index) + { + while (index < data.Length && int.TryParse(data[index], out int outValue)) + { + ints.Add(outValue); + index++; + } + + return ints.Count >= 2; // at least 2 elements + } + + + public int[] Resolve(ref string[] data, ref int index) + => ints.ToArray(); + + object ICommandLineArgumentResolver.Resolve(ref string[] data, ref int index) + => Resolve(ref data, ref index); + } +} diff --git a/UpdateLib/UpdateLib/Core/Internal/CommandLine/StringArgumentResolver.cs b/UpdateLib/UpdateLib/Core/Internal/CommandLine/StringArgumentResolver.cs new file mode 100644 index 0000000..2e91408 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Internal/CommandLine/StringArgumentResolver.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MatthiWare.UpdateLib.Abstractions; +using Microsoft.Extensions.Options; + +namespace MatthiWare.UpdateLib.Core.Internal.CommandLine +{ + public class StringArgumentResolver : ICommandLineArgumentResolver + { + private readonly UpdateLibOptions options; + + public StringArgumentResolver(IOptions options) + => this.options = options.Value; + + public bool CanResolve(ref string[] data, ref int index) + => !data[index].StartsWith(options.CommandLineArgumentPrefix); // if it is not a parameter + + + public string Resolve(ref string[] data, ref int index) + => data[index]; + + object ICommandLineArgumentResolver.Resolve(ref string[] data, ref int index) + => Resolve(ref data, ref index); + } +} diff --git a/UpdateLib/UpdateLib/Core/Internal/CommandLine/UpdateVersionArgumentResolver.cs b/UpdateLib/UpdateLib/Core/Internal/CommandLine/UpdateVersionArgumentResolver.cs new file mode 100644 index 0000000..fa92c04 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Internal/CommandLine/UpdateVersionArgumentResolver.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +using MatthiWare.UpdateLib.Abstractions; +using MatthiWare.UpdateLib.Common; + +namespace MatthiWare.UpdateLib.Core.Internal.CommandLine +{ + internal class UpdateVersionArgumentResolver : ICommandLineArgumentResolver + { + public bool CanResolve(ref string[] data, ref int index) + => UpdateVersion.CanParse(data[index]); + + public UpdateVersion Resolve(ref string[] data, ref int index) + => new UpdateVersion(data[index]); + + object ICommandLineArgumentResolver.Resolve(ref string[] data, ref int index) + => Resolve(ref data, ref index); + } +} diff --git a/UpdateLib/UpdateLib/Core/Internal/DefaultVersionResolver.cs b/UpdateLib/UpdateLib/Core/Internal/DefaultVersionResolver.cs new file mode 100644 index 0000000..36e16d0 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Internal/DefaultVersionResolver.cs @@ -0,0 +1,25 @@ +using System; +using System.Reflection; +using MatthiWare.UpdateLib.Abstractions; +using MatthiWare.UpdateLib.Common; + +namespace MatthiWare.UpdateLib.Core.Internal +{ + public sealed class DefaultVersionResolver : IValueResolver + { + private UpdateVersion m_versionCached; + + public UpdateVersion Resolve() => GetOrResolve(); + + private UpdateVersion GetOrResolve() + { + if (m_versionCached == null) + { + var attribute = Assembly.GetEntryAssembly().GetCustomAttribute(); + m_versionCached = attribute?.Version ?? throw new InvalidOperationException("Unable to resolve the application version from the assembly metadata. Consider using a custom resolver."); + } + + return m_versionCached; + } + } +} diff --git a/UpdateLib/UpdateLib/Core/Internal/UpdateLibOptionsSetup.cs b/UpdateLib/UpdateLib/Core/Internal/UpdateLibOptionsSetup.cs new file mode 100644 index 0000000..80603f7 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Internal/UpdateLibOptionsSetup.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Extensions.Options; + +namespace MatthiWare.UpdateLib.Core.Internal +{ + public class UpdateLibOptionsSetup : IConfigureOptions + { + private const string m_argUpdateSilent = "silent"; + private const string m_argUpdate = "update"; + private const string m_argWait = "wait"; + private const string m_rollback = "rollback"; + private const string m_argumentPrefix = "--"; + + public void Configure(UpdateLibOptions options) + { + options.CommandLineArgumentPrefix = m_argumentPrefix; + options.RollbackArgumentName = m_rollback; + options.UpdateSilentArgumentName = m_argUpdateSilent; + options.WaitArgumentName = m_argWait; + options.UpdateArgumentName = m_argUpdate; + } + } +} diff --git a/UpdateLib/UpdateLib/Core/Internal/UpdateManager.cs b/UpdateLib/UpdateLib/Core/Internal/UpdateManager.cs new file mode 100644 index 0000000..3a3091a --- /dev/null +++ b/UpdateLib/UpdateLib/Core/Internal/UpdateManager.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MatthiWare.UpdateLib.Abstractions; +using MatthiWare.UpdateLib.Abstractions.Internal; +using MatthiWare.UpdateLib.Common; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace MatthiWare.UpdateLib.Core.Internal +{ + internal class UpdateManager : IUpdateManager + { + private readonly IValueResolver versionResolver; + private readonly UpdateLibOptions options; + private readonly ILogger logger; + + public UpdateManager(IValueResolver versionResolver, IOptions options, ILogger logger) + { + this.versionResolver = versionResolver; + this.options = options.Value; + this.logger = logger; + } + + public Task CheckForUpdatesAsync(CancellationToken cancellation) + { + throw new NotImplementedException(); + } + + public Task UpdateAsync(CancellationToken cancellation) + { + throw new NotImplementedException(); + } + } +} diff --git a/UpdateLib/UpdateLib/Core/ParameterDefinition.cs b/UpdateLib/UpdateLib/Core/ParameterDefinition.cs new file mode 100644 index 0000000..105124a --- /dev/null +++ b/UpdateLib/UpdateLib/Core/ParameterDefinition.cs @@ -0,0 +1,76 @@ +using System; +using MatthiWare.UpdateLib.Abstractions; + +namespace MatthiWare.UpdateLib.Common +{ + + public class ParameterDefinition : IParameterDefinition + { + public string Name { get; } + + public ParamValueType ValueType { get; } + + public ParamMandatoryType MandatoryType { get; } + + public int Count { get; set; } + + public bool IsFound => Count > 0; + + public bool CanResolve(ref string[] args, ref int index) => false; + + public ParameterDefinition(string paramName, ParamMandatoryType mandatoryType, ParamValueType valueType) + { + Name = paramName; + MandatoryType = mandatoryType; + ValueType = valueType; + } + + public void Reset() => Count = 0; + + public void Resolve(ref string[] args, ref int index) => throw new NotImplementedException(); + } + + public class ParameterDefinition : IParameterDefinition + { + public string Name { get; } + + public ParamMandatoryType MandatoryType { get; } + + public ParamValueType ValueType { get; } + + private readonly ICommandLineArgumentResolver m_valueResolver; + + public T Value { get; set; } + + public int Count { get; set; } + + public bool IsFound => Count > 0; + + public ParameterDefinition(string paramName, ParamMandatoryType mandatoryType, ParamValueType valueType, ICommandLineArgumentResolver valueResolver) + { + Name = paramName; + MandatoryType = mandatoryType; + ValueType = valueType; + m_valueResolver = valueResolver; + } + + public void Resolve(ref string[] args, ref int index) + { + Value = m_valueResolver.Resolve(ref args, ref index); + Count++; + } + + public bool CanResolve(ref string[] args, ref int index) + { + if (index < 0 || index >= args.Length) return false; + + return m_valueResolver.CanResolve(ref args, ref index); + } + + public void Reset() + { + Value = default; + Count = 0; + } + } +} diff --git a/UpdateLib/UpdateLib/Files/PathVariableConverter.cs b/UpdateLib/UpdateLib/Core/PathVariableConverter.cs similarity index 99% rename from UpdateLib/UpdateLib/Files/PathVariableConverter.cs rename to UpdateLib/UpdateLib/Core/PathVariableConverter.cs index 0e8b61e..575663f 100644 --- a/UpdateLib/UpdateLib/Files/PathVariableConverter.cs +++ b/UpdateLib/UpdateLib/Core/PathVariableConverter.cs @@ -20,7 +20,7 @@ using System.IO; using System.Text; -namespace MatthiWare.UpdateLib.Files +namespace MatthiWare.UpdateLib.Common { /// /// This will convert specified path variables to their actual path diff --git a/UpdateLib/UpdateLib/Core/UpdateInfo.cs b/UpdateLib/UpdateLib/Core/UpdateInfo.cs new file mode 100644 index 0000000..3395dda --- /dev/null +++ b/UpdateLib/UpdateLib/Core/UpdateInfo.cs @@ -0,0 +1,114 @@ +/* Copyright + * + * UpdateLib - .Net auto update library + * + * File: UpdateInfo.cs v0.5 + * + * Author: Matthias Beerens + * + * Copyright (C) 2018 - MatthiWare + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System; +using System.Xml.Serialization; + +namespace MatthiWare.UpdateLib.Common +{ + /// + /// An entry for the + /// + public class UpdateInfo : IComparable, IComparable + { + /// + /// Specifies the version this patch is based on. + /// This field can be null in case it is not a patch. + /// + public UpdateVersion BasedOnVersion { get; set; } + + /// + /// The version of the update/patch. + /// + public UpdateVersion Version { get; set; } + + /// + /// The file name. + /// + public string FileName { get; set; } + + /// + /// The meta file name. + /// + public string MetaFileName { get; set; } + + /// + /// The calculated hash for the update/patch. + /// + public string Hash { get; set; } + + /// + /// The calculated hash for the meta file. + /// + public string MetaHash { get; set; } + + /// + /// Indicates if this update is a patch. + /// + public bool IsPatch => BasedOnVersion != null; + + public UpdateInfo() { } + + /// + /// A new catalog entry + /// + /// The update version + /// The version this update is based on, can be null if it's not a patch. + /// The file name for the update. + /// The calculated hash for the update + public UpdateInfo(UpdateVersion version, UpdateVersion basedOnVersion, string fileName, string hash) + { + Version = version ?? throw new ArgumentNullException(nameof(version)); + FileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); + Hash = hash ?? throw new ArgumentNullException(nameof(hash)); + + BasedOnVersion = basedOnVersion; + + if (version <= basedOnVersion) throw new ArgumentOutOfRangeException(nameof(basedOnVersion), "The new version cannot be smaller than the version it was based on."); + } + + public int CompareTo(UpdateInfo other) + { + if (other == null) return -1; + + if (Version > other.Version) return -1; + + if (Version == other.Version) + { + if (IsPatch && other.IsPatch) return BasedOnVersion.CompareTo(other.BasedOnVersion); + + if (IsPatch && !other.IsPatch) return -1; + + if (!IsPatch && other.IsPatch) return 1; + + return 0; + } + + return 1; + } + + public int CompareTo(object obj) + => CompareTo(obj as UpdateInfo); + } +} diff --git a/UpdateLib/UpdateLib/Core/UpdateLibOptions.cs b/UpdateLib/UpdateLib/Core/UpdateLibOptions.cs new file mode 100644 index 0000000..70012c3 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/UpdateLibOptions.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MatthiWare.UpdateLib.Core +{ + public sealed class UpdateLibOptions + { + public string UpdateSilentArgumentName { get; set; } + public string UpdateArgumentName { get; set; } + public string WaitArgumentName { get; set; } + public string RollbackArgumentName { get; set; } + public string UpdateUrl { get; set; } + public string CommandLineArgumentPrefix { get; set; } + } +} diff --git a/UpdateLib/UpdateLib/Core/UpdateLibServiceBuilder.cs b/UpdateLib/UpdateLib/Core/UpdateLibServiceBuilder.cs new file mode 100644 index 0000000..272d090 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/UpdateLibServiceBuilder.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MatthiWare.UpdateLib.Core +{ + class UpdateLibServiceBuilder + { + } +} diff --git a/UpdateLib/UpdateLib/Core/UpdateVersion.cs b/UpdateLib/UpdateLib/Core/UpdateVersion.cs new file mode 100644 index 0000000..904f2f3 --- /dev/null +++ b/UpdateLib/UpdateLib/Core/UpdateVersion.cs @@ -0,0 +1,293 @@ +/* UpdateLib - .Net auto update library + * Copyright (C) 2016 - MatthiWare (Matthias Beerens) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Text.RegularExpressions; +using System.Xml; +using System.Xml.Serialization; + +namespace MatthiWare.UpdateLib.Common +{ + /// + /// Versioning class with small extensions over the original as the original is sealed. + /// Support for version label's and serializable. + /// Partially based on Semantic Versioning + /// + [DebuggerDisplay("{Value}")] + public class UpdateVersion : IComparable, IComparable, IEquatable + { + private int m_major, m_minor, m_patch; + private VersionLabel m_label; + + #region Constants + + private const string ALPHA_STRING = "-alpha"; + private const string BETA_STRING = "-beta"; + private const string RC_STRING = "-rc"; + private static readonly char[] CharSplitDot = new char[] { '.' }; + private static readonly char[] CharSplitDash = new char[] { '-' }; + private static readonly Regex m_regex = new Regex(@"([v]?[0-9]+){1}(\.[0-9]+){0,2}([-](alpha|beta|rc))?"); + + #endregion + + #region Properties + + public int Major => m_major; + + public int Minor => m_minor; + + public int Patch => m_patch; + + public VersionLabel Label => m_label; + + public string Value + { + get { return ToString(); } + set + { + UpdateVersion version; + + if (!TryParse(value, out version)) + throw new ArgumentException(nameof(value), "Unable to parse input string"); + + m_major = version.m_major; + m_minor = version.m_minor; + m_patch = version.m_patch; + m_label = version.m_label; + } + } + + #endregion + + #region Constructor + + public UpdateVersion() + : this(0, 0, 0, VersionLabel.None) + { } + + public UpdateVersion(int major) + : this(major, 0, 0, VersionLabel.None) + { } + + public UpdateVersion(int major, int minor) + : this(major, minor, 0, VersionLabel.None) + { } + + public UpdateVersion(int major, int minor, int patch) + : this(major, minor, patch, VersionLabel.None) + { } + + public UpdateVersion(int major, int minor, int patch, VersionLabel label) + { + if (major < 0) throw new ArgumentOutOfRangeException(nameof(major), "Version cannot be negative"); + if (minor < 0) throw new ArgumentOutOfRangeException(nameof(minor), "Version cannot be negative"); + if (patch < 0) throw new ArgumentOutOfRangeException(nameof(patch), "Version cannot be negative"); + + m_major = major; + m_minor = minor; + m_patch = patch; + m_label = label; + } + + public UpdateVersion(string input) + { + UpdateVersion version; + + if (!TryParse(input, out version)) + throw new ArgumentException(nameof(input), "Unable to parse input string"); + + m_major = version.m_major; + m_minor = version.m_minor; + m_patch = version.m_patch; + m_label = version.m_label; + } + + #endregion + + #region Interface Impl. + + public int CompareTo(UpdateVersion other) + { + if (other == null) + return 1; + + if (m_major != other.m_major) + return m_major > other.m_major ? 1 : -1; + + if (m_minor != other.m_minor) + return m_minor > other.m_minor ? 1 : -1; + + if (m_patch != other.m_patch) + return m_patch > other.m_patch ? 1 : -1; + + if (m_label != other.m_label) + return m_label > other.m_label ? 1 : -1; + + return 0; + } + + public int CompareTo(object obj) + { + UpdateVersion other = obj as UpdateVersion; + + if (other == null) + return 1; + + return CompareTo(other); + } + + public bool Equals(UpdateVersion other) + { + if (other == null) + return false; + + return m_major == other.m_major + && m_minor == other.m_minor + && m_patch == other.m_patch + && m_label == other.m_label; + } + + public override bool Equals(object obj) + => Equals(obj as UpdateVersion); + + public override int GetHashCode() + { + int hash = 269; + + hash = (hash * 47) + Major.GetHashCode(); + hash = (hash * 47) + Minor.GetHashCode(); + hash = (hash * 47) + Patch.GetHashCode(); + hash = (hash * 47) + Label.GetHashCode(); + + return hash; + } + + #endregion + + public override string ToString() => $"{m_major}.{m_minor}.{m_patch}{LabelToString()}"; + + private string LabelToString() + { + switch (m_label) + { + case VersionLabel.Alpha: + return ALPHA_STRING; + case VersionLabel.Beta: + return BETA_STRING; + case VersionLabel.RC: + return RC_STRING; + case VersionLabel.None: + default: + return string.Empty; + } + } + + private static bool TryParseVersionLabelString(string input, out VersionLabel label) + { + input = $"-{input}"; + + if (input == ALPHA_STRING) + { + label = VersionLabel.Alpha; + return true; + } + else if (input == BETA_STRING) + { + label = VersionLabel.Beta; + return true; + } + else if (input == RC_STRING) + { + label = VersionLabel.RC; + return true; + } + else + { + label = VersionLabel.None; + return false; + } + } + + public static bool CanParse(string input) + => m_regex.IsMatch(input); + + /// + /// Tries to parse the to a + /// + /// Input string should be of format "(v)major.minor.patch(-label)". The (v) and (-label) are optional + /// The output parameter + /// True if succesfully parsed, false if failed + public static bool TryParse(string input, out UpdateVersion version) + { + if (input.StartsWith("v")) + input = input.Substring(1, input.Length - 2); + + var tokens = input.Split(CharSplitDot); + version = new UpdateVersion(); + + if (tokens.Length > 3) // invalid version format, needs to be the following major.minor.patch(-label) + return false; + + if (tokens.Length > 2) + { + var extraTokens = tokens[2].Split(CharSplitDash); + + if (!int.TryParse(extraTokens[0], out version.m_patch)) + return false; + + if (extraTokens.Length > 1 && !TryParseVersionLabelString(extraTokens[1], out version.m_label)) // unable to parse the version label + return false; + + if (extraTokens.Length > 2) return false; // invalid, can only contain 1 version label string + } + + if (tokens.Length > 1 && !int.TryParse(tokens[1], out version.m_minor)) + return false; + + if (tokens.Length > 0 && !int.TryParse(tokens[0], out version.m_major)) + return false; + + return true; // everything parsed succesfully + } + + public static bool operator ==(UpdateVersion v1, UpdateVersion v2) + => ReferenceEquals(v1, null) ? ReferenceEquals(v2, null) : v1.Equals(v2); + + public static bool operator !=(UpdateVersion v1, UpdateVersion v2) + => !(v1 == v2); + + public static bool operator >(UpdateVersion v1, UpdateVersion v2) + => v2 < v1; + + public static bool operator >=(UpdateVersion v1, UpdateVersion v2) + => v2 <= v1; + + public static bool operator <(UpdateVersion v1, UpdateVersion v2) + => !ReferenceEquals(v1, null) && v1.CompareTo(v2) < 0; + + public static bool operator <=(UpdateVersion v1, UpdateVersion v2) + => !ReferenceEquals(v1, null) && v1.CompareTo(v2) <= 0; + + public static implicit operator UpdateVersion(string value) + => new UpdateVersion(value); + + public static implicit operator string(UpdateVersion version) + => version.Value; + } +} diff --git a/UpdateLib/UpdateLib/Encoders/IEncoder.cs b/UpdateLib/UpdateLib/Encoders/IEncoder.cs deleted file mode 100644 index 7b652a2..0000000 --- a/UpdateLib/UpdateLib/Encoders/IEncoder.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MatthiWare.UpdateLib.Encoders -{ - public interface IEncoder - { - } -} diff --git a/UpdateLib/UpdateLib/Files/CacheFile.cs b/UpdateLib/UpdateLib/Files/CacheFile.cs new file mode 100644 index 0000000..ef30f2c --- /dev/null +++ b/UpdateLib/UpdateLib/Files/CacheFile.cs @@ -0,0 +1,22 @@ +using System; + +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Common.Abstraction; +using MatthiWare.UpdateLib.Utils; + +namespace MatthiWare.UpdateLib.Files +{ + [Serializable] + public class CacheFile : FileBase + { + private static Lazy m_filePath = new Lazy(() => $"{IOUtils.AppDataPath}\\Cache.xml"); + + public UpdateVersion CurrentVersion { get; set; } + + public override CacheFile Load() + => Load(m_filePath.Value); + + public override void Save() + => Save(m_filePath.Value); + } +} diff --git a/UpdateLib/UpdateLib/Files/HashCacheFile.cs b/UpdateLib/UpdateLib/Files/HashCacheFile.cs index 8ad356f..b1beb82 100644 --- a/UpdateLib/UpdateLib/Files/HashCacheFile.cs +++ b/UpdateLib/UpdateLib/Files/HashCacheFile.cs @@ -15,20 +15,21 @@ * along with this program. If not, see . */ -using MatthiWare.UpdateLib.Utils; using System; using System.Collections.Generic; -using System.IO; -using System.Xml.Serialization; using System.Linq; +using System.Xml.Serialization; + +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Common.Abstraction; +using MatthiWare.UpdateLib.Utils; namespace MatthiWare.UpdateLib.Files { [Serializable] - public class HashCacheFile + public class HashCacheFile : FileBase { - public const string CACHE_FOLDER_NAME = "Cache"; - public const string FILE_NAME = "HashCacheFile.xml"; + public const string FILE_NAME = "Cache.xml"; [XmlArray("Items")] [XmlArrayItem("Entry")] @@ -52,81 +53,34 @@ public void AddOrUpdateEntry(string fullPath, string hash = "") { HashCacheEntry entry = Items.FirstOrDefault(f => f.FilePath == fullPath); + entry?.Recalculate(); + if (entry == null) { entry = new HashCacheEntry(fullPath); Items.Add(entry); } - else - entry.Recalculate(); - Updater.Instance.Logger.Debug(nameof(HashCacheFile), nameof(AddOrUpdateEntry), $"Cache updated for file -> '{entry.FilePath}'"); + //Updater.Instance.Logger.Debug(nameof(HashCacheFile), nameof(AddOrUpdateEntry), $"Cache updated for file -> '{entry.FilePath}'"); } } #region Save/Load - private static string GetStoragePath() - { - string path = IOUtils.AppDataPath; - - return $@"{path}\{CACHE_FOLDER_NAME}\{FILE_NAME}"; - } + private static string GetStoragePath() => $@"{IOUtils.CachePath}\{FILE_NAME}"; /// /// Loads the from the default storage location /// /// The loaded or null if it doesn't exist - public static HashCacheFile Load() - { - return Load(GetStoragePath()); - } - - /// - /// Loads the from the given storage location - /// - /// The storage location - /// The loaded or null if it doesn't exist - public static HashCacheFile Load(string path) - { - if (!File.Exists(path)) - return null; - - using (Stream stream = File.Open(path, FileMode.Open, FileAccess.Read)) - { - XmlSerializer serializer = new XmlSerializer(typeof(HashCacheFile)); - return (HashCacheFile)serializer.Deserialize(stream); - } - } + public override HashCacheFile Load() + => Load(GetStoragePath()); /// /// Saves the in the default storage location /// - public void Save() - { - Save(GetStoragePath()); - } - - /// - /// Saves the in the given storage location - /// - /// The storage location - public void Save(string path) - { - FileInfo fi = new FileInfo(path); - - if (!fi.Directory.Exists) - fi.Directory.Create(); - - if (fi.Exists) - fi.Delete(); + public override void Save() + => Save(GetStoragePath()); - - using (Stream stream = fi.Open(FileMode.OpenOrCreate, FileAccess.Write)) - { - XmlSerializer serializer = new XmlSerializer(typeof(HashCacheFile)); - serializer.Serialize(stream, this); - } - } #endregion } diff --git a/UpdateLib/UpdateLib/Files/RegistryKeyEntry.cs b/UpdateLib/UpdateLib/Files/RegistryKeyEntry.cs deleted file mode 100644 index 8051d72..0000000 --- a/UpdateLib/UpdateLib/Files/RegistryKeyEntry.cs +++ /dev/null @@ -1,55 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using Microsoft.Win32; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Security.AccessControl; -using System.Text; -using System.Xml.Serialization; - -namespace MatthiWare.UpdateLib.Files -{ - [Serializable] - [DebuggerDisplay("RegistryKeyEntry: {DestinationLocation}")] - public class RegistryKeyEntry : EntryBase - { - /// - /// The type of registry key - /// - [XmlAttribute] - public RegistryValueKind Type { get; set; } - - /// - /// The value of the key - /// - public object Value { get; set; } = "Test"; - - public RegistryKeyEntry() - : this(string.Empty, RegistryValueKind.String, null) - { } - - public RegistryKeyEntry(string name, RegistryValueKind type, object value) - { - Name = name; - Type = type; - Value = value; - } - } -} diff --git a/UpdateLib/UpdateLib/Files/UpdateCatalogFile.cs b/UpdateLib/UpdateLib/Files/UpdateCatalogFile.cs new file mode 100644 index 0000000..9e55b5c --- /dev/null +++ b/UpdateLib/UpdateLib/Files/UpdateCatalogFile.cs @@ -0,0 +1,80 @@ +/* Copyright + * + * UpdateLib - .Net auto update library + * + * File: UpdateCatalogFile.cs v0.5 + * + * Author: Matthias Beerens + * + * Copyright (C) 2017 - MatthiWare + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Xml.Serialization; + +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Common.Abstraction; + +namespace MatthiWare.UpdateLib.Files +{ + [Serializable, Description("Update Catalog File")] + public class UpdateCatalogFile : FileBase + { + public const string FILE_NAME = "catalogus.gz"; + + /// + /// Gets or sets the name of the application + /// + [XmlAttribute] + public string ApplicationName { get; set; } = "UpdateLib"; + + /// + /// Gets the Catalog + /// + public List Catalog { get; private set; } = new List(); + + /// + /// Download Url's + /// + public List DownloadUrls { get; private set; } = new List(); + + /// + /// Gets the best update for the current version. + /// + /// The currect application version + /// + public UpdateInfo GetLatestUpdateForVersion(UpdateVersion currentVersion) + { + if (currentVersion == null) throw new ArgumentNullException(nameof(currentVersion)); + + return Catalog.OrderBy(c => c).Where(c => currentVersion < c.Version && ((c.IsPatch && c.BasedOnVersion == currentVersion) || !c.IsPatch)).FirstOrDefault(); + } + + public override UpdateCatalogFile Load() => throw new NotImplementedException(); + + public override UpdateCatalogFile Load(Stream stream) + => base.Load(stream); + + public override void Save() => throw new NotImplementedException(); + + public override void Save(Stream stream) + => base.Save(stream); + } +} diff --git a/UpdateLib/UpdateLib/Files/UpdateFile.cs b/UpdateLib/UpdateLib/Files/UpdateFile.cs deleted file mode 100644 index 5c66f16..0000000 --- a/UpdateLib/UpdateLib/Files/UpdateFile.cs +++ /dev/null @@ -1,151 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Tasks; -using System; -using System.Collections.Generic; -using System.IO; -using System.Xml; -using System.Xml.Serialization; -using System.Linq; - -namespace MatthiWare.UpdateLib.Files -{ - /// - /// The UpdateFile - /// - [Serializable] - public class UpdateFile - { - /// - /// Gets or sets the name of the application - /// - [XmlAttribute] - public string ApplicationName { get; set; } = "UpdateLib"; - - /// - /// Gets or sets the version of the current update. - /// The versionstring should be parsable by the to be valid. - /// - [XmlAttribute] - public string VersionString { get; set; } = "1.0.0.0"; - - /// - /// Gets the folders of the project - /// - [XmlArray("Folders"), XmlArrayItem("Directory")] - public List Folders { get; set; } = new List(); - - /// - /// Gets the count of all the files in the - /// and their subdirectories. - /// - [XmlIgnore] - public int FileCount { get { return Folders.Select(d => d.Count).Sum(); } } - - [XmlIgnore] - public int RegistryKeyCount { get { return Registry.Select(r => r.Count).Sum(); } } - - [XmlArray("Registry"), XmlArrayItem("Directory")] - public List Registry { get; set; } = new List(); - - public UpdateFile() - { - } - - /// - /// Saves the current to the output - /// - /// The output to write the object to - public void Save(Stream output) - { - if (output == null) - throw new ArgumentNullException(nameof(output)); - - if (!output.CanWrite) - throw new ArgumentException("Stream is not writable", nameof(output)); - - XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); - // ns.Add(string.Empty, string.Empty); - - XmlSerializer serializer = new XmlSerializer(typeof(UpdateFile), string.Empty); - serializer.Serialize(output, this, ns); - } - - /// - /// Saves the current to a specified file. - /// This method will delete the file specified in the path parameter if it exists and recreates it. - /// - /// The path of the file where to save - public void Save(string path) - { - if (string.IsNullOrEmpty(path)) - throw new ArgumentNullException(nameof(path)); - - if (File.Exists(path)) - File.Delete(path); - - using (Stream s = File.Open(path, FileMode.OpenOrCreate, FileAccess.Write)) - Save(s); - } - - /// - /// Loads a from a input . - /// This method doesn't close/dispose the . - /// - /// The input that contains this object - /// The loaded instance of - public static UpdateFile Load(Stream input) - { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - if (!input.CanRead) - throw new ArgumentException("Stream is not readable", nameof(input)); - - XmlSerializer serializer = new XmlSerializer(typeof(UpdateFile)); - - XmlReader xml = new XmlTextReader(input); - - if (!serializer.CanDeserialize(xml)) - throw new InvalidOperationException("The current stream cannot be deserialized"); - - UpdateFile file = (UpdateFile)serializer.Deserialize(xml); - - new UpdateFileProcessorTask(file).ConfigureAwait(false).Start().AwaitTask(); - - return file; - } - - /// - /// Loads a from a path. - /// - /// The path to the save file - /// The loaded instance of - public static UpdateFile Load(string path) - { - if (string.IsNullOrEmpty(path)) - throw new ArgumentNullException(nameof(path)); - - if (!File.Exists(path)) - throw new FileNotFoundException("The UpdateFile doesn't exist.", path); - - using (Stream s = File.Open(path, FileMode.Open, FileAccess.Read)) - return Load(s); - } - } -} diff --git a/UpdateLib/UpdateLib/Files/UpdateMetadataFile.cs b/UpdateLib/UpdateLib/Files/UpdateMetadataFile.cs new file mode 100644 index 0000000..18473d3 --- /dev/null +++ b/UpdateLib/UpdateLib/Files/UpdateMetadataFile.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Xml.Serialization; + +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Common.Abstraction; + +namespace MatthiWare.UpdateLib.Files +{ + [Serializable, Description("Update Metadata File")] + public class UpdateMetadataFile : FileBase + { + + public const string FILE_NAME = "update-metadata.gz"; + + /// + /// Gets the folders of the project + /// + [XmlArray("Folders"), XmlArrayItem("Directory")] + public List Folders { get; private set; } = new List(); + + /// + /// Gets the count of all the files in the + /// and their subdirectories. + /// + [XmlIgnore] + public int FileCount => Folders.Sum(dir => dir.Count); + + [XmlIgnore] + public int RegistryKeyCount => Registry.Sum(reg => reg.Count); + + [XmlArray("Registry"), XmlArrayItem("Directory")] + public List Registry { get; private set; } = new List(); + + public UpdateMetadataFile() { } + + public override UpdateMetadataFile Load() => throw new NotImplementedException(); + + public override UpdateMetadataFile Load(Stream stream) + => base.Load(stream); + + public override void Save() => throw new NotImplementedException(); + + public override void Save(Stream stream) + => base.Save(stream); + } +} diff --git a/UpdateLib/UpdateLib/Logging/ILogWriter.cs b/UpdateLib/UpdateLib/Logging/ILogWriter.cs deleted file mode 100644 index d5a50b2..0000000 --- a/UpdateLib/UpdateLib/Logging/ILogWriter.cs +++ /dev/null @@ -1,28 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Common; - -namespace MatthiWare.UpdateLib.Logging -{ - public interface ILogWriter - { - LoggingLevel LoggingLevel { get; } - - void Log(string text); - } -} diff --git a/UpdateLib/UpdateLib/Logging/ILogger.cs b/UpdateLib/UpdateLib/Logging/ILogger.cs deleted file mode 100644 index 0699618..0000000 --- a/UpdateLib/UpdateLib/Logging/ILogger.cs +++ /dev/null @@ -1,35 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Common; -using System; -using System.Collections.Generic; - -namespace MatthiWare.UpdateLib.Logging -{ - public interface ILogger - { - LoggingLevel LogLevel { get; set; } - ICollection Writers { get; } - void Log(string tag, string msg, LoggingLevel level); - void Debug(string className, string methodName, string msg); - void Info(string className, string methodName, string msg); - void Warn(string className, string methodName, string msg); - void Error(string className, string methodName, string msg); - void Error(string className, string methodName, Exception e); - } -} diff --git a/UpdateLib/UpdateLib/Logging/Logger.cs b/UpdateLib/UpdateLib/Logging/Logger.cs deleted file mode 100644 index d93d950..0000000 --- a/UpdateLib/UpdateLib/Logging/Logger.cs +++ /dev/null @@ -1,68 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using MatthiWare.UpdateLib.Common; - -namespace MatthiWare.UpdateLib.Logging -{ - public class Logger : ILogger - { - public LoggingLevel LogLevel { get; set; } = LoggingLevel.Debug; - - public ICollection Writers { get; } = new List(); - - private const string TEMPLATE = "[{0}][{1}][{2}]: {3}"; - - public void Log(string tag, string msg, LoggingLevel level) - { - if (level < LogLevel) return; - - Writers - .Where(w => w.LoggingLevel >= LogLevel && level >= w.LoggingLevel) - .ToList() - .ForEach(w => w.Log(string.Format(TEMPLATE, DateTime.Now, level, tag, msg))); - } - - public void Debug(string className, string methodName, string msg) - { - Log($"{className}::{methodName}", msg, LoggingLevel.Debug); - } - - public void Info(string className, string methodName, string msg) - { - Log($"{className}::{methodName}", msg, LoggingLevel.Info); - } - - public void Warn(string className, string methodName, string msg) - { - Log($"{className}::{methodName}", msg, LoggingLevel.Warn); - } - - public void Error(string className, string methodName, string msg) - { - Log($"{className}::{methodName}", msg, LoggingLevel.Error); - } - - public void Error(string className, string methodName, Exception e) - { - Error(className, string.IsNullOrEmpty(methodName) ? e.TargetSite.Name : methodName, e.ToString()); - } - } -} diff --git a/UpdateLib/UpdateLib/Logging/Writers/ConsoleLogWriter.cs b/UpdateLib/UpdateLib/Logging/Writers/ConsoleLogWriter.cs deleted file mode 100644 index 102f0d5..0000000 --- a/UpdateLib/UpdateLib/Logging/Writers/ConsoleLogWriter.cs +++ /dev/null @@ -1,32 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Common; -using System.Diagnostics; - -namespace MatthiWare.UpdateLib.Logging.Writers -{ - public class ConsoleLogWriter : ILogWriter - { - public LoggingLevel LoggingLevel { get { return LoggingLevel.Debug; } } - - public void Log(string text) - { - Debug.WriteLine(text); - } - } -} diff --git a/UpdateLib/UpdateLib/Logging/Writers/FileLogWriter.cs b/UpdateLib/UpdateLib/Logging/Writers/FileLogWriter.cs deleted file mode 100644 index 5217052..0000000 --- a/UpdateLib/UpdateLib/Logging/Writers/FileLogWriter.cs +++ /dev/null @@ -1,67 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Common; -using MatthiWare.UpdateLib.Utils; -using System; -using System.IO; -using System.Reflection; - -namespace MatthiWare.UpdateLib.Logging.Writers -{ - public class FileLogWriter : ILogWriter - { - public const string LOG_FOLDER_NAME = "Log"; - - public LoggingLevel LoggingLevel { get { return LoggingLevel.Debug; } } - - private Lazy m_logFile = new Lazy(GetLogFile); - - private readonly object sync = new object(); - - private static FileInfo GetLogFile() - { - string path = IOUtils.AppDataPath; - string name = Assembly.GetEntryAssembly().GetName().Name; - - FileInfo m_logFile = new FileInfo($@"{path}\{LOG_FOLDER_NAME}\log_{DateTime.Now.ToString("yyyyMMdd")}.log"); - - if (!m_logFile.Directory.Exists) - m_logFile.Directory.Create(); - - return m_logFile; - } - - public void Log(string text) - { - Action logAction = new Action(LogAsync); - logAction.BeginInvoke(text, new AsyncCallback(r => logAction.EndInvoke(r)), null); - } - - private void LogAsync(string text) - { - lock (sync) - { - using (StreamWriter writer = new StreamWriter(m_logFile.Value.Open(FileMode.OpenOrCreate, FileAccess.Write))) - { - writer.BaseStream.Seek(0, SeekOrigin.End); - writer.WriteLine(text); - } - } - } - } -} diff --git a/UpdateLib/UpdateLib/Properties/AssemblyInfo.cs b/UpdateLib/UpdateLib/Properties/AssemblyInfo.cs index b8c7614..a1018ca 100644 --- a/UpdateLib/UpdateLib/Properties/AssemblyInfo.cs +++ b/UpdateLib/UpdateLib/Properties/AssemblyInfo.cs @@ -1,36 +1,17 @@ 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("UpdateLib")] [assembly: AssemblyDescription("Auto Update Library")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("MatthiWare")] -[assembly: AssemblyProduct("UpdateLib")] -[assembly: AssemblyCopyright("Copyright © MatthiWare 2016")] -[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)] +#if DEBUG +// Make sure the internal methods are available for unit testing +[assembly: InternalsVisibleTo("UpdateLib.Tests")] -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("4394be57-95e2-45b1-a968-1404b0590b35")] - -// 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 Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.4.3.0")] -[assembly: AssemblyFileVersion("0.4.3.0")] +[assembly: AssemblyConfiguration("DEBUG")] +#else +[assembly: AssemblyConfiguration("RELEASE")] +#endif diff --git a/UpdateLib/UpdateLib/Properties/Resources.Designer.cs b/UpdateLib/UpdateLib/Properties/Resources.Designer.cs deleted file mode 100644 index dc9696e..0000000 --- a/UpdateLib/UpdateLib/Properties/Resources.Designer.cs +++ /dev/null @@ -1,133 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MatthiWare.UpdateLib.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // 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() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [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("MatthiWare.UpdateLib.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap status_done { - get { - object obj = ResourceManager.GetObject("status_done", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap status_download { - get { - object obj = ResourceManager.GetObject("status_download", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap status_error { - get { - object obj = ResourceManager.GetObject("status_error", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap status_info { - get { - object obj = ResourceManager.GetObject("status_info", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap status_update { - get { - object obj = ResourceManager.GetObject("status_update", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap status_warning { - get { - object obj = ResourceManager.GetObject("status_warning", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap status_working { - get { - object obj = ResourceManager.GetObject("status_working", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } -} diff --git a/UpdateLib/UpdateLib/Properties/Resources.resx b/UpdateLib/UpdateLib/Properties/Resources.resx deleted file mode 100644 index acdb544..0000000 --- a/UpdateLib/UpdateLib/Properties/Resources.resx +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\status_done.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\status_download.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\status_error.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\status_info.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\status_update.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\status_warning.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\status_working.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib/Resources/project_16px.png b/UpdateLib/UpdateLib/Resources/project_16px.png deleted file mode 100644 index 25fe536..0000000 Binary files a/UpdateLib/UpdateLib/Resources/project_16px.png and /dev/null differ diff --git a/UpdateLib/UpdateLib/Resources/status_done.png b/UpdateLib/UpdateLib/Resources/status_done.png deleted file mode 100644 index 85e3c5a..0000000 Binary files a/UpdateLib/UpdateLib/Resources/status_done.png and /dev/null differ diff --git a/UpdateLib/UpdateLib/Resources/status_download.png b/UpdateLib/UpdateLib/Resources/status_download.png deleted file mode 100644 index f94bfe7..0000000 Binary files a/UpdateLib/UpdateLib/Resources/status_download.png and /dev/null differ diff --git a/UpdateLib/UpdateLib/Resources/status_error.png b/UpdateLib/UpdateLib/Resources/status_error.png deleted file mode 100644 index ecbd604..0000000 Binary files a/UpdateLib/UpdateLib/Resources/status_error.png and /dev/null differ diff --git a/UpdateLib/UpdateLib/Resources/status_info.png b/UpdateLib/UpdateLib/Resources/status_info.png deleted file mode 100644 index 7b0b0bf..0000000 Binary files a/UpdateLib/UpdateLib/Resources/status_info.png and /dev/null differ diff --git a/UpdateLib/UpdateLib/Resources/status_update.png b/UpdateLib/UpdateLib/Resources/status_update.png deleted file mode 100644 index f079371..0000000 Binary files a/UpdateLib/UpdateLib/Resources/status_update.png and /dev/null differ diff --git a/UpdateLib/UpdateLib/Resources/status_warning.png b/UpdateLib/UpdateLib/Resources/status_warning.png deleted file mode 100644 index f034744..0000000 Binary files a/UpdateLib/UpdateLib/Resources/status_warning.png and /dev/null differ diff --git a/UpdateLib/UpdateLib/Resources/status_working.png b/UpdateLib/UpdateLib/Resources/status_working.png deleted file mode 100644 index 6003cee..0000000 Binary files a/UpdateLib/UpdateLib/Resources/status_working.png and /dev/null differ diff --git a/UpdateLib/UpdateLib/Security/HashUtil.cs b/UpdateLib/UpdateLib/Security/HashUtil.cs index 8fd3bd0..7dc277f 100644 --- a/UpdateLib/UpdateLib/Security/HashUtil.cs +++ b/UpdateLib/UpdateLib/Security/HashUtil.cs @@ -16,8 +16,8 @@ */ using System; -using System.Security.Cryptography; using System.IO; +using System.Security.Cryptography; namespace MatthiWare.UpdateLib.Security { @@ -29,10 +29,7 @@ public static class HashUtil /// /// The input file to hash /// The hashed string - public static string GetHash(string file) - { - return GetHash(file); - } + public static string GetHash(string file) => GetHash(file); /// /// Gets the hash from file using the given hashing algorithm. @@ -48,12 +45,12 @@ public static string GetHash(string file) where T : HashAlgorithm if (!File.Exists(file)) throw new FileNotFoundException("File not found", file); - using (Stream stream = File.OpenRead(file)) + using (var stream = File.OpenRead(file)) { - using (HashAlgorithm algo = HashAlgorithm.Create(typeof(T).FullName)) + using (var algo = HashAlgorithm.Create(typeof(T).FullName)) { - byte[] hash = algo.ComputeHash(stream); - return BitConverter.ToString(hash).Replace("-", string.Empty); + var computedHash = algo.ComputeHash(stream); + return BitConverter.ToString(computedHash).Replace("-", string.Empty); } } } diff --git a/UpdateLib/UpdateLib/Security/PermissionUtil.cs b/UpdateLib/UpdateLib/Security/PermissionUtil.cs deleted file mode 100644 index bfe8d5d..0000000 --- a/UpdateLib/UpdateLib/Security/PermissionUtil.cs +++ /dev/null @@ -1,150 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Common; -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Utils; -using Microsoft.Win32; -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using System.Security.AccessControl; -using System.Security.Principal; - -namespace MatthiWare.UpdateLib.Security -{ - public static class PermissionUtil - { - - private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; - private const string uacRegistryValue = "EnableLUA"; - - private static uint STANDARD_RIGHTS_READ = 0x00020000; - private static uint TOKEN_QUERY = 0x0008; - private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); - - [DllImport("advapi32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle); - - [DllImport("advapi32.dll", SetLastError = true)] - private static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength); - - - - public static bool IsUacEnabled - { - get - { - return m_lazyIsUacEnabled.Value; - } - } - - public static bool IsProcessElevated - { - get - { - return m_lazyIsElevated.Value; - } - } - - private static Lazy m_lazyIsUacEnabled = new Lazy(() => - { - RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false); - bool result = uacKey.GetValue(uacRegistryValue).Equals(1); - return result; - }); - - private static Lazy m_lazyIsElevated = new Lazy(() => - { - if (IsUacEnabled) - { - IntPtr tokenHandle; - if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle)) - { - Updater.Instance.Logger.Warn(nameof(PermissionUtil), nameof(IsProcessElevated), "Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error()); - return false; - } - - TOKEN_ELEVATION_TYPE elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault; - - int elevationResultSize = Marshal.SizeOf((int)elevationResult); - uint returnedSize = 0; - IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize); - - bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint)elevationResultSize, out returnedSize); - if (success) - { - elevationResult = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(elevationTypePtr); - bool isProcessAdmin = elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull; - return isProcessAdmin; - } - else - { - Updater.Instance.Logger.Warn(nameof(PermissionUtil), nameof(IsProcessElevated), "Unable to determine the current elevation."); - return false; - } - } - else - { - WindowsIdentity identity = WindowsIdentity.GetCurrent(); - WindowsPrincipal principal = new WindowsPrincipal(identity); - bool result = principal.IsInRole(WindowsBuiltInRole.Administrator); - return result; - } - }); - - - public static bool DirectoryHasPermission(string dir, FileSystemRights accessRights = FileSystemRights.Modify) - { - if (string.IsNullOrEmpty(dir)) - return false; - - try - { - AuthorizationRuleCollection rules = Directory.GetAccessControl(dir).GetAccessRules(true, true, typeof(SecurityIdentifier)); - WindowsIdentity identity = WindowsIdentity.GetCurrent(); - - foreach (FileSystemAccessRule rule in rules) - if (identity.Groups.Contains(rule.IdentityReference) || rule.IdentityReference == identity.User) - if ((accessRights & rule.FileSystemRights) == accessRights && rule.AccessControlType == AccessControlType.Allow) - return true; - } - catch (Exception e) - { - Updater.Instance.Logger.Warn(nameof(PermissionUtil), nameof(DirectoryHasPermission), $"Current user has no access rights to: '{dir}'{Environment.NewLine}{e.ToString()}"); - } - - return false; - } - - public static bool CheckRegPermission(RegistryKeyEntry key) - { - try - { - RegistryHelper.InternalOpenSubKey(key.Parent.DestinationLocation, key.Name); - return true; - } - catch (Exception ex) - { - Updater.Instance.Logger.Error(nameof(PermissionUtil), nameof(CheckRegPermission), ex); - return false; - } - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/AsyncTask.cs b/UpdateLib/UpdateLib/Tasks/AsyncTask.cs deleted file mode 100644 index 8ad53f0..0000000 --- a/UpdateLib/UpdateLib/Tasks/AsyncTask.cs +++ /dev/null @@ -1,433 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Threading; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Threading; - -namespace MatthiWare.UpdateLib.Tasks -{ - /// - /// Base class for all Tasks that need to be run Async - /// - public abstract class AsyncTask - { - - #region private fields - - private Exception m_lastException = null; - - private bool m_useSyncContext = true; - private SynchronizationContext m_syncContext; - - internal bool IsChildTask { get; set; } = false; - -#if DEBUG - public Stopwatch m_sw = new Stopwatch(); -#endif - - private readonly ConcurrentQueue m_childTasks = new ConcurrentQueue(); - private ManualResetEvent m_waitHandle = new ManualResetEvent(true); - private readonly object sync = new object(); - - private bool m_running = false; - private bool m_cancelled = false; - private bool m_completed = false; - - #endregion - - #region events - - /// - /// Raises when this is completed. - /// - public event EventHandler TaskCompleted; - /// - /// Raises when the progress changed. - /// - public event EventHandler TaskProgressChanged; - - #endregion - - #region properties - - public Exception LastException - { - get - { - lock (sync) - return m_lastException; - } - protected set - { - lock (sync) - m_lastException = value; - } - } - - /// - /// Gets if there have been any errors in the task. - /// - public bool HasErrors - { - get - { - lock (sync) - return m_lastException != null; - } - } - - public bool IsCompleted - { - get - { - lock (sync) - return m_completed; - } - set - { - lock (sync) - m_completed = value; - } - } - - /// - /// Gets if the current is cancelled. - /// - public bool IsCancelled - { - get - { - lock (sync) - return m_cancelled; - } - private set - { - lock (sync) - m_cancelled = value; - } - } - - - public bool IsRunning - { - get - { - lock (sync) - return m_running; - } - private set - { - lock (sync) - m_running = value; - } - } - - #endregion - - #region static methods - - /// - /// Blocks the calling threads and calls on each in . - /// - /// The tasks to await. - public static void WaitAll(IEnumerable tasks) - { - foreach (AsyncTask task in tasks) - task.AwaitTask(); - } - - #endregion - - #region FluentAPI - - /// - /// Enable if we should switch back to the synchronization context to continue our Task completed. - /// - /// default is true. - /// Indicate if we should use the synchronization context - /// The task object for fluent API. - public AsyncTask ConfigureAwait(bool useSyncContext) - { - m_useSyncContext = useSyncContext; - return this; - } - - #endregion - - /// - /// Resets the task back to its initial state - /// - private void Reset() - { - IsCancelled = false; - IsRunning = false; - LastException = null; - IsCompleted = false; - - m_waitHandle.Reset(); - m_childTasks.Clear(); - -#if DEBUG - m_sw.Reset(); -#endif - } - - /// - /// Starts the task - /// - /// Returns the current Task. - public AsyncTask Start() - { - if (IsRunning) - return this; - - Reset(); - - m_syncContext = SynchronizationContext.Current; - - Action worker = new Action(() => - { - try - { - IsRunning = true; - DoWork(); - } - catch (Exception ex) - { - LastException = ex; - - Updater.Instance.Logger.Error(GetType().Name, null, ex); - } - finally - { - AwaitWorkers(); - IsRunning = false; - IsCompleted = true; - } - }); - -#if DEBUG - m_sw.Start(); -#endif - - worker.BeginInvoke(new AsyncCallback((IAsyncResult r) => - { -#if DEBUG - m_sw.Stop(); - Updater.Instance.Logger.Debug(GetType().Name, nameof(Start), $"Completed in {m_sw.ElapsedMilliseconds}ms"); -#endif - worker.EndInvoke(r); - - OnTaskCompleted(m_lastException, IsCancelled); - - m_waitHandle.Set(); - - }), null); ; - - return this; - } - - /// - /// The worker method. - /// - protected abstract void DoWork(); - - /// - /// Cancels the current - /// Check in the worker code to see if the got cancelled. - /// - public virtual void Cancel() - { - IsCancelled = true; - } - - /// - /// Adds a new inner task - /// - /// - /// Optional arguments for the action - protected void Enqueue(Delegate action, params object[] args) - { - // Don't allow to start another task when the parent task has been cancelled or contains errors. - if (HasErrors || IsCancelled) - return; - - AsyncTask task = AsyncTaskFactory.From(action, args); - task.IsChildTask = true; - task.TaskCompleted += (o, e) => - { - if (e.Error != null) - { - LastException = e.Error?.InnerException ?? e.Error; - - Updater.Instance.Logger.Error(GetType().Name, null, LastException); - } - }; - - m_childTasks.Enqueue(task); - - WorkerScheduler.Instance.Schedule(task); - } - - /// - /// Blocks the calling thread until the complete task is done. - /// DO NOT call this in the worker method use method instead. - /// - public AsyncTask AwaitTask() - { - if (IsChildTask && !IsCompleted && !IsRunning) - Reset(); - - if (m_waitHandle != null) - { - m_waitHandle.WaitOne(); - m_waitHandle.Close(); - m_waitHandle = null; - } - - return this; - } - - private int x = 0; - - /// - /// Blocks the calling thread until all the workers are done. - /// - protected void AwaitWorkers() - { - AsyncTask task = null; - while (m_childTasks.TryDequeue(out task)) - task.AwaitTask(); - } - - /// - /// Raises the event. - /// - /// The amount of work that is done. - /// The total amount of work. - protected virtual void OnTaskProgressChanged(int done, int total) - { - double percent = ((double)done / total) * 100; - OnTaskProgressChanged((int)percent); - } - - /// /// Raises the event. - /// - /// The percentage of work that is done. - protected virtual void OnTaskProgressChanged(int percent) - { - OnTaskProgressChanged(new ProgressChangedEventArgs(percent, null)); - } - - private int m_lastProgressUpdate = -1; - - /// - /// Raises the event. - /// - /// The event. - protected virtual void OnTaskProgressChanged(ProgressChangedEventArgs e) - { - // filter out redundant calls - if (m_lastProgressUpdate == e.ProgressPercentage) - return; - - m_lastProgressUpdate = e.ProgressPercentage; - - if (!m_useSyncContext || m_syncContext == null) - TaskProgressChanged?.Invoke(this, e); - else - m_syncContext.Post(new SendOrPostCallback((o) => TaskProgressChanged?.Invoke(this, e)), null); - - } - - /// - /// Raises the event. - /// - /// If an occured pass the object. - /// Indicates whether the got cancelled. - protected virtual void OnTaskCompleted(Exception e, bool cancelled = false) - { - OnTaskCompleted(new AsyncCompletedEventArgs(e, cancelled, null)); - } - - /// - /// Raises the event. - /// - /// The event. - protected virtual void OnTaskCompleted(AsyncCompletedEventArgs e) - { - if (!m_useSyncContext || m_syncContext == null) - TaskCompleted?.Invoke(this, e); - else - m_syncContext.Post(new SendOrPostCallback((o) => TaskCompleted?.Invoke(this, e)), null); - } - } - - /// - /// Base class for all Tasks that need to be run Async - /// - /// The type of the Result object - public abstract class AsyncTask : AsyncTask - { - /// - /// Gets or sets the result - /// - public virtual T Result { get; protected set; } - - #region FluentAPI - - /// - /// Enable if we should switch back to the synchronization context to continue our Task completed. - /// - /// default is true. - /// Indicate if we should use the synchronization context - /// The task object for fluent API. - public new AsyncTask ConfigureAwait(bool useSyncContext) - { - return (AsyncTask)base.ConfigureAwait(useSyncContext); - } - - /// - /// Starts the task - /// - /// Returns the current Task. - public new AsyncTask Start() - { - return (AsyncTask)base.Start(); - - } - - /// - /// Blocks the calling thread until the complete task is done. - /// DO NOT call this in the worker method use method instead. - /// - /// - public new AsyncTask AwaitTask() - { - return (AsyncTask)base.AwaitTask(); - - } - - #endregion - - - } -} diff --git a/UpdateLib/UpdateLib/Tasks/AsyncTaskFactory.cs b/UpdateLib/UpdateLib/Tasks/AsyncTaskFactory.cs deleted file mode 100644 index 088e68e..0000000 --- a/UpdateLib/UpdateLib/Tasks/AsyncTaskFactory.cs +++ /dev/null @@ -1,82 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class AsyncTaskFactory - { - - public static AsyncTask StartNew(Delegate action, params object[] args) - { - AnonymousTask task = new AnonymousTask(action, args); - return task.Start(); - } - - public static AsyncTask StartNew(Delegate action, params object[] args) - { - AnonymousTask task = new AnonymousTask(action, args); - return task.Start(); - } - - public static AsyncTask From(Delegate action, params object[] args) - { - return new AnonymousTask(action, args); - } - - public static AsyncTask From(Delegate action, params object[] args) - { - return new AnonymousTask(action, args); - } - - private class AnonymousTask : AsyncTask - { - private Delegate action; - private object[] args; - - public AnonymousTask(Delegate action, params object[] args) - { - this.action = action; - this.args = args; - } - - protected override void DoWork() - { - Result = (T)action.DynamicInvoke(args); - } - } - - private class AnonymousTask : AsyncTask - { - private Delegate action; - private object[] args; - - public AnonymousTask(Delegate action, params object[] args) - { - this.action = action; - this.args = args; - } - - protected override void DoWork() - { - action.DynamicInvoke(args); - } - } - - } -} diff --git a/UpdateLib/UpdateLib/Tasks/CheckForUpdatedItemsTask.cs b/UpdateLib/UpdateLib/Tasks/CheckForUpdatedItemsTask.cs deleted file mode 100644 index 839044b..0000000 --- a/UpdateLib/UpdateLib/Tasks/CheckForUpdatedItemsTask.cs +++ /dev/null @@ -1,103 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Utils; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class CheckForUpdatedItemsTask : AsyncTask - { - private UpdateFile m_updateFile; - private HashCacheFile m_cacheFile; - - public CheckForUpdatedItemsTask(UpdateFile update, HashCacheFile cache) - { - if (update == null) throw new ArgumentNullException(nameof(update)); - if (cache == null) throw new ArgumentNullException(nameof(cache)); - - m_updateFile = update; - m_cacheFile = cache; - } - - protected override void DoWork() - { - foreach (DirectoryEntry dir in m_updateFile.Folders) - Enqueue(new Action(CheckFiles), dir); - - foreach (DirectoryEntry dir in m_updateFile.Registry) - Enqueue(new Action(CheckRegister), dir); - - AwaitWorkers(); - - Result = m_updateFile.FileCount > 0 || m_updateFile.RegistryKeyCount > 0; - } - - private void CheckFiles(DirectoryEntry dir) - { - dir.Items.RemoveAll(fe => - { - string convertedPath = Updater.Instance.Converter.Convert(fe.DestinationLocation); - HashCacheEntry cacheEntry = m_cacheFile.Items.Find(hash => hash.FilePath.Equals(convertedPath)); - - if (cacheEntry == null) - return false; - - bool val = (fe as FileEntry).Hash.Equals(cacheEntry.Hash); - return val; - }); - - IEnumerable dirsToCheck = dir.Directories.Where(d => d.Count > 0); - int left = dirsToCheck.Count(); - - foreach (DirectoryEntry subDir in dir.Directories) - { - if (--left == 0) - CheckFiles(subDir); - else - Enqueue(new Action(CheckFiles), subDir); - } - } - - private void CheckRegister(DirectoryEntry dir) - { - dir.Items.RemoveAll(entry => - { - RegistryKeyEntry key = entry as RegistryKeyEntry; - - if (key == null) - return true; - - return RegistryHelper.IsSame(key); - }); - - IEnumerable dirsToCheck = dir.Directories.Where(d => d.Count > 0); - int left = dirsToCheck.Count(); - - foreach (DirectoryEntry subDir in dir.Directories) - { - if (--left == 0) - CheckRegister(subDir); - else - Enqueue(new Action(CheckRegister), dir); - } - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/CheckForUpdatesCompletedEventArgs.cs b/UpdateLib/UpdateLib/Tasks/CheckForUpdatesCompletedEventArgs.cs deleted file mode 100644 index 279e1cf..0000000 --- a/UpdateLib/UpdateLib/Tasks/CheckForUpdatesCompletedEventArgs.cs +++ /dev/null @@ -1,41 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.ComponentModel; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class CheckForUpdatesCompletedEventArgs : AsyncCompletedEventArgs - { - public string LatestVersion { get; set; } - public bool UpdateAvailable { get; set; } - - public CheckForUpdatesCompletedEventArgs(CheckForUpdatesTask.CheckForUpdatesResult result, Exception error, bool cancelled, object userState) - : base(error, cancelled, userState) - { - LatestVersion = result.Version; - UpdateAvailable = result.UpdateAvailable; - } - - public CheckForUpdatesCompletedEventArgs(CheckForUpdatesTask.CheckForUpdatesResult result, AsyncCompletedEventArgs e) - : this(result, e.Error, e.Cancelled, e.UserState) - { - - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/CheckForUpdatesTask.cs b/UpdateLib/UpdateLib/Tasks/CheckForUpdatesTask.cs deleted file mode 100644 index a4438fc..0000000 --- a/UpdateLib/UpdateLib/Tasks/CheckForUpdatesTask.cs +++ /dev/null @@ -1,124 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Net; -using MatthiWare.UpdateLib.Files; -using System.IO; -using MatthiWare.UpdateLib.Utils; -using static MatthiWare.UpdateLib.Tasks.CheckForUpdatesTask; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class CheckForUpdatesTask : AsyncTask - { - public string Url { get; set; } - - private WebClient wcDownloader; - - public CheckForUpdatesTask(string url) - { - if (string.IsNullOrEmpty(url)) throw new ArgumentNullException(nameof(url)); - - Url = url; - - wcDownloader = new WebClient(); - } - - protected override void DoWork() - { - if (string.IsNullOrEmpty(Url)) throw new WebException("Invalid Url", WebExceptionStatus.NameResolutionFailure); - - Result = new CheckForUpdatesResult(); - - Updater updater = Updater.Instance; - - if (!NetworkUtils.HasConnection()) throw new WebException("No internet available", WebExceptionStatus.ConnectFailure); - - // Getting the file name from the url - string localFile = $@"{IOUtils.AppDataPath}\Update.xml"; - - if (IsCancelled) - return; - - if (IsUpdateFileInvalid(localFile)) - { - updater.Logger.Warn(nameof(CheckForUpdatesTask), nameof(DoWork), "Cached update file validity expired, downloading new one.."); - wcDownloader.DownloadFile(Url, localFile); - } - - // load the updatefile from disk - Result.UpdateFile = UpdateFile.Load(localFile); - Result.Version = Result.UpdateFile.VersionString; - - CheckRequiredPrivilegesTask privilegesCheckTask = CheckPrivileges(Result.UpdateFile); - - // lets wait for the Cache update to complete and get the task - HashCacheFile cache = updater.GetCache(); - - // Wait for the clean up to complete - updater.CleanUpTask.AwaitTask(); - - if (IsCancelled) - return; - - /* - * Start a task to get all the files that need to be updated - * Returns if there is anything to update - */ - CheckForUpdatedItemsTask updatedFilesTask = CheckForUpdatedFiles(Result.UpdateFile, cache); - - Result.AdminRightsNeeded = privilegesCheckTask.AwaitTask().Result; - Result.UpdateAvailable = updatedFilesTask.AwaitTask().Result; - } - - private bool IsUpdateFileInvalid(string localFile) - { - if (!File.Exists(localFile)) - return true; - - DateTime time = File.GetLastWriteTime(localFile); - - if (time.Add(Updater.Instance.CacheInvalidationTime) < DateTime.Now) - return true; - - return false; - } - - private CheckForUpdatedItemsTask CheckForUpdatedFiles(UpdateFile file, HashCacheFile cache) - { - CheckForUpdatedItemsTask task = new CheckForUpdatedItemsTask(file, cache); - task.ConfigureAwait(false).Start(); - return task; - } - - private CheckRequiredPrivilegesTask CheckPrivileges(UpdateFile file) - { - CheckRequiredPrivilegesTask task = new CheckRequiredPrivilegesTask(file); - task.ConfigureAwait(false).Start(); - return task; - } - - public class CheckForUpdatesResult - { - public string Version { get; set; } = string.Empty; - public bool UpdateAvailable { get; set; } = false; - public UpdateFile UpdateFile { get; set; } - public bool AdminRightsNeeded { get; set; } = false; - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/CheckRequiredPrivilegesTask.cs b/UpdateLib/UpdateLib/Tasks/CheckRequiredPrivilegesTask.cs deleted file mode 100644 index 4262536..0000000 --- a/UpdateLib/UpdateLib/Tasks/CheckRequiredPrivilegesTask.cs +++ /dev/null @@ -1,83 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Security; -using System.Linq; -using MatthiWare.UpdateLib.Utils; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class CheckRequiredPrivilegesTask : AsyncTask - { - - public UpdateFile File { get; set; } - - public CheckRequiredPrivilegesTask(UpdateFile file) - { - File = file; - } - - protected override void DoWork() - { - Result = false; - - if (PermissionUtil.IsProcessElevated) - return; - - foreach (DirectoryEntry dir in File.Folders) - if (!CheckHasSufficientPermissionsForDirectory(dir)) - { - Result = true; - return; - } - - - foreach (DirectoryEntry dir in File.Registry) - if (!CheckHasSufficientPermissionForRegistry(dir)) - { - Result = true; - return; - } - - Updater.Instance.Logger.Info(nameof(CheckRequiredPrivilegesTask), nameof(DoWork), $"Elavation required: {Result}"); - } - - private bool CheckHasSufficientPermissionsForDirectory(DirectoryEntry dir) - { - string localPath = Updater.Instance.Converter.Convert(dir.DestinationLocation); - - if (!PermissionUtil.DirectoryHasPermission(localPath)) - return false; - - foreach (DirectoryEntry subDir in dir.Directories) - if (!CheckHasSufficientPermissionsForDirectory(subDir)) - return false; - - return true; - } - - private bool CheckHasSufficientPermissionForRegistry(DirectoryEntry dir) - { - foreach (RegistryKeyEntry key in dir.GetItems().Select(e => e as RegistryKeyEntry).NotNull()) - if (!PermissionUtil.CheckRegPermission(key)) - return false; - - return true; - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/CleanUpTask.cs b/UpdateLib/UpdateLib/Tasks/CleanUpTask.cs deleted file mode 100644 index 27f637e..0000000 --- a/UpdateLib/UpdateLib/Tasks/CleanUpTask.cs +++ /dev/null @@ -1,53 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.IO; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class CleanUpTask : AsyncTask - { - public string PathToClean { get; set; } - public string SearchPattern { get; set; } - public bool IncludeSubDirectories { get; set; } - - public CleanUpTask(string pathToCleanUp, string searchPattern = "*.old.tmp", bool includeSubDirs = true) - { - PathToClean = Updater.Instance.Converter.Convert(pathToCleanUp); - SearchPattern = searchPattern; - IncludeSubDirectories = includeSubDirs; - } - protected override void DoWork() - { - DirectoryInfo dir = new DirectoryInfo(PathToClean); - FileInfo[] files = dir.GetFiles(SearchPattern, IncludeSubDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); - - foreach (FileInfo file in files) - { - try - { - file.Delete(); - } - catch (Exception e) - { - Updater.Instance.Logger.Error(nameof(CleanUpTask), nameof(DoWork), e); - } - } - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/DownloadManager.cs b/UpdateLib/UpdateLib/Tasks/DownloadManager.cs deleted file mode 100644 index b17466e..0000000 --- a/UpdateLib/UpdateLib/Tasks/DownloadManager.cs +++ /dev/null @@ -1,134 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Threading; -using MatthiWare.UpdateLib.Utils; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class DownloadManager - { - private AtomicInteger amountToDownload = new AtomicInteger(); - private UpdateFile file; - - private List tasks = new List(); - private bool hasRegUpdate, hasErrors = false; - - public event EventHandler Completed; - - public DownloadManager(UpdateFile file) - { - amountToDownload.Value = file.FileCount; - this.file = file; - } - - private void Reset() - { - tasks.Clear(); - hasRegUpdate = false; - hasErrors = false; - } - - public void Update() - { - Reset(); - - AddUpdates(); - StartUpdate(); - } - - private void StartUpdate() - { - IEnumerable _tasks = tasks.Select(task => task as DownloadTask).NotNull(); - - _tasks.ForEach(task => task.Start()); - - if (hasRegUpdate && _tasks.Count() == 0) - StartRegUpdate(); - } - - private void StartRegUpdate() - { - tasks.Select(task => task as UpdateRegistryTask).NotNull().FirstOrDefault()?.Start(); - } - - private void AddUpdates() - { - foreach (FileEntry file in file.Folders - .SelectMany(dir => dir.GetItems()) - .Select(e => e as FileEntry) - .Distinct() - .NotNull()) - { - DownloadTask task = new DownloadTask(file); - task.TaskCompleted += Task_TaskCompleted; - - tasks.Add(task); - } - - IEnumerable keys = file.Registry - .SelectMany(dir => dir.GetItems()) - .Select(e => e as RegistryKeyEntry) - .Distinct() - .NotNull(); - - if (keys.Count() == 0) - return; - - hasRegUpdate = true; - amountToDownload.Increment(); - - UpdateRegistryTask regTask = new UpdateRegistryTask(keys); - regTask.TaskCompleted += Task_TaskCompleted; - - tasks.Add(regTask); - } - - private void Task_TaskCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) - { - if (e.Error != null) - { - hasErrors = true; - - CancelOtherTasks(); - } - - int left = amountToDownload.Decrement(); - - if (hasErrors) - return; - - if (hasRegUpdate && left == 1) - StartRegUpdate(); - else if (left == 0) - Completed?.Invoke(this, EventArgs.Empty); - - } - - private void CancelOtherTasks() - { - foreach (UpdatableTask task in tasks) - if (!task.IsCancelled) - task.Cancel(); - } - - } -} diff --git a/UpdateLib/UpdateLib/Tasks/DownloadTask.cs b/UpdateLib/UpdateLib/Tasks/DownloadTask.cs deleted file mode 100644 index 718516b..0000000 --- a/UpdateLib/UpdateLib/Tasks/DownloadTask.cs +++ /dev/null @@ -1,109 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Security; -using System; -using System.IO; -using System.Net; -using System.Threading; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class DownloadTask : UpdatableTask - { - private WebClient webClient; - private ManualResetEvent wait; - - public FileEntry Entry { get; private set; } - - public DownloadTask(FileEntry entry) - { - Entry = entry; - webClient = new WebClient(); - webClient.DownloadProgressChanged += (o, e) => { OnTaskProgressChanged(e.ProgressPercentage, 110); }; - webClient.DownloadFileCompleted += (o, e) => { wait.Set(); }; - } - - protected override void DoWork() - { - if (IsCancelled) - return; - - wait = new ManualResetEvent(false); - - string localFile = Updater.Instance.Converter.Convert(Entry.DestinationLocation); - string remoteFile = string.Concat(Updater.Instance.RemoteBasePath, Entry.SourceLocation); - - Updater.Instance.Logger.Debug(nameof(DownloadTask), nameof(DoWork), $"LocalFile => {localFile}"); - Updater.Instance.Logger.Debug(nameof(DownloadTask), nameof(DoWork), $"RemoteFile => {remoteFile}"); - - FileInfo fi = new FileInfo(localFile); - - if (fi.Exists) - fi.MoveTo($"{localFile}.old.tmp"); - - if (!fi.Directory.Exists) - fi.Directory.Create(); - - Uri uri = new Uri(remoteFile); - webClient.DownloadFileAsync(uri, localFile); - - wait.WaitOne(); - wait.Close(); - wait = null; - - string hash = HashUtil.GetHash(localFile); - - if (hash.Length != Entry.Hash.Length || hash != Entry.Hash) - throw new InvalidHashException($"Calculated hash doesn't match provided hash for file: {localFile}"); - - Updater.Instance.GetCache().AddOrUpdateEntry(localFile, hash); - - OnTaskProgressChanged(100); - } - - public override void Rollback() - { - OnTaskProgressChanged(0); - - webClient.CancelAsync(); - - string localFile = Updater.Instance.Converter.Convert(Entry.DestinationLocation); - string localTempFile = $"{localFile}.old.tmp"; - - if (!File.Exists(localTempFile)) - { - OnTaskProgressChanged(100); - return; - } - - if (File.Exists(localFile)) - File.Delete(localFile); - - File.Move(localTempFile, localFile); - - OnTaskProgressChanged(50); - - Updater.Instance.GetCache().AddOrUpdateEntry(localFile); - - Updater.Instance.Logger.Warn(nameof(DownloadTask), nameof(Cancel), $"Rolled back -> {Entry.Name}"); - - OnTaskProgressChanged(100); - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/UpdatableTask.cs b/UpdateLib/UpdateLib/Tasks/UpdatableTask.cs deleted file mode 100644 index b4fe7d7..0000000 --- a/UpdateLib/UpdateLib/Tasks/UpdatableTask.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -namespace MatthiWare.UpdateLib.Tasks -{ - public abstract class UpdatableTask : AsyncTask - { - private new void Start() - { - base.Start(); - } - - public void Update() - { - Start(); - } - - public override void Cancel() - { - base.Cancel(); - - Rollback(); - } - - public abstract void Rollback(); - - } -} diff --git a/UpdateLib/UpdateLib/Tasks/UpdateCacheTask.cs b/UpdateLib/UpdateLib/Tasks/UpdateCacheTask.cs deleted file mode 100644 index 9ebef2a..0000000 --- a/UpdateLib/UpdateLib/Tasks/UpdateCacheTask.cs +++ /dev/null @@ -1,117 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Utils; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class UpdateCacheTask : AsyncTask - { - private Dictionary existingEntries = null; - private IEnumerable files = null; - - protected override void DoWork() - { - existingEntries = new Dictionary(); - - try - { - // first of lets load the file, (file might be corrupt..) - Result = HashCacheFile.Load(); - - Result.Items.ForEach(e => existingEntries.Add(e, false)); - } - catch (Exception e) - { - Updater.Instance.Logger.Error(nameof(UpdateCacheTask), nameof(DoWork), e); - Result = null; - } - - DirectoryInfo dir = new DirectoryInfo(Updater.Instance.Converter.Convert("%appdir%")); - files = dir.GetFiles("*", SearchOption.AllDirectories).Where(f => !f.FullName.Contains(".old.tmp")); - - Updater.Instance.Logger.Debug(nameof(UpdateCacheTask), nameof(DoWork), $"found {files.Count()} files to recheck."); - - if (Result == null) // The file doesn't exist yet - { - Result = CreateNewHashCacheFile(); - - return; - } - - CheckFiles(); - - existingEntries.Where(e => e.Value == false).ForEach(e => Result.Items.Remove(e.Key)); - - Result.Save(); - } - - private void CheckFiles() - { - foreach (FileInfo f in files) - { - HashCacheEntry entry = Result.Items.Find(match => match.FilePath == f.FullName); - if (entry == null) - { - try - { - Result.Items.Add(new HashCacheEntry(f.FullName)); - } - catch (Exception ex) // file might no longer exist or is in use - { - Updater.Instance.Logger.Error(nameof(UpdateCacheTask), nameof(DoWork), ex); - } - - continue; - } - - existingEntries[entry] = true; - - // check to see if the file has been modified since last cache check - entry.Recalculate(); - } - } - - private HashCacheFile CreateNewHashCacheFile() - { - Updater.Instance.Logger.Warn(nameof(UpdateCacheTask), nameof(DoWork), $"{nameof(HashCacheFile)} doesn't exist. Creating.."); - - var result = new HashCacheFile(); - - foreach (FileInfo f in files) - { - try - { - result.Items.Add(new HashCacheEntry(f.FullName)); - } - catch (Exception ex) // file might no longer exist or is in use - { - Updater.Instance.Logger.Error(nameof(UpdateCacheTask), nameof(DoWork), ex); - } - } - - result.Save(); - - return result; - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/UpdateFileProcessorTask.cs b/UpdateLib/UpdateLib/Tasks/UpdateFileProcessorTask.cs deleted file mode 100644 index 81f0db6..0000000 --- a/UpdateLib/UpdateLib/Tasks/UpdateFileProcessorTask.cs +++ /dev/null @@ -1,61 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using System; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class UpdateFileProcessorTask : AsyncTask - { - private UpdateFile file; - - public UpdateFileProcessorTask(UpdateFile file) - { - this.file = file; - } - - - private void PostProcessDirectory(DirectoryEntry dir) - { - foreach (EntryBase file in dir.Items) - file.Parent = dir; - - int left = dir.Directories.Count; - foreach (DirectoryEntry subDir in dir.Directories) - { - subDir.Parent = dir; - - if (--left == 0) - PostProcessDirectory(subDir); - else - Enqueue(new Action(PostProcessDirectory), subDir); - } - } - - protected override void DoWork() - { - foreach (DirectoryEntry dir in file.Folders) - PostProcessDirectory(dir); - - foreach (DirectoryEntry dir in file.Registry) - PostProcessDirectory(dir); - - AwaitWorkers(); - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/UpdateRegistryTask.cs b/UpdateLib/UpdateLib/Tasks/UpdateRegistryTask.cs deleted file mode 100644 index 8dd66a7..0000000 --- a/UpdateLib/UpdateLib/Tasks/UpdateRegistryTask.cs +++ /dev/null @@ -1,125 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Utils; -using Microsoft.Win32; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MatthiWare.UpdateLib.Tasks -{ - public class UpdateRegistryTask : UpdatableTask - { - - public IEnumerable Keys { get; set; } - - private List cachedUpdates = new List(); - - public UpdateRegistryTask(IEnumerable keys) - { - Keys = keys; - } - - protected override void DoWork() - { - cachedUpdates.Clear(); - - int total = Keys.Count(); - int count = 0; - - foreach (RegistryKeyEntry key in Keys) - { - UpdateKey(key); - - OnTaskProgressChanged(++count, total); - } - } - - private void UpdateKey(RegistryKeyEntry key) - { - string path = key.Parent.DestinationLocation; - - RollbackData rollback = new RollbackData(key); - - cachedUpdates.Add(rollback); - - RegistryHelper.Update(key, rollback); - - Updater.Instance.Logger.Info(nameof(UpdateRegistryTask), nameof(UpdateKey), - $"Succesfully updated {key.DestinationLocation}"); - } - - public override void Rollback() - { - int total = cachedUpdates.Count; - int count = 0; - - foreach (RollbackData data in cachedUpdates) - { - RollbackFailSafe(data); - - OnTaskProgressChanged(++count, total); - } - } - - private void RollbackFailSafe(RollbackData data) - { - try - { - RegistryKey key = RegistryHelper.GetOrMakeKey(data.path); - - if (!data.existed) - { - key.DeleteValue(data.key); - - Updater.Instance.Logger.Warn(nameof(UpdateRegistryTask), nameof(Rollback), - $"Deleted -> {data.path}\\{data.key}"); - - return; - } - - key.SetValue(data.key, data.cachedValue, data.type); - - Updater.Instance.Logger.Warn(nameof(UpdateRegistryTask), nameof(Rollback), - $"Rolled back -> {data.path}\\{data.key}"); - } - catch (Exception e) - { - Updater.Instance.Logger.Error(nameof(UpdateRegistryTask), nameof(Rollback), e); - } - } - - public struct RollbackData - { - public bool existed; - public string path; - public string key; - public object cachedValue; - public RegistryValueKind type; - - public RollbackData(RegistryKeyEntry l_key) - { - key = l_key.Name; - path = l_key.Parent.DestinationLocation; - existed = RegistryHelper.Exists(l_key, out cachedValue); - type = RegistryValueKind.Unknown; - } - } - } -} diff --git a/UpdateLib/UpdateLib/Tasks/WorkerScheduler.cs b/UpdateLib/UpdateLib/Tasks/WorkerScheduler.cs deleted file mode 100644 index 41b5ce9..0000000 --- a/UpdateLib/UpdateLib/Tasks/WorkerScheduler.cs +++ /dev/null @@ -1,121 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Threading; -using System; -using System.Threading; - -namespace MatthiWare.UpdateLib.Tasks -{ - internal class WorkerScheduler - { - - #region Singleton - private static volatile WorkerScheduler instance = null; - private static readonly object synclock = new object(); - - /// - /// Gets a thread safe instance of - /// - public static WorkerScheduler Instance - { - get - { - if (instance == null) - lock (synclock) - if (instance == null) - instance = new WorkerScheduler(); - - return instance; - } - } - #endregion - - #region Fields - - private readonly long MAX_WORKERS; - private readonly ConcurrentQueue m_taskQueue; - private readonly AtomicInteger m_currentWorkerCount; - private readonly AsyncTask m_dispatcherTask; - private readonly ManualResetEvent m_waitForAvailableWorker; - private readonly object sync = new object(); - - public const long MIN_WORKERS = 8; - - #endregion - - private WorkerScheduler() - { - MAX_WORKERS = Math.Max(Environment.ProcessorCount, MIN_WORKERS); - m_taskQueue = new ConcurrentQueue(); - m_dispatcherTask = AsyncTaskFactory.From(new Action(Dispatcher), null); - m_waitForAvailableWorker = new ManualResetEvent(true); - m_currentWorkerCount = new AtomicInteger(); - } - - public void Schedule(AsyncTask task) - { - Enqueue(task); - - lock (synclock) - if (!m_dispatcherTask.IsRunning) - m_dispatcherTask.Start(); - } - - private void Dispatcher() - { - AsyncTask task = null; - while (m_taskQueue.TryDequeue(out task)) - { - lock (sync) - { - if (task.IsCompleted || task.IsCancelled || task.HasErrors) - continue; - - SetupTask(task); - - if (m_currentWorkerCount.Value >= MAX_WORKERS) - m_waitForAvailableWorker.Reset(); - - m_waitForAvailableWorker.WaitOne(); - - Updater.Instance.Logger.Debug(nameof(WorkerScheduler), nameof(Dispatcher), $"Current worker count: {m_currentWorkerCount.Increment()} | Current queue count: {m_taskQueue.Count}"); - - task.ConfigureAwait(false).Start(); - } - } - } - - private void SetupTask(AsyncTask task) - { - task.TaskCompleted += (o, e) => - { - - if (m_currentWorkerCount.Decrement() < MAX_WORKERS) - m_waitForAvailableWorker.Set(); - - Updater.Instance.Logger.Debug(nameof(WorkerScheduler), nameof(Dispatcher), $"Current worker count: {m_currentWorkerCount}"); - }; - } - - private void Enqueue(AsyncTask task) - { - m_taskQueue.Enqueue(task); - } - - } -} diff --git a/UpdateLib/UpdateLib/UI/Components/ChangelogPage.Designer.cs b/UpdateLib/UpdateLib/UI/Components/ChangelogPage.Designer.cs deleted file mode 100644 index 55dbc85..0000000 --- a/UpdateLib/UpdateLib/UI/Components/ChangelogPage.Designer.cs +++ /dev/null @@ -1,83 +0,0 @@ -namespace MatthiWare.UpdateLib.UI.Components -{ - partial class ChangelogPage - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ChangelogPage)); - this.txtTitle = new System.Windows.Forms.Label(); - this.richTextBox1 = new System.Windows.Forms.RichTextBox(); - this.SuspendLayout(); - // - // txtTitle - // - this.txtTitle.AutoSize = true; - this.txtTitle.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtTitle.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(129)))), ((int)(((byte)(181))))); - this.txtTitle.Location = new System.Drawing.Point(12, 12); - this.txtTitle.Name = "txtTitle"; - this.txtTitle.Size = new System.Drawing.Size(224, 25); - this.txtTitle.TabIndex = 1; - this.txtTitle.Text = "Changelog / Patchnotes"; - // - // richTextBox1 - // - this.richTextBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.richTextBox1.BackColor = System.Drawing.SystemColors.Window; - this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.richTextBox1.Cursor = System.Windows.Forms.Cursors.IBeam; - this.richTextBox1.Location = new System.Drawing.Point(14, 52); - this.richTextBox1.Name = "richTextBox1"; - this.richTextBox1.ReadOnly = true; - this.richTextBox1.Size = new System.Drawing.Size(612, 359); - this.richTextBox1.TabIndex = 2; - this.richTextBox1.Text = resources.GetString("richTextBox1.Text"); - // - // ChangelogPage - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.Window; - this.Controls.Add(this.richTextBox1); - this.Controls.Add(this.txtTitle); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.Name = "ChangelogPage"; - this.Size = new System.Drawing.Size(637, 425); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label txtTitle; - private System.Windows.Forms.RichTextBox richTextBox1; - } -} diff --git a/UpdateLib/UpdateLib/UI/Components/ChangelogPage.cs b/UpdateLib/UpdateLib/UI/Components/ChangelogPage.cs deleted file mode 100644 index cad8560..0000000 --- a/UpdateLib/UpdateLib/UI/Components/ChangelogPage.cs +++ /dev/null @@ -1,127 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.UI.Components -{ - public partial class ChangelogPage : UserControl, IWizardPage - { - public ChangelogPage(UpdaterForm parent) - { - InitializeComponent(); - - _updaterForm = parent; - } - - public UserControl Conent - { - get - { - return this; - } - } - - - - public bool NeedsCancel - { - get - { - return false; - } - } - - public bool NeedsExecution - { - get - { - return false; - } - } - - public string Title - { - get - { - return txtTitle.Text; - } - } - - private UpdaterForm _updaterForm; - public UpdaterForm UpdaterForm - { - get - { - return _updaterForm; - } - } - - private bool _isbusy; - public bool IsBusy - { - get - { - return _isbusy; - } - - set - { - _isbusy = value; - } - } - - public bool IsDone - {get;set; - } - - public bool HasErrors - { - get; set; - } - - public void PageEntered() - { - IsDone = true; - } - - public event EventHandler PageUpdate; - - public bool NeedsRollBack { get { return false; } } - - public void UpdateState() - { - - } - - public void Cancel() - { - IsDone = true; - } - - public void Execute() - { - throw new NotImplementedException(); - } - - public void Rollback() - { - - } - } -} diff --git a/UpdateLib/UpdateLib/UI/Components/ChangelogPage.resx b/UpdateLib/UpdateLib/UI/Components/ChangelogPage.resx deleted file mode 100644 index 35f5067..0000000 --- a/UpdateLib/UpdateLib/UI/Components/ChangelogPage.resx +++ /dev/null @@ -1,235 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - # Change Log -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/) -and this project adheres to [Semantic Versioning](http://semver.org/). - -## [Unreleased] -### Added -- zh-CN and zh-TW translations from @tianshuo. -- de translation from @mpbzh. -- it-IT translation from @roalz. -- sv translation from @magol. -- tr-TR translation from @karalamalar. -- fr translation from @zapashcanon. - -### Changed -- Start versioning based on the current English version at 0.3.0 to help -translation authors keep things up-to-date. -- Fix typos in zh-CN translation. -- Fix typos in pt-BR translation. - -## [0.3.0] - 2015-12-03 -### Added -- RU translation from @aishek. -- pt-BR translation from @tallesl. -- es-ES translation from @ZeliosAriex. - -## [0.2.0] - 2015-10-06 -### Changed -- Remove exclusionary mentions of "open source" since this project can benefit -both "open" and "closed" source projects equally. - -## [0.1.0] - 2015-10-06 -### Added -- Answer "Should you ever rewrite a change log?". - -### Changed -- Improve argument against commit logs. -- Start following [SemVer](http://semver.org) properly. - -## [0.0.8] - 2015-02-17 -### Changed -- Update year to match in every README example. -- Reluctantly stop making fun of Brits only, since most of the world - writes dates in a strange way. - -### Fixed -- Fix typos in recent README changes. -- Update outdated unreleased diff link. - -## [0.0.7] - 2015-02-16 -### Added -- Link, and make it obvious that date format is ISO 8601. - -### Changed -- Clarified the section on "Is there a standard change log format?". - -### Fixed -- Fix Markdown links to tag comparison URL with footnote-style links. - -## [0.0.6] - 2014-12-12 -### Added -- README section on "yanked" releases. - -## [0.0.5] - 2014-08-09 -### Added -- Markdown links to version tags on release headings. -- Unreleased section to gather unreleased changes and encourage note -keeping prior to releases. - -## [0.0.4] - 2014-08-09 -### Added -- Better explanation of the difference between the file ("CHANGELOG") -and its function "the change log". - -### Changed -- Refer to a "change log" instead of a "CHANGELOG" throughout the site -to differentiate between the file and the purpose of the file - the -logging of changes. - -### Removed -- Remove empty sections from CHANGELOG, they occupy too much space and -create too much noise in the file. People will have to assume that the -missing sections were intentionally left out because they contained no -notable changes. - -## [0.0.3] - 2014-08-09 -### Added -- "Why should I care?" section mentioning The Changelog podcast. - -## [0.0.2] - 2014-07-10 -### Added -- Explanation of the recommended reverse chronological release ordering. - -## 0.0.1 - 2014-05-31 -### Added -- This CHANGELOG file to hopefully serve as an evolving example of a standardized open source project CHANGELOG. -- CNAME file to enable GitHub Pages custom domain -- README now contains answers to common questions about CHANGELOGs -- Good examples and basic guidelines, including proper date formatting. -- Counter-examples: "What makes unicorns cry?" - -[Unreleased]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.3.0...HEAD -[0.3.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.2.0...v0.3.0 -[0.2.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.1.0...v0.2.0 -[0.1.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.8...v0.1.0 -[0.0.8]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.7...v0.0.8 -[0.0.7]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.6...v0.0.7 -[0.0.6]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.5...v0.0.6 -[0.0.5]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.4...v0.0.5 -[0.0.4]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.3...v0.0.4 -[0.0.3]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.2...v0.0.3 -[0.0.2]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.1...v0.0.2 - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib/UI/Components/FinishPage.Designer.cs b/UpdateLib/UpdateLib/UI/Components/FinishPage.Designer.cs deleted file mode 100644 index e58fabf..0000000 --- a/UpdateLib/UpdateLib/UI/Components/FinishPage.Designer.cs +++ /dev/null @@ -1,97 +0,0 @@ -namespace MatthiWare.UpdateLib.UI.Components -{ - partial class FinishPage - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FinishPage)); - this.txtFinished = new System.Windows.Forms.Label(); - this.txtDescription = new System.Windows.Forms.Label(); - this.cbRestart = new System.Windows.Forms.CheckBox(); - this.SuspendLayout(); - // - // txtFinished - // - this.txtFinished.AutoSize = true; - this.txtFinished.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtFinished.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(129)))), ((int)(((byte)(181))))); - this.txtFinished.Location = new System.Drawing.Point(12, 12); - this.txtFinished.Name = "txtFinished"; - this.txtFinished.Size = new System.Drawing.Size(85, 25); - this.txtFinished.TabIndex = 0; - this.txtFinished.Text = "Finished"; - // - // txtDescription - // - this.txtDescription.AutoSize = true; - this.txtDescription.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtDescription.Location = new System.Drawing.Point(14, 52); - this.txtDescription.Name = "txtDescription"; - this.txtDescription.Size = new System.Drawing.Size(433, 136); - this.txtDescription.TabIndex = 1; - this.txtDescription.Text = resources.GetString("txtDescription.Text"); - // - // cbRestart - // - this.cbRestart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.cbRestart.AutoSize = true; - this.cbRestart.Checked = true; - this.cbRestart.CheckState = System.Windows.Forms.CheckState.Checked; - this.cbRestart.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.cbRestart.Location = new System.Drawing.Point(17, 202); - this.cbRestart.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.cbRestart.Name = "cbRestart"; - this.cbRestart.Size = new System.Drawing.Size(136, 21); - this.cbRestart.TabIndex = 2; - this.cbRestart.Text = "Restart application"; - this.cbRestart.UseVisualStyleBackColor = true; - this.cbRestart.CheckedChanged += new System.EventHandler(this.cbRestart_CheckedChanged); - // - // FinishPage - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.Window; - this.Controls.Add(this.cbRestart); - this.Controls.Add(this.txtDescription); - this.Controls.Add(this.txtFinished); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.Name = "FinishPage"; - this.Size = new System.Drawing.Size(701, 245); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label txtFinished; - private System.Windows.Forms.Label txtDescription; - private System.Windows.Forms.CheckBox cbRestart; - } -} diff --git a/UpdateLib/UpdateLib/UI/Components/FinishPage.cs b/UpdateLib/UpdateLib/UI/Components/FinishPage.cs deleted file mode 100644 index 75413fd..0000000 --- a/UpdateLib/UpdateLib/UI/Components/FinishPage.cs +++ /dev/null @@ -1,169 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using System; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.UI.Components -{ - public partial class FinishPage : UserControl, IWizardPage - { - public FinishPage(UpdaterForm parent) - { - InitializeComponent(); - - _updaterForm = parent; - - txtDescription.Text = txtDescription.Text.Replace("%AppName%", parent.updateInfoFile.ApplicationName); - txtDescription.Text = txtDescription.Text.Replace("%version%", parent.updateInfoFile.VersionString); - } - - public void UpdateState() - { - if (_updaterForm.hasHadErrors) - { - cbRestart.Checked = false; - cbRestart.Enabled = false; - - UpdateFile file = _updaterForm.updateInfoFile; - - txtDescription.Text = $"{file.ApplicationName} was unable to update to version {file.VersionString}!\n\n" + - "Check the log files for more information!\n\n" + - "Press Finish to close this wizard."; - - txtFinished.Text = "Finished (with errors)"; - } - else if (_updaterForm.UserCancelled) - { - cbRestart.Checked = false; - cbRestart.Enabled = false; - - UpdateFile file = _updaterForm.updateInfoFile; - - txtDescription.Text = $"{file.ApplicationName} was unable to update to version {file.VersionString}!\n\n" + - "Update process cancelled by the user.\n\n" + - "Press Finish to close this wizard."; - - txtFinished.Text = "Finished (cancelled)"; - } - } - - public UserControl Conent - { - get - { - return this; - } - } - - private bool _isbusy; - public bool IsBusy - { - get - { - return _isbusy; - } - - set - { - _isbusy = value; - } - } - - private bool _isdone; - public bool IsDone - { - get - { - return _isdone; - } - - set - { - _isdone = value; - } - } - - public void PageEntered() - { - IsDone = true; - } - - public bool NeedsCancel - { - get - { - return false; - } - } - - public bool NeedsExecution - { - get - { - return false; - } - } - - public string Title - { - get - { - return txtFinished.Text; - } - } - - private UpdaterForm _updaterForm; - public UpdaterForm UpdaterForm - { - get - { - return _updaterForm; - } - } - - public bool NeedsRollBack { get { return false; } } - - public bool HasErrors - { - get; set; - } - - public event EventHandler PageUpdate; - - public void Cancel() - { - IsDone = true; - } - - public void Execute() - { - throw new NotImplementedException(); - } - - private void cbRestart_CheckedChanged(object sender, EventArgs e) - { - UpdaterForm.NeedsRestart = cbRestart.Checked; - } - - public void Rollback() - { - - } - } -} diff --git a/UpdateLib/UpdateLib/UI/Components/FinishPage.resx b/UpdateLib/UpdateLib/UI/Components/FinishPage.resx deleted file mode 100644 index 166646a..0000000 --- a/UpdateLib/UpdateLib/UI/Components/FinishPage.resx +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - %AppName% has been succesfully updated to version %version%. - -%AppName% needs to restart for the changes to take effect. - -If you do not want this you can uncheck the Restart application checkbox. - -Press Finish to close this wizard. - - - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib/UI/Components/IntroPage.Designer.cs b/UpdateLib/UpdateLib/UI/Components/IntroPage.Designer.cs deleted file mode 100644 index 8c406d0..0000000 --- a/UpdateLib/UpdateLib/UI/Components/IntroPage.Designer.cs +++ /dev/null @@ -1,77 +0,0 @@ -namespace MatthiWare.UpdateLib.UI.Components -{ - partial class IntroPage - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(IntroPage)); - this.txtWelcome = new System.Windows.Forms.Label(); - this.txtDesc = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // txtWelcome - // - this.txtWelcome.AutoSize = true; - this.txtWelcome.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtWelcome.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(129)))), ((int)(((byte)(181))))); - this.txtWelcome.Location = new System.Drawing.Point(12, 12); - this.txtWelcome.Name = "txtWelcome"; - this.txtWelcome.Size = new System.Drawing.Size(360, 25); - this.txtWelcome.TabIndex = 0; - this.txtWelcome.Text = "Welcome to the %AppName% Updater!"; - // - // txtDesc - // - this.txtDesc.AutoSize = true; - this.txtDesc.Location = new System.Drawing.Point(14, 52); - this.txtDesc.Name = "txtDesc"; - this.txtDesc.Size = new System.Drawing.Size(425, 119); - this.txtDesc.TabIndex = 1; - this.txtDesc.Text = resources.GetString("txtDesc.Text"); - // - // IntroPage - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.Window; - this.Controls.Add(this.txtDesc); - this.Controls.Add(this.txtWelcome); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.Name = "IntroPage"; - this.Size = new System.Drawing.Size(515, 232); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label txtWelcome; - private System.Windows.Forms.Label txtDesc; - } -} diff --git a/UpdateLib/UpdateLib/UI/Components/IntroPage.cs b/UpdateLib/UpdateLib/UI/Components/IntroPage.cs deleted file mode 100644 index 02fcc62..0000000 --- a/UpdateLib/UpdateLib/UI/Components/IntroPage.cs +++ /dev/null @@ -1,138 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.UI.Components -{ - public partial class IntroPage : UserControl, IWizardPage - { - public IntroPage(UpdaterForm parent) - { - InitializeComponent(); - - _updateForm = parent; - - txtDesc.Text = txtDesc.Text.Replace("%AppName%", parent.updateInfoFile.ApplicationName); - txtWelcome.Text = txtWelcome.Text.Replace("%AppName%", parent.updateInfoFile.ApplicationName); - } - - public UserControl Conent - { - get - { - return this; - } - } - - private bool _isbusy; - public bool IsBusy - { - get - { - return _isbusy; - } - - set - { - _isbusy = value; - } - } - - private bool _isdone; - public bool IsDone - { - get - { - return _isdone; - } - - set - { - _isdone = value; - } - } - - public void PageEntered() - { - IsDone = true; - } - - public bool NeedsCancel - { - get - { - return false; - } - } - - public bool NeedsExecution - { - get - { - return false; - } - } - - public string Title - { - get - { - return txtWelcome.Text; - } - } - - private UpdaterForm _updateForm; - public UpdaterForm UpdaterForm - { - get - { - return _updateForm; - } - } - - public bool HasErrors - { - get; set; - } - - public event EventHandler PageUpdate; - - public void UpdateState() - { - - } - - public bool NeedsRollBack { get { return false; } } - - public void Cancel() - { - IsDone = true; - } - - public void Execute() - { - throw new NotImplementedException(); - } - - public void Rollback() - { - - } - } -} diff --git a/UpdateLib/UpdateLib/UI/Components/IntroPage.resx b/UpdateLib/UpdateLib/UI/Components/IntroPage.resx deleted file mode 100644 index 94af550..0000000 --- a/UpdateLib/UpdateLib/UI/Components/IntroPage.resx +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - This wizard will guide you throug the update process of %AppName%. - -To return to the previous screen, click Previous. - -To cancel the update process at any time, click Cancel. - -Click Next to continue. - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib/UI/Components/UpdatePage.Designer.cs b/UpdateLib/UpdateLib/UI/Components/UpdatePage.Designer.cs deleted file mode 100644 index 8aec832..0000000 --- a/UpdateLib/UpdateLib/UI/Components/UpdatePage.Designer.cs +++ /dev/null @@ -1,142 +0,0 @@ -namespace MatthiWare.UpdateLib.UI.Components -{ - partial class UpdatePage - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.lblHeader = new System.Windows.Forms.Label(); - this.lblSubheader = new System.Windows.Forms.Label(); - this.lvItems = new System.Windows.Forms.ListView(); - this.clmnName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnStatus = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnProgress = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnDescription = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.clmnPath = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.ilIcons = new System.Windows.Forms.ImageList(this.components); - this.SuspendLayout(); - // - // lblHeader - // - this.lblHeader.AutoSize = true; - this.lblHeader.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblHeader.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(129)))), ((int)(((byte)(181))))); - this.lblHeader.Location = new System.Drawing.Point(14, 14); - this.lblHeader.Name = "lblHeader"; - this.lblHeader.Size = new System.Drawing.Size(140, 25); - this.lblHeader.TabIndex = 0; - this.lblHeader.Text = "Apply updates"; - // - // lblSubheader - // - this.lblSubheader.AutoSize = true; - this.lblSubheader.Location = new System.Drawing.Point(14, 52); - this.lblSubheader.Name = "lblSubheader"; - this.lblSubheader.Size = new System.Drawing.Size(252, 17); - this.lblSubheader.TabIndex = 1; - this.lblSubheader.Text = "Press Update to start the update process."; - // - // lvItems - // - this.lvItems.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.lvItems.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.clmnName, - this.clmnStatus, - this.clmnProgress, - this.clmnDescription, - this.clmnPath}); - this.lvItems.FullRowSelect = true; - this.lvItems.Location = new System.Drawing.Point(17, 72); - this.lvItems.Name = "lvItems"; - this.lvItems.Size = new System.Drawing.Size(505, 255); - this.lvItems.TabIndex = 2; - this.lvItems.UseCompatibleStateImageBehavior = false; - this.lvItems.View = System.Windows.Forms.View.Details; - // - // clmnName - // - this.clmnName.Text = "File name"; - this.clmnName.Width = 125; - // - // clmnStatus - // - this.clmnStatus.Text = "Status"; - this.clmnStatus.Width = 131; - // - // clmnProgress - // - this.clmnProgress.Text = "Progress"; - this.clmnProgress.Width = 85; - // - // clmnDescription - // - this.clmnDescription.Text = "Description"; - this.clmnDescription.Width = 100; - // - // clmnPath - // - this.clmnPath.Text = "Path"; - this.clmnPath.Width = 350; - // - // ilIcons - // - this.ilIcons.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit; - this.ilIcons.ImageSize = new System.Drawing.Size(16, 16); - this.ilIcons.TransparentColor = System.Drawing.Color.Transparent; - // - // UpdatePage - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.Window; - this.Controls.Add(this.lvItems); - this.Controls.Add(this.lblSubheader); - this.Controls.Add(this.lblHeader); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); - this.Name = "UpdatePage"; - this.Size = new System.Drawing.Size(538, 341); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label lblHeader; - private System.Windows.Forms.Label lblSubheader; - private System.Windows.Forms.ListView lvItems; - private System.Windows.Forms.ImageList ilIcons; - private System.Windows.Forms.ColumnHeader clmnName; - private System.Windows.Forms.ColumnHeader clmnStatus; - private System.Windows.Forms.ColumnHeader clmnProgress; - private System.Windows.Forms.ColumnHeader clmnPath; - private System.Windows.Forms.ColumnHeader clmnDescription; - } -} diff --git a/UpdateLib/UpdateLib/UI/Components/UpdatePage.cs b/UpdateLib/UpdateLib/UI/Components/UpdatePage.cs deleted file mode 100644 index 04c23a8..0000000 --- a/UpdateLib/UpdateLib/UI/Components/UpdatePage.cs +++ /dev/null @@ -1,372 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.ComponentModel; -using System.Windows.Forms; -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Properties; -using MatthiWare.UpdateLib.Tasks; -using MatthiWare.UpdateLib.Threading; -using System.Collections.Generic; -using System.Linq; -using MatthiWare.UpdateLib.Utils; - -namespace MatthiWare.UpdateLib.UI.Components -{ - public partial class UpdatePage : UserControl, IWizardPage - { - - public UpdateFile UpdateFile { get; set; } - - public event EventHandler PageUpdate; - - private AtomicInteger amountToDownload = new AtomicInteger(); - private Dictionary m_items = new Dictionary(); - private bool hasRegTask = false; - - public UpdatePage(UpdaterForm parent) - { - InitializeComponent(); - - _updaterForm = parent; - - UpdateFile = parent.updateInfoFile; - - ImageList ilItems = MakeImageList(); - lvItems.SmallImageList = ilItems; - - - FillListView(); - - - } - - private ImageList MakeImageList() - { - ImageList imgList = new ImageList(); - - imgList.Images.Add("status_download", Resources.status_download); - imgList.Images.Add("status_done", Resources.status_done); - imgList.Images.Add("status_error", Resources.status_error); - imgList.Images.Add("status_info", Resources.status_info); - imgList.Images.Add("status_update", Resources.status_update); - imgList.Images.Add("status_warning", Resources.status_warning); - - return imgList; - } - - private void FillListView() - { - amountToDownload.Value = UpdateFile.FileCount; - - lvItems.BeginUpdate(); - - AddDirectoryToListView( - UpdateFile.Folders - .SelectMany(dir => dir.GetItems()) - .Select(e => e as FileEntry) - .Distinct() - .NotNull()); - - AddRegistryToListView(UpdateFile.Registry - .SelectMany(dir => dir.GetItems()) - .Select(e => e as RegistryKeyEntry) - .Distinct() - .NotNull()); - - lvItems.Columns[4].Width = -1; - lvItems.Columns[0].Width = -1; - - lvItems.EndUpdate(); - } - - private void AddDirectoryToListView(IEnumerable files) - { - foreach (FileEntry entry in files) - { - ListViewItem item = new ListViewItem(new string[] { entry.Name, "Ready to download", "0%", entry.Description, Updater.Instance.Converter.Convert(entry.DestinationLocation) }); - item.Tag = entry; - - DownloadTask task = new DownloadTask(entry); - task.TaskProgressChanged += Task_TaskProgressChanged; - task.TaskCompleted += Task_TaskCompleted; - - m_items.Add(task, item); - - lvItems.Items.Add(item); - } - } - - private void AddRegistryToListView(IEnumerable keys) - { - if (keys.Count() == 0) - return; - - amountToDownload.Increment(); - hasRegTask = true; - - ListViewItem item = new ListViewItem(new string[] { "Update registry", "Waiting for other tasks to complete", "0%", "Applies changes to the registry" }); - - UpdateRegistryTask task = new UpdateRegistryTask(keys); - task.TaskProgressChanged += Task_TaskProgressChanged; - task.TaskCompleted += Task_TaskCompleted; - - m_items.Add(task, item); - - lvItems.Items.Add(item); - } - - public void StartUpdate() - { - IsBusy = true; - PageUpdate?.Invoke(this, new EventArgs()); - - var items = m_items.Where(x => (x.Key as DownloadTask != null)); - - foreach (var kvp in items) - { - SetImageKey(kvp.Value, "status_download"); - SetSubItemText(kvp.Value.SubItems[1], "Downloading.."); - - kvp.Key.Start(); - } - - - if (hasRegTask && items.Count() == 0) - StartRegUpdate(); - - } - - private void StartRegUpdate() - { - var kvp = m_items.Where(x => (x.Key as UpdateRegistryTask) != null).NotNull().FirstOrDefault(); - - if (kvp.Key == null || kvp.Value == null) - return; - - var view = kvp.Value; - - SetImageKey(view, "status_download"); - SetSubItemText(view.SubItems[1], "Updating.."); - - kvp.Key.Start(); - - } - - private void Task_TaskCompleted(object sender, AsyncCompletedEventArgs e) - { - var task = (UpdatableTask)sender; - var view = m_items[task]; - - if (e.Cancelled) - { - SetSubItemText(view.SubItems[1], "Rolled back"); - SetImageKey(view, "status_warning"); - - return; - } - - if (e.Error != null) - { - HasErrors = true; - PageUpdate?.Invoke(this, EventArgs.Empty); - - Updater.Instance.Logger.Error(nameof(UpdatePage), nameof(StartUpdate), e.Error); - - SetSubItemText(view.SubItems[1], "Error"); - SetImageKey(view, "status_error"); - - return; - } - - SetSubItemText(view.SubItems[1], "Done"); - SetImageKey(view, "status_done"); - - int left = amountToDownload.Decrement(); - - if (left == 1 && hasRegTask) - StartRegUpdate(); - else if (left == 0) - { - IsBusy = false; - IsDone = true; - PageUpdate?.Invoke(this, EventArgs.Empty); - } - } - - private void Task_TaskProgressChanged(object sender, ProgressChangedEventArgs e) - { - UpdatableTask task = (UpdatableTask)sender; - - SetSubItemText(m_items[task].SubItems[2], $"{e.ProgressPercentage}%"); - } - - public void CancelUpdate() - { - - } - - private void StartDownloadItem(ListViewItem item) - { - - //Test(item); - - } - - private void SetImageKey(ListViewItem item, string key) - { - this.InvokeOnUI(() => item.ImageKey = key); - //if (InvokeRequired) - //{ - // Invoke(new Action(SetImageKey), item, key); - // return; - //} - //item.ImageKey = key; - } - - private void SetSubItemText(ListViewItem.ListViewSubItem item, string key) - { - this.InvokeOnUI(() => item.Text = key); - //if (InvokeRequired) - //{ - // Invoke(new Action(SetSubItemText), item, key); - // return; - //} - - //item.Text = key; - } - - public void Cancel() - { - if (NeedsRollBack) - Rollback(); - - IsDone = true; - - - PageUpdate?.Invoke(this, EventArgs.Empty); - } - - public void Execute() - { - StartUpdate(); - } - - private UpdaterForm _updaterForm; - public UpdaterForm UpdaterForm - { - get - { - return _updaterForm; - } - } - - public UserControl Conent - { - get - { - return this; - } - } - - public bool NeedsCancel - { - get - { - return true; - } - } - - public bool NeedsExecution - { - get - { - return true; - } - } - - public bool NeedsRollBack { get { return true; } } - - public bool IsBusy - { - get; set; - - } - - public void PageEntered() - { - - } - - public void UpdateState() - { - - } - - public void Rollback() - { - IsBusy = true; - - foreach (var item in m_items) - { - UpdatableTask task = item.Key; - ListViewItem view = item.Value; - - if (task.IsCancelled || (!task.IsCompleted && !task.IsRunning)) - { - SetSubItemText(view.SubItems[1], "No action"); - - SetImageKey(view, "status_warning"); - - continue; - } - - - task.Cancel(); - - SetSubItemText(view.SubItems[1], "Rolled back"); - - SetImageKey(view, "status_warning"); - } - - IsBusy = false; - HasErrors = false; - IsDone = true; - - PageUpdate?.Invoke(this, EventArgs.Empty); - } - - public bool IsDone - { - get; set; - } - - public string Title - { - get - { - return lblHeader.Text; - } - } - - public bool HasErrors - { - get; set; - } - } -} diff --git a/UpdateLib/UpdateLib/UI/Components/UpdatePage.resx b/UpdateLib/UpdateLib/UI/Components/UpdatePage.resx deleted file mode 100644 index be67fa0..0000000 --- a/UpdateLib/UpdateLib/UI/Components/UpdatePage.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib/UI/IWizardPage.cs b/UpdateLib/UpdateLib/UI/IWizardPage.cs deleted file mode 100644 index 7824d6d..0000000 --- a/UpdateLib/UpdateLib/UI/IWizardPage.cs +++ /dev/null @@ -1,41 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.UI -{ - public interface IWizardPage - { - event EventHandler PageUpdate; - UpdaterForm UpdaterForm { get; } - void Cancel(); - void Execute(); - UserControl Conent { get; } - bool NeedsCancel { get; } - bool NeedsExecution { get; } - bool IsBusy { get; set; } - bool IsDone { get; set; } - string Title { get; } - void PageEntered(); - void Rollback(); - bool HasErrors { get; set; } - bool NeedsRollBack { get; } - void UpdateState(); - } -} diff --git a/UpdateLib/UpdateLib/UI/MessageDialog.Designer.cs b/UpdateLib/UpdateLib/UI/MessageDialog.Designer.cs deleted file mode 100644 index ef98053..0000000 --- a/UpdateLib/UpdateLib/UI/MessageDialog.Designer.cs +++ /dev/null @@ -1,152 +0,0 @@ -namespace MatthiWare.UpdateLib.UI -{ - partial class MessageDialog - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MessageDialog)); - this.panel1 = new System.Windows.Forms.Panel(); - this.btn2 = new System.Windows.Forms.Button(); - this.btn1 = new System.Windows.Forms.Button(); - this.btn3 = new System.Windows.Forms.Button(); - this.pbIcon = new System.Windows.Forms.PictureBox(); - this.lblHeader = new System.Windows.Forms.Label(); - this.lblDesc = new System.Windows.Forms.Label(); - this.panel1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pbIcon)).BeginInit(); - this.SuspendLayout(); - // - // panel1 - // - this.panel1.BackColor = System.Drawing.SystemColors.Control; - this.panel1.Controls.Add(this.btn2); - this.panel1.Controls.Add(this.btn1); - this.panel1.Controls.Add(this.btn3); - this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.panel1.Location = new System.Drawing.Point(0, 100); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(401, 46); - this.panel1.TabIndex = 0; - // - // btn2 - // - this.btn2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btn2.Location = new System.Drawing.Point(227, 11); - this.btn2.Name = "btn2"; - this.btn2.Size = new System.Drawing.Size(75, 23); - this.btn2.TabIndex = 3; - this.btn2.UseVisualStyleBackColor = true; - this.btn2.Visible = false; - // - // btn1 - // - this.btn1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btn1.Location = new System.Drawing.Point(146, 11); - this.btn1.Name = "btn1"; - this.btn1.Size = new System.Drawing.Size(75, 23); - this.btn1.TabIndex = 2; - this.btn1.UseVisualStyleBackColor = true; - this.btn1.Visible = false; - // - // btn3 - // - this.btn3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btn3.Location = new System.Drawing.Point(308, 11); - this.btn3.Name = "btn3"; - this.btn3.Size = new System.Drawing.Size(75, 23); - this.btn3.TabIndex = 1; - this.btn3.UseVisualStyleBackColor = true; - this.btn3.Visible = false; - // - // pbIcon - // - this.pbIcon.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; - this.pbIcon.Location = new System.Drawing.Point(12, 12); - this.pbIcon.Name = "pbIcon"; - this.pbIcon.Size = new System.Drawing.Size(48, 48); - this.pbIcon.TabIndex = 1; - this.pbIcon.TabStop = false; - // - // lblHeader - // - this.lblHeader.AutoSize = true; - this.lblHeader.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblHeader.ForeColor = System.Drawing.Color.MidnightBlue; - this.lblHeader.Location = new System.Drawing.Point(65, 12); - this.lblHeader.Name = "lblHeader"; - this.lblHeader.Size = new System.Drawing.Size(212, 25); - this.lblHeader.TabIndex = 2; - this.lblHeader.Text = "Version 1.0.0.0 available"; - // - // lblDesc - // - this.lblDesc.AutoSize = true; - this.lblDesc.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblDesc.Location = new System.Drawing.Point(67, 46); - this.lblDesc.Name = "lblDesc"; - this.lblDesc.Size = new System.Drawing.Size(218, 34); - this.lblDesc.TabIndex = 3; - this.lblDesc.Text = "Update now?\r\nPress yes to update or no to cancel."; - // - // MessageDialog - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoSize = true; - this.BackColor = System.Drawing.SystemColors.Window; - this.ClientSize = new System.Drawing.Size(401, 146); - this.Controls.Add(this.lblDesc); - this.Controls.Add(this.lblHeader); - this.Controls.Add(this.pbIcon); - this.Controls.Add(this.panel1); - this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "MessageDialog"; - this.ShowIcon = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Message Dialog"; - this.panel1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.pbIcon)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Panel panel1; - private System.Windows.Forms.Button btn3; - private System.Windows.Forms.PictureBox pbIcon; - private System.Windows.Forms.Label lblHeader; - private System.Windows.Forms.Label lblDesc; - private System.Windows.Forms.Button btn1; - private System.Windows.Forms.Button btn2; - } -} \ No newline at end of file diff --git a/UpdateLib/UpdateLib/UI/MessageDialog.cs b/UpdateLib/UpdateLib/UI/MessageDialog.cs deleted file mode 100644 index 3d5c384..0000000 --- a/UpdateLib/UpdateLib/UI/MessageDialog.cs +++ /dev/null @@ -1,119 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System.Drawing; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.UI -{ - public partial class MessageDialog : Form - { - public static DialogResult Show(IWin32Window owner, string title, string header, string desc, Icon icon, MessageBoxButtons buttons = MessageBoxButtons.YesNo) - { - return new MessageDialog( - title, - header, - desc, - icon, - buttons).ShowDialog(owner); - } - - public static DialogResult Show(string title, string header, string desc, Icon icon, MessageBoxButtons buttons = MessageBoxButtons.YesNo) - { - return Show(null, title, header, desc, icon, buttons); - } - - public string Header - { - get { return this.lblHeader.Text; } - set { this.lblHeader.Text = value; } - } - - public string Description - { - get { return this.lblDesc.Text; } - set { this.lblDesc.Text = value; } - } - - public Icon DialogIcon - { - set { this.pbIcon.BackgroundImage = value.ToBitmap(); } - } - - public MessageDialog() - { - InitializeComponent(); - } - - public MessageDialog(string title, string header, string desc, Icon icon, MessageBoxButtons buttons = MessageBoxButtons.YesNo) - : this() - { - Header = header; - Description = desc; - Text = title; - DialogIcon = icon; - Icon = icon; - - ShowIcon = true; - - SetUpButtons(buttons); - } - - private void SetUpButtons(MessageBoxButtons buttons) - { - switch (buttons) - { - case MessageBoxButtons.OK: - default: - SetUpButton(btn3, "OK", DialogResult.OK, true); - break; - case MessageBoxButtons.OKCancel: - SetUpButton(btn2, "OK", DialogResult.OK, true); - SetUpButton(btn3, "Cancel", DialogResult.Cancel); - break; - case MessageBoxButtons.AbortRetryIgnore: - SetUpButton(btn3, "Ignore", DialogResult.Ignore); - SetUpButton(btn2, "Retry", DialogResult.Retry); - SetUpButton(btn1, "Abort", DialogResult.Abort, true); - break; - case MessageBoxButtons.YesNoCancel: - SetUpButton(btn3, "Cancel", DialogResult.Cancel); - SetUpButton(btn2, "No", DialogResult.No); - SetUpButton(btn1, "Yes", DialogResult.Yes, true); - break; - case MessageBoxButtons.YesNo: - SetUpButton(btn3, "No", DialogResult.No); - SetUpButton(btn2, "Yes", DialogResult.Yes, true); - break; - case MessageBoxButtons.RetryCancel: - SetUpButton(btn3, "Cancel", DialogResult.Cancel); - SetUpButton(btn2, "Retry", DialogResult.Retry, true); - break; - } - } - - private void SetUpButton(Button button, string text, DialogResult result, bool defaultButton = false) - { - button.Text = text; - button.DialogResult = result; - button.Visible = true; - - if (defaultButton) - button.TabIndex = 0; - } - } -} diff --git a/UpdateLib/UpdateLib/UI/MessageDialog.resx b/UpdateLib/UpdateLib/UI/MessageDialog.resx deleted file mode 100644 index 9fe1da0..0000000 --- a/UpdateLib/UpdateLib/UI/MessageDialog.resx +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - AAABAAIAMDAAAAEAIACoJQAAJgAAABAQAAABACAAaAQAAM4lAAAoAAAAMAAAAGAAAAABACAAAAAAAAAk - AAASCwAAEgsAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8ANJtQDDOYTkgxlEx2MZJLojCQSs0wkEr0MJBK4zCR - SsswkUuyMZJLmTGTTIAylk1fNJtQDP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AACEIy0UgTKaIIM89iuDQv8pgkD/JoI//yWF - QP8liUD/JYdA/yWHQP8mhED/JoI//yiBP/8qg0H/IIM89hSDM5kAhCMs////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAfB9RE30xxxt7Nv8kfjz/IYU8/yWP - Q/88oFb/VKxs/2e2ff9yvIf/abZ+/2K0ev9asXL/VK1t/02pZv82mFH/JYZA/yZ/Pf8bezb/En0wxwqD - K1sAgyMG////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAIUjFBN/Ma4ZdzT/In06/x6G - Ov9MqGP/iMaZ/6XUsv+cz6r/lMuk/43Hnf+JxJn/hMKU/4DAkv99vo3/ebyL/3a7if90u4f/abd//0+p - Zf8zkE3/JX49/yd8Pv8ggzrTDYsvIf///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8AMZRMiwCEIw7///8A////AP///wD///8A////AP///wD///8A////AP///wAJgClUHX037iF3 - OP8jiT//YrZ6/57Qq/+l07L/mc2n/5DIoP+KxZr/hsOX/4LBk/9+v4//er2M/3a7iP9yuYX/breC/2q1 - fv9ms3v/ZLJ5/2KyeP9hs3f/WrBy/zqYU/8nez7/HXw38wiCKUv///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8ALYZF/x58OO4WhzVpAIUkAv///wD///8A////AP///wD///8AAIQjAxN/ - MaEXci//Hno2/z6eWP+i06//p9Sz/5vNqf+TyaL/jsee/4vFmv+IxJn/hsOW/4PBlf+AwJP/fL6O/3a7 - iv9xuIT/a7Z//2aze/9isXf/Xq90/1qtcP9Wq23/VKps/1Ora/9Colv/J30+/xp1M/0VgjGDAIQjAf// - /wD///8A////AP///wD///8A////AP///wD///8ALIRE/yd3PP8mdjv/HX031AmBKkH///8A////AP// - /wANiy8EH4M7ryFyNv8fgzr/b7uD/6/au/+i0bD/mM2m/5TLo/+QyKD/kcig/5LJof+FwpX/c7mG/2Ox - eP9Tqmr/Uqlo/1uucv9jsnn/aLV+/2q1ff9isXj/XK5x/1arbf9SqWr/Tqdm/0ulZP9Jp2L/QaJd/y2G - Rv8ndTv/III6ug2MLxD///8A////AP///wD///8A////AP///wD///8ALIND/iyJRv87l1b/GG0u/xVt - LP8QeS2zDo4wIBuVPAUfgTqzHm80/yqHQv+e0qv/rNa4/5/PrP+YzKX/l8yl/5jNpv+UyqP/Z7R8/zme - Vf8llEP/KZZG/yuXSP8tmEr/LZhK/y2YSv8sl0n/K5dI/yuWSf9Co13/WK1u/1arbf9PqGf/SqVj/0ak - X/9Colz/P6JZ/z2jWP8ujUn/JnM7/x5/OccAhSQE////AP///wD///8A////AP///wD///8AK4FC/TKI - Sf/y/vT/f8OR/xt9Nv8Zai//JXU8+yuCQ9MdazL/J4dD/6TWsv+q1rb/nM2q/5nNpv+azqj/mM2n/1es - b/8nlET/KpZH/zCZTP8zm0//NJtQ/zSbUP80m1D/NJtQ/zSbUP80m1D/NJtQ/zObT/8xmk3/LphL/z6f - WP9JpWP/R6Vg/0KiXP8+oFj/Op5V/zadUv81n1L/L49K/yVuOf8SfS+W////AP///wD///8A////AP// - /wD///8AKn9B/SyDRf/f8+T/y+fS/8Hjyv9XrG7/FXQw/xNiKP8phkL/p9az/6rWtv+dz6r/nM6p/57Q - q/9+wJH/MplP/yuXSP8xmk7/NJtQ/zScUP81nVH/NZ5R/zagU/82olP/NqNU/zajVP82olP/NqBS/zWe - Uf80nFD/M5tP/zKaTv8zm1D/QKFb/z+hWf86nlX/NZxS/zObT/80nFD/NqBT/yyERP8XaC7/CH0mXf// - /wD///8A////AP///wD///8AKn1A/C6DRf/V7t3/udzD/7vexf/B4sr/oNOu/0OhXP+k1rL/qta2/53P - qv+czqr/otGv/1etb/8mlET/L5lM/zObT/80nFD/NZ1R/zagU/80nVH/MJFK/yuAQ/8lbzn/I2k2/yVu - OP8mdDv/Kn5B/zGVTf82olT/NZ9S/zScUP8zm0//MppO/zufVv83nFL/M5tP/zSbUP80m1D/NZ1R/zWg - Uv8mdT3/GW0w+QmEKy7///8A////AP///wD///8AKXxA+zGCSP/Q7Nj/tNq//7DYu/+v17r/sdi6/67W - uf+m1LP/nc+q/53Oqv+f0K3/Tahm/ymWRv8xmk7/NJtQ/zScUP81n1L/NZ5R/yp8QP8hZDP/Imc1/xlw - MfkOcSq/Am4gmgFrHrEObijIGW0w+iBlNP8lcDr/L49K/zahU/81nVH/NJtQ/zObUP8zm1D/NJtQ/zSb - UP80m1D/NJtQ/zWeUf80nVH/JGw3/xtzM+MOjjAP////AP///wD///8AKXo/+zGBSf/L6tX/sNi7/63W - uP+p1LT/pdKx/6HQrv+dzqr/ns6r/57Oq/9GpF//KpZH/zKaTv80nFD/NZ1R/zahU/8xlEz/Imo2/xdk - LP0Sei2dDYsvQACHJQb///8A////AP///wD///8AAIglEhN/MHYZbzDfIWEz/yuBQv81oVL/NZ5R/zSc - UP80m1D/NJtQ/zSbUP80m1D/NJxQ/zWdUf83pFX/MJFK/yJkNP8ceDW8AIMjAf///wD///8AKHg++jWC - Sf/I6NH/rda4/6nUtP+l0rH/odCu/53Oqv+bzan/otCu/0+nZ/8qlkf/MptP/zSbUP81nlH/NZ9S/yp/ - Qf8gYDL/GnEy5gqELD////8A////AP///wD///8A////AP///wD///8A////AP///wAAiCUHEHQsqBRc - J/8mcjr/NJ1R/zWeUf80m1D/NJtQ/zSbUP80nFH/Np9S/zWhU/8shET/IGMy/xdmLPoReC2BAHwXBP// - /wD///8AJ3c9+jaBSv/D587/qdW1/6XTsv+h0K7/nc6q/5rMqP+ezqv/cLmE/yeVRf8ymk7/NJtQ/zSb - UP81nlH/J3Q7/x9cL/8ndTz9KZtHTv///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AAZ2I3MUYCj9JG45/zWiU/81nVH/NJxQ/zWeUv83olT/MJJL/yNnNf8SWSb/DXApvgCB - ISL///8A////AP///wD///8AJ3U8+jd/S/++5Mj/pdOy/6HRrv+dz6v/mc6n/5zNqP+KxZr/KJVF/zCZ - Tf80m1D/NJtQ/zSbUP81nVH/NqJU/y2JRv8gYDL/E1om/w9wKbUBiiYg////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wAEdSRvEVYj/yt+Qf83o1T/NqJT/zSeUf8mdDv/HVgt/xlq - LusHfSdW////AP///wD///8A////AP///wD///8AJnM7+Th+TP+54sX/odGu/53Pq/+Zzaf/mc2o/5vM - qP80m1D/LphL/zSbUP80m1D/NJtQ/zSbUP80m1D/NZ1R/zagUv82olP/KX1A/x1ZLv8VYCn7EHcsjgCG - JAv///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ADm8osBxVLf8xkkv/LYZF/x9a - Lv8TWyf9EXUslACJJQv///8A////AP///wD///8A////AP///wD///8AJnI7+Dl+S/+04MD/nc+r/5nN - p/+Xzab/nc+r/0ynZP8rl0j/M5tP/zSbUP80m1D/NJtQ/zSbUP80m1D/NJtQ/zScUP82oVP/OalY/y+P - Sf8eWC3/D1Ag/wRzIqgAdAoB////AP///wD///8A////AP///wD///8A////AP///wD///8AAYkmDBdo - LeIdVCv/HFYt/xltMM0Khywu////AP///wD///8A////AP///wD///8A////AABiEiErgkOkJXA6+Dp8 - Sv+x3r3/ms2o/5bMpf+azqj/a7Z//yiVRv8ymk7/NJtQ/zSbUP80m1D/NJtQ/zSbUP80nFD/NZ5R/zei - VP80m0//JGs2/xpQKP8YZy7lB30oUv///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AAiAKC4JYSDnFH4waACIJQH///8A////AP///wD///8A////AP///wAAaBUID3MphBx3 - Nfgqf0HyJW859zp7S/+s3Ln/lsul/5fLpf+Mx5v/JpVF/zCaTf80m1D/NJtQ/zSbUP80m1D/NJtQ/zWd - Uf82oVP/NaFT/yd3Pv8ZTCf/E1km+BF4LYABiSYG////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wAAfhgC////AP///wD///8A////AP///wD///8A////AABp - GlUUdC7kL4BG/yV5O/8pfEDzJG049jp5TP+n2rb/k8qi/5nNqP9JpmL/LZhK/zSbUP80m1D/NJtQ/zSb - UP80nFH/NqBS/zimVv8rhET/G1Eq/w9NIP4NaiasAYsnGP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wAAYxEpB24jvglsJP9fk2//grSQ/yN6PP8oeT70JGs39jl3Sv+j2LH/k8qj/4PCk/8mlET/MppO/zSb - UP80m1D/NJxQ/zWfUv83pVX/MJFL/x5aLf8YSSb/FmYs0guGLDf///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8AAGIQDQxxJpAPcSn8LHtB/5a1nv/a69//OaVX/yR3Ov8ndj30I2o29Tp2S/+f1q//lsuk/0Cg - Wv8umEv/NJtQ/zScUP81nlH/N6NU/zSdUf8jZjX/FUIh/xJaJu8TfjBkAYkmAf///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wAAahxiE3Mt6xdyMf9jmHL/v9fH/9Hs1/+Lx5v/JppG/yZ0PP8mczv2I2k28jt2 - TP+g2K//eL2K/yiVRf8zm0//NZ1R/zahU/83o1P/J3c9/xZFI/8PUCH8DnIpkQGLJwv///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8AAGcTNAlvJcgKbCX/N4FL/6jFr//J6NH/vuLH/8Piy/8xmk7/MJ9O/yZz - O/8lcDn3I2o28j12Tf+i2bL/OJxU/y+aTP82oFL/OKZV/y2GRf8ZTij/C0Ub/wplJLwAhSMi////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AABhERMNciidEHAr/RxzM/94p4X/y+XQ/8Diyf+z277/ttvA/36/ - j/8llEP/NqJT/yVvOf8kbTj3I2o28UF3Uf96xI//KplI/zakVP8xlk3/Hlwv/xZEI/8VYireCH8pR/// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wAAhyQCD3MqbhZ0L/EWci//SYta/7jVwf/I59H/t93C/63Y - uv+t1rf/r9e5/yyYSP8vmUz/N6NU/yRtOP8jajb4I2o38El9Vf9Cr1//MZ1P/yRrN/8WQiH/Elck9RF5 - LXUBiiYD////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AAFrHj8YdTHSG3Qz/yN2Of+Qu5z/zerU/7zf - xf+v2Lr/qtW2/6XTs/+s1bj/ZLJ5/ymWRv8zm1D/N6RU/yNrN/8iZzX5I2o27zBzQf8ngED/F0ck/w5L - Hv0NbCaiAYwnEv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAYhIbDXEpqRJwLP4Vby7/XJtt/8fj - z//B48z/tNu//6vVtv+m07L/odGu/6LRr/+bzqn/JpRD/zCaTf80m1D/N6RV/yNnNv8hYzP5I2o37xdI - JP8LRBv/CWEhygCDIi7///8A////AP///wD///8A////AP///wD///8AAHoVAv///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAFcMBRB1K3sYdDD2GnMy/y5/ - Rf+pzrP/yOfQ/7jdwv+u17n/qNS0/6PRsP+ez6v/ms6o/6HQrf9LpmX/LJdJ/zSbUP80m1D/N6VV/yJl - M/8gYDH5JGs37xRfKOkHeiVZ////AP///wD///8A////AP///wD///8A////AP///wALhy1NGY453QqD - Kkv///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wACbR9LHHk23iF5 - Of8aczL/da+F/8zp1P+94Mf/r9m7/6nUtP+l0rH/oNCt/5vNqf+Wy6X/l8yl/3/Akf8mlET/MppO/zSb - UP80m1D/OKVV/yBiMv8fXTD6MI9KbgCIJQj///8A////AP///wD///8A////AP///wD///8AAIEhHhiO - OLAhkj//L5ZK/yGNPvAJgSkg////AP///wD///8A////AP///wD///8A////AP///wD///8A////AABj - EYobdzT/KXw//zOCSP/L6dT/zuzW/7bcwf+q1bb/pdOy/6HQrv+czqn/mMym/5PKov+QyKD/lsqk/zac - Uv8vmUv/NJtQ/zSbUP80m1D/OKZV/x9fMf8eWi77////AP///wD///8A////AP///wD///8A////AACB - IQQZjjl1IZI/9x+NPP8wlEz/Xaxy/yCKPf8giD3MAIMjBv///wD///8A////AP///wD///8A////AP// - /wD///8A////AABDAAQNbyh2GXEx8h1wNP80fUj/mcWl/7jgw/+o1rX/ntCs/5nMp/+UyqP/j8ie/4zG - nP+Nxp3/YrJ4/yqWR/8zm0//NJtQ/zSbUP80m1D/OKZW/x9dMP8dVy37////AP///wD///8A////AP// - /wD///8AC4gtOySUQtMlkkP/E4c0/4fCl////////////y2RSP8jhj7/E30wmP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8AAFsNFQlmI6IQZCf9E2Uq/0uGWv+cy6j/ndOt/5LJ - of+Mxpz/h8SY/4XClf+EwpT/K5dJ/zGaTf80m1D/NJtQ/zSbUP80m1D/OKdW/x5aLv8dVy38////AP// - /wD///8A////AACBIRMZjjmcI5JC/h+NPv9RpGb/8vn1///////8/v3//////9fs3f8UfS//GHwz/xB3 - LJAAhiQC////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAacTM7IWw19BNg - KP8RViT/f7KO/4rFmv+EwpX/gMGS/4HBlP9LpmT/LZhK/zSbUP80m1D/NJtQ/zSbUP80m1D/OKdW/x5a - L/8dViz8////AP///wD///8AAIEhYyWUQ+4zmE7/MJVM/0aiYP////////////L49P/r9e7/6vTs//X6 - 9v+t1bn/GX00/yF9Ov8deja/AGgcE////wD///8A////AP///wD///8A////AP///wD///8A////AABf - GTEUZSvXGmMt/yNoNf93s4n/jsyf/4LDk/98vo7/e76O/222gf8qlkf/MptP/zSbUP80m1D/NJtQ/zSb - UP80m1D/OKZW/x5cL/8dViz8////AP///wD///8ACoMqjTKXTv8ylk3/M5xQ/x+RPv+UyqP//////+z2 - 7v/j8ef/3+/j/97u4v/m9Or/v+HI/yGBO/8ddjX/GHQx6g1vKIgAYRAe////AP///wD///8A////AAA7 - AAMAXxdBCWEhlRBdJfsUXCn/RoNW/5TOpP+LyJv/f8CR/3m9i/93u4n/crqH/zKaTv8wmk3/NJtQ/zSb - UP80m1D/NJtQ/zSbUP80m1D/OKZW/x5cL/8dViz9////AP///wD///8AAIIiBSOMQMkxkUv/MpZN/y6a - S/8ckDz/u97E//P69P/f7+P/1+vc/9Lp2P/P59b/1ezc/8no0f9RmmT/Emss/xtvMv8Vayv9C2Qi0ABb - F7gAXBWkCWMhuxRkKfUdZTH/Fl4p/x5hMP9xq4D/kc+i/4LDlf96vYz/dbuI/3O6hf9zuYb/PZ9Y/y+Z - TP80m1D/NZ1R/zWeUf81nlH/NJxQ/zSbUP80m1D/OKZW/x5cL/8dViz9////AP///wD///8A////AAZ6 - JyEihz7yLoxI/zKZT/8smUr/G446/6PRsP/o8+r/1OrZ/8rl0f/F4s3/weDK/8TjzP/L6NL/stq+/0+b - ZP8fcDT/Dl8l/xFgJ/8TXyf/EFwl/xdiLP89gU7/bqh9/47Hn/+HyJr/fcCP/3a7if9yuYX/b7iC/262 - gv9Lp2X/LphL/zObT/81nlL/NqNT/yl8P/81oVL/NqJU/zWeUf80nFD/OKZW/x5cLv8dViz9////AP// - /wD///8A////AP///wAFdSNVIIE6/y2JRf80nFH/LppL/x2QPP+EwpX/2+3g/8vm0f+/38f/uNzC/7Ta - vv+y2b3/stm8/7XdwP+44cP/sNu8/5TKov+CvJH/lMej/57Wrv+Tz6T/iciZ/3/BkP95vYz/c7qG/264 - gv9stn//a7Z//0akX/8umEv/M5tP/zWeUv82pFT/JGo2/xdIJf8aTyn/K39B/zekVf82oVP/OKhX/x5c - MP8dViz+////AP///wD///8A////AP///wD///8AEXgtmSuDRP8shkX/NJ1R/zCbTf8jk0L/QqFc/7fc - wf/E4cv/tdu//63XuP+n07P/o9Gw/57Pq/+Zzaf/l8ul/5TLov+Pyp//iMWa/4PClP9+v4//eb2L/3S6 - h/9vuIP/bLaB/2m2ff9ntH3/P6Ba/y6ZS/8zm0//NZ9S/zalVP8kajf/GUwn/x1XLOkbUyr5GEwn/x1X - Lf8vjEj/O7Bb/x9gMv8cViz+////AP///wD///8A////AP///wD///8AAF0OBh17NrEqfED/K4BB/zOb - UP8znVD/KpdI/yKSQv9rt4D/r9i6/7HZu/+k0bD/m86p/5bLpf+RyaD/jcac/4jEmP+DwpT/fr+Q/3q9 - jP92u4j/cbmE/222gP9ptX7/Z7V8/1etb/81m1H/MJlM/zObT/82n1L/N6RV/yJqNf8ZTCf/Dk0g3Qdb - HRkAUBEgAksVtwxEG/4YSyb/I2o2/yBdMP8cViz+////AP///wD///8A////AP///wD///8A////AACH - JAEMbCibGnEy/yl4Pf8ymU7/NZ9S/zCaTf8plkb/I5JB/1mucf+Xy6X/odGu/5fMpv+PyJ//iMWZ/4HA - kv97vo3/druJ/3O5iP9xuIX/breB/2u1f/9brnH/Op1U/y6YSv8xmk7/NJ1R/zaiU/80nVH/IWQz/xlM - J/8QTyDYAFERFP///wD///8A////AABDAkQBRRLXC0cc/xtTKv8cViz/////AP///wD///8A////AP// - /wD///8A////AP///wD///8AAGQaghdrL/4lcjr/L4pI/zWhUv81n1L/MZtO/yuXSf8klEP/MZlO/1Gp - aP9rtn//er6L/3q+jP97vo3/eL6L/2u1f/9YrG//R6Rg/zmeU/8tmEr/MZpN/zScUP81n1L/OKVV/yyG - Rf8aUCn/CkQa/wFGFM0ARAEQ////AP///wD///8A////AP///wD///8AAEkNbg9OH+4cViz/////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AABfF2kWZy36I2o3/yVxOv8wkkv/N6NU/zWf - Uv80nFD/MZpO/y6YS/8qlkj/KJVG/yiVRv8olUb/KZZG/yuXSP8tmEr/MJlM/zKaTv80nFD/NqBS/zel - Vf81n1D/ImY0/xhLJv8MRxz6AEMKhf///wD///8A////AP///wD///8A////AP///wD///8A////AAA/ - AAwhYzOZ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAVAkjCV0ftRRd - J/4gYTL/J3U9/zGVTP82pVT/N6NU/zagUv81nVH/NJxQ/zSbUP80m1D/NJtQ/zScUP81nlH/NqBS/zej - VP84qFb/L49J/yJmNP8ZSSX/GVAp/xBRIdYATA0v////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AABWE0YTWyfWHlsw/x5aLv8fWy//JnE7/y2KSP82oVP/OalX/zioV/84qFb/OKhX/zeo - Vv8zmk//LolG/yh3Pf8dVSz/GEom/wpEGv8AQhHjAEoMgAAYAAL///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wACjSgBAE8PYwRSGrcQUSH1G1Qr/xpQKf8YSyb/GEkm/xpN - J/8bUyr/HVgt/xhKJv8XSSX/GEom/xhNJ/8MRhz9AUoWwABCAVL///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAndDwEI2o2TyFi - MqUfXTDRHlsv3R5aLucdWC3xHVgt+B5bL+EgXzG+IWMzlCJmNGQjaTYc////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A///AAf// - AAD//wAAf/8AAP/8AAAP/wAA//AAAAf/AAA/4AAAA/8AAA+AAAAA/wAABwAAAAB/AAAAAAAAAD8AAAAA - AAAAPwAAAAAAAAAfAAAAAAAAAA8AAAAAAAAABwAAAAAB4AADAAAAAA/4AAMAAAAAH/4ADwAAAAAH/wA/ - AAAAAAH/gH8AAAAAAP+B/AAAAAAD/8PwAAAAAAf/7+AAAAAAH///gAAAAAB///4AAAAAAP///AAAAAAD - ///wAAAAAA///8AAAAAAP///AAAAAAB///4AAAAAAf//+AAAAAAH9//gAAAAAB/j/8AAAAAAP4H/gAAA - AAD+AP+AAAAAAPwA/+AAAAAA8AA/+AAAAADgAB/wAAAAAOAAB4AAAAAA4AAAAAAAAADwAAAAAAAAAPgA - AAAAAAAA/AAAAAAAAAD8AAAAAAAAAP4AAAAA4AAA/4AAAAH4AAD/wAAAB/wAAP/gAAAP/wAA//gAAB// - AAD//AAA//8AAP//gAP//wAAKAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEgsAABILAAAAAAAAAAAAAP// - /wD///8A////AP///wA0m1AIMpJMbDOTTt0/mlj4Qpta+TuYVPUyk0zDMJFLIv///wD///8A////AP// - /wAvjEhW////AP///wAAbhkgJIU99Hu4jP+q17b/sdq8/6DRrv+PyZ//cbmF/zOPTf4FeCSi////AP// - /wD///8AQpFY/BB3K+4AbRp8LodG/MHgyf+j1LH/abZ+/0KkW/9BpFz/Wa9w/2W0ev9fsXX/NJVP/wZ0 - I83///8A////AGamd/3h9ef/cbCC/8rn0v9+wpD/I5ZD/yaNQf8mgT77J4FA+yeJQv8smUr/R6dh/0Kk - XP8giDz/AG0alP///wBionP91O3b/77fx/9otn7/JZVD/yV7PP4vhUahKZxJChuVPAQLaSU/G3Qz+DOf - Uf81oVL/IIU8/wJoHd7///8AX51w/cbn0P+ZzKf/I5JB/zKdT/8yl03/KHU8+Q1qJkz///8A////AABi - GiYccjP6Kn1B+R54N3j///8ALIVFFlqZa/3B5cr/O59W/y6bS/81n1H/G3Uz/RBtKb4AZwwK////AP// - /wD///8AAGEYJCCIPAsMXCIEKotEpTKDR/hVlGb9fseR/ymcSP8bdjT/DGIi5ABbDSH///8A////AP// - /wD///8A////AP///wARfS5ZU5Zk96zTtv8sg0T8SY5c/SyOSP8hbDb1GmwwVP///wD///8A////AP// - /wD///8A////AABfCSEQdCvjfrCL/9Lr2f9Wsm//Kn5B/SVuOfYabDGZJptFASOXQwgIiCsg////AP// - /wD///8AAF8HCA14KbdUmWf+weDL/7new/+MyJz/JppF/yl4Pv00m1AM////ABqTO2BLpGP4OplV+wB0 - GS7///8A////AA1uJ0A2hUv4nsiq/6vZt/+WzKX/NpxS/zGgT/8nczv9////AAqHLM9IoWD///////3/ - /v8efzb6AGYaTAFeGgkRaykKGHIwmjR3Rv6Mx5z/V65u/yyYSf83pVT/JnI7/f///wAAeR5jDn8s/ozJ - nf/t+PD/zufV/3ywi/9Bh1T9Sodb/XCqf/+Myp7/XrV1/yudSv8pfj//N6ZW/yZyO/3///8A////AAJy - IIgPeyv/QKRb/5jQqP+y3L3/otWx/5DNoP9zvof/TKtk/yycS/8SXCb9B1QbjghYHfAgYjL9////AP// - /wD///8ABGwfoBRwLfshij7/KZxJ/zmkVf85pFf/K5tJ/ymFQf8TWyX4AEgNNP///wD///8AImU0Zv// - /wD///8A////AP///wAlcDoLKXY+mSdyO/Umcjv7JnE7+ydwO+cmbzqHI2k2EP///wD///8A////AP// - /wDwDwAAYAcAAAADAAAAAQAAAAEAAADCAAAA4AAAA/AAAA/AAAAHAAAAQwAAAIAAAACAAAAAwAAAAOAG - AADwDwAA - - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib/UI/UIExtensions.cs b/UpdateLib/UpdateLib/UI/UIExtensions.cs deleted file mode 100644 index 56b18c7..0000000 --- a/UpdateLib/UpdateLib/UI/UIExtensions.cs +++ /dev/null @@ -1,43 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.ComponentModel; - -namespace MatthiWare.UpdateLib.UI -{ - public static class UIExtensions - { - public static void InvokeOnUI(this T control, Action action) where T : ISynchronizeInvoke - { - if (control != null && control.InvokeRequired) - control.Invoke(action, null); - else - action(); - - } - - public static TResult InvokeOnUI(this T control, Func action) where T : ISynchronizeInvoke - { - if (control != null && control.InvokeRequired) - return (TResult)control.Invoke(action, null); - else - return action(); - } - - } -} diff --git a/UpdateLib/UpdateLib/UI/UpdaterForm.Designer.cs b/UpdateLib/UpdateLib/UI/UpdaterForm.Designer.cs deleted file mode 100644 index 6dd450e..0000000 --- a/UpdateLib/UpdateLib/UI/UpdaterForm.Designer.cs +++ /dev/null @@ -1,167 +0,0 @@ -namespace MatthiWare.UpdateLib.UI -{ - partial class UpdaterForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UpdaterForm)); - this.pnlSide = new System.Windows.Forms.Panel(); - this.label1 = new System.Windows.Forms.Label(); - this.pnlBottom = new System.Windows.Forms.Panel(); - this.btnPrevious = new System.Windows.Forms.Button(); - this.btnNext = new System.Windows.Forms.Button(); - this.btnCancel = new System.Windows.Forms.Button(); - this.pnlContent = new System.Windows.Forms.Panel(); - this.linkSite = new System.Windows.Forms.LinkLabel(); - this.pnlSide.SuspendLayout(); - this.pnlBottom.SuspendLayout(); - this.SuspendLayout(); - // - // pnlSide - // - this.pnlSide.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(129)))), ((int)(((byte)(181))))); - this.pnlSide.Controls.Add(this.label1); - this.pnlSide.Dock = System.Windows.Forms.DockStyle.Left; - this.pnlSide.Location = new System.Drawing.Point(0, 0); - this.pnlSide.Name = "pnlSide"; - this.pnlSide.Size = new System.Drawing.Size(149, 376); - this.pnlSide.TabIndex = 0; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Segoe UI Semibold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.ForeColor = System.Drawing.SystemColors.Window; - this.label1.Location = new System.Drawing.Point(12, 23); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(115, 21); - this.label1.TabIndex = 0; - this.label1.Text = "Update wizard"; - // - // pnlBottom - // - this.pnlBottom.BackColor = System.Drawing.SystemColors.Control; - this.pnlBottom.Controls.Add(this.linkSite); - this.pnlBottom.Controls.Add(this.btnPrevious); - this.pnlBottom.Controls.Add(this.btnNext); - this.pnlBottom.Controls.Add(this.btnCancel); - this.pnlBottom.Dock = System.Windows.Forms.DockStyle.Bottom; - this.pnlBottom.Location = new System.Drawing.Point(149, 329); - this.pnlBottom.Name = "pnlBottom"; - this.pnlBottom.Size = new System.Drawing.Size(536, 47); - this.pnlBottom.TabIndex = 1; - // - // btnPrevious - // - this.btnPrevious.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnPrevious.Enabled = false; - this.btnPrevious.Location = new System.Drawing.Point(287, 13); - this.btnPrevious.Name = "btnPrevious"; - this.btnPrevious.Size = new System.Drawing.Size(75, 23); - this.btnPrevious.TabIndex = 1; - this.btnPrevious.Text = "< Previous"; - this.btnPrevious.UseVisualStyleBackColor = true; - this.btnPrevious.Click += new System.EventHandler(this.btnPrevious_Click); - // - // btnNext - // - this.btnNext.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnNext.Location = new System.Drawing.Point(368, 13); - this.btnNext.Name = "btnNext"; - this.btnNext.Size = new System.Drawing.Size(75, 23); - this.btnNext.TabIndex = 0; - this.btnNext.Text = "Next >"; - this.btnNext.UseVisualStyleBackColor = true; - this.btnNext.Click += new System.EventHandler(this.btnNext_Click); - // - // btnCancel - // - this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnCancel.Location = new System.Drawing.Point(449, 13); - this.btnCancel.Name = "btnCancel"; - this.btnCancel.Size = new System.Drawing.Size(75, 23); - this.btnCancel.TabIndex = 2; - this.btnCancel.Text = "Cancel"; - this.btnCancel.UseVisualStyleBackColor = true; - this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); - // - // pnlContent - // - this.pnlContent.Dock = System.Windows.Forms.DockStyle.Fill; - this.pnlContent.Location = new System.Drawing.Point(149, 0); - this.pnlContent.Name = "pnlContent"; - this.pnlContent.Size = new System.Drawing.Size(536, 329); - this.pnlContent.TabIndex = 2; - // - // linkSite - // - this.linkSite.AutoSize = true; - this.linkSite.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.linkSite.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(129)))), ((int)(((byte)(181))))); - this.linkSite.Location = new System.Drawing.Point(6, 17); - this.linkSite.Name = "linkSite"; - this.linkSite.Size = new System.Drawing.Size(126, 15); - this.linkSite.TabIndex = 3; - this.linkSite.TabStop = true; - this.linkSite.Text = "Powered by UpdateLib"; - this.linkSite.VisitedLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(43)))), ((int)(((byte)(129)))), ((int)(((byte)(181))))); - this.linkSite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkSite_LinkClicked); - // - // UpdaterForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.Window; - this.ClientSize = new System.Drawing.Size(685, 376); - this.Controls.Add(this.pnlContent); - this.Controls.Add(this.pnlBottom); - this.Controls.Add(this.pnlSide); - this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "UpdaterForm"; - this.Text = "Updater"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.UpdaterForm_FormClosing); - this.pnlSide.ResumeLayout(false); - this.pnlSide.PerformLayout(); - this.pnlBottom.ResumeLayout(false); - this.pnlBottom.PerformLayout(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Panel pnlSide; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Panel pnlBottom; - private System.Windows.Forms.Button btnPrevious; - private System.Windows.Forms.Button btnNext; - private System.Windows.Forms.Button btnCancel; - private System.Windows.Forms.Panel pnlContent; - private System.Windows.Forms.LinkLabel linkSite; - } -} \ No newline at end of file diff --git a/UpdateLib/UpdateLib/UI/UpdaterForm.cs b/UpdateLib/UpdateLib/UI/UpdaterForm.cs deleted file mode 100644 index 8cc21c8..0000000 --- a/UpdateLib/UpdateLib/UI/UpdaterForm.cs +++ /dev/null @@ -1,257 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.UI.Components; -using System; -using System.Diagnostics; -using System.Drawing; -using System.Windows.Forms; - -namespace MatthiWare.UpdateLib.UI -{ - public partial class UpdaterForm : Form - { - internal UpdateFile updateInfoFile; - internal bool NeedsRestart = true; - internal bool hasHadErrors = false; - internal bool UserCancelled = false; - - private WizardPageCollection pages; - - public UpdaterForm(UpdateFile updateFile) - { - InitializeComponent(); - - updateInfoFile = updateFile; - - pages = new WizardPageCollection(); - AddPage(new IntroPage(this)); - AddPage(new ChangelogPage(this)); - AddPage(new UpdatePage(this)); - AddPage(new FinishPage(this)); - - SetContentPage(pages.FirstPage); - } - - private void SetContentPage(IWizardPage page) - { - page.PageEntered(); - - for (int i = pnlContent.Controls.Count - 1; i >= 0; i--) - { - IWizardPage item = pnlContent.Controls[i] as IWizardPage; - if (item == null) - continue; - - pnlContent.Controls.RemoveAt(i); - } - - pnlContent.Controls.Add(page.Conent); - } - - private void AddPage(IWizardPage page) - { - page.PageUpdate += Page_PageUpdate; - pages.Add(page); - } - - private void Page_PageUpdate(object sender, EventArgs e) - { - - IWizardPage page = (IWizardPage)sender; - OnPageUpdate(page); - } - - delegate void _OnPageUpdate(IWizardPage page); - private void OnPageUpdate(IWizardPage page) - { - this.InvokeOnUI(() => - { - if (page.IsDone && !page.IsBusy) - { - btnNext.Enabled = true; - if (page == pages.CurrentPage) - btnNext.Focus(); - if (page.NeedsExecution) - btnNext.Text = "Next >"; - } - - if (page.HasErrors && page.NeedsRollBack) - { - hasHadErrors = true; - btnNext.Enabled = true; - btnPrevious.Enabled = false; - btnCancel.Enabled = false; - btnNext.Text = "Rollback"; - } - - if (!pages.CurrentPage.HasErrors && pages.CurrentPage.NeedsRollBack && hasHadErrors) - { - foreach (IWizardPage wp in pages) - wp.UpdateState(); - } - - if (pages.AllDone()) - btnCancel.Enabled = false; - - }); - } - - private void btnPrevious_Click(object sender, EventArgs e) - { - IWizardPage currentPage = pages.CurrentPage; - IWizardPage page = pages.Previous(); - - if (page == null) - return; - - if (!btnNext.Enabled) - btnNext.Enabled = true; - - if (page.NeedsExecution) - btnNext.Text = "Next >"; - - if (page == pages.FirstPage) - btnPrevious.Enabled = false; - - SetContentPage(page); - } - - private void btnNext_Click(object sender, EventArgs e) - { - if (pages.CurrentPage.HasErrors && pages.CurrentPage.NeedsRollBack) - { - btnNext.Enabled = false; - pages.CurrentPage.Rollback(); - return; - } - - if (pages.CurrentPage.NeedsExecution && !pages.CurrentPage.IsDone) - { - pages.CurrentPage.Execute(); - btnNext.Enabled = false; - return; - } - - if (pages.CurrentPage == pages.LastPage && pages.CurrentPage.IsDone) - { - ExitUpdater(); - return; - } - - IWizardPage page = pages.Next(); - if (page == null) - return; - - if (!btnPrevious.Enabled) - btnPrevious.Enabled = true; - - if (page.NeedsExecution && !page.IsDone) - btnNext.Text = "Update"; - - if (page.NeedsExecution && !page.IsDone && page.IsBusy) - btnNext.Enabled = false; - - if (page.HasErrors && page.NeedsRollBack) - btnNext.Text = "Rollback"; - - if (page == pages.LastPage) - { - btnNext.Text = "Finish"; - btnCancel.Enabled = false; - } - - - SetContentPage(page); - - } - - private void ExitUpdater() - { - Updater.Instance.GetCache().Save(); - - if (NeedsRestart) - { - Updater.Instance.RestartApp(); - } - else - { - pages.Clear(); - FinishPage page = new FinishPage(this); - page.UpdateState(); - pages.Add(page); - SetContentPage(page); - btnPrevious.Enabled = false; - btnCancel.Enabled = false; - Close(); - } - } - - private void btnCancel_Click(object sender, EventArgs e) - { - Cancel(); - } - - private void Cancel() - { - bool cancelled = MessageDialog.Show( - this, - "Cancel", - "Cancel updating?", - "Press Yes to cancel the updating process.\nPress No to keep updating.", - SystemIcons.Exclamation) == DialogResult.Yes; - - if (cancelled) - UserCancelled = true; - - if (!cancelled) - return; - - foreach (IWizardPage page in pages) - { - page.Cancel(); - page.UpdateState(); - } - - pages.CurrentPage = pages.LastPage; - SetContentPage(pages.CurrentPage); - - btnNext.Text = "Finish"; - btnPrevious.Enabled = true; - - OnPageUpdate(pages.CurrentPage); - - } - - private void UpdaterForm_FormClosing(object sender, FormClosingEventArgs e) - { - if (pages.AllDone()) - return; - - Cancel(); - - if (e.CloseReason == CloseReason.UserClosing || e.CloseReason == CloseReason.None) - e.Cancel = true; - } - - private void linkSite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - Process.Start("https://github.com/MatthiWare/UpdateLib"); - } - } -} diff --git a/UpdateLib/UpdateLib/UI/UpdaterForm.resx b/UpdateLib/UpdateLib/UI/UpdaterForm.resx deleted file mode 100644 index 9fe1da0..0000000 --- a/UpdateLib/UpdateLib/UI/UpdaterForm.resx +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - AAABAAIAMDAAAAEAIACoJQAAJgAAABAQAAABACAAaAQAAM4lAAAoAAAAMAAAAGAAAAABACAAAAAAAAAk - AAASCwAAEgsAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8ANJtQDDOYTkgxlEx2MZJLojCQSs0wkEr0MJBK4zCR - SsswkUuyMZJLmTGTTIAylk1fNJtQDP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AACEIy0UgTKaIIM89iuDQv8pgkD/JoI//yWF - QP8liUD/JYdA/yWHQP8mhED/JoI//yiBP/8qg0H/IIM89hSDM5kAhCMs////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAfB9RE30xxxt7Nv8kfjz/IYU8/yWP - Q/88oFb/VKxs/2e2ff9yvIf/abZ+/2K0ev9asXL/VK1t/02pZv82mFH/JYZA/yZ/Pf8bezb/En0wxwqD - K1sAgyMG////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAIUjFBN/Ma4ZdzT/In06/x6G - Ov9MqGP/iMaZ/6XUsv+cz6r/lMuk/43Hnf+JxJn/hMKU/4DAkv99vo3/ebyL/3a7if90u4f/abd//0+p - Zf8zkE3/JX49/yd8Pv8ggzrTDYsvIf///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8AMZRMiwCEIw7///8A////AP///wD///8A////AP///wD///8A////AP///wAJgClUHX037iF3 - OP8jiT//YrZ6/57Qq/+l07L/mc2n/5DIoP+KxZr/hsOX/4LBk/9+v4//er2M/3a7iP9yuYX/breC/2q1 - fv9ms3v/ZLJ5/2KyeP9hs3f/WrBy/zqYU/8nez7/HXw38wiCKUv///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8ALYZF/x58OO4WhzVpAIUkAv///wD///8A////AP///wD///8AAIQjAxN/ - MaEXci//Hno2/z6eWP+i06//p9Sz/5vNqf+TyaL/jsee/4vFmv+IxJn/hsOW/4PBlf+AwJP/fL6O/3a7 - iv9xuIT/a7Z//2aze/9isXf/Xq90/1qtcP9Wq23/VKps/1Ora/9Colv/J30+/xp1M/0VgjGDAIQjAf// - /wD///8A////AP///wD///8A////AP///wD///8ALIRE/yd3PP8mdjv/HX031AmBKkH///8A////AP// - /wANiy8EH4M7ryFyNv8fgzr/b7uD/6/au/+i0bD/mM2m/5TLo/+QyKD/kcig/5LJof+FwpX/c7mG/2Ox - eP9Tqmr/Uqlo/1uucv9jsnn/aLV+/2q1ff9isXj/XK5x/1arbf9SqWr/Tqdm/0ulZP9Jp2L/QaJd/y2G - Rv8ndTv/III6ug2MLxD///8A////AP///wD///8A////AP///wD///8ALIND/iyJRv87l1b/GG0u/xVt - LP8QeS2zDo4wIBuVPAUfgTqzHm80/yqHQv+e0qv/rNa4/5/PrP+YzKX/l8yl/5jNpv+UyqP/Z7R8/zme - Vf8llEP/KZZG/yuXSP8tmEr/LZhK/y2YSv8sl0n/K5dI/yuWSf9Co13/WK1u/1arbf9PqGf/SqVj/0ak - X/9Colz/P6JZ/z2jWP8ujUn/JnM7/x5/OccAhSQE////AP///wD///8A////AP///wD///8AK4FC/TKI - Sf/y/vT/f8OR/xt9Nv8Zai//JXU8+yuCQ9MdazL/J4dD/6TWsv+q1rb/nM2q/5nNpv+azqj/mM2n/1es - b/8nlET/KpZH/zCZTP8zm0//NJtQ/zSbUP80m1D/NJtQ/zSbUP80m1D/NJtQ/zObT/8xmk3/LphL/z6f - WP9JpWP/R6Vg/0KiXP8+oFj/Op5V/zadUv81n1L/L49K/yVuOf8SfS+W////AP///wD///8A////AP// - /wD///8AKn9B/SyDRf/f8+T/y+fS/8Hjyv9XrG7/FXQw/xNiKP8phkL/p9az/6rWtv+dz6r/nM6p/57Q - q/9+wJH/MplP/yuXSP8xmk7/NJtQ/zScUP81nVH/NZ5R/zagU/82olP/NqNU/zajVP82olP/NqBS/zWe - Uf80nFD/M5tP/zKaTv8zm1D/QKFb/z+hWf86nlX/NZxS/zObT/80nFD/NqBT/yyERP8XaC7/CH0mXf// - /wD///8A////AP///wD///8AKn1A/C6DRf/V7t3/udzD/7vexf/B4sr/oNOu/0OhXP+k1rL/qta2/53P - qv+czqr/otGv/1etb/8mlET/L5lM/zObT/80nFD/NZ1R/zagU/80nVH/MJFK/yuAQ/8lbzn/I2k2/yVu - OP8mdDv/Kn5B/zGVTf82olT/NZ9S/zScUP8zm0//MppO/zufVv83nFL/M5tP/zSbUP80m1D/NZ1R/zWg - Uv8mdT3/GW0w+QmEKy7///8A////AP///wD///8AKXxA+zGCSP/Q7Nj/tNq//7DYu/+v17r/sdi6/67W - uf+m1LP/nc+q/53Oqv+f0K3/Tahm/ymWRv8xmk7/NJtQ/zScUP81n1L/NZ5R/yp8QP8hZDP/Imc1/xlw - MfkOcSq/Am4gmgFrHrEObijIGW0w+iBlNP8lcDr/L49K/zahU/81nVH/NJtQ/zObUP8zm1D/NJtQ/zSb - UP80m1D/NJtQ/zWeUf80nVH/JGw3/xtzM+MOjjAP////AP///wD///8AKXo/+zGBSf/L6tX/sNi7/63W - uP+p1LT/pdKx/6HQrv+dzqr/ns6r/57Oq/9GpF//KpZH/zKaTv80nFD/NZ1R/zahU/8xlEz/Imo2/xdk - LP0Sei2dDYsvQACHJQb///8A////AP///wD///8AAIglEhN/MHYZbzDfIWEz/yuBQv81oVL/NZ5R/zSc - UP80m1D/NJtQ/zSbUP80m1D/NJxQ/zWdUf83pFX/MJFK/yJkNP8ceDW8AIMjAf///wD///8AKHg++jWC - Sf/I6NH/rda4/6nUtP+l0rH/odCu/53Oqv+bzan/otCu/0+nZ/8qlkf/MptP/zSbUP81nlH/NZ9S/yp/ - Qf8gYDL/GnEy5gqELD////8A////AP///wD///8A////AP///wD///8A////AP///wAAiCUHEHQsqBRc - J/8mcjr/NJ1R/zWeUf80m1D/NJtQ/zSbUP80nFH/Np9S/zWhU/8shET/IGMy/xdmLPoReC2BAHwXBP// - /wD///8AJ3c9+jaBSv/D587/qdW1/6XTsv+h0K7/nc6q/5rMqP+ezqv/cLmE/yeVRf8ymk7/NJtQ/zSb - UP81nlH/J3Q7/x9cL/8ndTz9KZtHTv///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AAZ2I3MUYCj9JG45/zWiU/81nVH/NJxQ/zWeUv83olT/MJJL/yNnNf8SWSb/DXApvgCB - ISL///8A////AP///wD///8AJ3U8+jd/S/++5Mj/pdOy/6HRrv+dz6v/mc6n/5zNqP+KxZr/KJVF/zCZ - Tf80m1D/NJtQ/zSbUP81nVH/NqJU/y2JRv8gYDL/E1om/w9wKbUBiiYg////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wAEdSRvEVYj/yt+Qf83o1T/NqJT/zSeUf8mdDv/HVgt/xlq - LusHfSdW////AP///wD///8A////AP///wD///8AJnM7+Th+TP+54sX/odGu/53Pq/+Zzaf/mc2o/5vM - qP80m1D/LphL/zSbUP80m1D/NJtQ/zSbUP80m1D/NZ1R/zagUv82olP/KX1A/x1ZLv8VYCn7EHcsjgCG - JAv///8A////AP///wD///8A////AP///wD///8A////AP///wD///8ADm8osBxVLf8xkkv/LYZF/x9a - Lv8TWyf9EXUslACJJQv///8A////AP///wD///8A////AP///wD///8AJnI7+Dl+S/+04MD/nc+r/5nN - p/+Xzab/nc+r/0ynZP8rl0j/M5tP/zSbUP80m1D/NJtQ/zSbUP80m1D/NJtQ/zScUP82oVP/OalY/y+P - Sf8eWC3/D1Ag/wRzIqgAdAoB////AP///wD///8A////AP///wD///8A////AP///wD///8AAYkmDBdo - LeIdVCv/HFYt/xltMM0Khywu////AP///wD///8A////AP///wD///8A////AABiEiErgkOkJXA6+Dp8 - Sv+x3r3/ms2o/5bMpf+azqj/a7Z//yiVRv8ymk7/NJtQ/zSbUP80m1D/NJtQ/zSbUP80nFD/NZ5R/zei - VP80m0//JGs2/xpQKP8YZy7lB30oUv///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AAiAKC4JYSDnFH4waACIJQH///8A////AP///wD///8A////AP///wAAaBUID3MphBx3 - Nfgqf0HyJW859zp7S/+s3Ln/lsul/5fLpf+Mx5v/JpVF/zCaTf80m1D/NJtQ/zSbUP80m1D/NJtQ/zWd - Uf82oVP/NaFT/yd3Pv8ZTCf/E1km+BF4LYABiSYG////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wAAfhgC////AP///wD///8A////AP///wD///8A////AABp - GlUUdC7kL4BG/yV5O/8pfEDzJG049jp5TP+n2rb/k8qi/5nNqP9JpmL/LZhK/zSbUP80m1D/NJtQ/zSb - UP80nFH/NqBS/zimVv8rhET/G1Eq/w9NIP4NaiasAYsnGP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wAAYxEpB24jvglsJP9fk2//grSQ/yN6PP8oeT70JGs39jl3Sv+j2LH/k8qj/4PCk/8mlET/MppO/zSb - UP80m1D/NJxQ/zWfUv83pVX/MJFL/x5aLf8YSSb/FmYs0guGLDf///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8AAGIQDQxxJpAPcSn8LHtB/5a1nv/a69//OaVX/yR3Ov8ndj30I2o29Tp2S/+f1q//lsuk/0Cg - Wv8umEv/NJtQ/zScUP81nlH/N6NU/zSdUf8jZjX/FUIh/xJaJu8TfjBkAYkmAf///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wAAahxiE3Mt6xdyMf9jmHL/v9fH/9Hs1/+Lx5v/JppG/yZ0PP8mczv2I2k28jt2 - TP+g2K//eL2K/yiVRf8zm0//NZ1R/zahU/83o1P/J3c9/xZFI/8PUCH8DnIpkQGLJwv///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8AAGcTNAlvJcgKbCX/N4FL/6jFr//J6NH/vuLH/8Piy/8xmk7/MJ9O/yZz - O/8lcDn3I2o28j12Tf+i2bL/OJxU/y+aTP82oFL/OKZV/y2GRf8ZTij/C0Ub/wplJLwAhSMi////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AABhERMNciidEHAr/RxzM/94p4X/y+XQ/8Diyf+z277/ttvA/36/ - j/8llEP/NqJT/yVvOf8kbTj3I2o28UF3Uf96xI//KplI/zakVP8xlk3/Hlwv/xZEI/8VYireCH8pR/// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wAAhyQCD3MqbhZ0L/EWci//SYta/7jVwf/I59H/t93C/63Y - uv+t1rf/r9e5/yyYSP8vmUz/N6NU/yRtOP8jajb4I2o38El9Vf9Cr1//MZ1P/yRrN/8WQiH/Elck9RF5 - LXUBiiYD////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AAFrHj8YdTHSG3Qz/yN2Of+Qu5z/zerU/7zf - xf+v2Lr/qtW2/6XTs/+s1bj/ZLJ5/ymWRv8zm1D/N6RU/yNrN/8iZzX5I2o27zBzQf8ngED/F0ck/w5L - Hv0NbCaiAYwnEv///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAYhIbDXEpqRJwLP4Vby7/XJtt/8fj - z//B48z/tNu//6vVtv+m07L/odGu/6LRr/+bzqn/JpRD/zCaTf80m1D/N6RV/yNnNv8hYzP5I2o37xdI - JP8LRBv/CWEhygCDIi7///8A////AP///wD///8A////AP///wD///8AAHoVAv///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAFcMBRB1K3sYdDD2GnMy/y5/ - Rf+pzrP/yOfQ/7jdwv+u17n/qNS0/6PRsP+ez6v/ms6o/6HQrf9LpmX/LJdJ/zSbUP80m1D/N6VV/yJl - M/8gYDH5JGs37xRfKOkHeiVZ////AP///wD///8A////AP///wD///8A////AP///wALhy1NGY453QqD - Kkv///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wACbR9LHHk23iF5 - Of8aczL/da+F/8zp1P+94Mf/r9m7/6nUtP+l0rH/oNCt/5vNqf+Wy6X/l8yl/3/Akf8mlET/MppO/zSb - UP80m1D/OKVV/yBiMv8fXTD6MI9KbgCIJQj///8A////AP///wD///8A////AP///wD///8AAIEhHhiO - OLAhkj//L5ZK/yGNPvAJgSkg////AP///wD///8A////AP///wD///8A////AP///wD///8A////AABj - EYobdzT/KXw//zOCSP/L6dT/zuzW/7bcwf+q1bb/pdOy/6HQrv+czqn/mMym/5PKov+QyKD/lsqk/zac - Uv8vmUv/NJtQ/zSbUP80m1D/OKZV/x9fMf8eWi77////AP///wD///8A////AP///wD///8A////AACB - IQQZjjl1IZI/9x+NPP8wlEz/Xaxy/yCKPf8giD3MAIMjBv///wD///8A////AP///wD///8A////AP// - /wD///8A////AABDAAQNbyh2GXEx8h1wNP80fUj/mcWl/7jgw/+o1rX/ntCs/5nMp/+UyqP/j8ie/4zG - nP+Nxp3/YrJ4/yqWR/8zm0//NJtQ/zSbUP80m1D/OKZW/x9dMP8dVy37////AP///wD///8A////AP// - /wD///8AC4gtOySUQtMlkkP/E4c0/4fCl////////////y2RSP8jhj7/E30wmP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8AAFsNFQlmI6IQZCf9E2Uq/0uGWv+cy6j/ndOt/5LJ - of+Mxpz/h8SY/4XClf+EwpT/K5dJ/zGaTf80m1D/NJtQ/zSbUP80m1D/OKdW/x5aLv8dVy38////AP// - /wD///8A////AACBIRMZjjmcI5JC/h+NPv9RpGb/8vn1///////8/v3//////9fs3f8UfS//GHwz/xB3 - LJAAhiQC////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAacTM7IWw19BNg - KP8RViT/f7KO/4rFmv+EwpX/gMGS/4HBlP9LpmT/LZhK/zSbUP80m1D/NJtQ/zSbUP80m1D/OKdW/x5a - L/8dViz8////AP///wD///8AAIEhYyWUQ+4zmE7/MJVM/0aiYP////////////L49P/r9e7/6vTs//X6 - 9v+t1bn/GX00/yF9Ov8deja/AGgcE////wD///8A////AP///wD///8A////AP///wD///8A////AABf - GTEUZSvXGmMt/yNoNf93s4n/jsyf/4LDk/98vo7/e76O/222gf8qlkf/MptP/zSbUP80m1D/NJtQ/zSb - UP80m1D/OKZW/x5cL/8dViz8////AP///wD///8ACoMqjTKXTv8ylk3/M5xQ/x+RPv+UyqP//////+z2 - 7v/j8ef/3+/j/97u4v/m9Or/v+HI/yGBO/8ddjX/GHQx6g1vKIgAYRAe////AP///wD///8A////AAA7 - AAMAXxdBCWEhlRBdJfsUXCn/RoNW/5TOpP+LyJv/f8CR/3m9i/93u4n/crqH/zKaTv8wmk3/NJtQ/zSb - UP80m1D/NJtQ/zSbUP80m1D/OKZW/x5cL/8dViz9////AP///wD///8AAIIiBSOMQMkxkUv/MpZN/y6a - S/8ckDz/u97E//P69P/f7+P/1+vc/9Lp2P/P59b/1ezc/8no0f9RmmT/Emss/xtvMv8Vayv9C2Qi0ABb - F7gAXBWkCWMhuxRkKfUdZTH/Fl4p/x5hMP9xq4D/kc+i/4LDlf96vYz/dbuI/3O6hf9zuYb/PZ9Y/y+Z - TP80m1D/NZ1R/zWeUf81nlH/NJxQ/zSbUP80m1D/OKZW/x5cL/8dViz9////AP///wD///8A////AAZ6 - JyEihz7yLoxI/zKZT/8smUr/G446/6PRsP/o8+r/1OrZ/8rl0f/F4s3/weDK/8TjzP/L6NL/stq+/0+b - ZP8fcDT/Dl8l/xFgJ/8TXyf/EFwl/xdiLP89gU7/bqh9/47Hn/+HyJr/fcCP/3a7if9yuYX/b7iC/262 - gv9Lp2X/LphL/zObT/81nlL/NqNT/yl8P/81oVL/NqJU/zWeUf80nFD/OKZW/x5cLv8dViz9////AP// - /wD///8A////AP///wAFdSNVIIE6/y2JRf80nFH/LppL/x2QPP+EwpX/2+3g/8vm0f+/38f/uNzC/7Ta - vv+y2b3/stm8/7XdwP+44cP/sNu8/5TKov+CvJH/lMej/57Wrv+Tz6T/iciZ/3/BkP95vYz/c7qG/264 - gv9stn//a7Z//0akX/8umEv/M5tP/zWeUv82pFT/JGo2/xdIJf8aTyn/K39B/zekVf82oVP/OKhX/x5c - MP8dViz+////AP///wD///8A////AP///wD///8AEXgtmSuDRP8shkX/NJ1R/zCbTf8jk0L/QqFc/7fc - wf/E4cv/tdu//63XuP+n07P/o9Gw/57Pq/+Zzaf/l8ul/5TLov+Pyp//iMWa/4PClP9+v4//eb2L/3S6 - h/9vuIP/bLaB/2m2ff9ntH3/P6Ba/y6ZS/8zm0//NZ9S/zalVP8kajf/GUwn/x1XLOkbUyr5GEwn/x1X - Lf8vjEj/O7Bb/x9gMv8cViz+////AP///wD///8A////AP///wD///8AAF0OBh17NrEqfED/K4BB/zOb - UP8znVD/KpdI/yKSQv9rt4D/r9i6/7HZu/+k0bD/m86p/5bLpf+RyaD/jcac/4jEmP+DwpT/fr+Q/3q9 - jP92u4j/cbmE/222gP9ptX7/Z7V8/1etb/81m1H/MJlM/zObT/82n1L/N6RV/yJqNf8ZTCf/Dk0g3Qdb - HRkAUBEgAksVtwxEG/4YSyb/I2o2/yBdMP8cViz+////AP///wD///8A////AP///wD///8A////AACH - JAEMbCibGnEy/yl4Pf8ymU7/NZ9S/zCaTf8plkb/I5JB/1mucf+Xy6X/odGu/5fMpv+PyJ//iMWZ/4HA - kv97vo3/druJ/3O5iP9xuIX/breB/2u1f/9brnH/Op1U/y6YSv8xmk7/NJ1R/zaiU/80nVH/IWQz/xlM - J/8QTyDYAFERFP///wD///8A////AABDAkQBRRLXC0cc/xtTKv8cViz/////AP///wD///8A////AP// - /wD///8A////AP///wD///8AAGQaghdrL/4lcjr/L4pI/zWhUv81n1L/MZtO/yuXSf8klEP/MZlO/1Gp - aP9rtn//er6L/3q+jP97vo3/eL6L/2u1f/9YrG//R6Rg/zmeU/8tmEr/MZpN/zScUP81n1L/OKVV/yyG - Rf8aUCn/CkQa/wFGFM0ARAEQ////AP///wD///8A////AP///wD///8AAEkNbg9OH+4cViz/////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AABfF2kWZy36I2o3/yVxOv8wkkv/N6NU/zWf - Uv80nFD/MZpO/y6YS/8qlkj/KJVG/yiVRv8olUb/KZZG/yuXSP8tmEr/MJlM/zKaTv80nFD/NqBS/zel - Vf81n1D/ImY0/xhLJv8MRxz6AEMKhf///wD///8A////AP///wD///8A////AP///wD///8A////AAA/ - AAwhYzOZ////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAVAkjCV0ftRRd - J/4gYTL/J3U9/zGVTP82pVT/N6NU/zagUv81nVH/NJxQ/zSbUP80m1D/NJtQ/zScUP81nlH/NqBS/zej - VP84qFb/L49J/yJmNP8ZSSX/GVAp/xBRIdYATA0v////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AABWE0YTWyfWHlsw/x5aLv8fWy//JnE7/y2KSP82oVP/OalX/zioV/84qFb/OKhX/zeo - Vv8zmk//LolG/yh3Pf8dVSz/GEom/wpEGv8AQhHjAEoMgAAYAAL///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wACjSgBAE8PYwRSGrcQUSH1G1Qr/xpQKf8YSyb/GEkm/xpN - J/8bUyr/HVgt/xhKJv8XSSX/GEom/xhNJ/8MRhz9AUoWwABCAVL///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAndDwEI2o2TyFi - MqUfXTDRHlsv3R5aLucdWC3xHVgt+B5bL+EgXzG+IWMzlCJmNGQjaTYc////AP///wD///8A////AP// - /wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A///AAf// - AAD//wAAf/8AAP/8AAAP/wAA//AAAAf/AAA/4AAAA/8AAA+AAAAA/wAABwAAAAB/AAAAAAAAAD8AAAAA - AAAAPwAAAAAAAAAfAAAAAAAAAA8AAAAAAAAABwAAAAAB4AADAAAAAA/4AAMAAAAAH/4ADwAAAAAH/wA/ - AAAAAAH/gH8AAAAAAP+B/AAAAAAD/8PwAAAAAAf/7+AAAAAAH///gAAAAAB///4AAAAAAP///AAAAAAD - ///wAAAAAA///8AAAAAAP///AAAAAAB///4AAAAAAf//+AAAAAAH9//gAAAAAB/j/8AAAAAAP4H/gAAA - AAD+AP+AAAAAAPwA/+AAAAAA8AA/+AAAAADgAB/wAAAAAOAAB4AAAAAA4AAAAAAAAADwAAAAAAAAAPgA - AAAAAAAA/AAAAAAAAAD8AAAAAAAAAP4AAAAA4AAA/4AAAAH4AAD/wAAAB/wAAP/gAAAP/wAA//gAAB// - AAD//AAA//8AAP//gAP//wAAKAAAABAAAAAgAAAAAQAgAAAAAAAABAAAEgsAABILAAAAAAAAAAAAAP// - /wD///8A////AP///wA0m1AIMpJMbDOTTt0/mlj4Qpta+TuYVPUyk0zDMJFLIv///wD///8A////AP// - /wAvjEhW////AP///wAAbhkgJIU99Hu4jP+q17b/sdq8/6DRrv+PyZ//cbmF/zOPTf4FeCSi////AP// - /wD///8AQpFY/BB3K+4AbRp8LodG/MHgyf+j1LH/abZ+/0KkW/9BpFz/Wa9w/2W0ev9fsXX/NJVP/wZ0 - I83///8A////AGamd/3h9ef/cbCC/8rn0v9+wpD/I5ZD/yaNQf8mgT77J4FA+yeJQv8smUr/R6dh/0Kk - XP8giDz/AG0alP///wBionP91O3b/77fx/9otn7/JZVD/yV7PP4vhUahKZxJChuVPAQLaSU/G3Qz+DOf - Uf81oVL/IIU8/wJoHd7///8AX51w/cbn0P+ZzKf/I5JB/zKdT/8yl03/KHU8+Q1qJkz///8A////AABi - GiYccjP6Kn1B+R54N3j///8ALIVFFlqZa/3B5cr/O59W/y6bS/81n1H/G3Uz/RBtKb4AZwwK////AP// - /wD///8AAGEYJCCIPAsMXCIEKotEpTKDR/hVlGb9fseR/ymcSP8bdjT/DGIi5ABbDSH///8A////AP// - /wD///8A////AP///wARfS5ZU5Zk96zTtv8sg0T8SY5c/SyOSP8hbDb1GmwwVP///wD///8A////AP// - /wD///8A////AABfCSEQdCvjfrCL/9Lr2f9Wsm//Kn5B/SVuOfYabDGZJptFASOXQwgIiCsg////AP// - /wD///8AAF8HCA14KbdUmWf+weDL/7new/+MyJz/JppF/yl4Pv00m1AM////ABqTO2BLpGP4OplV+wB0 - GS7///8A////AA1uJ0A2hUv4nsiq/6vZt/+WzKX/NpxS/zGgT/8nczv9////AAqHLM9IoWD///////3/ - /v8efzb6AGYaTAFeGgkRaykKGHIwmjR3Rv6Mx5z/V65u/yyYSf83pVT/JnI7/f///wAAeR5jDn8s/ozJ - nf/t+PD/zufV/3ywi/9Bh1T9Sodb/XCqf/+Myp7/XrV1/yudSv8pfj//N6ZW/yZyO/3///8A////AAJy - IIgPeyv/QKRb/5jQqP+y3L3/otWx/5DNoP9zvof/TKtk/yycS/8SXCb9B1QbjghYHfAgYjL9////AP// - /wD///8ABGwfoBRwLfshij7/KZxJ/zmkVf85pFf/K5tJ/ymFQf8TWyX4AEgNNP///wD///8AImU0Zv// - /wD///8A////AP///wAlcDoLKXY+mSdyO/Umcjv7JnE7+ydwO+cmbzqHI2k2EP///wD///8A////AP// - /wDwDwAAYAcAAAADAAAAAQAAAAEAAADCAAAA4AAAA/AAAA/AAAAHAAAAQwAAAIAAAACAAAAAwAAAAOAG - AADwDwAA - - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib/UI/WizardPageCollection.cs b/UpdateLib/UpdateLib/UI/WizardPageCollection.cs deleted file mode 100644 index c676ef0..0000000 --- a/UpdateLib/UpdateLib/UI/WizardPageCollection.cs +++ /dev/null @@ -1,178 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace MatthiWare.UpdateLib.UI -{ - public class WizardPageCollection : IList - { - private List store; - - private int index = 0; - - public IWizardPage CurrentPage - { - get - { - return this[index]; - } - set - { - index = store.IndexOf(value); - } - } - - public IWizardPage FirstPage { get { return this.First(); } } - - public IWizardPage LastPage { get { return this.Last(); } } - - - - public WizardPageCollection() { store = new List(5); } - - public void Cancel() - { - - } - - public IWizardPage Next() - { - if (CurrentPage == LastPage) - return null; - - if (CurrentPage.IsBusy || !CurrentPage.IsDone) - return null; - - index++; - return CurrentPage; - } - - public IWizardPage Previous() - { - if (CurrentPage == FirstPage) - return null; - - //if (CurrentPage.IsBusy || !CurrentPage.IsDone) - // return null; - - index--; - return CurrentPage; - } - - public bool AllDone() - { - foreach (IWizardPage page in store) - { - if (!page.IsDone || page.HasErrors) - return false; - } - return true; - } - - #region IList Implementation - - public int Count - { - get - { - return store.Count; - } - } - - public bool IsReadOnly - { - get - { - return false; - } - } - - public IWizardPage this[int index] - { - get - { - return store[index]; - } - - set - { - store[index] = value; - } - } - - public int IndexOf(IWizardPage item) - { - return store.IndexOf(item); - } - - public void Insert(int index, IWizardPage item) - { - store.Insert(index, item); - } - - public void RemoveAt(int index) - { - store.RemoveAt(index); - } - - public void Add(IWizardPage item) - { - if (item == null) - throw new ArgumentNullException("item"); - - item.Conent.Dock = System.Windows.Forms.DockStyle.Fill; - store.Add(item); - } - - public void Clear() - { - index = 0; - store.Clear(); - } - - public bool Contains(IWizardPage item) - { - return store.Contains(item); - } - - public void CopyTo(IWizardPage[] array, int arrayIndex) - { - store.CopyTo(array, arrayIndex); - } - - public bool Remove(IWizardPage item) - { - return store.Remove(item); - } - - public IEnumerator GetEnumerator() - { - return store.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return store.GetEnumerator(); - } - - #endregion - } -} diff --git a/UpdateLib/UpdateLib/UpdateLib.csproj b/UpdateLib/UpdateLib/UpdateLib.csproj index 96c445a..4ef8463 100644 --- a/UpdateLib/UpdateLib/UpdateLib.csproj +++ b/UpdateLib/UpdateLib/UpdateLib.csproj @@ -1,195 +1,22 @@ - - - + - Debug - AnyCPU - {4394BE57-95E2-45B1-A968-1404B0590B35} - Library - Properties + netstandard2.0 MatthiWare.UpdateLib - UpdateLib - v3.5 - 512 - - + false + 7.1 - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - Auto - - - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - updater.ico - - - - - - - - - - - - - - - UserControl - - - UpdaterControl.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Resources.resx - - - - - - - - UserControl - - - ChangelogPage.cs - - - UserControl - - - FinishPage.cs - - - UserControl - - - IntroPage.cs - - - UserControl - - - UpdatePage.cs - - - - Form - - - MessageDialog.cs - - - - Form - - - UpdaterForm.cs - - - - - - - - - - - + + + - - - - - - - - - - + - - UpdaterControl.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - - - ChangelogPage.cs - - - FinishPage.cs - - - IntroPage.cs - - - UpdatePage.cs - - - MessageDialog.cs - - - UpdaterForm.cs - + + + + - - \ No newline at end of file diff --git a/UpdateLib/UpdateLib/Updater.cs b/UpdateLib/UpdateLib/Updater.cs index e05ad6d..aebc0e3 100644 --- a/UpdateLib/UpdateLib/Updater.cs +++ b/UpdateLib/UpdateLib/Updater.cs @@ -1,5 +1,12 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) +/* Copyright + * + * UpdateLib - .Net auto update library + * + * File: Updater.cs v0.5 + * + * Author: Matthias Beerens + * + * Copyright (C) 2015 - MatthiWare * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published @@ -12,567 +19,177 @@ * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . + * along with this program. If not, see . */ using System; -using MatthiWare.UpdateLib.Files; -using System.Windows.Forms; -using MatthiWare.UpdateLib.UI; -using System.Drawing; -using MatthiWare.UpdateLib.Tasks; -using MatthiWare.UpdateLib.Logging; -using System.Security; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using MatthiWare.UpdateLib.Utils; -using System.Collections.Generic; using System.Reflection; -using System.Net; -using MatthiWare.UpdateLib.Security; -using System.ComponentModel; +using System.Threading; +using System.Threading.Tasks; +using MatthiWare.UpdateLib.Abstractions; +using MatthiWare.UpdateLib.Abstractions.Internal; using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Core; +using MatthiWare.UpdateLib.Utils; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace MatthiWare.UpdateLib { - public sealed class Updater + public sealed class Updater : IUpdater { - #region Singleton - private static volatile Updater instance = null; - private static readonly object synclock = new object(); - - /// - /// Gets a thread safe instance of - /// - public static Updater Instance - { - get - { - if (instance == null) - lock (synclock) - if (instance == null) - instance = new Updater(); - - return instance; - } - } - #endregion - #region Fields - private const string m_strUpdateLib = "UpdateLib"; - - private string m_updateUrl = string.Empty; - private const string m_argUpdateSilent = "silent"; - private const string m_argUpdate = "update"; - private const string m_argWait = "wait"; - private Lazy m_lazyPathVarConv = new Lazy(() => new PathVariableConverter()); - private TimeSpan m_cacheInvalidation = TimeSpan.FromMinutes(5); - private Lazy m_lazyLogger = new Lazy(() => new Logger()); - private InstallationMode m_installationMode = InstallationMode.Shared; - - private static Lazy m_lazyProductName = new Lazy(() => - { - AssemblyProductAttribute attr = Assembly.GetEntryAssembly()?.GetCustomAttributes(typeof(AssemblyProductAttribute), true).FirstOrDefault() as AssemblyProductAttribute; - - //AssemblyProductAttribute attr = Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), ) as AssemblyProductAttribute; - return attr?.Product ?? m_strUpdateLib; - }); - - private static Lazy m_lazyUpdaterName = new Lazy(() => - { - AssemblyProductAttribute attr = Assembly.GetAssembly(typeof(Updater))?.GetCustomAttributes(typeof(AssemblyProductAttribute), true).FirstOrDefault() as AssemblyProductAttribute; - - //AssemblyProductAttribute attr = Attribute.GetCustomAttribute(), typeof(AssemblyProductAttribute)) as AssemblyProductAttribute; - return attr?.Product ?? m_strUpdateLib; - }); - - #endregion - - #region Events - - /// - /// Check for updates completed event. - /// - public event EventHandler CheckForUpdatesCompleted; - - #endregion - - #region Properties - - internal static string ProductName { get { return m_lazyProductName.Value; } } - - internal static string UpdaterName { get { return m_lazyUpdaterName.Value; } } - - public CmdLineParser CommandLine { get; } = new CmdLineParser(); - - /// - /// Gets or sets the url to update from - /// - /// If you want to specify an unsafe connection you should enable - public string UpdateURL - { - get { return m_updateUrl; } - set - { - m_updateUrl = value; - RemoteBasePath = IOUtils.GetRemoteBasePath(value); - } - } - - /// - /// Gets the logger for the application. - /// - public ILogger Logger { get { return m_lazyLogger.Value; } } - - /// - /// Gets or sets the Updater Installation mode - /// - public InstallationMode InstallationMode - { - get { return m_installationMode; } - set - { - if (m_installationMode != value) - { - m_installationMode = value; - IOUtils.ReinitializeAppData(); - } - } - } + private readonly ILogger logger; + private readonly UpdateLibOptions options; + private readonly ICommandLineParser cmd; + private readonly IUpdateManager updateManager; + private bool m_initialized = false; /// /// Gets or sets if we want to check for updates before the actual program is loaded. /// - public bool StartUpdating { get; private set; } = false; - - /// - /// Gets or sets if we want to update silently (no UI interaction). - /// - public bool UpdateSilently { get; private set; } = false; + private bool m_startUpdating = false; /// /// Indicates if we want to wait for the given process to wait - /// See and - /// If this property has been set to true it will wait for the to exit before continuing when has been called. - /// - public bool WaitForProcessExit { get; private set; } - - /// - /// Gets the . - /// This property is only initialized when called. - /// - public PathVariableConverter Converter - { - get { return m_lazyPathVarConv.Value; } - private set { m_lazyPathVarConv.Value = value; } - } - - /// - /// Gets or sets if the updater allows unsafe connection - /// `True` to allow HTTP connections, `False` to only allow HTTPS connections - /// - public bool AllowUnsafeConnection { get; set; } = false; - - /// - /// Gets the clean up task - /// - public CleanUpTask CleanUpTask { get; private set; } - - /// - /// Gets the update cache task - /// - public UpdateCacheTask UpdateCacheTask { get; private set; } - - /// - /// Is the updater already initialized? - /// - public bool IsInitialized { get; private set; } - - /// - /// Time before all the cached files become invalid - /// - public TimeSpan CacheInvalidationTime - { - get { return m_cacheInvalidation; } - set { m_cacheInvalidation = value; } - } - - /// - /// Gets or sets if the updater needs to launch as a new instance. - /// True if you want cold-swapping, False if you want hot-swapping + /// If this property has been set to true it will wait for the to exit before continuing when has been called. /// - /// Hot-swapping might cause issues if the files are still in use. - public bool NeedsRestartBeforeUpdate { get; set; } = true; + private bool m_waitForProcessExit = false; - /// - /// The remote base path to use for downloading etc.. - /// - internal string RemoteBasePath { get; set; } + private bool m_rollback = false; #endregion - #region Fluent API - /// - /// Configures the path variable converter - /// - /// the action to perform on the - /// - public Updater ConfigurePathConverter(Action action) - { - action(Converter); - - return this; - } - - /// - /// Configures if unsafe connections are allowed - /// - /// Do not enable this unless you know what you are doing - /// Allowed? - /// - public Updater ConfigureUnsafeConnections(bool allow) - { - AllowUnsafeConnection = allow; - - return this; - } - - /// - /// Configures the logger + /// Initializes a new instance of with the default settings. /// - /// Action to perform on the logger - /// - public Updater ConfigureLogger(Action action) + public Updater(ILogger logger, IOptions options, ICommandLineParser commandLineParser, IUpdateManager updateManager) { - action(Logger); + this.logger = logger; + this.options = options.Value; + cmd = commandLineParser; + this.updateManager = updateManager; - return this; + //CommandLine.AddParameter(m_argUpdateSilent); + //CommandLine.AddParameter(m_argUpdate); + //CommandLine.AddParameter(m_argWait, ParamMandatoryType.Optional, ParamValueType.Int); + //CommandLine.AddParameter(m_rollback); } - /// - /// Configures the command line parser - /// - /// Action to perform on the command line parser - /// - public Updater ConfigureCommandLineParser(Action action) - { - action(CommandLine); - - return this; - } + public static UpdaterBuilder GetBuilder() + => UpdaterBuilder.CreateDefaultUpdateBuilder(); /// - /// Configures if the updater needs a restart before updating - /// - /// Disabling this feature will allow for hot-swapping of the files. - /// Restart updater in new instance - /// - public Updater ConfigureNeedsRestartBeforeUpdate(bool needsRestartBeforeUpdate) - { - NeedsRestartBeforeUpdate = needsRestartBeforeUpdate; - - return this; - } - - /// - /// Configures the time till the cache becomes invalid + /// Initializes the updater /// - /// Specify the validity time - /// - public Updater ConfigureCacheInvalidation(TimeSpan timeTillInvalidation) + public async Task InitializeAsync(CancellationToken cancellation = default) { - CacheInvalidationTime = timeTillInvalidation; + //StartInitializationTasks(); - return this; - } + // parse the command line + cmd.Parse(); - /// - /// Configures the installation mode for the client - /// - /// The - /// - public Updater ConfigureInstallationMode(InstallationMode mode) - { - InstallationMode = mode; + // Set cmd line flags + m_waitForProcessExit = cmd.Get(options.WaitArgumentName)?.IsFound ?? false; + m_startUpdating = cmd.Get(options.UpdateArgumentName)?.IsFound ?? false; + m_rollback = cmd.Get(options.RollbackArgumentName)?.IsFound ?? false; - return this; - } + if (m_waitForProcessExit) await WaitForProcessToExitAsync(cmd.Get(options.WaitArgumentName).Value, cancellation); - /// - /// Configures the update url - /// - /// To use HTTP you should enable - /// Url to update from - /// - public Updater ConfigureUpdateUrl(string url) - { - UpdateURL = url; + m_initialized = true; - return this; + if (m_startUpdating) await CheckForUpdatesAsync(cancellation); } - #endregion - - /// - /// Initializes a new instance of with the default settings. - /// - private Updater() + public async Task CheckForUpdatesAsync(CancellationToken cancellation = default) { - CommandLine.AddParameter(m_argUpdateSilent); - CommandLine.AddParameter(m_argUpdate); - CommandLine.AddParameter(m_argWait, ParamMandatoryType.Optional, ParamValueType.Int); - } + var childCts = CancellationTokenSource.CreateLinkedTokenSource(cancellation); - /// - /// Initializes the updater - /// - public void Initialize() - { - StartInitializationTasks(); + if (!m_initialized) throw new InvalidOperationException("The updater needs to be initialized first"); + if (string.IsNullOrEmpty(options.UpdateUrl)) throw new ArgumentException("No update url specified", nameof(UpdateLibOptions)); - // parse the command line - CommandLine.Parse(); + var checkForUpdatesTask = updateManager.CheckForUpdatesAsync(childCts.Token); + var result = await checkForUpdatesTask; + if (checkForUpdatesTask.IsCanceled || checkForUpdatesTask.IsFaulted || !result.UpdateAvailable) + { + // TODO: what to do here? Let the caller handle it? + return result; + } - WaitForProcessExit = CommandLine[m_argWait]?.IsFound ?? false; - StartUpdating = CommandLine[m_argUpdate]?.IsFound ?? false; - UpdateSilently = CommandLine[m_argUpdateSilent]?.IsFound ?? false; + // update available yay!! + // TODO: let the caller decide if we want to update with some middleware? + Func allowedToUpdate = new Func(() => true); - if (WaitForProcessExit) - WaitForProcessToExit((int)CommandLine[m_argWait].Value); + if (!allowedToUpdate()) + { + // TODO: Is this a good way? + childCts.Cancel(); + } - IsInitialized = true; + bool elevated = false; - if (StartUpdating) - CheckForUpdates(); - } + // we are allowed to update + if (((!m_startUpdating || (result.AdminRightsNeeded && !elevated))) && !RestartApp(true, true, result.AdminRightsNeeded)) + return result; - /// - /// Starts the initialization tasks - /// - private void StartInitializationTasks() - { - CleanUpTask = new CleanUpTask("%appdir%"); - CleanUpTask.ConfigureAwait(false).Start(); + await updateManager.UpdateAsync(childCts.Token); - UpdateCacheTask = new UpdateCacheTask(); - UpdateCacheTask.ConfigureAwait(false).Start(); + return result; } /// /// Waits for a process to exit on the current thread /// /// Process ID - private void WaitForProcessToExit(int pid) + private Task WaitForProcessToExitAsync(int pid, CancellationToken cancellation) { - Process[] processes = Process.GetProcesses(); - Process toWatch = processes.FirstOrDefault(p => p.Id == pid); - - if (toWatch == null) return; + logger.LogInformation($"Waiting for pid {pid} to exit"); - toWatch.CloseMainWindow(); - toWatch.WaitForExit(); - } + var tcs = new TaskCompletionSource(); - /// - /// Starting the update process - /// - /// Whether or not there is an update available and the latest version - public CheckForUpdatesTask.CheckForUpdatesResult CheckForUpdates() - { - return CheckForUpdatesAsync().AwaitTask().Result; - } - - /// - /// Starting the update process - /// - /// The owner window - /// Whether or not there is an update available and the latest version - public CheckForUpdatesTask.CheckForUpdatesResult CheckForUpdates(IWin32Window owner) - { - return CheckForUpdatesAsync(owner).AwaitTask().Result; - } - - /// - /// Start the update process asynchronously - /// - /// The update checker task. - public CheckForUpdatesTask CheckForUpdatesAsync() - { - return CheckForUpdatesAsync(null); - } - - /// - /// Start the update process asynchronously - /// - /// The owner window - /// The update checker task. - public CheckForUpdatesTask CheckForUpdatesAsync(IWin32Window owner) - { - if (!IsInitialized) - throw new InvalidOperationException("The updater needs to be initialized first."); - - if (string.IsNullOrEmpty(UpdateURL)) - throw new ArgumentException("You need to specifify an update url", nameof(UpdateURL)); - - if (!AllowUnsafeConnection && new Uri(UpdateURL).Scheme != Uri.UriSchemeHttps) - throw new SecurityException("Using unsafe connections to update from is not allowed"); - - CheckForUpdatesTask task = new CheckForUpdatesTask(UpdateURL); - task.TaskCompleted += (o, e) => + cancellation.Register(() => { - bool error = e.Error != null; - bool cancelled = e.Cancelled; - bool update = task.Result.UpdateAvailable; - bool adminReq = task.Result.AdminRightsNeeded; - - CheckForUpdatesCompleted?.Invoke(task, new CheckForUpdatesCompletedEventArgs(task.Result, e)); - - if (!update || cancelled || error) - { - if (error) - HandleException(owner, e.Error); - else if (cancelled) - HandleUserCancelled(owner); - else if (!update) - HandleNoUpdate(owner, task.Result.Version); - - return; - } - - DialogResult result = DialogResult.Yes; - - if (!UpdateSilently && !StartUpdating) - result = MessageDialog.Show( - owner, - "Update available", - $"Version {task.Result.Version} available", - "Update now?\nPress yes to update or no to cancel.", - SystemIcons.Question); + tcs.SetCanceled(); + }); - if (result != DialogResult.Yes) - return; + using (var process = Process.GetProcesses().FirstOrDefault(p => p.Id == pid)) + { + if (process.HasExited) tcs.SetResult(process.ExitCode); - if ((!StartUpdating && NeedsRestartBeforeUpdate) - || (adminReq && !PermissionUtil.IsProcessElevated)) - if (!RestartApp(true, UpdateSilently, true, adminReq)) - return; + process.EnableRaisingEvents = true; - if (UpdateSilently) - UpdateWithoutGUI(task.Result.UpdateFile); - else + process.Exited += (sender, args) => { - UpdaterForm updateForm = new UpdaterForm(task.Result.UpdateFile); - updateForm.ShowDialog(owner); - } - - - - }; + tcs.SetResult(process.ExitCode); + }; - return (CheckForUpdatesTask)task.Start(); - } - - private void HandleException(IWin32Window owner, Exception e) - { - if (UpdateSilently) - return; - - if (e is WebException) - MessageDialog.Show( - owner, - $"{ProductName} Updater", - "Error while updating", - "Unable to connect to the update server!\nPlease check your internet connection!", - SystemIcons.Warning, - MessageBoxButtons.OK); - else if (e is Win32Exception) - MessageDialog.Show( - owner, - $"{ProductName} Updater", - "Update cancelled", - "Update got cancelled by the user!", - SystemIcons.Warning, - MessageBoxButtons.OK); - else - MessageDialog.Show( - owner, - $"{ProductName} Updater", - "Error while updating", - "Check the log files for more information!", - SystemIcons.Error, - MessageBoxButtons.OK); - } - - private void HandleNoUpdate(IWin32Window owner, string latest) - { - Logger.Info(nameof(Updater), nameof(CheckForUpdatesAsync), "No update available"); - - if (!UpdateSilently) - MessageDialog.Show( - owner, - $"{ProductName} Updater", - "No Update available", - $"You already have the latest version {latest}", - SystemIcons.Information, - MessageBoxButtons.OK); - } - - private void HandleUserCancelled(IWin32Window owner) - { - Logger.Info(nameof(Updater), nameof(CheckForUpdatesAsync), "Update cancalled"); - - if (!UpdateSilently) - MessageDialog.Show( - owner, - $"{ProductName} Updater", - "Cancelled", - "Update got cancelled", - SystemIcons.Warning, - MessageBoxButtons.OK); - } + process?.CloseMainWindow(); + process?.WaitForExit(1); + } - /// - /// Gets the cached index of the current application - /// - /// The of the current application - public HashCacheFile GetCache() - { - return UpdateCacheTask.AwaitTask().Result; + return tcs.Task; } - /// - /// Updates without user interaction - /// - /// The update specifications file - private void UpdateWithoutGUI(UpdateFile file) - { - DownloadManager downloader = new DownloadManager(file); - downloader.Completed += (o, e) => - { - GetCache().Save(); - RestartApp(); - }; - - downloader.Update(); - } - internal bool RestartApp(bool update = false, bool silent = false, bool waitForPid = true, bool asAdmin = false) + internal bool RestartApp(bool update = false, bool waitForPid = true, bool asAdmin = false) { - Logger.Info(nameof(Updater), nameof(RestartApp), $"Restarting app: update={update} silent={silent} waitForPid={waitForPid} asAdmin={asAdmin}"); + logger.LogDebug($"Restarting app: [update={update}; waitForPid={waitForPid}; asAdmin={asAdmin}]"); List args = new List(Environment.GetCommandLineArgs()); for (int i = 0; i < args.Count; i++) { - if ((!update && args[i] == CommandLine.ParameterPrefix + m_argUpdate) || (!silent && args[i] == CommandLine.ParameterPrefix + m_argUpdateSilent)) + if (!update && args[i] == options.CommandLineArgumentPrefix + options.UpdateArgumentName) { args[i] = string.Empty; } - else if (args[i] == CommandLine.ParameterPrefix + m_argWait) + else if (args[i] == options.CommandLineArgumentPrefix + options.WaitArgumentName) { args[i] = string.Empty; if (i + 1 < args.Count) @@ -580,27 +197,23 @@ internal bool RestartApp(bool update = false, bool silent = false, bool waitForP } } - if (waitForPid && !args.Contains(CommandLine.ParameterPrefix + m_argWait)) + if (waitForPid && !args.Contains(options.CommandLineArgumentPrefix + options.WaitArgumentName)) { - args.Add(CommandLine.ParameterPrefix + m_argWait); + args.Add(options.CommandLineArgumentPrefix + options.WaitArgumentName); args.Add(Process.GetCurrentProcess().Id.ToString()); } - if (update && !args.Contains(CommandLine.ParameterPrefix + m_argUpdate)) - args.Add(CommandLine.ParameterPrefix + m_argUpdate); - - if (silent && !args.Contains(CommandLine.ParameterPrefix + m_argUpdateSilent)) - args.Add(CommandLine.ParameterPrefix + m_argUpdateSilent); + if (update && !args.Contains(options.CommandLineArgumentPrefix + options.UpdateArgumentName)) + args.Add(options.CommandLineArgumentPrefix + options.UpdateArgumentName); string arguments = args.NotEmpty().Distinct().AppendAll(" "); - ProcessStartInfo startInfo = new ProcessStartInfo(Assembly.GetEntryAssembly().Location, arguments); - - startInfo.WindowStyle = ProcessWindowStyle.Normal; - startInfo.UseShellExecute = true; - - if (asAdmin) - startInfo.Verb = "runas"; + ProcessStartInfo startInfo = new ProcessStartInfo(Assembly.GetEntryAssembly().Location, arguments) + { + WindowStyle = ProcessWindowStyle.Normal, + UseShellExecute = true, + Verb = (asAdmin) ? "runas" : string.Empty + }; try { @@ -610,9 +223,9 @@ internal bool RestartApp(bool update = false, bool silent = false, bool waitForP } catch (Exception e) { - Logger.Error(nameof(Updater), nameof(RestartApp), e); + logger.LogError(e, $"Unable to restart the application"); - HandleException(null, e); + //HandleException(owner, e); return false; } @@ -620,5 +233,10 @@ internal bool RestartApp(bool update = false, bool silent = false, bool waitForP // we will never reach this part of the code return true; } + + public void Dispose() + { + + } } } diff --git a/UpdateLib/UpdateLib/UpdaterBuilder.cs b/UpdateLib/UpdateLib/UpdaterBuilder.cs new file mode 100644 index 0000000..725ee23 --- /dev/null +++ b/UpdateLib/UpdateLib/UpdaterBuilder.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MatthiWare.UpdateLib.Abstractions; +using MatthiWare.UpdateLib.Abstractions.Internal; +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Core; +using MatthiWare.UpdateLib.Core.Internal; +using MatthiWare.UpdateLib.Core.Internal.CommandLine; +using MatthiWare.UpdateLib.Utils; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace MatthiWare.UpdateLib +{ + public class UpdaterBuilder + { + private IServiceCollection services; + private UpdateLibOptions options; + + private UpdaterBuilder() + { + services = new ServiceCollection(); + + options = new UpdateLibOptions + { + CommandLineArgumentPrefix = "--", + RollbackArgumentName = "rollback", + UpdateArgumentName = "update", + WaitArgumentName = "wait" + }; + } + + public UpdaterBuilder UseServiceCollection(IServiceCollection services) + { + services = Guard.NotNull(services, nameof(services)); + + return this; + } + + public UpdaterBuilder UseCommandLineArgumentPrefix(string prefix) + { + options.CommandLineArgumentPrefix = Guard.NotNullOrEmpty(prefix, nameof(prefix)); + + return this; + } + + public UpdaterBuilder UseUpdateUrl(string url) + { + options.UpdateUrl = Guard.NotNullOrEmpty(url, nameof(url)); + + return this; + } + + public UpdaterBuilder UseWaitArgument(string argument) + { + options.WaitArgumentName = Guard.NotNullOrEmpty(argument, nameof(argument)); + + return this; + } + + public UpdaterBuilder UseUpdateArgument(string argument) + { + options.UpdateArgumentName = Guard.NotNullOrEmpty(argument, nameof(argument)); + + return this; + } + + public UpdaterBuilder UseRollbackArgument(string argument) + { + options.RollbackArgumentName = Guard.NotNullOrEmpty(argument, nameof(argument)); + + return this; + } + + public static UpdaterBuilder CreateDefaultUpdateBuilder() => new UpdaterBuilder(); + + public IUpdater Build() + { + Validate(); + + RegisterDefaultServices(); + RegisterCommandLineServices(); + + var svcProvider = services.BuildServiceProvider(); + + return svcProvider.GetRequiredService(); + } + + private void RegisterCommandLineServices() + { + services.AddTransient, IntArgumentResolver>(); + services.AddTransient, MultipleIntArgumentResolver>(); + services.AddTransient, StringArgumentResolver>(); + services.AddTransient, UpdateVersionArgumentResolver>(); + } + + private void RegisterDefaultServices() + { + services.AddTransient, DefaultVersionResolver>(); + services.AddTransient(); + + services.AddOptions(); + + services.ConfigureOptions(options); + + services.AddSingleton(); + } + + private void Validate() + { + options.UpdateUrl.NotNullOrEmpty(nameof(options.UpdateUrl)); + } + } +} diff --git a/UpdateLib/UpdateLib/UpdaterControl.bmp b/UpdateLib/UpdateLib/UpdaterControl.bmp deleted file mode 100644 index b40cc5a..0000000 Binary files a/UpdateLib/UpdateLib/UpdaterControl.bmp and /dev/null differ diff --git a/UpdateLib/UpdateLib/Utils/CmdLineParser.cs b/UpdateLib/UpdateLib/Utils/CmdLineParser.cs index e3026ac..d11cb39 100644 --- a/UpdateLib/UpdateLib/Utils/CmdLineParser.cs +++ b/UpdateLib/UpdateLib/Utils/CmdLineParser.cs @@ -1,5 +1,4 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) +/* Copyright (C) 2016 - MatthiWare (Matthias Beerens) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published @@ -14,46 +13,58 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -using MatthiWare.UpdateLib.Common; + using System; -using System.Collections; using System.Collections.Generic; -using System.Collections.Specialized; using System.Linq; -using System.Text; +using MatthiWare.UpdateLib.Abstractions; +using MatthiWare.UpdateLib.Common; +using MatthiWare.UpdateLib.Core; +using Microsoft.Extensions.Options; namespace MatthiWare.UpdateLib.Utils { - public class CmdLineParser + public class CmdLineParser : ICommandLineParser { - private SortedDictionary m_params = new SortedDictionary(); + private SortedDictionary m_params = new SortedDictionary(); + private readonly string m_paramPrefix; - public string ParameterPrefix { get; set; } = "--"; + public CmdLineParser(IOptions options) + => m_paramPrefix = options.Value.CommandLineArgumentPrefix; public void AddParameter(string paramName, ParamMandatoryType mandatoryType = ParamMandatoryType.Optional, ParamValueType valueType = ParamValueType.None) { - if (string.IsNullOrEmpty(paramName)) throw new ArgumentNullException(nameof(paramName)); + Guard.NotNullOrEmpty(paramName, nameof(paramName)); + if (paramName.Contains(' ')) throw new ArgumentException("Parameter cannot contain spaces", nameof(paramName)); if (m_params.ContainsKey(paramName)) throw new ArgumentException("Key already exists", nameof(paramName)); - + var param = new ParameterDefinition(paramName, mandatoryType, valueType); m_params.Add(paramName, param); } - public ParameterDefinition this[string paramName] + public void AddParameter(string paramName, ParamMandatoryType mandatoryType, ParamValueType valueType, ICommandLineArgumentResolver resolver) { - get - { - return m_params.ContainsKey(paramName) ? m_params[paramName] : null; - } + Guard.NotNullOrEmpty(paramName, nameof(paramName)); + + if (paramName.Contains(' ')) throw new ArgumentException("Parameter cannot contain spaces", nameof(paramName)); + if (m_params.ContainsKey(paramName)) throw new ArgumentException("Key already exists", nameof(paramName)); + + var param = new ParameterDefinition(paramName, mandatoryType, valueType, resolver); + m_params.Add(paramName, param); } - public void Parse() => Parse(Environment.GetCommandLineArgs()); + public IParameterDefinition Get(string paramName) + => m_params.ContainsKey(paramName) ? m_params[paramName] as IParameterDefinition : default; + public IParameterDefinition Get(string paramName) + => m_params.ContainsKey(paramName) ? m_params[paramName] : default; + + public void Parse() => Parse(Environment.GetCommandLineArgs()); public void Parse(string[] args) { - if (string.IsNullOrEmpty(ParameterPrefix)) throw new ArgumentNullException(nameof(ParameterPrefix)); + if (string.IsNullOrEmpty(m_paramPrefix)) throw new ArgumentNullException(nameof(m_paramPrefix)); m_params.ForEach(kvp => kvp.Value.Reset()); @@ -61,7 +72,7 @@ public void Parse(string[] args) { string data = args[i]; - var def = m_params.Where(p => ParameterPrefix + p.Key == data).Select(p => p.Value).FirstOrDefault(); + var def = m_params.Where(p => m_paramPrefix + p.Key == data).Select(p => p.Value).FirstOrDefault(); if (def == null) continue; @@ -71,79 +82,36 @@ public void Parse(string[] args) if (def.ValueType == ParamValueType.None) continue; - FindParameterValue(def, args, ref i); + FindParameterValue(def, ref args, ref i); } CheckAllMandatoryParamsFound(); } - private void FindParameterValue(ParameterDefinition param, string[] args, ref int index) + private void FindParameterValue(IParameterDefinition param, ref string[] args, ref int index) { - string data = args[++index]; - bool succes = true; - - if (param.ValueType == ParamValueType.Int || param.ValueType == ParamValueType.OptionalInt) - { - int value; - succes = int.TryParse(data, out value); - - if (succes) - param.Value = value; - } - else if (param.ValueType == ParamValueType.Bool || param.ValueType == ParamValueType.OptionalBool) - { - bool value; - succes = bool.TryParse(data, out value); - - if (succes) - param.Value = value; - } - else if (param.ValueType == ParamValueType.String || param.ValueType == ParamValueType.OptionalString) - { - succes = !data.StartsWith(ParameterPrefix); - - if (succes) - param.Value = data; - } - else if (param.ValueType == ParamValueType.MultipleInts) - { - List values = new List(); - int outValue; - - while (index < args.Length && int.TryParse(args[index], out outValue)) - { - values.Add(outValue); - index++; - } + ++index; + bool succes = param.CanResolve(ref args, ref index); - succes = values.Count >= 2; - - if (succes) - param.Value = values.ToArray(); - } + if (succes) + param.Resolve(ref args, ref index); if (!succes) - { --index; - - if (param.ValueType != ParamValueType.OptionalBool && - param.ValueType != ParamValueType.OptionalInt && - param.ValueType != ParamValueType.OptionalString) - param.Count = 0; - } - } private void CheckAllMandatoryParamsFound() { + var exceptions = new List(); + m_params - .Where(kvp => kvp.Value.MandatoryType == ParamMandatoryType.Required) .Select(kvp => kvp.Value) - .ForEach(param => - { - if (!param.IsFound) - throw new KeyNotFoundException($"Mandatory parameter '{param.ParameterName}' is missing"); - }); + .Where(param => param.MandatoryType == ParamMandatoryType.Required && !param.IsFound) + .ForEach(param => exceptions.Add(new KeyNotFoundException($"Mandatory parameter '{param.Name}' is missing"))); + + if (exceptions.Any()) + throw new AggregateException("One or more mandatory parameters are missing", exceptions); + } } diff --git a/UpdateLib/UpdateLib/Utils/ExtensionMethods.cs b/UpdateLib/UpdateLib/Utils/ExtensionMethods.cs index eb829d1..88c6517 100644 --- a/UpdateLib/UpdateLib/Utils/ExtensionMethods.cs +++ b/UpdateLib/UpdateLib/Utils/ExtensionMethods.cs @@ -17,8 +17,12 @@ using System; using System.Collections.Generic; -using System.Text; +using System.ComponentModel; using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; namespace MatthiWare.UpdateLib.Utils { @@ -39,71 +43,83 @@ public static string AppendAll(this IEnumerable collection, string seperat return builder.ToString(); } - } - [DebuggerStepThrough] - public static void ForEach(this IEnumerable collection, Action action) + public static IEnumerable Replace(this IEnumerable collection, string oldStr, string newStr) { - using (var enumerator = collection.GetEnumerator()) - while (enumerator.MoveNext()) - action(enumerator.Current); + foreach (var str in collection) + yield return str.Replace(oldStr, newStr); } [DebuggerStepThrough] - public static IEnumerable NotNull(this IEnumerable collection) + public static T MaxOrDefault(this IEnumerable collection, Func resolve) where K : IComparable { - using (var enumerator = collection.GetEnumerator()) - while (enumerator.MoveNext()) - if (enumerator.Current != null) - yield return enumerator.Current; + T max = default(T); + foreach (T other in collection) + { + if (max == null) + { + max = other; + continue; + } + + if (resolve(other).CompareTo(resolve(max)) > 0) + max = other; + } + + return max; } + public static string GetDescription(this Type type) + => type.GetCustomAttributes(typeof(DescriptionAttribute), false).Cast().FirstOrDefault().Description ?? "No description available"; + + [DebuggerStepThrough] - public static IEnumerable NotEmpty(this IEnumerable collection) + public static void ForEach(this IEnumerable collection, Action action) { - using (var enumerator = collection.GetEnumerator()) - while (enumerator.MoveNext()) - if (!string.IsNullOrEmpty(enumerator.Current)) - yield return enumerator.Current; + foreach (T item in collection) + action(item); } - /// - /// Skips n amount of the last elements - /// - /// Any - /// The source collection - /// The count of last elements to skip - /// without the last elements. - [DebuggerStepThrough] - public static IEnumerable SkipLast(this IEnumerable source, int count) + public static async Task ForEachAsync(this IEnumerable source, Func action, int maxDegreeOfParallelism, CancellationToken cancellation = default) { - if (count == 0) + using (var semaphore = new SemaphoreSlim(maxDegreeOfParallelism, maxDegreeOfParallelism)) { - foreach (T item in source) - yield return item; - - yield break; - } + var throttledTasks = new List(); - int i = 0; - var buffer = new Queue(count + 1); - - using (var enumerator = source.GetEnumerator()) - { - while (enumerator.MoveNext()) + foreach (var task in source) { - if (i == count) + await semaphore.WaitAsync(cancellation); + + throttledTasks.Add(Task.Run(async () => { - yield return buffer.Dequeue(); - i--; - } + await action(task); + + semaphore.Release(); - buffer.Enqueue(enumerator.Current); - i++; + })); } + + await Task.WhenAll(throttledTasks.ToArray()); } } + + [DebuggerStepThrough] + public static IEnumerable NotNull(this IEnumerable collection) + { + foreach (T item in collection) + if (item != null) + yield return item; + + } + + [DebuggerStepThrough] + public static IEnumerable NotEmpty(this IEnumerable collection) + { + foreach (var item in collection) + if (!string.IsNullOrEmpty(item)) + yield return item; + } } } diff --git a/UpdateLib/UpdateLib/Utils/Guard.cs b/UpdateLib/UpdateLib/Utils/Guard.cs new file mode 100644 index 0000000..5fe459d --- /dev/null +++ b/UpdateLib/UpdateLib/Utils/Guard.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MatthiWare.UpdateLib.Utils +{ + internal static class Guard + { + public static T NotNull(this T value, string propertyName) where T : class + => value ?? throw new ArgumentNullException(propertyName); + + public static string NotNullOrEmpty(this string value, string propertyName) + { + if (string.IsNullOrEmpty(value)) + throw new ArgumentNullException(propertyName); + + return value; + } + } +} diff --git a/UpdateLib/UpdateLib/Utils/IOUtils.cs b/UpdateLib/UpdateLib/Utils/IOUtils.cs index 4430cac..35963e0 100644 --- a/UpdateLib/UpdateLib/Utils/IOUtils.cs +++ b/UpdateLib/UpdateLib/Utils/IOUtils.cs @@ -15,24 +15,30 @@ * along with this program. If not, see . */ -using MatthiWare.UpdateLib.Common; using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Text; +using MatthiWare.UpdateLib.Common; + namespace MatthiWare.UpdateLib.Utils { public static class IOUtils { - private static Lazy m_getAppDataPath = new Lazy(GetAppDataPath); + private static Lazy m_getAppDataPath = new Lazy(() => ""); + private static Lazy m_getCachePath = new Lazy(() => $""); + private static Lazy m_getLogPath = new Lazy(() => $""); + private static Lazy m_getTempPath = new Lazy(() => $""); - internal static void ReinitializeAppData() - { - m_getAppDataPath.Reset(); - } - public static string AppDataPath { get { return m_getAppDataPath.Value; } } + public static string AppDataPath => m_getAppDataPath.Value; + public static string CachePath => m_getCachePath.Value; + public static string LogPath => m_getLogPath.Value; + public static string TempPath => m_getTempPath.Value; - public static string GetRemoteBasePath(string url) + internal static string GetRemoteBasePath(string url) { if (string.IsNullOrEmpty(url)) throw new ArgumentNullException(nameof(url)); @@ -41,40 +47,118 @@ public static string GetRemoteBasePath(string url) StringBuilder builder = new StringBuilder(); - foreach (var s in url.Split(slash, backslash).SkipLast(1)) + foreach (var s in url.Split(slash, backslash)) { builder.Append(s); builder.Append(slash); - } return builder.ToString(); + } - //return .AppendAll(splitter.ToString()); + private class Stack1 + { + public string Key; + public DateTime StartDate; + public DateTime EndDate; } - private static string GetAppDataPath() + private static string GetPathPrefix() { - string path = GetPathPrefix(); - string updaterName = Updater.UpdaterName; - string productName = Updater.ProductName; + //switch (Updater.Instance.InstallationMode) + //{ + // case InstallationMode.Local: + // return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + // case InstallationMode.Shared: + // default: + // return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + //} + + return ""; + - return $@"{path}\{productName}\{updaterName}"; } - private static string GetPathPrefix() + internal static byte[] CheckedReadBytes(this Stream stream, int size) + { + byte[] ret = new byte[size]; + int index = 0; + + while (index < size) + { + int read = stream.Read(ret, index, size - index); + + if (read == 0) + throw new EndOfStreamException(); + + index += read; + } + + return ret; + } + + internal static void CheckedReadBytes(this Stream stream, byte[] buffer, int offset, int length) { - switch (Updater.Instance.InstallationMode) + int index = offset; + int size = offset + length; + + while (index < size) { - case InstallationMode.Local: - return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - case InstallationMode.Shared: - default: - return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + int read = stream.Read(buffer, index, size); + + if (read == 0) + throw new EndOfStreamException(); + + index += read; } + } + + internal static byte CheckedReadByte(this Stream stream) + { + int ret = stream.ReadByte(); + if (ret == -1) + throw new IOException("Unable to read byte from stream"); + return (byte)ret; } + internal static int ReadBigEndian7BitEncodedInt(this Stream stream) + { + int ret = 0; + + for (int i = 0; i < 5; i++) + { + int b = stream.ReadByte(); + if (b == -1) + throw new EndOfStreamException(); + + ret = (ret << 7) | (b & 0x7f); + if ((b & 0x80) == 0) + return ret; + } + + throw new IOException("Invalid 7-bit encoded integer in stream"); + } + + internal static void Copy(Stream source, Stream dest, byte[] buffer) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + if (dest == null) throw new ArgumentNullException(nameof(dest)); + if (buffer == null) throw new ArgumentNullException(nameof(buffer)); + + bool copying = true; + + while (copying) + { + int bytesRead = source.Read(buffer, 0, buffer.Length); + copying = bytesRead > 0; + + if (copying) + dest.Write(buffer, 0, bytesRead); + else + dest.Flush(); + } + } } } diff --git a/UpdateLib/UpdateLib/Utils/Lazy.cs b/UpdateLib/UpdateLib/Utils/Lazy.cs deleted file mode 100644 index 7ec9821..0000000 --- a/UpdateLib/UpdateLib/Utils/Lazy.cs +++ /dev/null @@ -1,82 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System; - -namespace MatthiWare.UpdateLib.Utils -{ - /// - /// Threadsafe lazy initialization - /// - /// The return type - public class Lazy - { - private readonly Func m_initFunction; - - private readonly object sync = new object(); - private bool m_initialized = false; - - private T m_storedValue = default(T); - - /// - /// Gets the value and initializes once. - /// - public T Value - { - get - { - if (!m_initialized) - lock (sync) - if (!m_initialized) - { - m_storedValue = m_initFunction(); - m_initialized = true; - } - - return m_storedValue; - } - set - { - lock (sync) - { - m_initialized = true; - m_storedValue = value; - } - } - } - - /// - /// Resets the lazy function - /// - public void Reset() - { - lock (sync) - m_initialized = false; - } - - /// - /// Makes a new instance of an lazy initializer - /// - /// The lazy initialization function - public Lazy(Func initFunction) - { - m_initFunction = initFunction; - } - - - } -} diff --git a/UpdateLib/UpdateLib/Utils/NetworkUtils.cs b/UpdateLib/UpdateLib/Utils/NetworkUtils.cs deleted file mode 100644 index b4dc6a7..0000000 --- a/UpdateLib/UpdateLib/Utils/NetworkUtils.cs +++ /dev/null @@ -1,31 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Win32; - -namespace MatthiWare.UpdateLib.Utils -{ - public static class NetworkUtils - { - public static bool HasConnection() - { - int desc; - return NativeMethods.InternetGetConnectedState(out desc, 0); - } - - } -} diff --git a/UpdateLib/UpdateLib/Utils/RegistryHelper.cs b/UpdateLib/UpdateLib/Utils/RegistryHelper.cs deleted file mode 100644 index 80aee92..0000000 --- a/UpdateLib/UpdateLib/Utils/RegistryHelper.cs +++ /dev/null @@ -1,160 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using MatthiWare.UpdateLib.Files; -using MatthiWare.UpdateLib.Tasks; -using Microsoft.Win32; -using System; -using System.Linq; -using System.Security.AccessControl; - -namespace MatthiWare.UpdateLib.Utils -{ - public static class RegistryHelper - { - - public static RegistryKey GetOrMakeKey(RegistryKeyEntry key) - { - if (key == null) throw new ArgumentNullException(nameof(key)); - - string pathToKeyRoot = key.Parent.DestinationLocation; - - return GetOrMakeKey(pathToKeyRoot); - } - - public static RegistryKey GetOrMakeKey(string pathToKeyRoot) - { - if (string.IsNullOrEmpty(pathToKeyRoot)) throw new ArgumentNullException(nameof(pathToKeyRoot)); - - string pathToKey = pathToKeyRoot.Split(char.Parse(@"\")).Skip(1).AppendAll(@"\"); - - return OpenSubKey(GetRootKey(pathToKeyRoot), pathToKey); - } - - private static RegistryKey GetRootKey(string pathToKeyRoot) - { - if (pathToKeyRoot.StartsWith("HKEY_LOCAL_MACHINE")) - return Registry.LocalMachine; - else if (pathToKeyRoot.StartsWith("HKEY_CURRENT_USER")) - return Registry.CurrentUser; - else if (pathToKeyRoot.StartsWith("HKEY_CLASSES_ROOT")) - return Registry.ClassesRoot; - else if (pathToKeyRoot.StartsWith("HKEY_USERS")) - return Registry.Users; - else if (pathToKeyRoot.StartsWith("HKEY_CURRENT_CONFIG")) - return Registry.CurrentConfig; - else if (pathToKeyRoot.StartsWith("HKEY_PERFORMANCE_DATA")) - return Registry.PerformanceData; - else if (pathToKeyRoot.StartsWith("HKEY_DYN_DATA")) - return Registry.DynData; - else - return null; - } - - private static RegistryKey OpenSubKey(RegistryKey key, string path) - { - if (key == null) - return null; - - RegistryKey reg = key?.OpenSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl); - - if (reg != null) - return reg; - - key.CreateSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree); - - return OpenSubKey(key, path); - } - - internal static void InternalOpenSubKey(string root, string keyName) - { - RegistryKey key = GetRootKey(root); - - foreach (string item in root.Split(char.Parse(@"\")).Skip(1).NotEmpty()) - { - RegistryKey tmp = key?.OpenSubKey(item, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl); - key?.Close(); - - key = tmp; - } - - key?.Close(); - } - - public static bool IsSame(RegistryKeyEntry key) - { - if (key == null) - return false; - - string path = key.Parent.DestinationLocation; - - try - { - object value = Registry.GetValue(path, key.Name, new NullObject()); - - return key.Value.Equals(value); - - } - catch (Exception e) - { - Updater.Instance.Logger.Error(nameof(RegistryHelper), nameof(IsSame), e); - } - - return false; - } - - public static bool Exists(RegistryKeyEntry key, out object value) - { - value = null; - - if (key == null) - return false; - - string path = key.Parent.DestinationLocation; - - try - { - value = Registry.GetValue(path, key.Name, null); - - return value != null; - } - catch (Exception e) - { - Updater.Instance.Logger.Error(nameof(RegistryHelper), nameof(Exists), e); - } - - return false; - } - - public static void Update(RegistryKeyEntry logicalKey, UpdateRegistryTask.RollbackData rollback) - { - if (logicalKey == null) throw new ArgumentNullException(nameof(logicalKey)); - - RegistryKey key = GetOrMakeKey(logicalKey); - - if (key?.GetValueNames().Contains(logicalKey.Name) ?? false) - rollback.type = key.GetValueKind(logicalKey.Name); - - key.SetValue(logicalKey.Name, logicalKey.Value, logicalKey.Type); - } - - /// - /// We do nothing with this - /// - private class NullObject { } - } -} diff --git a/UpdateLib/UpdateLib/Win32/NativeMethods.cs b/UpdateLib/UpdateLib/Win32/NativeMethods.cs deleted file mode 100644 index 5e7ba9f..0000000 --- a/UpdateLib/UpdateLib/Win32/NativeMethods.cs +++ /dev/null @@ -1,28 +0,0 @@ -/* UpdateLib - .Net auto update library - * Copyright (C) 2016 - MatthiWare (Matthias Beerens) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -using System.Runtime.InteropServices; - -namespace MatthiWare.UpdateLib.Win32 -{ - internal static class NativeMethods - { - [DllImport("wininet.dll")] - internal static extern bool InternetGetConnectedState(out int connDescription, int reservedValue); - - } -} diff --git a/UpdateLib/UpdateLib/updater.ico b/UpdateLib/UpdateLib/updater.ico deleted file mode 100644 index c952e49..0000000 Binary files a/UpdateLib/UpdateLib/updater.ico and /dev/null differ