diff --git a/Aubio/Aubio.cs b/Aubio/Aubio.cs new file mode 100644 index 0000000..f55a2db --- /dev/null +++ b/Aubio/Aubio.cs @@ -0,0 +1,20 @@ +global using System.Runtime.InteropServices; + +namespace Aubio; + +public static unsafe class Aubio { + internal const string dll = "libaubio-5.dll"; + internal const CharSet CharEnc = CharSet.Ansi; + + public static float DetectPitch(WaveContainer wave, PitchDetectionAlgorithm method = PitchDetectionAlgorithm.Default, float? tolerance = null) { + int hopSize = wave.SampleCount; + + using var tmp = new PitchDetect(method, (uint) hopSize, (uint) hopSize, (uint) wave.SampleRate); + + if (tolerance is float tolf) { + tmp.Tolerance = tolf; + } + + return tmp.Do(wave); + } +} diff --git a/Aubio/Fvec.cs b/Aubio/Fvec.cs new file mode 100644 index 0000000..c52739f --- /dev/null +++ b/Aubio/Fvec.cs @@ -0,0 +1,55 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Aubio; + +[StructLayout(LayoutKind.Sequential)] +internal abstract unsafe class FvecBase : IDisposable { + public readonly uint Count; + public readonly nint ptr; + private bool amDead; + + protected FvecBase(uint count, nint size) { + Count = count; + ptr = Marshal.AllocHGlobal(size); + } + + ~FvecBase() { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) { + if (!amDead) { + if (disposing) { + Marshal.FreeHGlobal(ptr); + } + + amDead = true; + } + } + + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } +} + +[StructLayout(LayoutKind.Sequential)] +internal unsafe sealed class FvecRet : FvecBase { + public FvecRet() : base(1, sizeof(float)) { + } + + // again, this is just a float + public static implicit operator float(FvecRet f) => ((float*) f.ptr)[0]; +} + +[StructLayout(LayoutKind.Sequential)] +internal unsafe class FvecSamples : FvecBase { + + public FvecSamples(WaveContainer samples) : base((uint) samples.SampleCount, samples.SampleCount * sizeof(float)) { + float* fsamps = (float*) ptr; + + for (int i = 0; i < Count; i++) { + fsamps[i] = samples[i]; + } + } +} diff --git a/Aubio/PitchDetect.cs b/Aubio/PitchDetect.cs new file mode 100644 index 0000000..c58e24d --- /dev/null +++ b/Aubio/PitchDetect.cs @@ -0,0 +1,131 @@ +namespace Aubio; + +public sealed unsafe partial class PitchDetect : IDisposable { + private readonly PitchT* _cstruct; + + public int Type => _cstruct->type; + public int Mode => _cstruct->mode; + + public float Silence { + get => _cstruct->silence; + set => _cstruct->silence = Math.Clamp(value, -200F, 0F); + } + + private string _pitchUnit = "Hz"; + public string PitchUnit { + get => _pitchUnit; + set { + string clean = value?.ToLowerInvariant() switch { + "hz" or + "hertz" or + "frequency" or + "freq" => "Hz", + + "midi" => "midi", + + "cent" or + "cents" => "cent", + + "bin" => "bin", + + _ => throw new ArgumentException($"Invalid unit: {value}") + }; + + _pitchUnit = clean; + aubio_pitch_set_unit(_cstruct, _pitchUnit); + + //[LibraryImport(Aubio.dll, EntryPoint = "aubio_pitch_set_unit", StringMarshalling = StringMarshalling.Utf8)] + [DllImport(Aubio.dll, EntryPoint = "aubio_pitch_set_unit", CharSet = CharSet.Ansi)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool aubio_pitch_set_unit(PitchT* t, string s); + } + } + + private uint _toleranceError = 0; + private bool meGone; + + public float Tolerance { + get { + return aubio_pitch_get_tolerance(_cstruct); + + //[LibraryImport(Aubio.dll, EntryPoint = "aubio_pitch_get_tolerance")] + [DllImport(Aubio.dll, EntryPoint = "aubio_pitch_get_tolerance")] + [return: MarshalAs(UnmanagedType.R4)] + static extern float aubio_pitch_get_tolerance(PitchT* p); + } + set { + _toleranceError = aubio_pitch_set_tolerance(_cstruct, value); + + //[LibraryImport(Aubio.dll, EntryPoint = "aubio_pitch_set_tolerance")] + [DllImport(Aubio.dll, EntryPoint = "aubio_pitch_set_tolerance")] + [return: MarshalAs(UnmanagedType.U4)] + static extern uint aubio_pitch_set_tolerance(PitchT* p, float v); + } + } + + + /// + /// Pitch Detective + /// + public PitchDetect(PitchDetectionAlgorithm method, uint bufferSize, uint hopSize, uint sampleRate) { + _cstruct = new_aubio_pitch(method.GetToken(), bufferSize, hopSize, sampleRate); + } + + [LibraryImport(Aubio.dll, EntryPoint = "new_aubio_pitch", StringMarshalling = StringMarshalling.Utf8)] + private static partial PitchT* new_aubio_pitch(string method, uint bufferSize, uint hopSize, uint sampleRate); + + public float Do(WaveContainer w) { + using FvecRet ret = new(); + using FvecSamples samps = new(w); + aubio_pitch_do(_cstruct, samps, ret); + + return ret; + + //[LibraryImport(Aubio.dll, EntryPoint = "aubio_pitch_do")] + [DllImport(Aubio.dll, EntryPoint = "aubio_pitch_do")] + static extern void aubio_pitch_do(PitchT* p, FvecSamples ptr, FvecRet retPtr); + } + + ~PitchDetect() { + Dispose(false); + } + + private void Dispose(bool disposing) { + if (!meGone) { + if (disposing) { + del_aubio_pitch(_cstruct); + + //[LibraryImport(Aubio.dll, EntryPoint = "del_aubio_pitch")] + [DllImport(Aubio.dll, EntryPoint = "del_aubio_pitch")] + static extern void del_aubio_pitch(PitchT* p); + } + + meGone = true; + } + } + + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + // This should never actually be created as a managed struct + // it only exists as a wrapper for member access to the unmanaged memory created by the aubio library + [StructLayout(LayoutKind.Sequential)] + private unsafe struct PitchT { + public int type; + public int mode; + public uint samplerate; + public uint bufsize; + public void* pobject; + public void* filter; + public void* filtered; + public void* pv; + public void* fftgrain; + public void* buf; + public void* detect_cb; + public void* conv_cb; + public void* conf_cb; + public float silence; + } +} diff --git a/Aubio/PitchDetectionAlgorithm.cs b/Aubio/PitchDetectionAlgorithm.cs new file mode 100644 index 0000000..f01f6d9 --- /dev/null +++ b/Aubio/PitchDetectionAlgorithm.cs @@ -0,0 +1,41 @@ +namespace Aubio; + +public enum PitchDetectionAlgorithm { + Default = 0, + + YIN, + YINFast, + Schmitt, + + // TODO these aren't actually implemented in the current dll this calls + FComb, + MComb, + YINFFT, + SpecAcf +} + +public static class PitchDetectionAlgorithmExtensions { + public static string GetToken(this PitchDetectionAlgorithm p) => p switch { + PitchDetectionAlgorithm.Default or + PitchDetectionAlgorithm.YIN => "yin", + PitchDetectionAlgorithm.YINFast => "yinfast", + PitchDetectionAlgorithm.Schmitt => "schmitt", + PitchDetectionAlgorithm.FComb => "fcomb", + PitchDetectionAlgorithm.MComb => "mcomb", + PitchDetectionAlgorithm.YINFFT => "yinfft", + PitchDetectionAlgorithm.SpecAcf => "specacf", + _ => throw new ArgumentException($"Not a valid {nameof(PitchDetectionAlgorithm)}!"), + }; + + public static string GetName(this PitchDetectionAlgorithm p) => p switch { + PitchDetectionAlgorithm.Default => "Default algorithm", + PitchDetectionAlgorithm.YIN => "YIN", + PitchDetectionAlgorithm.YINFast => "YIN but fast", + PitchDetectionAlgorithm.Schmitt => "Schmitt trigger", + PitchDetectionAlgorithm.FComb => "Fast comb filter", + PitchDetectionAlgorithm.MComb => "Multi-comb filter", + PitchDetectionAlgorithm.YINFFT => "Spectral YIN", + PitchDetectionAlgorithm.SpecAcf => "Spectral autocorrelation", + _ => throw new ArgumentException($"Not a valid {nameof(PitchDetectionAlgorithm)}!"), + }; +} diff --git a/BRRSuiteGUI.csproj b/BRRSuiteGUI.csproj index eeff8cb..0d7ffe5 100644 --- a/BRRSuiteGUI.csproj +++ b/BRRSuiteGUI.csproj @@ -27,6 +27,7 @@ + @@ -65,6 +66,9 @@ + + Always + SettingsSingleFileGenerator Settings.Designer.cs @@ -78,6 +82,9 @@ Always + + Always + \ No newline at end of file diff --git a/Controls/RoundedUpDown.cs b/Controls/RoundedUpDown.cs new file mode 100644 index 0000000..e3c1b1b --- /dev/null +++ b/Controls/RoundedUpDown.cs @@ -0,0 +1,30 @@ +using System.ComponentModel; + +namespace BRRSuiteGUI; + +[DefaultProperty(nameof(Value))] +[DefaultEvent(nameof(ValueChanged))] +[DefaultBindingProperty(nameof(Value))] +internal class RoundedUpDown : NumericUpDown { + public RoundedUpDown() : base() { } + + [Bindable(true)] + public new decimal Value { + get => base.Value; + set => base.Value = decimal.Round(value, DecimalPlaces, MidpointRounding.ToZero); + } + + protected override void OnMouseWheel(MouseEventArgs e) { + if (e is HandledMouseEventArgs f) { + f.Handled = true; + } + + if (e.Delta > 0) { + UpButton(); + } else if (e.Delta < 0) { + DownButton(); + } + + base.OnMouseWheel(e); + } +} diff --git a/AcknowledgementsWindow.Designer.cs b/Forms/AcknowledgementsWindow.Designer.cs similarity index 99% rename from AcknowledgementsWindow.Designer.cs rename to Forms/AcknowledgementsWindow.Designer.cs index d27e50c..3b7efec 100644 --- a/AcknowledgementsWindow.Designer.cs +++ b/Forms/AcknowledgementsWindow.Designer.cs @@ -148,7 +148,7 @@ private void InitializeComponent() { pictureBox1.SizeMode = PictureBoxSizeMode.Zoom; pictureBox1.TabIndex = 10; pictureBox1.TabStop = false; - pictureBox1.Click += pictureBox1_Click; + pictureBox1.Click += IClickedTheLogo; // // AcknowledgementsWindow // diff --git a/AcknowledgementsWindow.cs b/Forms/AcknowledgementsWindow.cs similarity index 91% rename from AcknowledgementsWindow.cs rename to Forms/AcknowledgementsWindow.cs index fc7f449..58549cb 100644 --- a/AcknowledgementsWindow.cs +++ b/Forms/AcknowledgementsWindow.cs @@ -16,7 +16,7 @@ private void LinkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs Process.Start("explorer.exe", "https://github.com/tewtal/mITroid/blob/master/mITroid/NSPC/BRR.cs/"); } - private void pictureBox1_Click(object sender, EventArgs e) { + private void IClickedTheLogo(object sender, EventArgs e) { Process.Start("explorer.exe", "https://github.com/spannerisms/BRRSuiteGUI/"); } } diff --git a/AcknowledgementsWindow.resx b/Forms/AcknowledgementsWindow.resx similarity index 100% rename from AcknowledgementsWindow.resx rename to Forms/AcknowledgementsWindow.resx diff --git a/Forms/AdvancedSettingsWindow.Designer.cs b/Forms/AdvancedSettingsWindow.Designer.cs new file mode 100644 index 0000000..a619522 --- /dev/null +++ b/Forms/AdvancedSettingsWindow.Designer.cs @@ -0,0 +1,131 @@ +namespace BRRSuiteGUI; + +partial class AdvancedSettingsWindow { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + Label label1; + Label label2; + TheAcceptButton = new Button(); + TheCancelButton = new Button(); + PreviewDurationBox = new RoundedUpDown(); + TrimZerosBox = new RoundedUpDown(); + label1 = new Label(); + label2 = new Label(); + ((System.ComponentModel.ISupportInitialize) PreviewDurationBox).BeginInit(); + ((System.ComponentModel.ISupportInitialize) TrimZerosBox).BeginInit(); + SuspendLayout(); + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(21, 9); + label1.Name = "label1"; + label1.Size = new Size(112, 15); + label1.TabIndex = 3; + label1.Text = "Preview duration (s)"; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new Point(12, 38); + label2.Name = "label2"; + label2.Size = new Size(121, 15); + label2.TabIndex = 4; + label2.Text = "Zeros when trimming"; + // + // TheAcceptButton + // + TheAcceptButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + TheAcceptButton.DialogResult = DialogResult.OK; + TheAcceptButton.Location = new Point(49, 102); + TheAcceptButton.Name = "TheAcceptButton"; + TheAcceptButton.Size = new Size(75, 23); + TheAcceptButton.TabIndex = 0; + TheAcceptButton.Text = "OK"; + TheAcceptButton.UseVisualStyleBackColor = true; + // + // TheCancelButton + // + TheCancelButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + TheCancelButton.DialogResult = DialogResult.Cancel; + TheCancelButton.Location = new Point(126, 102); + TheCancelButton.Name = "TheCancelButton"; + TheCancelButton.Size = new Size(75, 23); + TheCancelButton.TabIndex = 1; + TheCancelButton.Text = "Cancel"; + TheCancelButton.UseVisualStyleBackColor = true; + // + // PreviewDurationBox + // + PreviewDurationBox.DecimalPlaces = 1; + PreviewDurationBox.Increment = new decimal(new int[] { 1, 0, 0, 65536 }); + PreviewDurationBox.InterceptArrowKeys = false; + PreviewDurationBox.Location = new Point(146, 7); + PreviewDurationBox.Maximum = new decimal(new int[] { 5, 0, 0, 0 }); + PreviewDurationBox.Minimum = new decimal(new int[] { 1, 0, 0, 65536 }); + PreviewDurationBox.Name = "PreviewDurationBox"; + PreviewDurationBox.Size = new Size(53, 23); + PreviewDurationBox.TabIndex = 2; + PreviewDurationBox.TextAlign = HorizontalAlignment.Right; + PreviewDurationBox.Value = new decimal(new int[] { 1, 0, 0, 65536 }); + // + // TrimZerosBox + // + TrimZerosBox.InterceptArrowKeys = false; + TrimZerosBox.Location = new Point(146, 36); + TrimZerosBox.Maximum = new decimal(new int[] { 64, 0, 0, 0 }); + TrimZerosBox.Name = "TrimZerosBox"; + TrimZerosBox.Size = new Size(53, 23); + TrimZerosBox.TabIndex = 5; + TrimZerosBox.TextAlign = HorizontalAlignment.Right; + TrimZerosBox.Value = new decimal(new int[] { 1, 0, 0, 0 }); + // + // AdvancedSettingsWindow + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(204, 127); + ControlBox = false; + Controls.Add(TrimZerosBox); + Controls.Add(label2); + Controls.Add(label1); + Controls.Add(PreviewDurationBox); + Controls.Add(TheCancelButton); + Controls.Add(TheAcceptButton); + FormBorderStyle = FormBorderStyle.FixedToolWindow; + Name = "AdvancedSettingsWindow"; + Text = "Advanced settings"; + ((System.ComponentModel.ISupportInitialize) PreviewDurationBox).EndInit(); + ((System.ComponentModel.ISupportInitialize) TrimZerosBox).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Button TheAcceptButton; + private Button TheCancelButton; + private RoundedUpDown PreviewDurationBox; + private RoundedUpDown TrimZerosBox; +} diff --git a/Forms/AdvancedSettingsWindow.cs b/Forms/AdvancedSettingsWindow.cs new file mode 100644 index 0000000..bdeeb06 --- /dev/null +++ b/Forms/AdvancedSettingsWindow.cs @@ -0,0 +1,18 @@ +namespace BRRSuiteGUI; + +// I should learn how data binding works instead +public partial class AdvancedSettingsWindow : Form { + public decimal PreviewDuration { + get => PreviewDurationBox.Value; + set => PreviewDurationBox.Value = value; + } + + public int MinimumTrimZeros { + get => (int) TrimZerosBox.Value; + set => TrimZerosBox.Value = value; + } + + public AdvancedSettingsWindow() { + InitializeComponent(); + } +} diff --git a/Forms/AdvancedSettingsWindow.resx b/Forms/AdvancedSettingsWindow.resx new file mode 100644 index 0000000..8359303 --- /dev/null +++ b/Forms/AdvancedSettingsWindow.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + False + + + False + + \ No newline at end of file diff --git a/FrequencyWindow.Designer.cs b/Forms/FrequencyWindow.Designer.cs similarity index 98% rename from FrequencyWindow.Designer.cs rename to Forms/FrequencyWindow.Designer.cs index ffc82e1..702ca9c 100644 --- a/FrequencyWindow.Designer.cs +++ b/Forms/FrequencyWindow.Designer.cs @@ -57,6 +57,7 @@ private void InitializeComponent() { AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(388, 328); Controls.Add(CheatSheet); + DoubleBuffered = true; FormBorderStyle = FormBorderStyle.FixedDialog; Icon = (Icon) resources.GetObject("$this.Icon"); MaximizeBox = false; diff --git a/FrequencyWindow.cs b/Forms/FrequencyWindow.cs similarity index 94% rename from FrequencyWindow.cs rename to Forms/FrequencyWindow.cs index 66490ae..dc1a74e 100644 --- a/FrequencyWindow.cs +++ b/Forms/FrequencyWindow.cs @@ -64,6 +64,13 @@ private void Populate() { CheatSheet.DataSource = allnotes; } + protected override void OnFormClosing(FormClosingEventArgs e) { + if (e.CloseReason == CloseReason.UserClosing) { + Hide(); + e.Cancel = true; + } + } + private class NoteValues { public string Name { get; } diff --git a/FrequencyWindow.resx b/Forms/FrequencyWindow.resx similarity index 100% rename from FrequencyWindow.resx rename to Forms/FrequencyWindow.resx diff --git a/MainForm.Designer.cs b/Forms/MainForm.Designer.cs similarity index 75% rename from MainForm.Designer.cs rename to Forms/MainForm.Designer.cs index 94f71ae..0ed61b4 100644 --- a/MainForm.Designer.cs +++ b/Forms/MainForm.Designer.cs @@ -24,83 +24,119 @@ protected override void Dispose(bool disposing) { /// the contents of this method with the code editor. /// private void InitializeComponent() { + Label label1; + Label label2; + Label label21; + Label label9; + Label label14; + Label label15; + Label label8; + Label label12; + Label label7; + Label label6; + Label label11; + Label label13; + Label label10; + Label label5; + Label label4; + Label label3; + Panel panel2; + Label label17; + Label label16; + Label label20; + Label label19; + Label label18; + Panel panel3; + Panel panel1; + GroupBox groupBox1; + GroupBox groupBox3; System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + RefreshFileButton = new Button(); FileNameBox = new TextBox(); - label1 = new Label(); - label2 = new Label(); + ExportNameBox = new TextBox(); + ExportFinalNameBox = new TextBox(); + ExportThisButton = new Button(); + TaskProgress = new ProgressBar(); + LoopsFolderPanel = new Panel(); + OutputDirectoryBox = new TextBox(); + OpenOutputButton = new Button(); + CancelTaskButton = new Button(); + LoopFindRangeBox = new RoundedUpDown(); + FindLoopsButton = new Button(); + LoopAttemptsBox = new RoundedUpDown(); + LoopIncrementBox = new RoundedUpDown(); + LoopStartBox = new RoundedUpDown(); + AdjustButton = new Button(); + AdjustRangeBox = new RoundedUpDown(); + SampleAdjustAtBox = new RoundedUpDown(); OutputGroupBox = new GroupBox(); - label21 = new Label(); + EstimatedFrequencyBox = new CheckBox(); TrebleBoostFilterBox = new ComboBox(); - FilterSilenceBox = new CheckBox(); - groupBox1 = new GroupBox(); - LoopFindRangeBox = new NumericUpDown(); - FindLoopsButton = new Button(); - label9 = new Label(); - label14 = new Label(); - LoopAttemptsBox = new NumericUpDown(); - label15 = new Label(); - LoopIncrementBox = new NumericUpDown(); - LoopStartBox = new NumericUpDown(); - label8 = new Label(); CreateUnloopedButton = new Button(); - label12 = new Label(); OutputInterpolationBox = new ComboBox(); ResampleBox = new ComboBox(); - groupBox3 = new GroupBox(); - AdjustButton = new Button(); - label7 = new Label(); - AdjustRangeBox = new NumericUpDown(); - SampleAdjustAtBox = new NumericUpDown(); - label6 = new Label(); BRRBlocksBox = new TextBox(); - label11 = new Label(); - label13 = new Label(); - ExportNameBox = new TextBox(); InputGroupBox = new GroupBox(); + InFreqLabel = new Label(); TrimZerosBox = new CheckBox(); ScratchBox = new TextBox(); - label10 = new Label(); - TrimPointBox = new NumericUpDown(); + TrimPointBox = new RoundedUpDown(); FindZeroesButton = new Button(); ZeroCrossingBox = new TextBox(); - label5 = new Label(); - label4 = new Label(); - label3 = new Label(); SampleCountBox = new TextBox(); FidelityBox = new TextBox(); SampleRateBox = new TextBox(); - TaskProgress = new ProgressBar(); - panel2 = new Panel(); - RefreshFileButton = new Button(); - menuStrip1 = new MenuStrip(); - windowToolStripMenuItem = new ToolStripMenuItem(); - frequencyCheatsheetToolStripMenuItem = new ToolStripMenuItem(); - helpToolStripMenuItem = new ToolStripMenuItem(); - acknowledgementsToolStripMenuItem = new ToolStripMenuItem(); - UpdateAvailableToolStripMenuItem = new ToolStripMenuItem(); - LoopsFolderPanel = new Panel(); - OutputDirectoryBox = new TextBox(); - label17 = new Label(); - CancelTaskButton = new Button(); ListenGroupBox = new GroupBox(); + ExportTestSongBox = new CheckBox(); + ClearWhenGenButton = new CheckBox(); + ClearCandidatesBox = new Button(); + EstimatedFrequencyLabel = new Label(); BrrExportTypeBox = new ComboBox(); LoopStartInputLabel = new Label(); - label20 = new Label(); ExportWAVButton = new CheckBox(); ExportBRRBox = new CheckBox(); - label19 = new Label(); - label18 = new Label(); AutoPlayCheckBox = new CheckBox(); SizeLabel = new Label(); LoopPointLabel = new Label(); StopButton = new Button(); PlayButton = new Button(); BRRTestBox = new ListBox(); + TopMenuStrip = new ToolStrip(); + FrequencyCheatsheetButton = new ToolStripButton(); + UpdateAvailableToolStripMenuItem = new ToolStripButton(); + AboutMenuButton = new ToolStripButton(); + WaveformViewButton = new ToolStripButton(); + AdvancedSettingsButton = new ToolStripButton(); + label1 = new Label(); + label2 = new Label(); + label21 = new Label(); + label9 = new Label(); + label14 = new Label(); + label15 = new Label(); + label8 = new Label(); + label12 = new Label(); + label7 = new Label(); + label6 = new Label(); + label11 = new Label(); + label13 = new Label(); + label10 = new Label(); + label5 = new Label(); + label4 = new Label(); + label3 = new Label(); + panel2 = new Panel(); + label17 = new Label(); + label16 = new Label(); + label20 = new Label(); + label19 = new Label(); + label18 = new Label(); panel3 = new Panel(); - ExportFinalNameBox = new TextBox(); - ExportThisButton = new Button(); panel1 = new Panel(); - OutputGroupBox.SuspendLayout(); + groupBox1 = new GroupBox(); + groupBox3 = new GroupBox(); + panel2.SuspendLayout(); + panel3.SuspendLayout(); + panel1.SuspendLayout(); + LoopsFolderPanel.SuspendLayout(); groupBox1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize) LoopFindRangeBox).BeginInit(); ((System.ComponentModel.ISupportInitialize) LoopAttemptsBox).BeginInit(); @@ -109,27 +145,13 @@ private void InitializeComponent() { groupBox3.SuspendLayout(); ((System.ComponentModel.ISupportInitialize) AdjustRangeBox).BeginInit(); ((System.ComponentModel.ISupportInitialize) SampleAdjustAtBox).BeginInit(); + OutputGroupBox.SuspendLayout(); InputGroupBox.SuspendLayout(); ((System.ComponentModel.ISupportInitialize) TrimPointBox).BeginInit(); - panel2.SuspendLayout(); - menuStrip1.SuspendLayout(); - LoopsFolderPanel.SuspendLayout(); ListenGroupBox.SuspendLayout(); - panel3.SuspendLayout(); - panel1.SuspendLayout(); + TopMenuStrip.SuspendLayout(); SuspendLayout(); // - // FileNameBox - // - FileNameBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - FileNameBox.Cursor = Cursors.Hand; - FileNameBox.Location = new Point(55, 6); - FileNameBox.Name = "FileNameBox"; - FileNameBox.ReadOnly = true; - FileNameBox.Size = new Size(600, 23); - FileNameBox.TabIndex = 0; - FileNameBox.Click += FileNameBox_Click; - // // label1 // label1.AutoSize = true; @@ -149,59 +171,345 @@ private void InitializeComponent() { label2.TabIndex = 2; label2.Text = "Resample to"; // - // OutputGroupBox + // label21 + // + label21.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label21.AutoSize = true; + label21.Location = new Point(35, 105); + label21.Name = "label21"; + label21.Size = new Size(71, 15); + label21.TabIndex = 28; + label21.Text = "Treble boost"; + // + // label9 + // + label9.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label9.AutoSize = true; + label9.Location = new Point(21, 53); + label9.Name = "label9"; + label9.Size = new Size(85, 15); + label9.TabIndex = 22; + label9.Text = "Attempt count"; + // + // label14 + // + label14.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label14.AutoSize = true; + label14.Location = new Point(47, 82); + label14.Name = "label14"; + label14.Size = new Size(61, 15); + label14.TabIndex = 24; + label14.Text = "Increment"; + // + // label15 + // + label15.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label15.AutoSize = true; + label15.Location = new Point(68, 111); + label15.Name = "label15"; + label15.Size = new Size(40, 15); + label15.TabIndex = 26; + label15.Text = "Range"; + // + // label8 + // + label8.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label8.AutoSize = true; + label8.Location = new Point(11, 24); + label8.Name = "label8"; + label8.Size = new Size(97, 15); + label8.TabIndex = 13; + label8.Text = "First loop sample"; + // + // label12 + // + label12.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label12.AutoSize = true; + label12.Location = new Point(31, 77); + label12.Name = "label12"; + label12.Size = new Size(75, 15); + label12.TabIndex = 18; + label12.Text = "Interpolation"; + // + // label7 + // + label7.AutoSize = true; + label7.Location = new Point(84, 53); + label7.Name = "label7"; + label7.Size = new Size(40, 15); + label7.TabIndex = 14; + label7.Text = "Range"; + // + // label6 + // + label6.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + label6.AutoSize = true; + label6.Location = new Point(49, 24); + label6.Name = "label6"; + label6.Size = new Size(75, 15); + label6.TabIndex = 12; + label6.Text = "Loop sample"; + // + // label11 + // + label11.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + label11.AutoSize = true; + label11.Location = new Point(11, 19); + label11.Name = "label11"; + label11.Size = new Size(47, 15); + label11.TabIndex = 16; + label11.Text = "Est. size"; + // + // label13 + // + label13.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label13.AutoSize = true; + label13.Location = new Point(696, 9); + label13.Name = "label13"; + label13.Size = new Size(39, 15); + label13.TabIndex = 20; + label13.Text = "Name"; + // + // label10 + // + label10.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label10.AutoSize = true; + label10.Location = new Point(51, 105); + label10.Name = "label10"; + label10.Size = new Size(44, 15); + label10.TabIndex = 12; + label10.Text = "Trim to"; + // + // label5 + // + label5.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label5.AutoSize = true; + label5.Location = new Point(51, 77); + label5.Name = "label5"; + label5.Size = new Size(44, 15); + label5.TabIndex = 8; + label5.Text = "Length"; + // + // label4 + // + label4.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label4.AutoSize = true; + label4.Location = new Point(50, 48); + label4.Name = "label4"; + label4.Size = new Size(45, 15); + label4.TabIndex = 7; + label4.Text = "Fidelity"; + // + // label3 + // + label3.Anchor = AnchorStyles.Top | AnchorStyles.Right; + label3.AutoSize = true; + label3.Location = new Point(26, 19); + label3.Name = "label3"; + label3.Size = new Size(69, 15); + label3.TabIndex = 6; + label3.Text = "Sample rate"; + // + // panel2 + // + panel2.Controls.Add(RefreshFileButton); + panel2.Controls.Add(FileNameBox); + panel2.Controls.Add(label1); + panel2.Controls.Add(label13); + panel2.Controls.Add(ExportNameBox); + panel2.Dock = DockStyle.Top; + panel2.Location = new Point(0, 26); + panel2.Name = "panel2"; + panel2.Padding = new Padding(1, 6, 3, 1); + panel2.Size = new Size(967, 34); + panel2.TabIndex = 8; + // + // RefreshFileButton + // + RefreshFileButton.BackColor = Color.FromArgb( 0, 192, 0); + RefreshFileButton.BackgroundImage = Properties.Resources.refresh; + RefreshFileButton.BackgroundImageLayout = ImageLayout.Zoom; + RefreshFileButton.Cursor = Cursors.Hand; + RefreshFileButton.FlatAppearance.BorderColor = Color.FromArgb( 0, 192, 0); + RefreshFileButton.FlatAppearance.BorderSize = 0; + RefreshFileButton.FlatStyle = FlatStyle.Flat; + RefreshFileButton.Location = new Point(659, 6); + RefreshFileButton.Name = "RefreshFileButton"; + RefreshFileButton.Size = new Size(23, 23); + RefreshFileButton.TabIndex = 22; + RefreshFileButton.TabStop = false; + RefreshFileButton.UseVisualStyleBackColor = false; + RefreshFileButton.Click += RefreshFileButton_Click; + // + // FileNameBox + // + FileNameBox.Cursor = Cursors.Hand; + FileNameBox.Location = new Point(55, 6); + FileNameBox.Name = "FileNameBox"; + FileNameBox.ReadOnly = true; + FileNameBox.Size = new Size(600, 23); + FileNameBox.TabIndex = 0; + FileNameBox.Click += FileNameBox_Click; + // + // ExportNameBox + // + ExportNameBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; + ExportNameBox.Location = new Point(738, 6); + ExportNameBox.Name = "ExportNameBox"; + ExportNameBox.PlaceholderText = "wav name"; + ExportNameBox.Size = new Size(225, 23); + ExportNameBox.TabIndex = 21; + ExportNameBox.TextChanged += ExportNameBox_TextChanged; + ExportNameBox.KeyDown += ExportNames_KeyDown; + ExportNameBox.Leave += ExportNames_Leave; + // + // label17 + // + label17.Location = new Point(3, 3); + label17.Name = "label17"; + label17.Size = new Size(50, 23); + label17.TabIndex = 6; + label17.Text = "Output"; + label17.TextAlign = ContentAlignment.MiddleRight; + // + // label16 + // + label16.AutoSize = true; + label16.Location = new Point(207, 219); + label16.Name = "label16"; + label16.Size = new Size(118, 15); + label16.TabIndex = 23; + label16.Text = "Estimated frequency:"; + // + // label20 + // + label20.AutoSize = true; + label20.Location = new Point(207, 180); + label20.Name = "label20"; + label20.Size = new Size(94, 15); + label20.TabIndex = 13; + label20.Text = "Loop start input:"; + // + // label19 + // + label19.AutoSize = true; + label19.Location = new Point(207, 141); + label19.Name = "label19"; + label19.Size = new Size(68, 15); + label19.TabIndex = 8; + label19.Text = "Loop point:"; + // + // label18 + // + label18.AutoSize = true; + label18.Location = new Point(207, 102); + label18.Name = "label18"; + label18.Size = new Size(30, 15); + label18.TabIndex = 7; + label18.Text = "Size:"; + // + // panel3 + // + panel3.Controls.Add(ExportFinalNameBox); + panel3.Controls.Add(ExportThisButton); + panel3.Dock = DockStyle.Top; + panel3.Location = new Point(3, 19); + panel3.Name = "panel3"; + panel3.Size = new Size(407, 24); + panel3.TabIndex = 9; + // + // ExportFinalNameBox + // + ExportFinalNameBox.Dock = DockStyle.Fill; + ExportFinalNameBox.Location = new Point(0, 0); + ExportFinalNameBox.Margin = new Padding(0); + ExportFinalNameBox.Name = "ExportFinalNameBox"; + ExportFinalNameBox.PlaceholderText = "exported file name"; + ExportFinalNameBox.Size = new Size(332, 23); + ExportFinalNameBox.TabIndex = 0; + ExportFinalNameBox.KeyDown += ExportNames_KeyDown; + ExportFinalNameBox.Leave += ExportNames_Leave; + // + // ExportThisButton + // + ExportThisButton.Dock = DockStyle.Right; + ExportThisButton.Location = new Point(332, 0); + ExportThisButton.Name = "ExportThisButton"; + ExportThisButton.Size = new Size(75, 24); + ExportThisButton.TabIndex = 1; + ExportThisButton.Text = "Export"; + ExportThisButton.UseVisualStyleBackColor = true; + ExportThisButton.Click += ExportThisButton_Click; + // + // panel1 + // + panel1.Controls.Add(TaskProgress); + panel1.Controls.Add(LoopsFolderPanel); + panel1.Controls.Add(CancelTaskButton); + panel1.Dock = DockStyle.Bottom; + panel1.Location = new Point(0, 537); + panel1.Name = "panel1"; + panel1.Size = new Size(967, 29); + panel1.TabIndex = 13; + // + // TaskProgress // - OutputGroupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; - OutputGroupBox.BackColor = Color.Transparent; - OutputGroupBox.Controls.Add(label21); - OutputGroupBox.Controls.Add(TrebleBoostFilterBox); - OutputGroupBox.Controls.Add(FilterSilenceBox); - OutputGroupBox.Controls.Add(groupBox1); - OutputGroupBox.Controls.Add(CreateUnloopedButton); - OutputGroupBox.Controls.Add(label12); - OutputGroupBox.Controls.Add(OutputInterpolationBox); - OutputGroupBox.Controls.Add(ResampleBox); - OutputGroupBox.Controls.Add(label2); - OutputGroupBox.Controls.Add(groupBox3); - OutputGroupBox.Controls.Add(BRRBlocksBox); - OutputGroupBox.Controls.Add(label11); - OutputGroupBox.Location = new Point(275, 64); - OutputGroupBox.Name = "OutputGroupBox"; - OutputGroupBox.Size = new Size(269, 466); - OutputGroupBox.TabIndex = 16; - OutputGroupBox.TabStop = false; - OutputGroupBox.Text = "Output"; + TaskProgress.Dock = DockStyle.Fill; + TaskProgress.Location = new Point(446, 0); + TaskProgress.Margin = new Padding(3, 0, 3, 0); + TaskProgress.Name = "TaskProgress"; + TaskProgress.Size = new Size(440, 29); + TaskProgress.Style = ProgressBarStyle.Continuous; + TaskProgress.TabIndex = 0; // - // label21 + // LoopsFolderPanel // - label21.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label21.AutoSize = true; - label21.Location = new Point(35, 105); - label21.Name = "label21"; - label21.Size = new Size(71, 15); - label21.TabIndex = 28; - label21.Text = "Treble boost"; + LoopsFolderPanel.Controls.Add(OutputDirectoryBox); + LoopsFolderPanel.Controls.Add(label17); + LoopsFolderPanel.Controls.Add(OpenOutputButton); + LoopsFolderPanel.Dock = DockStyle.Left; + LoopsFolderPanel.Location = new Point(0, 0); + LoopsFolderPanel.Name = "LoopsFolderPanel"; + LoopsFolderPanel.Padding = new Padding(3); + LoopsFolderPanel.Size = new Size(446, 29); + LoopsFolderPanel.TabIndex = 10; // - // TrebleBoostFilterBox + // OutputDirectoryBox // - TrebleBoostFilterBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; - TrebleBoostFilterBox.DropDownStyle = ComboBoxStyle.DropDownList; - TrebleBoostFilterBox.FormattingEnabled = true; - TrebleBoostFilterBox.Location = new Point(112, 102); - TrebleBoostFilterBox.Name = "TrebleBoostFilterBox"; - TrebleBoostFilterBox.Size = new Size(151, 23); - TrebleBoostFilterBox.TabIndex = 27; + OutputDirectoryBox.Cursor = Cursors.Hand; + OutputDirectoryBox.Dock = DockStyle.Right; + OutputDirectoryBox.Location = new Point(111, 3); + OutputDirectoryBox.Name = "OutputDirectoryBox"; + OutputDirectoryBox.PlaceholderText = "Click to select output directory"; + OutputDirectoryBox.ReadOnly = true; + OutputDirectoryBox.Size = new Size(309, 23); + OutputDirectoryBox.TabIndex = 0; + OutputDirectoryBox.Click += OutputDirectoryBox_Click; + // + // OpenOutputButton // - // FilterSilenceBox + OpenOutputButton.Dock = DockStyle.Right; + OpenOutputButton.Location = new Point(420, 3); + OpenOutputButton.Name = "OpenOutputButton"; + OpenOutputButton.Size = new Size(23, 23); + OpenOutputButton.TabIndex = 17; + OpenOutputButton.Text = "🡥"; + OpenOutputButton.UseVisualStyleBackColor = true; + OpenOutputButton.Click += OpenOutputButton_Click; // - FilterSilenceBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; - FilterSilenceBox.AutoSize = true; - FilterSilenceBox.Location = new Point(112, 131); - FilterSilenceBox.Name = "FilterSilenceBox"; - FilterSilenceBox.Size = new Size(120, 19); - FilterSilenceBox.TabIndex = 26; - FilterSilenceBox.Text = "Force silence start"; - FilterSilenceBox.UseVisualStyleBackColor = true; + // CancelTaskButton + // + CancelTaskButton.BackColor = Color.RosyBrown; + CancelTaskButton.Dock = DockStyle.Right; + CancelTaskButton.Enabled = false; + CancelTaskButton.FlatStyle = FlatStyle.Popup; + CancelTaskButton.Location = new Point(886, 0); + CancelTaskButton.Name = "CancelTaskButton"; + CancelTaskButton.Size = new Size(81, 29); + CancelTaskButton.TabIndex = 11; + CancelTaskButton.Text = "Cancel"; + CancelTaskButton.UseVisualStyleBackColor = false; + CancelTaskButton.Click += CancelTaskButton_Click; // // groupBox1 // @@ -231,6 +539,7 @@ private void InitializeComponent() { LoopFindRangeBox.Size = new Size(151, 23); LoopFindRangeBox.TabIndex = 0; LoopFindRangeBox.TextAlign = HorizontalAlignment.Right; + LoopFindRangeBox.Value = new decimal(new int[] { 0, 0, 0, 0 }); // // FindLoopsButton // @@ -243,26 +552,6 @@ private void InitializeComponent() { FindLoopsButton.UseVisualStyleBackColor = true; FindLoopsButton.Click += FindLoopsButton_Click; // - // label9 - // - label9.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label9.AutoSize = true; - label9.Location = new Point(21, 53); - label9.Name = "label9"; - label9.Size = new Size(85, 15); - label9.TabIndex = 22; - label9.Text = "Attempt count"; - // - // label14 - // - label14.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label14.AutoSize = true; - label14.Location = new Point(47, 82); - label14.Name = "label14"; - label14.Size = new Size(61, 15); - label14.TabIndex = 24; - label14.Text = "Increment"; - // // LoopAttemptsBox // LoopAttemptsBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; @@ -276,16 +565,6 @@ private void InitializeComponent() { LoopAttemptsBox.TextAlign = HorizontalAlignment.Right; LoopAttemptsBox.Value = new decimal(new int[] { 20, 0, 0, 0 }); // - // label15 - // - label15.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label15.AutoSize = true; - label15.Location = new Point(68, 111); - label15.Name = "label15"; - label15.Size = new Size(40, 15); - label15.TabIndex = 26; - label15.Text = "Range"; - // // LoopIncrementBox // LoopIncrementBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; @@ -309,57 +588,7 @@ private void InitializeComponent() { LoopStartBox.Size = new Size(151, 23); LoopStartBox.TabIndex = 28; LoopStartBox.TextAlign = HorizontalAlignment.Right; - // - // label8 - // - label8.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label8.AutoSize = true; - label8.Location = new Point(11, 24); - label8.Name = "label8"; - label8.Size = new Size(97, 15); - label8.TabIndex = 13; - label8.Text = "First loop sample"; - // - // CreateUnloopedButton - // - CreateUnloopedButton.Location = new Point(3, 172); - CreateUnloopedButton.Name = "CreateUnloopedButton"; - CreateUnloopedButton.Size = new Size(263, 23); - CreateUnloopedButton.TabIndex = 1; - CreateUnloopedButton.Text = "Create unlooped"; - CreateUnloopedButton.UseVisualStyleBackColor = true; - CreateUnloopedButton.Click += CreateUnloopedButton_Click; - // - // label12 - // - label12.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label12.AutoSize = true; - label12.Location = new Point(31, 77); - label12.Name = "label12"; - label12.Size = new Size(75, 15); - label12.TabIndex = 18; - label12.Text = "Interpolation"; - // - // OutputInterpolationBox - // - OutputInterpolationBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; - OutputInterpolationBox.DropDownStyle = ComboBoxStyle.DropDownList; - OutputInterpolationBox.FormattingEnabled = true; - OutputInterpolationBox.Location = new Point(112, 74); - OutputInterpolationBox.Name = "OutputInterpolationBox"; - OutputInterpolationBox.Size = new Size(151, 23); - OutputInterpolationBox.TabIndex = 22; - // - // ResampleBox - // - ResampleBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; - ResampleBox.DropDownStyle = ComboBoxStyle.DropDownList; - ResampleBox.FormattingEnabled = true; - ResampleBox.Location = new Point(112, 45); - ResampleBox.Name = "ResampleBox"; - ResampleBox.Size = new Size(151, 23); - ResampleBox.TabIndex = 23; - ResampleBox.SelectedIndexChanged += SampleBox_SelectedIndexChanged; + LoopStartBox.Value = new decimal(new int[] { 0, 0, 0, 0 }); // // groupBox3 // @@ -387,15 +616,6 @@ private void InitializeComponent() { AdjustButton.UseVisualStyleBackColor = true; AdjustButton.Click += AdjustButton_Click; // - // label7 - // - label7.AutoSize = true; - label7.Location = new Point(84, 53); - label7.Name = "label7"; - label7.Size = new Size(40, 15); - label7.TabIndex = 14; - label7.Text = "Range"; - // // AdjustRangeBox // AdjustRangeBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; @@ -418,63 +638,100 @@ private void InitializeComponent() { SampleAdjustAtBox.Size = new Size(55, 23); SampleAdjustAtBox.TabIndex = 16; SampleAdjustAtBox.TextAlign = HorizontalAlignment.Right; + SampleAdjustAtBox.Value = new decimal(new int[] { 0, 0, 0, 0 }); // - // label6 + // OutputGroupBox // - label6.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - label6.AutoSize = true; - label6.Location = new Point(49, 24); - label6.Name = "label6"; - label6.Size = new Size(75, 15); - label6.TabIndex = 12; - label6.Text = "Loop sample"; + OutputGroupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; + OutputGroupBox.BackColor = Color.Transparent; + OutputGroupBox.Controls.Add(EstimatedFrequencyBox); + OutputGroupBox.Controls.Add(label21); + OutputGroupBox.Controls.Add(TrebleBoostFilterBox); + OutputGroupBox.Controls.Add(groupBox1); + OutputGroupBox.Controls.Add(CreateUnloopedButton); + OutputGroupBox.Controls.Add(label12); + OutputGroupBox.Controls.Add(OutputInterpolationBox); + OutputGroupBox.Controls.Add(ResampleBox); + OutputGroupBox.Controls.Add(label2); + OutputGroupBox.Controls.Add(groupBox3); + OutputGroupBox.Controls.Add(BRRBlocksBox); + OutputGroupBox.Controls.Add(label11); + OutputGroupBox.Location = new Point(275, 64); + OutputGroupBox.Name = "OutputGroupBox"; + OutputGroupBox.Size = new Size(269, 466); + OutputGroupBox.TabIndex = 16; + OutputGroupBox.TabStop = false; + OutputGroupBox.Text = "Output"; // - // BRRBlocksBox + // EstimatedFrequencyBox // - BRRBlocksBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - BRRBlocksBox.Enabled = false; - BRRBlocksBox.Location = new Point(64, 16); - BRRBlocksBox.Name = "BRRBlocksBox"; - BRRBlocksBox.PlaceholderText = "-"; - BRRBlocksBox.ReadOnly = true; - BRRBlocksBox.Size = new Size(199, 23); - BRRBlocksBox.TabIndex = 25; + EstimatedFrequencyBox.AutoSize = true; + EstimatedFrequencyBox.Checked = true; + EstimatedFrequencyBox.CheckState = CheckState.Checked; + EstimatedFrequencyBox.Location = new Point(112, 131); + EstimatedFrequencyBox.Name = "EstimatedFrequencyBox"; + EstimatedFrequencyBox.Size = new Size(127, 19); + EstimatedFrequencyBox.TabIndex = 24; + EstimatedFrequencyBox.Text = "Estimate frequency"; + EstimatedFrequencyBox.UseVisualStyleBackColor = true; // - // label11 + // TrebleBoostFilterBox // - label11.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - label11.AutoSize = true; - label11.Location = new Point(11, 19); - label11.Name = "label11"; - label11.Size = new Size(47, 15); - label11.TabIndex = 16; - label11.Text = "Est. size"; + TrebleBoostFilterBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; + TrebleBoostFilterBox.DropDownStyle = ComboBoxStyle.DropDownList; + TrebleBoostFilterBox.FormattingEnabled = true; + TrebleBoostFilterBox.Location = new Point(112, 102); + TrebleBoostFilterBox.Name = "TrebleBoostFilterBox"; + TrebleBoostFilterBox.Size = new Size(151, 23); + TrebleBoostFilterBox.TabIndex = 27; // - // label13 + // CreateUnloopedButton // - label13.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label13.AutoSize = true; - label13.Location = new Point(697, 10); - label13.Name = "label13"; - label13.Size = new Size(39, 15); - label13.TabIndex = 20; - label13.Text = "Name"; + CreateUnloopedButton.Location = new Point(3, 172); + CreateUnloopedButton.Name = "CreateUnloopedButton"; + CreateUnloopedButton.Size = new Size(263, 23); + CreateUnloopedButton.TabIndex = 1; + CreateUnloopedButton.Text = "Create unlooped"; + CreateUnloopedButton.UseVisualStyleBackColor = true; + CreateUnloopedButton.Click += CreateUnloopedButton_Click; + // + // OutputInterpolationBox + // + OutputInterpolationBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; + OutputInterpolationBox.DropDownStyle = ComboBoxStyle.DropDownList; + OutputInterpolationBox.FormattingEnabled = true; + OutputInterpolationBox.Location = new Point(112, 74); + OutputInterpolationBox.Name = "OutputInterpolationBox"; + OutputInterpolationBox.Size = new Size(151, 23); + OutputInterpolationBox.TabIndex = 22; + // + // ResampleBox + // + ResampleBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; + ResampleBox.DropDownStyle = ComboBoxStyle.DropDownList; + ResampleBox.FormattingEnabled = true; + ResampleBox.Location = new Point(112, 45); + ResampleBox.Name = "ResampleBox"; + ResampleBox.Size = new Size(151, 23); + ResampleBox.TabIndex = 23; + ResampleBox.SelectedIndexChanged += SampleBox_SelectedIndexChanged; // - // ExportNameBox + // BRRBlocksBox // - ExportNameBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; - ExportNameBox.Location = new Point(738, 6); - ExportNameBox.Name = "ExportNameBox"; - ExportNameBox.PlaceholderText = "wav name"; - ExportNameBox.Size = new Size(223, 23); - ExportNameBox.TabIndex = 21; - ExportNameBox.TextChanged += ExportNameBox_TextChanged; - ExportNameBox.KeyDown += ExportNames_KeyDown; - ExportNameBox.Leave += ExportNames_Leave; + BRRBlocksBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + BRRBlocksBox.Enabled = false; + BRRBlocksBox.Location = new Point(64, 16); + BRRBlocksBox.Name = "BRRBlocksBox"; + BRRBlocksBox.PlaceholderText = "-"; + BRRBlocksBox.ReadOnly = true; + BRRBlocksBox.Size = new Size(199, 23); + BRRBlocksBox.TabIndex = 25; // // InputGroupBox // InputGroupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; + InputGroupBox.BackColor = Color.Transparent; + InputGroupBox.Controls.Add(InFreqLabel); InputGroupBox.Controls.Add(TrimZerosBox); InputGroupBox.Controls.Add(ScratchBox); InputGroupBox.Controls.Add(label10); @@ -494,10 +751,21 @@ private void InitializeComponent() { InputGroupBox.TabStop = false; InputGroupBox.Text = "Input"; // + // InFreqLabel + // + InFreqLabel.AutoSize = true; + InFreqLabel.Location = new Point(7, 156); + InFreqLabel.Name = "InFreqLabel"; + InFreqLabel.Size = new Size(12, 15); + InFreqLabel.TabIndex = 22; + InFreqLabel.Text = "-"; + // // TrimZerosBox // TrimZerosBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; TrimZerosBox.AutoSize = true; + TrimZerosBox.Checked = true; + TrimZerosBox.CheckState = CheckState.Checked; TrimZerosBox.Location = new Point(101, 131); TrimZerosBox.Name = "TrimZerosBox"; TrimZerosBox.Size = new Size(121, 19); @@ -516,16 +784,6 @@ private void InitializeComponent() { ScratchBox.Size = new Size(257, 122); ScratchBox.TabIndex = 15; // - // label10 - // - label10.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label10.AutoSize = true; - label10.Location = new Point(51, 105); - label10.Name = "label10"; - label10.Size = new Size(44, 15); - label10.TabIndex = 12; - label10.Text = "Trim to"; - // // TrimPointBox // TrimPointBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; @@ -536,12 +794,13 @@ private void InitializeComponent() { TrimPointBox.Size = new Size(159, 23); TrimPointBox.TabIndex = 16; TrimPointBox.TextAlign = HorizontalAlignment.Right; + TrimPointBox.Value = new decimal(new int[] { 0, 0, 0, 0 }); TrimPointBox.ValueChanged += TrimPointBox_ValueChanged; // // FindZeroesButton // FindZeroesButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - FindZeroesButton.Location = new Point(132, 156); + FindZeroesButton.Location = new Point(132, 180); FindZeroesButton.Name = "FindZeroesButton"; FindZeroesButton.Size = new Size(128, 23); FindZeroesButton.TabIndex = 17; @@ -552,43 +811,13 @@ private void InitializeComponent() { // ZeroCrossingBox // ZeroCrossingBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - ZeroCrossingBox.Location = new Point(3, 185); + ZeroCrossingBox.Location = new Point(3, 206); ZeroCrossingBox.Multiline = true; ZeroCrossingBox.Name = "ZeroCrossingBox"; ZeroCrossingBox.ScrollBars = ScrollBars.Vertical; - ZeroCrossingBox.Size = new Size(257, 147); + ZeroCrossingBox.Size = new Size(257, 126); ZeroCrossingBox.TabIndex = 18; // - // label5 - // - label5.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label5.AutoSize = true; - label5.Location = new Point(51, 77); - label5.Name = "label5"; - label5.Size = new Size(44, 15); - label5.TabIndex = 8; - label5.Text = "Length"; - // - // label4 - // - label4.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label4.AutoSize = true; - label4.Location = new Point(50, 48); - label4.Name = "label4"; - label4.Size = new Size(45, 15); - label4.TabIndex = 7; - label4.Text = "Fidelity"; - // - // label3 - // - label3.Anchor = AnchorStyles.Top | AnchorStyles.Right; - label3.AutoSize = true; - label3.Location = new Point(26, 19); - label3.Name = "label3"; - label3.Size = new Size(69, 15); - label3.TabIndex = 6; - label3.Text = "Sample rate"; - // // SampleCountBox // SampleCountBox.Anchor = AnchorStyles.Top | AnchorStyles.Right; @@ -622,151 +851,15 @@ private void InitializeComponent() { SampleRateBox.Size = new Size(159, 23); SampleRateBox.TabIndex = 21; // - // TaskProgress - // - TaskProgress.Dock = DockStyle.Fill; - TaskProgress.Location = new Point(446, 0); - TaskProgress.Margin = new Padding(3, 0, 3, 0); - TaskProgress.Name = "TaskProgress"; - TaskProgress.Size = new Size(440, 29); - TaskProgress.Style = ProgressBarStyle.Continuous; - TaskProgress.TabIndex = 0; - // - // panel2 - // - panel2.Controls.Add(RefreshFileButton); - panel2.Controls.Add(FileNameBox); - panel2.Controls.Add(label1); - panel2.Controls.Add(label13); - panel2.Controls.Add(ExportNameBox); - panel2.Dock = DockStyle.Top; - panel2.Location = new Point(0, 24); - panel2.Name = "panel2"; - panel2.Padding = new Padding(1, 6, 3, 1); - panel2.Size = new Size(967, 34); - panel2.TabIndex = 8; - // - // RefreshFileButton - // - RefreshFileButton.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - RefreshFileButton.BackColor = Color.FromArgb( 0, 192, 0); - RefreshFileButton.BackgroundImage = Properties.Resources.refresh; - RefreshFileButton.BackgroundImageLayout = ImageLayout.Zoom; - RefreshFileButton.Cursor = Cursors.Hand; - RefreshFileButton.FlatAppearance.BorderColor = Color.FromArgb( 0, 192, 0); - RefreshFileButton.FlatAppearance.BorderSize = 0; - RefreshFileButton.FlatStyle = FlatStyle.Flat; - RefreshFileButton.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point, 0); - RefreshFileButton.Location = new Point(659, 6); - RefreshFileButton.Name = "RefreshFileButton"; - RefreshFileButton.Size = new Size(26, 23); - RefreshFileButton.TabIndex = 22; - RefreshFileButton.TabStop = false; - RefreshFileButton.UseVisualStyleBackColor = false; - RefreshFileButton.Click += RefreshFileButton_Click; - // - // menuStrip1 - // - menuStrip1.Items.AddRange(new ToolStripItem[] { windowToolStripMenuItem, helpToolStripMenuItem, UpdateAvailableToolStripMenuItem }); - menuStrip1.Location = new Point(0, 0); - menuStrip1.Name = "menuStrip1"; - menuStrip1.Size = new Size(967, 24); - menuStrip1.TabIndex = 9; - menuStrip1.Text = "menuStrip1"; - // - // windowToolStripMenuItem - // - windowToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { frequencyCheatsheetToolStripMenuItem }); - windowToolStripMenuItem.Name = "windowToolStripMenuItem"; - windowToolStripMenuItem.Size = new Size(63, 20); - windowToolStripMenuItem.Text = "Window"; - // - // frequencyCheatsheetToolStripMenuItem - // - frequencyCheatsheetToolStripMenuItem.Name = "frequencyCheatsheetToolStripMenuItem"; - frequencyCheatsheetToolStripMenuItem.Size = new Size(189, 22); - frequencyCheatsheetToolStripMenuItem.Text = "Frequency cheatsheet"; - frequencyCheatsheetToolStripMenuItem.Click += FrequencyCheatsheetToolStripMenuItem_Click; - // - // helpToolStripMenuItem - // - helpToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { acknowledgementsToolStripMenuItem }); - helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - helpToolStripMenuItem.Size = new Size(44, 20); - helpToolStripMenuItem.Text = "Help"; - // - // acknowledgementsToolStripMenuItem - // - acknowledgementsToolStripMenuItem.Name = "acknowledgementsToolStripMenuItem"; - acknowledgementsToolStripMenuItem.Size = new Size(179, 22); - acknowledgementsToolStripMenuItem.Text = "Acknowledgements"; - acknowledgementsToolStripMenuItem.Click += AcknowledgementsToolStripMenuItem_Click; - // - // UpdateAvailableToolStripMenuItem - // - UpdateAvailableToolStripMenuItem.Alignment = ToolStripItemAlignment.Right; - UpdateAvailableToolStripMenuItem.AutoSize = false; - UpdateAvailableToolStripMenuItem.BackColor = Color.SpringGreen; - UpdateAvailableToolStripMenuItem.DisplayStyle = ToolStripItemDisplayStyle.Text; - UpdateAvailableToolStripMenuItem.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 0); - UpdateAvailableToolStripMenuItem.Margin = new Padding(0, 0, 10, 0); - UpdateAvailableToolStripMenuItem.Name = "UpdateAvailableToolStripMenuItem"; - UpdateAvailableToolStripMenuItem.Padding = new Padding(0); - UpdateAvailableToolStripMenuItem.ShowShortcutKeys = false; - UpdateAvailableToolStripMenuItem.Size = new Size(98, 20); - UpdateAvailableToolStripMenuItem.Text = "Update available"; - UpdateAvailableToolStripMenuItem.Click += UpdateAvailableToolStripMenuItem_Click; - // - // LoopsFolderPanel - // - LoopsFolderPanel.Controls.Add(OutputDirectoryBox); - LoopsFolderPanel.Controls.Add(label17); - LoopsFolderPanel.Dock = DockStyle.Left; - LoopsFolderPanel.Location = new Point(0, 0); - LoopsFolderPanel.Name = "LoopsFolderPanel"; - LoopsFolderPanel.Padding = new Padding(3); - LoopsFolderPanel.Size = new Size(446, 29); - LoopsFolderPanel.TabIndex = 10; - // - // OutputDirectoryBox - // - OutputDirectoryBox.Cursor = Cursors.Hand; - OutputDirectoryBox.Dock = DockStyle.Right; - OutputDirectoryBox.Location = new Point(54, 3); - OutputDirectoryBox.Name = "OutputDirectoryBox"; - OutputDirectoryBox.PlaceholderText = "Click to select output directory"; - OutputDirectoryBox.ReadOnly = true; - OutputDirectoryBox.Size = new Size(389, 23); - OutputDirectoryBox.TabIndex = 0; - OutputDirectoryBox.Click += OutputDirectoryBox_Click; - // - // label17 - // - label17.Dock = DockStyle.Left; - label17.Location = new Point(3, 3); - label17.Name = "label17"; - label17.Size = new Size(50, 23); - label17.TabIndex = 6; - label17.Text = "Output"; - label17.TextAlign = ContentAlignment.MiddleRight; - // - // CancelTaskButton - // - CancelTaskButton.BackColor = Color.RosyBrown; - CancelTaskButton.Dock = DockStyle.Right; - CancelTaskButton.Enabled = false; - CancelTaskButton.FlatStyle = FlatStyle.Popup; - CancelTaskButton.Location = new Point(886, 0); - CancelTaskButton.Name = "CancelTaskButton"; - CancelTaskButton.Size = new Size(81, 29); - CancelTaskButton.TabIndex = 11; - CancelTaskButton.Text = "Cancel"; - CancelTaskButton.UseVisualStyleBackColor = false; - CancelTaskButton.Click += CancelTaskButton_Click; - // // ListenGroupBox // - ListenGroupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; + ListenGroupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; + ListenGroupBox.BackColor = Color.Transparent; + ListenGroupBox.Controls.Add(ExportTestSongBox); + ListenGroupBox.Controls.Add(ClearWhenGenButton); + ListenGroupBox.Controls.Add(ClearCandidatesBox); + ListenGroupBox.Controls.Add(label16); + ListenGroupBox.Controls.Add(EstimatedFrequencyLabel); ListenGroupBox.Controls.Add(BrrExportTypeBox); ListenGroupBox.Controls.Add(LoopStartInputLabel); ListenGroupBox.Controls.Add(label20); @@ -781,19 +874,67 @@ private void InitializeComponent() { ListenGroupBox.Controls.Add(PlayButton); ListenGroupBox.Controls.Add(BRRTestBox); ListenGroupBox.Controls.Add(panel3); - ListenGroupBox.Location = new Point(551, 64); + ListenGroupBox.Location = new Point(550, 64); ListenGroupBox.Name = "ListenGroupBox"; ListenGroupBox.Size = new Size(413, 466); ListenGroupBox.TabIndex = 14; ListenGroupBox.TabStop = false; ListenGroupBox.Text = "Listen"; // + // ExportTestSongBox + // + ExportTestSongBox.AutoSize = true; + ExportTestSongBox.Checked = true; + ExportTestSongBox.CheckState = CheckState.Checked; + ExportTestSongBox.Location = new Point(207, 323); + ExportTestSongBox.Name = "ExportTestSongBox"; + ExportTestSongBox.Size = new Size(106, 19); + ExportTestSongBox.TabIndex = 26; + ExportTestSongBox.Text = "Export test .spc"; + ExportTestSongBox.UseVisualStyleBackColor = true; + // + // ClearWhenGenButton + // + ClearWhenGenButton.AutoSize = true; + ClearWhenGenButton.Checked = true; + ClearWhenGenButton.CheckState = CheckState.Checked; + ClearWhenGenButton.Location = new Point(207, 441); + ClearWhenGenButton.Name = "ClearWhenGenButton"; + ClearWhenGenButton.Size = new Size(145, 19); + ClearWhenGenButton.TabIndex = 25; + ClearWhenGenButton.Text = "Clear when generating"; + ClearWhenGenButton.UseVisualStyleBackColor = true; + // + // ClearCandidatesBox + // + ClearCandidatesBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + ClearCandidatesBox.Location = new Point(2, 440); + ClearCandidatesBox.Name = "ClearCandidatesBox"; + ClearCandidatesBox.Size = new Size(201, 23); + ClearCandidatesBox.TabIndex = 24; + ClearCandidatesBox.Text = "Clear"; + ClearCandidatesBox.UseVisualStyleBackColor = true; + ClearCandidatesBox.Click += ClearCandidatesBox_Click; + // + // EstimatedFrequencyLabel + // + EstimatedFrequencyLabel.AutoSize = true; + EstimatedFrequencyLabel.Enabled = false; + EstimatedFrequencyLabel.Font = new Font("Segoe UI", 9F); + EstimatedFrequencyLabel.Location = new Point(208, 234); + EstimatedFrequencyLabel.Name = "EstimatedFrequencyLabel"; + EstimatedFrequencyLabel.Size = new Size(12, 15); + EstimatedFrequencyLabel.TabIndex = 22; + EstimatedFrequencyLabel.Text = "-"; + EstimatedFrequencyLabel.CursorChanged += EstimatedFrequencyLabel_CursorChanged; + EstimatedFrequencyLabel.Click += EstimatedFrequencyLabel_Click; + // // BrrExportTypeBox // BrrExportTypeBox.DropDownStyle = ComboBoxStyle.DropDownList; BrrExportTypeBox.FormattingEnabled = true; BrrExportTypeBox.Items.AddRange(new object[] { "Raw", "Header", "BRR Suite Sample" }); - BrrExportTypeBox.Location = new Point(294, 248); + BrrExportTypeBox.Location = new Point(294, 271); BrrExportTypeBox.Name = "BrrExportTypeBox"; BrrExportTypeBox.Size = new Size(110, 23); BrrExportTypeBox.TabIndex = 0; @@ -807,19 +948,10 @@ private void InitializeComponent() { LoopStartInputLabel.TabIndex = 14; LoopStartInputLabel.Text = "-"; // - // label20 - // - label20.AutoSize = true; - label20.Location = new Point(207, 180); - label20.Name = "label20"; - label20.Size = new Size(94, 15); - label20.TabIndex = 13; - label20.Text = "Loop start input:"; - // // ExportWAVButton // ExportWAVButton.AutoSize = true; - ExportWAVButton.Location = new Point(207, 275); + ExportWAVButton.Location = new Point(207, 298); ExportWAVButton.Name = "ExportWAVButton"; ExportWAVButton.Size = new Size(88, 19); ExportWAVButton.TabIndex = 15; @@ -831,31 +963,13 @@ private void InitializeComponent() { ExportBRRBox.AutoSize = true; ExportBRRBox.Checked = true; ExportBRRBox.CheckState = CheckState.Checked; - ExportBRRBox.Location = new Point(207, 250); + ExportBRRBox.Location = new Point(207, 273); ExportBRRBox.Name = "ExportBRRBox"; ExportBRRBox.Size = new Size(84, 19); ExportBRRBox.TabIndex = 16; ExportBRRBox.Text = "Export BRR"; ExportBRRBox.UseVisualStyleBackColor = true; // - // label19 - // - label19.AutoSize = true; - label19.Location = new Point(207, 141); - label19.Name = "label19"; - label19.Size = new Size(68, 15); - label19.TabIndex = 8; - label19.Text = "Loop point:"; - // - // label18 - // - label18.AutoSize = true; - label18.Location = new Point(207, 102); - label18.Name = "label18"; - label18.Size = new Size(30, 15); - label18.TabIndex = 7; - label18.Text = "Size:"; - // // AutoPlayCheckBox // AutoPlayCheckBox.AutoSize = true; @@ -908,59 +1022,91 @@ private void InitializeComponent() { // // BRRTestBox // - BRRTestBox.Dock = DockStyle.Left; + BRRTestBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; BRRTestBox.FormattingEnabled = true; BRRTestBox.ItemHeight = 15; - BRRTestBox.Location = new Point(3, 43); + BRRTestBox.Location = new Point(3, 45); + BRRTestBox.Margin = new Padding(3, 3, 3, 0); BRRTestBox.Name = "BRRTestBox"; - BRRTestBox.Size = new Size(198, 420); + BRRTestBox.Size = new Size(199, 394); BRRTestBox.TabIndex = 20; - BRRTestBox.SelectedValueChanged += BRRTestBox_SelectedValueChanged; + BRRTestBox.UseTabStops = false; + BRRTestBox.SelectedIndexChanged += BRRTestBox_SelectedValueChanged; BRRTestBox.DoubleClick += BRRTestBox_DoubleClick; + BRRTestBox.KeyDown += BRRTestBox_KeyDown; + // + // TopMenuStrip + // + TopMenuStrip.AllowMerge = false; + TopMenuStrip.BackColor = SystemColors.Control; + TopMenuStrip.GripMargin = new Padding(1); + TopMenuStrip.GripStyle = ToolStripGripStyle.Hidden; + TopMenuStrip.Items.AddRange(new ToolStripItem[] { FrequencyCheatsheetButton, UpdateAvailableToolStripMenuItem, AboutMenuButton, WaveformViewButton, AdvancedSettingsButton }); + TopMenuStrip.Location = new Point(0, 0); + TopMenuStrip.Name = "TopMenuStrip"; + TopMenuStrip.Padding = new Padding(5, 0, 1, 0); + TopMenuStrip.Size = new Size(967, 26); + TopMenuStrip.TabIndex = 0; + // + // FrequencyCheatsheetButton + // + FrequencyCheatsheetButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + FrequencyCheatsheetButton.Image = Properties.Resources.menubar_freq; + FrequencyCheatsheetButton.ImageTransparentColor = Color.Magenta; + FrequencyCheatsheetButton.Name = "FrequencyCheatsheetButton"; + FrequencyCheatsheetButton.Size = new Size(23, 23); + FrequencyCheatsheetButton.Text = "Frequency cheatsheet"; + FrequencyCheatsheetButton.Click += BonusWindowClick; // - // panel3 - // - panel3.Controls.Add(ExportFinalNameBox); - panel3.Controls.Add(ExportThisButton); - panel3.Dock = DockStyle.Top; - panel3.Location = new Point(3, 19); - panel3.Name = "panel3"; - panel3.Size = new Size(407, 24); - panel3.TabIndex = 9; - // - // ExportFinalNameBox - // - ExportFinalNameBox.Dock = DockStyle.Fill; - ExportFinalNameBox.Location = new Point(0, 0); - ExportFinalNameBox.Margin = new Padding(0); - ExportFinalNameBox.Name = "ExportFinalNameBox"; - ExportFinalNameBox.PlaceholderText = "exported file name"; - ExportFinalNameBox.Size = new Size(332, 23); - ExportFinalNameBox.TabIndex = 0; - ExportFinalNameBox.KeyDown += ExportNames_KeyDown; - ExportFinalNameBox.Leave += ExportNames_Leave; - // - // ExportThisButton - // - ExportThisButton.Dock = DockStyle.Right; - ExportThisButton.Location = new Point(332, 0); - ExportThisButton.Name = "ExportThisButton"; - ExportThisButton.Size = new Size(75, 24); - ExportThisButton.TabIndex = 1; - ExportThisButton.Text = "Export"; - ExportThisButton.UseVisualStyleBackColor = true; - ExportThisButton.Click += ExportThisButton_Click; + // UpdateAvailableToolStripMenuItem // - // panel1 + UpdateAvailableToolStripMenuItem.Alignment = ToolStripItemAlignment.Right; + UpdateAvailableToolStripMenuItem.AutoSize = false; + UpdateAvailableToolStripMenuItem.AutoToolTip = false; + UpdateAvailableToolStripMenuItem.BackColor = Color.Silver; + UpdateAvailableToolStripMenuItem.DisplayStyle = ToolStripItemDisplayStyle.Text; + UpdateAvailableToolStripMenuItem.ForeColor = Color.DimGray; + UpdateAvailableToolStripMenuItem.ImageTransparentColor = Color.Magenta; + UpdateAvailableToolStripMenuItem.Margin = new Padding(10, 2, 2, 2); + UpdateAvailableToolStripMenuItem.Name = "UpdateAvailableToolStripMenuItem"; + UpdateAvailableToolStripMenuItem.Overflow = ToolStripItemOverflow.Never; + UpdateAvailableToolStripMenuItem.Size = new Size(120, 22); + UpdateAvailableToolStripMenuItem.Text = "Update available"; + UpdateAvailableToolStripMenuItem.ToolTipText = "Check for updates"; + UpdateAvailableToolStripMenuItem.Click += UpdateAvailableToolStripMenuItem_Click; // - panel1.Controls.Add(TaskProgress); - panel1.Controls.Add(LoopsFolderPanel); - panel1.Controls.Add(CancelTaskButton); - panel1.Dock = DockStyle.Bottom; - panel1.Location = new Point(0, 537); - panel1.Name = "panel1"; - panel1.Size = new Size(967, 29); - panel1.TabIndex = 13; + // AboutMenuButton + // + AboutMenuButton.Alignment = ToolStripItemAlignment.Right; + AboutMenuButton.AutoToolTip = false; + AboutMenuButton.BackgroundImageLayout = ImageLayout.Stretch; + AboutMenuButton.Image = Properties.Resources.menubar_about; + AboutMenuButton.ImageTransparentColor = Color.Magenta; + AboutMenuButton.Name = "AboutMenuButton"; + AboutMenuButton.Size = new Size(60, 23); + AboutMenuButton.Text = "About"; + AboutMenuButton.ToolTipText = "About BRR Suite"; + AboutMenuButton.Click += Acknowledgements_Click; + // + // WaveformViewButton + // + WaveformViewButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + WaveformViewButton.Image = Properties.Resources.menubar_wave; + WaveformViewButton.ImageTransparentColor = Color.Magenta; + WaveformViewButton.Name = "WaveformViewButton"; + WaveformViewButton.Size = new Size(23, 23); + WaveformViewButton.Text = "Waveform viewer"; + WaveformViewButton.Click += BonusWindowClick; + // + // AdvancedSettingsButton + // + AdvancedSettingsButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + AdvancedSettingsButton.Image = Properties.Resources.menubar_encodersettings; + AdvancedSettingsButton.ImageTransparentColor = Color.Magenta; + AdvancedSettingsButton.Name = "AdvancedSettingsButton"; + AdvancedSettingsButton.Size = new Size(23, 23); + AdvancedSettingsButton.Text = "Advanced settings"; + AdvancedSettingsButton.Click += AdvancedButtonClick; // // MainForm // @@ -974,10 +1120,9 @@ private void InitializeComponent() { Controls.Add(InputGroupBox); Controls.Add(OutputGroupBox); Controls.Add(panel2); - Controls.Add(menuStrip1); + Controls.Add(TopMenuStrip); FormBorderStyle = FormBorderStyle.FixedDialog; Icon = (Icon) resources.GetObject("$this.Icon"); - MainMenuStrip = menuStrip1; MaximizeBox = false; MinimumSize = new Size(983, 605); Name = "MainForm"; @@ -985,8 +1130,13 @@ private void InitializeComponent() { DragDrop += MainForm_DragDrop; DragEnter += MainForm_DragEnter; DragLeave += MainForm_DragLeave; - OutputGroupBox.ResumeLayout(false); - OutputGroupBox.PerformLayout(); + panel2.ResumeLayout(false); + panel2.PerformLayout(); + panel3.ResumeLayout(false); + panel3.PerformLayout(); + panel1.ResumeLayout(false); + LoopsFolderPanel.ResumeLayout(false); + LoopsFolderPanel.PerformLayout(); groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); ((System.ComponentModel.ISupportInitialize) LoopFindRangeBox).EndInit(); @@ -997,20 +1147,15 @@ private void InitializeComponent() { groupBox3.PerformLayout(); ((System.ComponentModel.ISupportInitialize) AdjustRangeBox).EndInit(); ((System.ComponentModel.ISupportInitialize) SampleAdjustAtBox).EndInit(); + OutputGroupBox.ResumeLayout(false); + OutputGroupBox.PerformLayout(); InputGroupBox.ResumeLayout(false); InputGroupBox.PerformLayout(); ((System.ComponentModel.ISupportInitialize) TrimPointBox).EndInit(); - panel2.ResumeLayout(false); - panel2.PerformLayout(); - menuStrip1.ResumeLayout(false); - menuStrip1.PerformLayout(); - LoopsFolderPanel.ResumeLayout(false); - LoopsFolderPanel.PerformLayout(); ListenGroupBox.ResumeLayout(false); ListenGroupBox.PerformLayout(); - panel3.ResumeLayout(false); - panel3.PerformLayout(); - panel1.ResumeLayout(false); + TopMenuStrip.ResumeLayout(false); + TopMenuStrip.PerformLayout(); ResumeLayout(false); PerformLayout(); } @@ -1018,8 +1163,6 @@ private void InitializeComponent() { #endregion private TextBox FileNameBox; - private Label label1; - private Label label2; private GroupBox OutputGroupBox; private ComboBox ResampleBox; private GroupBox InputGroupBox; @@ -1027,43 +1170,22 @@ private void InitializeComponent() { private TextBox SampleCountBox; private TextBox FidelityBox; private TextBox ZeroCrossingBox; - private Label label5; - private Label label4; - private Label label3; - private NumericUpDown LoopStartBox; - private NumericUpDown SampleAdjustAtBox; - private GroupBox groupBox3; - private Label label7; - private NumericUpDown AdjustRangeBox; - private Label label6; + private RoundedUpDown LoopStartBox; + private RoundedUpDown SampleAdjustAtBox; + private RoundedUpDown AdjustRangeBox; private Button AdjustButton; - private Label label8; private Button FindZeroesButton; - private Label label10; - private NumericUpDown TrimPointBox; - private Label label11; + private RoundedUpDown TrimPointBox; private TextBox BRRBlocksBox; private Button FindLoopsButton; - private Label label12; private ComboBox OutputInterpolationBox; private ProgressBar TaskProgress; - private Label label13; private TextBox ExportNameBox; - private Label label14; - private NumericUpDown LoopIncrementBox; - private Label label9; - private NumericUpDown LoopAttemptsBox; - private Label label15; - private NumericUpDown LoopFindRangeBox; + private RoundedUpDown LoopIncrementBox; + private RoundedUpDown LoopAttemptsBox; + private RoundedUpDown LoopFindRangeBox; private TextBox ScratchBox; - private Panel panel2; - private MenuStrip menuStrip1; - private ToolStripMenuItem windowToolStripMenuItem; - private ToolStripMenuItem frequencyCheatsheetToolStripMenuItem; - private ToolStripMenuItem helpToolStripMenuItem; - private ToolStripMenuItem acknowledgementsToolStripMenuItem; private Panel LoopsFolderPanel; - private Label label17; private TextBox OutputDirectoryBox; private CheckBox TrimZerosBox; private Button CancelTaskButton; @@ -1075,21 +1197,25 @@ private void InitializeComponent() { private TextBox ExportFinalNameBox; private Label SizeLabel; private CheckBox AutoPlayCheckBox; - private Panel panel1; - private Label label19; - private Label label18; - private Panel panel3; private Button ExportThisButton; private CheckBox ExportBRRBox; private CheckBox ExportWAVButton; private Button CreateUnloopedButton; private Label LoopStartInputLabel; - private Label label20; - private GroupBox groupBox1; private ComboBox BrrExportTypeBox; - private CheckBox FilterSilenceBox; - private Label label21; private ComboBox TrebleBoostFilterBox; private Button RefreshFileButton; - private ToolStripMenuItem UpdateAvailableToolStripMenuItem; + private ToolStrip TopMenuStrip; + private ToolStripButton FrequencyCheatsheetButton; + private ToolStripButton UpdateAvailableToolStripMenuItem; + private ToolStripButton AboutMenuButton; + private ToolStripButton WaveformViewButton; + private Label InFreqLabel; + private Label EstimatedFrequencyLabel; + private CheckBox EstimatedFrequencyBox; + private Button ClearCandidatesBox; + private CheckBox ClearWhenGenButton; + private CheckBox ExportTestSongBox; + private Button OpenOutputButton; + private ToolStripButton AdvancedSettingsButton; } diff --git a/MainForm.cs b/Forms/MainForm.cs similarity index 56% rename from MainForm.cs rename to Forms/MainForm.cs index c769e1c..a60bf5b 100644 --- a/MainForm.cs +++ b/Forms/MainForm.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Xml; namespace BRRSuiteGUI; @@ -22,8 +23,6 @@ public sealed partial class MainForm : Form { private CancellationTokenSource CancelSource = new(); private CancellationToken CancelToken => CancelSource.Token; - - /*************************************************************************************************\ * Initialization \*************************************************************************************************/ @@ -34,7 +33,6 @@ public MainForm() { InitializeMore(); } - private record AppVersion(int Major, int Minor, int Build) { public override string ToString() => $"v{Major}.{Minor}.{Build}"; @@ -65,10 +63,25 @@ public int CompareTo(AppVersion? other) { private const string UnknownVersion = "v?.?.?"; internal static string VersionString => thisVersion?.ToString() ?? UnknownVersion; + private static readonly byte[]? engineBase; + + private static readonly string AppDirectory; static MainForm() { - // find the current app version the + AppDirectory = AppDomain.CurrentDomain.BaseDirectory; + + // try to get the test SPC engine + try { + using var rd = new FileStream($"{AppDirectory}/testengine.bin", FileMode.Open, FileAccess.Read); + // Verify WAV + engineBase = new byte[(int) rd.Length]; + rd.Read(engineBase, 0, engineBase.Length); + } catch { + // give up + engineBase = null; + } + // find the current app version try { var thisXml = new XmlDocument(); thisXml.LoadXml(Properties.Resources.version); @@ -77,6 +90,10 @@ static MainForm() { thisVersion = null; // give up } +#if DEBUG + availableVersion = new(0, 0, 0); +#else + // find the available version try { var newXml = new XmlDocument(); newXml.Load(XmlReader.Create("https://raw.githubusercontent.com/spannerisms/BRRSuiteGUI/main/version.xml")); @@ -84,39 +101,32 @@ static MainForm() { } catch { availableVersion = null; // give up } +#endif - + // local function to parse them the same way static AppVersion? MakeVersion(XmlDocument xml) { try { var vnode = xml.SelectSingleNode("//version"); - if (vnode?.Attributes is not XmlAttributeCollection attrs) { - return null; - } - - // get each version number - if (!int.TryParse(attrs["major"]?.Value, out int maj)) { - return null; // if any fail, give up - } + if (vnode?.Attributes is not XmlAttributeCollection attrs) return null; - if (!int.TryParse(attrs["minor"]?.Value, out int min)) { - return null; - } - - if (!int.TryParse(attrs["build"]?.Value, out int bld)) { - return null; - } + // get each version number; if any fail, give up + if (!int.TryParse(attrs["major"]?.Value, out int maj)) return null; + if (!int.TryParse(attrs["minor"]?.Value, out int min)) return null; + if (!int.TryParse(attrs["build"]?.Value, out int bld)) return null; return new(maj, min, bld); } catch { - // if any problems occur, just return null - return null; + return null; // if any problems occur, just return null } - } + } // end local } + private readonly WaveformWindow waveWindow = new() { Visible = false }; + + private void InitializeMore() { DisableTabStop(this); @@ -125,8 +135,6 @@ private void InitializeMore() { OutputInterpolationBox.DataSource = new ItemWithName[] { new("Nearest neighbor", ResamplingAlgorithms.NoInterpolation), - new("Linear", ResamplingAlgorithms.LinearInterpolation), - new("Sinusoidal", ResamplingAlgorithms.SineInterpolation), new("Cubic", ResamplingAlgorithms.CubicInterpolation), new("Band-limited", ResamplingAlgorithms.BandlimitedInterpolation), }; @@ -145,20 +153,21 @@ private void InitializeMore() { TrebleBoostFilterBox.SelectedIndex = 0; - AdjustRangeBox.MouseWheel += NumberBoxMouseWheel; - LoopAttemptsBox.MouseWheel += NumberBoxMouseWheel; - LoopFindRangeBox.MouseWheel += NumberBoxMouseWheel; - LoopIncrementBox.MouseWheel += NumberBoxMouseWheel; - LoopStartBox.MouseWheel += NumberBoxMouseWheel; - SampleAdjustAtBox.MouseWheel += NumberBoxMouseWheel; - TrimPointBox.MouseWheel += NumberBoxMouseWheel; - ExportNameBox.AcceptsReturn = true; ExportFinalNameBox.AcceptsReturn = true; + // add button windows + WaveformViewButton.Tag = waveWindow; + FrequencyCheatsheetButton.Tag = new FrequencyWindow() { Visible = false }; + + if (engineBase is null) { + ExportTestSongBox.Checked = false; + ExportTestSongBox.Enabled = false; + } + + CheckForUpdates(); EnableForm(false); - OffTextButton(); static void DisableTabStop(Control cont) { @@ -171,39 +180,21 @@ static void DisableTabStop(Control cont) { } } - private static void NumberBoxMouseWheel(object? sender, MouseEventArgs e) { - if (sender is not NumericUpDown box) return; + private readonly UpdateAnnouncer UpdateShower = new(); - if (e is HandledMouseEventArgs f) { - f.Handled = true; - } - - if (e.Delta > 0) { - if (box.Value == box.Maximum) { - return; - } - box.Value++; - } else if (e.Delta < 0) { - if (box.Value == box.Minimum) { - return; - } - box.Value--; - } - } - - - private readonly UpdateAnnouncer announcer = new(); + private static readonly Color Periwinkle = Color.FromArgb(0xCC, 0xCC, 0xFF); + private static readonly Color DarkPeriwinkle = Color.FromArgb(0x64, 0x64, 0xC8); private void CheckForUpdates() { - announcer.VersionCurrent = thisVersion?.ToString() ?? UnknownVersion; - announcer.VersionNew = availableVersion?.ToString() ?? UnknownVersion; + UpdateShower.VersionCurrent = thisVersion?.ToString() ?? UnknownVersion; + UpdateShower.VersionNew = availableVersion?.ToString() ?? UnknownVersion; if (thisVersion is null || availableVersion is null) { - UpdateAvailableToolStripMenuItem.BackColor = Color.DarkOrange; - UpdateAvailableToolStripMenuItem.ForeColor = SystemColors.ControlText; + UpdateAvailableToolStripMenuItem.BackColor = Color.Orange; + UpdateAvailableToolStripMenuItem.ForeColor = Color.Maroon; UpdateAvailableToolStripMenuItem.Text = "Problem"; - announcer.Message = (thisVersion, availableVersion) switch { + UpdateShower.Message = (thisVersion, availableVersion) switch { (null, null) => "Could not determine the current version or available version.", (null, _) => "Could not determine the current version.", (_, null) => "Could not determine available version.", @@ -217,28 +208,39 @@ private void CheckForUpdates() { if (test < 0) { UpdateAvailableToolStripMenuItem.BackColor = Color.SpringGreen; - UpdateAvailableToolStripMenuItem.ForeColor = SystemColors.ControlText; - UpdateAvailableToolStripMenuItem.Text = "Updates available"; - announcer.Message = "A new version is available."; + UpdateAvailableToolStripMenuItem.ForeColor = Color.Green; + UpdateAvailableToolStripMenuItem.Text = "Update available"; + UpdateShower.Message = "A new version is available."; } else if (test > 0) { - UpdateAvailableToolStripMenuItem.BackColor = Color.Aqua; - UpdateAvailableToolStripMenuItem.ForeColor = SystemColors.ControlDark; + UpdateAvailableToolStripMenuItem.BackColor = Periwinkle; + UpdateAvailableToolStripMenuItem.ForeColor = DarkPeriwinkle; UpdateAvailableToolStripMenuItem.Text = "Beta"; - announcer.Message = "It appears you have an unreleased version."; + UpdateShower.Message = "It appears you have an unreleased version."; } else { - UpdateAvailableToolStripMenuItem.BackColor = SystemColors.Control; - UpdateAvailableToolStripMenuItem.ForeColor = SystemColors.ControlDark; + UpdateAvailableToolStripMenuItem.BackColor = Color.Silver; + UpdateAvailableToolStripMenuItem.ForeColor = Color.DimGray; UpdateAvailableToolStripMenuItem.Text = "No updates"; - announcer.Message = "Your application is up to date."; + UpdateShower.Message = "Your application is up to date."; } } private void UpdateAvailableToolStripMenuItem_Click(object sender, EventArgs e) { - announcer.ShowDialog(); + UpdateShower.ShowDialog(); } + private readonly AdvancedSettingsWindow AdvancedWindow = new(); + private decimal DecodeMinimumLength = 1.5M; + private int MinimumTrimZeros = 3; + private void AdvancedButtonClick(object sender, EventArgs e) { + AdvancedWindow.PreviewDuration = DecodeMinimumLength; + AdvancedWindow.MinimumTrimZeros = MinimumTrimZeros; + if (AdvancedWindow.ShowDialog() is DialogResult.OK) { + DecodeMinimumLength = decimal.Round(AdvancedWindow.PreviewDuration, 1); + MinimumTrimZeros = AdvancedWindow.MinimumTrimZeros; + } + } /*************************************************************************************************\ * User communication @@ -270,11 +272,11 @@ private void CheckForOutputDirectory() { } private static string GetFormattedSize(int blocks) => - string.Format("{0} blocks - {1} bytes (${1:X4})", blocks, BrrBlockSize * blocks); + string.Format("{0} block{2} - {1} bytes (${1:X4})", blocks, Conversion.BRRBlockSize * blocks, blocks == 1 ? "" : "s"); private static string GetFormattedLoopPoint(int blocks) => blocks switch { < 0 => "-", - _ => string.Format("{0} blocks (${1:X4})", blocks, BrrBlockSize * blocks) + _ => string.Format("{0} block{2} (${1:X4})", blocks, Conversion.BRRBlockSize * blocks, blocks == 1 ? "" : "s") }; @@ -304,7 +306,6 @@ private void EnableControls(bool enable) { EnableForm(enable); } - private void SetOutputDirectory(string path) { OutputDirectory = null; @@ -324,10 +325,22 @@ private void SetOutputDirectory(string path) { OffTextButton(); } + private void AddCandidateToBox(TestContainer brr) { + BRRTestBox.Items.Add(brr); + } + + private void ClearFileListConditional() { + if (ClearWhenGenButton.Checked) { + ClearFileList(); + } + } + private void ClearFileList() { - Player.Stop(); + StopSamplePreview(); CurrentBRR = null; BRRTestBox.Items.Clear(); + BRRTestBox.SelectedIndex = -1; + ClearPreviewInfo(); } private const string InvalidChars = @"<>:""/\|?*[]{}"; @@ -380,7 +393,6 @@ private static void ValidateFileName(TextBox t) { t.Text = text; } - /*************************************************************************************************\ * Async tasks \*************************************************************************************************/ @@ -390,7 +402,7 @@ private async Task RunGUITask(Func func) { try { await func(); } catch (OperationCanceledException) { - // Do nothing + // Task was cancelled. Everything is fine. } catch (Exception f) { ShowError(f.Message); } @@ -432,7 +444,13 @@ private void CancelTaskButton_Click(object sender, EventArgs e) { * Input area methods and events \*************************************************************************************************/ private void FindZeroesButton_Click(object sender, EventArgs e) { - CheckForWave(); + try { + CheckForWave(); + } catch (Exception x) { + ZeroCrossingBox.Text = string.Empty; + ShowError(x.Message); + return; + } var crossings = new List(); int min = (int) LoopStartBox.Value; @@ -458,6 +476,27 @@ private void FindZeroesButton_Click(object sender, EventArgs e) { /*************************************************************************************************\ * General conversion methods and events \*************************************************************************************************/ +#pragma warning disable IDE0079 // shut up + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", + "CA1859:Use concrete types when possible for improved performance", + Justification = "We'll have other encoders eventually.")] + private BRREncoder GetCurrentEncoder() { + BRRtoolsEncoder ret = new() { + Resampler = GetCurrentResamplingAlgorithm(), + Filters = GetFilters(), + EnableFilter0 = true, + EnableFilter1 = true, + EnableFilter2 = true, + EnableFilter3 = true, + LeadingZeros = TrimZerosBox.Checked ? MinimumTrimZeros : -1, + ResampleFactor = CurrentSampleRate.ResampleFrom(CurrentWAV!.SampleRate), + Truncate = (int) TrimPointBox.Value, + }; + + return ret; + } +#pragma warning restore IDE0079 + private ResamplingAlgorithm GetCurrentResamplingAlgorithm() { var temp = OutputInterpolationBox.SelectedItem as ItemWithName; @@ -473,90 +512,78 @@ private void TrimPointBox_ValueChanged(object sender, EventArgs e) { } private void SampleBox_SelectedIndexChanged(object sender, EventArgs e) { - CurrentSampleRate = (ResampleBox.SelectedItem as SampleRate) ?? SampleRate.SR32000; + CurrentSampleRate = (ResampleBox.SelectedItem as SampleRate?) ?? SampleRate.SR32000; RecalculateNumberOfBRRBlocks(); } - private async void CreateUnloopedButton_Click(object sender, EventArgs e) { await RunGUITask(UnloopedFiles); } + private PreEncodingFilter GetFilters() { + PreEncodingFilter ret = PreEncodingFilters.NoFilter; - private EncodingAlgorithm GetEncoder() { - return Conversion.GetBRRtoolsBruteForce(FilterSilenceBox.Checked, false, false, false, false); - } - - private PreEncodingFilter[]? GetFilters() { if (TrebleBoostFilterBox.SelectedItem is ItemWithName i) { if (i.Thing is PreEncodingFilter j) { - return [j]; + ret += j; } } - return null; + return ret; } - private async Task UnloopedFiles() { CheckForWave(); - ClearFileList(); - - int trim = (int) TrimPointBox.Value; - bool trimFront = TrimZerosBox.Checked; - - ResamplingAlgorithm outResamp = GetCurrentResamplingAlgorithm(); + ClearFileListConditional(); string sampleName = wavName; NewTaskBarThing(2 * sampleRates.Count); - int[] wavSamples = CurrentWAV!.GetSamplesCopy(); - var encoder = GetEncoder(); - var filters = GetFilters(); + int[] wavSamples = CurrentWAV!.SamplesToArray(); + BRREncoder enc = GetCurrentEncoder(); + bool freqEst = EstimatedFrequencyBox.Checked; + var tasks = new List(); foreach (var freq in sampleRates) { - decimal resampleFactorBRR = CurrentWAV.SampleRate.ResampleTo(freq); + CancelToken.ThrowIfCancellationRequested(); + + enc.ResampleFactor = CurrentSampleRate.ResampleFrom(freq); BRRSample brr = await Task.Run(() => - Conversion.Encode( - wavSamples: wavSamples, - encoder: encoder, - resampleAlgorithm: outResamp, - resampleFactor: resampleFactorBRR, - truncate: trim, - waveFilters: filters, - trimLeadingZeroes: trimFront, - loopStart: NoLoop + enc.Encode( + pcmSamples: wavSamples, + pcmLoopPoint: Conversion.NoLoop )); - brr.EncodingFrequency = freq.Frequency; - TaskProgress.PerformStep(); CancelToken.ThrowIfCancellationRequested(); WaveContainer wavOut = await Task.Run(() => - Conversion.Decode( - brrSample: brr.Data, - loopBlock: NoLoop, - sampleRate: freq.Frequency, - applyGaussian: false + brr.Decode( + pitch: Conversion.DefaultVxPitch )); TaskProgress.PerformStep(); - CancelToken.ThrowIfCancellationRequested(); TestContainer addbrr = new(sampleName, brr, wavOut) { ListName = $"{sampleName}_{freq.FrequencykHz}", FileName = $"{sampleName}_{freq.FrequencykHz}", LoopSample = null, - Trim = trim, + EncodingFrequency = freq, + Trim = enc.Truncate, }; - BRRTestBox.Items.Add(addbrr); + if (freqEst) { + tasks.Add(Task.Run(addbrr.DoFrequencyEstimate)); + } + + AddCandidateToBox(addbrr); } + await Task.WhenAll(tasks); + return; } @@ -571,16 +598,14 @@ private async void FindLoopsButton_Click(object sender, EventArgs e) { private async Task LoopSearch() { CheckForWave(); - ClearFileList(); + ClearFileListConditional(); int minLoop = (int) LoopStartBox.Value; int increment = (int) LoopIncrementBox.Value; int attempts = (int) LoopAttemptsBox.Value; int range = (int) LoopFindRangeBox.Value; - int maxLoop = attempts * increment + minLoop; - bool trimFront = TrimZerosBox.Checked; + int maxLoop = (attempts - 1) * increment + minLoop; - SampleRate freq = CurrentSampleRate; string sampleName = wavName; string outFolder = OutputDirectory!; int trim = (int) TrimPointBox.Value; @@ -598,63 +623,60 @@ private async Task LoopSearch() { CancelToken.ThrowIfCancellationRequested(); attemptsList.RemoveAll(r => r < 0 || r >= trim); - - ResamplingAlgorithm outResamp = GetCurrentResamplingAlgorithm(); - decimal resampleFactorBRR = CurrentWAV!.SampleRate.ResampleTo(CurrentSampleRate); - decimal resampleFactorWAV = CurrentSampleRate.ResampleTo(SampleRate.SR32000); - var loopList = attemptsList.Distinct(); - NewTaskBarThing(2 * loopList.Count()); - int[] wavSamples = CurrentWAV.GetSamplesCopy(); - var encoder = GetEncoder(); - var filters = GetFilters(); + int[] wavSamples = CurrentWAV!.SamplesToArray(); + bool freqEst = EstimatedFrequencyBox.Checked; + decimal minLength = DecodeMinimumLength; + SampleRate freq = CurrentSampleRate; + + BRREncoder enc = GetCurrentEncoder(); + + // doing each step as an async task and making a wave file for each brr as it's encoded is fast + // but it also can't be cancelled, so plbt + var tasks = new List(); foreach (int loop in loopList) { CancelToken.ThrowIfCancellationRequested(); + BRRSample brr = await Task.Run(() => - Conversion.Encode( - wavSamples: wavSamples, - encoder: encoder, - resampleAlgorithm: outResamp, - resampleFactor: resampleFactorBRR, - truncate: trim, - waveFilters: filters, - trimLeadingZeroes: trimFront, - loopStart: loop + enc.Encode( + pcmSamples: wavSamples, + pcmLoopPoint: loop )); - brr.EncodingFrequency = freq.Frequency; - - int loopBlock = brr.LoopBlock; - TaskProgress.PerformStep(); CancelToken.ThrowIfCancellationRequested(); WaveContainer wavOut = await Task.Run(() => - Conversion.Decode( - brrSample: brr.Data, - loopBlock: loopBlock, - sampleRate: freq.Frequency, - minimumLength: 2.0M, - applyGaussian: false + brr.Decode( + pitch: Conversion.DefaultVxPitch, + minimumLength: minLength )); TaskProgress.PerformStep(); - CancelToken.ThrowIfCancellationRequested(); TestContainer addbrr = new(sampleName, brr, wavOut) { ListName = $"{sampleName}_{freq.FrequencykHz}_{loop}", - FileName = $"{sampleName}_{freq.FrequencykHz}_{loopBlock}", + FileName = $"{sampleName}_{freq.FrequencykHz}_{brr.LoopBlock}", LoopSample = loop, - Trim = trim, + EncodingFrequency = freq, + Trim = enc.Truncate, }; - BRRTestBox.Items.Add(addbrr); + + if (freqEst) { + tasks.Add(Task.Run(addbrr.DoFrequencyEstimate)); + } + + AddCandidateToBox(addbrr); } + + await Task.WhenAll(tasks); } + /*************************************************************************************************\ * Fine adjustment methods and events \*************************************************************************************************/ @@ -665,7 +687,8 @@ private async void AdjustButton_Click(object sender, EventArgs e) { private async Task SampleAdjust() { CheckForWave(); - ClearFileList(); + + ClearFileListConditional(); int loop = (int) SampleAdjustAtBox.Value; int distance = (int) AdjustRangeBox.Value; @@ -673,74 +696,68 @@ private async Task SampleAdjust() { int trimPoint = (int) TrimPointBox.Value; int minTrim = Math.Max(trimPoint - distance, 0); int maxTrim = Math.Min(trimPoint + distance, CurrentWAV!.SampleCount); - bool trimFront = TrimZerosBox.Checked; + + NewTaskBarThing(2 * (maxTrim - minTrim + 1)); ResamplingAlgorithm outResamp = GetCurrentResamplingAlgorithm(); - decimal resampleFactorBRR = CurrentWAV.SampleRate.ResampleTo(CurrentSampleRate); SampleRate freq = CurrentSampleRate; string sampleName = wavName; - NewTaskBarThing(2 * (maxTrim - minTrim + 1)); + int[] wavSamples = CurrentWAV.SamplesToArray(); + bool freqEst = EstimatedFrequencyBox.Checked; + decimal minLength = DecodeMinimumLength; - int[] wavSamples = CurrentWAV.GetSamplesCopy(); - var encoder = GetEncoder(); - var filters = GetFilters(); + BRREncoder enc = GetCurrentEncoder(); + var tasks = new List(); for (int trim = minTrim; trim <= maxTrim; trim++) { + CancelToken.ThrowIfCancellationRequested(); + + enc.Truncate = trim; BRRSample brr = await Task.Run(() => - Conversion.Encode( - wavSamples: wavSamples, - encoder: encoder, - resampleAlgorithm: outResamp, - resampleFactor: resampleFactorBRR, - trimLeadingZeroes: trimFront, - waveFilters: filters, - truncate: trim, - loopStart: loop + enc.Encode( + pcmSamples: wavSamples, + pcmLoopPoint: loop )); - brr.EncodingFrequency = freq.Frequency; - int loopBlock = brr.LoopBlock; - TaskProgress.PerformStep(); CancelToken.ThrowIfCancellationRequested(); WaveContainer wavOut = await Task.Run(() => - Conversion.Decode( - brrSample: brr.Data, - loopBlock: loopBlock, - sampleRate: freq.Frequency, - minimumLength: 2.0M, - applyGaussian: false + brr.Decode( + pitch: Conversion.DefaultVxPitch, + minimumLength: minLength )); - CancelToken.ThrowIfCancellationRequested(); + TaskProgress.PerformStep(); TestContainer addbrr = new(sampleName, brr, wavOut) { ListName = $"{sampleName}_{freq.FrequencykHz}_p{loop}t{trim}", - FileName = $"{sampleName}_{freq.FrequencykHz}_{loopBlock}", + FileName = $"{sampleName}_{freq.FrequencykHz}_{brr.LoopBlock}", LoopSample = loop, - Trim = trim, + EncodingFrequency = freq, + Trim = enc.Truncate, }; - BRRTestBox.Items.Add(addbrr); + if (freqEst) { + tasks.Add(Task.Run(addbrr.DoFrequencyEstimate)); + } - TaskProgress.PerformStep(); - CancelToken.ThrowIfCancellationRequested(); - this.MdiChildrenMinimizedAnchorBottom = true; + AddCandidateToBox(addbrr); } + + await Task.WhenAll(tasks); } private void RecalculateNumberOfBRRBlocks() { if (CurrentWAV is null) return; - int numberOfBlocks = (int) (TrimPointBox.Value / CurrentSampleRate.Cram / PcmBlockSize); + int numberOfBlocks = (int) (TrimPointBox.Value / CurrentSampleRate.Cram / Conversion.PCMBlockSize); BRRBlocksBox.Text = GetFormattedSize(numberOfBlocks); } - private string? oldText = null; private void MainForm_DragDrop(object sender, DragEventArgs e) { Activate(); @@ -759,6 +776,22 @@ private void MainForm_DragLeave(object sender, EventArgs e) { FileNameBox.Text = oldText; } + private static WaveContainer ReadWaveFromFile(string path) { + using var rd = new FileStream(path, FileMode.Open, FileAccess.Read); + + WaveContainer ret; + + try { + ret = new(rd); + } finally { + rd.Close(); + } + + return ret; + } + + + private void SetFile(string path) { string? newText = null; CurrentWAV = null; @@ -771,11 +804,21 @@ private void SetFile(string path) { ShowError($"The selected file is not a .{WaveContainer.Extension} file."); } else { try { - WaveContainer wav = WaveContainer.ReadFromFile(path); + WaveContainer wav = ReadWaveFromFile(path); SetWAV(wav); EnableForm(true); EnableControls(true); SampleAdjustAtBox.Maximum = TrimPointBox.Value = TrimPointBox.Maximum = CurrentWAV!.SampleCount; + + // if the sample is too large, don't detect the pitch and uncheck the sample calc box + if (wav.SampleCount > 15000) { + InFreqLabel.Text = "-"; + EstimatedFrequencyBox.Checked = false; + } else { + double freq = Aubio.Aubio.DetectPitch(wav); + InFreqLabel.Text = MusicUtility.GetFormattedFrequency(freq); + } + newText = path; ExportNameBox.Text = Path.GetFileNameWithoutExtension(path); } catch (Exception e) { @@ -791,7 +834,7 @@ private void SetFile(string path) { private void SetWAV(WaveContainer wav) { CurrentWAV = wav; - SampleRateBox.Text = $"{wav.SampleRate.Frequency} Hz"; + SampleRateBox.Text = $"{wav.SampleRate} Hz"; FidelityBox.Text = $"{wav.BitsPerSample} bits per sample"; SampleCountBox.Text = $"{wav.SampleCount} samples"; } @@ -800,24 +843,23 @@ private void SetWAV(WaveContainer wav) { * Auxiliary windows \*************************************************************************************************/ private readonly AcknowledgementsWindow acknowledgementWindow = new(); - private void AcknowledgementsToolStripMenuItem_Click(object sender, EventArgs e) { + private void Acknowledgements_Click(object sender, EventArgs e) { acknowledgementWindow.ShowDialog(); } - private FrequencyWindow? cheatsheet = null; - private void FrequencyCheatsheetToolStripMenuItem_Click(object sender, EventArgs e) { - // dumb stuff because I want to only allow 1 open at a time, but not as a modal dialog - if (cheatsheet?.IsDisposed ?? true) { - cheatsheet = new(); + private void BonusWindowClick(object sender, EventArgs e) { + // check for types that have a Tag property + object? w = sender switch { + ToolStripItem a => a.Tag, + Control a => a.Tag, + _ => null + }; - // change the class field back to null when it's disposed - cheatsheet.Disposed += (_, _) => { - cheatsheet = null; - }; + // show w if it's a form + if (w is Form f) { + f.Show(); + f.Focus(); } - - cheatsheet.Show(); - cheatsheet.Focus(); } private readonly OpenFileDialog openWavDialog = new() { @@ -836,6 +878,7 @@ private void FileNameBox_Click(object sender, EventArgs e) { SetFile(openWavDialog.FileName); } } + private void RefreshFileButton_Click(object sender, EventArgs e) { SetFile(FileNameBox.Text); } @@ -854,14 +897,17 @@ private void OutputDirectoryBox_Click(object sender, EventArgs e) { } } + private void OpenOutputButton_Click(object sender, EventArgs e) { + if (OutputDirectory is not null) { + Process.Start("explorer.exe", OutputDirectory); + } + } + + /*************************************************************************************************\ * Listen area \*************************************************************************************************/ - // TODO eventually add analysis tools for the preview - // make them checkboxes with the property and a label for the info? - // [*] Note pitch: A# - private TestContainer? CurrentBRR = null; private readonly System.Media.SoundPlayer Player = new(); @@ -872,7 +918,7 @@ private void BRRTestBox_SelectedValueChanged(object sender, EventArgs e) { } private SampleClickAction SetClickedBRR() { - Player.Stop(); + StopSamplePreview(); var newbr = BRRTestBox.SelectedItem as TestContainer; @@ -885,12 +931,12 @@ private SampleClickAction SetClickedBRR() { CurrentBRR = newbr; + waveWindow.TestSample = CurrentBRR; + Player.Stream?.Dispose(); if (CurrentBRR is null) { - SizeLabel.Text = "-"; - LoopPointLabel.Text = "-"; - ExportFinalNameBox.Text = null; + ClearPreviewInfo(); return SampleClickAction.SampleNull; }; @@ -901,9 +947,40 @@ private SampleClickAction SetClickedBRR() { ExportFinalNameBox.Text = CurrentBRR.FileName; Player.Stream = CurrentBRR.WaveFile.AsMemoryStream(); + if (CurrentBRR.EstimatedFrequency is double freq) { + EstimatedFrequencyLabel.Text = MusicUtility.GetFormattedFrequency(freq); + EstimatedFrequencyLabel.Cursor = Cursors.Default; + } else { + EstimatedFrequencyLabel.Text = "[No frequency calculated]"; + EstimatedFrequencyLabel.Cursor = Cursors.Hand; + } + + EstimatedFrequencyLabel.Enabled = true; + return SampleClickAction.SampleChanged; } + private void EstimatedFrequencyLabel_CursorChanged(object sender, EventArgs e) { + if (EstimatedFrequencyLabel.Cursor == Cursors.Hand) { + EstimatedFrequencyLabel.ForeColor = SystemColors.HotTrack; + EstimatedFrequencyLabel.Font = new Font(EstimatedFrequencyLabel.Font, FontStyle.Underline); + EstimatedFrequencyLabel.Enabled = true; + } else { + EstimatedFrequencyLabel.ForeColor = SystemColors.ControlText; + EstimatedFrequencyLabel.Font = new Font(EstimatedFrequencyLabel.Font, FontStyle.Regular); + EstimatedFrequencyLabel.Enabled = false; + } + } + + private void ClearPreviewInfo() { + SizeLabel.Text = "-"; + LoopPointLabel.Text = "-"; + LoopStartInputLabel.Text = "-"; + EstimatedFrequencyLabel.Text = "-"; + EstimatedFrequencyLabel.Cursor = Cursors.Default; + ExportFinalNameBox.Text = null; + } + private void PlaySamplePreview() { Player.Play(); } @@ -927,29 +1004,161 @@ private void BRRTestBox_DoubleClick(object sender, EventArgs e) { } private void ExportThisButton_Click(object sender, EventArgs e) { - CheckForOutputDirectory(); - CheckForPreviewBRR(); + try { + CheckForOutputDirectory(); + CheckForPreviewBRR(); + } catch (Exception x) { + ShowError(x.Message); + return; + } string fileName = $"{OutputDirectory}/{ExportFinalNameBox.Text.Trim()}"; + BRRSample brr = CurrentBRR!.BRRFile; if (ExportBRRBox.Checked) { switch (BrrExportTypeBox.SelectedIndex) { case 0: - CurrentBRR!.BRRFile.ExportRaw($"{fileName}"); + brr.Save($"{fileName}.{BRRSample.Extension}"); break; case 1: - CurrentBRR!.BRRFile.ExportHeadered($"{fileName}"); + brr.ExportWithHeader($"{fileName}.{BRRSample.HeaderedExtension}"); break; case 2: - CurrentBRR!.BRRFile.ExportSuiteSample($"{fileName}."); + var bs = new SuiteSample(brr){ + EncodingFrequency = CurrentBRR.EncodingFrequency, + InstrumentName = CurrentBRR.Name + }; + bs.Save($"{fileName}.{SuiteSample.Extension}"); break; } } if (ExportWAVButton.Checked) { - CurrentBRR!.WaveFile.Export($"{fileName}.{WaveContainer.Extension}"); + CurrentBRR!.WaveFile.Save($"{fileName}.{WaveContainer.Extension}"); + } + + if (ExportTestSongBox.Checked) { + //string path = $"{OutputDirectory}/{ExportFinalNameBox.Text.Trim()}-spctest.spc"; + string path = $"{OutputDirectory}/_test_.spc"; + + //string path2 = $"{OutputDirectory}/{ExportFinalNameBox.Text.Trim()}-spctest.spc"; + using var fs = new FileStream(path, FileMode.Create, FileAccess.Write); + + ExportSPCFile(CurrentBRR!, fs); + + + //File.Copy(path, path2, true); + } + } + + private void EstimatedFrequencyLabel_Click(object sender, EventArgs e) { + GetPitchOfCurrentCandidate(); + } + + private void GetPitchOfCurrentCandidate() { + EstimatedFrequencyLabel.Cursor = Cursors.Default; + + if (CurrentBRR is null) { + EstimatedFrequencyLabel.Text = "-"; + EstimatedFrequencyLabel.Enabled = true; + return; + } + + CurrentBRR.DoFrequencyEstimate(); + + if (CurrentBRR.EstimatedFrequency is double f) { + EstimatedFrequencyLabel.Text = MusicUtility.GetFormattedFrequency(f); + } else { + EstimatedFrequencyLabel.Text = "Something went wrong."; + EstimatedFrequencyLabel.ForeColor = Color.Red; + } + } + + + private void ClearCandidatesBox_Click(object sender, EventArgs e) { + ClearFileList(); + } + + private void BRRTestBox_KeyDown(object sender, KeyEventArgs e) { + if (e.Handled) { + return; + } + + // don't override the base functionality + switch (e.KeyCode) { + case Keys.Down: + case Keys.Up: + case Keys.PageUp: + case Keys.PageDown: + case Keys.Home: + case Keys.End: + return; + } + + e.Handled = true; + + // TODO figure out how to disable letters from navigating + // other keys + //switch (e.KeyCode) { + // case Keys.A: + // AutoPlayCheckBox.Checked = !AutoPlayCheckBox.Checked; + // return; + //} + + + int index = BRRTestBox.SelectedIndex; + + // the following commands require a valid item to be selected + if (index < 0 || CurrentBRR is null) { + return; + } + + switch (e.KeyCode) { + // delete item + case Keys.Delete: + BRRTestBox.Items.RemoveAt(index); + + int size = BRRTestBox.Items.Count; + + if (size == 0) { + index = -1; + } else if (index >= size) { + index = size - 1; + } + BRRTestBox.SelectedIndex = index; + return; + + // play sample + case Keys.Space: + PlaySamplePreview(); + return; + + + case Keys.Enter: // TODO use this for pitch if can't figure out letters + GetPitchOfCurrentCandidate(); + return; + + // add loop point + case Keys.Back: + if (CurrentBRR?.LoopSample is not int lppt) return; + if (string.IsNullOrWhiteSpace(ScratchBox.Text)) { + ScratchBox.Text = $"{lppt}"; + } else { + ScratchBox.Text += $" {lppt}"; + } + return; + + // detect pitch + //case Keys.P: + // GetPitchOfCurrentCandidate(); + // return; + // + //// select nothing + //case Keys.N: + // BRRTestBox.ClearSelected(); + // return; } } @@ -958,4 +1167,92 @@ private enum SampleClickAction { SampleChanged, SampleUnchanged } + + + + // https://wiki.superfamicom.org/spc-and-rsn-file-format + private static void ExportSPCFile(TestContainer brr, Stream stream) { + if (engineBase is null) { + throw new FileNotFoundException("No engine base resource is loaded."); + } + + stream.SetLength(0x10200); + + stream.Position = 0x00000; + + WriteString("SNES-SPC700 Sound File Data v0.30", 33); + + stream.WriteByte(26); // $00021 + stream.WriteByte(26); // $00022 + stream.WriteByte(26); // $00023 - add ID666 info + stream.WriteByte(30); // $00024 - minor version + + stream.WriteByte(0x00); // $00025 - PC low + stream.WriteByte(0x03); // $00026 - PC high + + stream.WriteByte(0x00); // $00027 - A + stream.WriteByte(0x00); // $00028 - X + stream.WriteByte(0x00); // $00029 - Y + stream.WriteByte(0x00); // $0002A - PSW + stream.WriteByte(0xFF); // $0002B - SP + + stream.WriteByte(0x00); // $0002C - Reserved + stream.WriteByte(0x00); // $0002D - Reserved + + WriteString($"{brr.FileName}", 32); // $0002E - song title + WriteString("BRR Suite GUI sample test song", 32); // $0004E - game title + WriteString("BRR Suite GUI", 16); // $0006E - name of dumper + WriteString("Cool song", 32); // $0007E - comments + WriteString(DateTime.Now.ToString("MM/dd/yyyy"), 11); // $0009E - dump date (MM/DD/YYYY) + + WriteString("999", 3); // $000A9 - time to play song before fading out + WriteString("0123", 4); // $000AC - length of fade + + WriteString("kan, with samples by you!", 32); // $000B1 - artist + + stream.WriteByte(0x01); // $000D1 - channel disables + stream.WriteByte(0x00); // $000D2 - emulator + + stream.WriteByte(0x00); // $000D3 - reserved + + PadTo(0x00100); + + stream.Position = 0x00100; + stream.Write(engineBase!); + + // remember the position we're at + long loop = stream.Position - 0x0100; + loop += brr.BRRFile.LoopPoint; + + stream.Write(brr.BRRFile.AsSpan()); + + if (brr.BRRFile.IsLooping) { + stream.Position = 0x00100 + 0x0202; // navigate to where loop point is saved + stream.WriteByte((byte) loop); + stream.WriteByte((byte) (loop >> 8)); + } + + stream.Position = 0x10100; + stream.Write(engineBase!, 0x0100, 0x80); // copy registers hidden in the stack + + PadTo(stream.Length); // top off the reserved area + + void WriteString(string s, int len) { + if (s.Length < len) { + s = s.PadRight(len, ' '); + } + + for (int i = 0; i < len; i++) { + stream.WriteByte((byte) s[i]); + } + } + + void PadTo(long pos) { + long count = pos - stream.Position; + + for (; count > 0; count--) { + stream.WriteByte(0x00); + } + } + } } diff --git a/MainForm.resx b/Forms/MainForm.resx similarity index 96% rename from MainForm.resx rename to Forms/MainForm.resx index d62073a..3ffa05b 100644 --- a/MainForm.resx +++ b/Forms/MainForm.resx @@ -117,11 +117,89 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 17, 17 + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + False + + + 119, 17 - 25 + 51 diff --git a/UpdateAnnouncer.Designer.cs b/Forms/UpdateAnnouncer.Designer.cs similarity index 100% rename from UpdateAnnouncer.Designer.cs rename to Forms/UpdateAnnouncer.Designer.cs diff --git a/UpdateAnnouncer.cs b/Forms/UpdateAnnouncer.cs similarity index 100% rename from UpdateAnnouncer.cs rename to Forms/UpdateAnnouncer.cs diff --git a/UpdateAnnouncer.resx b/Forms/UpdateAnnouncer.resx similarity index 100% rename from UpdateAnnouncer.resx rename to Forms/UpdateAnnouncer.resx diff --git a/Forms/WaveformWindow.Designer.cs b/Forms/WaveformWindow.Designer.cs new file mode 100644 index 0000000..7a11c51 --- /dev/null +++ b/Forms/WaveformWindow.Designer.cs @@ -0,0 +1,63 @@ +namespace BRRSuiteGUI; + +partial class WaveformWindow { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WaveformWindow)); + WavePanel = new PictureBox(); + ((System.ComponentModel.ISupportInitialize) WavePanel).BeginInit(); + SuspendLayout(); + // + // WavePanel + // + WavePanel.BackColor = SystemColors.ActiveCaptionText; + WavePanel.Dock = DockStyle.Top; + WavePanel.Location = new Point(0, 0); + WavePanel.MinimumSize = new Size(800, 360); + WavePanel.Name = "WavePanel"; + WavePanel.Padding = new Padding(5); + WavePanel.Size = new Size(800, 360); + WavePanel.SizeMode = PictureBoxSizeMode.StretchImage; + WavePanel.TabIndex = 0; + WavePanel.TabStop = false; + // + // WaveformWindow + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(WavePanel); + Icon = (Icon) resources.GetObject("$this.Icon"); + MinimumSize = new Size(816, 489); + Name = "WaveformWindow"; + Text = "Waveform viewer"; + VisibleChanged += WaveformWindow_VisibleChanged; + ((System.ComponentModel.ISupportInitialize) WavePanel).EndInit(); + ResumeLayout(false); + } + + #endregion + + private PictureBox WavePanel; +} diff --git a/Forms/WaveformWindow.cs b/Forms/WaveformWindow.cs new file mode 100644 index 0000000..b8f6329 --- /dev/null +++ b/Forms/WaveformWindow.cs @@ -0,0 +1,88 @@ +namespace BRRSuiteGUI; + +internal partial class WaveformWindow : Form { + + public static readonly Color Futaba = Color.FromArgb(unchecked((int) 0xFF78886A)); + public static readonly Color DarkFutaba = Color.FromArgb(unchecked((int) 0xFF313D26)); + public static readonly Color Periwinkle = Color.FromArgb(unchecked((int) 0xFFCCCCFF)); + public static readonly Color LoopColor = Color.RoyalBlue; + + private TestContainer? sampleContainer = null; + public TestContainer? TestSample { + get => sampleContainer; + set { + if (value == sampleContainer) { + return; + } + + sampleContainer = value; + RefreshImage(); + } + } + + private Bitmap? waveImage = null; + + public WaveformWindow() { + InitializeComponent(); + WavePanel.BackColor = Futaba; + } + + protected override void OnFormClosing(FormClosingEventArgs e) { + if (e.CloseReason == CloseReason.UserClosing) { + Hide(); + e.Cancel = true; + } + } + + private void RefreshImage() { + waveImage?.Dispose(); + + if (!Visible) { + WavePanel.Image = null; + return; + } + + waveImage = CreateWaveformImage(sampleContainer); + WavePanel.Image = waveImage; + } + + private static Bitmap? CreateWaveformImage(TestContainer? sample) { + if (sample is null) { + return null; + } + + const int height = 3201; + const int halfheight = height / 2; + + int width = sample.BRRFile.SampleCount; + var img = new Bitmap(width, height); + + using var g = Graphics.FromImage(img); + + g.Clear(DarkFutaba); + + var col = new Pen(Periwinkle); + + for (int i = 0; i < width; i++) { + if (i == sample.LoopBlock * 16) { + col = new Pen(LoopColor); + } + int h = sample.WaveFile[i] / 20; + g.DrawLine(col, i, halfheight, i, h + halfheight); + + + } + + g.DrawLine(new(Color.Black), 0, halfheight, width, halfheight); + + g.Flush(); + + return img; + } + + private void WaveformWindow_VisibleChanged(object sender, EventArgs e) { + if (Visible) { + RefreshImage(); + } + } +} diff --git a/Forms/WaveformWindow.resx b/Forms/WaveformWindow.resx new file mode 100644 index 0000000..992c217 --- /dev/null +++ b/Forms/WaveformWindow.resx @@ -0,0 +1,1607 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAFQx0ABUMdAUVDHQFFQx0BRUMdAUVDHQFFQx0BRUMdAUVDHQFFQx0BRUM + dAUVDHQFFQx0BRUMdAUVDHQFFQx0BRUMdAUVDHQFFQx0BRYOdAAoKCgAKCgoACcnJwAdGhoAHRkZAB0Z + GQAdGRkAHRkZAB0ZGQAdGRkAHRkZAB0ZGQAdGRkAHRkZAB0ZGQAdGRkAHRkZAB0ZGQAdGRkAJSUlACgo + KAAoKCgAJycnAB0aGgAdGRkAHRkZAB0ZGQAdGRkAHRkZAB0ZGQAdGRkAHRkZAB0ZGQAdGRkAHRkZAB0Z + GQAdGRkAHRkZABwZGQABAQEAAAAAAAAAAAAAAAAAAAAAABUMdAUVDHT0FQx0+hUMdPoVDHT6FQx0+hUM + dPoVDHT6FQx0+hUMdPoVDHT6FQx0+hUMdPoVDHT6FQx0+hUMdPoVDHT6FQx0+hUMdPQWDnQF/f39AP39 + /QD8+/sAx7i4AMa2tgDGtrYAxra2AMa2tgDGtrYAxra2AMa2tgDGtrYAxra2AMa2tgDGtrYAxra2AMa2 + tgDGtrYAxra2APHu7gD9/f0A/f39APz7+wDHuLgAxra2AMa2tgDGtrYAxra2AMa2tgDGtrYAxra2AMa2 + tgDGtrYAxra2AMa2tgDGtrYAxra2AMa2tgDEtbUAHBkZAAAAAAAAAAAAAAAAAAAAAAAWDHgFFgx4+hYM + eP8WDHj/Fgx4/xYMeP8WDHj/Fgx4/xYMeP8WDHj/Fgx4/xYMeP8WDHj/Fgx4/xYMeP8WDHj/Fgx4/xUM + dP8VDHT6Fg50Bf///wD///8A/v7+AMm6ugDIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADz8PAA////AP///wD+/v4Aybq6AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxra2AB0ZGQAAAAAAAAAAAAAA + AAAAAAAAKRjlBSkY5fopGOX/KRjl/ykY5f8pGOX/KRjl/ykY5f8pGOX/KRjl/ykY5f8pGOX/KRjl/ykY + 5f8pGOX/KRjl/ygY5P8WDHj/FQx0+hYOdAX///8A////AP7+/gDJuroAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgA8/DwAP///wD///8A/v7+AMm6 + ugDIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMa2 + tgAdGRkAAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQF////AP///wD+/v4Aybq6AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4APPw + 8AD///8A////AP7+/gDJuroAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADGtrYAHRkZAAAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50Bf// + /wD///8A/v7+AMm6ugDIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADz8PAA////AP///wD+/v4Aybq6AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxra2AB0ZGQAAAAAAAAAAAAAAAAAAAAAAKRjnBSkY + 5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5f8WDHj/FQx0+hYOdAX///8A////AP7+/gDJuroAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgA8/DwAP///wD///8A/v7+AMm6ugDIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMa2tgAdGRkAAAAAAAAA + AAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQF////AP///wD+/v4Aybq6AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4APPw8AD///8A////AP7+ + /gDJuroAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADGtrYAHRkZAAAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5f8pGOX/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50Bf///wD///8A/v7+AMm6 + ugDIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADz8PAA////AP///wD+/v4Aybq6AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAxra2AB0ZGQAAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY + 5/8pGOf/KRjn/x8Ru/8GAkf/BgJH/x8Ru/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYO + dAX///8A////AP7+/gDJuroAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgA8/DwAP///wD///8A/v7+AMm6ugDIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMa2tgAdGRkAAAAAAAAAAAAAAAAAAAAAACkY + 5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5f8GAkf/AAAA/wAAAP8GAkf/KRjl/ykY5/8pGOf/KRjn/ykY + 5/8pGOX/Fgx4/xUMdPoWDnQFNWOGAAJUfAUCVHwFAVR8BQFUfAUBVHwFAVR8BQFUfAUBVHwFAVR8BQFU + fAUBVHwFAVR8BQFUfAUBVHwFAVR8BQFUfAUBVHwFAVR8BTJhhAD///8A////AP7+/gDJuroAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADGtrYAHRkZAAAA + AAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOX/BgJH/wAAAP8AAAD/BgJH/ykY + 5f8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQJUfAUAVHz0AFR8+gBUfPoAVHz6AFR8+gBU + fPoAVHz6AFR8+gBUfPoAVHz6AFR8+gBUfPoAVHz6AFR8+gBUfPoAVHz6AFR8+gBUfPQCVHwF////AP// + /wD+/v4Aybq6AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAxra2AB0ZGQAAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/x8R + u/8GAkf/BgJH/x8Ru/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYOdAUCV4AFAFeA+gBX + gP8AV4D/AFeA/wBXgP8AV4D/AFeA/wBXgP8AV4D/AFeA/wBXgP8AV4D/AFeA/wBXgP8AV4D/AFeA/wBU + fP8AVHz6AlR8Bf///wD///8A/v7+AMm6ugDIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMa2tgAdGRkAAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjl/ykY5f8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUM + dPoWDnQFAqf2BQCn9voAp/b/AKf2/wCn9v8Ap/b/AKf2/wCn9v8Ap/b/AKf2/wCn9v8Ap/b/AKf2/wCn + 9v8Ap/b/AKf2/wCm9P8AV4D/AFR8+gJUfAX///8A////AP7+/gDJuroAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADGtrYAHRkZAAAAAAAAAAAAAAAAAAAA + AAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBUfPoCVHwF////AP///wD+/v4Aybq6AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxra2AB0Z + GQAAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf// + /wD///8A/v7+AMm6ugDIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMa2tgAdGRkAAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo + +PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn + 9v8AV4D/AFR8+gJUfAX///8A////AP7+/gDJuroAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADGtrYAHRkZAAAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYM + eP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBUfPoCVHwF////AP///wD+/v4Aybq6AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxra2AB0ZGQAAAAAAAAAAAAAA + AAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn + 9v8Ap/b/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf///wD///8A/v7+AMm6 + ugDIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMa2 + tgAdGRkAAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo + +P8AqPj/AKj4/wCIyf8AMU3/ADFN/wCIyf8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJU + fAX///8A////AP7+/gDJuroAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADGtrYAHRkZAAAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo + +AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCn9v8AMU3/AAAA/wAAAP8AMU3/AKf2/wCo+P8AqPj/AKj4/wCo + +P8Ap/b/AFeA/wBUfPoCVHwFiUY5AIAuEwWALhMFgC0SBYAtEgWALRIFgC0SBYAtEgWALRIFgC0SBYAt + EgWALRIFgC0SBYAtEgWALRIFgC0SBYAtEgWALRIFgC0SBYAtEgAAAAAAAAAAAAAAAAAAAAAAKRjnBSkY + 5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo+P8Ap/b/ADFN/wAAAP8AAAD/ADFN/wCn + 9v8AqPj/AKj4/wCo+P8AqPj/AKf2/wBXgP8AVHz6AlR8BYAuEwWALRH0gC0R+oAtEfqALRH6gC0R+oAt + EfqALRH6gC0R+oAtEfqALRH6gC0R+oAtEfqALRH6gC0R+oAtEfqALRH6gC0R+oAtEfSALREFAAAAAAAA + AAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCI + yf8AMU3/ADFN/wCIyf8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJUfAWFLxMFhC4R+oQu + Ef+ELhH/hC4R/4QuEf+ELhH/hC4R/4QuEf+ELhH/hC4R/4QuEf+ELhH/hC4R/4QuEf+ELhH/hC4R/4At + Ef+ALRH6gC0RBQAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKf2/wCn9v8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBU + fPoCVHwF/VoiBf1ZIfr9WSH//Vkh//1ZIf/9WSH//Vkh//1ZIf/9WSH//Vkh//1ZIf/9WSH//Vkh//1Z + If/9WSH//Vkh//tZIP+ELhH/gC0R+oAtEQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYO + dAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf9aIgX/WiH6/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH/hC4R/4AtEfqALREFAAAAAAAAAAAAAAAAAAAAACkY + 5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJUfAX/WiIF/1oh+v9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//Vkh/4QuEf+ALRH6gC0RBQAA + AAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBUfPoCVHwF/1oiBf9a + Ifr/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//1Z + If+ELhH/gC0R+oAtEQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBX + gP8AVHz6AlR8Bf9aIgX/WiH6/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/9WSH/hC4R/4AtEfqALREFAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUM + dPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJUfAX/WiIF/1oh+v9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//Vkh/4QuEf+ALRH6gC0RBQAAAAAAAAAAAAAAAAAA + AAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBUfPoCVHwF/1oiBf9aIfr/WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//1ZIf+ELhH/gC0R+oAt + EQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf9a + IgX/WiH6/1oh//9aIf//WiH//1oh//9aIf//WiH//Vkh//1ZIf//WiH//1oh//9aIf//WiH//1oh//9a + If/9WSH/hC4R/4AtEfqALREFAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo + +PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn + 9v8AV4D/AFR8+gJUfAX/WiIF/1oh+v9aIf//WiH//1oh//9aIf//WiH/z0cZ/08WBP9PFgT/z0cZ//9a + If//WiH//1oh//9aIf//WiH//Vkh/4QuEf+ALRH6gC0RBQAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYM + eP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBUfPoCVHwF/1oiBf9aIfr/WiH//1oh//9aIf//WiH//Vkh/08W + BP8AAAD/AAAA/08WBP/9WSH//1oh//9aIf//WiH//1oh//1ZIf+ELhH/gC0R+oAtEQUAAAAAAAAAAAAA + AAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf9aIgX/WiH6/1oh//9a + If//WiH//1oh//1ZIf9PFgT/AAAA/wAAAP9PFgT//Vkh//9aIf//WiH//1oh//9aIf/9WSH/hC4R/4At + EfqALREFAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJU + fAX/WiIF/1oh+v9aIf//WiH//1oh//9aIf//WiH/z0cZ/08WBP9PFgT/z0cZ//9aIf//WiH//1oh//9a + If//WiH//Vkh/4QuEf+ALRH6gC0RBQAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo + +AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8Ap/b/AFeA/wBUfPoCVHwF/1oiBf9aIfr/WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH//Vkh//9a + If//WiH//1oh//9aIf//WiH//1oh//1ZIf+ELhH/gC0R+oAtEQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY + 5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf9aIgX/WiH6/1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH/hC4R/4AtEfqALREFAAAAAAAA + AAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJUfAX/WiIF/1oh+v9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//Vkh/4Qu + Ef+ALRH6gC0RBQAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBU + fPoCVHwF/1oiBf9aIfr/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//1ZIf+ELhH/gC0R+oAtEQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYO + dAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf9aIgX/WiH6/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH/hC4R/4AtEfqALREFAAAAAAAAAAAAAAAAAAAAACkY + 5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJUfAX/WiIF/1oh+v9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//Vkh/4QuEf+ALRH6gC0RBQAA + AAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBUfPoCVHwF/1oiBf9a + Ifr/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//1Z + If+ELhH/gC0R+oAtEQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBX + gP8AVHz6AlR8Bf9aIgX/WiH6/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/9WSH/hC4R/4AtEfqALREFAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUM + dPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJUfAX/WiIF/1oh+v9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//Vkh/4QuEf+ALRH6gC0RBQAAAAAAAAAAAAAAAAAA + AAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBUfPoCVHwF/1oiBf9aIfr/WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//1ZIf+ELhH/gC0R+oAt + EQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf9a + IgX/WiH6/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If/9WSH/hC4R/4AtEfqALREFAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo + +PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn + 9v8AV4D/AFR8+gJUfAX/WiIF/1oh+v9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//Vkh/4QuEf+ALRH6gC0RBQAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYM + eP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBUfPoCVHwF/1oiBf9aIfr/WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//1ZIf+ELhH/gC0R+oAtEQUAAAAAAAAAAAAA + AAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/KRjl/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn + 9v8Ap/b/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf9aIgX/WiH6/1oh//9a + If//WiH//1oh//9aIf//WiH//Vkh//1ZIf//WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH/hC4R/4At + EfqALREFAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8fEbv/BgJH/wYC + R/8fEbv/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo + +P8AqPj/AKj4/wCIyf8AMU3/ADFN/wCIyf8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJU + fAX/WiIF/1oh+v9aIf//WiH//1oh//9aIf//WiH/z0cZ/08WBP9PFgT/z0cZ//9aIf//WiH//1oh//9a + If//WiH//Vkh/4QuEf+ALRH6gC0RBQAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY + 5/8pGOX/BgJH/wAAAP8AAAD/BgJH/ykY5f8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo + +AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCn9v8AMU3/AAAA/wAAAP8AMU3/AKf2/wCo+P8AqPj/AKj4/wCo + +P8Ap/b/AFeA/wBUfPoCVHwF/1oiBf9aIfr/WiH//1oh//9aIf//WiH//Vkh/08WBP8AAAD/AAAA/08W + BP/9WSH//1oh//9aIf//WiH//1oh//1ZIf+ELhH/gC0R+oAtEQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY + 5/opGOf/KRjn/ykY5/8pGOf/KRjl/wYCR/8AAAD/AAAA/wYCR/8pGOX/KRjn/ykY5/8pGOf/KRjn/ykY + 5f8WDHj/FQx0+hYOdAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo+P8Ap/b/ADFN/wAAAP8AAAD/ADFN/wCn + 9v8AqPj/AKj4/wCo+P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf9aIgX/WiH6/1oh//9aIf//WiH//1oh//1Z + If9PFgT/AAAA/wAAAP9PFgT//Vkh//9aIf//WiH//1oh//9aIf/9WSH/hC4R/4AtEfqALREFAAAAAAAA + AAAAAAAAAAAAACkY5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8fEbv/BgJH/wYCR/8fEbv/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCI + yf8AMU3/ADFN/wCIyf8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJUfAX/WiIF/1oh+v9a + If//WiH//1oh//9aIf//WiH/z0cZ/08WBP9PFgT/z0cZ//9aIf//WiH//1oh//9aIf//WiH//Vkh/4Qu + Ef+ALRH6gC0RBQAAAAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5f8pGOX/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKf2/wCn9v8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBU + fPoCVHwF/1oiBf9aIfr/WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH//Vkh//9aIf//WiH//1oh//9a + If//WiH//1oh//1ZIf+ELhH/gC0R+oAtEQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hYO + dAUCqPgFAKj4+gCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKf2/wBXgP8AVHz6AlR8Bf9aIgX/WiH6/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH/hC4R/4AtEfqALREFAAAAAAAAAAAAAAAAAAAAACkY + 5wUpGOf6KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOX/Fgx4/xUMdPoWDnQFAqj4BQCo+PoAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCn9v8AV4D/AFR8+gJUfAX/WiIF/1oh+v9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//Vkh/4QuEf+ALRH6gC0RBQAA + AAAAAAAAAAAAAAAAAAApGOcFKRjn+ikY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xYMeP8VDHT6Fg50BQKo+AUAqPj6AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8Ap/b/AFeA/wBUfPoCVHwF/1oiBf9a + Ifr/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//1Z + If+ELhH/gC0R+oAtEQUAAAAAAAAAAAAAAAAAAAAAKRjnBSkY5/opGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5f8WDHj/FQx0+hUMdAUAqPgFAKj4+gCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKf2/wBX + gP8AVHz6AFR8Bf9aIQX/WiH6/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/9WSH/hC4R/4AtEfqALREFAAAAAAAAAAAAAAAAAAAAACkY5wUpGOf0KRjn+ikY + 5/opGOf6KRjn+ikY5/opGOf6KRjn+ikY5/opGOf6KRjn+ikY5/opGOf6KRjn+ikY5/opGOX6Fgx4+hUM + dPQVDHQFAKj4BQCo+PQAqPj6AKj4+gCo+PoAqPj6AKj4+gCo+PoAqPj6AKj4+gCo+PoAqPj6AKj4+gCo + +PoAqPj6AKj4+gCn9voAV4D6AFR89ABUfAX/WiEF/1oh9P9aIfr/WiH6/1oh+v9aIfr/WiH6/1oh+v9a + Ifr/WiH6/1oh+v9aIfr/WiH6/1oh+v9aIfr/WiH6/Vkh+oQuEfqALRH0gC0RBQAAAAAAAAAAAAAAAAAA + AAApGOcAKRjnBSkY5wUpGOcFKRjnBSkY5wUpGOcFKRjnBSkY5wUpGOcFKRjnBSkY5wUpGOcFKRjnBSkY + 5wUpGOcFKRjlBRYMeAUVDHQFFQx0AACo+AAAqPgFAKj4BQCo+AUAqPgFAKj4BQCo+AUAqPgFAKj4BQCo + +AUAqPgFAKj4BQCo+AUAqPgFAKj4BQCo+AUAp/YFAFeABQBUfAUAVHwA/1ohAP9aIQX/WiEF/1ohBf9a + IQX/WiEF/1ohBf9aIQX/WiEF/1ohBf9aIQX/WiEF/1ohBf9aIQX/WiEF/1ohBf1ZIQWELhEFgC0RBYAt + EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////////+AA + B///////wAAD///////AAAP//////8AAA///////wAAD///////AAAP//////8AAA///////wAAD//// + ///AAAP//////8AAA///////wAACAAB////AAAAAAD///8AAAAAAP///wAAAAAA////AAAAAAD///8AA + AAAAP///wAAAAAA////AAAAAAD///8AAAAAAP///wAAAAAA////AAAAAACAAB8AAAAAAAAADwAAAAAAA + AAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAPAAAAAAAAAA8AA + AAAAAAADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAA + AAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAPAAAAAAAAAA8AA + AAAAAAADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAA + AAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAPgAAYAAGAAB/// + //////////////////8oAAAAgAAAAAABAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQx0ABUM + dAoVDHQLFQx0CxUMdAsVDHQLFQx0CxUMdAsVDHQLFQx0CxUMdAsVDHQLFQx0CxUMdAsVDHQLFQx0CxUM + dAsVDHQLFQx0CxUMdAsVDHQLFQx0CxUMdAsVDHQLFQx0CxUMdAsVDHQLFQx0CxUMdAsVDHQLFQx0CxUM + dAsVDHQLFQx0CxUMdAsVDHQLFQx0ChYNdAA6OjoAOjo6ADo6OgA6OjoAOjo6ADo6OgA5OTkALCgoACsn + JwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsn + JwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsn + JwAzMTEAOjo6ADo6OgA6OjoAOjo6ADo6OgA6OjoAOTk5ACwoKAArJycAKycnACsnJwArJycAKycnACsn + JwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsn + JwArJycAKycnACsnJwArJycAKycnACsnJwArJycAKycnACsnJwAqJiYAAwMDAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVDHQKFQx06hUMdPQVDHT0FQx09BUMdPQVDHT0FQx09BUM + dPQVDHT0FQx09BUMdPQVDHT0FQx09BUMdPQVDHT0FQx09BUMdPQVDHT0FQx09BUMdPQVDHT0FQx09BUM + dPQVDHT0FQx09BUMdPQVDHT0FQx09BUMdPQVDHT0FQx09BUMdPQVDHT0FQx09BUMdPQVDHTqFg10Cvr6 + +gD6+voA+vr6APr6+gD6+voA+vr6APj4+ADHuLgAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1 + tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1 + tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AOHb2wD6+voA+vr6APr6+gD6+voA+vr6APr6 + +gD4+PgAx7i4AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1 + tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1tQDEtbUAxLW1AMS1 + tQDEtbUAxLW1AMGxsQAqJiYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUM + dAsVDHT0FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUM + dP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUM + dP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdPQWDXQL////AP///wD///8A////AP///wD///8A/f39AMu8 + vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgA5t/fAP///wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQx0CxUMdPQVDHT/FQx0/xUMdP8VDHT/FQx0/xUM + dP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUM + dP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx0/xUMdP8VDHT/FQx09BYN + dAv///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADm398A////AP///wD///8A////AP// + /wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADEtbUAKycnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAWDXwLFg189BYNfP8WDXz/Fg18/xYNfP8WDXz/Fg18/xYNfP8WDXz/Fg18/xYNfP8WDXz/Fg18/xYN + fP8WDXz/Fg18/xYNfP8WDXz/Fg18/xYNfP8WDXz/Fg18/xYNfP8WDXz/Fg18/xYNfP8WDXz/Fg18/xYN + fP8WDXz/Fg18/xYNe/8VDHT/FQx0/xUMdP8VDHT0Fg10C////wD///8A////AP///wD///8A////AP39 + /QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AObf3wD///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1tQArJycAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgY5AsoGOT0KBjk/ygY5P8oGOT/KBjk/ygY + 5P8oGOT/KBjk/ygY5P8oGOT/KBjk/ygY5P8oGOT/KBjk/ygY5P8oGOT/KBjk/ygY5P8oGOT/KBjk/ygY + 5P8oGOT/KBjk/ygY5P8oGOT/KBjk/ygY5P8oGOT/KBjk/ygY5P8oGOT/KBfg/xYNe/8VDHT/FQx0/xUM + dPQWDXQL////AP///wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgA5t/fAP///wD///8A////AP// + /wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AP///wD///8A////AP// + /wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADm398A////AP///wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADEtbUAKycnAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUM + dP8VDHT0Fg10C////wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AObf3wD///8A////AP// + /wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1tQArJycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wD///8A////AP// + /wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgA5t/fAP///wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxLW1ACsn + JwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUM + dP8VDHT/FQx09BYNdAv///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADm398A////AP// + /wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADEtbUAKycnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8A////AP// + /wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AObf3wD///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1 + tQArJycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYN + fP8VDHT/FQx0/xUMdPQWDXQL////AP///wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgA5t/fAP// + /wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AP// + /wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADm398A////AP///wD///8A////AP///wD///8A/f39AMu8 + vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADEtbUAKycnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY + 5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AObf + 3wD///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1tQArJycAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP// + /wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgA5t/fAP///wD///8A////AP///wD///8A////AP39 + /QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY + 5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADm398A////AP///wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADEtbUAKycnAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/KBfj/ygX4/8pGOX/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C/// + /wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AObf3wD///8A////AP///wD///8A////AP// + /wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMS1tQArJycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY + 5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/IhPJ/xII + gP8DATP/AwEz/xIIgP8iE8n/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wD///8A////AP///wD///8A/f39AMu8 + vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgA5t/fAP///wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/yITyf8DATL/AAAA/wAAAP8AAAD/AAAA/wMBMv8iE8n/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYN + dAv///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADm398A////AP///wD///8A////AP// + /wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADEtbUAKycnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/EgiA/wAA + AP8AAAD/AAAA/wAAAP8AAAD/AAAA/xIIgP8pGOX/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8A////AP///wD///8A////AP39 + /QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AObf3wD///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1tQArJycAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygX4/8DATP/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwEz/ygX + 4/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUM + dPQWDXQL////AP///wAXWH4AAVR8CgFUfAsBVHwLAVR8CwFUfAsBVHwLAVR8CwFUfAsBVHwLAVR8CwFU + fAsBVHwLAVR8CwFUfAsBVHwLAVR8CwFUfAsBVHwLAVR8CwFUfAsBVHwLAVR8CwFUfAsBVHwLAVR8CwFU + fAsBVHwLAVR8CwFUfAsBVHwLAVR8CwFUfAsBVHwLAVR8CwFUfAsBVHwKFFd+AP///wD///8A////AP// + /wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBfj/wMB + M/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8DATP/KBfj/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAFUfAoAVHzqAFR89ABU + fPQAVHz0AFR89ABUfPQAVHz0AFR89ABUfPQAVHz0AFR89ABUfPQAVHz0AFR89ABUfPQAVHz0AFR89ABU + fPQAVHz0AFR89ABUfPQAVHz0AFR89ABUfPQAVHz0AFR89ABUfPQAVHz0AFR89ABUfPQAVHz0AFR89ABU + fPQAVHz0AFR89ABUfOoBVHwK////AP///wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADEtbUAKycnAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOX/EgiA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xII + gP8pGOX/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUM + dP8VDHT0Fg10C////wD///8AAVR8CwBUfPQAVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBU + fP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBU + fP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR89AFUfAv///8A////AP// + /wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1tQArJycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8iE8n/AwEy/wAAAP8AAAD/AAAA/wAAAP8DATL/IhPJ/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABVHwLAFR89ABU + fP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBU + fP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBUfP8AVHz/AFR8/wBU + fP8AVHz/AFR8/wBUfP8AVHz0AVR8C////wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxLW1ACsn + JwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8iE8n/EgiA/wMBM/8DATP/EgiA/yIT + yf8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUM + dP8VDHT/FQx09BYNdAv///8A////AAFahAsAWoT0AFqE/wBahP8AWoT/AFqE/wBahP8AWoT/AFqE/wBa + hP8AWoT/AFqE/wBahP8AWoT/AFqE/wBahP8AWoT/AFqE/wBahP8AWoT/AFqE/wBahP8AWoT/AFqE/wBa + hP8AWoT/AFqE/wBahP8AWoT/AFqE/wBahP8AWoT/AFmE/wBUfP8AVHz/AFR8/wBUfPQBVHwL////AP// + /wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADEtbUAKycnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOX/KBfj/ygX4/8pGOX/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAab0CwCm + 9PQApvT/AKb0/wCm9P8ApvT/AKb0/wCm9P8ApvT/AKb0/wCm9P8ApvT/AKb0/wCm9P8ApvT/AKb0/wCm + 9P8ApvT/AKb0/wCm9P8ApvT/AKb0/wCm9P8ApvT/AKb0/wCm9P8ApvT/AKb0/wCm9P8ApvT/AKb0/wCm + 9P8Ao/H/AFmE/wBUfP8AVHz/AFR89AFUfAv///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1 + tQArJycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYN + fP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C/// + /wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo + +AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD///8A////AP///wD///8A/f39AMu8 + vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADEtbUAKycnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY + 5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFU + fAv///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1tQArJycAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP// + /wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A////AP///wD///8A////AP39 + /QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY + 5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBU + fPQBVHwL////AP///wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADEtbUAKycnAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C/// + /wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP///wD///8A////AP// + /wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMS1tQArJycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY + 5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBU + fP8AVHz0AVR8C////wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYN + dAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD///8A////AP// + /wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADEtbUAKycnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBU + fP8AVHz/AFR89AFUfAv///8A////AP///wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1tQArJycAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUM + dPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A////AP// + /wD///8A////AP39/QDLvLwAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAxLW1ACsnJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9v8ApfP/AKXz/wCm + 9v8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBa + hP8AVHz/AFR8/wBUfPQBVHwL////AP///wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADEtbUAKycnAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUM + dP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8Aktj/AFyK/wAiOP8AIjj/AFyK/wCS2P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP// + /wD///8A////AP///wD9/f0Ay7y8AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMS1tQArJycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AJLY/wAiNv8AAAD/AAAA/wAA + AP8AAAD/ACI2/wCS2P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm + 9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A////AP///wD///8A////AP39/QDLvLwAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAxLW1ACsn + JwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUM + dP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCm9v8AXIr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AFyK/wCm9v8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP// + /wD///8A////AP///wD///8A/f39AMu8vADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4 + uADIuLgAyLi4AMi4uADIuLgAyLi4AMi4uADEtbUAKycnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo + +PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKXz/wAiOP8AAAD/AAAA/wAA + AP8AAAD/AAAA/wAAAP8AIjj/AKXz/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AII1IACALRIKgC0SC4AtEguALRILgC0RC4At + EQuALRELgC0RC4AtEQuALRELgC0RC4AtEQuALRELgC0RC4AtEQuALRELgC0RC4AtEQuALRELgC0RC4At + EQuALRELgC0RC4AtEQuALRELgC0RC4AtEQuALRELgC0RC4AtEQuALRELgC0RC4AtEQuALRELgC0RC4At + EQqALREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYN + fP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8ApfP/ACI4/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAiOP8ApfP/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C/// + /wD///8AgC0SCoAtEeqALRH0gC0R9IAtEfSALRH0gC0R9IAtEfSALRH0gC0R9IAtEfSALRH0gC0R9IAt + EfSALRH0gC0R9IAtEfSALRH0gC0R9IAtEfSALRH0gC0R9IAtEfSALRH0gC0R9IAtEfSALRH0gC0R9IAt + EfSALRH0gC0R9IAtEfSALRH0gC0R9IAtEfSALRH0gC0R6oAtEQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo + +AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9v8AXIr/AAAA/wAA + AP8AAAD/AAAA/wAAAP8AAAD/AFyK/wCm9v8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wCALRILgC0R9IAtEf+ALRH/gC0R/4At + Ef+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4At + Ef+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4At + Ef+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY + 5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCS2P8AIjb/AAAA/wAAAP8AAAD/AAAA/wAiNv8Aktj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFU + fAv///8A////AIAtEguALRH0gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4At + Ef+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4At + Ef+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEf+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP// + /wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCS + 2P8AXIr/ACI4/wAiOP8AXIr/AJLY/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8AiTATC4kwEvSJMBL/iTAS/4kw + Ev+JMBL/iTAS/4kwEv+JMBL/iTAS/4kwEv+JMBL/iTAS/4kwEv+JMBL/iTAS/4kwEv+JMBL/iTAS/4kw + Ev+JMBL/iTAS/4kwEv+JMBL/iTAS/4kwEv+JMBL/iTAS/4kwEv+JMBL/iTAS/4kwEv+IMBL/gC0R/4At + Ef+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY + 5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9v8ApfP/AKXz/wCm9v8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBU + fPQBVHwL////AP///wD7WSEL+1kg9PtZIP/7WSD/+1kg//tZIP/7WSD/+1kg//tZIP/7WSD/+1kg//tZ + IP/7WSD/+1kg//tZIP/7WSD/+1kg//tZIP/7WSD/+1kg//tZIP/7WSD/+1kg//tZIP/7WSD/+1kg//tZ + IP/7WSD/+1kg//tZIP/7WSD/+1kg//hXIP+IMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C/// + /wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kw + Ev+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY + 5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBU + fP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYN + dAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZ + IP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBU + fP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUM + dPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9a + IfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBa + hP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUM + dP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9a + IQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm + 9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAt + EQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUM + dP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP// + /wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo + +PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4At + EfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYN + fP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C/// + /wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo + +AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4At + Ef+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY + 5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFU + fAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP// + /wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4At + Ef+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY + 5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBU + fPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/9WSH/+lgg//pYIP/9WSH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C/// + /wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/3k0b/44uDf86DgL/Og4C/44u + Df/eTRv//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kw + Ev+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY + 5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBU + fP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh/95NG/84DQL/AAAA/wAAAP8AAAD/AAAA/zgNAv/eTRv//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYN + dAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH/ji4N/wAAAP8AAAD/AAAA/wAA + AP8AAAD/AAAA/44uDf/9WSH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZ + IP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBU + fP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//pYIP86DgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Og4C//pYIP//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUM + dPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9a + IfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+lgg/zoOAv8AAAD/AAAA/wAA + AP8AAAD/AAAA/wAAAP86DgL/+lgg//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBa + hP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/9WSH/ji4N/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/44uDf/9WSH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUM + dP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9a + IQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/eTRv/OA0C/wAA + AP8AAAD/AAAA/wAAAP84DQL/3k0b//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm + 9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/eTRv/ji4N/zoOAv86DgL/ji4N/95NG///WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAt + EQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUM + dP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP// + /wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If/9WSH/+lgg//pYIP/9WSH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo + +PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4At + EfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYN + fP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C/// + /wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo + +AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4At + Ef+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY + 5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFU + fAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP// + /wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4At + Ef+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY + 5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBU + fPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C/// + /wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kw + Ev+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY + 5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBU + fP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYN + dAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZ + IP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBU + fP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUM + dPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9a + IfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBa + hP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUM + dP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9a + IQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm + 9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAt + EQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUM + dP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP// + /wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo + +PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4At + EfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYN + fP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C/// + /wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo + +AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4At + Ef+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY + 5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFU + fAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP// + /wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4At + Ef+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY + 5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBU + fPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C/// + /wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kw + Ev+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY + 5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBU + fP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYN + dAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZ + IP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBU + fP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUM + dPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9a + IfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjl/ygX4/8oF+P/KRjl/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9v8ApfP/AKXz/wCm + 9v8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBa + hP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH/+lgg//pYIP/9WSH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/yITyf8SCID/AwEz/wMBM/8SCID/IhPJ/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUM + dP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8Aktj/AFyK/wAiOP8AIjj/AFyK/wCS2P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9a + IQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/3k0b/44u + Df86DgL/Og4C/44uDf/eTRv//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8iE8n/AwEy/wAAAP8AAAD/AAAA/wAAAP8DATL/IhPJ/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AJLY/wAiNv8AAAD/AAAA/wAA + AP8AAAD/ACI2/wCS2P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm + 9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh/95NG/84DQL/AAAA/wAAAP8AAAD/AAAA/zgNAv/eTRv//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAt + EQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/xIIgP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA + AP8SCID/KRjl/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUM + dP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCm9v8AXIr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AFyK/wCm9v8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP// + /wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH/ji4N/wAA + AP8AAAD/AAAA/wAAAP8AAAD/AAAA/44uDf/9WSH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8oF+P/AwEz/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMBM/8oF+P/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo + +PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKXz/wAiOP8AAAD/AAAA/wAA + AP8AAAD/AAAA/wAAAP8AIjj/AKXz/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//pYIP86DgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Og4C//pY + IP//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4At + EfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygX4/8DATP/AAAA/wAAAP8AAAD/AAAA/wAA + AP8AAAD/AwEz/ygX4/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYN + fP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8ApfP/ACI4/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAiOP8ApfP/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C/// + /wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+lgg/zoO + Av8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP86DgL/+lgg//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjl/xIIgP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8SCID/KRjl/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo + +AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9v8AXIr/AAAA/wAA + AP8AAAD/AAAA/wAAAP8AAAD/AFyK/wCm9v8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/9WSH/ji4N/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/44u + Df/9WSH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4At + Ef+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/IhPJ/wMBMv8AAAD/AAAA/wAA + AP8AAAD/AwEy/yITyf8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY + 5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCS2P8AIjb/AAAA/wAAAP8AAAD/AAAA/wAiNv8Aktj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFU + fAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If/eTRv/OA0C/wAAAP8AAAD/AAAA/wAAAP84DQL/3k0b//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/IhPJ/xIIgP8DATP/AwEz/xIIgP8iE8n/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP// + /wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCS + 2P8AXIr/ACI4/wAiOP8AXIr/AJLY/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/eTRv/ji4N/zoOAv86DgL/ji4N/95N + G///WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4At + Ef+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY + 5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjl/ygX + 4/8oF+P/KRjl/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9v8ApfP/AKXz/wCm9v8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBU + fPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf/9WSH/+lgg//pYIP/9WSH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C/// + /wD///8AAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kw + Ev+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY + 5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBU + fP8AVHz0AVR8C////wD///8A/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYN + dAv///8A////AAGo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZ + IP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0Fg10C////wD///8AAaj4CwCo+PQAqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBU + fP8AVHz/AFR89AFUfAv///8A////AP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUM + dPQWDXQL////AP///wABqPgLAKj49ACo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm9P8AWoT/AFR8/wBUfP8AVHz0AVR8C////wD///8A/1ohC/9a + IfT/WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If/7WSD/iTAS/4AtEf+ALRH/gC0R9IAtEQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUMdP8VDHT/FQx09BYNdAv///8A////AAGo+AsAqPj0AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBa + hP8AVHz/AFR8/wBUfPQBVHwL////AP///wD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUM + dP8VDHT0Fg10C/r6+gD6+voAAaj4CwCo+PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8ApvT/AFqE/wBUfP8AVHz/AFR89AFUfAv6+voA+vr6AP9a + IQv/WiH0/1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH/+1kg/4kwEv+ALRH/gC0R/4AtEfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAACkY5wspGOf0KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KBjk/xYNfP8VDHT/FQx0/xUMdPQVDHQLOjo6ADo6OgAAqPgLAKj49ACo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCm + 9P8AWoT/AFR8/wBUfP8AVHz0AFR8Czo6OgA6OjoA/1ohC/9aIfT/WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf/7WSD/iTAS/4AtEf+ALRH/gC0R9IAt + EQsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRjnCykY5/QpGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8oGOT/Fg18/xUM + dP8VDHT/FQx09BUMdAsAAAAAAAAAAACo+AsAqPj0AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKb0/wBahP8AVHz/AFR8/wBUfPQAVHwLAAAAAAAA + AAD/WiEL/1oh9P9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//tZIP+JMBL/gC0R/4AtEf+ALRH0gC0RCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAApGOcLKRjn9CkY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ykY + 5/8pGOf/KRjn/ykY5/8pGOf/KRjn/ygY5P8WDXz/FQx0/xUMdP8VDHT0FQx0CwAAAAAAAAAAAKj4CwCo + +PQAqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo+P8AqPj/AKj4/wCo + +P8ApvT/AFqE/wBUfP8AVHz/AFR89ABUfAsAAAAAAAAAAP9aIQv/WiH0/1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9a + If//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH//1oh//9aIf//WiH/+1kg/4kwEv+ALRH/gC0R/4At + EfSALRELAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkY5wopGOfqKRjn9CkY + 5/QpGOf0KRjn9CkY5/QpGOf0KRjn9CkY5/QpGOf0KRjn9CkY5/QpGOf0KRjn9CkY5/QpGOf0KRjn9CkY + 5/QpGOf0KRjn9CkY5/QpGOf0KRjn9CkY5/QpGOf0KRjn9CkY5/QpGOf0KRjn9CkY5/QpGOf0KBjk9BYN + fPQVDHT0FQx09BUMdOoVDHQKAAAAAAAAAAAAqPgKAKj46gCo+PQAqPj0AKj49ACo+PQAqPj0AKj49ACo + +PQAqPj0AKj49ACo+PQAqPj0AKj49ACo+PQAqPj0AKj49ACo+PQAqPj0AKj49ACo+PQAqPj0AKj49ACo + +PQAqPj0AKj49ACo+PQAqPj0AKj49ACo+PQAqPj0AKj49ACm9PQAWoT0AFR89ABUfPQAVHzqAFR8CgAA + AAAAAAAA/1ohCv9aIer/WiH0/1oh9P9aIfT/WiH0/1oh9P9aIfT/WiH0/1oh9P9aIfT/WiH0/1oh9P9a + IfT/WiH0/1oh9P9aIfT/WiH0/1oh9P9aIfT/WiH0/1oh9P9aIfT/WiH0/1oh9P9aIfT/WiH0/1oh9P9a + IfT/WiH0/1oh9P9aIfT7WSD0iTAS9IAtEfSALRH0gC0R6oAtEQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKRjnACkY5wopGOcLKRjnCykY5wspGOcLKRjnCykY5wspGOcLKRjnCykY + 5wspGOcLKRjnCykY5wspGOcLKRjnCykY5wspGOcLKRjnCykY5wspGOcLKRjnCykY5wspGOcLKRjnCykY + 5wspGOcLKRjnCykY5wspGOcLKRjnCykY5wsoGOQLFg18CxUMdAsVDHQLFQx0ChUMdAAAAAAAAAAAAACo + +AAAqPgKAKj4CwCo+AsAqPgLAKj4CwCo+AsAqPgLAKj4CwCo+AsAqPgLAKj4CwCo+AsAqPgLAKj4CwCo + +AsAqPgLAKj4CwCo+AsAqPgLAKj4CwCo+AsAqPgLAKj4CwCo+AsAqPgLAKj4CwCo+AsAqPgLAKj4CwCo + +AsAqPgLAKb0CwBahAsAVHwLAFR8CwBUfAoAVHwAAAAAAAAAAAD/WiEA/1ohCv9aIQv/WiEL/1ohC/9a + IQv/WiEL/1ohC/9aIQv/WiEL/1ohC/9aIQv/WiEL/1ohC/9aIQv/WiEL/1ohC/9aIQv/WiEL/1ohC/9a + IQv/WiEL/1ohC/9aIQv/WiEL/1ohC/9aIQv/WiEL/1ohC/9aIQv/WiEL/1ohC/tZIAuJMBILgC0RC4At + EQuALREKgC0RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAP////////////////////////////////////////////////////////////////// + /////////////////////////////////////////AAAAAA///////////////gAAAAAH/////////// + ///4AAAAAB//////////////+AAAAAAf//////////////gAAAAAH//////////////4AAAAAB////// + ////////+AAAAAAf//////////////gAAAAAH//////////////4AAAAAB//////////////+AAAAAAf + //////////////gAAAAAH//////////////4AAAAAB//////////////+AAAAAAf//////////////gA + AAAAH//////////////4AAAAAB//////////////+AAAAAAf//////////////gAAAAAH/////////// + ///4AAAAAB//////////////+AAAAAAf//////////////gAAAAAH//////////////4AAAAABwAAAAA + P///////+AAAAAAYAAAAAB////////gAAAAAGAAAAAAf///////4AAAAABgAAAAAH///////+AAAAAAY + AAAAAB////////gAAAAAGAAAAAAf///////4AAAAABgAAAAAH///////+AAAAAAYAAAAAB////////gA + AAAAGAAAAAAf///////4AAAAABgAAAAAH///////+AAAAAAYAAAAAB////////gAAAAAGAAAAAAf//// + ///4AAAAABgAAAAAH///////+AAAAAAYAAAAAB////////gAAAAAGAAAAAAf///////4AAAAABgAAAAA + H///////+AAAAAAYAAAAAB////////gAAAAAGAAAAAAf///////4AAAAABgAAAAAH///////+AAAAAAY + AAAAAB////////gAAAAAGAAAAAAcAAAAAD/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gA + AAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAA + AB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAA + GAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAY + AAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gA + AAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAA + AB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAA + GAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAY + AAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gA + AAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAA + AB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAA + GAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAY + AAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gA + AAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAA + AB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAA + GAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAY + AAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gA + AAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAA + AB/4AAAAABgAAAAAGAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAA + GAAAAAAf+AAAAAAYAAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf+AAAAAAY + AAAAABgAAAAAH/gAAAAAGAAAAAAYAAAAAB/4AAAAABgAAAAAGAAAAAAf/AAAAAA8AAAAADwAAAAAP/// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////// + + + \ No newline at end of file diff --git a/MusicUtility.cs b/MusicUtility.cs new file mode 100644 index 0000000..157069b --- /dev/null +++ b/MusicUtility.cs @@ -0,0 +1,69 @@ +namespace BRRSuiteGUI; + +public static class MusicUtility { + public const double ConcertA4 = 440.0000D; + public const double ConcertC4 = 261.6256D; + private const int OneOctave = 12; + + private static readonly string[] Notes = [ "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#" ]; + public static string GetNoteNameAndOctave(double freq) { + return $"{GetNoteName(freq)}{GetOctave(freq)}"; + } + + public static int GetOctave(double freq) { + int cents = GetCentsDifference(freq, ConcertC4); + cents += 50; // round + + if (cents >= 0) { // let flat Cs stay the correct octave + return 4 + cents / 1200; + } + + return 3 + cents / 1200; + } + + public static string GetNoteName(double freq) { + int n = GetNoteDifference(freq, ConcertA4); + n %= 12; + n += 12; + n %= 12; + return Notes[n]; + } + + public static int GetCentsFromConcertPitch(double freq) { + double betterFreq = RoundToNearestNote(freq); + int cents = GetCentsDifference(freq, betterFreq); + + if (cents < 51) { + return cents; + } + + return -(100 - cents); + } + + public static string GetCentsFromConcertPitchFormatted(double freq) { + int cents = GetCentsFromConcertPitch(freq); + + return cents switch { + 0 => "±0", + < 0 => $"{cents}", + > 0 => $"+{cents}" + }; + } + + public static double RoundToNearestNote(double freq) { + return Math.Pow(2, Math.Round(OneOctave * Math.Log2(freq / ConcertA4)) / OneOctave) * ConcertA4; + } + + public static int GetCentsDifference(double freqN, double freqD) { + return (int) Math.Round(OneOctave * 100 * Math.Log2(freqN / freqD)); + } + + private static int GetNoteDifference(double freqN, double freqD) { + return (int) Math.Round(OneOctave * Math.Log2(freqN / freqD)); + } + + public static string GetFormattedFrequency(double freq) { + return $"{freq:#####.0000} Hz ({GetNoteNameAndOctave(freq)} {GetCentsFromConcertPitchFormatted(freq)} cents)"; + } + +} diff --git a/Program.cs b/Program.cs index 0e01690..414fe5d 100644 --- a/Program.cs +++ b/Program.cs @@ -1,16 +1,11 @@ global using BRRSuite; -global using static BRRSuite.Constants; +global using Aubio; namespace BRRSuiteGUI; internal static class Program { - /// - /// The main entry point for the application. - /// [STAThread] - static void Main() { - // To customize application configuration such as set high DPI settings or default font, - // see https://aka.ms/applicationconfiguration. + static unsafe void Main() { ApplicationConfiguration.Initialize(); Application.Run(new MainForm()); } diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index 9204575..b6e081b 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -80,6 +80,46 @@ internal static System.Drawing.Bitmap logofull { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap menubar_about { + get { + object obj = ResourceManager.GetObject("menubar_about", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap menubar_encodersettings { + get { + object obj = ResourceManager.GetObject("menubar_encodersettings", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap menubar_freq { + get { + object obj = ResourceManager.GetObject("menubar_freq", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap menubar_wave { + get { + object obj = ResourceManager.GetObject("menubar_wave", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -93,7 +133,7 @@ internal static System.Drawing.Bitmap refresh { /// /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> ///<meta> - /// <version major="1" minor="0" build="0"/> + /// <version major="1" minor="1" build="0"/> ///</meta>. /// internal static string version { diff --git a/Properties/Resources.resx b/Properties/Resources.resx index d6f41b3..172bea7 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -1606,102 +1606,155 @@ - iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAABX2SURBVHhe7ZMxrgTLcQT/AeTIIECXpgzeRhbPQVMGj6Ob6Qr0vspIYNOIGry30wUMJiuA8Ha7 - G4mJP5ZlWZZlWZZlWZZlWZZlWZZlWZZlWZZlWZZlWZZlWZZlWZZleTf/99f/+jPZf/7HXy7VTC3//t8/ - /kz2f/77Ws3U8rd//Plnsv/5939dqpnmoCiSpOhdzdRCUSRJ0buaqYWiSJKidzXTHBRFkhS9q5laKIok - KXpXM7VQFElS9K5mmoOiSJKidzVTC0WRJEXvaqYWiiJJit7VTHNQFElS9K5maqEokqToXc3UQlEkSdG7 - mmkOiiJJit7VTC0URZIUvauZWiiKJCl6VzPNQVEkSdG7mqmFokiSonc1UwtFkSRF72qmOSiKJCl6VzO1 - UBRJUvSuZmqhKJKk6F3NNAdFkSRF72qmFooiSYre1UwtFEWSFL2rmeagKJKk6F3N1EJRJEnRu5qphaJI - kqJ3NdMcFEWSFL2rmVooiiQpelcztVAUSVL0rmaag6JIkqJ3NVMLRZEkRe9qphaKIkmK3tVMc1AUSVL0 - rmZqoSiSpOhdzdRCUSRJ0buaaQ6KIkmK3tVMLRRFkhS9q5laKIokKXpXM81BUSRJ0buaqYWiSJKidzVT - C0WRJEXvaqY5KIokKXpXM7VQFElS9K5maqEokqToXc00B0WRJEXvaqYWiiJJit7VTC0URZIUvauZ5qAo - kqToXc3UQlEkSdG7mqmFokiSonc10xwURZIUvauZWiiKJCl6VzO1UBRJUvSuZpqDokiSonc1UwtFkSRF - 72qmFooiSYre1UxzUBRJUvSuZmqhKJKk6F3N1EJRJEnRu5ppDooiSYre1UwtFEWSFL2rmVooiiQpelcz - zUFRJEnRu5qphaJIkqJ3NVMLRZEkRe9qpjkoiiQpelcztVAUSVL0rmZqoSiSpOhdzTQHRTFtXYvSb6el - 6N161yUUxbR1LUq/nZaid+tdl1AU09a1KP12WorerXfNQlFMWdf9SPrvlBS9W++5hKKYsq77kfTfKSl6 - t95zCUUxZV33I+m/U1L0br1nFopiwrrqV9IZE1L0br3lEopiwrrqV9IZE1L0br3lEopiwrrqV9IZE1L0 - br1lForitHXNV9JZp6Xo3XrHJRTFaeuar6SzTkvRu/WOSyiK09Y1X0lnnZaid+sds1AUp61rvpLOOi1F - 79Y7LqEoTlvXfCWddVqK3q13XEJRnLau+Uo667QUvVvvmIWiOGldcUs686QUvVtvuISiOGldcUs686QU - vVtvuISiOGldcUs686QUvVtvmIWiOGldcUs686QUvVtvuISiOGldcUs686QUvVtvuISiOGldcUs686QU - vVtvmIWiOGldcUs686QUvVtvuISiOGldcUs686QUvVtvuISiOGldcUs686QUvVtvmIWiOGldcUs686QU - vVtvuISiOGldcUs686QUvVtvuISiOGldcUs686QUvVtvmIWiOGldcUs686QUvVtvuISiOGldcUs686QU - vVtvuISiOGldcUs686QUvVtvmIWiOGldcUs686QUvVtvuISiOGldcUs686QUvVtvuISiOGldcUs686QU - vVtvmIWiOG1d85V01mkperfecQlFcdq65ivprNNS9G694xKK4rR1zVfSWael6N16xywUxWnrmq+ks05L - 0bv1jksoitPWNV9JZ52WonfrHZdQFKeta76SzjotRe/WO2ahKCasq34lnTEhRe/WWy6hKCasq34lnTEh - Re/WWy6hKCasq34lnTEhRe/WW2ahKKas634k/XdKit6t91xCUUxZ1/1I+u+UFL1b77mEopiyrvuR9N8p - KXq33jMLRTFtXYvSb6el6N161yUUxbR1LUq/nZaid+tdl1AU09a1KP12WorerXfNQlEkSdG7mqmFokiS - onc1UwtFkSRF72qmOSiKJCl6VzO1UBRJUvSuZmqhKJKk6F3NNAdFkSRF72qmFooiSYre1UwtFEWSFL2r - meagKJKk6F3N1EJRJEnRu5qphaJIkqJ3NdMcFEWSFL2rmVooiiQpelcztVAUSVL0rmaag6JIkqJ3NVML - RZEkRe9qphaKIkmK3tVMc1AUSVL0rmZqoSiSpOhdzdRCUSRJ0buaaQ6KIkmK3tVMLRRFkhS9q5laKIok - KXpXM81BUSRJ0buaqYWiSJKidzVTC0WRJEXvaqY5KIokKXpXM7VQFElS9K5maqEokqToXc00B0WRJEXv - aqYWiiJJit7VTC0URZIUvauZ5qAokqToXc3UQlEkSdG7mqmFokiSonc10xwURZIUvauZWiiKJCl6VzO1 - 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 - SUVORK5CYII= + 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 + + + + + ..\Resources\menubar-encodersettings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAArdJREFUWEe9 + VltLYmEU9QIhhbcyyAtHEbKLgkipmRxRmQef/AODClYKJpIvgemDBJX43MvENA8F/YV5nx/QX/Cbl8Ef + MDJPTrM+xw4ezym/vJwFi/Wd615n7/1tVTFiGfwO8oMjhUGD/wBfNBpND6qsiYODgwfIywh7JpMpBlUG + rVaLSyaTBEuRCVC5TFxeXnLRaLSDpWBC8XK0223nuAmwt7Kyolw5Go0Gx/O8qBxqtVrZTFATwWBw7plY + DofDD9fX19zw+F00m00Ou2NujSns83g8Tur1OpOJSqXC7e/vi0xM25h0wgkviUQiHWTCSS9MQrVa5bxe + r6Qc6+vrHyoHP3QuMnF+fs6UiePjY253d3fmctCbRSaw5UitVmMykUqlOIfDMZuJ1dVVmjaRib29vc7F + xQWTCRhw6nS62TMxXo5QKERKpRKTCTxLe0dkwmAw9IrFohVrZkjKEQgESLlcZjKRTqfzEOFZSpg4grID + D8SGE054yc7OTieXy000YTQaryAiA/l8/hP0w+DHTWxvb5NEIvGmCeyeE4goOHrrDjod8DWSxrTZbASU + zInT09OjjY2Nv1gK95rN5rtut6um12eBpDGH3S6YiMViJ1arVRQcZp6en59nDv4KSWOCxOfzfV5bW7tC + qUbPD7i0tPQT6WeaqEzQ6/VyJiaROAHo3PCuCZThiX756DmtVkuPmbYwK2RNWCyWO0KIeph20TCiJjY3 + N6/cbvc9fjduMebjOD89UHMe/4x/Y/ka5Eu/3xcazuVyOYdfLpgYJ8b8N+j0KBQKVr/fX8hkMm8NGW6S + CWzzM+jigBF+A5ENToly/IIuDviFvIfIBh/h4oB/S7cQuaADYof+gS4Oh4eHtNtlg1N6PJ5H6GKBIF8h + cgZINpu1QxcPu91+trW1RRtukHbMhMf/wVWqf7G+VzkqijEgAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAVlJREFUWEfN + l+FRg1AYBCnBUizFUuzEUizFUixBc2845rgsCYyK2ZkdfO/bIH+AZJr5mo/32NuJI+3jXcD7bEMnpU78 + 6AK0phPs3RO0/zYfr+hY6957vag9HRP6R24T2hu8XMyB1x17j9rGnea2Pyu0vwyeZ73uOPe7bbJtk7Hu + IE1obhtqbDLWHaQJzW1DjU3GuoP046KhuU30GWqscXcVtEL3Os1sPgtonpplnUNS9y7tt+r2tN2thv8h + bp4pbp7p9FkbZzs91cbZDmhA9qP6Nxz0C2NLsaeTR865QEFqaJbmK5vm6QoKUkOzNKF5uuLeI9fQLE32 + nnOBIpkvplsvnOwMdZJaDGVDjSSokwiFsqFGEtRJhELZUCMJ6iRCoWyokQR1EtFA97G/Rvvvxifplsju + XjuGRl8ctlB3pE1utZs/tZq+gFvs7Q6hexjvY+BPLuAIGxcwTd89SEpm3iPOUwAAAABJRU5ErkJggg== @@ -1719,7 +1772,6 @@ FLU5sn+yk1kVFf8ztdofIFiAEoVqI/EAAAAASUVORK5CYII= - ..\version.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 diff --git a/README.md b/README.md index 38b84cd..12c5c2f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ BRR Suite requires the .NET 8.0 runtime. [^1]: At least when that user is me. +## Dependencies +- [aubio](https://aubio.org/) ## My process As of now, this doesn't provide any fancy features over BRRtools. The main reason I wrote this is because my workflow—which involved batch files to create hundreds or thousands of tests)—was getting extremely tedious. This application improved pretty much everything about what I was doing. It's faster. It's easier to manage files (mostly due to not needing to make a billion of them). And most of it is in a compact GUI. @@ -19,7 +21,7 @@ Here's a rough step-by-step of what I do: - Truncate the sample to about 0.1 seconds. Longer files end up too big for my tastes after conversion. BRR Suite (and BRRtools) can truncate the file themselves, but I find it easier to work with when it's smaller. - Use Effect>Normalize to remove any DC offset - Use Effect>Amplify to make the waveform as loud as possible -3. Save to audio to a `.wav` file with the name I intend to use with my SNES code. +3. Save the audio to a `.wav` file with the name I intend to use with my SNES code. 4. Set the `Trim to` field to a 0 or close-to-zero sample, with the number found using Audacity. This should give enough room for the waveform to loop nicely, but ideally as close to the beginning as possible for a smaller output. 5. Set the `First loop sample` field to a 0 or close-to-zero sample as close to the beginning as possible that looks like it could smoothly transition in from the selected endpoint. 6. Click `Create loop candidates` @@ -46,12 +48,10 @@ Here's a rough step-by-step of what I do: **`Cancel`** - While any encoding process is ongoing, most of the interface will be disabled. The progress bar on the bottom of the form displays an estimate for the task. This button can be used to cancel a large task (although it will finish its current encoding or decoding subtask before it can respond to such a request). ## Menu bar -### Window **`Frequency cheat sheet`** - Opens a window that shows the frequency of notes in concert pitch (A440). ----- +**`Wave window`** - A very rough drawing of the waveform of exported samples. I'll improve this someday maybe. -### Help **`Acknowledgements`** - Info about this program's development. ## Input @@ -89,16 +89,12 @@ Cons of lower frequencies: **`Interpolation`** - The algorithm used for resampling. - None -- Linear -- Sinusoidal - Cubic - Band-limited (best quality) **`Create unlooped`** - Creates four unlooped BRRs, one for each of the available encoding frequencies. -**`Treble boost`** - Selects a treble boost filter to compensate for the Gaussian low pass of the SNES. - -**`Force silence at start`** - Forces block 0 of the BRR to be all silent samples, allowing the first block of audio to use any filter. This may produce marginally better samples at the expense of size. +**`Treble boost`** - Selects a treble boost filter to compensate for the Gaussian interpolation of the SNES. ## Loop search The loop search functionality allows you to prospect a large number of candidate loop points starting from a given point. @@ -145,9 +141,25 @@ As candidates are created, they will populate the candidates list in the `Listen > [!TIP] > Irrespective of the auto-play setting, double clicking a candidate in the list will play its audio. - **`Export BRR`** - Exports a BRR file with the extension `.brr` to the output directory. BRR samples can be exported in three different formats, which are detailed in the [Library's README](https://github.com/spannerisms/BRRSuite/blob/main/README.md) -**`Export WAV`** - Exports the preview audio with the extension `.wav` to the output directory. \ No newline at end of file +**`Export WAV`** - Exports the preview audio with the extension `.wav` to the output directory. + +**`Export test .spc`** - Creates a file named `_test_.spc` + +This file can then be opened in an SPC player (some emulators such as bsnes+ or Mesen2 support opening SPC files) to quickly preview the sample in a short test song to see how it performs. + +The file name is always the same so that it can be easily reloaded without fiddling around in file explorer. + +Currently, there is also a very nice violin sample doubling the test song to use as a tuning reference. Eventually I'll add support for more test customizations... + +### Candidate input +The following keys have a function when the candidate list is selected: + +- Up / Down - Select new item +- Space - Play sample preview +- Delete - Remove candidate from list +- Backspace - Add attempted loop sample to scratch box +- Enter - Detect sample pitch diff --git a/Resources/menubar-about.png b/Resources/menubar-about.png new file mode 100644 index 0000000..ac51488 Binary files /dev/null and b/Resources/menubar-about.png differ diff --git a/Resources/menubar-encodersettings.png b/Resources/menubar-encodersettings.png new file mode 100644 index 0000000..90ebf17 Binary files /dev/null and b/Resources/menubar-encodersettings.png differ diff --git a/Resources/menubar-freq.png b/Resources/menubar-freq.png new file mode 100644 index 0000000..f08ae53 Binary files /dev/null and b/Resources/menubar-freq.png differ diff --git a/Resources/menubar-wave.png b/Resources/menubar-wave.png new file mode 100644 index 0000000..e4499ae Binary files /dev/null and b/Resources/menubar-wave.png differ diff --git a/SampleRate.cs b/SampleRate.cs new file mode 100644 index 0000000..9e5c069 --- /dev/null +++ b/SampleRate.cs @@ -0,0 +1,103 @@ +namespace BRRSuiteGUI; + +/// +/// Represents an audio sample rate given in hertz. +/// +public readonly struct SampleRate : IComparable { + /// + /// Gets the number of samples per second expressed by this frequency. + /// + public int Frequency { get; } = Conversion.DSPFrequency; + + /// + /// Gets the frequency expressed as and rounded down to the nearest kilohertz. + /// + public int FrequencykHz => Frequency / 1000; + + /// + /// Gets the ratio between the SNES DSP frequency of 32000 and this frequency. + /// + public decimal Cram => 32000M / Frequency; + + /// + /// Creates a new struct for the specified frequency. + /// + /// The frequency of this sample. This should be a positive, nonzero value. + /// When is 0 or negative. + public SampleRate(int frequency) { + if (frequency < 1) { + throw new ArgumentException("Frequency should be a positive, non-zero value."); + } + + Frequency = frequency; + } + + /// + /// Returns a readable string of this frequency with units hertz. + /// + public override string ToString() => $"{Frequency} Hz"; + + /// + /// Calculates the ratio representing this sample rate resampled to the given target frequency. + /// + /// The target frequency to resample to. + /// A resampling ratio. + public decimal ResampleTo(int targetFrequency) { + return (decimal) Frequency / targetFrequency; + } + + /// + public decimal ResampleTo(SampleRate targetFrequency) { + return ResampleTo(targetFrequency.Frequency); + } + + /// + /// Calculates the ratio representing this sample rate resampled from the given target frequency. + /// + /// The frequency to resample from. + /// A resampling ratio. + public decimal ResampleFrom(int fromFrequency) { + return (decimal) Frequency / fromFrequency; + } + + /// + public decimal ResampleFrom(SampleRate fromFrequency) { + return ResampleFrom(fromFrequency.Frequency); + } + + /// + public int CompareTo(SampleRate other) { + return Frequency.CompareTo(other.Frequency); + } + + /// + /// Represents a sample rate of 32000 Hz, the frequency of the SNES DSP. + /// + public static readonly SampleRate SR32000 = new(32000); + + /// + /// Represents a sample rate of 16000 Hz. + /// + public static readonly SampleRate SR16000 = new(16000); + + /// + /// Represents a sample rate of 8000 Hz. + /// + public static readonly SampleRate SR8000 = new(8000); + + /// + /// Represents a sample rate of 4000 Hz. + /// + public static readonly SampleRate SR4000 = new(4000); + + /// + /// Represents a sample rate of 44100 Hz, the standard for CD-quality audio. + /// + public static readonly SampleRate SR44100 = new(44100); + + public static explicit operator SampleRate(int sr) => new(Math.Max(1, sr)); + + public static implicit operator int(SampleRate sr) => sr.Frequency; + public static implicit operator uint(SampleRate sr) => (uint) sr.Frequency; + public static implicit operator decimal(SampleRate sr) => sr.Frequency; +} diff --git a/TestContainer.cs b/TestContainer.cs index ded4b41..463022e 100644 --- a/TestContainer.cs +++ b/TestContainer.cs @@ -22,21 +22,20 @@ internal sealed class TestContainer { /// /// Gets the name this object should appear as in the user interface. /// - public string ListName { get; init; } + public required string ListName { get; init; } /// - /// Gets the preferred file name this container's children should use for export. + /// Gets the preferred file name this container's members should use for export. /// - public string FileName { get; init; } + public required string FileName { get; init; } + + public required int EncodingFrequency { get; init; } /// /// The sample the source audio was trimmed to /// public int Trim { get; init; } = 0; - /// - /// - /// public decimal ResampleRatio { get; set; } = 1.0M; /// @@ -54,18 +53,29 @@ internal sealed class TestContainer { /// public int LoopBlock => BRRFile.LoopBlock; + + public double? EstimatedFrequency { get; set; } = null; + /// - /// + /// ID for sorting, if necessary + /// + internal long ID { get; init; } + + /// + /// TestContainer /// - /// A simple name for this file. - /// - /// public TestContainer(string name, BRRSample brr, WaveContainer wav) { - FileName = ListName = Name = name; + Name = name; BRRFile = brr; WaveFile = wav; } /// public override string ToString() => ListName; + + public void DoFrequencyEstimate() { + if (EstimatedFrequency is not null) return; + + EstimatedFrequency = Aubio.Aubio.DetectPitch(WaveFile, PitchDetectionAlgorithm.YIN); + } } diff --git a/libaubio-5.dll b/libaubio-5.dll new file mode 100644 index 0000000..250edec Binary files /dev/null and b/libaubio-5.dll differ diff --git a/testengine.bin b/testengine.bin new file mode 100644 index 0000000..5ca5765 Binary files /dev/null and b/testengine.bin differ diff --git a/version.xml b/version.xml index f7ac800..0f03a3c 100644 --- a/version.xml +++ b/version.xml @@ -1,4 +1,4 @@  - + \ No newline at end of file