From c15f221d15d4ed3b943b379d1dbd23d944cd98c3 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 23 Jul 2022 23:20:57 +0200 Subject: [PATCH 01/32] Removed bottom toolbar --- .../UI WinForms/Components/Main.Designer.cs | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Main.Designer.cs b/I18N Commander/UI WinForms/Components/Main.Designer.cs index 7822135..fb07cf2 100644 --- a/I18N Commander/UI WinForms/Components/Main.Designer.cs +++ b/I18N Commander/UI WinForms/Components/Main.Designer.cs @@ -29,7 +29,6 @@ private void InitializeComponent() { this.tableLayout = new System.Windows.Forms.TableLayoutPanel(); - this.flowLayoutBottom = new System.Windows.Forms.FlowLayoutPanel(); this.splitContainerLR = new System.Windows.Forms.SplitContainer(); this.sectionTree = new UI_WinForms.Components.SectionTree(); this.splitContainerRTB = new System.Windows.Forms.SplitContainer(); @@ -48,27 +47,16 @@ // this.tableLayout.ColumnCount = 1; this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayout.Controls.Add(this.flowLayoutBottom, 0, 1); this.tableLayout.Controls.Add(this.splitContainerLR, 0, 0); this.tableLayout.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayout.Location = new System.Drawing.Point(0, 0); this.tableLayout.Name = "tableLayout"; - this.tableLayout.RowCount = 2; + this.tableLayout.RowCount = 1; this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 66F)); + this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tableLayout.Size = new System.Drawing.Size(965, 603); this.tableLayout.TabIndex = 0; // - // flowLayoutBottom - // - this.flowLayoutBottom.Dock = System.Windows.Forms.DockStyle.Fill; - this.flowLayoutBottom.Location = new System.Drawing.Point(0, 537); - this.flowLayoutBottom.Margin = new System.Windows.Forms.Padding(0); - this.flowLayoutBottom.Name = "flowLayoutBottom"; - this.flowLayoutBottom.Size = new System.Drawing.Size(965, 66); - this.flowLayoutBottom.TabIndex = 0; - // // splitContainerLR // this.splitContainerLR.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; @@ -85,7 +73,7 @@ // splitContainerLR.Panel2 // this.splitContainerLR.Panel2.Controls.Add(this.splitContainerRTB); - this.splitContainerLR.Size = new System.Drawing.Size(959, 531); + this.splitContainerLR.Size = new System.Drawing.Size(959, 597); this.splitContainerLR.SplitterDistance = 319; this.splitContainerLR.TabIndex = 1; // @@ -95,7 +83,7 @@ this.sectionTree.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); this.sectionTree.Location = new System.Drawing.Point(0, 0); this.sectionTree.Name = "sectionTree"; - this.sectionTree.Size = new System.Drawing.Size(317, 529); + this.sectionTree.Size = new System.Drawing.Size(317, 595); this.sectionTree.TabIndex = 0; // // splitContainerRTB @@ -111,7 +99,7 @@ // this.splitContainerRTB.Panel1.Controls.Add(this.textElements); this.splitContainerRTB.Panel1MinSize = 340; - this.splitContainerRTB.Size = new System.Drawing.Size(636, 531); + this.splitContainerRTB.Size = new System.Drawing.Size(636, 597); this.splitContainerRTB.SplitterDistance = 340; this.splitContainerRTB.TabIndex = 0; // @@ -147,7 +135,6 @@ #endregion private TableLayoutPanel tableLayout; - private FlowLayoutPanel flowLayoutBottom; private SplitContainer splitContainerLR; private SplitContainer splitContainerRTB; private SectionTree sectionTree; From 39a8b843c986ad08097853ad0c65937c4ab88063 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 23 Jul 2022 23:29:28 +0200 Subject: [PATCH 02/32] Added tab control --- .../UI WinForms/Components/Main.Designer.cs | 74 +++- .../UI WinForms/Components/Main.resx | 333 ++++++++++++++++++ 2 files changed, 400 insertions(+), 7 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Main.Designer.cs b/I18N Commander/UI WinForms/Components/Main.Designer.cs index fb07cf2..0f3b3c9 100644 --- a/I18N Commander/UI WinForms/Components/Main.Designer.cs +++ b/I18N Commander/UI WinForms/Components/Main.Designer.cs @@ -28,11 +28,17 @@ /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main)); this.tableLayout = new System.Windows.Forms.TableLayoutPanel(); this.splitContainerLR = new System.Windows.Forms.SplitContainer(); this.sectionTree = new UI_WinForms.Components.SectionTree(); this.splitContainerRTB = new System.Windows.Forms.SplitContainer(); this.textElements = new UI_WinForms.Components.TextElements(); + this.tabControl = new System.Windows.Forms.TabControl(); + this.tabTranslation = new System.Windows.Forms.TabPage(); + this.tabSettings = new System.Windows.Forms.TabPage(); + this.imageList = new System.Windows.Forms.ImageList(this.components); this.tableLayout.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainerLR)).BeginInit(); this.splitContainerLR.Panel1.SuspendLayout(); @@ -41,6 +47,8 @@ ((System.ComponentModel.ISupportInitialize)(this.splitContainerRTB)).BeginInit(); this.splitContainerRTB.Panel1.SuspendLayout(); this.splitContainerRTB.SuspendLayout(); + this.tabControl.SuspendLayout(); + this.tabTranslation.SuspendLayout(); this.SuspendLayout(); // // tableLayout @@ -49,12 +57,12 @@ this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayout.Controls.Add(this.splitContainerLR, 0, 0); this.tableLayout.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayout.Location = new System.Drawing.Point(0, 0); + this.tableLayout.Location = new System.Drawing.Point(3, 3); this.tableLayout.Name = "tableLayout"; this.tableLayout.RowCount = 1; this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayout.Size = new System.Drawing.Size(965, 603); + this.tableLayout.Size = new System.Drawing.Size(885, 589); this.tableLayout.TabIndex = 0; // // splitContainerLR @@ -73,7 +81,7 @@ // splitContainerLR.Panel2 // this.splitContainerLR.Panel2.Controls.Add(this.splitContainerRTB); - this.splitContainerLR.Size = new System.Drawing.Size(959, 597); + this.splitContainerLR.Size = new System.Drawing.Size(879, 583); this.splitContainerLR.SplitterDistance = 319; this.splitContainerLR.TabIndex = 1; // @@ -83,7 +91,7 @@ this.sectionTree.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); this.sectionTree.Location = new System.Drawing.Point(0, 0); this.sectionTree.Name = "sectionTree"; - this.sectionTree.Size = new System.Drawing.Size(317, 595); + this.sectionTree.Size = new System.Drawing.Size(317, 581); this.sectionTree.TabIndex = 0; // // splitContainerRTB @@ -99,7 +107,7 @@ // this.splitContainerRTB.Panel1.Controls.Add(this.textElements); this.splitContainerRTB.Panel1MinSize = 340; - this.splitContainerRTB.Size = new System.Drawing.Size(636, 597); + this.splitContainerRTB.Size = new System.Drawing.Size(556, 583); this.splitContainerRTB.SplitterDistance = 340; this.splitContainerRTB.TabIndex = 0; // @@ -109,14 +117,60 @@ this.textElements.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); this.textElements.Location = new System.Drawing.Point(0, 0); this.textElements.Name = "textElements"; - this.textElements.Size = new System.Drawing.Size(634, 338); + this.textElements.Size = new System.Drawing.Size(554, 338); this.textElements.TabIndex = 0; // + // tabControl + // + this.tabControl.Alignment = System.Windows.Forms.TabAlignment.Left; + this.tabControl.Controls.Add(this.tabTranslation); + this.tabControl.Controls.Add(this.tabSettings); + this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl.ImageList = this.imageList; + this.tabControl.Location = new System.Drawing.Point(0, 0); + this.tabControl.Multiline = true; + this.tabControl.Name = "tabControl"; + this.tabControl.Padding = new System.Drawing.Point(12, 12); + this.tabControl.SelectedIndex = 0; + this.tabControl.Size = new System.Drawing.Size(965, 603); + this.tabControl.TabIndex = 1; + // + // tabTranslation + // + this.tabTranslation.Controls.Add(this.tableLayout); + this.tabTranslation.ImageIndex = 1; + this.tabTranslation.Location = new System.Drawing.Point(70, 4); + this.tabTranslation.Name = "tabTranslation"; + this.tabTranslation.Padding = new System.Windows.Forms.Padding(3); + this.tabTranslation.Size = new System.Drawing.Size(891, 595); + this.tabTranslation.TabIndex = 0; + this.tabTranslation.Text = "Translation"; + this.tabTranslation.UseVisualStyleBackColor = true; + // + // tabSettings + // + this.tabSettings.ImageIndex = 0; + this.tabSettings.Location = new System.Drawing.Point(70, 4); + this.tabSettings.Name = "tabSettings"; + this.tabSettings.Padding = new System.Windows.Forms.Padding(3); + this.tabSettings.Size = new System.Drawing.Size(891, 595); + this.tabSettings.TabIndex = 1; + this.tabSettings.Text = "Settings"; + this.tabSettings.UseVisualStyleBackColor = true; + // + // imageList + // + this.imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; + this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream"))); + this.imageList.TransparentColor = System.Drawing.Color.Transparent; + this.imageList.Images.SetKeyName(0, "icons8-settings.svg.png"); + this.imageList.Images.SetKeyName(1, "icons8-language-45.png"); + // // Main // this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.Controls.Add(this.tableLayout); + this.Controls.Add(this.tabControl); this.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); this.Name = "Main"; this.Size = new System.Drawing.Size(965, 603); @@ -128,6 +182,8 @@ this.splitContainerRTB.Panel1.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainerRTB)).EndInit(); this.splitContainerRTB.ResumeLayout(false); + this.tabControl.ResumeLayout(false); + this.tabTranslation.ResumeLayout(false); this.ResumeLayout(false); } @@ -139,5 +195,9 @@ private SplitContainer splitContainerRTB; private SectionTree sectionTree; private TextElements textElements; + private TabControl tabControl; + private TabPage tabTranslation; + private TabPage tabSettings; + private ImageList imageList; } } diff --git a/I18N Commander/UI WinForms/Components/Main.resx b/I18N Commander/UI WinForms/Components/Main.resx index b5ae26c..92a0569 100644 --- a/I18N Commander/UI WinForms/Components/Main.resx +++ b/I18N Commander/UI WinForms/Components/Main.resx @@ -57,4 +57,337 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs + LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu + SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAApEsAAAJNU0Z0AUkBTAIBAQIB + AAEQAQABEAEAAS0BAAEtAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABtAMAAS0DAAEBAQABIAUAAZAB + fvoAAw8BFAMTARkEAf8A/wAqAAMnATkDSwGWA00BoQNNAaEDTQGhA0sBlgMnATp8AAMLAQ4BYwFUAUgB + ogGAAVsBRAHHAyUBNv8A/wAmAAMRARYDPAHzAToCOQH/AT0BPAE7Af8BPQE8ATsB/wE9ATwBOwH/AToC + OQH/AzwB9AMRARZ4AAMSARgBgwFdAUIBzAG8AVsBGQH/AY8BXgE9AdcDEAEV/wD/ACIAAz8BbgFGAUMB + QgH/AcQBrwGmAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8BxAGuAaYB/wFGAUMBQgH/A0ABcHgAAxIB + GAGDAV0BQgHMAbwBWwEZAf8BvAFbARkB/wGOAV0BOgHYAiYBJQE3BAH/AP8AGgADTwG3AVcBUgFQAf8B + 3gHFAbsB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHeAcUBuwH/AVcBUgFPAf8DTgG6BAF0AAMSARgB + gwFdAUIBzAG7AVsBGQH/AbwBWwEZAf8BvAFbARkB/wGNAV4BPQHVAhoBGQEj/wDxAAMDAQQDIgExAykB + PgMSARgUAAMSARgDSQHbAXsBcAFsAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AXoBcAFrAf8DSQHbAxMBGhQAAxIBFwMpAT4DIgExAwMBBFAAAxIBGAGDAV0BQgHMAbsBWwEZAf8B + uwFbARkB/wG7AVsBGQH/AbwBWwEZAf8BjAFdAT4B1AMhAS8EAf8A5QADAgEDAz0BaQNFAeQDPQHvA0wB + 0AM2AVkDBAEFDAADKAE7A0EB7AGrAZoBkwH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wGqAZkBkgH/A0AB7QMpAT0MAAMDAQQDNgFXA0wBzwM9Ae8DRQHlAz4BagMCAQNMAAMSARgB + gwFdAUIBzAG7AVsBGgH/AbsBWwEZAf8BuwFbARkB/wG7AVsBGQH/AbsBWwEZAf8BiwFcAT4B0wMiATH/ + AOEAAwIBAwM0AVMDQQHxAW8BaQFmAf8BtwGrAaQB/wFdAVkBVwH/AzoB+wNNAaQDGQEiAwQBBQMJAQwD + PwFuATgCNwH7AdwByAG+Af8B5wHOAcMB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AdgB + wAG2Af8CNQE0AfwDQAFxAwoBDQMDAQQDGAEgA00BogE7AToBOQH7AV4BVwFUAf8BtgGjAZsB/wFwAWcB + YwH/AUECQAHyAzUBVQMCAQNIAAMSARgBgwFdAUIBzAG7AVsBGgH/AbsBWwEaAf8BuwFbARkB/wG7AVsB + GQH/AbsBWwEZAf8BuwFbARkB/wGLAV0BPgHUAxgBIP8A2QADAwEEAz0BaANBAfEBfwF0AW8B/wHjAcwB + wQH/AewB2gHQAf8B5AHVAcsB/wGnAZ0BlwH/AVMBUAFPAf8DRQHkA0sBmANOAbQBQwJCAewBeAFyAW4B + /wHtAdwB0gH/AeoB1QHLAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AXUB + awFnAf8DQQHtA04BtQNLAZcDRAHiAVMBTgFMAf8BpAGUAY0B/wHfAcYBuwH/AecBzQHCAf8B4wHJAb4B + /wGAAXUBcAH/AUECQAHyAz4BagMDAQREAAMSARgBgwFdAUIBzAG6AVsBGgH/AbsBWwEaAf8BuwFbARoB + /wG7AVsBGgH/AbsBWwEZAf8BuwFbARkB/wG7AVsBGQH/AYwBXAE9AdYCJgElATf/ANUAAyEBLwNEAeMB + bwFqAWYB/wHjAcwBwgH/AecBzQHCAf8B6AHQAcUB/wHtAdwB0gH/Ae0B3QHTAf8B6AHZAc8B/wGEAX4B + eQH/AzcB/wFOAUwBSwH/AbcBqwGlAf8B6gHbAdEB/wHtAd0B0wH/Ae0B3QHTAf8B6wHVAcsB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeUBywHAAf8BswGgAZgB/wFNAUoBSAH/ATcCNgH/AYEB + dQFxAf8B4wHJAb8B/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeMByQG+Af8BcAFnAWMB + /wNFAeUDIgExJAACIgEhATABYgFTAUkBoAFpAVYBSQGrAWkBVgFJAasBaQFWAUkBqwFqAVYBSQGrAWoB + VgFJAasBagFWAUkBqwFvAVgBSAGzAaQBXQEsAe4BugFbARoB/wG6AVsBGgH/AbsBWwEaAf8BuwFbARoB + /wG7AVsBGgH/AbsBWwEaAf8BuwFbARkB/wG7AVsBGQH/AZ4BXwE0AeUBawFXAUkBrQFqAVYBSQGrAWoB + VgFJAasBagFWAUkBqwFpAVYBSgGpAXQBZQFRAasBdAFlAVEBqwF0AWUBUQGrAXQBZQFRAasBdAFlAVEB + qwF0AWUBUQGrAXQBZQFRAasBdAFlAVEBqwF0AWUBUQGrAXQBZQFRAasBdAFlAVEBqwFpAV8BTgGgAiIB + IQEw/wCNAAMoATwDQAHtAbcBqwGkAf8B7AHbAdAB/wHpAdEBxgH/AecBzQHCAf8B6AHRAcYB/wHsAdoB + 0AH/Ae0B3QHTAf8B7AHcAdIB/wHeAc8BxgH/AewB3AHSAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B + 7QHdAdMB/wHtAd0B0wH/AeoB1QHLAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AeYBzAHBAf8B2AHAAbYB/wHmAcwBwQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AbEBngGXAf8DPQHvAykBPSAAAyABLgGiAV0BLQHsAbkBWgEaAf8BuQFaARoB + /wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG6AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsBGgH/AboB + WwEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEaAf8BuwFbARkB + /wG7AVsBGQH/AbsBWwEZAf8BuwFbARkB/wG7AVsBGQH/AbwBWwEZAf8ByQF1ASoB/AHsAaQBQgH/AewB + pAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B6wGkAUIB + /wHrAaQBQgH/AesBpAFCAf8B6wGkAUIB/wHGAZMBTAHrAyABLf8AiQADEAEVA0sBzQFcAVkBVgH/AeMB + 1AHLAf8B7QHcAdIB/wHpAdEBxgH/AecBzQHCAf8B6AHQAcUB/wHsAdsB0QH/Ae0B3QHTAf8B7QHdAdMB + /wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAdwB0gH/AesB + 1QHKAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB + /wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B3QHFAboB/wFaAVUBUgH/A0wB + zgMRARYgAAE0ATMBMgFQAa0BXAElAfYBuQFaARsB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoB + GgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8B + ugFbARoB/wG6AVsBGgH/AboBWwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEaAf8BuwFbARkB/wG7AVsB + GQH/AbsBWwEZAf8BuQFfARwB/gHWAYoBNwH9Ae0BpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B + 7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHrAaQB + QgH/AdgBmQFGAfYBNAIzAVD/AI0AAzMBUgI9ATwB+gGmAZsBlQH/Ae0B3QHTAf8B7AHbAdAB/wHpAdEB + xgH/AesB1wHQAf8B7AHaAdMB/wHsAdsB0QH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B + 7QHdAdMB/wHtAd0B0wH/AeoB2gHQAf8BxgG5AbEB/wHqAdoB0AH/AeoB1QHKAf8B5wHOAcMB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AaEBkQGLAf8BOgI5AfsDNQFWJAABNAIzAVEBrQFbASUB9wG4AVoBGwH/AbkB + WgEbAf8BuQFaARsB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BugFaARoB + /wG6AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AbsB + WwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEZAf8BuwFbARkB/wG+AWUBIAH+AeEBmQFAAf0B7QGkAUIB + /wHtAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewB + pAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B2AGZAUYB9gE1ATQBMwFR/wCNAAMDAQQDTAGdAVIB + TwFNAf8B5wHXAc0B/wHtAd0B0wH/AfAB5AHfAf8B9gHyAfcB/wH1AfEB9QH/Ae0B2wHVAf8B7AHaAdAB + /wHtAd0B0wH/AdgBygHBAf8BxgG5AbEB/wHoAdYBzAH/Ad8BywHBAf8BzwG7AbEB/wFBAj8B/wHPAboB + sQH/Ad8BygHAAf8BpAGWAY8B/wGPAYIBfAH/AeYBzAHBAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHhAcgBvgH/AVABTAFKAf8DTQGiAwMBBCQAATQC + MwFRAa0BWwElAfcBuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuQFaARsB/wG5AVoBGwH/AbkBWgEaAf8B + uQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsB + GgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEaAf8B + xwFzASoB/AHsAaMBQQH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7AGkAUIB/wHsAaQB + QgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AdoBmQFGAfYB + NQE0ATMBUf8AkQADFwEfA0UB3wF/AXkBdAH/AewB3AHSAf8B7QHdAdQB/wH0Au0B/wHwAeQB4gH/AecB + zQHCAf8B5QHOAcMB/wG7Aa8BqAH/AUYBRAFDAf8BTwFLAUkB/wHQAbcBrAH/AdABtwGsAf8BxAGtAaMB + /wE4AjcB/wHEAa0BowH/AcMBrAGiAf8BTwFLAUkB/wFkAVwBWQH/AeIByAG9Af8B5gHMAcEB/wHmAcwB + wQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5gHMAcEB/wF+AXQBbgH/A0QB4gMYASAo + AAE0AjMBUQGtAVsBJQH3AbgBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG5AVoB + GwH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AboBWgEaAf8B + ugFaARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG7AVsB + GgH/AdkBjgE4AfsB7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B + 7QGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHaAZkB + RgH2ATUBNAEzAVH/AJEAAwMBBANKAZMDNgH/AdoBygHBAf8B7QHdAdMB/wHuAd8B1gH/Ae0B3QHUAf8B + 5QHOAcMB/wGWAYgBggH/ATgCNwH/AWwBYwFfAf8BtgGhAZgB/wHQAbcBrAH/AdABtwGsAf8BzAG0AakB + /wGcAYsBhAH/AcwBtAGpAf8BtgGiAZgB/wFUAU8BTAH/AaoBlwGPAf8BzwG2AawB/wGUAYUBgAH/Aa8B + ngGWAf8B5gHMAcEB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHZAcABtgH/ATcCNgH/A0sBlgMDAQQo + AAE0AjMBUQGtAVsBJQH3AbgBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG4AVoB + GwH/AbgBWgEbAf8BuQFaARsB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8B + uQFaARoB/wG6AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG+AWYB + JAH8AeoBoAFDAf4B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B + 7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHaAZkB + RgH2ATUBNAEzAVH/AJEAAwkBDANPAbIBSQFGAUUB/wHmAc8BxAH/Ae0B3AHSAf8B7QHdAdMB/wHtAd0B + 0wH/AbwBsAGoAf8COAE3Af8BewFwAWsB/wHOAbUBqgH/AdABtwGsAf8B0AG3AawB/wHQAbcBrAH/AdAB + twGsAf8B0AG3AawB/wHQAbcBrAH/Ac8BtgGrAf8BzAG0AakB/wHPAbYBqwH/AYQBdwFyAf8DNQH/AZMB + hQF/Af8B5gHMAcEB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHmAcwBwQH/AVABSwFKAf8DTgG0AwkB + DCgAATQCMwFRAawBWwElAfcBtwFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgB + WgEbAf8BuAFaARsB/wG4AVoBGwH/AbkBWgEbAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB + /wG5AVoBGgH/AbkBWgEaAf8BugFaARoB/wG6AVoBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AdAB + gAExAfsB7gGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB + /wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AdoB + mQFGAfYBNQE0ATMBUf8AiQADEwEaAykBPQNAAXADQQHrAa8BnwGYAf8B5wHNAcIB/wHpAdEBxgH/AewB + 2wHQAf8B1gHIAb8B/wFGAUQBQwH/AWsBYgFeAf8BzgG1AaoB/wHQAbcBrAH/Ac4BtgGrAf8BogGRAYkB + /wFoAWABXAH/AUEBPwE+Af8DNQH/AUEBPgE9Af8BaAFfAVsB/wGiAZABiAH/Ac0BtAGqAf8BlAGFAX4B + /wGEAXcBcQH/Ac8BtgGsAf8B4wHJAb4B/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AbQB + ogGaAf8CQgFBAesDPwFuAygBPAMTARkgAAE0AjMBUQGsAVsBJQH3AbcBWgEbAf8BtwFaARsB/wG4AVoB + GwH/AbgBWgEbAf8BwwFyATwB/wHLAYUBVgH/Ab8BaQEwAf8BuAFaARsB/wG4AVoBGwH/AbkBWgEbAf8B + uQFaARsB/wG9AWQBKAH/AcsBhQFWAf8BxQF2AUEB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG6AVoB + GgH/AboBWwEaAf8BvgFfASEB/QHgAZcBPwH9Ae4BpAFCAf8B7gGkAUIB/wHeAZQBOgH/Ae0BowFCAf8B + 7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHrAaIBQQH/Ad0BkwE6Af8B7QGkAUIB/wHtAaQB + QgH/AewBpAFCAf8B7AGkAUIB/wHaAZkBRgH2ATUBNAEzAVH/AH0AAxEBFgNAAXADTgG6A0kB2wNAAe0D + NQH8AXYBcAFtAf8B6QHZAc8B/wHpAdEBxwH/AecBzQHCAf8B6AHQAcUB/wGFAX0BdwH/AT4BPAE7Af8B + sQGdAZQB/wHQAbcBrAH/Ac4BtgGrAf8BggF1AXAB/wE9AjwB/wFLAWABZwH/AXIBpwG6Af8BfQG7AdIB + /wFyAagBvAH/AUwBYQFoAf8BPQI8Af8BgQF0AW8B/wHNAbUBqgH/Ac8BtgGrAf8BwAGpAZ8B/wGFAXgB + cwH/AaABkAGJAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5QHLAcAB/wF5AW8BagH/AjgBNwH7A0EB + 7ANJAdsDTwG4A0ABbwMRARYUAAE0AjMBUQGsAVsBJQH3AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbcB + WgEbAf8BzgGMAWEB/wH7AfUB8QH/Ad0BsQGTAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB + /wHWAaABfAH/AfsB9QHxAf8B1wGhAX4B/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AbkB + WgEaAf8BwgFsASgB/QHoAZ0BQgH+Ae4BpAFCAf8B2QGPATgB/wGWAUwBFwH/AcUBegEuAf8B7AGjAUEB + /wHtAaQBQgH/Ae0BpAFCAf8B6QGgAUAB/wG5AW0BJwH/AZgBSgEVAf8B3gGUAToB/wHtAaQBQgH/Ae0B + pAFCAf8B7QGkAUIB/wHbAZkBRgH2ATUBNAEzAVH/AHkAAyYBOAM8AfMBRgFDAUIB/wFXAVIBTwH/AXkB + bwFqAf8BqgGZAZIB/wHaAcYBvQH/Ae0B3AHSAf8B7QHdAdMB/wHsAdsB0QH/AegB0AHGAf8B1gG+AbQB + /wFXAVEBTwH/AWQBXAFYAf8B0AG3AawB/wHQAbcBrAH/AaMBkQGJAf8BPQI8Af8BWgF7AYgB/wGLAdYB + 8AH/AY8B3QH5Af8BjwHdAfkB/wGPAd0B+QH/AYsB1gHxAf8BWwF8AYkB/wE9AjwB/wGiAZABiQH/AcwB + tAGpAf8BTQFJAUcB/wFHAUQBQgH/AYsBfwF6Af8B5gHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB + /wHnAc0BwgH/Ad0BxAG6Af8BrwGdAZYB/wF+AXMBbwH/AVkBVAFRAf8BRwFEAUMB/wM8AfMDJwE5EAAB + NAIzAVEBrAFbASUB9wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbgBXgEgAf8B+QHxAewB + /wH4Ae4B5wH/AckBgQFQAf8ByQGBAVAB/wHJAYEBUAH/AckBgQFQAf8B9AHlAdwB/wH7AfYB8wH/AcYB + eAFEAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/Ac4BfwEwAfsB7gGkAUIB + /wHtAaMBQgH/AbwBcgEqAf8BjQFCARIB/wGOAUIBEgH/Ab8BdAErAf8B6AGeAT8B/wHbAZEBOQH/AaMB + VQEbAf8BjgE/ARAB/wGYAUoBFgH/AcwBggExAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B2wGZAUYB + 9gE1ATQBMwFR/wB5AANKAZQBOgI5Af8BwgGtAaQB/wHeAcUBuwH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AeoB1AHKAf8B7QHdAdMB/wHtAd0B0wH/AewB2wHRAf8BxQGzAaoB/wFDAUABPwH/AaABjgGHAf8B + 0AG3AawB/wHQAbcBrAH/AWoBYQFdAf8BSgFeAWUB/wGLAdYB8AH/AY8B3QH5Af8BjwHdAfkB/wGPAd0B + +QH/AY8B3QH5Af8BjwHdAfkB/wGLAdYB8QH/AUsBYAFoAf8BaAFgAVwB/wHPAbYBqwH/AagBlgGNAf8B + uAGjAZkB/wHdAckBvwH/AeoB1QHKAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHgAccBvQH/AcYBsQGnAf8BOwI5Af8DSwGWEAABNAIzAVEBqwFbASUB + 9wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbcBWwEcAf8B5gHGAbEZ/wHvAdkBywH/Ab4B + ZwEtAf8BuAFaARsB/wG5AVoBGwH/AbkBWgEaAf8BuQFaARoB/wG2AV0BHAH+Ad4BlAE7AfwB7gGkAUIB + /wHuAaQBQgH/AekBnwE/Af8BxwF9AS8B/wGTAUcBFQH/AY0BQQESAf8BpwFbAR4B/wGZAUwBFgH/AY4B + QAERAf8BrwFhASEB/wHbAZEBOQH/AewBowFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B2wGZAUYB + 9gE1ATQBMwFR/wB5AANNAaIBPQE8ATsB/wHmAcwBwQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecB + zQHCAf8B5wHNAcIB/wHqAdQByQH/Ae0B3QHTAf8B7QHdAdMB/wG9AbEBqQH/ATcCNgH/AcQBrQGjAf8B + 0AG3AawB/wHQAbcBrAH/AUMBQAE/Af8BcAGlAbcB/wGPAd0B+QH/AY8B3QH5Af8BbAGcAa0B/wE6AUEB + RAH/AWoBmgGrAf8BjwHdAfkB/wGPAd0B+QH/AXIBpwG6Af8BQQE/AT4B/wHQAbcBrAH/AcwBswGpAf8B + xAGtAaMB/wHPAbsBsQH/AeoB2gHQAf8B6wHVAcoB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8BPQE8ATsB/wNNAaEQAAE0AjMBUQGrAVsB + JgH3AbYBWgEcAf8BtwFaARsB/wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wHUAZwBdgH/Af4B/QH8Af8B + 9gHqAeMB/wHjAcABqAH/AeQBwAGnAf8B8gHgAdQF/wHhAbgBnAH/AbgBWwEcAf8BuAFaARsB/wG4AVoB + GwH/AbkBWgEbAf8BuQFaARsB/wG/AW4BKAH6Ae8BowFCAf8B7wGjAUIB/wHuAaQBQgH/Ae4BpAFCAf8B + 7gGkAUIB/wHNAYMBMgH/AZABRAETAf8BjAFAAREB/wGNAT8BEAH/AbgBbAEmAf8B7AGiAUEB/wHuAaQB + QgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B2wGZAUYB9gE1ATQBMwFR/wB5AANNAaIB + PQE8ATsB/wHmAcwBwQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AeoB1AHKAf8B7QHcAdIB/wG4AawBpQH/AzMB/wHOAbUBqgH/AdABtwGsAf8B0AG3AawB/wE4AjcB + /wF8AbkB0AH/AY8B3QH5Af8BjwHdAfkB/wE9AUYBSQH/AzMB/wE7AUMBRQH/AY8B3QH5Af8BjwHdAfkB + /wF8AbsB0QH/ATYCNQH/AdABtwGsAf8BnAGLAYMB/wE4AjcB/wFBAUABPwH/AccBugGyAf8B7QHcAdIB + /wHqAdUBygH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecB + zQHCAf8BPQE8ATsB/wNNAaEQAAE0AjMBUQGrAVsBJgH3AbYBWgEcAf8BtgFaARwB/wG3AVoBGwH/AbcB + WgEbAf8BtwFaARsB/wHFAXoBRwH/AfkB8gHtAf8B8QHeAdIB/wG9AWgBLwH/AboBYAEjAf8B6AHJAbQF + /wHMAYgBWwH/AbgBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BtgFdAR0B/gHZAY8BOQH7Ae8B + owFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BpAFCAf8B7gGkAUIB/wHOAYMBMgH/AZEBRQETAf8BjAFAAREB + /wGOAUABEQH/AcUBeQEtAf8B7QGjAUIB/wHuAaQBQgH/Ae4BpAFCAf8B7gGkAUIB/wHtAaQBQgH/Ae0B + pAFCAf8B2wGZAUYB9gE1ATQBMwFR/wB5AANNAaIBPQE8ATsB/wHmAcwBwQH/AecBzQHCAf8B5wHNAcIB + /wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B6gHUAcoB/wG9AbEBqgH/AjcB + NgH/AcMBrAGiAf8B0AG3AawB/wHQAbcBrAH/AUMBQQFAAf8BbwGjAbYB/wGPAd0B+QH/AY8B3QH5Af8B + bgGgAbEB/wE+AUgBSwH/AW0BngGvAf8BjwHdAfkB/wGPAd0B+QH/AXEBpgG4Af8BQgFAAT4B/wHQAbcB + rAH/AcwBtAGpAf8BxAGtAaMB/wHPAbsBsQH/AeoB2gHQAf8B7QHdAdMB/wHtAd0B0wH/AesB1QHKAf8B + 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8BPQE8ATsB/wNNAaEQ + AAE0AjMBUQGrAVsBJgH3AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtgFaARsB/wG4AV0B + HwH/AfEB3wHSAf8B+gHzAe8B/wHHAX8BTgH/Ab4BaQEwAf8B9gHrAeQB/wH7AfUB8gH/AboBXwEhAf8B + uAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG+AWYBJgH9AekBnAFCAf4B7wGjAUIB/wHvAaMB + QgH/Ae8BowFCAf8B7wGjAUIB/wHpAZ0BPwH/AZcBSwEWAf8BjAFAAREB/wGsAWABIAH/AZEBQwESAf8B + lQFGARQB/wHWAYsBNgH/Ae4BpAFCAf8B7gGkAUIB/wHuAaQBQgH/Ae4BpAFCAf8B7QGkAUIB/wHbAZkB + RgH2ATUBNAEzAVH/AHkAA0oBkgE6AjkB/wHCAa0BpAH/Ad0BxQG6Af8B5wHNAcIB/wHnAc0BwgH/AecB + zQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHGAbQBqwH/AUQBQgFBAf8BngGNAYUB + /wHQAbcBrAH/AdABtwGsAf8BawFiAV4B/wFJAVwBZAH/AYsB1QHvAf8BjwHdAfkB/wGPAd0B+QH/AY8B + 3QH5Af8BjwHdAfkB/wGPAd0B+QH/AYsB1QHwAf8BSgFeAWUB/wFpAWEBXQH/Ac8BtgGrAf8BtgGhAZgB + /wHCAasBoQH/AeABzAHBAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHqAdUBygH/AecB + zgHDAf8B5wHNAcIB/wHnAc0BwgH/AdsBwwG5Af8BwQGsAaQB/wE6AjkB/wNLAZUQAAE0AjMBUQGrAVsB + JgH3AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBGwH/AdYBoAF8Bf8B + 1wGjAYAB/wHNAYwBXwP/Af4B/wHdAbABkwH/AbcBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8B + uAFaARsB/wHMAXoBKwH8Ae4BogFBAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHRAYUB + MwH/AZsBUAEZAf8BuQFtASgB/wHrAaABQQH/AbgBbAEmAf8BjgE/ARAB/wGoAVsBHgH/AewBoQFBAf8B + 7gGkAUIB/wHuAaQBQgH/Ae4BpAFCAf8B7gGkAUIB/wHbAZkBRgH2ATUBNAEzAVH/AHkAAyMBMwM/Ae4B + RQFDAUEB/wFWAVEBTwH/AXgBbgFqAf8BqQGYAZEB/wHYAcABtgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B1wG/AbUB/wFYAVIBUAH/AWIBWwFXAf8BzwG3AawB/wHQAbcBrAH/AaQBkgGKAf8B + PgI8Af8BWQF4AYQB/wGKAdUB7wH/AY8B3QH5Af8BjwHdAfkB/wGPAd0B+QH/AYsB1QHwAf8BWQF6AYYB + /wE9AjwB/wGjAZEBigH/Ac0BtAGpAf8BVgFRAU4B/wFOAUoBSAH/AagBnQGWAf8B7QHdAdMB/wHtAd0B + 0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAdwB0gH/AdcBwwG6Af8BpQGVAY4B/wF1AWsBZwH/AVUBUAFOAf8B + RAFCAUEB/wI/AT4B8QMlATYQAAE0AjMBUQGrAVsBJgH3AbUBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYB + WgEcAf8BtgFaARwB/wG2AVoBHAH/AbwBZQErAf8B/AH4AfYB/wHuAdgByAH/AekBzQG6Af8B/QH6AfgB + /wG/AW0BNQH/AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbgBWgEbAf8BugFcARwB/wHWAYgBNQH8AfAB + owFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/AeMBlwE8Af8B6wGfAUAB + /wHvAaMBQgH/AekBngE/Af8BpQFXARwB/wGPAUABEQH/AcQBeAEsAf8B7gGkAUIB/wHuAaQBQgH/Ae4B + pAFCAf8B7gGkAUIB/wHcAZkBRgH2ATUBNAEzAVH/AH0AAwwBEAM8AWYDTgGwA0gB2QNAAeoCOgE5AfoB + cgFpAWUB/wHkAcoBvwH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AYUBeQF1Af8BPgE8ATsB/wGvAZsB + kgH/AdABtwGsAf8BzwG2AasB/wGFAXgBcgH/AT4BPQE8Af8BSQFcAWMB/wFvAaIBtQH/AXsBuQHPAf8B + bwGjAbUB/wFKAV0BZAH/AT4CPAH/AYQBdwFxAf8BzAG0AakB/wHOAbYBqwH/Aa0BmgGRAf8BZwFgAV0B + /wGgAZYBkQH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/AeoB2gHQAf8BcwFtAWoB/wE3AjYB+wNBAesD + SgHaA04BtAM9AWkDDgESFAABNAIzAVEBqwFaASYB9wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoB + HAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AegByQG1Af8B/gL9Af8B/gH9AfwB/wHuAdcByAH/AbgB + XQEfAf8BtwFaARsB/wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG6AWQBIQH+AegBnwFAAf0B8AGjAUIB + /wHwAaMBQgH/Ae8BowFCAf8BugFuASkB/wGmAVsBHwH/AacBWwEfAf8BpwFbAR8B/wGnAVsBHwH/AaUB + WAEdAf8BpwFZAR0B/wGgAVIBGQH/AY4BPwEQAf8BkAFBAREB/wGoAVsBHQH/Ac8BhAEyAf8B7gGkAUIB + /wHuAaQBQgH/AdwBmQFGAfYBNQE0ATMBUf8AiQADDwEUAyUBNwM9AWkDQwHpAa0BnAGUAf8B5wHNAcIB + /wHnAc0BwgH/AecBzQHCAf8B0wG8AbIB/wFIAUUBRAH/AWgBYAFcAf8BzgG1AaoB/wHQAbcBrAH/Ac8B + tgGrAf8BpQGTAYsB/wFrAWIBXgH/AUQBQgFAAf8COQE4Af8BRAFBAUAB/wFrAWIBXgH/AaQBkgGKAf8B + zQG0AaoB/wGNAX8BeAH/AYABcwFuAf8BzgG3Aa0B/wHoAdYBzAH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B + 0wH/Ae0B3QHTAf8BtAGpAaIB/wNBAesDPwFtAycBOgMRARYgAAE0AjMBUQGrAVoBJgH3AbUBWQEcAf8B + tQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8B0AGUAWwB/wH+Af0B + /AL/Av4B/wHbAa0BjgH/AbcBWwEcAf8BtwFaARsB/wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wHKAX0B + MQH6AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8BpgFbAR8B/wGLAUABEQH/AYsBQAERAf8B + iwFAAREB/wGMAUABEQH/AY0BQAERAf8BjwE/ARAB/wGNAT8BEAH/AY4BPwEQAf8BjgE/ARAB/wGPAT8B + EAH/AcQBeAEsAf8B7gGkAUIB/wHuAaQBQgH/AdwBmQFGAfYBNQE0ATMBUf8AkQADCAEKA04BrwFJAUYB + RAH/AeUBywHAAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8BuwGnAZ8B/wE5AjgB/wF0AWoBZQH/Ac4B + tQGqAf8B0AG3AawB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB + /wHQAbcBrAH/Ac8BtgGrAf8BhQF4AXMB/wM1Af8BkgGGAYEB/wHsAdsB0QH/Ae0B3QHTAf8B7QHdAdMB + /wHtAd0B0wH/AesB2wHRAf8BSwFJAUgB/wNOAbMDCQEMKAABNAIzAVEBqwFaASYB9wG1AVkBHAH/AbUB + WQEcAf8BtQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoBHAH/AcIBdQFCAf8B9QHoAeAB + /wH6AfQB7wH/AcoBhwFaAf8BtgFaARwB/wG2AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG1AV0BHgH+AeEB + nAFBAfsB8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B7wGjAUIB + /wHvAaMBQgH/Ae8BowFCAf8BjQFAAREB/wGmAVgBHAH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8B + owFCAf8B7wGkAUIB/wHuAaQBQgH/Ae4BpAFCAf8B3AGZAUYB9gE1ATQBMwFR/wCRAAMDAQQDSgGUAzYB + /wHWAb4BtAH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeQBygG/Af8BmwGMAYUB/wE6AjkB/wFoAWAB + XAH/Aa8BmwGSAf8BzwG2AawB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB/wHQAbcBrAH/AdABtwGsAf8B + 0AG3AawB/wHQAbcBrAH/AdABuQGuAf8BmQGMAYYB/wGyAaABmAH/AegB0AHFAf8B7AHbAdEB/wHxAeUB + 4QH/Ae0B3QHUAf8B3QHOAcUB/wM3Af8DSwGXAwMBBCgAATQCMwFRAasBWgEmAfcBtQFZARwB/wG1AVkB + HAH/AbUBWQEcAf8BtQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtQFaARwB/wG3AV0BIQH/AcEBcwE+Af8B + wwF2AUIB/wG4AV8BIwH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbcBWgEbAf8BwwFuASgB+wHwAaMB + QgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B + 8AGjAUIB/wHvAaMBQgH/AZsBTwEZAf8BsQFjASIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMB + QgH/Ae8BowFCAf8B7wGjAUIB/wHuAaQBQgH/AdwBmQFGAfYBNQE0ATMBUf8AkQADGAEgA0QB4gF/AXQB + bwH/AeYBzAHBAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHkAcoBvwH/Ab4BqQGhAf8B + SgFHAUUB/wE+ATwBOwH/AWIBWgFXAf8BpgGUAYwB/wHQAbcBrAH/AdABtwGsAf8BxQGuAaQB/wGeAY0B + hgH/AZMBhAF9Af8B2QHDAbgB/wHoAdYBzAH/AewB3AHRAf8B6QHRAcYB/wHnAc0BwgH/AewB2AHSAf8B + 9wH0AfkB/wHyAegB5AH/AewB3AHSAf8BhgF+AXoB/wNEAeMDGAEhKAABNAIzAVEBqwFaASYB9wG0AVkB + HAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWgEcAf8B + tgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtAFdAR4B/gHTAYQB + MwH8AfEBowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B + 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B6AGbAT4B/wHpAZ0BPwH/Ae8BowFCAf8B7wGjAUIB/wHvAaMB + QgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B3QGYAUYB9gE1ATQBMwFR/wCNAAMDAQQD + TQGiAVEBTAFKAf8B4QHIAb4B/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AdUBvgG0Af8BiwF+AXgB/wFaAVUBUgH/AV8BWgFXAf8B2wHGAbsB/wHRAbwB + sgH/AU8BTAFKAf8BRgFDAUIB/wFiAVsBWAH/AewB2wHRAf8B7QHdAdMB/wHtAd0B0wH/AewB2wHQAf8B + 6QHRAcYB/wHnAc0BwgH/AewB2gHUAf8B7AHbAdEB/wHtAd0B0wH/AekB2QHQAf8BVAFSAVAB/wNNAaQD + BAEFJAABNAIzAVEBqwFaAScB9wG0AVkBHAH/AbQBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8B + tQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFaARwB/wG1AVoBHAH/AbYBWgEcAf8BtgFaARwB/wG2AVoB + HAH/AbYBWgEcAf8BugFlASMB/gHiAZcBQAH9AfEBowFCAf8B8QGjAUIB/wHwAaMBQgH/AfABowFCAf8B + 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMB + QgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B + 3QGYAUYB9gE1ATQBMwFR/wCNAAM1AVYBOgI5AfsBoQGRAYsB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB + /wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AdkB + wgG3Af8B1gHCAbkB/wHtAd0B0wH/AesB3AHSAf8ByQG9AbQB/wHJAbYBrQH/AdoBwgG4Af8B6AHRAcYB + /wHsAdsB0AH/Ae0B3QHTAf8B7QHdAdMB/wHtAdsB0QH/AekB0gHHAf8B5wHNAcIB/wHoAdABxQH/AewB + 2gHQAf8B7QHdAdMB/wGpAZ4BmAH/ATsCOgH7AzYBWCQAATQCMwFRAasBWgEnAfcBtAFZAR0B/wG0AVkB + HQH/AbQBWQEcAf8BtAFZARwB/wG0AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8B + tQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoBHAH/AcMBcAEqAfwB8AGiAUEB/wHxAaMB + QgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B + 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B7wGjAUIB/wHvAaMB + QgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ad0BmAFGAfYBNQE0ATMBUf8AiQADEQEWA0wBzgFaAVUB + UgH/Ad0BxQG6Af8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B6gHUAcoB/wHtAd4B + 1AH/Ae0B3QHTAf8B7AHbAdEB/wHoAdABxQH/AecBzQHCAf8B6QHRAcYB/wHtAdwB0gH/Ae0B3QHTAf8B + 7QHdAdMB/wHsAdsB0QH/AekB0QHGAf8B5wHNAcIB/wHoAdEBxgH/Ae0B3AHSAf8B5QHWAcwB/wFgAVwB + WQH/A0wB0AMSARcgAAE0AjMBUQGrAVoBJwH3AbQBWQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEcAf8B + tAFZARwB/wG0AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVoB + HAH/AbUBWgEcAf8BtgFaARwB/wHYAYkBNwH7AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B + 8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMB + QgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B + 7wGjAUIB/wHdAZgBRgH2ATUBNAEzAVH/AIkAAygBPANAAe0BrgGcAZUB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHmAcwBwQH/AdUBvQGzAf8B5AHKAcAB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzgHDAf8B8QHmAeQB/wHwAeQB3gH/Ae0B3QHTAf8B + 7AHbAdAB/wHpAdEBxgH/AecBzQHCAf8B5wHPAcQB/wHbAcsBwgH/AewB3AHSAf8B7QHdAdMB/wHsAdsB + 0AH/AekB0QHGAf8B5wHNAcIB/wHoAdABxQH/AewB2gHQAf8BugGuAaYB/wM9Ae8DKQE+IAABNAIzAVEB + qgFaAScB9wG0AVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEdAf8BtAFZARwB/wG0AVkB + HAH/AbQBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbgBYgEkAfwB + 7AGdAUMB/gHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMB + QgH/AfEBowFCAf8B8QGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B + 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B3QGYAUYB9gE1ATQB + MwFR/wCJAAMgAS4DRAHiAWkBYgFeAf8B4QHIAb0B/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AeEByAG9Af8BfgFzAW4B/wM2Af8BRwFEAUMB/wGrAZoBkwH/AeMBygG/Af8B5wHNAcIB/wHnAc0B + wgH/Ae4B3gHZAf8B9wH2AfwB/wH3AfYB+wH/AfAB4wHdAf8B7QHdAdMB/wHqAdkBzwH/AbEBoQGaAf8B + SwFIAUYB/wE3AjYB/wF+AXcBcwH/AeYB1wHNAf8B7QHdAdMB/wHtAdwB0gH/AekB0QHGAf8B5wHNAcIB + /wHjAcsBwQH/AW0BZwFjAf8DRQHkAyEBMCAAATQCMwFRAakBWwEnAfYBswFZAR0B/wGzAVkBHQH/AbQB + WQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHAH/AbQBWQEcAf8BtQFZARwB + /wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wHNAXsBLwH7AfIBowFCAf8B8gGjAUIB/wHxAaMBQgH/AfEB + owFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB + /wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfAB + owFCAf8B8AGjAUIB/wHvAaMBQgH/Ad0BmAFGAfYBNQE0ATMBUf8AiQADAgEDAzsBZANAAe8BewFxAW0B + /wHhAcgBvQH/AecBzQHCAf8B3gHFAbsB/wGiAZIBiwH/AVEBTAFLAf8DRgHgA0oBkwNOAbADQwHpAW8B + ZgFiAf8B5wHNAcIB/wHqAdYBzwH/AfMB7AHuAf8B+AH3Af4B/wH3AfYB/QH/AfIB6QHoAf8B7gHeAdYB + /wF8AXUBcQH/A0EB6gNOAbADSgGSA0UB3wFQAU0BTAH/AaMBmQGTAf8B4QHSAckB/wHsAdsB0AH/AeMB + zAHBAf8BfQFyAW0B/wNBAfEDPQFoAwMBBCAAAx0BKAGQAV0BOwHdAbMBWQEdAf8BswFZAR0B/wGzAVkB + HQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHAH/AbQBWQEcAf8B + tAFZARwB/wG1AVkBHAH/AbYBYAEgAf4B4gGVAT8B/QHyAaMBQgH/AfIBowFCAf8B8gGjAUIB/wHxAaMB + QgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B + 8QGjAUIB/wHxAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMB + QgH/AfABowFCAf8B8AGjAUIB/wGzAYYBTwHdAx0BKP8AjQAEAgMyAU8DQAHvAWkBYgFeAf8BsQGeAZYB + /wFbAVUBUwH/AT0CPAH6A0wBngMYASADAwEEAwkBCwM/AWwDNgH7AdQBvQGzAf8B5wHNAcIB/wHoAdAB + xwH/AfMB6wHtAf8B7wHhAd8B/wHoAc8BxQH/AeABzAHCAf8DNwH8Az8BbgMJAQsDAwEEAxYBHgNMAZoD + PgH5AVkBVgFUAf8BsAGlAZ4B/wFsAWcBYwH/A0AB8AMzAVIDAgEDJAAEAQMaASQBQAE+ATwBaAFFAUIB + PwFxAUUBQgE/AXEBRQFCAT8BcQFFAUIBPwFxAUUBQgE/AXEBRQFCAT8BcQFFAUIBPwFxAUUBQgE/AXEB + RQFCAT8BcQFFAUIBPwFxAUUBQgE/AXEBRQFCAT8BcAFHAUQBQAFxAUcBRAFBAXEBRwFEAUEBcQFHAUQB + QQFxAUcBRAFBAXEBRwFEAUEBcQFHAUQBQQFxAUcBRAFBAXEBRwFEAUEBcQFHAUQBQQFxAUcBRAFBAXEB + RwFEAUEBcQFHAUQBQQFxAUcBRAFBAXEBRwFEAUEBcQFHAUQBQQFxAUcBRAFBAXEBRwFEAUEBcQFHAUQB + QQFxAUcBRAFBAXEBRwFEAUEBcQFCAUABPQFoAxoBJAQB/wCRAAQCAzsBZANEAeIDQAHtA0sBzQM0AVQD + AwEEDAADJwE6A0EB6wGlAZQBjgH/AecBzQHCAf8B5wHNAcIB/wHqAdYBzgH/AegBzgHEAf8B5wHNAcIB + /wGxAZ8BlwH/A0EB7AMpAT0MAAMCAQMDMwFRA0wBywNAAe0DRAHjAz0BZwMCAQP/AP8AWgADAgEDAyAB + LQMoATsDEAEVFAADEgEXA0oB2gF0AWsBZwH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wGAAXUBcAH/A0kB2wMTARkUAAMPARQDKAE7AyABLgMCAQP/AP8AhgADTgGzAVUBUAFOAf8B + 3AHDAbkB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHhAcgBvQH/AVoBVAFSAf8DTgG6/wD/AK4AAz0B + aQFEAUIBQQH/AcABqwGjAf8B5QHMAcEB/wHlAcwBwQH/AeUBzAHBAf8BxQGwAacB/wFIAUUBQwH/A0AB + cf8A/wCuAAMNARECPgE9AfABOgI5Af8BPQI7Af8BPQI7Af8BPQI7Af8BOgI5Af8DPAHzAxEBFv8A/wCy + AAMkATQDSgGSA00BogNNAaIDTQGiA0oBkwMlATf/AP8A/wD/AP8APQABQgFNAT4HAAE+AwABKAMAAbQD + AAEtAwABAQEAAQEFAAE4AQQWAAP/AQAH/wHHA/8BwAwAAv8B4AE/A/8BhwP/AcAMAAL/AcABHwP/AYMD + /wHADAAC/wHAAR8D/wGAA/8BwAwAAv8BwAEPA/8BgAP/AcAMAAH/AQ8BgAEPAYcC/wGAAT8C/wHADAAB + /gEDAYABDgEDAv8BgAE/Av8BwAwAAfwDAAEBAv8BgAEfAv8BwAwAAfgEAAL/AYABDwL/AcAMAAH4BAAB + /wGAAwABAwHADAAB+AQAAf8EAAEBAcAMAAH4BAAB/wQAAQEBwAwAAfwDAAEBAf8EAAEBAcAMAAH8AwAB + AQH/BAABAQHADAAB/gMAAQMB/wQAAQEBwAwAAf4DAAEDAf8EAAEBAcAMAAH+AwABAwH/BAABAQHADAAB + +AQAAf8EAAEBAcAMAAHABAABHwQAAQEBwAwAAYAEAAEPBAABAQHADAABgAQAAQ8EAAEBAcAMAAGABAAB + DwQAAQEBwAwAAYAEAAEPBAABAQHADAABgAQAAQ8EAAEBAcAMAAGABAABDwQAAQEBwAwAAYAEAAEPBAAB + AQHADAABwAQAAR8EAAEBAcAMAAH4BAAB/wQAAQEBwAwAAf4DAAEDAf8EAAEBAcAMAAH+AwABAwH/BAAB + AQHADAAB/gMAAQMB/wQAAQEBwAwAAfwDAAEBAf8EAAEBAcAMAAH8AwABAQH/BAABAQHADAAB+AQAAf8E + AAEBAcAMAAH4BAAB/wQAAQEBwAwAAfgEAAH/BAABAQHADAAB+AQAAf8EAAEBAcAMAAH8AwABAQH/BAAB + AQHADAAB/gEDAYABDgEDBv8BwAwAAf8BDwGAAQ8Bhwb/AcAMAAL/AcABHwf/AcAMAAL/AcABHwf/AcAM + AAL/AcABHwf/AcAMAAL/AeABPwf/AcAMAAv/AcAMAAs= + + \ No newline at end of file From da1bb941f02679862f596ea1be299d615cefbb56 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Mon, 25 Jul 2022 19:03:49 +0200 Subject: [PATCH 03/32] Renamed settings name to code --- .../DataModel/Database/Common/DataContext.cs | 2 +- I18N Commander/DataModel/Database/Setting.cs | 2 +- ...0320_202207RenamedSettingsCode.Designer.cs | 201 ++++++++++++++++++ ...0220725170320_202207RenamedSettingsCode.cs | 35 +++ .../Migrations/DataContextModelSnapshot.cs | 14 +- 5 files changed, 245 insertions(+), 9 deletions(-) create mode 100644 I18N Commander/DataModel/Migrations/20220725170320_202207RenamedSettingsCode.Designer.cs create mode 100644 I18N Commander/DataModel/Migrations/20220725170320_202207RenamedSettingsCode.cs diff --git a/I18N Commander/DataModel/Database/Common/DataContext.cs b/I18N Commander/DataModel/Database/Common/DataContext.cs index 4d633ee..dc6e797 100644 --- a/I18N Commander/DataModel/Database/Common/DataContext.cs +++ b/I18N Commander/DataModel/Database/Common/DataContext.cs @@ -23,7 +23,7 @@ public sealed class DataContext : DbContext #region Settings modelBuilder.Entity().HasIndex(n => n.Id); - modelBuilder.Entity().HasIndex(n => n.Name).IsUnique(); + modelBuilder.Entity().HasIndex(n => n.Code).IsUnique(); modelBuilder.Entity().HasIndex(n => n.BoolValue); modelBuilder.Entity().HasIndex(n => n.GuidValue); modelBuilder.Entity().HasIndex(n => n.IntegerValue); diff --git a/I18N Commander/DataModel/Database/Setting.cs b/I18N Commander/DataModel/Database/Setting.cs index cf0dc62..8c2dc74 100644 --- a/I18N Commander/DataModel/Database/Setting.cs +++ b/I18N Commander/DataModel/Database/Setting.cs @@ -7,7 +7,7 @@ public sealed class Setting [Key] public int Id { get; set; } - public string Name { get; set; } = string.Empty; + public string Code { get; set; } = string.Empty; public string TextValue { get; set; } = string.Empty; diff --git a/I18N Commander/DataModel/Migrations/20220725170320_202207RenamedSettingsCode.Designer.cs b/I18N Commander/DataModel/Migrations/20220725170320_202207RenamedSettingsCode.Designer.cs new file mode 100644 index 0000000..20b0d4a --- /dev/null +++ b/I18N Commander/DataModel/Migrations/20220725170320_202207RenamedSettingsCode.Designer.cs @@ -0,0 +1,201 @@ +// +using System; +using DataModel.Database.Common; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DataModel.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20220725170320_202207RenamedSettingsCode")] + partial class _202207RenamedSettingsCode + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.5"); + + modelBuilder.Entity("DataModel.Database.Section", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DataKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DataKey"); + + b.HasIndex("Depth"); + + b.HasIndex("Id"); + + b.HasIndex("Name"); + + b.HasIndex("ParentId"); + + b.ToTable("Sections"); + }); + + modelBuilder.Entity("DataModel.Database.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BoolValue") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GuidValue") + .HasColumnType("TEXT"); + + b.Property("IntegerValue") + .HasColumnType("INTEGER"); + + b.Property("TextValue") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BoolValue"); + + b.HasIndex("Code") + .IsUnique(); + + b.HasIndex("GuidValue"); + + b.HasIndex("Id"); + + b.HasIndex("IntegerValue"); + + b.HasIndex("TextValue"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("DataModel.Database.TextElement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SectionId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("Id"); + + b.HasIndex("Name"); + + b.HasIndex("SectionId"); + + b.ToTable("TextElements"); + }); + + modelBuilder.Entity("DataModel.Database.Translation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Culture") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Text") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TextElementId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Culture"); + + b.HasIndex("Id"); + + b.HasIndex("Text"); + + b.HasIndex("TextElementId"); + + b.ToTable("Translations"); + }); + + modelBuilder.Entity("DataModel.Database.Section", b => + { + b.HasOne("DataModel.Database.Section", "Parent") + .WithMany() + .HasForeignKey("ParentId"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("DataModel.Database.TextElement", b => + { + b.HasOne("DataModel.Database.Section", "Section") + .WithMany("TextElements") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Section"); + }); + + modelBuilder.Entity("DataModel.Database.Translation", b => + { + b.HasOne("DataModel.Database.TextElement", "TextElement") + .WithMany("Translations") + .HasForeignKey("TextElementId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TextElement"); + }); + + modelBuilder.Entity("DataModel.Database.Section", b => + { + b.Navigation("TextElements"); + }); + + modelBuilder.Entity("DataModel.Database.TextElement", b => + { + b.Navigation("Translations"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/I18N Commander/DataModel/Migrations/20220725170320_202207RenamedSettingsCode.cs b/I18N Commander/DataModel/Migrations/20220725170320_202207RenamedSettingsCode.cs new file mode 100644 index 0000000..7b753ab --- /dev/null +++ b/I18N Commander/DataModel/Migrations/20220725170320_202207RenamedSettingsCode.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DataModel.Migrations +{ + public partial class _202207RenamedSettingsCode : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "Name", + table: "Settings", + newName: "Code"); + + migrationBuilder.RenameIndex( + name: "IX_Settings_Name", + table: "Settings", + newName: "IX_Settings_Code"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "Code", + table: "Settings", + newName: "Name"); + + migrationBuilder.RenameIndex( + name: "IX_Settings_Code", + table: "Settings", + newName: "IX_Settings_Name"); + } + } +} diff --git a/I18N Commander/DataModel/Migrations/DataContextModelSnapshot.cs b/I18N Commander/DataModel/Migrations/DataContextModelSnapshot.cs index 616d211..a43e0c8 100644 --- a/I18N Commander/DataModel/Migrations/DataContextModelSnapshot.cs +++ b/I18N Commander/DataModel/Migrations/DataContextModelSnapshot.cs @@ -61,16 +61,16 @@ namespace DataModel.Migrations b.Property("BoolValue") .HasColumnType("INTEGER"); + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + b.Property("GuidValue") .HasColumnType("TEXT"); b.Property("IntegerValue") .HasColumnType("INTEGER"); - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - b.Property("TextValue") .IsRequired() .HasColumnType("TEXT"); @@ -79,15 +79,15 @@ namespace DataModel.Migrations b.HasIndex("BoolValue"); + b.HasIndex("Code") + .IsUnique(); + b.HasIndex("GuidValue"); b.HasIndex("Id"); b.HasIndex("IntegerValue"); - b.HasIndex("Name") - .IsUnique(); - b.HasIndex("TextValue"); b.ToTable("Settings"); From fa5d39318fa70f9e52ab33e11484d2d8d4c538a0 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 26 Jul 2022 19:07:10 +0200 Subject: [PATCH 04/32] Added database handling of DeepL setting --- .../DataModel/Database/SettingDeepL.cs | 9 +++ .../DataModel/Database/SettingNames.cs | 6 ++ I18N Commander/Processor/AppSettings.cs | 60 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 I18N Commander/DataModel/Database/SettingDeepL.cs create mode 100644 I18N Commander/DataModel/Database/SettingNames.cs create mode 100644 I18N Commander/Processor/AppSettings.cs diff --git a/I18N Commander/DataModel/Database/SettingDeepL.cs b/I18N Commander/DataModel/Database/SettingDeepL.cs new file mode 100644 index 0000000..7101b11 --- /dev/null +++ b/I18N Commander/DataModel/Database/SettingDeepL.cs @@ -0,0 +1,9 @@ +namespace DataModel.Database; + +public enum SettingDeepL +{ + DISABLED, + + USE_FREE_ACCOUNT, + USE_PRO_ACCOUNT, +} \ No newline at end of file diff --git a/I18N Commander/DataModel/Database/SettingNames.cs b/I18N Commander/DataModel/Database/SettingNames.cs new file mode 100644 index 0000000..b9fe29f --- /dev/null +++ b/I18N Commander/DataModel/Database/SettingNames.cs @@ -0,0 +1,6 @@ +namespace DataModel.Database; + +public static class SettingNames +{ + public static readonly string DEEPL_MODE = "DeepL Mode"; +} \ No newline at end of file diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs new file mode 100644 index 0000000..ae6b7e9 --- /dev/null +++ b/I18N Commander/Processor/AppSettings.cs @@ -0,0 +1,60 @@ +using DataModel.Database; +using DataModel.Database.Common; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; + +namespace Processor; + +public static class AppSettings +{ + public static async Task SetDeepLMode(SettingDeepL mode) + { + // Convert the enum to its int value: + var intValue = (int)mode; + + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_MODE) is {} existingSetting) + { + existingSetting.IntegerValue = intValue; + await db.SaveChangesAsync(); + } + + // Does not exist, so create it: + else + { + var setting = new Setting + { + Code = SettingNames.DEEPL_MODE, + IntegerValue = intValue, + }; + + await db.Settings.AddAsync(setting); + await db.SaveChangesAsync(); + } + } + + public static async Task GetDeepLMode() + { + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_MODE) is { } existingSetting) + return (SettingDeepL) existingSetting.IntegerValue; + + // Does not exist, so create it: + var setting = new Setting + { + Code = SettingNames.DEEPL_MODE, + IntegerValue = (int)SettingDeepL.DISABLED, + }; + + await db.Settings.AddAsync(setting); + await db.SaveChangesAsync(); + + return (SettingDeepL) setting.IntegerValue; + } +} \ No newline at end of file From 9ed66908e735e4b481858c1e5d1bf7691e25f68a Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 26 Jul 2022 19:08:47 +0200 Subject: [PATCH 05/32] Implemented settings handling --- .../UI WinForms/Components/Main.Designer.cs | 14 + .../UI WinForms/Components/Main.resx | 623 +++++++++--------- .../Components/Setting.Designer.cs | 123 ++++ .../UI WinForms/Components/Setting.cs | 79 +++ .../UI WinForms/Components/Setting.resx | 60 ++ .../Components/Settings.Designer.cs | 110 ++++ .../UI WinForms/Components/Settings.cs | 14 + .../UI WinForms/Components/Settings.resx | 60 ++ .../UI WinForms/Resources/Icons.Designer.cs | 10 + .../UI WinForms/Resources/Icons.resx | 3 + .../Resources/icons8-settings.svg.png | Bin 0 -> 5246 bytes 11 files changed, 782 insertions(+), 314 deletions(-) create mode 100644 I18N Commander/UI WinForms/Components/Setting.Designer.cs create mode 100644 I18N Commander/UI WinForms/Components/Setting.cs create mode 100644 I18N Commander/UI WinForms/Components/Setting.resx create mode 100644 I18N Commander/UI WinForms/Components/Settings.Designer.cs create mode 100644 I18N Commander/UI WinForms/Components/Settings.cs create mode 100644 I18N Commander/UI WinForms/Components/Settings.resx create mode 100644 I18N Commander/UI WinForms/Resources/icons8-settings.svg.png diff --git a/I18N Commander/UI WinForms/Components/Main.Designer.cs b/I18N Commander/UI WinForms/Components/Main.Designer.cs index 0f3b3c9..783d13c 100644 --- a/I18N Commander/UI WinForms/Components/Main.Designer.cs +++ b/I18N Commander/UI WinForms/Components/Main.Designer.cs @@ -38,6 +38,7 @@ this.tabControl = new System.Windows.Forms.TabControl(); this.tabTranslation = new System.Windows.Forms.TabPage(); this.tabSettings = new System.Windows.Forms.TabPage(); + this.settings = new UI_WinForms.Components.Settings(); this.imageList = new System.Windows.Forms.ImageList(this.components); this.tableLayout.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainerLR)).BeginInit(); @@ -49,6 +50,7 @@ this.splitContainerRTB.SuspendLayout(); this.tabControl.SuspendLayout(); this.tabTranslation.SuspendLayout(); + this.tabSettings.SuspendLayout(); this.SuspendLayout(); // // tableLayout @@ -149,6 +151,7 @@ // // tabSettings // + this.tabSettings.Controls.Add(this.settings); this.tabSettings.ImageIndex = 0; this.tabSettings.Location = new System.Drawing.Point(70, 4); this.tabSettings.Name = "tabSettings"; @@ -158,6 +161,15 @@ this.tabSettings.Text = "Settings"; this.tabSettings.UseVisualStyleBackColor = true; // + // settings + // + this.settings.Dock = System.Windows.Forms.DockStyle.Fill; + this.settings.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.settings.Location = new System.Drawing.Point(3, 3); + this.settings.Name = "settings"; + this.settings.Size = new System.Drawing.Size(885, 589); + this.settings.TabIndex = 0; + // // imageList // this.imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; @@ -184,6 +196,7 @@ this.splitContainerRTB.ResumeLayout(false); this.tabControl.ResumeLayout(false); this.tabTranslation.ResumeLayout(false); + this.tabSettings.ResumeLayout(false); this.ResumeLayout(false); } @@ -199,5 +212,6 @@ private TabPage tabTranslation; private TabPage tabSettings; private ImageList imageList; + private Settings settings; } } diff --git a/I18N Commander/UI WinForms/Components/Main.resx b/I18N Commander/UI WinForms/Components/Main.resx index 92a0569..73f84a8 100644 --- a/I18N Commander/UI WinForms/Components/Main.resx +++ b/I18N Commander/UI WinForms/Components/Main.resx @@ -64,330 +64,325 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu - SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAApEsAAAJNU0Z0AUkBTAIBAQIB - AAEQAQABEAEAAS0BAAEtAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABtAMAAS0DAAEBAQABIAUAAZAB - fvoAAw8BFAMTARkEAf8A/wAqAAMnATkDSwGWA00BoQNNAaEDTQGhA0sBlgMnATp8AAMLAQ4BYwFUAUgB - ogGAAVsBRAHHAyUBNv8A/wAmAAMRARYDPAHzAToCOQH/AT0BPAE7Af8BPQE8ATsB/wE9ATwBOwH/AToC - OQH/AzwB9AMRARZ4AAMSARgBgwFdAUIBzAG8AVsBGQH/AY8BXgE9AdcDEAEV/wD/ACIAAz8BbgFGAUMB + SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAjEoAAAJNU0Z0AUkBTAIBAQIB + AAEgAQABIAEAAS0BAAEtAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABtAMAAS0DAAEBAQABIAUAAZAB + fvoAAw8BFAMTARkEAf8A/wAqAAMnATkDTgGWA1EBoQNRAaEDUQGhA04BlgMnATp8AAMLAQ4BVQFTAVEB + ogFpAVsBUgHHAyUBNv8A/wAmAAMRARYDQgHzAToCOQH/AT0BPAE7Af8BPQE8ATsB/wE9ATwBOwH/AToC + OQH/A0AB9AMRARZ4AAMSARgBbQFdAVIBzAG8AVsBGQH/AXkBXgFOAdcDEAEV/wD/ACIAAz8BbgFGAUMB QgH/AcQBrwGmAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8BxAGuAaYB/wFGAUMBQgH/A0ABcHgAAxIB - GAGDAV0BQgHMAbwBWwEZAf8BvAFbARkB/wGOAV0BOgHYAiYBJQE3BAH/AP8AGgADTwG3AVcBUgFQAf8B - 3gHFAbsB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHeAcUBuwH/AVcBUgFPAf8DTgG6BAF0AAMSARgB - gwFdAUIBzAG7AVsBGQH/AbwBWwEZAf8BvAFbARkB/wGNAV4BPQHVAhoBGQEj/wDxAAMDAQQDIgExAykB - PgMSARgUAAMSARgDSQHbAXsBcAFsAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B - wgH/AXoBcAFrAf8DSQHbAxMBGhQAAxIBFwMpAT4DIgExAwMBBFAAAxIBGAGDAV0BQgHMAbsBWwEZAf8B - uwFbARkB/wG7AVsBGQH/AbwBWwEZAf8BjAFdAT4B1AMhAS8EAf8A5QADAgEDAz0BaQNFAeQDPQHvA0wB - 0AM2AVkDBAEFDAADKAE7A0EB7AGrAZoBkwH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B - 5wHNAcIB/wGqAZkBkgH/A0AB7QMpAT0MAAMDAQQDNgFXA0wBzwM9Ae8DRQHlAz4BagMCAQNMAAMSARgB - gwFdAUIBzAG7AVsBGgH/AbsBWwEZAf8BuwFbARkB/wG7AVsBGQH/AbsBWwEZAf8BiwFcAT4B0wMiATH/ - AOEAAwIBAwM0AVMDQQHxAW8BaQFmAf8BtwGrAaQB/wFdAVkBVwH/AzoB+wNNAaQDGQEiAwQBBQMJAQwD - PwFuATgCNwH7AdwByAG+Af8B5wHOAcMB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AdgB - wAG2Af8CNQE0AfwDQAFxAwoBDQMDAQQDGAEgA00BogE7AToBOQH7AV4BVwFUAf8BtgGjAZsB/wFwAWcB - YwH/AUECQAHyAzUBVQMCAQNIAAMSARgBgwFdAUIBzAG7AVsBGgH/AbsBWwEaAf8BuwFbARkB/wG7AVsB - GQH/AbsBWwEZAf8BuwFbARkB/wGLAV0BPgHUAxgBIP8A2QADAwEEAz0BaANBAfEBfwF0AW8B/wHjAcwB - wQH/AewB2gHQAf8B5AHVAcsB/wGnAZ0BlwH/AVMBUAFPAf8DRQHkA0sBmANOAbQBQwJCAewBeAFyAW4B - /wHtAdwB0gH/AeoB1QHLAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AXUB - awFnAf8DQQHtA04BtQNLAZcDRAHiAVMBTgFMAf8BpAGUAY0B/wHfAcYBuwH/AecBzQHCAf8B4wHJAb4B - /wGAAXUBcAH/AUECQAHyAz4BagMDAQREAAMSARgBgwFdAUIBzAG6AVsBGgH/AbsBWwEaAf8BuwFbARoB - /wG7AVsBGgH/AbsBWwEZAf8BuwFbARkB/wG7AVsBGQH/AYwBXAE9AdYCJgElATf/ANUAAyEBLwNEAeMB - bwFqAWYB/wHjAcwBwgH/AecBzQHCAf8B6AHQAcUB/wHtAdwB0gH/Ae0B3QHTAf8B6AHZAc8B/wGEAX4B - eQH/AzcB/wFOAUwBSwH/AbcBqwGlAf8B6gHbAdEB/wHtAd0B0wH/Ae0B3QHTAf8B6wHVAcsB/wHnAc0B - wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeUBywHAAf8BswGgAZgB/wFNAUoBSAH/ATcCNgH/AYEB - dQFxAf8B4wHJAb8B/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeMByQG+Af8BcAFnAWMB - /wNFAeUDIgExJAACIgEhATABYgFTAUkBoAFpAVYBSQGrAWkBVgFJAasBaQFWAUkBqwFqAVYBSQGrAWoB - VgFJAasBagFWAUkBqwFvAVgBSAGzAaQBXQEsAe4BugFbARoB/wG6AVsBGgH/AbsBWwEaAf8BuwFbARoB - /wG7AVsBGgH/AbsBWwEaAf8BuwFbARkB/wG7AVsBGQH/AZ4BXwE0AeUBawFXAUkBrQFqAVYBSQGrAWoB - VgFJAasBagFWAUkBqwFpAVYBSgGpAXQBZQFRAasBdAFlAVEBqwF0AWUBUQGrAXQBZQFRAasBdAFlAVEB - qwF0AWUBUQGrAXQBZQFRAasBdAFlAVEBqwF0AWUBUQGrAXQBZQFRAasBdAFlAVEBqwFpAV8BTgGgAiIB - IQEw/wCNAAMoATwDQAHtAbcBqwGkAf8B7AHbAdAB/wHpAdEBxgH/AecBzQHCAf8B6AHRAcYB/wHsAdoB - 0AH/Ae0B3QHTAf8B7AHcAdIB/wHeAc8BxgH/AewB3AHSAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B - 7QHdAdMB/wHtAd0B0wH/AeoB1QHLAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B - wgH/AeYBzAHBAf8B2AHAAbYB/wHmAcwBwQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B - 5wHNAcIB/wHnAc0BwgH/AbEBngGXAf8DPQHvAykBPSAAAyABLgGiAV0BLQHsAbkBWgEaAf8BuQFaARoB - /wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG6AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsBGgH/AboB - WwEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEaAf8BuwFbARkB - /wG7AVsBGQH/AbsBWwEZAf8BuwFbARkB/wG7AVsBGQH/AbwBWwEZAf8ByQF1ASoB/AHsAaQBQgH/AewB - pAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B6wGkAUIB - /wHrAaQBQgH/AesBpAFCAf8B6wGkAUIB/wHGAZMBTAHrAyABLf8AiQADEAEVA0sBzQFcAVkBVgH/AeMB - 1AHLAf8B7QHcAdIB/wHpAdEBxgH/AecBzQHCAf8B6AHQAcUB/wHsAdsB0QH/Ae0B3QHTAf8B7QHdAdMB - /wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAdwB0gH/AesB - 1QHKAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB - /wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B3QHFAboB/wFaAVUBUgH/A0wB - zgMRARYgAAE0ATMBMgFQAa0BXAElAfYBuQFaARsB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoB - GgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8B - ugFbARoB/wG6AVsBGgH/AboBWwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEaAf8BuwFbARkB/wG7AVsB - GQH/AbsBWwEZAf8BuQFfARwB/gHWAYoBNwH9Ae0BpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B - 7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHrAaQB - QgH/AdgBmQFGAfYBNAIzAVD/AI0AAzMBUgI9ATwB+gGmAZsBlQH/Ae0B3QHTAf8B7AHbAdAB/wHpAdEB - xgH/AesB1wHQAf8B7AHaAdMB/wHsAdsB0QH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B - 7QHdAdMB/wHtAd0B0wH/AeoB2gHQAf8BxgG5AbEB/wHqAdoB0AH/AeoB1QHKAf8B5wHOAcMB/wHnAc0B - wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B - 5wHNAcIB/wHnAc0BwgH/AaEBkQGLAf8BOgI5AfsDNQFWJAABNAIzAVEBrQFbASUB9wG4AVoBGwH/AbkB - WgEbAf8BuQFaARsB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BugFaARoB - /wG6AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AbsB - WwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEZAf8BuwFbARkB/wG+AWUBIAH+AeEBmQFAAf0B7QGkAUIB - /wHtAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewB - pAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B2AGZAUYB9gE1ATQBMwFR/wCNAAMDAQQDTAGdAVIB - TwFNAf8B5wHXAc0B/wHtAd0B0wH/AfAB5AHfAf8B9gHyAfcB/wH1AfEB9QH/Ae0B2wHVAf8B7AHaAdAB - /wHtAd0B0wH/AdgBygHBAf8BxgG5AbEB/wHoAdYBzAH/Ad8BywHBAf8BzwG7AbEB/wFBAj8B/wHPAboB - sQH/Ad8BygHAAf8BpAGWAY8B/wGPAYIBfAH/AeYBzAHBAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B - 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHhAcgBvgH/AVABTAFKAf8DTQGiAwMBBCQAATQC - MwFRAa0BWwElAfcBuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuQFaARsB/wG5AVoBGwH/AbkBWgEaAf8B - uQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsB + GAFtAV0BUgHMAbwBWwEZAf8BvAFbARkB/wF3AV8BTAHYAyUBNwQB/wD/ABoAA1YBtwFXAVIBUAH/Ad4B + xQG7Af8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B3gHFAbsB/wFXAVIBTwH/A1YBugQBdAADEgEYAW0B + XQFSAcwBuwFbARkB/wG8AVsBGQH/AbwBWwEZAf8BdwFfAU8B1QIaARkBI/8A8QADAwEEAyIBMQMpAT4D + EgEYFAADEgEYA1UB2wF7AXABbAH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB + /wF6AXABawH/A1UB2wMTARoUAAMSARcDKQE+AyIBMQMDAQRQAAMSARgBbQFdAVIBzAG7AVsBGQH/AbsB + WwEZAf8BuwFbARkB/wG8AVsBGQH/AXUBXQFRAdQDIQEvBAH/AOUAAwIBAwM9AWkDTwHkA0UB7wNWAdAD + NgFZAwQBBQwAAygBOwNKAewBqwGaAZMB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecB + zQHCAf8BqgGZAZIB/wNIAe0DKQE9DAADAwEEAzYEVwHPA0UB7wNPAeUDPgFqAwIBA0wAAxIBGAFtAV0B + UgHMAbsBWwEaAf8BuwFbARkB/wG7AVsBGQH/AbsBWwEZAf8BuwFbARkB/wFzAVwBTwHTAyIBMf8A4QAD + AgEDAzQBUwNHAfEBbwFpAWYB/wG3AasBpAH/AV0BWQFXAf8DOgH7A1EBpAMZASIDBAEFAwkBDAM/AW4B + OAI3AfsB3AHIAb4B/wHnAc4BwwH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B2AHAAbYB + /wIzATIB/ANAAXEDCgENAwMBBAMYASADUQGiATsBOgE5AfsBXgFXAVQB/wG2AaMBmwH/AXABZwFjAf8D + SAHyAzUBVQMCAQNIAAMSARgBbQFdAVIBzAG7AVsBGgH/AbsBWwEaAf8BuwFbARkB/wG7AVsBGQH/AbsB + WwEZAf8BuwFbARkB/wF1AV0BUQHUAxgBIP8A2QADAwEEAz0BaANHAfEBfwF0AW8B/wHjAcwBwQH/AewB + 2gHQAf8B5AHVAcsB/wGnAZ0BlwH/AVMBUAFPAf8DTwHkA04BmANVAbQBTAJLAewBeAFyAW4B/wHtAdwB + 0gH/AeoB1QHLAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AXUBawFnAf8D + SAHtA1QBtQNOAZcDUAHiAVMBTgFMAf8BpAGUAY0B/wHfAcYBuwH/AecBzQHCAf8B4wHJAb4B/wGAAXUB + cAH/A0gB8gM+AWoDAwEERAADEgEYAW0BXQFSAcwBugFbARoB/wG7AVsBGgH/AbsBWwEaAf8BuwFbARoB + /wG7AVsBGQH/AbsBWwEZAf8BuwFbARkB/wF2AVwBTgHWAyUBN/8A1QADIQEvA1AB4wFvAWoBZgH/AeMB + zAHCAf8B5wHNAcIB/wHoAdABxQH/Ae0B3AHSAf8B7QHdAdMB/wHoAdkBzwH/AYQBfgF5Af8DNwH/AU4B + TAFLAf8BtwGrAaUB/wHqAdsB0QH/Ae0B3QHTAf8B7QHdAdMB/wHrAdUBywH/AecBzQHCAf8B5wHNAcIB + /wHnAc0BwgH/AecBzQHCAf8B5QHLAcAB/wGzAaABmAH/AU0BSgFIAf8BNwI2Af8BgQF1AXEB/wHjAckB + vwH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B4wHJAb4B/wFwAWcBYwH/A08B5QMiATEk + AAMhATABVAFSAVABoAFZAVYBUwGrAVkBVgFTAasBWQFWAVMBqwFZAVYBUwGrAVkBVgFTAasBWQFWAVMB + qwFdAVgBUwGzAZQBXwE5Ae4BugFbARoB/wG6AVsBGgH/AbsBWwEaAf8BuwFbARoB/wG7AVsBGgH/AbsB + WwEaAf8BuwFbARkB/wG7AVsBGQH/AYkBXwFGAeUBWgFVAVMBrQFZAVYBUwGrAVkBVgFTAasBWQFWAVMB + qwFYAVQBUgGpAVsBWQFUAasBWwFZAVQBqwFbAVkBVAGrAVsBWQFUAasBWwFZAVQBqwFbAVkBVAGrAVsB + WQFUAasBWwFZAVQBqwFbAVkBVAGrAVsBWQFUAasBWwFZAVQBqwFVAVQBUQGgAyEBMP8AjQADKAE8A0gB + 7QG3AasBpAH/AewB2wHQAf8B6QHRAcYB/wHnAc0BwgH/AegB0QHGAf8B7AHaAdAB/wHtAd0B0wH/AewB + 3AHSAf8B3gHPAcYB/wHsAdwB0gH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB + /wHqAdUBywH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHmAcwBwQH/AdgB + wAG2Af8B5gHMAcEB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB + /wGxAZ4BlwH/A0UB7wMpAT0gAAMgAS4BkwFdAT0B7AG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoB + GgH/AbkBWgEaAf8BugFaARoB/wG6AVoBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8B + ugFbARoB/wG6AVsBGgH/AbsBWwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEZAf8BuwFbARkB/wG7AVsB + GQH/AbsBWwEZAf8BuwFbARkB/wG8AVsBGQH/AcUBdQErAfwB7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B + 7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AesBpAFCAf8B6wGkAUIB/wHrAaQB + QgH/AesBpAFCAf8BqwGGAVMB6wMgAS3/AIkAAxABFQNUAc0BXAFZAVYB/wHjAdQBywH/Ae0B3AHSAf8B + 6QHRAcYB/wHnAc0BwgH/AegB0AHFAf8B7AHbAdEB/wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B + 0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B7QHcAdIB/wHrAdUBygH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/Ad0BxQG6Af8BWgFVAVIB/wNWAc4DEQEWIAADMwFQAaIB + XgEtAfYBuQFaARsB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB + /wG5AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AboB + WwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEaAf8BuwFbARkB/wG7AVsBGQH/AbsBWwEZAf8BtQFhAR4B + /gHQAYoBOwH9Ae0BpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewB + pAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHrAaQBQgH/AccBkwFIAfYDMwFQ/wCN + AAMzAVICQQFAAfoBpgGbAZUB/wHtAd0B0wH/AewB2wHQAf8B6QHRAcYB/wHrAdcB0AH/AewB2gHTAf8B + 7AHbAdEB/wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHqAdoB + 0AH/AcYBuQGxAf8B6gHaAdAB/wHqAdUBygH/AecBzgHDAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wGhAZEB + iwH/AToCOQH7AzUBViQAAzMBUQGnAVsBLgH3AbgBWgEbAf8BuQFaARsB/wG5AVoBGwH/AbkBWgEaAf8B + uQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG6AVoBGgH/AboBWgEaAf8BugFaARoB/wG6AVsB GgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BuwFbARoB/wG7AVsBGgH/AbsBWwEaAf8B - xwFzASoB/AHsAaMBQQH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7AGkAUIB/wHsAaQB - QgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AdoBmQFGAfYB - NQE0ATMBUf8AkQADFwEfA0UB3wF/AXkBdAH/AewB3AHSAf8B7QHdAdQB/wH0Au0B/wHwAeQB4gH/AecB - zQHCAf8B5QHOAcMB/wG7Aa8BqAH/AUYBRAFDAf8BTwFLAUkB/wHQAbcBrAH/AdABtwGsAf8BxAGtAaMB - /wE4AjcB/wHEAa0BowH/AcMBrAGiAf8BTwFLAUkB/wFkAVwBWQH/AeIByAG9Af8B5gHMAcEB/wHmAcwB - wQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5gHMAcEB/wF+AXQBbgH/A0QB4gMYASAo - AAE0AjMBUQGtAVsBJQH3AbgBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG5AVoB - GwH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AboBWgEaAf8B - ugFaARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG7AVsB - GgH/AdkBjgE4AfsB7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B - 7QGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHaAZkB - RgH2ATUBNAEzAVH/AJEAAwMBBANKAZMDNgH/AdoBygHBAf8B7QHdAdMB/wHuAd8B1gH/Ae0B3QHUAf8B - 5QHOAcMB/wGWAYgBggH/ATgCNwH/AWwBYwFfAf8BtgGhAZgB/wHQAbcBrAH/AdABtwGsAf8BzAG0AakB - /wGcAYsBhAH/AcwBtAGpAf8BtgGiAZgB/wFUAU8BTAH/AaoBlwGPAf8BzwG2AawB/wGUAYUBgAH/Aa8B - ngGWAf8B5gHMAcEB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHZAcABtgH/ATcCNgH/A0sBlgMDAQQo - AAE0AjMBUQGtAVsBJQH3AbgBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG4AVoB - GwH/AbgBWgEbAf8BuQFaARsB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8B - uQFaARoB/wG6AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG+AWYB - JAH8AeoBoAFDAf4B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B - 7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHaAZkB - RgH2ATUBNAEzAVH/AJEAAwkBDANPAbIBSQFGAUUB/wHmAc8BxAH/Ae0B3AHSAf8B7QHdAdMB/wHtAd0B - 0wH/AbwBsAGoAf8COAE3Af8BewFwAWsB/wHOAbUBqgH/AdABtwGsAf8B0AG3AawB/wHQAbcBrAH/AdAB - twGsAf8B0AG3AawB/wHQAbcBrAH/Ac8BtgGrAf8BzAG0AakB/wHPAbYBqwH/AYQBdwFyAf8DNQH/AZMB - hQF/Af8B5gHMAcEB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHmAcwBwQH/AVABSwFKAf8DTgG0AwkB - DCgAATQCMwFRAawBWwElAfcBtwFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgB + uwFbARkB/wG7AVsBGQH/AboBZwEiAf4B2wGZAUAB/QHtAaQBQgH/Ae0BpAFCAf8B7AGkAUIB/wHsAaQB + QgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B + 7AGkAUIB/wHHAZMBSAH2AzMBUf8AjQADAwEEA1ABnQFSAU8BTQH/AecB1wHNAf8B7QHdAdMB/wHwAeQB + 3wH/AfYB8gH3Af8B9QHxAfUB/wHtAdsB1QH/AewB2gHQAf8B7QHdAdMB/wHYAcoBwQH/AcYBuQGxAf8B + 6AHWAcwB/wHfAcsBwQH/Ac8BuwGxAf8BQQI/Af8BzwG6AbEB/wHfAcoBwAH/AaQBlgGPAf8BjwGCAXwB + /wHmAcwBwQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecB + zQHCAf8B4QHIAb4B/wFQAUwBSgH/A1EBogMDAQQkAAMzAVEBpwFbAS4B9wG4AVoBGwH/AbgBWgEbAf8B + uAFaARsB/wG5AVoBGwH/AbkBWgEbAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoB + GgH/AbkBWgEaAf8BugFaARoB/wG6AVsBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AboBWwEaAf8B + ugFbARoB/wG7AVsBGgH/AbsBWwEaAf8BuwFbARoB/wHDAXMBKwH8AewBowFBAf8B7QGkAUIB/wHtAaQB + QgH/Ae0BpAFCAf8B7QGkAUIB/wHsAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8B + 7AGkAUIB/wHsAaQBQgH/AewBpAFCAf8ByQGTAUgB9gMzAVH/AJEAAxcBHwNQAd8BfwF5AXQB/wHsAdwB + 0gH/Ae0B3QHUAf8B9ALtAf8B8AHkAeIB/wHnAc0BwgH/AeUBzgHDAf8BuwGvAagB/wFGAUQBQwH/AU8B + SwFJAf8B0AG3AawB/wHQAbcBrAH/AcQBrQGjAf8BOAI3Af8BxAGtAaMB/wHDAawBogH/AU8BSwFJAf8B + ZAFcAVkB/wHiAcgBvQH/AeYBzAHBAf8B5gHMAcEB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AeYBzAHBAf8BfgF0AW4B/wNQAeIDGAEgKAADMwFRAacBWwEuAfcBuAFaARsB/wG4AVoBGwH/AbgB WgEbAf8BuAFaARsB/wG4AVoBGwH/AbkBWgEbAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB - /wG5AVoBGgH/AbkBWgEaAf8BugFaARoB/wG6AVoBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AdAB - gAExAfsB7gGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB - /wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AdoB - mQFGAfYBNQE0ATMBUf8AiQADEwEaAykBPQNAAXADQQHrAa8BnwGYAf8B5wHNAcIB/wHpAdEBxgH/AewB - 2wHQAf8B1gHIAb8B/wFGAUQBQwH/AWsBYgFeAf8BzgG1AaoB/wHQAbcBrAH/Ac4BtgGrAf8BogGRAYkB - /wFoAWABXAH/AUEBPwE+Af8DNQH/AUEBPgE9Af8BaAFfAVsB/wGiAZABiAH/Ac0BtAGqAf8BlAGFAX4B - /wGEAXcBcQH/Ac8BtgGsAf8B4wHJAb4B/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AbQB - ogGaAf8CQgFBAesDPwFuAygBPAMTARkgAAE0AjMBUQGsAVsBJQH3AbcBWgEbAf8BtwFaARsB/wG4AVoB - GwH/AbgBWgEbAf8BwwFyATwB/wHLAYUBVgH/Ab8BaQEwAf8BuAFaARsB/wG4AVoBGwH/AbkBWgEbAf8B - uQFaARsB/wG9AWQBKAH/AcsBhQFWAf8BxQF2AUEB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG6AVoB - GgH/AboBWwEaAf8BvgFfASEB/QHgAZcBPwH9Ae4BpAFCAf8B7gGkAUIB/wHeAZQBOgH/Ae0BowFCAf8B - 7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHrAaIBQQH/Ad0BkwE6Af8B7QGkAUIB/wHtAaQB - QgH/AewBpAFCAf8B7AGkAUIB/wHaAZkBRgH2ATUBNAEzAVH/AH0AAxEBFgNAAXADTgG6A0kB2wNAAe0D - NQH8AXYBcAFtAf8B6QHZAc8B/wHpAdEBxwH/AecBzQHCAf8B6AHQAcUB/wGFAX0BdwH/AT4BPAE7Af8B - sQGdAZQB/wHQAbcBrAH/Ac4BtgGrAf8BggF1AXAB/wE9AjwB/wFLAWABZwH/AXIBpwG6Af8BfQG7AdIB - /wFyAagBvAH/AUwBYQFoAf8BPQI8Af8BgQF0AW8B/wHNAbUBqgH/Ac8BtgGrAf8BwAGpAZ8B/wGFAXgB - cwH/AaABkAGJAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5QHLAcAB/wF5AW8BagH/AjgBNwH7A0EB - 7ANJAdsDTwG4A0ABbwMRARYUAAE0AjMBUQGsAVsBJQH3AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbcB + /wG5AVoBGgH/AbkBWgEaAf8BugFaARoB/wG6AVoBGgH/AboBWwEaAf8BugFbARoB/wG6AVsBGgH/AboB + WwEaAf8BugFbARoB/wG6AVsBGgH/AbsBWwEaAf8B0wGMATgB+wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB + /wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHsAaQBQgH/AewB + pAFCAf8B7AGkAUIB/wHsAaQBQgH/AckBkwFIAfYDMwFR/wCRAAMDAQQDTQGTAzYB/wHaAcoBwQH/Ae0B + 3QHTAf8B7gHfAdYB/wHtAd0B1AH/AeUBzgHDAf8BlgGIAYIB/wE4AjcB/wFsAWMBXwH/AbYBoQGYAf8B + 0AG3AawB/wHQAbcBrAH/AcwBtAGpAf8BnAGLAYQB/wHMAbQBqQH/AbYBogGYAf8BVAFPAUwB/wGqAZcB + jwH/Ac8BtgGsAf8BlAGFAYAB/wGvAZ4BlgH/AeYBzAHBAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 2QHAAbYB/wE3AjYB/wNOAZYDAwEEKAADMwFRAacBWwEuAfcBuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8B + uAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG5AVoBGwH/AbkBWgEaAf8BuQFaARoB/wG5AVoB + GgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AboBWgEaAf8BugFaARoB/wG6AVsBGgH/AboBWwEaAf8B + ugFbARoB/wG6AVsBGgH/AboBZgEoAfwB5gGcAUUB/gHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQB + QgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHsAaQBQgH/AewBpAFCAf8B + 7AGkAUIB/wHsAaQBQgH/AckBkwFIAfYDMwFR/wCRAAMJAQwDVAGyAUkBRgFFAf8B5gHPAcQB/wHtAdwB + 0gH/Ae0B3QHTAf8B7QHdAdMB/wG8AbABqAH/AjgBNwH/AXsBcAFrAf8BzgG1AaoB/wHQAbcBrAH/AdAB + twGsAf8B0AG3AawB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB/wHPAbYBqwH/AcwBtAGpAf8BzwG2AasB + /wGEAXcBcgH/AzUB/wGTAYUBfwH/AeYBzAHBAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5gHMAcEB + /wFQAUsBSgH/A1UBtAMJAQwoAAMzAVEBpgFbAS4B9wG3AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG4AVoB + GwH/AbgBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuQFaARsB/wG5AVoBGgH/AbkBWgEaAf8B + uQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG6AVoBGgH/AboBWgEaAf8BugFbARoB/wG6AVsB + GgH/AboBWwEaAf8BygF9ATEB+wHuAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B + 7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7AGkAUIB/wHsAaQB + QgH/AewBpAFCAf8ByQGTAUgB9gMzAVH/AIkAAxMBGgMpAT0DQAFwA0wB6wGvAZ8BmAH/AecBzQHCAf8B + 6QHRAcYB/wHsAdsB0AH/AdYByAG/Af8BRgFEAUMB/wFrAWIBXgH/Ac4BtQGqAf8B0AG3AawB/wHOAbYB + qwH/AaIBkQGJAf8BaAFgAVwB/wFBAT8BPgH/AzUB/wFBAT4BPQH/AWgBXwFbAf8BogGQAYgB/wHNAbQB + qgH/AZQBhQF+Af8BhAF3AXEB/wHPAbYBrAH/AeMByQG+Af8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wG0AaIBmgH/A0wB6wM/AW4DKAE8AxMBGSAAAzMBUQGmAVsBLgH3AbcBWgEbAf8BtwFaARsB + /wG4AVoBGwH/AbgBWgEbAf8BwwFyATwB/wHLAYUBVgH/Ab8BaQEwAf8BuAFaARsB/wG4AVoBGwH/AbkB + WgEbAf8BuQFaARsB/wG9AWQBKAH/AcsBhQFWAf8BxQF2AUEB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB + /wG6AVoBGgH/AboBWwEaAf8BvgFdASUB/QHaAZcBQAH9Ae4BpAFCAf8B7gGkAUIB/wHeAZQBOgH/Ae0B + owFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B7QGkAUIB/wHrAaIBQQH/Ad0BkwE6Af8B7QGkAUIB + /wHtAaQBQgH/AewBpAFCAf8B7AGkAUIB/wHJAZMBSAH2AzMBUf8AfQADEQEWA0ABcANWAboDVQHbA0gB + 7QMzAfwBdgFwAW0B/wHpAdkBzwH/AekB0QHHAf8B5wHNAcIB/wHoAdABxQH/AYUBfQF3Af8BPgE8ATsB + /wGxAZ0BlAH/AdABtwGsAf8BzgG2AasB/wGCAXUBcAH/AT0CPAH/AUsBYAFnAf8BcgGnAboB/wF9AbsB + 0gH/AXIBqAG8Af8BTAFhAWgB/wE9AjwB/wGBAXQBbwH/Ac0BtQGqAf8BzwG2AasB/wHAAakBnwH/AYUB + eAFzAf8BoAGQAYkB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHlAcsBwAH/AXkBbwFqAf8COAE3AfsD + SgHsA1UB2wNWAbgDQAFvAxEBFhQAAzMBUQGmAVsBLgH3AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbcB WgEbAf8BzgGMAWEB/wH7AfUB8QH/Ad0BsQGTAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB /wHWAaABfAH/AfsB9QHxAf8B1wGhAX4B/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AbkB - WgEaAf8BwgFsASgB/QHoAZ0BQgH+Ae4BpAFCAf8B2QGPATgB/wGWAUwBFwH/AcUBegEuAf8B7AGjAUEB + WgEaAf8BvgFqASwB/QHkAZkBRAH+Ae4BpAFCAf8B2QGPATgB/wGWAUwBFwH/AcUBegEuAf8B7AGjAUEB /wHtAaQBQgH/Ae0BpAFCAf8B6QGgAUAB/wG5AW0BJwH/AZgBSgEVAf8B3gGUAToB/wHtAaQBQgH/Ae0B - pAFCAf8B7QGkAUIB/wHbAZkBRgH2ATUBNAEzAVH/AHkAAyYBOAM8AfMBRgFDAUIB/wFXAVIBTwH/AXkB - bwFqAf8BqgGZAZIB/wHaAcYBvQH/Ae0B3AHSAf8B7QHdAdMB/wHsAdsB0QH/AegB0AHGAf8B1gG+AbQB - /wFXAVEBTwH/AWQBXAFYAf8B0AG3AawB/wHQAbcBrAH/AaMBkQGJAf8BPQI8Af8BWgF7AYgB/wGLAdYB - 8AH/AY8B3QH5Af8BjwHdAfkB/wGPAd0B+QH/AYsB1gHxAf8BWwF8AYkB/wE9AjwB/wGiAZABiQH/AcwB - tAGpAf8BTQFJAUcB/wFHAUQBQgH/AYsBfwF6Af8B5gHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB - /wHnAc0BwgH/Ad0BxAG6Af8BrwGdAZYB/wF+AXMBbwH/AVkBVAFRAf8BRwFEAUMB/wM8AfMDJwE5EAAB - NAIzAVEBrAFbASUB9wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbgBXgEgAf8B+QHxAewB - /wH4Ae4B5wH/AckBgQFQAf8ByQGBAVAB/wHJAYEBUAH/AckBgQFQAf8B9AHlAdwB/wH7AfYB8wH/AcYB - eAFEAf8BuQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/Ac4BfwEwAfsB7gGkAUIB - /wHtAaMBQgH/AbwBcgEqAf8BjQFCARIB/wGOAUIBEgH/Ab8BdAErAf8B6AGeAT8B/wHbAZEBOQH/AaMB - VQEbAf8BjgE/ARAB/wGYAUoBFgH/AcwBggExAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B2wGZAUYB - 9gE1ATQBMwFR/wB5AANKAZQBOgI5Af8BwgGtAaQB/wHeAcUBuwH/AecBzQHCAf8B5wHNAcIB/wHnAc0B - wgH/AeoB1AHKAf8B7QHdAdMB/wHtAd0B0wH/AewB2wHRAf8BxQGzAaoB/wFDAUABPwH/AaABjgGHAf8B - 0AG3AawB/wHQAbcBrAH/AWoBYQFdAf8BSgFeAWUB/wGLAdYB8AH/AY8B3QH5Af8BjwHdAfkB/wGPAd0B - +QH/AY8B3QH5Af8BjwHdAfkB/wGLAdYB8QH/AUsBYAFoAf8BaAFgAVwB/wHPAbYBqwH/AagBlgGNAf8B - uAGjAZkB/wHdAckBvwH/AeoB1QHKAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B - wgH/AecBzQHCAf8B5wHNAcIB/wHgAccBvQH/AcYBsQGnAf8BOwI5Af8DSwGWEAABNAIzAVEBqwFbASUB - 9wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbcBWwEcAf8B5gHGAbEZ/wHvAdkBywH/Ab4B - ZwEtAf8BuAFaARsB/wG5AVoBGwH/AbkBWgEaAf8BuQFaARoB/wG2AV0BHAH+Ad4BlAE7AfwB7gGkAUIB - /wHuAaQBQgH/AekBnwE/Af8BxwF9AS8B/wGTAUcBFQH/AY0BQQESAf8BpwFbAR4B/wGZAUwBFgH/AY4B - QAERAf8BrwFhASEB/wHbAZEBOQH/AewBowFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B2wGZAUYB - 9gE1ATQBMwFR/wB5AANNAaIBPQE8ATsB/wHmAcwBwQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecB - zQHCAf8B5wHNAcIB/wHqAdQByQH/Ae0B3QHTAf8B7QHdAdMB/wG9AbEBqQH/ATcCNgH/AcQBrQGjAf8B - 0AG3AawB/wHQAbcBrAH/AUMBQAE/Af8BcAGlAbcB/wGPAd0B+QH/AY8B3QH5Af8BbAGcAa0B/wE6AUEB - RAH/AWoBmgGrAf8BjwHdAfkB/wGPAd0B+QH/AXIBpwG6Af8BQQE/AT4B/wHQAbcBrAH/AcwBswGpAf8B - xAGtAaMB/wHPAbsBsQH/AeoB2gHQAf8B6wHVAcoB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B - wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8BPQE8ATsB/wNNAaEQAAE0AjMBUQGrAVsB - JgH3AbYBWgEcAf8BtwFaARsB/wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wHUAZwBdgH/Af4B/QH8Af8B - 9gHqAeMB/wHjAcABqAH/AeQBwAGnAf8B8gHgAdQF/wHhAbgBnAH/AbgBWwEcAf8BuAFaARsB/wG4AVoB - GwH/AbkBWgEbAf8BuQFaARsB/wG/AW4BKAH6Ae8BowFCAf8B7wGjAUIB/wHuAaQBQgH/Ae4BpAFCAf8B - 7gGkAUIB/wHNAYMBMgH/AZABRAETAf8BjAFAAREB/wGNAT8BEAH/AbgBbAEmAf8B7AGiAUEB/wHuAaQB - QgH/Ae0BpAFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8B2wGZAUYB9gE1ATQBMwFR/wB5AANNAaIB - PQE8ATsB/wHmAcwBwQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B - wgH/AeoB1AHKAf8B7QHcAdIB/wG4AawBpQH/AzMB/wHOAbUBqgH/AdABtwGsAf8B0AG3AawB/wE4AjcB - /wF8AbkB0AH/AY8B3QH5Af8BjwHdAfkB/wE9AUYBSQH/AzMB/wE7AUMBRQH/AY8B3QH5Af8BjwHdAfkB - /wF8AbsB0QH/ATYCNQH/AdABtwGsAf8BnAGLAYMB/wE4AjcB/wFBAUABPwH/AccBugGyAf8B7QHcAdIB - /wHqAdUBygH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecB - zQHCAf8BPQE8ATsB/wNNAaEQAAE0AjMBUQGrAVsBJgH3AbYBWgEcAf8BtgFaARwB/wG3AVoBGwH/AbcB - WgEbAf8BtwFaARsB/wHFAXoBRwH/AfkB8gHtAf8B8QHeAdIB/wG9AWgBLwH/AboBYAEjAf8B6AHJAbQF - /wHMAYgBWwH/AbgBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BtgFdAR0B/gHZAY8BOQH7Ae8B - owFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BpAFCAf8B7gGkAUIB/wHOAYMBMgH/AZEBRQETAf8BjAFAAREB - /wGOAUABEQH/AcUBeQEtAf8B7QGjAUIB/wHuAaQBQgH/Ae4BpAFCAf8B7gGkAUIB/wHtAaQBQgH/Ae0B - pAFCAf8B2wGZAUYB9gE1ATQBMwFR/wB5AANNAaIBPQE8ATsB/wHmAcwBwQH/AecBzQHCAf8B5wHNAcIB - /wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B6gHUAcoB/wG9AbEBqgH/AjcB - NgH/AcMBrAGiAf8B0AG3AawB/wHQAbcBrAH/AUMBQQFAAf8BbwGjAbYB/wGPAd0B+QH/AY8B3QH5Af8B - bgGgAbEB/wE+AUgBSwH/AW0BngGvAf8BjwHdAfkB/wGPAd0B+QH/AXEBpgG4Af8BQgFAAT4B/wHQAbcB - rAH/AcwBtAGpAf8BxAGtAaMB/wHPAbsBsQH/AeoB2gHQAf8B7QHdAdMB/wHtAd0B0wH/AesB1QHKAf8B - 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8BPQE8ATsB/wNNAaEQ - AAE0AjMBUQGrAVsBJgH3AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtgFaARsB/wG4AV0B - HwH/AfEB3wHSAf8B+gHzAe8B/wHHAX8BTgH/Ab4BaQEwAf8B9gHrAeQB/wH7AfUB8gH/AboBXwEhAf8B - uAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wG+AWYBJgH9AekBnAFCAf4B7wGjAUIB/wHvAaMB - QgH/Ae8BowFCAf8B7wGjAUIB/wHpAZ0BPwH/AZcBSwEWAf8BjAFAAREB/wGsAWABIAH/AZEBQwESAf8B - lQFGARQB/wHWAYsBNgH/Ae4BpAFCAf8B7gGkAUIB/wHuAaQBQgH/Ae4BpAFCAf8B7QGkAUIB/wHbAZkB - RgH2ATUBNAEzAVH/AHkAA0oBkgE6AjkB/wHCAa0BpAH/Ad0BxQG6Af8B5wHNAcIB/wHnAc0BwgH/AecB - zQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHGAbQBqwH/AUQBQgFBAf8BngGNAYUB - /wHQAbcBrAH/AdABtwGsAf8BawFiAV4B/wFJAVwBZAH/AYsB1QHvAf8BjwHdAfkB/wGPAd0B+QH/AY8B - 3QH5Af8BjwHdAfkB/wGPAd0B+QH/AYsB1QHwAf8BSgFeAWUB/wFpAWEBXQH/Ac8BtgGrAf8BtgGhAZgB - /wHCAasBoQH/AeABzAHBAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHqAdUBygH/AecB - zgHDAf8B5wHNAcIB/wHnAc0BwgH/AdsBwwG5Af8BwQGsAaQB/wE6AjkB/wNLAZUQAAE0AjMBUQGrAVsB - JgH3AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBGwH/AdYBoAF8Bf8B - 1wGjAYAB/wHNAYwBXwP/Af4B/wHdAbABkwH/AbcBWgEbAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8B - uAFaARsB/wHMAXoBKwH8Ae4BogFBAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHRAYUB - MwH/AZsBUAEZAf8BuQFtASgB/wHrAaABQQH/AbgBbAEmAf8BjgE/ARAB/wGoAVsBHgH/AewBoQFBAf8B - 7gGkAUIB/wHuAaQBQgH/Ae4BpAFCAf8B7gGkAUIB/wHbAZkBRgH2ATUBNAEzAVH/AHkAAyMBMwM/Ae4B - RQFDAUEB/wFWAVEBTwH/AXgBbgFqAf8BqQGYAZEB/wHYAcABtgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B - wgH/AecBzQHCAf8B1wG/AbUB/wFYAVIBUAH/AWIBWwFXAf8BzwG3AawB/wHQAbcBrAH/AaQBkgGKAf8B - PgI8Af8BWQF4AYQB/wGKAdUB7wH/AY8B3QH5Af8BjwHdAfkB/wGPAd0B+QH/AYsB1QHwAf8BWQF6AYYB - /wE9AjwB/wGjAZEBigH/Ac0BtAGpAf8BVgFRAU4B/wFOAUoBSAH/AagBnQGWAf8B7QHdAdMB/wHtAd0B - 0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAdwB0gH/AdcBwwG6Af8BpQGVAY4B/wF1AWsBZwH/AVUBUAFOAf8B - RAFCAUEB/wI/AT4B8QMlATYQAAE0AjMBUQGrAVsBJgH3AbUBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYB - WgEcAf8BtgFaARwB/wG2AVoBHAH/AbwBZQErAf8B/AH4AfYB/wHuAdgByAH/AekBzQG6Af8B/QH6AfgB - /wG/AW0BNQH/AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbgBWgEbAf8BugFcARwB/wHWAYgBNQH8AfAB - owFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/AeMBlwE8Af8B6wGfAUAB - /wHvAaMBQgH/AekBngE/Af8BpQFXARwB/wGPAUABEQH/AcQBeAEsAf8B7gGkAUIB/wHuAaQBQgH/Ae4B - pAFCAf8B7gGkAUIB/wHcAZkBRgH2ATUBNAEzAVH/AH0AAwwBEAM8AWYDTgGwA0gB2QNAAeoCOgE5AfoB - cgFpAWUB/wHkAcoBvwH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AYUBeQF1Af8BPgE8ATsB/wGvAZsB - kgH/AdABtwGsAf8BzwG2AasB/wGFAXgBcgH/AT4BPQE8Af8BSQFcAWMB/wFvAaIBtQH/AXsBuQHPAf8B - bwGjAbUB/wFKAV0BZAH/AT4CPAH/AYQBdwFxAf8BzAG0AakB/wHOAbYBqwH/Aa0BmgGRAf8BZwFgAV0B - /wGgAZYBkQH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/AeoB2gHQAf8BcwFtAWoB/wE3AjYB+wNBAesD - SgHaA04BtAM9AWkDDgESFAABNAIzAVEBqwFaASYB9wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoB - HAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AegByQG1Af8B/gL9Af8B/gH9AfwB/wHuAdcByAH/AbgB - XQEfAf8BtwFaARsB/wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG6AWQBIQH+AegBnwFAAf0B8AGjAUIB - /wHwAaMBQgH/Ae8BowFCAf8BugFuASkB/wGmAVsBHwH/AacBWwEfAf8BpwFbAR8B/wGnAVsBHwH/AaUB - WAEdAf8BpwFZAR0B/wGgAVIBGQH/AY4BPwEQAf8BkAFBAREB/wGoAVsBHQH/Ac8BhAEyAf8B7gGkAUIB - /wHuAaQBQgH/AdwBmQFGAfYBNQE0ATMBUf8AiQADDwEUAyUBNwM9AWkDQwHpAa0BnAGUAf8B5wHNAcIB - /wHnAc0BwgH/AecBzQHCAf8B0wG8AbIB/wFIAUUBRAH/AWgBYAFcAf8BzgG1AaoB/wHQAbcBrAH/Ac8B - tgGrAf8BpQGTAYsB/wFrAWIBXgH/AUQBQgFAAf8COQE4Af8BRAFBAUAB/wFrAWIBXgH/AaQBkgGKAf8B - zQG0AaoB/wGNAX8BeAH/AYABcwFuAf8BzgG3Aa0B/wHoAdYBzAH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B - 0wH/Ae0B3QHTAf8BtAGpAaIB/wNBAesDPwFtAycBOgMRARYgAAE0AjMBUQGrAVoBJgH3AbUBWQEcAf8B - tQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8B0AGUAWwB/wH+Af0B - /AL/Av4B/wHbAa0BjgH/AbcBWwEcAf8BtwFaARsB/wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wHKAX0B - MQH6AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8BpgFbAR8B/wGLAUABEQH/AYsBQAERAf8B - iwFAAREB/wGMAUABEQH/AY0BQAERAf8BjwE/ARAB/wGNAT8BEAH/AY4BPwEQAf8BjgE/ARAB/wGPAT8B - EAH/AcQBeAEsAf8B7gGkAUIB/wHuAaQBQgH/AdwBmQFGAfYBNQE0ATMBUf8AkQADCAEKA04BrwFJAUYB - RAH/AeUBywHAAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8BuwGnAZ8B/wE5AjgB/wF0AWoBZQH/Ac4B - tQGqAf8B0AG3AawB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB - /wHQAbcBrAH/Ac8BtgGrAf8BhQF4AXMB/wM1Af8BkgGGAYEB/wHsAdsB0QH/Ae0B3QHTAf8B7QHdAdMB - /wHtAd0B0wH/AesB2wHRAf8BSwFJAUgB/wNOAbMDCQEMKAABNAIzAVEBqwFaASYB9wG1AVkBHAH/AbUB + pAFCAf8B7QGkAUIB/wHKAZMBSAH2AzMBUf8AeQADJgE4A0IB8wFGAUMBQgH/AVcBUgFPAf8BeQFvAWoB + /wGqAZkBkgH/AdoBxgG9Af8B7QHcAdIB/wHtAd0B0wH/AewB2wHRAf8B6AHQAcYB/wHWAb4BtAH/AVcB + UQFPAf8BZAFcAVgB/wHQAbcBrAH/AdABtwGsAf8BowGRAYkB/wE9AjwB/wFaAXsBiAH/AYsB1gHwAf8B + jwHdAfkB/wGPAd0B+QH/AY8B3QH5Af8BiwHWAfEB/wFbAXwBiQH/AT0CPAH/AaIBkAGJAf8BzAG0AakB + /wFNAUkBRwH/AUcBRAFCAf8BiwF/AXoB/wHmAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecB + zQHCAf8B3QHEAboB/wGvAZ0BlgH/AX4BcwFvAf8BWQFUAVEB/wFHAUQBQwH/A0IB8wMnATkQAAMzAVEB + pgFbAS4B9wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbgBXgEgAf8B+QHxAewB/wH4Ae4B + 5wH/AckBgQFQAf8ByQGBAVAB/wHJAYEBUAH/AckBgQFQAf8B9AHlAdwB/wH7AfYB8wH/AcYBeAFEAf8B + uQFaARoB/wG5AVoBGgH/AbkBWgEaAf8BuQFaARoB/wG5AVoBGgH/AcgBewEwAfsB7gGkAUIB/wHtAaMB + QgH/AbwBcgEqAf8BjQFCARIB/wGOAUIBEgH/Ab8BdAErAf8B6AGeAT8B/wHbAZEBOQH/AaMBVQEbAf8B + jgE/ARAB/wGYAUoBFgH/AcwBggExAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8BygGTAUgB9gMzAVH/ + AHkAA04BlAE6AjkB/wHCAa0BpAH/Ad4BxQG7Af8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B6gHUAcoB + /wHtAd0B0wH/Ae0B3QHTAf8B7AHbAdEB/wHFAbMBqgH/AUMBQAE/Af8BoAGOAYcB/wHQAbcBrAH/AdAB + twGsAf8BagFhAV0B/wFKAV4BZQH/AYsB1gHwAf8BjwHdAfkB/wGPAd0B+QH/AY8B3QH5Af8BjwHdAfkB + /wGPAd0B+QH/AYsB1gHxAf8BSwFgAWgB/wFoAWABXAH/Ac8BtgGrAf8BqAGWAY0B/wG4AaMBmQH/Ad0B + yQG/Af8B6gHVAcoB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB + /wHnAc0BwgH/AeABxwG9Af8BxgGxAacB/wE7AjkB/wNOAZYQAAMzAVEBpQFbAS4B9wG3AVoBGwH/AbcB + WgEbAf8BtwFaARsB/wG3AVoBGwH/AbcBWwEcAf8B5gHGAbEZ/wHvAdkBywH/Ab4BZwEtAf8BuAFaARsB + /wG5AVoBGwH/AbkBWgEaAf8BuQFaARoB/wGyAV8BHgH+AdQBjgE5AfwB7gGkAUIB/wHuAaQBQgH/AekB + nwE/Af8BxwF9AS8B/wGTAUcBFQH/AY0BQQESAf8BpwFbAR4B/wGZAUwBFgH/AY4BQAERAf8BrwFhASEB + /wHbAZEBOQH/AewBowFCAf8B7QGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8BygGTAUgB9gMzAVH/AHkAA1EB + ogE9ATwBOwH/AeYBzAHBAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeoB + 1AHJAf8B7QHdAdMB/wHtAd0B0wH/Ab0BsQGpAf8BNwI2Af8BxAGtAaMB/wHQAbcBrAH/AdABtwGsAf8B + QwFAAT8B/wFwAaUBtwH/AY8B3QH5Af8BjwHdAfkB/wFsAZwBrQH/AToBQQFEAf8BagGaAasB/wGPAd0B + +QH/AY8B3QH5Af8BcgGnAboB/wFBAT8BPgH/AdABtwGsAf8BzAGzAakB/wHEAa0BowH/Ac8BuwGxAf8B + 6gHaAdAB/wHrAdUBygH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wE9ATwBOwH/A1EBoRAAAzMBUQGlAVsBLwH3AbYBWgEcAf8BtwFaARsB + /wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wHUAZwBdgH/Af4B/QH8Af8B9gHqAeMB/wHjAcABqAH/AeQB + wAGnAf8B8gHgAdQF/wHhAbgBnAH/AbgBWwEcAf8BuAFaARsB/wG4AVoBGwH/AbkBWgEbAf8BuQFaARsB + /wG1AW4BKgH6Ae8BowFCAf8B7wGjAUIB/wHuAaQBQgH/Ae4BpAFCAf8B7gGkAUIB/wHNAYMBMgH/AZAB + RAETAf8BjAFAAREB/wGNAT8BEAH/AbgBbAEmAf8B7AGiAUEB/wHuAaQBQgH/Ae0BpAFCAf8B7QGkAUIB + /wHtAaQBQgH/Ae0BpAFCAf8BygGTAUgB9gMzAVH/AHkAA1EBogE9ATwBOwH/AeYBzAHBAf8B5wHNAcIB + /wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B6gHUAcoB/wHtAdwB0gH/AbgB + rAGlAf8DMwH/Ac4BtQGqAf8B0AG3AawB/wHQAbcBrAH/ATgCNwH/AXwBuQHQAf8BjwHdAfkB/wGPAd0B + +QH/AT0BRgFJAf8DMwH/ATsBQwFFAf8BjwHdAfkB/wGPAd0B+QH/AXwBuwHRAf8BNgI1Af8B0AG3AawB + /wGcAYsBgwH/ATgCNwH/AUEBQAE/Af8BxwG6AbIB/wHtAdwB0gH/AeoB1QHKAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wE9ATwBOwH/A1EBoRAAAzMB + UQGlAVsBLwH3AbYBWgEcAf8BtgFaARwB/wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wHFAXoBRwH/AfkB + 8gHtAf8B8QHeAdIB/wG9AWgBLwH/AboBYAEjAf8B6AHJAbQF/wHMAYgBWwH/AbgBWgEbAf8BuAFaARsB + /wG4AVoBGwH/AbgBWgEbAf8BsgFfAR8B/gHTAY0BOQH7Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8B + pAFCAf8B7gGkAUIB/wHOAYMBMgH/AZEBRQETAf8BjAFAAREB/wGOAUABEQH/AcUBeQEtAf8B7QGjAUIB + /wHuAaQBQgH/Ae4BpAFCAf8B7gGkAUIB/wHtAaQBQgH/Ae0BpAFCAf8BygGTAUgB9gMzAVH/AHkAA1EB + ogE9ATwBOwH/AeYBzAHBAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecB + zQHCAf8B5wHNAcIB/wHqAdQBygH/Ab0BsQGqAf8CNwE2Af8BwwGsAaIB/wHQAbcBrAH/AdABtwGsAf8B + QwFBAUAB/wFvAaMBtgH/AY8B3QH5Af8BjwHdAfkB/wFuAaABsQH/AT4BSAFLAf8BbQGeAa8B/wGPAd0B + +QH/AY8B3QH5Af8BcQGmAbgB/wFCAUABPgH/AdABtwGsAf8BzAG0AakB/wHEAa0BowH/Ac8BuwGxAf8B + 6gHaAdAB/wHtAd0B0wH/Ae0B3QHTAf8B6wHVAcoB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wE9ATwBOwH/A1EBoRAAAzMBUQGlAVsBLwH3AbYBWgEcAf8BtgFaARwB + /wG2AVoBHAH/AbYBWgEcAf8BtgFaARsB/wG4AV0BHwH/AfEB3wHSAf8B+gHzAe8B/wHHAX8BTgH/Ab4B + aQEwAf8B9gHrAeQB/wH7AfUB8gH/AboBXwEhAf8BuAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB + /wG+AWQBKgH9AeUBmAFEAf4B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHpAZ0BPwH/AZcB + SwEWAf8BjAFAAREB/wGsAWABIAH/AZEBQwESAf8BlQFGARQB/wHWAYsBNgH/Ae4BpAFCAf8B7gGkAUIB + /wHuAaQBQgH/Ae4BpAFCAf8B7QGkAUIB/wHKAZMBSAH2AzMBUf8AeQADTQGSAToCOQH/AcIBrQGkAf8B + 3QHFAboB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AcYBtAGrAf8BRAFCAUEB/wGeAY0BhQH/AdABtwGsAf8B0AG3AawB/wFrAWIBXgH/AUkBXAFkAf8B + iwHVAe8B/wGPAd0B+QH/AY8B3QH5Af8BjwHdAfkB/wGPAd0B+QH/AY8B3QH5Af8BiwHVAfAB/wFKAV4B + ZQH/AWkBYQFdAf8BzwG2AasB/wG2AaEBmAH/AcIBqwGhAf8B4AHMAcEB/wHtAd0B0wH/Ae0B3QHTAf8B + 7QHdAdMB/wHtAd0B0wH/AeoB1QHKAf8B5wHOAcMB/wHnAc0BwgH/AecBzQHCAf8B2wHDAbkB/wHBAawB + pAH/AToCOQH/A04BlRAAAzMBUQGlAVsBLwH3AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8B + tgFaARwB/wG2AVoBGwH/AdYBoAF8Bf8B1wGjAYAB/wHNAYwBXwP/Af4B/wHdAbABkwH/AbcBWgEbAf8B + uAFaARsB/wG4AVoBGwH/AbgBWgEbAf8BuAFaARsB/wHIAXoBKwH8Ae4BogFBAf8B7wGjAUIB/wHvAaMB + QgH/Ae8BowFCAf8B7wGjAUIB/wHRAYUBMwH/AZsBUAEZAf8BuQFtASgB/wHrAaABQQH/AbgBbAEmAf8B + jgE/ARAB/wGoAVsBHgH/AewBoQFBAf8B7gGkAUIB/wHuAaQBQgH/Ae4BpAFCAf8B7gGkAUIB/wHKAZMB + SAH2AzMBUf8AeQADIwEzA0gB7gFFAUMBQQH/AVYBUQFPAf8BeAFuAWoB/wGpAZgBkQH/AdgBwAG2Af8B + 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHXAb8BtQH/AVgBUgFQAf8BYgFbAVcB/wHPAbcB + rAH/AdABtwGsAf8BpAGSAYoB/wE+AjwB/wFZAXgBhAH/AYoB1QHvAf8BjwHdAfkB/wGPAd0B+QH/AY8B + 3QH5Af8BiwHVAfAB/wFZAXoBhgH/AT0CPAH/AaMBkQGKAf8BzQG0AakB/wFWAVEBTgH/AU4BSgFIAf8B + qAGdAZYB/wHtAd0B0wH/Ae0B3QHTAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3AHSAf8B1wHDAboB/wGlAZUB + jgH/AXUBawFnAf8BVQFQAU4B/wFEAUIBQQH/AkcBRgHxAyUBNhAAAzMBUQGlAVsBLwH3AbUBWgEcAf8B + tgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbwBZQErAf8B/AH4AfYB/wHuAdgB + yAH/AekBzQG6Af8B/QH6AfgB/wG/AW0BNQH/AbcBWgEbAf8BtwFaARsB/wG3AVoBGwH/AbgBWgEbAf8B + ugFcARwB/wHQAYIBMwH8AfABowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMB + QgH/AeMBlwE8Af8B6wGfAUAB/wHvAaMBQgH/AekBngE/Af8BpQFXARwB/wGPAUABEQH/AcQBeAEsAf8B + 7gGkAUIB/wHuAaQBQgH/Ae4BpAFCAf8B7gGkAUIB/wHLAZMBSAH2AzMBUf8AfQADDAEQAzwBZgNUAbAD + UwHZA0kB6gI+AT0B+gFyAWkBZQH/AeQBygG/Af8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8BhQF5AXUB + /wE+ATwBOwH/Aa8BmwGSAf8B0AG3AawB/wHPAbYBqwH/AYUBeAFyAf8BPgE9ATwB/wFJAVwBYwH/AW8B + ogG1Af8BewG5Ac8B/wFvAaMBtQH/AUoBXQFkAf8BPgI8Af8BhAF3AXEB/wHMAbQBqQH/Ac4BtgGrAf8B + rQGaAZEB/wFnAWABXQH/AaABlgGRAf8B7QHdAdMB/wHtAd0B0wH/Ae0B3QHTAf8B6gHaAdAB/wFzAW0B + agH/ATcCNgH7A0wB6wNVAdoDVQG0Az0BaQMOARIUAAMzAVEBpQFaAS8B9wG1AVoBHAH/AbUBWgEcAf8B + tgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AegByQG1Af8B/gL9Af8B/gH9AfwB + /wHuAdcByAH/AbgBXQEfAf8BtwFaARsB/wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG2AWYBIwH+AeIB + nwFAAf0B8AGjAUIB/wHwAaMBQgH/Ae8BowFCAf8BugFuASkB/wGmAVsBHwH/AacBWwEfAf8BpwFbAR8B + /wGnAVsBHwH/AaUBWAEdAf8BpwFZAR0B/wGgAVIBGQH/AY4BPwEQAf8BkAFBAREB/wGoAVsBHQH/Ac8B + hAEyAf8B7gGkAUIB/wHuAaQBQgH/AcsBkwFIAfYDMwFR/wCJAAMPARQDJQE3Az0BaQNMAekBrQGcAZQB + /wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHTAbwBsgH/AUgBRQFEAf8BaAFgAVwB/wHOAbUBqgH/AdAB + twGsAf8BzwG2AasB/wGlAZMBiwH/AWsBYgFeAf8BRAFCAUAB/wI5ATgB/wFEAUEBQAH/AWsBYgFeAf8B + pAGSAYoB/wHNAbQBqgH/AY0BfwF4Af8BgAFzAW4B/wHOAbcBrQH/AegB1gHMAf8B7QHdAdMB/wHtAd0B + 0wH/Ae0B3QHTAf8B7QHdAdMB/wG0AakBogH/A0wB6wM/AW0DJwE6AxEBFiAAAzMBUQGlAVoBLwH3AbUB + WQEcAf8BtQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8B0AGUAWwB + /wH+Af0B/AL/Av4B/wHbAa0BjgH/AbcBWwEcAf8BtwFaARsB/wG3AVoBGwH/AbcBWgEbAf8BtwFaARsB + /wHAAX0BMwH6AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8BpgFbAR8B/wGLAUABEQH/AYsB + QAERAf8BiwFAAREB/wGMAUABEQH/AY0BQAERAf8BjwE/ARAB/wGNAT8BEAH/AY4BPwEQAf8BjgE/ARAB + /wGPAT8BEAH/AcQBeAEsAf8B7gGkAUIB/wHuAaQBQgH/AcsBkwFIAfYDMwFR/wCRAAMIAQoDVAGvAUkB + RgFEAf8B5QHLAcAB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wG7AacBnwH/ATkCOAH/AXQBagFlAf8B + zgG1AaoB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB/wHQAbcB + rAH/AdABtwGsAf8BzwG2AasB/wGFAXgBcwH/AzUB/wGSAYYBgQH/AewB2wHRAf8B7QHdAdMB/wHtAd0B + 0wH/Ae0B3QHTAf8B6wHbAdEB/wFLAUkBSAH/A1UBswMJAQwoAAMzAVEBpQFaAS8B9wG1AVkBHAH/AbUB WQEcAf8BtQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoBHAH/AcIBdQFCAf8B9QHoAeAB - /wH6AfQB7wH/AcoBhwFaAf8BtgFaARwB/wG2AVoBGwH/AbcBWgEbAf8BtwFaARsB/wG1AV0BHgH+AeEB - nAFBAfsB8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B7wGjAUIB + /wH6AfQB7wH/AcoBhwFaAf8BtgFaARwB/wG2AVoBGwH/AbcBWgEbAf8BtwFaARsB/wGxAV8BIAH+AdkB + mgFDAfsB8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B7wGjAUIB /wHvAaMBQgH/Ae8BowFCAf8BjQFAAREB/wGmAVgBHAH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8B - owFCAf8B7wGkAUIB/wHuAaQBQgH/Ae4BpAFCAf8B3AGZAUYB9gE1ATQBMwFR/wCRAAMDAQQDSgGUAzYB - /wHWAb4BtAH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeQBygG/Af8BmwGMAYUB/wE6AjkB/wFoAWAB - XAH/Aa8BmwGSAf8BzwG2AawB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB/wHQAbcBrAH/AdABtwGsAf8B - 0AG3AawB/wHQAbcBrAH/AdABuQGuAf8BmQGMAYYB/wGyAaABmAH/AegB0AHFAf8B7AHbAdEB/wHxAeUB - 4QH/Ae0B3QHUAf8B3QHOAcUB/wM3Af8DSwGXAwMBBCgAATQCMwFRAasBWgEmAfcBtQFZARwB/wG1AVkB - HAH/AbUBWQEcAf8BtQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtQFaARwB/wG3AV0BIQH/AcEBcwE+Af8B - wwF2AUIB/wG4AV8BIwH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbcBWgEbAf8BwwFuASgB+wHwAaMB - QgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B - 8AGjAUIB/wHvAaMBQgH/AZsBTwEZAf8BsQFjASIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMB - QgH/Ae8BowFCAf8B7wGjAUIB/wHuAaQBQgH/AdwBmQFGAfYBNQE0ATMBUf8AkQADGAEgA0QB4gF/AXQB - bwH/AeYBzAHBAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHkAcoBvwH/Ab4BqQGhAf8B - SgFHAUUB/wE+ATwBOwH/AWIBWgFXAf8BpgGUAYwB/wHQAbcBrAH/AdABtwGsAf8BxQGuAaQB/wGeAY0B - hgH/AZMBhAF9Af8B2QHDAbgB/wHoAdYBzAH/AewB3AHRAf8B6QHRAcYB/wHnAc0BwgH/AewB2AHSAf8B - 9wH0AfkB/wHyAegB5AH/AewB3AHSAf8BhgF+AXoB/wNEAeMDGAEhKAABNAIzAVEBqwFaASYB9wG0AVkB - HAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWgEcAf8B - tgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtAFdAR4B/gHTAYQB - MwH8AfEBowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B - 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B6AGbAT4B/wHpAZ0BPwH/Ae8BowFCAf8B7wGjAUIB/wHvAaMB - QgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B3QGYAUYB9gE1ATQBMwFR/wCNAAMDAQQD - TQGiAVEBTAFKAf8B4QHIAb4B/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B - 5wHNAcIB/wHnAc0BwgH/AdUBvgG0Af8BiwF+AXgB/wFaAVUBUgH/AV8BWgFXAf8B2wHGAbsB/wHRAbwB - sgH/AU8BTAFKAf8BRgFDAUIB/wFiAVsBWAH/AewB2wHRAf8B7QHdAdMB/wHtAd0B0wH/AewB2wHQAf8B - 6QHRAcYB/wHnAc0BwgH/AewB2gHUAf8B7AHbAdEB/wHtAd0B0wH/AekB2QHQAf8BVAFSAVAB/wNNAaQD - BAEFJAABNAIzAVEBqwFaAScB9wG0AVkBHAH/AbQBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8B - tQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFaARwB/wG1AVoBHAH/AbYBWgEcAf8BtgFaARwB/wG2AVoB - HAH/AbYBWgEcAf8BugFlASMB/gHiAZcBQAH9AfEBowFCAf8B8QGjAUIB/wHwAaMBQgH/AfABowFCAf8B + owFCAf8B7wGkAUIB/wHuAaQBQgH/Ae4BpAFCAf8BywGTAUgB9gMzAVH/AJEAAwMBBANOAZQDNgH/AdYB + vgG0Af8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5AHKAb8B/wGbAYwBhQH/AToCOQH/AWgBYAFcAf8B + rwGbAZIB/wHPAbYBrAH/AdABtwGsAf8B0AG3AawB/wHQAbcBrAH/AdABtwGsAf8B0AG3AawB/wHQAbcB + rAH/AdABtwGsAf8B0AG5Aa4B/wGZAYwBhgH/AbIBoAGYAf8B6AHQAcUB/wHsAdsB0QH/AfEB5QHhAf8B + 7QHdAdQB/wHdAc4BxQH/AzcB/wNOAZcDAwEEKAADMwFRAaUBWgEvAfcBtQFZARwB/wG1AVkBHAH/AbUB + WQEcAf8BtQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtQFaARwB/wG3AV0BIQH/AcEBcwE+Af8BwwF2AUIB + /wG4AV8BIwH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbcBWgEbAf8BvQFqASgB+wHwAaMBQgH/AfAB + owFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB + /wHvAaMBQgH/AZsBTwEZAf8BsQFjASIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8B + owFCAf8B7wGjAUIB/wHuAaQBQgH/AcsBkwFIAfYDMwFR/wCRAAMYASADUAHiAX8BdAFvAf8B5gHMAcEB + /wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeQBygG/Af8BvgGpAaEB/wFKAUcBRQH/AT4B + PAE7Af8BYgFaAVcB/wGmAZQBjAH/AdABtwGsAf8B0AG3AawB/wHFAa4BpAH/AZ4BjQGGAf8BkwGEAX0B + /wHZAcMBuAH/AegB1gHMAf8B7AHcAdEB/wHpAdEBxgH/AecBzQHCAf8B7AHYAdIB/wH3AfQB+QH/AfIB + 6AHkAf8B7AHcAdIB/wGGAX4BegH/A1AB4wMYASEoAAMzAVEBpQFaAS8B9wG0AVkBHAH/AbUBWQEcAf8B + tQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoB + HAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BsAFfASAB/gHPAX4BMQH8AfEBowFCAf8B 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMB - QgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B - 3QGYAUYB9gE1ATQBMwFR/wCNAAM1AVYBOgI5AfsBoQGRAYsB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB - /wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AdkB - wgG3Af8B1gHCAbkB/wHtAd0B0wH/AesB3AHSAf8ByQG9AbQB/wHJAbYBrQH/AdoBwgG4Af8B6AHRAcYB - /wHsAdsB0AH/Ae0B3QHTAf8B7QHdAdMB/wHtAdsB0QH/AekB0gHHAf8B5wHNAcIB/wHoAdABxQH/AewB - 2gHQAf8B7QHdAdMB/wGpAZ4BmAH/ATsCOgH7AzYBWCQAATQCMwFRAasBWgEnAfcBtAFZAR0B/wG0AVkB - HQH/AbQBWQEcAf8BtAFZARwB/wG0AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8B - tQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wG2AVoBHAH/AcMBcAEqAfwB8AGiAUEB/wHxAaMB - QgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B - 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B7wGjAUIB/wHvAaMB - QgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ad0BmAFGAfYBNQE0ATMBUf8AiQADEQEWA0wBzgFaAVUB - UgH/Ad0BxQG6Af8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B - 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B6gHUAcoB/wHtAd4B - 1AH/Ae0B3QHTAf8B7AHbAdEB/wHoAdABxQH/AecBzQHCAf8B6QHRAcYB/wHtAdwB0gH/Ae0B3QHTAf8B - 7QHdAdMB/wHsAdsB0QH/AekB0QHGAf8B5wHNAcIB/wHoAdEBxgH/Ae0B3AHSAf8B5QHWAcwB/wFgAVwB - WQH/A0wB0AMSARcgAAE0AjMBUQGrAVoBJwH3AbQBWQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEcAf8B - tAFZARwB/wG0AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVoB - HAH/AbUBWgEcAf8BtgFaARwB/wHYAYkBNwH7AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B - 8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMB - QgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B - 7wGjAUIB/wHdAZgBRgH2ATUBNAEzAVH/AIkAAygBPANAAe0BrgGcAZUB/wHnAc0BwgH/AecBzQHCAf8B - 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHmAcwBwQH/AdUBvQGzAf8B5AHKAcAB/wHnAc0B - wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzgHDAf8B8QHmAeQB/wHwAeQB3gH/Ae0B3QHTAf8B - 7AHbAdAB/wHpAdEBxgH/AecBzQHCAf8B5wHPAcQB/wHbAcsBwgH/AewB3AHSAf8B7QHdAdMB/wHsAdsB - 0AH/AekB0QHGAf8B5wHNAcIB/wHoAdABxQH/AewB2gHQAf8BugGuAaYB/wM9Ae8DKQE+IAABNAIzAVEB - qgFaAScB9wG0AVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEdAf8BtAFZARwB/wG0AVkB - HAH/AbQBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbgBYgEkAfwB - 7AGdAUMB/gHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMB - QgH/AfEBowFCAf8B8QGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B - 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B3QGYAUYB9gE1ATQB - MwFR/wCJAAMgAS4DRAHiAWkBYgFeAf8B4QHIAb0B/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B - wgH/AeEByAG9Af8BfgFzAW4B/wM2Af8BRwFEAUMB/wGrAZoBkwH/AeMBygG/Af8B5wHNAcIB/wHnAc0B - wgH/Ae4B3gHZAf8B9wH2AfwB/wH3AfYB+wH/AfAB4wHdAf8B7QHdAdMB/wHqAdkBzwH/AbEBoQGaAf8B - SwFIAUYB/wE3AjYB/wF+AXcBcwH/AeYB1wHNAf8B7QHdAdMB/wHtAdwB0gH/AekB0QHGAf8B5wHNAcIB - /wHjAcsBwQH/AW0BZwFjAf8DRQHkAyEBMCAAATQCMwFRAakBWwEnAfYBswFZAR0B/wGzAVkBHQH/AbQB - WQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHAH/AbQBWQEcAf8BtQFZARwB - /wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wHNAXsBLwH7AfIBowFCAf8B8gGjAUIB/wHxAaMBQgH/AfEB - owFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB + QgH/AfABowFCAf8B6AGbAT4B/wHpAZ0BPwH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B + 7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8BzAGSAUgB9gMzAVH/AI0AAwMBBANRAaIBUQFMAUoB/wHhAcgB + vgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B + 1QG+AbQB/wGLAX4BeAH/AVoBVQFSAf8BXwFaAVcB/wHbAcYBuwH/AdEBvAGyAf8BTwFMAUoB/wFGAUMB + QgH/AWIBWwFYAf8B7AHbAdEB/wHtAd0B0wH/Ae0B3QHTAf8B7AHbAdAB/wHpAdEBxgH/AecBzQHCAf8B + 7AHaAdQB/wHsAdsB0QH/Ae0B3QHTAf8B6QHZAdAB/wFUAVIBUAH/A1EBpAMEAQUkAAMzAVEBpQFaATAB + 9wG0AVkBHAH/AbQBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUB + WQEcAf8BtQFaARwB/wG1AVoBHAH/AbYBWgEcAf8BtgFaARwB/wG2AVoBHAH/AbYBWgEcAf8BtgFnASUB + /gHcAZcBQAH9AfEBowFCAf8B8QGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfAB + owFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/Ae8BowFCAf8B7wGjAUIB + /wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8BzAGSAUgB9gMzAVH/AI0AAzUB + VgE6AjkB+wGhAZEBiwH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B2QHCAbcB/wHWAcIBuQH/Ae0B3QHTAf8B + 6wHcAdIB/wHJAb0BtAH/AckBtgGtAf8B2gHCAbgB/wHoAdEBxgH/AewB2wHQAf8B7QHdAdMB/wHtAd0B + 0wH/Ae0B2wHRAf8B6QHSAccB/wHnAc0BwgH/AegB0AHFAf8B7AHaAdAB/wHtAd0B0wH/AakBngGYAf8B + OwI6AfsDNgFYJAADMwFRAaUBWgEwAfcBtAFZAR0B/wG0AVkBHQH/AbQBWQEcAf8BtAFZARwB/wG0AVkB + HAH/AbUBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVoBHAH/AbUBWgEcAf8B + tgFaARwB/wG2AVoBHAH/Ab8BcAErAfwB8AGiAUEB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMB + QgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B + 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B7wGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHvAaMB + QgH/AcwBkgFIAfYDMwFR/wCJAAMRARYDVgHOAVoBVQFSAf8B3QHFAboB/wHnAc0BwgH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHqAdQBygH/Ae0B3gHUAf8B7QHdAdMB/wHsAdsB0QH/AegB0AHFAf8B + 5wHNAcIB/wHpAdEBxgH/Ae0B3AHSAf8B7QHdAdMB/wHtAd0B0wH/AewB2wHRAf8B6QHRAcYB/wHnAc0B + wgH/AegB0QHGAf8B7QHcAdIB/wHlAdYBzAH/AWABXAFZAf8DVgHQAxIBFyAAAzMBUQGlAVoBMAH3AbQB + WQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEcAf8BtAFZARwB/wG0AVkBHAH/AbUBWQEcAf8BtQFZARwB + /wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wG1AVoBHAH/AbUBWgEcAf8BtgFaARwB/wHSAYcBNwH7AfEB + owFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8AGjAUIB /wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfAB - owFCAf8B8AGjAUIB/wHvAaMBQgH/Ad0BmAFGAfYBNQE0ATMBUf8AiQADAgEDAzsBZANAAe8BewFxAW0B - /wHhAcgBvQH/AecBzQHCAf8B3gHFAbsB/wGiAZIBiwH/AVEBTAFLAf8DRgHgA0oBkwNOAbADQwHpAW8B - ZgFiAf8B5wHNAcIB/wHqAdYBzwH/AfMB7AHuAf8B+AH3Af4B/wH3AfYB/QH/AfIB6QHoAf8B7gHeAdYB - /wF8AXUBcQH/A0EB6gNOAbADSgGSA0UB3wFQAU0BTAH/AaMBmQGTAf8B4QHSAckB/wHsAdsB0AH/AeMB - zAHBAf8BfQFyAW0B/wNBAfEDPQFoAwMBBCAAAx0BKAGQAV0BOwHdAbMBWQEdAf8BswFZAR0B/wGzAVkB - HQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHAH/AbQBWQEcAf8B - tAFZARwB/wG1AVkBHAH/AbYBYAEgAf4B4gGVAT8B/QHyAaMBQgH/AfIBowFCAf8B8gGjAUIB/wHxAaMB - QgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B - 8QGjAUIB/wHxAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMB - QgH/AfABowFCAf8B8AGjAUIB/wGzAYYBTwHdAx0BKP8AjQAEAgMyAU8DQAHvAWkBYgFeAf8BsQGeAZYB - /wFbAVUBUwH/AT0CPAH6A0wBngMYASADAwEEAwkBCwM/AWwDNgH7AdQBvQGzAf8B5wHNAcIB/wHoAdAB - xwH/AfMB6wHtAf8B7wHhAd8B/wHoAc8BxQH/AeABzAHCAf8DNwH8Az8BbgMJAQsDAwEEAxYBHgNMAZoD - PgH5AVkBVgFUAf8BsAGlAZ4B/wFsAWcBYwH/A0AB8AMzAVIDAgEDJAAEAQMaASQBQAE+ATwBaAFFAUIB - PwFxAUUBQgE/AXEBRQFCAT8BcQFFAUIBPwFxAUUBQgE/AXEBRQFCAT8BcQFFAUIBPwFxAUUBQgE/AXEB - RQFCAT8BcQFFAUIBPwFxAUUBQgE/AXEBRQFCAT8BcAFHAUQBQAFxAUcBRAFBAXEBRwFEAUEBcQFHAUQB - QQFxAUcBRAFBAXEBRwFEAUEBcQFHAUQBQQFxAUcBRAFBAXEBRwFEAUEBcQFHAUQBQQFxAUcBRAFBAXEB - RwFEAUEBcQFHAUQBQQFxAUcBRAFBAXEBRwFEAUEBcQFHAUQBQQFxAUcBRAFBAXEBRwFEAUEBcQFHAUQB - QQFxAUcBRAFBAXEBRwFEAUEBcQFCAUABPQFoAxoBJAQB/wCRAAQCAzsBZANEAeIDQAHtA0sBzQM0AVQD - AwEEDAADJwE6A0EB6wGlAZQBjgH/AecBzQHCAf8B5wHNAcIB/wHqAdYBzgH/AegBzgHEAf8B5wHNAcIB - /wGxAZ8BlwH/A0EB7AMpAT0MAAMCAQMDMwFRA0wBywNAAe0DRAHjAz0BZwMCAQP/AP8AWgADAgEDAyAB - LQMoATsDEAEVFAADEgEXA0oB2gF0AWsBZwH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B - 5wHNAcIB/wGAAXUBcAH/A0kB2wMTARkUAAMPARQDKAE7AyABLgMCAQP/AP8AhgADTgGzAVUBUAFOAf8B - 3AHDAbkB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHhAcgBvQH/AVoBVAFSAf8DTgG6/wD/AK4AAz0B - aQFEAUIBQQH/AcABqwGjAf8B5QHMAcEB/wHlAcwBwQH/AeUBzAHBAf8BxQGwAacB/wFIAUUBQwH/A0AB - cf8A/wCuAAMNARECPgE9AfABOgI5Af8BPQI7Af8BPQI7Af8BPQI7Af8BOgI5Af8DPAHzAxEBFv8A/wCy - AAMkATQDSgGSA00BogNNAaIDTQGiA0oBkwMlATf/AP8A/wD/AP8APQABQgFNAT4HAAE+AwABKAMAAbQD - AAEtAwABAQEAAQEFAAE4AQQWAAP/AQAH/wHHA/8BwAwAAv8B4AE/A/8BhwP/AcAMAAL/AcABHwP/AYMD - /wHADAAC/wHAAR8D/wGAA/8BwAwAAv8BwAEPA/8BgAP/AcAMAAH/AQ8BgAEPAYcC/wGAAT8C/wHADAAB - /gEDAYABDgEDAv8BgAE/Av8BwAwAAfwDAAEBAv8BgAEfAv8BwAwAAfgEAAL/AYABDwL/AcAMAAH4BAAB - /wGAAwABAwHADAAB+AQAAf8EAAEBAcAMAAH4BAAB/wQAAQEBwAwAAfwDAAEBAf8EAAEBAcAMAAH8AwAB - AQH/BAABAQHADAAB/gMAAQMB/wQAAQEBwAwAAf4DAAEDAf8EAAEBAcAMAAH+AwABAwH/BAABAQHADAAB - +AQAAf8EAAEBAcAMAAHABAABHwQAAQEBwAwAAYAEAAEPBAABAQHADAABgAQAAQ8EAAEBAcAMAAGABAAB - DwQAAQEBwAwAAYAEAAEPBAABAQHADAABgAQAAQ8EAAEBAcAMAAGABAABDwQAAQEBwAwAAYAEAAEPBAAB - AQHADAABwAQAAR8EAAEBAcAMAAH4BAAB/wQAAQEBwAwAAf4DAAEDAf8EAAEBAcAMAAH+AwABAwH/BAAB - AQHADAAB/gMAAQMB/wQAAQEBwAwAAfwDAAEBAf8EAAEBAcAMAAH8AwABAQH/BAABAQHADAAB+AQAAf8E - AAEBAcAMAAH4BAAB/wQAAQEBwAwAAfgEAAH/BAABAQHADAAB+AQAAf8EAAEBAcAMAAH8AwABAQH/BAAB - AQHADAAB/gEDAYABDgEDBv8BwAwAAf8BDwGAAQ8Bhwb/AcAMAAL/AcABHwf/AcAMAAL/AcABHwf/AcAM - AAL/AcABHwf/AcAMAAL/AeABPwf/AcAMAAv/AcAMAAs= + owFCAf8B8AGjAUIB/wHvAaMBQgH/Ae8BowFCAf8B7wGjAUIB/wHMAZIBSAH2AzMBUf8AiQADKAE8A0gB + 7QGuAZwBlQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeYB + zAHBAf8B1QG9AbMB/wHkAcoBwAH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B5wHOAcMB + /wHxAeYB5AH/AfAB5AHeAf8B7QHdAdMB/wHsAdsB0AH/AekB0QHGAf8B5wHNAcIB/wHnAc8BxAH/AdsB + ywHCAf8B7AHcAdIB/wHtAd0B0wH/AewB2wHQAf8B6QHRAcYB/wHnAc0BwgH/AegB0AHFAf8B7AHaAdAB + /wG6Aa4BpgH/A0UB7wMpAT4gAAMzAVEBpAFaATAB9wG0AVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkB + HQH/AbQBWQEdAf8BtAFZARwB/wG0AVkBHAH/AbQBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8B + tQFZARwB/wG1AVkBHAH/AbQBYgEoAfwB6AGZAUUB/gHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMB + QgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHwAaMBQgH/AfABowFCAf8B + 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHvAaMB + QgH/Ae8BowFCAf8BzAGSAUgB9gMzAVH/AIkAAyABLgNQAeIBaQFiAV4B/wHhAcgBvQH/AecBzQHCAf8B + 5wHNAcIB/wHnAc0BwgH/AecBzQHCAf8B4QHIAb0B/wF+AXMBbgH/AzYB/wFHAUQBQwH/AasBmgGTAf8B + 4wHKAb8B/wHnAc0BwgH/AecBzQHCAf8B7gHeAdkB/wH3AfYB/AH/AfcB9gH7Af8B8AHjAd0B/wHtAd0B + 0wH/AeoB2QHPAf8BsQGhAZoB/wFLAUgBRgH/ATcCNgH/AX4BdwFzAf8B5gHXAc0B/wHtAd0B0wH/Ae0B + 3AHSAf8B6QHRAcYB/wHnAc0BwgH/AeMBywHBAf8BbQFnAWMB/wNPAeQDIQEwIAADMwFRAZ0BXQEuAfYB + swFZAR0B/wGzAVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkB + HAH/AbQBWQEcAf8BtQFZARwB/wG1AVkBHAH/AbUBWQEcAf8BtQFZARwB/wHHAXcBLwH7AfIBowFCAf8B + 8gGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMB + QgH/AfEBowFCAf8B8QGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B + 8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHvAaMBQgH/AcwBkgFIAfYDMwFR/wCJAAMCAQMD + OwFkA0gB7wF7AXEBbQH/AeEByAG9Af8B5wHNAcIB/wHeAcUBuwH/AaIBkgGLAf8BUQFMAUsB/wNSAeAD + TQGTA1QBsANMAekBbwFmAWIB/wHnAc0BwgH/AeoB1gHPAf8B8wHsAe4B/wH4AfcB/gH/AfcB9gH9Af8B + 8gHpAegB/wHuAd4B1gH/AXwBdQFxAf8DSgHqA1QBsANNAZIDUAHfAVABTQFMAf8BowGZAZMB/wHhAdIB + yQH/AewB2wHQAf8B4wHMAcEB/wF9AXIBbQH/A0cB8QM9AWgDAwEEIAADHQEoAXsBXgFLAd0BswFZAR0B + /wGzAVkBHQH/AbMBWQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQBWQEdAf8BtAFZAR0B/wG0AVkBHQH/AbQB + WQEcAf8BtAFZARwB/wG0AVkBHAH/AbUBWQEcAf8BsgFiASIB/gHcAZUBQAH9AfIBowFCAf8B8gGjAUIB + /wHyAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8QGjAUIB/wHxAaMBQgH/AfEB + owFCAf8B8QGjAUIB/wHxAaMBQgH/AfEBowFCAf8B8AGjAUIB/wHwAaMBQgH/AfABowFCAf8B8AGjAUIB + /wHwAaMBQgH/AfABowFCAf8B8AGjAUIB/wHwAaMBQgH/AY8BdQFXAd0DHQEo/wCNAAQCAzIBTwNIAe8B + aQFiAV4B/wGxAZ4BlgH/AVsBVQFTAf8BQQJAAfoDTwGeAxgBIAMDAQQDCQELAz8BbAM2AfsB1AG9AbMB + /wHnAc0BwgH/AegB0AHHAf8B8wHrAe0B/wHvAeEB3wH/AegBzwHFAf8B4AHMAcIB/wM1AfwDPwFuAwkB + CwMDAQQDFgEeA1ABmgNBAfkBWQFWAVQB/wGwAaUBngH/AWwBZwFjAf8DRgHwAzMBUgMCAQMkAAQBAxoB + JAM9AWgCQQFAAXECQQFAAXECQQFAAXECQQFAAXECQQFAAXECQQFAAXECQQFAAXECQQFAAXECQQFAAXEC + QQFAAXECQQFAAXECQQFAAXACQQFAAXEDQQFxA0EBcQNBAXEDQQFxA0EBcQNBAXEDQQFxA0EBcQNBAXED + QQFxA0EBcQNBAXEDQQFxA0EBcQNBAXEDQQFxA0EBcQNBAXEDQQFxA0EBcQM9AWgDGgEkBAH/AJEABAID + OwFkA1AB4gNIAe0DVAHNAzQBVAMDAQQMAAMnAToDTAHrAaUBlAGOAf8B5wHNAcIB/wHnAc0BwgH/AeoB + 1gHOAf8B6AHOAcQB/wHnAc0BwgH/AbEBnwGXAf8DSgHsAykBPQwAAwIBAwMzAVEDVgHLA0gB7QNQAeMD + PQFnAwIBA/8A/wBaAAMCAQMDIAEtAygBOwMQARUUAAMSARcDVQHaAXQBawFnAf8B5wHNAcIB/wHnAc0B + wgH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AYABdQFwAf8DVQHbAxMBGRQAAw8BFAMoATsDIAEuAwIB + A/8A/wCGAANVAbMBVQFQAU4B/wHcAcMBuQH/AecBzQHCAf8B5wHNAcIB/wHnAc0BwgH/AeEByAG9Af8B + WgFUAVIB/wNWAbr/AP8ArgADPQFpAUQBQgFBAf8BwAGrAaMB/wHlAcwBwQH/AeUBzAHBAf8B5QHMAcEB + /wHFAbABpwH/AUgBRQFDAf8DQAFx/wD/AK4AAw0BEQJEAUMB8AE6AjkB/wE9AjsB/wE9AjsB/wE9AjsB + /wE6AjkB/wNCAfMDEQEW/wD/ALIAAyQBNANNAZIDUQGiA1EBogNRAaIDTQGTAyUBN/8A/wD/AP8A/wA9 + AAFCAU0BPgcAAT4DAAEoAwABtAMAAS0DAAEBAQABAQUAATgBBBYAA/8BAAf/AccD/wHADAAC/wHgAT8D + /wGHA/8BwAwAAv8BwAEfA/8BgwP/AcAMAAL/AcABHwP/AYAD/wHADAAC/wHAAQ8D/wGAA/8BwAwAAf8B + DwGAAQ8BhwL/AYABPwL/AcAMAAH+AQMBgAEOAQMC/wGAAT8C/wHADAAB/AMAAQEC/wGAAR8C/wHADAAB + +AQAAv8BgAEPAv8BwAwAAfgEAAH/AYADAAEDAcAMAAH4BAAB/wQAAQEBwAwAAfgEAAH/BAABAQHADAAB + /AMAAQEB/wQAAQEBwAwAAfwDAAEBAf8EAAEBAcAMAAH+AwABAwH/BAABAQHADAAB/gMAAQMB/wQAAQEB + wAwAAf4DAAEDAf8EAAEBAcAMAAH4BAAB/wQAAQEBwAwAAcAEAAEfBAABAQHADAABgAQAAQ8EAAEBAcAM + AAGABAABDwQAAQEBwAwAAYAEAAEPBAABAQHADAABgAQAAQ8EAAEBAcAMAAGABAABDwQAAQEBwAwAAYAE + AAEPBAABAQHADAABgAQAAQ8EAAEBAcAMAAHABAABHwQAAQEBwAwAAfgEAAH/BAABAQHADAAB/gMAAQMB + /wQAAQEBwAwAAf4DAAEDAf8EAAEBAcAMAAH+AwABAwH/BAABAQHADAAB/AMAAQEB/wQAAQEBwAwAAfwD + AAEBAf8EAAEBAcAMAAH4BAAB/wQAAQEBwAwAAfgEAAH/BAABAQHADAAB+AQAAf8EAAEBAcAMAAH4BAAB + /wQAAQEBwAwAAfwDAAEBAf8EAAEBAcAMAAH+AQMBgAEOAQMG/wHADAAB/wEPAYABDwGHBv8BwAwAAv8B + wAEfB/8BwAwAAv8BwAEfB/8BwAwAAv8BwAEfB/8BwAwAAv8B4AE/B/8BwAwAC/8BwAwACw== \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Components/Setting.Designer.cs b/I18N Commander/UI WinForms/Components/Setting.Designer.cs new file mode 100644 index 0000000..7548387 --- /dev/null +++ b/I18N Commander/UI WinForms/Components/Setting.Designer.cs @@ -0,0 +1,123 @@ +namespace UI_WinForms.Components +{ + partial class Setting + { + /// + /// 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.tableLayout = new System.Windows.Forms.TableLayoutPanel(); + this.buttonSave = new System.Windows.Forms.Button(); + this.labelExplanation = new System.Windows.Forms.Label(); + this.labelSettingName = new System.Windows.Forms.Label(); + this.labelIcon = new System.Windows.Forms.Label(); + this.tableLayout.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayout + // + this.tableLayout.ColumnCount = 5; + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 66F)); + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 250F)); + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 220F)); + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 120F)); + this.tableLayout.Controls.Add(this.buttonSave, 4, 0); + this.tableLayout.Controls.Add(this.labelExplanation, 3, 0); + this.tableLayout.Controls.Add(this.labelSettingName, 1, 0); + this.tableLayout.Controls.Add(this.labelIcon, 0, 0); + this.tableLayout.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayout.Location = new System.Drawing.Point(0, 0); + this.tableLayout.Margin = new System.Windows.Forms.Padding(0); + this.tableLayout.Name = "tableLayout"; + this.tableLayout.RowCount = 1; + this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayout.Size = new System.Drawing.Size(1264, 70); + this.tableLayout.TabIndex = 0; + // + // buttonSave + // + this.buttonSave.Dock = System.Windows.Forms.DockStyle.Fill; + this.buttonSave.Location = new System.Drawing.Point(1147, 3); + this.buttonSave.Name = "buttonSave"; + this.buttonSave.Size = new System.Drawing.Size(114, 64); + this.buttonSave.TabIndex = 0; + this.buttonSave.Text = "Save"; + this.buttonSave.UseVisualStyleBackColor = true; + this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click); + // + // labelExplanation + // + this.labelExplanation.AutoSize = true; + this.labelExplanation.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelExplanation.Location = new System.Drawing.Point(539, 0); + this.labelExplanation.Name = "labelExplanation"; + this.labelExplanation.Size = new System.Drawing.Size(602, 70); + this.labelExplanation.TabIndex = 1; + this.labelExplanation.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // labelSettingName + // + this.labelSettingName.AutoSize = true; + this.labelSettingName.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelSettingName.Location = new System.Drawing.Point(69, 0); + this.labelSettingName.Name = "labelSettingName"; + this.labelSettingName.Size = new System.Drawing.Size(244, 70); + this.labelSettingName.TabIndex = 2; + this.labelSettingName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // labelIcon + // + this.labelIcon.AutoSize = true; + this.labelIcon.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelIcon.Location = new System.Drawing.Point(3, 0); + this.labelIcon.Name = "labelIcon"; + this.labelIcon.Size = new System.Drawing.Size(60, 70); + this.labelIcon.TabIndex = 3; + // + // Setting + // + this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.Controls.Add(this.tableLayout); + this.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Name = "Setting"; + this.Size = new System.Drawing.Size(1264, 70); + this.tableLayout.ResumeLayout(false); + this.tableLayout.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private TableLayoutPanel tableLayout; + private Button buttonSave; + private Label labelExplanation; + private Label labelSettingName; + private Label labelIcon; + } +} diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs new file mode 100644 index 0000000..a3a4421 --- /dev/null +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -0,0 +1,79 @@ +using DataModel.Database; +using Processor; +using UI_WinForms.Resources; + +namespace UI_WinForms.Components; + +public partial class Setting : UserControl +{ + private readonly SettingUIData settingData; + + public Setting() + { + this.InitializeComponent(); + } + + private Setting(SettingUIData settingData) + { + this.InitializeComponent(); + this.settingData = settingData; + this.labelIcon.Image = settingData.Icon; + this.labelSettingName.Text = settingData.SettingName(); + this.labelExplanation.Text = settingData.SettingExplanation(); + + var dataControl = this.settingData.SetupDataControl(); + this.tableLayout.Controls.Add(dataControl, 2, 0); + } + + private void buttonSave_Click(object sender, EventArgs e) + { + } + + private readonly record struct SettingUIData( + Bitmap Icon, + Func SettingName, + Func SettingExplanation, + Func SetupDataControl, + Func GetCurrentSetting, + Func SaveSetting + ); + + public static async Task> ShowDeepLSettingAsync() + { + var currentSetting = await AppSettings.GetDeepLMode(); + + var settingData = new Setting.SettingUIData( + Icon: Icons.icons8_add_folder_512, + SettingName: () => "DeepL Service", + SettingExplanation: () => "DeepL is a translation service that offers a wide range of translation services. This setting allows you to choose between the free and pro version of DeepL.", + SetupDataControl: () => + { + var dropdown = new ComboBox(); + dropdown.Items.Add("Disabled"); + dropdown.Items.Add("Free version"); + dropdown.Items.Add("Pro version"); + dropdown.SelectedIndex = currentSetting switch + { + SettingDeepL.DISABLED => 0, + SettingDeepL.USE_FREE_ACCOUNT => 1, + SettingDeepL.USE_PRO_ACCOUNT => 2, + + _ => 0, + }; + + // Apply the desired design: + dropdown.Dock = DockStyle.Fill; + dropdown.DropDownStyle = ComboBoxStyle.DropDownList; + + return dropdown; + }, + + GetCurrentSetting: () => currentSetting, + SaveSetting: async setting => await AppSettings.SetDeepLMode(setting)); + + return new Setting(settingData) + { + Dock = DockStyle.Top, + }; + } +} \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Components/Setting.resx b/I18N Commander/UI WinForms/Components/Setting.resx new file mode 100644 index 0000000..b5ae26c --- /dev/null +++ b/I18N Commander/UI WinForms/Components/Setting.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Components/Settings.Designer.cs b/I18N Commander/UI WinForms/Components/Settings.Designer.cs new file mode 100644 index 0000000..3b0c22b --- /dev/null +++ b/I18N Commander/UI WinForms/Components/Settings.Designer.cs @@ -0,0 +1,110 @@ +namespace UI_WinForms.Components +{ + partial class Settings + { + /// + /// 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.tableLayout = new System.Windows.Forms.TableLayoutPanel(); + this.labelHeadIcon = new System.Windows.Forms.Label(); + this.labelHead = new System.Windows.Forms.Label(); + this.panelSettings = new System.Windows.Forms.Panel(); + this.tableLayout.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayout + // + this.tableLayout.ColumnCount = 2; + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 70F)); + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayout.Controls.Add(this.labelHeadIcon, 0, 0); + this.tableLayout.Controls.Add(this.labelHead, 1, 0); + this.tableLayout.Controls.Add(this.panelSettings, 0, 1); + this.tableLayout.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayout.Location = new System.Drawing.Point(0, 0); + this.tableLayout.Name = "tableLayout"; + this.tableLayout.RowCount = 2; + this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 66F)); + this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayout.Size = new System.Drawing.Size(1001, 381); + this.tableLayout.TabIndex = 1; + // + // labelHeadIcon + // + this.labelHeadIcon.AutoSize = true; + this.labelHeadIcon.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelHeadIcon.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.labelHeadIcon.Image = global::UI_WinForms.Resources.Icons.icons8_settings_svg; + this.labelHeadIcon.Location = new System.Drawing.Point(3, 0); + this.labelHeadIcon.Name = "labelHeadIcon"; + this.labelHeadIcon.Size = new System.Drawing.Size(64, 66); + this.labelHeadIcon.TabIndex = 0; + // + // labelHead + // + this.labelHead.AutoSize = true; + this.labelHead.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelHead.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.labelHead.Location = new System.Drawing.Point(73, 0); + this.labelHead.Name = "labelHead"; + this.labelHead.Size = new System.Drawing.Size(925, 66); + this.labelHead.TabIndex = 1; + this.labelHead.Text = "Settings"; + this.labelHead.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // panelSettings + // + this.panelSettings.AutoScroll = true; + this.tableLayout.SetColumnSpan(this.panelSettings, 21); + this.panelSettings.Dock = System.Windows.Forms.DockStyle.Fill; + this.panelSettings.Location = new System.Drawing.Point(0, 66); + this.panelSettings.Margin = new System.Windows.Forms.Padding(0); + this.panelSettings.Name = "panelSettings"; + this.panelSettings.Size = new System.Drawing.Size(1001, 315); + this.panelSettings.TabIndex = 2; + // + // Settings + // + this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.Controls.Add(this.tableLayout); + this.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Name = "Settings"; + this.Size = new System.Drawing.Size(1001, 381); + this.tableLayout.ResumeLayout(false); + this.tableLayout.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private TableLayoutPanel tableLayout; + private Label labelHeadIcon; + private Label labelHead; + private Panel panelSettings; + } +} diff --git a/I18N Commander/UI WinForms/Components/Settings.cs b/I18N Commander/UI WinForms/Components/Settings.cs new file mode 100644 index 0000000..106ade4 --- /dev/null +++ b/I18N Commander/UI WinForms/Components/Settings.cs @@ -0,0 +1,14 @@ +namespace UI_WinForms.Components; + +public partial class Settings : UserControl +{ + public Settings() + { + this.InitializeComponent(); + this.Load += async (sender, args) => + { + var deepL = await Setting.ShowDeepLSettingAsync(); + this.panelSettings.Controls.Add(deepL); + }; + } +} diff --git a/I18N Commander/UI WinForms/Components/Settings.resx b/I18N Commander/UI WinForms/Components/Settings.resx new file mode 100644 index 0000000..b5ae26c --- /dev/null +++ b/I18N Commander/UI WinForms/Components/Settings.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs index 8311735..25312af 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs +++ b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs @@ -199,5 +199,15 @@ namespace UI_WinForms.Resources { return ((System.Drawing.Bitmap)(obj)); } } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap icons8_settings_svg { + get { + object obj = ResourceManager.GetObject("icons8_settings_svg", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } } } diff --git a/I18N Commander/UI WinForms/Resources/Icons.resx b/I18N Commander/UI WinForms/Resources/Icons.resx index 41a3205..1b73e58 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.resx +++ b/I18N Commander/UI WinForms/Resources/Icons.resx @@ -160,4 +160,7 @@ icons8-rename-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + icons8-settings.svg.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Resources/icons8-settings.svg.png b/I18N Commander/UI WinForms/Resources/icons8-settings.svg.png new file mode 100644 index 0000000000000000000000000000000000000000..545b9d5fc867fa8f391c3d3c687641dff5f2ed05 GIT binary patch literal 5246 zcmai2cU+Un)(*WWh!m+p3|&e>hY)%fLk9stYJkuJNhnezpwc^nR25K)lm!u#CLkh9 zk&Z}_UZfZ4^#2v^qxD07ziZzAbgxaCpgl+6mwg_QgHxE1x0KgP{J#6e;5Llos!V&2%2U@Rf z00EKqa-drha0uK(1>uC$^g|;I{dA1%{9Np0>_H0hlrUc?p1=)(wE_CNxw>PZzH*=+ zyiol6`7{^={2_vMkpr2+^?)iUGy*6gEFla5$x{MhXnO~!fvWl+%J`8S$O((}fP%q3 zK0d-eV!|l2BUnU6Mg|NK1&fLb;U$DHcipizzC!L8&U1>N9I6P69UAF@MWWn+=bSdS zC@-uW2!zLhe~@F54u7({WB%Aa-Vxw)1S}#90sp5s!Wa2J#LtnxiF-JquqccZ%H!7t z{<6d`_-~4M_x-bquZ_n)3B%$4x44_zU$%k4s(Irb@rP6YV$;7Dz!=^2K!6Pp7?c;< z4x#3aaL01~@Wi=apjvJ=j)VkA$&162G+QpDLz* zVsaoENwCPDkl8;%=dOn8A$<|9rm9FcggXY$`pb$xL9_n>s-Rp^XhVEjBji9o*ZLI) z=no8zvd2SWKg{?O(o#{;L!%s!u6PV%prH)ZQd5x>k&%=X5*7YQgAW=MuZwiJt7?PA zONm18xe1XH5|uO(k%o#upb%*Rh$s{S`N8}{8ea?cHdvegPyRfkfiS!V91hh)Vz4Om z-5*mw)7%i@`E&Gh=!*Q2-$3AxC_`=R&b=-N@<5~Pz3dS7KNiQ+{X{V+2ds|`8lmKf z53n3a$-x1MkI!A8-g)K%MTA8l!at+?OT)(rfoJ>QdjtPr8Th>7{%slz{5RuaKLq}x zMDcn*=kTSE?;+q{O$0yq)rJu6_}+uYHyNhK*E#?If?y;*EPo3J0Kk{vmC!Aqs!!jl zAf__oNPnTtwy#V%nwB*xjfpZUE&q6=?(TSJLE5Gtifj1#ZMBFPs|%-uRqf{dAZ~3l zI@ayXg~BxZuGO*c)f4{Ri{qH4BKz0H#-FK%EyknOnu7}$({N`L3ZDiHwW3~{ee?}5 z&3;}#G3`0+m2X(IT^&^7cjt}xh7tKC=g>4p_RH+IyI84F6jIJeuRHsyZ<`-opq!BQ zdq3wGW+)s4b-i9r?z{Yus1T$>U!Eda@qP;(GTfQC>(8;kE#c=bDqL<{M-s)P|DKo$ z5l$Ys4FO^}vL1X(WZ>Sa4cg*0ePjW5xX*C&ie>_jZdie~f#u^=ddtTNHZ6;16YtF1 z#^Z0-^IV*Zt2!AWJ%#U&l&!`Qjh;e@Cx|i^C=a5Jdd_$b)s-%+DSc(hyhH!`gJfoj zN`HNJ`cm91-5yWU2Kr)Ue~$-=afN&Ly*-&4B82g~C0cLqY|E~pPk}`GK8|DdD^t($ zrv-(FrWpnRp#E_F5F`swv*J&k1ua!2Bh!b2X-KTGaY}2@-nf)*o3?W31+E8xU_kJ! zts<$u2uPowp5cbMr*n~ZQTy7g%oZq>z0*Db4RMr>rB4VuV^i$~&cP9o%@-|v7h zsmjW~b6&gF){*gjt^Q={p@uSPLFLwqUGw#3S;wdKXA5J2yTe4sR}&$r@9EXj2w~*U zy;Zp}_DqD~DZ(fk7W& zo+>4$=*jCGK3YBEx40ShxCLbnn3!B>JDdj|oB68D9Lgp!Gsd{q;lzsc|7 z)3vPI=10$3+{o($32|yWyKf~E6R!FY95gnE00sGlv!*g7znf&5M1-)hx`!puXAo4F zDMOf$&d&79U76{Gj|lp43bVgAFN{?>6=Ek6HJIgX>Fru|TPDWckp&8JxJ{)rWP7BBxBS>&>psMIztH_9brz#Z<bdTi&M3Qv1J^X~tctP0AOXC_txa!ZsjS_3Mya)fAknT&hIv#cRHuu>aH_}fgL zF(i^a1oxS$tO+=YWr}FcEk2nx#F;;<0e=ll59?mI(Ee(Sg%UfKobrU9x3bEbc6jVciVwxXksC?%v?ZGH`>*Vten}T^nuhVS#Q#lQ3`su8pvm{OF zoA`pbcQX1o30Iq;n%*CN9mhvmuqka7v=j8fws)>^;bd`nXbvAlc*=eGsNANc~J%J@gi@gD_$fcIy^Cz zIMZ25)S=+2B@KD2QA$wV#r1btJB|0*uC}q`>5g;=CmgSIlk@j+eGcjF>c14D(S`2mp|>8C;x(<91`d6Cn~bb* zSD{y1>i)bjx8;*&;4LTBT`$J}=I!(7SIdr$E2H%%#&E+?oQax#Y*M&Zia+d0R8KN7 zUt|t>$VQ1+%c^(v*u|^ziSKi0)#I`TIs~D|ZgpoLFQk@8uAPKEB_hn%WwZShx%bv> zUhhf3GvbVv)Y(fK({(2ik9S6w(t_4!W*O)=+sMF|qtsIyHtsomH62%ZSK55niY|=W zw@}{T;rbXe^tfdI#O)roer#rQr5@X-9iyIf)XRHM#bH-Z@XBo~6Cy>vFE{*ei@oW5 zd)D_v#;7u?oO1eLR#V@h5%2qt0b^49MNYIzO=u=bp@z|X$PJMgP}8qfi~WGm)i3XytqRTBXDwzIbKj==AB4E^cbZ;IOW#aCNSn9G|Gw zVo9><13TgRI_iB^QN}2<_qGY&R#sGFTFXtrWJgnaG&22Z$7fyn$(ao_v#YvwZRMHQ zyx%tg0IhK*oAVuK?L`e|++L14*~>Js1*)J;m-lG+vri5bMaIfBjn?8IEz+E?wzN@$ zvA@a0AD?{*O!BDhguQbzKo^(GJnD4*7@gJGeY(nU?_i~9HkJ=a3(wrB?Bnja2RD|v z?VsqxHFm$rHl@sru2icZOWYeWIREV3u6-h}R6{&ilAV_go;h$;ilNMXxW4mg5+qww zyo-^wsO=M2b;xU}`w164>FXH1y)ABFutHAwI9GxpmhFp%wl=3)3qlcO^tIfM@m^4Po0=ID)nf%~E|!HX z-J<>R(GSHLjPcW5)^n{WkH*^jrsD14Aruy7ZQ&18*ko61j^--^YHdhrs{-MC1D63$ zb`Jt}XmQ;OMcrLpr$81esr^y#jfEwhMFn5)vV#mTJmwu{nhU`)Ri|vQ%jB4(64PD9a6G6LM^=~K;BSQ27Vwcq-MATkr z=4c+qyM``U>aa?{?GCKQCuc5MMfmT!x|PUca48%T4%`K<1SZ35wZ8Rk1|@}_MrK>@M+{qvC8fNMEl_Od>EU44=wKIR#)`#>c zeJ9~i%mR`p1S?unZR<_Ovd(vEKi5=D>3Gl~n7s^=`g+KDI+w;+_?ukU62m$VV@uBE z&!raXf-FrAn4FKY!?iQ4W5~rZ@jdsC_@2j*F?v-e?<<6HlA1Q*PJ_7K*JeN+=u$`R z;zENT`~4Q<*mJzg<^vQn5CA)mzLLV$K6)tL{wVM>A$BX!n6D~*BIWCf$r_7P4CoQ%-jABnwkG-xs zh&4aS+E?)$QSme);Ns67bFP@t>1ec$FEju2)`B{cCnf%|0-?TWLb6y$NH5(X@o1K+ z7XD(RANU+ymxt5{l%JTAKRA?`yVh7y%}E)J80uCY(#q3pDv11?+`prd$dzEFr&(^Nx8HdZKOctG;uz!rjrn^<8M=< zubGWCZ0FxhE%qo(Wsh)r@LM>yIDF=d4cMyGH!kWEyff9Z>DZrLspkEy))~*;^;4pv4^vzOkR1+>Js?;R|f1R$NHd)mXN&94P-_CTAbb3?T#pE8& zaW941a_9+}qyJ~G-<%dI;_lq?f*(*8brb6lvLE_ET7ryjI$ Date: Tue, 26 Jul 2022 19:15:36 +0200 Subject: [PATCH 06/32] Added the DeepL icon --- I18N Commander/UI WinForms/Components/Setting.cs | 2 +- .../UI WinForms/Resources/Icons.Designer.cs | 10 ++++++++++ I18N Commander/UI WinForms/Resources/Icons.resx | 3 +++ .../Resources/deepl_logo_icon_170284.png | Bin 0 -> 2865 bytes 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 I18N Commander/UI WinForms/Resources/deepl_logo_icon_170284.png diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index a3a4421..9d0f92e 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -43,7 +43,7 @@ public partial class Setting : UserControl var currentSetting = await AppSettings.GetDeepLMode(); var settingData = new Setting.SettingUIData( - Icon: Icons.icons8_add_folder_512, + Icon: Icons.deepl_logo_icon_170284, SettingName: () => "DeepL Service", SettingExplanation: () => "DeepL is a translation service that offers a wide range of translation services. This setting allows you to choose between the free and pro version of DeepL.", SetupDataControl: () => diff --git a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs index 25312af..b9099aa 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs +++ b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs @@ -60,6 +60,16 @@ namespace UI_WinForms.Resources { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap deepl_logo_icon_170284 { + get { + object obj = ResourceManager.GetObject("deepl_logo_icon_170284", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/I18N Commander/UI WinForms/Resources/Icons.resx b/I18N Commander/UI WinForms/Resources/Icons.resx index 1b73e58..65f228a 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.resx +++ b/I18N Commander/UI WinForms/Resources/Icons.resx @@ -118,6 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + deepl_logo_icon_170284.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + icons8-add-folder-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/I18N Commander/UI WinForms/Resources/deepl_logo_icon_170284.png b/I18N Commander/UI WinForms/Resources/deepl_logo_icon_170284.png new file mode 100644 index 0000000000000000000000000000000000000000..d0daf5678161555d6a226b4d8521f3d493b02436 GIT binary patch literal 2865 zcmai0dmxkh8(#;B#7~Bin03L)-dzf985I-NkfD)FGcOi)XG5u6LnU1(B}b`MbEzR+ zT*}CiN-8RpkeqbkM;A%Qc}IuSseZpd-fhqK^Lakc^L?J@`+b+<>bz!-s=g`=2AkvL zXzvDnqvg-6nb0RuzdIWSQ#{XfrwM43^+X0c9H0lX13*9&&Vg_k%-UAOp)*230Wts# zX0k}AfveRhBr}kN+Gs(+QaE;C2-7i|2U4S*-5JrL3_>8v)<)G@M1%ywK>-~p3J+uP zi6RneLYD~rmM>#a$O(!dl!T&DT#7a=D6S^Gvj?M{T3)uV+HfL%B--MWg zzjK7j_hT0ko%16yh4R1Y;o;wGgD)UQLWTHR)NgY7I{@E3iUVTYKt4Ny#{kKZAWN`d zq7w4D5S_y5!Qgt36)XrLp_Wn})o8 z2+2!LbY+UbFq%Cx9Axn!)u}9|L9d^HcI+@Vj|z=7NJ349mEWSFuvQG)kr6@oh6Q7X^F-IlQK}#h>$NcD9WBLfLM4eG@Do}G~Uu3MQ5BXRX({$9Du_D zlii*25Qcz|+Ryif`I;FsZD(U{u67<{%yx?n)=>XaUKgQc z9#L~L^;~a)NrJeQcdntmCVcI$R~Byl^>y>}xSI0QhD(Oi8XEB1j}#=v$DX&GeRY5J z@(*c;4rXd*X7$|3-*_nZ^I;6Pwxq;3#kV`>4@H${vbu$g5xo<+nn#ic@hgi9&g}2p zcr%wy=4l`C7z!~zu#l{ten#R(0&vFBJ`ULxkH@RGwP?jF^!BS8J+RTcvB~OD`ENAr z?j}2#so~Bynt=4s*dYZ(tZt=ibI0dr9Xm=IQ+3*R4pTz5yPoteUHG`RFh#NA_)3PN zcX3{9UPnppw!H(!6@Y()($$!|3;J@>I#&b1E!JkGRnY4~h2!YOhrwoR$)6dp>|+S% z^>W0?ew8~dvGQ@~8Q(f><-yKMp$TrSo%h1iW%+G4?nyNZ!q?`#>s1i8?boo;cf0OJ zO^pk9rI0<^;F5XqLCAI8xV4Lz^Y+hG($k(@##}diN?Xsq0&&1`L(!Q+OA9W~+4h#o z<&GG?m;wH9@-V&WxYw)dhXr0GtwieLT_*}WyXIX|>ND=ndXyC)V!K73UTmCiD$(d1nNJ(uBj;=(G={4{BHrpnXAfjk8M3&OD0(tv3fd-`R~iGtQ{2kW?E zMzor*f341~^~GM}ykOP`N3ADiXy1b#J0*eszKlx|%En#(Bbpyt%SInTQr;5HQd+?VULkn(#LwQWjZfU6x_MdG)UQ+ZzeMqX~kSX*I});47uJTd*vibxF(q{ z2~Rm=8s*&|&62E?DgEoN^r?2%X>jv`V%y))|4i_qRThEkk@zzE@P)jM~@oxY~R6er;<`uaYs98 z7B@zV3^raJD$*7ySmh%kbwP{7GM@Kn&df1&F`^Z15Y}V(JlzjS7K4?2Wh1^DJY#wd zJ{Q7eK?J2sVylbJfR16-0dd<}-MpkzYr5uJ?`d~aOHP$$JK+p+#eG_$U-~p?)eAEX z6I-O4#!5^j>?RX6v!r-^AIEi+QAL~G#pVXDJ#3crt8UtIuYS9}<1>P9GE2Gt3GUMOF*DiJ zcwU+kXZe<^rqO8j{PGZaXo=6^01;f0Ds4;M##^;+uV?V@8D}-=ZC=qvthKm`_L$f* zQ%Me$I-l(2yEpgu@)xzjl0DbfywJ4S+56<}yGWmhtKT}7a?@jtD(2=gjrqn`zRXn4 zFchaqA-}}Bw*=n7!|>4|#B;-|+{&&M7iLrgH~XzbE*A&GAw+R+BPoN7upf0M#CqB# z09p6%+$JfBdrDsz=+cXi%?E0(Nza*D-ML%o4bW_D!`>=3A8J)j2T@$ky zo5g;tQ-~LCYUvGc+CJx)moH9QB+;a*vBiiY;k`~>i~6Gh4U+%DW&Rhm{g)bN5f-5n z;4)>ir0Pasn0jRF?D%kr3Xxwj-~t_5T|)Kp)Qyl;wn;Xw+zL?UZ!I1 ITD>{$FXZ))RsaA1 literal 0 HcmV?d00001 From 83cc7644d10ae1eaadd5e9b44d601fa55634c85d Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 26 Jul 2022 19:40:46 +0200 Subject: [PATCH 07/32] Implemented the save function --- .../Components/Setting.Designer.cs | 22 ++----- .../UI WinForms/Components/Setting.cs | 61 ++++++++++--------- .../UI WinForms/Components/Settings.cs | 2 +- 3 files changed, 37 insertions(+), 48 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Setting.Designer.cs b/I18N Commander/UI WinForms/Components/Setting.Designer.cs index 7548387..f183b05 100644 --- a/I18N Commander/UI WinForms/Components/Setting.Designer.cs +++ b/I18N Commander/UI WinForms/Components/Setting.Designer.cs @@ -1,6 +1,6 @@ namespace UI_WinForms.Components { - partial class Setting + partial class Setting { /// /// Required designer variable. @@ -29,7 +29,6 @@ private void InitializeComponent() { this.tableLayout = new System.Windows.Forms.TableLayoutPanel(); - this.buttonSave = new System.Windows.Forms.Button(); this.labelExplanation = new System.Windows.Forms.Label(); this.labelSettingName = new System.Windows.Forms.Label(); this.labelIcon = new System.Windows.Forms.Label(); @@ -38,13 +37,12 @@ // // tableLayout // - this.tableLayout.ColumnCount = 5; + this.tableLayout.ColumnCount = 4; this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 66F)); this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 250F)); this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 220F)); this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 120F)); - this.tableLayout.Controls.Add(this.buttonSave, 4, 0); + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tableLayout.Controls.Add(this.labelExplanation, 3, 0); this.tableLayout.Controls.Add(this.labelSettingName, 1, 0); this.tableLayout.Controls.Add(this.labelIcon, 0, 0); @@ -57,24 +55,13 @@ this.tableLayout.Size = new System.Drawing.Size(1264, 70); this.tableLayout.TabIndex = 0; // - // buttonSave - // - this.buttonSave.Dock = System.Windows.Forms.DockStyle.Fill; - this.buttonSave.Location = new System.Drawing.Point(1147, 3); - this.buttonSave.Name = "buttonSave"; - this.buttonSave.Size = new System.Drawing.Size(114, 64); - this.buttonSave.TabIndex = 0; - this.buttonSave.Text = "Save"; - this.buttonSave.UseVisualStyleBackColor = true; - this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click); - // // labelExplanation // this.labelExplanation.AutoSize = true; this.labelExplanation.Dock = System.Windows.Forms.DockStyle.Fill; this.labelExplanation.Location = new System.Drawing.Point(539, 0); this.labelExplanation.Name = "labelExplanation"; - this.labelExplanation.Size = new System.Drawing.Size(602, 70); + this.labelExplanation.Size = new System.Drawing.Size(722, 70); this.labelExplanation.TabIndex = 1; this.labelExplanation.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // @@ -115,7 +102,6 @@ #endregion private TableLayoutPanel tableLayout; - private Button buttonSave; private Label labelExplanation; private Label labelSettingName; private Label labelIcon; diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index 9d0f92e..0a06612 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -4,45 +4,35 @@ using UI_WinForms.Resources; namespace UI_WinForms.Components; -public partial class Setting : UserControl +public partial class Setting : UserControl { - private readonly SettingUIData settingData; - public Setting() { this.InitializeComponent(); } - private Setting(SettingUIData settingData) + private Setting(SettingUIData settingMetaData) { this.InitializeComponent(); - this.settingData = settingData; - this.labelIcon.Image = settingData.Icon; - this.labelSettingName.Text = settingData.SettingName(); - this.labelExplanation.Text = settingData.SettingExplanation(); + this.labelIcon.Image = settingMetaData.Icon; + this.labelSettingName.Text = settingMetaData.SettingName(); + this.labelExplanation.Text = settingMetaData.SettingExplanation(); - var dataControl = this.settingData.SetupDataControl(); + var dataControl = settingMetaData.SetupDataControl(); this.tableLayout.Controls.Add(dataControl, 2, 0); } - private void buttonSave_Click(object sender, EventArgs e) - { - } - - private readonly record struct SettingUIData( + private readonly record struct SettingUIData( Bitmap Icon, Func SettingName, Func SettingExplanation, - Func SetupDataControl, - Func GetCurrentSetting, - Func SaveSetting + Func SetupDataControl ); - public static async Task> ShowDeepLSettingAsync() + public static async Task ShowDeepLSettingAsync() { var currentSetting = await AppSettings.GetDeepLMode(); - - var settingData = new Setting.SettingUIData( + var settingData = new Setting.SettingUIData( Icon: Icons.deepl_logo_icon_170284, SettingName: () => "DeepL Service", SettingExplanation: () => "DeepL is a translation service that offers a wide range of translation services. This setting allows you to choose between the free and pro version of DeepL.", @@ -57,21 +47,34 @@ public partial class Setting : UserControl SettingDeepL.DISABLED => 0, SettingDeepL.USE_FREE_ACCOUNT => 1, SettingDeepL.USE_PRO_ACCOUNT => 2, - + _ => 0, }; - - // Apply the desired design: + + // Setup the change event handler: + dropdown.SelectedValueChanged += async (sender, args) => + { + var newSetting = dropdown.SelectedIndex switch + { + 0 => SettingDeepL.DISABLED, + 1 => SettingDeepL.USE_FREE_ACCOUNT, + 2 => SettingDeepL.USE_PRO_ACCOUNT, + + _ => SettingDeepL.DISABLED, + }; + + await AppSettings.SetDeepLMode(newSetting); + }; + + // Apply the desired layout: dropdown.Dock = DockStyle.Fill; dropdown.DropDownStyle = ComboBoxStyle.DropDownList; return dropdown; - }, - - GetCurrentSetting: () => currentSetting, - SaveSetting: async setting => await AppSettings.SetDeepLMode(setting)); - - return new Setting(settingData) + } + ); + + return new Setting(settingData) { Dock = DockStyle.Top, }; diff --git a/I18N Commander/UI WinForms/Components/Settings.cs b/I18N Commander/UI WinForms/Components/Settings.cs index 106ade4..c04e767 100644 --- a/I18N Commander/UI WinForms/Components/Settings.cs +++ b/I18N Commander/UI WinForms/Components/Settings.cs @@ -7,7 +7,7 @@ public partial class Settings : UserControl this.InitializeComponent(); this.Load += async (sender, args) => { - var deepL = await Setting.ShowDeepLSettingAsync(); + var deepL = await Setting.ShowDeepLSettingAsync(); this.panelSettings.Controls.Add(deepL); }; } From e91d8fe2ebf708a885f4b718b2872f0c785e21a6 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 26 Jul 2022 19:45:18 +0200 Subject: [PATCH 08/32] Implemented GetAllSettings generator to render all settings --- I18N Commander/UI WinForms/Components/Setting.cs | 5 +++++ I18N Commander/UI WinForms/Components/Settings.cs | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index 0a06612..1d57e21 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -79,4 +79,9 @@ public partial class Setting : UserControl Dock = DockStyle.Top, }; } + + public static IEnumerable> GetAllSettings() + { + yield return ShowDeepLSettingAsync(); + } } \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Components/Settings.cs b/I18N Commander/UI WinForms/Components/Settings.cs index c04e767..dcbef4c 100644 --- a/I18N Commander/UI WinForms/Components/Settings.cs +++ b/I18N Commander/UI WinForms/Components/Settings.cs @@ -7,8 +7,8 @@ public partial class Settings : UserControl this.InitializeComponent(); this.Load += async (sender, args) => { - var deepL = await Setting.ShowDeepLSettingAsync(); - this.panelSettings.Controls.Add(deepL); + foreach (var setting in Setting.GetAllSettings()) + this.panelSettings.Controls.Add(await setting); }; } } From b86e05712237c5616c7cf1d60626eb43325310e5 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 26 Jul 2022 19:46:44 +0200 Subject: [PATCH 09/32] Optimizations --- I18N Commander/UI WinForms/Components/Setting.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index 1d57e21..aa6e3ab 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -28,11 +28,11 @@ public partial class Setting : UserControl Func SettingExplanation, Func SetupDataControl ); - - public static async Task ShowDeepLSettingAsync() + + private static async Task ShowDeepLSettingAsync() { var currentSetting = await AppSettings.GetDeepLMode(); - var settingData = new Setting.SettingUIData( + var settingData = new SettingUIData( Icon: Icons.deepl_logo_icon_170284, SettingName: () => "DeepL Service", SettingExplanation: () => "DeepL is a translation service that offers a wide range of translation services. This setting allows you to choose between the free and pro version of DeepL.", From 506a21e792f3029ead3a71ad948032bf8285a139 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 26 Jul 2022 19:48:30 +0200 Subject: [PATCH 10/32] Optimizations --- .../UI WinForms/Components/Setting.cs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index aa6e3ab..f2f2cdf 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -52,19 +52,14 @@ public partial class Setting : UserControl }; // Setup the change event handler: - dropdown.SelectedValueChanged += async (sender, args) => + dropdown.SelectedValueChanged += async (sender, args) => await AppSettings.SetDeepLMode(dropdown.SelectedIndex switch { - var newSetting = dropdown.SelectedIndex switch - { - 0 => SettingDeepL.DISABLED, - 1 => SettingDeepL.USE_FREE_ACCOUNT, - 2 => SettingDeepL.USE_PRO_ACCOUNT, + 0 => SettingDeepL.DISABLED, + 1 => SettingDeepL.USE_FREE_ACCOUNT, + 2 => SettingDeepL.USE_PRO_ACCOUNT, - _ => SettingDeepL.DISABLED, - }; - - await AppSettings.SetDeepLMode(newSetting); - }; + _ => SettingDeepL.DISABLED, + }); // Apply the desired layout: dropdown.Dock = DockStyle.Fill; From fa74291e398a5e9422b94a5a31bb9325d5b10be4 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Wed, 27 Jul 2022 21:38:54 +0200 Subject: [PATCH 11/32] Changed the setting control to adjust its height as needed --- .../UI WinForms/Components/Setting.Designer.cs | 10 +++++----- I18N Commander/UI WinForms/Components/Setting.cs | 8 ++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Setting.Designer.cs b/I18N Commander/UI WinForms/Components/Setting.Designer.cs index f183b05..d78d7dd 100644 --- a/I18N Commander/UI WinForms/Components/Setting.Designer.cs +++ b/I18N Commander/UI WinForms/Components/Setting.Designer.cs @@ -52,7 +52,7 @@ this.tableLayout.Name = "tableLayout"; this.tableLayout.RowCount = 1; this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayout.Size = new System.Drawing.Size(1264, 70); + this.tableLayout.Size = new System.Drawing.Size(1000, 72); this.tableLayout.TabIndex = 0; // // labelExplanation @@ -61,7 +61,7 @@ this.labelExplanation.Dock = System.Windows.Forms.DockStyle.Fill; this.labelExplanation.Location = new System.Drawing.Point(539, 0); this.labelExplanation.Name = "labelExplanation"; - this.labelExplanation.Size = new System.Drawing.Size(722, 70); + this.labelExplanation.Size = new System.Drawing.Size(458, 72); this.labelExplanation.TabIndex = 1; this.labelExplanation.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // @@ -71,7 +71,7 @@ this.labelSettingName.Dock = System.Windows.Forms.DockStyle.Fill; this.labelSettingName.Location = new System.Drawing.Point(69, 0); this.labelSettingName.Name = "labelSettingName"; - this.labelSettingName.Size = new System.Drawing.Size(244, 70); + this.labelSettingName.Size = new System.Drawing.Size(244, 72); this.labelSettingName.TabIndex = 2; this.labelSettingName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // @@ -81,7 +81,7 @@ this.labelIcon.Dock = System.Windows.Forms.DockStyle.Fill; this.labelIcon.Location = new System.Drawing.Point(3, 0); this.labelIcon.Name = "labelIcon"; - this.labelIcon.Size = new System.Drawing.Size(60, 70); + this.labelIcon.Size = new System.Drawing.Size(60, 72); this.labelIcon.TabIndex = 3; // // Setting @@ -92,7 +92,7 @@ this.Controls.Add(this.tableLayout); this.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); this.Name = "Setting"; - this.Size = new System.Drawing.Size(1264, 70); + this.Size = new System.Drawing.Size(1000, 72); this.tableLayout.ResumeLayout(false); this.tableLayout.PerformLayout(); this.ResumeLayout(false); diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index f2f2cdf..021eef9 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -18,6 +18,14 @@ public partial class Setting : UserControl this.labelSettingName.Text = settingMetaData.SettingName(); this.labelExplanation.Text = settingMetaData.SettingExplanation(); + // Calculate the needed height of the explanation label when the parent window is resized: + this.tableLayout.Resize += (sender, args) => + { + // Adjust the height of the parent controls (table & user control): + this.tableLayout.Height = Math.Max((int)this.labelExplanation.CreateGraphics().MeasureString(this.labelExplanation.Text, this.labelExplanation.Font, new SizeF(this.labelExplanation.Width, 1000)).Height, 66); + this.Height = this.tableLayout.Height + this.tableLayout.Margin.Vertical; + }; + var dataControl = settingMetaData.SetupDataControl(); this.tableLayout.Controls.Add(dataControl, 2, 0); } From 8e21ddffc9718ff88fb32743f73bd4205a4c1d3c Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Wed, 27 Jul 2022 21:56:59 +0200 Subject: [PATCH 12/32] Vertical align the data control --- I18N Commander/UI WinForms/Components/Setting.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index 021eef9..f0a1bd6 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -17,17 +17,25 @@ public partial class Setting : UserControl this.labelIcon.Image = settingMetaData.Icon; this.labelSettingName.Text = settingMetaData.SettingName(); this.labelExplanation.Text = settingMetaData.SettingExplanation(); + + var dataControl = settingMetaData.SetupDataControl(); + this.tableLayout.Controls.Add(dataControl, 2, 0); - // Calculate the needed height of the explanation label when the parent window is resized: + // Ensure, that this data control is vertical centered by calculating the needed margin, considering the outer size of the table layout: + var margin = (this.tableLayout.GetRowHeights().First() - dataControl.Height) / 2f; + dataControl.Margin = new Padding(0, (int) margin, 0, (int)margin); + + // Calculate the needed height of the explanation label & centering of the data control when the parent window is resized: this.tableLayout.Resize += (sender, args) => { // Adjust the height of the parent controls (table & user control): this.tableLayout.Height = Math.Max((int)this.labelExplanation.CreateGraphics().MeasureString(this.labelExplanation.Text, this.labelExplanation.Font, new SizeF(this.labelExplanation.Width, 1000)).Height, 66); this.Height = this.tableLayout.Height + this.tableLayout.Margin.Vertical; + + // Ensure, that this data control is vertical centered by calculating the needed margin, considering the outer size of the table layout: + var margin = (this.tableLayout.GetRowHeights().First() - dataControl.Height) / 2f; + dataControl.Margin = new Padding(0, (int) margin, 0, (int)margin); }; - - var dataControl = settingMetaData.SetupDataControl(); - this.tableLayout.Controls.Add(dataControl, 2, 0); } private readonly record struct SettingUIData( From 3b99632427a650c25a1d770476b494fe0f01cd78 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 15:48:04 +0200 Subject: [PATCH 13/32] Added key icon --- .../UI WinForms/Resources/Icons.Designer.cs | 10 ++++++++++ I18N Commander/UI WinForms/Resources/Icons.resx | 3 +++ .../UI WinForms/Resources/icons8-key-512.png | Bin 0 -> 2479 bytes 3 files changed, 13 insertions(+) create mode 100644 I18N Commander/UI WinForms/Resources/icons8-key-512.png diff --git a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs index b9099aa..bb5ab78 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs +++ b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs @@ -150,6 +150,16 @@ namespace UI_WinForms.Resources { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap icons8_key_512 { + get { + object obj = ResourceManager.GetObject("icons8_key_512", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/I18N Commander/UI WinForms/Resources/Icons.resx b/I18N Commander/UI WinForms/Resources/Icons.resx index 65f228a..e4db609 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.resx +++ b/I18N Commander/UI WinForms/Resources/Icons.resx @@ -145,6 +145,9 @@ icons8-document-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + icons8-key-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + icons8-language-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/I18N Commander/UI WinForms/Resources/icons8-key-512.png b/I18N Commander/UI WinForms/Resources/icons8-key-512.png new file mode 100644 index 0000000000000000000000000000000000000000..f396b69ee0aabc0d47ead3342678bea6738abf05 GIT binary patch literal 2479 zcmai0eIQin8Xtunq|aNcRhm6o*M>PW4%2cxtoThhmF zwwG>vaV%s*OuSE%AH;R=@F(utI!?JC4?;mI8yzlS#{GR81p67jL_IY`_ z>g#@_OCS*R*={T!{M$nH5Vi47=%b!&0zvb8#E*+{IUW!njUn>{XgExk$4GFTK(KR= zOL+Wf7$b$l5r~)p3|H3yBt*af0f7P15}#*+J|C=5Y^Tsh`m`faa82>!mW5)#F#D&a3iaM!ds6YdKqjG zPDqt%$P1CfA}$MwfyFXhbvBAQFz7uX6BVISU%ahh1~BbwwhoXQW!}IQmmC zfuNCs;AMHM90Y>t;n>3pGnV&1nj9>d#=<-<*A3J!Se$QSv%*s8&;8{9t?d`PQRa;= zTX$F@75+b@FEy-NF{vfWxZuOuc&x(2rk}3(E=$ln)G>OoYlmW>Q&w-}S+X*}a1E`! z#%R^Jne1@FRb}dtxDG6z<ScTa!*$ChYry5YLE$EmJ<9EIK{ z;-<1b>;09f!FT*H_5`cSHB(Qwi@Uw_iekk--6xT9qlMa+JJ*)3HQNwSAGJ|IyncN| za7*jixc#s0AtQq#xA47kLv5$Vk$lQEQ;oz06!UXmhSiK+OJApa<)F0eTN{`Wl%Lj2 zWBc?CEV)3s+q-mGUK9N7r<-5Bz8`2z?YHocSLQyyX|=_+{-Vwn!$Re@t=U`lcFU7T zMRbSCMNBjgJ!-8mvN}^g;1aYyrlB1=-x=-AcwtPxGPF;#X4P)nc{c*R>bxGe58J!O zFAmE%dnxr~X#c-P5AN^EYm3x?S*9=XUke?HTab)E&|9W@Gzi&W8xRQd4cIIvKkgSp zZ4POxV1uR+#bCnCi4T^2(zA4N?;4MmqnnEsix!y1*{&`WON)Q}ahO$f3$r?go&_H_b1hkQEe#Dj#G~7kXBC`$=sEi9o4%ZmQ%qMg-kc@=RJDge85L(_mSpT`h4rDKNfwWy^#<*jr#eG`X5a zCBDe$JWJ`o}9b@E3)>>^~Dfr{ZhxevKp$(4S zXGt4J)E}FlfZtKT=T0h_NJoHR_w$7{But-VkdU>SAIqJnB zoz}(-k2I4T)wNMl;@Ff<>%wksa#H~m(0re5pPJE>lde1)yW>^Sh;MSMepNLfL^IgL zu?!8WKPlEP3;fp321vehQ|RwV9E;NY3ff$vOH7%f&U0Js|GQqw6okK61Zt%^f-FLD z{?*gT8~e?NLM|71OHN-nT5xjI-^nS|D9mfnURd@abC+|jqI>nZ`HJNa9t?cdP3o^` zr>6vt)K)!>?tfU^vXfuN2(N5C6?i^#@6+Twq%N?w5n+xTN=zPqxHyIvVWwf7n zXROZk={y>n Date: Sat, 30 Jul 2022 15:49:02 +0200 Subject: [PATCH 14/32] Changed size of third column --- I18N Commander/UI WinForms/Components/Setting.Designer.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Setting.Designer.cs b/I18N Commander/UI WinForms/Components/Setting.Designer.cs index d78d7dd..50e35a5 100644 --- a/I18N Commander/UI WinForms/Components/Setting.Designer.cs +++ b/I18N Commander/UI WinForms/Components/Setting.Designer.cs @@ -40,9 +40,8 @@ this.tableLayout.ColumnCount = 4; this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 66F)); this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 250F)); - this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 220F)); + this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 300F)); this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tableLayout.Controls.Add(this.labelExplanation, 3, 0); this.tableLayout.Controls.Add(this.labelSettingName, 1, 0); this.tableLayout.Controls.Add(this.labelIcon, 0, 0); @@ -59,9 +58,9 @@ // this.labelExplanation.AutoSize = true; this.labelExplanation.Dock = System.Windows.Forms.DockStyle.Fill; - this.labelExplanation.Location = new System.Drawing.Point(539, 0); + this.labelExplanation.Location = new System.Drawing.Point(619, 0); this.labelExplanation.Name = "labelExplanation"; - this.labelExplanation.Size = new System.Drawing.Size(458, 72); + this.labelExplanation.Size = new System.Drawing.Size(378, 72); this.labelExplanation.TabIndex = 1; this.labelExplanation.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // From 87c12de06636a593710654f8dad24eb13d733225 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 15:49:19 +0200 Subject: [PATCH 15/32] Added DeepL API key setting --- .../DataModel/Database/SettingNames.cs | 1 + I18N Commander/Processor/AppSettings.cs | 56 +++++++++++++++++++ .../UI WinForms/Components/Setting.cs | 28 +++++++++- 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/I18N Commander/DataModel/Database/SettingNames.cs b/I18N Commander/DataModel/Database/SettingNames.cs index b9fe29f..7a41b64 100644 --- a/I18N Commander/DataModel/Database/SettingNames.cs +++ b/I18N Commander/DataModel/Database/SettingNames.cs @@ -2,5 +2,6 @@ public static class SettingNames { + public static readonly string DEEPL_API_KEY = "DeepL API Key"; public static readonly string DEEPL_MODE = "DeepL Mode"; } \ No newline at end of file diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index ae6b7e9..b8b1f25 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -7,6 +7,8 @@ namespace Processor; public static class AppSettings { + #region DeepL Mode + public static async Task SetDeepLMode(SettingDeepL mode) { // Convert the enum to its int value: @@ -57,4 +59,58 @@ public static class AppSettings return (SettingDeepL) setting.IntegerValue; } + + #endregion + + #region DeepL API Key + + public static async Task SetDeepLAPIKey(string apiKey) + { + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_API_KEY) is {} existingSetting) + { + existingSetting.TextValue = apiKey; + await db.SaveChangesAsync(); + } + + // Does not exist, so create it: + else + { + var setting = new Setting + { + Code = SettingNames.DEEPL_API_KEY, + TextValue = apiKey, + }; + + await db.Settings.AddAsync(setting); + await db.SaveChangesAsync(); + } + } + + public static async Task GetDeepLAPIKey() + { + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_API_KEY) is { } existingSetting) + return existingSetting.TextValue; + + // Does not exist, so create it: + var setting = new Setting + { + Code = SettingNames.DEEPL_API_KEY, + TextValue = string.Empty, + }; + + await db.Settings.AddAsync(setting); + await db.SaveChangesAsync(); + + return setting.TextValue; + } + + #endregion } \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index f0a1bd6..d4ca5a3 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -45,7 +45,7 @@ public partial class Setting : UserControl Func SetupDataControl ); - private static async Task ShowDeepLSettingAsync() + private static async Task ShowDeepLModeSettingAsync() { var currentSetting = await AppSettings.GetDeepLMode(); var settingData = new SettingUIData( @@ -91,8 +91,32 @@ public partial class Setting : UserControl }; } + private static async Task ShowDeepLAPIKeySettingAsync() + { + var currentSetting = await AppSettings.GetDeepLAPIKey(); + var settingData = new SettingUIData( + Icon: Icons.icons8_key_512, + SettingName: () => "DeepL API Key", + SettingExplanation: () => "The API key is required to use the DeepL translation service. You can find your API key on the DeepL website.", + SetupDataControl: () => + { + var textbox = new TextBox(); + textbox.Text = currentSetting; + textbox.TextChanged += async (sender, args) => await AppSettings.SetDeepLAPIKey(textbox.Text); + textbox.Dock = DockStyle.Fill; + return textbox; + } + ); + + return new Setting(settingData) + { + Dock = DockStyle.Top, + }; + } + public static IEnumerable> GetAllSettings() { - yield return ShowDeepLSettingAsync(); + yield return ShowDeepLAPIKeySettingAsync(); + yield return ShowDeepLModeSettingAsync(); } } \ No newline at end of file From b74367aa6f9221270ef28763640901a55ce07f30 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 16:09:58 +0200 Subject: [PATCH 16/32] Renamed DeepL mode setting --- .../{SettingDeepL.cs => SettingDeepLMode.cs} | 2 +- I18N Commander/Processor/AppSettings.cs | 10 +++++----- I18N Commander/UI WinForms/Components/Setting.cs | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) rename I18N Commander/DataModel/Database/{SettingDeepL.cs => SettingDeepLMode.cs} (72%) diff --git a/I18N Commander/DataModel/Database/SettingDeepL.cs b/I18N Commander/DataModel/Database/SettingDeepLMode.cs similarity index 72% rename from I18N Commander/DataModel/Database/SettingDeepL.cs rename to I18N Commander/DataModel/Database/SettingDeepLMode.cs index 7101b11..d4f93d0 100644 --- a/I18N Commander/DataModel/Database/SettingDeepL.cs +++ b/I18N Commander/DataModel/Database/SettingDeepLMode.cs @@ -1,6 +1,6 @@ namespace DataModel.Database; -public enum SettingDeepL +public enum SettingDeepLMode { DISABLED, diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index b8b1f25..63f28f5 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -9,7 +9,7 @@ public static class AppSettings { #region DeepL Mode - public static async Task SetDeepLMode(SettingDeepL mode) + public static async Task SetDeepLMode(SettingDeepLMode mode) { // Convert the enum to its int value: var intValue = (int)mode; @@ -38,26 +38,26 @@ public static class AppSettings } } - public static async Task GetDeepLMode() + public static async Task GetDeepLMode() { // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_MODE) is { } existingSetting) - return (SettingDeepL) existingSetting.IntegerValue; + return (SettingDeepLMode) existingSetting.IntegerValue; // Does not exist, so create it: var setting = new Setting { Code = SettingNames.DEEPL_MODE, - IntegerValue = (int)SettingDeepL.DISABLED, + IntegerValue = (int)SettingDeepLMode.DISABLED, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); - return (SettingDeepL) setting.IntegerValue; + return (SettingDeepLMode) setting.IntegerValue; } #endregion diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index d4ca5a3..411c5bb 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -60,9 +60,9 @@ public partial class Setting : UserControl dropdown.Items.Add("Pro version"); dropdown.SelectedIndex = currentSetting switch { - SettingDeepL.DISABLED => 0, - SettingDeepL.USE_FREE_ACCOUNT => 1, - SettingDeepL.USE_PRO_ACCOUNT => 2, + SettingDeepLMode.DISABLED => 0, + SettingDeepLMode.USE_FREE_ACCOUNT => 1, + SettingDeepLMode.USE_PRO_ACCOUNT => 2, _ => 0, }; @@ -70,11 +70,11 @@ public partial class Setting : UserControl // Setup the change event handler: dropdown.SelectedValueChanged += async (sender, args) => await AppSettings.SetDeepLMode(dropdown.SelectedIndex switch { - 0 => SettingDeepL.DISABLED, - 1 => SettingDeepL.USE_FREE_ACCOUNT, - 2 => SettingDeepL.USE_PRO_ACCOUNT, + 0 => SettingDeepLMode.DISABLED, + 1 => SettingDeepLMode.USE_FREE_ACCOUNT, + 2 => SettingDeepLMode.USE_PRO_ACCOUNT, - _ => SettingDeepL.DISABLED, + _ => SettingDeepLMode.DISABLED, }); // Apply the desired layout: From 9cd735ad5c5cdaa20e7d436bf05b4f6b8f0b1414 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 16:38:07 +0200 Subject: [PATCH 17/32] Moved the dock setting into constructor --- .../UI WinForms/Components/Setting.Designer.cs | 2 +- I18N Commander/UI WinForms/Components/Setting.cs | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/I18N Commander/UI WinForms/Components/Setting.Designer.cs b/I18N Commander/UI WinForms/Components/Setting.Designer.cs index 50e35a5..c78b1e7 100644 --- a/I18N Commander/UI WinForms/Components/Setting.Designer.cs +++ b/I18N Commander/UI WinForms/Components/Setting.Designer.cs @@ -1,6 +1,6 @@ namespace UI_WinForms.Components { - partial class Setting + sealed partial class Setting { /// /// Required designer variable. diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index 411c5bb..e7a6966 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -4,7 +4,7 @@ using UI_WinForms.Resources; namespace UI_WinForms.Components; -public partial class Setting : UserControl +public sealed partial class Setting : UserControl { public Setting() { @@ -14,6 +14,7 @@ public partial class Setting : UserControl private Setting(SettingUIData settingMetaData) { this.InitializeComponent(); + this.Dock = DockStyle.Top; this.labelIcon.Image = settingMetaData.Icon; this.labelSettingName.Text = settingMetaData.SettingName(); this.labelExplanation.Text = settingMetaData.SettingExplanation(); @@ -85,10 +86,7 @@ public partial class Setting : UserControl } ); - return new Setting(settingData) - { - Dock = DockStyle.Top, - }; + return new Setting(settingData); } private static async Task ShowDeepLAPIKeySettingAsync() @@ -108,10 +106,7 @@ public partial class Setting : UserControl } ); - return new Setting(settingData) - { - Dock = DockStyle.Top, - }; + return new Setting(settingData); } public static IEnumerable> GetAllSettings() From c211c9ef6209dee5fb5363818fdba8961809c40e Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 16:38:38 +0200 Subject: [PATCH 18/32] Added DeepL action setting --- .../DataModel/Database/SettingDeepLAction.cs | 7 +++ .../DataModel/Database/SettingNames.cs | 1 + I18N Commander/Processor/AppSettings.cs | 55 ++++++++++++++++++ .../UI WinForms/Components/Setting.cs | 42 +++++++++++++ .../UI WinForms/Resources/Icons.Designer.cs | 10 ++++ .../UI WinForms/Resources/Icons.resx | 3 + .../Resources/icons8-play-512 (2).png | Bin 0 -> 2051 bytes 7 files changed, 118 insertions(+) create mode 100644 I18N Commander/DataModel/Database/SettingDeepLAction.cs create mode 100644 I18N Commander/UI WinForms/Resources/icons8-play-512 (2).png diff --git a/I18N Commander/DataModel/Database/SettingDeepLAction.cs b/I18N Commander/DataModel/Database/SettingDeepLAction.cs new file mode 100644 index 0000000..50312d7 --- /dev/null +++ b/I18N Commander/DataModel/Database/SettingDeepLAction.cs @@ -0,0 +1,7 @@ +namespace DataModel.Database; + +public enum SettingDeepLAction +{ + MANUAL, + AUTOMATIC_ALL, +} \ No newline at end of file diff --git a/I18N Commander/DataModel/Database/SettingNames.cs b/I18N Commander/DataModel/Database/SettingNames.cs index 7a41b64..d507d63 100644 --- a/I18N Commander/DataModel/Database/SettingNames.cs +++ b/I18N Commander/DataModel/Database/SettingNames.cs @@ -2,6 +2,7 @@ public static class SettingNames { + public static readonly string DEEPL_ACTION = "DeepL Action"; public static readonly string DEEPL_API_KEY = "DeepL API Key"; public static readonly string DEEPL_MODE = "DeepL Mode"; } \ No newline at end of file diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index 63f28f5..1d97a66 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -113,4 +113,59 @@ public static class AppSettings } #endregion + + #region DeepL Action + + public static async Task SetDeepLAction(SettingDeepLAction action) + { + // Convert the enum to its int value: + var intValue = (int)action; + + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_ACTION) is {} existingSetting) + { + existingSetting.IntegerValue = intValue; + await db.SaveChangesAsync(); + } + + // Does not exist, so create it: + else + { + var setting = new Setting + { + Code = SettingNames.DEEPL_ACTION, + IntegerValue = intValue, + }; + + await db.Settings.AddAsync(setting); + await db.SaveChangesAsync(); + } + } + + public static async Task GetDeepLAction() + { + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_ACTION) is { } existingSetting) + return (SettingDeepLAction) existingSetting.IntegerValue; + + // Does not exist, so create it: + var setting = new Setting + { + Code = SettingNames.DEEPL_ACTION, + IntegerValue = (int)SettingDeepLAction.MANUAL, + }; + + await db.Settings.AddAsync(setting); + await db.SaveChangesAsync(); + + return (SettingDeepLAction) setting.IntegerValue; + } + + #endregion } \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index e7a6966..6bff82f 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -108,9 +108,51 @@ public sealed partial class Setting : UserControl return new Setting(settingData); } + + private static async Task ShowDeepLActionSettingAsync() + { + var currentSetting = await AppSettings.GetDeepLAction(); + var settingData = new SettingUIData( + Icon: Icons.icons8_play_512__2_, + SettingName: () => "DeepL Operation", + SettingExplanation: () => "Should the missing translations be automatically completed by DeepL? This can lead to higher costs. By default, DeepL is only applied manually.", + SetupDataControl: () => + { + // We set up a combo box with the available actions: + var dropdown = new ComboBox(); + dropdown.Items.Add("Manual"); + dropdown.Items.Add("Automatic"); + dropdown.SelectedIndex = currentSetting switch + { + SettingDeepLAction.MANUAL => 0, + SettingDeepLAction.AUTOMATIC_ALL => 1, + + _ => 0, + }; + + // Setup the change event handler: + dropdown.SelectedValueChanged += async (sender, args) => await AppSettings.SetDeepLAction(dropdown.SelectedIndex switch + { + 0 => SettingDeepLAction.MANUAL, + 1 => SettingDeepLAction.AUTOMATIC_ALL, + + _ => SettingDeepLAction.MANUAL, + }); + + // Apply the desired layout: + dropdown.Dock = DockStyle.Fill; + dropdown.DropDownStyle = ComboBoxStyle.DropDownList; + + return dropdown; + } + ); + + return new Setting(settingData); + } public static IEnumerable> GetAllSettings() { + yield return ShowDeepLActionSettingAsync(); yield return ShowDeepLAPIKeySettingAsync(); yield return ShowDeepLModeSettingAsync(); } diff --git a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs index bb5ab78..f0d5fcd 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs +++ b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs @@ -200,6 +200,16 @@ namespace UI_WinForms.Resources { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap icons8_play_512__2_ { + get { + object obj = ResourceManager.GetObject("icons8_play_512__2_", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/I18N Commander/UI WinForms/Resources/Icons.resx b/I18N Commander/UI WinForms/Resources/Icons.resx index e4db609..a18a78c 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.resx +++ b/I18N Commander/UI WinForms/Resources/Icons.resx @@ -160,6 +160,9 @@ icons8-open-file-under-cursor-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + icons8-play-512 (2).png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + icons8-remove-tag-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/I18N Commander/UI WinForms/Resources/icons8-play-512 (2).png b/I18N Commander/UI WinForms/Resources/icons8-play-512 (2).png new file mode 100644 index 0000000000000000000000000000000000000000..03d329fdcc8fe1392c7035d4e444c1755a523767 GIT binary patch literal 2051 zcmah~2~ZPf6b==tATZ!Ty-JsGR%LT=nV6Uo!Vw@029$sd8j>YhA=$XukOVt%{)7p~a(G`X@n9(Ka)iHUfS=XWQB0?mHW=b#xES6%a2&_}608S#Y zI69SBl8z8iDk4LbZ1PA;8yP~SY;r|1PXuyU@Cc)9mK+=X-pw6Y{D3< z*kn0DsF)OrR;z`zelUj1C^QCxL7~zqbh}KxC9B!M3jWP zITNP5F!>6x42edRGD6NK`v<%OB%soF_f0|>8dD|KC{f^=K4l`B!r0^>I)yd`CB7Fj zrJ5Ow>W~Z(4^<#aHBg<5VhT+B02qR0V0av8YlKa<_?oN((~Jo)DS-UUVN5~%kdRm$ zOG7gNrWS^CA%18`AdL|i=u3w!GN5QoV2h^dd13;v=v2^~)F59!YCJ8FNe^QBQI}Ea zOe)o^Y-WSIAQcnh|KpoF8e#zpfq)r-stF9&o3|`&9*1nQtSrk6)ZE_?WUew(EHP!B zO;+KUR3ky8X6Hc8f~v7JLMz6RU>PVdn;e{$hJyO&p;%MrLNu60g)P;cw9v{Cp!VUj zQ6?gzm~Pzb&{&jd!L!VSH?AnKv+RMZ4`v8ua)^M%(4^4X=?)ezCmXTsOHTO0GvLOwg8y{V_%xAC467Z?j}ELY==`YW zW|My3E8CTo{)U*ic!RO}iG17fu`R`yO0K6gto=(po^(-|oX{@xW}W;lDMgp8!#!)u z&w2JA|E4PHg7*bi0qm14d00>99IRMAdhBwN$2{xwhPq|XizRI$KDtn>XFQH>KK!!3 zE4#@3P^E3u@SKq^ygL?HB}Y@aPMlZvmxsHG%Tf|od$x_N%q_3DyOe%noM7`VdYgf$J=s@b7!>TnsCy_&m4X`yLk9uY%jH>Y{o^OPxBsGU2E9$vVWC* zYf1;6HB}V>IV?AI~;= z4i9t7Dzxwxs}zImj-WEX5xg#JRS}755^45a(_=*{uUG&|l+Nb`$BPOcU9aD0j9t=x zyLRoF*qJ%AZ0@@TIWOsOtsvr8l;&7hHa{mRVc2jAUiziWw|g9$dHoN6{iH76X8sAs zeaj<93U=@A`#n3oo5SJaG2AugPk@nojqi3e{6^>BHHy+7y{=|19X)sO#)YsQgTftX z^@g74CPUqhzGvHxxg9k+^`ss+IatVhdhIrxBJu7Zn%b{a<6jLrF6&yds$({*OL;wz z~ycc+tI}# z>u>0JPvL=5{>z`7dM-Kj9HHdrw<^UcxJDb>Ca^PeGYzsP|sf`KIyDonJZB zKC#E{|B=J?c+u@K<~G*S_&mi6ZR~&G%TjT3VM{iQ_PJIM^OGX|MeZ9-?{0o*46lZ} GA@5&^UiNDM literal 0 HcmV?d00001 From 90be288d176133ef90f1efaac09d2ad82478c702 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 17:04:32 +0200 Subject: [PATCH 19/32] Added setting cache --- I18N Commander/Processor/AppSettings.cs | 42 +++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index 1d97a66..90f1f94 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -9,11 +9,18 @@ public static class AppSettings { #region DeepL Mode + private static SettingDeepLMode CACHE_DEEPL_MODE = SettingDeepLMode.DISABLED; + private static bool CACHE_DEEPL_MODE_IS_LOADED = false; + public static async Task SetDeepLMode(SettingDeepLMode mode) { // Convert the enum to its int value: var intValue = (int)mode; + // Update the cache: + CACHE_DEEPL_MODE = mode; + CACHE_DEEPL_MODE_IS_LOADED = true; + // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); @@ -40,6 +47,9 @@ public static class AppSettings public static async Task GetDeepLMode() { + if (CACHE_DEEPL_MODE_IS_LOADED) + return CACHE_DEEPL_MODE; + // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); @@ -57,15 +67,26 @@ public static class AppSettings await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); - return (SettingDeepLMode) setting.IntegerValue; + var mode = (SettingDeepLMode) setting.IntegerValue; + CACHE_DEEPL_MODE = mode; + CACHE_DEEPL_MODE_IS_LOADED = true; + + return mode; } #endregion #region DeepL API Key + private static string CACHE_DEEPL_API_KEY = string.Empty; + private static bool CACHE_DEEPL_API_KEY_IS_LOADED = false; + public static async Task SetDeepLAPIKey(string apiKey) { + // Update the cache: + CACHE_DEEPL_API_KEY = apiKey; + CACHE_DEEPL_API_KEY_IS_LOADED = true; + // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); @@ -109,18 +130,29 @@ public static class AppSettings await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); - return setting.TextValue; + var key = setting.TextValue; + CACHE_DEEPL_API_KEY = key; + CACHE_DEEPL_API_KEY_IS_LOADED = true; + + return key; } #endregion #region DeepL Action + private static SettingDeepLAction CACHE_DEEPL_ACTION = SettingDeepLAction.MANUAL; + private static bool CACHE_DEEPL_ACTION_IS_LOADED = false; + public static async Task SetDeepLAction(SettingDeepLAction action) { // Convert the enum to its int value: var intValue = (int)action; + // Update the cache: + CACHE_DEEPL_ACTION = action; + CACHE_DEEPL_ACTION_IS_LOADED = true; + // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); @@ -164,7 +196,11 @@ public static class AppSettings await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); - return (SettingDeepLAction) setting.IntegerValue; + var action = (SettingDeepLAction) setting.IntegerValue; + CACHE_DEEPL_ACTION = action; + CACHE_DEEPL_ACTION_IS_LOADED = true; + + return action; } #endregion From f27366e0a230d4c5c1dbd2cf281534e1d6479ddd Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 23:07:04 +0200 Subject: [PATCH 20/32] Added culture settings --- .../DataModel/Database/SettingNames.cs | 1 + I18N Commander/Processor/AppSettings.cs | 78 +++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/I18N Commander/DataModel/Database/SettingNames.cs b/I18N Commander/DataModel/Database/SettingNames.cs index d507d63..d59e7d9 100644 --- a/I18N Commander/DataModel/Database/SettingNames.cs +++ b/I18N Commander/DataModel/Database/SettingNames.cs @@ -2,6 +2,7 @@ public static class SettingNames { + public static readonly string CULTURE = "Culture"; public static readonly string DEEPL_ACTION = "DeepL Action"; public static readonly string DEEPL_API_KEY = "DeepL API Key"; public static readonly string DEEPL_MODE = "DeepL Mode"; diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index 90f1f94..a5eee75 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -7,6 +7,8 @@ namespace Processor; public static class AppSettings { + #region DeepL Settings + #region DeepL Mode private static SettingDeepLMode CACHE_DEEPL_MODE = SettingDeepLMode.DISABLED; @@ -204,4 +206,80 @@ public static class AppSettings } #endregion + + #endregion + + #region Translation Settings + + #region Number of cultures + + public static async Task GetNumberCultures() + { + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Count the number of cultures: + var count = await db.Settings.CountAsync(n => n.Code == SettingNames.CULTURE); + + // We have at least one default culture: + if(count == 0) + return 1; + + return count; + } + + #endregion + + #region Get a culture + + public static async Task GetCultureCode(int index) + { + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Get the culture code: + var code = await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.CULTURE && n.IntegerValue == index); + + // When the culture code is not set, fake the default culture as en-US: + if(code == null) + return "en-US"; + + // Return the code: + return code.TextValue; + } + + #endregion + + #region Set a culture + + public static async Task SetCultureCode(int index, string code) + { + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.CULTURE && n.IntegerValue == index) is {} existingSetting) + { + existingSetting.TextValue = code; + await db.SaveChangesAsync(); + } + + // Does not exist, so create it: + else + { + var setting = new Setting + { + Code = SettingNames.CULTURE, + IntegerValue = index, + TextValue = code, + }; + + await db.Settings.AddAsync(setting); + await db.SaveChangesAsync(); + } + } + + #endregion + + #endregion } \ No newline at end of file From 276fa51e92627f47e4743b9d8664672f56205d4a Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 23:14:39 +0200 Subject: [PATCH 21/32] Added caching to the cultures --- I18N Commander/Processor/AppSettings.cs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index a5eee75..555731d 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -232,20 +232,32 @@ public static class AppSettings #region Get a culture + // Cache the cultures: + private static readonly Dictionary CACHE_CULTURES = new(); + public static async Task GetCultureCode(int index) { + // Check the cache: + if (CACHE_CULTURES.TryGetValue(index, out var cultureCode)) + return cultureCode; + // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Get the culture code: var code = await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.CULTURE && n.IntegerValue == index); - // When the culture code is not set, fake the default culture as en-US: - if(code == null) + // When the culture code is not set & index = 1, use the default culture en-US: + if(code is null && index == 1) + { + CACHE_CULTURES.Add(index, "en-US"); return "en-US"; + } - // Return the code: - return code.TextValue; + // Update the cache & return the code: + var codeText = code?.TextValue ?? string.Empty; + CACHE_CULTURES[index] = codeText; + return codeText; } #endregion @@ -254,6 +266,9 @@ public static class AppSettings public static async Task SetCultureCode(int index, string code) { + // Update the cache: + CACHE_CULTURES[index] = code; + // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); From 9419642525742c58acb3bd72c077f6015e3b467f Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 23:17:57 +0200 Subject: [PATCH 22/32] Added cache to the number of cultures --- I18N Commander/Processor/AppSettings.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index 555731d..b99d94d 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -212,9 +212,15 @@ public static class AppSettings #region Translation Settings #region Number of cultures + + private static int CACHE_NUMBER_OF_CULTURES = -1; public static async Task GetNumberCultures() { + // When possible, use the cache: + if (CACHE_NUMBER_OF_CULTURES > -1) + return CACHE_NUMBER_OF_CULTURES; + // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); @@ -223,8 +229,12 @@ public static class AppSettings // We have at least one default culture: if(count == 0) + { + CACHE_NUMBER_OF_CULTURES = 1; return 1; + } + CACHE_NUMBER_OF_CULTURES = count; return count; } @@ -291,6 +301,10 @@ public static class AppSettings await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); + + // Update the number of cultures cache: + if(CACHE_NUMBER_OF_CULTURES > -1) + CACHE_NUMBER_OF_CULTURES++; } } From 38416cb6756d70f3c1e320a289b2c437d214c628 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 23:34:45 +0200 Subject: [PATCH 23/32] Implemented adding of additional cultures --- .../Components/Settings.Designer.cs | 47 +++++++++++++++++- .../UI WinForms/Components/Settings.cs | 29 ++++++++--- .../UI WinForms/Components/Settings.resx | 3 ++ .../UI WinForms/Resources/Icons.Designer.cs | 10 ++++ .../UI WinForms/Resources/Icons.resx | 3 ++ .../Resources/icons8-collectibles-512.png | Bin 0 -> 2529 bytes 6 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 I18N Commander/UI WinForms/Resources/icons8-collectibles-512.png diff --git a/I18N Commander/UI WinForms/Components/Settings.Designer.cs b/I18N Commander/UI WinForms/Components/Settings.Designer.cs index 3b0c22b..e38eb64 100644 --- a/I18N Commander/UI WinForms/Components/Settings.Designer.cs +++ b/I18N Commander/UI WinForms/Components/Settings.Designer.cs @@ -28,11 +28,16 @@ /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); this.tableLayout = new System.Windows.Forms.TableLayoutPanel(); this.labelHeadIcon = new System.Windows.Forms.Label(); this.labelHead = new System.Windows.Forms.Label(); this.panelSettings = new System.Windows.Forms.Panel(); + this.flowLayoutToolbar = new System.Windows.Forms.FlowLayoutPanel(); + this.buttonAddCulture = new System.Windows.Forms.Button(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.tableLayout.SuspendLayout(); + this.flowLayoutToolbar.SuspendLayout(); this.SuspendLayout(); // // tableLayout @@ -43,12 +48,14 @@ this.tableLayout.Controls.Add(this.labelHeadIcon, 0, 0); this.tableLayout.Controls.Add(this.labelHead, 1, 0); this.tableLayout.Controls.Add(this.panelSettings, 0, 1); + this.tableLayout.Controls.Add(this.flowLayoutToolbar, 0, 2); this.tableLayout.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayout.Location = new System.Drawing.Point(0, 0); this.tableLayout.Name = "tableLayout"; - this.tableLayout.RowCount = 2; + this.tableLayout.RowCount = 3; this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 66F)); this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 66F)); this.tableLayout.Size = new System.Drawing.Size(1001, 381); this.tableLayout.TabIndex = 1; // @@ -83,9 +90,41 @@ this.panelSettings.Location = new System.Drawing.Point(0, 66); this.panelSettings.Margin = new System.Windows.Forms.Padding(0); this.panelSettings.Name = "panelSettings"; - this.panelSettings.Size = new System.Drawing.Size(1001, 315); + this.panelSettings.Size = new System.Drawing.Size(1001, 249); this.panelSettings.TabIndex = 2; // + // flowLayoutToolbar + // + this.tableLayout.SetColumnSpan(this.flowLayoutToolbar, 2); + this.flowLayoutToolbar.Controls.Add(this.buttonAddCulture); + this.flowLayoutToolbar.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutToolbar.Location = new System.Drawing.Point(0, 315); + this.flowLayoutToolbar.Margin = new System.Windows.Forms.Padding(0); + this.flowLayoutToolbar.Name = "flowLayoutToolbar"; + this.flowLayoutToolbar.Size = new System.Drawing.Size(1001, 66); + this.flowLayoutToolbar.TabIndex = 3; + // + // buttonAddCulture + // + this.buttonAddCulture.FlatAppearance.BorderSize = 0; + this.buttonAddCulture.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.buttonAddCulture.Image = global::UI_WinForms.Resources.Icons.icons8_collectibles_512; + this.buttonAddCulture.Location = new System.Drawing.Point(3, 3); + this.buttonAddCulture.Name = "buttonAddCulture"; + this.buttonAddCulture.Size = new System.Drawing.Size(60, 60); + this.buttonAddCulture.TabIndex = 0; + this.toolTip.SetToolTip(this.buttonAddCulture, "Add another culture"); + this.buttonAddCulture.UseVisualStyleBackColor = true; + this.buttonAddCulture.Click += new System.EventHandler(this.buttonAddCulture_Click); + // + // toolTip + // + this.toolTip.AutoPopDelay = 30000; + this.toolTip.InitialDelay = 500; + this.toolTip.ReshowDelay = 100; + this.toolTip.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info; + this.toolTip.ToolTipTitle = "Help"; + // // Settings // this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); @@ -96,6 +135,7 @@ this.Size = new System.Drawing.Size(1001, 381); this.tableLayout.ResumeLayout(false); this.tableLayout.PerformLayout(); + this.flowLayoutToolbar.ResumeLayout(false); this.ResumeLayout(false); } @@ -106,5 +146,8 @@ private Label labelHeadIcon; private Label labelHead; private Panel panelSettings; + private FlowLayoutPanel flowLayoutToolbar; + private ToolTip toolTip; + private Button buttonAddCulture; } } diff --git a/I18N Commander/UI WinForms/Components/Settings.cs b/I18N Commander/UI WinForms/Components/Settings.cs index dcbef4c..cb6f551 100644 --- a/I18N Commander/UI WinForms/Components/Settings.cs +++ b/I18N Commander/UI WinForms/Components/Settings.cs @@ -1,14 +1,31 @@ -namespace UI_WinForms.Components; +using Processor; + +namespace UI_WinForms.Components; public partial class Settings : UserControl { public Settings() { this.InitializeComponent(); - this.Load += async (sender, args) => - { - foreach (var setting in Setting.GetAllSettings()) - this.panelSettings.Controls.Add(await setting); - }; + this.Load += async (sender, args) => await this.LoadAllSettings(); + } + + private async Task LoadAllSettings() + { + this.panelSettings.Controls.Clear(); + foreach (var setting in Setting.GetAllSettings()) + this.panelSettings.Controls.Add(await setting); + } + + private async void buttonAddCulture_Click(object sender, EventArgs e) + { + // Get the current number of cultures: + var numberCultures = await AppSettings.GetNumberCultures(); + + // Add a new culture: + await AppSettings.SetCultureCode(++numberCultures, string.Empty); + + // Reload all settings: + await this.LoadAllSettings(); } } diff --git a/I18N Commander/UI WinForms/Components/Settings.resx b/I18N Commander/UI WinForms/Components/Settings.resx index b5ae26c..99de901 100644 --- a/I18N Commander/UI WinForms/Components/Settings.resx +++ b/I18N Commander/UI WinForms/Components/Settings.resx @@ -57,4 +57,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs index f0d5fcd..6a7f135 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs +++ b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs @@ -120,6 +120,16 @@ namespace UI_WinForms.Resources { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap icons8_collectibles_512 { + get { + object obj = ResourceManager.GetObject("icons8_collectibles_512", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/I18N Commander/UI WinForms/Resources/Icons.resx b/I18N Commander/UI WinForms/Resources/Icons.resx index a18a78c..e23ca7c 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.resx +++ b/I18N Commander/UI WinForms/Resources/Icons.resx @@ -136,6 +136,9 @@ icons8-cancel-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + icons8-collectibles-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + icons8-delete-folder-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/I18N Commander/UI WinForms/Resources/icons8-collectibles-512.png b/I18N Commander/UI WinForms/Resources/icons8-collectibles-512.png new file mode 100644 index 0000000000000000000000000000000000000000..929c2a4389e64a58b748b042223bcf2a98ecb1c4 GIT binary patch literal 2529 zcmai030PBC77j~`f-Iudh+BBUU9y6bKwyAqWeFmo5Eciryd*D>ypRMEtn8I4)Fu6p z)v72|hE0WvB3MunY6L+UT#6tSq@buUj4aCM%uAq9tIp*6UXpwN|NQ6NbIv`<0bidl zO^vOLQ7DwD#}2w5@@cDm=6#O5Q>~ulqELqCAb*yE#qg$bVKI))gE=5hC6*#M3gzUY zlCrrGpaR1I1(1XWysD`KFc6Oh1lltQ45>RPgm&zafy_NV{@gtgTnZ0xaW-~RQ4s+# zs9QUwG{ zFj`GE2aZ1+8U$*)4pcwK-FOkn1?`QT^Mta zhr7G44CX_T2qyRY(hcLW&3y}zvSo`c2{$c+6pf15Li|`dTY<1h1f(|!TW!e%e-fEW za-fnan+PN-fuK{?v5~vLV=LJIkFV`$j1ywPU{H5Jas@1l)oo3;ITMVUUQI6}AzgoC zFuE#J*<5YbX@FD)^P;&RPv;zwn?~g@U!i2nKvw}$U>e}c=R-(+Vllqj&czUML;`NQ zy0aEaA&97b`fT`_$ne@5_eW?>_z!}2(h>f2MG?E{J>=>mGXy_7M3BYo7y>28?2#cu zCL{Oo1PY~>1R-Vlpd2XFdUdqAbrXHp;wBfeJJ!W&Uq!YZ#4b5rTezIO&gmvveg$wsgy4f)YAg%m%Gvk{gXtk2ntZEnBD~@{^7Lj%%`m@cZ*G{Ju zKi#)(-NFX>7eWen`~#ReDHJZvaCU|4(nZ(itM%k!iD z@u*Vc+%#?xoOSkcau;pj=;)!Rt7S!k=hyjJp~$breCduLISOU6Nc-raa*v@=C<9Lq zx~o5H--~Q7cu^oa^#obouezOsPG+W9Gt`#W8!aOItR+xr}+skfStx_DAuI}+Qv_i)`L z-^mJ1>T7o^=pw|8ywU41sn_KHY(7Q#`dxFcU7n@a&am2d6zLZZIewexD-&}bjtbuS zSo*Y=G3yU_dycFKbBqTpqu)GgdE6-KC=Akj%*!q^G&CG88B1%=N^qFmh+7#k++OBb zlhj!s*hg;KHBlee^Y6k}b@6xb+4LulJ-*k5-iDWTP*yG->KxppJmJ&vI3U4#-l0Bl zNxDT{P2<~lcfUjZucEheK&C%V5J>6=-7W9nQkQ4Vpr6TteiEoPw2wK+~z^8`j+5s7Ewrk)5BPw4`>gny2$&jaog3D!RY?r>T3X7oI$u8ugP)%!K+&8y1Xr zmqlL;ca$!cdbLnITdEsm2H~O?Oan=2*hE{aruxXO#}4%(6Vbte=-sHC_`P3$pRTwv z-~4zz$DUdV8k)T{+S+M)IwiEAtr~=*;{?#h?LGv5ytgpCD1dGTEE%sa(%#5c`tP+z)zH2LKNi{mxV`b^Ez$PJy o=+Ld7uzy*AOVuw&tW)}2IHmckiz=HoYyX*fZ1bU)yM-tJ7wQ%9NdN!< literal 0 HcmV?d00001 From c9bd1b5be92ab164de17c87065dac84a1d3cda14 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 30 Jul 2022 23:38:01 +0200 Subject: [PATCH 24/32] Fixed cache handling for DeepL action & API key --- I18N Commander/Processor/AppSettings.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index b99d94d..5d07220 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -115,6 +115,10 @@ public static class AppSettings public static async Task GetDeepLAPIKey() { + // Check the cache: + if (CACHE_DEEPL_API_KEY_IS_LOADED) + return CACHE_DEEPL_API_KEY; + // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); @@ -181,6 +185,10 @@ public static class AppSettings public static async Task GetDeepLAction() { + // Check the cache: + if (CACHE_DEEPL_ACTION_IS_LOADED) + return CACHE_DEEPL_ACTION; + // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); From a47b18b7a8bc3e07fc685869d374536f60700f61 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sun, 31 Jul 2022 21:19:13 +0200 Subject: [PATCH 25/32] Fixed culture code handling --- I18N Commander/Processor/AppSettings.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index 5d07220..8951fd2 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -233,7 +233,7 @@ public static class AppSettings await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Count the number of cultures: - var count = await db.Settings.CountAsync(n => n.Code == SettingNames.CULTURE); + var count = await db.Settings.CountAsync(n => n.Code.StartsWith(SettingNames.CULTURE)); // We have at least one default culture: if(count == 0) @@ -263,7 +263,7 @@ public static class AppSettings await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Get the culture code: - var code = await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.CULTURE && n.IntegerValue == index); + var code = await db.Settings.FirstOrDefaultAsync(n => n.Code.StartsWith(SettingNames.CULTURE) && n.IntegerValue == index); // When the culture code is not set & index = 1, use the default culture en-US: if(code is null && index == 1) @@ -291,7 +291,7 @@ public static class AppSettings await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: - if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.CULTURE && n.IntegerValue == index) is {} existingSetting) + if (await db.Settings.FirstOrDefaultAsync(n => n.Code.StartsWith(SettingNames.CULTURE) && n.IntegerValue == index) is {} existingSetting) { existingSetting.TextValue = code; await db.SaveChangesAsync(); @@ -302,7 +302,7 @@ public static class AppSettings { var setting = new Setting { - Code = SettingNames.CULTURE, + Code = $"{SettingNames.CULTURE} {index}", IntegerValue = index, TextValue = code, }; From fa112de26d0636456ab815eb0cd20257a309c1fb Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sun, 31 Jul 2022 21:19:54 +0200 Subject: [PATCH 26/32] Added the culture setting entries --- .../UI WinForms/Components/Setting.cs | 55 ++++++++++++++++++ .../UI WinForms/Resources/Icons.Designer.cs | 10 ++++ .../UI WinForms/Resources/Icons.resx | 3 + .../Resources/icons8-chat-bubble-512.png | Bin 0 -> 2239 bytes 4 files changed, 68 insertions(+) create mode 100644 I18N Commander/UI WinForms/Resources/icons8-chat-bubble-512.png diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index 6bff82f..87dc1a4 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -150,8 +150,63 @@ public sealed partial class Setting : UserControl return new Setting(settingData); } + private static IEnumerable> ShowCultureSettingsAsync() + { + var isFirstCulture = true; // We need this flag to distinguish the first task from the others. + var numberOfCultures = int.MaxValue; // There is always at least one culture, which is the default culture. We update this value later, out of the tasks. + while (numberOfCultures > 0) + { + var innerLoopIndex = numberOfCultures; // needed to avoid closure issues. + yield return Task.Run(async () => + { + var localCultureIndex = innerLoopIndex; + + // Get the total number of cultures. We cannot do this in the outer loop, + // because we cannot await there. The AppSettings is caching the answer, though. + var numberCultures = await AppSettings.GetNumberCultures(); + + // Update the number of cultures in the outer loop for the first call: + if(isFirstCulture) + { + localCultureIndex = numberCultures; + numberOfCultures = numberCultures; + isFirstCulture = false; + } + + // Get the current culture code: + var currentCultureCode = await AppSettings.GetCultureCode(localCultureIndex); + + // Construct the setting: + return new Setting(new() + { + Icon = Icons.icons8_chat_bubble_512, + SettingName = () => $"{localCultureIndex}. Culture", + SettingExplanation = () => "The culture according to RFC 4646: First comes the ISO 639-1 language code in lower case, followed by a hyphen, followed by the ISO 3166-1 alpha-2 country code in upper case. Example: en-US for English in the USA, de-DE for German in Germany.", + SetupDataControl = () => + { + var textbox = new TextBox(); + textbox.Text = currentCultureCode; + textbox.TextChanged += async (sender, args) => + { + await AppSettings.SetCultureCode(localCultureIndex, textbox.Text); + }; + textbox.Dock = DockStyle.Fill; + return textbox; + } + }); + }); + + numberOfCultures--; + } + } + public static IEnumerable> GetAllSettings() { + foreach (var setting in ShowCultureSettingsAsync()) + { + yield return setting; + } + yield return ShowDeepLActionSettingAsync(); yield return ShowDeepLAPIKeySettingAsync(); yield return ShowDeepLModeSettingAsync(); diff --git a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs index 6a7f135..7f3e9af 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs +++ b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs @@ -120,6 +120,16 @@ namespace UI_WinForms.Resources { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap icons8_chat_bubble_512 { + get { + object obj = ResourceManager.GetObject("icons8_chat_bubble_512", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/I18N Commander/UI WinForms/Resources/Icons.resx b/I18N Commander/UI WinForms/Resources/Icons.resx index e23ca7c..6b0ceae 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.resx +++ b/I18N Commander/UI WinForms/Resources/Icons.resx @@ -136,6 +136,9 @@ icons8-cancel-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + icons8-chat-bubble-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + icons8-collectibles-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/I18N Commander/UI WinForms/Resources/icons8-chat-bubble-512.png b/I18N Commander/UI WinForms/Resources/icons8-chat-bubble-512.png new file mode 100644 index 0000000000000000000000000000000000000000..2fa61023d89f32ab92a8a085e747b11248fadf66 GIT binary patch literal 2239 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK1|+Sd9?fE4VA+rv5>XQ2>tmIipR1RclAn~S zSCLx)lxJYDv9BmdOwLX%QAkQn&&;z`dcS+Wl0s&Rtx~wDuYqrYb81GWM^#a3aFt(3 za#eP+Wr~u$9hXgo70`g()RIJnirk#MVyg;UC9t_xKsHENUr7P1q$Jx`DZ)2E!8yMu zRl!uxRL?-kj!VI&C?(A*$i)q+8OXC$$|xx*u+rBrFE7_CH`dE9O4m2Ew6xSWFw!?N z(gmu}Ew0QfNvzP#D^>;>0WrfRwK%ybv!En1KTiQQ?NYIsRz8p8Cv zVyO3l0ih3)(KpmH&_`CDT9JuEIYnD>p{1Fbu8|(Z7+|DX0rh64Rk|dW096?o0Mn*{xvsHch@qL4 zfuWVLfwqB>m4N}+WUy*rUPwtSNhG8ml%f@EfI57AtvoV|OY(~LsCa0!=Ee9G0kuAMf`%b3A!9zN*zlhv~R7LQ|zhW zct*$i_uKsRw!4uVSc1Kx)|We4O}_jmIPQ2-#>vF$gKqq5uUwQ0D=F18kX*8?_MZ2g z8*djxt}eT?|C&tiORg)XT>aXsrU}mzn-_a}rP_Ora;=jEAwPU>tUSru`rgMj=u!A& zVbywGY+|0W#e#|`7-7Km0 z;bGzo!;f-og~lq@SxsjxwGu9MdOg0JP-F3Afwk>mL4LWz;i2d4t`-)MbOSL^+yg&DUAx~L zI;vJ;yDCvPX382P-H#S~<~n(ESmiCq+<9g5CrfpHftcy*ceU-Um6-5j+thgVTj?iD z#N)05YYWZ-kH}&M25w;xW@MN(M}mQYNyF2{F(jh(?bVH^g%V{Be0(4IqF~B{YtNKe z+Hc&}c=i8*n&2MYyH{?AZTTvGWdgs2g(X*8^A4}QGcG9d%JQwByl}~*=m5DNG0v)$ z^VY{bd>Q>+_Wk!eciY?BtvR@UZ4WZzEs5RFI)~xp2=%aSgq_@DL zXIZAorn{*g-PAA#O ztv^%0-{0$GhRLU%Z#6bjy=<3XPARbPS$^5kYp0R9@8qDBE;e$@@4ru;_3TuPm*?8B zWCMwWNU^tN)&F1I%yHX%^Nz*zpd<;lw#1wmV;R1c*I&oQ?|tJ{XAAeM=z{N8)St7S zuXmB3d?4F3@SYWWebYa#J?#7bu6;F0%z<4)tovwd@e9$vk`-Jw;!bO9&#d3G;C$n8 zhft2h{OCRB%UsVlRy%cUu1zY-y?x!8DZgR&ai+Gn*0pSR#GU5+ZoIkGH-o!^)keUn z=Htc9!L$30dp~$+*c5xY^zX5SypE3lqwh1uT-~Lhf8a$qsNLb|>gTe~DWM4fH_%6j literal 0 HcmV?d00001 From fd3d844df4ac965ec20f370d71a807c85cde13c8 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Mon, 1 Aug 2022 21:04:47 +0200 Subject: [PATCH 27/32] Implemented list of culture info & DeepL source culture --- .../DataModel/Database/SettingNames.cs | 1 + I18N Commander/Processor/AppSettings.cs | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/I18N Commander/DataModel/Database/SettingNames.cs b/I18N Commander/DataModel/Database/SettingNames.cs index d59e7d9..d4ee3fb 100644 --- a/I18N Commander/DataModel/Database/SettingNames.cs +++ b/I18N Commander/DataModel/Database/SettingNames.cs @@ -2,6 +2,7 @@ public static class SettingNames { + public static readonly string DEEPL_SOURCE_CULTURE = "DeepL Source Culture"; public static readonly string CULTURE = "Culture"; public static readonly string DEEPL_ACTION = "DeepL Action"; public static readonly string DEEPL_API_KEY = "DeepL API Key"; diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index 8951fd2..047897f 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -215,6 +215,73 @@ public static class AppSettings #endregion + #region DeepL Source Culture + + private static int CACHE_DEEPL_SOURCE_CULTURE = -1; + private static bool CACHE_DEEPL_SOURCE_CULTURE_IS_LOADED = false; + + public static async Task SetDeepLSourceCulture(int cultureIndex) + { + // Update the cache: + CACHE_DEEPL_SOURCE_CULTURE = cultureIndex; + CACHE_DEEPL_SOURCE_CULTURE_IS_LOADED = true; + + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_SOURCE_CULTURE) is {} existingSetting) + { + existingSetting.IntegerValue = cultureIndex; + await db.SaveChangesAsync(); + } + + // Does not exist, so create it: + else + { + var setting = new Setting + { + Code = SettingNames.DEEPL_SOURCE_CULTURE, + IntegerValue = cultureIndex, + }; + + await db.Settings.AddAsync(setting); + await db.SaveChangesAsync(); + } + } + + public static async Task GetDeepLSourceCultureIndex() + { + // Check the cache: + if (CACHE_DEEPL_SOURCE_CULTURE_IS_LOADED) + return CACHE_DEEPL_SOURCE_CULTURE; + + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_SOURCE_CULTURE) is { } existingSetting) + return existingSetting.IntegerValue; + + // Does not exist, so create it: + var setting = new Setting + { + Code = SettingNames.DEEPL_SOURCE_CULTURE, + IntegerValue = -1, + }; + + await db.Settings.AddAsync(setting); + await db.SaveChangesAsync(); + + var cultureIndex = setting.IntegerValue; + CACHE_DEEPL_SOURCE_CULTURE = cultureIndex; + CACHE_DEEPL_SOURCE_CULTURE_IS_LOADED = true; + + return cultureIndex; + } + + #endregion + #endregion #region Translation Settings @@ -318,5 +385,28 @@ public static class AppSettings #endregion + #region Get a list of cultures + + public readonly record struct CultureInfo(string Code, int Index); + + public static async Task> GetCultureInfos() + { + // Get the number of cultures: + var numberOfCultures = await AppSettings.GetNumberCultures(); + + // Get the culture codes: + var cultureInfos = new List(); + for (var i = 1; i <= numberOfCultures; i++) + cultureInfos.Add(new CultureInfo + { + Code = await AppSettings.GetCultureCode(i), + Index = i, + }); + + return cultureInfos; + } + + #endregion + #endregion } \ No newline at end of file From fee963f8bd6c70f090e43aec5842dab3032192ff Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 2 Aug 2022 20:41:55 +0200 Subject: [PATCH 28/32] Fixed culture setting handling for non-continuous indices --- I18N Commander/Processor/AppSettings.cs | 36 +++++++++---------- .../UI WinForms/Components/Setting.cs | 22 +++++++----- .../UI WinForms/Components/Settings.cs | 6 ++-- 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index 047897f..edd48cb 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -288,29 +288,30 @@ public static class AppSettings #region Number of cultures - private static int CACHE_NUMBER_OF_CULTURES = -1; + private static List CACHE_CULTURES_INDICES = new(); - public static async Task GetNumberCultures() + public static async Task> GetCultureIndices() { // When possible, use the cache: - if (CACHE_NUMBER_OF_CULTURES > -1) - return CACHE_NUMBER_OF_CULTURES; + if (CACHE_CULTURES_INDICES.Count > 0) + return CACHE_CULTURES_INDICES; // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Count the number of cultures: - var count = await db.Settings.CountAsync(n => n.Code.StartsWith(SettingNames.CULTURE)); + var list = await db.Settings.Where(n => n.Code.StartsWith(SettingNames.CULTURE)).OrderBy(n => n.IntegerValue).Select(n => n.IntegerValue).ToListAsync(); // We have at least one default culture: - if(count == 0) + if(list.Count == 0) { - CACHE_NUMBER_OF_CULTURES = 1; - return 1; + // Add the default culture, which is en-US: + await AppSettings.SetCultureCode(1, "en-US"); } - - CACHE_NUMBER_OF_CULTURES = count; - return count; + else + CACHE_CULTURES_INDICES = list; + + return CACHE_CULTURES_INDICES; } #endregion @@ -377,9 +378,8 @@ public static class AppSettings await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); - // Update the number of cultures cache: - if(CACHE_NUMBER_OF_CULTURES > -1) - CACHE_NUMBER_OF_CULTURES++; + // Update the list of cultures indices: + CACHE_CULTURES_INDICES.Add(index); } } @@ -392,15 +392,15 @@ public static class AppSettings public static async Task> GetCultureInfos() { // Get the number of cultures: - var numberOfCultures = await AppSettings.GetNumberCultures(); + var cultureIndices = await AppSettings.GetCultureIndices(); // Get the culture codes: var cultureInfos = new List(); - for (var i = 1; i <= numberOfCultures; i++) + foreach (var cultureIndex in cultureIndices) cultureInfos.Add(new CultureInfo { - Code = await AppSettings.GetCultureCode(i), - Index = i, + Code = await AppSettings.GetCultureCode(cultureIndex), + Index = cultureIndex, }); return cultureInfos; diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index 87dc1a4..0d08121 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -153,23 +153,27 @@ public sealed partial class Setting : UserControl private static IEnumerable> ShowCultureSettingsAsync() { var isFirstCulture = true; // We need this flag to distinguish the first task from the others. - var numberOfCultures = int.MaxValue; // There is always at least one culture, which is the default culture. We update this value later, out of the tasks. - while (numberOfCultures > 0) + var cultureIndices = new List(new []{ -1 }); + while (cultureIndices.Count > 0) { - var innerLoopIndex = numberOfCultures; // needed to avoid closure issues. + var innerLoopIndex = cultureIndices.Last(); // needed to avoid closure issues. yield return Task.Run(async () => { var localCultureIndex = innerLoopIndex; - // Get the total number of cultures. We cannot do this in the outer loop, - // because we cannot await there. The AppSettings is caching the answer, though. - var numberCultures = await AppSettings.GetNumberCultures(); + // Get a list of culture indices. Thus, we know the number of cultures. We cannot do this in the outer loop, + // because we cannot await there. The AppSettings is caching the answer, though. The list of indices is ordered + // ascending. + var localCultureIndices = await AppSettings.GetCultureIndices(); // Update the number of cultures in the outer loop for the first call: if(isFirstCulture) { - localCultureIndex = numberCultures; - numberOfCultures = numberCultures; + localCultureIndex = localCultureIndices.Last(); + innerLoopIndex = localCultureIndices.Last(); + + cultureIndices.Clear(); + cultureIndices.AddRange(localCultureIndices); isFirstCulture = false; } @@ -196,7 +200,7 @@ public sealed partial class Setting : UserControl }); }); - numberOfCultures--; + cultureIndices.Remove(innerLoopIndex); } } diff --git a/I18N Commander/UI WinForms/Components/Settings.cs b/I18N Commander/UI WinForms/Components/Settings.cs index cb6f551..ba36e48 100644 --- a/I18N Commander/UI WinForms/Components/Settings.cs +++ b/I18N Commander/UI WinForms/Components/Settings.cs @@ -19,11 +19,11 @@ public partial class Settings : UserControl private async void buttonAddCulture_Click(object sender, EventArgs e) { - // Get the current number of cultures: - var numberCultures = await AppSettings.GetNumberCultures(); + // Get the current indices of cultures: + var cultureIndices = await AppSettings.GetCultureIndices(); // Add a new culture: - await AppSettings.SetCultureCode(++numberCultures, string.Empty); + await AppSettings.SetCultureCode(cultureIndices.Max() + 1, string.Empty); // Reload all settings: await this.LoadAllSettings(); From 0c53c97a481554e541ad59026920c9bc091d881b Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 2 Aug 2022 20:43:58 +0200 Subject: [PATCH 29/32] Implemented the culture delete function --- I18N Commander/Processor/AppSettings.cs | 23 ++++++++++++++ .../Components/Settings.Designer.cs | 26 ++++++++++++++++ .../UI WinForms/Components/Settings.cs | 29 ++++++++++++++++++ .../UI WinForms/Components/Settings.resx | 3 ++ .../UI WinForms/Resources/Icons.Designer.cs | 10 ++++++ .../UI WinForms/Resources/Icons.resx | 3 ++ .../Resources/icons8-trash-can-512.png | Bin 0 -> 2285 bytes 7 files changed, 94 insertions(+) create mode 100644 I18N Commander/UI WinForms/Resources/icons8-trash-can-512.png diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index edd48cb..dcae4d9 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -385,6 +385,29 @@ public static class AppSettings #endregion + #region Delete a culture + + public static async Task DeleteCulture(int index) + { + // Get the database: + await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); + + // Check, if the setting is already set: + if (await db.Settings.FirstOrDefaultAsync(n => n.Code.StartsWith(SettingNames.CULTURE) && n.IntegerValue == index) is {} existingSetting) + { + db.Settings.Remove(existingSetting); + await db.SaveChangesAsync(); + } + + // Update the list of cultures indices: + CACHE_CULTURES_INDICES.Remove(index); + + // Update the cache: + CACHE_CULTURES.Remove(index); + } + + #endregion + #region Get a list of cultures public readonly record struct CultureInfo(string Code, int Index); diff --git a/I18N Commander/UI WinForms/Components/Settings.Designer.cs b/I18N Commander/UI WinForms/Components/Settings.Designer.cs index e38eb64..6701b53 100644 --- a/I18N Commander/UI WinForms/Components/Settings.Designer.cs +++ b/I18N Commander/UI WinForms/Components/Settings.Designer.cs @@ -35,6 +35,8 @@ this.panelSettings = new System.Windows.Forms.Panel(); this.flowLayoutToolbar = new System.Windows.Forms.FlowLayoutPanel(); this.buttonAddCulture = new System.Windows.Forms.Button(); + this.buttonDeleteCulture = new System.Windows.Forms.Button(); + this.contextMenuDelete = new System.Windows.Forms.ContextMenuStrip(this.components); this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.tableLayout.SuspendLayout(); this.flowLayoutToolbar.SuspendLayout(); @@ -97,6 +99,7 @@ // this.tableLayout.SetColumnSpan(this.flowLayoutToolbar, 2); this.flowLayoutToolbar.Controls.Add(this.buttonAddCulture); + this.flowLayoutToolbar.Controls.Add(this.buttonDeleteCulture); this.flowLayoutToolbar.Dock = System.Windows.Forms.DockStyle.Fill; this.flowLayoutToolbar.Location = new System.Drawing.Point(0, 315); this.flowLayoutToolbar.Margin = new System.Windows.Forms.Padding(0); @@ -117,6 +120,27 @@ this.buttonAddCulture.UseVisualStyleBackColor = true; this.buttonAddCulture.Click += new System.EventHandler(this.buttonAddCulture_Click); // + // buttonDeleteCulture + // + this.buttonDeleteCulture.ContextMenuStrip = this.contextMenuDelete; + this.buttonDeleteCulture.FlatAppearance.BorderSize = 0; + this.buttonDeleteCulture.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.buttonDeleteCulture.Image = global::UI_WinForms.Resources.Icons.icons8_trash_can_512; + this.buttonDeleteCulture.Location = new System.Drawing.Point(69, 3); + this.buttonDeleteCulture.Name = "buttonDeleteCulture"; + this.buttonDeleteCulture.Size = new System.Drawing.Size(60, 60); + this.buttonDeleteCulture.TabIndex = 0; + this.toolTip.SetToolTip(this.buttonDeleteCulture, "Delete a culture"); + this.buttonDeleteCulture.UseVisualStyleBackColor = true; + this.buttonDeleteCulture.Click += new System.EventHandler(this.buttonDeleteCulture_Click); + // + // contextMenuDelete + // + this.contextMenuDelete.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.contextMenuDelete.ImageScalingSize = new System.Drawing.Size(20, 20); + this.contextMenuDelete.Name = "contextMenuDelete"; + this.contextMenuDelete.Size = new System.Drawing.Size(211, 32); + // // toolTip // this.toolTip.AutoPopDelay = 30000; @@ -149,5 +173,7 @@ private FlowLayoutPanel flowLayoutToolbar; private ToolTip toolTip; private Button buttonAddCulture; + private Button buttonDeleteCulture; + private ContextMenuStrip contextMenuDelete; } } diff --git a/I18N Commander/UI WinForms/Components/Settings.cs b/I18N Commander/UI WinForms/Components/Settings.cs index ba36e48..ef8efd4 100644 --- a/I18N Commander/UI WinForms/Components/Settings.cs +++ b/I18N Commander/UI WinForms/Components/Settings.cs @@ -28,4 +28,33 @@ public partial class Settings : UserControl // Reload all settings: await this.LoadAllSettings(); } + + private async void buttonDeleteCulture_Click(object sender, EventArgs e) + { + // Read all cultures: + var cultures = await AppSettings.GetCultureInfos(); + + // Populate the delete button's menu strip with all cultures: + this.contextMenuDelete.Items.Clear(); + foreach (var culture in cultures) + { + var item = new ToolStripMenuItem($"{culture.Index}. Culture: {culture.Code}"); + item.Tag = culture.Index; + item.Click += async (senderObj, args) => + { + if (senderObj is not ToolStripMenuItem toolStripMenuItem) + return; + + // Delete the culture: + await AppSettings.DeleteCulture((int)toolStripMenuItem.Tag); + + // Reload all settings: + await this.LoadAllSettings(); + }; + + this.contextMenuDelete.Items.Add(item); + } + + this.contextMenuDelete.Show((Button)sender, new Point(0, (this.contextMenuDelete.Height + this.buttonDeleteCulture.Height / 2) * -1)); + } } diff --git a/I18N Commander/UI WinForms/Components/Settings.resx b/I18N Commander/UI WinForms/Components/Settings.resx index 99de901..3688329 100644 --- a/I18N Commander/UI WinForms/Components/Settings.resx +++ b/I18N Commander/UI WinForms/Components/Settings.resx @@ -60,4 +60,7 @@ 17, 17 + + 122, 17 + \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs index 7f3e9af..ab02ede 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.Designer.cs +++ b/I18N Commander/UI WinForms/Resources/Icons.Designer.cs @@ -259,5 +259,15 @@ namespace UI_WinForms.Resources { return ((System.Drawing.Bitmap)(obj)); } } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap icons8_trash_can_512 { + get { + object obj = ResourceManager.GetObject("icons8_trash_can_512", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } } } diff --git a/I18N Commander/UI WinForms/Resources/Icons.resx b/I18N Commander/UI WinForms/Resources/Icons.resx index 6b0ceae..f4a76ae 100644 --- a/I18N Commander/UI WinForms/Resources/Icons.resx +++ b/I18N Commander/UI WinForms/Resources/Icons.resx @@ -178,4 +178,7 @@ icons8-settings.svg.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + icons8-trash-can-512.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/I18N Commander/UI WinForms/Resources/icons8-trash-can-512.png b/I18N Commander/UI WinForms/Resources/icons8-trash-can-512.png new file mode 100644 index 0000000000000000000000000000000000000000..ac54a12e5d6e7b3b3fa5f02f4188bbfe178e1ac3 GIT binary patch literal 2285 zcmai0ZCDdm7M@5cC8)Ip1Qgpi(o$QKNdiGKn@CAQNrY$$LBW1VNG4<;$%M>=1nmQq zm8TJ0ZIGh1;0KBbSkS6f5C|4%cTtPWBK3=}Qbp@p+h+x_NZCn3p;q1fF-h)y-}9bx z&pG!@Hp^B;&!H}$0st^aA{NDw-*m_G+_U5-yx{v?0PxHaRGvsAN@HOqrei2nSPH_h z=nNzd0K5o`L7_}X2wDn~it72`-P3lEhN}4BT8@+{H3$(6D&Am3;y0|4D>tMoxhgPX z1(j!kNdX-~C}Z#l*(vA%!tr93=V?{uAtI*MwJ?l z6TLNMOs@E#h9C?u1ewidhB<_R8B-w^m&=8iY>3UKlMFhZr6&{?x*lKRkZ@^;5L{_Q z4FrnmX%0#6uJX>jBe0i1cqxc z!}I|jaWM@)W=N**$tD(s;Ynnv^ncTJx<`(I6H%FDBBql1NKC&wz~xy61d2m&%w$v| zQJILISmMltBQLN-r$|L&5q&D5;e(-^KLKk|)t~nrLRyof5(#>gbj_YINu0s>;Bq#^ znt_s@2su&>%TNoVO%$OzM30lI(^1TTNlyWVm=-g}lWmRgL6@)TI>1g$im6B_#2Lm6 zBoPW_Mof)rNeqvR7SJS7!Y~#$ER4=(xMawp!K5v!&JrmIlEr3{y~zxxGud($7Y=2? z9PS%THq2x?m7Q$zE~pfQ;{Wj-9Zlnr7E&oJMsWf&W;wT9Z61$gxK^&E7IpSFjpnQ} ztWY|#&Ib)fOl49cDyMT&&V}NbnlLMjNMtHmU_KbBR-0#=h9dV7L(zs?zDwj zgOF-ZKN~a^8RWQezlX+y9t)o5B>drul6I~=^6HZ_1ezWqi{O{Pv(?_V$-KN00imeC7`=wTEH5mxrWf zH})-*eA$s%@Zv)I{DLS6ZJo!T{r5odO(-(yZO}gcmz<)*Kcul2 z9!~i}lo!Np5WQFOV?*1in+;ohYF157j$SOdKhkh9y;b%=bG7b{?1X22qb?`#Qs&^i zj+X~`@#i{!5>9@0^FevfmmbZg@TS+&j_Sg%=HA#Sn6(;!a50l>@K@lb$WrTzdgD?uWP zlqcrj*=bMrR`}=ciAl@0hH(zPK)3qePC2uW;`hqO5pQ}#iX+RK&*=4F!{)r&q~`OB zDXAV_pMdk1S;1#2e9_2<6kqq4*sh?a($@CmuU@I|EcB!H9}8^kA8)>IxZh`hG@-j} zN{f!RDI7SEE8cTlH}H9}vG?{w%l_l@K^YoN^*VJ2+>6 zCA)1idxpCQeQ1mESohuYEz+geS62ot7E#}U2Z-8&nqTG#{98D*UXza-yTzOwpt+~9 z>8~@~`WwDobD;QS@2x9`c((!uQnnrYYfF|N|66WbiBDke;wFYYAp9kP^>&MUGFAN0 z<0I+b=XkcbK2!XFnpf141g&wip7^z{o_@(TGR6?dSzuWmsO_y#&7=mUra;M(F~wu~)@hbu54)@uuMR7g7)YiFWDE*G#x+~D}ju<+X7KRkOo`)Bb9an!E?2Cqbq;%w0(O>*4_cijrB+dJyu z9Z+doADr)TeRSW}reVwS<)8JAUWnfR&n*T0-9ts+XG}yo|E5TyR*7l_$$9?;x}s$} literal 0 HcmV?d00001 From f138be5a1f89a7501c8379f95290b23877284f78 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Fri, 5 Aug 2022 21:11:02 +0200 Subject: [PATCH 30/32] Fixed spelling --- I18N Commander/Processor/AppSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index dcae4d9..17dbea1 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -286,7 +286,7 @@ public static class AppSettings #region Translation Settings - #region Number of cultures + #region List of culture indices private static List CACHE_CULTURES_INDICES = new(); From ba86c99ad5af778eed6461bc77f7276ffad1391d Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Fri, 5 Aug 2022 21:33:33 +0200 Subject: [PATCH 31/32] Fixed naming --- I18N Commander/Processor/AppSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/I18N Commander/Processor/AppSettings.cs b/I18N Commander/Processor/AppSettings.cs index 17dbea1..86d2a2e 100644 --- a/I18N Commander/Processor/AppSettings.cs +++ b/I18N Commander/Processor/AppSettings.cs @@ -220,7 +220,7 @@ public static class AppSettings private static int CACHE_DEEPL_SOURCE_CULTURE = -1; private static bool CACHE_DEEPL_SOURCE_CULTURE_IS_LOADED = false; - public static async Task SetDeepLSourceCulture(int cultureIndex) + public static async Task SetDeepLSourceCultureIndex(int cultureIndex) { // Update the cache: CACHE_DEEPL_SOURCE_CULTURE = cultureIndex; From c07571c4771faa0d3e8615c376cbc2f107505b96 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Fri, 5 Aug 2022 21:34:20 +0200 Subject: [PATCH 32/32] Added DeepL source culture --- .../UI WinForms/Components/Setting.cs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/I18N Commander/UI WinForms/Components/Setting.cs b/I18N Commander/UI WinForms/Components/Setting.cs index 0d08121..639487b 100644 --- a/I18N Commander/UI WinForms/Components/Setting.cs +++ b/I18N Commander/UI WinForms/Components/Setting.cs @@ -150,6 +150,59 @@ public sealed partial class Setting : UserControl return new Setting(settingData); } + internal readonly record struct ComboBoxItem(string DisplayText, int CultureIndex) + { + public override string ToString() => this.DisplayText; + } + + private static async Task ShowDeepLSourceCultureSettingAsync() + { + var currentSourceCultureIndex = await AppSettings.GetDeepLSourceCultureIndex(); + + // We load the corresponding culture for that index. As dropdown items, we show + // all other available cultures: + var allCultures = await AppSettings.GetCultureInfos(); + var sourceCulture = allCultures.FirstOrDefault(n => n.Index == currentSourceCultureIndex); + + // Attention: We have to store the culture's index, because the index is not + // continuous and can change when the user adds or removes a culture! + var settingData = new SettingUIData( + Icon: Icons.icons8_chat_bubble_512, + SettingName: () => "DeepL Source Culture", + SettingExplanation: () => "The source culture is used to translate the missing translations.", + SetupDataControl: () => + { + var dropdown = new ComboBox(); + var currentCultureDropdownIndex = 0; + for (var n = 0; n < allCultures.Count; n++) + { + var cultureInfo = allCultures[n]; + if(cultureInfo.Index == currentSourceCultureIndex) + currentCultureDropdownIndex = n; + + dropdown.Items.Add(new ComboBoxItem($"{cultureInfo.Index}.: {cultureInfo.Code}", cultureInfo.Index)); + } + + dropdown.SelectedIndex = currentCultureDropdownIndex; + + // Setup the change event handler: + dropdown.SelectedValueChanged += async (sender, args) => + { + if(dropdown.SelectedItem is ComboBoxItem selectedItem) + await AppSettings.SetDeepLSourceCultureIndex(selectedItem.CultureIndex); + }; + + // Apply the desired layout: + dropdown.Dock = DockStyle.Fill; + dropdown.DropDownStyle = ComboBoxStyle.DropDownList; + + return dropdown; + } + ); + + return new Setting(settingData); + } + private static IEnumerable> ShowCultureSettingsAsync() { var isFirstCulture = true; // We need this flag to distinguish the first task from the others. @@ -206,6 +259,7 @@ public sealed partial class Setting : UserControl public static IEnumerable> GetAllSettings() { + yield return ShowDeepLSourceCultureSettingAsync(); foreach (var setting in ShowCultureSettingsAsync()) { yield return setting;