diff --git a/ToonTown Rewritten Bot/AboutBox1.resx b/ToonTown Rewritten Bot/AboutBox1.resx deleted file mode 100644 index 6dae11dd..00000000 --- a/ToonTown Rewritten Bot/AboutBox1.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/ToonTown Rewritten Bot/BotFunctions.cs b/ToonTown Rewritten Bot/BotFunctions.cs deleted file mode 100644 index 28596d53..00000000 --- a/ToonTown Rewritten Bot/BotFunctions.cs +++ /dev/null @@ -1,374 +0,0 @@ -using System; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Runtime.InteropServices; -using System.Threading; -using System.Windows.Forms; - -namespace ToonTown_Rewritten_Bot -{ - class BotFunctions : AdvancedSettings - { - //eventually clean up repetative code - - public static bool isAutoDetectFishingBtnActive = true; - - public static void DoMouseClick() - { - DoMouseClick(getCursorLocation()); - } - - public static void DoFishingClick() - { - //click red button - DoMouseClickDown(getCursorLocation()); - Thread.Sleep(500);//sleep 2 sec - - //get the coords of the red button and move cursor from there, downward - int[] coordinates = getCoordinates("15"); - int x = coordinates[0]; - int y = coordinates[1]; - MoveCursor(x, (y+150));//pull it back - Thread.Sleep(500); - DoMouseClickUp(getCursorLocation()); - } - private static void DoMouseClick(Point location)//simulate left button mouse click - { - //Call the imported function with the cursor's current position - uint X = Convert.ToUInt32(location.X); - uint Y = Convert.ToUInt32(location.Y); - mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0); - } - - private static void DoMouseClickDown(Point location) - { - uint X = Convert.ToUInt32(location.X); - uint Y = Convert.ToUInt32(location.Y); - mouse_event(MOUSEEVENTF_LEFTDOWN, X, Y, 0, 0); - } - - private static void DoMouseClickUp(Point location) - { - uint X = Convert.ToUInt32(location.X); - uint Y = Convert.ToUInt32(location.Y); - mouse_event(MOUSEEVENTF_LEFTUP, X, Y, 0, 0); - } - - public static Color GetColorAt(int x, int y) - { - IntPtr desk = GetDesktopWindow(); - IntPtr dc = GetWindowDC(desk); - int a = (int)GetPixel(dc, x, y); - ReleaseDC(desk, dc); - return Color.FromArgb(255, (a >> 0) & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff); - } - - public static Point getCursorLocation() - { - Point cursorLocation = new Point(); - GetCursorPos(ref cursorLocation); - return cursorLocation; - } - - public static String HexConverter(Color c) - { - return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2"); - } - - public static void MoveCursor(int x, int y) - { - Cursor.Position = new Point(x, y); - } - - // Maximizes and Focuces TTR - public static void maximizeAndFocus() - { - IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, "Toontown Rewritten"); - ShowWindow(hwnd, 6);//6 min - ShowWindow(hwnd, 3);//3 max - } - - private static string[] lines; - public static void readTextFile() - { - if (File.Exists("Coordinates Data File.txt")) - { - try - { - lines = File.ReadAllLines(Path.GetFullPath("Coordinates Data File.txt")); - } - catch (Exception e) - { - MessageBox.Show("The file could not be read:"); - Console.WriteLine(e.Message); - } - } - else - createFreshCoordinatesFile(); - } - - private static void updateTextFile() - { - try - { - using (StreamWriter writer = new StreamWriter(Path.GetFullPath("Coordinates Data File.txt"))) - { - for (int i = 0; i < lines.Length; i++) - { - writer.WriteLine(lines[i]); - } - writer.Close(); - } - } - catch (Exception e) - { - Console.WriteLine("The file could not be written to:"); - Console.WriteLine(e.Message); - } - } - - public static void updateTextFile(string[] lines)//manually updating coords - { - try - { - using (StreamWriter writer = new StreamWriter(Path.GetFullPath("Coordinates Data File.txt"))) - { - for (int i = 0; i < lines.Length; i++) - { - writer.WriteLine(lines[i]); - } - writer.Close(); - } - } - catch (Exception e) - { - Console.WriteLine("The file could not be written to:"); - Console.WriteLine(e.Message); - } - } - - public static void manualUpdateCoordinates(String locationToUpdate) - { - UpdateCoordsHelper updateCoordsWindow = new UpdateCoordsHelper(); - try - { - updateCoordsWindow.startCountDown(Form1.dataFileMap[locationToUpdate]); - updateCoordsWindow.ShowDialog(); - } - catch - { - MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); - } - - Point coords = getCursorLocation(); - string x = Convert.ToString(coords.X); - string y = Convert.ToString(coords.Y); - lines = File.ReadAllLines(Path.GetFullPath("Coordinates Data File.txt")); - for (int i = 0; i < lines.Length; i++) - { - if (lines[i].Contains(".")) - { - if (locationToUpdate.Equals(lines[i].Substring(0, lines[i].IndexOf('.'))))//look for the number it cooresponds to - { - lines[i] = locationToUpdate + "." + "(" + x + "," + y + ")"; - updateTextFile();//changes the coordinate values in the data file - } - } - } - } - - public static void manuallyUpdateCoordinatesNoUI(string locationToUpdate, Point coodinates) - { - string[] lines = File.ReadAllLines(Path.GetFullPath("Coordinates Data File.txt")); - for (int i = 0; i < lines.Length; i++) - { - if (lines[i].Contains(".")) - { - if (locationToUpdate.Equals(lines[i].Substring(0, lines[i].IndexOf('.'))))//look for the number it cooresponds to - { - lines[i] = locationToUpdate + "." + "(" + coodinates.X + "," + coodinates.Y + ")"; - updateTextFile(lines);//changes the coordinate values in the data file - } - } - } - } - - public static int[] getCoordinates(String coordsToRetrieve) - { - lines = File.ReadAllLines(Path.GetFullPath("Coordinates Data File.txt")); - for (int i = 0; i < lines.Length; i++) - { - if (lines[i].Contains(".")) - { - if (coordsToRetrieve.Equals(lines[i].Substring(0, lines[i].IndexOf('.'))))//look for the number it cooresponds to - { - String check = lines[i]; - char[] removeChars = {'(', ')' }; - String coords = check.Substring(check.IndexOf('(') + 1); - coords = coords.Trim(removeChars); - String[] points = coords.Split(','); - int x = Convert.ToInt32(points[0]); - int y = Convert.ToInt32(points[1]); - int[] locations = {x,y}; - return locations; - } - } - } - return null; - } - - public static bool checkCoordinates(String checkCoords) - { - string filePath = "Coordinates Data File.txt"; - if (!File.Exists(filePath)) - { - // Create the file and write the default coordinates - createFreshCoordinatesFile(); - } - - lines = File.ReadAllLines(Path.GetFullPath("Coordinates Data File.txt")); - for (int i = 0; i < lines.Length; i++) - { - if (lines[i].Contains(".")) - { - if (checkCoords.Equals(lines[i].Substring(0, lines[i].IndexOf('.'))))//look for the number it cooresponds to - { - String check = lines[i]; - char[] removeChars = { '(', ')' }; - String coords = check.Substring(check.IndexOf('(') + 1); - coords = coords.Trim(removeChars); - if ("0,0".Equals(coords)) - { - return false;//returns false if they equals 0,0 - } - } - } - } - return true;//return true if they're not 0,0 - } - - public static void resetAllCoordinates() - { - string filePath = "Coordinates Data File.txt"; - if (!File.Exists(filePath)) - { - // Create the file and write the default coordinates - createFreshCoordinatesFile(); - } - else - { - // Read the existing file and overwrite with default coordinates - string[] lines = File.ReadAllLines(filePath); - for (int i = 0; i < Form1.dataFileMap.Count; i++) - { - lines[i] = $"{i}.(0,0)"; - } - writeDefaultCords(lines); - } - } - - public static void createFreshCoordinatesFile() - { - string filePath = "Coordinates Data File.txt"; - // Delete the file if it exists - if (File.Exists(filePath)) - File.Delete(filePath); - // Create the file and write the default coordinates - using (StreamWriter sw = File.CreateText(filePath)) - { - for (int i = 1; i <= Form1.dataFileMap.Count; i++) - { - sw.WriteLine($"{i}.(0,0)"); - } - } - } - - public static void tellFishingLocation(string location) - { - switch (location) - { - case "TOONTOWN CENTRAL PUNCHLINE PLACE": - MessageBox.Show("Fishes in the first dock when you walk in"); - break; - case "DONALD DREAM LAND LULLABY LANE": - MessageBox.Show("Fishes in the dock to the left of the small box"); - break; - case "BRRRGH POLAR PLACE": - MessageBox.Show("Fishes in the top right dock"); - break; - case "BRRRGH WALRUS WAY": - MessageBox.Show("Fishes in the top left dock"); - break; - case "BRRRGH SLEET STREET": - MessageBox.Show("Fishes in the first dock when you walk in"); - break; - case "MINNIE'S MELODYLAND TENOR TERRACE": - MessageBox.Show("Fishes in the top left dock"); - break; - case "DONALD DOCK LIGHTHOUSE LANE": - MessageBox.Show("Fishes in the 2nd one on the right"); - break; - case "DAISY'S GARDEN ELM STREET": - MessageBox.Show("Fishes in the bottom left dock when you walk in"); - break; - case "FISH ANYWHERE": - MessageBox.Show("Fishes for you anywhere, but will only fish, will not sell fish!"); - break; - } - } - - //probably delete eventually. Use createFreshCoordinatesFile func - private static void writeDefaultCords(String[] line) - { - try - { - using (StreamWriter writer = new StreamWriter(Path.GetFullPath("Coordinates Data File.txt"))) - { - for (int i = 0; i < line.Length; i++) - { - writer.WriteLine(line[i]); - } - writer.Close(); - } - } - catch (Exception e) - { - Console.WriteLine("The file could not be written to:"); - Console.WriteLine(e.Message); - } - } - - - - - //ignore .dll imports below - [DllImport("user32.dll")] - private static extern bool GetCursorPos(ref Point lpPoint); - - [DllImport("user32.dll", EntryPoint = "FindWindow")] - private static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); - - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); - - [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] - private static extern int BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop); - [DllImport("user32.dll", SetLastError = true)] - private static extern IntPtr GetDesktopWindow(); - [DllImport("user32.dll", SetLastError = true)] - private static extern IntPtr GetWindowDC(IntPtr window); - [DllImport("gdi32.dll", SetLastError = true)] - private static extern uint GetPixel(IntPtr dc, int x, int y); - [DllImport("user32.dll", SetLastError = true)] - private static extern int ReleaseDC(IntPtr window, IntPtr dc); - [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] - private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo); - - private const int MOUSEEVENTF_LEFTDOWN = 0x02; - private const int MOUSEEVENTF_LEFTUP = 0x04; - private const int MOUSEEVENTF_RIGHTDOWN = 0x08; - private const int MOUSEEVENTF_RIGHTUP = 0x10; - } -} diff --git a/ToonTown Rewritten Bot/DevForm.Designer.cs b/ToonTown Rewritten Bot/DevForm.Designer.cs deleted file mode 100644 index f6f89318..00000000 --- a/ToonTown Rewritten Bot/DevForm.Designer.cs +++ /dev/null @@ -1,186 +0,0 @@ -namespace ToonTown_Rewritten_Bot -{ - partial class DevForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.button1 = new System.Windows.Forms.Button(); - this.button2 = new System.Windows.Forms.Button(); - this.trackBar1 = new System.Windows.Forms.TrackBar(); - this.checkBox1 = new System.Windows.Forms.CheckBox(); - this.comboBox1 = new System.Windows.Forms.ComboBox(); - //this.imageBox1 = new Emgu.CV.UI.ImageBox(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.label1 = new System.Windows.Forms.Label(); - this.groupBox2 = new System.Windows.Forms.GroupBox(); - this.checkBox2 = new System.Windows.Forms.CheckBox(); - ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); - //((System.ComponentModel.ISupportInitialize)(this.imageBox1)).BeginInit(); - this.groupBox1.SuspendLayout(); - this.groupBox2.SuspendLayout(); - this.SuspendLayout(); - // - // button1 - // - this.button1.Location = new System.Drawing.Point(27, 29); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(124, 58); - this.button1.TabIndex = 0; - this.button1.Text = "Capture Screen"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.button1_Click); - // - // button2 - // - this.button2.Location = new System.Drawing.Point(393, 287); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(124, 58); - this.button2.TabIndex = 3; - this.button2.Text = "Find Coords"; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.button2_Click); - // - // trackBar1 - // - this.trackBar1.LargeChange = 1; - this.trackBar1.Location = new System.Drawing.Point(6, 19); - this.trackBar1.Name = "trackBar1"; - this.trackBar1.Size = new System.Drawing.Size(184, 45); - this.trackBar1.TabIndex = 4; - this.trackBar1.Value = 5; - this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll); - // - // checkBox1 - // - this.checkBox1.AutoSize = true; - this.checkBox1.Location = new System.Drawing.Point(246, 267); - this.checkBox1.Name = "checkBox1"; - this.checkBox1.Size = new System.Drawing.Size(135, 17); - this.checkBox1.TabIndex = 5; - this.checkBox1.Text = "Use advanced settings"; - this.checkBox1.UseVisualStyleBackColor = true; - this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged); - // - // comboBox1 - // - this.comboBox1.FormattingEnabled = true; - this.comboBox1.Location = new System.Drawing.Point(42, 49); - this.comboBox1.Name = "comboBox1"; - this.comboBox1.Size = new System.Drawing.Size(148, 21); - this.comboBox1.TabIndex = 6; - // - // imageBox1 - // - /*this.imageBox1.Location = new System.Drawing.Point(1025, 8); - this.imageBox1.Name = "imageBox1"; - this.imageBox1.Size = new System.Drawing.Size(99, 93); - this.imageBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.imageBox1.TabIndex = 2; - this.imageBox1.TabStop = false;*/ - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.groupBox2); - this.groupBox1.Controls.Add(this.comboBox1); - this.groupBox1.Controls.Add(this.button2); - this.groupBox1.Controls.Add(this.checkBox1); - this.groupBox1.Location = new System.Drawing.Point(269, 173); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(538, 373); - this.groupBox1.TabIndex = 7; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Image Rec"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(208, 20); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(22, 13); - this.label1.TabIndex = 8; - this.label1.Text = "0.5"; - this.label1.Visible = false; - // - // groupBox2 - // - this.groupBox2.Controls.Add(this.checkBox2); - this.groupBox2.Controls.Add(this.trackBar1); - this.groupBox2.Controls.Add(this.label1); - this.groupBox2.Enabled = false; - this.groupBox2.Location = new System.Drawing.Point(246, 32); - this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(270, 229); - this.groupBox2.TabIndex = 9; - this.groupBox2.TabStop = false; - this.groupBox2.Text = "Advanced Settings"; - // - // checkBox2 - // - this.checkBox2.AutoSize = true; - this.checkBox2.Location = new System.Drawing.Point(14, 70); - this.checkBox2.Name = "checkBox2"; - this.checkBox2.Size = new System.Drawing.Size(121, 17); - this.checkBox2.TabIndex = 9; - this.checkBox2.Text = "Display Debug View"; - this.checkBox2.UseVisualStyleBackColor = true; - this.checkBox2.CheckedChanged += new System.EventHandler(this.checkBox2_CheckedChanged); - // - // DevForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1146, 599); - this.Controls.Add(this.groupBox1); - //this.Controls.Add(this.imageBox1); - this.Controls.Add(this.button1); - this.Name = "DevForm"; - this.Text = "DevForm"; - ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit(); - //((System.ComponentModel.ISupportInitialize)(this.imageBox1)).EndInit(); - this.groupBox1.ResumeLayout(false); - this.groupBox1.PerformLayout(); - this.groupBox2.ResumeLayout(false); - this.groupBox2.PerformLayout(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Button button1; - //private Emgu.CV.UI.ImageBox imageBox1; - private System.Windows.Forms.Button button2; - private System.Windows.Forms.TrackBar trackBar1; - private System.Windows.Forms.CheckBox checkBox1; - private System.Windows.Forms.ComboBox comboBox1; - private System.Windows.Forms.GroupBox groupBox1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.GroupBox groupBox2; - private System.Windows.Forms.CheckBox checkBox2; - } -} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/DevForm.cs b/ToonTown Rewritten Bot/DevForm.cs deleted file mode 100644 index 7d85f102..00000000 --- a/ToonTown Rewritten Bot/DevForm.cs +++ /dev/null @@ -1,237 +0,0 @@ -//using Emgu.CV; -//using Emgu.CV.Structure; -using System; -using System.Drawing; -using System.Runtime.InteropServices; -using System.Threading; -using System.Windows.Forms; -//using Tesseract; -using System.Diagnostics; -using System.IO; - -namespace ToonTown_Rewritten_Bot -{ - public partial class DevForm : Form - { - string scriptPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @".\Search_Images")); - public DevForm() - { - InitializeComponent(); - - //string resourcesPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @".\Search Images")); - //Console.WriteLine("The current directory is {0}", scriptPath); - //Console.WriteLine("Num of files: " + Directory.GetFiles(newPath,"*.png", SearchOption.AllDirectories).Length); - int numOfFiles = Directory.GetFiles(scriptPath, "*.png", SearchOption.AllDirectories).Length; - string[] fileEntries = Directory.GetFiles(scriptPath); - - for (int i = 0; i < numOfFiles; i++) - { - if(!fileEntries[i].Substring(fileEntries[i].LastIndexOf(@"\", fileEntries[i].Length) + 1).Contains(" "))//dont add files that contain a space - comboBox1.Items.Add(fileEntries[i].Substring(fileEntries[i].LastIndexOf(@"\", fileEntries[i].Length)+1)); - } - } - - private void button2_Click(object sender, EventArgs e) - { - //var test = Properties.Resources.imageRecognitionTesting; - cmdexe(); - } - - static float defaultConfidence = 0.5f; - - //Arguments = "/K cd Resources&python ./imageRecognitionTesting.py" - public void cmdexe()//dont multi-thread so that the py script doesn't keep running if the debug view window isnt closed - { - Process p = new Process(); - ProcessStartInfo startInfo = new ProcessStartInfo(); - //startInfo.WindowStyle = ProcessWindowStyle.Hidden; - startInfo.WorkingDirectory = Environment.CurrentDirectory; - startInfo.UseShellExecute = false; - startInfo.FileName = "cmd.exe"; - startInfo.Arguments = "/r echo %cd%"; - if(checkBox1.Checked) - startInfo.Arguments = "/r cd Search_Images&python ./imageRecognitionTesting.py " + comboBox1.SelectedItem.ToString() + " " + (trackBar1.Value / 10.0f) + " " + debugView; - else - startInfo.Arguments = "/r cd Search_Images&python ./imageRecognitionTesting.py " + comboBox1.SelectedItem.ToString() + " " + defaultConfidence + " " + debugView; - p.StartInfo = startInfo; - p.StartInfo.RedirectStandardOutput = true; - p.StartInfo.RedirectStandardInput = true; - startInfo.WindowStyle = ProcessWindowStyle.Hidden; - p.Start(); - while (!p.StandardOutput.EndOfStream) - { - string line = p.StandardOutput.ReadLine(); - Console.WriteLine(line); - } - p.WaitForExit(); - } - - private void button1_Click(object sender, EventArgs e) - { - IntPtr hWnd = FindWindow(null, "Toontown Rewritten"); - if (hWnd != (IntPtr)0x00) - { - Thread t = new Thread(() => CaptureWindow(hWnd)); - t.Start(); - } - else - Console.WriteLine("Toontown Rewritten not running"); - } - - //prob wont use in release version - //Capturing the screen without boarders using GetClientRect - public void CaptureWindow(IntPtr handle) - { - ClientToScreen(handle, out var pnt);//must stay out of the loop - //need to fix it so when the window is moved/resized, it gets the updated points (pnt) - while (true) - { - //Console.WriteLine(pnt); - GetClientRect(handle, out var rect); - var size = new Size(rect.Right - rect.Left, rect.Bottom - rect.Top); - var result = new Bitmap(size.Width, size.Height); - using (var graphics = Graphics.FromImage(result)) - { - graphics.CopyFromScreen(pnt, Point.Empty, size); - } - - //result.Save("C:/Users/Mike/Documents/Github/Toontown Rewritten Bot/[Source] Toontown Rewritten Bot/ToonTown Rewritten Bot/Resources/screenCapture.bmp"); - //result.ToImage(); - - var image = result; - //readText(image); - //var previousImage = pictureBox1.Image; - //pictureBox1.Image = image; - //previousImage?.Dispose(); - - //testing - //testImageCapture(result); - } - } - - //prob just use to show box where the coords are for debugging purposes in release version - /*Image template = new Image(Properties.Resources.stickerBook.ToImage().Data); // Image A - private void testImageCapture(Bitmap inputImage) - { - //find image a in b - Image source = new Image(inputImage.ToImage().Data); - //Image source = new Image("C:/Users/Mike/Documents/Github/Toontown Rewritten Bot/[Source] Toontown Rewritten Bot/ToonTown Rewritten Bot/Resources/screenCapture.bmp"); // Image B - //Image template = new Image("C:/Users/Mike/Documents/Github/Toontown Rewritten Bot/[Source] Toontown Rewritten Bot/ToonTown Rewritten Bot/Resources/toonLaughBottomLeft.png"); // Image A - Image imageToShow = source.Copy(); - - - //CcoeffNormed is more accurate but needs to solve the rescale issue - //Ccoeff less accurate but doesnt have scale issues, can find the image max window or other sized - using (Image result = source.MatchTemplate(template, Emgu.CV.CvEnum.TemplateMatchingType.Ccoeff)) - { - double[] minValues, maxValues; - Point[] minLocations, maxLocations; - result.MinMax(out minValues, out maxValues, out minLocations, out maxLocations); - - if (maxValues[0] > 0.6) - { - // This is a match. Do something with it, for example draw a rectangle around it. - Rectangle match = new Rectangle(maxLocations[0], template.Size); - imageToShow.Draw(match, new Bgr(Color.Red), 3); - } - } - - imageBox1.Image = imageToShow; - }*/ - - [StructLayout(LayoutKind.Sequential)] - public struct POINT - { - public int X; - public int Y; - - public POINT(int x, int y) - { - this.X = x; - this.Y = y; - } - - public static implicit operator Point(POINT p) - { - return new Point(p.X, p.Y); - } - - public static implicit operator POINT(Point p) - { - return new POINT(p.X, p.Y); - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct Rect - { - public int Left; - public int Top; - public int Right; - public int Bottom; - } - - [DllImport("user32.dll")] - static extern bool GetClientRect(IntPtr hWnd, out Rect lpRect); - - [DllImport("user32.dll")] - static extern bool ClientToScreen(IntPtr hWnd, out Point lpPoint); - - [DllImport("user32.dll", SetLastError = true)] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - //testing Tesseract stuff here - - public const string TESS_PATH = "tessdata/"; - public const string TESS_LANGUAGE = "eng"; - //private static TesseractEngine engine; - - /*public static void readText(Image inputImage) - { - using (engine = new TesseractEngine(TESS_PATH, TESS_LANGUAGE)) - { - // have to load Pix via a bitmap since Pix doesn't support loading a stream. - using (var image = new Bitmap(inputImage)) - { - using (var pix = PixConverter.ToPix(image)) - { - using (var page = engine.Process(pix)) - { - Console.WriteLine(page.GetMeanConfidence() + " : " + page.GetText()); - } - } - } - } - }*/ - - private void trackBar1_Scroll(object sender, EventArgs e) - { - //Console.WriteLine("Trackbar val: " + (trackBar1.Value/10.0f)); - label1.Text = (trackBar1.Value / 10.0f).ToString(); - } - - private void checkBox1_CheckedChanged(object sender, EventArgs e) - { - if (checkBox1.Checked) - { - groupBox2.Enabled = true; - label1.Visible = true; - } - else - { - groupBox2.Enabled = false; - label1.Visible = false; - checkBox2.Checked = false; - } - } - - private static bool debugView = false; - private void checkBox2_CheckedChanged(object sender, EventArgs e) - { - if (checkBox2.Checked) - debugView = true; - else - debugView = false; - } - } -} diff --git a/ToonTown Rewritten Bot/DoodleTraining.cs b/ToonTown Rewritten Bot/DoodleTraining.cs deleted file mode 100644 index 08c80ee6..00000000 --- a/ToonTown Rewritten Bot/DoodleTraining.cs +++ /dev/null @@ -1,350 +0,0 @@ -using System; -using System.Threading; -using System.Windows.Forms; - -namespace ToonTown_Rewritten_Bot -{ - class DoodleTraining - { - public static int numberOfFeeds, numberOfScratches; - private static string selectedTrick; - private static bool infiniteTimeCheckBox, justFeedCheckBox, justScratchCheckBox; - public static bool shouldStopTraining = false; - public static void startTrainingDoodle(int feeds, int scratches, bool unlimitedCheckBox, string trick, bool justFeed, bool justScratch) - { - numberOfFeeds = feeds; - numberOfScratches = scratches; - selectedTrick = trick; - infiniteTimeCheckBox = unlimitedCheckBox; - justFeedCheckBox = justFeed; - justScratchCheckBox = justScratch; - Thread.Sleep(2000); - feedAndScratch(); - } - - public static void feedAndScratch() - { - if (!infiniteTimeCheckBox)//infinite checkbox is not checked - { - //code here is required so it doesn't get stuck in infinite loop below - if (justFeedCheckBox) - numberOfScratches = 0; - else if (justScratchCheckBox) - numberOfFeeds = 0; - while (numberOfFeeds > 0 || numberOfScratches > 0 && !shouldStopTraining) - { - Thread.Sleep(5000); - if (numberOfFeeds > 0)//feed doodle - { - feedDoodle(); - numberOfFeeds--; - } - if (numberOfScratches > 0)//scratch doodle - { - scratchDoodle(); - numberOfScratches--; - } - determineSelectedTrick();//perform trick - } - } - else //infinite checkbox is checked, so loop until stopped - { - while (true && !shouldStopTraining) - { - if (justFeedCheckBox)//just feed is checked - feedDoodle(); - else if (justScratchCheckBox)//just scratch is checked - scratchDoodle(); - else if(!justFeedCheckBox && !justScratchCheckBox)//neither are checked, so do both - { - feedDoodle(); - scratchDoodle(); - } - determineSelectedTrick(); - Thread.Sleep(5000); - } - } - } - - public static void determineSelectedTrick() - { - Thread.Sleep(1000); - switch (selectedTrick) - { - case "Jump (5 - 10 laff)": - for(int i = 0; i < 2; i++)//attempt trick 2 times incase doodle gets confused - { - openSpeedChat(); - trainJump(); - } - break; - case "Beg (6 - 12 laff)": - for (int i = 0; i < 2; i++)//attempt trick 2 times incase doodle gets confused - { - openSpeedChat(); - trainBeg(); - } - break; - case "Play Dead (7 - 14 laff)": - for (int i = 0; i < 2; i++)//attempt trick 2 times incase doodle gets confused - { - openSpeedChat(); - trainPlayDead(); - } - break; - case "Rollover (8 - 16 laff)": - for (int i = 0; i < 2; i++)//attempt trick 2 times incase doodle gets confused - { - openSpeedChat(); - trainRollover(); - } - break; - case "Backflip (9 - 18 laff)": - for (int i = 0; i < 2; i++)//attempt trick 2 times incase doodle gets confused - { - openSpeedChat(); - trainBackflip(); - } - break; - case "Dance (10 - 20 laff)": - for (int i = 0; i < 2; i++)//attempt trick 2 times incase doodle gets confused - { - openSpeedChat(); - trainDance(); - } - break; - case "Speak (11 - 22 laff)": - for (int i = 0; i < 2; i++)//attempt trick 2 times incase doodle gets confused - { - openSpeedChat(); - trainSpeak(); - } - break; - default: - MessageBox.Show("Error!"); - break; - } - } - - public static void openSpeedChat() - { - Thread.Sleep(1000); - //Below is the location for the SpeedChat button location - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("20")) - { - getCoords("20"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(1000); - - //Below is the location for pets tab - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("21")) - { - getCoords("21"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(1000); - - //Below is the location for tricks tab - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("22")) - { - getCoords("22"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(1000); - } - else - { - BotFunctions.manualUpdateCoordinates("22"); - Thread.Sleep(2000); - openSpeedChat(); - } - } - else - { - BotFunctions.manualUpdateCoordinates("21"); - Thread.Sleep(2000); - openSpeedChat(); - } - } - else//means it was (0,0) and needs updated - { - BotFunctions.manualUpdateCoordinates("20"); - Thread.Sleep(2000); - openSpeedChat(); - } - } - - public static void trainBeg() - { - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("24")) - { - getCoords("24"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - else//means it was (0,0) and needs updated - { - BotFunctions.manualUpdateCoordinates("24"); - Thread.Sleep(2000); - trainBeg(); - } - } - - public static void trainPlayDead() - { - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("25")) - { - getCoords("25"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - else//means it was (0,0) and needs updated - { - BotFunctions.manualUpdateCoordinates("25"); - Thread.Sleep(2000); - trainPlayDead(); - } - } - - public static void trainRollover() - { - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("26")) - { - getCoords("26"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - else//means it was (0,0) and needs updated - { - BotFunctions.manualUpdateCoordinates("26"); - Thread.Sleep(2000); - trainRollover(); - } - } - - public static void trainBackflip() - { - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("27")) - { - getCoords("27"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - else//means it was (0,0) and needs updated - { - BotFunctions.manualUpdateCoordinates("27"); - Thread.Sleep(2000); - trainBackflip(); - } - } - - public static void trainDance() - { - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("28")) - { - getCoords("28"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - else//means it was (0,0) and needs updated - { - BotFunctions.manualUpdateCoordinates("28"); - Thread.Sleep(2000); - trainDance(); - } - } - - public static void trainSpeak() - { - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("29")) - { - getCoords("29"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - else//means it was (0,0) and needs updated - { - BotFunctions.manualUpdateCoordinates("29"); - Thread.Sleep(2000); - trainSpeak(); - } - } - - public static void trainJump() - { - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("23")) - { - getCoords("23"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - else//means it was (0,0) and needs updated - { - BotFunctions.manualUpdateCoordinates("23"); - Thread.Sleep(2000); - trainJump(); - } - } - - public static void feedDoodle() - { - //check if coordinates for the button is (0,0). True means they're not (0,0). - if (BotFunctions.checkCoordinates("18")) - { - getCoords("18"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(11500); - } - else//means it was (0,0) and needs updated - { - BotFunctions.manualUpdateCoordinates("18"); - Thread.Sleep(2000); - feedDoodle(); - } - } - - public static void scratchDoodle() - { - if (BotFunctions.checkCoordinates("19")) - { - getCoords("19"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(10000); - } - else - { - BotFunctions.manualUpdateCoordinates("19"); - Thread.Sleep(2000); - scratchDoodle(); - } - } - - private static int x, y; - private static void getCoords(String item) - { - int[] coordinates = BotFunctions.getCoordinates(item); - x = coordinates[0]; - y = coordinates[1]; - } - } -} diff --git a/ToonTown Rewritten Bot/Fishing.cs b/ToonTown Rewritten Bot/Fishing.cs deleted file mode 100644 index 1190cb0c..00000000 --- a/ToonTown Rewritten Bot/Fishing.cs +++ /dev/null @@ -1,521 +0,0 @@ -using System; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Runtime.InteropServices; -using System.Threading; -using System.Windows.Forms; -using WindowsInput; - -namespace ToonTown_Rewritten_Bot -{ - class Fishing : AdvancedSettings - { - /** The random variance of casting the fishing rod (if enabled).*/ - public static int VARIANCE = 20; - private new static int x, y; - private static Random rand = new Random(); - private static string redFishingButtonColor = "#FD0000"; - public static bool shouldStopFishing = false; - - //location, num of casts, num of sells - public static async void startFishing(string location, int numberOfCasts, int numberOfTimesToMeetFisherman, bool randomCasting) - { - if (numberOfTimesToMeetFisherman != 0) - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(3000); - if (!BotFunctions.checkCoordinates("15"))//if they're 0,0, enter. Checks the red fishing button - { - //imgRecLocateRedCastBtn();//use the image rec to locate the image and set the coordinates - - //manuallyLocateRedFishingButton(); - - if (BotFunctions.isAutoDetectFishingBtnActive) - { - //do the image search for color here. Make it so you can use the search or manual set (temp code testing) - Image screenshot = ImageRecognition.GetWindowScreenshot(); - Point coords = await ImageRecognition.locateColorInImage(screenshot, redFishingButtonColor, 10); - - //debugColorCoords(screenshot, coords); - - if (coords.X == 0 && coords.Y == 0)//color not found, manually update - { - MessageBox.Show("Unable to detect red fishing button."); - manuallyLocateRedFishingButton(); - } - else - BotFunctions.manuallyUpdateCoordinatesNoUI("15", coords); - } - else - manuallyLocateRedFishingButton(); - - } - - //start fishing - startFishing(numberOfCasts, randomCasting); - //walking to fisherman - if (!shouldStopFishing) - { - switch (location) - { - case "TOONTOWN CENTRAL PUNCHLINE PLACE": - fishTTCPunchlinePlace();//goes to fisherman and back to dock - startFishing(location, numberOfCasts, numberOfTimesToMeetFisherman - 1, randomCasting); - break; - case "DONALD DREAM LAND LULLABY LANE": - fishDDLLullabyLane(); - startFishing(location, numberOfCasts, numberOfTimesToMeetFisherman - 1, randomCasting); - break; - case "BRRRGH POLAR PLACE": - fishBrrrghPolarPlace(); - startFishing(location, numberOfCasts, numberOfTimesToMeetFisherman - 1, randomCasting); - break; - case "BRRRGH WALRUS WAY": - fishBrrrghWalrusWay(); - startFishing(location, numberOfCasts, numberOfTimesToMeetFisherman - 1, randomCasting); - break; - case "BRRRGH SLEET STREET": - fishBrrrghSleetSt(); - startFishing(location, numberOfCasts, numberOfTimesToMeetFisherman - 1, randomCasting); - break; - case "MINNIE'S MELODYLAND TENOR TERRACE": - fishMMTenorTerrace(); - startFishing(location, numberOfCasts, numberOfTimesToMeetFisherman - 1, randomCasting); - break; - case "DONALD DOCK LIGHTHOUSE LANE": - fishDDLighthouseLane(); - startFishing(location, numberOfCasts, numberOfTimesToMeetFisherman - 1, randomCasting); - break; - case "DAISY'S GARDEN ELM STREET": - fishDaisyGardenElmSt(); - startFishing(location, numberOfCasts, numberOfTimesToMeetFisherman - 1, randomCasting); - break; - case "FISH ANYWHERE": - break; - } - MessageBox.Show("Done!"); - } - } - } - - private static void fishTTCPunchlinePlace() - { - //Go to fisherman - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(2000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); - Thread.Sleep(800); - InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); - Thread.Sleep(700); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - Thread.Sleep(2000); - sellFish();//sell fish - //Go back to dock - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(700); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); - Thread.Sleep(750); - InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); - Thread.Sleep(2000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - } - - private static void fishDDLLullabyLane() - { - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); - Thread.Sleep(4000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - sellFish(); - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(6500); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - } - - private static void fishBrrrghPolarPlace() - { - InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); - Thread.Sleep(800); - InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; - Thread.Sleep(2000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - sellFish(); - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(2000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - } - - private static void fishMMTenorTerrace() - { - InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); - Thread.Sleep(1090); - InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; - Thread.Sleep(2200); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - sellFish(); - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(3000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - } - - private static void fishBrrrghWalrusWay() - { - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; - Thread.Sleep(100); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); - Thread.Sleep(730); - InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; - Thread.Sleep(2000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - sellFish(); - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(2100); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); - Thread.Sleep(700); - InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(1000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - } - - private static void fishBrrrghSleetSt() - { - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(600); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); - Thread.Sleep(850); - InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; - Thread.Sleep(1000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - sellFish(); - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(1700); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); - Thread.Sleep(850); - InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; - Thread.Sleep(600); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - } - - private static void fishDaisyGardenElmSt() - { - InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); - Thread.Sleep(80); - InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; - Thread.Sleep(2000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - sellFish(); - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(4500); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - } - - private static void fishDDLighthouseLane() - { - InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); - Thread.Sleep(330); - InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; - Thread.Sleep(2200); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - sellFish(); - InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); - Thread.Sleep(4500); - InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); - } - - private static void startFishing(int numberOfCasts, bool fishVariance) - { - Stopwatch stopwatch = new Stopwatch(); - while (numberOfCasts != 0 && !shouldStopFishing) - { - castLine(fishVariance); - stopwatch.Start(); - while (stopwatch.Elapsed.Seconds < 30 && !checkIfFishCaught()) - { - checkIfFishCaught(); - } - stopwatch.Stop(); - stopwatch.Reset(); - numberOfCasts--; - Thread.Sleep(1000); - } - if (!shouldStopFishing) // Only call exitFishing() if we didn't break out of the loop - { - exitFishing(); - Thread.Sleep(3000); - } - } - - private static void sellFish() - { - retry: - if (BotFunctions.checkCoordinates("17"))//returns true if they are not 0,0 - { - Thread.Sleep(2100); - getCoords("17"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - } - else - { - BotFunctions.manualUpdateCoordinates("17"); - //imgRecLocateSellBtn(); - goto retry; - } - Thread.Sleep(2000); - } - - private static void exitFishing() - { - retry: - if (BotFunctions.checkCoordinates("16"))//returns true if they are not 0,0 - { - getCoords("16"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - } - else - { - BotFunctions.manualUpdateCoordinates("16"); - //imgRecLocateExitBtn();//use image rec to find the exit fishing button - goto retry; - } - } - - private static void castLine(bool fishVariance) - { - getCoords("15"); - - int randX = 0; - int randY = 0; - if (fishVariance) { - randX = rand.Next(-VARIANCE, VARIANCE+1); - randY = rand.Next(-VARIANCE, VARIANCE+1); - } - BotFunctions.MoveCursor(x + randX, y + randY); - //Debug.WriteLine("X variance: " + randX + " \nY Variance: " + randY); - BotFunctions.DoFishingClick(); - } - - private static bool checkIfFishCaught() - { - bool result = false; - getCoords("15"); - String color = BotFunctions.HexConverter(BotFunctions.GetColorAt(x, y - 600)); - if (color.Equals("#FFFFBE") || color.Equals("#FFFFBF")) - result = true;//fish caught - // Check if boot caught (smaller catch window) - color = BotFunctions.HexConverter(BotFunctions.GetColorAt(x, 110)); - if (color.Equals("#FFFFBE") || color.Equals("#FFFFBF")) - result = true;//fish caught - return result; - } - - private static AdvancedSettings imgRec; - private static void imgRecLocateExitBtn() - { - retry: - imgRec = new AdvancedSettings(); - if (Properties.Settings.Default["exitFishingBtn"].ToString() == "")//no image has been set to the property - { - MessageBox.Show("Exit Fishing Button Image Not Set. Set it in Settings."); - openImageSettingsForm(); - } - else - imgRec.callImageRecScript("exitFishingBtn");//run the script to try to find the imate and update/set them - - //eventually make this a function to use less code, just pass through the numerical value of the coordinate - if (imgRec.message == "")//coordinates were found - { - Point coords = new Point(Convert.ToInt16(imgRec.x), Convert.ToInt16(imgRec.y)); - string x = imgRec.x; - string y = imgRec.y; - string[] lines = File.ReadAllLines(Path.GetFullPath("Coordinates Data File.txt")); - for (int i = 0; i < lines.Length; i++) - { - if (lines[i].Contains(".")) - { - if ("16".Equals(lines[i].Substring(0, lines[i].IndexOf('.'))))//look for the number it cooresponds to - { - lines[i] = "16" + "." + "(" + x + "," + y + ")"; - BotFunctions.updateTextFile(lines);//changes the coordinate values in the data file - } - } - } - } - else//coordinates were not found, try to update them manually instead - { - DialogResult dialogResult = MessageBox.Show(imgRec.message + ". Select Yes to try again or No to update the coordinate manually", imgRec.message, MessageBoxButtons.YesNoCancel); - if (dialogResult == DialogResult.Yes) - { - goto retry; - } - else if (dialogResult == DialogResult.No) - { - BotFunctions.manualUpdateCoordinates("16"); - } - else//cancel - return; - } - } - - private static void imgRecLocateSellBtn() - { - retry: - imgRec = new AdvancedSettings(); - if (Properties.Settings.Default["sellFishBtn"].ToString() == "")//no image has been set to the property - { - MessageBox.Show("Sell Fish Button Image Not Set. Set it in Settings."); - openImageSettingsForm(); - } - else - imgRec.callImageRecScript("sellFishBtn");//run the script to try to find the imate and update/set them - - //eventually make this a function to use less code, just pass through the numerical value of the coordinate - if (imgRec.message == "")//coordinates were found - { - Point coords = new Point(Convert.ToInt16(imgRec.x), Convert.ToInt16(imgRec.y)); - string x = imgRec.x; - string y = imgRec.y; - string[] lines = File.ReadAllLines(Path.GetFullPath("Coordinates Data File.txt")); - for (int i = 0; i < lines.Length; i++) - { - if (lines[i].Contains(".")) - { - if ("17".Equals(lines[i].Substring(0, lines[i].IndexOf('.'))))//look for the number it cooresponds to - { - lines[i] = "17" + "." + "(" + x + "," + y + ")"; - BotFunctions.updateTextFile(lines);//changes the coordinate values in the data file - } - } - } - } - else//coordinates were not found, try to update them manually instead - { - DialogResult dialogResult = MessageBox.Show(imgRec.message + ". Select Yes to try again or No to update the coordinate manually", imgRec.message, MessageBoxButtons.YesNoCancel); - if (dialogResult == DialogResult.Yes) - { - goto retry; - } - else if (dialogResult == DialogResult.No) - { - BotFunctions.manualUpdateCoordinates("17"); - } - else//cancel - return; - } - } - - private static void imgRecLocateRedCastBtn() - { - retry: - imgRec = new AdvancedSettings(); - if (Properties.Settings.Default["fishingCastBtn"].ToString() == "")//no image has been set to the property - { - MessageBox.Show("Red Fishing Button Image Not Set. Set it in Settings."); - openImageSettingsForm(); - } - else - imgRec.callImageRecScript("fishingCastBtn");//run the script to try to find the imate and update/set them - - //eventually make this a function to use less code, just pass through the numerical value of the coordinate - if (imgRec.message == "")//coordinates were found - { - Point coords = new Point(Convert.ToInt16(imgRec.x), Convert.ToInt16(imgRec.y)); - string x = imgRec.x; - string y = imgRec.y; - string[] lines = File.ReadAllLines(Path.GetFullPath("Coordinates Data File.txt")); - for (int i = 0; i < lines.Length; i++) - { - if (lines[i].Contains(".")) - { - if ("15".Equals(lines[i].Substring(0, lines[i].IndexOf('.'))))//look for the number it cooresponds to - { - lines[i] = "15" + "." + "(" + x + "," + y + ")"; - BotFunctions.updateTextFile(lines);//changes the coordinate values in the data file - } - } - } - } - else//coordinates were not found, try to update them manually instead - { - DialogResult dialogResult = MessageBox.Show(imgRec.message + ". Select Yes to try again or No to update the coordinate manually", imgRec.message, MessageBoxButtons.YesNoCancel); - if (dialogResult == DialogResult.Yes) - { - goto retry; - } - else if (dialogResult == DialogResult.No) - { - manuallyLocateRedFishingButton();//manually locate/show the bot where the red fishing button is - } - else//cancel - return; - } - } - - private static void openImageSettingsForm() - { - UpdateImages updateRecImages = new UpdateImages(); - try - { - updateRecImages.ShowDialog(); - } - catch - { - MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); - } - } - - private static void manuallyLocateRedFishingButton() - { - BotFunctions.manualUpdateCoordinates("15");//update the red fishing button coords - } - - private static void getCoords(String item) - { - int[] coordinates = BotFunctions.getCoordinates(item); - x = coordinates[0]; - y = coordinates[1]; - } - - private static void debugColorCoords(Image screenshot, Point coords) - { - // Create a new Bitmap object from the screenshot image - Bitmap bitmap = new Bitmap(screenshot); - - // Create a new Graphics object from the Bitmap object - Graphics graphics = Graphics.FromImage(bitmap); - - // Create a new Pen object for drawing the red square - Pen pen = new Pen(Color.Green, 3); - - // Draw a red square around the point - graphics.DrawRectangle(pen, new Rectangle(coords.X - 10, coords.Y - 10, 20, 20)); - - // Display the image with the red square - using (var form = new Form()) - { - form.StartPosition = FormStartPosition.CenterScreen; - form.ClientSize = new Size(bitmap.Width, bitmap.Height); - form.BackgroundImage = bitmap; - form.BackgroundImageLayout = ImageLayout.Zoom; - form.ShowDialog(); - } - } - } -} diff --git a/ToonTown Rewritten Bot/Form1.cs b/ToonTown Rewritten Bot/Form1.cs deleted file mode 100644 index 04f0149e..00000000 --- a/ToonTown Rewritten Bot/Form1.cs +++ /dev/null @@ -1,484 +0,0 @@ -//using Emgu.CV.XPhoto; -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Threading; -using System.Windows.Forms; -using ToonTown_Rewritten_Bot.Properties; - -namespace ToonTown_Rewritten_Bot -{ - public partial class Form1 : Form - { - public bool fishVariance = false; - - public Form1() - { - //isTTRRunning(); - InitializeComponent(); - BotFunctions.readTextFile(); - createDataFileMap(); - loadCoordsIntoResetBox(); - } - - //important functions for bot - private void startSpamButton_Click(object sender, EventArgs e)//spam message on screen - {//if the user presses ALT key, it will break the loop - bool loopBroken = ToonTown_Rewritten_Bot.Misc.sendMessage(messageToType.Text, Convert.ToInt32(numericUpDown2.Value), checkBox1.Checked, numericUpDown2); - } - - private int timeLeft; - private void keepToonAwakeButton_Click(object sender, EventArgs e)//keep toon - { - timeLeft = Convert.ToInt32(numericUpDown1.Value) * 60; - MessageBox.Show("Press OK when ready to begin!"); - Thread.Sleep(2000); - timer1.Start(); - bool loopBroken = ToonTown_Rewritten_Bot.Misc.keepToonAwake(Convert.ToInt32(numericUpDown1.Value)); - if (loopBroken) - { - timer1.Stop(); - label1.Visible = false; - } - } - - private void button1_Click(object sender, EventArgs e)//open the flower manager - { - Plants plantsForm = new Plants(); - try - { - string selected = (string)comboBox2.SelectedItem; - plantsForm.loadFlowers(selected); - plantsForm.ShowDialog(); - } - catch - { - MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); - } - plantsForm.comboBox1.Items.Clear(); - } - - //misc functions for bot - private void checkBox1_CheckedChanged(object sender, EventArgs e) - { - if (checkBox1.Checked) - numericUpDown2.Visible = true; - else - numericUpDown2.Visible = false; - } - - private void checkBox2_CheckedChanged_1(object sender, EventArgs e) - { - if (checkBox2.Checked) - TopMost = true; - else - TopMost = false; - } - private void isTTRRunning() - { - DialogResult confirmation; - while (!(Process.GetProcessesByName("TTREngine").Length > 0)) - { - confirmation = MessageBox.Show("Press OK once running or Cancel.", "ToonTown Rewritten is not running!", MessageBoxButtons.OKCancel); - if (confirmation.Equals(DialogResult.Cancel)) - Environment.Exit(0); - } - BotFunctions.maximizeAndFocus(); - } - - public static Dictionary dataFileMap = new Dictionary(); - private void createDataFileMap() - { - //Gardening Coords - dataFileMap.Add("1", "Plant Flower/Remove Button"); - dataFileMap.Add("2", "Red Jellybean Button"); - dataFileMap.Add("3", "Green Jellybean Button"); - dataFileMap.Add("4", "Orange Jellybean Button"); - dataFileMap.Add("5", "Purple Jellybean Button"); - dataFileMap.Add("6", "Blue Jellybean Button"); - dataFileMap.Add("7", "Pink Jellybean Button"); - dataFileMap.Add("8", "Yellow Jellybean Button"); - dataFileMap.Add("9", "Cyan Jellybean Button"); - dataFileMap.Add("10", "Silver Jellybean Button"); - dataFileMap.Add("11", "Blue Plant Button"); - dataFileMap.Add("12", "Blue Ok Button"); - dataFileMap.Add("13", "Watering Can Button"); - dataFileMap.Add("14", "Blue Yes Button"); - //Fishing Coords - dataFileMap.Add("15", "Red Fishing Button"); - dataFileMap.Add("16", "Exit Fishing Button"); - dataFileMap.Add("17", "Blue Sell All Button"); - //Racing Coords - //Doodle Training Coords - dataFileMap.Add("18", "Feed Doodle Button"); - dataFileMap.Add("19", "Scratch Doodle Button"); - dataFileMap.Add("20", "Green SpeedChat Button"); - dataFileMap.Add("21", "Pets Tab in SpeedChat"); - dataFileMap.Add("22", "Tricks Tab in SpeedChat"); - dataFileMap.Add("23", "Jump Trick Option in SpeedChat"); - dataFileMap.Add("24", "Beg Trick Option in SpeedChat"); - dataFileMap.Add("25", "Play Dead Trick Option in SpeedChat"); - dataFileMap.Add("26", "Rollover Trick Option in SpeedChat"); - dataFileMap.Add("27", "Backflip Trick Option in SpeedChat"); - dataFileMap.Add("28", "Dance Trick Option in SpeedChat"); - dataFileMap.Add("29", "Speak Trick Option in SpeedChat"); - - } - - /*private void button4_Click(object sender, EventArgs e) - { - //Thread.Sleep(4000); - //textBox1.Text = BotFunctions.HexConverter(BotFunctions.GetColorAt(BotFunctions.getCursorLocation().X, BotFunctions.getCursorLocation().Y)); - }*/ - - private void timer1_Tick(object sender, EventArgs e) - { - label1.Visible = true; - if (timeLeft > 0) - { - timeLeft = timeLeft - 1; - label1.Text = timeLeft + " seconds"; - } - else - { - timer1.Stop(); - label1.Visible = false; - } - } - - private void button2_Click(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Gardening.waterPlant(); - } - - private void button3_Click(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Gardening.removePlant(); - } - - private void button7_Click(object sender, EventArgs e) - { - BotFunctions.createFreshCoordinatesFile(); - MessageBox.Show("All coordinates reset!"); - } - - private void loadCoordsIntoResetBox() - { - comboBox1.Items.Clear(); - words = new String[dataFileMap.Count]; - for (int i = 0; i < dataFileMap.Count; i++) - { - words[i] = dataFileMap[Convert.ToString(i + 1)]; - } - comboBox1.Items.AddRange(words); - } - - private static String[] words; - private void button6_Click(object sender, EventArgs e) - { - string selected = (string)comboBox1.SelectedItem; - try - { - for (int i = 0; i < words.Length; i++) - { - if (words[i].Equals(selected)) - BotFunctions.manualUpdateCoordinates(Convert.ToString(i + 1)); - } - } - catch - { - MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); - } - MessageBox.Show("Coordinate's updated for " + selected); - } - - private void startFishing_Click(object sender, EventArgs e)//button to start fishing - { - string selected = (string)comboBox3.SelectedItem;//fishing location - int numberOfCasts = Convert.ToInt32(numericUpDown3.Value);//number of casts - int numberOfSells = Convert.ToInt32(numericUpDown4.Value);//number of sells - BotFunctions.tellFishingLocation(selected);//tell the bot what location were fishing at to provide instructions - MessageBox.Show("Make sure you're in the fishing dock before pressing OK!"); - startFishingThread(selected, numberOfCasts, numberOfSells, false);//begin fishing - } - - private void randomFishing_CheckedChanged(object sender, EventArgs e) - { - if (randomFishing.Checked) - { - MessageBox.Show("This will add randomness to the line casting!"); - fishVariance = true; - } - else - { - fishVariance = false; - } - } - - Thread fishingThreading; - public void startFishingThread(string selected, int numberOfCasts, int numberOfSells, bool stopCheck)//fishing location, num of casts, num of sells, check if the user clicked stop button - { - if (!stopCheck) - { - fishingThreading = new Thread(() => ToonTown_Rewritten_Bot.Fishing.startFishing(selected, numberOfCasts, numberOfSells, fishVariance)); - fishingThreading.Start(); - } - } - - private void button4_Click(object sender, EventArgs e)//button to stop fishing - { - ToonTown_Rewritten_Bot.Fishing.shouldStopFishing = true; - MessageBox.Show("Fishing stopped!"); - } - - private void smartFishing_CheckedChanged(object sender, EventArgs e) - { - if (smartFishing.Checked) - BotFunctions.isAutoDetectFishingBtnActive = true; - else - BotFunctions.isAutoDetectFishingBtnActive = false; - } - - private async void button5_Click(object sender, EventArgs e)//racing test - { - MessageBox.Show("Press OK when ready to begin!"); - Thread.Sleep(5000); - Point test = BotFunctions.getCursorLocation(); - BotFunctions.GetColorAt(test.X, test.Y); - string hexColor = BotFunctions.HexConverter(BotFunctions.GetColorAt(test.X, test.Y)); - //Debug.WriteLine("HEX: " + BotFunctions.HexConverter(BotFunctions.GetColorAt(test.X, test.Y)) + " RGB: " + BotFunctions.GetColorAt(test.X, test.Y)); - Debug.WriteLine("HEX: " + BotFunctions.HexConverter(BotFunctions.GetColorAt(test.X, test.Y)) + " RGB: " + BotFunctions.GetColorAt(test.X, test.Y)); - MessageBox.Show("Done"); - - BotFunctions.maximizeAndFocus(); - - Image screenshot = ImageRecognition.GetWindowScreenshot(); - /*PictureBox pictureBox = new PictureBox(); - pictureBox.Image = screenshot; - pictureBox.SizeMode = PictureBoxSizeMode.AutoSize;*/ - - string redFishingButton = "#FD0000"; - string fishingExitButton = "#E6A951"; - - await ImageRecognition.locateColorInImage(screenshot, redFishingButton, 10); - - // Set the size of the form to the size of the image - /*Form form = new Form(); - form.ClientSize = screenshot.Size; - form.Controls.Add(pictureBox); - form.ShowDialog();*/ - - - /*BotFunctions.DoMouseClick(); - ToonTown_Rewritten_Bot.Racing.startRacing(); - - Rectangle bounds = Screen.GetWorkingArea(Point.Empty); - using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height)) - { - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size); - } - int x = 950; - int y = 755; - while (y <= 780 && x <= 970) - { - richTextBox1.AppendText(BotFunctions.HexConverter(bitmap.GetPixel(x, y)) + "\n"); - x++; - y++; - } - }*/ - } - - private void button8_Click(object sender, EventArgs e) - { - AboutBox1 aboutBox = new AboutBox1(); - try - { - aboutBox.ShowDialog(); - } - catch - { - MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); - } - } - - private void button9_Click(object sender, EventArgs e) - { - Help helpBox = new Help(); - try - { - helpBox.ShowDialog(); - } - catch - { - MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); - } - } - - // GOLF- Afternoon Tee - private void golfAfternoonTee(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.afternoonTee(); - } - - // GOLF - Holey Mackeral - private void golfHoleyMackeral(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.holeyMackeral(); - } - - // GOLF - Hole on the Range - private void golfHoleOnTheRange(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.holeOnTheRange(); - } - - // GOLF - Seeing green - private void golfSeeingGreen(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.seeingGreen(); - } - - // GOLF - Swing Time - private void button15_Click(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.swingTime(); - } - - // GOLF - Down the Hatch - private void button14_Click(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.downTheHatch(); - } - - //GOLF - Peanut Putter - private void button13_Click(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.peanutPutter(); - } - - //GOLF - Hot Links - private void button16_Click(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.hotLinks(); - } - - //GOLF - Hole In Fun - private void button17_Click(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.holeInFun(); - } - - //GOLF - Swing-A-Long - private void button18_Click(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.swingALong(); - } - - //GOLF - One Little Birdie - private void One_Little_Birdie_Click(object sender, EventArgs e) - { - ToonTown_Rewritten_Bot.Golf.oneLittleBirdie(); - } - - private void checkBox3_CheckedChanged(object sender, EventArgs e) - { - if (checkBox3.Checked) - { - numericUpDown5.Enabled = false; - numericUpDown6.Enabled = false; - } - else - { - numericUpDown5.Enabled = true; - numericUpDown6.Enabled = true; - } - } - - private void button20_Click(object sender, EventArgs e) - { - string selected = (string)comboBox4.SelectedItem; - startDoodleTrainingThread(Convert.ToInt32(numericUpDown6.Value), Convert.ToInt32(numericUpDown5.Value), checkBox3.Checked, false, selected); - } - - Thread doodleTrainingThreading; - public void startDoodleTrainingThread(int numberOfFeeds, int numberOfScratches, bool checkBoxChecked, bool stopTrainingClicked, string selectedTrick) - { - if (!stopTrainingClicked) - { - doodleTrainingThreading = new Thread(() => DoodleTraining.startTrainingDoodle(numberOfFeeds, numberOfScratches, checkBox3.Checked, selectedTrick, checkBox4.Checked, checkBox5.Checked)); - doodleTrainingThreading.Start(); - } - } - - private void button19_Click(object sender, EventArgs e) - { - DoodleTraining.shouldStopTraining = true; - MessageBox.Show("Doodle Training stopped!"); - } - - private void checkBox4_CheckedChanged(object sender, EventArgs e) - { - if (checkBox4.Checked) - { - numericUpDown5.Enabled = false; - checkBox5.Checked = false; - } - else - { - numericUpDown5.Enabled = true; - if (checkBox3.Checked) - { - numericUpDown6.Enabled = false; - numericUpDown5.Enabled = false; - } - } - } - - private void checkBox5_CheckedChanged(object sender, EventArgs e) - { - if (checkBox5.Checked) - { - numericUpDown6.Enabled = false; - checkBox4.Checked = false; - } - else - { - numericUpDown6.Enabled = true; - if (checkBox3.Checked) - { - numericUpDown6.Enabled = false; - numericUpDown5.Enabled = false; - } - } - } - - //Settings page, button to open update images setting - private void updateImagesBtn_Click(object sender, EventArgs e) - { - UpdateImages updateRecImages = new UpdateImages(); - try - { - updateRecImages.ShowDialog(); - } - catch - { - MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); - } - } - - //Settings page, button to reset all images - private void resetImagesBtn_Click(object sender, EventArgs e) - { - foreach (SettingsProperty currentProperty in Properties.Settings.Default.Properties) - { - Properties.Settings.Default[currentProperty.Name] = ""; - } - Properties.Settings.Default.Save(); - } - } -} diff --git a/ToonTown Rewritten Bot/Gardening.cs b/ToonTown Rewritten Bot/Gardening.cs deleted file mode 100644 index 9349100c..00000000 --- a/ToonTown Rewritten Bot/Gardening.cs +++ /dev/null @@ -1,193 +0,0 @@ -using System; -using System.Threading; -using System.Windows.Forms; - -namespace ToonTown_Rewritten_Bot -{ - class Gardening - { - private static int x, y; - public static void plantFlower(String flowerCombo) - { - DialogResult confirmation; - //check if plant button is (0,0). True means continue, not (0,0) - if (BotFunctions.checkCoordinates("1")) - { - confirmation = MessageBox.Show("Press OK when ready to begin!","", MessageBoxButtons.OKCancel); - if (confirmation.Equals(DialogResult.Cancel)) - return; - Thread.Sleep(2000); - getCoords("1"); - BotFunctions.MoveCursor(x,y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - checkBeans("2"); - - char[] beans = flowerCombo.ToCharArray(); - selectBeans(flowerCombo, beans); - pressPlantButton(); - Thread.Sleep(1500); - MessageBox.Show("Done!"); - } - else - { - BotFunctions.manualUpdateCoordinates("1");//update the plant flower button coords - plantFlower(flowerCombo); - Thread.Sleep(2000); - } - } - - private static void selectBeans(String flowerCombo, char[] beans) - { - for (int i = 0; i < flowerCombo.Length; i++) - { - switch (beans[i]) - { - case 'r': - getCoords("2"); - break; - case 'g': - getCoords("3"); - break; - case 'o': - getCoords("4"); - break; - case 'u': - getCoords("5"); - break; - case 'b': - getCoords("6"); - break; - case 'i': - getCoords("7"); - break; - case 'y': - getCoords("8"); - break; - case 'c': - getCoords("9"); - break; - case 's': - getCoords("10"); - break; - } - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - } - - private static void checkBeans(String location) - { - if (Convert.ToInt32(location) <= 10) - { - if (!BotFunctions.checkCoordinates(location))//if they're 0,0 - { - BotFunctions.manualUpdateCoordinates(location); - checkBeans(Convert.ToString(Convert.ToInt32(location) + 1)); - } - else - checkBeans(Convert.ToString(Convert.ToInt32(location) + 1)); - } - } - - private static void pressPlantButton() - { - if (BotFunctions.checkCoordinates("11")) - { - getCoords("11"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(8000); - clickOKAfterPlant(); - waterPlant(); - } - else - { - BotFunctions.manualUpdateCoordinates("11"); - Thread.Sleep(2000); - pressPlantButton(); - } - } - - private static void clickOKAfterPlant() - { - if (BotFunctions.checkCoordinates("12")) - { - getCoords("12"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - else - { - BotFunctions.manualUpdateCoordinates("12"); - Thread.Sleep(2000); - clickOKAfterPlant(); - } - } - - public static void waterPlant() - { - if (BotFunctions.checkCoordinates("13")) - { - getCoords("13"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(4000); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - Thread.Sleep(2000); - } - else - { - BotFunctions.manualUpdateCoordinates("13"); - Thread.Sleep(2000); - waterPlant(); - } - } - - public static void removePlant() - { - if (BotFunctions.checkCoordinates("1")) - { - getCoords("1"); - MessageBox.Show("Press OK when ready to begin!"); - Thread.Sleep(2000); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - selectYESToRemove(); - } - else - { - BotFunctions.manualUpdateCoordinates("1");//update the plant flower button coords - removePlant(); - Thread.Sleep(2000); - } - - } - - private static void selectYESToRemove() - { - if (BotFunctions.checkCoordinates("14")) - { - getCoords("14"); - BotFunctions.MoveCursor(x, y); - BotFunctions.DoMouseClick(); - } - else - { - BotFunctions.manualUpdateCoordinates("14");//update the plant flower button coords - selectYESToRemove(); - Thread.Sleep(2000); - } - } - - private static void getCoords(String item) - { - int[] coordinates = BotFunctions.getCoordinates(item); - x = coordinates[0]; - y = coordinates[1]; - } - } -} diff --git a/ToonTown Rewritten Bot/Golf.cs b/ToonTown Rewritten Bot/Golf.cs deleted file mode 100644 index 2ab0aabc..00000000 --- a/ToonTown Rewritten Bot/Golf.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System.Diagnostics; -using System.Threading; -using System.Windows.Forms; -using WindowsInput; - -namespace ToonTown_Rewritten_Bot -{ - class Golf - { - // GOLF- Afternoon Tee - public static void afternoonTee()//works, finished - { - Debug.WriteLine("1"); - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - Debug.WriteLine("2"); - toonLookAtHole(); - Thread.Sleep(3000); - Debug.WriteLine("3"); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(2120); - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - Debug.WriteLine("4"); - } - - // GOLF - Holey Mackeral - public static void holeyMackeral()//works, finished - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - toonLookAtHole(); - Thread.Sleep(3000); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(1000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - // GOLF - Hole on the Range - public static void holeOnTheRange()//needs fixed? Not sure - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - toonLookAtHole(); - Thread.Sleep(3000); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(1800); // 68% - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - // GOLF - Seeing green - public static void seeingGreen()//works, finished - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - toonLookAtHole(); - Thread.Sleep(3000); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(1790); // 67% - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - // GOLF - Swing Time - public static void swingTime()//yellow, needs fixed (move to the right?) - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(100); - //move toon to the right location - InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); - Thread.Sleep(50); - InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); - Thread.Sleep(100); - Thread.Sleep(15000); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(2000); - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - // GOLF - Down the Hatch - public static void downTheHatch()//yellow, needs fixed - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(2340); - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - //GOLF - Peanut Putter - public static void peanutPutter() - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - toonLookAtHole(); - Thread.Sleep(3000); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(1860); // 69-70% ? - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - //GOLF - Hot Links - public static void hotLinks() - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - toonLookAtHole(); - Thread.Sleep(3000); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(1800); // 67% - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - //GOLF - Hole In Fun - public static void holeInFun() - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - toonLookAtHole(); - Thread.Sleep(3000); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(1300);// 52% - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - //GOLF - Swing-A-Long - public static void swingALong() - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(2340);// 82% - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - public static void oneLittleBirdie() - { - BotFunctions.maximizeAndFocus(); - Thread.Sleep(15000); - //rotate the toon right - InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); - Thread.Sleep(700); - InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(1870); // 69-70% ? - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - private static void confirmLocation() - { - InputSimulator.SimulateKeyDown(VirtualKeyCode.CONTROL); - Thread.Sleep(50); - InputSimulator.SimulateKeyUp(VirtualKeyCode.CONTROL); - } - - private static void toonLookAtHole()//this is just to stop the timer - { - InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); - Thread.Sleep(50); - InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); - } - } -} diff --git a/ToonTown Rewritten Bot/Help.Designer.cs b/ToonTown Rewritten Bot/Help.Designer.cs deleted file mode 100644 index 69075a01..00000000 --- a/ToonTown Rewritten Bot/Help.Designer.cs +++ /dev/null @@ -1,134 +0,0 @@ -namespace ToonTown_Rewritten_Bot -{ - partial class Help - { - /// - /// 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(Help)); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.label1 = new System.Windows.Forms.Label(); - this.richTextBox1 = new System.Windows.Forms.RichTextBox(); - this.groupBox2 = new System.Windows.Forms.GroupBox(); - this.label2 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.groupBox1.SuspendLayout(); - this.groupBox2.SuspendLayout(); - this.SuspendLayout(); - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.label1); - this.groupBox1.Controls.Add(this.richTextBox1); - this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.groupBox1.Location = new System.Drawing.Point(16, 15); - this.groupBox1.Margin = new System.Windows.Forms.Padding(4); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Padding = new System.Windows.Forms.Padding(4); - this.groupBox1.Size = new System.Drawing.Size(393, 213); - this.groupBox1.TabIndex = 0; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Coordinates Updater Info"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(7, 157); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(299, 48); - this.label1.TabIndex = 1; - this.label1.Text = "Notice: You will only have to teach the bot once \r\n(first time loading the progra" + - "m on PC), unless you \r\nreset your coordinates!\r\n"; - // - // richTextBox1 - // - this.richTextBox1.Location = new System.Drawing.Point(8, 26); - this.richTextBox1.Margin = new System.Windows.Forms.Padding(4); - this.richTextBox1.Name = "richTextBox1"; - this.richTextBox1.Size = new System.Drawing.Size(376, 127); - this.richTextBox1.TabIndex = 0; - this.richTextBox1.Text = resources.GetString("richTextBox1.Text"); - // - // groupBox2 - // - this.groupBox2.Controls.Add(this.label3); - this.groupBox2.Controls.Add(this.label2); - this.groupBox2.Location = new System.Drawing.Point(12, 235); - this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(396, 58); - this.groupBox2.TabIndex = 1; - this.groupBox2.TabStop = false; - this.groupBox2.Text = "Contact Info"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(11, 18); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(138, 16); - this.label2.TabIndex = 0; - this.label2.Text = "Skype: drprimetime43"; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(172, 18); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(169, 16); - this.label3.TabIndex = 1; - this.label3.Text = "Discord: primetime43#2909"; - // - // Help - // - this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(429, 305); - this.Controls.Add(this.groupBox2); - this.Controls.Add(this.groupBox1); - this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Margin = new System.Windows.Forms.Padding(4); - this.Name = "Help"; - this.Text = "Help Infomation"; - this.groupBox1.ResumeLayout(false); - this.groupBox1.PerformLayout(); - this.groupBox2.ResumeLayout(false); - this.groupBox2.PerformLayout(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.GroupBox groupBox1; - private System.Windows.Forms.RichTextBox richTextBox1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.GroupBox groupBox2; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label label3; - } -} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Help.cs b/ToonTown Rewritten Bot/Help.cs deleted file mode 100644 index 716e7033..00000000 --- a/ToonTown Rewritten Bot/Help.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Windows.Forms; - -namespace ToonTown_Rewritten_Bot -{ - public partial class Help : Form - { - public Help() - { - InitializeComponent(); - } - } -} diff --git a/ToonTown Rewritten Bot/Misc.cs b/ToonTown Rewritten Bot/Misc.cs deleted file mode 100644 index c7d29d04..00000000 --- a/ToonTown Rewritten Bot/Misc.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using WindowsInput; -using System.Threading; -using System.Windows.Forms; - -namespace ToonTown_Rewritten_Bot -{ - class Misc - { - public static Boolean sendMessage(String message, int spamCount, bool spam, NumericUpDown upDown) - { - DialogResult confirmation; - Console.WriteLine("Spam? : " + spam); - if (!message.Equals("")) - { - confirmation = MessageBox.Show("Send Message?", "Continue...", MessageBoxButtons.YesNo); - if (confirmation.Equals(DialogResult.Yes)) - { - if (spam && spamCount > 1)//spam checkbox check - { - while (spamCount >= 1) - { - if (Control.ModifierKeys == Keys.Alt)//break out of loop - { - upDown.Value = 1; - return true; - } - send(message); - spamCount--; - if (spamCount != 0) - upDown.Value = spamCount; - } - } - else if (!spam || spamCount == 1) - send(message); - } - else if (confirmation.Equals(DialogResult.No) || confirmation.Equals(DialogResult.Cancel)) - return false; - } - else - MessageBox.Show("You must enter a message to send!"); - return false; - } - private static void send(String text) - { - BotFunctions.DoMouseClick(); - Thread.Sleep(500); - InputSimulator.SimulateTextEntry(text); - Thread.Sleep(500); - SendKeys.SendWait("{ENTER}"); - } - - public static Boolean keepToonAwake(int min) - { - DateTime endTime = DateTime.Now.AddMinutes(min); - BotFunctions.DoMouseClick(); - while (endTime > DateTime.Now) - { - SendKeys.SendWait("^"); - if (Control.ModifierKeys == Keys.Alt)//break out of loop - return true; - } - return false; - } - } -} diff --git a/ToonTown Rewritten Bot/Models/Coordinates.cs b/ToonTown Rewritten Bot/Models/Coordinates.cs new file mode 100644 index 00000000..75cf836b --- /dev/null +++ b/ToonTown Rewritten Bot/Models/Coordinates.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static ToonTown_Rewritten_Bot.Models.Coordinates; + +namespace ToonTown_Rewritten_Bot.Models +{ + /// + /// Represents actions associated with coordinates in the UI, such as button locations. + /// + public class CoordinateActions : ICoordinateData + { + public string Key { get; set; } + public string Description { get; set; } + public int X { get; set; } + public int Y { get; set; } + + private static readonly Dictionary _actionDescriptionMap = new Dictionary(); + + /// + /// Static constructor to initialize the action description map. + /// + static CoordinateActions() + { + CreateActionDescriptionMap(); + } + + /// + /// Initializes the description map with keys and corresponding descriptions. + /// This map is what is used when creating the default UIElementCoordinates.json file + /// + private static void CreateActionDescriptionMap() + { + // Gardening Actions + _actionDescriptionMap.Add("1", "Plant Flower/Remove Button"); + _actionDescriptionMap.Add("2", "Red Jellybean Button"); + _actionDescriptionMap.Add("3", "Green Jellybean Button"); + _actionDescriptionMap.Add("4", "Orange Jellybean Button"); + _actionDescriptionMap.Add("5", "Purple Jellybean Button"); + _actionDescriptionMap.Add("6", "Blue Jellybean Button"); + _actionDescriptionMap.Add("7", "Pink Jellybean Button"); + _actionDescriptionMap.Add("8", "Yellow Jellybean Button"); + _actionDescriptionMap.Add("9", "Cyan Jellybean Button"); + _actionDescriptionMap.Add("10", "Silver Jellybean Button"); + _actionDescriptionMap.Add("11", "Blue Plant Button"); + _actionDescriptionMap.Add("12", "Blue Ok Button"); + _actionDescriptionMap.Add("13", "Watering Can Button"); + _actionDescriptionMap.Add("14", "Blue Yes Button"); + + // Fishing Actions + _actionDescriptionMap.Add("15", "Red Fishing Button"); + _actionDescriptionMap.Add("16", "Exit Fishing Button"); + _actionDescriptionMap.Add("17", "Blue Sell All Button"); + + // Doodle Training Actions + _actionDescriptionMap.Add("18", "Feed Doodle Button"); + _actionDescriptionMap.Add("19", "Scratch Doodle Button"); + _actionDescriptionMap.Add("20", "Green SpeedChat Button"); + _actionDescriptionMap.Add("21", "Pets Tab in SpeedChat"); + _actionDescriptionMap.Add("22", "Tricks Tab in SpeedChat"); + _actionDescriptionMap.Add("23", "Jump Trick Option in SpeedChat"); + _actionDescriptionMap.Add("24", "Beg Trick Option in SpeedChat"); + _actionDescriptionMap.Add("25", "Play Dead Trick Option in SpeedChat"); + _actionDescriptionMap.Add("26", "Rollover Trick Option in SpeedChat"); + _actionDescriptionMap.Add("27", "Backflip Trick Option in SpeedChat"); + _actionDescriptionMap.Add("28", "Dance Trick Option in SpeedChat"); + _actionDescriptionMap.Add("29", "Speak Trick Option in SpeedChat"); + } + + /// + /// Retrieves the description for a given key. + /// + /// The key whose description is to be retrieved. + /// The description if found; otherwise, null. + public static string GetDescription(string key) + { + if (_actionDescriptionMap.TryGetValue(key, out var description)) + { + return description; + } + + return null; // Or throw an exception, depending on your needs + } + + /// + /// Provides access to the complete plantComboDictionary of action descriptions. + /// + /// A plantComboDictionary of all descriptions mapped by their keys. + public static Dictionary GetAllDescriptions() => _actionDescriptionMap; + + /// + /// Finds the key for a given description. + /// + /// The description to find the key for. + /// The key if found; otherwise, null. + public static string GetKeyFromDescription(string description) + { + // Iterate over the key-value pairs in the map + foreach (var pair in _actionDescriptionMap) + { + // Check if the value matches the provided description + if (pair.Value == description) + { + return pair.Key; // Return the key that matches the description + } + } + + return null; // Return null if no match is found + } + } + + public class Coordinates + { + public enum GardeningCoordinatesEnum + { + PlantFlowerRemoveButton = 1, + RedJellybeanButton, + GreenJellybeanButton, + OrangeJellybeanButton, + PurpleJellybeanButton, + BlueJellybeanButton, + PinkJellybeanButton, + YellowJellybeanButton, + CyanJellybeanButton, + SilverJellybeanButton, + BluePlantButton, + BlueOkButton, + WateringCanButton, + BlueYesButton + } + + public enum FishingCoordinatesEnum + { + RedFishingButton = 15, + ExitFishingButton, + BlueSellAllButton + } + + public enum DoodleTrainingCoordinatesEnum + { + FeedDoodleButton = 18, + ScratchDoodleButton, + GreenSpeedChatButton, + PetsTabInSpeedChat, + TricksTabInSpeedChat, + JumpTrickOptionInSpeedChat, + BegTrickOptionInSpeedChat, + PlayDeadTrickOptionInSpeedChat, + RolloverTrickOptionInSpeedChat, + BackflipTrickOptionInSpeedChat, + DanceTrickOptionInSpeedChat, + SpeakTrickOptionInSpeedChat + } + } + + public static class FishingLocationMessages + { + private static readonly Dictionary _locationMessageMap = new Dictionary + { + ["TOONTOWN CENTRAL PUNCHLINE PLACE"] = "Fishes in the first dock when you walk in", + ["DONALD DREAM LAND LULLABY LANE"] = "Fishes in the dock to the left of the small box", + ["BRRRGH POLAR PLACE"] = "Fishes in the top right dock", + ["BRRRGH WALRUS WAY"] = "Fishes in the top left dock", + ["BRRRGH SLEET STREET"] = "Fishes in the first dock when you walk in", + ["MINNIE'S MELODYLAND TENOR TERRACE"] = "Fishes in the top left dock", + ["DONALD DOCK LIGHTHOUSE LANE"] = "Fishes in the middle right dock (middle right)", + ["DAISY'S GARDEN ELM STREET"] = "Fishes in the bottom left dock when you walk in", + ["FISH ANYWHERE"] = "Fishes for you anywhere, but will only fish, will not sell fish!", + ["CUSTOM FISHING ACTION"] = "Select your custom fishing actions in the dropdown" + }; + + public static void TellFishingLocation(string location) + { + if (_locationMessageMap.TryGetValue(location, out var message)) + { + MessageBox.Show(message); + } + else + { + MessageBox.Show("Location not found."); + } + } + + public static string GetLocationMessage(string location) + { + if (_locationMessageMap.TryGetValue(location, out var message)) + { + return message; + } + else + { + return "Location not found."; // You could also return null or throw an exception depending on your requirements + } + } + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Models/FishingActionKeys.cs b/ToonTown Rewritten Bot/Models/FishingActionKeys.cs new file mode 100644 index 00000000..9f24b530 --- /dev/null +++ b/ToonTown Rewritten Bot/Models/FishingActionKeys.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; + +namespace ToonTown_Rewritten_Bot.Models +{ + public class FishingActionKeys + { + // Property to hold the mapping + public Dictionary ActionKeyMap { get; private set; } + + // Constructor to initialize the mapping + public FishingActionKeys() + { + ActionKeyMap = new Dictionary + { + {"WALK FORWARDS", "UP"}, + {"WALK BACKWARDS", "DOWN"}, + {"TURN LEFT", "LEFT"}, + {"TURN RIGHT", "RIGHT"}, + {"SELL FISH", "SELL"}, + }; + } + + // Method to get the VirtualKeyCode string representation by action name + public string GetKeyCodeString(string action) + { + if (ActionKeyMap.TryGetValue(action, out var keyCodeString)) + { + return keyCodeString; + } + else + { + return null; // or throw an exception, depending on your error handling preference + } + } + } + + public class FishingActionCommand + { + public string Action { get; set; } + public string Command { get; set; } + } + +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Models/FishingLocationNames.cs b/ToonTown Rewritten Bot/Models/FishingLocationNames.cs new file mode 100644 index 00000000..a055daf5 --- /dev/null +++ b/ToonTown Rewritten Bot/Models/FishingLocationNames.cs @@ -0,0 +1,16 @@ +namespace ToonTown_Rewritten_Bot.Models +{ + public static class FishingLocationNames + { + public static readonly string ToontownCentralPunchlinePlace = "TOONTOWN CENTRAL PUNCHLINE PLACE"; + public static readonly string DonaldDreamLandLullabyLane = "DONALD DREAM LAND LULLABY LANE"; + public static readonly string BrrrghPolarPlace = "BRRRGH POLAR PLACE"; + public static readonly string BrrrghWalrusWay = "BRRRGH WALRUS WAY"; + public static readonly string BrrrghSleetStreet = "BRRRGH SLEET STREET"; + public static readonly string MinniesMelodylandTenorTerrace = "MINNIE'S MELODYLAND TENOR TERRACE"; + public static readonly string DonaldDockLighthouseLane = "DONALD DOCK LIGHTHOUSE LANE"; + public static readonly string DaisysGardenElmStreet = "DAISY'S GARDEN ELM STREET"; + public static readonly string FishAnywhere = "FISH ANYWHERE"; + public static readonly string CustomFishingAction = "CUSTOM FISHING ACTION"; + } +} diff --git a/ToonTown Rewritten Bot/Models/GolfActionKeys.cs b/ToonTown Rewritten Bot/Models/GolfActionKeys.cs new file mode 100644 index 00000000..28d1b27c --- /dev/null +++ b/ToonTown Rewritten Bot/Models/GolfActionKeys.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Models +{ + public class GolfActionCommand + { + public string Action { get; set; } + public string Command { get; set; } + public int Duration { get; set; } // Duration in milliseconds + } + + public class GolfActionKeys + { + public Dictionary ActionKeyMap { get; private set; } + + public GolfActionKeys() + { + ActionKeyMap = new Dictionary + { + {"SWING POWER", VirtualKeyCode.CONTROL}, + {"TURN LEFT", VirtualKeyCode.LEFT}, + {"TURN RIGHT", VirtualKeyCode.RIGHT}, + {"MOVE TO LEFT TEE SPOT", VirtualKeyCode.LEFT}, + {"MOVE TO RIGHT TEE SPOT", VirtualKeyCode.RIGHT}, + }; + } + + // This method might throw an exception if the action is not found, consider using TryGetValue instead in your logic if you want to avoid exceptions. + public VirtualKeyCode GetKeyCode(string action) + { + if (ActionKeyMap.TryGetValue(action, out var keyCode)) + { + return keyCode; + } + else + { + throw new KeyNotFoundException($"No key code found for action: {action}"); + } + } + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Models/ICoordinateData.cs b/ToonTown Rewritten Bot/Models/ICoordinateData.cs new file mode 100644 index 00000000..50468331 --- /dev/null +++ b/ToonTown Rewritten Bot/Models/ICoordinateData.cs @@ -0,0 +1,28 @@ +namespace ToonTown_Rewritten_Bot.Models +{ + /// + /// Provides a contract for coordinate data, including keys, descriptions, and positions. + /// + public interface ICoordinateData + { + /// + /// Gets or sets the key associated with the coordinate data. + /// + string Key { get; set; } + + /// + /// Gets or sets the description of the coordinate data. + /// + string Description { get; set; } + + /// + /// Gets or sets the X-coordinate. + /// + int X { get; set; } + + /// + /// Gets or sets the Y-coordinate. + /// + int Y { get; set; } + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Plants.Designer.cs b/ToonTown Rewritten Bot/Plants.Designer.cs deleted file mode 100644 index f681b542..00000000 --- a/ToonTown Rewritten Bot/Plants.Designer.cs +++ /dev/null @@ -1,194 +0,0 @@ -namespace ToonTown_Rewritten_Bot -{ - partial class Plants - { - /// - /// 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(Plants)); - this.comboBox1 = new System.Windows.Forms.ComboBox(); - this.label1 = new System.Windows.Forms.Label(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.pictureBox2 = new System.Windows.Forms.PictureBox(); - this.pictureBox3 = new System.Windows.Forms.PictureBox(); - this.pictureBox4 = new System.Windows.Forms.PictureBox(); - this.pictureBox5 = new System.Windows.Forms.PictureBox(); - this.pictureBox6 = new System.Windows.Forms.PictureBox(); - this.pictureBox7 = new System.Windows.Forms.PictureBox(); - this.pictureBox8 = new System.Windows.Forms.PictureBox(); - this.button1 = new System.Windows.Forms.Button(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox5)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox6)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox7)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox8)).BeginInit(); - this.SuspendLayout(); - // - // comboBox1 - // - this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.comboBox1.FormattingEnabled = true; - this.comboBox1.Location = new System.Drawing.Point(63, 49); - this.comboBox1.Name = "comboBox1"; - this.comboBox1.Size = new System.Drawing.Size(261, 28); - this.comboBox1.TabIndex = 0; - this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(126, 9); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(70, 25); - this.label1.TabIndex = 1; - this.label1.Text = "label1"; - // - // pictureBox1 - // - this.pictureBox1.Location = new System.Drawing.Point(14, 123); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(40, 67); - this.pictureBox1.TabIndex = 2; - this.pictureBox1.TabStop = false; - // - // pictureBox2 - // - this.pictureBox2.Location = new System.Drawing.Point(60, 123); - this.pictureBox2.Name = "pictureBox2"; - this.pictureBox2.Size = new System.Drawing.Size(40, 67); - this.pictureBox2.TabIndex = 3; - this.pictureBox2.TabStop = false; - // - // pictureBox3 - // - this.pictureBox3.Location = new System.Drawing.Point(106, 123); - this.pictureBox3.Name = "pictureBox3"; - this.pictureBox3.Size = new System.Drawing.Size(40, 67); - this.pictureBox3.TabIndex = 4; - this.pictureBox3.TabStop = false; - // - // pictureBox4 - // - this.pictureBox4.Location = new System.Drawing.Point(152, 123); - this.pictureBox4.Name = "pictureBox4"; - this.pictureBox4.Size = new System.Drawing.Size(40, 67); - this.pictureBox4.TabIndex = 5; - this.pictureBox4.TabStop = false; - // - // pictureBox5 - // - this.pictureBox5.Location = new System.Drawing.Point(198, 123); - this.pictureBox5.Name = "pictureBox5"; - this.pictureBox5.Size = new System.Drawing.Size(40, 67); - this.pictureBox5.TabIndex = 6; - this.pictureBox5.TabStop = false; - // - // pictureBox6 - // - this.pictureBox6.Location = new System.Drawing.Point(244, 123); - this.pictureBox6.Name = "pictureBox6"; - this.pictureBox6.Size = new System.Drawing.Size(40, 67); - this.pictureBox6.TabIndex = 7; - this.pictureBox6.TabStop = false; - // - // pictureBox7 - // - this.pictureBox7.Location = new System.Drawing.Point(290, 123); - this.pictureBox7.Name = "pictureBox7"; - this.pictureBox7.Size = new System.Drawing.Size(40, 67); - this.pictureBox7.TabIndex = 8; - this.pictureBox7.TabStop = false; - // - // pictureBox8 - // - this.pictureBox8.Location = new System.Drawing.Point(336, 123); - this.pictureBox8.Name = "pictureBox8"; - this.pictureBox8.Size = new System.Drawing.Size(40, 67); - this.pictureBox8.TabIndex = 9; - this.pictureBox8.TabStop = false; - // - // button1 - // - this.button1.Location = new System.Drawing.Point(125, 83); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(113, 34); - this.button1.TabIndex = 10; - this.button1.Text = "Plant"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.button1_Click); - // - // Plants - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(393, 156); - this.Controls.Add(this.button1); - this.Controls.Add(this.pictureBox8); - this.Controls.Add(this.pictureBox7); - this.Controls.Add(this.pictureBox6); - this.Controls.Add(this.pictureBox5); - this.Controls.Add(this.pictureBox4); - this.Controls.Add(this.pictureBox3); - this.Controls.Add(this.pictureBox2); - this.Controls.Add(this.pictureBox1); - this.Controls.Add(this.label1); - this.Controls.Add(this.comboBox1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "Plants"; - this.Text = "Flower Manager"; - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox5)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox6)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox7)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox8)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - private System.Windows.Forms.Label label1; - public System.Windows.Forms.ComboBox comboBox1; - private System.Windows.Forms.PictureBox pictureBox1; - private System.Windows.Forms.PictureBox pictureBox2; - private System.Windows.Forms.PictureBox pictureBox3; - private System.Windows.Forms.PictureBox pictureBox4; - private System.Windows.Forms.PictureBox pictureBox5; - private System.Windows.Forms.PictureBox pictureBox6; - private System.Windows.Forms.PictureBox pictureBox7; - private System.Windows.Forms.PictureBox pictureBox8; - private System.Windows.Forms.Button button1; - } -} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Program.cs b/ToonTown Rewritten Bot/Program.cs index 1111b512..74c838b5 100644 --- a/ToonTown Rewritten Bot/Program.cs +++ b/ToonTown Rewritten Bot/Program.cs @@ -17,8 +17,7 @@ static void Main() Application.EnableVisualStyles(); Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); - //Application.Run(new DevForm()); + Application.Run(new MainForm()); } } } diff --git a/ToonTown Rewritten Bot/Services/BotFunctions.cs b/ToonTown Rewritten Bot/Services/BotFunctions.cs new file mode 100644 index 00000000..a76504cb --- /dev/null +++ b/ToonTown Rewritten Bot/Services/BotFunctions.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WindowsInput; +using System.Threading; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Views; +using ToonTown_Rewritten_Bot.Models; + +namespace ToonTown_Rewritten_Bot.Services +{ + public class BotFunctions + { + private static Dictionary _dataFileMap = new Dictionary(); + public static bool SendMessage(string message, int spamCount, bool spam, NumericUpDown upDown) + { + DialogResult confirmation; + if (!message.Equals("")) + { + confirmation = MessageBox.Show("Send Message?", "Continue...", MessageBoxButtons.YesNo); + if (confirmation.Equals(DialogResult.Yes)) + { + if (spam && spamCount > 1)//spam checkbox check + { + while (spamCount >= 1) + { + if (Control.ModifierKeys == Keys.Alt)//break out of loop + { + upDown.Value = 1; + return true; + } + Send(message); + spamCount--; + if (spamCount != 0) + upDown.Value = spamCount; + } + } + else if (!spam || spamCount == 1) + Send(message); + } + else if (confirmation.Equals(DialogResult.No) || confirmation.Equals(DialogResult.Cancel)) + return false; + } + else + MessageBox.Show("You must enter a message to Send!"); + return false; + } + private static void Send(string text) + { + CoreFunctionality.DoMouseClick(); + Thread.Sleep(500); + InputSimulator.SimulateTextEntry(text); + Thread.Sleep(500); + SendKeys.SendWait("{ENTER}"); + } + + public static async Task KeepToonAwake(int timeInSeconds, CancellationToken cancellationToken) + { + CoreFunctionality.MaximizeAndFocusTTRWindow(); // Ensure the game window is focused + DateTime endTime = DateTime.Now.AddSeconds(timeInSeconds); // Calculate the end time based on seconds + CoreFunctionality.DoMouseClick(); // Initial action to "keep awake" + + try + { + while (endTime > DateTime.Now) + { + cancellationToken.ThrowIfCancellationRequested(); // Check for cancellation + SendKeys.SendWait("^"); // Simulate key press to keep the toon awake + await Task.Delay(1000, cancellationToken); // Wait for a second before the next key press + } + } + catch (OperationCanceledException) + { + } + } + + /*public static Dictionary GetDataFileMap() + { + return _dataFileMap; + }*/ + + public static void CreateItemsDataFileMap() + { + //Gardening Coords + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.PlantFlowerRemoveButton).ToString(), "Plant Flower/Remove Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.RedJellybeanButton).ToString(), "Red Jellybean Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.GreenJellybeanButton).ToString(), "Green Jellybean Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.OrangeJellybeanButton).ToString(), "Orange Jellybean Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.PurpleJellybeanButton).ToString(), "Purple Jellybean Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.BlueJellybeanButton).ToString(), "Blue Jellybean Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.PinkJellybeanButton).ToString(), "Pink Jellybean Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.YellowJellybeanButton).ToString(), "Yellow Jellybean Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.CyanJellybeanButton).ToString(), "Cyan Jellybean Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.SilverJellybeanButton).ToString(), "Silver Jellybean Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.BluePlantButton).ToString(), "Blue Plant Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.BlueOkButton).ToString(), "Blue Ok Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.WateringCanButton).ToString(), "Watering Can Button"); + _dataFileMap.Add(((int)Coordinates.GardeningCoordinatesEnum.BlueYesButton).ToString(), "Blue Yes Button"); + //Fishing Coords + _dataFileMap.Add(((int)Coordinates.FishingCoordinatesEnum.RedFishingButton).ToString(), "Red Fishing Button"); + _dataFileMap.Add(((int)Coordinates.FishingCoordinatesEnum.ExitFishingButton).ToString(), "Exit Fishing Button"); + _dataFileMap.Add(((int)Coordinates.FishingCoordinatesEnum.BlueSellAllButton).ToString(), "Blue Sell All Button"); + //Racing Coords + //Doodle Training Coords + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.FeedDoodleButton).ToString(), "Feed Doodle Button"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.ScratchDoodleButton).ToString(), "Scratch Doodle Button"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.GreenSpeedChatButton).ToString(), "Green SpeedChat Button"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.PetsTabInSpeedChat).ToString(), "Pets Tab in SpeedChat"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.TricksTabInSpeedChat).ToString(), "Tricks Tab in SpeedChat"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.JumpTrickOptionInSpeedChat).ToString(), "Jump Trick Option in SpeedChat"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.BegTrickOptionInSpeedChat).ToString(), "Beg Trick Option in SpeedChat"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.PlayDeadTrickOptionInSpeedChat).ToString(), "Play Dead Trick Option in SpeedChat"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.RolloverTrickOptionInSpeedChat).ToString(), "Rollover Trick Option in SpeedChat"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.BackflipTrickOptionInSpeedChat).ToString(), "Backflip Trick Option in SpeedChat"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.DanceTrickOptionInSpeedChat).ToString(), "Dance Trick Option in SpeedChat"); + _dataFileMap.Add(((int)Coordinates.DoodleTrainingCoordinatesEnum.SpeakTrickOptionInSpeedChat).ToString(), "Speak Trick Option in SpeedChat"); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/CoordinatesManager.cs b/ToonTown Rewritten Bot/Services/CoordinatesManager.cs new file mode 100644 index 00000000..605ad837 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CoordinatesManager.cs @@ -0,0 +1,326 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Models; + +namespace ToonTown_Rewritten_Bot.Services +{ + public class CoordinatesManager + { + private const string CoordinatesFileName = "UIElementCoordinates.json"; + // Static readonly field that computes the file path only once when the class is loaded + private static readonly string CoordinatesFilePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), CoordinatesFileName); + public CoordinatesManager() + { + if (!File.Exists(CoordinatesFilePath)) + { + CreateFreshCoordinatesFile(); + } + } + + /// + /// Provides the fully qualified path to the coordinates file. + /// This path is based on the assembly's current execution location, + /// ensuring consistent access to the coordinates file throughout the application. + /// + /// A string containing the path to the coordinates file. + public static string GetCoordinatesFilePath() + { + return CoordinatesFilePath; + } + + /// + /// Reads the coordinate data from the JSON file and returns a list of CoordinateActions. + /// + /// A list of CoordinateActions representing the coordinates. If the file does not exist, returns an empty list. + public static List ReadCoordinates() + { + return ReadCoordinatesFromJsonFile(); + } + + /// + /// Checks if the coordinates associated with a given key are set and valid. + /// + /// The enum value representing the coordinate key to check. + /// True if the coordinates are valid and set; otherwise, false if they are default (0,0) or not found. + public static bool CheckCoordinates(Enum coordinateKey) + { + // Check if the coordinates file exists. If not, create a fresh one with default values. + if (!File.Exists(CoordinatesFilePath)) + { + CreateFreshCoordinatesFile(); + } + + // Read the JSON file containing the coordinates data. + string json = File.ReadAllText(CoordinatesFilePath); + // Deserialize the JSON data into a list of CoordinateActions objects. + List coordinateActions = JsonConvert.DeserializeObject>(json); + + // Convert the enum key to its corresponding integer value, then convert that to a string. + string keyAsString = Convert.ToInt32(coordinateKey).ToString(); + + // Attempt to find a CoordinateAction that matches the provided key. + var coordinate = coordinateActions.FirstOrDefault(ca => ca.Key == keyAsString); + + // Check if the coordinate exists and if its X and Y values are not the default (0,0), indicating they have been set. + if (coordinate != null && (coordinate.X == 0 && coordinate.Y == 0)) + { + return false; // The coordinates are default (0,0), indicating they have not been properly set. + } + + // If the coordinate exists and is not default, or if no coordinate with the provided key exists, assume the coordinates are valid. + return true; // The coordinates are valid and have been set. + } + + /// + /// Retrieves the coordinates from a JSON file based on the given enum key. + /// + /// An enum value representing the coordinate key to retrieve. The enum should be convertible to an integer that matches keys stored in the JSON. + /// A tuple containing the X and Y coordinates associated with the provided enum key. + /// Thrown if the UIElementCoordinates cannot be found at the expected location. + /// Thrown if no coordinates are found for the given key, indicating a possible issue with data consistency or key validity. + /// + /// This method reads from a JSON file located relative to the executable's directory, deserializing it into a list of objects. + /// It then attempts to find a object where the key matches the provided enum's numeric value converted to string. + /// If found, it returns the X and Y coordinates; otherwise, it throws an exception indicating the key was not found. + /// + public static (int x, int y) GetCoordsFromMap(Enum key) + { + // Convert the Enum to its integer value, then to string + string keyAsString = Convert.ToInt32(key).ToString(); + + if (File.Exists(CoordinatesFilePath)) + { + string json = File.ReadAllText(CoordinatesFilePath); + //Gets all of the coordinate models + var coordinateActions = JsonConvert.DeserializeObject>(json); + + var action = coordinateActions.FirstOrDefault(a => a.Key == keyAsString); + if (action != null) + { + return (action.X, action.Y); + } + else + { + throw new Exception($"No coordinates found for the key: {keyAsString}"); + } + } + else + { + throw new FileNotFoundException("UIElementCoordinates not found."); + } + } + + /// + /// Updates the coordinates for a specified location programmatically without user interaction. + /// This function reads the existing coordinates from the JSON file, updates them with new values, + /// and then writes the updated coordinates back to the file. + /// + /// The enum value representing the location to update. + /// This should be a value from an established Enum type that corresponds to specific coordinate keys. + /// The new coordinates to set for the location, encapsulated in a Point structure. + public static void UpdateCoordinatesAutomatically(Enum locationToUpdateEnum, Point coordinates) + { + // Convert the Enum to its integer value, then to string + string keyAsString = Convert.ToInt32(locationToUpdateEnum).ToString(); + + // Read the existing JSON file + if (File.Exists(CoordinatesFilePath)) + { + string json = File.ReadAllText(CoordinatesFilePath); + var coordinateActions = JsonConvert.DeserializeObject>(json); + + // Find and update the coordinates for the specified location + var actionToUpdate = coordinateActions.Find(action => action.Key == keyAsString); + if (actionToUpdate != null) + { + actionToUpdate.X = coordinates.X; + actionToUpdate.Y = coordinates.Y; + + // Serialize the updated list back to JSON and write it to the file + string updatedJson = JsonConvert.SerializeObject(coordinateActions, Formatting.Indented); + File.WriteAllText(CoordinatesFilePath, updatedJson); + } + else + { + throw new InvalidOperationException("No matching coordinate action found for the given key."); + } + } + else + { + throw new FileNotFoundException("UIElementCoordinates not found."); + } + } + + public static async Task ManualUpdateCoordinates(Enum locationToUpdateEnum) + { + CoreFunctionality.BringBotWindowToFront(); + + UpdateCoordsHelper updateCoordsWindow = new UpdateCoordsHelper(); + // Convert the Enum to its integer value, then to string + string keyAsString = Convert.ToInt32(locationToUpdateEnum).ToString(); + try + { + // Use CoordinateActions.GetDescription to retrieve the description by key + string description = CoordinateActions.GetDescription(keyAsString); + if (description == null) + { + throw new Exception("Description not found for the given key."); + } + updateCoordsWindow.startCountDown(description); + // Set the window to be topmost to ensure it appears above other applications. + updateCoordsWindow.TopMost = true; + updateCoordsWindow.ShowDialog(); + } + catch + { + MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + + // Get the updated cursor location + Point coords = CoreFunctionality.getCursorLocation(); + string x = Convert.ToString(coords.X); + string y = Convert.ToString(coords.Y); + + // Read the JSON file and deserialize it into a list of CoordinateAction objects + List coordinateActions; + if (File.Exists(CoordinatesFilePath)) + { + string json = File.ReadAllText(CoordinatesFilePath); + coordinateActions = JsonConvert.DeserializeObject>(json); + } + else + { + // Handle case where file does not exist + coordinateActions = new List(); + } + + // Find the coordinate by key and update its X and Y values + var coordinateToUpdate = coordinateActions.FirstOrDefault(ca => ca.Key == keyAsString); + if (coordinateToUpdate != null) + { + coordinateToUpdate.X = int.Parse(x); + coordinateToUpdate.Y = int.Parse(y); + } + + // Serialize the list back to JSON and write it to the file + string updatedJson = JsonConvert.SerializeObject(coordinateActions, Formatting.Indented); + File.WriteAllText(CoordinatesFilePath, updatedJson); + + CoreFunctionality.MaximizeAndFocusTTRWindow(); + } + + public async Task ManualUpdateCoordinates(string locationToUpdate) + { + CoreFunctionality.BringBotWindowToFront(); + + UpdateCoordsHelper updateCoordsWindow = new UpdateCoordsHelper(); + try + { + // Use CoordinateActions.GetDescription to retrieve the description by key + string description = CoordinateActions.GetDescription(locationToUpdate); + if (description == null) + { + throw new Exception("Description not found for the given key."); + } + updateCoordsWindow.startCountDown(description); + // Set the window to be topmost to ensure it appears above other applications. + updateCoordsWindow.TopMost = true; + updateCoordsWindow.ShowDialog(); + } + catch + { + MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + + // Get the updated cursor location + Point coords = CoreFunctionality.getCursorLocation(); + string x = Convert.ToString(coords.X); + string y = Convert.ToString(coords.Y); + + // Read the JSON file and deserialize it into a list of CoordinateAction objects + List coordinateActions; + if (File.Exists(CoordinatesFilePath)) + { + string json = File.ReadAllText(CoordinatesFilePath); + coordinateActions = JsonConvert.DeserializeObject>(json); + } + else + { + // Handle case where file does not exist + coordinateActions = new List(); + } + + // Find the coordinate by key and update its X and Y values + var coordinateToUpdate = coordinateActions.FirstOrDefault(ca => ca.Key == locationToUpdate); + if (coordinateToUpdate != null) + { + coordinateToUpdate.X = int.Parse(x); + coordinateToUpdate.Y = int.Parse(y); + } + + // Serialize the list back to JSON and write it to the file + string updatedJson = JsonConvert.SerializeObject(coordinateActions, Formatting.Indented); + File.WriteAllText(CoordinatesFilePath, updatedJson); + + //CoreFunctionality.MaximizeAndFocusTTRWindow(); + } + + /// + /// Reads the coordinate data from the JSON file and returns a list of CoordinateActions. + /// + /// A list of CoordinateActions representing the coordinates. If the file does not exist, returns an empty list. + private static List ReadCoordinatesFromJsonFile() + { + // Check if the file exists at the specified path. + if (File.Exists(CoordinatesFilePath)) + { + // Read the JSON content from the file. + string json = File.ReadAllText(CoordinatesFilePath); + + // Deserialize the JSON content into a list of CoordinateActions objects. + return JsonConvert.DeserializeObject>(json); + } + + // If the file does not exist, return an empty list to prevent null reference issues. + return new List(); + } + + public static void CreateFreshCoordinatesFile() + { + // Delete the file if it exists + if (File.Exists(CoordinatesFilePath)) + File.Delete(CoordinatesFilePath); + + // Retrieve all descriptions to populate the JSON file + var allDescriptions = CoordinateActions.GetAllDescriptions(); + + // Create a list to hold coordinate data + List coordinateList = new List(); + + // Populate the list with default values + foreach (var entry in allDescriptions) + { + coordinateList.Add(new CoordinateActions + { + Key = entry.Key, + Description = entry.Value, + X = 0, // Default X coordinate + Y = 0 // Default Y coordinate + }); + } + + // Serialize the list to JSON + string json = JsonConvert.SerializeObject(coordinateList, Formatting.Indented); + + // Write the JSON to the file + File.WriteAllText(CoordinatesFilePath, json); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/CoreFunctionality.cs b/ToonTown Rewritten Bot/Services/CoreFunctionality.cs new file mode 100644 index 00000000..9b88200e --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CoreFunctionality.cs @@ -0,0 +1,293 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Models; +using static ToonTown_Rewritten_Bot.Models.Coordinates; +using static ToonTown_Rewritten_Bot.Utilities.ImageRecognition; + +namespace ToonTown_Rewritten_Bot.Services +{ + public class CoreFunctionality + { + public static bool isAutoDetectFishingBtnActive = true; + + public static void DoMouseClick() + { + DoMouseClick(getCursorLocation()); + } + + public static void DoFishingClick() + { + //click red button + DoMouseClickDown(getCursorLocation()); + Thread.Sleep(500);//sleep 2 sec + + // Retrieve coordinates for the red fishing button from the JSON-based coordinates map + (int x, int y) = CoordinatesManager.GetCoordsFromMap(FishingCoordinatesEnum.RedFishingButton); + MoveCursor(x, y + 150);//pull it back + Thread.Sleep(500); + DoMouseClickUp(getCursorLocation()); + } + private static void DoMouseClick(Point location)//simulate left button mouse click + { + //Call the imported function with the cursor's current position + uint X = Convert.ToUInt32(location.X); + uint Y = Convert.ToUInt32(location.Y); + mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0); + } + + private static void DoMouseClickDown(Point location) + { + uint X = Convert.ToUInt32(location.X); + uint Y = Convert.ToUInt32(location.Y); + mouse_event(MOUSEEVENTF_LEFTDOWN, X, Y, 0, 0); + } + + private static void DoMouseClickUp(Point location) + { + uint X = Convert.ToUInt32(location.X); + uint Y = Convert.ToUInt32(location.Y); + mouse_event(MOUSEEVENTF_LEFTUP, X, Y, 0, 0); + } + + public static Color GetColorAt(int x, int y) + { + nint desk = GetDesktopWindow(); + nint dc = GetWindowDC(desk); + int a = (int)GetPixel(dc, x, y); + ReleaseDC(desk, dc); + return Color.FromArgb(255, a >> 0 & 0xff, a >> 8 & 0xff, a >> 16 & 0xff); + } + + public static Point getCursorLocation() + { + Point cursorLocation = new Point(); + GetCursorPos(ref cursorLocation); + return cursorLocation; + } + + public static string HexConverter(Color c) + { + return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2"); + } + + public static void MoveCursor(int x, int y) + { + Cursor.Position = new Point(x, y); + } + + // Maximizes and Focuces TTR + public static void MaximizeAndFocusTTRWindow() + { + nint hwnd = FindToontownWindow(); + ShowWindow(hwnd, 6);//6 min + ShowWindow(hwnd, 3);//3 max + } + + /// + /// Brings the Toontown Rewritten Bot window to the foreground. + /// + /// + /// This function searches for the bot window by its title and, if found, brings it to the front of all other windows. + /// This is useful for ensuring the bot's window is visible, especially when displaying messages or prompts that require user attention. + /// + public static void BringBotWindowToFront() + { + // Get the current process + Process currentProcess = Process.GetCurrentProcess(); + + // Use the main window title of the current process + string windowTitle = currentProcess.MainWindowTitle; + + // Attempt to find the window by its title + IntPtr hWnd = NativeMethods.FindWindow(null, windowTitle); + // If a handle was found, attempt to bring the window to the front + if (hWnd != IntPtr.Zero) + { + NativeMethods.SetForegroundWindow(hWnd); + } + } + + /// + /// Either creates and returns the path to a specific custom actions folder or returns the paths of all JSON files within that folder. + /// + /// The type of actions folder to manage ('Fishing' or 'Golf'). + /// If true, returns paths of all .json files in the folder; otherwise, returns the folder path. + /// If returnFiles is false, returns the path to the folder. If returnFiles is true, returns an array of file paths for .json files in the folder. + public static object ManageCustomActionsFolder(string actionType, bool returnFiles = false) + { + // Define the folder name based on the action type + string folderName = actionType == "Fishing" ? "Custom Fishing Actions" : "Custom Golf Actions"; + + // Get the directory where the executable is running + string exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + + // Combine the executable path with the specific folder name + string customActionsFolderPath = Path.Combine(exePath, folderName); + + // Ensure the directory exists. This method creates the directory if it does not exist + // and does nothing if it already exists. + Directory.CreateDirectory(customActionsFolderPath); + + // If only the path is required, return it + if (!returnFiles) + { + return customActionsFolderPath; + } + + // If files are requested, read and return only .json files in the folder + return Directory.GetFiles(customActionsFolderPath, "*.json"); + } + + /// + /// Extracts an embedded resource from the assembly and writes it to a specified file path. + /// + /// The fully qualified name of the embedded resource. + /// The path where the resource file should be saved. This method overwrites any existing file. + /// Thrown if the specified resource is not found in the assembly. + public static void ExtractResourceToFile(string resourceName, string outputFile) + { + var assembly = Assembly.GetExecutingAssembly(); + using (var resourceStream = assembly.GetManifestResourceStream(resourceName)) + { + if (resourceStream == null) + { + throw new FileNotFoundException($"Resource '{resourceName}' not found in assembly."); + } + + using (var fileStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write)) + { + resourceStream.CopyTo(fileStream); + } + } + } + + /// + /// Ensures that all necessary JSON files from embedded resources related to both Fishing and Golf are available + /// in the application's directory. It extracts any missing files. + /// + public static void EnsureAllEmbeddedJsonFilesExist() + { + // Handle Fishing Actions + string fishingFolderPath = (string)ManageCustomActionsFolder("Fishing", false); + var fishingResources = GetFishingResourceDictionary(); + EnsureEmbeddedJsonFilesExist(fishingFolderPath, fishingResources); + + // Handle Golf Actions + string golfFolderPath = (string)ManageCustomActionsFolder("Golf", false); + var golfResources = GetGolfResourceDictionary(); + EnsureEmbeddedJsonFilesExist(golfFolderPath, golfResources); + } + + /// + /// Checks and extracts missing files for the specified custom actions based on the given resource dictionary. + /// + /// The folder path where files should be checked and saved. + /// A dictionary of embedded resource names and their respective file names. + private static void EnsureEmbeddedJsonFilesExist(string folderPath, Dictionary resources) + { + foreach (var resource in resources) + { + string fullPath = Path.Combine(folderPath, resource.Value); + if (!File.Exists(fullPath)) + { + ExtractResourceToFile(resource.Key, fullPath); + Console.WriteLine($"Extracted: {resource.Value}"); + } + } + } + + /// + /// Retrieves a dictionary of embedded resource file names related to Custom Fishing Actions. + /// This dictionary maps the embedded resource names to more readable JSON file names, to be used when extracting these resources to the file system. + /// The method scans all embedded resources that start with a specific prefix related to Custom Fishing Actions. + /// + /// A dictionary where keys are the full embedded resource names and values are the corresponding filenames intended for saving to disk. + public static Dictionary GetFishingResourceDictionary() + { + var assembly = Assembly.GetExecutingAssembly(); + string[] resourceNames = assembly.GetManifestResourceNames(); + string prefix = "ToonTown_Rewritten_Bot.Services.CustomFishingActions"; + Dictionary resourceMap = new Dictionary(); + + foreach (string resourceName in resourceNames) + { + if (resourceName.StartsWith(prefix)) + { + // Extracting the filename from the resource path and removing extension for better readability + string fileName = Path.GetFileNameWithoutExtension(resourceName.Substring(prefix.Length + 1)); + resourceMap.Add(resourceName, fileName + ".json"); + } + } + return resourceMap; + } + + /// + /// Retrieves a dictionary of embedded resource file names related to Custom Golf Actions. + /// This dictionary maps the embedded resource names to more readable JSON file names, to be used when extracting these resources to the file system. + /// The method scans all embedded resources that start with a specific prefix related to Custom Golf Actions. + /// + /// A dictionary where keys are the full embedded resource names and values are the corresponding filenames intended for saving to disk. + public static Dictionary GetGolfResourceDictionary() + { + var assembly = Assembly.GetExecutingAssembly(); + string[] resourceNames = assembly.GetManifestResourceNames(); + string prefix = "ToonTown_Rewritten_Bot.Services.CustomGolfActions"; + Dictionary resourceMap = new Dictionary(); + + foreach (string resourceName in resourceNames) + { + if (resourceName.StartsWith(prefix)) + { + // Extracting the filename from the resource path and removing extension for better readability + string fileName = Path.GetFileNameWithoutExtension(resourceName.Substring(prefix.Length + 1)); + resourceMap.Add(resourceName, fileName + ".json"); + } + } + return resourceMap; + } + + //ignore .dll imports below + [DllImport("user32.dll")] + private static extern bool GetCursorPos(ref Point lpPoint); + + [DllImport("user32.dll", SetLastError = true)] + static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + + public static IntPtr FindToontownWindow() + { + // Attempt to find the Toontown window by its title + return FindWindow(null, "Toontown Rewritten"); + } + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool ShowWindow(nint hWnd, int nCmdShow); + + [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] + private static extern int BitBlt(nint hDC, int x, int y, int nWidth, int nHeight, nint hSrcDC, int xSrc, int ySrc, int dwRop); + [DllImport("user32.dll", SetLastError = true)] + private static extern nint GetDesktopWindow(); + [DllImport("user32.dll", SetLastError = true)] + private static extern nint GetWindowDC(nint window); + [DllImport("gdi32.dll", SetLastError = true)] + private static extern uint GetPixel(nint dc, int x, int y); + [DllImport("user32.dll", SetLastError = true)] + private static extern int ReleaseDC(nint window, nint dc); + [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo); + + private const int MOUSEEVENTF_LEFTDOWN = 0x02; + private const int MOUSEEVENTF_LEFTUP = 0x04; + private const int MOUSEEVENTF_RIGHTDOWN = 0x08; + private const int MOUSEEVENTF_RIGHTUP = 0x10; + } +} diff --git a/ToonTown Rewritten Bot/Services/CustomFishingActions/BrrrghPolarPlaceFishing Top Right Dock.json b/ToonTown Rewritten Bot/Services/CustomFishingActions/BrrrghPolarPlaceFishing Top Right Dock.json new file mode 100644 index 00000000..88628ecd --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomFishingActions/BrrrghPolarPlaceFishing Top Right Dock.json @@ -0,0 +1,9 @@ +[ + {"Action": "TURN RIGHT", "Command": "RIGHT"}, + {"Action": "TIME", "Command": "800 milliseconds"}, + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "2000 milliseconds"}, + {"Action": "SELL FISH", "Command": "SELL"}, + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "2000 milliseconds"} +] diff --git a/ToonTown Rewritten Bot/Services/CustomFishingActions/BrrrghSleetStFishing First Dock.json b/ToonTown Rewritten Bot/Services/CustomFishingActions/BrrrghSleetStFishing First Dock.json new file mode 100644 index 00000000..60609b16 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomFishingActions/BrrrghSleetStFishing First Dock.json @@ -0,0 +1,15 @@ +[ + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "600 milliseconds"}, + {"Action": "TURN RIGHT", "Command": "RIGHT"}, + {"Action": "TIME", "Command": "850 milliseconds"}, + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "1000 milliseconds"}, + {"Action": "SELL FISH", "Command": "SELL"}, + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "1700 milliseconds"}, + {"Action": "TURN LEFT", "Command": "LEFT"}, + {"Action": "TIME", "Command": "850 milliseconds"}, + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "600 milliseconds"} +] diff --git a/ToonTown Rewritten Bot/Services/CustomFishingActions/BrrrghWalrusWayFishing Top Left Dock.json b/ToonTown Rewritten Bot/Services/CustomFishingActions/BrrrghWalrusWayFishing Top Left Dock.json new file mode 100644 index 00000000..873d3c07 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomFishingActions/BrrrghWalrusWayFishing Top Left Dock.json @@ -0,0 +1,15 @@ +[ + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "100 milliseconds"}, + {"Action": "TURN LEFT", "Command": "LEFT"}, + {"Action": "TIME", "Command": "730 milliseconds"}, + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "2000 milliseconds"}, + {"Action": "SELL FISH", "Command": "SELL"}, + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "2100 milliseconds"}, + {"Action": "TURN RIGHT", "Command": "RIGHT"}, + {"Action": "TIME", "Command": "700 milliseconds"}, + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "1000 milliseconds"} +] diff --git a/ToonTown Rewritten Bot/Services/CustomFishingActions/DDLLullabyLaneFishing Dock Left Of The Small Box.json b/ToonTown Rewritten Bot/Services/CustomFishingActions/DDLLullabyLaneFishing Dock Left Of The Small Box.json new file mode 100644 index 00000000..5714c492 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomFishingActions/DDLLullabyLaneFishing Dock Left Of The Small Box.json @@ -0,0 +1,7 @@ +[ + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "4000 milliseconds"}, + {"Action": "SELL FISH", "Command": "SELL"}, + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "6500 milliseconds"} +] diff --git a/ToonTown Rewritten Bot/Services/CustomFishingActions/DDLighthouseLaneFishing Middle Right Dock.json b/ToonTown Rewritten Bot/Services/CustomFishingActions/DDLighthouseLaneFishing Middle Right Dock.json new file mode 100644 index 00000000..bc9bbbf6 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomFishingActions/DDLighthouseLaneFishing Middle Right Dock.json @@ -0,0 +1,9 @@ +[ + {"Action": "TURN RIGHT", "Command": "RIGHT"}, + {"Action": "TIME", "Command": "330 milliseconds"}, + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "2200 milliseconds"}, + {"Action": "SELL FISH", "Command": "SELL"}, + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "4500 milliseconds"} +] diff --git a/ToonTown Rewritten Bot/Services/CustomFishingActions/DaisyGardenElmStFishing Bottom Left Dock.json b/ToonTown Rewritten Bot/Services/CustomFishingActions/DaisyGardenElmStFishing Bottom Left Dock.json new file mode 100644 index 00000000..c5129325 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomFishingActions/DaisyGardenElmStFishing Bottom Left Dock.json @@ -0,0 +1,9 @@ +[ + {"Action": "TURN LEFT", "Command": "LEFT"}, + {"Action": "TIME", "Command": "80 milliseconds"}, + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "2000 milliseconds"}, + {"Action": "SELL FISH", "Command": "SELL"}, + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "4500 milliseconds"} +] diff --git a/ToonTown Rewritten Bot/Services/CustomFishingActions/MMTenorTerraceFishing Top Left Dock.json b/ToonTown Rewritten Bot/Services/CustomFishingActions/MMTenorTerraceFishing Top Left Dock.json new file mode 100644 index 00000000..76ac2fa8 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomFishingActions/MMTenorTerraceFishing Top Left Dock.json @@ -0,0 +1,9 @@ +[ + {"Action": "TURN LEFT", "Command": "LEFT"}, + {"Action": "TIME", "Command": "1090 milliseconds"}, + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "2200 milliseconds"}, + {"Action": "SELL FISH", "Command": "SELL"}, + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "3000 milliseconds"} +] diff --git a/ToonTown Rewritten Bot/Services/CustomFishingActions/TTCPunchlinePlaceFishing First Dock.json b/ToonTown Rewritten Bot/Services/CustomFishingActions/TTCPunchlinePlaceFishing First Dock.json new file mode 100644 index 00000000..a8fbd2d8 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomFishingActions/TTCPunchlinePlaceFishing First Dock.json @@ -0,0 +1,15 @@ +[ + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "2000 milliseconds"}, + {"Action": "TURN RIGHT", "Command": "RIGHT"}, + {"Action": "TIME", "Command": "800 milliseconds"}, + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "700 milliseconds"}, + {"Action": "SELL FISH", "Command": "SELL"}, + {"Action": "WALK BACKWARDS", "Command": "DOWN"}, + {"Action": "TIME", "Command": "600 milliseconds"}, + {"Action": "TURN LEFT", "Command": "LEFT"}, + {"Action": "TIME", "Command": "750 milliseconds"}, + {"Action": "WALK FORWARDS", "Command": "UP"}, + {"Action": "TIME", "Command": "2000 milliseconds"} +] diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/CustomActionsGolf.cs b/ToonTown Rewritten Bot/Services/CustomGolfActions/CustomActionsGolf.cs new file mode 100644 index 00000000..87b56d10 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/CustomActionsGolf.cs @@ -0,0 +1,83 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using System.Threading; +using WindowsInput; +using ToonTown_Rewritten_Bot.Models; +using System.Windows.Forms; + +namespace ToonTown_Rewritten_Bot.Services.CustomGolfActions +{ + public class CustomActionsGolf + { + private List actions = new List(); + + public CustomActionsGolf(string filePath) + { + LoadActionsFromJson(filePath); + } + + private void LoadActionsFromJson(string filePath) + { + if (File.Exists(filePath)) + { + string json = File.ReadAllText(filePath); + actions = JsonConvert.DeserializeObject>(json); + } + } + + private async void PrepareToHitBall() + { + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); + await Task.Delay(50); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + } + + public async Task PerformGolfActions(CancellationToken cancellationToken) + { + CoreFunctionality.MaximizeAndFocusTTRWindow(); + await Task.Delay(1000, cancellationToken); // Initial delay before starting actions + GolfActionKeys keys = new GolfActionKeys(); + + foreach (var actionCommand in actions) + { + cancellationToken.ThrowIfCancellationRequested(); + + // Handle delay time actions separately + if (actionCommand.Action == "DELAY TIME") + { + await Task.Delay(actionCommand.Duration, cancellationToken); + continue; // Skip the rest of the loop for delay actions + } + + // Process other actions that should correspond to actual key presses + if (keys.ActionKeyMap.TryGetValue(actionCommand.Action, out VirtualKeyCode keyCode)) + { + // Tee movements use the duration to wait after the movement, but do not apply delay during key press. + if (actionCommand.Action == "MOVE TO RIGHT TEE SPOT" || actionCommand.Action == "MOVE TO LEFT TEE SPOT") + { + InputSimulator.SimulateKeyDown(keyCode); + // Press and release key immediately for tee spot moves + InputSimulator.SimulateKeyUp(keyCode); + PrepareToHitBall(); // Assuming this function correctly prepares for the next golf swing + await Task.Delay(actionCommand.Duration, cancellationToken); // Use specified duration to delay after moving to tee spot + } + else + { + // For all other actions, hold the key for the duration specified, then release + InputSimulator.SimulateKeyDown(keyCode); + await Task.Delay(actionCommand.Duration, cancellationToken); + InputSimulator.SimulateKeyUp(keyCode); + } + } + else + { + CoreFunctionality.BringBotWindowToFront(); + MessageBox.Show($"Unsupported action: {actionCommand.Action}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Afternoon Tee.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Afternoon Tee.json new file mode 100644 index 00000000..ee42b6b9 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Afternoon Tee.json @@ -0,0 +1,12 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "CONTROL", + "Duration": 2120 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Down the Hatch.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Down the Hatch.json new file mode 100644 index 00000000..652a7b2e --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Down the Hatch.json @@ -0,0 +1,12 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 2340 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Hole In Fun.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Hole In Fun.json new file mode 100644 index 00000000..5c6b2c9e --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Hole In Fun.json @@ -0,0 +1,12 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 1300 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Hole on the Range.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Hole on the Range.json new file mode 100644 index 00000000..86fae515 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Hole on the Range.json @@ -0,0 +1,12 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 1800 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Holey Mackeral.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Holey Mackeral.json new file mode 100644 index 00000000..8e26b263 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Holey Mackeral.json @@ -0,0 +1,12 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 1000 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Hot Links.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Hot Links.json new file mode 100644 index 00000000..86fae515 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Hot Links.json @@ -0,0 +1,12 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 1800 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - One Little Birdie.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - One Little Birdie.json new file mode 100644 index 00000000..5f1807a6 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - One Little Birdie.json @@ -0,0 +1,17 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "TURN RIGHT", + "Command": "TURN RIGHT", + "Duration": 700 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 1870 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Peanut Putter.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Peanut Putter.json new file mode 100644 index 00000000..cffb39e7 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Peanut Putter.json @@ -0,0 +1,12 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 1860 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Seeing green.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Seeing green.json new file mode 100644 index 00000000..3dfefe21 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Seeing green.json @@ -0,0 +1,12 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 1790 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Swing Time.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Swing Time.json new file mode 100644 index 00000000..a7c2d7a5 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Swing Time.json @@ -0,0 +1,17 @@ +[ + { + "Action": "MOVE TO RIGHT TEE SPOT", + "Command": "RIGHT", + "Duration": 50 + }, + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 2000 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Swing-A-Long.json b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Swing-A-Long.json new file mode 100644 index 00000000..652a7b2e --- /dev/null +++ b/ToonTown Rewritten Bot/Services/CustomGolfActions/EASY - Swing-A-Long.json @@ -0,0 +1,12 @@ +[ + { + "Action": "DELAY TIME", + "Command": "DELAY TIME", + "Duration": 15000 + }, + { + "Action": "SWING POWER", + "Command": "SWING POWER", + "Duration": 2340 + } +] \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/DoodleTraining.cs b/ToonTown Rewritten Bot/Services/DoodleTraining.cs new file mode 100644 index 00000000..137075de --- /dev/null +++ b/ToonTown Rewritten Bot/Services/DoodleTraining.cs @@ -0,0 +1,305 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Views; +using static ToonTown_Rewritten_Bot.Models.Coordinates; + +namespace ToonTown_Rewritten_Bot.Services +{ + public class DoodleTraining : CoreFunctionality + { + public static int numberOfFeeds, numberOfScratches; + private static string selectedTrick; + private static bool infiniteTimeCheckBox, justFeedCheckBox, justScratchCheckBox; + public async Task StartDoodleTraining(int feeds, int scratches, bool unlimitedCheckBox, string trick, bool justFeed, bool justScratch, CancellationToken cancellationToken) + { + numberOfFeeds = feeds; + numberOfScratches = scratches; + selectedTrick = trick; + infiniteTimeCheckBox = unlimitedCheckBox; + justFeedCheckBox = justFeed; + justScratchCheckBox = justScratch; + + await Task.Delay(2000, cancellationToken); // Use cancellation token + await feedAndScratch(cancellationToken); // Pass cancellation token down + } + + private async Task feedAndScratch(CancellationToken cancellationToken) + { + // Continue looping indefinitely if unlimited, or until tasks are done + while (infiniteTimeCheckBox || numberOfFeeds > 0 || numberOfScratches > 0) + { + cancellationToken.ThrowIfCancellationRequested(); // Check for cancellation + + if (!justScratchCheckBox && numberOfFeeds > 0) // Feed if not just scratching and feeds are left + { + await feedDoodle(cancellationToken); + if (!infiniteTimeCheckBox) numberOfFeeds--; // Only decrement if not unlimited + } + + if (!justFeedCheckBox && numberOfScratches > 0) // Scratch if not just feeding and scratches are left + { + await scratchDoodle(cancellationToken); + if (!infiniteTimeCheckBox) numberOfScratches--; // Only decrement if not unlimited + } + + if (selectedTrick != "None") // If a trick is selected, perform it + await DetermineSelectedTrick(cancellationToken); + + await Task.Delay(5000, cancellationToken); // Wait for 5 seconds between actions, respect cancellation + } + } + + public async Task DetermineSelectedTrick(CancellationToken cancellationToken) + { + // Ensure there's a small delay before starting the trick (simulating setup time). + await Task.Delay(1000, cancellationToken); + + // Check if the selected trick is recognized and perform the associated actions. + switch (selectedTrick) + { + case "Jump (5 - 10 laff)": + await PerformTrickAsync(TrainJump, cancellationToken); + break; + case "Beg (6 - 12 laff)": + await PerformTrickAsync(TrainBeg, cancellationToken); + break; + case "Play Dead (7 - 14 laff)": + await PerformTrickAsync(TrainPlayDead, cancellationToken); + break; + case "Rollover (8 - 16 laff)": + await PerformTrickAsync(TrainRollover, cancellationToken); + break; + case "Backflip (9 - 18 laff)": + await PerformTrickAsync(TrainBackflip, cancellationToken); + break; + case "Dance (10 - 20 laff)": + await PerformTrickAsync(TrainDance, cancellationToken); + break; + case "Speak (11 - 22 laff)": + await PerformTrickAsync(TrainSpeak, cancellationToken); + break; + default: + MessageBox.Show("Selected trick is not recognized. Please check the trick name and try again.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + break; + } + } + + private async Task PerformTrickAsync(Func trickAction, CancellationToken cancellationToken) + { + // Try the trick two times in case the first attempt fails (doodle might get confused). + for (int i = 0; i < 2; i++) + { + await OpenSpeedChat(cancellationToken); // Ensure OpenSpeedChat is now designed to accept and use CancellationToken. + await trickAction(cancellationToken); + cancellationToken.ThrowIfCancellationRequested(); // Properly handle cancellation between attempts. + } + } + + public async Task OpenSpeedChat(CancellationToken cancellationToken) + { + await Task.Delay(1000, cancellationToken); // Simulate delay before starting the operation + + // Check coordinates for the SpeedChat button + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.GreenSpeedChatButton)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.GreenSpeedChatButton); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(1000, cancellationToken); // Delay after clicking SpeedChat + + // Check coordinates for the Pets tab + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.PetsTabInSpeedChat)) + { + (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.PetsTabInSpeedChat); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(1000, cancellationToken); // Delay after clicking Pets tab + + // Check coordinates for the Tricks tab + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.TricksTabInSpeedChat)) + { + (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.TricksTabInSpeedChat); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(1000, cancellationToken); // Delay after clicking Tricks tab + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.TricksTabInSpeedChat); + await Task.Delay(2000, cancellationToken); + await OpenSpeedChat(cancellationToken); // Recursively call with cancellation support + } + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.PetsTabInSpeedChat); + await Task.Delay(2000, cancellationToken); + await OpenSpeedChat(cancellationToken); // Recursively call with cancellation support + } + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.GreenSpeedChatButton); + await Task.Delay(2000, cancellationToken); + await OpenSpeedChat(cancellationToken); // Recursively call with cancellation support + } + } + + public async Task TrainBeg(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.BegTrickOptionInSpeedChat)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.BegTrickOptionInSpeedChat); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(2000, cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.BegTrickOptionInSpeedChat); + await Task.Delay(2000, cancellationToken); + await TrainBeg(cancellationToken); + } + } + + public async Task TrainPlayDead(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.PlayDeadTrickOptionInSpeedChat)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.PlayDeadTrickOptionInSpeedChat); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(2000, cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.PlayDeadTrickOptionInSpeedChat); + await Task.Delay(2000, cancellationToken); + await TrainPlayDead(cancellationToken); + } + } + + public async Task TrainRollover(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.RolloverTrickOptionInSpeedChat)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.RolloverTrickOptionInSpeedChat); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(2000, cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.RolloverTrickOptionInSpeedChat); + await Task.Delay(2000, cancellationToken); + await TrainRollover(cancellationToken); + } + } + + public async Task TrainBackflip(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.BackflipTrickOptionInSpeedChat)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.BackflipTrickOptionInSpeedChat); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(2000, cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.BackflipTrickOptionInSpeedChat); + await Task.Delay(2000, cancellationToken); + await TrainBackflip(cancellationToken); + } + } + + public async Task TrainDance(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.DanceTrickOptionInSpeedChat)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.DanceTrickOptionInSpeedChat); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(2000, cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.DanceTrickOptionInSpeedChat); + await Task.Delay(2000, cancellationToken); + await TrainDance(cancellationToken); + } + } + + public async Task TrainSpeak(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.SpeakTrickOptionInSpeedChat)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.SpeakTrickOptionInSpeedChat); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(2000, cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.SpeakTrickOptionInSpeedChat); + await Task.Delay(2000, cancellationToken); + await TrainSpeak(cancellationToken); + } + } + + public async Task TrainJump(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.JumpTrickOptionInSpeedChat)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.JumpTrickOptionInSpeedChat); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(2000, cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.JumpTrickOptionInSpeedChat); + await Task.Delay(2000, cancellationToken); + await TrainJump(cancellationToken); + } + } + + public async Task feedDoodle(CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.FeedDoodleButton)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.FeedDoodleButton); + MoveCursor(x, y); + DoMouseClick(); + await Task.Delay(11500, cancellationToken); // Respect cancellation + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.FeedDoodleButton); + await Task.Delay(2000, cancellationToken); + await feedDoodle(cancellationToken); // Recursive call with cancellation + } + } + + public async Task scratchDoodle(CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + if (CoordinatesManager.CheckCoordinates(DoodleTrainingCoordinatesEnum.ScratchDoodleButton)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(DoodleTrainingCoordinatesEnum.ScratchDoodleButton); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(10000, cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(DoodleTrainingCoordinatesEnum.ScratchDoodleButton); + await Task.Delay(2000, cancellationToken); + await scratchDoodle(cancellationToken); + } + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/BrrrghPolarPlaceFishing.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/BrrrghPolarPlaceFishing.cs new file mode 100644 index 00000000..4083de64 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/BrrrghPolarPlaceFishing.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public class BrrrghPolarPlaceFishing : FishingStrategyBase + { + public override async Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + // Simulation of leaving the fishing dock & walking over to the fisherman to sell + InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); + await Task.Delay(800, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; + await Task.Delay(2000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + + await SellFishAsync(cancellationToken); + + // Simulation of going back to the dock + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(2000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/BrrrghSleetStFishing.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/BrrrghSleetStFishing.cs new file mode 100644 index 00000000..9c3aad6f --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/BrrrghSleetStFishing.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public class BrrrghSleetStFishing : FishingStrategyBase + { + public override async Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + // Simulation of leaving the fishing dock & walking over to the fisherman to sell + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(600, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); + await Task.Delay(850, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; + await Task.Delay(1000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + + await SellFishAsync(cancellationToken); + + // Simulation of going back to the dock + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(1700, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); + await Task.Delay(850, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; + await Task.Delay(600, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/BrrrghWalrusWayFishing.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/BrrrghWalrusWayFishing.cs new file mode 100644 index 00000000..8c88d689 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/BrrrghWalrusWayFishing.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public class BrrrghWalrusWayFishing : FishingStrategyBase + { + public override async Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + // Simulation of leaving the fishing dock & walking over to the fisherman to sell + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; + await Task.Delay(100, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); + await Task.Delay(730, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; + await Task.Delay(2000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + + await SellFishAsync(cancellationToken); //sell fish + + // Simulation of going back to the dock + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(2100, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); + await Task.Delay(700, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(1000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/CustomActionsFishing.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/CustomActionsFishing.cs new file mode 100644 index 00000000..6e838fad --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/CustomActionsFishing.cs @@ -0,0 +1,75 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using System.Threading; +using WindowsInput; +using System.Diagnostics; +using ToonTown_Rewritten_Bot.Models; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public class CustomActionsFishing : FishingStrategyBase + { + private List actions = new List(); + + public CustomActionsFishing(string filePath) + { + LoadActionsFromJson(filePath); + } + + private void LoadActionsFromJson(string filePath) + { + if (File.Exists(filePath)) + { + string json = File.ReadAllText(filePath); + actions = JsonConvert.DeserializeObject>(json); + } + } + + public override async Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + foreach (var actionCommand in actions) + { + Debug.WriteLine($"Executing action: {actionCommand.Action}"); + + if (!actionCommand.Command.StartsWith("TIME")) + { + if (actionCommand.Command == "SELL") + { + await SellFishAsync(cancellationToken); // Handle selling fish + await Task.Delay(3000, cancellationToken); // Delay to ensure the selling action is complete + } + else if (Enum.TryParse(actionCommand.Command, out var keyCode)) + { + InputSimulator.SimulateKeyDown(keyCode); + // Find the next action + int currentIndex = actions.IndexOf(actionCommand); + if (currentIndex + 1 < actions.Count && actions[currentIndex + 1].Action == "TIME") + { + var nextAction = actions[currentIndex + 1]; + if (int.TryParse(nextAction.Command.Split(' ')[0], out int milliseconds)) + { + await Task.Delay(milliseconds, cancellationToken); + InputSimulator.SimulateKeyUp(keyCode); + } + } + else + { + await Task.Delay(500, cancellationToken); // Default press duration for keys without a specified time + InputSimulator.SimulateKeyUp(keyCode); + } + } + } + else + { + if (int.TryParse(actionCommand.Command.Split(' ')[0], out int milliseconds)) + { + await Task.Delay(milliseconds, cancellationToken); // Wait for the specified time in milliseconds + } + } + } + } + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/DDLLullabyLaneFishing.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/DDLLullabyLaneFishing.cs new file mode 100644 index 00000000..c201873d --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/DDLLullabyLaneFishing.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public class DDLLullabyLaneFishing : FishingStrategyBase + { + public override async Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); + await Task.Delay(4000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + await SellFishAsync(cancellationToken); + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(6500, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/DDLighthouseLaneFishing.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/DDLighthouseLaneFishing.cs new file mode 100644 index 00000000..34ddde7b --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/DDLighthouseLaneFishing.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public class DDLighthouseLaneFishing : FishingStrategyBase + { + public override async Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + // Simulation of leaving the fishing dock & walking over to the fisherman to sell + InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); + await Task.Delay(330, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; + await Task.Delay(2200, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + + await SellFishAsync(cancellationToken); + + // Simulation of going back to the dock + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(4500, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/DaisyGardenElmStFishing.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/DaisyGardenElmStFishing.cs new file mode 100644 index 00000000..10a1397c --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/DaisyGardenElmStFishing.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public class DaisyGardenElmStFishing : FishingStrategyBase + { + public override async Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + // Simulation of leaving the fishing dock & walking over to the fisherman to sell + InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); + await Task.Delay(80, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; + await Task.Delay(2000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + + await SellFishAsync(cancellationToken); + + // Simulation of going back to the dock + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(4500, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/FishingStrategyBase.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/FishingStrategyBase.cs new file mode 100644 index 00000000..c580bc11 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/FishingStrategyBase.cs @@ -0,0 +1,127 @@ +using System; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using static ToonTown_Rewritten_Bot.Models.Coordinates; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public abstract class FishingStrategyBase : CoreFunctionality + { + protected bool shouldStopFishing = false; + /// + /// The random variance of casting the fishing rod, if enabled. + /// + protected int _VARIANCE = 20; + protected Random _rand = new Random(); + protected string _redFishingButtonColor = "#FD0000"; + + /// + /// An abstract method to be implemented by derived classes, detailing the process + /// of leaving the fishing dock, selling the caught fish at the fisherman, and returning + /// to the dock. This method defines the required actions to perform the sell operation + /// in specific fishing locations. + /// + /// A token to observe while waiting for the task to complete, + /// allowing the operation to be cancelled. + /// A task that represents the asynchronous operation of leaving the dock, + /// selling fish, and returning. + public abstract Task LeaveDockAndSellAsync(CancellationToken cancellationToken); + + /// + /// Initiates the fishing actions for a specified number of casts, applying variance if enabled, and handles the operation asynchronously. + /// + /// The total number of casts to attempt. + /// Indicates whether to apply a variance to casting, simulating a more natural fishing experience. + /// A token to observe while waiting for the task to complete, allowing the operation to be cancelled. + /// A task that represents the asynchronous fishing operation, performing casts, checking for catches, and optionally exiting fishing upon completion. + /// + /// This method controls the flow of the fishing operation, including casting the line, waiting for a catch, and handling the asynchronous delays between actions. + /// It also respects the cancellation token to safely exit the operation if requested and ensures that the fishing process is attempted for the specified number of casts. + /// After completing the fishing attempts or if instructed to stop, it will exit the fishing operation. + /// + public async Task StartFishingActionsAsync(int numberOfCasts, bool fishVariance, CancellationToken cancellationToken) + { + Stopwatch stopwatch = new Stopwatch(); + while (numberOfCasts != 0 && !shouldStopFishing) + { + await CastLine(fishVariance, cancellationToken); + stopwatch.Start(); + while (stopwatch.Elapsed.Seconds < 30 && !await CheckIfFishCaught(cancellationToken)) + { + if (cancellationToken.IsCancellationRequested) return; + } + stopwatch.Stop(); + stopwatch.Reset(); + numberOfCasts--; + await Task.Delay(1000, cancellationToken); + } + if (!shouldStopFishing) + { + await ExitFishing(cancellationToken); + await Task.Delay(3000, cancellationToken); + } + } + + protected async Task CastLine(bool fishVariance, CancellationToken cancellationToken) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(FishingCoordinatesEnum.RedFishingButton); + + int randX = fishVariance ? _rand.Next(-_VARIANCE, _VARIANCE + 1) : 0; + int randY = fishVariance ? _rand.Next(-_VARIANCE, _VARIANCE + 1) : 0; + MoveCursor(x + randX, y + randY); + DoFishingClick(); + await Task.Delay(100, cancellationToken); // Adding a small delay for realism or replace with necessary async call + } + + protected async Task CheckIfFishCaught(CancellationToken cancellationToken) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(FishingCoordinatesEnum.RedFishingButton); + string color = HexConverter(GetColorAt(x, y - 600)); + if (color.Equals("#FFFFBE") || color.Equals("#FFFFBF")) return true; + + color = HexConverter(GetColorAt(x, 110)); + return color.Equals("#FFFFBE") || color.Equals("#FFFFBF"); + } + + protected async Task ExitFishing(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(FishingCoordinatesEnum.ExitFishingButton)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(FishingCoordinatesEnum.ExitFishingButton); + MoveCursor(x, y); + DoMouseClick(); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(FishingCoordinatesEnum.ExitFishingButton); + await ExitFishing(cancellationToken); + } + await Task.Delay(2000, cancellationToken); + } + + protected async Task SellFishAsync(CancellationToken cancellationToken) + { + retry: + if (CoordinatesManager.CheckCoordinates(FishingCoordinatesEnum.BlueSellAllButton))//returns true if they are not 0,0 + { + await Task.Delay(2100, cancellationToken); + var (x, y) = CoordinatesManager.GetCoordsFromMap(FishingCoordinatesEnum.BlueSellAllButton); + MoveCursor(x, y); + DoMouseClick(); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(FishingCoordinatesEnum.BlueSellAllButton); + //imgRecLocateSellBtn(); + goto retry; + } + await Task.Delay(2000, cancellationToken); + } + + protected async Task ManuallyLocateRedFishingButton() + { + await CoordinatesManager.ManualUpdateCoordinates(FishingCoordinatesEnum.RedFishingButton);//update the red fishing button coords + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/MMTenorTerraceFishing.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/MMTenorTerraceFishing.cs new file mode 100644 index 00000000..bf638352 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/MMTenorTerraceFishing.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public class MMTenorTerraceFishing : FishingStrategyBase + { + public override async Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + // Simulation of leaving the fishing dock & walking over to the fisherman to sell + InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); + await Task.Delay(1090, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); ; + await Task.Delay(2200, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + + await SellFishAsync(cancellationToken); + + // Simulation of going back to the dock + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(3000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingLocationsWalking/TTCPunchlinePlaceFishing.cs b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/TTCPunchlinePlaceFishing.cs new file mode 100644 index 00000000..d6475ec0 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingLocationsWalking/TTCPunchlinePlaceFishing.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using ToonTown_Rewritten_Bot.Views; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Services.FishingLocationsWalking +{ + public class TTCPunchlinePlaceFishing : FishingStrategyBase + { + public override async Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + // Simulation of leaving the fishing dock & walking over to the fisherman to sell + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(2000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + InputSimulator.SimulateKeyDown(VirtualKeyCode.RIGHT); + await Task.Delay(800, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.RIGHT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); + await Task.Delay(700, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + + await SellFishAsync(cancellationToken); // Call to sell fish asynchronously + + // Simulation of going back to the dock + InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN); + await Task.Delay(600, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.DOWN); + InputSimulator.SimulateKeyDown(VirtualKeyCode.LEFT); + await Task.Delay(750, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.LEFT); + InputSimulator.SimulateKeyDown(VirtualKeyCode.UP); + await Task.Delay(2000, cancellationToken); + InputSimulator.SimulateKeyUp(VirtualKeyCode.UP); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/FishingService.cs b/ToonTown Rewritten Bot/Services/FishingService.cs new file mode 100644 index 00000000..c8b1ad71 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/FishingService.cs @@ -0,0 +1,149 @@ +using System; +using System.Drawing; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Models; +using ToonTown_Rewritten_Bot.Services.FishingLocationsWalking; +using ToonTown_Rewritten_Bot.Utilities; +using static ToonTown_Rewritten_Bot.Models.Coordinates; + +namespace ToonTown_Rewritten_Bot.Services +{ + public class FishingService : FishingStrategyBase + { + /// + /// Initiates the fishing process for a given location with specified parameters. + /// + /// The location where fishing will take place. If "FISH ANYWHERE" is specified, the selling process is skipped. + /// The number of times to cast the fishing line. + /// The number of times to visit the fisherman to sell fish. If the location is "FISH ANYWHERE", selling is not performed. + /// Indicates whether a variance in casting should be applied for a more natural fishing experience. + /// Token to signal the cancellation of the fishing operation. + /// A task representing the asynchronous fishing operation. + /// + /// This method manages the entire fishing operation including preparing for fishing, casting, and optionally selling the fish based on the provided location. It utilizes different fishing strategies based on the specified location and handles selling operations unless fishing in the "FISH ANYWHERE" mode. + /// + public async Task StartFishing(string locationName, int casts, int sells, bool variance, CancellationToken cancellationToken, string customFishingFilePath = "") + { + while (sells > 0 && !cancellationToken.IsCancellationRequested) + { + await PrepareForFishing(cancellationToken); + await StartFishingActionsAsync(casts, variance, cancellationToken); + + if (locationName != FishingLocationNames.FishAnywhere && locationName != FishingLocationNames.CustomFishingAction) + { + // Hardcoded Fishing Locations' if + FishingStrategyBase fishingStrategy = DetermineFishingStrategy(locationName); + await fishingStrategy.LeaveDockAndSellAsync(cancellationToken); + sells--; + } + else if(locationName == FishingLocationNames.CustomFishingAction && customFishingFilePath != "") + { + // Custom Fishing's if + CustomActionsFishing customFishing = new CustomActionsFishing(customFishingFilePath); + await customFishing.LeaveDockAndSellAsync(cancellationToken); // Start the action sequence + sells--; + } + else + { + // If "FISH ANYWHERE" is selected, skip the selling process. + sells = 0; + } + } + + if(locationName == FishingLocationNames.CustomFishingAction && customFishingFilePath != "") + // Update the location name to only the file name without the extension + locationName = Path.GetFileNameWithoutExtension(customFishingFilePath); + + BringBotWindowToFront(); + MessageBox.Show($"Done Fishing in '{locationName}'."); + } + + /// + /// Starts a custom fishing debugging session using a specified JSON file. + /// + /// The path to the JSON file containing the custom actions to be executed. + /// + /// This method is intended for debugging custom fishing actions. It simulates the fishing actions + /// without actual fishing, focusing on the movement and actions defined in the JSON file. + /// It ensures the game window is maximized and focused before starting the actions + /// + public async Task StartCustomFishingDebugging(string jsonPath) + { + CustomActionsFishing customFishing = new CustomActionsFishing(jsonPath); + + // Prepare + MaximizeAndFocusTTRWindow(); + await Task.Delay(3000, CancellationToken.None); // Initial delay before starting. + await customFishing.LeaveDockAndSellAsync(CancellationToken.None); // Start the action sequence + MessageBox.Show("Done Debugging Custom Action"); + } + + + /// + /// Prepares the fishing environment by ensuring that the game window is focused and checking the necessary coordinates before starting the fishing process. + /// + /// A token to observe while waiting for the task to complete, allowing the operation to be cancelled. + /// A task representing the asynchronous operation of preparing the environment for fishing. + /// + /// This method focuses the game window and performs an initial delay to ensure the environment is ready for fishing actions. + /// It checks for the presence of the red fishing button within the game window. If the button's coordinates are not set or if the button cannot be automatically detected, + /// it prompts the user to manually locate the button. This preparation step is crucial for the subsequent fishing operations to run smoothly. + /// + private async Task PrepareForFishing(CancellationToken cancellationToken) + { + // Prepare for fishing based on initial conditions + MaximizeAndFocusTTRWindow(); + await Task.Delay(3000, cancellationToken); // Initial delay before starting. + + if (!CoordinatesManager.CheckCoordinates(FishingCoordinatesEnum.RedFishingButton)) // Checks the red fishing button + { + //imgRecLocateRedCastBtn();//use the image rec to locate the image and set the coordinates + + //manuallyLocateRedFishingButton(); + + if (isAutoDetectFishingBtnActive) + { + //do the image search for color here. Make it so you can use the search or manual set (temp code testing) + Image screenshot = ImageRecognition.GetWindowScreenshot(); + Point coords = await ImageRecognition.locateColorInImage(screenshot, _redFishingButtonColor, 10); + + //debugColorCoords(screenshot, coords); + + if (coords.X == 0 && coords.Y == 0)//color not found, manually update + { + MessageBox.Show("Unable to detect red fishing button."); + await ManuallyLocateRedFishingButton(); + } + else + CoordinatesManager.UpdateCoordinatesAutomatically(FishingCoordinatesEnum.RedFishingButton, coords); + } + else + await ManuallyLocateRedFishingButton(); + } + } + + private FishingStrategyBase DetermineFishingStrategy(string locationName) + { + return locationName switch + { + var location when location == FishingLocationNames.ToontownCentralPunchlinePlace => new TTCPunchlinePlaceFishing(), + var location when location == FishingLocationNames.DonaldDreamLandLullabyLane => new DDLLullabyLaneFishing(), + var location when location == FishingLocationNames.BrrrghPolarPlace => new BrrrghPolarPlaceFishing(), + var location when location == FishingLocationNames.BrrrghWalrusWay => new BrrrghWalrusWayFishing(), + var location when location == FishingLocationNames.BrrrghSleetStreet => new BrrrghSleetStFishing(), + var location when location == FishingLocationNames.MinniesMelodylandTenorTerrace => new MMTenorTerraceFishing(), + var location when location == FishingLocationNames.DonaldDockLighthouseLane => new DDLighthouseLaneFishing(), + var location when location == FishingLocationNames.DaisysGardenElmStreet => new DaisyGardenElmStFishing(), + _ => throw new NotImplementedException($"Fishing strategy for location '{locationName}' is not implemented."), + }; + } + + public override Task LeaveDockAndSellAsync(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + } +} diff --git a/ToonTown Rewritten Bot/Services/Gardening.cs b/ToonTown Rewritten Bot/Services/Gardening.cs new file mode 100644 index 00000000..3ebd757d --- /dev/null +++ b/ToonTown Rewritten Bot/Services/Gardening.cs @@ -0,0 +1,208 @@ +using System; +using System.Drawing; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Views; +using static ToonTown_Rewritten_Bot.Models.Coordinates; +using static ToonTown_Rewritten_Bot.Utilities.ImageRecognition; + +namespace ToonTown_Rewritten_Bot.Services +{ + public class Gardening : CoreFunctionality + { + public static async Task PlantFlowerAsync(string flowerCombo, CancellationToken cancellationToken) + { + if (!CoordinatesManager.CheckCoordinates(GardeningCoordinatesEnum.PlantFlowerRemoveButton)) + { + await CoordinatesManager.ManualUpdateCoordinates(GardeningCoordinatesEnum.PlantFlowerRemoveButton); + if (!CoordinatesManager.CheckCoordinates(GardeningCoordinatesEnum.PlantFlowerRemoveButton)) + return; + } + + //BringBotWindowToFront(); + //var confirmation = MessageBox.Show("Press OK when ready to begin!", "", MessageBoxButtons.OKCancel); + var confirmation = MessageBox.Show( + "Press OK when ready to begin!", + "Begin Gardening", + MessageBoxButtons.OKCancel, + MessageBoxIcon.None, + MessageBoxDefaultButton.Button1, + MessageBoxOptions.DefaultDesktopOnly); + if (confirmation == DialogResult.Cancel) + return; + + await Task.Delay(2000); + + var (x, y) = CoordinatesManager.GetCoordsFromMap(GardeningCoordinatesEnum.PlantFlowerRemoveButton); + MoveCursor(x, y); + DoMouseClick(); + await Task.Delay(2000); + + await CheckBeansAsync(GardeningCoordinatesEnum.RedJellybeanButton, cancellationToken); + + char[] beans = flowerCombo.ToCharArray(); + foreach (var bean in beans) + { + await SelectBeanAsync(bean, cancellationToken); + } + await PressPlantButtonAsync(cancellationToken); + + MessageBox.Show( + "Done!", + "Gardening Complete", + MessageBoxButtons.OKCancel, + MessageBoxIcon.None, + MessageBoxDefaultButton.Button1, + MessageBoxOptions.DefaultDesktopOnly); + } + + private static async Task SelectBeanAsync(char beanType, CancellationToken cancellationToken) + { + GardeningCoordinatesEnum location = beanType switch + { + 'r' => GardeningCoordinatesEnum.RedJellybeanButton, + 'g' => GardeningCoordinatesEnum.GreenJellybeanButton, + 'o' => GardeningCoordinatesEnum.OrangeJellybeanButton, + 'u' => GardeningCoordinatesEnum.PurpleJellybeanButton, + 'b' => GardeningCoordinatesEnum.BlueJellybeanButton, + 'i' => GardeningCoordinatesEnum.PinkJellybeanButton, + 'y' => GardeningCoordinatesEnum.YellowJellybeanButton, + 'c' => GardeningCoordinatesEnum.CyanJellybeanButton, + 's' => GardeningCoordinatesEnum.SilverJellybeanButton, + _ => throw new ArgumentException("Invalid bean type", nameof(beanType)), + }; + + if (!CoordinatesManager.CheckCoordinates(location)) + { + await CoordinatesManager.ManualUpdateCoordinates(location); + if (!CoordinatesManager.CheckCoordinates(location)) return; // Ensure coordinates are set after update. + } + var (x, y) = CoordinatesManager.GetCoordsFromMap(location); + MoveCursor(x, y); + DoMouseClick(); + await Task.Delay(2000, cancellationToken); + } + + private static async Task CheckBeansAsync(GardeningCoordinatesEnum location, CancellationToken cancellationToken) + { + int locationNumericalVal = Convert.ToInt32(location); + if (locationNumericalVal <= 10) + { + if (!CoordinatesManager.CheckCoordinates(location))//if they're 0,0 + { + await CoordinatesManager.ManualUpdateCoordinates(location); + GardeningCoordinatesEnum nextLocation = (GardeningCoordinatesEnum)(locationNumericalVal + 1); + if (Enum.IsDefined(typeof(GardeningCoordinatesEnum), nextLocation)) + { + await CheckBeansAsync(nextLocation, cancellationToken); + } + } + else + { + GardeningCoordinatesEnum nextLocation = (GardeningCoordinatesEnum)(locationNumericalVal + 1); + if (Enum.IsDefined(typeof(GardeningCoordinatesEnum), nextLocation)) + { + await CheckBeansAsync(nextLocation, cancellationToken); + } + } + } + } + + private static async Task PressPlantButtonAsync(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(GardeningCoordinatesEnum.BluePlantButton)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(GardeningCoordinatesEnum.BluePlantButton); + MoveCursor(x, y); + DoMouseClick(); + Thread.Sleep(8000); + await ClickOKAfterPlantAsync(cancellationToken); + await WaterPlantAsync(3, cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(GardeningCoordinatesEnum.BluePlantButton); + Thread.Sleep(2000); + await PressPlantButtonAsync(cancellationToken); + } + } + + private static async Task ClickOKAfterPlantAsync(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(GardeningCoordinatesEnum.BlueOkButton)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(GardeningCoordinatesEnum.BlueOkButton); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + Thread.Sleep(2000); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(GardeningCoordinatesEnum.BlueOkButton); + Thread.Sleep(2000); + await ClickOKAfterPlantAsync(cancellationToken); + } + } + + public static async Task WaterPlantAsync(int waterPlantCount, CancellationToken cancellationToken) + { + if (!CoordinatesManager.CheckCoordinates(GardeningCoordinatesEnum.WateringCanButton)) + { + await CoordinatesManager.ManualUpdateCoordinates(GardeningCoordinatesEnum.WateringCanButton); + // Recheck coordinates after update + if (!CoordinatesManager.CheckCoordinates(GardeningCoordinatesEnum.WateringCanButton)) + { + throw new InvalidOperationException("Watering can button coordinates not set."); + } + } + + var (x, y) = CoordinatesManager.GetCoordsFromMap(GardeningCoordinatesEnum.WateringCanButton); + + for (int i = 0; i < waterPlantCount; i++) + { + cancellationToken.ThrowIfCancellationRequested(); // Check if the operation has been cancelled + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await Task.Delay(4000, cancellationToken); + } + } + + public static async Task RemovePlantAsync(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(GardeningCoordinatesEnum.PlantFlowerRemoveButton)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(GardeningCoordinatesEnum.PlantFlowerRemoveButton); + MessageBox.Show("Press OK when ready to begin!"); + Thread.Sleep(2000); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + await SelectYESToRemoveAsync(cancellationToken); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(GardeningCoordinatesEnum.PlantFlowerRemoveButton);//update the plant flower button coords + await RemovePlantAsync(cancellationToken); + Thread.Sleep(2000); + } + + } + + private static async Task SelectYESToRemoveAsync(CancellationToken cancellationToken) + { + if (CoordinatesManager.CheckCoordinates(GardeningCoordinatesEnum.BlueYesButton)) + { + var (x, y) = CoordinatesManager.GetCoordsFromMap(GardeningCoordinatesEnum.BlueYesButton); + CoreFunctionality.MoveCursor(x, y); + CoreFunctionality.DoMouseClick(); + } + else + { + await CoordinatesManager.ManualUpdateCoordinates(GardeningCoordinatesEnum.BlueYesButton);//update the plant flower button coords + await SelectYESToRemoveAsync(cancellationToken); + Thread.Sleep(2000); + } + } + } +} diff --git a/ToonTown Rewritten Bot/BotFunctions.resx b/ToonTown Rewritten Bot/Services/Gardening.resx similarity index 100% rename from ToonTown Rewritten Bot/BotFunctions.resx rename to ToonTown Rewritten Bot/Services/Gardening.resx diff --git a/ToonTown Rewritten Bot/Services/GolfService.cs b/ToonTown Rewritten Bot/Services/GolfService.cs new file mode 100644 index 00000000..1b029d31 --- /dev/null +++ b/ToonTown Rewritten Bot/Services/GolfService.cs @@ -0,0 +1,60 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Models; +using ToonTown_Rewritten_Bot.Services.CustomGolfActions; +using ToonTown_Rewritten_Bot.Views; +using WindowsInput; +using static System.Windows.Forms.Design.AxImporter; + +namespace ToonTown_Rewritten_Bot.Services +{ + class GolfService + { + public static async Task StartCustomGolfAction(string filePath, CancellationToken cancellationToken) + { + // Initialize the CustomActionsGolf with the file path + CustomActionsGolf customGolfActions = new CustomActionsGolf(filePath); + + try + { + // Perform the actions read from the JSON file + await customGolfActions.PerformGolfActions(cancellationToken); + } + catch (OperationCanceledException) + { + Console.WriteLine("Operation was canceled by the user."); + } + catch (Exception ex) + { + MessageBox.Show($"An error occurred: {ex.Message}"); + } + } + + public static GolfActionCommand[] GetCustomGolfActions(string filePath) + { + if (!File.Exists(filePath)) + { + Debug.WriteLine("File does not exist: " + filePath); + return new GolfActionCommand[0]; // Return an empty array if the file doesn't exist + } + + string json = File.ReadAllText(filePath); + return JsonConvert.DeserializeObject(json); + } + + public static string GetCustomGolfActionFilePath(string fileName) + { + // Get the directory where the executable is running. + string exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + // Combine the executable path with the "Custom Golf Actions" folder name and the file name. + return Path.Combine(exePath, "Custom Golf Actions", fileName + ".json"); + } + } +} diff --git a/ToonTown Rewritten Bot/Racing.cs b/ToonTown Rewritten Bot/Services/Racing.cs similarity index 99% rename from ToonTown Rewritten Bot/Racing.cs rename to ToonTown Rewritten Bot/Services/Racing.cs index a2dcad1f..cb5002ac 100644 --- a/ToonTown Rewritten Bot/Racing.cs +++ b/ToonTown Rewritten Bot/Services/Racing.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using WindowsInput; -namespace ToonTown_Rewritten_Bot +namespace ToonTown_Rewritten_Bot.Services { class Racing { diff --git a/ToonTown Rewritten Bot/Settings.cs b/ToonTown Rewritten Bot/Services/Settings.cs similarity index 100% rename from ToonTown Rewritten Bot/Settings.cs rename to ToonTown Rewritten Bot/Services/Settings.cs diff --git a/ToonTown Rewritten Bot/Thumbs.db b/ToonTown Rewritten Bot/Thumbs.db deleted file mode 100644 index 8b9137be..00000000 Binary files a/ToonTown Rewritten Bot/Thumbs.db and /dev/null differ diff --git a/ToonTown Rewritten Bot/ToonTown Rewritten Bot.csproj b/ToonTown Rewritten Bot/ToonTown Rewritten Bot.csproj index 9fb05869..afc1bddc 100644 --- a/ToonTown Rewritten Bot/ToonTown Rewritten Bot.csproj +++ b/ToonTown Rewritten Bot/ToonTown Rewritten Bot.csproj @@ -47,6 +47,27 @@ false + + + + + + + + + + + + + + + + + + + + + False @@ -69,12 +90,58 @@ false + + + Never + + + + + + + + + + Never + + + Never + + + Never + + + Never + + + Never + + + Never + + + Never + + + Never + + + Never + + + Never + + + Never + + + - + all - + \ No newline at end of file diff --git a/ToonTown Rewritten Bot/ToonTown Rewritten Bot.csproj.user b/ToonTown Rewritten Bot/ToonTown Rewritten Bot.csproj.user index 2d9a08c5..32585542 100644 --- a/ToonTown Rewritten Bot/ToonTown Rewritten Bot.csproj.user +++ b/ToonTown Rewritten Bot/ToonTown Rewritten Bot.csproj.user @@ -12,42 +12,42 @@ false - <_LastSelectedProfileId>C:\Users\primetime43\source\repos\Toontown-Rewritten-Bot\ToonTown Rewritten Bot\Properties\PublishProfiles\FolderProfile.pubxml + <_LastSelectedProfileId>C:\source control\repos\Toontown-Rewritten-Bot\ToonTown Rewritten Bot\Properties\PublishProfiles\FolderProfile.pubxml - + Form - + Form - + Form - + Form - + Form - + Form - + Form - + Form - + Form - + Form - + Designer diff --git a/ToonTown Rewritten Bot/Utilities/GithubReleaseChecker.cs b/ToonTown Rewritten Bot/Utilities/GithubReleaseChecker.cs new file mode 100644 index 00000000..1d0e2a28 --- /dev/null +++ b/ToonTown Rewritten Bot/Utilities/GithubReleaseChecker.cs @@ -0,0 +1,76 @@ +using System; +using System.Diagnostics; +using System.Net.Http; +using System.Net.Http.Json; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace ToonTown_Rewritten_Bot.Utilities +{ + public static class GithubReleaseChecker + { + private static readonly HttpClient client = new HttpClient { BaseAddress = new Uri("https://api.github.com/") }; + private const string repoOwner = "primetime43"; + private const string repoName = "Toontown-Rewritten-Bot"; + private const string userAgent = "request"; + + static GithubReleaseChecker() + { + if (!client.DefaultRequestHeaders.Contains("User-Agent")) + { + client.DefaultRequestHeaders.Add("User-Agent", userAgent); + } + } + + public static async Task CheckForNewVersion() + { + string url = $"repos/{repoOwner}/{repoName}/releases/latest"; + try + { + var release = await client.GetFromJsonAsync(url); + if (release != null) + { + CompareAndPrompt(release); + } + else + { + MessageBox.Show("No new releases found.", "Check for Updates", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + catch (Exception ex) + { + MessageBox.Show($"Failed to check for updates: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private static void CompareAndPrompt(Release release) + { + string currentVersion = GlobalSettings.ApplicationInfo.Version; + if (release.tag_name != currentVersion) + { + var result = MessageBox.Show($"New version available: {release.tag_name}\nDo you want to download it?", + "Update Available", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + + if (result == DialogResult.Yes) + { + Process.Start(new ProcessStartInfo + { + FileName = $"https://github.com/{repoOwner}/{repoName}/releases/latest", + UseShellExecute = true + }); + } + } + else + { + Debug.WriteLine("You are already using the latest version.", "No Updates", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + public class Release + { + public string tag_name { get; set; } + public string name { get; set; } + public DateTime published_at { get; set; } + } + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Utilities/GlobalSettings.cs b/ToonTown Rewritten Bot/Utilities/GlobalSettings.cs new file mode 100644 index 00000000..46c66747 --- /dev/null +++ b/ToonTown Rewritten Bot/Utilities/GlobalSettings.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ToonTown_Rewritten_Bot.Utilities +{ + public class GlobalSettings + { + public static class ApplicationInfo + { + public static string Version { get; } = "1.5.0"; + public static readonly string ReleaseDate = ""; + public static string Author { get; } = "primetime43"; + } + } +} diff --git a/ToonTown Rewritten Bot/ImageRecognition.cs b/ToonTown Rewritten Bot/Utilities/ImageRecognition.cs similarity index 87% rename from ToonTown Rewritten Bot/ImageRecognition.cs rename to ToonTown Rewritten Bot/Utilities/ImageRecognition.cs index efd75d54..aff5c5e9 100644 --- a/ToonTown Rewritten Bot/ImageRecognition.cs +++ b/ToonTown Rewritten Bot/Utilities/ImageRecognition.cs @@ -13,7 +13,7 @@ using System.Threading.Tasks; using System.Drawing.Imaging; -namespace ToonTown_Rewritten_Bot +namespace ToonTown_Rewritten_Bot.Utilities { class ImageRecognition { @@ -21,8 +21,8 @@ public static Image GetWindowScreenshot() { string windowName = "Toontown Rewritten"; // Find the window by name - IntPtr windowHandle = NativeMethods.FindWindow(null, windowName); - if (windowHandle == IntPtr.Zero) + nint windowHandle = NativeMethods.FindWindow(null, windowName); + if (windowHandle == nint.Zero) { throw new ArgumentException("Window not found."); } @@ -100,10 +100,14 @@ public struct Rect } [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] - public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + public static extern nint FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] - public static extern bool GetWindowRect(IntPtr hWnd, ref Rect lpRect); + public static extern bool GetWindowRect(nint hWnd, ref Rect lpRect); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetForegroundWindow(IntPtr hWnd); } #endregion } diff --git a/ToonTown Rewritten Bot/Utilities/ScreenCapture.cs b/ToonTown Rewritten Bot/Utilities/ScreenCapture.cs new file mode 100644 index 00000000..08153be8 --- /dev/null +++ b/ToonTown Rewritten Bot/Utilities/ScreenCapture.cs @@ -0,0 +1,48 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; + +namespace ToonTown_Rewritten_Bot.Utilities +{ + public class ScreenCapture + { + [DllImport("user32.dll")] + private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); + + [StructLayout(LayoutKind.Sequential)] + private struct RECT + { + public int Left; + public int Top; + public int Right; + public int Bottom; + } + + public static Bitmap CaptureGameWindow(IntPtr gameWindowHandle) + { + // Get the dimensions of the game window + if (GetWindowRect(gameWindowHandle, out RECT rect)) + { + int width = rect.Right - rect.Left; + int height = rect.Bottom - rect.Top; + + // Create a new bitmap with the size of the window + Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); + + // Create a graphics object from the bitmap + using (Graphics gfxBmp = Graphics.FromImage(bmp)) + { + // Use CopyFromScreen to capture the specific window + gfxBmp.CopyFromScreen(rect.Left, rect.Top, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy); + } + + return bmp; + } + else + { + throw new InvalidOperationException("Unable to capture the game window."); + } + } + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/AboutBox1.Designer.cs b/ToonTown Rewritten Bot/Views/AboutBox1.Designer.cs similarity index 98% rename from ToonTown Rewritten Bot/AboutBox1.Designer.cs rename to ToonTown Rewritten Bot/Views/AboutBox1.Designer.cs index 039775d9..cbe75823 100644 --- a/ToonTown Rewritten Bot/AboutBox1.Designer.cs +++ b/ToonTown Rewritten Bot/Views/AboutBox1.Designer.cs @@ -62,7 +62,7 @@ private void InitializeComponent() textBoxDescription.Size = new System.Drawing.Size(316, 147); textBoxDescription.TabIndex = 23; textBoxDescription.TabStop = false; - textBoxDescription.Text = "This program is a bot that will perform certain time consuming tasks on ToonTown Rewritten."; + textBoxDescription.Text = "This program is a bot that will perform certain time consuming tasks on Toontown Rewritten."; // // labelCompanyName // @@ -108,7 +108,7 @@ private void InitializeComponent() labelProductName.Name = "labelProductName"; labelProductName.Size = new System.Drawing.Size(316, 20); labelProductName.TabIndex = 19; - labelProductName.Text = "ToonTown Rewritten Bot"; + labelProductName.Text = "Toontown Rewritten Bot"; labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // logoPictureBox diff --git a/ToonTown Rewritten Bot/AboutBox1.cs b/ToonTown Rewritten Bot/Views/AboutBox1.cs similarity index 89% rename from ToonTown Rewritten Bot/AboutBox1.cs rename to ToonTown Rewritten Bot/Views/AboutBox1.cs index daa57a51..980db2c2 100644 --- a/ToonTown Rewritten Bot/AboutBox1.cs +++ b/ToonTown Rewritten Bot/Views/AboutBox1.cs @@ -1,11 +1,7 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Linq; +using System; using System.Reflection; -using System.Threading.Tasks; using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Utilities; namespace ToonTown_Rewritten_Bot { @@ -14,10 +10,10 @@ partial class AboutBox1 : Form public AboutBox1() { InitializeComponent(); - this.Text = String.Format("About {0} by primetime43", AssemblyTitle); + this.Text = String.Format("About {0} by " + GlobalSettings.ApplicationInfo.Author, AssemblyTitle); this.labelProductName.Text = AssemblyProduct; - this.labelVersion.Text = "Version 1.4.1"; - this.labelCopyright.Text = "Programmed by primetime43"; + this.labelVersion.Text = "Version " + GlobalSettings.ApplicationInfo.Version; + this.labelCopyright.Text = "Programmed by " + GlobalSettings.ApplicationInfo.Author; this.labelCompanyName.Text = AssemblyCompany; this.textBoxDescription.Text = "This program is a bot that will perform certain time consuming tasks on ToonTown Rewritten."; } diff --git a/ToonTown Rewritten Bot/Fishing.resx b/ToonTown Rewritten Bot/Views/AboutBox1.resx similarity index 93% rename from ToonTown Rewritten Bot/Fishing.resx rename to ToonTown Rewritten Bot/Views/AboutBox1.resx index 1af7de15..af32865e 100644 --- a/ToonTown Rewritten Bot/Fishing.resx +++ b/ToonTown Rewritten Bot/Views/AboutBox1.resx @@ -1,17 +1,17 @@  - diff --git a/ToonTown Rewritten Bot/AdvancedSettings.Designer.cs b/ToonTown Rewritten Bot/Views/AdvancedSettings.Designer.cs similarity index 100% rename from ToonTown Rewritten Bot/AdvancedSettings.Designer.cs rename to ToonTown Rewritten Bot/Views/AdvancedSettings.Designer.cs diff --git a/ToonTown Rewritten Bot/AdvancedSettings.cs b/ToonTown Rewritten Bot/Views/AdvancedSettings.cs similarity index 100% rename from ToonTown Rewritten Bot/AdvancedSettings.cs rename to ToonTown Rewritten Bot/Views/AdvancedSettings.cs diff --git a/ToonTown Rewritten Bot/AdvancedSettings.resx b/ToonTown Rewritten Bot/Views/AdvancedSettings.resx similarity index 100% rename from ToonTown Rewritten Bot/AdvancedSettings.resx rename to ToonTown Rewritten Bot/Views/AdvancedSettings.resx diff --git a/ToonTown Rewritten Bot/Views/AdvancedTemp.cs b/ToonTown Rewritten Bot/Views/AdvancedTemp.cs new file mode 100644 index 00000000..b31b2057 --- /dev/null +++ b/ToonTown Rewritten Bot/Views/AdvancedTemp.cs @@ -0,0 +1,15 @@ +using System; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Windows.Forms; + +namespace ToonTown_Rewritten_Bot.Views +{ + class AdvancedTemp : AdvancedSettings + { + + } +} diff --git a/ToonTown Rewritten Bot/DevForm.resx b/ToonTown Rewritten Bot/Views/AdvancedTemp.resx similarity index 100% rename from ToonTown Rewritten Bot/DevForm.resx rename to ToonTown Rewritten Bot/Views/AdvancedTemp.resx diff --git a/ToonTown Rewritten Bot/Views/CustomFishingActions.Designer.cs b/ToonTown Rewritten Bot/Views/CustomFishingActions.Designer.cs new file mode 100644 index 00000000..76919a6e --- /dev/null +++ b/ToonTown Rewritten Bot/Views/CustomFishingActions.Designer.cs @@ -0,0 +1,166 @@ +namespace ToonTown_Rewritten_Bot.Views +{ + partial class CustomFishingActions + { + /// + /// 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(CustomFishingActions)); + addItemBtn = new System.Windows.Forms.Button(); + removeItemBtn = new System.Windows.Forms.Button(); + comboBox1 = new System.Windows.Forms.ComboBox(); + actionTimeTxtBox = new System.Windows.Forms.TextBox(); + label1 = new System.Windows.Forms.Label(); + saveActionItemBtn = new System.Windows.Forms.Button(); + loadActionItemBtn = new System.Windows.Forms.Button(); + actionItemsListBox = new System.Windows.Forms.ListBox(); + updateSelectedActionItemBtn = new System.Windows.Forms.Button(); + SuspendLayout(); + // + // addItemBtn + // + addItemBtn.Location = new System.Drawing.Point(250, 49); + addItemBtn.Name = "addItemBtn"; + addItemBtn.Size = new System.Drawing.Size(91, 28); + addItemBtn.TabIndex = 1; + addItemBtn.Text = "Add Item"; + addItemBtn.UseVisualStyleBackColor = true; + addItemBtn.Click += addItemBtn_Click; + // + // removeItemBtn + // + removeItemBtn.Location = new System.Drawing.Point(347, 49); + removeItemBtn.Name = "removeItemBtn"; + removeItemBtn.Size = new System.Drawing.Size(91, 28); + removeItemBtn.TabIndex = 2; + removeItemBtn.Text = "Remove Item"; + removeItemBtn.UseVisualStyleBackColor = true; + removeItemBtn.Click += removeItemBtn_Click; + // + // comboBox1 + // + comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + comboBox1.FormattingEnabled = true; + comboBox1.Items.AddRange(new object[] { "WALK FORWARDS", "WALK BACKWARDS", "TURN LEFT", "TURN RIGHT", "TIME", "SELL FISH" }); + comboBox1.Location = new System.Drawing.Point(250, 15); + comboBox1.Name = "comboBox1"; + comboBox1.Size = new System.Drawing.Size(188, 23); + comboBox1.TabIndex = 3; + comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged; + // + // actionTimeTxtBox + // + actionTimeTxtBox.Enabled = false; + actionTimeTxtBox.Location = new System.Drawing.Point(250, 179); + actionTimeTxtBox.Name = "actionTimeTxtBox"; + actionTimeTxtBox.Size = new System.Drawing.Size(144, 23); + actionTimeTxtBox.TabIndex = 4; + actionTimeTxtBox.TextChanged += actionTimeTxtBox_TextChanged; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(250, 161); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(117, 15); + label1.TabIndex = 5; + label1.Text = "Time for action (ms):"; + // + // saveActionItemBtn + // + saveActionItemBtn.Location = new System.Drawing.Point(174, 274); + saveActionItemBtn.Name = "saveActionItemBtn"; + saveActionItemBtn.Size = new System.Drawing.Size(144, 34); + saveActionItemBtn.TabIndex = 6; + saveActionItemBtn.Text = "Save Action Item"; + saveActionItemBtn.UseVisualStyleBackColor = true; + saveActionItemBtn.Click += saveActionItemBtn_Click; + // + // loadActionItemBtn + // + loadActionItemBtn.Location = new System.Drawing.Point(14, 274); + loadActionItemBtn.Name = "loadActionItemBtn"; + loadActionItemBtn.Size = new System.Drawing.Size(144, 34); + loadActionItemBtn.TabIndex = 7; + loadActionItemBtn.Text = "Load Action Item"; + loadActionItemBtn.UseVisualStyleBackColor = true; + loadActionItemBtn.Click += loadActionItemBtn_Click; + // + // actionItemsListBox + // + actionItemsListBox.FormattingEnabled = true; + actionItemsListBox.ItemHeight = 15; + actionItemsListBox.Location = new System.Drawing.Point(14, 13); + actionItemsListBox.Name = "actionItemsListBox"; + actionItemsListBox.Size = new System.Drawing.Size(230, 244); + actionItemsListBox.TabIndex = 8; + actionItemsListBox.SelectedIndexChanged += actionItemsListBox_SelectedIndexChanged; + // + // updateSelectedActionItemBtn + // + updateSelectedActionItemBtn.Enabled = false; + updateSelectedActionItemBtn.Location = new System.Drawing.Point(250, 83); + updateSelectedActionItemBtn.Name = "updateSelectedActionItemBtn"; + updateSelectedActionItemBtn.Size = new System.Drawing.Size(188, 28); + updateSelectedActionItemBtn.TabIndex = 9; + updateSelectedActionItemBtn.Text = "Update Selected Item"; + updateSelectedActionItemBtn.UseVisualStyleBackColor = true; + updateSelectedActionItemBtn.Click += updateSelectedActionItemBtn_Click; + // + // CustomFishingActions + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(453, 320); + Controls.Add(updateSelectedActionItemBtn); + Controls.Add(actionItemsListBox); + Controls.Add(loadActionItemBtn); + Controls.Add(saveActionItemBtn); + Controls.Add(label1); + Controls.Add(actionTimeTxtBox); + Controls.Add(comboBox1); + Controls.Add(removeItemBtn); + Controls.Add(addItemBtn); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); + Name = "CustomFishingActions"; + Text = "Custom Fishing Actions Manager"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + private System.Windows.Forms.Button addItemBtn; + private System.Windows.Forms.Button removeItemBtn; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.TextBox actionTimeTxtBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button saveActionItemBtn; + private System.Windows.Forms.Button loadActionItemBtn; + private System.Windows.Forms.ListBox actionItemsListBox; + private System.Windows.Forms.Button updateSelectedActionItemBtn; + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Views/CustomFishingActions.cs b/ToonTown Rewritten Bot/Views/CustomFishingActions.cs new file mode 100644 index 00000000..fd63df3c --- /dev/null +++ b/ToonTown Rewritten Bot/Views/CustomFishingActions.cs @@ -0,0 +1,217 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Models; +using ToonTown_Rewritten_Bot.Services; + +namespace ToonTown_Rewritten_Bot.Views +{ + public partial class CustomFishingActions : Form + { + public CustomFishingActions() + { + InitializeComponent(); + } + + private void addItemBtn_Click(object sender, EventArgs e) + { + string selectedItem = comboBox1.SelectedItem?.ToString() ?? ""; + if (selectedItem == "TIME") + { + // Now parse the time input as milliseconds + if (int.TryParse(actionTimeTxtBox.Text, out int timeInMilliseconds)) + { + // Add the time in milliseconds to the ListBox + actionItemsListBox.Items.Add($"{selectedItem} ({timeInMilliseconds} milliseconds)"); + actionTimeTxtBox.Clear(); // Optionally clear the TextBox after adding + } + else + { + MessageBox.Show("Please enter a valid time in milliseconds.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + else if (!string.IsNullOrEmpty(selectedItem)) + { + // For other selections, just add the selected item directly + actionItemsListBox.Items.Add(selectedItem); + } + else + { + MessageBox.Show("Please select an item from the ComboBox.", "No Selection", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + + private void removeItemBtn_Click(object sender, EventArgs e) + { + actionItemsListBox.Items.Remove(actionItemsListBox.SelectedItem); + } + + private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) + { + if (comboBox1.SelectedItem.ToString() == "TIME") + actionTimeTxtBox.Enabled = true; + else + actionTimeTxtBox.Enabled = false; + } + + private void actionTimeTxtBox_TextChanged(object sender, EventArgs e) + { + + } + + private void listBox1_SelectedIndexChanged(object sender, EventArgs e) + { + + } + + private FishingActionKeys _fishingActionKeys = new FishingActionKeys(); + private void saveActionItemBtn_Click(object sender, EventArgs e) + { + List actionsList = new List(); + + foreach (var item in actionItemsListBox.Items) + { + string actionText = item.ToString(); + string action, command; + + if (actionText.StartsWith("TIME")) + { + action = "TIME"; + command = actionText.Split('(')[1].Split(' ')[0]; // Extracts "XXXX milliseconds" from "TIME (XXXX milliseconds)" + } + else + { + action = actionText; + command = _fishingActionKeys.GetKeyCodeString(actionText); + if (string.IsNullOrEmpty(command)) + { + command = "UNKNOWN"; // Handle the case where no key code is found for the action + } + } + + actionsList.Add(new FishingActionCommand { Action = action, Command = command }); + } + + string json = Newtonsoft.Json.JsonConvert.SerializeObject(actionsList, Newtonsoft.Json.Formatting.Indented); + SaveToJsonFile(json); + } + + private void SaveToJsonFile(string jsonContent) + { + string folderPath = (string)CoreFunctionality.ManageCustomActionsFolder("Fishing", false); // Getting the folder path only + + SaveFileDialog saveFileDialog = new SaveFileDialog + { + Filter = "JSON File|*.json", + Title = "Save an Actions JSON File", + InitialDirectory = folderPath + }; + + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + File.WriteAllText(saveFileDialog.FileName, jsonContent); + MessageBox.Show($"Actions saved to {saveFileDialog.FileName}", "Save Successful", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + private void loadActionItemBtn_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new OpenFileDialog + { + Filter = "JSON File|*.json", + Title = "Open an Actions JSON File", + InitialDirectory = (string)CoreFunctionality.ManageCustomActionsFolder("Fishing", false) + }; + + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + string json = File.ReadAllText(openFileDialog.FileName); + var actionsList = Newtonsoft.Json.JsonConvert.DeserializeObject>(json); + + actionItemsListBox.Items.Clear(); + foreach (var actionCommand in actionsList) + { + string displayText = actionCommand.Action == "TIME" + ? $"TIME ({actionCommand.Command})" + : actionCommand.Action; + actionItemsListBox.Items.Add(displayText); + } + } + } + + private void actionItemsListBox_SelectedIndexChanged(object sender, EventArgs e) + { + // Check if an item is actually selected + if (actionItemsListBox.SelectedItem != null) + { + updateSelectedActionItemBtn.Enabled = true; + string selectedItem = actionItemsListBox.SelectedItem.ToString(); + + // Check if the selected item is a "TIME" entry + if (selectedItem.StartsWith("TIME")) + { + // Select "TIME" in comboBox1 if available + comboBox1.SelectedItem = "TIME"; + + // Extract the numeric value (time in seconds) + string timeValue = new String(selectedItem.Where(char.IsDigit).ToArray()); + + // Set the extracted time into textBox1 + actionTimeTxtBox.Text = timeValue; + } + else + { + // For non-time actions, find and select the action in comboBox1 + comboBox1.SelectedItem = selectedItem; + + // Since it's not a time action, disable or clear textBox1 + actionTimeTxtBox.Clear(); + actionTimeTxtBox.Enabled = false; + } + } + } + + private void updateSelectedActionItemBtn_Click(object sender, EventArgs e) + { + if (actionItemsListBox.SelectedItem == null) + { + MessageBox.Show("No item is selected to update."); + return; + } + + int selectedIndex = actionItemsListBox.SelectedIndex; + string selectedItem = comboBox1.SelectedItem?.ToString() ?? ""; + + if (selectedItem == "TIME") + { + if (int.TryParse(actionTimeTxtBox.Text, out int timeInMilliseconds)) + { + // Update the item in the ListBox with the new time in milliseconds + actionItemsListBox.Items[selectedIndex] = $"{selectedItem} ({timeInMilliseconds} milliseconds)"; + } + else + { + MessageBox.Show("Please enter a valid time in milliseconds.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + } + else if (!string.IsNullOrEmpty(selectedItem)) + { + // Update the item with the new action from the comboBox + actionItemsListBox.Items[selectedIndex] = selectedItem; + } + else + { + MessageBox.Show("Please select a valid action.", "No Action Selected", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + } + } +} diff --git a/ToonTown Rewritten Bot/Views/CustomFishingActions.resx b/ToonTown Rewritten Bot/Views/CustomFishingActions.resx new file mode 100644 index 00000000..940fa3ce --- /dev/null +++ b/ToonTown Rewritten Bot/Views/CustomFishingActions.resx @@ -0,0 +1,1499 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + AAABAAEAjY0AAAEAIADQQQEAFgAAACgAAACNAAAAGgEAAAEAIAAAAAAApDYBABIXAAASFwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUDAElbDgxVVRUMVVUVDElVFQA9 + SRUAPUkVAD1JFQA9SRUAPUkVAD1JFQA9SRUAPUkVAElhFQ1ZZhQAZmYPAEBABAAAAAEAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAE1mCgpS + UhkGS1cpCVBfVgtZZnALVF9zC1FecgtFU3ILRVNyC0VRcgtFUXILRVFyC0VRcgtFU3ILSFdyC1JfcwtW + ZnEITl9bBlFdLApYYhoLYGoYAE5ODQBVVQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAgBNZgoITVUhDlVjSAtVYHgMUFyTCk1XywpSX+UNT13nDE1b5wpJVucKSljnDEpY5wxK + WOcMSljnDEpX5wpLWOcMS1nnDE9c6AxRXuUJS1nQCktYnAxWYoANWmV3CVJeUQhkdCEVaoAMAFWqAwAA + gAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAIAW1sOB1VjJApUZUkLT1uHCk1ZugpQXOUMUV3xDFRh/Qxb + af8OYXD/EGZ3/xFqfP8RbID/Em+B/xJvg/8Sb4L/Em5//xFrff8QZnf/D2Jy/w1ba/8MVmT9DVBe8gxQ + XusJUV3kC09bwg1XZokJXWlVBltmLRBYYCAAQEAMAFVVAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRJBwdXXyMMVmJWDFBelQlN + W8gLTVrxDFNg/A9da/8RbH3/FIKV/xiTq/8Yn7r/GKjF/xiryP8Zrsz/GbDP/xqwz/8Zr8//Ga/N/xmr + yv8YqsX/GKS9/xeXsf8Wh57/E3aK/xBmdv8OWmn/DVNh/QtOXvEJT1zSClFcrg1LWI4NTl9ODVdrJgBV + VQkAVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + gAIAVVUPCktfMwpUX4MKT17HC01c7gxUYvwQZHX/FH6T/xeXrv8Yp8L/GbTR/xu41/8butj/G7rX/xu6 + 1/8butf/G7rX/xu61/8butf/G7rX/xu61/8butf/G7rY/xu51/8bttP/Ga/L/xeivf8Xkqv/FH6T/xBo + ef8PV2b+Ck9c+QhMWesLTlzBDVZliwpOXEsHV1cjAFWABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACAgIACgICACGZmZgqZmZkFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAADMzBQdQXyMMUV1YCk9elQpMW+EMVGD8EGJz/xR/lf8Xnbf/GrLO/xq4 + 1v8budb/GrfV/xq21P8attP/GrbT/xq20/8attT/GrbT/xq20/8attP/GrbT/xq20/8atdL/GrXS/xq2 + 1P8auNX/GrjW/xq51/8budb/GbHP/xeivv8UjKP/EnCC/w9cav8KUF37CUxc6gxMWcAKTliCEFNjMQB0 + iwsAVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgIACcY5xCXd3 + dw+Ojo4JAAAAAQAAAAAAAAAAAAAAAFVVVQN2gHYceHx1RnuBe013iHcvqqqqCQAAAAAAAAAAAAAAAAAA + AAFtkkkHbW1tDmaAZgpVVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKysGC0pVLQpQXYMJTV3NCUxZ7Q1Y + Zv4TdYf/F5mx/xmy0P8butf/GrfW/xq31P8attT/GrjU/xq31v8auNX/GrfW/xq31v8attT/GrbU/xq2 + 1f8at9b/GrjW/xq41f8at9b/GrfV/xq30/8attP/GrXS/xq10v8attP/GrjU/xq51v8auNX/GKvI/xWQ + qv8TdYj/Dl5s/wpOXPsKTFveDlNilw1ecVEJansdAFWqAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAFVVVQN2gG0ceoV3S3qAel5+gXZFqqqqEgAAAAEAAAAAAAAAAoCJgBp2fXRsb3Rtv32D + esqAhH+Vp7GnNFVVVQMAAAAAAAAAAICAgAptdm02b3dvXHh4eEiEjoQbqqqqAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr + KwYLVVstDVRihQlOXt4JTVv/EV5s/xWAlv8Yq8n/GrvX/xq41P8at9T/GrjV/xq51v8bt9T/GrLR/xqu + yf8YpsH/F6C3/xaZsv8Wlq//Fpat/xaXsP8WnbX/GKG7/xmpxP8asM3/GrXS/xu41P8autf/GrjW/xq2 + 0/8attP/GrXS/xq10v8attP/G7jX/xq41v8Yrcn/FpGp/xNvgf8OWGn9C01d7wtVZcINX2p0DV5yJhFm + Zg8AAIACAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAIyMjBR6gnhkdnx1wHR6dNpzeG+znKacUI6O + jgkAAAAAgICABoCNhDp3enS0bnRu/I+Vjf2JkYjao6ygaZKSbQcAAAAAAAAAAHyDfCdyeXKJcnly0nt/ + e7uDiYFhkp6SFf///wEAAAAAAAAAAAAAAAAAAAAA////AQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAACtVBgxRVywMT1yFCU5d3QpOXP8RZHP/Foqk/xiuy/8auNf/GrjU/xq4 + 1/8audf/GrTQ/xinwf8Xlq7/FIaa/xNyhf8QYXD/D1Vi/w5PXP8OTVn/Dk1Y/w5NW/8OUV7/EFpo/xFo + eP8TeY3/FYug/xeZsv8YpsP/GrPQ/xu62P8audf/GrfU/xq20/8atdL/GrXS/xq30/8buNb/GrfU/xeo + wv8Vh5//D2h4/wtSX/kKTFnTDFRijw9jb1UVYGoYkpKSB2uGeRNvhXoXgICABgAAAAAAAAAAgICAAnZ8 + didzeHCidnx094iPh/98gnzrj5WNi5mjmRkAAAAAbZJtB36FfkF+g3zAkJeP/ay0q/6cpZzhkZmRdqqq + qgkAAAAAmZmZBX6BflF7gHi/iY+I+I+Yj++NlIyblqGWLv///wIAAAAAAAAAAJmZmQV5eXkVd4B3HoaG + hhO/v78EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAEBkRRKQpOW4YJUFzbC1Bd/xJm + d/8Wkqj/GbLP/xu51/8audX/GrfV/xquyf8XnbT/FICV/xBjc/8PU2L/DU5a/wxJVv8NSVT/DUtZ/w5P + XP8OUWD/DlFf/w5QX/8OTVv/DUtX/w1JVf8NSlf/DlBd/w9YZf8QYnP/FHuP/xaVrv8Yp8T/GbLP/xu5 + 1v8bt9b/GrbT/xq10v8atdL/GrfU/xu51P8ass//F5y0/xJ0if8NWGj8ClBc6wtWY74aYm5rUWhoQl1p + Zmtgbmlyc3hzNYCAgAYAAAAAgICAAnmAeSp4gHisjZaM+amyqf+ZopfxfoR7pJmkny2AgIACkpKSB3h8 + eEJ5gHnCl5+W/aWtpP6aoZnhjJOMdqqqqgkAAAABhpJ5FW91b4x/hH/npKqi/6y2rPOlrqWkpaqlM4CA + gAIAAAAAqqqqBoKIgi11enJrcXdvh32FfWKOlY4kv7+/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAASmAYCU1bcAdNWOQMT1z/EWZ1/xeVr/8bttL/G7rX/xq41/8btdL/Fpmx/xFoev8OT13/DUtW/wxO + Wv8PVWP/D1xr/w9ebv8OXm//DV5v/w1ebv8NXW7/DF1u/wxdbv8MXm7/DV5v/w1db/8OXGz/Dlpp/w5V + Y/8PT1z/DEZT/wxJVf8QXW3/E3uP/xeivf8attX/G7fX/xq31P8atdL/GrXS/xq10v8bt9T/G7fU/xmr + x/8Wi6P/EGZ2/wtQX/kOUl7bLlRbwlNYU+JbX1ribGplkICAeCQAAAAAgICAAnmGeSp+hHuqh42I+aSr + o/+epp77goqC0o2XjWWAmYAUoqKiFnuGe111fHXPn6ed/aWspP6epp7pmqGYjaGhoRuAkoAOiIiEPHB1 + cMaHjob6pq2k/6Sro/OlraWiqK2jMoCAgAIAAAABgI+AIG52cH9wdm/aeH129ICDfM6KkohpmbOZFAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVVQMOXmg2DFJeqAlOWvoQYG3/Foyl/xu00f8audb/GrjX/xmq + xf8Teoz/D09b/w1JU/8NUmD/Dltp/w9ecP8OX2//DVxr/wxbav8NXGz/DVxs/w5cbf8QXW3/EV9t/xFe + bv8PXW3/DVxs/w1cbP8NXGz/DVxs/w1dbv8OXm7/DlRj/w5LWf8NT1z/DEpW/xBaaf8UfJL/GKXC/xq4 + 1f8at9b/GrfT/xq10v8atdL/GrbT/xu31f8ZsdD/F5Wv/xJtgP8LU2D+FFBa/EViZP9pcGv5YF5bxWpq + ZFJ0dHQLgICAAoCGgCp+hH6qh42G+aSro/+jqqL/kJeQ7nyGfKaFlIVWfoZ+YXqCeq15fnnxoqih/6Ws + o/+gqZ/4kJeQy36Dfm+Dg4NOgYV+f3+Gf+eXn5f/p66m/6SqovOjqaKnpKifNaqqqgOAmYAKbnJrSmdr + Z7WEiYT2oKif/aCqn9WfqJ9tqraqFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAUBALU2ByCk5c3A1a + Z/4VhZr/GK/P/xq62P8atdT/F5+7/xFtfv8MQkz/DEZS/w9ZaP8PX2//Dltr/w1bav8RXW3/HGV0/zFy + gP9Ggo3/UoiU/1iNlv9jlZ7/aZeg/2aWnv9ckJn/UoiU/02FkP8+fIj/J2x6/xlicv8PXG3/DFVk/w1S + Yf8OXm3/Dltp/w5SYP8MSlb/EF1t/xWIn/8Zq8f/GrfX/xq31P8attP/GrXS/xq20/8at9X/G7TQ/xee + uf8SdYr/D1ho/xlXYv9Hamz/ZWtm7V5bVqZrdm9FjIyMFH2CfTd+hH6who2G+aSro/+lrKP/m6Ob/H2E + e+p3fHbMcHZx1G5zbfGGi4T/pKuj/6SspP+gp6D/hIuE92txbNt8gXzKe4B62YmQiPujq6P/payk/6Cn + n/iepJ2+nJ+aWJWVjR2Ag4BAbXBrm3d8eOaaoJr+qLGn9KizqKqttq07mZmZBQAAAAAAAAAAgICABHR0 + dAttgG0OYGBgCP///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAFWABgVgajUKTlutDFFf8xN3iv8YqMX/G7vY/xq20/8Xla3/D1lp/wxGUP8PWWn/DlZl/wxT + Y/8OXGv/F2Ny/zBygP9RipT/iK20/7jJzP/V2dn/3t3d/9/c3P/h3dz/497d/+Hf3f/f29z/3dzb/9ja + 2f/H0dL/pL3B/3ahqP9Ig43/Lmt3/xpcav8PXGz/DFxs/wxcbP8PW2r/DVBe/wxJVv8Ranv/F5y2/xm0 + 0P8auNb/GrfU/xq10v8atdL/GrfU/xu10v8XpsH/E3yS/wxXZP8XVWD/P2Vm/1dfWe1ia2eudHlwcG50 + bn13fnjMiI+I+6Sqo/+lq6P/oamh/5Oak/+Hjof+j5eP/pmgmP+iqaL/o6qj/6Oqov+hqqH/oKaf/5ee + lv+SmpL+kJWP/p6lnv+krKP/pauj/5qgmf+Ijojsg4aCsX6BeoJyd3KlcHZw5o6Vjf6orqb/pa2l8Kuz + q5eurq4pAAAAAQAAAACAgIAEcXhxJG1wbVJqbWpecntyOoiZiA8A/wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIACB2BnJQ5ZaJALUF3pEGR1/xidt/8audf/G7bV/xaS + qv8OU2D/DElU/w9ca/8OXm7/C1Zn/xNVZv80dYH/bZ6m/7DKzf/f4uL/8uvp/+3o5v/l4+H/4t/f/9/f + 3//f3Nz/3dzc/93c3P/f3dz/393d/+De3v/l4eD/7OXj/+vl5f/V2tr/r8DE/3mhqP8/fYr/Imh2/w9c + bf8MWmr/DV1t/w9ZZ/8OTFn/DlVj/xWDmf8Zrsv/G7rX/xq30/8atdL/GrXS/xq10v8attL/GKfD/xN9 + kf8PWWn/F1Rf/0BiY/9aXlr2aGpm4mltaOV7gXv4mJ6Y/6Sro/+jq6P/pKqh/6SspP+mr6f/pauj/6Sr + o/+kq6P/o6qi/6Oqov+jqqL/pKyk/6WspP+lrKT/pq+m/6Srov+jqqL/pKuj/56lnP+JkIn/fIF79XN3 + cehqbWnzhIuE/6Sro/+kraT/pa2k8Kuzq5eorq4pAAAAAUBAQAR0fHQha3Jtd2luashobmjXdHh0o4OL + g0Kfn58IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXV0LDlVmWgxT + YdYLVGL/FX2U/xu30/8bu9n/FZex/w5VZP8NSlf/D11u/w1eb/8NWWn/Hmd1/12Omf+zys//8/Ly//35 + 9v/x7ev/5OTj/+Hi4v/g4OD/4ODg/9/g4P/e4OD/3uDg/97f3//f39//4ODg/+Dg4P/f39//4OHg/+bl + 5f/u6en/8uno/+zm5P/F0NH/ia2z/0qFj/8dZHT/C1lq/wxbbf8OXWz/D1Bf/w1LWP8SboD/F6C8/xu6 + 2P8at9b/GrXS/xq10v8atdT/GrbU/xemw/8TfpP/D1hn/xZTX/9BYGD/bHBq/4uQh/+jqaL/pK2l/6Kp + of+gqZ//oKig/6GooP+iqaD/pKqj/6WspP+lrKT/o6qi/6Oqov+jqqL/o6qi/6Spo/+jqqL/oqmh/6Gp + oP+hqKD/oaig/6Oro/+nrqb/pauj/5WclP+PlpD/naae/6SrpP+kq6P/o6ui8qCnoKOlqqUzgICACGxs + bCFgZmBwaG5nzoCGf/uIj4j+gYmB1IqUimacnJwSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAgAIAUV4mDVRjmAtMWvERanv/GJ66/xu83f8Yobz/EGBv/w1IU/8PXGz/Dlxs/xJd + bf84eIf/hbC2/9vo6v/6+vr/6enp/97e3v/m5+f/5+fn/+Pj4//j4+P/4eHh/+Hh4f/h4eH/4uLi/+Li + 4v/i4uL/4+Pj/+Tk5P/k5OT/2dnZ/7CwsP+0tbX/3t/f/+Xk5f/t5+f/8Ojn/8fR0/9+pq3/PXuJ/xdh + cf8MWmr/DV1t/w5WY/8NS1b/EWNz/xactf8attT/GrjW/xq10v8atdL/GrfT/xq21P8ZpsH/FH6S/w1a + af8hXGX/YXx6/5KXj/+boZr/n6ie/6Wso/+psan/sLew/7e9tv+/xL//wsfC/7a8tf+iqaH/o6mh/6Oq + ov+jqqL/pKqj/7K2sf+/xL//vcK8/7S7s/+utKz/p66n/6Sqov+hqaH/o6qi/6iupv+osKj/pa2l/6Oq + ov+krKP/l5yW+YOIgsyAhH1yeoF2Q2ZsZnZiaWLKgYiC96WupP+ss6v1qLCosqKpokeOqo4JAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOYg0LUmNdC1Je1gtTYP8ViZ7/Gbra/xms + yP8RZXX/DEhU/w9dbf8NXGz/EVts/0WBj/+61Nj/+/r6//v6+v/j4+P/kZGR/25ubv/Dw8P/7+/v/+fn + 5//j4+P/4uLi/+Li4v/k5OT/5OTk/+Tk5P/m5ub/5ubm/+jo6P/r6+v/xcXF/1VVVf9FRUX/qqqq/+vr + 6//j4+P/5OPj/+rl5v/s5uX/xNDR/3Cepf8qcH3/DVlp/wxcbf8PXGv/DlFd/w9ZZ/8VjaT/GrbV/xu5 + 1v8atdL/GrXS/xq21P8bttP/GKnE/xN9kv8MVmX/IFZg/2R6ef+hopz/tbm0/8fMx//Z29f/5ujm/+/w + 7f/19fX/7u/v/7y9vP+HjYf/n6ad/6Oro/+jqaL/o6uj/7zAuv/o6ej/8/Pz/+jp6P/e4N7/0dbQ/8LG + wP+0urT/qbCq/6Opof+gqKD/oqqi/6Sqov+lrKP/mp6Z/36FfvpxeXLbbXRtxGpvat6FjIX6o6qi/6eu + pvukrKLWpK2kc6q1qhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVAwZb + YSoNWWigCUtb9xBlc/8Yp8H/GrfU/xN+kv8NSVX/DlZm/w5cbf8SXWz/QoCN/63M0P/5+/r/+fj3//T0 + 9P/U1dX/WVlZ/ygoKP+FhYX/8/Pz/+rq6v/j4+P/4eHh/+Hh4f/j4+P/5OTk/+fn5//o6Oj/6enp/+rq + 6v/u7u7/2tra/5mZmf9LS0v/b29v/+jo6P/n5+f/5OTl/+Tj5P/m5eT/7Onm/9/g4P+euL3/QX2K/xFe + bv8MWmr/Dlxr/w9QXv8NU1//FIqg/xq20v8buNb/GrXS/xq10v8atdP/GrXT/xikvv8Sdor/D1Nh/zdm + bv+nsK3/4N3c//Hw8f/5+fn/+/r7//j4+P/29vb/5ubm/6qrqv97f3r/oaie/6Oro/+jqqL/oqmi/7K3 + sf/f39//9/f3//r6+v/7+vv/+Pr4//Hy8f/j5eL/0NbS/7/Ev/+wt7D/qK+n/6SrpP+jqqL/payk/6Oq + ov+Um5T+goiC/IuRiv2iqaH/pq6k/aSqouKnrqeRpa+lM5nMmQUAAAAAAAAAAW1tbQdqgGoMgICACmaZ + ZgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAADtiDQtRWlsLTlvUC1Ff/xR/lP8butr/F5y1/w5OWv8MUF3/D15u/xFc + bP8+fIv/rcvR/+/u7f/y8fD/9/f3//b29v/p6en/i4uL/yMjI/9tbW3/8vLy/+zs7P/j4+P/3t7e/9bW + 1v/Y2Nj/4+Pj/+jo6P/r6+v/7Ozs/+7u7v/u7u7/9fX1/9PT0/9VVVX/a2tr/9HR0f/r6+v/6enp/+fn + 5//l5+b/5OTk/+nn5f/p5uX/wc3R/1yQm/8bYXL/DFts/w5ebv8PU2H/DU9a/xWFmf8auNX/G7jV/xq1 + 0v8atdL/GrbT/xu00P8WnLb/D22B/xdZZf9qjJX/zc3O/+Xj4v/h4eH/1tbW/8nKyv+9vb3/r6+v/4yO + jP97gHv/oamg/6Oro/+kqqL/oqmi/56kn/+traz/v7+//9DQ0P/d3N3/6unq//X09f/6+vr/+fr4/+3v + 7P/Q0tD/rLGs/56lnv+iqaH/o6uj/6WspP+mraX/pauj/6WspP+krKP/oqmi96Sqorijp6NLqqqqCQAA + AACAgIACeXl5FW93bzxmbGZVcHZwUIWKhTCVlZUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIACB1VjJApNWpwFS1n2EFxr/xea + t/8atdT/E3qN/wxJVv8OXGr/DVxs/y90gf+jxcr/8O3t/+Dd3f/v7+//+Pj4//b29v/09PT/ycnJ/1lZ + Wf9cXFz/zs7O/+3t7f/j4+P/vr6+/5ycnP+oqKj/zMzM/+bm5v/r6+v/7u7u//Dw8P/w8PD/9PT0/+7u + 7v+kpKT/VFRU/4qKiv/x8fH/7u7u/+np6f/o6Oj/5+fn/+bm5v/m5eT/6+fm/9Xa2v95o6r/JGt5/wxa + af8OWGf/DUtZ/w1UYf8Vi6L/GrjV/xq31f8atdL/GrXS/xq20/8ZsM3/FpSu/w9leP8gXGf/cYmO/6ik + pP+dnZz/jI+N/3p8ev9tb23/a3Br/3J1cv+Jj4j/pKuj/6Oqov+kq6P/o6mh/4uSi/9wc27/a3Br/36A + fv+TlZP/qKmo/8DAwP/Y2Nj/6urp/+3t7P/GxcX/h4mF/4ePiP+kq6P/o6uj/6Oqov+jqqL/oqqi/6Or + o/+kq6L/oqqh+J2jmsSSm5BekpKSFYCAgARqdWoYcHNwW2pvaa9qbWrUcXZxz4SKgpeVnpU6gKqABgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAQEAEBUpYNwtTYLgITlz8E3CD/xmy0f8XmbH/D1Ri/w1VY/8MXW3/GGZ0/36ss//29PT/4N3c/9nb + 2//v7+//+fn5//X19f/39/f/9/f3/8vLy/92dnb/nJyc//Hx8f/W1tb/mZmZ/6ioqP+hoaH/mJiY/8rK + yv/r6+v/7u7u//Hx8f/09PT/9PT0//f39//p6en/sLCw/8nJyf/09PT/7+/v/+7u7v/s7Oz/6+vr/+np + 6f/n5+f/5ubm/+zp5//k4+L/jK61/yFmc/8LT17/DVVl/w9UYv8OVmT/FZKp/xu62f8at9T/GrXS/xq1 + 0v8atdP/Ga3K/xWJoP8OWmr/IlRf/1JeXv9ra2f/c3l0/32Dff+Ijof/lpyU/6Clnf+kq6P/o6ui/6Oq + ov+jqqL/pKuj/6GpoP+ZoJb/jZSM/32Eff93fXf/dHl0/3R5df+FiIX/pqem/7i5uP+RlJL/dHl0/5Sb + k/+mrqb/o6qi/6Oqov+iqqL/pKqi/6Oqof+kqqL/oamh/5CXjvF7gXu2eH54W3R6dC5scWxhZm9ovHd+ + d/OUnJP/jZSL9oOJgcean5dipaWlEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVVUSCVRfdglOW+MMVWP+FpKp/xq41v8Rb4D/DEdT/w1c + bP8TXW3/YJeg/97n6f/g4OD/1dXV/97e3v/v7+//+/v7//f39//29vb/9vb2//n5+f/19fX/8PDw//Dw + 8P+8vLz/p6en//z8/P/q6ur/vLy8/5OTk//BwcH/7e3t/+/v7//w8PD/8vLy//Pz8//29vb/+/v7//n5 + +f/z8/P/8/Pz//Pz8//w8PD/7+/v/+3t7f/r6+v/6Ojo/+jo6P/v7Oz/6ujp/521uf81cH3/DFlp/w1c + a/8PVWL/EFpp/xeXrf8bu9n/GrfU/xq10v8atdP/GrbS/xmoxP8SfpP/DVdm/zFcYf+Bi4P/oaae/6at + pP+nr6b/p6+n/6Sro/+jq6P/o6qi/6Oqov+jqqL/o6qi/6SspP+lraT/qK+n/6ivp/+mrqb/oKig/5Sa + k/+DiYP/fIF7/3V6dv9yeHL/jZWN/6aupv+kq6L/oaig/6atpv+4vrj/uL24/6eupf+hqaD/o6ui/5+o + n/+Olo32fIJ70nZ7driDiILUlJyU96Ksov+nrqb2pqumvamup2ugpqArkpKSBwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEJXnsbC1ponwdM + WfkQYXL/GKjF/xejvv8PUmH/DFJh/w1bbP81dYT/sMzR/+zp6f/Y2Nj/29vb/9/f3//t7e3/+vr6//r6 + +v/39/f/9/f3//b29v/5+fn/+/v7//T09P/CwsL/r6+v//39/f/z8/P/4ODg/6+vr/+cnJz/z8/P/+zs + 7P/o6Oj/6urq/+zs7P/x8fH/9PT0//b29v/39/f/9vb2//X19f/z8/P/8vLy//Dw8P/v7+//7e3t/+Tk + 5P/U1dX/49/f/+rp6f+fur//O3iF/wxZaf8NWmr/D1Zk/xFldf8XnbX/G7rZ/xq30/8atdL/GrXU/xq0 + 0P8Xnbf/EnSI/xtdaf9VdXb/k5aQ/6Clnf+hqaH/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+kqqL/pa2l/6aupv+mraX/naWd/5CXkP+SmpL/oKig/6SspP+iqaD/pKqj/7e9 + tv/a3dn/3uHe/8HGwP+qsan/oqmh/6Sso/+jqqH/lp6V+5KZk/acpJz7pq2l/6aspfqkqKHUo6ehd6Wt + pSKZmZkFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEJaHEbDFZgpAtPXPkSdIn/GbTR/xN9kf8MR1L/DVpr/xhhcv97qrP/6Ozs/97d + 3P/Z2tr/3d3d/+Hh4f/s7Oz/+vr6//v7+//6+vr/+vr6//n5+f/4+Pj/+vr6//n5+f/Z2dn/tra2//z8 + /P/6+vr/7+/v/9vb2/+tra3/oKCg/97e3v/n5+f/5+fn/+rq6v/p6en/7+/v//f39//5+fn/+fn5//j4 + +P/39/f/9fX1//Pz8//z8/P/9PT0/+Li4v+enp7/lJWV/+zq6v/s6er/n7u+/zFyf/8JV2j/Dltq/w1R + X/8Ranz/GKrE/xu72P8atdL/GrXS/xq21P8asc3/F5Ou/xFpe/8lXWj/c4SC/5+hlv+gp6D/pKqi/6Sr + o/+kqqL/pKqi/6Sqov+kqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+kq6P/pa2l/6au + pv+mraX/pKuj/6Oqov+iqKH/pKmj/7/Cvf/n6Of/+fn5/+jr6P/JzMj/rLKq/6CpoP+jq6P/payk/6au + pv+mraT/pKuj/qSpo96mq6KJoaehMaqqqgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgAIIZHQhCkxZqw1SYfoViaD/GrLQ/w9d + bP8MTlr/DV5u/zJ1hP+71dn/7urp/9rZ2f/d3d3/4ODg/+Hh4f/s7Oz/+vr6//v7+//6+vr/+vr6//r6 + +v/6+vr/+vr6//z8/P/p6en/t7e3/9vb2//+/v7/+Pj4/+rq6v/Dw8P/gICA/6SkpP/AwMD/ubm5/8nJ + yf/l5eX/7e3t//X19f/6+vr/+vr6//r6+v/6+vr/9/f3//b29v/29vb/9vb2/9XV1f9lZWX/SEhI/87N + zf/29PX/4ePi/46vtf8gZnf/CVhp/w9YaP8OU2L/FH2S/xq20/8at9X/GrXS/xq10/8attP/GarF/xKD + mv8UYnH/R3Fz/5KVjv+gpZ3/pKuk/6Wro/+kq6P/pKuj/6Sro/+krKP/pKuj/6Sro/+lq6P/pKuj/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+lq6P/nKKc/5WZlP+4uLj/6urq//r6 + +v/t7uv/yMzI/6qwqf+jqaH/oqqi/6Oro/+kq6L/oquh/KKqocOqraRRqqqqDAAAAAAAAAABaoCADHqF + eheAl4AWiYl2DVWqVQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA + YAgSY3VICk9czw1cavwYnbf/F6TA/w5IVP8MUWD/FGFx/2icp//h6er/4+Df/9zc3P/f39//4ODg/+Tk + 5P/t7e3/+/v7//39/f/8/Pz/+/v7//z8/P/8/Pz//Pz8//v7+//l5eX/pKSk/6Kiov/y8vL/8vLy/83N + zf+np6f/kpKS/6ioqP+5ubn/qKio/5ycnP/Dw8P/6urq//X19f/7+/v//f39//v7+//7+/v/+vr6//f3 + 9//4+Pj/9/f3/9DQ0P9cXFz/Li4u/5GRkf/r6+v/7+7t/9bc3P91n6r/FmFx/wtZa/8PWGb/D1xt/xaW + r/8butj/GrbS/xq10v8attT/GrPS/xebtv8Sc4f/I2Vw/2qAf/+bm5L/mqCZ/5eel/+VnZX/lZyU/5Sc + lP+WnJT/maCZ/56knf+gqKD/o6mg/6Sro/+kqqP/pKuj/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+lrKT/nqae/4aMhf9+gX7/q6yr/+Tk5P/7+/v/6uzp/8XJxP+pr6j/oaih/6Kqof+krKP/n6ee/ZCY + kNSKkYx2n6WfMIuTiyF9iH0rfoR+U3N3c3hsdWp4e4F7TZKekhUAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaaREQYW9xCU9c8BFoev8YrMj/FIqf/wxCTv8KUWD/KGh3/6nH + zP/w7Or/3t3d/+Pj4//j4+P/4+Pj/+Xl5f/t7e3/+fn5//39/f/8/Pz//Pz8//z8/P/8/Pz//f39/+zs + 7P+2trb/paWl/6Kiov+4uLj/vb29/62trf/AwMD/19fX/+fn5//n5+f/29vb/7e3t/+VlZX/0NDQ//b2 + 9v/7+/v//f39//39/f/8/Pz/+vr6//r6+v/6+vr/+fn5/+zs7P+pqan/TExM/1NTU//X19f/8vHx/+zp + 6f/J1Nb/VouY/wpZaf8MWmv/D1Zl/xJrfP8Yq8b/GrrY/xq10f8attP/GrfT/xityf8UjKP/FWp7/zpo + b/9vc23/bnJs/2puav9mamT/Y2hj/2RoY/9nbWf/bXFs/3R4dP99gn3/iY+I/5iel/+fpp//o6qj/6Sr + o/+kqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/pKui/5+mnv+Jj4j/en56/6Okov/h4uH/+fn5/+jq + 5//DxsL/pq2m/6KqoP+kq6P/oamg/4iPh/V5f3nLh42HnX+EgItpbmuZanFswHh9duB+hX7dgIiAn4uU + izmAqoAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNWRQMVmN8Ck9a9hJ2 + iv8ZsdD/EGp6/wxJVf8NV2f/QnuH/9Pj5P/p5eX/xMTE/7y8vP/o6Oj/5+fn/+fn5//s7Oz/+fn5//39 + /f/9/f3//f39//39/f/9/f3/+fn5/9PT0/+fn5//2tra/8zMzP+JiYn/n5+f/9nZ2f/5+fn//v7+//n5 + +f/29vb/9/f3/9/f3/+VlZX/r6+v//b29v/9/f3//f39//7+/v/+/v7//Pz8//v7+//6+vr/+vr6//v7 + +//v7+//r6+v/4qKiv/b29v/8fHx/+ro6P/q5ub/q8LF/yVsev8IV2j/Dlpo/w9XZv8UiJ3/G7va/xq3 + 1P8atdH/GrXT/xq00f8Wobz/E3qP/xtea/80Rkj/Pz46/0BEQf9CRUH/QURB/0JFQv9DSEP/Q0dD/0NF + Qf9GSUb/UFRQ/2hsaP98gXz/kJWP/52jnP+kq6P/pauj/6Oqo/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Ss + pP+jq6P/i5OL/3l+eP+go6H/4eLi//v7+v/l5eT/vMG8/6Wtpf+kq6P/pauk/5igmP99g3z6cnZx73N6 + c+t5f3nvhIqE+JKakv+YnpX0j5aOuYyViVKdsZ0NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAgBVVSQMS1iWDE5a+BSEmf8Zrcr/DlNf/w1RX/8OXm7/WpGc/+jt7f/k4eD/paam/2dn + Z//AwMD/8vLy/+vr6//t7e3/9/f3//7+/v/+/v7//v7+//7+/v/+/v7/+Pj4/83Nzf+tra3/+fn5/9DQ + 0P+bm5v/z8/P////////////+fn5/+jo6P/n5+f//f39/+Tk5P+bm5v/rKys//b29v/+/v7//v7+//7+ + /v/+/v7//f39//z8/P/7+/v/+vr6//r6+v/5+fn/9fX1/+bm5v/t7e3/7u7u/+rp6f/s6en/3N7f/2uZ + ov8RXm7/DFlq/w5ZZv8RZ3j/GaXA/xu92f8atdL/GrXS/xq20/8Yrcn/FY6o/xFqe/8hTFP/RUZB/1FV + T/9UWlX/VlxV/1ZbVv9VWlT/UlZS/0tQS/9ESEP/P0I+/0BFQf9KTkr/Wl5a/3h7dv+TmJH/oKaf/6Sr + o/+jq6P/o6qi/6Oqov+jqqL/o6qi/6Oqov+lrKT/o6yj/4yTjP95fnj/q62s/+zt7P/5+Pj/2NjX/62x + q/+gpp7/o6qh/6SspP+Xnpb/hYuE/4uRi/+bo5v/pq6k/6aupvOiqqK9mqOYcpSZlDKOqo4JAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF10CwpQWVAJSlTJDFNh/ReRp/8XpMD/DUlW/wxX + Zv8WY3P/d6iv/+/u7P/g39//wsPD/3p6ev9xcXH/u7u7/+3t7f/w8PD/9vb2//39/f/+/v7//v7+//7+ + /v/+/v7/9fX1/76+vv+SkpL/4eHh/8jIyP+mpqb/9fX1//39/f/s7Oz/yMjI/8HBwf/Z2dn/6Ojo/8nJ + yf+ZmZn/y8vL//z8/P///////v7+//7+/v/+/v7//v7+//39/f/9/f3//Pz8//v7+//5+fn/+vr6//r6 + +v/z8/P/7+/v/+zs7P/q6en/6ejn/73N0P9GgY3/C1lq/w5Zaf8PWGj/E32T/xq41P8at9X/GrXS/xq1 + 0/8as9H/F6K9/xN/lP8iZXD/VWJd/2psZP9rcGr/a3Bq/2twa/9rcWr/am9q/2huZ/9jaWP/XWFb/1RX + Uv9LTkv/RUlE/0tOSv9bYFz/eH13/5WblP+jqaH/o6uj/6Oqov+jqqL/o6qi/6Oqov+jqqL/payk/6Oq + ov+NlIz/g4mD/7CxsP/a2tv/wsLC/4yPi/+KkIr/oqmh/6WspP+kq6P/pKyk/6atpf+krKT/paqi7aOq + o7SnsKdXo62tGaqqqgYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVDxBY + Zm4JTVnoDllo/xictP8XnLb/DUtX/wxZaP8mbn7/m7/E/+7o5//d3d3/5eXl/9HR0f97e3v/WFhY/62t + rf/29vb/9/f3//z8/P/+/v7//v7+//7+/v/7+/v/4eHh/6Wlpf+ampr/tra2/8jIyP+1tbX/2dnZ/9LS + 0v+qqqr/mpqa/6SkpP+8vLz/uLm4/56env+Wlpb/4+Pj///////////////////////+/v7//v7+//7+ + /v/+/v7//v7+//39/f/7+/v/+fn5//f39//19fX/8/Pz/+7u7v/q6+v/7Orq/+nn5v+YtLr/HWd1/wlZ + af8OWGj/EGR1/xaet/8butn/GrTS/xq10v8atdP/Gq3K/xSSqv8ZcoL/Q2Vm/2hqY/9tcGz/bHJt/2xx + a/9scWz/bHFs/2xxa/9scWr/a3Fr/2lvaP9lamT/XWNd/09VT/9CRkH/SEpH/2drZv+Mkor/oKaf/6Sr + ov+jq6P/o6qi/6Oqov+jqqL/o6qi/6aspP+lq6P/io+I/3x/e/+Nj47/g4WD/3J2cv+LkIr/o6qj/6Sr + o/+jqqL/o6uj/6Gpov+hqKHzpKqktKWupVWurq4T/wAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAFVmDxBkdG4KVmPoDl1s/xejvv8Wj6f/Dkxa/wtZaf89fov/vNPX/+rk + 4//d3Nz/5OTk/+Tk5P+enp7/Pz8//4+Pj//39/f/+fn5//z8/P/+/v7//v7+//7+/v/4+Pj/zc3N/6Gg + of/U1NT/ubm5/7S0tP+8vLz/sLCw/52dnf+FhYX/lZWV/6enp//FxcX/ycnJ/7m5uf+kpKT/y8vL//r6 + +v///////////////////////v7+//7+/v/+/v7//v7+//7+/v/9/f3/+/v7//n5+f/29vb/8/Pz//Hx + 8f/t7e3/6enp/+zp6P/S2dn/WY6Y/wtZav8OWmn/D1lo/xN9kv8bt9T/GrfV/xq10v8atdL/GrPQ/xag + vP8Tf5T/Lmpx/15oY/9ub2n/bHJt/21zbP9tc2z/bHJs/2xybP9scmz/bHJr/2twa/9rcGv/aW9p/2Rq + ZP9aX1r/S09L/0VJRf9bYFv/g4qC/5+knP+kq6P/o6qi/6Oqov+jqqL/o6qi/6Oqov+mraX/n6ae/4eN + hv92enb/fIJ8/5CWj/+gpp//pKqj/6Oqov+jqqL/o6qi/6CpoP+epp7jnqSchqW0pSKAgIACAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZ3DxBmeW4KWWXoD2N0/xmp + xv8UgZf/DU5b/wtba/9Sj5n/2+Tm/+bi4v/d3d3/4+Pj/+Li4v++vr7/oaGh/9HR0f/39/f/9vb2//z8 + /P/+/v7//v7+//7+/v/7+/v/19fX/6ampv/k5OT/5ubm/83Nzf/Ly8v/p6en/5ycnP+ampr/sbGx/9LS + 0v/Z2dn/09PT/+Tk5P/CwsL/tLS0//T09P///////////////////////v7+//7+/v/+/v7//v7+//7+ + /v/+/v7/+/v7//r6+v/39/f/9fX1//Pz8//v7+//6+vr/+vq6f/q5ub/pLu//xxndv8JWWn/Dldm/xJr + ev8Yq8b/G7rZ/xq10v8atdL/GrbT/xmsyP8Uj6f/IHF//1FoZv9sbWX/bXNs/21zbP9tc2z/bXNs/21z + bP9tc2z/bHJs/2xybf9scWv/a3Br/2pvav9obmj/Ymhi/1NZU/9HS0f/VlpV/36Dfv+dpJz/o6uj/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/pK2k/6CmoP+Yn5j/nqWd/6SspP+krKP/o6mi/6Kqof+jqqL/pKqi/6Kp + of+Pl4/tho6Enp+onzVtbW0HgJmACnZ2dhp4eHgge3txG3R0dAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAGaIDxBoe24LWGboD2p8/xqtyP8SdYn/DE1c/wxdbP9nnaf/7u7v/+Lf3//d3d3/4+Pj/+Xl + 5f/q6ur/8fHx//T09P/z8/P/9vb2//z8/P///////v7+//7+/v//////8fHx/8HBwf+4uLj/3t7e/+7u + 7v/X19f/paWl/6Ghof+ysrL/2tra/7S0tP9oaGj/hISE/9fX1/+3t7f/x8fH//n5+f////////////// + ///////////////////+/v7//v7+//7+/v/+/v7//Pz8//v7+//5+fn/9vb2//Pz8//w8PD/7+/v/+7t + 7f/u6ur/0dfY/1CIlP8JWGn/Dltp/xBhcf8VlK3/G7vZ/xq30/8atdL/GrbU/xqzz/8WnLj/GHuO/z9q + bP9pamP/bHJr/25zbP9tc2z/bXNs/21zbP9tc2z/bXNs/21zbP9tc2z/bHJs/2xxa/9rb2n/aW5o/2Rp + ZP9YXlf/SUxI/1VYVP+Ch4H/oKef/6Wro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Sro/+lrKT/pKuj/6Oq + ov+hqaH/oaig/6Krov+lq6P/o6qj/6Sro/+RmI/8fod+znyFfnF2gHY2fIN8THV5dXprcWuManJqfXh8 + eEiqqqoSAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZ3DxBtfW4MXGzoEG6D/xqvy/8Rbn7/DE9f/w1e + bv92p7D/9PLy/9/e3f/f39//4+Pj/+fn5//q6ur/7+/v//Dw8P/09PT/9/f3//v7+/////////////// + /////////v7+/+zs7P+8vLz/ubm5/8vLy/+zs7P/jo6O/46Ojv/Pz8//5+fn/4yMjP8hISH/Ozs7/6Sk + pP++vr7/6urq/////////////////////////////////////////////v7+//7+/v/+/v7//v7+//v7 + +//6+vr/9/f3//b29v/v7+//ysrK/6+vr//Y2Nj/5+Xl/5q1uf8ZYXD/ClVk/w9VZP8Sd4r/GbHP/xq6 + 1/8atdL/GrbT/xq20v8Yp8P/FIWe/ytwe/9eaWX/bXBp/21zbf9tc2z/bXNs/21zbP9tc2z/bXNs/21z + bP9tc2z/bXNs/2xybP9scWv/am9p/2huaP9la2X/Wl9Z/0lNSf9eYV7/jZOM/6Opof+kq6P/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/o6qh/6Kqov+mrKT/r7ev/7W8tf+qsar/oqqi/6Sro/+ep57/iI+H7m93 + cMFveG+hc351unN6c99xeXHqcnly4oOJgaKjq6M9qqqqBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZ3DxBr + fW4LXG3oEXSK/xquzP8Ranj/DFBh/w5fbv97qrP/9vHx/93d3P/g4OD/4+Pj/+fn5//q6ur/7u7u//Hx + 8f/09PT/+Pj4//v7+//9/f3///////////////////////7+/v/x8fH/19fX/9jY2P/Nzc3/ra2t/4uL + i//Gxsb/3t7e/6urq/9JSUn/Gxsb/3l5ef/s7Oz//f39//////////////////////////////////// + //////////////7+/v/+/v7//v7+//v7+//7+/v/+fn5//n5+f/o6Oj/j4+P/0xMTP+dnZz/6+jo/8nS + 1f89d4P/Bktb/w5SYP8RY3T/F6G6/xu62f8attL/GrXS/xu30/8arsv/FJWs/x56jP9ObGr/bG5n/21y + bP9tc2z/bnNs/21zbP9tc2z/bXNs/21zbP9tc2z/bXNs/21zbP9scmz/bHFs/2pvav9pb2j/ZWtk/1de + V/9OUk7/am9p/5Sblf+kqqP/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oqmh/6StpP+4v7n/19vX/9bY + 1/+ts67/naSc/6Oqov+lq6P/maCY/oeQh/eKkYjxj5eO+JKZkf6TmpP9j5aO+pGaj8mgqaBZqqqqDAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAFVmDwlYaG4KUmLoEXiO/xqvzf8RZ3j/DFBh/w5fbv96qrL/9O/u/97d + 3f/g4OD/5OTk/+fn5//q6ur/7u7u//Ly8v/09PT/+Pj4//r6+v/8/Pz///////////////////////// + ///////////////////+/v7/7Ozs/8TExP+2trb/v7+//7y8vP94eHj/Ghoa/2xsbP/7+/v///////// + ///////////////////////////////////////////////////+/v7//v7+//39/f/7+/v/+vr6//n5 + +f/r6+v/qamp/1dXV/9paWn/4N7e/9/h4f9zmaL/C1Rl/wxWZf8QXm3/FY6l/xu41/8at9T/GrXS/xq1 + 0/8ass//F6G5/xiFm/89cXX9Z2tl9GxxavFscWvxbHJr9Gxxa/1tcmv/bXJs/21zbP9tc2z/bXNs/21z + bP9tc2z/bHJs/2xxbP9rcWr/aW5o/2RpZP9UWVT/UVZR/3V7df+boZr/pKuj/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6mh/6Cnnv+yuLL/4+Tj/+/w8P+3ubb/k5qU/56mn/+jq6P/o6uj/6Kqov+krKL/pa2l/Kev + pvGqsanSp6yks6CpoIyepp4/n5+ACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAERVDwVKWG4HTVroEXuR/xqw + zf8RZ3j/DFFh/xBfbv96qrH/8+7s/9/e3v/h4eH/5OTk/+fn5//r6+v/7u7u//Ly8v/29vb/+Pj4//r6 + +v/8/Pz//v7+//////////////////////////////////////////////////n5+f/f39//09PT/9zc + 3P+vr6//MzMz/1lZWf/w8PD///////////////////////////////////////////////////////// + ///+/v7//v7+//7+/v/7+/v/+/v7//j4+P/19fX/5+fn/6CgoP9YWFj/rays/+nn5v+nvsL/Imx5/whV + Zv8PW2r/EniN/xqxzf8budX/GrXS/xq10v8atNL/GKnF/xWRqfwpeofkYW1osGtuap1qb2qcam5oq2hv + Z9drcWvxbHFr/mxybP9tc2z/bXNs/21zbP9tc2z/bXNs/21zbP9scmz/anBq/2htZv9fZV//UFVP/1pd + WP+FjIT/oqig/6Oro/+jqqL/o6qi/6Oqov+jqqL/pKqi/5mhmf+Wm5b/y8zL//j5+P/Ky8v/k5iU/5ad + lv+kq6P/o6qi/6Sso/+lraX4oqqi1qSqoaWjrKNsqq6mP6q2qiqcqpwS////AQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAADNVDwVKVm4JTV3oEXmS/xqxzv8Ranv/DFFh/xBfbv96qLH/8+7s/9/e3v/h4eH/5OTk/+fn + 5//r6+v/7u7u//Ly8v/29vb/+fn5//r6+v/8/Pz//v7+//////////////////////////////////// + ///////////////////+/v7/+/v7//39/f/T09P/UVFR/0lJSf/h4eH///////////////////////// + /////////////////////////////////////////v7+//7+/v/9/f3/+/v7//n5+f/4+Pj/9PT0/7a2 + tv9DQ0P/eXl5/+vo6P/K0tP/UIiS/wZVZf8OWmn/EWd3/xekvf8autf/GrXS/xq10v8atdP/Ga/N/xSa + tPgXh6DGRICIXmZsbC1odGgsampqPGltaXBrbmmla3Br1mpwafVscmv/bXNs/21zbP9tc2z/bXNs/21z + bP9tc2z/a3Fr/2puav9nbGb/WmFa/09TT/9rcWv/mJ+W/6Sro/+jqqL/o6qi/6Oqov+jqqL/pKqi/56m + nv+QlY//sbSx/+3u7f/j4+P/paak/5KZkv+jqqL/o6qi/6Kqof6lqqLZpqykhKStpDuxvLEXzMzMBVVV + VQMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAERmDwdTX24ITV3oEXmP/xqwz/8RcH//DFBf/w5e + bv96qrH/8+/t/9/d3f/k5eX/6+vr/+vr6//r6+v/7u7u//Ly8v/29vb/+Pj4//r6+v/8/Pz//v7+//// + ///////////////////////////////////////////////////////////////////e3t7/ZGRk/z8/ + P//Z2dn///////////////////////////////////////////////////////////////////////7+ + /v/+/v7/+/v7//n5+f/39/f/8vLy/8rKyv+EhIT/qKio/+jm5v/Z2tv/fqOq/wxbav8MWWn/EF9u/xWQ + pf8budf/GrbS/xq10v8attP/GrPQ/xWhvfsOjqrVFpiwaiKqzA8AAAACVYBVBmpqahhpbWk4Z2xnb2lv + abdqcGrsbHJs/m1ybP9tc2z/bXNs/21zbP9tc2z/bXNs/2twa/9obmf/YWdh/1JYUv9bX1r/ho2F/6Oq + ov+jq6P/o6qi/6Oqov+jqqL/o6qi/6Oqov+Um5P/nKCd/9jZ2f/29fb/u7u7/5KWkf+fp57/pKyj/6Gp + ofygpp7DoaehUaK5ogv///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZ3Dw5m + e24JWmvoEXeM/xqxzv8SdIb/C0xZ/w9YZ/97p6//9fHv/97d3f/Kysr/ubm5/9zc3P/u7u7/7u7u//Ly + 8v/19fX/9/f3//r6+v/8/Pz//f39//7+/v////////////////////////////////////////////// + ///////////////////i4uL/bGxs/z09Pf/X19f///////////////////////////////////////// + //////////////////////////////7+/v/+/v7/+/v7//r6+v/39/f/8/Pz/+3t7f/l5eX/5eXl/+Pi + 4v/d3tz/mbS6/xpjdP8JV2f/D1xr/xOBlf8bt9X/GrfT/xq10v8attP/G7XS/xeoxf8PlLDuE5+9lxeb + uSEAAAAAAAAAAAAAAABmZmYFb29vF2dwZ1JqcWqrbXFr621ybP5tc2z/bXNs/21zbP9tc2z/bXNs/2xx + bP9qb2n/ZWpk/1tgW/9UWVP/cnhy/5yjm/+lrKT/o6qi/6Oqov+jqqL/o6qi/6Sro/+aoZn/k5iS/8bI + xv/6+vr/yMnI/4+Sjv+Xn5f/pq2k/6KooP6boZnWmqGYcqStpBxVVVUDgICAAoCAgAIAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAGZ3DxN0i24MYnXoEXGH/xqxzv8TgJf/C0tZ/w1ZZ/96p67/+vf1/9jW + 1v91dXX/S0tL/5iYmP/w8PD/8vLy//Hx8f/09PT/+Pj4//r6+v/8/Pz//Pz8//7+/v////////////// + ///////////////////////////////////////////////////h4eH/Z2dn/0JCQv/c3Nz///////// + //////////////////////////////////////////////////////////////7+/v/+/v7/+/v7//v7 + +//4+Pj/9PT0//Hx8f/w8PD/6enp/+Pi4v/i39//s8TH/zR2g/8GVmb/EFxr/xN3i/8ass7/GrfU/xq1 + 0v8atdL/HLfT/xmvy/8SnLvyE6G/ow6YsyUAAAAAAAAAAAAAAAAAAAAAAAAAAHBwcBBrbmtPaW9prGxz + bOxtc23+bXNs/21zbP9tc2z/bXNs/21zbP9rcGr/aG1m/2BmX/9TWlP/Ymdi/5CWj/+mrKT/o6qi/6Oq + ov+jqqL/o6qi/6Sqov+gp57/lpyV/73Avf/09PT/1tbV/5GUkP+OlI3/pq6l/6Kqov+WnZXyi4+JrX6E + fldxdnE0cXFxNG54bjNzgHMod3d3DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaIDxNyhm4MYHHoEG+E/xqt + y/8VkKf/DVBf/w1dbf9ypKz/+ff3/9fV1P9cXFz/IiIi/1VVVf/c3Nz/9/f3//Hx8f/09PT/+Pj4//n5 + +f/8/Pz//Pz8//7+/v///////////////////////////////////////////////////////v7+/+vr + 6/+rq6v/SUlJ/1BQUP/p6en///////////////////////////////////////////////////////// + //////////////7+/v/+/v7//Pz8//v7+//5+fn/9fX1/+/v7//r6+v/5ubm/+Pj4//k4eH/ytDT/1WM + lv8GVWf/DVpq/xFugP8YqcX/GrnW/xq10v8atdL/HLbU/xu00P8To8HyDpm6oxWYuiUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABea14TaGtoXWpvasZscmv8bXNs/21zbP9tc2z/bXNs/21zbP9rcWv/aW9o/2Nq + Yv9YXlj/XWBb/4WKg/+jq6P/o6uj/6Oqov+jqqL/o6qi/6Oqov+hqaH/m6KZ/7y/u//v8PD/5ubm/52e + nP+HjYb/o6uj/6atpP+WnJX8eoF64G1xbLZxeXGlcnlwpGpyaqNwd26NgYV+R4mdiQ0AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAGZ3DxJziG8LX3HpD2p+/xqqx/8Wnrb/DVFg/wtaa/9fmKL/6ezu/+Th4P+urq7/VVVV/ysr + K/+IiIj/3Nzc//T09P/09PT/9/f3//n5+f/7+/v//Pz8//7+/v/+/v7///////////////////////// + ////////////////////////7e3t/5mZmf88PDz/HR0d/19fX//y8vL///////////////////////// + //////////////////////////////////////////////7+/v/+/v7//v7+//v7+//5+fn/9fX1//Hx + 8f/t7e3/6Ojo/+Pj4//j4eD/2dna/3ihp/8KWmr/DFhp/xFmdf8WnLT/G7rZ/xq10v8atdL/G7bT/xu2 + 0v8WqsfyEZy8oxWqxiQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZXJlJmZrZJFob2frbHNr/m1z + bP9tc2z/bXNs/21zbP9tcWv/am9q/2RqZP9cYlz/WF1Y/3h+d/+epJ3/pKyk/6Oqov+jqqL/o6qi/6Oq + ov+iqaH/naWd/7a7t//p6er/8/Lz/62urP+IjIb/oaig/6WspP+epZ3/kJWP/ImQifWNlIvyi5SK8oaN + hfKEjYPkjZWLkaGuoSaAgIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZ2DRFuhGgKW23iDmh5/xmlv/8Ypr//DlBg/wtX + aP9LiZX/0d7g/+vm5v/k5OT/l5eX/x4eHv9FRUX/xMTE//n5+f/y8vL/9vb2//j4+P/6+vr//Pz8//39 + /f/+/v7/////////////////////////////////////////////////2NjY/1FRUf8AAAD/BwcH/01N + Tf/e3t7///////////////////////////////////////////////////////////////////////// + ///+/v7//v7+//v7+//5+fn/9vb2//Ly8v/u7u7/6enp/+Xl5f/i4eD/4N/e/5Sxtv8TYG//CVdn/xBg + cP8VjKX/G7rZ/xq20v8atdL/GrbT/xy30/8Zr8zzEaLCpySy0CsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAVVVVDGhtaFtkbGTLaG5n+m50bf9tc2z/bXNs/21zbP9tc2v/anBq/2VsZv9eZF7/VlxV/21y + bP+Ynpb/pa2k/6Oqov+jqqL/o6qi/6Oqov+kqqL/n6ae/6erqP/Nzs3/4N/g/6usqv+Ii4b/nqSd/6St + pP+kq6P/payk/6Wro/+jqqL/oKmg+KKpoe6fpp7pnKaco6KsojRVVVUDAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICACAtp + gEQKWWm7DGR0/Bieuf8Yq8j/D1dn/wtUZP82eon/ss/S/+vl4v/h3+D/zMzM/319ff+MjIz/3t7e//Pz + 8//y8vL/9PT0//j4+P/5+fn//Pz8//z8/P/+/v7///////////////////////////////////////// + ////////3t7e/2JiYv8BAQH/AQEB/zAwMP/FxcX///////////////////////////////////////// + ///////////////////////////////////+/v7//v7+//v7+//6+vr/9vb2//Pz8//v7+//6urq/+Xl + 5f/j4+L/4+Dg/6e9wP8bZnb/BlZm/xBfb/8UgZj/GrfW/xq30/8atdL/GrbT/x230/8asM/5EqbGxiG2 + zlQcxuMJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnJ3ci9haGCYZGlh6Wxyav5tc23/bXNs/21z + bP9tc2z/bHBr/2dsZ/9fZl//V11X/2ZsZv+RmJD/pqyl/6Oqov+jqqL/o6qi/6Oqov+lq6P/oaif/46U + jv+Ii4j/jpGO/31/ff+Ag4D/nqWd/6WtpP+jqqL/o6ui+KSqo+ujrKPeoqmhu6Ksopemr6aNpq6mYZmq + oh7///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAP//AQltgBwJXm+KCmJz+BeXsf8atNH/EGh4/wpQX/8jb33/k7q//+3n + 5v/d3Nz/3+Hh/93d3f/h4eH/7Ozs/+7u7v/x8fH/9PT0//j4+P/5+fn//Pz8//z8/P/+/v7///////// + ////////////////////////////////////////8/Pz/6ioqP8lJSX/CQkJ/0JCQv/Q0ND///////// + ///////////////////////////////////////////////////////////////////+/v7//v7+//z8 + /P/6+vr/9/f3//Pz8//v7+//7+/v/+nq6v/k4+P/5ODh/6/Bw/8fanj/BlVm/xBebv8Teo3/GbTR/xq3 + 1P8atdL/GrbS/x230/8btM/+E6rI5iW504Qrqr8YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHl5 + eRNiZV1oYWde02pwaf1udG3/bXNs/21zbP9tc2z/bHBs/2htZ/9hZ2D/V15X/2RoY/+Nk4z/pqyk/6Or + o/+jqqL/o6qi/6Oqov+kq6P/pKqi/5CWj/97gXv/d353/3qAef+Nk4z/oqig/6Sro/+iqaD6oqqg0aKo + opmkq6R2pKukTJ+mnyierZ4irq6uFoCqgAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmgBQMaHh7CmJy9hWN + p/8at9T/E4CW/wxOW/8VYnL/c6St/+7p5//e3Nz/3uDg/+Xl5f/n5+f/6Ojo/+zs7P/w8PD/9PT0//f3 + 9//4+Pj/+vr6//z8/P/9/f3//////////////////////////////////////////////////f39/9TU + 1P9YWFj/NDQ0/56env/v7+////////////////////////////////////////////////////////// + ///////////////////+/v7//v7+//39/f/7+/v/+Pj4//Pz8//w8PD/4+Pj/9ja2v/i4eH/5eLi/7TE + xv8kb3z/BlZn/xBdbP8TdYf/Ga7L/xu51v8atdL/GbXS/x231P8et9H/FK7M7Sa60pMmvcYbAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpqagxnaWRcYmdgzGhuZvxtc23/bXNs/21zbP9tc2z/bHFr/2hu + Z/9iZ2H/WV5Z/2JmYv+KkYr/payk/6Oro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Kqov+hqJ//n6ae/6Go + n/+jqqL/o6uj/6Orov+iqqHzoKeeq6WtoUSmsaYXmbOzCv///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAABmdw8Pb4NnCmBy6RKEm/8btdD/Fpqz/w1TYv8OWmr/XJSe/+fr6v/i397/3d3d/+Hh + 4f/k5OT/6Ojo/+zs7P/v7+//8vLy//X19f/4+Pj/+fn5//z8/P/8/Pz//v7+//////////////////// + /////////////////////////f39/9HR0f9UVFT/X19f//Hx8f////////////////////////////// + ///////////////////////////////////////////////////+/v7//v7+//39/f/7+/v/+fn5//j4 + +P/g4OD/iouL/4SEhP/g39//6ujm/7rIyv8udYL/BVZn/w9dbP8TcIP/GKnE/xu61/8atdL/GbXS/x62 + 1P8gudT/GLLQ7Sa60pMms8YbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpqagxvdGlcY2ljzGZr + ZPxtc23/bXNs/21zbP9tc2z/bHJr/2huZ/9jZ2H/WV5Z/2JnYv+KkIn/pauj/6Oro/+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Sqov+krKT/pKyk/6WspP+jq6P/o6qi/6Srov+iqaD1o6qgsaevp0OOqo4JgICAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJkgcNco06CWJ0xBF9k/sZrsr/GazG/w5g + bv8MVWT/SYeU/9rn5//n5OL/3Nzc/+Dg4P/j4+P/5+fn/+rq6v/u7u7/8fHx//X19f/4+Pj/+fn5//z8 + /P/8/Pz//v7+//7+/v//////////////////////////////////////+/v7/8DAwP83Nzf/b29v//// + //////////////////////////////////////////////////////////////////////////////// + ///+/v7//v7+//7+/v/7+/v/+fn5//r6+v/Y2Nj/WVlZ/0lJSf/Gxsb/8/Dv/8LMzv85e4b/BlZn/w5b + a/8Tb4H/GKXA/xu62f8atdH/GbXS/x621P8iutT/G7XS7Sa70pMms8YbAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGpqagxvcmdcYmhgzGVrY/xtc23/bXNs/21zbP9tc2z/bHFr/2htZ/9iZ2H/WV5Z/2Ro + Y/+MkYv/pKuj/6Sro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Kpof+hp5//oKee/6GooP+iqqH/o6qi/6Sr + o/+hqKD8mZ+X2pSZkoqSmpJEm62kHJ+fnwhVVVUDAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + /wEJe40dCWh6pw54i/kYpMH/GrTR/xJxg/8LT1//MHaE/7jR1v/v6er/3Nzc/9/f3//i4uL/5OTk/+jo + 6P/s7Oz/7+/v//T09P/29vb/+Pj4//v7+//8/Pz//v7+//7+/v////////////////////////////// + ////////+fn5/7a2tv8tLS3/fX19//////////////////////////////////////////////////// + /////////////////////////////////////////v7+//7+/v/7+/v/+fn5//f39//q6ur/s7Oz/39/ + f/9+fn7/zs3M/83W2P9AfIb/BlBf/w5VYv8UaHn/GKK+/xu72f8atdH/GbXS/x221P8ludT/HbjS7SS7 + 0pMms8YbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpqagxlamJbYGVezGZsZvxtc23/bXNs/21z + bP9tc2z/a3Br/2dtZ/9hZ2D/WV5Z/2ZtZ/+PlY7/pauj/6Oro/+jqqL/o6qi/6Oqov+jqaH/oqqi/6et + pv+ssqv/rLOr/620q/+or6f/o6qi/6Oqov+jqaH/kZmR+YGFgNx2fXS0a3FrgWdwZ1l8g3xCjZWNHYD/ + gAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEJe4QbDG6EpA1xg/kWmLT/GrjV/xSKoP8MUF7/GWNz/4Ct + t//p6ur/39zc/+Dg4P/p6en/6urq/+fn5//q6ur/7u7u//Ly8v/09PT/9/f3//n5+f/8/Pz//f39//7+ + /v/+/v7/////////////////////////////////+fn5/7Ozs/8qKir/fn5+//////////////////// + /////////////////////////////////////////////////////////////////////////v7+//7+ + /v/7+/v/+fn5//b29v/29vb/7+/v/5ubm/80NDT/hoSE/9Xh4/9HgIr/B1Bf/w1RYP8VZnb/GKG9/xu9 + 2f8atdH/GbXS/x230/8lu9f/ILrT7SS60pMcs8YbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiI + iA9WW1ZiW2Baz2luaPxudG3/bXNs/21zbP9tcmz/a3Br/2ZsZv9fZV7/WV5Z/21xa/+UmZL/pKyk/6Or + o/+jqqL/o6qi/6Oqov+iqaH/oqmh/7O5sv/O0s7/19rX/8HFwf+kqaP/n6af/6Oro/+jq6P/m6Ga/46T + jP6Bh4D5eH5243R7c852f3azgYl+Y56enhUAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEKcHoZDnWJlwls + gPYUjab/G7bT/xikvv8PXm3/DVdm/0qHlP/T4eT/6OTi/9PT0/+8vLz/y8vL/+zs7P/p6en/7e3t//Hx + 8f/09PT/9vb2//j4+P/7+/v//Pz8//7+/v/+/v7//v7+////////////////////////////+vr6/7e3 + t/8rKyv/cnJy///////+/v7//v7+//7+/v/8/Pz//f39//39/f////////////////////////////// + /////////////////////////v7+//7+/v/7+/v/+fn5//X19f/19fX/6+vr/56env89PT3/hoSE/9fi + 4/9Ih4//CFVo/w9ZaP8VbX7/GqS//xq72f8atdH/GbXS/x231P8nvNf/IrrU7Si70pMmvcYbAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAXJyciZOU06KVlxV42lwaf5udG3/bXNs/21zbP9scmz/anBq/2Zr + ZP9eZFz/Wl5a/3N4c/+Znpj/pKyk/6Oqov+jqqL/o6qi/6Oqov+iqaH/oamg/7m/uP/m6Ob/9vX2/8LD + wv+Pko7/mp+Y/6WtpP+jqqL/oqqi/6Oqof+fpZ3/maGY/pGYj/2LkYnyjJSMoKGmoS6AgIACAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAASgIAOF3aOYw1xhdYRhJ3+Ga/N/xqz0f8SdYb/C1Jh/ypufP+uy9D/8u/u/8PC + wv9ra2v/aWlp/8DAwP/x8fH/7Ozs/+/v7//y8vL/9fX1//j4+P/5+fn//Pz8//39/f/+/v7//v7+//// + /////////////////////////Pz8/8bGxv9BQUH/YWFh//Ly8v/s7Oz/6+vr//b29v/6+vr/+fn5//n5 + +f/8/Pz//Pz8///////////////////////////////////////+/v7//v7+//7+/v/7+/v/+fn5//X1 + 9f/z8/P/8PDw/9TV1f+tra3/y8nJ/8/Y2f9FhI7/CFho/w5ca/8VcYH/G6bA/xq62f8atdH/GbXS/x22 + 1P8qvdf/J7rW7S271JM5vdkbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICACFZcVlBOVVDAXGJc+G1z + bP9udG3/bXNs/21zbP9tcmz/am9p/2RqZP9aYFr/XWBc/32CfP+fpZ3/pKuk/6Oqov+jqqL/o6qi/6Oq + ov+iqaH/oamh/77Cvf/t7ez/9vX2/7S0tP+FiYT/mqGZ/6Wtpf+iqaH/oqmh9KGpoeSiqqDdo6ui3aOq + o96iqaHZoqegl5+qnzBVqlUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARBAcBAzTWYeU4eNMRZ5jLEOe5L8GKXC/xq5 + 1v8Vi6L/DFZk/xRebv9uoqv/6O7w/9fW1f+Hh4f/MjIy/21tbf/l5eX/8PDw/+3t7f/w8PD/9PT0//j4 + +P/4+Pj//Pz8//z8/P/+/v7//v7+//7+/v///////////////////////v7+/9jY2P9dXV3/QUFB/7Oz + s/+1tbX/ra2t/8nJyf/09PT/+vr6//j4+P/5+fn/+/v7//z8/P/9/f3///////////////////////// + ///+/v7//v7+//7+/v/7+/v/+fn5//f39//z8/P/7+/v/+3u7v/v7u7/7Orp/8fQ0/9Af4v/B1Zo/w5c + a/8XcYH/GqbB/xq62f8atdH/GbXS/x631P8rvtf/Kb3Y7TK915M5veMbAAAAAAAAAAAAAAAAAAAAAAAA + AACAgIAGb3RvLlJWUI9UWlTmaG5o/W50bf9tc23/bXNs/21zbP9scWv/aG5n/2JnYf9YXlj/YmZi/4mP + h/+jqqL/pKuk/6Oqov+jqqL/o6qi/6Oqov+iqaH/payj/8jLx//z8/L/7u7u/6Wmpf+DiIL/n6ad/6Ss + pP+jqqHvoKmfup6nnoOcp5xxn6ifcJ6pnnGhqqFvoKqgS6KiohYA/wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFixZFxot + T1ovPlaDfYCCbEmKk70Qdo78FZm0/xu31f8Yobz/EGp6/wtVZP81doP/vtPZ//Du7v+xsbH/Nzc3/0ND + Q/+0tLT/8vLy/+3t7f/v7+//8vLy//X19f/4+Pj/+vr6//z8/P/9/f3//v7+//7+/v////////////// + /////////Pz8/9TU1P9kZGT/IiIi/319ff/Gxsb/tbW1/56env/ExMT/4eHh/+rq6v/s7Oz/9vb2//z8 + /P/8/Pz//f39///////////////////////+/v7//v7+//7+/v/7+/v/+fn5//f39//z8/P/7u7u/+rq + 6v/n5ub/6ebl/8XP0P82e4X/BlZo/w9dbP8YcYL/G6bA/xq62f8atdL/GbXS/x+41P8uv9f/K8DX7TjB + 25M5vdkbAAAAAAAAAAAAAAAAAAAAAICAgAZ3fXEtXmBcglFUT9dhZl77bnRt/250bf9tc2z/bXNs/21z + a/9scGr/Zmxm/15kXv9YXVf/bHJs/5SblP+lrKP/pKuj/6Oqov+jqqL/o6qi/6Oqov+hqJ//qK+m/9HU + 0P/4+fj/4+Tj/5OWlP9/hn//o6qi/6Oqof2iqKDLoKWeZpuimyGUoZQTnLicEqGulBOhoZQTlaqVDICA + gAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAIRK1UeFilLaRszVsQnOVvlTFNd1nCDheoogpD9E4yo/xmvzf8atNH/FISZ/wxQ + Xv8XWWn/eaWt//Ly9P/Fw8P/X19f/z8/P/+Wlpb/7+/v/+7u7v/t7e3/8fHx//T09P/39/f/+Pj4//v7 + +//8/Pz//f39//7+/v/+/v7////////////6+vr/39/f/7W1tf+BgYH/Jycn/1ZWVv/h4eH/5+fn/5qa + mv+RkZH/oaGh/8XFxf/ExMT/wcHB/+Pj4//9/f3//f39///////////////////////+/v7//v7+//7+ + /v/7+/v/+fn5//b29v/z8/P/7u7u/+rq6v/n5ub/6eXl/7zKzf8rdID/BlVm/xFdbf8bdob/G6nF/xm6 + 1/8atdL/GbXS/yK51P8xwNn/LcDZ7T7B3JNCvdkbAAAAAAAAAAAAAAAAgICABHF2cTZZXVeJTVNN1lpe + WvlqcWr/bnRu/21zbf9tc2z/bXNs/2xxa/9qbmn/Y2hj/1pfWf9dYVz/fIN9/56knP+krKT/o6uj/6Oq + ov+jqqL/o6qi/6Opof+hqaH/r7Wt/9rd2v/8+/v/0NHQ/4GFgf+EioL/pa2l/6SqovuhqqG2pa2lPoCA + gAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASM6aBYYMFtrGS9VziZCbvknRXH/JzlZ/U9V + Xv86cnv/E4ef/ximwf8bu9j/F5u0/w5aaP8NU2H/OnmG/8bb3//s5+j/sbKy/4mJif+5ubn/6urq/+np + 6f/r6+v/7+/v//Ly8v/09PT/9/f3//n5+f/8/Pz//Pz8//39/f/+/v7//v7+///////s7Oz/s7Oz/8HB + wf+4uLj/WVlZ/2dnZ//V1dX/y8vL/5SUlP+RkZH/m5ub/9TU1P/Nzc3/p6en/6ysrP/n5+f//v7+//7+ + /v/////////////////+/v7//v7+//7+/v/7+/v/+fn5//b29v/z8/P/7u7u/+rq6v/o5ub/6ebl/7XF + yP8jbXv/BVVm/xJfb/8de4v/G6/K/xm41v8atdL/GbTR/yW61v80wdv/LsHa7ELH4JI5xuMbAAAAAWBg + YAhmZmYPaW9pJ1RaVI5MUEzeVltU+2lvaf9udG7/bXNt/21zbP9tc2z/bXJr/2twa/9nbWf/XmRe/1Zb + Vv9oa2f/jpWO/6Opo/+kq6P/o6qi/6Oqov+jqqL/o6qi/6Kpof+kqqL/usC5/+Xn5f/5+fn/uru6/3t+ + ev+Plo7/p6+m/6Kqovydo5rIlZqVYI6OjhuqqqoGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVAyVA + cDAeOWWrHjll+SxOff8vT4D/KEd3/yg6Wf8sSlv/FX6V/xeft/8bt9b/Ga7K/xN3i/8NWGf/GGFx/3Wm + r//z8/P/5OPj/9nZ2f/f39//5OTk/+fn5//p6en/7e3t//Dw8P/z8/P/9fX1//j4+P/7+/v//Pz8//z8 + /P/+/v7//v7+//7+/v/b29v/n5+f/+7u7v/g4OD/tLS0/8bGxv/MzMz/np6e/5SUlP+MjIz/qKio/9TU + 1P/f39//1tbW/6Kjov++vr7//Pz8///////////////////////+/v7//v7+//7+/v/7+/v/+fn5//f3 + 9//09PT/7u7u/+rq6v/o5uf/6uXl/7HDxf8eann/BlVm/xRhcP8fgpP/G7PQ/xm31P8atdL/GrXR/ym9 + 1v85w93/McTd7kjG3plXhYssd3d3Hm5xbkhmbmZkT1RPhU1STdxZYVn7anBp/292bv9tc23/bXNs/21z + bP9scmz/a3Bq/2luaP9kamP/WV9Z/1peWP96f3n/nKOc/6Wro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Kp + oP+nrqf/yc3H//Hx8P/u7u//pqem/3+Dfv+aopj/pq2l/6Oqov+Ql4/sd313smpvb3Fze3M8kJuQF6qq + qgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAACAAiZEcSIhQXCNJUNx5ilJef4wTn//MFOF/ytId/8mQmf/G2yK/xaV + rP8ar8v/G7jW/xeas/8QZHb/DVhn/zh4iP+/2Nv/8e7t/+Df3v/h4eH/4ODg/+Tk5P/n5+f/6urq/+7u + 7v/w8PD/9PT0//f39//4+Pj/+/v7//z8/P/9/f3//v7+//39/f/d3d3/oKCg/9bW1v/i4uL/3Nzc/8/P + z/+qqqr/iYmJ/4ODg/+QkJD/oaGh/7Gxsf+2trb/3Nzc/8jIyP+vr6//+/v7//////////////////// + ///+/v7//v7+//7+/v/8/Pz//Pz8//b29v/z8/P/7u7u/+rq6v/p5+f/5+Xj/6K8v/8WY3P/B1dn/xZk + dP8gjZ//GrbU/xq30/8ZtNL/HLbS/y6/2f8/xt7/ObXJ90iIksVSWlp/TVVPgVBWULVXX1fTWFxY42Jn + Yftscmv/b3Vu/21zbf9tc2z/bXNs/2xybP9rcWz/am5p/2VsZf9dY1z/VlxW/2htaf+PlY//o6mh/6Or + o/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Kqof+zuLL/297b//j4+f/Z2Nn/kJGP/4SJhP+hqaD/pKuj/6Sr + o/+YoJn+h4+G8XV7ddZrcWunfoN+b5CZkDeJnYkNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAP8BAAAAAAAkSQckSHA5J0h3oyhH + ePMwT4D/MFKE/y9Rg/8vTn//JVZ//xeGoP8Zp8L/G7jW/xqxzv8TgJX/Dlpo/xhfb/9om6b/3+nq/+fk + 5P/b29v/4ODg/+Pj4//k5OT/6Ojo/+zs7P/w8PD/8vLy//X19f/39/f/+fn5//v7+//8/Pz//f39//39 + /f/x8fH/vb29/5+fn//CwsL/zMzM/8HBwf+bm5v/hYWF/5SUlP+2uLb/ra2t/6ysrP+1tbX/paWl/66u + rv+/v7///Pz8//////////////////7+/v/+/v7//v7+//39/f/39/f/8fHx//b29v/z8/P/7u7u/+rq + 6v/r6Of/4uHi/4eqsf8OWmz/C1ho/xhqeP8gl63/GrnX/xq20v8atdL/H7bU/zbC2/9EyN//Qqe4/lZk + YfRZYl3gV15Y5FZcVvZhZl7+aXBp/m50bf9vdG3/bXNs/21zbP9tc2z/bHJs/2txa/9qb2n/Z2tl/2Bm + X/9WXFb/X2Re/4KHg/+fpp//pKuj/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6mh/6Kqov+yt7L/19nY/+3t + 7v+2t7f/eXx5/4ySjP+krKT/o6qi/6Sqov+kqqP/oqqi/5aclf6HjYbwfoR91Xh+dZCAhXoymcyZBQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHDljEhks + USkcMk4kK1WADFVVqgMPPHgRKkZ1bSZFc+YtTX//MFOF/zBShP8vUIH/K0x7/x5wkf8XoLf/G7LP/xy7 + 1v8YoL3/Emt+/w1YZ/8obnz/mb/G/+7v7//c2tr/3d3d/+Dg4P/k5OT/5+fn/+np6f/t7e3/8vLy//X1 + 9f/29vb/9/f3//r6+v/7+/v//Pz8//39/f/z8/P/xcXF/7S0tP/a2tr/3Nzc/8bGxv+kpKT/u7u7/9/f + 3//j4+P/ycnJ/7Gysf/Ly8v/nJyc/5GRkf/f39////////////////////////7+/v/+/v7//v7+//z8 + /P/b29v/oqKi/87Ozv/4+Pj/7+/v/+vq6v/r6Oj/1trc/2OVnv8GVmj/D1pp/xpvfv8eo7z/GrrX/xq1 + 0v8ZtdL/IrjU/z7F3v9IyN//TKWx/2hsZ/9rbmj/bHJr/210bP9vdm7/b3Vt/21zbP9tc2z/bXNs/21z + bP9scmz/bHFr/2pvav9nbGb/Ymhh/1pfWP9aXln/eHx4/5mfmf+lq6P/o6uj/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/pKqi/6CooP+TmZP/mZua/7Gysv+PkY//eHt3/5ifmP+lraT/pKyj/6Kqov6hqaD8oamg/KSt + o/yiqqH8k5qS9YaLg7eHjoNIjo6OCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEjRnQWHTlfWRYrTpQaL1eMHzplUyZCbTYqR3k9IkBugCM/bOksTH7/MFOG/zBS + hP8vUIL/L01+/yZZhP8XkKv/Ga3H/x661v8attT/Fouj/w5dbP8PWWv/R4SS/7/U2f/o5eX/29zc/9/f + 3//g4OD/5OTk/+np6f/u7u7/9fX1//v7+//39/f/9fX1//j4+P/6+vr/+/v7//39/f/l5eX/p6en/+Tk + 5P/9/f3/6+vr/8bGxv/V1dX/+fn5///////19fX/0dHR/7Ozs//d3d3/xsbG/6ioqP/z8/P///////// + //////////////7+/v/+/v7//v7+//39/f/X19f/e3t7/5KSkv/09PT/8/Pz/+vq6v/r5+j/vszR/zp7 + iP8GVWb/EV1s/x55iv8er8b/GrjV/xq10v8ZtNL/JrvW/0XI4P9Kxt3/VJuj/21waf9udGz/bnRt/25z + bP9tc2z/bXNs/21zbP9tc2z/bXNs/21ya/9rcWv/am5q/2dsZ/9iaWL/WmBa/1VaVv9ucm3/lpqU/6Sq + ov+jq6P/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/pKqi/6Kpov+Qlo//eH13/3V3df92eHb/ipCJ/6Oq + ov+kqqP/pauk96Oso96fpp7MoaqgyaSrocmlq6TJo6ujvKKtonybqJspgICABAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkSQcjNmFCGy9RuhszWO0kQW3nJkNwwyQ+ + bKwmQm+vJD9tyylJd/gwUYT/MFKF/zBShP8wUoT/L0+D/ytMev8dcZL/GaG7/xy41P8eutf/GarG/xR7 + j/8OWWj/GF9v/2aapf/e5+f/5uPj/93d3f/g4OD/4+Pj/+fo5//h4uH/sbGx/6+vr//p6en/9/f3//X1 + 9f/4+Pj/+vr6//z8/P/h4eH/np6e/+rq6v/+/v7/9PT0/+zs7P/7+/v///////b29v/Ly8v/n5+f/6qr + qv/s7Oz/xsbG/7Kysv/19fX////////////////////////////+/v7//v7+//39/f/z8/P/sbGx/2ho + aP/AwMD/9fX1/+3s6//n5eb/nrm9/xlkc/8KWGf/FWJx/yKJm/8btND/GbfT/xq10v8btdL/ML7Y/0zN + 4/9PwNb/XYmL/25vZv9uc2z/bXNs/21zbP9tc2z/bXNs/2xybP9sc2z/a3Fs/2twa/9pbmj/Zmxl/2Fm + YP9ZXlj/V1xX/2pvav+Ok47/oqmi/6Sro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Sr + o/+kqqL/l52V/4WLhf+Jj4j/nKSb/6Srov+iqqH0pa2jw6Suonuhp55Xpa6lUqmvplOmr6NTo6qjSJ+l + nyWSkpIHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu + RgsaLU9aFihL3SNAa/8tTX3/K0p8/SlJefkoRXX5KUp5/DBShf8wU4X/MFKE/zBShP8vUoX/L0+A/ylB + bP8cRWD/Fn2W/xyz0P8fu9X/HrnV/xeguv8SbHz/DVZl/yNqef+SusD/6+vr/+Lf3//e3t7/29vb/7u8 + u/+enp7/Wlpa/0dHR/+jo6P/9fX1//b29v/19fX/9/f3//r6+v/r6+v/sbKx/8bGxv/09PT///////// + ///7+/v/5eXl/8bGxv+kpKT/paWl/6mqqf+3t7f/ra2t/83Nzf/6+vr///////////////////////7+ + /v/+/v7//v7+//z8/P/9/f3/1NTU/1ZWVv9vb2//5+fn//Lw8P/d3+L/cp+m/whYaP8OWmn/HGp5/yWX + rf8auNT/GrXS/xm10v8et9T/PMPc/1PN5f9UtcT/Znh3/25waf9tc2z/bXNs/2xybf9scmz/bHJs/2xx + bP9rcWv/am5q/2dsaP9kamT/X2Re/1ddV/9VW1X/bXFt/5GVkP+iqKH/pKuj/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Kpof+gp5//oamh/6Kqov+kq6P/pqyk/6SspP+krKP/pKuj/6GpoP+jrKPkqbGnhqGu + oSaStpIHgKqABoCqgAaAqqoGgICABICAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwUVKkc9GjJVsSdFcvErSXj/L1CA/y9RhP8uUIT/MFOF/zBT + hf8wUoP/MFOF/y9Sg/8vToH/KERu/xwtS/8TIzr/FVVx/xmmxP8duNT/IbrV/xuz0P8Wkaj/EWRz/w5X + Z/84eoj/r8vP/+rn6P/g39//2tra/5ycnP9bW1v/S0tL/zw8PP9aWlr/ysrK//j4+P/09PT/9fX1//j4 + +P/39/f/29vb/7CxsP+9vb3/1NTU/9TU1P+7u7v/t7e3/729vf/IyMj/3t7e/7e3t/+Ojo7/v7+///Ly + 8v////////////////////////////7+/v/+/v7//v7+//v7+//7+/v/5eXl/5KSkv+AgID/4N/f//Pw + 8f/A0NP/OXqI/wZUZf8RXWz/InaG/yOmvf8ZudX/GrXS/xi00v8lutX/Scnh/1fM4/9bo67/a3Jr/2xx + bP9scmz/bHJs/2xya/9rcmv/a3Br/2lvaf9nbmj/ZWpk/2FmYf9cYlv/VlpU/1leWf9ydXH/kpeS/6Sq + ov+kq6T/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oqmh/6Srov+psaf/pq6m/6Kqof+iqqL/o6qi/6Sq + ov+lq6P/o6qi/6Oqov+boZnqj5eNlo6TjjSfn58IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEeLVoRJENwVCtH + d7QpSnj2L09+/zBSgv8wU4X/MFKE/zBShP8wUoT/L1OF/y5Of/8pRHH/GyxI/xIhOv8SI0H/EjVW/xV7 + l/8asMz/IrvW/yG71v8ascz/Foaa/xFebv8QWGr/S4eT/73T2P/o5+j/39/f/8DAwP9mZmb/Tk5O/0ND + Q/8xMTH/iYmJ//z8/P/w8PD/9PT0//X19f/4+Pj/9vX2/9nZ2f+7u7v/xcXF/729vf+MjIz/tbW1/+3t + 7f/29vb/9PT0/9PT0/+srKz/0tLS//39/f///////////////////////v7+//7+/v/+/v7//v7+//v7 + +//6+vr/9fX1/+bm5v/Z2dn/7Ovq/+Xo6P+HrLT/EVxt/wtYaP8WY3H/JYmb/x60zv8Zt9T/GrXS/xq1 + 0/8uv9j/Vc7m/1zJ3v9gk5b/amxl/2pwav9qcGr/am9p/2puaP9nbmf/Z2tm/2RqZP9iZ2D/XWNd/1dc + V/9VWlT/YWZh/3yAff+ZnZj/pKqi/6Wso/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+iqaH/oqqh/7S5 + s//M0Mv/xcrE/7C3r/+mrqb/o6uj/6Oqov+jqqL/o6qi/6Sro/+Xnpf7gIR+1nR4cIaAhHs4h4eHEaqq + qgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABLUuHESxQelYsTn3QLU19/C9Qgv8wUoP/MFKE/zBShP8wUoT/L1GC/ylG + c/8dLkz/Eh83/xMnSP8TJkj/EyM+/x1MY/8dmbb/HrjV/yW81/8fu9b/GanD/xV+kv8RWmr/Fl1t/1mS + nv/C1tr/6urp/9/d3f+Wlpb/SUlJ/1dXV/81NTX/hISE//j4+P/u7u7/8PDw//T09P/19fX/9/f3//n5 + +f/y8vL/7+/v/+jo6P+5ubn/urq6//Pz8//+/v7/+fn5/+jo6P+/v7//urq6//X19f////////////// + //////////////7+/v/+/v7//f39//v7+//5+fn/9vb2//f4+P/29vb/8fDv/87Y2v9DgI7/BlVl/xFd + bP8fbn3/JZ6y/xu41/8ZttP/GrXS/x221P87wtz/YNHp/1y7zP9he3j/Z2hh/2VrZf9la2X/ZGtj/2No + Y/9iZ2H/X2Ve/1pgWv9WXFb/VlpW/11jXv9wdnH/jJGK/6Ckn/+lq6P/pKuj/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Kpof+hqJ//rbOs/9LU0f/w8PD/5ebl/7y+vf+aoJr/nKOb/6Sso/+jqqL/o6qi/6Sq + ov+jqaH/lZmU+n2CfNpyd26dgIV9XJKZiiO/v78EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBVqgMAVVUDADNmBStOeCQnRXCrJ0V1+TBR + hP8wUoX/MFKE/zBShP8vUoX/LU19/yA0Vf8SITf/EyhJ/xMoSv8TJD//JDBG/zhKYf8mc5D/FqfI/iK7 + 2P8lvdf/HrnW/xmiu/8Wc4P/D1pq/xZgcP9glqD/zt3e/+7r6/+3trb/T09P/4aGh/+kpKT/wsLC/+7u + 7v/r6+v/7e3t//Dw8P/z8/P/9PT0//b29v/6+vr//f39//z8/P/n5+f/r6+v/8rKyv/7+/v//v7+//T0 + 9P/IyMj/oaGh/+jo6P////////////////////////////7+/v/+/v7/+/v7//v7+//5+fn/9fX1//Pz + 8//y8fH/6e3s/5Gwtv8WW2r/CVZl/xVhcf8qg5P/JK/G/xm51v8ZtdL/GbXS/ya61f9NyuL/ZM/k/1qb + pP9aY13/XGFZ/1xiXP9bYlv/WmBa/1hfV/9XW1f/VlpV/1hdWP9gZF7/bnJu/4eMhv+coZz/pKuj/6Sr + o/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oqqi/6Gon/+nraX/yMzH/+7v7v/5+fn/4eHh/5+f + n/97gHv/lp2W/6Wupf+iqqL/oKig/aKpoPyjq6P+pqyl/5qhmfx+hX7tdX11wIWKhWSZmZkU////AQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQEAIHDdgJRQn + TjQdMV00IjtiNClFckofOWG2JkRz+jBShv8wUoT/MFKE/zBShf8vUYP/JkBp/xYkPf8RJEL/FCpP/xEk + QP8nNkz/OUxl/zVFZv44Wnn2JaC86Bu41vgmvtf/JrzY/x220v8amLD/F29//w9aav8ZXm3/Z5Gb/8ba + 3f/a2dn/pqal/7+/v//r6+v/6Ojo/+Tk5P/o6Oj/6enp/+zs7P/w8PD/8vLy//f39//29vb/+vr6//z8 + /P/19fX/0NDQ/62trf/a2tr/+/v7//v7+//R0dH/mZmZ/+Li4v////////////v7+//v7+//9fX1//7+ + /v/+/v7/+/v7//v7+//4+Pj/9fX1//Pz8//09PP/x9ja/z18h/8HUF7/DlFg/xpmdf8qmq//HrfU/xm3 + 1P8atdL/HLbT/zbB2v9h0un/ZcTW/1p7ff9YWFH/WFxY/1ddWP9YXVj/Wl1a/1xgW/9gY1//aGxo/3t/ + e/+LkYz/maCZ/6Oqo/+mrKX/pKuj/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqaH/oamg/6eu + pf/CxcD/6Oro//n6+f/q6ur/sbGy/3d6d/+Ah4D/oamg/6Sso/2iqqLroKee06CooM+hqqDmo6yh+Kau + pfuYn5b6h4+H24iQinqSm5Ic////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAVQMjOWokFi1RgRYuT6sbNV2sGzZeqx85X7YjPmfjLE1+/jBThv8wUoT/MFKF/zBT + hv8tTXz/HC5L/xEhPP8VKlD/EidH/x0uR/82SmX/OU9y/0hZevlZZn3OSqO4kB+3078fvNjzKL3X/yi8 + 2P8btNL/Gpiw/xhygf8PUWD/Flhn/1aPm/+yys//8vDv/+nl5P/e3t3/4eHh/+Hh4f/k5OT/5+fn/+np + 6f/s7Oz/7+/v/+7u7v/Q0ND/srKy/+zs7P/8/Pz/8/Pz/83Nzf+1tbX/0NHQ/+Pj4//ExMT/oqKi/+rq + 6v/29vb/4eHh/7m5uf+SkpL/09PT///////9/f3/+/v7//r6+v/39/f/9vb1//b19v/b5+b/cJ+m/w5e + bf8MWWf/E1lo/yd5iP8krsf/GbrW/xm20v8ZtNL/JbrV/07K4f9v1On/c7vF/32Ihv98fHf/e356/3yA + e/98g3z/gYWB/4aKhv+LkYv/kpqT/6Gnn/+mraX/pq2l/6Ssov+iqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Kpof+gqKD/qrKp/8bLxf/o6ef/+Pf4/+rq6v+4t7n/fYB9/32DfP+dpZ3/p66m/qOr + ouSjqaGgnqieZKGmnlyfqZ+FpK2hq6OqorKjqqOuo6qhipejl0CAlYAMAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAcBAkP2hdFipJ1B84YPkjP2v5Ij9p+SVC + bPkrSXn/MFOF/zBShP8wUoT/MFKE/y9Thf8pRW7/FSI5/xMnSP8UKlD/EyZC/zBBWv8zTHD/OE9y9218 + kNxwcoiJbZiwKiu71l4ft9a/IbzY9CzA2v8kvNj/G7XU/xuZsP8ZbXz/EFlo/w5aa/9EgY//scnN/+vp + 5//l4eD/3d3c/+Dg4P/h4eH/5OTk/+fn5//q6ur/3Nzc/6Kiov+Wlpb/Z2dn/6+vr//8/Pz/+Pj4//Pz + 8//Pz8//tbW1/7Ozs/+wsLD/zs7O//j4+P/c3Nz/i4uL/4CAgP9MTEz/nJyc//v7+//9/f3/+/v7//n5 + +f/29vb/+ff2/+nw8P+Ms7r/G2Z1/wpYaP8PXWz/H299/zCarP8cttT/GLfT/xq00v8cttL/OsLb/2fT + 6P940OL/jLS1/6Omnf+ipqD/oaeg/6GooP+jqKH/pKmk/6aspP+mraX/pq6l/6Wso/+jq6L/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oaqh/6Kqof+utKz/y8/L/+3u7P/6+fr/7Ozs/7q6 + uv98fXz/d313/5qhmP+nraX/o6mh/KWspMSsr6lTj5+fEKqqqgmcpZwfrbeoNaewpzqfpJ84n6WfJbOz + swoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAiRC + bSMnQWuWFShI9CU/a/8pR3X/LEp5/y5Of/8wUYP/MFKE/zBShP8wUoT/MFKF/y5Rgf8kPGL/EiM//xQr + T/8TKEr/HC1H/zJIaP8uSnH2S2J/y3B+j3tndII5ADNmBSnC1hknu9NiIbrWwCe/2fMvwNv/I7zY/xyz + 0f8cmbH/HHeH/xJdav8RWmr/QH+M/5m6wf/c4uT/5+Xl/97c3P/e3t7/4eHh/+Tk5P/n5+f/0dHR/2pq + av9xcXH/hISE/2xsbP/m5ub/+fn5//X19f/19fX/3Nzc/8PDw//Pz8//9fX1//7+/v/W1tb/a2tr/39/ + f/+RkZH/e3t7/8jIyP/7+/v/+/v7//n5+f/5+Pj/7fLz/6DBx/8xdYH/CVdo/w1ba/8aZXT/Loqb/yey + y/8YuNX/GbXS/xm10/8nvNf/V8zj/3jY7P+AydT/nqyj/6eqoP+lrKT/payk/6WtpP+lq6P/pauj/6Sr + o/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+iqaD/o6uj/7O7 + s//T1tL/7/Dv//n5+f/t7e3/vLy8/31+ff90eHP/lZyU/6WtpP+krKT/oqmh/Zeelc2Hj4dmkJubF/// + /wL//wABgICABICAgASqqqoDgICAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAACAAidIbycmQm2bGS5S4iQ8aO0lQG3+KUd3/y1Nfv8wUIH/MFKE/zBS + hP8wUoT/MFOF/y5Nfv8eNFX/EiVE/xUrUf8SJkf/JjdS/zBJb/89VHbwX3GIp3F9iC1JSW0HAAAAAAD/ + /wIms9AbJLnTYiO71b4rwNn3MMLY/yO81/8ctNL/HKC2/x58i/8UYXD/DVlo/ydwff95qLH/xNXY/+jm + 5v/k4N//393d/+Dg4P/j4+P/39/f/5ubm/9eXl7/jo6O/2RkZP+goKD/9fX1//T09P/09PT/9vb2//Hx + 8f/29vb////////////u7u7/n5+f/2dnZ/+urq7/Y2Nj/29vb//r6+v//v7+//r6+v/x9fb/sMvQ/zl8 + h/8MWWj/DFpq/xVhb/8sfY3/L6i8/xq31v8Zt9P/GrTS/x+31P9Cxd3/c9fq/37W5f+Ou77/pKie/6Op + oP+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/oKif/66yrf/Z29n/9vb2/+fn5/+8u7z/gYKB/3N3cv+UmpP/payj/6Sq + ov+jq6P/pKyj/4yVjfB0fHS3e4R7XZ+fnxiAgIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARw5cRInP2xVIj1nfihE + b5ooQnDTK0l37S5Off0vT4D/MFKD/zBShP8wUoT/L1OH/yxLef8bLEr/EiZG/xQrUf8VKUf/Kz5a/y1H + cftGXHnQXGmAcmZzcxQAAAAAAAAAAAAAAAAA//8CM7jMGSe71WEoutbIMcHb9jLB2v8lvdj/HLbT/x2l + vv8ehZf/F2Ry/wxYaP8ZYnP/UYuW/6PBx//b4OL/5+Xl/+Xi4f/h4OD/5OPk/9LS0v9vb2//UVFR/21t + bf9zc3P/5OTk//T09P/w8PD/8vLy//T09P/29vb/+/v7//39/f/8/Pz/y8vL/15eXv9nZ2f/YWFh/15e + Xv/l5eX//v7+/+3z9P+tytD/SISP/wxaav8MWWn/El5s/yh1hP8yn7T/HbbT/xi30/8atdL/G7XT/zO/ + 2f9l0uX/gNvr/4jI0P+draf/pKig/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/oqmh/6Gpof+iqaH/oqqi/6Oqov+lq6P/n6ad/4uPiv+oqqn/0dHQ/7Gx + sf98fnv/d3x1/5aclf+lraT/o6ui/6GpoP6iqqL+payj/52knP+Bh4HxcHdvuoGJgV+PmY8ZgICAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEgMHAQKUd6GTFMdy8uUHxpL057ri1MfvMtToD/MFKD/zBShP8wUoT/MFSG/ytJ + c/8YKEX/EyhJ/xUrUf8XKkj/KkBi/yxHcPk9UnG1QVVtP1VVVQMAAAAAAAAAAAAAAAAAAAAAAID/Ai/G + 0BsrutRrLbzWxzTF3vY0w9z/KLzZ/xu41f8dq8T/IYqe/xxtfP8QW2v/Dlhp/y1zf/9wn6n/sMrO/9/l + 5f/o5+X/6ubn/+Lh4P+Xlpb/RUVF/4qKiv+4uLj/4ODg/+zs7P/r6+v/7Ozs/+7u7v/v7+//8fHx//f3 + 9//8/Pz/4+Pj/4WFhv9nZ2f/sbGx/7q6uv/w8vL/2+jq/5O6wP87e4j/DFpq/wxYaP8RXW3/JXF//zSa + rP8itND/GLfW/xm10f8ZtNH/KbvW/1jN4/+C3Oz/iNTg/5i2s/+kp53/o6qh/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oamh/6Gpof+gqKD/oqmg/6SrpP+lrKT/o6uj/6Kq + ov+kq6P/pKuj/42SjP+DhoP/i4yK/3l7eP94fXb/l52V/6atpf+jqqL9oaig66Con96hqaDtoqqi/aau + pv+aoZn/fIN68nd9dLSKlIpMi4uLCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAImQnsbK0h5eCdH + eOotT4D/MFOE/zBShP8wUoT/MFSF/yhFcf8XJkP/EyhM/xUqUP8WKUf/Jz1i/yxIcvk0SWy1MUpnPgCA + gAIAAAAAAAAAAAAAAAAAAAAAAAAAAFWqqgM8u90eML7Zai/B2cc4w933OMPe/yu81/8dutX/Ha7K/yGX + rf8ieon/GGNx/wtWZ/8QXGz/O3yL/3yqs/+zy8//2+Tm/+ro6P/U0dD/ra2t/87MzP/t7e3/5eTk/+Tk + 5P/n5ub/6Ojo/+jo6P/p6ur/6erq/+3t7f/y8vL/8fHx/9HR0v/Ew8P/8/T0/+fx8/+509f/a56n/ylu + fP8IVmf/DFpq/xNdbP8ncYD/N5iq/yayzv8Yt9T/GrbS/xi00f8iudX/TMbf/37a6/+M2+f/kL/C/5+n + n/+jp5//oqqi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+iqqL/oamh/6GooP+gp5//oKif/6Go + of+or6f/t7y2/8XKxf+6v7n/pauj/6Gpof+jq6L/payk/6GooP+Jj4j/dHhz/4CGf/+bopv/pq2l/6Kq + of2jq6Pko6yko6Cpnnyhp56ppK2k5aWtpPunr6b/lZ2U/HuBecx2e3NfgI+AEAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABIEBgCCJVdw8rSYAqKkJtkyU/a/EtUIP/MFKF/zBShP8wUoX/MFSF/ylGcf8XJ0L/EylN/xUs + Uf8UKUn/JDpi/yhFcPkvRmmvQlx7OgD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVqv8DPMTVHjXC + 2WU1wdrBPMXh8zzG3v8yv9n/H7rX/xy00P8ho7z/I42f/x50hP8YYG7/DVdm/xVhcf89fYz/bp+p/5O3 + vf+2zdP/2Obo//Dw7//x7+//8O7t//Dt6//v6+v/7+vr//Dr6//w7Oz/8+7t//Tw7//18PD/9/Tx//Dz + 9P/P4eL/psTJ/3imrf9DgY7/FF9w/whXZ/8NWmj/GGJx/y58i/80nLD/KbTN/xi31f8ZttL/GbTR/yG4 + 1P9Ix93/e9nq/5Ph7f+g1dv/p7ax/6aqoP+jq6L/oamg/6Oqov+jq6P/o6qj/6Oqov+jqqL/o6qi/6Kq + ov+gqKD/o6qh/6ivqP+wta//ub+4/8TJxP/T19P/5Obk//Dx8P/U19T/qa6o/6GnoP+kq6P/o6qi/6Wr + o/+dpZz/lp6W/6Cnn/+mraX/o6qi/6Sro/aosKi4qLKoT56enh2gp5xDpK6jiqeupMSmr6bjo6qi04uS + i4hwdWowgICABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIXOl0WGjBZRRUrS18iNVmGIzpi1ihDavwwUYX/MFKE/zBS + hP8wUoT/L1OG/ypHcv8YKUX/EyhM/xYsUf8UKUn/IThh/ylGcfksQWC1Q1x9PQAAgAIAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAICAAkC/1Rg+xNxfO8Tevz7K4vRByOH/NsDa/yS71/8audX/HLHN/yWh + uP8niZn/H3B//xRdbP8LV2X/DFpq/x1neP86fIn/aZeg/5S5v/+ry9D/uNLW/8vd3v/Z5Ob/4ujo/+To + 5//i5+f/2uLj/8za3P+3ztD/pMHF/4uwuf9akJv/LG16/xNaa/8IV2j/Clho/xBca/8haXb/M4WT/zWo + vf8kttL/GLfV/xm20v8ZtNH/HbfT/0HF3P992ur/l+Xx/67p8f/S4+T/1tfS/8rOyf/Bx8H/uL63/6+1 + rv+mrKX/oqmh/6Oqov+jqqL/oqui/6yyq/+6wLn/xMfC/9HUz//c39z/6Ovo//Lz8v/4+fn/+Pj5//Pz + 8//V1NT/np+e/4+Ujf+gqJ//pKuj/6Oqov+lq6P/pa2k/6Sso/+jqqL/pKuj/5uim/eVnJW3naSdSaqq + qgmOqo4JpayfJaixqFiorqaHqK6ocqqwqi22trYHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAwYBAUKUtYFChMsxgw + VM4kPGHgJUJu+i1Kef8wUYP/MFKD/zBShP8wUoT/L1OG/yxKef8ZLEr/EihK/xcuVP8TKUr/HjZb/ypI + dvkySGq0PlZ3PgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wJOxNgaQcjgYkDK + 479Cy+bzR8ri/z7D3P8rvdf/HbrW/xq20/8grsf/Jpyz/yeFlv8hcID/FWBv/wxZaf8JU2L/D1Rj/x1m + dP8ud4T/PYCO/1OPmv9nmqX/caKs/3Wjrf9xoqr/Z5qk/1SOmf8+f4r/K3KA/x1od/8PXGv/B05e/wlP + X/8QWmr/HGRz/yt3hP83lKT/MqzB/yC31P8Yt9T/GbXS/xm00f8hudT/P8Tc/3TZ5/+e5/P/rujx/9fu + 8f/3+Pf/9/f2//P18//u8O7/4eLg/7u+u/+Vm5X/oKif/6Oro/+jqqH/o6qj/7m+uP/f4+D/8fHx//f3 + 9//5+fn/+Pj4//T09P/q6ur/2NjY/7q7uv+bm5v/fH57/4GHf/+epp7/pKyk/6Oqov+iqaH/oaig/6Gp + of+iqqL/pqyk/5adlf6CiYLdiI6GfJ6nnh0AAAAAgICAAp+vnxCjuKokra2tHJKSkgcAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAhxAYyQZLVSaFSxO9CI8Zv0oRG/+Kkl4/yxMe/8uT3//MFCD/zBShP8wUoT/MFOG/y1N + fP8cMFL/EiZH/xYuU/8TKk3/GjBS/yxId/s0TXHJO1RwcHmGmSiqgIAGAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACA//8CTL3QG0fA1GVFu9LIS8jf/FDO5f9JyN//NsDa/yO61/8auNX/HLXR/yKs + xP8nn7X/Koyd/yh4if8cZnT/ElRj/wxXZ/8JV2n/C1ho/wxYav8QXGz/EF1t/xBfb/8RX27/D1xt/w1b + a/8JWGr/B1Zn/whXaP8NWWr/Eltp/xxea/8sdoP/OY+e/zWkuf8otM3/HbfU/xi30/8ZtdL/GbXS/yO6 + 1P9FyN3/etvr/53j8P+Xztj/n7a6/8bFxP/c29v/5+fn//Dw8P/19PX/6+vs/7O0s/+AhoD/oaaf/6Or + o/+jqqH/oqui/7a7tv/k5OP/8vLy/+rq6v/i4uL/09TT/7++v/+oqKb/jY6N/3Z5dv90eHP/goeC/5ac + lP+iqaH/pKuj/6GooP+hqaH0oqqg5qGmoOmiqqL2pKyk/qGnn/+KkIn2gomCs5WZkkaOjo4JAAAAAAAA + AAAAAAAB////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAiI8ZSYhPGScFixQ9iE5Y/0iPmn9J0Nu/ShG + dP4sTHv/MFCA/zBSgv8wUoT/MFKE/y9Rgv8iOV7/EyZF/xUsU/8VK1D/FSpL/ydCbf8yTnXxU2R8znyD + j3+Ah4cigICAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVar/A0mYpCpMjJebTJKh+Uyz + x/9TzOT/VNDm/0TI3v8vv9j/IbnV/xi31P8attL/IrHM/yqlvP8plqr/KYSV/yl9i/8kc4H/HWp5/xhj + cf8UYG//EV1t/xBdbP8QXGz/EV1s/xRfbf8UYG//GWV0/yBsev8sd4b/M4WT/zSRov80pbn/L7TK/x+3 + 0/8Yt9T/GLbS/xi00v8attT/KrvW/1HL3/+G3e3/per0/6Xb4f+Rqaj/f4R//4GBfv+JjIr/nZ6d/6+v + r/+9vr3/wcDC/5mamf97fnj/oaig/6Oro/+jqqL/oqmg/6Wrpf+3uLb/vLy8/6ipqP+XmJf/hIiF/3t+ + e/96f3n/eoB6/4OIgv+Um5P/oKig/6Wso/+iqqL/pKyk/qSspO2kraO3o62hiJ6nno6gp5/Co6qi8aat + pv+an5j/h42F2YKJgG6MmYwUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAR48 + aREkQGlcFitOuh85YNEhPWjRKERx1S1Kd+otS3v+Lk9+/zBSg/8wUoT/MFKE/zBShf8nQ2z/FChI/xQq + UP8WLVT/FChK/yE5Xf8zUH3/R1l2+GNpdMNla3Zda2tzH4CAgAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQGBgCEdtbS9GWWCgOkxc+TRkgf9Dmbn/VcPa/17V6v9Uz+X/QcXd/yq81/8et9T/GLfU/xi2 + 0/8dttL/JLLL/yurwf8torX/K5mt/yuRov8sipr/LYaX/y2Ek/8uhJP/MISU/y+Hlv8vjZv/MJOk/zGd + rv81prv/NK/G/ye20f8cuNX/GbfT/xi10v8YtNL/GbTS/yC41P86wNr/ZdHk/5fi8P+s6fP/qdre/6K7 + uP+dpJz/kpeQ/4SIhP95f3r/e396/32BfP+BhIH/goSC/3V4df9/hH3/o6qh/6Oro/+kq6P/oamg/5GY + kf9/g4D/f4F//3yAfP95fnn/eYB5/4SLg/+Um5L/oKae/6atpf+mraT/pKuj/6Oqov+iqaH/o6uh+6Ws + pM+osKZqr6+vI5+lnyWiqqJgoqmivqWro/WiqqL9jpWO1Hl+d2mGlIYTAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIsN28XGzZjSydEbGErSnVgL054bDJOeq4rSnn5LU1//zBR + g/8wUoT/MFKE/y9Uhv8tS3n/GCpM/xIoSf8WLVL/FCtP/xktTP8oRW7/Lkpy/T9OZupIVmy1Zm95eGJn + bS+Skm0HAAAAAQAAAAEzM2YFM2ZmBUltbQdNWVkUQk9YOj1JWXY1Q1XPKjta/SU+af8oS23/MnCI/0yq + xf9gzuX/Y9bq/1XO4/9AxN3/LLvW/x+30/8YttT/FrbU/xi21f8buNP/HrfT/yS20P8os8v/LLHI/y6v + x/8wsMb/L7DI/y+xyv8qtM3/JrfQ/yK31P8dt9T/GbfV/xi30/8XtNL/F7TS/xi00v8cttT/LLzW/1HK + 4P+D3O3/qOr1/7Lp7/+p0dT/oLWw/56hmv+eo5z/oKig/6GooP+co5z/lp6W/5CXj/+KkIr/hIqD/4KJ + gv+UmpP/oqig/6Koof+jqaL/oqmh/5efl/+KkYn/jJKM/5Wclf+co5z/oqqh/6atpf+lraX/pKyj/qGq + ofuhqKD7o6qi/aSro/+kqqL/nKOb/JmgmNKjq6FnqriqEgAA/wGZo5kZn6eiaKOrosWiqqLbmp+XmISJ + hDiSkpIHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIEBgCCc7 + dg03SW0OK0p1GDBNdWQmQm/jKkt7/jBThP8wUoT/MFKE/zBShf8vUoL/IThd/xUoR/8UKk7/FStR/xUo + SP8fM1X/LEhy/zBHbv40SWn0SFRm1z5OZ5RBUmVOQEpaMFheXjFRV15MVVhcTktRV1JBSlFyPUZUqyw7 + TtUsQFz2K0Rs/yQ8ZP8XJT7/FClF/yNObf87fpn/W7XI/2rS5v9p2Or/W9Lm/0nG3/84wtn/KbvX/x+4 + 1f8YtdL/FrbT/xW21P8WttT/GLfV/xm31f8Zt9X/GbfV/xi31v8Yt9X/F7bV/xe20/8XtdP/FrTS/xi0 + 0f8atdL/I7rV/za/2f9TyuH/e9no/6Xo9P+y6O//rdnc/6TCwP+isKv/rbKr/6yuqf+ip6H/nqOc/5mf + lv+YnpX/mp+X/5ygmP+boZn/mqCY/5qhmP+bopr/m6Kc/52knP+fpZ7/oKeg/6OooP+krKL/pKyk/6Wu + pP+mraX/pKyj/6Orov+kq6T7o6qg4Z+nnr+dp528oKeg36KqovulraT/naSc/5Obk+eXm5eFoqqiHgAA + AAD//wABnKWcH5+nomCep550n6ebPaqqqgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM2aACixIbVIhOVzYKkp5/TBThf8wUoP/MFKE/zBS + hP8vUob/LEx4/xwwUf8TJ0b/FSpQ/xUsUP8VJkP/HTNT/yhFcv8sRW//LEBg/C1CX+kuPVbBMkFWnT5E + TJ1IT1fCPUZPxTtETcguOkncMz9U9yI4V/4qQmr/Ijtf/xkrQ/8RIjz/ESRG/xAgPv8kOVP/RXGQ/1CZ + uv9ju9P/ctPl/3bc7v9u2ur/XtHl/0vH3/84wdr/LbvX/yK61v8dt9P/GbTR/xe00v8WtNH/FrTR/xaz + 0f8WtNH/FrTR/xi00f8dt9P/JLnV/zC92P9Gxtz/ZNLj/4jd7P+s6fP/vO32/6Pg6f91vMf/bpqc/5GZ + j/+traf/0c7L/9DOzP+6trP/mJeP/5GRh/+TlYv/kpWM/5OWjP+XmJD/mZqR/5qakf+YmZD/mJqS/5md + lf+aoJn/nKKc/5+lnv+iqqH/p6yl/6atpf+jq6P/oamh/6Srov+lq6T0o6mgsaCsoFmcpZxVnaOapp+l + nu+jq6P/o6qi/5adluuMlIyKnKWcHwAAAAAAAAAAgICAApa0pRGurq4Wn5+fCAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGAIKTtbOB40 + VpchOV7vK0t8/y5Pgf8uUIH/MFCB/zBSgv8wUoT/L1KE/yZBa/8YLEv/EyhJ/xUsT/8TKUz/FidE/x4z + Uv8lPmf/J0Ju/yhBaP8mPF74KjpW7ig1TOw0QVP7KDhP+yc4TfwjN1j9Kj9h/yQ8Zv8hNln/FydA/xIi + Pf8SJ0f/ECZF/x0tR/86TGr/OlaE/zJZiv89cJn/T4+z/2a30P96z+P/gN3s/4Dg7/932+r/a9bn/13Q + 5f9QyeH/RMXc/zzC2v83v9n/M7/Z/zPA2f82wNn/PcTb/0fH3f9WzeH/atLl/4Xb6/+e5fD/tOz0/7vs + 8/+t5e3/gNLg/0a3zP8hkqj/M3Z//4mPiv+6trL/yMvN/8HLzP+ZrLD/X39//1iDhP9dj5P/Wo2R/1qO + lf9klZr/bZia/3aYmv+AlpP/h5GM/5CUjP+XmZD/nqGa/7G2sP/Cx8L/yMzI/620rf+gqKD/oqqh/6Kq + ov+jqqLwo6yimaCspiufn58YnqWeZp+mn8mjqaH2pa2l/5+mnuqUnZKKnKWUHwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAQAgWLFQ6Gy9SmR02XOQnQm/+LUp6/yxKef8tTHz/Lk5//zBQgv8wUoP/MFOF/y5Q + gP8mPmX/Gi5M/xIoSP8UKU//EylM/xMmQf8ZKkf/HjRU/yM7X/8lPmX/Izle/yI4W/8kOVv/Izpd/yE3 + Wf8jOV7/HzVX/xosSv8WJT//EiRA/xImR/8QJEX/HCxF/zhMZv9CYIf/MVKG/y1Of/8tTH3/L1KB/ztn + kf9Lgqb/XJu5/3C4zf+G0+L/jd7q/5Hj8P+M4e//hd3s/oHc6/5+2+v+ftrq/oDb6v6F3ev+i9/t/pfj + 8P6j5/H+r+v1/rbr9f+u5+//k9nl/3LN3f9OwdX/KbPL/xaryP8SmLP/HneI/1iBiP90nKH/Y5yn/1iY + pP89j577KYWW7CWKneIfip/hG4me4xyQpeMhmbDoKJux+C6dsf46lqb+Ro6Z/1aLkf9wjYv/lp2X/8nH + wv/o6Of/6+vr/62wrf+VmpP/o6qi/6Kqov+gqZ/wpKukl6aspii/v78EpaylJaCmnnagpp7Ooquh8qGq + odigpqB7m6SbHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxMlRCkVKUyUHDFV5yQ+aP4nQ2//J0Ju/ihE + cf4rSHf/LEx8/y9Qgf8wUYL/MFKE/y9Thf8vT37/J0Jm/x0yTv8TKEX/EihM/xMpTv8SJ0X/EyVA/xcq + R/8aLEv/GSxI/xstS/8bLUr/GixJ/xkqSP8YKkb/FSZB/xEiPf8RJEP/ESZH/xEkQf8dLUb/Ok5o/0Nf + hf8yVof/LVCD/y9PgP8sTHv/K0h4/ylGdf8qR3T/Lk95/zlghv9Kepj/VYeb/26hrP6d2ePzoebx3qXo + 8Nqn6PLaqOnx2qzq89qv6vPatev02rrt9Nq+7vPbsuv04YLZ5/ZZxdv/NbXP/x6uy/8Xrsv/FarI/xek + wP8Wkqv/FXuQ/x59kP8fiJ//Fomh/xSJoP4ZjqbrKZivryOZrm4ThqBpFYylehWTrnsbnraMJKK3vSGr + x9oir8vmHqjC+xuZs/8uj6L/V5Oc/6m8vP/s6Oj/9vPy/7q8uv+TmZL/n6ee/6Sro/+gqaDwoqigmaiu + qCn///8BgICABJqhlCaco5x3nqadpp2nnYWbpptCnZ2dDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzBREm + SDwWKU26GjFW/SE4X/8gOV/3IDpg4SZCb9wrSnb4K0l5/y5OgP8wUYL/MFKE/y9ShP8wU4X/L1CA/y1H + a/8iNlT/FytI/xIoRv8SKEr/EShL/xMnSf8SJkb/EiRB/xIkQP8SIz//EiRA/xIkQf8SJkb/EydI/xEm + R/8QI0P/FCZA/yU2Tv8/Um//RmKK/zNWh/8vUIP/L1CB/y5Mff8rSnj/KkZy/ydDbv8lP2v+JD9o/yM7 + ZP8iOGD/HTFP/i1AU+x5nKaxr+fudqzl7myo6vFsqurxbKrq8Wyz7PFstuzzbL/x9Wu97PZtnd/rgFHE + 1sEruNP1G6/M/xapx/8Xorz/F5ew/xWKov8WiJz/Fouk/xWYs/8Vor//F6jF/xioxP4jorvqI4mfmhR2 + iScAgKoGIZumFxWAnxgynKokQaGuTzy81m9Jw9uaPsHa5S271/8aq8j/HZu1/0+jtP+pyM//7urq/9fW + 1v+hpKH/mJ+W/6Sso/6hqaDtoqiilqKomyn///8BAAAAAIC/gASco5wknqeZN56lniKioqILAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAg8fRiEWK02OFipM6xktUeceNF65ITtigidGc3wrSnTIK0p4+S5O + f/8wUIL/MFKE/zBShP8wUoT/MFKF/zFTg/8zTXb/LUJh/x8wTP8XKkb/EydF/xEmR/8RJkj/ESdI/xAm + SP8QJkj/ESZH/xElR/8QJEX/ECRD/xQlQf8eL0f/M0Vc/0ddff9DYYv/M1aI/y1QhP8wU4T/L0+C/y1L + ev8pR3P/JUJs/CU+ae8iO2XoIDlf+B81W/scMVT+GSxO7BssTawrRVhOtd/VGL/f7xC04fARtOHwEbTh + 8BG04fARtPDwEcPh4RG///8QiszbI1e/0W83udHYI6W9/heTrP8UiaL/FYed/xaOp/8Ym7T/GajE/xmy + zv8atNL/HLnW/yO71v8qma/4Gmd4xA9balQui4sLAFVVAwAAAAAA//8BAMzmClzCzBl9q65YdK2x0WC/ + zv83wtz/GrXS/xehvf9FpLf/ss/V/+fn5v2xtbP6kpmS8pylm9yeqJ6+oKagdpeflyD///8BAAAAAAAA + AACqqqoDgICABP///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkSQcSKUZFFCpJmRku + T4UgOWNIMUJ7HyZEcSIsSnR5LEt46CtJef8uUIH/L1GC/y9Rgv8wUYL/L1KD/zBSg/8zVIX/NlOA/zJM + cf8wR2f/Kj5b/yE1UP8gMkz/HzJL/x0vSv8bLEj/HS1I/yExTP8kNE3/JzpU/zZIZP89VHT/Q16D/0Bg + jv8xU4b/LVCB/zBSg/8vUoP/L06A/yxJeP8nQ3H8JD9q4CM/Z58jPGOEHjhfqhwzVr0XK07RHDBTph83 + Z0oiM2YPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPaq2FTObr2kkmq/WGo2l/RWM + pf8Vkqz/GJ24/xiqxv8Zsc7/GrTR/xm30/8fudb/LcLd/zCwyP8daXb+EkZR6QlDT6gJR1JaEVFoLABt + bQcAAAAAAAAAAHGqqgmHn5hIj5eQxIOqqPJfu8T0Lr7X+haz0v8Zo8D/Vq2+/NDW1tnCxMO3mp+anZaf + lnCgqqBOmKOYL6KiogsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAHjwRFixTLiM+ah0AK1UGAAAAACBAYAgpQ2tYIz5m2yZDcv8uT3//LU19/y1N + ff8uTX//LlCA/zBQgv8wUoT/MFOF/zNWiP84WYb/OleB/zZSdv85UHL/PFNx/zxQb/88T2z/PlNw/0NY + dP9BV3n/Plp//0Nhif8+X47/MlOG/yxPgv8tT4H/L09//y5Of/8uTn//LUx9/ypJeP8nRHH3KUFvvCNC + bEkbQGQcIjplNR8zXEsZL1FoGDBYQBdGdAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ + /wFbyNsOIpy0SxKLpLQUjabzFZey/xikwf8Zrsv/GbPQ/xq10/8ZtdL/GrXT/yO71/82xeD/QL3V/yqE + lv8MRlL/CkNO/ghFUO4FQk7CB0hVcgxhbRUAAAAAAAAAAGaZmQWCnZ0vi6GXgoqhmaN3r7CsP7fM0hi4 + 1voVstH/IKTA9X+vtpnCzMlLsLWqLZmZmRSZmZkFgP+AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVAwAAAAEAAAAAAAAAASY5 + XhsgN1uBFy9R6yhFc/8sSnj/K0d0/ypIdf8rSXj/LUt8/y5QgP8wUIL/L1KE/zBRhP8wU4T/MVSG/zNX + hv83WIj/PFyJ/z9civ9AXon/Ql+L/z5fi/86Wor/NFeJ/zFUh/8uUIT/LE+B/y5Of/8tTHv/LUp6/y1K + ef8tSnn/LEt5/ytIdv8nQm/5ITdiyCRDcFQ5VY4JAABABAA5cQkYMVUVGk1mCgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAUnI2w4vu9BHH6zJphWkwPAXpsL/GK/N/xm00v8ZttL/GbbT/xu4 + 0/8iudX/MMHe/0LI4f9Ft83/L4ia/xNXZP8MTl3/DlRk/wtTYv8GTFrsCUtYkxNocRsAAAAAAAAAAAAA + AAGAlZUMhqafKIKnpzF5tLg9P7PIeRexz94UtdP8FbDN8ympv4NapbUfgICAAv///wEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAACBACBo0VU4VK0vLIThg/idFb/8nP2n/IT1l/CM9aOwmQW/4Kkh3/y1N + ff8vUID/MFCB/y9QgP8vUIH/L1CA/y9Qgv8wUIT/MFGE/zBShP8vUYP/L1GD/y9Qgv8uUIP/L1CC/y9R + gv8vUYL/Lk9+/y1Lev8rR3X/J0Vv/yRAbP4lQW3/KEVx/ypHcf8lP2v/GzBY7RcsUJwxSXkqAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8BN7HIFyeuyGIVnbrAKa3J9EzM + 4/88xuD+Mb/c/yzA3P8wwd3/Osbg/0rN5f9XzeT/UbjL/zSJmf8bZXP/DlJe/w5WZP8OUWD/Dllo/w5e + bf8LWmrlDFhoggtkbxcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAgIAEKrbLMRevzLMTsdD5FbXT/BKv + zbgYs89KGrPMCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABICtKGBMmSnkVKEvsIztg/yE4 + X/8fNFr6IjxlzCVCapAqSHS7LUp4+C1MfP8tTH7/Lk5//y1Mff8sTHz/LUx9/y1Nfv8uUID/L1CB/y9R + gv8vT4D/Lk5+/y1Mff8tTHz/LU1+/y5PgP8uT3//Lkt7/ytIdv8mQm/9IT5o7CVAbNMmQWzmJkBn/CU/ + aP8lPmb/HTNY+xIkQ9AiPmViJEltDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAas+YKH7HPSxejwrwVn772Pr7V93HW6dtp1ufZYs7f+F7L3/9dx9r/V7rN/0mmuf84jJv/IW16/xBQ + X/8OUmL/DVJh/w5ZaP8OWmj/D1xq/xJhb/cPYG29DlpoRwBmZgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAgIACEqzKKxKuzKsSrcr5FrTT/xOz0tYUs9BoD6XDEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAABpNCh4uVk0ZLFG5GzFT9hgtTvYcMFPTJkRuZiNHeCQrSnhkLUp63ClHdP8sTHv/LEt5/ytH + df8pRnT/KUZ0/yxKeP8sTHz/Lk6A/y5PgP8tS3z/LEp5/ytJdf8qSXX/K0l3/yxLev8tTHz/LEt6/ydG + cf4mQ2/lJkNumSNBal4mQm2IIzph2yA2W/8fNFn9Gy9S6hUrSrMbNFdeNzdtDgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA/wIfosEhD5y7hBKfvucru9X2UsrixG/R425ZtsJ+M4GN2yx0 + hP8rdIL/ImZ2/xdebP8QVmP/DlRj/w5TYf8OVWL/D1Zl/w5SYf8PXW3/EWFw/hJiceQPYG6HEVVmHgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIACDKTOKhGry6oRqsn5F7TS/xm209oVs9BsHrTSEQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARsoXhMfNFlTGy5RoRgsTakbL1FyIEBgGCsr + VQYmRXJDJkJszh84X/8rS3r/KUZy/ydBbf4kP2z6I0Fu+ChEdPosSnn/LUx8/y5Mff8rS3j/KkZz/ydB + bf4lQW35KERw/CxId/8sSXj/K0l2/yZCbvsiPWbSJD1mZBs2axMjOmMsIjpeiB0wU+MZLU7hFytNmRwy + VUghMVofAABVAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ASm41hkYpsNqC5W1zByv + zfVAxeDLZcndaFK20Rw1i5VNGF1tzAlJWv8NUF//DFFe/w1UY/8NVGL/DlNj/w9baf8OUmH/Dlhn/w5Z + Z/8UYnD+GWp36BVmc50SYW46AFVVBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIACDJy5LA+i + v6wRqcj5F7TT/Bu308AWs9BRF6LRCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAESJFsOFDRVJx0uVywVK0oYAAAAAQAzZgUjO2pBHTNWzR00Wv8qRXH/JD5m/SI7ZOYlQGusJ0RzlSpI + d7srSHnzKkl3/ytKeP8qRnP/JD5r+SI9Z9QiP2emLERxuylEcPAnQ3D/J0Rv/yQ+aP4dNFzmJD1mhSBA + YBgAKysGHjFVKhwxVG0cMVFuGzBQMBozTQoAAFUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAJLa2BxquyDwUo8C1EqPC9ie92uQ/xeKFXcHRIRpmZgoYY3BLD1hozAlRYf8NV2X/DFNi/w1W + Zv8OWGj/DFBf/w1YaP8NV2X/EVxq/xppePwicXzeJXJ8kiZoezYcVXEJAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAUxNgND6C7UxCaus8Urcr8GbfS9R200Y8itdAmAP//AgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgCAgAIAAAAAAAAAAAAzZgUbMlVCFipMzh42 + XP8kPGT/IDdc9yE5YMEnRGtWIUd3LytCdnclQG7kJEFu/ylGcv8lQGr8ITli2CE4YnokPWsyKkFrViI7 + ZLsgOWD4JkBo/yE6Yv8cM1fvIztklytEZh4AAAAAAABABBozWRQjLmgWACtVBgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF7noCxinwlQQn7/PGLHQ9Cy/27g3veJGVdX/BiBg + gAgXZXFEE19xuxRjcvIWZHP/EF9t/w9da/8PXm3/EF1p/xRib/8baXf/JHJ9+Ch3hNcrdYOOLnqFMiRt + bQcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAELtcoYE565fA+eu/AXs9L/HLrW7x+5 + 03QuxdwWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAMwUSKVI4GCtKthszVe0aMFH8GzFS3CE9ZnouQHYcHjxpESZAbmQgOGHfHzde/ydC + bf8jOmL3HzZcvSM6XUIAM2YFK01mHiM5XoIdM1jlHzZZ/xwxVP8VK0zvFy1OmitEZh4AAAAAAAAAAAAA + AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqqoDHLrWJRqu + y4oRoMHqG7nW6iu/3JA8u90eAAAAAQBVVQMRZm8eGmp2YxhodqASYnHVEWBw3w5ebd8PW23fE2Jx3yNy + fd8pdYPWJnOAry94hGwtfYgtJG1tBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA + /wIOmLMlD5q3lROnxPgcudf6Jr7Y0Ci30EdAn78IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAGkAUGC5PVB0yV48aL1G9GDJSiShD + ayYAQIAEK0CADCM+alcdMVjQGCtN/iM5YP8dNFf3HTRYtyE5YzYAAAABHDlxCSM6XUIXME+0FipL9Rov + UOIbMVXGGCpOfx89ZhkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAqtUGFrDGOhCiv7QSp8T7G7bS6RiwzogxztsVAAAAAAAAAAAAQEAEDG15FRVo + bTERYnNbEl9vYwpdamMVYnFjHGp2Yyx2gWMseoVcK3eAPCZzgBQrgIAGAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAP//AQuqvxgPm7lmEJ26yxWz0fwevdj2Lr/Ytza81yYA//8BAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABESJVDxw3WiUeNFlFGTJRKTMzZgUAAAAAAECABB43ZyobL0+XEiVD7xcrT/wVKkvzHDBRthw5 + VTYAAAABAACAAiIzVR4WK1FyFCdJqBktUXIdNF5PGzFRLwArVQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAttsHFKbCPw2cvb4SrMn9F7bU6BOt + zIgkztsVAAAAAAAAAAAAAAAAAAAAAAAzZgUUYnYNEWZmDwBVZg8RZncPImaIDyJ3iA8kgIAOJG1tBwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8BC6rVGBSlwWYRnbrFEqjG9hy5 + 1/8pwd3rKL/VmDO41hkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIgQGAIAECABAAAAAAAAAAAAAAAAB48 + aREdNVhXFypNqhMnSr0VKUy1FypNhRsvUSYAAAABAAAAAAAAJAcPJEkjGCtMNgwjURYXLkYLACuABgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAkrYHDKbGPxGlxL4Sr839F7TS6BGuzIgYttsVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ + /wELtcoYF6nFZRKgvMYSpML2GLbV/iK82O8yv9mvML7aSyS2tgcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVQMXLlEWGylNOBAlRj4RK008GCRHKxxVVQkAAAAAAAAAAAAA + AAAAAAADACtVBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkrYHDKrGPxGsyb4Trs/9FLTR6BWy0IcMqs4VAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAP//ARaxyBcSoMBhEJ66wxKiv/YXs9L/HLnW8Su/2a40vtVPM6rMDwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABADMzBQAA + KwYAACsGAEBABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkrYHEKrGPxGr + x8ATrs39FbPQ6xCvzowdutgaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtrYHE5W0KQyatG0PlrPJEqTD9hey + 0f8ZutXvH7zVqzLB1UI3ttsOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAqtUGFrDKOhGqyLURrMr8FrLQ9hCqy7oat9hOEpKkDgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+l + tBEOnLtLDJKvkw+WtdATpsP5F7PQ/xi41fEct9GwHrPNTU3M5goAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8CCbvMHhCpzH0Rq8rkF7PR/hOs + yuwSpMOtEarMSyC/vwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAqtUGFazBJRGevFwOlbO1EJu76RaqyvkXtdP/HLfU8Rm01LAdt85OEbvMDwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAKrjCRWxzUgWss69E7TS/Biyzv4QoL3sD5azrBitxEE5xsYJAP//AQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wEAv78IEqS/HBWatTAQnbpRDpWzkxCXt8USpMPzFbHO/ha2 + 1PcauNPaGrnRpxez0U0Ru8wPAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AQqnxBoVs9VsFrbUzhe20vwWrsr+E5+96hao + wqQZsNBRI7jNJCvV1QYA//8DAFWqAwBVqgMAVaoDAFWqAwBVqgMA1f8GC5+/GA6kwDUMm7dSD527ig2Y + t64OmLTGEqDB7RWsyvgVs9D7HLrV8By30bwfus9rF7bNOBKktg4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACq + qgMYr88gG7PQch2309Aaudb7Fq/P/Q+iv+wQmbTFE6TAkhKcvVUPnrRED5+8RQ+fwEUPo8BFEqPARQ+b + uUUNnrJPEJq3fBGevLAPmLTJDpy35xKnxvQUrsz4FbHQ9xe10OAcs8++F7PNnhuy0FYYqsIVK9X/BgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqqoDJrTLIiO813MhvNfRILzY+he11P4SqMj5EJ++6A6d + u8oPnLrBEKHAwQ+hwcEQocLBEKXCwQ+fusEPmLLHD5223xGkwvUTq8r5FK/M+xWz0vUUttLiFrPSrxez + 0Hget9FDHKzNLhC/zxAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKr/Aym9 + xR8oudVmJbvXvyK72uofudfzG7bV/ha10foTr9D5Eq7O+RGtzPkRrc35Eq7O+ROwzvkUtND6F7LP+BWy + 0ewUsNDYFbDPqhSx0IkTsdFpD6zONBWqyhggv98IAL+/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wIrv98YI7nZUCq72YAoutefHLbV1Ra00+cVstDnFLDO5xKs + zOcSq8vnErDN5xOx0OcWtdXeGLbTuBW1z4YUsM1nEq3IOBClxR8NockTAL+/BAAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8CFLHYDSa9 + 0Bslr88wILTUXxmy0nEXsNBxEqzJcRCpyXEQqcdxEq7HcRSuyXEUsdBoFrbQRhGzzB4Ns8wUAKrVBgCA + gAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAmcwFD6W0ERiethUYnrYVDJ62FQySqhUMkqoVDJKqFQye + qhUNobwTHKrGCQD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD//////gAAP/////////////gAAP/////wAAAP//////// + ////+AAA/////8AAAAH////////////4AAD/////AAAAAH////////////gAAP////4AAAAAH/////// + ////+AAA////+AAAAAAP///D///////4AAD////wAAAAAAP/g4HB//////gAAP///+AAAAAAAf8BAMD/ + ////+AAA////wAAAAAAAbwEAwHn////4AAD///+AAAAAAAAGAQCAYP////gAAP///wAAAAAAAAIAAABA + f///+AAA////AAAAAAAAAgAAAAB////4AAD///4AAAAAAAAAAAAAAH////gAAP///gAAAAAAAAAAAAAA + YP//+AAA///8AAAAAAAAAAAAAABAf//4AAD///gAAAAAAAAAAAAAAAB///gAAP//+AAAAAAAAAAAAAAA + AH//+AAA///wAAAAAAAAAAAAAAAAf//4AAD///AAAAAAAAAAAAAAAAD///gAAP//4AAAAAAAAAAAAAAA + AIP/+AAA///gAAAAAAAAAAAAAAABAf/4AAD//8AAAAAAAAAAAAAAAAAA//gAAP//wAAAAAAAAAAAAAAA + AAD/+AAA///AAAAAAAAAAAAAAAAAAP/4AAD//4AAAAAAAAAAAAAAAAAB//gAAP//gAAAAAAAAAAAAAAA + AAP/+AAA//+AAAAAAAAAAAAAAAAABA/4AAD//4AAAAAAAAAAAAAAAAAAB/gAAP//gAAAAAAAAAAAAAAA + AAAH+AAA//+AAAAAAAAAAAAAAAAAAAf4AAD//wAAAAAAAAAAAAAAAAAAA/gAAP//AAAAAAAAAAAAAAAA + AAAH+AAA//8AAAAAAAAAAAAAAAAAAB/4AAD//wAAAAAAAAAAAAAAAAAAP/gAAP//AAAAAAAAAAAAAAAA + AAAB+AAA//8AAAAAAAAAAAAAAAAAAAB4AAD//wAAAAAAAAAAAAAAAAAAAHgAAP//AAAAAAAAAAAAAAAA + AAAAeAAA//8AAAAAAAAAAAAAAAAAAAB4AAD//wAAAAAAAAAAAAAAAAAAAHgAAP//AAAAAAAAAAAAAAAA + AAAA+AAA//8AAAAAAAAAAAAAAAAAAAf4AAD//wAAAAAAAAAAAAcAAAAAAPgAAP//AAAAAAAAAAAAB8AA + AAAAeAAA//8AAAAAAAAAAAAH4AAAAAA4AAD//wAAAAAAAAAAAAfgAAAAABgAAP//AAAAAAAAAAAAB/AA + AAAAGAAA//8AAAAAAAAAAAAD8AAAAAAYAAD//wAAAAAAAAAAAAP4AAAAADgAAP//gAAAAAAAAAAAA/gA + AAAB+AAA//+AAAAAAAAAAAAD+AAAAAP4AAD//4AAAAAAAAAAAAP4AAAAAHgAAP//gAAAAAAAAAAAA/gA + AAAAOAAA//+AAAAAAAAAAAAD+AAAAAAYAAD//4AAAAAAAAAAAAPwAAAAABgAAP//wAAAAAAAAAAAA/AA + AAAAGAAA//8AAAAAAAAAAAAD4AAAAAAYAAD//gAAAAAAAAAAAAPAAAAAADgAAP/8AAAAAAAAAAAAA4AA + AAAP+AAA//gAAAAAAAAAAAAAAAAAAAf4AAD/+AAAAAAAAAAAAAAAAAAAAfgAAP/4AAAAAAAAAAAAAAAA + AAAA+AAA/+QAAAAAAAAAAAAAAAAAAAB4AAD/gAAAAAAAAAAAAAAAAAAAAHgAAP8AAAAAAAAAAAAAAAAA + AAAAeAAA/wAAAAAAAAAAAAAAAAAAAAD4AAD/AAAAAAAAAAAAAAAAAAAAAfgAAP8AAAAAAAAAAAAAAAAA + AAA/+AAA/wAAAAAAAAAAAAAAAAAAAA/4AAD/gAAAAAAAAAAAAAAAAAAAB/gAAP4AAAAAAAAAAAAAAAAA + AAAD+AAA/AAAAAAAAAAAAAAAAAAAAAP4AAD4AAAAAAAAAAAAAAAAAAAAB/gAAPgAAAAAAAAAAAAAAAAA + AAAP+AAA8AAAAAAAAAAAAAAAAAAAAB/4AADwAAAIAAAAAAAAAAAAAAAB//gAAPAAABwAAAAAAAAAAAAA + AAD/+AAA+AAAHgAAAAAAAAAAAAAAAP/4AAD/AAAfAAAAAAAAAAAAAAAA//gAAPwAAB+AAAAAAAAAAAAA + AAD/+AAA+AAAH8AAAAAAAAAAAAAAAf/4AADwAAAf4AAAAAAAAAAAAACD//gAAPAAAA/wAAAAAAAAAAAA + AGf/+AAA8AAAB/gAAAAAAAAAAAAAf//4AADwAAAD+AAAAAAAAAAAAAB///gAAPgAAAAAAAAAAAAAAAAA + AH//+AAA/AAAAAAAAAAAAAAAAABA///4AAD/wAAAAAAAAAAAAAAAAGH///gAAP+AAAAAAAAAAAAAAAAA + f///+AAA/wAAAAAAAAAAAAAAAAB////4AAD+AAAAAAAAAAAAAAAAAH////gAAP4AAAAAAAAAAAAAAAAg + f///+AAA/gAAAAAAAAAAAAIAADH////4AAD/AAAAAAAAP8AAAYAAf/////gAAP8EAAAAAAB/gAABgAD/ + ////+AAA/8gAAAAAAP8AAAGAA//////4AAD/+AAAAAAH/gAAAfAH//////gAAP/wAAAAAAf+AAAB+Af/ + ////+AAA//gAAAAAB/wAAAP4B//////4AAD/+AAAAAAH+AAAA/gH//////gAAP/8AAAAAA/4AAAH+Af/ + ////+AAA//8wAAAEP/gAAA/wD//////4AAD///AAAAd/8AAAH/AP//////gAAP//8AAAB//wGAA/4A// + ////+AAA///4EAAH//AeAP/AH//////4AAD///44BA//8B///4Af//////gAAP////gOf//wH///AD// + ////+AAA/////B////Af//4Af//////4AAD/////////8A///AD///////gAAP/////////wB//wAf// + ////+AAA//////////gB/wAB///////4AAD/////////+AAAAAf///////gAAP/////////8AAAAD/// + ////+AAA//////////4AAAAf///////4AAD//////////wAAAH////////gAAP//////////gAAB//// + ////+AAA///////////AAAf////////4AAD///////////AAf/////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAA= + + + \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Views/CustomGolfActions.Designer.cs b/ToonTown Rewritten Bot/Views/CustomGolfActions.Designer.cs new file mode 100644 index 00000000..a0faaec5 --- /dev/null +++ b/ToonTown Rewritten Bot/Views/CustomGolfActions.Designer.cs @@ -0,0 +1,165 @@ +namespace ToonTown_Rewritten_Bot.Views +{ + partial class CustomGolfActions + { + /// + /// 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(CustomGolfActions)); + updateSelectedActionItemBtn = new System.Windows.Forms.Button(); + actionItemsListBox = new System.Windows.Forms.ListBox(); + loadActionItemBtn = new System.Windows.Forms.Button(); + saveActionItemBtn = new System.Windows.Forms.Button(); + label1 = new System.Windows.Forms.Label(); + actionTimeTxtBox = new System.Windows.Forms.TextBox(); + comboBox1 = new System.Windows.Forms.ComboBox(); + removeItemBtn = new System.Windows.Forms.Button(); + addItemBtn = new System.Windows.Forms.Button(); + SuspendLayout(); + // + // updateSelectedActionItemBtn + // + updateSelectedActionItemBtn.Enabled = false; + updateSelectedActionItemBtn.Location = new System.Drawing.Point(248, 82); + updateSelectedActionItemBtn.Name = "updateSelectedActionItemBtn"; + updateSelectedActionItemBtn.Size = new System.Drawing.Size(188, 28); + updateSelectedActionItemBtn.TabIndex = 18; + updateSelectedActionItemBtn.Text = "Update Selected Item"; + updateSelectedActionItemBtn.UseVisualStyleBackColor = true; + updateSelectedActionItemBtn.Click += updateSelectedActionItemBtn_Click; + // + // actionItemsListBox + // + actionItemsListBox.FormattingEnabled = true; + actionItemsListBox.ItemHeight = 15; + actionItemsListBox.Location = new System.Drawing.Point(12, 12); + actionItemsListBox.Name = "actionItemsListBox"; + actionItemsListBox.Size = new System.Drawing.Size(230, 244); + actionItemsListBox.TabIndex = 17; + actionItemsListBox.SelectedIndexChanged += actionItemsListBox_SelectedIndexChanged; + // + // loadActionItemBtn + // + loadActionItemBtn.Location = new System.Drawing.Point(12, 273); + loadActionItemBtn.Name = "loadActionItemBtn"; + loadActionItemBtn.Size = new System.Drawing.Size(144, 34); + loadActionItemBtn.TabIndex = 16; + loadActionItemBtn.Text = "Load Action Item"; + loadActionItemBtn.UseVisualStyleBackColor = true; + loadActionItemBtn.Click += loadActionItemBtn_Click; + // + // saveActionItemBtn + // + saveActionItemBtn.Location = new System.Drawing.Point(172, 273); + saveActionItemBtn.Name = "saveActionItemBtn"; + saveActionItemBtn.Size = new System.Drawing.Size(144, 34); + saveActionItemBtn.TabIndex = 15; + saveActionItemBtn.Text = "Save Action Item"; + saveActionItemBtn.UseVisualStyleBackColor = true; + saveActionItemBtn.Click += saveActionItemBtn_Click; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(248, 160); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(117, 15); + label1.TabIndex = 14; + label1.Text = "Time for action (ms):"; + // + // actionTimeTxtBox + // + actionTimeTxtBox.Enabled = false; + actionTimeTxtBox.Location = new System.Drawing.Point(248, 178); + actionTimeTxtBox.Name = "actionTimeTxtBox"; + actionTimeTxtBox.Size = new System.Drawing.Size(144, 23); + actionTimeTxtBox.TabIndex = 13; + // + // comboBox1 + // + comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + comboBox1.FormattingEnabled = true; + comboBox1.Items.AddRange(new object[] { "SWING POWER", "TURN LEFT", "TURN RIGHT", "MOVE TO LEFT TEE SPOT", "MOVE TO RIGHT TEE SPOT", "DELAY TIME" }); + comboBox1.Location = new System.Drawing.Point(248, 14); + comboBox1.Name = "comboBox1"; + comboBox1.Size = new System.Drawing.Size(188, 23); + comboBox1.TabIndex = 12; + comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged; + // + // removeItemBtn + // + removeItemBtn.Location = new System.Drawing.Point(345, 48); + removeItemBtn.Name = "removeItemBtn"; + removeItemBtn.Size = new System.Drawing.Size(91, 28); + removeItemBtn.TabIndex = 11; + removeItemBtn.Text = "Remove Item"; + removeItemBtn.UseVisualStyleBackColor = true; + removeItemBtn.Click += removeItemBtn_Click; + // + // addItemBtn + // + addItemBtn.Location = new System.Drawing.Point(248, 48); + addItemBtn.Name = "addItemBtn"; + addItemBtn.Size = new System.Drawing.Size(91, 28); + addItemBtn.TabIndex = 10; + addItemBtn.Text = "Add Item"; + addItemBtn.UseVisualStyleBackColor = true; + addItemBtn.Click += addItemBtn_Click; + // + // CustomGolfActions + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(453, 320); + Controls.Add(updateSelectedActionItemBtn); + Controls.Add(actionItemsListBox); + Controls.Add(loadActionItemBtn); + Controls.Add(saveActionItemBtn); + Controls.Add(label1); + Controls.Add(actionTimeTxtBox); + Controls.Add(comboBox1); + Controls.Add(removeItemBtn); + Controls.Add(addItemBtn); + Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); + Name = "CustomGolfActions"; + Text = "Custom Golf Actions Manager"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private System.Windows.Forms.Button updateSelectedActionItemBtn; + private System.Windows.Forms.ListBox actionItemsListBox; + private System.Windows.Forms.Button loadActionItemBtn; + private System.Windows.Forms.Button saveActionItemBtn; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox actionTimeTxtBox; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.Button removeItemBtn; + private System.Windows.Forms.Button addItemBtn; + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Views/CustomGolfActions.cs b/ToonTown Rewritten Bot/Views/CustomGolfActions.cs new file mode 100644 index 00000000..f5b54c96 --- /dev/null +++ b/ToonTown Rewritten Bot/Views/CustomGolfActions.cs @@ -0,0 +1,227 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Models; +using ToonTown_Rewritten_Bot.Services; +using WindowsInput; + +namespace ToonTown_Rewritten_Bot.Views +{ + public partial class CustomGolfActions : Form + { + public CustomGolfActions() + { + InitializeComponent(); + } + + private void addItemBtn_Click(object sender, EventArgs e) + { + string selectedItem = comboBox1.SelectedItem?.ToString() ?? ""; + // Check if the action is one that can have a duration + if (selectedItem == "DELAY TIME" || selectedItem == "SWING POWER" || selectedItem == "TURN LEFT" || selectedItem == "TURN RIGHT") + { + if (int.TryParse(actionTimeTxtBox.Text, out int timeInMilliseconds)) + { + actionItemsListBox.Items.Add($"{selectedItem} ({timeInMilliseconds} milliseconds)"); + actionTimeTxtBox.Clear(); // Clear the TextBox after adding + } + else + { + MessageBox.Show("Please enter a valid time in milliseconds.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + else if (!string.IsNullOrEmpty(selectedItem)) + { + // For other selections like "MOVE TO LEFT TEE SPOT" or "MOVE TO RIGHT TEE SPOT" that do not require duration + actionItemsListBox.Items.Add(selectedItem); + } + else + { + MessageBox.Show("Please select an item from the ComboBox.", "No Selection", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + + private void removeItemBtn_Click(object sender, EventArgs e) + { + actionItemsListBox.Items.Remove(actionItemsListBox.SelectedItem); + } + + private void updateSelectedActionItemBtn_Click(object sender, EventArgs e) + { + if (actionItemsListBox.SelectedItem == null) + { + MessageBox.Show("No item is selected to update."); + return; + } + + int selectedIndex = actionItemsListBox.SelectedIndex; + string selectedItem = comboBox1.SelectedItem?.ToString() ?? ""; + + if (selectedItem == "DELAY TIME" || selectedItem == "SWING POWER" || selectedItem == "TURN LEFT" || selectedItem == "TURN RIGHT") + { + if (int.TryParse(actionTimeTxtBox.Text, out int timeInMilliseconds)) + { + actionItemsListBox.Items[selectedIndex] = $"{selectedItem} ({timeInMilliseconds} milliseconds)"; + } + else + { + MessageBox.Show("Please enter a valid time in milliseconds.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + } + else + { + // No duration to update, just update the action + actionItemsListBox.Items[selectedIndex] = selectedItem; + } + } + + private void loadActionItemBtn_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new OpenFileDialog + { + Filter = "JSON File|*.json", + Title = "Open an Actions JSON File", + InitialDirectory = (string)CoreFunctionality.ManageCustomActionsFolder("Golf", false) // Getting the folder path only + }; + + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + string json = File.ReadAllText(openFileDialog.FileName); + var actionsList = JsonConvert.DeserializeObject>(json); + + actionItemsListBox.Items.Clear(); + foreach (var action in actionsList) + { + string displayText; + // Check if the action is associated with a duration and is not "TIME" + if (action.Duration > 0 && action.Action != "TIME") + { + displayText = $"{action.Action} ({action.Duration} milliseconds)"; + } + else if (action.Action == "TIME") + { + displayText = $"TIME ({action.Duration} milliseconds)"; + } + else + { + displayText = action.Action; // For actions without a duration + } + actionItemsListBox.Items.Add(displayText); + } + } + } + + private GolfActionKeys _golfActionKeys = new GolfActionKeys(); + private void saveActionItemBtn_Click(object sender, EventArgs e) + { + List actionsList = new List(); + + foreach (var item in actionItemsListBox.Items) + { + string actionText = item.ToString(); + GolfActionCommand actionCommand = new GolfActionCommand(); + + // Extract just the action name in case the text includes duration + string actionName = actionText.Contains("(") ? actionText.Substring(0, actionText.IndexOf('(')).Trim() : actionText; + + // Check if the action text includes time specification and parse it + if (actionText.Contains("milliseconds")) + { + actionCommand.Action = actionName; + actionCommand.Command = actionName; // Command is typically the action name or key command + // Parse the duration from the list item + actionCommand.Duration = int.Parse(actionText.Split('(')[1].Split(' ')[0].Replace("milliseconds", "").Trim()); + } + else + { + actionCommand.Action = actionName; + if (_golfActionKeys.ActionKeyMap.TryGetValue(actionName, out VirtualKeyCode keyCode)) + { + actionCommand.Command = keyCode.ToString(); + // Apply default duration for specific actions not specified as "milliseconds" + if (actionName == "MOVE TO LEFT TEE SPOT" || actionName == "MOVE TO RIGHT TEE SPOT" || actionName == "TURN LEFT" || actionName == "TURN RIGHT") + { + actionCommand.Duration = 50; // Set a specific duration for tee and turn actions + } + else + { + // If no duration is specified in the list item, apply a default duration or leave as is + // Consider providing a user interface to specify this default duration or set a logical default here + actionCommand.Duration = 1000; // Example: Default duration for unspecified actions + } + } + else + { + MessageBox.Show($"No key code found for the action: {actionName}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + continue; // Skip adding this action if the key code is not found + } + } + + actionsList.Add(actionCommand); + } + + string json = JsonConvert.SerializeObject(actionsList, Formatting.Indented); + SaveToJsonFile(json); + actionItemsListBox.Items.Clear(); + } + + private void SaveToJsonFile(string jsonContent) + { + string folderPath = (string)CoreFunctionality.ManageCustomActionsFolder("Golf", false); // Getting the folder path only + + SaveFileDialog saveFileDialog = new SaveFileDialog + { + Filter = "JSON File|*.json", + Title = "Save an Actions JSON File", + InitialDirectory = folderPath + }; + + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + File.WriteAllText(saveFileDialog.FileName, jsonContent); + MessageBox.Show($"Actions saved to {saveFileDialog.FileName}", "Save Successful", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) + { + string selectedItem = comboBox1.SelectedItem?.ToString() ?? ""; + if (selectedItem == "DELAY TIME" || selectedItem == "SWING POWER" || selectedItem == "TURN LEFT" || selectedItem == "TURN RIGHT") + actionTimeTxtBox.Enabled = true; + else + actionTimeTxtBox.Enabled = false; + } + + private void actionItemsListBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (actionItemsListBox.SelectedItem != null) + { + updateSelectedActionItemBtn.Enabled = true; + string selectedItem = actionItemsListBox.SelectedItem.ToString(); + + if (selectedItem.Contains("TIME") || selectedItem.Contains("SWING POWER") || selectedItem.Contains("TURN LEFT") || selectedItem.Contains("TURN RIGHT")) + { + comboBox1.SelectedItem = selectedItem.Split(' ')[0]; // Select the action type without duration + string timeValue = new String(selectedItem.Where(char.IsDigit).ToArray()); + actionTimeTxtBox.Text = timeValue; + actionTimeTxtBox.Enabled = true; + } + else + { + comboBox1.SelectedItem = selectedItem; + actionTimeTxtBox.Clear(); + actionTimeTxtBox.Enabled = false; + } + } + } + } +} diff --git a/ToonTown Rewritten Bot/Views/CustomGolfActions.resx b/ToonTown Rewritten Bot/Views/CustomGolfActions.resx new file mode 100644 index 00000000..940fa3ce --- /dev/null +++ b/ToonTown Rewritten Bot/Views/CustomGolfActions.resx @@ -0,0 +1,1499 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + AAABAAEAjY0AAAEAIADQQQEAFgAAACgAAACNAAAAGgEAAAEAIAAAAAAApDYBABIXAAASFwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUDAElbDgxVVRUMVVUVDElVFQA9 + SRUAPUkVAD1JFQA9SRUAPUkVAD1JFQA9SRUAPUkVAElhFQ1ZZhQAZmYPAEBABAAAAAEAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAE1mCgpS + UhkGS1cpCVBfVgtZZnALVF9zC1FecgtFU3ILRVNyC0VRcgtFUXILRVFyC0VRcgtFU3ILSFdyC1JfcwtW + ZnEITl9bBlFdLApYYhoLYGoYAE5ODQBVVQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAgBNZgoITVUhDlVjSAtVYHgMUFyTCk1XywpSX+UNT13nDE1b5wpJVucKSljnDEpY5wxK + WOcMSljnDEpX5wpLWOcMS1nnDE9c6AxRXuUJS1nQCktYnAxWYoANWmV3CVJeUQhkdCEVaoAMAFWqAwAA + gAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAIAW1sOB1VjJApUZUkLT1uHCk1ZugpQXOUMUV3xDFRh/Qxb + af8OYXD/EGZ3/xFqfP8RbID/Em+B/xJvg/8Sb4L/Em5//xFrff8QZnf/D2Jy/w1ba/8MVmT9DVBe8gxQ + XusJUV3kC09bwg1XZokJXWlVBltmLRBYYCAAQEAMAFVVAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRJBwdXXyMMVmJWDFBelQlN + W8gLTVrxDFNg/A9da/8RbH3/FIKV/xiTq/8Yn7r/GKjF/xiryP8Zrsz/GbDP/xqwz/8Zr8//Ga/N/xmr + yv8YqsX/GKS9/xeXsf8Wh57/E3aK/xBmdv8OWmn/DVNh/QtOXvEJT1zSClFcrg1LWI4NTl9ODVdrJgBV + VQkAVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + gAIAVVUPCktfMwpUX4MKT17HC01c7gxUYvwQZHX/FH6T/xeXrv8Yp8L/GbTR/xu41/8butj/G7rX/xu6 + 1/8butf/G7rX/xu61/8butf/G7rX/xu61/8butf/G7rY/xu51/8bttP/Ga/L/xeivf8Xkqv/FH6T/xBo + ef8PV2b+Ck9c+QhMWesLTlzBDVZliwpOXEsHV1cjAFWABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACAgIACgICACGZmZgqZmZkFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAADMzBQdQXyMMUV1YCk9elQpMW+EMVGD8EGJz/xR/lf8Xnbf/GrLO/xq4 + 1v8budb/GrfV/xq21P8attP/GrbT/xq20/8attT/GrbT/xq20/8attP/GrbT/xq20/8atdL/GrXS/xq2 + 1P8auNX/GrjW/xq51/8budb/GbHP/xeivv8UjKP/EnCC/w9cav8KUF37CUxc6gxMWcAKTliCEFNjMQB0 + iwsAVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgIACcY5xCXd3 + dw+Ojo4JAAAAAQAAAAAAAAAAAAAAAFVVVQN2gHYceHx1RnuBe013iHcvqqqqCQAAAAAAAAAAAAAAAAAA + AAFtkkkHbW1tDmaAZgpVVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKysGC0pVLQpQXYMJTV3NCUxZ7Q1Y + Zv4TdYf/F5mx/xmy0P8butf/GrfW/xq31P8attT/GrjU/xq31v8auNX/GrfW/xq31v8attT/GrbU/xq2 + 1f8at9b/GrjW/xq41f8at9b/GrfV/xq30/8attP/GrXS/xq10v8attP/GrjU/xq51v8auNX/GKvI/xWQ + qv8TdYj/Dl5s/wpOXPsKTFveDlNilw1ecVEJansdAFWqAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAFVVVQN2gG0ceoV3S3qAel5+gXZFqqqqEgAAAAEAAAAAAAAAAoCJgBp2fXRsb3Rtv32D + esqAhH+Vp7GnNFVVVQMAAAAAAAAAAICAgAptdm02b3dvXHh4eEiEjoQbqqqqAwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr + KwYLVVstDVRihQlOXt4JTVv/EV5s/xWAlv8Yq8n/GrvX/xq41P8at9T/GrjV/xq51v8bt9T/GrLR/xqu + yf8YpsH/F6C3/xaZsv8Wlq//Fpat/xaXsP8WnbX/GKG7/xmpxP8asM3/GrXS/xu41P8autf/GrjW/xq2 + 0/8attP/GrXS/xq10v8attP/G7jX/xq41v8Yrcn/FpGp/xNvgf8OWGn9C01d7wtVZcINX2p0DV5yJhFm + Zg8AAIACAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAIyMjBR6gnhkdnx1wHR6dNpzeG+znKacUI6O + jgkAAAAAgICABoCNhDp3enS0bnRu/I+Vjf2JkYjao6ygaZKSbQcAAAAAAAAAAHyDfCdyeXKJcnly0nt/ + e7uDiYFhkp6SFf///wEAAAAAAAAAAAAAAAAAAAAA////AQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAACtVBgxRVywMT1yFCU5d3QpOXP8RZHP/Foqk/xiuy/8auNf/GrjU/xq4 + 1/8audf/GrTQ/xinwf8Xlq7/FIaa/xNyhf8QYXD/D1Vi/w5PXP8OTVn/Dk1Y/w5NW/8OUV7/EFpo/xFo + eP8TeY3/FYug/xeZsv8YpsP/GrPQ/xu62P8audf/GrfU/xq20/8atdL/GrXS/xq30/8buNb/GrfU/xeo + wv8Vh5//D2h4/wtSX/kKTFnTDFRijw9jb1UVYGoYkpKSB2uGeRNvhXoXgICABgAAAAAAAAAAgICAAnZ8 + didzeHCidnx094iPh/98gnzrj5WNi5mjmRkAAAAAbZJtB36FfkF+g3zAkJeP/ay0q/6cpZzhkZmRdqqq + qgkAAAAAmZmZBX6BflF7gHi/iY+I+I+Yj++NlIyblqGWLv///wIAAAAAAAAAAJmZmQV5eXkVd4B3HoaG + hhO/v78EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAEBkRRKQpOW4YJUFzbC1Bd/xJm + d/8Wkqj/GbLP/xu51/8audX/GrfV/xquyf8XnbT/FICV/xBjc/8PU2L/DU5a/wxJVv8NSVT/DUtZ/w5P + XP8OUWD/DlFf/w5QX/8OTVv/DUtX/w1JVf8NSlf/DlBd/w9YZf8QYnP/FHuP/xaVrv8Yp8T/GbLP/xu5 + 1v8bt9b/GrbT/xq10v8atdL/GrfU/xu51P8ass//F5y0/xJ0if8NWGj8ClBc6wtWY74aYm5rUWhoQl1p + Zmtgbmlyc3hzNYCAgAYAAAAAgICAAnmAeSp4gHisjZaM+amyqf+ZopfxfoR7pJmkny2AgIACkpKSB3h8 + eEJ5gHnCl5+W/aWtpP6aoZnhjJOMdqqqqgkAAAABhpJ5FW91b4x/hH/npKqi/6y2rPOlrqWkpaqlM4CA + gAIAAAAAqqqqBoKIgi11enJrcXdvh32FfWKOlY4kv7+/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAASmAYCU1bcAdNWOQMT1z/EWZ1/xeVr/8bttL/G7rX/xq41/8btdL/Fpmx/xFoev8OT13/DUtW/wxO + Wv8PVWP/D1xr/w9ebv8OXm//DV5v/w1ebv8NXW7/DF1u/wxdbv8MXm7/DV5v/w1db/8OXGz/Dlpp/w5V + Y/8PT1z/DEZT/wxJVf8QXW3/E3uP/xeivf8attX/G7fX/xq31P8atdL/GrXS/xq10v8bt9T/G7fU/xmr + x/8Wi6P/EGZ2/wtQX/kOUl7bLlRbwlNYU+JbX1ribGplkICAeCQAAAAAgICAAnmGeSp+hHuqh42I+aSr + o/+epp77goqC0o2XjWWAmYAUoqKiFnuGe111fHXPn6ed/aWspP6epp7pmqGYjaGhoRuAkoAOiIiEPHB1 + cMaHjob6pq2k/6Sro/OlraWiqK2jMoCAgAIAAAABgI+AIG52cH9wdm/aeH129ICDfM6KkohpmbOZFAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVVQMOXmg2DFJeqAlOWvoQYG3/Foyl/xu00f8audb/GrjX/xmq + xf8Teoz/D09b/w1JU/8NUmD/Dltp/w9ecP8OX2//DVxr/wxbav8NXGz/DVxs/w5cbf8QXW3/EV9t/xFe + bv8PXW3/DVxs/w1cbP8NXGz/DVxs/w1dbv8OXm7/DlRj/w5LWf8NT1z/DEpW/xBaaf8UfJL/GKXC/xq4 + 1f8at9b/GrfT/xq10v8atdL/GrbT/xu31f8ZsdD/F5Wv/xJtgP8LU2D+FFBa/EViZP9pcGv5YF5bxWpq + ZFJ0dHQLgICAAoCGgCp+hH6qh42G+aSro/+jqqL/kJeQ7nyGfKaFlIVWfoZ+YXqCeq15fnnxoqih/6Ws + o/+gqZ/4kJeQy36Dfm+Dg4NOgYV+f3+Gf+eXn5f/p66m/6SqovOjqaKnpKifNaqqqgOAmYAKbnJrSmdr + Z7WEiYT2oKif/aCqn9WfqJ9tqraqFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAUBALU2ByCk5c3A1a + Z/4VhZr/GK/P/xq62P8atdT/F5+7/xFtfv8MQkz/DEZS/w9ZaP8PX2//Dltr/w1bav8RXW3/HGV0/zFy + gP9Ggo3/UoiU/1iNlv9jlZ7/aZeg/2aWnv9ckJn/UoiU/02FkP8+fIj/J2x6/xlicv8PXG3/DFVk/w1S + Yf8OXm3/Dltp/w5SYP8MSlb/EF1t/xWIn/8Zq8f/GrfX/xq31P8attP/GrXS/xq20/8at9X/G7TQ/xee + uf8SdYr/D1ho/xlXYv9Hamz/ZWtm7V5bVqZrdm9FjIyMFH2CfTd+hH6who2G+aSro/+lrKP/m6Ob/H2E + e+p3fHbMcHZx1G5zbfGGi4T/pKuj/6SspP+gp6D/hIuE92txbNt8gXzKe4B62YmQiPujq6P/payk/6Cn + n/iepJ2+nJ+aWJWVjR2Ag4BAbXBrm3d8eOaaoJr+qLGn9KizqKqttq07mZmZBQAAAAAAAAAAgICABHR0 + dAttgG0OYGBgCP///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAFWABgVgajUKTlutDFFf8xN3iv8YqMX/G7vY/xq20/8Xla3/D1lp/wxGUP8PWWn/DlZl/wxT + Y/8OXGv/F2Ny/zBygP9RipT/iK20/7jJzP/V2dn/3t3d/9/c3P/h3dz/497d/+Hf3f/f29z/3dzb/9ja + 2f/H0dL/pL3B/3ahqP9Ig43/Lmt3/xpcav8PXGz/DFxs/wxcbP8PW2r/DVBe/wxJVv8Ranv/F5y2/xm0 + 0P8auNb/GrfU/xq10v8atdL/GrfU/xu10v8XpsH/E3yS/wxXZP8XVWD/P2Vm/1dfWe1ia2eudHlwcG50 + bn13fnjMiI+I+6Sqo/+lq6P/oamh/5Oak/+Hjof+j5eP/pmgmP+iqaL/o6qj/6Oqov+hqqH/oKaf/5ee + lv+SmpL+kJWP/p6lnv+krKP/pauj/5qgmf+Ijojsg4aCsX6BeoJyd3KlcHZw5o6Vjf6orqb/pa2l8Kuz + q5eurq4pAAAAAQAAAACAgIAEcXhxJG1wbVJqbWpecntyOoiZiA8A/wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIACB2BnJQ5ZaJALUF3pEGR1/xidt/8audf/G7bV/xaS + qv8OU2D/DElU/w9ca/8OXm7/C1Zn/xNVZv80dYH/bZ6m/7DKzf/f4uL/8uvp/+3o5v/l4+H/4t/f/9/f + 3//f3Nz/3dzc/93c3P/f3dz/393d/+De3v/l4eD/7OXj/+vl5f/V2tr/r8DE/3mhqP8/fYr/Imh2/w9c + bf8MWmr/DV1t/w9ZZ/8OTFn/DlVj/xWDmf8Zrsv/G7rX/xq30/8atdL/GrXS/xq10v8attL/GKfD/xN9 + kf8PWWn/F1Rf/0BiY/9aXlr2aGpm4mltaOV7gXv4mJ6Y/6Sro/+jq6P/pKqh/6SspP+mr6f/pauj/6Sr + o/+kq6P/o6qi/6Oqov+jqqL/pKyk/6WspP+lrKT/pq+m/6Srov+jqqL/pKuj/56lnP+JkIn/fIF79XN3 + cehqbWnzhIuE/6Sro/+kraT/pa2k8Kuzq5eorq4pAAAAAUBAQAR0fHQha3Jtd2luashobmjXdHh0o4OL + g0Kfn58IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXV0LDlVmWgxT + YdYLVGL/FX2U/xu30/8bu9n/FZex/w5VZP8NSlf/D11u/w1eb/8NWWn/Hmd1/12Omf+zys//8/Ly//35 + 9v/x7ev/5OTj/+Hi4v/g4OD/4ODg/9/g4P/e4OD/3uDg/97f3//f39//4ODg/+Dg4P/f39//4OHg/+bl + 5f/u6en/8uno/+zm5P/F0NH/ia2z/0qFj/8dZHT/C1lq/wxbbf8OXWz/D1Bf/w1LWP8SboD/F6C8/xu6 + 2P8at9b/GrXS/xq10v8atdT/GrbU/xemw/8TfpP/D1hn/xZTX/9BYGD/bHBq/4uQh/+jqaL/pK2l/6Kp + of+gqZ//oKig/6GooP+iqaD/pKqj/6WspP+lrKT/o6qi/6Oqov+jqqL/o6qi/6Spo/+jqqL/oqmh/6Gp + oP+hqKD/oaig/6Oro/+nrqb/pauj/5WclP+PlpD/naae/6SrpP+kq6P/o6ui8qCnoKOlqqUzgICACGxs + bCFgZmBwaG5nzoCGf/uIj4j+gYmB1IqUimacnJwSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAgAIAUV4mDVRjmAtMWvERanv/GJ66/xu83f8Yobz/EGBv/w1IU/8PXGz/Dlxs/xJd + bf84eIf/hbC2/9vo6v/6+vr/6enp/97e3v/m5+f/5+fn/+Pj4//j4+P/4eHh/+Hh4f/h4eH/4uLi/+Li + 4v/i4uL/4+Pj/+Tk5P/k5OT/2dnZ/7CwsP+0tbX/3t/f/+Xk5f/t5+f/8Ojn/8fR0/9+pq3/PXuJ/xdh + cf8MWmr/DV1t/w5WY/8NS1b/EWNz/xactf8attT/GrjW/xq10v8atdL/GrfT/xq21P8ZpsH/FH6S/w1a + af8hXGX/YXx6/5KXj/+boZr/n6ie/6Wso/+psan/sLew/7e9tv+/xL//wsfC/7a8tf+iqaH/o6mh/6Oq + ov+jqqL/pKqj/7K2sf+/xL//vcK8/7S7s/+utKz/p66n/6Sqov+hqaH/o6qi/6iupv+osKj/pa2l/6Oq + ov+krKP/l5yW+YOIgsyAhH1yeoF2Q2ZsZnZiaWLKgYiC96WupP+ss6v1qLCosqKpokeOqo4JAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOYg0LUmNdC1Je1gtTYP8ViZ7/Gbra/xms + yP8RZXX/DEhU/w9dbf8NXGz/EVts/0WBj/+61Nj/+/r6//v6+v/j4+P/kZGR/25ubv/Dw8P/7+/v/+fn + 5//j4+P/4uLi/+Li4v/k5OT/5OTk/+Tk5P/m5ub/5ubm/+jo6P/r6+v/xcXF/1VVVf9FRUX/qqqq/+vr + 6//j4+P/5OPj/+rl5v/s5uX/xNDR/3Cepf8qcH3/DVlp/wxcbf8PXGv/DlFd/w9ZZ/8VjaT/GrbV/xu5 + 1v8atdL/GrXS/xq21P8bttP/GKnE/xN9kv8MVmX/IFZg/2R6ef+hopz/tbm0/8fMx//Z29f/5ujm/+/w + 7f/19fX/7u/v/7y9vP+HjYf/n6ad/6Oro/+jqaL/o6uj/7zAuv/o6ej/8/Pz/+jp6P/e4N7/0dbQ/8LG + wP+0urT/qbCq/6Opof+gqKD/oqqi/6Sqov+lrKP/mp6Z/36FfvpxeXLbbXRtxGpvat6FjIX6o6qi/6eu + pvukrKLWpK2kc6q1qhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVAwZb + YSoNWWigCUtb9xBlc/8Yp8H/GrfU/xN+kv8NSVX/DlZm/w5cbf8SXWz/QoCN/63M0P/5+/r/+fj3//T0 + 9P/U1dX/WVlZ/ygoKP+FhYX/8/Pz/+rq6v/j4+P/4eHh/+Hh4f/j4+P/5OTk/+fn5//o6Oj/6enp/+rq + 6v/u7u7/2tra/5mZmf9LS0v/b29v/+jo6P/n5+f/5OTl/+Tj5P/m5eT/7Onm/9/g4P+euL3/QX2K/xFe + bv8MWmr/Dlxr/w9QXv8NU1//FIqg/xq20v8buNb/GrXS/xq10v8atdP/GrXT/xikvv8Sdor/D1Nh/zdm + bv+nsK3/4N3c//Hw8f/5+fn/+/r7//j4+P/29vb/5ubm/6qrqv97f3r/oaie/6Oro/+jqqL/oqmi/7K3 + sf/f39//9/f3//r6+v/7+vv/+Pr4//Hy8f/j5eL/0NbS/7/Ev/+wt7D/qK+n/6SrpP+jqqL/payk/6Oq + ov+Um5T+goiC/IuRiv2iqaH/pq6k/aSqouKnrqeRpa+lM5nMmQUAAAAAAAAAAW1tbQdqgGoMgICACmaZ + ZgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAADtiDQtRWlsLTlvUC1Ff/xR/lP8butr/F5y1/w5OWv8MUF3/D15u/xFc + bP8+fIv/rcvR/+/u7f/y8fD/9/f3//b29v/p6en/i4uL/yMjI/9tbW3/8vLy/+zs7P/j4+P/3t7e/9bW + 1v/Y2Nj/4+Pj/+jo6P/r6+v/7Ozs/+7u7v/u7u7/9fX1/9PT0/9VVVX/a2tr/9HR0f/r6+v/6enp/+fn + 5//l5+b/5OTk/+nn5f/p5uX/wc3R/1yQm/8bYXL/DFts/w5ebv8PU2H/DU9a/xWFmf8auNX/G7jV/xq1 + 0v8atdL/GrbT/xu00P8WnLb/D22B/xdZZf9qjJX/zc3O/+Xj4v/h4eH/1tbW/8nKyv+9vb3/r6+v/4yO + jP97gHv/oamg/6Oro/+kqqL/oqmi/56kn/+traz/v7+//9DQ0P/d3N3/6unq//X09f/6+vr/+fr4/+3v + 7P/Q0tD/rLGs/56lnv+iqaH/o6uj/6WspP+mraX/pauj/6WspP+krKP/oqmi96Sqorijp6NLqqqqCQAA + AACAgIACeXl5FW93bzxmbGZVcHZwUIWKhTCVlZUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIACB1VjJApNWpwFS1n2EFxr/xea + t/8atdT/E3qN/wxJVv8OXGr/DVxs/y90gf+jxcr/8O3t/+Dd3f/v7+//+Pj4//b29v/09PT/ycnJ/1lZ + Wf9cXFz/zs7O/+3t7f/j4+P/vr6+/5ycnP+oqKj/zMzM/+bm5v/r6+v/7u7u//Dw8P/w8PD/9PT0/+7u + 7v+kpKT/VFRU/4qKiv/x8fH/7u7u/+np6f/o6Oj/5+fn/+bm5v/m5eT/6+fm/9Xa2v95o6r/JGt5/wxa + af8OWGf/DUtZ/w1UYf8Vi6L/GrjV/xq31f8atdL/GrXS/xq20/8ZsM3/FpSu/w9leP8gXGf/cYmO/6ik + pP+dnZz/jI+N/3p8ev9tb23/a3Br/3J1cv+Jj4j/pKuj/6Oqov+kq6P/o6mh/4uSi/9wc27/a3Br/36A + fv+TlZP/qKmo/8DAwP/Y2Nj/6urp/+3t7P/GxcX/h4mF/4ePiP+kq6P/o6uj/6Oqov+jqqL/oqqi/6Or + o/+kq6L/oqqh+J2jmsSSm5BekpKSFYCAgARqdWoYcHNwW2pvaa9qbWrUcXZxz4SKgpeVnpU6gKqABgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAQEAEBUpYNwtTYLgITlz8E3CD/xmy0f8XmbH/D1Ri/w1VY/8MXW3/GGZ0/36ss//29PT/4N3c/9nb + 2//v7+//+fn5//X19f/39/f/9/f3/8vLy/92dnb/nJyc//Hx8f/W1tb/mZmZ/6ioqP+hoaH/mJiY/8rK + yv/r6+v/7u7u//Hx8f/09PT/9PT0//f39//p6en/sLCw/8nJyf/09PT/7+/v/+7u7v/s7Oz/6+vr/+np + 6f/n5+f/5ubm/+zp5//k4+L/jK61/yFmc/8LT17/DVVl/w9UYv8OVmT/FZKp/xu62f8at9T/GrXS/xq1 + 0v8atdP/Ga3K/xWJoP8OWmr/IlRf/1JeXv9ra2f/c3l0/32Dff+Ijof/lpyU/6Clnf+kq6P/o6ui/6Oq + ov+jqqL/pKuj/6GpoP+ZoJb/jZSM/32Eff93fXf/dHl0/3R5df+FiIX/pqem/7i5uP+RlJL/dHl0/5Sb + k/+mrqb/o6qi/6Oqov+iqqL/pKqi/6Oqof+kqqL/oamh/5CXjvF7gXu2eH54W3R6dC5scWxhZm9ovHd+ + d/OUnJP/jZSL9oOJgcean5dipaWlEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVVUSCVRfdglOW+MMVWP+FpKp/xq41v8Rb4D/DEdT/w1c + bP8TXW3/YJeg/97n6f/g4OD/1dXV/97e3v/v7+//+/v7//f39//29vb/9vb2//n5+f/19fX/8PDw//Dw + 8P+8vLz/p6en//z8/P/q6ur/vLy8/5OTk//BwcH/7e3t/+/v7//w8PD/8vLy//Pz8//29vb/+/v7//n5 + +f/z8/P/8/Pz//Pz8//w8PD/7+/v/+3t7f/r6+v/6Ojo/+jo6P/v7Oz/6ujp/521uf81cH3/DFlp/w1c + a/8PVWL/EFpp/xeXrf8bu9n/GrfU/xq10v8atdP/GrbS/xmoxP8SfpP/DVdm/zFcYf+Bi4P/oaae/6at + pP+nr6b/p6+n/6Sro/+jq6P/o6qi/6Oqov+jqqL/o6qi/6SspP+lraT/qK+n/6ivp/+mrqb/oKig/5Sa + k/+DiYP/fIF7/3V6dv9yeHL/jZWN/6aupv+kq6L/oaig/6atpv+4vrj/uL24/6eupf+hqaD/o6ui/5+o + n/+Olo32fIJ70nZ7driDiILUlJyU96Ksov+nrqb2pqumvamup2ugpqArkpKSBwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEJXnsbC1ponwdM + WfkQYXL/GKjF/xejvv8PUmH/DFJh/w1bbP81dYT/sMzR/+zp6f/Y2Nj/29vb/9/f3//t7e3/+vr6//r6 + +v/39/f/9/f3//b29v/5+fn/+/v7//T09P/CwsL/r6+v//39/f/z8/P/4ODg/6+vr/+cnJz/z8/P/+zs + 7P/o6Oj/6urq/+zs7P/x8fH/9PT0//b29v/39/f/9vb2//X19f/z8/P/8vLy//Dw8P/v7+//7e3t/+Tk + 5P/U1dX/49/f/+rp6f+fur//O3iF/wxZaf8NWmr/D1Zk/xFldf8XnbX/G7rZ/xq30/8atdL/GrXU/xq0 + 0P8Xnbf/EnSI/xtdaf9VdXb/k5aQ/6Clnf+hqaH/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+kqqL/pa2l/6aupv+mraX/naWd/5CXkP+SmpL/oKig/6SspP+iqaD/pKqj/7e9 + tv/a3dn/3uHe/8HGwP+qsan/oqmh/6Sso/+jqqH/lp6V+5KZk/acpJz7pq2l/6aspfqkqKHUo6ehd6Wt + pSKZmZkFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEJaHEbDFZgpAtPXPkSdIn/GbTR/xN9kf8MR1L/DVpr/xhhcv97qrP/6Ozs/97d + 3P/Z2tr/3d3d/+Hh4f/s7Oz/+vr6//v7+//6+vr/+vr6//n5+f/4+Pj/+vr6//n5+f/Z2dn/tra2//z8 + /P/6+vr/7+/v/9vb2/+tra3/oKCg/97e3v/n5+f/5+fn/+rq6v/p6en/7+/v//f39//5+fn/+fn5//j4 + +P/39/f/9fX1//Pz8//z8/P/9PT0/+Li4v+enp7/lJWV/+zq6v/s6er/n7u+/zFyf/8JV2j/Dltq/w1R + X/8Ranz/GKrE/xu72P8atdL/GrXS/xq21P8asc3/F5Ou/xFpe/8lXWj/c4SC/5+hlv+gp6D/pKqi/6Sr + o/+kqqL/pKqi/6Sqov+kqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+kq6P/pa2l/6au + pv+mraX/pKuj/6Oqov+iqKH/pKmj/7/Cvf/n6Of/+fn5/+jr6P/JzMj/rLKq/6CpoP+jq6P/payk/6au + pv+mraT/pKuj/qSpo96mq6KJoaehMaqqqgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgAIIZHQhCkxZqw1SYfoViaD/GrLQ/w9d + bP8MTlr/DV5u/zJ1hP+71dn/7urp/9rZ2f/d3d3/4ODg/+Hh4f/s7Oz/+vr6//v7+//6+vr/+vr6//r6 + +v/6+vr/+vr6//z8/P/p6en/t7e3/9vb2//+/v7/+Pj4/+rq6v/Dw8P/gICA/6SkpP/AwMD/ubm5/8nJ + yf/l5eX/7e3t//X19f/6+vr/+vr6//r6+v/6+vr/9/f3//b29v/29vb/9vb2/9XV1f9lZWX/SEhI/87N + zf/29PX/4ePi/46vtf8gZnf/CVhp/w9YaP8OU2L/FH2S/xq20/8at9X/GrXS/xq10/8attP/GarF/xKD + mv8UYnH/R3Fz/5KVjv+gpZ3/pKuk/6Wro/+kq6P/pKuj/6Sro/+krKP/pKuj/6Sro/+lq6P/pKuj/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+lq6P/nKKc/5WZlP+4uLj/6urq//r6 + +v/t7uv/yMzI/6qwqf+jqaH/oqqi/6Oro/+kq6L/oquh/KKqocOqraRRqqqqDAAAAAAAAAABaoCADHqF + eheAl4AWiYl2DVWqVQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA + YAgSY3VICk9czw1cavwYnbf/F6TA/w5IVP8MUWD/FGFx/2icp//h6er/4+Df/9zc3P/f39//4ODg/+Tk + 5P/t7e3/+/v7//39/f/8/Pz/+/v7//z8/P/8/Pz//Pz8//v7+//l5eX/pKSk/6Kiov/y8vL/8vLy/83N + zf+np6f/kpKS/6ioqP+5ubn/qKio/5ycnP/Dw8P/6urq//X19f/7+/v//f39//v7+//7+/v/+vr6//f3 + 9//4+Pj/9/f3/9DQ0P9cXFz/Li4u/5GRkf/r6+v/7+7t/9bc3P91n6r/FmFx/wtZa/8PWGb/D1xt/xaW + r/8butj/GrbS/xq10v8attT/GrPS/xebtv8Sc4f/I2Vw/2qAf/+bm5L/mqCZ/5eel/+VnZX/lZyU/5Sc + lP+WnJT/maCZ/56knf+gqKD/o6mg/6Sro/+kqqP/pKuj/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+lrKT/nqae/4aMhf9+gX7/q6yr/+Tk5P/7+/v/6uzp/8XJxP+pr6j/oaih/6Kqof+krKP/n6ee/ZCY + kNSKkYx2n6WfMIuTiyF9iH0rfoR+U3N3c3hsdWp4e4F7TZKekhUAAAABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaaREQYW9xCU9c8BFoev8YrMj/FIqf/wxCTv8KUWD/KGh3/6nH + zP/w7Or/3t3d/+Pj4//j4+P/4+Pj/+Xl5f/t7e3/+fn5//39/f/8/Pz//Pz8//z8/P/8/Pz//f39/+zs + 7P+2trb/paWl/6Kiov+4uLj/vb29/62trf/AwMD/19fX/+fn5//n5+f/29vb/7e3t/+VlZX/0NDQ//b2 + 9v/7+/v//f39//39/f/8/Pz/+vr6//r6+v/6+vr/+fn5/+zs7P+pqan/TExM/1NTU//X19f/8vHx/+zp + 6f/J1Nb/VouY/wpZaf8MWmv/D1Zl/xJrfP8Yq8b/GrrY/xq10f8attP/GrfT/xityf8UjKP/FWp7/zpo + b/9vc23/bnJs/2puav9mamT/Y2hj/2RoY/9nbWf/bXFs/3R4dP99gn3/iY+I/5iel/+fpp//o6qj/6Sr + o/+kqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/pKui/5+mnv+Jj4j/en56/6Okov/h4uH/+fn5/+jq + 5//DxsL/pq2m/6KqoP+kq6P/oamg/4iPh/V5f3nLh42HnX+EgItpbmuZanFswHh9duB+hX7dgIiAn4uU + izmAqoAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNWRQMVmN8Ck9a9hJ2 + iv8ZsdD/EGp6/wxJVf8NV2f/QnuH/9Pj5P/p5eX/xMTE/7y8vP/o6Oj/5+fn/+fn5//s7Oz/+fn5//39 + /f/9/f3//f39//39/f/9/f3/+fn5/9PT0/+fn5//2tra/8zMzP+JiYn/n5+f/9nZ2f/5+fn//v7+//n5 + +f/29vb/9/f3/9/f3/+VlZX/r6+v//b29v/9/f3//f39//7+/v/+/v7//Pz8//v7+//6+vr/+vr6//v7 + +//v7+//r6+v/4qKiv/b29v/8fHx/+ro6P/q5ub/q8LF/yVsev8IV2j/Dlpo/w9XZv8UiJ3/G7va/xq3 + 1P8atdH/GrXT/xq00f8Wobz/E3qP/xtea/80Rkj/Pz46/0BEQf9CRUH/QURB/0JFQv9DSEP/Q0dD/0NF + Qf9GSUb/UFRQ/2hsaP98gXz/kJWP/52jnP+kq6P/pauj/6Oqo/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Ss + pP+jq6P/i5OL/3l+eP+go6H/4eLi//v7+v/l5eT/vMG8/6Wtpf+kq6P/pauk/5igmP99g3z6cnZx73N6 + c+t5f3nvhIqE+JKakv+YnpX0j5aOuYyViVKdsZ0NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAgBVVSQMS1iWDE5a+BSEmf8Zrcr/DlNf/w1RX/8OXm7/WpGc/+jt7f/k4eD/paam/2dn + Z//AwMD/8vLy/+vr6//t7e3/9/f3//7+/v/+/v7//v7+//7+/v/+/v7/+Pj4/83Nzf+tra3/+fn5/9DQ + 0P+bm5v/z8/P////////////+fn5/+jo6P/n5+f//f39/+Tk5P+bm5v/rKys//b29v/+/v7//v7+//7+ + /v/+/v7//f39//z8/P/7+/v/+vr6//r6+v/5+fn/9fX1/+bm5v/t7e3/7u7u/+rp6f/s6en/3N7f/2uZ + ov8RXm7/DFlq/w5ZZv8RZ3j/GaXA/xu92f8atdL/GrXS/xq20/8Yrcn/FY6o/xFqe/8hTFP/RUZB/1FV + T/9UWlX/VlxV/1ZbVv9VWlT/UlZS/0tQS/9ESEP/P0I+/0BFQf9KTkr/Wl5a/3h7dv+TmJH/oKaf/6Sr + o/+jq6P/o6qi/6Oqov+jqqL/o6qi/6Oqov+lrKT/o6yj/4yTjP95fnj/q62s/+zt7P/5+Pj/2NjX/62x + q/+gpp7/o6qh/6SspP+Xnpb/hYuE/4uRi/+bo5v/pq6k/6aupvOiqqK9mqOYcpSZlDKOqo4JAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF10CwpQWVAJSlTJDFNh/ReRp/8XpMD/DUlW/wxX + Zv8WY3P/d6iv/+/u7P/g39//wsPD/3p6ev9xcXH/u7u7/+3t7f/w8PD/9vb2//39/f/+/v7//v7+//7+ + /v/+/v7/9fX1/76+vv+SkpL/4eHh/8jIyP+mpqb/9fX1//39/f/s7Oz/yMjI/8HBwf/Z2dn/6Ojo/8nJ + yf+ZmZn/y8vL//z8/P///////v7+//7+/v/+/v7//v7+//39/f/9/f3//Pz8//v7+//5+fn/+vr6//r6 + +v/z8/P/7+/v/+zs7P/q6en/6ejn/73N0P9GgY3/C1lq/w5Zaf8PWGj/E32T/xq41P8at9X/GrXS/xq1 + 0/8as9H/F6K9/xN/lP8iZXD/VWJd/2psZP9rcGr/a3Bq/2twa/9rcWr/am9q/2huZ/9jaWP/XWFb/1RX + Uv9LTkv/RUlE/0tOSv9bYFz/eH13/5WblP+jqaH/o6uj/6Oqov+jqqL/o6qi/6Oqov+jqqL/payk/6Oq + ov+NlIz/g4mD/7CxsP/a2tv/wsLC/4yPi/+KkIr/oqmh/6WspP+kq6P/pKyk/6atpf+krKT/paqi7aOq + o7SnsKdXo62tGaqqqgYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVDxBY + Zm4JTVnoDllo/xictP8XnLb/DUtX/wxZaP8mbn7/m7/E/+7o5//d3d3/5eXl/9HR0f97e3v/WFhY/62t + rf/29vb/9/f3//z8/P/+/v7//v7+//7+/v/7+/v/4eHh/6Wlpf+ampr/tra2/8jIyP+1tbX/2dnZ/9LS + 0v+qqqr/mpqa/6SkpP+8vLz/uLm4/56env+Wlpb/4+Pj///////////////////////+/v7//v7+//7+ + /v/+/v7//v7+//39/f/7+/v/+fn5//f39//19fX/8/Pz/+7u7v/q6+v/7Orq/+nn5v+YtLr/HWd1/wlZ + af8OWGj/EGR1/xaet/8butn/GrTS/xq10v8atdP/Gq3K/xSSqv8ZcoL/Q2Vm/2hqY/9tcGz/bHJt/2xx + a/9scWz/bHFs/2xxa/9scWr/a3Fr/2lvaP9lamT/XWNd/09VT/9CRkH/SEpH/2drZv+Mkor/oKaf/6Sr + ov+jq6P/o6qi/6Oqov+jqqL/o6qi/6aspP+lq6P/io+I/3x/e/+Nj47/g4WD/3J2cv+LkIr/o6qj/6Sr + o/+jqqL/o6uj/6Gpov+hqKHzpKqktKWupVWurq4T/wAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAFVmDxBkdG4KVmPoDl1s/xejvv8Wj6f/Dkxa/wtZaf89fov/vNPX/+rk + 4//d3Nz/5OTk/+Tk5P+enp7/Pz8//4+Pj//39/f/+fn5//z8/P/+/v7//v7+//7+/v/4+Pj/zc3N/6Gg + of/U1NT/ubm5/7S0tP+8vLz/sLCw/52dnf+FhYX/lZWV/6enp//FxcX/ycnJ/7m5uf+kpKT/y8vL//r6 + +v///////////////////////v7+//7+/v/+/v7//v7+//7+/v/9/f3/+/v7//n5+f/29vb/8/Pz//Hx + 8f/t7e3/6enp/+zp6P/S2dn/WY6Y/wtZav8OWmn/D1lo/xN9kv8bt9T/GrfV/xq10v8atdL/GrPQ/xag + vP8Tf5T/Lmpx/15oY/9ub2n/bHJt/21zbP9tc2z/bHJs/2xybP9scmz/bHJr/2twa/9rcGv/aW9p/2Rq + ZP9aX1r/S09L/0VJRf9bYFv/g4qC/5+knP+kq6P/o6qi/6Oqov+jqqL/o6qi/6Oqov+mraX/n6ae/4eN + hv92enb/fIJ8/5CWj/+gpp//pKqj/6Oqov+jqqL/o6qi/6CpoP+epp7jnqSchqW0pSKAgIACAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZ3DxBmeW4KWWXoD2N0/xmp + xv8UgZf/DU5b/wtba/9Sj5n/2+Tm/+bi4v/d3d3/4+Pj/+Li4v++vr7/oaGh/9HR0f/39/f/9vb2//z8 + /P/+/v7//v7+//7+/v/7+/v/19fX/6ampv/k5OT/5ubm/83Nzf/Ly8v/p6en/5ycnP+ampr/sbGx/9LS + 0v/Z2dn/09PT/+Tk5P/CwsL/tLS0//T09P///////////////////////v7+//7+/v/+/v7//v7+//7+ + /v/+/v7/+/v7//r6+v/39/f/9fX1//Pz8//v7+//6+vr/+vq6f/q5ub/pLu//xxndv8JWWn/Dldm/xJr + ev8Yq8b/G7rZ/xq10v8atdL/GrbT/xmsyP8Uj6f/IHF//1FoZv9sbWX/bXNs/21zbP9tc2z/bXNs/21z + bP9tc2z/bHJs/2xybf9scWv/a3Br/2pvav9obmj/Ymhi/1NZU/9HS0f/VlpV/36Dfv+dpJz/o6uj/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/pK2k/6CmoP+Yn5j/nqWd/6SspP+krKP/o6mi/6Kqof+jqqL/pKqi/6Kp + of+Pl4/tho6Enp+onzVtbW0HgJmACnZ2dhp4eHgge3txG3R0dAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAGaIDxBoe24LWGboD2p8/xqtyP8SdYn/DE1c/wxdbP9nnaf/7u7v/+Lf3//d3d3/4+Pj/+Xl + 5f/q6ur/8fHx//T09P/z8/P/9vb2//z8/P///////v7+//7+/v//////8fHx/8HBwf+4uLj/3t7e/+7u + 7v/X19f/paWl/6Ghof+ysrL/2tra/7S0tP9oaGj/hISE/9fX1/+3t7f/x8fH//n5+f////////////// + ///////////////////+/v7//v7+//7+/v/+/v7//Pz8//v7+//5+fn/9vb2//Pz8//w8PD/7+/v/+7t + 7f/u6ur/0dfY/1CIlP8JWGn/Dltp/xBhcf8VlK3/G7vZ/xq30/8atdL/GrbU/xqzz/8WnLj/GHuO/z9q + bP9pamP/bHJr/25zbP9tc2z/bXNs/21zbP9tc2z/bXNs/21zbP9tc2z/bHJs/2xxa/9rb2n/aW5o/2Rp + ZP9YXlf/SUxI/1VYVP+Ch4H/oKef/6Wro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Sro/+lrKT/pKuj/6Oq + ov+hqaH/oaig/6Krov+lq6P/o6qj/6Sro/+RmI/8fod+znyFfnF2gHY2fIN8THV5dXprcWuManJqfXh8 + eEiqqqoSAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZ3DxBtfW4MXGzoEG6D/xqvy/8Rbn7/DE9f/w1e + bv92p7D/9PLy/9/e3f/f39//4+Pj/+fn5//q6ur/7+/v//Dw8P/09PT/9/f3//v7+/////////////// + /////////v7+/+zs7P+8vLz/ubm5/8vLy/+zs7P/jo6O/46Ojv/Pz8//5+fn/4yMjP8hISH/Ozs7/6Sk + pP++vr7/6urq/////////////////////////////////////////////v7+//7+/v/+/v7//v7+//v7 + +//6+vr/9/f3//b29v/v7+//ysrK/6+vr//Y2Nj/5+Xl/5q1uf8ZYXD/ClVk/w9VZP8Sd4r/GbHP/xq6 + 1/8atdL/GrbT/xq20v8Yp8P/FIWe/ytwe/9eaWX/bXBp/21zbf9tc2z/bXNs/21zbP9tc2z/bXNs/21z + bP9tc2z/bXNs/2xybP9scWv/am9p/2huaP9la2X/Wl9Z/0lNSf9eYV7/jZOM/6Opof+kq6P/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/o6qh/6Kqov+mrKT/r7ev/7W8tf+qsar/oqqi/6Sro/+ep57/iI+H7m93 + cMFveG+hc351unN6c99xeXHqcnly4oOJgaKjq6M9qqqqBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZ3DxBr + fW4LXG3oEXSK/xquzP8Ranj/DFBh/w5fbv97qrP/9vHx/93d3P/g4OD/4+Pj/+fn5//q6ur/7u7u//Hx + 8f/09PT/+Pj4//v7+//9/f3///////////////////////7+/v/x8fH/19fX/9jY2P/Nzc3/ra2t/4uL + i//Gxsb/3t7e/6urq/9JSUn/Gxsb/3l5ef/s7Oz//f39//////////////////////////////////// + //////////////7+/v/+/v7//v7+//v7+//7+/v/+fn5//n5+f/o6Oj/j4+P/0xMTP+dnZz/6+jo/8nS + 1f89d4P/Bktb/w5SYP8RY3T/F6G6/xu62f8attL/GrXS/xu30/8arsv/FJWs/x56jP9ObGr/bG5n/21y + bP9tc2z/bnNs/21zbP9tc2z/bXNs/21zbP9tc2z/bXNs/21zbP9scmz/bHFs/2pvav9pb2j/ZWtk/1de + V/9OUk7/am9p/5Sblf+kqqP/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oqmh/6StpP+4v7n/19vX/9bY + 1/+ts67/naSc/6Oqov+lq6P/maCY/oeQh/eKkYjxj5eO+JKZkf6TmpP9j5aO+pGaj8mgqaBZqqqqDAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAFVmDwlYaG4KUmLoEXiO/xqvzf8RZ3j/DFBh/w5fbv96qrL/9O/u/97d + 3f/g4OD/5OTk/+fn5//q6ur/7u7u//Ly8v/09PT/+Pj4//r6+v/8/Pz///////////////////////// + ///////////////////+/v7/7Ozs/8TExP+2trb/v7+//7y8vP94eHj/Ghoa/2xsbP/7+/v///////// + ///////////////////////////////////////////////////+/v7//v7+//39/f/7+/v/+vr6//n5 + +f/r6+v/qamp/1dXV/9paWn/4N7e/9/h4f9zmaL/C1Rl/wxWZf8QXm3/FY6l/xu41/8at9T/GrXS/xq1 + 0/8ass//F6G5/xiFm/89cXX9Z2tl9GxxavFscWvxbHJr9Gxxa/1tcmv/bXJs/21zbP9tc2z/bXNs/21z + bP9tc2z/bHJs/2xxbP9rcWr/aW5o/2RpZP9UWVT/UVZR/3V7df+boZr/pKuj/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6mh/6Cnnv+yuLL/4+Tj/+/w8P+3ubb/k5qU/56mn/+jq6P/o6uj/6Kqov+krKL/pa2l/Kev + pvGqsanSp6yks6CpoIyepp4/n5+ACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAERVDwVKWG4HTVroEXuR/xqw + zf8RZ3j/DFFh/xBfbv96qrH/8+7s/9/e3v/h4eH/5OTk/+fn5//r6+v/7u7u//Ly8v/29vb/+Pj4//r6 + +v/8/Pz//v7+//////////////////////////////////////////////////n5+f/f39//09PT/9zc + 3P+vr6//MzMz/1lZWf/w8PD///////////////////////////////////////////////////////// + ///+/v7//v7+//7+/v/7+/v/+/v7//j4+P/19fX/5+fn/6CgoP9YWFj/rays/+nn5v+nvsL/Imx5/whV + Zv8PW2r/EniN/xqxzf8budX/GrXS/xq10v8atNL/GKnF/xWRqfwpeofkYW1osGtuap1qb2qcam5oq2hv + Z9drcWvxbHFr/mxybP9tc2z/bXNs/21zbP9tc2z/bXNs/21zbP9scmz/anBq/2htZv9fZV//UFVP/1pd + WP+FjIT/oqig/6Oro/+jqqL/o6qi/6Oqov+jqqL/pKqi/5mhmf+Wm5b/y8zL//j5+P/Ky8v/k5iU/5ad + lv+kq6P/o6qi/6Sso/+lraX4oqqi1qSqoaWjrKNsqq6mP6q2qiqcqpwS////AQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAADNVDwVKVm4JTV3oEXmS/xqxzv8Ranv/DFFh/xBfbv96qLH/8+7s/9/e3v/h4eH/5OTk/+fn + 5//r6+v/7u7u//Ly8v/29vb/+fn5//r6+v/8/Pz//v7+//////////////////////////////////// + ///////////////////+/v7/+/v7//39/f/T09P/UVFR/0lJSf/h4eH///////////////////////// + /////////////////////////////////////////v7+//7+/v/9/f3/+/v7//n5+f/4+Pj/9PT0/7a2 + tv9DQ0P/eXl5/+vo6P/K0tP/UIiS/wZVZf8OWmn/EWd3/xekvf8autf/GrXS/xq10v8atdP/Ga/N/xSa + tPgXh6DGRICIXmZsbC1odGgsampqPGltaXBrbmmla3Br1mpwafVscmv/bXNs/21zbP9tc2z/bXNs/21z + bP9tc2z/a3Fr/2puav9nbGb/WmFa/09TT/9rcWv/mJ+W/6Sro/+jqqL/o6qi/6Oqov+jqqL/pKqi/56m + nv+QlY//sbSx/+3u7f/j4+P/paak/5KZkv+jqqL/o6qi/6Kqof6lqqLZpqykhKStpDuxvLEXzMzMBVVV + VQMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAERmDwdTX24ITV3oEXmP/xqwz/8RcH//DFBf/w5e + bv96qrH/8+/t/9/d3f/k5eX/6+vr/+vr6//r6+v/7u7u//Ly8v/29vb/+Pj4//r6+v/8/Pz//v7+//// + ///////////////////////////////////////////////////////////////////e3t7/ZGRk/z8/ + P//Z2dn///////////////////////////////////////////////////////////////////////7+ + /v/+/v7/+/v7//n5+f/39/f/8vLy/8rKyv+EhIT/qKio/+jm5v/Z2tv/fqOq/wxbav8MWWn/EF9u/xWQ + pf8budf/GrbS/xq10v8attP/GrPQ/xWhvfsOjqrVFpiwaiKqzA8AAAACVYBVBmpqahhpbWk4Z2xnb2lv + abdqcGrsbHJs/m1ybP9tc2z/bXNs/21zbP9tc2z/bXNs/2twa/9obmf/YWdh/1JYUv9bX1r/ho2F/6Oq + ov+jq6P/o6qi/6Oqov+jqqL/o6qi/6Oqov+Um5P/nKCd/9jZ2f/29fb/u7u7/5KWkf+fp57/pKyj/6Gp + ofygpp7DoaehUaK5ogv///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZ3Dw5m + e24JWmvoEXeM/xqxzv8SdIb/C0xZ/w9YZ/97p6//9fHv/97d3f/Kysr/ubm5/9zc3P/u7u7/7u7u//Ly + 8v/19fX/9/f3//r6+v/8/Pz//f39//7+/v////////////////////////////////////////////// + ///////////////////i4uL/bGxs/z09Pf/X19f///////////////////////////////////////// + //////////////////////////////7+/v/+/v7/+/v7//r6+v/39/f/8/Pz/+3t7f/l5eX/5eXl/+Pi + 4v/d3tz/mbS6/xpjdP8JV2f/D1xr/xOBlf8bt9X/GrfT/xq10v8attP/G7XS/xeoxf8PlLDuE5+9lxeb + uSEAAAAAAAAAAAAAAABmZmYFb29vF2dwZ1JqcWqrbXFr621ybP5tc2z/bXNs/21zbP9tc2z/bXNs/2xx + bP9qb2n/ZWpk/1tgW/9UWVP/cnhy/5yjm/+lrKT/o6qi/6Oqov+jqqL/o6qi/6Sro/+aoZn/k5iS/8bI + xv/6+vr/yMnI/4+Sjv+Xn5f/pq2k/6KooP6boZnWmqGYcqStpBxVVVUDgICAAoCAgAIAAAABAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAGZ3DxN0i24MYnXoEXGH/xqxzv8TgJf/C0tZ/w1ZZ/96p67/+vf1/9jW + 1v91dXX/S0tL/5iYmP/w8PD/8vLy//Hx8f/09PT/+Pj4//r6+v/8/Pz//Pz8//7+/v////////////// + ///////////////////////////////////////////////////h4eH/Z2dn/0JCQv/c3Nz///////// + //////////////////////////////////////////////////////////////7+/v/+/v7/+/v7//v7 + +//4+Pj/9PT0//Hx8f/w8PD/6enp/+Pi4v/i39//s8TH/zR2g/8GVmb/EFxr/xN3i/8ass7/GrfU/xq1 + 0v8atdL/HLfT/xmvy/8SnLvyE6G/ow6YsyUAAAAAAAAAAAAAAAAAAAAAAAAAAHBwcBBrbmtPaW9prGxz + bOxtc23+bXNs/21zbP9tc2z/bXNs/21zbP9rcGr/aG1m/2BmX/9TWlP/Ymdi/5CWj/+mrKT/o6qi/6Oq + ov+jqqL/o6qi/6Sqov+gp57/lpyV/73Avf/09PT/1tbV/5GUkP+OlI3/pq6l/6Kqov+WnZXyi4+JrX6E + fldxdnE0cXFxNG54bjNzgHMod3d3DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaIDxNyhm4MYHHoEG+E/xqt + y/8VkKf/DVBf/w1dbf9ypKz/+ff3/9fV1P9cXFz/IiIi/1VVVf/c3Nz/9/f3//Hx8f/09PT/+Pj4//n5 + +f/8/Pz//Pz8//7+/v///////////////////////////////////////////////////////v7+/+vr + 6/+rq6v/SUlJ/1BQUP/p6en///////////////////////////////////////////////////////// + //////////////7+/v/+/v7//Pz8//v7+//5+fn/9fX1/+/v7//r6+v/5ubm/+Pj4//k4eH/ytDT/1WM + lv8GVWf/DVpq/xFugP8YqcX/GrnW/xq10v8atdL/HLbU/xu00P8To8HyDpm6oxWYuiUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABea14TaGtoXWpvasZscmv8bXNs/21zbP9tc2z/bXNs/21zbP9rcWv/aW9o/2Nq + Yv9YXlj/XWBb/4WKg/+jq6P/o6uj/6Oqov+jqqL/o6qi/6Oqov+hqaH/m6KZ/7y/u//v8PD/5ubm/52e + nP+HjYb/o6uj/6atpP+WnJX8eoF64G1xbLZxeXGlcnlwpGpyaqNwd26NgYV+R4mdiQ0AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAGZ3DxJziG8LX3HpD2p+/xqqx/8Wnrb/DVFg/wtaa/9fmKL/6ezu/+Th4P+urq7/VVVV/ysr + K/+IiIj/3Nzc//T09P/09PT/9/f3//n5+f/7+/v//Pz8//7+/v/+/v7///////////////////////// + ////////////////////////7e3t/5mZmf88PDz/HR0d/19fX//y8vL///////////////////////// + //////////////////////////////////////////////7+/v/+/v7//v7+//v7+//5+fn/9fX1//Hx + 8f/t7e3/6Ojo/+Pj4//j4eD/2dna/3ihp/8KWmr/DFhp/xFmdf8WnLT/G7rZ/xq10v8atdL/G7bT/xu2 + 0v8WqsfyEZy8oxWqxiQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZXJlJmZrZJFob2frbHNr/m1z + bP9tc2z/bXNs/21zbP9tcWv/am9q/2RqZP9cYlz/WF1Y/3h+d/+epJ3/pKyk/6Oqov+jqqL/o6qi/6Oq + ov+iqaH/naWd/7a7t//p6er/8/Lz/62urP+IjIb/oaig/6WspP+epZ3/kJWP/ImQifWNlIvyi5SK8oaN + hfKEjYPkjZWLkaGuoSaAgIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZ2DRFuhGgKW23iDmh5/xmlv/8Ypr//DlBg/wtX + aP9LiZX/0d7g/+vm5v/k5OT/l5eX/x4eHv9FRUX/xMTE//n5+f/y8vL/9vb2//j4+P/6+vr//Pz8//39 + /f/+/v7/////////////////////////////////////////////////2NjY/1FRUf8AAAD/BwcH/01N + Tf/e3t7///////////////////////////////////////////////////////////////////////// + ///+/v7//v7+//v7+//5+fn/9vb2//Ly8v/u7u7/6enp/+Xl5f/i4eD/4N/e/5Sxtv8TYG//CVdn/xBg + cP8VjKX/G7rZ/xq20v8atdL/GrbT/xy30/8Zr8zzEaLCpySy0CsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAVVVVDGhtaFtkbGTLaG5n+m50bf9tc2z/bXNs/21zbP9tc2v/anBq/2VsZv9eZF7/VlxV/21y + bP+Ynpb/pa2k/6Oqov+jqqL/o6qi/6Oqov+kqqL/n6ae/6erqP/Nzs3/4N/g/6usqv+Ii4b/nqSd/6St + pP+kq6P/payk/6Wro/+jqqL/oKmg+KKpoe6fpp7pnKaco6KsojRVVVUDAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICACAtp + gEQKWWm7DGR0/Bieuf8Yq8j/D1dn/wtUZP82eon/ss/S/+vl4v/h3+D/zMzM/319ff+MjIz/3t7e//Pz + 8//y8vL/9PT0//j4+P/5+fn//Pz8//z8/P/+/v7///////////////////////////////////////// + ////////3t7e/2JiYv8BAQH/AQEB/zAwMP/FxcX///////////////////////////////////////// + ///////////////////////////////////+/v7//v7+//v7+//6+vr/9vb2//Pz8//v7+//6urq/+Xl + 5f/j4+L/4+Dg/6e9wP8bZnb/BlZm/xBfb/8UgZj/GrfW/xq30/8atdL/GrbT/x230/8asM/5EqbGxiG2 + zlQcxuMJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnJ3ci9haGCYZGlh6Wxyav5tc23/bXNs/21z + bP9tc2z/bHBr/2dsZ/9fZl//V11X/2ZsZv+RmJD/pqyl/6Oqov+jqqL/o6qi/6Oqov+lq6P/oaif/46U + jv+Ii4j/jpGO/31/ff+Ag4D/nqWd/6WtpP+jqqL/o6ui+KSqo+ujrKPeoqmhu6Ksopemr6aNpq6mYZmq + oh7///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAP//AQltgBwJXm+KCmJz+BeXsf8atNH/EGh4/wpQX/8jb33/k7q//+3n + 5v/d3Nz/3+Hh/93d3f/h4eH/7Ozs/+7u7v/x8fH/9PT0//j4+P/5+fn//Pz8//z8/P/+/v7///////// + ////////////////////////////////////////8/Pz/6ioqP8lJSX/CQkJ/0JCQv/Q0ND///////// + ///////////////////////////////////////////////////////////////////+/v7//v7+//z8 + /P/6+vr/9/f3//Pz8//v7+//7+/v/+nq6v/k4+P/5ODh/6/Bw/8fanj/BlVm/xBebv8Teo3/GbTR/xq3 + 1P8atdL/GrbS/x230/8btM/+E6rI5iW504Qrqr8YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHl5 + eRNiZV1oYWde02pwaf1udG3/bXNs/21zbP9tc2z/bHBs/2htZ/9hZ2D/V15X/2RoY/+Nk4z/pqyk/6Or + o/+jqqL/o6qi/6Oqov+kq6P/pKqi/5CWj/97gXv/d353/3qAef+Nk4z/oqig/6Sro/+iqaD6oqqg0aKo + opmkq6R2pKukTJ+mnyierZ4irq6uFoCqgAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmgBQMaHh7CmJy9hWN + p/8at9T/E4CW/wxOW/8VYnL/c6St/+7p5//e3Nz/3uDg/+Xl5f/n5+f/6Ojo/+zs7P/w8PD/9PT0//f3 + 9//4+Pj/+vr6//z8/P/9/f3//////////////////////////////////////////////////f39/9TU + 1P9YWFj/NDQ0/56env/v7+////////////////////////////////////////////////////////// + ///////////////////+/v7//v7+//39/f/7+/v/+Pj4//Pz8//w8PD/4+Pj/9ja2v/i4eH/5eLi/7TE + xv8kb3z/BlZn/xBdbP8TdYf/Ga7L/xu51v8atdL/GbXS/x231P8et9H/FK7M7Sa60pMmvcYbAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpqagxnaWRcYmdgzGhuZvxtc23/bXNs/21zbP9tc2z/bHFr/2hu + Z/9iZ2H/WV5Z/2JmYv+KkYr/payk/6Oro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Kqov+hqJ//n6ae/6Go + n/+jqqL/o6uj/6Orov+iqqHzoKeeq6WtoUSmsaYXmbOzCv///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAABmdw8Pb4NnCmBy6RKEm/8btdD/Fpqz/w1TYv8OWmr/XJSe/+fr6v/i397/3d3d/+Hh + 4f/k5OT/6Ojo/+zs7P/v7+//8vLy//X19f/4+Pj/+fn5//z8/P/8/Pz//v7+//////////////////// + /////////////////////////f39/9HR0f9UVFT/X19f//Hx8f////////////////////////////// + ///////////////////////////////////////////////////+/v7//v7+//39/f/7+/v/+fn5//j4 + +P/g4OD/iouL/4SEhP/g39//6ujm/7rIyv8udYL/BVZn/w9dbP8TcIP/GKnE/xu61/8atdL/GbXS/x62 + 1P8gudT/GLLQ7Sa60pMms8YbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpqagxvdGlcY2ljzGZr + ZPxtc23/bXNs/21zbP9tc2z/bHJr/2huZ/9jZ2H/WV5Z/2JnYv+KkIn/pauj/6Oro/+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Sqov+krKT/pKyk/6WspP+jq6P/o6qi/6Srov+iqaD1o6qgsaevp0OOqo4JgICAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJkgcNco06CWJ0xBF9k/sZrsr/GazG/w5g + bv8MVWT/SYeU/9rn5//n5OL/3Nzc/+Dg4P/j4+P/5+fn/+rq6v/u7u7/8fHx//X19f/4+Pj/+fn5//z8 + /P/8/Pz//v7+//7+/v//////////////////////////////////////+/v7/8DAwP83Nzf/b29v//// + //////////////////////////////////////////////////////////////////////////////// + ///+/v7//v7+//7+/v/7+/v/+fn5//r6+v/Y2Nj/WVlZ/0lJSf/Gxsb/8/Dv/8LMzv85e4b/BlZn/w5b + a/8Tb4H/GKXA/xu62f8atdH/GbXS/x621P8iutT/G7XS7Sa70pMms8YbAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGpqagxvcmdcYmhgzGVrY/xtc23/bXNs/21zbP9tc2z/bHFr/2htZ/9iZ2H/WV5Z/2Ro + Y/+MkYv/pKuj/6Sro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Kpof+hp5//oKee/6GooP+iqqH/o6qi/6Sr + o/+hqKD8mZ+X2pSZkoqSmpJEm62kHJ+fnwhVVVUDAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + /wEJe40dCWh6pw54i/kYpMH/GrTR/xJxg/8LT1//MHaE/7jR1v/v6er/3Nzc/9/f3//i4uL/5OTk/+jo + 6P/s7Oz/7+/v//T09P/29vb/+Pj4//v7+//8/Pz//v7+//7+/v////////////////////////////// + ////////+fn5/7a2tv8tLS3/fX19//////////////////////////////////////////////////// + /////////////////////////////////////////v7+//7+/v/7+/v/+fn5//f39//q6ur/s7Oz/39/ + f/9+fn7/zs3M/83W2P9AfIb/BlBf/w5VYv8UaHn/GKK+/xu72f8atdH/GbXS/x221P8ludT/HbjS7SS7 + 0pMms8YbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpqagxlamJbYGVezGZsZvxtc23/bXNs/21z + bP9tc2z/a3Br/2dtZ/9hZ2D/WV5Z/2ZtZ/+PlY7/pauj/6Oro/+jqqL/o6qi/6Oqov+jqaH/oqqi/6et + pv+ssqv/rLOr/620q/+or6f/o6qi/6Oqov+jqaH/kZmR+YGFgNx2fXS0a3FrgWdwZ1l8g3xCjZWNHYD/ + gAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEJe4QbDG6EpA1xg/kWmLT/GrjV/xSKoP8MUF7/GWNz/4Ct + t//p6ur/39zc/+Dg4P/p6en/6urq/+fn5//q6ur/7u7u//Ly8v/09PT/9/f3//n5+f/8/Pz//f39//7+ + /v/+/v7/////////////////////////////////+fn5/7Ozs/8qKir/fn5+//////////////////// + /////////////////////////////////////////////////////////////////////////v7+//7+ + /v/7+/v/+fn5//b29v/29vb/7+/v/5ubm/80NDT/hoSE/9Xh4/9HgIr/B1Bf/w1RYP8VZnb/GKG9/xu9 + 2f8atdH/GbXS/x230/8lu9f/ILrT7SS60pMcs8YbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiI + iA9WW1ZiW2Baz2luaPxudG3/bXNs/21zbP9tcmz/a3Br/2ZsZv9fZV7/WV5Z/21xa/+UmZL/pKyk/6Or + o/+jqqL/o6qi/6Oqov+iqaH/oqmh/7O5sv/O0s7/19rX/8HFwf+kqaP/n6af/6Oro/+jq6P/m6Ga/46T + jP6Bh4D5eH5243R7c852f3azgYl+Y56enhUAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEKcHoZDnWJlwls + gPYUjab/G7bT/xikvv8PXm3/DVdm/0qHlP/T4eT/6OTi/9PT0/+8vLz/y8vL/+zs7P/p6en/7e3t//Hx + 8f/09PT/9vb2//j4+P/7+/v//Pz8//7+/v/+/v7//v7+////////////////////////////+vr6/7e3 + t/8rKyv/cnJy///////+/v7//v7+//7+/v/8/Pz//f39//39/f////////////////////////////// + /////////////////////////v7+//7+/v/7+/v/+fn5//X19f/19fX/6+vr/56env89PT3/hoSE/9fi + 4/9Ih4//CFVo/w9ZaP8VbX7/GqS//xq72f8atdH/GbXS/x231P8nvNf/IrrU7Si70pMmvcYbAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAXJyciZOU06KVlxV42lwaf5udG3/bXNs/21zbP9scmz/anBq/2Zr + ZP9eZFz/Wl5a/3N4c/+Znpj/pKyk/6Oqov+jqqL/o6qi/6Oqov+iqaH/oamg/7m/uP/m6Ob/9vX2/8LD + wv+Pko7/mp+Y/6WtpP+jqqL/oqqi/6Oqof+fpZ3/maGY/pGYj/2LkYnyjJSMoKGmoS6AgIACAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAASgIAOF3aOYw1xhdYRhJ3+Ga/N/xqz0f8SdYb/C1Jh/ypufP+uy9D/8u/u/8PC + wv9ra2v/aWlp/8DAwP/x8fH/7Ozs/+/v7//y8vL/9fX1//j4+P/5+fn//Pz8//39/f/+/v7//v7+//// + /////////////////////////Pz8/8bGxv9BQUH/YWFh//Ly8v/s7Oz/6+vr//b29v/6+vr/+fn5//n5 + +f/8/Pz//Pz8///////////////////////////////////////+/v7//v7+//7+/v/7+/v/+fn5//X1 + 9f/z8/P/8PDw/9TV1f+tra3/y8nJ/8/Y2f9FhI7/CFho/w5ca/8VcYH/G6bA/xq62f8atdH/GbXS/x22 + 1P8qvdf/J7rW7S271JM5vdkbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICACFZcVlBOVVDAXGJc+G1z + bP9udG3/bXNs/21zbP9tcmz/am9p/2RqZP9aYFr/XWBc/32CfP+fpZ3/pKuk/6Oqov+jqqL/o6qi/6Oq + ov+iqaH/oamh/77Cvf/t7ez/9vX2/7S0tP+FiYT/mqGZ/6Wtpf+iqaH/oqmh9KGpoeSiqqDdo6ui3aOq + o96iqaHZoqegl5+qnzBVqlUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARBAcBAzTWYeU4eNMRZ5jLEOe5L8GKXC/xq5 + 1v8Vi6L/DFZk/xRebv9uoqv/6O7w/9fW1f+Hh4f/MjIy/21tbf/l5eX/8PDw/+3t7f/w8PD/9PT0//j4 + +P/4+Pj//Pz8//z8/P/+/v7//v7+//7+/v///////////////////////v7+/9jY2P9dXV3/QUFB/7Oz + s/+1tbX/ra2t/8nJyf/09PT/+vr6//j4+P/5+fn/+/v7//z8/P/9/f3///////////////////////// + ///+/v7//v7+//7+/v/7+/v/+fn5//f39//z8/P/7+/v/+3u7v/v7u7/7Orp/8fQ0/9Af4v/B1Zo/w5c + a/8XcYH/GqbB/xq62f8atdH/GbXS/x631P8rvtf/Kb3Y7TK915M5veMbAAAAAAAAAAAAAAAAAAAAAAAA + AACAgIAGb3RvLlJWUI9UWlTmaG5o/W50bf9tc23/bXNs/21zbP9scWv/aG5n/2JnYf9YXlj/YmZi/4mP + h/+jqqL/pKuk/6Oqov+jqqL/o6qi/6Oqov+iqaH/payj/8jLx//z8/L/7u7u/6Wmpf+DiIL/n6ad/6Ss + pP+jqqHvoKmfup6nnoOcp5xxn6ifcJ6pnnGhqqFvoKqgS6KiohYA/wABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFixZFxot + T1ovPlaDfYCCbEmKk70Qdo78FZm0/xu31f8Yobz/EGp6/wtVZP81doP/vtPZ//Du7v+xsbH/Nzc3/0ND + Q/+0tLT/8vLy/+3t7f/v7+//8vLy//X19f/4+Pj/+vr6//z8/P/9/f3//v7+//7+/v////////////// + /////////Pz8/9TU1P9kZGT/IiIi/319ff/Gxsb/tbW1/56env/ExMT/4eHh/+rq6v/s7Oz/9vb2//z8 + /P/8/Pz//f39///////////////////////+/v7//v7+//7+/v/7+/v/+fn5//f39//z8/P/7u7u/+rq + 6v/n5ub/6ebl/8XP0P82e4X/BlZo/w9dbP8YcYL/G6bA/xq62f8atdL/GbXS/x+41P8uv9f/K8DX7TjB + 25M5vdkbAAAAAAAAAAAAAAAAAAAAAICAgAZ3fXEtXmBcglFUT9dhZl77bnRt/250bf9tc2z/bXNs/21z + a/9scGr/Zmxm/15kXv9YXVf/bHJs/5SblP+lrKP/pKuj/6Oqov+jqqL/o6qi/6Oqov+hqJ//qK+m/9HU + 0P/4+fj/4+Tj/5OWlP9/hn//o6qi/6Oqof2iqKDLoKWeZpuimyGUoZQTnLicEqGulBOhoZQTlaqVDICA + gAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAIRK1UeFilLaRszVsQnOVvlTFNd1nCDheoogpD9E4yo/xmvzf8atNH/FISZ/wxQ + Xv8XWWn/eaWt//Ly9P/Fw8P/X19f/z8/P/+Wlpb/7+/v/+7u7v/t7e3/8fHx//T09P/39/f/+Pj4//v7 + +//8/Pz//f39//7+/v/+/v7////////////6+vr/39/f/7W1tf+BgYH/Jycn/1ZWVv/h4eH/5+fn/5qa + mv+RkZH/oaGh/8XFxf/ExMT/wcHB/+Pj4//9/f3//f39///////////////////////+/v7//v7+//7+ + /v/7+/v/+fn5//b29v/z8/P/7u7u/+rq6v/n5ub/6eXl/7zKzf8rdID/BlVm/xFdbf8bdob/G6nF/xm6 + 1/8atdL/GbXS/yK51P8xwNn/LcDZ7T7B3JNCvdkbAAAAAAAAAAAAAAAAgICABHF2cTZZXVeJTVNN1lpe + WvlqcWr/bnRu/21zbf9tc2z/bXNs/2xxa/9qbmn/Y2hj/1pfWf9dYVz/fIN9/56knP+krKT/o6uj/6Oq + ov+jqqL/o6qi/6Opof+hqaH/r7Wt/9rd2v/8+/v/0NHQ/4GFgf+EioL/pa2l/6SqovuhqqG2pa2lPoCA + gAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASM6aBYYMFtrGS9VziZCbvknRXH/JzlZ/U9V + Xv86cnv/E4ef/ximwf8bu9j/F5u0/w5aaP8NU2H/OnmG/8bb3//s5+j/sbKy/4mJif+5ubn/6urq/+np + 6f/r6+v/7+/v//Ly8v/09PT/9/f3//n5+f/8/Pz//Pz8//39/f/+/v7//v7+///////s7Oz/s7Oz/8HB + wf+4uLj/WVlZ/2dnZ//V1dX/y8vL/5SUlP+RkZH/m5ub/9TU1P/Nzc3/p6en/6ysrP/n5+f//v7+//7+ + /v/////////////////+/v7//v7+//7+/v/7+/v/+fn5//b29v/z8/P/7u7u/+rq6v/o5ub/6ebl/7XF + yP8jbXv/BVVm/xJfb/8de4v/G6/K/xm41v8atdL/GbTR/yW61v80wdv/LsHa7ELH4JI5xuMbAAAAAWBg + YAhmZmYPaW9pJ1RaVI5MUEzeVltU+2lvaf9udG7/bXNt/21zbP9tc2z/bXJr/2twa/9nbWf/XmRe/1Zb + Vv9oa2f/jpWO/6Opo/+kq6P/o6qi/6Oqov+jqqL/o6qi/6Kpof+kqqL/usC5/+Xn5f/5+fn/uru6/3t+ + ev+Plo7/p6+m/6Kqovydo5rIlZqVYI6OjhuqqqoGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVAyVA + cDAeOWWrHjll+SxOff8vT4D/KEd3/yg6Wf8sSlv/FX6V/xeft/8bt9b/Ga7K/xN3i/8NWGf/GGFx/3Wm + r//z8/P/5OPj/9nZ2f/f39//5OTk/+fn5//p6en/7e3t//Dw8P/z8/P/9fX1//j4+P/7+/v//Pz8//z8 + /P/+/v7//v7+//7+/v/b29v/n5+f/+7u7v/g4OD/tLS0/8bGxv/MzMz/np6e/5SUlP+MjIz/qKio/9TU + 1P/f39//1tbW/6Kjov++vr7//Pz8///////////////////////+/v7//v7+//7+/v/7+/v/+fn5//f3 + 9//09PT/7u7u/+rq6v/o5uf/6uXl/7HDxf8eann/BlVm/xRhcP8fgpP/G7PQ/xm31P8atdL/GrXR/ym9 + 1v85w93/McTd7kjG3plXhYssd3d3Hm5xbkhmbmZkT1RPhU1STdxZYVn7anBp/292bv9tc23/bXNs/21z + bP9scmz/a3Bq/2luaP9kamP/WV9Z/1peWP96f3n/nKOc/6Wro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Kp + oP+nrqf/yc3H//Hx8P/u7u//pqem/3+Dfv+aopj/pq2l/6Oqov+Ql4/sd313smpvb3Fze3M8kJuQF6qq + qgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAACAAiZEcSIhQXCNJUNx5ilJef4wTn//MFOF/ytId/8mQmf/G2yK/xaV + rP8ar8v/G7jW/xeas/8QZHb/DVhn/zh4iP+/2Nv/8e7t/+Df3v/h4eH/4ODg/+Tk5P/n5+f/6urq/+7u + 7v/w8PD/9PT0//f39//4+Pj/+/v7//z8/P/9/f3//v7+//39/f/d3d3/oKCg/9bW1v/i4uL/3Nzc/8/P + z/+qqqr/iYmJ/4ODg/+QkJD/oaGh/7Gxsf+2trb/3Nzc/8jIyP+vr6//+/v7//////////////////// + ///+/v7//v7+//7+/v/8/Pz//Pz8//b29v/z8/P/7u7u/+rq6v/p5+f/5+Xj/6K8v/8WY3P/B1dn/xZk + dP8gjZ//GrbU/xq30/8ZtNL/HLbS/y6/2f8/xt7/ObXJ90iIksVSWlp/TVVPgVBWULVXX1fTWFxY42Jn + Yftscmv/b3Vu/21zbf9tc2z/bXNs/2xybP9rcWz/am5p/2VsZf9dY1z/VlxW/2htaf+PlY//o6mh/6Or + o/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Kqof+zuLL/297b//j4+f/Z2Nn/kJGP/4SJhP+hqaD/pKuj/6Sr + o/+YoJn+h4+G8XV7ddZrcWunfoN+b5CZkDeJnYkNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEAAP8BAAAAAAAkSQckSHA5J0h3oyhH + ePMwT4D/MFKE/y9Rg/8vTn//JVZ//xeGoP8Zp8L/G7jW/xqxzv8TgJX/Dlpo/xhfb/9om6b/3+nq/+fk + 5P/b29v/4ODg/+Pj4//k5OT/6Ojo/+zs7P/w8PD/8vLy//X19f/39/f/+fn5//v7+//8/Pz//f39//39 + /f/x8fH/vb29/5+fn//CwsL/zMzM/8HBwf+bm5v/hYWF/5SUlP+2uLb/ra2t/6ysrP+1tbX/paWl/66u + rv+/v7///Pz8//////////////////7+/v/+/v7//v7+//39/f/39/f/8fHx//b29v/z8/P/7u7u/+rq + 6v/r6Of/4uHi/4eqsf8OWmz/C1ho/xhqeP8gl63/GrnX/xq20v8atdL/H7bU/zbC2/9EyN//Qqe4/lZk + YfRZYl3gV15Y5FZcVvZhZl7+aXBp/m50bf9vdG3/bXNs/21zbP9tc2z/bHJs/2txa/9qb2n/Z2tl/2Bm + X/9WXFb/X2Re/4KHg/+fpp//pKuj/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6mh/6Kqov+yt7L/19nY/+3t + 7v+2t7f/eXx5/4ySjP+krKT/o6qi/6Sqov+kqqP/oqqi/5aclf6HjYbwfoR91Xh+dZCAhXoymcyZBQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHDljEhks + USkcMk4kK1WADFVVqgMPPHgRKkZ1bSZFc+YtTX//MFOF/zBShP8vUIH/K0x7/x5wkf8XoLf/G7LP/xy7 + 1v8YoL3/Emt+/w1YZ/8obnz/mb/G/+7v7//c2tr/3d3d/+Dg4P/k5OT/5+fn/+np6f/t7e3/8vLy//X1 + 9f/29vb/9/f3//r6+v/7+/v//Pz8//39/f/z8/P/xcXF/7S0tP/a2tr/3Nzc/8bGxv+kpKT/u7u7/9/f + 3//j4+P/ycnJ/7Gysf/Ly8v/nJyc/5GRkf/f39////////////////////////7+/v/+/v7//v7+//z8 + /P/b29v/oqKi/87Ozv/4+Pj/7+/v/+vq6v/r6Oj/1trc/2OVnv8GVmj/D1pp/xpvfv8eo7z/GrrX/xq1 + 0v8ZtdL/IrjU/z7F3v9IyN//TKWx/2hsZ/9rbmj/bHJr/210bP9vdm7/b3Vt/21zbP9tc2z/bXNs/21z + bP9scmz/bHFr/2pvav9nbGb/Ymhh/1pfWP9aXln/eHx4/5mfmf+lq6P/o6uj/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/pKqi/6CooP+TmZP/mZua/7Gysv+PkY//eHt3/5ifmP+lraT/pKyj/6Kqov6hqaD8oamg/KSt + o/yiqqH8k5qS9YaLg7eHjoNIjo6OCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEjRnQWHTlfWRYrTpQaL1eMHzplUyZCbTYqR3k9IkBugCM/bOksTH7/MFOG/zBS + hP8vUIL/L01+/yZZhP8XkKv/Ga3H/x661v8attT/Fouj/w5dbP8PWWv/R4SS/7/U2f/o5eX/29zc/9/f + 3//g4OD/5OTk/+np6f/u7u7/9fX1//v7+//39/f/9fX1//j4+P/6+vr/+/v7//39/f/l5eX/p6en/+Tk + 5P/9/f3/6+vr/8bGxv/V1dX/+fn5///////19fX/0dHR/7Ozs//d3d3/xsbG/6ioqP/z8/P///////// + //////////////7+/v/+/v7//v7+//39/f/X19f/e3t7/5KSkv/09PT/8/Pz/+vq6v/r5+j/vszR/zp7 + iP8GVWb/EV1s/x55iv8er8b/GrjV/xq10v8ZtNL/JrvW/0XI4P9Kxt3/VJuj/21waf9udGz/bnRt/25z + bP9tc2z/bXNs/21zbP9tc2z/bXNs/21ya/9rcWv/am5q/2dsZ/9iaWL/WmBa/1VaVv9ucm3/lpqU/6Sq + ov+jq6P/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/pKqi/6Kpov+Qlo//eH13/3V3df92eHb/ipCJ/6Oq + ov+kqqP/pauk96Oso96fpp7MoaqgyaSrocmlq6TJo6ujvKKtonybqJspgICABAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkSQcjNmFCGy9RuhszWO0kQW3nJkNwwyQ+ + bKwmQm+vJD9tyylJd/gwUYT/MFKF/zBShP8wUoT/L0+D/ytMev8dcZL/GaG7/xy41P8eutf/GarG/xR7 + j/8OWWj/GF9v/2aapf/e5+f/5uPj/93d3f/g4OD/4+Pj/+fo5//h4uH/sbGx/6+vr//p6en/9/f3//X1 + 9f/4+Pj/+vr6//z8/P/h4eH/np6e/+rq6v/+/v7/9PT0/+zs7P/7+/v///////b29v/Ly8v/n5+f/6qr + qv/s7Oz/xsbG/7Kysv/19fX////////////////////////////+/v7//v7+//39/f/z8/P/sbGx/2ho + aP/AwMD/9fX1/+3s6//n5eb/nrm9/xlkc/8KWGf/FWJx/yKJm/8btND/GbfT/xq10v8btdL/ML7Y/0zN + 4/9PwNb/XYmL/25vZv9uc2z/bXNs/21zbP9tc2z/bXNs/2xybP9sc2z/a3Fs/2twa/9pbmj/Zmxl/2Fm + YP9ZXlj/V1xX/2pvav+Ok47/oqmi/6Sro/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Sr + o/+kqqL/l52V/4WLhf+Jj4j/nKSb/6Srov+iqqH0pa2jw6Suonuhp55Xpa6lUqmvplOmr6NTo6qjSJ+l + nyWSkpIHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu + RgsaLU9aFihL3SNAa/8tTX3/K0p8/SlJefkoRXX5KUp5/DBShf8wU4X/MFKE/zBShP8vUoX/L0+A/ylB + bP8cRWD/Fn2W/xyz0P8fu9X/HrnV/xeguv8SbHz/DVZl/yNqef+SusD/6+vr/+Lf3//e3t7/29vb/7u8 + u/+enp7/Wlpa/0dHR/+jo6P/9fX1//b29v/19fX/9/f3//r6+v/r6+v/sbKx/8bGxv/09PT///////// + ///7+/v/5eXl/8bGxv+kpKT/paWl/6mqqf+3t7f/ra2t/83Nzf/6+vr///////////////////////7+ + /v/+/v7//v7+//z8/P/9/f3/1NTU/1ZWVv9vb2//5+fn//Lw8P/d3+L/cp+m/whYaP8OWmn/HGp5/yWX + rf8auNT/GrXS/xm10v8et9T/PMPc/1PN5f9UtcT/Znh3/25waf9tc2z/bXNs/2xybf9scmz/bHJs/2xx + bP9rcWv/am5q/2dsaP9kamT/X2Re/1ddV/9VW1X/bXFt/5GVkP+iqKH/pKuj/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Kpof+gp5//oamh/6Kqov+kq6P/pqyk/6SspP+krKP/pKuj/6GpoP+jrKPkqbGnhqGu + oSaStpIHgKqABoCqgAaAqqoGgICABICAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwUVKkc9GjJVsSdFcvErSXj/L1CA/y9RhP8uUIT/MFOF/zBT + hf8wUoP/MFOF/y9Sg/8vToH/KERu/xwtS/8TIzr/FVVx/xmmxP8duNT/IbrV/xuz0P8Wkaj/EWRz/w5X + Z/84eoj/r8vP/+rn6P/g39//2tra/5ycnP9bW1v/S0tL/zw8PP9aWlr/ysrK//j4+P/09PT/9fX1//j4 + +P/39/f/29vb/7CxsP+9vb3/1NTU/9TU1P+7u7v/t7e3/729vf/IyMj/3t7e/7e3t/+Ojo7/v7+///Ly + 8v////////////////////////////7+/v/+/v7//v7+//v7+//7+/v/5eXl/5KSkv+AgID/4N/f//Pw + 8f/A0NP/OXqI/wZUZf8RXWz/InaG/yOmvf8ZudX/GrXS/xi00v8lutX/Scnh/1fM4/9bo67/a3Jr/2xx + bP9scmz/bHJs/2xya/9rcmv/a3Br/2lvaf9nbmj/ZWpk/2FmYf9cYlv/VlpU/1leWf9ydXH/kpeS/6Sq + ov+kq6T/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oqmh/6Srov+psaf/pq6m/6Kqof+iqqL/o6qi/6Sq + ov+lq6P/o6qi/6Oqov+boZnqj5eNlo6TjjSfn58IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEeLVoRJENwVCtH + d7QpSnj2L09+/zBSgv8wU4X/MFKE/zBShP8wUoT/L1OF/y5Of/8pRHH/GyxI/xIhOv8SI0H/EjVW/xV7 + l/8asMz/IrvW/yG71v8ascz/Foaa/xFebv8QWGr/S4eT/73T2P/o5+j/39/f/8DAwP9mZmb/Tk5O/0ND + Q/8xMTH/iYmJ//z8/P/w8PD/9PT0//X19f/4+Pj/9vX2/9nZ2f+7u7v/xcXF/729vf+MjIz/tbW1/+3t + 7f/29vb/9PT0/9PT0/+srKz/0tLS//39/f///////////////////////v7+//7+/v/+/v7//v7+//v7 + +//6+vr/9fX1/+bm5v/Z2dn/7Ovq/+Xo6P+HrLT/EVxt/wtYaP8WY3H/JYmb/x60zv8Zt9T/GrXS/xq1 + 0/8uv9j/Vc7m/1zJ3v9gk5b/amxl/2pwav9qcGr/am9p/2puaP9nbmf/Z2tm/2RqZP9iZ2D/XWNd/1dc + V/9VWlT/YWZh/3yAff+ZnZj/pKqi/6Wso/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+iqaH/oqqh/7S5 + s//M0Mv/xcrE/7C3r/+mrqb/o6uj/6Oqov+jqqL/o6qi/6Sro/+Xnpf7gIR+1nR4cIaAhHs4h4eHEaqq + qgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAABLUuHESxQelYsTn3QLU19/C9Qgv8wUoP/MFKE/zBShP8wUoT/L1GC/ylG + c/8dLkz/Eh83/xMnSP8TJkj/EyM+/x1MY/8dmbb/HrjV/yW81/8fu9b/GanD/xV+kv8RWmr/Fl1t/1mS + nv/C1tr/6urp/9/d3f+Wlpb/SUlJ/1dXV/81NTX/hISE//j4+P/u7u7/8PDw//T09P/19fX/9/f3//n5 + +f/y8vL/7+/v/+jo6P+5ubn/urq6//Pz8//+/v7/+fn5/+jo6P+/v7//urq6//X19f////////////// + //////////////7+/v/+/v7//f39//v7+//5+fn/9vb2//f4+P/29vb/8fDv/87Y2v9DgI7/BlVl/xFd + bP8fbn3/JZ6y/xu41/8ZttP/GrXS/x221P87wtz/YNHp/1y7zP9he3j/Z2hh/2VrZf9la2X/ZGtj/2No + Y/9iZ2H/X2Ve/1pgWv9WXFb/VlpW/11jXv9wdnH/jJGK/6Ckn/+lq6P/pKuj/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Kpof+hqJ//rbOs/9LU0f/w8PD/5ebl/7y+vf+aoJr/nKOb/6Sso/+jqqL/o6qi/6Sq + ov+jqaH/lZmU+n2CfNpyd26dgIV9XJKZiiO/v78EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBVqgMAVVUDADNmBStOeCQnRXCrJ0V1+TBR + hP8wUoX/MFKE/zBShP8vUoX/LU19/yA0Vf8SITf/EyhJ/xMoSv8TJD//JDBG/zhKYf8mc5D/FqfI/iK7 + 2P8lvdf/HrnW/xmiu/8Wc4P/D1pq/xZgcP9glqD/zt3e/+7r6/+3trb/T09P/4aGh/+kpKT/wsLC/+7u + 7v/r6+v/7e3t//Dw8P/z8/P/9PT0//b29v/6+vr//f39//z8/P/n5+f/r6+v/8rKyv/7+/v//v7+//T0 + 9P/IyMj/oaGh/+jo6P////////////////////////////7+/v/+/v7/+/v7//v7+//5+fn/9fX1//Pz + 8//y8fH/6e3s/5Gwtv8WW2r/CVZl/xVhcf8qg5P/JK/G/xm51v8ZtdL/GbXS/ya61f9NyuL/ZM/k/1qb + pP9aY13/XGFZ/1xiXP9bYlv/WmBa/1hfV/9XW1f/VlpV/1hdWP9gZF7/bnJu/4eMhv+coZz/pKuj/6Sr + o/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oqqi/6Gon/+nraX/yMzH/+7v7v/5+fn/4eHh/5+f + n/97gHv/lp2W/6Wupf+iqqL/oKig/aKpoPyjq6P+pqyl/5qhmfx+hX7tdX11wIWKhWSZmZkU////AQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQEAIHDdgJRQn + TjQdMV00IjtiNClFckofOWG2JkRz+jBShv8wUoT/MFKE/zBShf8vUYP/JkBp/xYkPf8RJEL/FCpP/xEk + QP8nNkz/OUxl/zVFZv44Wnn2JaC86Bu41vgmvtf/JrzY/x220v8amLD/F29//w9aav8ZXm3/Z5Gb/8ba + 3f/a2dn/pqal/7+/v//r6+v/6Ojo/+Tk5P/o6Oj/6enp/+zs7P/w8PD/8vLy//f39//29vb/+vr6//z8 + /P/19fX/0NDQ/62trf/a2tr/+/v7//v7+//R0dH/mZmZ/+Li4v////////////v7+//v7+//9fX1//7+ + /v/+/v7/+/v7//v7+//4+Pj/9fX1//Pz8//09PP/x9ja/z18h/8HUF7/DlFg/xpmdf8qmq//HrfU/xm3 + 1P8atdL/HLbT/zbB2v9h0un/ZcTW/1p7ff9YWFH/WFxY/1ddWP9YXVj/Wl1a/1xgW/9gY1//aGxo/3t/ + e/+LkYz/maCZ/6Oqo/+mrKX/pKuj/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqaH/oamg/6eu + pf/CxcD/6Oro//n6+f/q6ur/sbGy/3d6d/+Ah4D/oamg/6Sso/2iqqLroKee06CooM+hqqDmo6yh+Kau + pfuYn5b6h4+H24iQinqSm5Ic////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAVQMjOWokFi1RgRYuT6sbNV2sGzZeqx85X7YjPmfjLE1+/jBThv8wUoT/MFKF/zBT + hv8tTXz/HC5L/xEhPP8VKlD/EidH/x0uR/82SmX/OU9y/0hZevlZZn3OSqO4kB+3078fvNjzKL3X/yi8 + 2P8btNL/Gpiw/xhygf8PUWD/Flhn/1aPm/+yys//8vDv/+nl5P/e3t3/4eHh/+Hh4f/k5OT/5+fn/+np + 6f/s7Oz/7+/v/+7u7v/Q0ND/srKy/+zs7P/8/Pz/8/Pz/83Nzf+1tbX/0NHQ/+Pj4//ExMT/oqKi/+rq + 6v/29vb/4eHh/7m5uf+SkpL/09PT///////9/f3/+/v7//r6+v/39/f/9vb1//b19v/b5+b/cJ+m/w5e + bf8MWWf/E1lo/yd5iP8krsf/GbrW/xm20v8ZtNL/JbrV/07K4f9v1On/c7vF/32Ihv98fHf/e356/3yA + e/98g3z/gYWB/4aKhv+LkYv/kpqT/6Gnn/+mraX/pq2l/6Ssov+iqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Kpof+gqKD/qrKp/8bLxf/o6ef/+Pf4/+rq6v+4t7n/fYB9/32DfP+dpZ3/p66m/qOr + ouSjqaGgnqieZKGmnlyfqZ+FpK2hq6OqorKjqqOuo6qhipejl0CAlYAMAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAcBAkP2hdFipJ1B84YPkjP2v5Ij9p+SVC + bPkrSXn/MFOF/zBShP8wUoT/MFKE/y9Thf8pRW7/FSI5/xMnSP8UKlD/EyZC/zBBWv8zTHD/OE9y9218 + kNxwcoiJbZiwKiu71l4ft9a/IbzY9CzA2v8kvNj/G7XU/xuZsP8ZbXz/EFlo/w5aa/9EgY//scnN/+vp + 5//l4eD/3d3c/+Dg4P/h4eH/5OTk/+fn5//q6ur/3Nzc/6Kiov+Wlpb/Z2dn/6+vr//8/Pz/+Pj4//Pz + 8//Pz8//tbW1/7Ozs/+wsLD/zs7O//j4+P/c3Nz/i4uL/4CAgP9MTEz/nJyc//v7+//9/f3/+/v7//n5 + +f/29vb/+ff2/+nw8P+Ms7r/G2Z1/wpYaP8PXWz/H299/zCarP8cttT/GLfT/xq00v8cttL/OsLb/2fT + 6P940OL/jLS1/6Omnf+ipqD/oaeg/6GooP+jqKH/pKmk/6aspP+mraX/pq6l/6Wso/+jq6L/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oaqh/6Kqof+utKz/y8/L/+3u7P/6+fr/7Ozs/7q6 + uv98fXz/d313/5qhmP+nraX/o6mh/KWspMSsr6lTj5+fEKqqqgmcpZwfrbeoNaewpzqfpJ84n6WfJbOz + swoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAiRC + bSMnQWuWFShI9CU/a/8pR3X/LEp5/y5Of/8wUYP/MFKE/zBShP8wUoT/MFKF/y5Rgf8kPGL/EiM//xQr + T/8TKEr/HC1H/zJIaP8uSnH2S2J/y3B+j3tndII5ADNmBSnC1hknu9NiIbrWwCe/2fMvwNv/I7zY/xyz + 0f8cmbH/HHeH/xJdav8RWmr/QH+M/5m6wf/c4uT/5+Xl/97c3P/e3t7/4eHh/+Tk5P/n5+f/0dHR/2pq + av9xcXH/hISE/2xsbP/m5ub/+fn5//X19f/19fX/3Nzc/8PDw//Pz8//9fX1//7+/v/W1tb/a2tr/39/ + f/+RkZH/e3t7/8jIyP/7+/v/+/v7//n5+f/5+Pj/7fLz/6DBx/8xdYH/CVdo/w1ba/8aZXT/Loqb/yey + y/8YuNX/GbXS/xm10/8nvNf/V8zj/3jY7P+AydT/nqyj/6eqoP+lrKT/payk/6WtpP+lq6P/pauj/6Sr + o/+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+iqaD/o6uj/7O7 + s//T1tL/7/Dv//n5+f/t7e3/vLy8/31+ff90eHP/lZyU/6WtpP+krKT/oqmh/Zeelc2Hj4dmkJubF/// + /wL//wABgICABICAgASqqqoDgICAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAACAAidIbycmQm2bGS5S4iQ8aO0lQG3+KUd3/y1Nfv8wUIH/MFKE/zBS + hP8wUoT/MFOF/y5Nfv8eNFX/EiVE/xUrUf8SJkf/JjdS/zBJb/89VHbwX3GIp3F9iC1JSW0HAAAAAAD/ + /wIms9AbJLnTYiO71b4rwNn3MMLY/yO81/8ctNL/HKC2/x58i/8UYXD/DVlo/ydwff95qLH/xNXY/+jm + 5v/k4N//393d/+Dg4P/j4+P/39/f/5ubm/9eXl7/jo6O/2RkZP+goKD/9fX1//T09P/09PT/9vb2//Hx + 8f/29vb////////////u7u7/n5+f/2dnZ/+urq7/Y2Nj/29vb//r6+v//v7+//r6+v/x9fb/sMvQ/zl8 + h/8MWWj/DFpq/xVhb/8sfY3/L6i8/xq31v8Zt9P/GrTS/x+31P9Cxd3/c9fq/37W5f+Ou77/pKie/6Op + oP+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/oKif/66yrf/Z29n/9vb2/+fn5/+8u7z/gYKB/3N3cv+UmpP/payj/6Sq + ov+jq6P/pKyj/4yVjfB0fHS3e4R7XZ+fnxiAgIACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARw5cRInP2xVIj1nfihE + b5ooQnDTK0l37S5Off0vT4D/MFKD/zBShP8wUoT/L1OH/yxLef8bLEr/EiZG/xQrUf8VKUf/Kz5a/y1H + cftGXHnQXGmAcmZzcxQAAAAAAAAAAAAAAAAA//8CM7jMGSe71WEoutbIMcHb9jLB2v8lvdj/HLbT/x2l + vv8ehZf/F2Ry/wxYaP8ZYnP/UYuW/6PBx//b4OL/5+Xl/+Xi4f/h4OD/5OPk/9LS0v9vb2//UVFR/21t + bf9zc3P/5OTk//T09P/w8PD/8vLy//T09P/29vb/+/v7//39/f/8/Pz/y8vL/15eXv9nZ2f/YWFh/15e + Xv/l5eX//v7+/+3z9P+tytD/SISP/wxaav8MWWn/El5s/yh1hP8yn7T/HbbT/xi30/8atdL/G7XT/zO/ + 2f9l0uX/gNvr/4jI0P+draf/pKig/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/oqmh/6Gpof+iqaH/oqqi/6Oqov+lq6P/n6ad/4uPiv+oqqn/0dHQ/7Gx + sf98fnv/d3x1/5aclf+lraT/o6ui/6GpoP6iqqL+payj/52knP+Bh4HxcHdvuoGJgV+PmY8ZgICAAgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEgMHAQKUd6GTFMdy8uUHxpL057ri1MfvMtToD/MFKD/zBShP8wUoT/MFSG/ytJ + c/8YKEX/EyhJ/xUrUf8XKkj/KkBi/yxHcPk9UnG1QVVtP1VVVQMAAAAAAAAAAAAAAAAAAAAAAID/Ai/G + 0BsrutRrLbzWxzTF3vY0w9z/KLzZ/xu41f8dq8T/IYqe/xxtfP8QW2v/Dlhp/y1zf/9wn6n/sMrO/9/l + 5f/o5+X/6ubn/+Lh4P+Xlpb/RUVF/4qKiv+4uLj/4ODg/+zs7P/r6+v/7Ozs/+7u7v/v7+//8fHx//f3 + 9//8/Pz/4+Pj/4WFhv9nZ2f/sbGx/7q6uv/w8vL/2+jq/5O6wP87e4j/DFpq/wxYaP8RXW3/JXF//zSa + rP8itND/GLfW/xm10f8ZtNH/KbvW/1jN4/+C3Oz/iNTg/5i2s/+kp53/o6qh/6Oqov+jqqL/o6qi/6Oq + ov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+jqqL/oamh/6Gpof+gqKD/oqmg/6SrpP+lrKT/o6uj/6Kq + ov+kq6P/pKuj/42SjP+DhoP/i4yK/3l7eP94fXb/l52V/6atpf+jqqL9oaig66Con96hqaDtoqqi/aau + pv+aoZn/fIN68nd9dLSKlIpMi4uLCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAImQnsbK0h5eCdH + eOotT4D/MFOE/zBShP8wUoT/MFSF/yhFcf8XJkP/EyhM/xUqUP8WKUf/Jz1i/yxIcvk0SWy1MUpnPgCA + gAIAAAAAAAAAAAAAAAAAAAAAAAAAAFWqqgM8u90eML7Zai/B2cc4w933OMPe/yu81/8dutX/Ha7K/yGX + rf8ieon/GGNx/wtWZ/8QXGz/O3yL/3yqs/+zy8//2+Tm/+ro6P/U0dD/ra2t/87MzP/t7e3/5eTk/+Tk + 5P/n5ub/6Ojo/+jo6P/p6ur/6erq/+3t7f/y8vL/8fHx/9HR0v/Ew8P/8/T0/+fx8/+509f/a56n/ylu + fP8IVmf/DFpq/xNdbP8ncYD/N5iq/yayzv8Yt9T/GrbS/xi00f8iudX/TMbf/37a6/+M2+f/kL/C/5+n + n/+jp5//oqqi/6Oqov+jqqL/o6qi/6Oqov+jqqL/o6qi/6Oqov+iqqL/oamh/6GooP+gp5//oKif/6Go + of+or6f/t7y2/8XKxf+6v7n/pauj/6Gpof+jq6L/payk/6GooP+Jj4j/dHhz/4CGf/+bopv/pq2l/6Kq + of2jq6Pko6yko6Cpnnyhp56ppK2k5aWtpPunr6b/lZ2U/HuBecx2e3NfgI+AEAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABIEBgCCJVdw8rSYAqKkJtkyU/a/EtUIP/MFKF/zBShP8wUoX/MFSF/ylGcf8XJ0L/EylN/xUs + Uf8UKUn/JDpi/yhFcPkvRmmvQlx7OgD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVqv8DPMTVHjXC + 2WU1wdrBPMXh8zzG3v8yv9n/H7rX/xy00P8ho7z/I42f/x50hP8YYG7/DVdm/xVhcf89fYz/bp+p/5O3 + vf+2zdP/2Obo//Dw7//x7+//8O7t//Dt6//v6+v/7+vr//Dr6//w7Oz/8+7t//Tw7//18PD/9/Tx//Dz + 9P/P4eL/psTJ/3imrf9DgY7/FF9w/whXZ/8NWmj/GGJx/y58i/80nLD/KbTN/xi31f8ZttL/GbTR/yG4 + 1P9Ix93/e9nq/5Ph7f+g1dv/p7ax/6aqoP+jq6L/oamg/6Oqov+jq6P/o6qj/6Oqov+jqqL/o6qi/6Kq + ov+gqKD/o6qh/6ivqP+wta//ub+4/8TJxP/T19P/5Obk//Dx8P/U19T/qa6o/6GnoP+kq6P/o6qi/6Wr + o/+dpZz/lp6W/6Cnn/+mraX/o6qi/6Sro/aosKi4qLKoT56enh2gp5xDpK6jiqeupMSmr6bjo6qi04uS + i4hwdWowgICABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIXOl0WGjBZRRUrS18iNVmGIzpi1ihDavwwUYX/MFKE/zBS + hP8wUoT/L1OG/ypHcv8YKUX/EyhM/xYsUf8UKUn/IThh/ylGcfksQWC1Q1x9PQAAgAIAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAICAAkC/1Rg+xNxfO8Tevz7K4vRByOH/NsDa/yS71/8audX/HLHN/yWh + uP8niZn/H3B//xRdbP8LV2X/DFpq/x1neP86fIn/aZeg/5S5v/+ry9D/uNLW/8vd3v/Z5Ob/4ujo/+To + 5//i5+f/2uLj/8za3P+3ztD/pMHF/4uwuf9akJv/LG16/xNaa/8IV2j/Clho/xBca/8haXb/M4WT/zWo + vf8kttL/GLfV/xm20v8ZtNH/HbfT/0HF3P992ur/l+Xx/67p8f/S4+T/1tfS/8rOyf/Bx8H/uL63/6+1 + rv+mrKX/oqmh/6Oqov+jqqL/oqui/6yyq/+6wLn/xMfC/9HUz//c39z/6Ovo//Lz8v/4+fn/+Pj5//Pz + 8//V1NT/np+e/4+Ujf+gqJ//pKuj/6Oqov+lq6P/pa2k/6Sso/+jqqL/pKuj/5uim/eVnJW3naSdSaqq + qgmOqo4JpayfJaixqFiorqaHqK6ocqqwqi22trYHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAwYBAUKUtYFChMsxgw + VM4kPGHgJUJu+i1Kef8wUYP/MFKD/zBShP8wUoT/L1OG/yxKef8ZLEr/EihK/xcuVP8TKUr/HjZb/ypI + dvkySGq0PlZ3PgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wJOxNgaQcjgYkDK + 479Cy+bzR8ri/z7D3P8rvdf/HbrW/xq20/8grsf/Jpyz/yeFlv8hcID/FWBv/wxZaf8JU2L/D1Rj/x1m + dP8ud4T/PYCO/1OPmv9nmqX/caKs/3Wjrf9xoqr/Z5qk/1SOmf8+f4r/K3KA/x1od/8PXGv/B05e/wlP + X/8QWmr/HGRz/yt3hP83lKT/MqzB/yC31P8Yt9T/GbXS/xm00f8hudT/P8Tc/3TZ5/+e5/P/rujx/9fu + 8f/3+Pf/9/f2//P18//u8O7/4eLg/7u+u/+Vm5X/oKif/6Oro/+jqqH/o6qj/7m+uP/f4+D/8fHx//f3 + 9//5+fn/+Pj4//T09P/q6ur/2NjY/7q7uv+bm5v/fH57/4GHf/+epp7/pKyk/6Oqov+iqaH/oaig/6Gp + of+iqqL/pqyk/5adlf6CiYLdiI6GfJ6nnh0AAAAAgICAAp+vnxCjuKokra2tHJKSkgcAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAhxAYyQZLVSaFSxO9CI8Zv0oRG/+Kkl4/yxMe/8uT3//MFCD/zBShP8wUoT/MFOG/y1N + fP8cMFL/EiZH/xYuU/8TKk3/GjBS/yxId/s0TXHJO1RwcHmGmSiqgIAGAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACA//8CTL3QG0fA1GVFu9LIS8jf/FDO5f9JyN//NsDa/yO61/8auNX/HLXR/yKs + xP8nn7X/Koyd/yh4if8cZnT/ElRj/wxXZ/8JV2n/C1ho/wxYav8QXGz/EF1t/xBfb/8RX27/D1xt/w1b + a/8JWGr/B1Zn/whXaP8NWWr/Eltp/xxea/8sdoP/OY+e/zWkuf8otM3/HbfU/xi30/8ZtdL/GbXS/yO6 + 1P9FyN3/etvr/53j8P+Xztj/n7a6/8bFxP/c29v/5+fn//Dw8P/19PX/6+vs/7O0s/+AhoD/oaaf/6Or + o/+jqqH/oqui/7a7tv/k5OP/8vLy/+rq6v/i4uL/09TT/7++v/+oqKb/jY6N/3Z5dv90eHP/goeC/5ac + lP+iqaH/pKuj/6GooP+hqaH0oqqg5qGmoOmiqqL2pKyk/qGnn/+KkIn2gomCs5WZkkaOjo4JAAAAAAAA + AAAAAAAB////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAiI8ZSYhPGScFixQ9iE5Y/0iPmn9J0Nu/ShG + dP4sTHv/MFCA/zBSgv8wUoT/MFKE/y9Rgv8iOV7/EyZF/xUsU/8VK1D/FSpL/ydCbf8yTnXxU2R8znyD + j3+Ah4cigICAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVar/A0mYpCpMjJebTJKh+Uyz + x/9TzOT/VNDm/0TI3v8vv9j/IbnV/xi31P8attL/IrHM/yqlvP8plqr/KYSV/yl9i/8kc4H/HWp5/xhj + cf8UYG//EV1t/xBdbP8QXGz/EV1s/xRfbf8UYG//GWV0/yBsev8sd4b/M4WT/zSRov80pbn/L7TK/x+3 + 0/8Yt9T/GLbS/xi00v8attT/KrvW/1HL3/+G3e3/per0/6Xb4f+Rqaj/f4R//4GBfv+JjIr/nZ6d/6+v + r/+9vr3/wcDC/5mamf97fnj/oaig/6Oro/+jqqL/oqmg/6Wrpf+3uLb/vLy8/6ipqP+XmJf/hIiF/3t+ + e/96f3n/eoB6/4OIgv+Um5P/oKig/6Wso/+iqqL/pKyk/qSspO2kraO3o62hiJ6nno6gp5/Co6qi8aat + pv+an5j/h42F2YKJgG6MmYwUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAR48 + aREkQGlcFitOuh85YNEhPWjRKERx1S1Kd+otS3v+Lk9+/zBSg/8wUoT/MFKE/zBShf8nQ2z/FChI/xQq + UP8WLVT/FChK/yE5Xf8zUH3/R1l2+GNpdMNla3Zda2tzH4CAgAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAQGBgCEdtbS9GWWCgOkxc+TRkgf9Dmbn/VcPa/17V6v9Uz+X/QcXd/yq81/8et9T/GLfU/xi2 + 0/8dttL/JLLL/yurwf8torX/K5mt/yuRov8sipr/LYaX/y2Ek/8uhJP/MISU/y+Hlv8vjZv/MJOk/zGd + rv81prv/NK/G/ye20f8cuNX/GbfT/xi10v8YtNL/GbTS/yC41P86wNr/ZdHk/5fi8P+s6fP/qdre/6K7 + uP+dpJz/kpeQ/4SIhP95f3r/e396/32BfP+BhIH/goSC/3V4df9/hH3/o6qh/6Oro/+kq6P/oamg/5GY + kf9/g4D/f4F//3yAfP95fnn/eYB5/4SLg/+Um5L/oKae/6atpf+mraT/pKuj/6Oqov+iqaH/o6uh+6Ws + pM+osKZqr6+vI5+lnyWiqqJgoqmivqWro/WiqqL9jpWO1Hl+d2mGlIYTAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIsN28XGzZjSydEbGErSnVgL054bDJOeq4rSnn5LU1//zBR + g/8wUoT/MFKE/y9Uhv8tS3n/GCpM/xIoSf8WLVL/FCtP/xktTP8oRW7/Lkpy/T9OZupIVmy1Zm95eGJn + bS+Skm0HAAAAAQAAAAEzM2YFM2ZmBUltbQdNWVkUQk9YOj1JWXY1Q1XPKjta/SU+af8oS23/MnCI/0yq + xf9gzuX/Y9bq/1XO4/9AxN3/LLvW/x+30/8YttT/FrbU/xi21f8buNP/HrfT/yS20P8os8v/LLHI/y6v + x/8wsMb/L7DI/y+xyv8qtM3/JrfQ/yK31P8dt9T/GbfV/xi30/8XtNL/F7TS/xi00v8cttT/LLzW/1HK + 4P+D3O3/qOr1/7Lp7/+p0dT/oLWw/56hmv+eo5z/oKig/6GooP+co5z/lp6W/5CXj/+KkIr/hIqD/4KJ + gv+UmpP/oqig/6Koof+jqaL/oqmh/5efl/+KkYn/jJKM/5Wclf+co5z/oqqh/6atpf+lraX/pKyj/qGq + ofuhqKD7o6qi/aSro/+kqqL/nKOb/JmgmNKjq6FnqriqEgAA/wGZo5kZn6eiaKOrosWiqqLbmp+XmISJ + hDiSkpIHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIEBgCCc7 + dg03SW0OK0p1GDBNdWQmQm/jKkt7/jBThP8wUoT/MFKE/zBShf8vUoL/IThd/xUoR/8UKk7/FStR/xUo + SP8fM1X/LEhy/zBHbv40SWn0SFRm1z5OZ5RBUmVOQEpaMFheXjFRV15MVVhcTktRV1JBSlFyPUZUqyw7 + TtUsQFz2K0Rs/yQ8ZP8XJT7/FClF/yNObf87fpn/W7XI/2rS5v9p2Or/W9Lm/0nG3/84wtn/KbvX/x+4 + 1f8YtdL/FrbT/xW21P8WttT/GLfV/xm31f8Zt9X/GbfV/xi31v8Yt9X/F7bV/xe20/8XtdP/FrTS/xi0 + 0f8atdL/I7rV/za/2f9TyuH/e9no/6Xo9P+y6O//rdnc/6TCwP+isKv/rbKr/6yuqf+ip6H/nqOc/5mf + lv+YnpX/mp+X/5ygmP+boZn/mqCY/5qhmP+bopr/m6Kc/52knP+fpZ7/oKeg/6OooP+krKL/pKyk/6Wu + pP+mraX/pKyj/6Orov+kq6T7o6qg4Z+nnr+dp528oKeg36KqovulraT/naSc/5Obk+eXm5eFoqqiHgAA + AAD//wABnKWcH5+nomCep550n6ebPaqqqgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM2aACixIbVIhOVzYKkp5/TBThf8wUoP/MFKE/zBS + hP8vUob/LEx4/xwwUf8TJ0b/FSpQ/xUsUP8VJkP/HTNT/yhFcv8sRW//LEBg/C1CX+kuPVbBMkFWnT5E + TJ1IT1fCPUZPxTtETcguOkncMz9U9yI4V/4qQmr/Ijtf/xkrQ/8RIjz/ESRG/xAgPv8kOVP/RXGQ/1CZ + uv9ju9P/ctPl/3bc7v9u2ur/XtHl/0vH3/84wdr/LbvX/yK61v8dt9P/GbTR/xe00v8WtNH/FrTR/xaz + 0f8WtNH/FrTR/xi00f8dt9P/JLnV/zC92P9Gxtz/ZNLj/4jd7P+s6fP/vO32/6Pg6f91vMf/bpqc/5GZ + j/+traf/0c7L/9DOzP+6trP/mJeP/5GRh/+TlYv/kpWM/5OWjP+XmJD/mZqR/5qakf+YmZD/mJqS/5md + lf+aoJn/nKKc/5+lnv+iqqH/p6yl/6atpf+jq6P/oamh/6Srov+lq6T0o6mgsaCsoFmcpZxVnaOapp+l + nu+jq6P/o6qi/5adluuMlIyKnKWcHwAAAAAAAAAAgICAApa0pRGurq4Wn5+fCAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGAIKTtbOB40 + VpchOV7vK0t8/y5Pgf8uUIH/MFCB/zBSgv8wUoT/L1KE/yZBa/8YLEv/EyhJ/xUsT/8TKUz/FidE/x4z + Uv8lPmf/J0Ju/yhBaP8mPF74KjpW7ig1TOw0QVP7KDhP+yc4TfwjN1j9Kj9h/yQ8Zv8hNln/FydA/xIi + Pf8SJ0f/ECZF/x0tR/86TGr/OlaE/zJZiv89cJn/T4+z/2a30P96z+P/gN3s/4Dg7/932+r/a9bn/13Q + 5f9QyeH/RMXc/zzC2v83v9n/M7/Z/zPA2f82wNn/PcTb/0fH3f9WzeH/atLl/4Xb6/+e5fD/tOz0/7vs + 8/+t5e3/gNLg/0a3zP8hkqj/M3Z//4mPiv+6trL/yMvN/8HLzP+ZrLD/X39//1iDhP9dj5P/Wo2R/1qO + lf9klZr/bZia/3aYmv+AlpP/h5GM/5CUjP+XmZD/nqGa/7G2sP/Cx8L/yMzI/620rf+gqKD/oqqh/6Kq + ov+jqqLwo6yimaCspiufn58YnqWeZp+mn8mjqaH2pa2l/5+mnuqUnZKKnKWUHwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAQAgWLFQ6Gy9SmR02XOQnQm/+LUp6/yxKef8tTHz/Lk5//zBQgv8wUoP/MFOF/y5Q + gP8mPmX/Gi5M/xIoSP8UKU//EylM/xMmQf8ZKkf/HjRU/yM7X/8lPmX/Izle/yI4W/8kOVv/Izpd/yE3 + Wf8jOV7/HzVX/xosSv8WJT//EiRA/xImR/8QJEX/HCxF/zhMZv9CYIf/MVKG/y1Of/8tTH3/L1KB/ztn + kf9Lgqb/XJu5/3C4zf+G0+L/jd7q/5Hj8P+M4e//hd3s/oHc6/5+2+v+ftrq/oDb6v6F3ev+i9/t/pfj + 8P6j5/H+r+v1/rbr9f+u5+//k9nl/3LN3f9OwdX/KbPL/xaryP8SmLP/HneI/1iBiP90nKH/Y5yn/1iY + pP89j577KYWW7CWKneIfip/hG4me4xyQpeMhmbDoKJux+C6dsf46lqb+Ro6Z/1aLkf9wjYv/lp2X/8nH + wv/o6Of/6+vr/62wrf+VmpP/o6qi/6Kqov+gqZ/wpKukl6aspii/v78EpaylJaCmnnagpp7Ooquh8qGq + odigpqB7m6SbHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxMlRCkVKUyUHDFV5yQ+aP4nQ2//J0Ju/ihE + cf4rSHf/LEx8/y9Qgf8wUYL/MFKE/y9Thf8vT37/J0Jm/x0yTv8TKEX/EihM/xMpTv8SJ0X/EyVA/xcq + R/8aLEv/GSxI/xstS/8bLUr/GixJ/xkqSP8YKkb/FSZB/xEiPf8RJEP/ESZH/xEkQf8dLUb/Ok5o/0Nf + hf8yVof/LVCD/y9PgP8sTHv/K0h4/ylGdf8qR3T/Lk95/zlghv9Kepj/VYeb/26hrP6d2ePzoebx3qXo + 8Nqn6PLaqOnx2qzq89qv6vPatev02rrt9Nq+7vPbsuv04YLZ5/ZZxdv/NbXP/x6uy/8Xrsv/FarI/xek + wP8Wkqv/FXuQ/x59kP8fiJ//Fomh/xSJoP4ZjqbrKZivryOZrm4ThqBpFYylehWTrnsbnraMJKK3vSGr + x9oir8vmHqjC+xuZs/8uj6L/V5Oc/6m8vP/s6Oj/9vPy/7q8uv+TmZL/n6ee/6Sro/+gqaDwoqigmaiu + qCn///8BgICABJqhlCaco5x3nqadpp2nnYWbpptCnZ2dDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzBREm + SDwWKU26GjFW/SE4X/8gOV/3IDpg4SZCb9wrSnb4K0l5/y5OgP8wUYL/MFKE/y9ShP8wU4X/L1CA/y1H + a/8iNlT/FytI/xIoRv8SKEr/EShL/xMnSf8SJkb/EiRB/xIkQP8SIz//EiRA/xIkQf8SJkb/EydI/xEm + R/8QI0P/FCZA/yU2Tv8/Um//RmKK/zNWh/8vUIP/L1CB/y5Mff8rSnj/KkZy/ydDbv8lP2v+JD9o/yM7 + ZP8iOGD/HTFP/i1AU+x5nKaxr+fudqzl7myo6vFsqurxbKrq8Wyz7PFstuzzbL/x9Wu97PZtnd/rgFHE + 1sEruNP1G6/M/xapx/8Xorz/F5ew/xWKov8WiJz/Fouk/xWYs/8Vor//F6jF/xioxP4jorvqI4mfmhR2 + iScAgKoGIZumFxWAnxgynKokQaGuTzy81m9Jw9uaPsHa5S271/8aq8j/HZu1/0+jtP+pyM//7urq/9fW + 1v+hpKH/mJ+W/6Sso/6hqaDtoqiilqKomyn///8BAAAAAIC/gASco5wknqeZN56lniKioqILAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAg8fRiEWK02OFipM6xktUeceNF65ITtigidGc3wrSnTIK0p4+S5O + f/8wUIL/MFKE/zBShP8wUoT/MFKF/zFTg/8zTXb/LUJh/x8wTP8XKkb/EydF/xEmR/8RJkj/ESdI/xAm + SP8QJkj/ESZH/xElR/8QJEX/ECRD/xQlQf8eL0f/M0Vc/0ddff9DYYv/M1aI/y1QhP8wU4T/L0+C/y1L + ev8pR3P/JUJs/CU+ae8iO2XoIDlf+B81W/scMVT+GSxO7BssTawrRVhOtd/VGL/f7xC04fARtOHwEbTh + 8BG04fARtPDwEcPh4RG///8QiszbI1e/0W83udHYI6W9/heTrP8UiaL/FYed/xaOp/8Ym7T/GajE/xmy + zv8atNL/HLnW/yO71v8qma/4Gmd4xA9balQui4sLAFVVAwAAAAAA//8BAMzmClzCzBl9q65YdK2x0WC/ + zv83wtz/GrXS/xehvf9FpLf/ss/V/+fn5v2xtbP6kpmS8pylm9yeqJ6+oKagdpeflyD///8BAAAAAAAA + AACqqqoDgICABP///wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkSQcSKUZFFCpJmRku + T4UgOWNIMUJ7HyZEcSIsSnR5LEt46CtJef8uUIH/L1GC/y9Rgv8wUYL/L1KD/zBSg/8zVIX/NlOA/zJM + cf8wR2f/Kj5b/yE1UP8gMkz/HzJL/x0vSv8bLEj/HS1I/yExTP8kNE3/JzpU/zZIZP89VHT/Q16D/0Bg + jv8xU4b/LVCB/zBSg/8vUoP/L06A/yxJeP8nQ3H8JD9q4CM/Z58jPGOEHjhfqhwzVr0XK07RHDBTph83 + Z0oiM2YPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPaq2FTObr2kkmq/WGo2l/RWM + pf8Vkqz/GJ24/xiqxv8Zsc7/GrTR/xm30/8fudb/LcLd/zCwyP8daXb+EkZR6QlDT6gJR1JaEVFoLABt + bQcAAAAAAAAAAHGqqgmHn5hIj5eQxIOqqPJfu8T0Lr7X+haz0v8Zo8D/Vq2+/NDW1tnCxMO3mp+anZaf + lnCgqqBOmKOYL6KiogsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAEAHjwRFixTLiM+ah0AK1UGAAAAACBAYAgpQ2tYIz5m2yZDcv8uT3//LU19/y1N + ff8uTX//LlCA/zBQgv8wUoT/MFOF/zNWiP84WYb/OleB/zZSdv85UHL/PFNx/zxQb/88T2z/PlNw/0NY + dP9BV3n/Plp//0Nhif8+X47/MlOG/yxPgv8tT4H/L09//y5Of/8uTn//LUx9/ypJeP8nRHH3KUFvvCNC + bEkbQGQcIjplNR8zXEsZL1FoGDBYQBdGdAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ + /wFbyNsOIpy0SxKLpLQUjabzFZey/xikwf8Zrsv/GbPQ/xq10/8ZtdL/GrXT/yO71/82xeD/QL3V/yqE + lv8MRlL/CkNO/ghFUO4FQk7CB0hVcgxhbRUAAAAAAAAAAGaZmQWCnZ0vi6GXgoqhmaN3r7CsP7fM0hi4 + 1voVstH/IKTA9X+vtpnCzMlLsLWqLZmZmRSZmZkFgP+AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVAwAAAAEAAAAAAAAAASY5 + XhsgN1uBFy9R6yhFc/8sSnj/K0d0/ypIdf8rSXj/LUt8/y5QgP8wUIL/L1KE/zBRhP8wU4T/MVSG/zNX + hv83WIj/PFyJ/z9civ9AXon/Ql+L/z5fi/86Wor/NFeJ/zFUh/8uUIT/LE+B/y5Of/8tTHv/LUp6/y1K + ef8tSnn/LEt5/ytIdv8nQm/5ITdiyCRDcFQ5VY4JAABABAA5cQkYMVUVGk1mCgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAUnI2w4vu9BHH6zJphWkwPAXpsL/GK/N/xm00v8ZttL/GbbT/xu4 + 0/8iudX/MMHe/0LI4f9Ft83/L4ia/xNXZP8MTl3/DlRk/wtTYv8GTFrsCUtYkxNocRsAAAAAAAAAAAAA + AAGAlZUMhqafKIKnpzF5tLg9P7PIeRexz94UtdP8FbDN8ympv4NapbUfgICAAv///wEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAACBACBo0VU4VK0vLIThg/idFb/8nP2n/IT1l/CM9aOwmQW/4Kkh3/y1N + ff8vUID/MFCB/y9QgP8vUIH/L1CA/y9Qgv8wUIT/MFGE/zBShP8vUYP/L1GD/y9Qgv8uUIP/L1CC/y9R + gv8vUYL/Lk9+/y1Lev8rR3X/J0Vv/yRAbP4lQW3/KEVx/ypHcf8lP2v/GzBY7RcsUJwxSXkqAAAAAQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8BN7HIFyeuyGIVnbrAKa3J9EzM + 4/88xuD+Mb/c/yzA3P8wwd3/Osbg/0rN5f9XzeT/UbjL/zSJmf8bZXP/DlJe/w5WZP8OUWD/Dllo/w5e + bf8LWmrlDFhoggtkbxcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAgIAEKrbLMRevzLMTsdD5FbXT/BKv + zbgYs89KGrPMCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABICtKGBMmSnkVKEvsIztg/yE4 + X/8fNFr6IjxlzCVCapAqSHS7LUp4+C1MfP8tTH7/Lk5//y1Mff8sTHz/LUx9/y1Nfv8uUID/L1CB/y9R + gv8vT4D/Lk5+/y1Mff8tTHz/LU1+/y5PgP8uT3//Lkt7/ytIdv8mQm/9IT5o7CVAbNMmQWzmJkBn/CU/ + aP8lPmb/HTNY+xIkQ9AiPmViJEltDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAas+YKH7HPSxejwrwVn772Pr7V93HW6dtp1ufZYs7f+F7L3/9dx9r/V7rN/0mmuf84jJv/IW16/xBQ + X/8OUmL/DVJh/w5ZaP8OWmj/D1xq/xJhb/cPYG29DlpoRwBmZgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAgIACEqzKKxKuzKsSrcr5FrTT/xOz0tYUs9BoD6XDEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAABpNCh4uVk0ZLFG5GzFT9hgtTvYcMFPTJkRuZiNHeCQrSnhkLUp63ClHdP8sTHv/LEt5/ytH + df8pRnT/KUZ0/yxKeP8sTHz/Lk6A/y5PgP8tS3z/LEp5/ytJdf8qSXX/K0l3/yxLev8tTHz/LEt6/ydG + cf4mQ2/lJkNumSNBal4mQm2IIzph2yA2W/8fNFn9Gy9S6hUrSrMbNFdeNzdtDgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA/wIfosEhD5y7hBKfvucru9X2UsrixG/R425ZtsJ+M4GN2yx0 + hP8rdIL/ImZ2/xdebP8QVmP/DlRj/w5TYf8OVWL/D1Zl/w5SYf8PXW3/EWFw/hJiceQPYG6HEVVmHgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIACDKTOKhGry6oRqsn5F7TS/xm209oVs9BsHrTSEQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARsoXhMfNFlTGy5RoRgsTakbL1FyIEBgGCsr + VQYmRXJDJkJszh84X/8rS3r/KUZy/ydBbf4kP2z6I0Fu+ChEdPosSnn/LUx8/y5Mff8rS3j/KkZz/ydB + bf4lQW35KERw/CxId/8sSXj/K0l2/yZCbvsiPWbSJD1mZBs2axMjOmMsIjpeiB0wU+MZLU7hFytNmRwy + VUghMVofAABVAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ASm41hkYpsNqC5W1zByv + zfVAxeDLZcndaFK20Rw1i5VNGF1tzAlJWv8NUF//DFFe/w1UY/8NVGL/DlNj/w9baf8OUmH/Dlhn/w5Z + Z/8UYnD+GWp36BVmc50SYW46AFVVBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIACDJy5LA+i + v6wRqcj5F7TT/Bu308AWs9BRF6LRCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAESJFsOFDRVJx0uVywVK0oYAAAAAQAzZgUjO2pBHTNWzR00Wv8qRXH/JD5m/SI7ZOYlQGusJ0RzlSpI + d7srSHnzKkl3/ytKeP8qRnP/JD5r+SI9Z9QiP2emLERxuylEcPAnQ3D/J0Rv/yQ+aP4dNFzmJD1mhSBA + YBgAKysGHjFVKhwxVG0cMVFuGzBQMBozTQoAAFUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAJLa2BxquyDwUo8C1EqPC9ie92uQ/xeKFXcHRIRpmZgoYY3BLD1hozAlRYf8NV2X/DFNi/w1W + Zv8OWGj/DFBf/w1YaP8NV2X/EVxq/xppePwicXzeJXJ8kiZoezYcVXEJAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAUxNgND6C7UxCaus8Urcr8GbfS9R200Y8itdAmAP//AgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgCAgAIAAAAAAAAAAAAzZgUbMlVCFipMzh42 + XP8kPGT/IDdc9yE5YMEnRGtWIUd3LytCdnclQG7kJEFu/ylGcv8lQGr8ITli2CE4YnokPWsyKkFrViI7 + ZLsgOWD4JkBo/yE6Yv8cM1fvIztklytEZh4AAAAAAABABBozWRQjLmgWACtVBgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF7noCxinwlQQn7/PGLHQ9Cy/27g3veJGVdX/BiBg + gAgXZXFEE19xuxRjcvIWZHP/EF9t/w9da/8PXm3/EF1p/xRib/8baXf/JHJ9+Ch3hNcrdYOOLnqFMiRt + bQcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAELtcoYE565fA+eu/AXs9L/HLrW7x+5 + 03QuxdwWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAMwUSKVI4GCtKthszVe0aMFH8GzFS3CE9ZnouQHYcHjxpESZAbmQgOGHfHzde/ydC + bf8jOmL3HzZcvSM6XUIAM2YFK01mHiM5XoIdM1jlHzZZ/xwxVP8VK0zvFy1OmitEZh4AAAAAAAAAAAAA + AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqqoDHLrWJRqu + y4oRoMHqG7nW6iu/3JA8u90eAAAAAQBVVQMRZm8eGmp2YxhodqASYnHVEWBw3w5ebd8PW23fE2Jx3yNy + fd8pdYPWJnOAry94hGwtfYgtJG1tBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA + /wIOmLMlD5q3lROnxPgcudf6Jr7Y0Ci30EdAn78IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAGkAUGC5PVB0yV48aL1G9GDJSiShD + ayYAQIAEK0CADCM+alcdMVjQGCtN/iM5YP8dNFf3HTRYtyE5YzYAAAABHDlxCSM6XUIXME+0FipL9Rov + UOIbMVXGGCpOfx89ZhkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAqtUGFrDGOhCiv7QSp8T7G7bS6RiwzogxztsVAAAAAAAAAAAAQEAEDG15FRVo + bTERYnNbEl9vYwpdamMVYnFjHGp2Yyx2gWMseoVcK3eAPCZzgBQrgIAGAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAP//AQuqvxgPm7lmEJ26yxWz0fwevdj2Lr/Ytza81yYA//8BAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAABESJVDxw3WiUeNFlFGTJRKTMzZgUAAAAAAECABB43ZyobL0+XEiVD7xcrT/wVKkvzHDBRthw5 + VTYAAAABAACAAiIzVR4WK1FyFCdJqBktUXIdNF5PGzFRLwArVQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAttsHFKbCPw2cvb4SrMn9F7bU6BOt + zIgkztsVAAAAAAAAAAAAAAAAAAAAAAAzZgUUYnYNEWZmDwBVZg8RZncPImaIDyJ3iA8kgIAOJG1tBwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8BC6rVGBSlwWYRnbrFEqjG9hy5 + 1/8pwd3rKL/VmDO41hkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIgQGAIAECABAAAAAAAAAAAAAAAAB48 + aREdNVhXFypNqhMnSr0VKUy1FypNhRsvUSYAAAABAAAAAAAAJAcPJEkjGCtMNgwjURYXLkYLACuABgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAkrYHDKbGPxGlxL4Sr839F7TS6BGuzIgYttsVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ + /wELtcoYF6nFZRKgvMYSpML2GLbV/iK82O8yv9mvML7aSyS2tgcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVQMXLlEWGylNOBAlRj4RK008GCRHKxxVVQkAAAAAAAAAAAAA + AAAAAAADACtVBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkrYHDKrGPxGsyb4Trs/9FLTR6BWy0IcMqs4VAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAP//ARaxyBcSoMBhEJ66wxKiv/YXs9L/HLnW8Su/2a40vtVPM6rMDwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABADMzBQAA + KwYAACsGAEBABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkrYHEKrGPxGr + x8ATrs39FbPQ6xCvzowdutgaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtrYHE5W0KQyatG0PlrPJEqTD9hey + 0f8ZutXvH7zVqzLB1UI3ttsOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAqtUGFrDKOhGqyLURrMr8FrLQ9hCqy7oat9hOEpKkDgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+l + tBEOnLtLDJKvkw+WtdATpsP5F7PQ/xi41fEct9GwHrPNTU3M5goAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8CCbvMHhCpzH0Rq8rkF7PR/hOs + yuwSpMOtEarMSyC/vwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAqtUGFazBJRGevFwOlbO1EJu76RaqyvkXtdP/HLfU8Rm01LAdt85OEbvMDwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAKrjCRWxzUgWss69E7TS/Biyzv4QoL3sD5azrBitxEE5xsYJAP//AQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wEAv78IEqS/HBWatTAQnbpRDpWzkxCXt8USpMPzFbHO/ha2 + 1PcauNPaGrnRpxez0U0Ru8wPAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AQqnxBoVs9VsFrbUzhe20vwWrsr+E5+96hao + wqQZsNBRI7jNJCvV1QYA//8DAFWqAwBVqgMAVaoDAFWqAwBVqgMA1f8GC5+/GA6kwDUMm7dSD527ig2Y + t64OmLTGEqDB7RWsyvgVs9D7HLrV8By30bwfus9rF7bNOBKktg4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACq + qgMYr88gG7PQch2309Aaudb7Fq/P/Q+iv+wQmbTFE6TAkhKcvVUPnrRED5+8RQ+fwEUPo8BFEqPARQ+b + uUUNnrJPEJq3fBGevLAPmLTJDpy35xKnxvQUrsz4FbHQ9xe10OAcs8++F7PNnhuy0FYYqsIVK9X/BgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqqoDJrTLIiO813MhvNfRILzY+he11P4SqMj5EJ++6A6d + u8oPnLrBEKHAwQ+hwcEQocLBEKXCwQ+fusEPmLLHD5223xGkwvUTq8r5FK/M+xWz0vUUttLiFrPSrxez + 0Hget9FDHKzNLhC/zxAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKr/Aym9 + xR8oudVmJbvXvyK72uofudfzG7bV/ha10foTr9D5Eq7O+RGtzPkRrc35Eq7O+ROwzvkUtND6F7LP+BWy + 0ewUsNDYFbDPqhSx0IkTsdFpD6zONBWqyhggv98IAL+/BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wIrv98YI7nZUCq72YAoutefHLbV1Ra00+cVstDnFLDO5xKs + zOcSq8vnErDN5xOx0OcWtdXeGLbTuBW1z4YUsM1nEq3IOBClxR8NockTAL+/BAAAAAEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP8CFLHYDSa9 + 0Bslr88wILTUXxmy0nEXsNBxEqzJcRCpyXEQqcdxEq7HcRSuyXEUsdBoFrbQRhGzzB4Ns8wUAKrVBgCA + gAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAmcwFD6W0ERiethUYnrYVDJ62FQySqhUMkqoVDJKqFQye + qhUNobwTHKrGCQD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD//////gAAP/////////////gAAP/////wAAAP//////// + ////+AAA/////8AAAAH////////////4AAD/////AAAAAH////////////gAAP////4AAAAAH/////// + ////+AAA////+AAAAAAP///D///////4AAD////wAAAAAAP/g4HB//////gAAP///+AAAAAAAf8BAMD/ + ////+AAA////wAAAAAAAbwEAwHn////4AAD///+AAAAAAAAGAQCAYP////gAAP///wAAAAAAAAIAAABA + f///+AAA////AAAAAAAAAgAAAAB////4AAD///4AAAAAAAAAAAAAAH////gAAP///gAAAAAAAAAAAAAA + YP//+AAA///8AAAAAAAAAAAAAABAf//4AAD///gAAAAAAAAAAAAAAAB///gAAP//+AAAAAAAAAAAAAAA + AH//+AAA///wAAAAAAAAAAAAAAAAf//4AAD///AAAAAAAAAAAAAAAAD///gAAP//4AAAAAAAAAAAAAAA + AIP/+AAA///gAAAAAAAAAAAAAAABAf/4AAD//8AAAAAAAAAAAAAAAAAA//gAAP//wAAAAAAAAAAAAAAA + AAD/+AAA///AAAAAAAAAAAAAAAAAAP/4AAD//4AAAAAAAAAAAAAAAAAB//gAAP//gAAAAAAAAAAAAAAA + AAP/+AAA//+AAAAAAAAAAAAAAAAABA/4AAD//4AAAAAAAAAAAAAAAAAAB/gAAP//gAAAAAAAAAAAAAAA + AAAH+AAA//+AAAAAAAAAAAAAAAAAAAf4AAD//wAAAAAAAAAAAAAAAAAAA/gAAP//AAAAAAAAAAAAAAAA + AAAH+AAA//8AAAAAAAAAAAAAAAAAAB/4AAD//wAAAAAAAAAAAAAAAAAAP/gAAP//AAAAAAAAAAAAAAAA + AAAB+AAA//8AAAAAAAAAAAAAAAAAAAB4AAD//wAAAAAAAAAAAAAAAAAAAHgAAP//AAAAAAAAAAAAAAAA + AAAAeAAA//8AAAAAAAAAAAAAAAAAAAB4AAD//wAAAAAAAAAAAAAAAAAAAHgAAP//AAAAAAAAAAAAAAAA + AAAA+AAA//8AAAAAAAAAAAAAAAAAAAf4AAD//wAAAAAAAAAAAAcAAAAAAPgAAP//AAAAAAAAAAAAB8AA + AAAAeAAA//8AAAAAAAAAAAAH4AAAAAA4AAD//wAAAAAAAAAAAAfgAAAAABgAAP//AAAAAAAAAAAAB/AA + AAAAGAAA//8AAAAAAAAAAAAD8AAAAAAYAAD//wAAAAAAAAAAAAP4AAAAADgAAP//gAAAAAAAAAAAA/gA + AAAB+AAA//+AAAAAAAAAAAAD+AAAAAP4AAD//4AAAAAAAAAAAAP4AAAAAHgAAP//gAAAAAAAAAAAA/gA + AAAAOAAA//+AAAAAAAAAAAAD+AAAAAAYAAD//4AAAAAAAAAAAAPwAAAAABgAAP//wAAAAAAAAAAAA/AA + AAAAGAAA//8AAAAAAAAAAAAD4AAAAAAYAAD//gAAAAAAAAAAAAPAAAAAADgAAP/8AAAAAAAAAAAAA4AA + AAAP+AAA//gAAAAAAAAAAAAAAAAAAAf4AAD/+AAAAAAAAAAAAAAAAAAAAfgAAP/4AAAAAAAAAAAAAAAA + AAAA+AAA/+QAAAAAAAAAAAAAAAAAAAB4AAD/gAAAAAAAAAAAAAAAAAAAAHgAAP8AAAAAAAAAAAAAAAAA + AAAAeAAA/wAAAAAAAAAAAAAAAAAAAAD4AAD/AAAAAAAAAAAAAAAAAAAAAfgAAP8AAAAAAAAAAAAAAAAA + AAA/+AAA/wAAAAAAAAAAAAAAAAAAAA/4AAD/gAAAAAAAAAAAAAAAAAAAB/gAAP4AAAAAAAAAAAAAAAAA + AAAD+AAA/AAAAAAAAAAAAAAAAAAAAAP4AAD4AAAAAAAAAAAAAAAAAAAAB/gAAPgAAAAAAAAAAAAAAAAA + AAAP+AAA8AAAAAAAAAAAAAAAAAAAAB/4AADwAAAIAAAAAAAAAAAAAAAB//gAAPAAABwAAAAAAAAAAAAA + AAD/+AAA+AAAHgAAAAAAAAAAAAAAAP/4AAD/AAAfAAAAAAAAAAAAAAAA//gAAPwAAB+AAAAAAAAAAAAA + AAD/+AAA+AAAH8AAAAAAAAAAAAAAAf/4AADwAAAf4AAAAAAAAAAAAACD//gAAPAAAA/wAAAAAAAAAAAA + AGf/+AAA8AAAB/gAAAAAAAAAAAAAf//4AADwAAAD+AAAAAAAAAAAAAB///gAAPgAAAAAAAAAAAAAAAAA + AH//+AAA/AAAAAAAAAAAAAAAAABA///4AAD/wAAAAAAAAAAAAAAAAGH///gAAP+AAAAAAAAAAAAAAAAA + f///+AAA/wAAAAAAAAAAAAAAAAB////4AAD+AAAAAAAAAAAAAAAAAH////gAAP4AAAAAAAAAAAAAAAAg + f///+AAA/gAAAAAAAAAAAAIAADH////4AAD/AAAAAAAAP8AAAYAAf/////gAAP8EAAAAAAB/gAABgAD/ + ////+AAA/8gAAAAAAP8AAAGAA//////4AAD/+AAAAAAH/gAAAfAH//////gAAP/wAAAAAAf+AAAB+Af/ + ////+AAA//gAAAAAB/wAAAP4B//////4AAD/+AAAAAAH+AAAA/gH//////gAAP/8AAAAAA/4AAAH+Af/ + ////+AAA//8wAAAEP/gAAA/wD//////4AAD///AAAAd/8AAAH/AP//////gAAP//8AAAB//wGAA/4A// + ////+AAA///4EAAH//AeAP/AH//////4AAD///44BA//8B///4Af//////gAAP////gOf//wH///AD// + ////+AAA/////B////Af//4Af//////4AAD/////////8A///AD///////gAAP/////////wB//wAf// + ////+AAA//////////gB/wAB///////4AAD/////////+AAAAAf///////gAAP/////////8AAAAD/// + ////+AAA//////////4AAAAf///////4AAD//////////wAAAH////////gAAP//////////gAAB//// + ////+AAA///////////AAAf////////4AAD///////////AAf/////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAD///////////////////////gAAP////////////////// + ////+AAA///////////////////////4AAA= + + + \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Views/Help.Designer.cs b/ToonTown Rewritten Bot/Views/Help.Designer.cs new file mode 100644 index 00000000..b7b91886 --- /dev/null +++ b/ToonTown Rewritten Bot/Views/Help.Designer.cs @@ -0,0 +1,122 @@ +namespace ToonTown_Rewritten_Bot +{ + partial class Help + { + /// + /// 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(Help)); + groupBox1 = new System.Windows.Forms.GroupBox(); + label1 = new System.Windows.Forms.Label(); + richTextBox1 = new System.Windows.Forms.RichTextBox(); + groupBox2 = new System.Windows.Forms.GroupBox(); + linkLabel1 = new System.Windows.Forms.LinkLabel(); + groupBox1.SuspendLayout(); + groupBox2.SuspendLayout(); + SuspendLayout(); + // + // groupBox1 + // + groupBox1.Controls.Add(label1); + groupBox1.Controls.Add(richTextBox1); + groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); + groupBox1.Location = new System.Drawing.Point(16, 15); + groupBox1.Margin = new System.Windows.Forms.Padding(4); + groupBox1.Name = "groupBox1"; + groupBox1.Padding = new System.Windows.Forms.Padding(4); + groupBox1.Size = new System.Drawing.Size(393, 213); + groupBox1.TabIndex = 0; + groupBox1.TabStop = false; + groupBox1.Text = "Coordinates Updater Info"; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(7, 157); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(298, 48); + label1.TabIndex = 1; + label1.Text = "Notice: You will only have to teach the bot once \r\n(first time loading the program on PC), unless you \r\nreset your coordinates!\r\n"; + // + // richTextBox1 + // + richTextBox1.Location = new System.Drawing.Point(8, 26); + richTextBox1.Margin = new System.Windows.Forms.Padding(4); + richTextBox1.Name = "richTextBox1"; + richTextBox1.Size = new System.Drawing.Size(376, 127); + richTextBox1.TabIndex = 0; + richTextBox1.Text = resources.GetString("richTextBox1.Text"); + // + // groupBox2 + // + groupBox2.Controls.Add(linkLabel1); + groupBox2.Location = new System.Drawing.Point(12, 235); + groupBox2.Name = "groupBox2"; + groupBox2.Size = new System.Drawing.Size(396, 58); + groupBox2.TabIndex = 1; + groupBox2.TabStop = false; + groupBox2.Text = "Contact Info"; + // + // linkLabel1 + // + linkLabel1.AutoSize = true; + linkLabel1.Location = new System.Drawing.Point(6, 25); + linkLabel1.Name = "linkLabel1"; + linkLabel1.Size = new System.Drawing.Size(188, 16); + linkLabel1.TabIndex = 2; + linkLabel1.TabStop = true; + linkLabel1.Text = "https://github.com/primetime43"; + linkLabel1.LinkClicked += linkLabel1_LinkClicked; + // + // Help + // + AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(429, 305); + Controls.Add(groupBox2); + Controls.Add(groupBox1); + Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); + Margin = new System.Windows.Forms.Padding(4); + Name = "Help"; + Text = "Help Infomation"; + groupBox1.ResumeLayout(false); + groupBox1.PerformLayout(); + groupBox2.ResumeLayout(false); + groupBox2.PerformLayout(); + ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.LinkLabel linkLabel1; + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Views/Help.cs b/ToonTown Rewritten Bot/Views/Help.cs new file mode 100644 index 00000000..4153ad73 --- /dev/null +++ b/ToonTown Rewritten Bot/Views/Help.cs @@ -0,0 +1,23 @@ +using System.Windows.Forms; + +namespace ToonTown_Rewritten_Bot +{ + public partial class Help : Form + { + public Help() + { + InitializeComponent(); + } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + var psi = new System.Diagnostics.ProcessStartInfo + { + FileName = linkLabel1.Text, + UseShellExecute = true // Allows the process to open the link in the default browser + }; + + System.Diagnostics.Process.Start(psi); + } + } +} diff --git a/ToonTown Rewritten Bot/Help.resx b/ToonTown Rewritten Bot/Views/Help.resx similarity index 99% rename from ToonTown Rewritten Bot/Help.resx rename to ToonTown Rewritten Bot/Views/Help.resx index f982eb2f..63af304c 100644 --- a/ToonTown Rewritten Bot/Help.resx +++ b/ToonTown Rewritten Bot/Views/Help.resx @@ -1,17 +1,17 @@  - diff --git a/ToonTown Rewritten Bot/Form1.Designer.cs b/ToonTown Rewritten Bot/Views/MainForm.Designer.cs similarity index 62% rename from ToonTown Rewritten Bot/Form1.Designer.cs rename to ToonTown Rewritten Bot/Views/MainForm.Designer.cs index 4af91600..73030db1 100644 --- a/ToonTown Rewritten Bot/Form1.Designer.cs +++ b/ToonTown Rewritten Bot/Views/MainForm.Designer.cs @@ -1,6 +1,6 @@ namespace ToonTown_Rewritten_Bot { - partial class Form1 + partial class MainForm { /// /// Required designer variable. @@ -29,7 +29,7 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); tabControl1 = new System.Windows.Forms.TabControl(); Main = new System.Windows.Forms.TabPage(); label8 = new System.Windows.Forms.Label(); @@ -38,63 +38,60 @@ private void InitializeComponent() label7 = new System.Windows.Forms.Label(); pictureBox1 = new System.Windows.Forms.PictureBox(); Fishing = new System.Windows.Forms.TabPage(); + createCustomFishingActionsBtn = new System.Windows.Forms.Button(); + label12 = new System.Windows.Forms.Label(); groupBox6 = new System.Windows.Forms.GroupBox(); + debugCustomActionsCheckBox = new System.Windows.Forms.CheckBox(); button4 = new System.Windows.Forms.Button(); - randomFishing = new System.Windows.Forms.CheckBox(); + customFishingFilesComboBox = new System.Windows.Forms.ComboBox(); + randomFishingCheckBox = new System.Windows.Forms.CheckBox(); smartFishing = new System.Windows.Forms.CheckBox(); label4 = new System.Windows.Forms.Label(); numericUpDown4 = new System.Windows.Forms.NumericUpDown(); label3 = new System.Windows.Forms.Label(); numericUpDown3 = new System.Windows.Forms.NumericUpDown(); startFishing = new System.Windows.Forms.Button(); - comboBox3 = new System.Windows.Forms.ComboBox(); + fishingLocationscomboBox = new System.Windows.Forms.ComboBox(); Racing = new System.Windows.Forms.TabPage(); label6 = new System.Windows.Forms.Label(); richTextBox1 = new System.Windows.Forms.RichTextBox(); startRacing = new System.Windows.Forms.Button(); Gardening = new System.Windows.Forms.TabPage(); groupBox5 = new System.Windows.Forms.GroupBox(); - button3 = new System.Windows.Forms.Button(); + removePlantBtn = new System.Windows.Forms.Button(); groupBox4 = new System.Windows.Forms.GroupBox(); - button2 = new System.Windows.Forms.Button(); + waterPlantNumericUpDown = new System.Windows.Forms.NumericUpDown(); + waterPlantBtn = new System.Windows.Forms.Button(); groupBox3 = new System.Windows.Forms.GroupBox(); - comboBox2 = new System.Windows.Forms.ComboBox(); - button1 = new System.Windows.Forms.Button(); + flowerBeanAmountDropdown = new System.Windows.Forms.ComboBox(); + selectFlowerBeanAmountBtn = new System.Windows.Forms.Button(); Golf = new System.Windows.Forms.TabPage(); - label2 = new System.Windows.Forms.Label(); - Near_Hole = new System.Windows.Forms.GroupBox(); - One_Little_Birdie = new System.Windows.Forms.Button(); - button14 = new System.Windows.Forms.Button(); - button18 = new System.Windows.Forms.Button(); - button15 = new System.Windows.Forms.Button(); - button13 = new System.Windows.Forms.Button(); - button16 = new System.Windows.Forms.Button(); - Hole_In_One = new System.Windows.Forms.GroupBox(); - button12 = new System.Windows.Forms.Button(); - button5 = new System.Windows.Forms.Button(); - button17 = new System.Windows.Forms.Button(); - button10 = new System.Windows.Forms.Button(); - button11 = new System.Windows.Forms.Button(); + groupBox10 = new System.Windows.Forms.GroupBox(); + golfActionsListBox = new System.Windows.Forms.ListBox(); + customGolfFilesComboBox = new System.Windows.Forms.ComboBox(); + button1 = new System.Windows.Forms.Button(); + createCustomGolfActionsBtn = new System.Windows.Forms.Button(); Doodles = new System.Windows.Forms.TabPage(); richTextBox2 = new System.Windows.Forms.RichTextBox(); groupBox8 = new System.Windows.Forms.GroupBox(); - checkBox5 = new System.Windows.Forms.CheckBox(); - checkBox4 = new System.Windows.Forms.CheckBox(); - comboBox4 = new System.Windows.Forms.ComboBox(); + justScratchDoodleCheckBox = new System.Windows.Forms.CheckBox(); + justFeedDoodleCheckBox = new System.Windows.Forms.CheckBox(); + doodleTrickComboBox = new System.Windows.Forms.ComboBox(); pictureBox2 = new System.Windows.Forms.PictureBox(); - checkBox3 = new System.Windows.Forms.CheckBox(); - button19 = new System.Windows.Forms.Button(); + unlimitedTrainingCheckBox = new System.Windows.Forms.CheckBox(); + stopDoodleTrainingBtn = new System.Windows.Forms.Button(); label9 = new System.Windows.Forms.Label(); - numericUpDown5 = new System.Windows.Forms.NumericUpDown(); + numberOfDoodleScratchesNumericUpDown = new System.Windows.Forms.NumericUpDown(); label10 = new System.Windows.Forms.Label(); - numericUpDown6 = new System.Windows.Forms.NumericUpDown(); - button20 = new System.Windows.Forms.Button(); + numberOfDoodleFeedsNumericUpDown = new System.Windows.Forms.NumericUpDown(); + startDoodleTrainingBtn = new System.Windows.Forms.Button(); Misc = new System.Windows.Forms.TabPage(); checkBox2 = new System.Windows.Forms.CheckBox(); groupBox2 = new System.Windows.Forms.GroupBox(); + stopKeepToonAwakeButton = new System.Windows.Forms.Button(); label1 = new System.Windows.Forms.Label(); numericUpDown1 = new System.Windows.Forms.NumericUpDown(); - keepToonAwakeButton = new System.Windows.Forms.Button(); + startKeepToonAwakeButton = new System.Windows.Forms.Button(); groupBox1 = new System.Windows.Forms.GroupBox(); numericUpDown2 = new System.Windows.Forms.NumericUpDown(); checkBox1 = new System.Windows.Forms.CheckBox(); @@ -107,12 +104,12 @@ private void InitializeComponent() resetImagesBtn = new System.Windows.Forms.Button(); label5 = new System.Windows.Forms.Label(); groupBox7 = new System.Windows.Forms.GroupBox(); + button2 = new System.Windows.Forms.Button(); button6 = new System.Windows.Forms.Button(); comboBox1 = new System.Windows.Forms.ComboBox(); button7 = new System.Windows.Forms.Button(); toolTip1 = new System.Windows.Forms.ToolTip(components); timer1 = new System.Windows.Forms.Timer(components); - golfNoteLbl = new System.Windows.Forms.Label(); tabControl1.SuspendLayout(); Main.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); @@ -124,15 +121,15 @@ private void InitializeComponent() Gardening.SuspendLayout(); groupBox5.SuspendLayout(); groupBox4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)waterPlantNumericUpDown).BeginInit(); groupBox3.SuspendLayout(); Golf.SuspendLayout(); - Near_Hole.SuspendLayout(); - Hole_In_One.SuspendLayout(); + groupBox10.SuspendLayout(); Doodles.SuspendLayout(); groupBox8.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox2).BeginInit(); - ((System.ComponentModel.ISupportInitialize)numericUpDown5).BeginInit(); - ((System.ComponentModel.ISupportInitialize)numericUpDown6).BeginInit(); + ((System.ComponentModel.ISupportInitialize)numberOfDoodleScratchesNumericUpDown).BeginInit(); + ((System.ComponentModel.ISupportInitialize)numberOfDoodleFeedsNumericUpDown).BeginInit(); Misc.SuspendLayout(); groupBox2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)numericUpDown1).BeginInit(); @@ -154,7 +151,7 @@ private void InitializeComponent() tabControl1.Controls.Add(Misc); tabControl1.Controls.Add(Dev); tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; - tabControl1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + tabControl1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F); tabControl1.Location = new System.Drawing.Point(0, 0); tabControl1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); tabControl1.Name = "tabControl1"; @@ -234,6 +231,8 @@ private void InitializeComponent() // // Fishing // + Fishing.Controls.Add(createCustomFishingActionsBtn); + Fishing.Controls.Add(label12); Fishing.Controls.Add(groupBox6); Fishing.Location = new System.Drawing.Point(4, 25); Fishing.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); @@ -244,29 +243,66 @@ private void InitializeComponent() Fishing.Text = "Fishing"; Fishing.UseVisualStyleBackColor = true; // + // createCustomFishingActionsBtn + // + createCustomFishingActionsBtn.Location = new System.Drawing.Point(401, 12); + createCustomFishingActionsBtn.Name = "createCustomFishingActionsBtn"; + createCustomFishingActionsBtn.Size = new System.Drawing.Size(137, 43); + createCustomFishingActionsBtn.TabIndex = 10; + createCustomFishingActionsBtn.Text = "Create Custom Fishing Actions"; + toolTip1.SetToolTip(createCustomFishingActionsBtn, "This will allow you to build custom fishing actions\r\nfor walking from the fishing dock to the fisherman\r\n to sell and back to the fishing dock"); + createCustomFishingActionsBtn.UseVisualStyleBackColor = true; + createCustomFishingActionsBtn.Click += createCustomFishingActionsBtn_Click; + // + // label12 + // + label12.AutoSize = true; + label12.Location = new System.Drawing.Point(13, 278); + label12.Name = "label12"; + label12.Size = new System.Drawing.Size(51, 16); + label12.TabIndex = 9; + label12.Text = "label12"; + label12.Visible = false; + // // groupBox6 // + groupBox6.Controls.Add(debugCustomActionsCheckBox); groupBox6.Controls.Add(button4); - groupBox6.Controls.Add(randomFishing); + groupBox6.Controls.Add(customFishingFilesComboBox); + groupBox6.Controls.Add(randomFishingCheckBox); groupBox6.Controls.Add(smartFishing); groupBox6.Controls.Add(label4); groupBox6.Controls.Add(numericUpDown4); groupBox6.Controls.Add(label3); groupBox6.Controls.Add(numericUpDown3); groupBox6.Controls.Add(startFishing); - groupBox6.Controls.Add(comboBox3); + groupBox6.Controls.Add(fishingLocationscomboBox); groupBox6.Location = new System.Drawing.Point(9, 7); groupBox6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox6.Name = "groupBox6"; groupBox6.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - groupBox6.Size = new System.Drawing.Size(385, 196); + groupBox6.Size = new System.Drawing.Size(385, 236); groupBox6.TabIndex = 8; groupBox6.TabStop = false; groupBox6.Text = "Fishing Locations"; // + // debugCustomActionsCheckBox + // + debugCustomActionsCheckBox.AutoSize = true; + debugCustomActionsCheckBox.Enabled = false; + debugCustomActionsCheckBox.Location = new System.Drawing.Point(194, 122); + debugCustomActionsCheckBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + debugCustomActionsCheckBox.Name = "debugCustomActionsCheckBox"; + debugCustomActionsCheckBox.Size = new System.Drawing.Size(162, 20); + debugCustomActionsCheckBox.TabIndex = 13; + debugCustomActionsCheckBox.Text = "Debug Custom Actions"; + toolTip1.SetToolTip(debugCustomActionsCheckBox, "This will allow you to debug the custom action\r\nwalk from the dock to the fisherman"); + debugCustomActionsCheckBox.UseVisualStyleBackColor = true; + debugCustomActionsCheckBox.Visible = false; + // // button4 // - button4.Location = new System.Drawing.Point(194, 144); + button4.Location = new System.Drawing.Point(193, 183); button4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); button4.Name = "button4"; button4.Size = new System.Drawing.Size(184, 38); @@ -275,18 +311,28 @@ private void InitializeComponent() button4.UseVisualStyleBackColor = true; button4.Click += button4_Click; // - // randomFishing - // - randomFishing.AutoSize = true; - randomFishing.Location = new System.Drawing.Point(194, 110); - randomFishing.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - randomFishing.Name = "randomFishing"; - randomFishing.Size = new System.Drawing.Size(135, 20); - randomFishing.TabIndex = 11; - randomFishing.Text = "Random Variance"; - toolTip1.SetToolTip(randomFishing, "This add some randomness and will make it so you \r\nwon't cast your line at the same spot every time!"); - randomFishing.UseVisualStyleBackColor = true; - randomFishing.CheckedChanged += randomFishing_CheckedChanged; + // customFishingFilesComboBox + // + customFishingFilesComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + customFishingFilesComboBox.FormattingEnabled = true; + customFishingFilesComboBox.Location = new System.Drawing.Point(4, 153); + customFishingFilesComboBox.Name = "customFishingFilesComboBox"; + customFishingFilesComboBox.Size = new System.Drawing.Size(373, 24); + customFishingFilesComboBox.TabIndex = 11; + customFishingFilesComboBox.Visible = false; + // + // randomFishingCheckBox + // + randomFishingCheckBox.AutoSize = true; + randomFishingCheckBox.Location = new System.Drawing.Point(194, 96); + randomFishingCheckBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + randomFishingCheckBox.Name = "randomFishingCheckBox"; + randomFishingCheckBox.Size = new System.Drawing.Size(135, 20); + randomFishingCheckBox.TabIndex = 11; + randomFishingCheckBox.Text = "Random Variance"; + toolTip1.SetToolTip(randomFishingCheckBox, "This add some randomness and will make it so you \r\nwon't cast your line at the same spot every time!"); + randomFishingCheckBox.UseVisualStyleBackColor = true; + randomFishingCheckBox.CheckedChanged += randomFishing_CheckedChanged; // // smartFishing // @@ -349,7 +395,7 @@ private void InitializeComponent() // // startFishing // - startFishing.Location = new System.Drawing.Point(7, 144); + startFishing.Location = new System.Drawing.Point(6, 183); startFishing.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); startFishing.Name = "startFishing"; startFishing.Size = new System.Drawing.Size(184, 38); @@ -358,16 +404,17 @@ private void InitializeComponent() startFishing.UseVisualStyleBackColor = true; startFishing.Click += startFishing_Click; // - // comboBox3 + // fishingLocationscomboBox // - comboBox3.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - comboBox3.Items.AddRange(new object[] { "TOONTOWN CENTRAL PUNCHLINE PLACE", "DONALD DREAM LAND LULLABY LANE", "BRRRGH POLAR PLACE", "BRRRGH WALRUS WAY", "BRRRGH SLEET STREET", "MINNIE'S MELODYLAND TENOR TERRACE", "DONALD DOCK LIGHTHOUSE LANE", "DAISY'S GARDEN ELM STREET", "FISH ANYWHERE" }); - comboBox3.Location = new System.Drawing.Point(7, 24); - comboBox3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - comboBox3.Name = "comboBox3"; - comboBox3.Size = new System.Drawing.Size(370, 24); - comboBox3.TabIndex = 1; - toolTip1.SetToolTip(comboBox3, "Select the location you wish to fish at"); + fishingLocationscomboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + fishingLocationscomboBox.Items.AddRange(new object[] { "TOONTOWN CENTRAL PUNCHLINE PLACE", "DONALD DREAM LAND LULLABY LANE", "BRRRGH POLAR PLACE", "BRRRGH WALRUS WAY", "BRRRGH SLEET STREET", "MINNIE'S MELODYLAND TENOR TERRACE", "DONALD DOCK LIGHTHOUSE LANE", "DAISY'S GARDEN ELM STREET", "FISH ANYWHERE", "CUSTOM FISHING ACTION" }); + fishingLocationscomboBox.Location = new System.Drawing.Point(7, 24); + fishingLocationscomboBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + fishingLocationscomboBox.Name = "fishingLocationscomboBox"; + fishingLocationscomboBox.Size = new System.Drawing.Size(370, 24); + fishingLocationscomboBox.TabIndex = 1; + toolTip1.SetToolTip(fishingLocationscomboBox, "Select the location you wish to fish at"); + fishingLocationscomboBox.SelectedIndexChanged += fishingLocationscomboBox_SelectedIndexChanged; // // Racing // @@ -430,8 +477,8 @@ private void InitializeComponent() // // groupBox5 // - groupBox5.Controls.Add(button3); - groupBox5.Location = new System.Drawing.Point(9, 197); + groupBox5.Controls.Add(removePlantBtn); + groupBox5.Location = new System.Drawing.Point(9, 198); groupBox5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox5.Name = "groupBox5"; groupBox5.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); @@ -440,44 +487,54 @@ private void InitializeComponent() groupBox5.TabStop = false; groupBox5.Text = "Remove Plant"; // - // button3 + // removePlantBtn // - button3.Location = new System.Drawing.Point(34, 24); - button3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button3.Name = "button3"; - button3.Size = new System.Drawing.Size(115, 42); - button3.TabIndex = 0; - button3.Text = "Remove"; - button3.UseVisualStyleBackColor = true; - button3.Click += button3_Click; + removePlantBtn.Location = new System.Drawing.Point(34, 24); + removePlantBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + removePlantBtn.Name = "removePlantBtn"; + removePlantBtn.Size = new System.Drawing.Size(115, 42); + removePlantBtn.TabIndex = 0; + removePlantBtn.Text = "Remove"; + removePlantBtn.UseVisualStyleBackColor = true; + removePlantBtn.Click += removePlantBtn_Click; // // groupBox4 // - groupBox4.Controls.Add(button2); + groupBox4.Controls.Add(waterPlantNumericUpDown); + groupBox4.Controls.Add(waterPlantBtn); groupBox4.Location = new System.Drawing.Point(9, 113); groupBox4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox4.Name = "groupBox4"; groupBox4.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - groupBox4.Size = new System.Drawing.Size(195, 77); + groupBox4.Size = new System.Drawing.Size(195, 79); groupBox4.TabIndex = 4; groupBox4.TabStop = false; groupBox4.Text = "Water Plant"; // - // button2 + // waterPlantNumericUpDown // - button2.Location = new System.Drawing.Point(34, 24); - button2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button2.Name = "button2"; - button2.Size = new System.Drawing.Size(115, 42); - button2.TabIndex = 0; - button2.Text = "Water"; - button2.UseVisualStyleBackColor = true; - button2.Click += button2_Click; + waterPlantNumericUpDown.Location = new System.Drawing.Point(20, 32); + waterPlantNumericUpDown.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); + waterPlantNumericUpDown.Name = "waterPlantNumericUpDown"; + waterPlantNumericUpDown.Size = new System.Drawing.Size(44, 22); + waterPlantNumericUpDown.TabIndex = 1; + waterPlantNumericUpDown.Value = new decimal(new int[] { 2, 0, 0, 0 }); + // + // waterPlantBtn + // + waterPlantBtn.Location = new System.Drawing.Point(71, 21); + waterPlantBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + waterPlantBtn.Name = "waterPlantBtn"; + waterPlantBtn.Size = new System.Drawing.Size(115, 42); + waterPlantBtn.TabIndex = 0; + waterPlantBtn.Text = "Water"; + waterPlantBtn.UseVisualStyleBackColor = true; + waterPlantBtn.Click += waterPlantBtn_Click; // // groupBox3 // - groupBox3.Controls.Add(comboBox2); - groupBox3.Controls.Add(button1); + groupBox3.Controls.Add(flowerBeanAmountDropdown); + groupBox3.Controls.Add(selectFlowerBeanAmountBtn); groupBox3.Location = new System.Drawing.Point(9, 3); groupBox3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox3.Name = "groupBox3"; @@ -487,33 +544,31 @@ private void InitializeComponent() groupBox3.TabStop = false; groupBox3.Text = "Plant Flower"; // - // comboBox2 + // flowerBeanAmountDropdown // - comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - comboBox2.Items.AddRange(new object[] { "1 Bean Plant", "2 Bean Plant", "3 Bean Plant", "4 Bean Plant", "5 Bean Plant", "6 Bean Plant", "7 Bean Plant", "8 Bean Plant" }); - comboBox2.Location = new System.Drawing.Point(20, 24); - comboBox2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - comboBox2.Name = "comboBox2"; - comboBox2.Size = new System.Drawing.Size(140, 24); - comboBox2.TabIndex = 0; + flowerBeanAmountDropdown.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + flowerBeanAmountDropdown.Items.AddRange(new object[] { "1 Bean Plant", "2 Bean Plant", "3 Bean Plant", "4 Bean Plant", "5 Bean Plant", "6 Bean Plant", "7 Bean Plant", "8 Bean Plant" }); + flowerBeanAmountDropdown.Location = new System.Drawing.Point(20, 24); + flowerBeanAmountDropdown.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + flowerBeanAmountDropdown.Name = "flowerBeanAmountDropdown"; + flowerBeanAmountDropdown.Size = new System.Drawing.Size(140, 24); + flowerBeanAmountDropdown.TabIndex = 0; // - // button1 + // selectFlowerBeanAmountBtn // - button1.Location = new System.Drawing.Point(34, 59); - button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button1.Name = "button1"; - button1.Size = new System.Drawing.Size(115, 29); - button1.TabIndex = 1; - button1.Text = "Select"; - button1.UseVisualStyleBackColor = true; - button1.Click += button1_Click; + selectFlowerBeanAmountBtn.Location = new System.Drawing.Point(34, 59); + selectFlowerBeanAmountBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + selectFlowerBeanAmountBtn.Name = "selectFlowerBeanAmountBtn"; + selectFlowerBeanAmountBtn.Size = new System.Drawing.Size(115, 29); + selectFlowerBeanAmountBtn.TabIndex = 1; + selectFlowerBeanAmountBtn.Text = "Select"; + selectFlowerBeanAmountBtn.UseVisualStyleBackColor = true; + selectFlowerBeanAmountBtn.Click += selectFlowerBeanAmountBtn_Click; // // Golf // - Golf.Controls.Add(golfNoteLbl); - Golf.Controls.Add(label2); - Golf.Controls.Add(Near_Hole); - Golf.Controls.Add(Hole_In_One); + Golf.Controls.Add(groupBox10); + Golf.Controls.Add(createCustomGolfActionsBtn); Golf.Location = new System.Drawing.Point(4, 25); Golf.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); Golf.Name = "Golf"; @@ -523,184 +578,58 @@ private void InitializeComponent() Golf.Text = "Golf"; Golf.UseVisualStyleBackColor = true; // - // label2 - // - label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); - label2.Location = new System.Drawing.Point(7, 10); - label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - label2.Name = "label2"; - label2.Size = new System.Drawing.Size(317, 37); - label2.TabIndex = 16; - label2.Text = "Walk In The Par - Easy"; - label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // Near_Hole - // - Near_Hole.Controls.Add(One_Little_Birdie); - Near_Hole.Controls.Add(button14); - Near_Hole.Controls.Add(button18); - Near_Hole.Controls.Add(button15); - Near_Hole.Controls.Add(button13); - Near_Hole.Controls.Add(button16); - Near_Hole.Location = new System.Drawing.Point(7, 186); - Near_Hole.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - Near_Hole.Name = "Near_Hole"; - Near_Hole.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - Near_Hole.Size = new System.Drawing.Size(350, 128); - Near_Hole.TabIndex = 15; - Near_Hole.TabStop = false; - Near_Hole.Text = "Near Hole"; - toolTip1.SetToolTip(Near_Hole, "On these courses, you will get near the hole, then you need to shoot the ball in yourself afterwards."); - // - // One_Little_Birdie - // - One_Little_Birdie.BackColor = System.Drawing.Color.Yellow; - One_Little_Birdie.Location = new System.Drawing.Point(174, 91); - One_Little_Birdie.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - One_Little_Birdie.Name = "One_Little_Birdie"; - One_Little_Birdie.Size = new System.Drawing.Size(160, 27); - One_Little_Birdie.TabIndex = 14; - One_Little_Birdie.Text = "One Little Birdie"; - One_Little_Birdie.UseVisualStyleBackColor = false; - One_Little_Birdie.Click += One_Little_Birdie_Click; - // - // button14 - // - button14.BackColor = System.Drawing.Color.Yellow; - button14.Location = new System.Drawing.Point(7, 24); - button14.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button14.Name = "button14"; - button14.Size = new System.Drawing.Size(160, 27); - button14.TabIndex = 10; - button14.Text = "Down the Hatch"; - button14.UseVisualStyleBackColor = false; - button14.Click += button14_Click; - // - // button18 - // - button18.BackColor = System.Drawing.Color.Yellow; - button18.Location = new System.Drawing.Point(174, 58); - button18.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button18.Name = "button18"; - button18.Size = new System.Drawing.Size(160, 27); - button18.TabIndex = 13; - button18.Text = "Swing-A-Long"; - button18.UseVisualStyleBackColor = false; - button18.Click += button18_Click; - // - // button15 - // - button15.BackColor = System.Drawing.Color.Yellow; - button15.Location = new System.Drawing.Point(7, 91); - button15.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button15.Name = "button15"; - button15.Size = new System.Drawing.Size(160, 27); - button15.TabIndex = 11; - button15.Text = "Swing Time"; - toolTip1.SetToolTip(button15, "You must select this course befoer the first timer runs out!"); - button15.UseVisualStyleBackColor = false; - button15.Click += button15_Click; - // - // button13 - // - button13.BackColor = System.Drawing.Color.Yellow; - button13.Location = new System.Drawing.Point(7, 58); - button13.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button13.Name = "button13"; - button13.Size = new System.Drawing.Size(160, 27); - button13.TabIndex = 9; - button13.Text = "Peanut Putter"; - button13.UseVisualStyleBackColor = false; - button13.Click += button13_Click; - // - // button16 - // - button16.BackColor = System.Drawing.Color.Yellow; - button16.Location = new System.Drawing.Point(174, 24); - button16.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button16.Name = "button16"; - button16.Size = new System.Drawing.Size(160, 27); - button16.TabIndex = 8; - button16.Text = "Hot Links"; - button16.UseVisualStyleBackColor = false; - button16.Click += button16_Click; - // - // Hole_In_One - // - Hole_In_One.Controls.Add(button12); - Hole_In_One.Controls.Add(button5); - Hole_In_One.Controls.Add(button17); - Hole_In_One.Controls.Add(button10); - Hole_In_One.Controls.Add(button11); - Hole_In_One.Location = new System.Drawing.Point(7, 51); - Hole_In_One.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - Hole_In_One.Name = "Hole_In_One"; - Hole_In_One.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - Hole_In_One.Size = new System.Drawing.Size(350, 128); - Hole_In_One.TabIndex = 14; - Hole_In_One.TabStop = false; - Hole_In_One.Text = "Hole In One"; - toolTip1.SetToolTip(Hole_In_One, "On these courses, you will get a hole in one."); - // - // button12 - // - button12.BackColor = System.Drawing.Color.LawnGreen; - button12.Location = new System.Drawing.Point(7, 24); - button12.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button12.Name = "button12"; - button12.Size = new System.Drawing.Size(160, 27); - button12.TabIndex = 4; - button12.Text = "Afternoon Tee"; - button12.UseVisualStyleBackColor = false; - button12.Click += golfAfternoonTee; - // - // button5 - // - button5.BackColor = System.Drawing.Color.LawnGreen; - button5.Location = new System.Drawing.Point(7, 58); - button5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button5.Name = "button5"; - button5.Size = new System.Drawing.Size(160, 27); - button5.TabIndex = 5; - button5.Text = "Holey Mackeral"; - button5.UseVisualStyleBackColor = false; - button5.Click += golfHoleyMackeral; - // - // button17 - // - button17.BackColor = System.Drawing.Color.LawnGreen; - button17.Location = new System.Drawing.Point(174, 58); - button17.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button17.Name = "button17"; - button17.Size = new System.Drawing.Size(160, 27); - button17.TabIndex = 12; - button17.Text = "Hole In Fun"; - button17.UseVisualStyleBackColor = false; - button17.Click += button17_Click; - // - // button10 - // - button10.BackColor = System.Drawing.Color.LawnGreen; - button10.Location = new System.Drawing.Point(7, 91); - button10.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button10.Name = "button10"; - button10.Size = new System.Drawing.Size(160, 27); - button10.TabIndex = 6; - button10.Text = "Hole on the Range"; - button10.UseVisualStyleBackColor = false; - button10.Click += golfHoleOnTheRange; - // - // button11 - // - button11.BackColor = System.Drawing.Color.LawnGreen; - button11.Location = new System.Drawing.Point(174, 24); - button11.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button11.Name = "button11"; - button11.Size = new System.Drawing.Size(160, 27); - button11.TabIndex = 7; - button11.Text = "Seeing Green"; - button11.UseVisualStyleBackColor = false; - button11.Click += golfSeeingGreen; + // groupBox10 + // + groupBox10.Controls.Add(golfActionsListBox); + groupBox10.Controls.Add(customGolfFilesComboBox); + groupBox10.Controls.Add(button1); + groupBox10.Location = new System.Drawing.Point(7, 6); + groupBox10.Name = "groupBox10"; + groupBox10.Size = new System.Drawing.Size(354, 314); + groupBox10.TabIndex = 21; + groupBox10.TabStop = false; + groupBox10.Text = "Golf Actions"; + // + // golfActionsListBox + // + golfActionsListBox.FormattingEnabled = true; + golfActionsListBox.ItemHeight = 16; + golfActionsListBox.Location = new System.Drawing.Point(6, 59); + golfActionsListBox.Name = "golfActionsListBox"; + golfActionsListBox.Size = new System.Drawing.Size(342, 196); + golfActionsListBox.TabIndex = 21; + // + // customGolfFilesComboBox + // + customGolfFilesComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + customGolfFilesComboBox.FormattingEnabled = true; + customGolfFilesComboBox.Location = new System.Drawing.Point(6, 21); + customGolfFilesComboBox.Name = "customGolfFilesComboBox"; + customGolfFilesComboBox.Size = new System.Drawing.Size(342, 24); + customGolfFilesComboBox.Sorted = true; + customGolfFilesComboBox.TabIndex = 19; + customGolfFilesComboBox.SelectedIndexChanged += customGolfFilesComboBox_SelectedIndexChanged; + // + // button1 + // + button1.Location = new System.Drawing.Point(117, 269); + button1.Name = "button1"; + button1.Size = new System.Drawing.Size(126, 39); + button1.TabIndex = 20; + button1.Text = "Start Golf"; + button1.UseVisualStyleBackColor = true; + button1.Click += button1_Click; + // + // createCustomGolfActionsBtn + // + createCustomGolfActionsBtn.Location = new System.Drawing.Point(392, 10); + createCustomGolfActionsBtn.Name = "createCustomGolfActionsBtn"; + createCustomGolfActionsBtn.Size = new System.Drawing.Size(126, 41); + createCustomGolfActionsBtn.TabIndex = 18; + createCustomGolfActionsBtn.Text = "Create Custom Golf Actions"; + toolTip1.SetToolTip(createCustomGolfActionsBtn, "This will allow you to build custom golf actions\r\nfor golfing any course"); + createCustomGolfActionsBtn.UseVisualStyleBackColor = true; + createCustomGolfActionsBtn.Click += createCustomGolfActionsBtn_Click; // // Doodles // @@ -726,17 +655,17 @@ private void InitializeComponent() // // groupBox8 // - groupBox8.Controls.Add(checkBox5); - groupBox8.Controls.Add(checkBox4); - groupBox8.Controls.Add(comboBox4); + groupBox8.Controls.Add(justScratchDoodleCheckBox); + groupBox8.Controls.Add(justFeedDoodleCheckBox); + groupBox8.Controls.Add(doodleTrickComboBox); groupBox8.Controls.Add(pictureBox2); - groupBox8.Controls.Add(checkBox3); - groupBox8.Controls.Add(button19); + groupBox8.Controls.Add(unlimitedTrainingCheckBox); + groupBox8.Controls.Add(stopDoodleTrainingBtn); groupBox8.Controls.Add(label9); - groupBox8.Controls.Add(numericUpDown5); + groupBox8.Controls.Add(numberOfDoodleScratchesNumericUpDown); groupBox8.Controls.Add(label10); - groupBox8.Controls.Add(numericUpDown6); - groupBox8.Controls.Add(button20); + groupBox8.Controls.Add(numberOfDoodleFeedsNumericUpDown); + groupBox8.Controls.Add(startDoodleTrainingBtn); groupBox8.Location = new System.Drawing.Point(9, 3); groupBox8.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox8.Name = "groupBox8"; @@ -746,42 +675,42 @@ private void InitializeComponent() groupBox8.TabStop = false; groupBox8.Text = "Doodle Training"; // - // checkBox5 - // - checkBox5.AutoSize = true; - checkBox5.Location = new System.Drawing.Point(10, 192); - checkBox5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - checkBox5.Name = "checkBox5"; - checkBox5.Size = new System.Drawing.Size(146, 20); - checkBox5.TabIndex = 15; - checkBox5.Text = "Just Scratch Doodle"; - toolTip1.SetToolTip(checkBox5, "Select this if you only want to train using scratching"); - checkBox5.UseVisualStyleBackColor = true; - checkBox5.CheckedChanged += checkBox5_CheckedChanged; - // - // checkBox4 - // - checkBox4.AutoSize = true; - checkBox4.Location = new System.Drawing.Point(10, 162); - checkBox4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - checkBox4.Name = "checkBox4"; - checkBox4.Size = new System.Drawing.Size(133, 20); - checkBox4.TabIndex = 14; - checkBox4.Text = "Just Feed Doodle"; - toolTip1.SetToolTip(checkBox4, "Select this if you only want to train using feeding"); - checkBox4.UseVisualStyleBackColor = true; - checkBox4.CheckedChanged += checkBox4_CheckedChanged; - // - // comboBox4 - // - comboBox4.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - comboBox4.Items.AddRange(new object[] { "Jump (5 - 10 laff)", "Beg (6 - 12 laff)", "Play Dead (7 - 14 laff)", "Rollover (8 - 16 laff)", "Backflip (9 - 18 laff)", "Dance (10 - 20 laff)", "Speak (11 - 22 laff)" }); - comboBox4.Location = new System.Drawing.Point(10, 24); - comboBox4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - comboBox4.Name = "comboBox4"; - comboBox4.Size = new System.Drawing.Size(199, 24); - comboBox4.TabIndex = 11; - toolTip1.SetToolTip(comboBox4, "Select the trick you wish to train."); + // justScratchDoodleCheckBox + // + justScratchDoodleCheckBox.AutoSize = true; + justScratchDoodleCheckBox.Location = new System.Drawing.Point(10, 192); + justScratchDoodleCheckBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + justScratchDoodleCheckBox.Name = "justScratchDoodleCheckBox"; + justScratchDoodleCheckBox.Size = new System.Drawing.Size(146, 20); + justScratchDoodleCheckBox.TabIndex = 15; + justScratchDoodleCheckBox.Text = "Just Scratch Doodle"; + toolTip1.SetToolTip(justScratchDoodleCheckBox, "Select this if you only want to train using scratching"); + justScratchDoodleCheckBox.UseVisualStyleBackColor = true; + justScratchDoodleCheckBox.CheckedChanged += justScratchDoodleCheckBox_CheckedChanged; + // + // justFeedDoodleCheckBox + // + justFeedDoodleCheckBox.AutoSize = true; + justFeedDoodleCheckBox.Location = new System.Drawing.Point(10, 162); + justFeedDoodleCheckBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + justFeedDoodleCheckBox.Name = "justFeedDoodleCheckBox"; + justFeedDoodleCheckBox.Size = new System.Drawing.Size(133, 20); + justFeedDoodleCheckBox.TabIndex = 14; + justFeedDoodleCheckBox.Text = "Just Feed Doodle"; + toolTip1.SetToolTip(justFeedDoodleCheckBox, "Select this if you only want to train using feeding"); + justFeedDoodleCheckBox.UseVisualStyleBackColor = true; + justFeedDoodleCheckBox.CheckedChanged += justFeedDoodleCheckBox_CheckedChanged; + // + // doodleTrickComboBox + // + doodleTrickComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + doodleTrickComboBox.Items.AddRange(new object[] { "None", "Jump (5 - 10 laff)", "Beg (6 - 12 laff)", "Play Dead (7 - 14 laff)", "Rollover (8 - 16 laff)", "Backflip (9 - 18 laff)", "Dance (10 - 20 laff)", "Speak (11 - 22 laff)" }); + doodleTrickComboBox.Location = new System.Drawing.Point(10, 24); + doodleTrickComboBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + doodleTrickComboBox.Name = "doodleTrickComboBox"; + doodleTrickComboBox.Size = new System.Drawing.Size(199, 24); + doodleTrickComboBox.TabIndex = 11; + toolTip1.SetToolTip(doodleTrickComboBox, "Select the trick you wish to train."); // // pictureBox2 // @@ -794,29 +723,29 @@ private void InitializeComponent() pictureBox2.TabIndex = 10; pictureBox2.TabStop = false; // - // checkBox3 - // - checkBox3.AutoSize = true; - checkBox3.Location = new System.Drawing.Point(10, 132); - checkBox3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - checkBox3.Name = "checkBox3"; - checkBox3.Size = new System.Drawing.Size(194, 20); - checkBox3.TabIndex = 13; - checkBox3.Text = "Train until I click stop training"; - toolTip1.SetToolTip(checkBox3, "Has no feed or scratch limit, it will go forever until you click the stop training button."); - checkBox3.UseVisualStyleBackColor = true; - checkBox3.CheckedChanged += checkBox3_CheckedChanged; - // - // button19 - // - button19.Location = new System.Drawing.Point(194, 222); - button19.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button19.Name = "button19"; - button19.Size = new System.Drawing.Size(184, 38); - button19.TabIndex = 12; - button19.Text = "Stop Training"; - button19.UseVisualStyleBackColor = true; - button19.Click += button19_Click; + // unlimitedTrainingCheckBox + // + unlimitedTrainingCheckBox.AutoSize = true; + unlimitedTrainingCheckBox.Location = new System.Drawing.Point(10, 132); + unlimitedTrainingCheckBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + unlimitedTrainingCheckBox.Name = "unlimitedTrainingCheckBox"; + unlimitedTrainingCheckBox.Size = new System.Drawing.Size(194, 20); + unlimitedTrainingCheckBox.TabIndex = 13; + unlimitedTrainingCheckBox.Text = "Train until I click stop training"; + toolTip1.SetToolTip(unlimitedTrainingCheckBox, "Has no feed or scratch limit, it will go forever until you click the stop training button."); + unlimitedTrainingCheckBox.UseVisualStyleBackColor = true; + unlimitedTrainingCheckBox.CheckedChanged += unlimitedTrainingCheckBox_CheckedChanged; + // + // stopDoodleTrainingBtn + // + stopDoodleTrainingBtn.Location = new System.Drawing.Point(194, 222); + stopDoodleTrainingBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + stopDoodleTrainingBtn.Name = "stopDoodleTrainingBtn"; + stopDoodleTrainingBtn.Size = new System.Drawing.Size(184, 38); + stopDoodleTrainingBtn.TabIndex = 12; + stopDoodleTrainingBtn.Text = "Stop Training"; + stopDoodleTrainingBtn.UseVisualStyleBackColor = true; + stopDoodleTrainingBtn.Click += stopDoodleTrainingBtn_Click; // // label9 // @@ -828,17 +757,17 @@ private void InitializeComponent() label9.TabIndex = 9; label9.Text = "Number of Scratches:"; // - // numericUpDown5 + // numberOfDoodleScratchesNumericUpDown // - numericUpDown5.Location = new System.Drawing.Point(173, 99); - numericUpDown5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - numericUpDown5.Maximum = new decimal(new int[] { 900, 0, 0, 0 }); - numericUpDown5.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); - numericUpDown5.Name = "numericUpDown5"; - numericUpDown5.Size = new System.Drawing.Size(48, 22); - numericUpDown5.TabIndex = 8; - toolTip1.SetToolTip(numericUpDown5, "This number indicates the number of times to go to the fisherman to sell the fish"); - numericUpDown5.Value = new decimal(new int[] { 1, 0, 0, 0 }); + numberOfDoodleScratchesNumericUpDown.Location = new System.Drawing.Point(173, 99); + numberOfDoodleScratchesNumericUpDown.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + numberOfDoodleScratchesNumericUpDown.Maximum = new decimal(new int[] { 900, 0, 0, 0 }); + numberOfDoodleScratchesNumericUpDown.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); + numberOfDoodleScratchesNumericUpDown.Name = "numberOfDoodleScratchesNumericUpDown"; + numberOfDoodleScratchesNumericUpDown.Size = new System.Drawing.Size(48, 22); + numberOfDoodleScratchesNumericUpDown.TabIndex = 8; + toolTip1.SetToolTip(numberOfDoodleScratchesNumericUpDown, "This number indicates the number of times to go to the fisherman to sell the fish"); + numberOfDoodleScratchesNumericUpDown.Value = new decimal(new int[] { 1, 0, 0, 0 }); // // label10 // @@ -850,35 +779,35 @@ private void InitializeComponent() label10.TabIndex = 7; label10.Text = "Number of Feeds:"; // - // numericUpDown6 - // - numericUpDown6.Location = new System.Drawing.Point(148, 67); - numericUpDown6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - numericUpDown6.Maximum = new decimal(new int[] { 900, 0, 0, 0 }); - numericUpDown6.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); - numericUpDown6.Name = "numericUpDown6"; - numericUpDown6.Size = new System.Drawing.Size(48, 22); - numericUpDown6.TabIndex = 6; - toolTip1.SetToolTip(numericUpDown6, "This number indicates the number of times to cast your fishing rod"); - numericUpDown6.Value = new decimal(new int[] { 1, 0, 0, 0 }); - // - // button20 - // - button20.Location = new System.Drawing.Point(7, 222); - button20.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - button20.Name = "button20"; - button20.Size = new System.Drawing.Size(184, 38); - button20.TabIndex = 2; - button20.Text = "Start Training"; - button20.UseVisualStyleBackColor = true; - button20.Click += button20_Click; + // numberOfDoodleFeedsNumericUpDown + // + numberOfDoodleFeedsNumericUpDown.Location = new System.Drawing.Point(148, 67); + numberOfDoodleFeedsNumericUpDown.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + numberOfDoodleFeedsNumericUpDown.Maximum = new decimal(new int[] { 900, 0, 0, 0 }); + numberOfDoodleFeedsNumericUpDown.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); + numberOfDoodleFeedsNumericUpDown.Name = "numberOfDoodleFeedsNumericUpDown"; + numberOfDoodleFeedsNumericUpDown.Size = new System.Drawing.Size(48, 22); + numberOfDoodleFeedsNumericUpDown.TabIndex = 6; + toolTip1.SetToolTip(numberOfDoodleFeedsNumericUpDown, "This number indicates the number of times to cast your fishing rod"); + numberOfDoodleFeedsNumericUpDown.Value = new decimal(new int[] { 1, 0, 0, 0 }); + // + // startDoodleTrainingBtn + // + startDoodleTrainingBtn.Location = new System.Drawing.Point(7, 222); + startDoodleTrainingBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + startDoodleTrainingBtn.Name = "startDoodleTrainingBtn"; + startDoodleTrainingBtn.Size = new System.Drawing.Size(184, 38); + startDoodleTrainingBtn.TabIndex = 2; + startDoodleTrainingBtn.Text = "Start Training"; + startDoodleTrainingBtn.UseVisualStyleBackColor = true; + startDoodleTrainingBtn.Click += startDoodleTrainingBtn_Click; // // Misc // Misc.Controls.Add(checkBox2); Misc.Controls.Add(groupBox2); Misc.Controls.Add(groupBox1); - Misc.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + Misc.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F); Misc.Location = new System.Drawing.Point(4, 25); Misc.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); Misc.Name = "Misc"; @@ -901,9 +830,10 @@ private void InitializeComponent() // // groupBox2 // + groupBox2.Controls.Add(stopKeepToonAwakeButton); groupBox2.Controls.Add(label1); groupBox2.Controls.Add(numericUpDown1); - groupBox2.Controls.Add(keepToonAwakeButton); + groupBox2.Controls.Add(startKeepToonAwakeButton); groupBox2.Location = new System.Drawing.Point(9, 137); groupBox2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox2.Name = "groupBox2"; @@ -913,6 +843,18 @@ private void InitializeComponent() groupBox2.TabStop = false; groupBox2.Text = "Keep Toon Awake"; // + // stopKeepToonAwakeButton + // + stopKeepToonAwakeButton.AccessibleRole = System.Windows.Forms.AccessibleRole.None; + stopKeepToonAwakeButton.Location = new System.Drawing.Point(114, 58); + stopKeepToonAwakeButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + stopKeepToonAwakeButton.Name = "stopKeepToonAwakeButton"; + stopKeepToonAwakeButton.Size = new System.Drawing.Size(88, 39); + stopKeepToonAwakeButton.TabIndex = 7; + stopKeepToonAwakeButton.Text = "Stop"; + stopKeepToonAwakeButton.UseVisualStyleBackColor = true; + stopKeepToonAwakeButton.Click += stopKeepToonAwakeButton_Click; + // // label1 // label1.AutoSize = true; @@ -935,18 +877,18 @@ private void InitializeComponent() toolTip1.SetToolTip(numericUpDown1, "How many minutes do you wish to keep your toon awake for?"); numericUpDown1.Value = new decimal(new int[] { 1, 0, 0, 0 }); // - // keepToonAwakeButton + // startKeepToonAwakeButton // - keepToonAwakeButton.AccessibleRole = System.Windows.Forms.AccessibleRole.None; - keepToonAwakeButton.Location = new System.Drawing.Point(18, 58); - keepToonAwakeButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - keepToonAwakeButton.Name = "keepToonAwakeButton"; - keepToonAwakeButton.Size = new System.Drawing.Size(141, 39); - keepToonAwakeButton.TabIndex = 3; - keepToonAwakeButton.Text = "Start Stay Awake"; - toolTip1.SetToolTip(keepToonAwakeButton, "Press the ALT key to stop the jumping loop at any time!"); - keepToonAwakeButton.UseVisualStyleBackColor = true; - keepToonAwakeButton.Click += keepToonAwakeButton_Click; + startKeepToonAwakeButton.AccessibleRole = System.Windows.Forms.AccessibleRole.None; + startKeepToonAwakeButton.Location = new System.Drawing.Point(18, 58); + startKeepToonAwakeButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + startKeepToonAwakeButton.Name = "startKeepToonAwakeButton"; + startKeepToonAwakeButton.Size = new System.Drawing.Size(88, 39); + startKeepToonAwakeButton.TabIndex = 3; + startKeepToonAwakeButton.Text = "Start"; + toolTip1.SetToolTip(startKeepToonAwakeButton, "Press the ALT key to stop the jumping loop at any time!"); + startKeepToonAwakeButton.UseVisualStyleBackColor = true; + startKeepToonAwakeButton.Click += startKeepToonAwakeButton_Click; // // groupBox1 // @@ -994,7 +936,7 @@ private void InitializeComponent() messageToType.Name = "messageToType"; messageToType.Size = new System.Drawing.Size(181, 22); messageToType.TabIndex = 2; - toolTip1.SetToolTip(messageToType, "Enter the message to send"); + toolTip1.SetToolTip(messageToType, "Enter the message to Send"); // // startSpamButton // @@ -1039,7 +981,7 @@ private void InitializeComponent() // label11 // label11.AutoSize = true; - label11.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + label11.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F); label11.Location = new System.Drawing.Point(36, 21); label11.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label11.Name = "label11"; @@ -1073,7 +1015,7 @@ private void InitializeComponent() // label5 // label5.AutoSize = true; - label5.Location = new System.Drawing.Point(6, 163); + label5.Location = new System.Drawing.Point(9, 162); label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label5.Name = "label5"; label5.Size = new System.Drawing.Size(282, 32); @@ -1082,6 +1024,7 @@ private void InitializeComponent() // // groupBox7 // + groupBox7.Controls.Add(button2); groupBox7.Controls.Add(button6); groupBox7.Controls.Add(comboBox1); groupBox7.Controls.Add(button7); @@ -1094,6 +1037,18 @@ private void InitializeComponent() groupBox7.TabStop = false; groupBox7.Text = "Coordinates"; // + // button2 + // + button2.Location = new System.Drawing.Point(143, 104); + button2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + button2.Name = "button2"; + button2.Size = new System.Drawing.Size(123, 38); + button2.TabIndex = 3; + button2.Text = "Open File"; + toolTip1.SetToolTip(button2, "This will reset all of your coordinates!"); + button2.UseVisualStyleBackColor = true; + button2.Click += button2_Click; + // // button6 // button6.Location = new System.Drawing.Point(56, 59); @@ -1117,10 +1072,10 @@ private void InitializeComponent() // // button7 // - button7.Location = new System.Drawing.Point(56, 104); + button7.Location = new System.Drawing.Point(12, 104); button7.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); button7.Name = "button7"; - button7.Size = new System.Drawing.Size(163, 38); + button7.Size = new System.Drawing.Size(123, 38); button7.TabIndex = 0; button7.Text = "Reset All"; toolTip1.SetToolTip(button7, "This will reset all of your coordinates!"); @@ -1137,15 +1092,7 @@ private void InitializeComponent() timer1.Interval = 1000; timer1.Tick += timer1_Tick; // - // golfNoteLbl - // - golfNoteLbl.Location = new System.Drawing.Point(364, 3); - golfNoteLbl.Name = "golfNoteLbl"; - golfNoteLbl.Size = new System.Drawing.Size(182, 134); - golfNoteLbl.TabIndex = 17; - golfNoteLbl.Text = "Do not click a button until after the changing tee spot.\r\nClick a button once it gives you the option to press control to swing"; - // - // Form1 + // MainForm // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; @@ -1153,13 +1100,14 @@ private void InitializeComponent() Controls.Add(tabControl1); Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - Name = "Form1"; + Name = "MainForm"; Text = "Toontown Rewritten Bot by primetime43"; tabControl1.ResumeLayout(false); Main.ResumeLayout(false); Main.PerformLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); Fishing.ResumeLayout(false); + Fishing.PerformLayout(); groupBox6.ResumeLayout(false); groupBox6.PerformLayout(); ((System.ComponentModel.ISupportInitialize)numericUpDown4).EndInit(); @@ -1169,16 +1117,16 @@ private void InitializeComponent() Gardening.ResumeLayout(false); groupBox5.ResumeLayout(false); groupBox4.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)waterPlantNumericUpDown).EndInit(); groupBox3.ResumeLayout(false); Golf.ResumeLayout(false); - Near_Hole.ResumeLayout(false); - Hole_In_One.ResumeLayout(false); + groupBox10.ResumeLayout(false); Doodles.ResumeLayout(false); groupBox8.ResumeLayout(false); groupBox8.PerformLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox2).EndInit(); - ((System.ComponentModel.ISupportInitialize)numericUpDown5).EndInit(); - ((System.ComponentModel.ISupportInitialize)numericUpDown6).EndInit(); + ((System.ComponentModel.ISupportInitialize)numberOfDoodleScratchesNumericUpDown).EndInit(); + ((System.ComponentModel.ISupportInitialize)numberOfDoodleFeedsNumericUpDown).EndInit(); Misc.ResumeLayout(false); Misc.PerformLayout(); groupBox2.ResumeLayout(false); @@ -1207,18 +1155,18 @@ private void InitializeComponent() private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.ToolTip toolTip1; private System.Windows.Forms.CheckBox checkBox2; - private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button selectFlowerBeanAmountBtn; private System.Windows.Forms.GroupBox groupBox3; - private System.Windows.Forms.ComboBox comboBox2; + private System.Windows.Forms.ComboBox flowerBeanAmountDropdown; public System.Windows.Forms.NumericUpDown numericUpDown1; - public System.Windows.Forms.Button keepToonAwakeButton; + public System.Windows.Forms.Button startKeepToonAwakeButton; private System.Windows.Forms.TextBox messageToType; private System.Windows.Forms.NumericUpDown numericUpDown2; private System.Windows.Forms.CheckBox checkBox1; private System.Windows.Forms.GroupBox groupBox5; - private System.Windows.Forms.Button button3; + private System.Windows.Forms.Button removePlantBtn; private System.Windows.Forms.GroupBox groupBox4; - private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button waterPlantBtn; private System.Windows.Forms.Label label1; private System.Windows.Forms.Timer timer1; private System.Windows.Forms.TabPage Dev; @@ -1228,7 +1176,7 @@ private void InitializeComponent() private System.Windows.Forms.Button button7; private System.Windows.Forms.GroupBox groupBox6; private System.Windows.Forms.Button startFishing; - private System.Windows.Forms.ComboBox comboBox3; + private System.Windows.Forms.ComboBox fishingLocationscomboBox; private System.Windows.Forms.Label label4; private System.Windows.Forms.NumericUpDown numericUpDown4; private System.Windows.Forms.Label label3; @@ -1241,44 +1189,41 @@ private void InitializeComponent() private System.Windows.Forms.Label label7; private System.Windows.Forms.Button button8; private System.Windows.Forms.Button button9; - private System.Windows.Forms.CheckBox randomFishing; + private System.Windows.Forms.CheckBox randomFishingCheckBox; private System.Windows.Forms.Button button4; private System.Windows.Forms.TabPage Golf; - private System.Windows.Forms.Button button11; - private System.Windows.Forms.Button button10; - private System.Windows.Forms.Button button5; - private System.Windows.Forms.Button button12; - private System.Windows.Forms.Button button14; - private System.Windows.Forms.Button button13; - private System.Windows.Forms.Button button16; - private System.Windows.Forms.Button button15; - private System.Windows.Forms.Button button17; - private System.Windows.Forms.Button button18; - private System.Windows.Forms.GroupBox Near_Hole; - private System.Windows.Forms.GroupBox Hole_In_One; - private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label8; - private System.Windows.Forms.Button One_Little_Birdie; private System.Windows.Forms.TabPage Doodles; private System.Windows.Forms.GroupBox groupBox8; - private System.Windows.Forms.Button button19; + private System.Windows.Forms.Button stopDoodleTrainingBtn; private System.Windows.Forms.Label label9; - private System.Windows.Forms.NumericUpDown numericUpDown5; + private System.Windows.Forms.NumericUpDown numberOfDoodleScratchesNumericUpDown; private System.Windows.Forms.Label label10; - private System.Windows.Forms.NumericUpDown numericUpDown6; - private System.Windows.Forms.Button button20; - private System.Windows.Forms.CheckBox checkBox3; + private System.Windows.Forms.NumericUpDown numberOfDoodleFeedsNumericUpDown; + private System.Windows.Forms.Button startDoodleTrainingBtn; + private System.Windows.Forms.CheckBox unlimitedTrainingCheckBox; private System.Windows.Forms.PictureBox pictureBox2; - private System.Windows.Forms.ComboBox comboBox4; - private System.Windows.Forms.CheckBox checkBox5; - private System.Windows.Forms.CheckBox checkBox4; + private System.Windows.Forms.ComboBox doodleTrickComboBox; + private System.Windows.Forms.CheckBox justScratchDoodleCheckBox; + private System.Windows.Forms.CheckBox justFeedDoodleCheckBox; private System.Windows.Forms.RichTextBox richTextBox2; private System.Windows.Forms.GroupBox groupBox9; private System.Windows.Forms.Label label11; private System.Windows.Forms.Button updateImagesBtn; private System.Windows.Forms.Button resetImagesBtn; public System.Windows.Forms.CheckBox smartFishing; - private System.Windows.Forms.Label golfNoteLbl; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.Button createCustomFishingActionsBtn; + private System.Windows.Forms.ComboBox customFishingFilesComboBox; + private System.Windows.Forms.CheckBox debugCustomActionsCheckBox; + private System.Windows.Forms.NumericUpDown waterPlantNumericUpDown; + public System.Windows.Forms.Button stopKeepToonAwakeButton; + private System.Windows.Forms.Button createCustomGolfActionsBtn; + private System.Windows.Forms.ComboBox customGolfFilesComboBox; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.GroupBox groupBox10; + private System.Windows.Forms.ListBox golfActionsListBox; + private System.Windows.Forms.Button button2; } } diff --git a/ToonTown Rewritten Bot/Views/MainForm.cs b/ToonTown Rewritten Bot/Views/MainForm.cs new file mode 100644 index 00000000..2d6434e2 --- /dev/null +++ b/ToonTown Rewritten Bot/Views/MainForm.cs @@ -0,0 +1,698 @@ +using System; +using System.Configuration; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Models; +using ToonTown_Rewritten_Bot.Services; +using ToonTown_Rewritten_Bot.Utilities; +using ToonTown_Rewritten_Bot.Views; + +namespace ToonTown_Rewritten_Bot +{ + public partial class MainForm : Form + { + private CoordinatesManager _coordinatesManagerService = new CoordinatesManager(); + private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); + private FishingService _fishingService = new FishingService(); + public MainForm() + { + InitializeComponent(); + + // Check if a new version of the program is available + GithubReleaseChecker.CheckForNewVersion().ContinueWith(t => + { + if (t.IsFaulted) + { + MessageBox.Show("Error checking for updates: " + t.Exception.Flatten().InnerException.Message); + } + }, TaskScheduler.FromCurrentSynchronizationContext()); // Ensures the continuation runs on the UI thread + + CoreFunctionality.EnsureAllEmbeddedJsonFilesExist(); + + // Move this eventually + LoadCustomActions("Golf", customGolfFilesComboBox); + + CoordinatesManager.ReadCoordinates(); + BotFunctions.CreateItemsDataFileMap(); + LoadCoordinatesIntoResetBox(); + doodleTrickComboBox.SelectedIndex = 0; // clean this up/move this eventually + } + + //important functions for bot + private void startSpamButton_Click(object sender, EventArgs e)//spam message on screen + {//if the user presses ALT key, it will break the loop + bool loopBroken = BotFunctions.SendMessage(messageToType.Text, Convert.ToInt32(numericUpDown2.Value), checkBox1.Checked, numericUpDown2); + } + + private int timeLeft; + private bool isToonAwakeActive = false; // Flag to track if the function is active + private void startKeepToonAwakeButton_Click(object sender, EventArgs e) + { + if (_cancellationTokenSource != null) + { + _cancellationTokenSource.Dispose(); // Dispose any existing token source + } + _cancellationTokenSource = new CancellationTokenSource(); + isToonAwakeActive = true; // Flag to indicate the task is active + + int timeInSeconds = Convert.ToInt32(numericUpDown1.Value) * 60; // Convert minutes to seconds + timeLeft = timeInSeconds; // Set timeLeft for countdown + MessageBox.Show("Press OK when ready to begin!"); + + timer1.Start(); // Start the countdown timer + + Task.Run(() => + { + return BotFunctions.KeepToonAwake(timeInSeconds, _cancellationTokenSource.Token); + }, _cancellationTokenSource.Token) + .ContinueWith(task => + { + if (task.IsCompletedSuccessfully) + { + CoreFunctionality.BringBotWindowToFront(); + MessageBox.Show("Keep Toon Awake completed successfully!", "Keep Awake Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else if (task.IsFaulted) + { + timer1.Stop(); // Ensure timer is stopped on error + MessageBox.Show($"Error: {task.Exception.InnerException.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + }, TaskScheduler.FromCurrentSynchronizationContext()); // Ensure UI updates are on the main thread + } + + private void selectFlowerBeanAmountBtn_Click(object sender, EventArgs e)//open the flower manager + { + Plants plantsForm = new Plants(); + try + { + string selected = (string)flowerBeanAmountDropdown.SelectedItem; + plantsForm.PopulateFlowerOptionsBasedOnBeanCount(selected); + this.Hide(); + plantsForm.ShowDialog();// Shows the form that allows the user to select one of the flowers from PopulateFlowerOptionsBasedOnBeanCount + this.Show(); + } + catch + { + MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + plantsForm.comboBox1.Items.Clear(); + } + + //misc functions for bot + private void checkBox1_CheckedChanged(object sender, EventArgs e) + { + if (checkBox1.Checked) + numericUpDown2.Visible = true; + else + numericUpDown2.Visible = false; + } + + private void checkBox2_CheckedChanged_1(object sender, EventArgs e) + { + if (checkBox2.Checked) + TopMost = true; + else + TopMost = false; + } + + /*private void loadActonItemBtn_Click(object sender, EventArgs e) + { + //Thread.Sleep(4000); + //textBox1.Text = BotFunctions.HexConverter(BotFunctions.GetColorAt(BotFunctions.getCursorLocation().X, BotFunctions.getCursorLocation().Y)); + }*/ + + private void timer1_Tick(object sender, EventArgs e) + { + label1.Visible = true; + if (timeLeft > 0) + { + timeLeft = timeLeft - 1; + label1.Text = timeLeft + " seconds"; + } + else + { + timer1.Stop(); + label1.Visible = false; + } + } + + private async void waterPlantBtn_Click(object sender, EventArgs e) + { + try + { + await Services.Gardening.WaterPlantAsync((int)waterPlantNumericUpDown.Value, _cancellationTokenSource.Token); + } + catch (OperationCanceledException) + { + MessageBox.Show("Watering was canceled."); + } + catch (Exception ex) + { + // General error handling + MessageBox.Show($"An error occurred: {ex.Message}"); + } + } + + private async void removePlantBtn_Click(object sender, EventArgs e) + { + try + { + // Assuming RemovePlantAsync is an instance method requiring a CancellationToken. + await Services.Gardening.RemovePlantAsync(_cancellationTokenSource.Token); + } + catch (OperationCanceledException) + { + MessageBox.Show("Removing plant was canceled."); + } + catch (Exception ex) + { + // General error handling + MessageBox.Show($"An error occurred: {ex.Message}"); + } + } + + private void button7_Click(object sender, EventArgs e) + { + CoordinatesManager.CreateFreshCoordinatesFile(); + MessageBox.Show("All coordinates reset!"); + } + + private void LoadCoordinatesIntoResetBox() + { + comboBox1.Items.Clear(); + var descriptions = CoordinateActions.GetAllDescriptions(); + comboBox1.Items.AddRange(descriptions.Values.ToArray()); + } + + private async void button6_Click(object sender, EventArgs e) + { + string selectedDescription = comboBox1.SelectedItem as string; + if (string.IsNullOrEmpty(selectedDescription)) + { + MessageBox.Show("Please select a valid item from the list.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + string keyToUpdate = CoordinateActions.GetKeyFromDescription(selectedDescription); + if (keyToUpdate == null) + { + MessageBox.Show("No valid key found for the selected description.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + try + { + await _coordinatesManagerService.ManualUpdateCoordinates(keyToUpdate); + CoreFunctionality.BringBotWindowToFront(); + MessageBox.Show("Coordinates updated for " + selectedDescription); + } + catch (Exception ex) + { + MessageBox.Show("Unable to perform this action: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + + /// + /// Handles the start fishing button click event. This method initiates fishing + /// based on the selected location and settings specified in the user interface. + /// + /// The object that raised the event. + /// Event data that provides information about the click event. + /// + /// This method checks the selected fishing location from a comboBox and determines + /// whether to initiate standard fishing or a custom fishing action based on JSON configurations. + /// If "CUSTOM FISHING ACTION" is selected, it allows for either debugging the custom actions or + /// performing them normally based on a checkbox selection. If any other location is selected, + /// it proceeds with standard fishing operations. Exceptions are handled to address user cancellation + /// and other errors, providing appropriate feedback. + /// + private async void startFishing_Click(object sender, EventArgs e) + { + var token = _cancellationTokenSource.Token; // Token to handle task cancellation + + try + { + string selectedLocation = (string)fishingLocationscomboBox.SelectedItem; // Retrieve the location selected by the user + int numberOfCasts = Convert.ToInt32(numericUpDown3.Value); // Number of times to cast the line + int numberOfSells = Convert.ToInt32(numericUpDown4.Value); // Number of times to sell the caught fish + + // Check if the selected location is to perform custom fishing actions + if (selectedLocation == "CUSTOM FISHING ACTION") + { + MessageBox.Show("Make sure you're in the fishing dock before pressing OK!"); + string selectedFileName = customFishingFilesComboBox.SelectedItem?.ToString(); + if (string.IsNullOrEmpty(selectedFileName)) + { + MessageBox.Show("Please select a custom fishing action."); + return; + } + + string exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + string filePath = Path.Combine(exePath, "Custom Fishing Actions", selectedFileName); + + // Decide whether to debug custom actions or perform them normally + if (debugCustomActionsCheckBox.Checked) + { + await _fishingService.StartCustomFishingDebugging(filePath + ".json"); // Debugging custom fishing actions + } + else + { + await _fishingService.StartFishing(selectedLocation, numberOfCasts, numberOfSells, randomFishingCheckBox.Checked, token, filePath + ".json"); // Perform custom fishing actions + } + } + else + { + FishingLocationMessages.TellFishingLocation(selectedLocation); // Provide location-specific messages + MessageBox.Show("Make sure you're in the fishing dock before pressing OK!"); + await _fishingService.StartFishing(selectedLocation, numberOfCasts, numberOfSells, randomFishingCheckBox.Checked, token); // Start standard fishing + } + } + catch (TaskCanceledException) + { + MessageBox.Show("Fishing was cancelled."); // Handle cancellation of the task + } + catch (Exception ex) // Catch any other unforeseen errors + { + MessageBox.Show("An error occurred: " + ex.Message); + } + } + + private void randomFishing_CheckedChanged(object sender, EventArgs e) + { + if (randomFishingCheckBox.Checked) + { + MessageBox.Show("This will add randomness to the line casting!"); + } + } + + private void button4_Click(object sender, EventArgs e)//button to stop fishing + { + // Check if the operation is already canceled or not started + if (_cancellationTokenSource == null || _cancellationTokenSource.IsCancellationRequested) + { + MessageBox.Show("Fishing is not currently in progress."); + return; + } + + // Signal the cancellation + _cancellationTokenSource.Cancel(); + MessageBox.Show("Fishing stopped!"); + } + + private void smartFishing_CheckedChanged(object sender, EventArgs e) + { + if (smartFishing.Checked) + CoreFunctionality.isAutoDetectFishingBtnActive = true; + else + CoreFunctionality.isAutoDetectFishingBtnActive = false; + } + + private async void button5_Click(object sender, EventArgs e)//racing test + { + MessageBox.Show("Press OK when ready to begin!"); + Thread.Sleep(5000); + Point test = CoreFunctionality.getCursorLocation(); + CoreFunctionality.GetColorAt(test.X, test.Y); + string hexColor = CoreFunctionality.HexConverter(CoreFunctionality.GetColorAt(test.X, test.Y)); + //Debug.WriteLine("HEX: " + BotFunctions.HexConverter(BotFunctions.GetColorAt(test.X, test.Y)) + " RGB: " + BotFunctions.GetColorAt(test.X, test.Y)); + Debug.WriteLine("HEX: " + CoreFunctionality.HexConverter(CoreFunctionality.GetColorAt(test.X, test.Y)) + " RGB: " + CoreFunctionality.GetColorAt(test.X, test.Y)); + MessageBox.Show("Done"); + + CoreFunctionality.MaximizeAndFocusTTRWindow(); + + Image screenshot = ImageRecognition.GetWindowScreenshot(); + /*PictureBox pictureBox = new PictureBox(); + pictureBox.Image = screenshot; + pictureBox.SizeMode = PictureBoxSizeMode.AutoSize;*/ + + string redFishingButton = "#FD0000"; + string fishingExitButton = "#E6A951"; + + await ImageRecognition.locateColorInImage(screenshot, redFishingButton, 10); + + // Set the size of the form to the size of the image + /*Form form = new Form(); + form.ClientSize = screenshot.Size; + form.Controls.Add(pictureBox); + form.ShowDialog();*/ + + + /*BotFunctions.DoMouseClick(); + ToonTown_Rewritten_Bot.Racing.startRacing(); + + Rectangle bounds = Screen.GetWorkingArea(Point.Empty); + using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height)) + { + using (Graphics g = Graphics.FromImage(bitmap)) + { + g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size); + } + int x = 950; + int y = 755; + while (y <= 780 && x <= 970) + { + richTextBox1.AppendText(BotFunctions.HexConverter(bitmap.GetPixel(x, y)) + "\n"); + x++; + y++; + } + }*/ + } + + private void button8_Click(object sender, EventArgs e) + { + AboutBox1 aboutBox = new AboutBox1(); + try + { + aboutBox.ShowDialog(); + } + catch + { + MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + + private void button9_Click(object sender, EventArgs e) + { + Help helpBox = new Help(); + try + { + helpBox.ShowDialog(); + } + catch + { + MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + + private void unlimitedTrainingCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (unlimitedTrainingCheckBox.Checked) + { + numberOfDoodleScratchesNumericUpDown.Enabled = false; + numberOfDoodleFeedsNumericUpDown.Enabled = false; + justFeedDoodleCheckBox.Checked = false; + justScratchDoodleCheckBox.Checked = false; + justFeedDoodleCheckBox.Enabled = false; + justScratchDoodleCheckBox.Enabled = false; + } + else + { + numberOfDoodleScratchesNumericUpDown.Enabled = true; + numberOfDoodleFeedsNumericUpDown.Enabled = true; + justFeedDoodleCheckBox.Enabled = true; + justScratchDoodleCheckBox.Enabled = true; + } + } + + private bool isTrainingActive = false; // Flag to track training status + + private async void startDoodleTrainingBtn_Click(object sender, EventArgs e) + { + string selectedTrick = (string)doodleTrickComboBox.SelectedItem; + int numberOfFeeds = Convert.ToInt32(numberOfDoodleFeedsNumericUpDown.Value); + int numberOfScratches = Convert.ToInt32(numberOfDoodleScratchesNumericUpDown.Value); + bool unlimitedCheckBox = unlimitedTrainingCheckBox.Checked; + bool justFeed = justFeedDoodleCheckBox.Checked; + bool justScratch = justScratchDoodleCheckBox.Checked; + + // Ensure we have a fresh CancellationTokenSource + if (_cancellationTokenSource != null) + { + _cancellationTokenSource.Dispose(); // Dispose the old one if it exists + } + _cancellationTokenSource = new CancellationTokenSource(); + isTrainingActive = true; // Set the flag to indicate that training has started + + try + { + // Run the training task and handle completion + await Task.Run(() => new DoodleTraining().StartDoodleTraining( + numberOfFeeds, numberOfScratches, unlimitedCheckBox, + selectedTrick, justFeed, justScratch, _cancellationTokenSource.Token), + _cancellationTokenSource.Token) + .ContinueWith(task => + { + isTrainingActive = false; // Clear the flag when training completes or is canceled + if (task.IsCompletedSuccessfully) + { + CoreFunctionality.BringBotWindowToFront(); + MessageBox.Show("Doodle training completed successfully!", "Training Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else if (task.IsFaulted) + { + MessageBox.Show($"Error occurred during doodle training: {task.Exception?.GetBaseException().Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + }, TaskScheduler.FromCurrentSynchronizationContext()); // Ensure UI updates are done on the main thread. + } + catch (OperationCanceledException) + { + isTrainingActive = false; // Ensure flag is cleared if training is canceled + } + } + + private void stopDoodleTrainingBtn_Click(object sender, EventArgs e) + { + // Check if the cancellation token source is created and the training is active + if (_cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested && isTrainingActive) + { + _cancellationTokenSource.Cancel(); // Request cancellation + _cancellationTokenSource.Dispose(); // Dispose the token source + _cancellationTokenSource = null; // Reset the source to be sure it's fresh when restarted + isTrainingActive = false; // Clear the flag + + MessageBox.Show("Doodle Training stopped!", "Training Stopped", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else + { + // If the training was not active, show a different message + MessageBox.Show("No active training to stop.", "Stop Failed", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + + private void justFeedDoodleCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (justFeedDoodleCheckBox.Checked) + { + numberOfDoodleScratchesNumericUpDown.Enabled = false; + justScratchDoodleCheckBox.Checked = false; + } + else + { + numberOfDoodleScratchesNumericUpDown.Enabled = true; + if (unlimitedTrainingCheckBox.Checked) + { + numberOfDoodleFeedsNumericUpDown.Enabled = false; + numberOfDoodleScratchesNumericUpDown.Enabled = false; + } + } + } + + private void justScratchDoodleCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (justScratchDoodleCheckBox.Checked) + { + numberOfDoodleFeedsNumericUpDown.Enabled = false; + justFeedDoodleCheckBox.Checked = false; + } + else + { + numberOfDoodleFeedsNumericUpDown.Enabled = true; + if (unlimitedTrainingCheckBox.Checked) + { + numberOfDoodleFeedsNumericUpDown.Enabled = false; + numberOfDoodleScratchesNumericUpDown.Enabled = false; + } + } + } + + //Settings page, button to open update images setting + private void updateImagesBtn_Click(object sender, EventArgs e) + { + UpdateImages updateRecImages = new UpdateImages(); + try + { + updateRecImages.ShowDialog(); + } + catch + { + MessageBox.Show("Unable to perform this action", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + + //Settings page, button to reset all images + private void resetImagesBtn_Click(object sender, EventArgs e) + { + foreach (SettingsProperty currentProperty in Properties.Settings.Default.Properties) + { + Properties.Settings.Default[currentProperty.Name] = ""; + } + Properties.Settings.Default.Save(); + } + + private void fishingLocationscomboBox_SelectedIndexChanged(object sender, EventArgs e) + { + // Ensure there's a selected item to avoid NullReferenceException + if (fishingLocationscomboBox.SelectedItem != null) + { + string selectedLocation = fishingLocationscomboBox.SelectedItem.ToString(); + label12.Text = FishingLocationMessages.GetLocationMessage(selectedLocation); + label12.Visible = true; + + if (selectedLocation == "CUSTOM FISHING ACTION") + { + debugCustomActionsCheckBox.Visible = true; + debugCustomActionsCheckBox.Enabled = true; + customFishingFilesComboBox.Visible = true; + LoadCustomActions("Fishing", customFishingFilesComboBox); + } + else + { + debugCustomActionsCheckBox.Visible = false; + debugCustomActionsCheckBox.Enabled = false; + customFishingFilesComboBox.Visible = false; + } + } + else + label12.Visible = false; + } + + private void createCustomFishingActionsBtn_Click(object sender, EventArgs e) + { + using (var form = new CustomFishingActions()) + { + form.ShowDialog(); // This will block until the form is closed + } + LoadCustomActions("Fishing", customFishingFilesComboBox); // load fishing actions after the form is closed + } + + public void LoadCustomActions(string actionType, ComboBox comboBox) + { + string[] files = (string[])CoreFunctionality.ManageCustomActionsFolder(actionType, true); + + // Clear the items from the ComboBox passed as a parameter. + comboBox.Items.Clear(); + + // Iterate through the files, adding them to the ComboBox if they are JSON files. + foreach (string file in files) + { + // Check if the file extension is .json + if (Path.GetExtension(file).Equals(".json", StringComparison.OrdinalIgnoreCase)) + { + // Add the file name without the .json extension to the ComboBox + comboBox.Items.Add(Path.GetFileNameWithoutExtension(file)); + } + } + } + + private void stopKeepToonAwakeButton_Click(object sender, EventArgs e) + { + // Check if the cancellation token source is created and not yet cancelled and the function is active + if (_cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested && isToonAwakeActive) + { + _cancellationTokenSource.Cancel(); // Request cancellation + _cancellationTokenSource.Dispose(); // Dispose the token source + _cancellationTokenSource = null; // Reset the source to ensure it's fresh when restarted + isToonAwakeActive = false; // Clear the flag + timer1.Stop(); + timeLeft = 0; + label1.Visible = false; + + MessageBox.Show("Keep Toon Awake stopped!", "Keep Toon Awake Stopped", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else + { + // If the function was not active, show a different message + MessageBox.Show("No active 'Keep Toon Awake' function to stop.", "Stop Failed", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + + private void createCustomGolfActionsBtn_Click(object sender, EventArgs e) + { + using (var form = new CustomGolfActions()) + { + form.ShowDialog(); // This will block until the form is closed + } + + LoadCustomActions("Golf", customGolfFilesComboBox); // load golf actions after the form is closed + } + + private async void button1_Click(object sender, EventArgs e) + { + string selectedFileName = customGolfFilesComboBox.SelectedItem?.ToString(); + if (string.IsNullOrEmpty(selectedFileName)) + { + MessageBox.Show("Please select a custom golf action file."); + return; + } + + // Get the full path to the selected golf action file. + string filePath = GolfService.GetCustomGolfActionFilePath(selectedFileName); + + if (_cancellationTokenSource != null) + { + _cancellationTokenSource.Cancel(); + _cancellationTokenSource.Dispose(); + } + + _cancellationTokenSource = new CancellationTokenSource(); + + try + { + await GolfService.StartCustomGolfAction(filePath, _cancellationTokenSource.Token); + CoreFunctionality.BringBotWindowToFront(); + MessageBox.Show("Golf actions completed successfully.", "Golf Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (OperationCanceledException) + { + MessageBox.Show("Golf actions were cancelled."); + } + catch (Exception ex) + { + MessageBox.Show($"An error occurred: {ex.Message}"); + } + } + + private void customGolfFilesComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (customGolfFilesComboBox.SelectedItem == null) + { + MessageBox.Show("Please select a custom golf action file."); + return; + } + + golfActionsListBox.Items.Clear(); + string selectedFileName = customGolfFilesComboBox.SelectedItem.ToString(); + string filePath = GolfService.GetCustomGolfActionFilePath(selectedFileName); + var actions = GolfService.GetCustomGolfActions(filePath); + + foreach (var action in actions) + { + //Debug.WriteLine($"Action: {action.Action}, Command: {action.Command}, Duration: {action.Duration}"); + golfActionsListBox.Items.Add($"{action.Action} - {action.Duration} ms"); + } + } + + private void button2_Click(object sender, EventArgs e) + { + try + { + Process.Start(new ProcessStartInfo + { + FileName = CoordinatesManager.GetCoordinatesFilePath(), + UseShellExecute = true, + Verb = "open" + }); + } + catch (Exception ex) + { + MessageBox.Show($"Failed to open the folder: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } +} diff --git a/ToonTown Rewritten Bot/Form1.resx b/ToonTown Rewritten Bot/Views/MainForm.resx similarity index 99% rename from ToonTown Rewritten Bot/Form1.resx rename to ToonTown Rewritten Bot/Views/MainForm.resx index 96660d3f..a6743559 100644 --- a/ToonTown Rewritten Bot/Form1.resx +++ b/ToonTown Rewritten Bot/Views/MainForm.resx @@ -1,4 +1,64 @@ - + + + @@ -64,7 +124,7 @@ iVBORw0KGgoAAAANSUhEUgAAA58AAAG5CAYAAAAJe4B+AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL - DgAACw4BQL7hQQAAAAd0SU1FB98CBA0aOqTncFcAAP+fSURBVHhe7J0FYBTJEoY3m+Cuwd3d3eXgjsPu + DAAACwwBP0AiyAAAAAd0SU1FB98CBA0aOqTncFcAAP+fSURBVHhe7J0FYBTJEoY3m+Cuwd3d3eXgjsPu DofD3d3d3d2DuwUniru7S3B3r1d/73aYLBtD7hGo/73/ZmVsN8t0f1PV1SaRSCQSiUQikUgkEv1QcrDa zHayLu1Jr6PXF4lEIpFIJBKJRCKRKFBpiHRkh7Yu8Tw2Oye7HLsSuzQ7EzsaWwvraRAViUQikUgkEolE IpHIrjQ8ItIZjh2KDcCczD7Hfs8mg9+wT7Nnsf9mR2VDAqEikUgkEolEIpFIJPJXAEYAZwR2eDainHfY diff --git a/ToonTown Rewritten Bot/Views/Plants.Designer.cs b/ToonTown Rewritten Bot/Views/Plants.Designer.cs new file mode 100644 index 00000000..94958a7f --- /dev/null +++ b/ToonTown Rewritten Bot/Views/Plants.Designer.cs @@ -0,0 +1,219 @@ +namespace ToonTown_Rewritten_Bot +{ + partial class Plants + { + /// + /// 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(Plants)); + comboBox1 = new System.Windows.Forms.ComboBox(); + label1 = new System.Windows.Forms.Label(); + pictureBox1 = new System.Windows.Forms.PictureBox(); + pictureBox2 = new System.Windows.Forms.PictureBox(); + pictureBox3 = new System.Windows.Forms.PictureBox(); + pictureBox4 = new System.Windows.Forms.PictureBox(); + pictureBox5 = new System.Windows.Forms.PictureBox(); + pictureBox6 = new System.Windows.Forms.PictureBox(); + pictureBox7 = new System.Windows.Forms.PictureBox(); + pictureBox8 = new System.Windows.Forms.PictureBox(); + button1 = new System.Windows.Forms.Button(); + button2 = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox2).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox3).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox4).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox5).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox6).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox7).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox8).BeginInit(); + SuspendLayout(); + // + // comboBox1 + // + comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + comboBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); + comboBox1.FormattingEnabled = true; + comboBox1.Location = new System.Drawing.Point(74, 57); + comboBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + comboBox1.Name = "comboBox1"; + comboBox1.Size = new System.Drawing.Size(304, 28); + comboBox1.TabIndex = 0; + comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged; + // + // label1 + // + label1.AutoSize = true; + label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); + label1.Location = new System.Drawing.Point(147, 10); + label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(70, 25); + label1.TabIndex = 1; + label1.Text = "label1"; + // + // pictureBox1 + // + pictureBox1.Location = new System.Drawing.Point(16, 142); + pictureBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + pictureBox1.Name = "pictureBox1"; + pictureBox1.Size = new System.Drawing.Size(47, 77); + pictureBox1.TabIndex = 2; + pictureBox1.TabStop = false; + // + // pictureBox2 + // + pictureBox2.Location = new System.Drawing.Point(70, 142); + pictureBox2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + pictureBox2.Name = "pictureBox2"; + pictureBox2.Size = new System.Drawing.Size(47, 77); + pictureBox2.TabIndex = 3; + pictureBox2.TabStop = false; + // + // pictureBox3 + // + pictureBox3.Location = new System.Drawing.Point(124, 142); + pictureBox3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + pictureBox3.Name = "pictureBox3"; + pictureBox3.Size = new System.Drawing.Size(47, 77); + pictureBox3.TabIndex = 4; + pictureBox3.TabStop = false; + // + // pictureBox4 + // + pictureBox4.Location = new System.Drawing.Point(177, 142); + pictureBox4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + pictureBox4.Name = "pictureBox4"; + pictureBox4.Size = new System.Drawing.Size(47, 77); + pictureBox4.TabIndex = 5; + pictureBox4.TabStop = false; + // + // pictureBox5 + // + pictureBox5.Location = new System.Drawing.Point(231, 142); + pictureBox5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + pictureBox5.Name = "pictureBox5"; + pictureBox5.Size = new System.Drawing.Size(47, 77); + pictureBox5.TabIndex = 6; + pictureBox5.TabStop = false; + // + // pictureBox6 + // + pictureBox6.Location = new System.Drawing.Point(285, 142); + pictureBox6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + pictureBox6.Name = "pictureBox6"; + pictureBox6.Size = new System.Drawing.Size(47, 77); + pictureBox6.TabIndex = 7; + pictureBox6.TabStop = false; + // + // pictureBox7 + // + pictureBox7.Location = new System.Drawing.Point(338, 142); + pictureBox7.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + pictureBox7.Name = "pictureBox7"; + pictureBox7.Size = new System.Drawing.Size(47, 77); + pictureBox7.TabIndex = 8; + pictureBox7.TabStop = false; + // + // pictureBox8 + // + pictureBox8.Location = new System.Drawing.Point(392, 142); + pictureBox8.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + pictureBox8.Name = "pictureBox8"; + pictureBox8.Size = new System.Drawing.Size(47, 77); + pictureBox8.TabIndex = 9; + pictureBox8.TabStop = false; + // + // button1 + // + button1.Location = new System.Drawing.Point(85, 91); + button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + button1.Name = "button1"; + button1.Size = new System.Drawing.Size(132, 39); + button1.TabIndex = 10; + button1.Text = "Plant"; + button1.UseVisualStyleBackColor = true; + button1.Click += button1_Click; + // + // button2 + // + button2.Location = new System.Drawing.Point(231, 91); + button2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + button2.Name = "button2"; + button2.Size = new System.Drawing.Size(132, 39); + button2.TabIndex = 11; + button2.Text = "Stop Planting"; + button2.UseVisualStyleBackColor = true; + button2.Click += button2_Click; + // + // Plants + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(458, 180); + Controls.Add(button2); + Controls.Add(button1); + Controls.Add(pictureBox8); + Controls.Add(pictureBox7); + Controls.Add(pictureBox6); + Controls.Add(pictureBox5); + Controls.Add(pictureBox4); + Controls.Add(pictureBox3); + Controls.Add(pictureBox2); + Controls.Add(pictureBox1); + Controls.Add(label1); + Controls.Add(comboBox1); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); + Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + Name = "Plants"; + Text = "Flower Manager"; + ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox2).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox3).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox4).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox5).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox6).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox7).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox8).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + private System.Windows.Forms.Label label1; + public System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.PictureBox pictureBox2; + private System.Windows.Forms.PictureBox pictureBox3; + private System.Windows.Forms.PictureBox pictureBox4; + private System.Windows.Forms.PictureBox pictureBox5; + private System.Windows.Forms.PictureBox pictureBox6; + private System.Windows.Forms.PictureBox pictureBox7; + private System.Windows.Forms.PictureBox pictureBox8; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button2; + } +} \ No newline at end of file diff --git a/ToonTown Rewritten Bot/Plants.cs b/ToonTown Rewritten Bot/Views/Plants.cs similarity index 52% rename from ToonTown Rewritten Bot/Plants.cs rename to ToonTown Rewritten Bot/Views/Plants.cs index c931f086..6841c637 100644 --- a/ToonTown Rewritten Bot/Plants.cs +++ b/ToonTown Rewritten Bot/Views/Plants.cs @@ -3,7 +3,9 @@ using System.Drawing; using System.Drawing.Imaging; using System.Threading; +using System.Threading.Tasks; using System.Windows.Forms; +using ToonTown_Rewritten_Bot.Services; namespace ToonTown_Rewritten_Bot { @@ -16,59 +18,69 @@ public Plants() createMap(); } - private Dictionary dictionary = new Dictionary(); + private Dictionary plantComboDictionary = new Dictionary(); private void createMap() { //1 bean - dictionary.Add("Laff-o-dil", "g"); - dictionary.Add("Dandy Pansy", "o"); - dictionary.Add("What-in Carnation", "i"); - dictionary.Add("School Daisy", "y"); - dictionary.Add("Lily-of-the-Alley", "c"); + plantComboDictionary.Add("Laff-o-dil", "g"); + plantComboDictionary.Add("Dandy Pansy", "o"); + plantComboDictionary.Add("What-in Carnation", "i"); + plantComboDictionary.Add("School Daisy", "y"); + plantComboDictionary.Add("Lily-of-the-Alley", "c"); //2 bean - dictionary.Add("Daffy Dill", "gc"); - dictionary.Add("Chim Pansy", "oc"); - dictionary.Add("Instant Carnation", "iy"); - dictionary.Add("Lazy Daisy", "yr"); - dictionary.Add("Lily Pad", "cg"); + plantComboDictionary.Add("Daffy Dill", "gc"); + plantComboDictionary.Add("Chim Pansy", "oc"); + plantComboDictionary.Add("Instant Carnation", "iy"); + plantComboDictionary.Add("Lazy Daisy", "yr"); + plantComboDictionary.Add("Lily Pad", "cg"); //3 bean - dictionary.Add("Summer's Last Rose", "rrr"); - dictionary.Add("Potsen Pansy", "orr"); - dictionary.Add("Hybrid Carnation", "irr"); - dictionary.Add("Midsummer Daisy", "yrg"); - dictionary.Add("Tiger Lily", "coo"); + plantComboDictionary.Add("Summer's Last Rose", "rrr"); + plantComboDictionary.Add("Potsen Pansy", "orr"); + plantComboDictionary.Add("Hybrid Carnation", "irr"); + plantComboDictionary.Add("Midsummer Daisy", "yrg"); + plantComboDictionary.Add("Tiger Lily", "coo"); //4 bean - dictionary.Add("Corn Rose", "ryoy"); - dictionary.Add("Giraff-o-dil", "giyy"); - dictionary.Add("Marzi Pansy", "oyyr"); - dictionary.Add("Freshasa Daisy", "yrco"); - dictionary.Add("Livered Lily", "cooi"); + plantComboDictionary.Add("Corn Rose", "ryoy"); + plantComboDictionary.Add("Giraff-o-dil", "giyy"); + plantComboDictionary.Add("Marzi Pansy", "oyyr"); + plantComboDictionary.Add("Freshasa Daisy", "yrco"); + plantComboDictionary.Add("Livered Lily", "cooi"); //5 bean - dictionary.Add("Time and a half-o-dil", "gibii"); - dictionary.Add("Onelip", "urbuu"); - dictionary.Add("Side Carnation", "irgbr"); - dictionary.Add("Whoopsie Daisy", "yrooo"); - dictionary.Add("Chili Lily", "crrrr"); + plantComboDictionary.Add("Time and a half-o-dil", "gibii"); + plantComboDictionary.Add("Onelip", "urbuu"); + plantComboDictionary.Add("Side Carnation", "irgbr"); + plantComboDictionary.Add("Whoopsie Daisy", "yrooo"); + plantComboDictionary.Add("Chili Lily", "crrrr"); //6 bean - dictionary.Add("Tinted Rose", "rioroi"); - dictionary.Add("Smarty Pansy", "oiiobi"); - dictionary.Add("Twolip", "urrruu"); - dictionary.Add("Upsy Daisy", "ybcubb"); - dictionary.Add("Silly Lily", "cruuuu"); + plantComboDictionary.Add("Tinted Rose", "rioroi"); + plantComboDictionary.Add("Smarty Pansy", "oiiobi"); + plantComboDictionary.Add("Twolip", "urrruu"); + plantComboDictionary.Add("Upsy Daisy", "ybcubb"); + plantComboDictionary.Add("Silly Lily", "cruuuu"); //7 bean - dictionary.Add("Stinking Rose", "rcoiucc"); - dictionary.Add("Car Petunia", "bubucbb"); - dictionary.Add("Model Carnation", "iggggyg"); - dictionary.Add("Crazy Daisy", "ygroggg"); - dictionary.Add("Indubitab Lily", "cucbcbb"); + plantComboDictionary.Add("Stinking Rose", "rcoiucc"); + plantComboDictionary.Add("Car Petunia", "bubucbb"); + plantComboDictionary.Add("Model Carnation", "iggggyg"); + plantComboDictionary.Add("Crazy Daisy", "ygroggg"); + plantComboDictionary.Add("Indubitab Lily", "cucbcbb"); //8 bean - dictionary.Add("Istilla Rose", "rbuubbib"); - dictionary.Add("Threelip", "uyyuyouy"); - dictionary.Add("Platoonia", "biibroyy"); - dictionary.Add("Hazy Dazy", "ybucurou"); - dictionary.Add("Dilly Lilly", "cbyycbyy"); + plantComboDictionary.Add("Istilla Rose", "rbuubbib"); + plantComboDictionary.Add("Threelip", "uyyuyouy"); + plantComboDictionary.Add("Platoonia", "biibroyy"); + plantComboDictionary.Add("Hazy Dazy", "ybucurou"); + plantComboDictionary.Add("Dilly Lilly", "cbyycbyy"); } - public void loadFlowers(String beans) + + /// + /// Populates the flower selection combo box based on the specified number of beans. + /// + /// The bean count category which determines the list of available flowers. + /// + /// This method updates the UI elements to reflect the available flower options based on the bean count. + /// The bean count is represented as a string that includes the number of beans followed by the text 'Bean Plant'. + /// Depending on the bean count, different flower options are added to the combo box for user selection. + /// + public void PopulateFlowerOptionsBasedOnBeanCount(String beans) { label1.Text = beans; switch (beans) @@ -103,12 +115,12 @@ public void loadFlowers(String beans) private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { string selected = (string)comboBox1.SelectedItem; - loadBeans(dictionary[selected], 0); + loadBeans(plantComboDictionary[selected], 0); } private void loadBeans(String beansCombo, int index) { - + if (index != beansCombo.Length) { char letter = beansCombo[index]; @@ -175,14 +187,40 @@ private void loadBeans(String beansCombo, int index) } } - private void button1_Click(object sender, EventArgs e) + CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); + private async void button1_Click(object sender, EventArgs e) { - DialogResult confirmation; - confirmation = MessageBox.Show("Make sure you're at the flower bed before pressing OK!", "", MessageBoxButtons.OKCancel); + DialogResult confirmation = MessageBox.Show("Make sure you're at the flower bed before pressing OK!", "", MessageBoxButtons.OKCancel); if (confirmation.Equals(DialogResult.Cancel)) return; + string selected = (string)comboBox1.SelectedItem; - Gardening.plantFlower(dictionary[selected]); + + try + { + // Place the task on a background thread to avoid blocking the UI + await Task.Run(() => Gardening.PlantFlowerAsync(plantComboDictionary[selected], _cancellationTokenSource.Token)); + } + catch (OperationCanceledException) + { + MessageBox.Show("Planting was canceled."); + } + catch (Exception ex) + { + MessageBox.Show($"An error occurred: {ex.Message}"); + } + } + + private void button2_Click(object sender, EventArgs e) + { + // Check if the operation is already canceled or not started + if (_cancellationTokenSource == null || _cancellationTokenSource.IsCancellationRequested) + { + MessageBox.Show("Planting is not currently in progress."); + return; + } + + _cancellationTokenSource.Cancel(); } } } diff --git a/ToonTown Rewritten Bot/Plants.resx b/ToonTown Rewritten Bot/Views/Plants.resx similarity index 99% rename from ToonTown Rewritten Bot/Plants.resx rename to ToonTown Rewritten Bot/Views/Plants.resx index 5fc3191c..15eae2c5 100644 --- a/ToonTown Rewritten Bot/Plants.resx +++ b/ToonTown Rewritten Bot/Views/Plants.resx @@ -1,17 +1,17 @@  - diff --git a/ToonTown Rewritten Bot/UpdateCoordsHelper.Designer.cs b/ToonTown Rewritten Bot/Views/UpdateCoordsHelper.Designer.cs similarity index 100% rename from ToonTown Rewritten Bot/UpdateCoordsHelper.Designer.cs rename to ToonTown Rewritten Bot/Views/UpdateCoordsHelper.Designer.cs diff --git a/ToonTown Rewritten Bot/UpdateCoordsHelper.cs b/ToonTown Rewritten Bot/Views/UpdateCoordsHelper.cs similarity index 100% rename from ToonTown Rewritten Bot/UpdateCoordsHelper.cs rename to ToonTown Rewritten Bot/Views/UpdateCoordsHelper.cs diff --git a/ToonTown Rewritten Bot/UpdateCoordsHelper.resx b/ToonTown Rewritten Bot/Views/UpdateCoordsHelper.resx similarity index 100% rename from ToonTown Rewritten Bot/UpdateCoordsHelper.resx rename to ToonTown Rewritten Bot/Views/UpdateCoordsHelper.resx diff --git a/ToonTown Rewritten Bot/updateImages.Designer.cs b/ToonTown Rewritten Bot/Views/updateImages.Designer.cs similarity index 100% rename from ToonTown Rewritten Bot/updateImages.Designer.cs rename to ToonTown Rewritten Bot/Views/updateImages.Designer.cs diff --git a/ToonTown Rewritten Bot/updateImages.cs b/ToonTown Rewritten Bot/Views/updateImages.cs similarity index 100% rename from ToonTown Rewritten Bot/updateImages.cs rename to ToonTown Rewritten Bot/Views/updateImages.cs diff --git a/ToonTown Rewritten Bot/updateImages.resx b/ToonTown Rewritten Bot/Views/updateImages.resx similarity index 100% rename from ToonTown Rewritten Bot/updateImages.resx rename to ToonTown Rewritten Bot/Views/updateImages.resx