From cb5471b574955c4d79b457e8480160888a9b1adc Mon Sep 17 00:00:00 2001
From: t0815 <10379828+t0815@users.noreply.github.com>
Date: Fri, 6 Sep 2024 13:59:39 +0200
Subject: [PATCH] add crc32 hashing for new pages, add option to enable hashing
of new pages [#6]
---
MyCBZ/App.config | 6 +
MyCBZ/Data/AddImagesThreadParams.cs | 2 +
MyCBZ/Data/ParseFilesThreadParams.cs | 2 +
MyCBZ/Forms/MainForm.cs | 1 +
MyCBZ/Forms/PageSettingsForm.cs | 6 +
MyCBZ/Forms/SettingsDialog.Designer.cs | 105 +++++++--
MyCBZ/Forms/SettingsDialog.cs | 6 +
MyCBZ/Forms/SettingsDialog.resx | 290 ++++++++++++-------------
MyCBZ/Hash/CRC32.cs | 36 ++-
MyCBZ/Models/MetaData.cs | 1 -
MyCBZ/Models/MetaDataEntryPage.cs | 11 +-
MyCBZ/Models/Page.cs | 39 +++-
MyCBZ/Models/ProjectModel.cs | 144 +++++++++++-
MyCBZ/Win_CBZSettings.Designer.cs | 24 ++
MyCBZ/Win_CBZSettings.settings | 6 +
15 files changed, 496 insertions(+), 183 deletions(-)
diff --git a/MyCBZ/App.config b/MyCBZ/App.config
index 9a2f4d16..6d7f5d65 100644
--- a/MyCBZ/App.config
+++ b/MyCBZ/App.config
@@ -114,6 +114,12 @@
0
+
+ False
+
+
+ False
+
diff --git a/MyCBZ/Data/AddImagesThreadParams.cs b/MyCBZ/Data/AddImagesThreadParams.cs
index bffc73f3..c6ccb5d5 100644
--- a/MyCBZ/Data/AddImagesThreadParams.cs
+++ b/MyCBZ/Data/AddImagesThreadParams.cs
@@ -20,5 +20,7 @@ internal class AddImagesThreadParams : ThreadParam
public string[] FilterExtensions { get; set; } = new string[0];
public int MaxCountPages { get; set; } = 0;
+
+ public bool HashFiles { get; set; } = false;
}
}
diff --git a/MyCBZ/Data/ParseFilesThreadParams.cs b/MyCBZ/Data/ParseFilesThreadParams.cs
index 9fcf6d5e..c93d2569 100644
--- a/MyCBZ/Data/ParseFilesThreadParams.cs
+++ b/MyCBZ/Data/ParseFilesThreadParams.cs
@@ -22,6 +22,8 @@ internal class ParseFilesThreadParams : ThreadParam
public MetaData.PageIndexVersion PageIndexVerToWrite { get; set; } = MetaData.PageIndexVersion.VERSION_1;
+ public bool HashFiles { get; set; } = false;
+
public bool ContinuePipeline { get; set; }
}
}
diff --git a/MyCBZ/Forms/MainForm.cs b/MyCBZ/Forms/MainForm.cs
index bf5f74c7..0cdbc245 100644
--- a/MyCBZ/Forms/MainForm.cs
+++ b/MyCBZ/Forms/MainForm.cs
@@ -4898,6 +4898,7 @@ private void SettingsToolStripMenuItem_Click(object sender, EventArgs e)
Win_CBZSettings.Default.OmitEmptyXMLTags = settingsDialog.OmitEmptyXMLTags;
Win_CBZSettings.Default.AutoDeleteTempFiles = settingsDialog.DeleteTempFilesImediately;
Win_CBZSettings.Default.SkipIndexCheck = settingsDialog.SkipIndexCheck;
+ Win_CBZSettings.Default.CalculateHash = settingsDialog.CalculateCrc32;
Win_CBZSettings.Default.CustomMetadataFields.Clear();
foreach (String line in settingsDialog.CustomFieldTypesCollection)
diff --git a/MyCBZ/Forms/PageSettingsForm.cs b/MyCBZ/Forms/PageSettingsForm.cs
index 99342fac..8109e92e 100644
--- a/MyCBZ/Forms/PageSettingsForm.cs
+++ b/MyCBZ/Forms/PageSettingsForm.cs
@@ -16,6 +16,7 @@
using System.Drawing.Imaging;
using System.Runtime.Versioning;
using System.Threading;
+using Win_CBZ.Hash;
namespace Win_CBZ.Forms
{
@@ -345,6 +346,11 @@ private void ButtonReloadImage_Click(object sender, EventArgs e)
{
Invoke(new Action(() =>
{
+ if (Win_CBZ.Win_CBZSettings.Default.CalculateHash)
+ {
+ HashCrc32.Calculate(ref FirstPage);
+ }
+
ImagePreviewButton.BackgroundImage = Image.FromHbitmap(t.Result.GetHbitmap());
LabelDimensions.Text = FirstPage.Format.W.ToString() + " x " + FirstPage.Format.H.ToString() + " px";
diff --git a/MyCBZ/Forms/SettingsDialog.Designer.cs b/MyCBZ/Forms/SettingsDialog.Designer.cs
index cd0176fc..b150bdaa 100644
--- a/MyCBZ/Forms/SettingsDialog.Designer.cs
+++ b/MyCBZ/Forms/SettingsDialog.Designer.cs
@@ -49,10 +49,14 @@ private void InitializeComponent()
RestoreFieldTypesButton = new System.Windows.Forms.Button();
tabPage5 = new System.Windows.Forms.TabPage();
tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
+ pictureBox3 = new System.Windows.Forms.PictureBox();
CheckBoxSkipIndexCheck = new System.Windows.Forms.CheckBox();
label9 = new System.Windows.Forms.Label();
label7 = new System.Windows.Forms.Label();
CheckBoxDeleteTempFiles = new System.Windows.Forms.CheckBox();
+ label8 = new System.Windows.Forms.Label();
+ CheckBoxCalculateCrc = new System.Windows.Forms.CheckBox();
+ pictureBox4 = new System.Windows.Forms.PictureBox();
CBZSettingsTabControl = new System.Windows.Forms.TabControl();
tabPage2 = new System.Windows.Forms.TabPage();
tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
@@ -104,6 +108,8 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)CustomFieldsDataGrid).BeginInit();
tabPage5.SuspendLayout();
tableLayoutPanel4.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)pictureBox3).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)pictureBox4).BeginInit();
CBZSettingsTabControl.SuspendLayout();
tabPage2.SuspendLayout();
tableLayoutPanel2.SuspendLayout();
@@ -238,11 +244,11 @@ private void InitializeComponent()
//
AppSettingsTabControl.Controls.Add(TabPageAppSettings);
AppSettingsTabControl.Controls.Add(tabPage5);
- AppSettingsTabControl.Location = new System.Drawing.Point(271, 2);
+ AppSettingsTabControl.Location = new System.Drawing.Point(275, 2);
AppSettingsTabControl.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5);
AppSettingsTabControl.Name = "AppSettingsTabControl";
AppSettingsTabControl.SelectedIndex = 0;
- AppSettingsTabControl.Size = new System.Drawing.Size(147, 460);
+ AppSettingsTabControl.Size = new System.Drawing.Size(144, 460);
AppSettingsTabControl.TabIndex = 3;
//
// TabPageAppSettings
@@ -252,7 +258,7 @@ private void InitializeComponent()
TabPageAppSettings.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5);
TabPageAppSettings.Name = "TabPageAppSettings";
TabPageAppSettings.Padding = new System.Windows.Forms.Padding(3, 5, 3, 5);
- TabPageAppSettings.Size = new System.Drawing.Size(139, 427);
+ TabPageAppSettings.Size = new System.Drawing.Size(136, 427);
TabPageAppSettings.TabIndex = 0;
TabPageAppSettings.Text = "Metadata Editor";
TabPageAppSettings.UseVisualStyleBackColor = true;
@@ -275,7 +281,7 @@ private void InitializeComponent()
CustomFieldTypesTablePanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 49F));
CustomFieldTypesTablePanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
CustomFieldTypesTablePanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 54F));
- CustomFieldTypesTablePanel.Size = new System.Drawing.Size(133, 417);
+ CustomFieldTypesTablePanel.Size = new System.Drawing.Size(130, 417);
CustomFieldTypesTablePanel.TabIndex = 1;
//
// CustomFieldsDataGrid
@@ -299,7 +305,7 @@ private void InitializeComponent()
CustomFieldsDataGrid.Name = "CustomFieldsDataGrid";
CustomFieldsDataGrid.RowHeadersWidth = 51;
CustomFieldsDataGrid.RowTemplate.Height = 24;
- CustomFieldsDataGrid.Size = new System.Drawing.Size(127, 304);
+ CustomFieldsDataGrid.Size = new System.Drawing.Size(124, 304);
CustomFieldsDataGrid.TabIndex = 0;
CustomFieldsDataGrid.CellContentClick += CustomFieldsDataGrid_CellContentClick;
CustomFieldsDataGrid.CellValueChanged += CustomFieldsDataGrid_CellValueChanged;
@@ -315,7 +321,7 @@ private void InitializeComponent()
AddFieldTypeButton.Location = new System.Drawing.Point(3, 371);
AddFieldTypeButton.Margin = new System.Windows.Forms.Padding(3, 8, 3, 4);
AddFieldTypeButton.Name = "AddFieldTypeButton";
- AddFieldTypeButton.Size = new System.Drawing.Size(32, 42);
+ AddFieldTypeButton.Size = new System.Drawing.Size(31, 42);
AddFieldTypeButton.TabIndex = 1;
AddFieldTypeButton.Text = "Add";
AddFieldTypeButton.UseVisualStyleBackColor = true;
@@ -336,10 +342,10 @@ private void InitializeComponent()
RemoveFieldTypeButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
RemoveFieldTypeButton.ImageIndex = 1;
RemoveFieldTypeButton.ImageList = DialogImages;
- RemoveFieldTypeButton.Location = new System.Drawing.Point(41, 371);
+ RemoveFieldTypeButton.Location = new System.Drawing.Point(40, 371);
RemoveFieldTypeButton.Margin = new System.Windows.Forms.Padding(3, 8, 3, 4);
RemoveFieldTypeButton.Name = "RemoveFieldTypeButton";
- RemoveFieldTypeButton.Size = new System.Drawing.Size(32, 42);
+ RemoveFieldTypeButton.Size = new System.Drawing.Size(31, 42);
RemoveFieldTypeButton.TabIndex = 2;
RemoveFieldTypeButton.Text = "Remove";
RemoveFieldTypeButton.UseVisualStyleBackColor = true;
@@ -348,7 +354,7 @@ private void InitializeComponent()
// RestoreFieldTypesButton
//
RestoreFieldTypesButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
- RestoreFieldTypesButton.Location = new System.Drawing.Point(96, 371);
+ RestoreFieldTypesButton.Location = new System.Drawing.Point(93, 371);
RestoreFieldTypesButton.Margin = new System.Windows.Forms.Padding(3, 8, 3, 4);
RestoreFieldTypesButton.Name = "RestoreFieldTypesButton";
RestoreFieldTypesButton.Size = new System.Drawing.Size(34, 42);
@@ -364,7 +370,7 @@ private void InitializeComponent()
tabPage5.Margin = new System.Windows.Forms.Padding(2);
tabPage5.Name = "tabPage5";
tabPage5.Padding = new System.Windows.Forms.Padding(2);
- tabPage5.Size = new System.Drawing.Size(139, 427);
+ tabPage5.Size = new System.Drawing.Size(136, 427);
tabPage5.TabIndex = 2;
tabPage5.Text = "Behaviour";
tabPage5.UseVisualStyleBackColor = true;
@@ -373,24 +379,44 @@ private void InitializeComponent()
//
tableLayoutPanel4.ColumnCount = 3;
tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 153F));
- tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
- tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 7F));
+ tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 85.7816849F));
+ tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.2183151F));
+ tableLayoutPanel4.Controls.Add(pictureBox3, 2, 0);
tableLayoutPanel4.Controls.Add(CheckBoxSkipIndexCheck, 1, 0);
tableLayoutPanel4.Controls.Add(label9, 0, 0);
tableLayoutPanel4.Controls.Add(label7, 0, 1);
tableLayoutPanel4.Controls.Add(CheckBoxDeleteTempFiles, 1, 1);
+ tableLayoutPanel4.Controls.Add(label8, 0, 2);
+ tableLayoutPanel4.Controls.Add(CheckBoxCalculateCrc, 1, 2);
+ tableLayoutPanel4.Controls.Add(pictureBox4, 2, 2);
tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
tableLayoutPanel4.Location = new System.Drawing.Point(2, 2);
tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
tableLayoutPanel4.Name = "tableLayoutPanel4";
- tableLayoutPanel4.RowCount = 4;
- tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 60.60606F));
+ tableLayoutPanel4.RowCount = 6;
tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F));
tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F));
- tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 248F));
- tableLayoutPanel4.Size = new System.Drawing.Size(135, 423);
+ tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F));
+ tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F));
+ tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 59F));
+ tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
+ tableLayoutPanel4.Size = new System.Drawing.Size(132, 423);
tableLayoutPanel4.TabIndex = 2;
//
+ // pictureBox3
+ //
+ pictureBox3.Image = Properties.Resources.information;
+ pictureBox3.InitialImage = Properties.Resources.information;
+ pictureBox3.Location = new System.Drawing.Point(135, 0);
+ pictureBox3.Margin = new System.Windows.Forms.Padding(0);
+ pictureBox3.Name = "pictureBox3";
+ pictureBox3.Padding = new System.Windows.Forms.Padding(7, 20, 7, 8);
+ pictureBox3.Size = new System.Drawing.Size(1, 52);
+ pictureBox3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
+ pictureBox3.TabIndex = 14;
+ pictureBox3.TabStop = false;
+ TagValidationTooltip.SetToolTip(pictureBox3, "By default, when opening a cbz-archive, all files and info from the\r\nComicInfo.xml -Pageindex is verified with actual image data.\r\nBy enabling this, opening archives will be significatly faster.");
+ //
// CheckBoxSkipIndexCheck
//
CheckBoxSkipIndexCheck.AutoSize = true;
@@ -408,14 +434,14 @@ private void InitializeComponent()
label9.Location = new System.Drawing.Point(18, 20);
label9.Margin = new System.Windows.Forms.Padding(18, 20, 18, 20);
label9.Name = "label9";
- label9.Size = new System.Drawing.Size(45, 17);
+ label9.Size = new System.Drawing.Size(45, 19);
label9.TabIndex = 9;
label9.Text = "Index";
//
// label7
//
label7.AutoSize = true;
- label7.Location = new System.Drawing.Point(18, 77);
+ label7.Location = new System.Drawing.Point(18, 79);
label7.Margin = new System.Windows.Forms.Padding(18, 20, 3, 0);
label7.Name = "label7";
label7.Size = new System.Drawing.Size(113, 20);
@@ -425,7 +451,7 @@ private void InitializeComponent()
// CheckBoxDeleteTempFiles
//
CheckBoxDeleteTempFiles.AutoSize = true;
- CheckBoxDeleteTempFiles.Location = new System.Drawing.Point(162, 77);
+ CheckBoxDeleteTempFiles.Location = new System.Drawing.Point(162, 79);
CheckBoxDeleteTempFiles.Margin = new System.Windows.Forms.Padding(9, 20, 3, 4);
CheckBoxDeleteTempFiles.Name = "CheckBoxDeleteTempFiles";
CheckBoxDeleteTempFiles.Size = new System.Drawing.Size(1, 24);
@@ -433,6 +459,41 @@ private void InitializeComponent()
CheckBoxDeleteTempFiles.Text = "Delete Immediately";
CheckBoxDeleteTempFiles.UseVisualStyleBackColor = true;
//
+ // label8
+ //
+ label8.AutoSize = true;
+ label8.Location = new System.Drawing.Point(18, 138);
+ label8.Margin = new System.Windows.Forms.Padding(18, 20, 3, 0);
+ label8.Name = "label8";
+ label8.Size = new System.Drawing.Size(63, 20);
+ label8.TabIndex = 12;
+ label8.Text = "Hashing";
+ //
+ // CheckBoxCalculateCrc
+ //
+ CheckBoxCalculateCrc.AutoSize = true;
+ CheckBoxCalculateCrc.Location = new System.Drawing.Point(162, 138);
+ CheckBoxCalculateCrc.Margin = new System.Windows.Forms.Padding(9, 20, 3, 3);
+ CheckBoxCalculateCrc.Name = "CheckBoxCalculateCrc";
+ CheckBoxCalculateCrc.Size = new System.Drawing.Size(1, 24);
+ CheckBoxCalculateCrc.TabIndex = 13;
+ CheckBoxCalculateCrc.Text = "Calculate crc32 for new pages";
+ CheckBoxCalculateCrc.UseVisualStyleBackColor = true;
+ //
+ // pictureBox4
+ //
+ pictureBox4.Image = Properties.Resources.information;
+ pictureBox4.InitialImage = Properties.Resources.information;
+ pictureBox4.Location = new System.Drawing.Point(135, 118);
+ pictureBox4.Margin = new System.Windows.Forms.Padding(0);
+ pictureBox4.Name = "pictureBox4";
+ pictureBox4.Padding = new System.Windows.Forms.Padding(7, 20, 7, 8);
+ pictureBox4.Size = new System.Drawing.Size(1, 52);
+ pictureBox4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
+ pictureBox4.TabIndex = 15;
+ pictureBox4.TabStop = false;
+ TagValidationTooltip.SetToolTip(pictureBox4, "Caldulates a hash for every newly added page. \r\nThis is helpful when identifying duplicate pages, but slows down\r\nadding new images significantly!");
+ //
// CBZSettingsTabControl
//
CBZSettingsTabControl.Controls.Add(tabPage2);
@@ -982,6 +1043,8 @@ private void InitializeComponent()
tabPage5.ResumeLayout(false);
tableLayoutPanel4.ResumeLayout(false);
tableLayoutPanel4.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)pictureBox3).EndInit();
+ ((System.ComponentModel.ISupportInitialize)pictureBox4).EndInit();
CBZSettingsTabControl.ResumeLayout(false);
tabPage2.ResumeLayout(false);
tableLayoutPanel2.ResumeLayout(false);
@@ -1074,5 +1137,9 @@ private void InitializeComponent()
private System.Windows.Forms.Label label7;
private System.Windows.Forms.CheckBox CheckBoxDeleteTempFiles;
private System.Windows.Forms.ImageList AutocompleteIcons;
+ private System.Windows.Forms.Label label8;
+ private System.Windows.Forms.CheckBox CheckBoxCalculateCrc;
+ private System.Windows.Forms.PictureBox pictureBox3;
+ private System.Windows.Forms.PictureBox pictureBox4;
}
}
\ No newline at end of file
diff --git a/MyCBZ/Forms/SettingsDialog.cs b/MyCBZ/Forms/SettingsDialog.cs
index d1323ed3..66437678 100644
--- a/MyCBZ/Forms/SettingsDialog.cs
+++ b/MyCBZ/Forms/SettingsDialog.cs
@@ -53,6 +53,8 @@ internal partial class SettingsDialog : Form
public bool SkipIndexCheck;
+ public bool CalculateCrc32;
+
DataValidation validation;
public SettingsDialog()
@@ -87,6 +89,8 @@ public SettingsDialog()
SkipIndexCheck = Win_CBZSettings.Default.SkipIndexCheck;
+ CalculateCrc32 = Win_CBZSettings.Default.CalculateHash;
+
//CustomFieldTypesCollection = Win_CBZSettings.Default.CustomMetadataFields.OfType().ToArray();
CustomFieldTypesSettings = MetaDataFieldConfig.GetInstance().GetAllTypes();
@@ -106,6 +110,7 @@ public SettingsDialog()
CheckBoxPruneEmplyTags.Checked = OmitEmptyXMLTags;
CheckBoxSkipIndexCheck.Checked = SkipIndexCheck;
+ CheckBoxCalculateCrc.Checked = CalculateCrc32;
ComboBoxFileName.Text = MetaDataFilename;
@@ -422,6 +427,7 @@ private void SettingsDialog_FormClosing(object sender, FormClosingEventArgs e)
OmitEmptyXMLTags = CheckBoxPruneEmplyTags.Checked;
DeleteTempFilesImediately = CheckBoxDeleteTempFiles.Checked;
SkipIndexCheck = CheckBoxSkipIndexCheck.Checked;
+ CalculateCrc32 = CheckBoxCalculateCrc.Checked;
List fieldConfigItems = new List();
foreach (MetaDataFieldType fieldTypeCnf in CustomFieldTypesSettings)
{
diff --git a/MyCBZ/Forms/SettingsDialog.resx b/MyCBZ/Forms/SettingsDialog.resx
index cbfd5faa..e4e82d30 100644
--- a/MyCBZ/Forms/SettingsDialog.resx
+++ b/MyCBZ/Forms/SettingsDialog.resx
@@ -125,7 +125,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAoAIAAAJNU0Z0AUkBTAIBAQIB
- AAEwAQMBMAEDARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAARADAAEBAQABGAYAAQz/
+ AAFYAQMBWAEDARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAARADAAEBAQABGAYAAQz/
AAwAA+cBUgFUAVUD+g8AA7gBtgK4ewAD9gO+A70D4BgAA+YDUAMlA30D+gYAA/0DtAMrAyUDungAAdEC
0gYlAYoCixUAA+cMJQNGA/oDAAO0DCUBtgK4dQAB0QLSBiUBigKLFQAD6AM1DCUDfQO0AysJJQMrA7h1
AAHRAtIGJQGKAosYAAPzAzUbJQO0bwADlAGKAosBigKLAWYCZwYlA0cBigKLAYoCiwGKAosD4A8AA+AD
@@ -338,154 +338,154 @@ VERSION_2 = <Image="[FileName]" Key="[UniqueID]" ...>
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
- SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAYiIAAAJNU0Z0AUkBTAIBAQ0B
- AAGgAQEBoAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAAUADAAEBAQABIAYAAUD/
+ SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAXCIAAAJNU0Z0AUkBTAIBAQ0B
+ AAHIAQEByAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAAUADAAEBAQABIAYAAUD/
ABsAA0wBkAMlAf8DYgHhCAADJAE0AyUB/wMlAf8DKgE/3AADMgFPAyUB/wMlAf8DGgEkBAAEAgNZAe8D
JQH/A0YBgNgAAxABFQMbASYDQAH9AyUB/wNAAW8DEAEVAxABFQNYAboDJQH/A1oBxAMQARUDDwET0AAD
XAHZAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMrAfwDDgESzAADTgGXAyUB
/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DMwFRzAADFAEbAyoBPwNAAXED
- JQH/AyUB/wM7AWQDKgE/AyoBPwNhAesDJQH/A1MBqgMqAT8DFgEe1AADCgENAkoBSwH6AyUB/wM+AWoI
- AANUAasDJQH/A1kBxuAAA1kBxgMlAf8DVAGrCAADPgFqAyUB/wJKAUsB+gMKAQ3UAAMWAR4DKgE/A1MB
- qgMlAf8DYQHrAyoBPwMqAT8DOwFkAyUB/wMlAf8DQAFxAyoBPwMUARvMAAMzAVEDJQH/AyUB/wMlAf8D
- JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNOAZfMAAMOARIDKwH8AyUB/wMlAf8DJQH/AyUB
- /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNcAdnQAAMPARMDEAEVA1oBxAMlAf8DWAG6AxABFQMQARUD
- QAFvAyUB/wNAAf0DGwEmAxABFdgAA0YBgAMlAf8DWQHvBAIEAAMaASQDJQH/AyUB/wMyAU/cAAMqAT8D
- JQH/AyUB/wMkATQIAANiAeEDJQH/A0wBkP8A/wDeAAMYASEDUAGcA1oB8gNQAZwDGAEhOAADOAFdAzAB
- SgMEAQUkAAMTARoDSQGIA10B1ANBAfkDQQH5A10B1ANJAYgDEwEaIAADEwEaA0kBiANdAdQDQQH5A0EB
- +QNdAdQDSQGIAxMBGhwAAxgBIANPAZkDWgHyA1EBogMlAf8DUQGiA1oB8gNPAZkDGAEgMAADOgFiA00B
- +gNdAdwDJAE0HAADNwFaA2IB7gNLAY0DIwEyAwYBBwMGAQcDIwEyA0sBjQNdAeoDNwFaGAADNwFaA2AB
- 8wNNAfoDWAG3A0kBhwNJAYcDWAG3A00B+gNgAfMDNwFaEAADFQEcA04BlgNaAfIDUQGeAxoBIwMIAQoD
- JQH/AwgBCgMaASMDUQGeA1oB8gNOAZYDFQEcKAADQgF0A1MBqgMzAVEDYAHoAxcBHxQAAzcBWgNbAeQD
- XQHOAwMBBBAAAzQBUwM2AVcDYAHgAzcBWhAAAzcBWgNEAf4DWgG/AxgBIRAAAxgBIQNaAb8DRAH+AzcB
- WgwAA18B5QNRAaQDGwElCAADCAEKAyUB/wMIAQoIAAMbASUDUQGkA18B5RgAAysBQQNRAaEDXgHdA00B
- +gNfAdUDHQEoBAADRgF+A1ABnBAAAxMBGgNdAeoDPQFnAyUB/wNaAb8DBAEFDAADXAHWAyYB+wMoATsD
- XQHqAxMBGggAAxMBGgNgAfMDWgG/AwUBBhgAAwUBBgNaAb8DYAHzAxMBGggAAyUB/wMQARUMAAMIAQoD
- JQH/AwgBCgwAAxABFQMlAf8QAAMOARIDVgGzA1sB2AM/AW0DHQEoAwUBBgwAAxUBHANhAesDDwETDAAD
- SQGIA0IBdANXAcIDJQH/AyUB/wMlATcMAANeAe0DJQH/A0QBeANLAY0DSQGICAADSQGIA00B+gMYASEg
- AAMYASEDTQH6A0kBiAgAAyUB/wMQARUMAAMIAQoDJQH/AwgBCgwAAxABFQMlAf8MAAMIAQoDXQHPA0oB
- iwMEAQUcAANHAYIDXQHPAwgBCggAA10B1AM6AWIDJQH/A0AB/QNLAYwDBgEHBAADCwEOAyYBOQMlAf8D
- JQH/A1oBxwMdASgDXQHUCAADXQHUA1gBtygAA1gBtwNdAdQIAAMlAf8DEAEVBAADFwEfAxEBFgMIAQoD
- JQH/AwgBCgwAAxABFQMlAf8MAANHAYIDUgGjCQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
- AAHSAfoB/wEAAdIB+gH/CAADUwGmA0cBgggAA0EB+QNMAZEDXgHwAzsBZAgAAxYBHgNlAfEDJQH/AyUB
- /wMlAf8DJQH/AysEQQH5CAADQQH5A0kBhxEAAdIB+gH/AQAB0gH6Af8QAANJAYcDQQH5CAADJQH/AxAB
- FQNYAbgBPgK+Af0DIQEvA0sBjwMlAf8DSwGPAxIBGAgAAxABFQMlAf8MAANdAd8DHgEqKAADHgEqA10B
- 3wgAA0EB+QNbAcoDCwEODAADMwFSAyUB/wMlAf8DJQH/AyUB/wMlAf8DPgFrA0EB+QgAA0EB+QNJAYcM
- AAMEAQUBSAFrAXIB9gFIAWsBcgH2AVwCYQHZAzMBUggAA0kBhwNBAfkIAAMlAf8DEAEVAVMBaAFrAfQB
- AAHSAfoB/wFAAkEBcQNFAXwDLgFIA1IBqANeAfADSgGLAxEBFgMQARUDJQH/DAADQAH9AwIBAwkAAdIB
- +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wgAAwIBAwNAAf0IAANdAdQD
- WQHvAxoBIwwAAxYBHQNgAfMDJQH/A1EB9wNbAeQDSAH2A0QB/gNdAdQIAANdAdQDWAG3DAADSwGNAVoC
- XAHEAyUBNwNFAXwDYgHuAzUBVQQAA1gBtwNdAdQIAAMlAf8DOgFgAVsCXQHKAQAB0gH6Af8BAAHSAfoB
- /wFbAmEB3gM0AVMEAgMgAS4DVAGrA14B8ANOAZcDJQH/DAADXQHfAx4BKigAAx4BKgNdAd8IAANJAYgD
- JQH/A10B3wMeASoMAAM3AVoDUQGhAzABSgNLAY0DYgHuAyUB/wNJAYgIAANJAYgDTQH6AxgBIQQAAxEB
- FgNiAe4DHAEnCAADCQELAxABFQMYASEDTQH6A0kBiAgAA18B5QNbAcUDGwEmAUoCSwGKAV4CZQHiASAB
- kgG5Af4BIAGSAbkB/gFeAmUB3QMzAVAEAQM0AVMDTQH6A18B5QwAA0cBggNSAaUJAAHSAfoB/wEAAdIB
- +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8IAANSAaUDRwGCCAADEwEaA2AB8wMlAf8D
- RAH+AzEBTggAAzYBWANaAb8DWgHyAyUB/wMlAf8DYAHzAxMBGggAAxMBGgNgAfMDWgG/AwUBBgFbAl0B
- ygNLAY0QAAMFAQYDWgG/A2AB8wMTARoIAAMVARwDRAF4A1oB8gNGAX4DFwEfAzgBWwFgAmUB4wEfAZQB
- vAH+AQAB0gH6Af8BYAJkAdsBOgI7AWIDQwF2AxUBHAwAAwgBCgNdAc8DSwGNAwQBBRgAAwQBBQNLAY0D
- XQHPAwgBCgwAAzcBWgNEAf4DJQH/AysBQgNTAakDTgGYAycBOgMjATMDXgHSA0oBiwMrAfwDNwFaEAAD
- NwFaA0QB/gNaAb8BQAJBAXADDAEPDAADGAEhA1oBvwNEAf4DNwFaFAADGAEgA0QBegNaAfIDRQF8Ax0B
- KAFPAlABmwFbAmEB3gNVAawDEAEVGAADDgESA1YBswNeAdcDPgFrAxsBJgMEAQUDBAEFAxsBJgM+AWsD
- XgHXA1YBswMOARIUAAM3AVoDYAHzA10B1ANZAe8DJQH/A1cBuQMYASADQAFxA10B6gM3AVoYAAM3AVoD
- YAHzA00B+gNYAbcDSQGHA0kBhwNYAbcDTQH6A2AB8wM3AVogAAMYASEDRgF9A1oB8gNLAY0EAigAAysB
- QQNRAaEDXgHdA00B+gNNAfoDXgHdA1EBoQMrAUEgAAMTARoDSQGIA10B1ANBAfkDQQH5A10B1ANJAYgD
- EwEaIAADEwEaA0kBiANdAdQDQQH5A0EB+QNdAdQDSQGIAxMBGv8A/wAeAAMzAVADWgHpAyUB/wMlAf8D
- JQH/AyUB/wMlAf8DXAHIGAADMQFNA1UBtANbAeQDJgH7AyYB+wNbAeQDVQG0AzEBTSQAAzMBUANaAekD
- JQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
- WQJcAcFUAANaAekDJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/GAADQQH5AyUB/wMlAf8DJQH/AyUB
- /wMlAf8DJQH/A0EB+SQAA1oB6QMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
- AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/zAAAxcBHwNJAYcDXAHWA1oB+ANTAaoQAAMlAf8D
- JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/GAADYAHgAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A2AB
- 4CQAAyUB/wMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB
- +gH/AQAB0gH6Af8BAAHSAfoB/yQAAwkEDAEPA00BkwNNAfoDJQH/AyUB/wMlAf8DYAHzEAADJQH/AyUB
- /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMzAVIBAAHSAfoB/wFcAl8ByAwAAzwBZgNbAcoDRAF6Ay4B
- SAMwAUsDRAF6A1sBygM8AWYkAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB
- +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8cAAE7AjwBZQNVAa8DNgFYA1wB5wNgAeAD
- PgFqAzoEYAHoAyUB/wNVAa4QAAMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMBUgEAAdIB
- +gH/AQAB0gH6Af8QAAMXAR8DNgFXA1oBxANaAcQDOQFeAxgBIAMbASYBTAJNAZEBIQGHAZAB+wEhAYcB
- kAH7AVsCYwHkAVUCVwG0AzEBTQwAAyUB/wMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB
- 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/xgAASYCJwE5AVUCVgGuA0QBegNaAfUD
- OQFfAz0BZwFgAmkB6AMgAS4DVwG5AyYB+wMhATAQAAMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8D
- JQH/AzMBUgEAAdIB+gH/AQAB0gH6Af8QAAM9AWkDSgH+AyUB/wMlAf8DSgH+Az0BaQMZASIBAAHSAfoB
- /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AUEBewGEAfkMAAMlAf8DJQH/AyUB/wUAAdIB
- +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8Y
- AAMyAU8DQgF1A2AB2wM1AVYBXgJlAeIBAAHSAfoB/wEAAdIB+gH/AVACUQGdA0wBkQNGAYAUAAMlAf8D
- JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMBUgEAAdIB+gH/AQAB0gH6Af8QAANhAeYDJQH/AyUB
- /wMlAf8DJQH/A2EB5gMeASoBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AWAC
- ZgHgDAADJQH/AyUB/wMlAf8FAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB
- 0gH6Af8BAAHSAfoB/wEAAdIB+gH/FAADBwEJA0oBigNdAc8DOgFgATMBfQGMAfoBAAHSAfoB/wEAAdIB
- +gH/AQAB0gH6Af8BKwGJAaMB/AMpAT0EAhQAAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNcAcgD
- MwFSAQAB0gH6Af8BAAHSAfoB/xAAA1oB9QMlAf8DJQH/AyUB/wMlAf8DWgH1AysBQgNEAXoDLgFIAzAB
- SwNEAXoBWwJdAcoDPAFmDAADJQH/AyUB/wMlAf8FAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB
- /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/EAAEAgNLAY8DYAHgAzUBVgEfAZUBvQH+AQAB
- 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BKwGJAaMB/AMEAQUYAAMlAf8DJQE3FAADOwFlAzMB
- UgEAAdIB+gH/AQAB0gH6Af8QAANRAZ4DJQH/AyUB/wMlAf8DJQH/A1EBngMXAR8DNgFXAVoCXAHEAVoC
- XAHEAzkBXgMYASAQAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB
- 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8QAANBAXMDJQH/AzYBWAFgAmYB4AEAAdIB+gH/AQAB
- 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BWQJcAcEcAANaAekDJQE3EAADCwEOAyUB/wMzAVIB
- AAHSAfoB/wEAAdIB+gH/EAADCAEKA04BmANlAfEDZQHxA04BmAMIAQoDNAFUASUBiQGxAf4BAAHSAfoB
- /wEAAdIB+gH/ASUBiQGxAf4BPQI+AWkQAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB
- /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8MAAMcAScDJgH7A10BzgMbASUB
- QQGDAYoB+QEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AUEBgwGKAfkBJgInATkcAAMzAVAD
- WgHpAyUB/wMlAf8DJQH/AyUB/wMlAf8DWwHKA0YBfgEAAdIB+gH/AVwCXwHIKAABYQJqAeYBAAHSAfoB
- /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wFhAmoB5hAAAyUB/wMlAf8DJQH/BAABJAGLAbMB/gEkAYsB
- swH+ASQBiwGzAf4BJAGLAbMB/gEkAYsBswH+AQAB0gH6Af8BAAHSAfoB/wFGAkcBgAwAA1UBrgMlAf8D
- YAHoAzoBYAMwAUsBWAJaAb0BAAHSAfoB/wEAAdIB+gH/A14B0gMqAT8sAAM8AWYDBQEGFAADRgF+KAAB
- WgJuAfUBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wFaAm4B9RAAAyUB/wMlATc0AANgAfMD
- JQH/AyUB/wMlAf8DWgHyAygBPAMRARYDEQEWNAABWgJjAekDJQE3EAADCwEOAQAB0gH6Af8oAANRAZ4B
- AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wNRAZ4QAANaAekDJQE3IAADCwEOAQAB0gH6Af8M
- AANTAaoDWgH4A1wB1gNJAYcDFwEfQAADMwFQAVoCYwHpAQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB
- 0gH6Af8BAAHSAfoB/wFbAl0ByigAAwgBCgNOAZgBZQJwAfEBZQJwAfEDTgGYAwgBChAAAzMBUANaAekD
- JQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
- UQJTAaL/AP8AYgADFwEfAyUB/wMlAf8DCAEKJAADHQEpAz8BbgMGAQgQAAMGAQgDPwFuAx0BKRgAAxMB
- GQNHAYIDWQHDA1oB6QMrAfwDKwH8A1oB6QNZAcMDRgGBAxMBGWAAAxcBHwMlAf8DPAFmA04BlwMlAf8D
- CAEKIAADUgGoAyUB/wNbAdADHQEoCAADHQEoA1sB0AMlAf8DUgGoGAADWwHkAyUB/wMlAf8DJQH/AyUB
- /wMlAf8DJQH/AyUB/wMlAf8DWwHkXAADFgEeAyUB/wM7AWUEAAQBA04BlwMlAf8DCAEKHAADPwFsAyUB
- /wMlAf8DUwH0AzsBYwM7AWMDUwH0AyUB/wMlAf8DPwFsGAADUQH3AyUB/wMlAf8DJQH/AyUB/wMlAf8D
- JQH/AyUB/wMlAf8DUQH3EAABXAJfAcgBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB
- +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
- XAJfAcgQAAMWAR4DJQH/AzwBZgwABAEDTgGXAyUB/wMIAQoYAAMUARsDQAH9AyUB/wMlAf8DJQH/AyUB
- /wMlAf8DJQH/A0AB/QMUARsYAANbAc0DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNbAc0R
- AAHSAfoB/zEAAdIB+gH/DAADFgEeAyUB/wM8AWYUAAQBA04BmAMlAf8cAANZAcYDJQH/AyUB/wMlAf8D
- JQH/AyUB/wMlAf8DWQHGHAADNQFWA1QB/gMlAf8DYQHmA10BzwNdAc8DYQHmAyUB/wNUAf4DNQFWEQAB
- 0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB+gH/CAADFgEeAyUB
- /wM8AWYcAAM2AVkDJQH/BAEUAAQBA1QBqwMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNUAasEARwAAzAB
- TAMqAT8DGwElAw0BEQMNAREDHQEpAyoBPwMwAUwVAAHSAfoB/wQAAyUB/wQAAyUB/wM8AWYDJQH/AyUB
- /wQAAyUB/wM8AWYDJQH/BQAB0gH6Af8IAAMlAf8DUgGgHAADNgFXAyUB/wMdASkBVgJYAbMQAAMQARUD
- VgG1AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DVgG1AxABFRwAAxYBHgM5AV8DWgHHA1oB
- xwM5AV8DFgEeGQAB0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB
- +gH/CAADJQH/AysB/AM5AV4UAAM2AVcDJQH/Aw8BEwM9AWgBAAHSAfoB/wwAAysBQgNhAeYDJQH/AyUB
- /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A2EB5gMrAUIUAAMdASkDXgHwAyUB/wMlAf8D
- JQH/AyUB/wNeAfADHQEpFQAB0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB
- /wUAAdIB+gH/CAADJQH/AyUB/wMrAfwDOQFeDAADNQFWAyUB/wMPARQDPAFmAQAB0gH6Af8DFgEeDAAD
- WgHyAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A1oB8hQAA1UB
- sQMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNVAbEVAAHSAfoB/wQAAyUB/wQAAyUB/wM8AWYDJQH/AyUB
- /wQAAyUB/wM8AWYDJQH/BQAB0gH6Af8IAAMlAf8DRgGBA1YBsgMrAfwDOAFdBAADNQFWAyUB/wMPARQD
- PAFmAQAB0gH6Af8DFgEeEAADPQFpA1ABnANPAZsDTwGbA1MBpwMlAf8DJQH/AyUB/wMlAf8DUwGnA08B
- mwNPAZsDUAGcAz0BaRQAA1MB9AMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNTAfQVAAHSAfoB/wQAAyUB
- /wQAAyUB/wM8AWYDJQH/AyUB/wQAAyUB/wM8AWYDJQH/BQAB0gH6Af8IAANZAf4DGgEjA0IBdQMlAf8D
- KwH8A04BlgMlAf8DDwEUAzwBZgEAAdIB+gH/AxYBHigAA14B1wMlAf8DJQH/A14B1ygAA1MB9AMlAf8D
- JQH/AyUB/wMlAf8DJQH/AyUB/wNTAfQVAAHSAfoB/zEAAdIB+gH/CAADTgGVA00B+gMrAfwDJQH/AyUB
- /wMlAf8DCwEOATsCPAFlAQAB0gH6Af8DFgEeLAADSQGFAyUB/wMlAf8DSQGGKAADVQGxAyUB/wMlAf8D
- JQH/AyUB/wMlAf8DJQH/A1UBsRQAAVwCXwHIAQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
- AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB
- +gH/AVwCXwHICAADBQEGA0cBggMNAREDKwFBAyoBQAE7AjwBZQNSAaABAAHSAfoB/wMXAR8wAAMkATQD
- JQH/AyUB/wMkATQoAAMdASkDXgHwAyUB/wMlAf8DJQH/AyUB/wNeAfADHQEpVAAEAQNNAZIBNAGAAZMB
- /gEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AxcBHzQABAEDXAHIA1wByAQBLAADHQEpA1UB
- sQNTAfQDUwH0A1UBsQMdASn/AFUAAUIBTQE+BwABPgMAASgDAAFAAwABQAMAAQEBAAEBBgABAhYAA/8B
- AAL/BgABxgEfBgABwgEfBgABgAEHBgABgAEDBgABgAEDBgABgAEDBgAB4QGPBgAB8QGHBgABwAEBBgAB
- wAEBBgABwAEBBgAB4AEBBgAB+AFDBgAB+AFjBgAC/wYACP8B+AE/Af8BHwHwAQ8B8AEPAeABDwH/AQ8B
- 4AEHAeABBwGAAQMB/wEHBMMBjAFjAfABJwGBAcEBhwHhAZwBcwHAAeMBgQHBAY8B8QGcAXMBhwHxAYEB
- AQGfAfkBkAFzAZgBGQGGAQEBngF5AYABMwGfAfkBjgEBAZwBGQGAAQMBmAEZAY4BAQGcAQkBgAEDAZ8B
- +QGHAQEBiAHBAYABAwGYARkBgwEBAYEB4QGAAQMBhwHhAcABAwHBAcMB4AEPAcABAwHgAQcB4AEHAfgB
- PwHwAQ8B8AEPAfABDxD/AeABHwGAAX8BxAEDAv8B4AEfAYABfwHEAQMB/wHBAeABHwGAAX8BxAEDAf4B
- AQHgAQMBgAF/AcQBAwH4AQEB4AEDAcABAQHEAQMB8AEBAeABAwHAAQEBxAEDAfABAwHgAQMBwAEBAcQB
- AwHgAQMB4AEDAcABAQHEAQMBwAEHAecBwwHAAQMBxAEDAcABDwHnAYMBwAEDAcQBAwGAAQ8B4AEDAf8B
- AwHEAQMBgAEfAfwB+wH/AQMBzwH/AYABfwH8AfMB/wEDAc8B8wGDAf8B/AEDAf8BAwHEAQMS/wH8AT8B
- 4wHHAeABBwL/AfgBHwHhAYcB4AEHAv8B8QEPAeABBwHgAQcBgAEBAeMBhwHgAQcB4AEHAb8B/QLHAfAB
- DwHgAQcBqAFFAY8B4wHgAQcB8AEPAagBRQGfAcMBwAEDAfgBHwGoAUUBjwGDAYABAQHwAQ8BqAFFAYcB
- AwGAAQEB8AEPAagBRQGCAQcBgAEBAfABDwGoAUUBgAEPAfwBPwHwAQ8BvwH9AYABHwH8AT8B8AEPAYAB
- AQGAAT8B/AE/AfABDwL/AYABfwH8AT8B+AEfCv8L
+ JQH/AyUB/wM7AWQDKgE/AyoBPwNhAesDJQH/A1MBqgMqAT8DFgEe1AADCgENA00B+gMlAf8DPgFqCAAD
+ VAGrAyUB/wNZAcbgAANZAcYDJQH/A1QBqwgAAz4BagMlAf8DTQH6AwoBDdQAAxYBHgMqAT8DUwGqAyUB
+ /wNhAesDKgE/AyoBPwM7AWQDJQH/AyUB/wNAAXEDKgE/AxQBG8wAAzMBUQMlAf8DJQH/AyUB/wMlAf8D
+ JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A04Bl8wAAw4BEgMrAfwDJQH/AyUB/wMlAf8DJQH/AyUB
+ /wMlAf8DJQH/AyUB/wMlAf8DJQH/A1wB2dAAAw8BEwMQARUDWgHEAyUB/wNYAboDEAEVAxABFQNAAW8D
+ JQH/A0AB/QMbASYDEAEV2AADRgGAAyUB/wNZAe8EAgQAAxoBJAMlAf8DJQH/AzIBT9wAAyoBPwMlAf8D
+ JQH/AyQBNAgAA2IB4QMlAf8DTAGQ/wD/AN4AAxgBIQNQAZwDWgHyA1ABnAMYASE4AAM4AV0DMAFKAwQB
+ BSQAAxMBGgNJAYgDXQHUA0EB+QNBAfkDXQHUA0kBiAMTARogAAMTARoDSQGIA10B1ANBAfkDQQH5A10B
+ 1ANJAYgDEwEaHAADGAEgA08BmQNaAfIDUQGiAyUB/wNRAaIDWgHyA08BmQMYASAwAAM6AWIDTQH6A10B
+ 3AMkATQcAAM3AVoDYgHuA0sBjQMjATIDBgEHAwYBBwMjATIDSwGNA10B6gM3AVoYAAM3AVoDYAHzA00B
+ +gNYAbcDSQGHA0kBhwNYAbcDTQH6A2AB8wM3AVoQAAMVARwDTgGWA1oB8gNRAZ4DGgEjAwgBCgMlAf8D
+ CAEKAxoBIwNRAZ4DWgHyA04BlgMVARwoAANCAXQDUwGqAzMBUQNgAegDFwEfFAADNwFaA1sB5ANdAc4D
+ AwEEEAADNAFTAzYBVwNgAeADNwFaEAADNwFaA0kB/gNaAb8DGAEhEAADGAEhA1oBvwNJAf4DNwFaDAAD
+ XwHlA1EBpAMbASUIAAMIAQoDJQH/AwgBCggAAxsBJQNRAaQDXwHlGAADKwFBA1EBoQNeAd0DTQH6A18B
+ 1QMdASgEAANGAX4DUAGcEAADEwEaA10B6gM9AWcDJQH/A1oBvwMEAQUMAANcAdYDJgH7AygBOwNdAeoD
+ EwEaCAADEwEaA2AB8wNaAb8DBQEGGAADBQEGA1oBvwNgAfMDEwEaCAADJQH/AxABFQwAAwgBCgMlAf8D
+ CAEKDAADEAEVAyUB/xAAAw4BEgNWAbMDWwHYAz8BbQMdASgDBQEGDAADFQEcA2EB6wMPARMMAANJAYgD
+ QgF0A1cBwgMlAf8DJQH/AyUBNwwAA14B7QMlAf8DRAF4A0sBjQNJAYgIAANJAYgDTQH6AxgBISAAAxgB
+ IQNNAfoDSQGICAADJQH/AxABFQwAAwgBCgMlAf8DCAEKDAADEAEVAyUB/wwAAwgBCgNdAc8DSgGLAwQB
+ BRwAA0cBggNdAc8DCAEKCAADXQHUAzoBYgMlAf8DQAH9A0sBjAMGAQcEAAMLAQ4DJgE5AyUB/wMlAf8D
+ WgHHAx0BKANdAdQIAANdAdQDWAG3KAADWAG3A10B1AgAAyUB/wMQARUEAAMXAR8DEQEWAwgBCgMlAf8D
+ CAEKDAADEAEVAyUB/wwAA0cBggNSAaMJAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB
+ +gH/AQAB0gH6Af8IAANTAaYDRwGCCAADQQH5A0wBkQNeAfADOwFkCAADFgEeA2UB8QMlAf8DJQH/AyUB
+ /wMlAf8DKwRBAfkIAANBAfkDSQGHEQAB0gH6Af8BAAHSAfoB/xAAA0kBhwNBAfkIAAMlAf8DEAEVA1gB
+ uAFAAr4B/QMhAS8DSwGPAyUB/wNLAY8DEgEYCAADEAEVAyUB/wwAA10B3wMeASooAAMeASoDXQHfCAAD
+ QQH5A1sBygMLAQ4MAAMzAVIDJQH/AyUB/wMlAf8DJQH/AyUB/wM+AWsDQQH5CAADQQH5A0kBhwwAAwQB
+ BQFIAWMBaQH2AUgBYwFpAfYBXAJhAdkDMwFSCAADSQGHA0EB+QgAAyUB/wMQARUBUwJoAfQBAAHSAfoB
+ /wFAAkEBcQNFAXwDLgFIA1IBqANeAfADSgGLAxEBFgMQARUDJQH/DAADQAH9AwIBAwkAAdIB+gH/AQAB
+ 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wgAAwIBAwNAAf0IAANdAdQDWQHvAxoB
+ IwwAAxYBHQNgAfMDJQH/A1EB9wNbAeQDSAH2A0kB/gNdAdQIAANdAdQDWAG3DAADSwGNAVoCXAHEAyUB
+ NwNFAXwDYgHuAzUBVQQAA1gBtwNdAdQIAAMlAf8DOgFgAVsCXQHKAQAB0gH6Af8BAAHSAfoB/wFbAmEB
+ 3gM0AVMEAgMgAS4DVAGrA14B8ANOAZcDJQH/DAADXQHfAx4BKigAAx4BKgNdAd8IAANJAYgDJQH/A10B
+ 3wMeASoMAAM3AVoDUQGhAzABSgNLAY0DYgHuAyUB/wNJAYgIAANJAYgDTQH6AxgBIQQAAxEBFgNiAe4D
+ HAEnCAADCQELAxABFQMYASEDTQH6A0kBiAgAA18B5QNbAcUDGwEmAUoCSwGKAV4CZQHiASUBiAGvAf4B
+ JQGIAa8B/gFeAmUB3QMzAVAEAQM0AVMDTQH6A18B5QwAA0cBggNSAaUJAAHSAfoB/wEAAdIB+gH/AQAB
+ 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8IAANSAaUDRwGCCAADEwEaA2AB8wMlAf8DSQH+AzEB
+ TggAAzYBWANaAb8DWgHyAyUB/wMlAf8DYAHzAxMBGggAAxMBGgNgAfMDWgG/AwUBBgFbAl0BygNLAY0Q
+ AAMFAQYDWgG/A2AB8wMTARoIAAMVARwDRAF4A1oB8gNGAX4DFwEfAzgBWwFgAmUB4wEkAYoBsgH+AQAB
+ 0gH6Af8BYAJkAdsBOgI7AWIDQwF2AxUBHAwAAwgBCgNdAc8DSwGNAwQBBRgAAwQBBQNLAY0DXQHPAwgB
+ CgwAAzcBWgNJAf4DJQH/AysBQgNTAakDTgGYAycBOgMjATMDXgHSA0oBiwMrAfwDNwFaEAADNwFaA0kB
+ /gNaAb8BQAJBAXADDAEPDAADGAEhA1oBvwNJAf4DNwFaFAADGAEgA0QBegNaAfIDRQF8Ax0BKAFPAlAB
+ mwFbAmEB3gNVAawDEAEVGAADDgESA1YBswNeAdcDPgFrAxsBJgMEAQUDBAEFAxsBJgM+AWsDXgHXA1YB
+ swMOARIUAAM3AVoDYAHzA10B1ANZAe8DJQH/A1cBuQMYASADQAFxA10B6gM3AVoYAAM3AVoDYAHzA00B
+ +gNYAbcDSQGHA0kBhwNYAbcDTQH6A2AB8wM3AVogAAMYASEDRgF9A1oB8gNLAY0EAigAAysBQQNRAaED
+ XgHdA00B+gNNAfoDXgHdA1EBoQMrAUEgAAMTARoDSQGIA10B1ANBAfkDQQH5A10B1ANJAYgDEwEaIAAD
+ EwEaA0kBiANdAdQDQQH5A0EB+QNdAdQDSQGIAxMBGv8A/wAeAAMzAVADWgHpAyUB/wMlAf8DJQH/AyUB
+ /wMlAf8DXAHIGAADMQFNA1UBtANbAeQDJgH7AyYB+wNbAeQDVQG0AzEBTSQAAzMBUANaAekDJQH/BQAB
+ 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BWQJcAcFU
+ AANaAekDJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/GAADQQH5AyUB/wMlAf8DJQH/AyUB/wMlAf8D
+ JQH/A0EB+SQAA1oB6QMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB
+ /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/zAAAxcBHwNJAYcDXAHWA1wB+ANTAaoQAAMlAf8DJQH/AyUB
+ /wMlAf8DJQH/AyUB/wMlAf8DJQH/GAADYAHgAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A2AB4CQAAyUB
+ /wMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB
+ 0gH6Af8BAAHSAfoB/yQAAwkEDAEPA00BkwNNAfoDJQH/AyUB/wMlAf8DYAHzEAADJQH/AyUB/wMlAf8D
+ JQH/AyUB/wMlAf8DJQH/AyUB/wMzAVIBAAHSAfoB/wFcAl8ByAwAAzwBZgNbAcoDRAF6Ay4BSAMwAUsD
+ RAF6A1sBygM8AWYkAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB
+ 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8cAAE7AjwBZQNVAa8DNgFYA1wB5wNgAeADPgFqAzoE
+ YAHoAyUB/wNVAa4QAAMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMBUgEAAdIB+gH/AQAB
+ 0gH6Af8QAAMXAR8DNgFXA1oBxANaAcQDOQFeAxgBIAMbASYBTAJNAZEBIQGCAYsB+wEhAYIBiwH7AVsC
+ YwHkAVUCVwG0AzEBTQwAAyUB/wMlAf8DJQH/BQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
+ AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/xgAASYCJwE5AVUCVgGuA0QBegNaAfUDOQFfAz0B
+ ZwFgAmkB6AMgAS4DVwG5AyYB+wMhATAQAAMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMB
+ UgEAAdIB+gH/AQAB0gH6Af8QAAM9AWkDTwH+AyUB/wMlAf8DTwH+Az0BaQMZASIBAAHSAfoB/wEAAdIB
+ +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AUEBcQF/AfkMAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB
+ 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8YAAMyAU8D
+ QgF1A2AB2wM1AVYBXgJlAeIBAAHSAfoB/wEAAdIB+gH/AVACUQGdA0wBkQNGAYAUAAMlAf8DJQH/AyUB
+ /wMlAf8DJQH/AyUB/wMlAf8DJQH/AzMBUgEAAdIB+gH/AQAB0gH6Af8QAANhAeYDJQH/AyUB/wMlAf8D
+ JQH/A2EB5gMeASoBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AWACZgHgDAAD
+ JQH/AyUB/wMlAf8FAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
+ AAHSAfoB/wEAAdIB+gH/FAADBwEJA0oBigNdAc8DOgFgATwBfQF+AfoBAAHSAfoB/wEAAdIB+gH/AQAB
+ 0gH6Af8BKwF+AZQB/AMpAT0EAhQAAyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNcAcgDMwFSAQAB
+ 0gH6Af8BAAHSAfoB/xAAA1oB9QMlAf8DJQH/AyUB/wMlAf8DWgH1AysBQgNEAXoDLgFIAzABSwNEAXoB
+ WwJdAcoDPAFmDAADJQH/AyUB/wMlAf8FAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB
+ +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/EAAEAgNLAY8DYAHgAzUBVgEkAYsBswH+AQAB0gH6Af8B
+ AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BKwF+AZQB/AMEAQUYAAMlAf8DJQE3FAADOwFlAzMBUgEAAdIB
+ +gH/AQAB0gH6Af8QAANRAZ4DJQH/AyUB/wMlAf8DJQH/A1EBngMXAR8DNgFXAVoCXAHEAVoCXAHEAzkB
+ XgMYASAQAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
+ AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8QAANBAXMDJQH/AzYBWAFgAmYB4AEAAdIB+gH/AQAB0gH6Af8B
+ AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BWQJcAcEcAANaAekDJQE3EAADCwEOAyUB/wMzAVIBAAHSAfoB
+ /wEAAdIB+gH/EAADCAEKA04BmANlAfEDZQHxA04BmAMIAQoDNAFUASoBgAGnAf4BAAHSAfoB/wEAAdIB
+ +gH/ASoBgAGnAf4BPQI+AWkQAAMlAf8DJQH/AyUB/wUAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB
+ +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8MAAMcAScDJgH7A10BzgMbASUBQQF9AYUB
+ +QEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AUEBfQGFAfkBJgInATkcAAMzAVADWgHpAyUB
+ /wMlAf8DJQH/AyUB/wMlAf8DWwHKA0YBfgEAAdIB+gH/AVwCXwHIKAABYQJqAeYBAAHSAfoB/wEAAdIB
+ +gH/AQAB0gH6Af8BAAHSAfoB/wFhAmoB5hAAAyUB/wMlAf8DJQH/BAABKQGBAakB/gEpAYEBqQH+ASkB
+ gQGpAf4BKQGBAakB/gEpAYEBqQH+AQAB0gH6Af8BAAHSAfoB/wFGAkcBgAwAA1UBrgMlAf8DYAHoAzoB
+ YAMwAUsBWAJaAb0BAAHSAfoB/wEAAdIB+gH/A14B0gMqAT8sAAM8AWYDBQEGFAADRgF+KAABWgJuAfUB
+ AAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wFaAm4B9RAAAyUB/wMlATc0AANgAfMDJQH/AyUB
+ /wMlAf8DWgHyAygBPAMRARYDEQEWNAABWgJjAekDJQE3EAADCwEOAQAB0gH6Af8oAANRAZ4BAAHSAfoB
+ /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wNRAZ4QAANaAekDJQE3IAADCwEOAQAB0gH6Af8MAANTAaoD
+ XAH4A1wB1gNJAYcDFwEfQAADMwFQAVoCYwHpAQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8B
+ AAHSAfoB/wFbAl0ByigAAwgBCgNOAZgBZQJwAfEBZQJwAfEDTgGYAwgBChAAAzMBUANaAekDJQH/BQAB
+ 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BUQJTAaL/
+ AP8AYgADFwEfAyUB/wMlAf8DCAEKJAADHQEpAz8BbgMGAQgQAAMGAQgDPwFuAx0BKRgAAxMBGQNHAYID
+ WQHDA1oB6QMrAfwDKwH8A1oB6QNZAcMDRgGBAxMBGWAAAxcBHwMlAf8DPAFmA04BlwMlAf8DCAEKIAAD
+ UgGoAyUB/wNbAdADHQEoCAADHQEoA1sB0AMlAf8DUgGoGAADWwHkAyUB/wMlAf8DJQH/AyUB/wMlAf8D
+ JQH/AyUB/wMlAf8DWwHkXAADFgEeAyUB/wM7AWUEAAQBA04BlwMlAf8DCAEKHAADPwFsAyUB/wMlAf8D
+ UwH0AzsBYwM7AWMDUwH0AyUB/wMlAf8DPwFsGAADUQH3AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB
+ /wMlAf8DUQH3EAABXAJfAcgBAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB
+ 0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BXAJfAcgQ
+ AAMWAR4DJQH/AzwBZgwABAEDTgGXAyUB/wMIAQoYAAMUARsDQAH9AyUB/wMlAf8DJQH/AyUB/wMlAf8D
+ JQH/A0AB/QMUARsYAANbAc0DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNbAc0RAAHSAfoB
+ /zEAAdIB+gH/DAADFgEeAyUB/wM8AWYUAAQBA04BmAMlAf8cAANZAcYDJQH/AyUB/wMlAf8DJQH/AyUB
+ /wMlAf8DWQHGHAADNQFWA1kB/gMlAf8DYQHmA10BzwNdAc8DYQHmAyUB/wNZAf4DNQFWEQAB0gH6Af8E
+ AAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB+gH/CAADFgEeAyUB/wM8AWYc
+ AAM2AVkDJQH/BAEUAAQBA1QBqwMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNUAasEARwAAzABTAMqAT8D
+ GwElAw0BEQMNAREDHQEpAyoBPwMwAUwVAAHSAfoB/wQAAyUB/wQAAyUB/wM8AWYDJQH/AyUB/wQAAyUB
+ /wM8AWYDJQH/BQAB0gH6Af8IAAMlAf8DUgGgHAADNgFXAyUB/wMdASkBVgJYAbMQAAMQARUDVgG1AyUB
+ /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DVgG1AxABFRwAAxYBHgM5AV8DWgHHA1oBxwM5AV8D
+ FgEeGQAB0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB+gH/CAAD
+ JQH/AysB/AM5AV4UAAM2AVcDJQH/Aw8BEwM9AWgBAAHSAfoB/wwAAysBQgNhAeYDJQH/AyUB/wMlAf8D
+ JQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A2EB5gMrAUIUAAMdASkDXgHwAyUB/wMlAf8DJQH/AyUB
+ /wNeAfADHQEpFQAB0gH6Af8EAAMlAf8EAAMlAf8DPAFmAyUB/wMlAf8EAAMlAf8DPAFmAyUB/wUAAdIB
+ +gH/CAADJQH/AyUB/wMrAfwDOQFeDAADNQFWAyUB/wMPARQDPAFmAQAB0gH6Af8DFgEeDAADWgHyAyUB
+ /wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wMlAf8DJQH/A1oB8hQAA1UBsQMlAf8D
+ JQH/AyUB/wMlAf8DJQH/AyUB/wNVAbEVAAHSAfoB/wQAAyUB/wQAAyUB/wM8AWYDJQH/AyUB/wQAAyUB
+ /wM8AWYDJQH/BQAB0gH6Af8IAAMlAf8DRgGBA1YBsgMrAfwDOAFdBAADNQFWAyUB/wMPARQDPAFmAQAB
+ 0gH6Af8DFgEeEAADPQFpA1ABnANPAZsDTwGbA1MBpwMlAf8DJQH/AyUB/wMlAf8DUwGnA08BmwNPAZsD
+ UAGcAz0BaRQAA1MB9AMlAf8DJQH/AyUB/wMlAf8DJQH/AyUB/wNTAfQVAAHSAfoB/wQAAyUB/wQAAyUB
+ /wM8AWYDJQH/AyUB/wQAAyUB/wM8AWYDJQH/BQAB0gH6Af8IAANeAf4DGgEjA0IBdQMlAf8DKwH8A04B
+ lgMlAf8DDwEUAzwBZgEAAdIB+gH/AxYBHigAA14B1wMlAf8DJQH/A14B1ygAA1MB9AMlAf8DJQH/AyUB
+ /wMlAf8DJQH/AyUB/wNTAfQVAAHSAfoB/zEAAdIB+gH/CAADTgGVA00B+gMrAfwDJQH/AyUB/wMlAf8D
+ CwEOATsCPAFlAQAB0gH6Af8DFgEeLAADSQGFAyUB/wMlAf8DSQGGKAADVQGxAyUB/wMlAf8DJQH/AyUB
+ /wMlAf8DJQH/A1UBsRQAAVwCXwHIAQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB
+ /wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AVwC
+ XwHICAADBQEGA0cBggMNAREDKwFBAyoBQAE7AjwBZQNSAaABAAHSAfoB/wMXAR8wAAMkATQDJQH/AyUB
+ /wMkATQoAAMdASkDXgHwAyUB/wMlAf8DJQH/AyUB/wNeAfADHQEpVAAEAQNNAZIBOQGAAYkB/gEAAdIB
+ +gH/AQAB0gH6Af8BAAHSAfoB/wEAAdIB+gH/AxcBHzQABAEDXAHIA1wByAQBLAADHQEpA1UBsQNTAfQD
+ UwH0A1UBsQMdASn/AFUAAUIBTQE+BwABPgMAASgDAAFAAwABQAMAAQEBAAEBBgABAhYAA/8BAAL/BgAB
+ xgEfBgABwgEfBgABgAEHBgABgAEDBgABgAEDBgABgAEDBgAB4QGPBgAB8QGHBgABwAEBBgABwAEBBgAB
+ wAEBBgAB4AEBBgAB+AFDBgAB+AFjBgAC/wYACP8B+AE/Af8BHwHwAQ8B8AEPAeABDwH/AQ8B4AEHAeAB
+ BwGAAQMB/wEHBMMBjAFjAfABJwGBAcEBhwHhAZwBcwHAAeMBgQHBAY8B8QGcAXMBhwHxAYEBAQGfAfkB
+ kAFzAZgBGQGGAQEBngF5AYABMwGfAfkBjgEBAZwBGQGAAQMBmAEZAY4BAQGcAQkBgAEDAZ8B+QGHAQEB
+ iAHBAYABAwGYARkBgwEBAYEB4QGAAQMBhwHhAcABAwHBAcMB4AEPAcABAwHgAQcB4AEHAfgBPwHwAQ8B
+ 8AEPAfABDxD/AeABHwGAAX8BxAEDAv8B4AEfAYABfwHEAQMB/wHBAeABHwGAAX8BxAEDAf4BAQHgAQMB
+ gAF/AcQBAwH4AQEB4AEDAcABAQHEAQMB8AEBAeABAwHAAQEBxAEDAfABAwHgAQMBwAEBAcQBAwHgAQMB
+ 4AEDAcABAQHEAQMBwAEHAecBwwHAAQMBxAEDAcABDwHnAYMBwAEDAcQBAwGAAQ8B4AEDAf8BAwHEAQMB
+ gAEfAfwB+wH/AQMBzwH/AYABfwH8AfMB/wEDAc8B8wGDAf8B/AEDAf8BAwHEAQMS/wH8AT8B4wHHAeAB
+ BwL/AfgBHwHhAYcB4AEHAv8B8QEPAeABBwHgAQcBgAEBAeMBhwHgAQcB4AEHAb8B/QLHAfABDwHgAQcB
+ qAFFAY8B4wHgAQcB8AEPAagBRQGfAcMBwAEDAfgBHwGoAUUBjwGDAYABAQHwAQ8BqAFFAYcBAwGAAQEB
+ 8AEPAagBRQGCAQcBgAEBAfABDwGoAUUBgAEPAfwBPwHwAQ8BvwH9AYABHwH8AT8B8AEPAYABAQGAAT8B
+ /AE/AfABDwL/AYABfwH8AT8B+AEfCv8L
\ No newline at end of file
diff --git a/MyCBZ/Hash/CRC32.cs b/MyCBZ/Hash/CRC32.cs
index 029b80c6..a4e22fde 100644
--- a/MyCBZ/Hash/CRC32.cs
+++ b/MyCBZ/Hash/CRC32.cs
@@ -9,14 +9,48 @@
using SharpCompress.Common;
using SharpCompress.Readers;
using System.IO;
+using System.Runtime.Versioning;
+using System.Numerics;
namespace Win_CBZ.Hash
{
internal class HashCrc32
{
- public HashCrc32(LocalFile input)
+ [SupportedOSPlatform("windows")]
+ public static void Calculate(ref Page page)
{
+ if (page == null)
+ {
+ throw new ArgumentNullException("page");
+ }
+ if (page.LocalFile == null)
+ {
+ throw new ArgumentNullException("page.LocalFile");
+ }
+
+ if (!page.LocalFile.Exists())
+ {
+ throw new FileNotFoundException("File not found", page.LocalFile.FullPath);
+ }
+
+ LocalFile localFile = page.LocalFile;
+ if (page.Compressed || page.Changed)
+ {
+ localFile = page.TemporaryFile;
+ }
+
+ using (var stream = localFile.LocalFileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ {
+ var crc32 = new Crc32();
+ crc32.Append(stream);
+
+ var hash = crc32.GetHashAndReset();
+
+ page.Hash = BitConverter.ToString(hash).Replace("-", "").ToUpper();
+
+ crc32 = null;
+ }
}
}
}
diff --git a/MyCBZ/Models/MetaData.cs b/MyCBZ/Models/MetaData.cs
index 4edd2c39..ef5507e3 100644
--- a/MyCBZ/Models/MetaData.cs
+++ b/MyCBZ/Models/MetaData.cs
@@ -254,7 +254,6 @@ public void Save(String path)
}
}
-
public MemoryStream BuildComicInfoXMLStream(bool withoutXMLHeaderTag = false)
{
MemoryStream ms = new MemoryStream();
diff --git a/MyCBZ/Models/MetaDataEntryPage.cs b/MyCBZ/Models/MetaDataEntryPage.cs
index 683ff150..b8bd755a 100644
--- a/MyCBZ/Models/MetaDataEntryPage.cs
+++ b/MyCBZ/Models/MetaDataEntryPage.cs
@@ -28,10 +28,13 @@ internal class MetaDataEntryPage
public const String COMIC_PAGE_TYPE_OTHER = "Other";
public const String COMIC_PAGE_TYPE_DELETED = "Deleted";
- public static String [] PageTypes = {COMIC_PAGE_TYPE_STORY, COMIC_PAGE_TYPE_FRONT_COVER,
- COMIC_PAGE_TYPE_INNER_COVER, COMIC_PAGE_TYPE_BACK_COVER, COMIC_PAGE_TYPE_ROUNDUP, COMIC_PAGE_TYPE_ADVERTICEMENT,
- COMIC_PAGE_TYPE_EDITORIAL,COMIC_PAGE_TYPE_LETTERS, COMIC_PAGE_TYPE_PREVIEW, COMIC_PAGE_TYPE_OTHER,
- COMIC_PAGE_TYPE_DELETED};
+ public static String [] PageTypes = {
+ COMIC_PAGE_TYPE_STORY, COMIC_PAGE_TYPE_FRONT_COVER,
+ COMIC_PAGE_TYPE_INNER_COVER, COMIC_PAGE_TYPE_BACK_COVER, COMIC_PAGE_TYPE_ROUNDUP,
+ COMIC_PAGE_TYPE_ADVERTICEMENT,
+ COMIC_PAGE_TYPE_EDITORIAL,COMIC_PAGE_TYPE_LETTERS, COMIC_PAGE_TYPE_PREVIEW,
+ COMIC_PAGE_TYPE_OTHER, COMIC_PAGE_TYPE_DELETED
+ };
/*
diff --git a/MyCBZ/Models/Page.cs b/MyCBZ/Models/Page.cs
index ed012ced..9427b2cb 100644
--- a/MyCBZ/Models/Page.cs
+++ b/MyCBZ/Models/Page.cs
@@ -273,7 +273,6 @@ public Page(ZipArchiveEntry entry, String workingDir, String randomId = null)
Format = new PageImageFormat(FileExtension);
}
-
public Page(Stream fileInputStream, String name)
{
@@ -1286,8 +1285,6 @@ public void UpdateImageExtension(string newExtension)
FileExtension = ExtractFileExtension(Filename);
}
-
-
public string SizeFormat()
{
double size = Size;
@@ -1308,7 +1305,6 @@ public string SizeFormat()
return size.ToString("n2") + " " + selectedUnit;
}
-
///
/// Serialize the page to XML- Fragment
///
@@ -1843,25 +1839,35 @@ public void LoadImageInfo(bool force = false)
}
}
- public Image GetThumbnail()
+ public Image GetThumbnail(int w = 0, int h = 0)
{
if (!Closed)
{
LoadImage();
}
+ if (w == 0)
+ {
+ w = ThumbW;
+ }
+
+ if (h == 0)
+ {
+ h = ThumbH;
+ }
+
if (Image != null)
{
try
{
- var newBitmap = new Bitmap(ThumbW, ThumbH);
+ var newBitmap = new Bitmap(w, h);
using (Graphics g = Graphics.FromImage(newBitmap))
{
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
- g.DrawImage(Image, new Rectangle(0, 0, ThumbW, ThumbH));
+ g.DrawImage(Image, new Rectangle(0, 0, w, h));
}
Thumbnail = Image.FromHbitmap(newBitmap.GetHbitmap());
//openBitmap.Dispose(); //Clear The Old Large Bitmap From Memory
@@ -1879,25 +1885,34 @@ public Image GetThumbnail()
return Thumbnail;
}
- public Bitmap GetThumbnailBitmap()
+ public Bitmap GetThumbnailBitmap(int w = 0, int h = 0)
{
if (!Closed)
{
LoadImage();
}
+ if (w == 0) {
+ w = ThumbW;
+ }
+
+ if (h == 0)
+ {
+ h = ThumbH;
+ }
+
if (Image != null)
{
try
{
- var newBitmap = new Bitmap(ThumbW, ThumbH);
+ var newBitmap = new Bitmap(w, h);
using (Graphics g = Graphics.FromImage(newBitmap))
{
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
- g.DrawImage(Image, new Rectangle(0, 0, ThumbW, ThumbH));
+ g.DrawImage(Image, new Rectangle(0, 0, w, h));
}
return newBitmap;
@@ -1920,7 +1935,7 @@ public Bitmap GetThumbnailBitmap()
/*
* This will use Windows api fetching cached explorer thumbs
*/
- public Image GetWindowsThumbnail(Image.GetThumbnailImageAbort callback, IntPtr data)
+ public Image GetWindowsThumbnail(Image.GetThumbnailImageAbort callback, IntPtr callbackData)
{
if (!Closed)
{
@@ -1931,7 +1946,7 @@ public Image GetWindowsThumbnail(Image.GetThumbnailImageAbort callback, IntPtr d
{
try
{
- Thumbnail = Image.GetThumbnailImage(ThumbW, ThumbH, callback, data);
+ Thumbnail = Image.GetThumbnailImage(ThumbW, ThumbH, callback, callbackData);
Image?.Dispose();
Image = null;
diff --git a/MyCBZ/Models/ProjectModel.cs b/MyCBZ/Models/ProjectModel.cs
index 4aea3674..7d14553a 100644
--- a/MyCBZ/Models/ProjectModel.cs
+++ b/MyCBZ/Models/ProjectModel.cs
@@ -41,6 +41,7 @@
using System.Windows.Interop;
using Win_CBZ.Events;
using System.Text.RegularExpressions;
+using Win_CBZ.Hash;
namespace Win_CBZ
{
@@ -276,6 +277,7 @@ private void HandlePipeline(object sender, PipelineEvent e)
InvalidFileNames = FilteredFileNames.ToArray(),
CancelToken = TokenStore.GetInstance().CancellationTokenSourceForName(TokenStore.TOKEN_SOURCE_PROCESS_FILES).Token,
MaxCountPages = p.MaxCountPages,
+ HashFiles = p.HashFiles,
});
currentPerformed = e.Task;
@@ -1861,6 +1863,129 @@ public void CancelAllThreads()
*/
}
+
+ public Page AddPageFromFile(LocalFile localFile, PageIndexVersion version, int insertAt = -1)
+ {
+ int pageStatus = 0;
+ bool pageError = false;
+ FileInfo targetPath;
+ FileInfo localPath;
+ int realNewIndex = Pages.Count;
+ Page page;
+ Page insertPage = null;
+
+ if (insertAt >= 0 && insertAt < Pages.Count)
+ {
+ realNewIndex = insertAt;
+ insertPage = GetPageByIndex(realNewIndex);
+ }
+
+ targetPath = MakeNewTempFileName();
+
+ //CopyFile(fileObject.FullPath, targetPath.FullName);
+
+ page = GetPageByName(localFile.Name);
+
+ if (page == null)
+ {
+ page = new Page(localFile, targetPath.Directory.FullName, FileAccess.ReadWrite)
+ {
+ Number = realNewIndex + 1,
+ Index = realNewIndex,
+ OriginalIndex = realNewIndex,
+ Key = version == PageIndexVersion.VERSION_1 ? localFile.Name : RandomId.GetInstance().Make(),
+ };
+ pageStatus = PageChangedEvent.IMAGE_STATUS_NEW;
+ }
+ else
+ {
+ throw new PageException(page, "Page already exists!", true);
+ }
+
+ try
+ {
+ page.LoadImage(true); // dont load full image here!
+ }
+ catch (PageException pe)
+ {
+ pageStatus = PageChangedEvent.IMAGE_STATUS_ERROR;
+
+ MessageLogger.Instance.Log(LogMessageEvent.LOGMESSAGE_TYPE_WARNING, "Failed to load image metadata for page ['" + page.Name + "']! [" + pe.Message + "]");
+ }
+ finally
+ {
+ page.FreeImage();
+ }
+
+ if (insertAt > -1 && insertAt < Pages.Count)
+ {
+ Pages.Insert(realNewIndex, page);
+
+ } else
+ {
+ Pages.Add(page);
+ }
+
+ AppEventHandler.OnPageChanged(this, new PageChangedEvent(page, insertPage, pageStatus));
+
+ return page;
+ }
+
+ public Page AddPage(Page page, int insertAt = -1)
+ {
+ int pageStatus = 0;
+ int realNewIndex = Pages.Count;
+ Page insertPage = null;
+
+ if (insertAt >= 0 && insertAt < Pages.Count)
+ {
+ realNewIndex = insertAt;
+ insertPage = GetPageByIndex(realNewIndex);
+ }
+
+ if (page != null)
+ {
+ pageStatus = PageChangedEvent.IMAGE_STATUS_NEW;
+
+ try
+ {
+ page.LoadImage(true); // dont load full image here!
+ }
+ catch (PageException pe)
+ {
+ pageStatus = PageChangedEvent.IMAGE_STATUS_ERROR;
+
+ MessageLogger.Instance.Log(LogMessageEvent.LOGMESSAGE_TYPE_WARNING, "Failed to load image metadata for page ['" + page.Name + "']! [" + pe.Message + "]");
+ }
+ finally
+ {
+ page.FreeImage();
+ }
+
+ page.Index = realNewIndex;
+ page.Number = realNewIndex + 1;
+
+ if (insertAt > -1 && insertAt < Pages.Count)
+ {
+ Pages.Insert(realNewIndex, page);
+
+ }
+ else
+ {
+ Pages.Add(page);
+ }
+
+ AppEventHandler.OnPageChanged(this, new PageChangedEvent(page, insertPage, pageStatus));
+ }
+ else
+ {
+ throw new PageException(page, "Page already exists!", true);
+ }
+
+
+ return page;
+ }
+
public void AddImagesProc(object threadParams)
{
AddImagesThreadParams tParams = threadParams as AddImagesThreadParams;
@@ -1928,6 +2053,21 @@ public void AddImagesProc(object threadParams)
page.Changed = true;
}
+ try {
+ if (tParams.HashFiles)
+ {
+ HashCrc32.Calculate(ref page);
+ }
+ } catch (Exception pe)
+ {
+ pageStatus = PageChangedEvent.IMAGE_STATUS_ERROR;
+
+ MessageLogger.Instance.Log(LogMessageEvent.LOGMESSAGE_TYPE_WARNING, "Failed calculate crc32 for page ['" + page.Name + "']! [" + pe.Message + "]");
+ } finally
+ {
+ //
+ }
+
try
{
page.LoadImage(true); // dont load full image here!
@@ -2028,6 +2168,7 @@ public void ParseFiles(List files)
CancelToken = TokenStore.GetInstance().CancellationTokenSourceForName(TokenStore.TOKEN_SOURCE_PARSE_FILES).Token,
Pages = Pages,
MaxCountPages = Pages.Count,
+ HashFiles = Win_CBZSettings.Default.CalculateHash,
});
}
@@ -2085,6 +2226,8 @@ public void ParseFilesProc(object threadParams)
LocalFiles = files.ToList(),
PageIndexVerToWrite = tParams.PageIndexVerToWrite,
MaxCountPages = tParams.MaxCountPages,
+ CancelToken = tParams.CancelToken,
+ HashFiles = tParams.HashFiles,
}
},
new StackItem
@@ -2557,7 +2700,6 @@ public void RestoreOriginalNamesProc(object threadParams)
AppEventHandler.OnOperationFinished(this, new OperationFinishedEvent(0, Pages.Count));
AppEventHandler.OnApplicationStateChanged(this, new ApplicationStatusEvent(this, ApplicationStatusEvent.STATE_READY));
}
-
public void RenamePage(Page page, String name, bool ignoreDuplicates = false, bool showErrors = false)
{
diff --git a/MyCBZ/Win_CBZSettings.Designer.cs b/MyCBZ/Win_CBZSettings.Designer.cs
index b56d6488..dc2546c8 100644
--- a/MyCBZ/Win_CBZSettings.Designer.cs
+++ b/MyCBZ/Win_CBZSettings.Designer.cs
@@ -497,5 +497,29 @@ public int WhatsNewVersion {
this["WhatsNewVersion"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool CalculateHash {
+ get {
+ return ((bool)(this["CalculateHash"]));
+ }
+ set {
+ this["CalculateHash"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool CheckDuplicatePages {
+ get {
+ return ((bool)(this["CheckDuplicatePages"]));
+ }
+ set {
+ this["CheckDuplicatePages"] = value;
+ }
+ }
}
}
diff --git a/MyCBZ/Win_CBZSettings.settings b/MyCBZ/Win_CBZSettings.settings
index 884c13c0..0cea6997 100644
--- a/MyCBZ/Win_CBZSettings.settings
+++ b/MyCBZ/Win_CBZSettings.settings
@@ -141,5 +141,11 @@
0
+
+ False
+
+
+ False
+
\ No newline at end of file