diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3bcd603
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,140 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+x64/
+bld/
+[Bb]in/
+[Oo]bj/
+
+# Roslyn cache directories
+*.ide/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+#NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Installshield output folder
+[Ee]xpress/
+
+# NuGet Packages Directory
+#packages/*
+## TODO: If the tool you use requires repositories.config
+## uncomment the next line
+!packages/repositories.config
+
+# Enable "build/" folder in the NuGet Packages folder since
+# NuGet packages use it for MSBuild targets.
+# This line needs to be after the ignore of the build folder
+# (and the packages folder if the line above has been uncommented)
+!packages/build/
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# LightSwitch generated files
+GeneratedArtifacts/
+_Pvt_Extensions/
+ModelManifest.xml
+/.vs/VSWorkspaceState.json
+/.vs/slnx.sqlite
+
+*/packages/
+*/.vs/
+.vs/
+
+
+
+## Ignore eclipse and maven build artifacts
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# External tool builders
+.externalToolBuilders/
+
+
+# validation artifacts
+*.json
+
+# Java annotation processor (APT)
+.factorypath
+
+# sbteclipse plugin
+.target
+
+# Annotation Processing
+.apt_generated/
+.apt_generated_test/
diff --git a/AddIn/EABridge_Example_AddIn.sln b/AddIn/EABridge_Example_AddIn.sln
new file mode 100644
index 0000000..4c98cac
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn.sln
@@ -0,0 +1,50 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32328.378
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EABridge_Example_AddIn", "EABridge_Example_AddIn\EABridge_Example_AddIn.csproj", "{9865ECCC-F07B-447A-BD11-C75B081EEBA4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EABridge_Example_AddIn_Tests", "EABridge_Example_AddIn_Tests\EABridge_Example_AddIn_Tests.csproj", "{7B90E5BE-58B0-4326-BD48-815220DC0D3B}"
+EndProject
+Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "EABridge_Example_AddIn_Setup", "EABridge_Example_AddIn_Setup\EABridge_Example_AddIn_Setup.wixproj", "{788CC963-0BEA-4CC6-826C-589AEA2AD2DB}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9865ECCC-F07B-447A-BD11-C75B081EEBA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9865ECCC-F07B-447A-BD11-C75B081EEBA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9865ECCC-F07B-447A-BD11-C75B081EEBA4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9865ECCC-F07B-447A-BD11-C75B081EEBA4}.Debug|x86.Build.0 = Debug|Any CPU
+ {9865ECCC-F07B-447A-BD11-C75B081EEBA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9865ECCC-F07B-447A-BD11-C75B081EEBA4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9865ECCC-F07B-447A-BD11-C75B081EEBA4}.Release|x86.ActiveCfg = Release|Any CPU
+ {9865ECCC-F07B-447A-BD11-C75B081EEBA4}.Release|x86.Build.0 = Release|Any CPU
+ {7B90E5BE-58B0-4326-BD48-815220DC0D3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7B90E5BE-58B0-4326-BD48-815220DC0D3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7B90E5BE-58B0-4326-BD48-815220DC0D3B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7B90E5BE-58B0-4326-BD48-815220DC0D3B}.Debug|x86.Build.0 = Debug|Any CPU
+ {7B90E5BE-58B0-4326-BD48-815220DC0D3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7B90E5BE-58B0-4326-BD48-815220DC0D3B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7B90E5BE-58B0-4326-BD48-815220DC0D3B}.Release|x86.ActiveCfg = Release|Any CPU
+ {7B90E5BE-58B0-4326-BD48-815220DC0D3B}.Release|x86.Build.0 = Release|Any CPU
+ {788CC963-0BEA-4CC6-826C-589AEA2AD2DB}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {788CC963-0BEA-4CC6-826C-589AEA2AD2DB}.Debug|x86.ActiveCfg = Debug|x86
+ {788CC963-0BEA-4CC6-826C-589AEA2AD2DB}.Debug|x86.Build.0 = Debug|x86
+ {788CC963-0BEA-4CC6-826C-589AEA2AD2DB}.Release|Any CPU.ActiveCfg = Release|x86
+ {788CC963-0BEA-4CC6-826C-589AEA2AD2DB}.Release|Any CPU.Build.0 = Release|x86
+ {788CC963-0BEA-4CC6-826C-589AEA2AD2DB}.Release|x86.ActiveCfg = Release|x86
+ {788CC963-0BEA-4CC6-826C-589AEA2AD2DB}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C3020ED3-76DD-48D8-8380-FEBD30D0B75C}
+ EndGlobalSection
+EndGlobal
diff --git a/AddIn/EABridge_Example_AddIn/ApplicationHandlers/ExampleHeadlessApplicationHandler.cs b/AddIn/EABridge_Example_AddIn/ApplicationHandlers/ExampleHeadlessApplicationHandler.cs
new file mode 100644
index 0000000..ce7c81e
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/ApplicationHandlers/ExampleHeadlessApplicationHandler.cs
@@ -0,0 +1,195 @@
+using EABridge_Example_AddIn.Utils;
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Threading;
+
+namespace EABridge_Example_AddIn.ApplicationHandlers
+{
+ public class ExampleHeadlessApplicationHandler
+ {
+
+ public event OperationCompleteHandler OperationComplete;
+
+ public delegate void OperationCompleteHandler(ExampleHeadlessApplicationHandler sender, ExternApplicationEventArgs e);
+
+ private Process p;
+
+ private Thread thread = null;
+
+
+ public bool IsThreadRunning()
+ {
+ return thread != null;
+ }
+
+ public void StartExternValidationOperationAsync(string guid, string path)
+ {
+ string reportFile = ExampleHeadlessApplicationHandler.GetReportFilePath();
+ string[] arguments = ComputeArguments(guid, path, reportFile, false);
+ StartExternApplicationAsync(arguments, reportFile);
+ }
+
+ private string[] ComputeArguments(string guid, string path, string targePath, bool isVerbose)
+ {
+ string[] arguments = new string[5];
+
+ arguments[0] = "validate";
+
+ arguments[1] = @"""" + path + @"""";
+ arguments[2] = @"""" + targePath + @"""";
+
+
+ if (guid.Length > 0)
+ {
+ arguments[3] = @"""" + guid + @"""";
+ }
+ else
+ {
+ arguments[3] = "";
+ }
+ arguments[4] = "-v";
+
+ string executablePath = HeadlessApplicationUtils.FindExecutable();
+
+ if (!File.Exists(executablePath))
+ {
+ Debug.WriteLine("Error: " + executablePath + " not found.");
+ throw new FileNotFoundException("Error: " + executablePath + " not found.");
+ }
+ return arguments;
+ }
+
+ private void StartExternApplicationAsync(string[] arguments,
+ string reportFile,
+ DataReceivedEventHandler outputActionHandler = null)
+ {
+ string args = string.Join(" ", arguments);
+ args += HeadlessApplicationUtils.GetExecuableInIArguments();
+ thread = new Thread(() => StartExternApplication(args, reportFile, outputActionHandler));
+ thread.Start();
+ }
+
+ private void StartExternApplication(string arguments,
+ string reportFile,
+ DataReceivedEventHandler outputActionHandler = null)
+ {
+ p = new Process();
+
+ try
+ {
+ Debug.WriteLine("Starting headless application: " + arguments);
+ p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
+ p.EnableRaisingEvents = true;
+ if (outputActionHandler != null)
+ {
+ p.OutputDataReceived -= outputActionHandler;
+ p.ErrorDataReceived -= outputActionHandler;
+ p.OutputDataReceived += outputActionHandler;
+ p.ErrorDataReceived += outputActionHandler;
+ }
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.CreateNoWindow = true;
+ p.StartInfo.RedirectStandardOutput = true;
+ p.StartInfo.RedirectStandardError = false;
+ p.StartInfo.FileName = HeadlessApplicationUtils.FindExecutable();
+ p.StartInfo.Arguments = arguments;
+ DateTime startTime = DateTime.Now;
+ p.Start();
+ string standardOutput = "";
+ if (outputActionHandler == null)
+ {
+ // read cli output and save it in a temporary log
+ standardOutput = p.StandardOutput.ReadToEnd();
+ } else
+ {
+ p.BeginOutputReadLine();
+ }
+
+ p.WaitForExit();
+
+ DateTime endTime = DateTime.Now;
+
+
+
+
+ ExternApplicationEventArgs eventArgs = new ExternApplicationEventArgs();
+ eventArgs.ReportFile = reportFile;
+ eventArgs.ReturnCode = p.ExitCode;
+ eventArgs.Duration = DateTimeUtils.GetTimeDifferenceInMilisec(startTime, endTime);
+
+ if (!string.IsNullOrEmpty(standardOutput))
+ {
+ try
+ {
+ string logFilePath = GetReportFilePath();
+ var sw = File.AppendText(logFilePath);
+ sw.Write(standardOutput);
+ sw.Close();
+ eventArgs.LogFile = logFilePath;
+ }
+ catch (Exception)
+ {
+ // do nothing
+ }
+ }
+
+ if (this != null)
+ {
+ OperationComplete(this, eventArgs);
+ thread = null;
+ }
+ }
+ catch (ThreadAbortException)
+ {
+ Debug.WriteLine("Validation aborted.");
+ }
+ finally
+ {
+ p = null;
+ }
+ }
+
+ public void KillProcess()
+ {
+ try
+ {
+ if (thread != null)
+ {
+ if (p != null)
+ {
+
+ p.Kill();
+ }
+ if (thread.IsAlive)
+ {
+ thread.Abort();
+ }
+ }
+ thread = null;
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ }
+
+ public static string GetReportFilePath()
+ {
+ return Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
+ }
+ }
+
+
+ public class ExternApplicationEventArgs : EventArgs
+ {
+ public string ReportFile { get; set; }
+
+ public int ReturnCode { get; set; }
+
+ public long Duration { get; set; }
+
+ public string LogFile { get; set; }
+ }
+
+}
diff --git a/AddIn/EABridge_Example_AddIn/EABridge_Example_AddIn.csproj b/AddIn/EABridge_Example_AddIn/EABridge_Example_AddIn.csproj
new file mode 100644
index 0000000..b696d68
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/EABridge_Example_AddIn.csproj
@@ -0,0 +1,112 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {9865ECCC-F07B-447A-BD11-C75B081EEBA4}
+ Library
+ EABridge_Example_AddIn
+ EABridge_Example_AddIn
+ v4.5
+ 512
+ true
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ true
+ true
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+ true
+
+
+
+
+
+
+
+ ..\..\..\..\..\..\Program Files (x86)\Sparx Systems\EA\Interop.EA.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ CLIPathForm.cs
+
+
+ UserControl
+
+
+ ValidationIssuesControl.cs
+
+
+
+
+
+
+
+
+
+
+ CLIPathForm.cs
+
+
+ ValidationIssuesControl.cs
+
+
+
+
+ 6.0.4
+
+
+ 6.0.2
+
+
+
+
+ "%25Windir%25\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "$(TargetPath)" "/tlb:$(TargetName).tlb" /codebase /silent
+
+
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn/ExampleValidationAddIn.cs b/AddIn/EABridge_Example_AddIn/ExampleValidationAddIn.cs
new file mode 100644
index 0000000..ef68220
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/ExampleValidationAddIn.cs
@@ -0,0 +1,279 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.IO;
+using System.Threading;
+using System.Windows.Forms;
+using File = System.IO.File;
+using EA;
+using EABridge_Example_AddIn.UI;
+using EABridge_Example_AddIn.Utils;
+using EABridge_Example_AddIn.Reports;
+using Newtonsoft.Json;
+using EABridge_Example_AddIn.ApplicationHandlers;
+
+namespace EABridge_Example_AddIn
+{
+ [Guid("95251B40-21BA-449B-8E51-0745339E755F")]
+ [ComVisible(true)]
+ public class ExampleValidationAddIn
+ {
+ const string AddInHeader = "-&YAKINDU EA-Bridge Integration";
+ const string ValidationMenuEntry = "&Model Validation";
+ const string ConfigurationMenuEntry = "&Configure CLI Path.. ";
+ public const string RESULTS_TAB = "Results";
+ public const string VALIDATION_TAB = "Model Validation Results";
+
+ private readonly ExampleHeadlessApplicationHandler applicationHandler = new ExampleHeadlessApplicationHandler();
+
+ public delegate void ShowValidationViewHandler(System.Runtime.Remoting.Contexts.Context sender, ExternRefreshValidationViewArgs e);
+ public event ShowValidationViewHandler ShowValidationView;
+
+ private Repository repository;
+
+ private SerializableValidationResult ValidationReport;
+
+ private ValidationIssuesControl validationIssuesControl;
+
+ public ExampleValidationAddIn()
+ {
+ ShowValidationView += ShowValidationViewMethod;
+ applicationHandler.OperationComplete += OperationCompleteMethod;
+ }
+
+ public String EA_Connect(Repository Repository)
+ {
+ this.repository = Repository;
+ return "EA repository connected";
+ }
+
+ public object EA_GetMenuItems(Repository Repository, string Location, string MenuName)
+ {
+ if (MenuName == "")
+ {
+ return AddInHeader;
+ }
+ if ("MainMenu" == Location)
+ {
+ return new string[] {ValidationMenuEntry, ConfigurationMenuEntry};
+ } else
+ {
+ return new string[] { ValidationMenuEntry};
+ }
+
+ }
+
+ bool IsProjectOpen(Repository Repository)
+ {
+ try
+ {
+ Collection c = Repository.Models;
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public void EA_GetMenuState(Repository Repository, string Location, string MenuName, string ItemName, ref bool IsEnabled, ref bool IsChecked)
+ {
+ if (IsProjectOpen(Repository))
+ {
+ if ("MainMenu" == Location || EARepositoryUtils.IsCLIOperationForContextObjectAllowed(Repository.GetContextObject()))
+ {
+ IsChecked = false;
+ switch (ItemName)
+ {
+ case ValidationMenuEntry:
+ IsEnabled = true;
+ break;
+ default:
+ IsEnabled = true;
+ break;
+ }
+ } else
+ {
+ // not a valid choice for operations
+ IsEnabled = false;
+ }
+ }
+ else
+ {
+ // If no open project, disable all menu options
+ IsEnabled = false;
+ }
+ }
+
+ public void EA_MenuClick(Repository Repository, string Location, string MenuName, string ItemName)
+ {
+ string operationGuid = "";
+ bool isValidationOperation = true;
+ this.repository = Repository;
+ if (applicationHandler.IsThreadRunning())
+ {
+ if (DialogResult.Yes == MessageBox.Show(Win32Window.GetMainWindowHandle(), "The CLI application is still running. Do you want to abort the current operation ?" + Environment.NewLine + Environment.NewLine + "All changes will be lost.", "Abort current operation ?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2))
+ {
+ this.applicationHandler.KillProcess();
+ } else
+ {
+ return;
+ }
+ }
+ if (ValidationMenuEntry != ItemName)
+ {
+ isValidationOperation = false;
+ } else
+ {
+ isValidationOperation = true;
+ }
+ if ("MainMenu" != Location)
+ {
+ // get the context element
+ object cxt = repository.GetContextObject();
+ operationGuid = EARepositoryUtils.GetGuidOfPackageOrElementOrDiagram(cxt);
+ }
+ try
+ {
+ PerformOperation(operationGuid, isValidationOperation);
+ } catch (FileNotFoundException)
+ {
+ MessageBox.Show(Win32Window.GetMainWindowHandle(),
+ string.Format("The CLI application could not be found at the expected location '{0}'. ", HeadlessApplicationUtils.FindExecutable()),
+ "CLI application not found",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ }
+ }
+
+
+ private void PerformOperation(string contextGuid, bool isValidation)
+ {
+ try
+ {
+ if (!isValidation)
+ {
+ var cliPathDialog = new CLIPathForm();
+ cliPathDialog.ShowDialog();
+ }
+ else
+ {
+ repository.CreateOutputTab(RESULTS_TAB);
+ repository.ClearOutput(RESULTS_TAB);
+ string path = repository.ConnectionString;
+ repository.WriteOutput(RESULTS_TAB, "Starting Validation of " + path, 0);
+ applicationHandler.StartExternValidationOperationAsync(contextGuid, path);
+ if (validationIssuesControl != null)
+ {
+ // TODO: lock on this instance of the add in
+ // because validationIssuesControl has a weak identity
+ // c.f. https://rules.sonarsource.com/csharp/RSPEC-3998
+ lock (validationIssuesControl)
+ {
+ validationIssuesControl.UpdateValidationViewState(contextGuid, applicationHandler);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ if (e is FileNotFoundException)
+ {
+ repository.WriteOutput(RESULTS_TAB, e.Message, -1);
+ MessageBox.Show(Win32Window.GetMainWindowHandle(),
+ "Please choose a valid path to the CLI validator first! (from the ribbon menu)",
+ "Unexpected Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ }
+ else
+ {
+ repository.WriteOutput(RESULTS_TAB, e.Message, -1);
+ MessageBox.Show(Win32Window.GetMainWindowHandle(),
+ string.Format("Unexpected Error:\r\n {0}\r\n {1} ", e.Message, e.StackTrace),
+ "Unexpected Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ }
+ }
+ finally
+ {
+ repository.EnsureOutputVisible(RESULTS_TAB);
+ }
+ }
+
+ private void OpenValidationIssue()
+ {
+ try
+ {
+ repository.HideAddinWindow();
+ if (this.validationIssuesControl == null)
+ {
+ this.validationIssuesControl = this.repository.AddWindow(VALIDATION_TAB, typeof(ValidationIssuesControl).FullName) as ValidationIssuesControl;
+ }
+ this.validationIssuesControl.UpdateValidationIssues(this.ValidationReport, repository);
+ this.repository.ShowAddinWindow(validationIssuesControl);
+ }
+ catch (Exception e)
+ {
+ MessageBox.Show(Win32Window.GetMainWindowHandle(),
+ string.Format("The validation issues view could not be shown. \r\n{0} \r\n{1} ", e.Message, e.StackTrace),
+ "Validation view could not be shown",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ }
+ }
+
+
+ private void OperationCompleteMethod(ExampleHeadlessApplicationHandler sender, ExternApplicationEventArgs e)
+ {
+ repository.CreateOutputTab(RESULTS_TAB);
+ string logFilePath = "";
+ try
+ {
+
+ string reportFilePath = e.ReportFile;
+ logFilePath = e.LogFile;
+ if (e.ReturnCode == 0 && !File.Exists(reportFilePath))
+ {
+ repository.WriteOutput(RESULTS_TAB, "Validation finished in " + DateTimeUtils.GetHumanReadableDuration(e.Duration) + ", 0 issue(s)", -2);
+ repository.EnsureOutputVisible(RESULTS_TAB);
+ return;
+ }
+ if (e.ReturnCode != 0 && !File.Exists(reportFilePath))
+ {
+ throw new Exception("Error: Validation incomplete, view log for more information");
+ }
+ this.ValidationReport = JsonConvert.DeserializeObject(File.ReadAllText(reportFilePath));
+ repository.WriteOutput(RESULTS_TAB, "========== Validation finished in " + DateTimeUtils.GetHumanReadableDuration(e.Duration) + ", " + this.ValidationReport.Count().ToString() + " issue(s) ========== ", -2);
+ File.Delete(reportFilePath);
+ repository.EnsureOutputVisible(RESULTS_TAB);
+ ExternRefreshValidationViewArgs validationViewEventArgs = new ExternRefreshValidationViewArgs();
+ ShowValidationView(Thread.CurrentContext, validationViewEventArgs);
+ }
+ catch (Exception ex)
+ {
+ if (!string.IsNullOrEmpty(logFilePath))
+ {
+ repository.WriteOutput(RESULTS_TAB, "Validation failed. Check the log file for more information", -1);
+ repository.WriteOutput(RESULTS_TAB, logFilePath , -1);
+ }
+ }
+ }
+
+
+ private void ShowValidationViewMethod(System.Runtime.Remoting.Contexts.Context sender, ExternRefreshValidationViewArgs e){
+ OpenValidationIssue();
+ }
+
+ public void EA_Disconnect()
+ {
+ GC.WaitForPendingFinalizers();
+ }
+
+ public class ExternRefreshValidationViewArgs : EventArgs
+ {
+ public IList issues { get; set; }
+ }
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/Install.bat b/AddIn/EABridge_Example_AddIn/Install.bat
new file mode 100644
index 0000000..cbe5baa
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Install.bat
@@ -0,0 +1,14 @@
+echo ####################################
+echo ### Administrator Rights Needed! ###
+echo ####################################
+
+set dir=%~dp0
+set assembly1=bin\Debug\EABridge_Example_AddIn.dll
+
+
+"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "%dir%%assembly1%" /codebase
+
+reg ADD "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Sparx Systems\EAAddins\Example Validation AddIn Dev" /f /d "EABridge_Example_AddIn.ExampleValidationAddIn"
+
+
+pause
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn/Properties/AssemblyInfo.cs b/AddIn/EABridge_Example_AddIn/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9b5984b
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("EABridge_Example_AddIn")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("EABridge_Example_AddIn")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7A0AE073-B3BE-4293-8E5E-2AD62D152514")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/AddIn/EABridge_Example_AddIn/Reports/SerializableValidationResult.cs b/AddIn/EABridge_Example_AddIn/Reports/SerializableValidationResult.cs
new file mode 100644
index 0000000..bb1d1d4
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Reports/SerializableValidationResult.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EABridge_Example_AddIn.Reports
+{
+
+ public class SerializableValidationResult
+ {
+ public List resourceIssues { get; set; }
+
+ public List loadIssues { get; set; }
+
+ public List umlIssues { get; set; }
+
+ public List customIssues { get; set; }
+
+ public int Count()
+ {
+ return resourceIssues.Count + loadIssues.Count + umlIssues.Count + customIssues.Count;
+ }
+
+ public IDictionary GetAllValidationIssues()
+ {
+ var result = new Dictionary();
+ resourceIssues.ForEach(issue => result.Add(issue, ValidationIssueCategory.Resource));
+ loadIssues.ForEach(issue => result.Add(issue, ValidationIssueCategory.Load));
+ umlIssues.ForEach(issue => result.Add(issue, ValidationIssueCategory.UML));
+ customIssues.ForEach(issue => result.Add(issue, ValidationIssueCategory.Custom));
+ return result;
+ }
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/Reports/ValidationIssue.cs b/AddIn/EABridge_Example_AddIn/Reports/ValidationIssue.cs
new file mode 100644
index 0000000..28f4eae
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Reports/ValidationIssue.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EABridge_Example_AddIn.Reports
+{
+ public class ValidationIssue
+ {
+ public string severity { get; set; }
+
+ public string type { get; set; }
+
+ public string id { get; set; }
+
+ public string msg { get; set; }
+
+ public override string ToString()
+ {
+ return msg + " | " + severity + " | " + type + " | " + id;
+ }
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/Reports/ValidationIssueCategory.cs b/AddIn/EABridge_Example_AddIn/Reports/ValidationIssueCategory.cs
new file mode 100644
index 0000000..7ace5b2
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Reports/ValidationIssueCategory.cs
@@ -0,0 +1,10 @@
+namespace EABridge_Example_AddIn.Reports
+{
+ public enum ValidationIssueCategory
+ {
+ Load,
+ UML,
+ Resource,
+ Custom,
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/Reports/ValidationIssueSeverity.cs b/AddIn/EABridge_Example_AddIn/Reports/ValidationIssueSeverity.cs
new file mode 100644
index 0000000..5a2535d
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Reports/ValidationIssueSeverity.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EABridge_Example_AddIn.Reports
+{
+
+ public enum ValidationIssueSeverity
+ {
+ Error,
+ Warning,
+ Information,
+ None
+ }
+ public static class ValidationIssueSeverityUtils
+ {
+
+ public static ValidationIssueSeverity GetSeverity(string severity)
+ {
+ switch (severity)
+ {
+ case "E": return ValidationIssueSeverity.Error;
+ case "W": return ValidationIssueSeverity.Warning;
+ case "I": return ValidationIssueSeverity.Information;
+ default: return ValidationIssueSeverity.None;
+ }
+ }
+
+ public static int GetSeverityLevel(ValidationIssueSeverity severity)
+ {
+ switch (severity)
+ {
+ case ValidationIssueSeverity.Error: return 2;
+ case ValidationIssueSeverity.Warning: return 1;
+ case ValidationIssueSeverity.Information: return 0;
+ default: return -1;
+ }
+ }
+
+ public static int CompareSeverityLevels(string first, string second)
+ {
+ var firstSeverity= GetSeverity(first);
+ var secondSeverity = GetSeverity(second);
+ return GetSeverityLevel(firstSeverity) - GetSeverityLevel(secondSeverity);
+ }
+
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/UI/CLIPathForm.Designer.cs b/AddIn/EABridge_Example_AddIn/UI/CLIPathForm.Designer.cs
new file mode 100644
index 0000000..2afe786
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/UI/CLIPathForm.Designer.cs
@@ -0,0 +1,140 @@
+namespace EABridge_Example_AddIn.UI
+{
+ partial class CLIPathForm
+ {
+ ///
+ /// 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(CLIPathForm));
+ this.cliPathTextBox = new System.Windows.Forms.TextBox();
+ this.browseButton = new System.Windows.Forms.Button();
+ this.okButton = new System.Windows.Forms.Button();
+ this.cancelButton = new System.Windows.Forms.Button();
+ this.label = new System.Windows.Forms.Label();
+ this.pathNotValidLabel = new System.Windows.Forms.Label();
+ this.chooseFolderDialog = new System.Windows.Forms.FolderBrowserDialog();
+ this.SuspendLayout();
+ //
+ // cliPathTextBox
+ //
+ this.cliPathTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.cliPathTextBox.Location = new System.Drawing.Point(12, 38);
+ this.cliPathTextBox.Name = "cliPathTextBox";
+ this.cliPathTextBox.Size = new System.Drawing.Size(635, 20);
+ this.cliPathTextBox.TabIndex = 0;
+ this.cliPathTextBox.TextChanged += new System.EventHandler(this.cliPathTextBox_TextChanged);
+ //
+ // browseButton
+ //
+ this.browseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.browseButton.Location = new System.Drawing.Point(664, 36);
+ this.browseButton.Name = "browseButton";
+ this.browseButton.Size = new System.Drawing.Size(108, 23);
+ this.browseButton.TabIndex = 1;
+ this.browseButton.Text = "Browse";
+ this.browseButton.UseVisualStyleBackColor = true;
+ this.browseButton.Click += new System.EventHandler(this.browseButton_Click);
+ //
+ // okButton
+ //
+ this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.okButton.Location = new System.Drawing.Point(550, 117);
+ this.okButton.Name = "okButton";
+ this.okButton.Size = new System.Drawing.Size(108, 23);
+ this.okButton.TabIndex = 2;
+ this.okButton.Text = "OK";
+ this.okButton.UseVisualStyleBackColor = true;
+ this.okButton.Click += new System.EventHandler(this.okButton_Click);
+ //
+ // cancelButton
+ //
+ this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancelButton.Location = new System.Drawing.Point(664, 117);
+ this.cancelButton.Name = "cancelButton";
+ this.cancelButton.Size = new System.Drawing.Size(108, 23);
+ this.cancelButton.TabIndex = 3;
+ this.cancelButton.Text = "Cancel";
+ this.cancelButton.UseVisualStyleBackColor = true;
+ //
+ // label
+ //
+ this.label.AutoSize = true;
+ this.label.Location = new System.Drawing.Point(12, 13);
+ this.label.Name = "label";
+ this.label.Size = new System.Drawing.Size(493, 13);
+ this.label.TabIndex = 4;
+ this.label.Text = "Select the path to the YAKINDU EA-Bridge CLI Application which executes the actua" +
+ "l model validation.";
+ //
+ // pathNotValidLabel
+ //
+ this.pathNotValidLabel.AutoSize = true;
+ this.pathNotValidLabel.ForeColor = System.Drawing.Color.Red;
+ this.pathNotValidLabel.Location = new System.Drawing.Point(12, 72);
+ this.pathNotValidLabel.Name = "pathNotValidLabel";
+ this.pathNotValidLabel.Size = new System.Drawing.Size(405, 13);
+ this.pathNotValidLabel.TabIndex = 5;
+ this.pathNotValidLabel.Text = "This path does not contain the YAKINDU EA-Bridge CLI. Please choose a valid path";
+ //
+ // CLIPathForm
+ //
+ this.AcceptButton = this.okButton;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.AutoSize = true;
+ this.CancelButton = this.cancelButton;
+ this.ClientSize = new System.Drawing.Size(784, 161);
+ this.Controls.Add(this.pathNotValidLabel);
+ this.Controls.Add(this.label);
+ this.Controls.Add(this.cancelButton);
+ this.Controls.Add(this.okButton);
+ this.Controls.Add(this.browseButton);
+ this.Controls.Add(this.cliPathTextBox);
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.MaximizeBox = false;
+ this.MaximumSize = new System.Drawing.Size(800, 200);
+ this.MinimizeBox = false;
+ this.MinimumSize = new System.Drawing.Size(800, 200);
+ this.Name = "CLIPathForm";
+ this.Text = "Select Path to YAKINDU EA-Bridge CLI Application";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TextBox cliPathTextBox;
+ private System.Windows.Forms.Button browseButton;
+ private System.Windows.Forms.Button okButton;
+ private System.Windows.Forms.Button cancelButton;
+ private System.Windows.Forms.Label label;
+ private System.Windows.Forms.Label pathNotValidLabel;
+ private System.Windows.Forms.FolderBrowserDialog chooseFolderDialog;
+ }
+}
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn/UI/CLIPathForm.cs b/AddIn/EABridge_Example_AddIn/UI/CLIPathForm.cs
new file mode 100644
index 0000000..0f76022
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/UI/CLIPathForm.cs
@@ -0,0 +1,71 @@
+using EABridge_Example_AddIn.ApplicationHandlers;
+using EABridge_Example_AddIn.Utils;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace EABridge_Example_AddIn.UI
+{
+ public partial class CLIPathForm : Form
+ {
+ private string CliPath = "";
+ private ValidationConfiguration validationConfiguration;
+ public CLIPathForm()
+ {
+ InitializeComponent();
+ validationConfiguration = FileUtils.ReadValidationConfigurationFile();
+ if (validationConfiguration != null)
+ {
+ cliPathTextBox.Text = validationConfiguration.ValidationCLIPath;
+ CliPath = validationConfiguration.ValidationCLIPath;
+ }
+ ValidateContent();
+ }
+
+ private void ValidateContent()
+ {
+ if (HeadlessApplicationUtils.IsHeadlessApplicationDirectory(CliPath))
+ {
+ okButton.Enabled = true;
+ pathNotValidLabel.Visible = false;
+ } else
+ {
+ okButton.Enabled = false;
+ pathNotValidLabel.Visible = true;
+ }
+ }
+
+ private void browseButton_Click(object sender, EventArgs e)
+ {
+ if (DialogResult.OK == chooseFolderDialog.ShowDialog())
+ {
+ CliPath = chooseFolderDialog.SelectedPath;
+ cliPathTextBox.Text = chooseFolderDialog.SelectedPath;
+ }
+ ValidateContent();
+ }
+
+ private void cliPathTextBox_TextChanged(object sender, EventArgs e)
+ {
+ CliPath = cliPathTextBox.Text;
+ ValidateContent();
+ }
+
+ private void okButton_Click(object sender, EventArgs e)
+ {
+ var configuration = new ValidationConfiguration
+ {
+ ValidationCLIPath = CliPath
+ };
+ FileUtils.UpadteOrCreateValidationConfiguration(configuration);
+ this.DialogResult = DialogResult.OK;
+ this.Close();
+ }
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/UI/CLIPathForm.resx b/AddIn/EABridge_Example_AddIn/UI/CLIPathForm.resx
new file mode 100644
index 0000000..f05451c
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/UI/CLIPathForm.resx
@@ -0,0 +1,2890 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 17, 17
+
+
+
+
+ AAABAAEAyMgAAAEAIAAIhwIAFgAAACgAAADIAAAAkAEAAAEAIAAAAAAAAHECACcAAAAnAAAAAAAAAAAA
+ AAD/////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////9/////P3///n8///9/////f/////////////////+/////v////v////8////
+ /P////v///79/////v////////38////+P////f////4////+P////v////7///9+////fr///7////+
+ /////v////7////9/////f////3///79///////////+///+/f/+/Pv///79/////v//////////////
+ //////////////7+/v/7/f7/+/3+//3////9/////v7+/////////////////////v///fz///79////
+ /v////z////8////+/////v////6////+v////r////7///+/f/+/v7/////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////9/////f////v9/v/8/v///P7///39
+ /f/9/f3//v7+///////////////////////9/////f////3////////////8////+f////v////7////
+ +/////z////8/////v////7///7+///9/f///P7//v3////+/////v////7////9/P////v////+////
+ /v////7////+//78+//7+/v//Pz8//39/f/////////////////9/////f////3//////////v7+//r6
+ +v/7+/v///79/////v////7////+//78+////fz////7/////P////z////+/////v////7/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///8/v//+/3+//z+///9////+/7///v+///7/v//+v7///r+///4/v//+P7///X7///z+f//9Pr///f9
+ ///7/////f/+//3////8//3/+/78//v+/P/8//3//f/+//3//v/9//7//f/+//3//v/9//7//f/+//3/
+ /v/8//3////8///++f///Pn////7///++v///vr////8/////v////7////+/////v////7////+//39
+ /f/8/Pz/+/v7//r6+v///////////////////////f39//39/f/////////////////9/////f////3/
+ ///7/v//+fz///j7///9////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////v7+//7+/v///v///f////3+///7/v//+/7///r+///6/f//+P7///b8
+ ///3/f//+v7///r+///6/v//+Pv///v9/f/7/vz//v/7/////P////v////5////+P////f////z////
+ 8P///ez///ro///65v//+uT///nj///44v/y5M7/797J/+zbxv/t3Mf/69zJ/+zdyv/15tP//vDd///2
+ 5P//9+X///jm///55///++n///7u////8v////T////4///+9////PX///32////+/////v////8///+
+ +v////7///////3////8/v//+v3///r+///4/v//+v7///3///////////////7+/v/+/v7//v7+////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////v3////+///////9/////P7///n9
+ /v/5/P//+v3///v8///9//////////z6+f/9+vb////6////+f////j////4////9/////X////y///y
+ 4P/q2sP/0byh/8GoiP+vlG//qoph/514TP+NZTT/gFUi/3ZKFP9yRQz/b0IJ/2xCDf9oQAz/aEAM/2tD
+ D/9qQg7/Zj4K/2hAD/9uRhX/a0MT/3FLG/9+WCj/jGY2/5x2Rv+tiVv/wJxu/8iof//Ywqb/6NfC///z
+ 4P////D////x////8f////T////1////+P////v////8///////7/f7/+Pz///j+///6/v///f//////
+ //////////////7+/v/+/v7/////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v////7///////7+/v/9/f3//f/////+///////////8////+f////b////0////8f///+7///LZ//Tf
+ xP/SvKD/uqKE/5Z8Xv92Wzn/Zkkk/2REG/9pRBj/b0cW/3NHEv9zRQv/d0QG/3hCAf98QwD/f0QA/4FG
+ AP+BRwD/fUUA/3tEAP98RQD/f0gD/31GAf94RAD/eEMA/3lFAv93QwH/ekYE/3xIBv94RgT/dUID/3VC
+ A/95Rgf/d0kP/2tHGf9nRx7/a0wl/3pdOP+Welf/vKF//93Fp//x3MH///Xg///86v////T////4////
+ +/////v////+///////+/v7//v7+/////////////////////////////v7+////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////v7+//////////7////8///89f////L////t///2
+ 3//z273/zbCL/6SCV/+GYjT/fVYi/3FGDf9yRQj/cEMG/3JDBv9zRAb/dEYG/3VFBf92RAL/cz8A/3VB
+ AP94QwD/e0YD/39IA/9+RwL/fEYA/3pEAP99RQD/fUUA/3xEAP98RAD/fUUA/31FAP9+RQD/fUYB/3lC
+ AP94QwD/ekUC/3pFAv95QwL/eEQC/3hEAv95RQP/dkIA/3pGBP97SAn/d0YI/3BCCP9vQw3/c0sX/3ZS
+ JP+IaD//ooZj/8uzlf/u2sH///Ld///+7P////H////3///9+f/9/f3//v7+////////////////////
+ ///+/v7/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////f/////////9//////////3//////////f////v////7//////7////////////////+////
+ /v////7///////3////9/////f////////////7////+/////v////7////+////+/////r////4////
+ 8///9+f//+/Y/9W/o/+tkW//gGA3/21JG/9uQxD/b0IJ/3FBB/96RQb/fkcA/4BIAP+ARwD/f0YA/31G
+ AP99RgD/fkcA/31IAP+ASgP/fkgB/3pGAP95RQD/eUUA/3lFAP95RgD/ekYA/31FAP9/SAD/gUcA/35H
+ AP+BRwD/gEkA/35GAP97QwD/fkcC/3xFAP97RAD/e0QA/3xFAv97RgP/e0QB/3pDAP+CRwD/gUcA/4BG
+ AP9/RQD/fkYA/3tGA/94RQb/c0QH/29CCf9pQQ3/Z0MV/21LIP+DZD3/rZFu/+LHpf//69D///7u///+
+ 9f////f////5////+/////z////+//7+/v///////f////3////9///////////////////////+////
+ /v////7////+//////////////////////////////7/////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////7////+////
+ /v////7//f/+//3//v/9/////f////3////7/////f////v////9////+/////3////6////9v////P7
+ ///9/v/////////7+/////z////8/////P/9/f3/+/////r////6////+/z6/////P////n////5////
+ /P///vn////4////8f//6dP/1reY/5x3Uf9ySRz/bkEO/3FCCv9zRAf/dUUF/3lFA/96RAP/fkQD/4BE
+ Av9/RQD/gUgA/4FIAP+ARwD/fkcA/4BJAP99RwD/ekQA/3tEAP95RQD/eUUA/3pGAP95RQL/eUUC/3lF
+ Av95RQD/ekQA/3pEAP9+RgD/fkgB/4BIAf9/RwD/fUUA/31FAP+ASAH/fUUA/3xDAP99RAD/fUQA/3pD
+ AP98QwD/fEUA/4BGBP98RQL/ekMA/3tEAP98RQD/fUYB/31GAf96RQL/eUUD/3dEBf92RQf/dEUH/3FD
+ Cf9vQwj/dEcO/3RMG/+aflv/y7WZ///t1P///+/////z////+P////v////+//z+///7/v//+/7///v+
+ ///9//////////////////v////7///++f/+/fn////+/////////v////7////+/////f////7/////
+ ///////////+/////v/9//7//f/+////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////7////+/////v/9//7//f/+//3////9/////f////3////9/////f////3/
+ ///9/////f////v////y+fz/+P////3/////+vv///7+/////P//+/j///38//3////3+/z/9/38//v/
+ /v////v////3////9f////T////t//3v2f/Qu6D/jXBR/2dDG/9wRBX/e0kU/3M/A/95RQP/ekYA/3pG
+ AP98RwD/fEYA/35GAP+ARQD/gEUA/39HAP+ASAH/f0cA/31FAP97RQD/fUcA/35IAf99RgH/f0gD/31G
+ Af98RQD/e0QA/3lFAP95RQD/ekYA/3pGAP9/SAP/e0cA/3tEAP93QwD/eUIA/3tFAP99RgH/f0kC/39G
+ Af97RAD/fkUA/39GAf9/RgH/fkUA/35FAP9+RwT/eEAA/3pEA/99Rwb/fEcE/3pDAP93QAD/e0MA/31F
+ AP9+RgD/fEUA/3xFAP97RwH/eUQB/3dDAP95RQL/eUkJ/29DDf9fOQn/Z0Ua/5Z5VP/UvJ7//+7X////
+ 8P////j////7/////v///////f////z+///9/f3//v7+/////v////z////7/////v////7//f39//38
+ /v///v////7////9/////v////////////////7////+/////v////7/////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////+////
+ /v////7////+/////v////7////+/////v/////////+/////P/8/Pb//Pn1///9/P///f7///z+///+
+ ///9////+/////3///////z///31////9/////T//+/e/+TNs/+njGD/fFwn/2Q+CP9uRgz/d0kP/3A/
+ Af9wPQD/eEcD/3dGAP93RwD/d0cA/3dHAP95RwD/ekYA/3xGAP98RQD/d0EA/3hEAv95RQP/eUUC/3pF
+ Av97RgP/fUYD/3tEAP96QwD/fUQA/39HAP+ASQD/gkgA/4JIAP+BRwD/fkYA/3lCAP94RQD/fEcE/3xJ
+ A/99SAX/fEgC/3pFAv94RAD/fUYD/3pFAv99RgP/fkcE/31GA/97RAH/ekMA/3tEAf99RgP/fEUC/3tE
+ Af97RAD/fEUA/31GAf9+RwL/f0gD/3xFAP95RAH/ekUC/3pGA/95RQP/dUMB/3VCA/94RAL/gUkC/39I
+ A/97SAn/c0UL/2pCEf97WS7/r5Ry/+DMs///++n////1///99v/8+fX////+///////8/Pz/+/3+//n9
+ /v/6/v///f////3////////////////////9+/v///7//////////////////////v////z////8////
+ /P////7/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////v////7////+
+ //////////////////////7////+/////v////7////+/////v////7////+//////////7///75///+
+ +f////7///7///r5/f/7+////f7///r8/f/9+/r///72////9P///+//+ujR/8u2m/+NdVn/ZEUe/2xE
+ Cf90RgD/d0YA/3hFAP94QQD/fEUA/39IA/98SAL/eUcA/3dHAP93RwD/d0cA/3lHAP96RgD/fEYA/3xF
+ AP9+SAf/fEcI/3pGBP93QwH/d0EA/3hDAP97RAH/fEUC/31EAP9+RQD/gUYA/4FGAP+ARgD/gEUA/39E
+ AP9+QwD/fUYB/3pGA/94RAH/dkIA/3ZCAP94RAH/e0YD/3xHBP93QgD/eEMA/3tEAf98RQD/fEUC/3tE
+ AP9+RAL/fUYB/39IBf98RQD/eUIA/3lDAP98RgD/gEgB/35GAP97QwD/fEUA/3tEAP98RQD/fUYB/3tG
+ A/97RgP/eUUD/3tEAP9/QwD/gkUA/4JFAP99RQD/dkIA/29BB/9tRRT/bkwh/490Uv/Pup////Ld////
+ 8v////f///rz//349f////7/+/////r////7/v//+fz///z+///9//////////7+/v/////////+////
+ /v////7////8/////P////z////8////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////3////9//////7////+/////////////////v////7////+/////v////7////+////
+ //////////7///////////7///////b5/f/1+P//+vz///r9///29/v///76////9f///+7//+zN/8Sq
+ hf+DYzj/Y0AU/2U+Ef9uRA//dUUD/3pEAP9/RwD/hEkD/4JHAf+BRgD/gEUA/3tDAP98RgD/ekYA/3pG
+ AP96RgD/fEcA/35HAP+ARgD/gEUA/3g/AP96QAD/fkQC/4BGBP+ARgT/fkQC/3xCAP97QQD/gEYE/39F
+ A/9+RQD/fUQA/3xDAP+ARQD/g0gD/4RLBv97RAH/e0YD/3tGA/96RQL/eUUA/3lFAP96QwD/d0AA/35H
+ Av9+RwL/f0YB/39HAP9/RgH/f0cA/4FGAf9+RgD/d0AA/3tFAP+BSQL/g0wD/4FKAf+BRwD/gkgA/4JI
+ AP+CSAD/gUcA/4FHAP+BRwD/gkgA/4NJAP+CRwD/gUYA/4VLAP+ESgD/hEcA/4FHAP+DSQH/hEwF/3pF
+ Av9tPAD/aj4I/2pEFP+GZj3/xquJ///u1f////D////0////+P/9+fj/+fv8//r9///7/v//+v7///j9
+ ///6/v///f///////v////v////7////+/////z////8////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////f////3+/////v////7///////////////7/////
+ /v////7////+///+///////////////+/////v////7///r8/f/7/v//+v7///r9///7/v////7/////
+ +/////T/9uPI/62Sbf9uTB7/aEAL/3RHDv9zQwn/cEAG/3VEBv93QQD/fEUA/4FIA/+ARQD/fD8A/4FD
+ AP+FRwH/gEQA/4BFAP+ARQD/fkYA/35GAP9+RgD/fkUA/4BFAP+ARQD/g0kH/4FHBf9+RgX/fEQD/3lD
+ BP94QgX/eEQI/3hIDv9wPwf/cEEL/3FCDv9wQxD/bUIR/2tAD/9oPg//Zz4N/3RMGP97Ux//glom/4Rc
+ KP+DWyb/flYh/3dNGP9vRRD/bUEM/21BC/9sQAr/az8J/29BC/9xRAv/b0EL/20/Bf96SAb/ekYD/3hE
+ AP92QgD/eEIA/3lDAP98RQD/f0UA/4FHAP+BRwD/gUcA/4BGAP+ARgD/gUcA/4FGAP9/RQD/dj8A/3pD
+ AP+BSQL/g0kB/39FAP9+QgD/f0UA/4RKAv+BTAn/bTwA/29DDf9oQhL/akoh/7WaeP//8tT////r////
+ 9f////n////+///+///6/v//+P7///r////5/v3////8////+f////j////5/////P////7///7///3+
+ /////v//////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////v////7////+
+ /////v////7///////////////////////////////7////+/////v///f7///3+///7/v//+v7///r+
+ ///7/v///v7+////+/////X/7drF/7GVdv96Vyv/ckgT/24/Af91QQD/ekMA/35FAP9/RgH/eUMC/3tF
+ CP91QQX/eUIF/35FB/+CRgT/hEUB/4RGAP+AQgD/g0UA/4FFAP+ARQD/fkUA/3xEA/96RAX/ekMG/3pD
+ Bv96RQb/dkAD/3E9Af9uPgT/ckMP/3tQH/+HYDT/jWxF/6SFZP+tknf/vqiP/9G9q//i0sL/8OLW//ru
+ 5P//9Oj///Ti///35P//+OL///Te///z3v//9N////Td///x2v//7Nb/9+PK/+bSuf/RvaT/v6mQ/6uW
+ e/+WgGf/jnRQ/4NbJv+CUxX/dkcJ/3FCBP91RQX/eEgI/3pIBv94RgT/eUUD/3pGBP97RgP/eUQB/3tE
+ Af98RQL/fEUC/3hEAv93Rgj/ckMG/3RBAv95RAH/fUYB/4BGAP+BRwD/gkgA/3g+AP+IUAn/eEQC/24/
+ Av93SxX/akIO/4FbK//EpHv//+jK///55P////X////6//j6+//4/v//+P7///r///////z////5////
+ +P////n////8///+///7/f//+v3///3/////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////v////7////+/////v////7////+/////v///f////3////9/////f////3+
+ ///9/v//+/7///3+///////////7////+P////T/+ejT/7ykhv9/Xjf/Zj4O/2o9BP92QwT/gEkE/4FH
+ AP9/RQD/g0kA/4RJAf96QQD/ekUG/3dEBv96RQb/fEQD/3xCAP+ARQD/gkYA/35DAP+ARQD/fEUC/3lE
+ Bf91Qwf/cUIK/3BBDf9sQRD/akAR/3tUJ/+MZzv/q4hd/86uhf/ry6j//ODB///u1P//+OH////v////
+ 9f////j////8///+/v/9/P///Pz///3+///9/f3////+/////v///vr///79/////P////z////7////
+ +/////j///75///+9/////n////4///68///8+P///DQ///iu//nyaD/x6d8/6aFWP+HZTf/dE4e/2pD
+ D/9qQAv/b0MN/3NFC/9zRAf/dUQG/3hFB/96RQb/d0QG/3FCBf90RQj/eUYH/3hEAv95RAH/fkcC/4JI
+ AP9/RgD/g0gA/35EAP98RQD/fEcE/3VCA/9wQQP/c0MJ/29DDv+IYTX/yKiF///v1f////H////5////
+ /v/7////+P38//3//v////v////5////+////////f7///r8///6/P///f7/////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////9/////f////3////7////+/////v+
+ ///7/v//+Pv///v+///7/v//+v7///j8/f/7//////79////9f///un///je/9vAnv+GZDn/Zj8L/3RH
+ Dv9xQAL/d0MB/31GAf9+RQD/fUUA/4JHAf+CRwH/fkMA/3tDAP9/SAD/fEcA/31IAP9/SgH/fUgA/3tF
+ AP95RQD/eUgE/3NEBv9vQwj/akQO/2hHFv9qTSH/f2Q//6yTcf/QvqH/8OLQ//zz5v////X////1////
+ 9/////f////4///+9/////n////7/////P////z////+/////v////////////3////7/v//+/7///v/
+ ///9/v///f////3//////////////////v/////////+/////v////z////+/////v///////v/9////
+ +/////n////1//704//p2MP/2MKm/6qOa/+IaD//b0gb/25DEP9xQgr/cT8D/3RBA/98SAb/ekUC/3tE
+ AP9+RwL/f0gD/3hDAP93QgD/ekUC/3xIAv97RAH/fEcE/3xHBP94RAL/eEQC/3tHBf96RgT/dEED/3ZD
+ C/9rPQ3/jWo//9zBn////OX////0////9v////z//P/9//r9+////////f////3+///7/v//+/3///f5
+ ///9////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////7////+//3/
+ /v/9////+/////r////6////+v////b7/v/6////+/////3////7/Pr////+/////P////b////o//fX
+ s/+dek7/YjsH/2xABf96Rwj/d0MA/4JMBf+CSQT/fkcC/3tEAf96QwD/fEMA/3tDAP9/RAD/iE8E/4FI
+ AP99RgD/eUQA/3ZEAP90RQH/c0cH/29GCP9nQgr/YT4M/3JSJ/+XfVj/ybSU//fmy////+v////u////
+ 9P/7+vb//f////3////8/v7/+fv7//7+/v/////////+/////v////7////+/////P////z////8////
+ /P////7//f////v+///7/v//+/7///3+///9/v///f////3////9////////////////////////////
+ /v//////+/7///H7///u+///8vz///b+///6///////+////+P///fD////w///+4///5sf/1raS/557
+ UP95UiX/a0MT/2s/Cf92RQf/eEMA/3hDAP96RQL/e0YD/39KB/9+SQb/eEMA/3lEAf94QwD/eUQB/3tG
+ A/96RQL/d0IA/3lEAf9/Sgf/dz8A/4BKDf9xQgz/aEIS/5x9Vv/t2br////u////8/////v//f////v+
+ ///6/v//8/b7//b2/P/9/v////7////+////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+/////P////z//f/+//3////7////+v////r////6////+v////v///////z/+fbx////
+ +P///vP///vu///y2/+4l3D/dUoX/2Y5AP+CURP/eUUC/3M9AP+ASQD/e0MA/3lCAP97RgP/e0UE/3tF
+ BP9+RwT/f0QA/35EAP+BRwD/fkQA/4ZQCf93RQP/bUEC/3BJEv9jQhH/cFQr/6SMaP/kz7P/+enS////
+ 7/////T////1////9P///vT//Pz2/////P////7////+/////v/+//3////+/////v////z////8////
+ /P////z////8/////P////v////7/////P////////7////+/////v//////////////////////////
+ //////7////+/////v////7////8/////v//////+v3///j+///6////+f3+//n7/P/9/f3////+////
+ +/////j///70////8f////L////x///w3f/Ou6b/oYdp/3JOIP9zRxH/dEYM/3ZHCv92QwT/dkEA/3xE
+ AP9/RQD/gEYA/4NJAf+CSAD/fkYA/35HAv9+Sgf/eUQF/3A8AP9+RwT/eD4A/3VAAP95SQn/cUQL/3FN
+ Hf+ymHT///fd////9//z8fD/+v////X7///7/v////7//////v////z/////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////7////8/////P////7//f////v////6////+v////r/
+ ///9///////7////9/////T///7r////7f/Vwqf/fmI//2lAD/94Rgz/dkME/3E9AP94QgD/gksC/4JL
+ Av9+RgD/ekMA/35IB/97RQb/dkAA/3lDAv9/SAP/f0gA/3pEAP95Rgj/azwE/21CD/93UyX/kXRN/8m0
+ lP/97db////t////9/////n////8///69//++vn////+/////v/9//7/+/39//r8/P/8/v7/////////
+ //////7//v7+//7//f////7////+/////v////7////8/////P////z////8/////v////7/////////
+ /v////7////+/////v////7////+/////v////z////8/////P////z////8/////P///v3////+////
+ /v////7////+/////v///fz//fv6/////v////v////8/////P////v////7////+f///O7///LW/8+w
+ if+ObEH/ckwc/3BEDv90RQj/fEcE/39HAP+CSAD/gEYA/4BGAP+BRwD/eUIA/3M+AP91QgP/gEwK/3xF
+ AP+DSwT/gUcA/31FAP96RQL/b0AD/3FMGv+CZ0L/2six////9f////z////////9/f////7///34///+
+ +f////7/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////v////z////8////
+ /v/9////+/////v+///7/////f//////+/////f////x////5v//8dH/qo1o/2pIHf9sRBT/cUIM/3hE
+ CP93RAX/eEcD/3xJA/97RwD/eEQA/3pEAP95QgD/fEQD/3xDBf95QwT/eUQF/3ZDBP9zQwP/ckYL/2c/
+ Ff94VTT/spR3/+7Wvv//9uX////1////+f///v3//fj6///8/////P////3////+/////P7///7+//3/
+ ///6////+P7///j+///6/v//+f3///j9///5/f//+v////v+///7/v///f////3////9////////////
+ ///////////+/////P////7////8/////P////z////8/////P////z////8/////P////z////8////
+ /P////z////7////+f////n////4////+f////v////7/////P////7////+///+/f////7////+//78
+ +//8+vn////+////+/////b////y////6v/v2b3/spVw/39bLf9uQgz/ckED/3ZBAP99RQD/gEgB/4BI
+ Af9+RwL/e0YD/3lFA/94RAL/dUEA/35IAf99RgD/fkQA/4FKAf93QgD/ajsA/2lAD/9yUSr/r5d7///z
+ 4P//++3////3////+P////j////5/////v//////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////v////7////////+///9/v///f7///3///////7////5////7////+3/9tu5/4hl
+ Ov9oQAz/ckUM/3A+Av92QAP/ekQF/3pGBP92RQH/dUQA/3lHAP98SAH/fkgB/4RLBv9+RAL/ekED/31H
+ C/92Rw//aUEM/29KGP98XDP/yq+V///r2/////L////0////+f////v/9fX1///+/////f////v///35
+ /////f////3////+/////////f////v+///6/v//+v7///r+///7/v//+v3///v+///7/v//+/7///v+
+ ///9/v///f7///3////9/////f/////////////////+/////v////7////+/////v////7////+////
+ /v////7////+/////v////7////+/////v////z////7////+f////v////7///9+v/++/f//vz7///+
+ /f/9/f3//f39////////////////////////////+vr6/////v///Pj///v0////9P///+7//+rO/8Om
+ gf+FYjb/bEQQ/3FEC/90QwX/dUID/3dCAP96QwD/ekMA/3pDAP98SAL/ekYA/3hCAP99RQD/gkoD/39G
+ Af95QwL/f0wO/3BBC/9mPg7/jWxF//bewP///+7////x///+9P/+/fn////+////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////+/////v////////7///3+///9/v////7/////
+ /P////f///Xi/7yihP9pRR3/az8K/3lGCP9/RgH/gUYA/4JHAv9+RQD/eUQB/3hFAP94RQD/fEgB/35K
+ AP97QgD/eT4A/4FEAP9+RQf/cD8H/2Y/Ev+BZkH/zbue////7v///vL////2////+P////n////7//3/
+ +//9//z////+/////v///f7///z9///9/v/9/f3/+vz8//n//v/7/////P37///+/f///v////7////+
+ /////v/////////+/v///v////7////+/////v////7////+/////v////7////+/////v////7////+
+ /////v////7///3////9/////f////3////7////+/////v+///7/v//+v////v////9/f3///7+////
+ //////////7///3////9/v//+/7///v+///7/v//+/////v9/v/5+/v//f///////v////7/////////
+ //////////38///9+P////j////1///04f/DrpP/jHBN/147D/9jOQT/ekkL/4BJBP+BRwD/gkgA/31I
+ AP97RwD/d0MA/3ZCAP96RgT/fUcG/31EAP95PgD/gEQA/4RKCP90Qgj/cUsb/8ivj////ev////7//v/
+ ///9////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////7////+////
+ /v////7///////3////9////+/7///3////////////+/////v////7//////////v////z////+///+
+ /////v///f3////+//////z////1//Xgyv+dgV//Y0AU/29FEP93RQn/eEEA/35EAP+FSAD/fUMA/4FJ
+ Av99RgH/e0QA/39IA/97RQD/eEIA/35IAf+ASQb/dUIE/3RFEf+XcUf/172f///24/////j//vv3////
+ /v////z////8////+v/9//f////7//3/+//+//v///38/////P////z////8/////P/8//3/+P////r/
+ //////7////8///++////Pn///36/////P////7///79/////v///v//////////////////////////
+ //////////7////+///9/v///f7///3+///9/v//+/7///v+///7/v//+/////v////7////+/7///v+
+ ///6////+/7///3+///7/f7/+fr+//z9///9/v//+/7///n8///5/P//+v3///n8///7/////f////z+
+ /v/7/f3////+/////v///////Pz8//v9/v/9////+/3+//3////////////7////9//87tv/yrSY/4hp
+ Qv9oQA//b0EH/3tHBf94QgD/ekQA/3lFAP96SAb/d0cH/3VCBP95QwL/gkcB/4dIAP+JSQD/hEYA/31E
+ AP9wQgj/aEca/6CLbP/q4M7////3/////P////7////+/////v////7//////////////////f////3/
+ ///9/////f////3/////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+/////P////n////5////+/////7/+/7///j+///2/f//9vz///v9/v////z////7////
+ +/////7///76////+/////z///7///f5///6/P///v3/////9f/p07f/gl4w/3FFCv91RQP/dEMA/3VE
+ AP98Swf/d0MA/3xIAf94RAD/gEoD/4FJAv97QAD/gUYB/4FHBf91PwD/dkQI/2xCDf+EYzb/y7KQ///3
+ 4P////f///38//v9///6/P///f7//////v////v////4////+P////n////8/////v/////////+////
+ +/////v////7/////v/6////+v7///////////7////+/////v////7////+/////v////7////+////
+ /v////7////+/////v////7////+/////v/////////////+///9/////f7///v+///7////+/////3/
+ /////////////////////v////7///3////9//////7//////////v////7////+///9/////f////3/
+ ///9/////f////3///////////////////////////////////////////////////////7////+////
+ /v////z///75////9v////T//+/Y/8Sri/9/YDn/ZUET/3BEDv95QwL/gEcC/3lFA/95SQn/dEEC/3tF
+ BP99QgD/hUgA/4RJAP+BSQD/fkcC/3FBAf9vQgn/aUEQ/5JwQv/w2LT////0////+/////z/+/j0////
+ /P////7/+vr6//3////7////+/7///r+///6////+/////3///////7////+////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////7////8////+f////j////5/////v/7/v//+P7///b9
+ ///4/v///////////P///Pf///75/////v///v3///35/////P/6+fv///7////+/////vT/1b6k/3FP
+ JP9xRQr/d0QA/39LAP96RgD/eUUA/3tIAv9xQAD/eEQB/3tHAf93QQD/gUoF/3xFAv99RAb/eUQL/20+
+ Cv98VSj/vaB7//zny/////D///7z/////v/7/v//9vj///j8///4/f//+/7//////P////n////5////
+ +////////f////3////////////7////+f////n////8//v+///6/v///f//////////////////////
+ //////////////////////7////+/////v////7////+/////v////7////+/////v////////7///3/
+ ///7/v//+/////v////9/////////////v////7////+//////////////7////+////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7////+/////P////z////+/////v////7////8////+P////X////w//3ozf+wl3f/akcf/3RF
+ Ef9vOwD/fksN/3RBAv98RgX/fUYB/4JIAP97QgD/fkUA/3pDAP9/SAP/e0cE/3xJCv92RQf/b0AD/4Bb
+ Kf/axan//vTj////9/////n/+fj0//7+/v/9/////f////3////7////+/7///v+///7/////f//////
+ /v////7/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////7////8////
+ +/////z////+//3////7/v//+fz///3///////7////8///9+f////7/+/7///r////7/////f//////
+ /v////b///7p/7qcef9iOgr/dUgP/3FCBP95RwX/ekYA/3hDAP+CSQD/gEkA/3lFA/+ASwz/gkkE/39H
+ AP90PgD/eEYK/2s/Cv9kPxP/pIdi//Pbvf///Of////y////9/////v////+///////8+/3/+v7///T9
+ ///0/f//+v7///////////////////r+///6/v//+v7///3///////v////4////+P////n///////3/
+ ///9/////f/////+///9//////7///3////9/////f////3+///9/v///f////3////9/////f/////+
+ /////v////7////+/////v///f////v////7/////f////3////////////+/////v////z////+////
+ /v/////////////+///9/////f////3////9/////f////3////9/////f////3////9/////f////3/
+ ///9/////f////3//////////////////v////7////8/////P////7///////z8/P/////////8///6
+ 8/////T////x///95v/24MT/k3dU/188Ef9xQQ3/fEUI/3g/AP+FTgX/eEMA/31JAv+CSQT/eUAA/4BH
+ Av93QwD/dEMA/3tLCf92QwX/azwE/3JPI//DqIb///rl////9f////7/+f7///n8///2+vv////+////
+ /P////7////+///////9/////f////3/////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//////////////////////////7///76/////P////z////+//3/
+ ///6/v//9vz///j////3/Pr////z///64P+ggFf/ckYR/3dGCP94RAL/e0cF/3xIBf96RgD/gksC/4RJ
+ Af97QAD/eD8B/3dBAv95QQD/dT8A/35OFP9mPwv/eVsy/9rDo////+n////0////+P/+9/T///z7////
+ /v/79/b///76////+//3+vj/9v7///b9///7/v/////////////9////+v7///j+///6/v///f//////
+ /P////n////5////+////////f/////+//////////////3////9/////f7///3+///7/v//+/7///v+
+ ///7/v//+/7///v+///9/////f7////+/////v////7///3////9////+/////v////9///////+////
+ /v////7////8/////P////7////+////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////+/////v////z////+////
+ ///9/////f////3////9///////+////+f////b////z////7v//9uP/3MSo/31XLf9wQQv/eEME/3hE
+ AP9+SgP/fkoE/3xHBP95QgD/gUoH/3tHAf90QAD/ekYD/35IB/9+SQr/cUEH/2tDEv+vlXH///bg//77
+ 8//9////+/7///3///////7////7////+/////v////+///////7////+/////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////9/////f////3+///7/v///f////////////7////8////
+ +////vn////7/////v/8/v//+Pv///j8///3/f//8vr6////+P/86Mn/nXtN/3FDCf98SAb/f0oH/3Y/
+ AP9+RgD/fkQA/4BGAP+DSAL/e0EA/3pAAP+DSAr/fkUI/3hCBv92RxH/aUMT/6qNZv/+7tH////v////
+ 9/////7//v3////9/////f////7////+/f////v////4////+f////7////+////+/////n////5////
+ /P/9////+/7///r+///7/v///////////v////7///////r+///6/////////////v////7/////////
+ ///9/////f////3////9/////f////3////9/////f///////////v////7////+///9/v///f////3/
+ ///9/////f////////////7////+/////P////7////+/////v////7///////////////7////+////
+ /v////7////+/////v////7////+/////v////7////+/////v////7////+/////v////7/////////
+ //////7////+/////v////7///////3////3+v7/+Pz///r+///7/v//+fn5///9+f////v////5////
+ 9/////L/9eLH/5qAWP90TRn/cEEE/3tGA/9yOwD/eEUA/3dGAv97RwT/e0YD/39FA/+ARQD/eUEA/3tD
+ AP+ARwL/ekoK/2U9DP+bgV3///Th///99v///////f///////v////z////5////+P////v////+//v+
+ ///6/////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////3////7/v//+v7///r+
+ ///7/v///////////P////n////5///++f////7//f////n8///4+////////////P////f/8OTM/49y
+ Rv91SQ7/ekUC/31FAP93PwD/g0sE/4NJAf+ARgD/gEYA/31CAP95QQD/gEcK/4BHCv9yPAX/c0UW/35a
+ Mv/Wupf////l////6/////T/+//+//X8///4+///+vv///j1/v/++v////7/////+//7/PP////4////
+ +/////v////5////+f////n////7///////7/v//+/7///v+///9///////////////9////+v7///r/
+ ///////////+//////////////////3////9/////f////3////9/////f////3/////////////////
+ /////////f7///3+///9/////f////3////////////+/////v////7////+////////////////////
+ /////////////////v////7////+/////v////7////+/////v////7////+/////v////7////+////
+ /v////7////+/////v///////////////v////7////+///////9////+/////v+///5/f//9fv///n9
+ ///7/v///f/////////7+fj////8///99v////T///rg/8qwjP9+WCj/ckEJ/4BLDP92RQH/e0oG/3ZE
+ Av90PgD/f0UD/4ZJBf+CRwD/g0kA/35EAP96RAD/dUYI/2c/Dv+Td1T//u3Y////9v////z////+////
+ /P////n////5////+/////7/+/7///r+///9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////f////v+///6/v//+v7///v+///////////7////+f////r///79//v+///6/v//+v3/////
+ /v////j///zp//fhvv+Kaz7/aUEM/29AA/98RwT/fkYA/4JKA/9+RgD/f0YB/35GAP+DSQH/gEUA/4NJ
+ B/97RAf/azcC/29EGf+IaUr/9uDH////7v////L////3////+//7////+v////n8///7/v////3////+
+ ///5+fn//P37//3//P/8//v////+//////////7////+/////v////7//f////v+///7/v//+/7///3/
+ ///////////////////9/////f/////+//////////7///3////9////+/7///v+///7/v//+/7///v+
+ ///9/////f/////////////////////////9/v///f7////+/////////////////v////7////+////
+ ///9/////f////3////9//////7////+/////v//////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////3/
+ ///7////+fz///b6///6/v//+v7///r+///4+///+/7///3///////7////8//v49P////j////x/+/a
+ u/+La0D/ZT4H/3BBA/98SAb/e0cF/3pEA/98RQL/f0QA/4RFAP+DRAD/g0gC/3pEAP9+RgD/fEgG/2o+
+ CP+TcUb//OjP////9f////z//////////P////z////8/////v/7/v//+/7///3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////9////+/7///r+///6/////f///////v////v////5////
+ /v/9////+P7///X7/////v/////4///65//+5MD/gFgj/3JDBv93SAv/ckED/3pEBf9/RQP/ej8A/4FG
+ AP97RAD/fEUC/31GAf92QQD/ekcI/29ACP95TyL/uJl4////7/////f///30////+P////r/+//6//3/
+ ///5/f7/+/////n8///8/v///f////3////9////+/////v////9/////f//////////////////////
+ /////v///f////3////9//////////////////7////+/////v///////f////3////9/////f////3/
+ ///9/////f////3////9/////f/////////////////////////////////////+/////v//////////
+ /v////7////+/////v/9/////f////v+///7/v//+/7///3+///9//////7////+/////v///f////3/
+ ///9/////f////3////9/////f////3////9/////f////3////9/////f////3////9////////////
+ /////////////////////////f////3////7/v//+/7///v+///5/P//+Pv///v+///7/v//9/r+//j8
+ /f/9//////7//////v///vf////y///83/+ymW//cEgX/3BBCf92QwX/f0sJ/3tHAf96QgD/h0gA/4hI
+ Af96QwD/fkcC/35EAP+BRwD/gUoF/2o+A/+Ja0L/+ejO////9/////z////+//////////////////v+
+ ///7/v///f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////3////9////+/7///3/
+ ///////////8////+/////z//f////j+///0/f//+P7////7+P////H//+XC/4BYJP98RQL/gUYA/3tF
+ Bv94RQf/e0UJ/3tCBP9+QwD/gEUA/3xFAP97RwT/cUAC/3NHDP9nPwv/fVou/+HDoP///+r////4//3/
+ ///9//7////+/////v////7////+/////v/9//7/+//+//v////7////+/////v////9/////f////79
+ //////////////////////7////+///7+v////z////8/////P////7////+/////v////7////+////
+ /v///////f/////+//////////////////////7////+//37+v////7/+/n4/////v/+/Pv////+///+
+ /f/////////////////////////+/////v////7////+//3////6////+v7///n9///6/v//+Pv////+
+ /////////vz8////////////////////////////////////////////////////////////////////
+ /////////////////////v7///38//7+/v//////9/n6//z+///9/////P7///3////9/////f////3/
+ ///9/////f////3////7/v//+P7///r//////v/////+////+/////f////z////7f/Uupz/e1ku/2o+
+ CP91QgP/gUoF/39EAP+AQgD/f0QA/3lEBf94RAL/gEYA/4RIAP+DRwD/f0gD/21CCf+IaD//+eXM////
+ 9////v3/+/z///j7///7/v//9fj8//3/////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////f////3////9/////////////P////z////8/////v/7/v//+P7///b9///9///////1//3l
+ x/+FXy//eEUH/4JHAP+ERQD/fEIA/3lDBP97RAf/fUQH/4FFA/+CRwH/ekMA/3FBAf9sQwz/Y0IU/4Vr
+ Rv/u2rv////r///97P/9//7/9v////r////9///////////+//////7////+//3//v/7//7/+v/+//r/
+ ///7/////f/////+/////v////7///v9/v/8/v///f////////////7////7////+f////v////7////
+ /v////////////////////7////+/////////////////////v////z////8////+/////v////7////
+ /P///fn////+///////9////+vz9//3//////////////////v////7////8/////P//////+/////r/
+ ///1+///9vr///r9///////////8////+////fj////+/////v/////////+//////////7/////////
+ /v/////////+//////////7//////////v/////////+/////P////z////+//v7+//9/////f////j6
+ +//9//////////////////7////+/////v////7///////3////4/v//+P7///3///////7////8////
+ /P////r////3///+7v/jzrL/j29E/2pAC/9xPgD/fUYD/4NIA/+CSAb/ekYE/3hEAv98RQD/gkgA/4BG
+ AP+DSQH/cj0A/3JGEP+IaUL//+zT////9///////9/v///f7///9/////f39////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7////8/////P////7///////n9
+ ///6/v//+Pr7////+f/7587/k3FG/3VGCf94QQD/gUYB/35DAP+ARQD/gUUD/31DAv98QgH/f0MB/3tC
+ AP+BSgX/dUgL/19AE/+Pe1z/9e7b////9f////L////3//v//v/4////+//////+/////v////7////+
+ ////////+/////j////4////+P////3///////7////+///+/////v//+v3///r+///7/v//+/3+//v5
+ +P///vn////3////+f////v////+//3////7/v//+/7///3//////////////////v////7////8////
+ +/////n////5////+f///fX////6/////v/9////9/v///j+///y+f//9/3///3////////////+////
+ /P////z////8///////7////+f7///j9///7/v/////+////+////fP////x////9P////n////8////
+ /v////z////+/////P////7////8/////v////z////+/////P////7////8/////v////z///z3///8
+ 9/////z////+///////9/////f////z+///////////+/////P////z////8/////P////7///////v+
+ ///6/v//+v////v//v////z////8/////v////v////5////9P/4583/kXRP/2o/Dv96RQz/eUMC/3Y/
+ AP9/SAP/e0YD/3ZDBP94RQb/dkEA/35HAv+BRwD/fkcC/21AB/+Ydkv//u3Y////+P/9////8/f8//3/
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////+////
+ /v////z////8///////9/////f///////v////j//ezX/4xvSv9qQg7/ekUC/4ZMBP98RQL/fEQD/4BG
+ BP+BRQP/fkIA/4BEAv+CRwL/eUIA/24/Af9tSBT/pZFu//nv3f////n//f/+//z89v////v/+//+//r/
+ ///9//////7////+/////v////7///3////6////+P////j////6/////f///////v////z////+////
+ ///8/v//+/7///z+//////z////4//Hj0f/+7dj//OrT//rq0//36df/8+ja//Po2v/z6Nr/9+nX//fp
+ 1//16df/9enX//fp1v/46tT/+urT//zr0f/869H//OrT//vt1//47Nr/7+fa///89f/9+/r//f////r+
+ ///6/v///f////////////7////8/////P////z///////v////7/v//+////////v/++PH/8ebY//7r
+ 1v//7tL//+rO//zp1P/46db/+OnW//jp1v/46db/+OnW//jp1v/46db/+OnW//jp1v/46db/+OnW//jp
+ 1v/46db/+OnW//fp1//37N7////2///68/////z///////n7/P/8/v///f////////////7////8////
+ +/////v////8/////P////7//f7///v+///6////+////////v////7////+/////v/8//3////7////
+ 9f//897/nn5b/3FHGP9xQQf/ekYD/3tDAP96QwD/cUAC/3ZHCv94Rgr/ekQD/4FHAP+CRQD/gUoF/21B
+ C/+VeVb///fl///9+P///////fv6/////v//////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////7////+/////v///////////////v///fj///vu///+5f+WeVT/aUEQ/3BB
+ BP96QwD/fkYA/3tGA/95RQP/eUQF/3lDAv+AQwD/g0cB/4FGAf9zQgT/aUUV/7ulgv//+eX////3////
+ +//2+ff/+/////r+///////////+/////v////////7////+/////v///f7///r////6////+v////v/
+ ///////////+/////P////z///35/////P////z////5////8P/34sf/cFEq/2tFFf9zSRT/c0oT/3FJ
+ Ff9wSBf/cEgX/3NJFP93ShH/dUkT/3BIF/9uSBj/cEgX/3FJFP9zShP/c0oT/3NKE/9xSRX/bEYW/2hI
+ Hf92XDj/8Nu/////8P////T///zz///++f////////7//////v////7////8/////P///////f////X3
+ 9/////v///73/9bJuf9pVDn/XkIf/2xHG/9zSxr/cEgX/3BIF/9wSBf/cEgX/3BIF/9wSBf/cEgX/3BI
+ F/9xSRj/cUkY/3FJGP9xSRj/cUkY/3FJGP9xSRj/akgd/1pGLf//+uz////3///89f/+/Pv//f////z+
+ ///8/v///////////v////z////8/////P////z////+/////v/////////////9/////v///f////v/
+ ///9//7////8/////v////7//fn4////+P//++j/qZBu/2xEFP93RQn/gUgD/4RMBf9zQgT/bkAG/3ZG
+ DP92QwX/fkMA/4BDAP99QgD/ekYE/2xEE/+kiWf///nm///+9f////v///z7////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////3////9///////8////
+ 8////+v/qYpj/2lBDf92Rwr/e0YD/4BJBP96QwD/eUUC/3ZEAv93QwH/ekUC/4FGAP95QAD/c0AB/3JK
+ Fv/FrIr////r////9f////v////7//b4+P/6/v//+fz///////////7////+/////////////f////3/
+ ///9/////f////3////9//////7////+/////////////////v///v3////8////+/////j////w///v
+ z/9lPw//cUIF/3pFAv98RQD/ekUC/3pFAv96RQL/fEYA/4FHAP+ARgD/ekUC/3dFA/95RQL/ekYA/3xG
+ AP98RgD/fEYA/3lFAv90RQj/a0EM/2pJHP/64Lz////r////8f////b////7///+///9/v//////////
+ /v////7////+/////v////7////+////+f////T/3822/2BEIf9oQhL/dEYM/3ZBAv95RQP/ekUC/3pF
+ Av96RQL/ekUC/3pFAv96RQL/ekUC/3pFAv96RQL/ekUC/3pFAv96RQL/ekUC/3pFAv9uQgz/WT4c////
+ 8P////H////4/////P/8/v//+Pv///v+///9/////////////v////7////+/////v/////////////+
+ /f////7///7////9///9/v//+/////v////7//7//f39///9/f///v7////8////8////ef/uZ17/3FJ
+ Gf9yPwH/fEUA/31ICf9yQQP/dEIG/3dEBv+ASQb/hUoE/39EAP98QwD/d0gL/2lBEf+2m3n////w////
+ +P////z////+////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////3////9/////f////3/
+ ///7/v//+/7///3///////v///vo/9S5l/9oQAz/eUYH/3xFAP9+RgD/eEMA/3lFAv90RQH/d0cA/3xF
+ AP+DSgD/f0cA/3A/Af+DXiz/s5d0////6P////P////5//Tz7////////f7///v+///9/f////7////+
+ //////////////3////9/////f///////////v////7////+/////v////7///3+///6////+v////r/
+ ///7/v///f7/////+////u7//+nL/2M/Ef91Rw3/ekUC/3xFAP95RQP/eUUD/3lFA/96RQL/gEUA/4BG
+ AP96RgD/ekYA/3xGAP9+RwD/gEYA/4BGAP98RgD/eUUC/3BDBv9sRRH/cVIr//Ldwf///+3////5//v9
+ /f/5/v//+v7///v+/////v///////////v////7////+/////v///Pf////3////8P/hyav/aUUX/29B
+ B/+ARwL/gkgA/35GAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3FDCf9ZPBf////r////8f////f///z4//v9/v/7/v//+v3///v+///9/////f//////
+ /////////f////3//////v////79///++/////z////+///+///9/v//+v7///r+///6/////f//////
+ +/////b////1////9P///Oz/v6qL/3lOG/9tOQD/f0gF/4RLBv99RgP/eEIB/3pFBv92QQL/gksI/3lC
+ AP97RAH/dUQG/3NLG//RtZb///7w/////P////7/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////f////3////9////////////////////////////////////////////
+ ///////////////////9/v//+/7///v+///9///////8////9f/eyKz/akYY/3dEBv+CSAD/gUcA/39F
+ AP98RwT/eUUC/3pIAP97SQD/fUQA/3xGAP9yQwX/bkkX/7KXdf///+7////1////+f////z////+//79
+ ///6+///+/v////9/////v////7//////////////f/+//3//v////7////+///+/////v////3////+
+ /////v//+/7///j////4////+v7///j8///3+///////////9//+6c7/akQU/3FAAv96RQL/fEUA/3lF
+ A/95RQP/eUUD/3pFAv98RQD/fkYA/3xFAP96RgD/fkYA/35HAP+ARgD/gEYA/35GAP96RQL/dkcJ/2M7
+ Bv9tUCn/7tvA////9f////7/9/z///j+///6////+/7///3//////////////////v////7////+////
+ +/////f////x/+DHp/94UBz/eUUD/4JFAP+FRwD/gEYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35G
+ AP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/c0QH/2FBGP///+j////x///68f////z//f////r7
+ ///7/v//+/7///v//////v////////3////9/////f/////+/////v3///77////+/////z///////3/
+ ///7/v//+v7///j9///9///////7////9v////j///30////+f////L/vqB9/3VKF/90QQP/f0gF/3tC
+ AP95QgD/fEcI/3ZDBP94QQD/gUkC/4NIAP96QwD/cUIK/3FPJP/r1rv////0////+//////////+////
+ /v////7////////+///9/////f////3///////7////+/////v////7///////3/////////////////
+ /////////////////////////////////v////7///////3////7////+/////v+///9////////////
+ //////7////+/////v////7//////////v///fz////+//r9///6/v//+v/+////+P////T/69i9/3pY
+ Lf9tPwX/gkcA/4hIAP+ERwD/f0QA/39IBf97RAD/hEgA/35EAP97RAD/cEMK/2tIHf/AqIr////x///+
+ 9f////z////+/////v/////////////+///9/v///f7////+////////////////////////////////
+ ///////////////////////////////////9/////f////3////9/////P7///v+///9///////6//vp
+ 0v9pQQ3/e0YD/3xFAP98RQD/ekUC/3pFAv98RQD/fEUA/3xFAP98RQD/ekUC/3pGAP9+RgD/fkYA/3xF
+ AP98RQD/fkYA/3xFAP96RQL/cUMJ/3BOI//y3cL////3//7+/v/9/////f///////////////f////3/
+ ///////////+///////////////8////+f////f/3Miv/3NLF/96RQL/f0QA/4BGAP9+RgD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwb/Y0AU////
+ 5f////j///79//////////////////3////9/v///f///////v////7///////3////9////////////
+ //////7////+/////v////////////3////9/////f////////////7////8/////P////z////+////
+ +/////L/uqSI/2VBE/90RAr/eUQB/3xEAP+ASQT/fEUA/4BFAP+DSQD/gUcA/3xDAP91Rgn/aT8K/4Je
+ MP/+4sP////1/////v/7+vb////7/////P///////v3///v+///4////+v///////P////n////7////
+ /P/9////+v////3////////////////////////////////////////////+/////v/9/////f////v/
+ ///6////+/7///3////////////+/////v////z////+/////v///////////////v/++fr//f7///j8
+ /f/7/Pj////1///w1v+Mckr/akAL/3RAAP+HSQL/h0YA/4RGAP99QgD/f0UD/3pBAP9+QgD/ilAI/3FC
+ Bf9nQBP/xqyO////7v///PX////+///+/////v/////////////////////////+///9////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ///////////////////////////+////+///+ur/spd1/21HF/9wQQT/e0YD/35GAP99QwD/gEYA/4JI
+ AP+BRwD/ekMA/3lGB/9zRgn/ckUM/598UP//7tz////5////+f////n///z4/////////v//+/7///j+
+ ///6///////8////+f////v////8//3////6/////f//////////////////////////////////////
+ //////////////3////9////+/////v////9/////f////////////7////+/////v/////////////+
+ /////v///v3////+//////7////7////+P///+7/qZFt/2I9C/91Rgn/f0kI/3xGBf96QAD/gUYA/39F
+ AP+DSAL/fUYB/3ZBAP93SAv/aEAP/7WYc////ef///vu/////P///v///f/////+///////////+////
+ /v//////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ //////////////////////////////////////////////////////z////5////9P//9+L/p4xq/2dB
+ Ef92Rwr/f0gD/4BGAP9+RAD/fUUA/39IA/97RgP/dUEA/3dHB/9tPwX/Z0ER/7ScgP////D////1////
+ +f////7///7///79///8/f//+/////3///////7////8/////v////7//f////v/////////////////
+ /////////////////////////////////////////f////3////9/////f////3////////////+////
+ /v////7////+//////////////7///3+///6/P////7////79v////X////y/9LAo/9gPhD/dEgN/3lF
+ A/97RgP/dUIE/3pEB/+BSAP/fkQA/4FHAP94QwD/eEsS/2E7C/+dgFv////m////8v////n/+/v7//v+
+ ///9/v///f////////////7////+/////v//////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /P////j////0////8///+eb/lHhV/2hAD/91QgP/fUUA/31GAf94QwD/ekUC/31IBf92QQD/d0MB/3pI
+ DP9uRA//aksk/9W/o/////H////3/////v/6/P3//f////79//////////////////////////7/////
+ /////////////////////////////////////////////////////////f////3//////v////7/////
+ /////////////////v////7////+//////////////7///3////7/v//+/7///v9///5+Pz////6////
+ 8f/24cL/elks/29FCv93RQP/eEMA/3hDAP92QwX/d0UJ/3RBAv94QwD/gksC/3lHBf9hPQ//jXRU///x
+ 2P///+/////5/////v/7////+f7///v+///9///////+/////P////z////8/////v////7/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ///////////////////////////8////+P////j////8///+9f/97Nf/iWxH/2s/Cf95Rgf/fUkH/3hE
+ Av90QAD/ekYE/3xHBP93QgD/ekUG/3BDBv9pQQ3/fl41//3ozf////T///76//f7/P/7////////////
+ /v////7///7///v////6////+/////////////7/////////////////////////////////////////
+ ///9/v///f/////+/////v///////////v////7////+/////v////7///////3////9////+/////r/
+ ///6/v//9/n////+/////vf///vk/5h2S/9vRAv/eUcF/3tFAP+BSgX/fUYD/3pFBv92QwX/b0AD/3dI
+ Cv93QwD/b0IF/3tfPP/26NL////y////9v/+/Pv/9/v8//r////6////+/////3///////7////8////
+ /P////z////+/////v//////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ //////////////////////////////////////////////////////7////6///++f/+/v7//vz7////
+ 9f/s2b7/hGE2/2xACv90QwX/ekYE/3hEAv93QwH/fkkG/3hEAP98RQL/eEQC/3ZHCf9lPQn/pIVk///5
+ 5/////n//f/+//j9/P/9//7////+/////v///v//+v////j+///4////////////////////////////
+ //////////////////////////////v+///9/v////7///////////7////8/////P////z////+////
+ /v///////f////3////7////+v////v+///4+P7////+////9P+6oYH/dUwV/3ZCAP9/SAD/gkgA/3pC
+ AP96QQD/fkUA/3tHBf91Rw3/cUYN/2Y6AP+DXCj/5dK3////9f///vb/+/r2//3////6////+f3///n+
+ ///7/////f///////v////z////8/////P////7////+////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7////+//////////7////7///76v/cxKj/dFIn/21AB/95RQP/f0oH/3lCAP97RgP/eUUA/4NI
+ Av+DTAP/dkIA/3lKDP9nPRL/0rWa///+8P////v/+f34//3//v////7////+///+///7////9v////j/
+ /////v//////////////////////////////////////////////////+/7///3+/////v//////////
+ /v////z////8/////P////7///////3////9////+/////v////7/////f/////9/v////n/69S+/35b
+ M/9vQAL/gEkA/35FAP+BRwD/gkcB/39HAP+BRgH/eEIB/3BCCP9lPgf/cUwY/8+ziv////H/+vfy////
+ /P/9////+Pz9//r////7/v//+v3///3///////7////+/////P////z////+/////v//////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ //////////////////////////////r8/f/9///////+//z79////fz////5////7/+8o4P/bkYV/3A/
+ Af99SAX/ekQA/35HBP97RAD/gEYA/35EAP9+SAD/eEQB/3NDD/+AWzX/+eTO///98P////v/+/78////
+ /v///v////7///3////4////+P////3+/////v//////////////////////////////////////////
+ ///7/v///f7////+///////////+/////P////z////8/////v/+/v7//f////j8/f/9/////f////r7
+ +f////z///35////8v+Rb0v/bEAL/3hFBv98RgD/f0YA/4BGAP+GSwP/fUIA/35FAP+ASgn/dEUH/2Q+
+ CP+iiGD////p////9/////z////+/////v/9////+/////3////9/////f///////v////7////+////
+ /v/9/////f////3/////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ///////////////////////////////////////////////////9////+/7///v+/////v3////8////
+ /v////z///71///96P+ff1b/bEAK/3tHBf97QwD/fkYA/4NJAf98QgD/g0kA/4NLAP93QAD/fEUI/20/
+ D/+fg2D////u////9f////z///7////9/v////7////+//X6+f/6/////f7////+/////v//////////
+ //////////////////////////////v+///9/v////7//////v////z////8/////P////7///////r8
+ /P/7////9/v8//3///////7////7///+9f////T/xayS/3VLHP9zQgT/eUUC/3xGAP9/SAD/gUcA/3xC
+ AP+BRgD/e0QB/3VAAf9wQgj/lHJE///z2P////T////7/////v////7////+/////v////7/////////
+ /v////7////+/////v////7//f////3////7/////f//////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ //////////////////////////////////////////////////////////////////////////////3/
+ ///7/v//+v3////+/f////z////+/////v///vn///7w///t0f9/XDD/dEYM/3tEAP+BRwD/fUMA/4ZM
+ Af+ARwD/fUUA/4VMAf9+QgD/eEMK/2hEFv/ZwqL///7t////+f///fz///7////8+/////z//f/+//v/
+ ///8/P///Pz////+////////////////////////////////////////+/7///3////////////+////
+ /P////v////8/////v/8/v7/+f3+//v////6/Pz////+////+v////f////y///ozv+AXTX/aDoE/3hE
+ Av99RgH/fUcA/3pEAP99RgH/gkkE/3pDAP9/SAX/d0UJ/3ZOGv/v07D////y////+/////z////+////
+ /v////7////+/////P////7////+/////v////7////////////9/////f////3////9////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ //////////////////////////////3////8/v///v7+//////////7////8/////P////f////x/9S8
+ nv91Tx//eEcJ/3tBAP+FSQD/f0cA/3tFAP95RAD/hE0E/4JHAP9zOwD/b0IJ/4BgNf//9Nr////0////
+ +/////7///76////+/////z/+/78//3+///9/v////7/////////////////////////////////////
+ ///7/v///f////////////z////7////+/////z////+//z+///7////+/////z+/v////v////4///8
+ 7////+r/t5du/25ED/90RQj/d0MB/31HAP+BSgH/d0AA/3tGA/95QwL/e0UG/3U/Av92SBL/yqmC///6
+ 4/////n/+/39//////////7////+/////v////z////8/////P////z////+/////v////////////3/
+ ///9/////f//////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////+///////8/v///P7/////
+ /v////z////+////+//+9+7////u/7ibdv9oPgn/gEsI/3xCAP9/SAP/eEQA/3pEAP+BSgH/e0EA/4JH
+ Af9/TA3/ZT4K/8KohP///+7////1/////P////7///38//z9+/////7//f////z+////////////////
+ //////////////////////////////v////9///////+/////P////v////8/////v//////+/7///v+
+ ///4+//////////++f////X////x/+nQsP94Thn/d0QF/3ZHCf90RAT/fEYA/35HAP97RAD/fEYF/3hD
+ BP94RAj/bj8J/5l0SP//89r////3/////v/7/////f/////////////////+/////P////z////+////
+ /v/////////////+/////v//////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v////z////8//3////9/////////////v/////////+/////v////b//+zT/45uRf9vQgn/dEAA/31I
+ Bf96RQL/fEUA/3hCAP+ARgD/hE0E/3dAAP91RQv/dVEj///mxv////H//Pnx/////v/9/////Pz8////
+ //////7//f78////////////////////////////////////////////+/////3///////7////8////
+ +/////z////+//3////7/v//+v7///f6/v/////////5///+8P///+r/nYBb/3NDA/99RgD/ckAA/3lJ
+ Cf95RgD/d0EA/4BKA/98RQL/d0ID/3xLE/9vRhn/99u8////9f///Pv//f////r+///7/v///f/////+
+ ///////////+/////v////7////+//////////////7////+///////////+/////v////7/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ///////////////////////////+////+/////v///////3////9/////f////3////9//////7/////
+ +/////D/5Myu/2xIGv9yRQz/dkIA/3xFAP98RQL/e0QB/39JAv96RQD/fEQA/3hCAf9rPQf/sI1l////
+ 6/////X//P7+//v+///8+//////////89/////v////+////////////////////////////////////
+ ///9/////f///////v////z////7/////P//////+/////r+///6/v//+v3//////v////j////u/9K8
+ o/9tSyD/f0sF/4FGAP96RAD/e0kH/3RGBv90QgD/hEoC/39EAP96QgH/bD0J/7+ggf////L////7////
+ ///2+Pn/+/7///v+///7/v///f7////+//////////////////////////7////+/////v////7/////
+ //////7////+/////v//////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ //////////////////////////////////////////////////////7////8////+/////z///////v+
+ ///5/f//9/3///r////4+Pj////7////+P//++j/tZx8/2xGFv95RQP/fUIA/3xCAP+BSwr/bz4A/35M
+ BP9/RQD/gEUA/3tFCP9zSRr/4s6v////9f/5/f7/+P3///f5/////v////72////+P////z/////////
+ //////////////////////////////3///////7////+/////P////z////8/////v/9////+v3///v+
+ ///9/v///vv3////9P///+3/i29N/2hADP98RQD/gkUA/4ZPBv91QQD/dkUH/3tICf+CRwD/f0UA/3RC
+ Bv+KZTn///Lf////+/////z//fv6///////6/P3/+/7///v+///9/v////7/////////////////////
+ /////v////7////+/////////////////v////7////+////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v////v////6////+/////7//f////n+///3/f//+v7//////////Pj////7////9f//79b/eVgx/3FB
+ B/9/SAX/fkcE/3ZBAP94RwP/ekcB/3xFAP9/RAD/eUAC/3FCDv+bflf////n////+f/6/v///fv////+
+ //////r////5/////v///////////////////////////////////////f/+/////v///v////7/////
+ /v////z//f/8/////v///f////z////+//////v////w/9O9mv9tQg//fUcI/4FIAP+BRwD/fEQA/39I
+ Bf97RQb/ekIB/4JGAP96RAP/aEQU/93IrP///vb/+///////+/////n////6/////v///////f/////+
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ///////////////////////////+/////P////v////7////+/////z////+//3////7/////f//////
+ /////fr////3////7v/UtZT/cEca/20+Bv94RAH/fEYA/3lCAP97RAD/fkkA/3tHAP90QQP/ckMN/3ZO
+ Gv/qzab////x////+v//+vr///7///b5/f/6/////f//////////////////////////////////////
+ ///9//z////+///+/////f///////////v/9//z////8///9/////f////r7////9////+j/iG1B/3ZE
+ CP+ARQD/fkUA/35HAP99RAD/fEUC/31DAv+GTAv/ekAA/3FCCv+ghWD/8+rW//v//P/1/f3//Pv3////
+ +f////v///z5/////v//////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////+/////P////v////5////
+ +/////v////+//3////4+////f///////v////j///7t///64P+Pb0v/a0MS/3REAv98RgD/gUoH/3hB
+ AP95QwD/fUkC/3A/Af92Rgz/dUUL/6Z+Tv///+r////0///++v/++Pn/+v7///b8///9////////////
+ //////////////////////////////3//P////7///7////+///////////+//3//P/9//7///7////+
+ //////7///3v/9rIqf9gPxH/dUMH/35DAP+ARgD/fkcA/3pFAv95QwL/fEQD/3dBAv95Rw3/dk4e/+zX
+ uP////H//f/8//r////9//////38///9+v////z////+////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+/////P////v////8/////P//////+/////r+///5/P///v7+////+/////H////t/+HJ
+ q/9qSRz/eksN/3U+AP97RwH/fUkD/3tDAP97RQD/e0cF/3ZDBP90QQL/c0kU/+fOrv///+/////7//78
+ /P/9/v//+/7///3//////////////////////////////////////////f/8/////v///v////7/////
+ //////7//f/+//v////9/v///fr8////+f//+uf/jHNL/2dDDf93RAb/fEMA/31GAP+BSwT/e0YD/3hC
+ Af9+RgX/cT0B/2xDEv+rjmn///3o////9//+/vj/+/////r////4+/////v8/////v//////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ///////////////////////////////+///////////+/////v////z////+///////7/v//+v7///n9
+ ///3+v7////+////+P//+ef////t/5l+Wf9wQwr/eUQB/3hFAP98SAH/gEcC/3o/AP+ASQT/eEQA/3dD
+ AP90Rw7/mXhR////6v////n//f////z8/P//////////////////////////////////////////////
+ ///9//7//f/////+/////f///////////v/9//7/+/////r9/////v////3z/+nUuP9oRxb/bkIF/3pG
+ BP98RQD/eEIA/4FNBv93QwD/d0MB/3tFBP92Rw//bEsk//jky////vD////5////+//5+/v/9f3///j9
+ /////v////v6////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ /////////////////////////////////////////////////////v////7////+/////v////7/////
+ /v////7///////v+///3+///+P7///j+///3+/z////7////9////u3/7Ne7/21FFf97SAr/gE0H/3I+
+ AP+CRwL/gUQA/3xCAP9/SgH/ekYA/3VGCP9xSBv//eLH///88f/6//3////8///++v//////////////
+ //////////////////////////////3//v/9/////f7////+///////////+//3////7////+fz////+
+ /////+//n4Ng/2tCC/93RQP/d0IA/3xHBP96RgD/ekYA/3VAAP98SAb/d0QG/2c8C/+wmHz////z////
+ +P////z////7//z8/P/2/f//9vz////+/////fz/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ///////////////////////////////////////////////////////////////////////////////+
+ /////v////7////9/////v////7//////v///////f////n9///4/v//+P7///X8///5/vz////7//z7
+ 8f///+3/rYlj/2Q2AP95SAT/e0YA/39CAP+GSQX/fEMA/35HAP98RgD/c0AB/3FCDv+1lXH////y//3/
+ +/////v///36/////v/////////////////////////////////////////+//3////7/v///f3/////
+ //////7//f////3////8/f/////7//Hbwv9sSR3/d0cH/4FLBP94QQD/e0YD/3xIBf93RAD/eEIA/31J
+ Bv9xQwn/c1Al//zr2P//+vP////8//78+/////z///////j9///y+f///fz/////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ //////////////////////////7///3+/////v////3//////////v/////+/////////v//+/7///f7
+ ///4/v//+P////r////1+vj////8////8//13ML/b0gc/3BAAP+FTgX/gEMA/4JGAP+ESgL/ekMA/3pG
+ AP93QwH/eUUJ/3hRJP/16NL////4////+/////z////+////////////////////////////////////
+ //////7//f////v+///7/v////7///////////////////////////f/rJNz/2xEEP9+SgT/fEIA/39I
+ A/93QwH/dEMA/35LBf+ASQD/d0MA/2pAC/+rj2z///3x/////v///f3///79/////v/8+vr/+/7///r9
+ ///9/v//////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ /////////////////////////////////////////////////////v///f7///3+/////v//////////
+ /v////7////+///////8/v//+/7///j9///6////+/////r+///6/Pz////5///66v+ihGH/dkcK/3pC
+ AP+DSAP/dzwA/4dMBv97RQD/eUUC/3dDAf97RgP/bUEL/8SvkP//++z////5/////v//////////////
+ /////////////////////////////////v//////9vv+//r+///9/////f39/////////fz////5///1
+ 4v95WTD/dUcN/35EAP+ESAD/ekMA/3tHBP91QwH/e0cB/4BHAP94RAH/cEwe//fixv///PP/////////
+ /////////////////////v////7////+/////v//////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ //////////////////////////////////////////////////////////////////////////////3/
+ ///7////+/////3////////////+/////P////z////+/////v///////f////3////9/////f/////+
+ //////7////5//Dawf9wQQ3/f0UD/3xFAP97RAD/fUYD/3pEA/91QgT/eUYH/3lDAP91Rgj/jW5H///x
+ 3P////n//P7+///////////////////////////////////////////////+///////6////+v////n8
+ ///7/f7/////////+/////T/0byg/3NNHf94RQf/gEUA/4RIAP97RQD/eUUC/3pGBP94QwD/gEkA/3ND
+ A/+dgFn///rk////+v///////////////////v////7//////v////7///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ /////////////////////////f////v////6////+/////3//v////7////8/////P////z////+////
+ /v////////7////+/////v////7////+//////////Xl/6N6Tf93QQT/dkIA/3tHBP96RAP/ekUG/3RC
+ Bv93RAX/gEsC/3ZCAP9yShr/5Myw////9//6/Pz/////////////////////////////////////////
+ /////v3///////v////2/f//+v7///v+/////v/////3////7f+Tdk//bkIM/3lDAv+ARAD/hEYA/31H
+ AP94RAH/e0cF/3M9AP9/Sgf/dksS/93Gpv////T////7///////////////////+/////v/////8////
+ +////////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ///////////////////////////////////////////////////9////+/////r////7/////f/+////
+ /v////7////8/////P////z////+/////v///v////7////+/////v////7///r+//////j/4b6c/3VG
+ EP9yRAT/d0gE/3hDBP93RAb/d0cN/249AP98SAD/fEgB/2s8Bv+ti2f////0/////v//////////////
+ /////////////////////////////////v///fz/+v/+//b9///4/v//+/7////8+/////T//+/N/3JP
+ Hf9vQAL/fUYD/35DAP+ARQD/f0gD/3lFAP98RwT/dD8A/3RFCP+VcUH///nf////9v////z//f39////
+ //////////7////+//////v////7/////v/7////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ //////////////////////////////////////////////////////////////////////////////3/
+ ///7////+/////v//v/9//7//f/+/////v////7////8/////P////z////+/////v///v////7////+
+ /////v//+v7//////P//79X/jGU5/3JGC/90RAL/eEME/3hCBf93RQn/c0AB/3ZBAP+ASwL/fUcK/3xV
+ Kf/87dr////7/////v/////////////////////////////////////////8///+/f/8//3/9/////b9
+ ///6/P////r6////7//ZuY7/bUQG/3dDAP+CSQT/fEIB/3xEA/99SQP/eUUA/39GAf94RQf/Zj0M/8qw
+ jP////D//v3z/////P////////7////+/////v//////////+/////v////+//v/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ //////////////////////////////3////9/////f////3////9/////f////////////7////+////
+ /v////z////8/////v////7////////+///7/v///fz4////8v+6n33/aEAL/3VFBf97RQT/e0UE/3Q/
+ AP+ATAr/e0UA/3xFAP+ARgT/cEQP/8+5nf////T////8////////////////////////////////////
+ /////vv////8//3//P/4////8vv///j7/////v7////p/555Rf9yQwD/e0UA/4JJBP96Qwb/eUMG/3tG
+ A/97RQD/f0QA/3pGCv9wTSX/+eXM////8f////n////8///////9/v////7////+/////v/////8////
+ /P/9//z/+//+////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////f////3/
+ ///9/////f/////////////////+/////P////z////+/////v///////f////39/f////z////4/+bW
+ v/9xSxv/eEUG/3pDAP9/RwD/eUIA/4BJBP+ARwL/fUUA/3tAAP94SA7/k3dU////8f////v/////////
+ ///////////////////////////////8+f////z//v/7//j////z/P//+vz//////P/64sr/eFAW/3hF
+ AP+BSAD/fUQA/3xFDP93Qgn/eUQB/35HAP9/QwD/dUIK/6OHaP///+7///zx////+/////z//P7+//v+
+ ///9/f////7////+///////////+//3//v/7//7/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////+///9/v///f7///v+///7/v///f////3///////7////8/////P////7//f/+//v/
+ ///9//7///75////+//9//7///jp/6F+Uv96RAf/ekIA/4BGAP+BSAD/fEEA/39FA/+BSAP/fUMA/3hI
+ CP9uSyP///Hb////+f////////////////////////////////////////36/////P/4/Pf/+v////T7
+ ///9/f////ry/9a6m/9vQwb/fEgA/4NKAP94QAD/fUcL/3ZCBv94RAD/gUkC/39FA/9uPwv/3MWr////
+ 9/////n////8//3//v/9////+/7///39/////v////7////+///9/////f/+//3//P////7/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////7////+///9/v//+/7///3+///9/////f////3/
+ //////7////+//3//v/9//7/+////////v////n////6//b7/P////n/1LiZ/3FCDv99RQD/g0gA/39G
+ AP98RAD/gUcF/3xCAP98RgD/dEIA/2pBEP/fw6T////0/////v////////7////+///////////+////
+ /v////z///38//v////7/v//+/7//////P///un/nn9Y/3JFCP98RgD/fkQA/31FAP99Rwb/e0UE/31F
+ AP98SAL/ckII/3lUKP//+eD////0///+/f/5/f7/+/3+//3//////v////7////+///9/////f7///3/
+ //////z////8/////v//////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////7////+
+ ///9//////7////////////////////////////////////////9///////+////+P////v/+fz///7/
+ /f/26dn/b08r/3hEAv+BRQD/gUkC/3M+AP+ASQb/eUQB/3pGBP9yQgL/d0gL/62JWf///+j////5//38
+ /v/9/f////7////////8+/f////5/////P////7/+/7///r9///////////3///r0P99Wi7/c0QH/31H
+ AP99RQD/fEQA/3xFAP97RAD/fEUA/3pGA/9pQQ3/pIdi////6f////f///////r9///9////////////
+ /v////7//f////v+///7/v///f///////P////z////+////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7///32////+//5/P///f////z27/+SfGD/dkUH/4JIAP+ASQT/dUEA/31GA/94QwD/eEcJ/3ZF
+ B/93QwH/j2Yv///52v////X///////z8///+/f//////////+f////j////8///9/P/7/v//+v//////
+ //////X/4cmt/2dDFf9zQgT/gEgB/35GAP98RAD/e0QA/3tEAP9+QwD/ekUG/2dBEf/ix6X////w////
+ 9///////+fz///z+///////////+/////v///v///f////v+///9///////+/////P////7/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////v////v////7//n8///9///////5/8y3nP9wQgj/f0UA/31I
+ Bf95RQL/fEUC/3hDAP95Rgf/eUYH/3VAAP9xRg3/79y7////8P////7//v3////+///////////7////
+ +f////z//vz7//r9///6///////8///+8P+1mXr/bEIT/3ZAA/+ASAH/f0gA/3tGAP97RwD/fUYB/4BF
+ AP93Qwf/c1Al///x1f////L///73//v9/v/7/v//+/3+/////v////z////8///////9/////f7///3/
+ //////7////+////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////+////+/////v/+v3///r9
+ //////v/+eXM/3dLFf97RAD/eUQB/3xHBP99RgH/ekUC/3VCA/92QwT/e0YD/21BBv/Bq4f////w////
+ /P///v////7///////////z////3///+/v///v//+f7///j///////n///nl/4lpRv9xQg//e0IF/4JH
+ Af9+RwD/e0cA/3xIAf98SAL/fUQA/3RCCP+WdlL////r////9f////z/+fv8//v+///8/v/////+////
+ /P////z///////3////9/////f//////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7////8///+/f/7/v//+fz/////+////+r/kmo5/3pHCP93QwH/e0YD/3xFAP9+RwL/dkIA/3ZC
+ AP+BSgX/ckUI/5V7Vv///+////75///+/////v///v7+/////P////f///39///+///6////9f77////
+ 9//569T/ck4m/3E/C/+BRAb/gkYA/31GAP95RwD/ekkA/3lFAP98QgD/c0MP/8Opi/////H////5////
+ /v/6+///+/7///z+/////v3////8/////P////7////////////9////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////fz//v7+//r+///6/f/////7////8P+7mGz/c0UL/3hF
+ Bv94RAH/ekMA/35HAv96RQL/eUQB/35HAv9yQwb/eFwz///y2////vX////////+///8/v7////8////
+ +f//+/3///7///j////3//v////0/9vLrv9sRRn/ekIL/4JEBP+DRQD/fUYA/3pJAP95SAD/dkQA/35F
+ B/98Th//69S+////9v////z//v7+//3+///6/f///f/////9/P////z////7/////P////7/////////
+ ///9/////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////+/f//////+v7///r9
+ //////v////v/+vMpf9xRxL/dUYJ/3hEAv97RAH/fEUA/3tGA/98RwT/e0QA/3NCBP9rSh3/4c+y////
+ 9P///v3///////z+/v////z////7///9/////P3/9v79//r/+////+z/uaWC/2g9DP9+RAn/g0MD/4JE
+ AP99RgD/ekoA/3dJAP91RAD/gUsP/4RYL//97dz////8//7+/v/6/P3//f////n7/P/////////+////
+ /P////z////8/////P////7///////3////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+///////5/f//+fz//////v////P///XV/3dRIf9wQgj/eUUD/31IBf96QwD/eUQB/35H
+ Av98RAD/d0cH/2VADv/Fr4z////y////+////////f/////++v////r///v+///+///6/////f/4////
+ 7P+KcUn/c0MP/4BCBv+CQgL/g0YC/31JAP93RwD/c0UA/3pMBf9wPwf/n3lW////9f/9/////f////3/
+ ///9///////////////////////+/////P////z////8/////v///////f////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////f////b5/f/7/v/////+////9////uX/knJJ/25C
+ DP94RQb/eUQB/39IA/95QgD/eUIA/4JKA/92RAL/bkQP/56BXP////D////4//z9+//9/////Pr5////
+ /P///f///vn7//v//v////b////i/3hbL/9yPwf/gUIF/4NDA/9+QQD/e0YA/3xMAP95SAD/dEUB/3FC
+ D//Jp4n////5//v+///9///////////////////////////////////////+/////P////z////8////
+ ///9////+//////+////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////39/f/9////+/7///v+
+ ///+/Pv////3////8P+xlnT/akAL/3ZDBP95RAH/fkcC/3tEAP97RAD/gEgB/3ZCAP9tQAf/jmxB///3
+ 4P////X//f78//3////+/Pv////8///9///9+vz//f/+////9f/76sn/bEsa/3U/A/+DRgT/gkUF/3pB
+ AP97RgD/fEsA/3pJAP9vQQH/bUMU/+vQtv////z/+v7///3////////////+/////v///////f////3/
+ ///////////8/////P////z////+//3////7//////7/////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////P7///3////7/v///f////z8/P////r////0/9W/o/9uRhL/dUID/3lFA/98RQD/fEUA/35G
+ AP99RgH/eEMA/3ZECP9/WSn/9uXK////9f////z/+//////9/P////7///v////+///+//3////0/93H
+ o/9vSBT/eUME/4JFAf9/RQT/fEUC/31HAP95RwD/e0gA/3NHCP9zTSP/+eLM/////v/4/v///f//////
+ /v////z////8///////9////+/7///3///////7////8/////P////7//f////v//////v//////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////9/////P7///3+///8/v///////////P////j/69nC/3lR
+ IP90RAT/e0cF/3hDAP97RAD/fUUA/3xFAP98RwT/fEcI/3RMGP/l0bL////0//3//P/6//7///39///+
+ /f/8+/////7///38+P////L/wqiA/21EDf98RQL/f0QA/3pCAf97RQT/fkgB/3pFAP98SAH/dkkM/4Vm
+ P///8+L///////r+///////////7////+/////z///////v+///6/v//+/7//////v////z////7////
+ /P/9////+//////+////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////7/f3//f////3/
+ ///////////+///++v/87dr/hWEz/3JBA/98Rwj/eEMA/3xFAP99RQD/e0QA/31IBf96QgH/bUEL/8q1
+ lf////L/+v74//r//v////////3+//3+///6/P3////7////7/+wkmn/aj4D/39GAf+ARgD/eEQC/3dE
+ Bf98RQD/fkcA/3tFAP9tQQb/nIBd////8P//////+v7//////v////n////5////+//9////+v7///j+
+ ///6/v///////////P////v////8//3////7//////7/////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////v7+//7+/v/9///////////+/f///fz/////////8P+ZdUf/cD8B/3lGB/96RQL/fUYB/3xF
+ AP95RAH/fUYD/3xDAP9wQQn/r5l1////8f/8//r/+////////////v//+/7///z+//////z////t/5h2
+ S/9vQAP/f0cA/4FHAP94RgT/dkYG/3pDAP9/RwD/eUIA/2o9BP+4n3/////1///////7/v/////8////
+ +f////n////7//3////6/v//+P7///r+///////////8////+/////z//f////v//////v//////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////9/f3///////////////////38//z8/P/9///////0/7WS
+ Zv9zQgT/d0QF/3lEAf98RQD/fUYB/3pFAv97RAD/gkcB/3VGCf+Wflr////v//3/+//7//////7+///+
+ ///1+v3//f//////+v///On/f1ou/3lICv9/RwD/fUYA/3ZEAv95Rgf/eUIA/39HAP98RQD/ckYQ/9C6
+ nv////f///////v///////7////7////+f////z//f////r+///6/v//+v7///////////7////8////
+ /v/9/////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////+vz9////
+ /////v3///38//////////L/yaqD/3VID/93RAX/d0IA/3pDAP99RgH/e0YD/3pDAP+ARQD/dEIG/4Zq
+ Qf///+f////7//v////9+/v////+//v+///////////5///23/90TBz/eEUG/3tEAP99RwD/fEcE/3pF
+ Av99RAD/e0MA/4JLBv9iOAP/69nC///9+P///////f////////////7////+/////v///////f////3/
+ ///9//////////////////7/////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////3////7/v///f///////v////z////+////9//jzbH/Yj4Q/3RFCP99RgH/eUIA/3pD
+ AP98RQD/fUYB/3tEAP93Rgj/c08f////5f///fj/+////////v////v/+v3///7+/v////j//OjP/25G
+ Ev93QwH/eEMA/3xFAP97RAD/fEUA/4BIAf95QgD/f0oH/3BIFP/46db////+////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////f////v+///7///////+////+/////z////3/+nX
+ wP9kRh3/dEQK/3xFAP96QwD/fEUA/3xFAP98RQD/eUQB/3VEBv9zSxf///XT///9+P/7/v/////7////
+ +f/9///////+////9v/q1r3/aUEN/3hEAv96RQL/fUYB/3tEAP99RgH/gEkE/3hBAP96RQL/flYl///z
+ 4f////7/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////9////+/7///v/
+ //////7////7/////P////f/+ObP/3JUK/90RAr/e0QA/3xFAP9+RwL/fUYB/3tEAP97RgP/dUQG/25G
+ Ev/54L7////6//v+//////v////5///+//////7////4/9rFqv9pPwr/e0YD/35HAv99RgH/fUYB/31G
+ Af+ASQT/d0IA/3VBAP+LYzL///jm///9/P//////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////3////7/v//+////////v////v////8////9///79j/f2A5/3JECv96QwD/fEUA/31G
+ Af99RgH/fEUA/31GA/91RAb/bkYS/+jNq/////n/+v3//////P////n///39/////P////f/yLOY/2k/
+ Cv98RwT/fUYB/3xEAP99RgH/ekMA/3xHBP97RgP/dkME/5p0RP///e3/////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////f////v+///7///////+////+/////z////4///z
+ 3v+Ka0T/ckQK/3pDAP98RQD/fEUA/35GAP98RgD/e0QA/3hFBv9vRxP/2L2b////+f/8/v/////8////
+ +f///v3////7////9/+7pYn/bUEL/35KBP9/RgH/fUUA/31GAf96QwD/ekUC/3tHBf94RQf/poJU///+
+ 8P/+/v7/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////9////+/7///v+
+ //////7////8/////v////j///fi/5R1Tv9xQwn/ekMA/31GAf96QwD/fUUA/39HAP96QwD/d0QF/3BF
+ Ev/MsY/////5//v9/v////z////5/////P////j////1/66YfP9tQQv/fkoE/39GAf9/RwD/fUYB/31G
+ Af95RAH/d0UD/3VEBv+vjGD///7x//n7/P//////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+///////7/v//+/7//////v////z////+////+P///un/nH9a/3FDCf96QwD/fkcC/3pD
+ AP99RQD/fkYA/35GAP92RAL/bkQP/8Oohv///fb//f///////P////j////8///89f////P/pI9w/2k9
+ B/99RgH/fEQA/39HAP96QwD/fUgF/3hEAv91QgP/dkUH/7mWav////X/+v7////+////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////7///////v+///7/v/////+/////P////7////5////
+ 8P+ihWD/cUMJ/3pDAP9/SAP/e0QA/31FAP99RQD/gUkC/3lFA/9tQw7/waWC///99P/9///////8///+
+ 9/////v////4////9P+hiWv/b0EL/35HAv99RQD/fkYA/3xFAP96RQL/eUUD/3hFBv91RAb/wp9z////
+ 9f/7//////7/////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////v//////+/7///v+
+ //////7////8/////v////n////u/6iLZv9xRAv/eEMA/31GAf97RAD/f0cA/39HAP9/RwD/d0MB/21D
+ Dv+3m3j///71//3//////vn////4////+/////j////0/6GJa/9vQgn/fkcC/31FAP98RgD/fEUC/3pF
+ Av95RQP/eEUG/3VEBv/Cn3P////1//v//////v//////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+///////7/v//+/7//////v////7/////////+f////D/spVw/3JFDP96RQL/fUYB/3tE
+ AP9+RgD/fkYA/39HAP94RAL/bUEM/66Sb///+/L/////////+v////j////7////+P////T/oYlr/29C
+ Cf9+RwL/fUUA/3xGAP98RQL/ekUC/3lFA/94RQb/dUQG/8Kfc/////X/+//////+////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////7///////v+///7/v/////+/////v/////////7////
+ 8f+6nnv/cEMK/3pFAv99RgH/fEUA/35GAP9+RgD/gEYA/3lFAv9sQAr/popn///99P/////////6////
+ +P////v////4////9P+hiWv/b0IJ/35HAv99RQD/fkYA/3xFAP96RQL/eUUD/3hFBv91RAb/wp9z////
+ 9f/7//////7/////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////v//////+/7///v+
+ //////7////+//////////v////x/7+jgP9uQQj/ekUC/3xFAv98RQD/f0cA/35GAP9/RQD/e0YD/25C
+ DP+miWT////2//////////v////4/////P////n////1/6GJa/9vQgn/fkcC/31FAP9+RgD/fEUA/3pF
+ Av95RQP/eEUG/3VEBv/Cn3P////1//v//////v//////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//v7+//3////9//////79//fp
+ 0/9tQQz/f0cA/35GAP98RgD/fEUC/3pGAP9+RQD/fEYA/3xFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwX/ZUAU////
+ 5f////n/+v7////+///////////+///////9/////f///////P////z///////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+///////7/v//+/7///////////7/////////+/////H/v6OA/2xACv95RQL/ekUC/3xF
+ AP9/RwD/fkYA/39FAP97RgP/bkIM/6aJZP////b/////////+/////j////8////+f////X/n4lt/21B
+ C/9+RwL/fUUA/35GAP98RQD/ekYA/3pEA/94RQb/dUQG/8Kfc/////X/+//////+////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v/+/v7//f////3//////v3/9+nT/21BDP9/RwD/fkYA/3xGAP98RQL/ekYA/35FAP98RgD/fEUC/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/e0QA/3JDBf9lQBT////l////+f/6/v////7///////////7///////3////9///////8////
+ /P///////f//////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////7///////v+///7/v///////////v///v/////7////
+ 8f+6nnv/bkIM/3lFA/97RgP/ekYA/35FAP9+RgD/gEYA/3pFAv9uQAr/qItm///98/////7////6////
+ +P////z////5////9f+fiW3/bUEL/35HAv99RQD/fkYA/3xFAP96RgD/ekQD/3hFBv91RAb/wp9z////
+ 9f/7//////7/////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////+//7+/v/9/////f/////+/f/36dP/bUEM/39HAP9+RgD/fEYA/3xF
+ Av96RgD/fkUA/3xGAP98RQL/ekUC/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP97RAD/ckMF/2VAFP///+X////5//r+/////v//////////
+ /v///////f////3///////z////8///////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////v//////+/7///v+
+ ///////////+///+//////v////x/6+Ucv9wRA7/eUUD/3tGA/95RQD/fkUA/35GAP+BRwD/eUUA/29C
+ Cf+wk27///vx/////v////r////4/////P////n////1/5+Ka/9tQQv/fkcC/3tEAP98RQD/fEUA/3pF
+ Av96RQL/ekYE/3VEBv/EoHL////0//3/////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////v////7///////////////7////+////
+ /v///////f////3//////////////////////////////////////////v7+//v+///9///////7//no
+ 0/9rQA3/fUYB/35GAP9+RgD/ekUC/3lFA/96RQL/ekUC/3pFAv96RQL/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3tEAP9yQwb/Y0AU////
+ 5f////j//v7+///////////////////////9/////////////P////z///////3//////v//////////
+ /////////f////3////9/////f////////////7////+/////v//////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////9/////f///////////////f///////P///+//popn/3FDDf94QwD/e0YD/3tE
+ AP99RgH/f0cA/4FHAP96QwD/ckQK/7ucdf///vT////////++v////v////8///99v////P/p49x/2w+
+ CP99RgH/ekMA/3pFAv98RwT/eEMA/3tGA/96RQL/e0cF/7+Zaf///+//////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////7////5///8
+ 9//9/////P7/////+v////n////8///////7/v//+/7///////////7///////3////9/////f////7+
+ /v/9////+v7///r9//////r/+ObP/2xEFP95RQP/gEYA/4BGAP96RQL/dUQG/3NEB/91RAb/ekUC/3xF
+ AP96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3NEB/9fPxb////n////8v////n////+///////5+/z//f////////////7////8////
+ /P////7///////3////9/////v7+//3////3+///+P7///T6///7/v///////////P////v////7////
+ /v///////f////3////////////+////////////////////////////////////////////////////
+ ///////////////////////////////////9/////////////v////7//f////v+///6/v/////8////
+ 7v+khV7/cUIK/3dCAP9/SAP/e0QA/3tEAP99RQD/f0cA/3pFAv91Rgn/wqJ5////9//7/v///f////v9
+ /v////z////4////9P+vl3n/bT8J/35HAv95RAH/ekUC/3tFBP95RAH/fEUA/3pFAv95RQP/to5d///9
+ 7f/8/Pz/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////v////v////7//r+///5/f/////8////+P///vr/+vr6//n9///5/f///v7+///+
+ /f/+/f///P7///z+///8/v////////3////5/f//+vz9////+P/+6tH/ZT8P/3ZDBP+BRgD/gUcA/3pF
+ Av91RAb/c0QH/3VFBf9+RQD/gEYA/3xFAP96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/cUMJ/2FEH////+v////y////+P/6+Pf//P7///v+
+ ///5/P///v7+///+/f////v////7///+/f/+/v7//P3///z+/////v3//v7+//r+///2/f//9v3///j8
+ ///7+/v///z3////+f////n////+//3////7/v///f////////////7/////////////////////////
+ //////////////////////////////////////////////////////////////3////////////7////
+ /P/9////+v7///j+//////z////p/6CAV/9xQwn/eEQA/4BHAv99RQD/fEUA/31GAf99RQD/eUQB/3NF
+ C//JqYD////2//n9///6/v//+Pz//////v////v////1/7qlhv9sQAr/fUgF/31GAf96RgD/eUQB/3pF
+ Av97RAD/e0YD/3lFA/+oglL////w//z8/P//////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////r6+v/6/v//8fz///H6///9//////76////
+ /v/9////+v7///r+///////////+//3////7/v//+/7///3////9+/r//fv6//3+///////////3///t
+ 0v9hOwv/eEYE/4FHAP+DRwD/fkYA/3pFAv95RQP/ekYA/4NGAP+DRwD/fkYA/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP9wRAn/VTkX///7
+ 6P////H////5///////7/v//+v7///j8///9/////////////v////7////+//3////7/v///f//////
+ +/////r///////n9///5/f//+/7//////v////v////5////+////////f////v+///9////////////
+ /v//////////////////////////////////////////////////////////////////////////////
+ /////////f////////////v////8//3////6/v//+v7//////P//+eD/mXdM/3JECv95RQD/gEcC/31F
+ AP98RQD/fUYB/3pDAP94RAL/c0YN/9O0jf////X/+v3///r+///5/f/////+////+/////X/yrSY/2k/
+ Cv98RwT/fUYB/3xFAP98RQD/fUYB/3xFAP98RwT/eUUD/5hyQv////D//v7+////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////9/////f7///j+
+ ///x/P//8Pn//////v///fb////5///++f///v3///79////+P////f////6////+/////v////6////
+ +P////j////7///+9////+///+nL/2hADP9+Sgj/gUcA/4NHAP9+RgD/fEUA/3pFAv9+RgD/hUcA/4VH
+ AP9+RgD/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3FDCf9cPxr////r////8P///fD////5////+//59/b////+////+v////j////3////
+ 9/////f////4////+/////j////y////8/////v//v7+//f6/v/9/////fv6//779/////v////8////
+ ///9////+/7///3////////////+////////////////////////////////////////////////////
+ ///////////////////////////////////9////////////+/////z//f////r+///7/v/////7///1
+ 2v+PbED/dEUI/3hDAP99RgH/fkYA/31GAf99RgH/fEUA/3ZDBP9xRQ//3sOe////9//7/v//+v7///r+
+ ///+/v7////8////9//axar/aT8K/3pFAv9+RgD/fkYA/39HAP9+RwL/fEUA/3pFAv94RAL/hV8v///6
+ 6P///v3/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////9/f3/+Pz9//X6///7/v/////1////7f///+3////u////8f////H////r////
+ 6v///+3////u////8P////D////t////6f////H////x////6v//5cD/dUkT/3VAAP+BRwD/g0cA/35G
+ AP98RQD/ekUC/35GAP+FRwD/hUcA/35GAP96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/dUQG/2lDE////dj////m////5////+7////x////
+ 7v////H////w////7v///+v////r////6////+3////w////7v///+v////p///+8P////v//f39//3/
+ //////7////8/////P////z///////3////7/v///f///////v////7/////////////////////////
+ //////////////////////////////////////////////////////////////3////////////8////
+ /P/9////+/7///3///////j//+/T/4VhM/9zRAf/eEMA/3xFAP99RgH/f0cA/31FAP9+RwL/dkME/2xE
+ EP/t0rD////2//v+///6/v//+v7///7+/v////z////3/+vXvv9qQg7/eEMA/31FAP+ARgD/gEYA/35G
+ AP98RQD/eEMA/3tHBf93USH///Lg/////v//////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////+/////P////z///////r07f+3pY7/lXpY/5l6
+ U/+XeFH/lHhV/5R4Vf+cek//nHpP/5p6Uf+YeVL/lnlU/5Z5VP+efVb/mHlS/5F4WP+Telr/l3tY/598
+ UP9pOwH/fUgF/4FHAP+BRwD/fEUA/3pFAv95RQP/ekYA/4FHAP+BRwD/fEUA/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP95RQP/aDsC/62F
+ Uf+jfU3/nHpP/5F0T/+SdlP/l3xa/5R4Vf+WeVT/mHlS/5p6Uf+cek//mnpR/5h5Uv+WeVT/lnlU/5R3
+ Uv+SeVn/saCL///67f////z///////v5+f///fz////+/////v/9/////f////v+///9///////+////
+ /P//////////////////////////////////////////////////////////////////////////////
+ /////////f////////////z////+//v+///7/v//////////9//85Mb/eVMj/3NEB/95RAH/fEUA/35H
+ Av9/RwD/fUUA/31GAf90QwX/bUUV//nhw/////b/+/7///n9///5/f///v7+/////v////n/+ejT/25G
+ Ff93QwH/fUUA/4JIAP+BRwD/fUMA/31GAf93QgD/fkoI/25GFf/15tP////8/////v//////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////7///rz////
+ 9/////j///fl/5R3Uv9lPQz/bUEL/3JFDP9tQw7/b0MN/3RFCP92RQf/ckQK/3FEC/9vQw3/b0QL/29B
+ B/9wQwr/aEAP/2hCEv9hOwv/a0EM/3I/AP+BSgX/gEYA/35GAP95RQP/d0QF/3VEBv91RQX/ekUC/3xF
+ AP96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP9+SQb/ekYE/249AP92SA7/c0cR/2tBDP9tRRH/aT8K/29DDf9xRAv/ckQK/3JE
+ Cv9yRAr/ckQK/3FEC/9tQw7/ZT0M/18/Fv+Iclb///ro////+f////7///7+//////////////////3/
+ ///7/v//+/7///3///////7////8////////////////////////////////////////////////////
+ /////////////////////////////////////////////////P////7/+/7///v+//////7////0//LX
+ tf9uRhX/dkUH/3pFAv95RAH/fUYB/35GAP99RQD/e0QA/3RFCP9vSh7///LW////+P/7/v//+f3///r+
+ ///////////+/////P//9OH/b0sd/3ZDBP98RAD/gkgA/4NJAP9+RAD/f0gD/3VAAP99SQf/YzwI/+nX
+ wP///vf////+////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////v////n////2////9v///un/m3hM/3JECv98SAb/eEMA/3ZDBP94RAL/fUUA/39F
+ AP97RAD/eEQB/3hEAv95RAH/f0cA/31GAf9yQQP/dkgO/29BB/9xQgX/gk0K/3lBAP9+RgD/fEUA/3lF
+ A/91RAb/c0QH/3NEB/93RAX/eUUD/3pFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fkYA/4BGAP+ARgD/gEgB/3lEAf97RwX/dUID/3dG
+ CP93RAX/eEQC/3lEAf95RAH/eUUA/3tEAf95RAH/eUQB/3ZDBP9xQwn/a0MS/4pvTf///un////4///+
+ /f///////v7+///////9/////f7///v+///7/v///f///////v////z/////////////////////////
+ //////////////////////////////////////////////////////////////////////7////+////
+ /v/7/v///f///////P////H/6syp/2Y+Cv92RQf/fEcE/3hDAP97RAD/fkYA/39HAP96QwD/dEYM/3JQ
+ Jf///uX////5//3////6/f//+v7///39/f///////fv6///87P99WzD/dkcJ/31EAP+CSAD/gUUA/4JI
+ AP95QgD/ekUC/3lFA/9tRRD/zrme////9f////z/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////v////z////7///55v+de1D/b0EH/3lF
+ A/98RQD/eUUD/3pFAv+ARgD/gUcA/35GAP98RQD/fEUC/35GAP+DRwD/g0cA/35GAP95RQP/d0QF/3lF
+ A/98RQD/fkYA/35GAP98RQD/eUUD/3VEBv91RAb/dUQG/3dEBf95RQP/ekUC/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP9+RgD/gEYA/4BG
+ AP9+RgD/fEUA/3pFAv95RQP/eUUD/3lFA/96RQL/fEUA/3xFAP98RgD/fkUA/3xFAP98RQD/ekUC/3ZD
+ BP9vQw3/kHFK////6f////f////+//7+/v/9//////////3////9/v//+/7///v+///9///////+////
+ /P//////////////////////////////////////////////////////////////////////////////
+ //////////79/////v///v3///////r9///6/P3////5////6//JqIH/cEcQ/3ZDBf95RAH/ekYE/3pF
+ Av99RQD/f0cA/3pDAP91Rw3/hmdA////6v////n/+/3+//v+///7/v////////////////////zu/5R0
+ S/9vQQf/fkcC/39FAP+BRwD/gUgA/3tEAP98RwT/eEMA/2k9B/+4noD////0////+///////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////f//////
+ //////z///nn/517UP9vQQf/ekUC/3xFAP96RQL/ekUC/4BGAP+BRwD/fkYA/3xFAP98RQD/gEYA/4VH
+ AP+FRwD/gEYA/3xFAP95RQP/eUUD/3xFAP9+RgD/fkYA/35GAP96RQL/eUUD/3lFA/95RQP/eUUD/3pF
+ Av96RQL/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP9+RgD/fkYA/3xFAP98RQD/ekUC/3pFAv96RQL/ekUC/3xFAP98RQD/fkUA/35G
+ AP9+RgD/fkYA/35GAP98RQD/eUQB/3JECv+Sckn////n////9/////7//v3///3///////////////3/
+ ///7/v//+/7///3///////7////+////////////////////////////////////////////////////
+ //////////////////////////////////////7////+//78+///////+/7///7+/v////j////t/7GP
+ ZP9uQQj/d0QF/3pFAv97RwX/e0YD/3xEAP9+RgD/ekMA/3JFDP+YfFn////v////+f///////f////v+
+ //////7//v7+//3///////b/r5Jt/2xACv98SAb/fkQA/39FAP+ARgD/fUYD/3tGA/98RQD/b0EH/5+B
+ Xv///+7////5////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////3////7/v//+/7/////////+Oj/m3tS/29BB/96RQL/fEUA/3lFA/96RQL/fkYA/4BG
+ AP98RQD/fEUA/3xFAP9+RgD/gUcA/4BHAP9+RQD/ekUC/3lFA/95RQP/ekUC/3xFAP9+RgD/gEYA/4BG
+ AP9+RgD/fkYA/35GAP9+RgD/fkYA/3xFAP96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/ekUC/3pFAv96RQL/ekUC/3pF
+ Av96RQL/ekUC/3pGAP98RQD/fEUA/3xFAP98RQD/fkYA/35GAP97RAD/dEUI/5RyR////+f////3////
+ /v/8/v///f///////////////f////3////9/////f///////v////7/////////////////////////
+ /////////////////////////////////////////////////////////////////v///fz///38//3/
+ ///7/v//////////9////+X/lnJE/20/Bf95Rgf/eUQB/3tHBf97RgP/fEQA/4JIAP96RQL/b0MN/7Ob
+ ff////T///75///////9////+/7//////v//////9/r+////+P/Gq4n/bEQP/3dEBf9/RwD/fUMA/4BG
+ AP97RgP/d0IA/39HAP96SQv/h2c+///13v////n/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////f////v+///7/v/////////46P+de1D/b0EH/3pF
+ Av98RQD/eUUD/3lFAv9+RgD/gEYA/3xFAP98RQD/fEUA/35GAP9+RgD/fEUA/3pFAv95RQP/d0QF/3dE
+ Bf95RQP/ekYA/35GAP+ARgD/gUcA/4FHAP+BRwD/gUcA/4FHAP+ARgD/fEUA/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/ekUC/3pF
+ Av96RQL/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/35GAP9+RgD/fkYA/3tE
+ AP90RQj/lHJH////5/////j///////z9///7/v///////////////v///f////3////9////////////
+ /v//////////////////////////////////////////////////////////////////////////////
+ //////7////+///9/P///////f////v+///+/v7////z///x1f+DXS3/c0QH/31JB/91QQD/d0QF/3pG
+ BP9/RQD/g0kB/3xHBP9sQg3/z7qf////9////Pf///////v9/v/7/v/////8///////3+v7////5/+HI
+ qP9uRhX/c0EF/35HAv9/RwD/fUUA/3pFAv93QgD/fkYA/3hFBv90UCL/++XJ////+P//////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////f////3/
+ //////z///nm/6B8Tv9zQgT/fEUA/35GAP96RQL/ekUC/4BFAP+ARgD/fkYA/35GAP9+RgD/fkYA/3xF
+ AP96RQL/eUUD/3dEBf93RAX/d0QF/3lFA/96RQL/fkUA/4BGAP+BRwD/g0cA/4NHAP+DRwD/gUcA/4BG
+ AP98RQD/ekYA/35FAP98RgD/fEUC/3pGAP9+RQD/fkYA/35GAP91RAb/cU4i//Ldwv////j//v7+////
+ ///////////+/////v/9////+/////////////7//f////////////7////7////+//YyLH/dUoX/3pG
+ AP99RAD/fkYA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP9+RgD/gEYA/4BGAP9+RgD/fkYA/35GAP9+RgD/fkYA/35G
+ AP9+RgD/gEYA/4BGAP+ARgD/e0QA/3JECv+Sckn////n////+P/9////+v3///v+///////////+////
+ /////////f////3////////////+////////////////////////////////////////////////////
+ /////////////////////////////////v////7////+///////9////+v3//////v////T/89u9/3hQ
+ HP93Rgj/fEgG/3VBAP93RAX/ekYE/4BGAP+BRwD/e0YD/29HE//l0bj////4///9+f//////+fv8//v+
+ //////z//f39//r+/////fj//ObK/3JMHP9vQQf/ekUC/4FJAv97QwD/eUQB/31IBf+ARgD/dkEA/25G
+ Ev/s07P////3////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////9/////////////P//+eb/oHxO/3VCA/9+RgD/fkYA/3pFAv95RQP/fkYA/35H
+ AP9+RQD/fEUA/35GAP9+RgD/ekUC/3pFAv95RQP/eUUD/3lFA/95RQP/eUUD/3pFAv98RQD/fkYA/4FH
+ AP+BRwD/gUcA/4BGAP9+RgD/fEYA/3xFAv96RgD/fkUA/3xGAP98RQL/ekYA/35FAP9+RgD/fkYA/3VE
+ Bv9xTiL/8t3C////+P/+/v7///////////////7////+//3////7/////////////v/9////////////
+ /v////v////7/9jIsf91Shf/ekYA/31EAP9+RgD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3pFAv98RQD/fEUA/35GAP+ARgD/gEYA/4BG
+ AP9+RgD/fkYA/35GAP9+RQD/fEYA/35GAP9+RwD/gEYA/35GAP97RAD/ckQK/5JySf///+n////5//3/
+ ///6/f//+/7///////////7//////////////v////////////////7/////////////////////////
+ ///////////////////////////////////////////////////////////+/////P////7///////r+
+ ///5/P/////+////8v/Xvp7/b0UQ/3dEBf94RAL/d0MB/3hFBv96RgT/gEYA/35FAP97RAH/gFgk//fl
+ zv////n////7///////6/P3/+/7//////P/9/f3/+v7////++v///uP/gF0x/3BDCv93QwH/fUYB/3lC
+ AP95RQP/fkkG/4FHAP98RQD/bEIN/8Ophf////f/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////3////9///////8///55v+gfE7/c0IE/3xF
+ AP98RQD/d0QF/3dEBf96RQL/ekYA/3pEA/95RQP/ekUC/3xFAP98RQD/fEUA/35GAP98RQD/fEUA/3pF
+ Av95RQP/eUUD/3pFAv98RQD/fkYA/35GAP9+RgD/ekUC/3lFA/93RQP/ekQD/3pGAP9+RQD/fEYA/3xF
+ Av96RgD/fkUA/35GAP9+RgD/dUQG/3FOIv/y3cL////4//7+/v///////////////v////7//f////v/
+ ///////////+//3////////////+////+/////v/2Mix/3VKF/96RgD/fUQA/35GAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP96RQL/eUUD/3lF
+ A/96RQL/fEUA/35GAP9+RgD/fkYA/3xFAP98RQD/ekYA/3pFAv96RQL/fEUC/3xFAP9+RQD/fEUA/3lE
+ Af9xRAv/kHFK////6v////n//f////r9///7/v///////////v////7////+////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7////8/////P/9/f3/+/////r9//////7////y/6+Ucv9rQQz/d0QF/3ZCAP96RgT/dkUH/3ZD
+ BP+BRwD/fkUA/3pDAP+acj7///jj////+/////v////+//z+///7/v/////7//7//f/7/v/////+////
+ 8P+Obkr/cUIM/3pEA/96QwD/fEgC/3pGA/95RQD/fkQA/4NLBP9sPQX/l3dT////9f////7/////////
+ /v//////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////9////+v7///v+
+ //////z///nm/517UP9vQQf/ekQD/3xFAP95RQP/d0QF/3pFAv96RQL/eUUD/3lFA/96RQL/fEUA/35G
+ AP9+RgD/gEYA/35GAP9+RgD/fEUA/3pFAv96RQL/ekUC/3xFAP9+RgD/fkYA/3xFAP96RQL/d0QF/3dE
+ Bf95RQP/ekUC/3xFAP9+RgD/fEUA/3xGAP9+RgD/fkYA/3xFAP9zRAf/cE4j//Ldwv////j//v7+//3/
+ ///9///////////////9/////f///////////////f////3///////7////7////+P/cyK//c0sX/3pF
+ Av9/RQD/gEYA/35GAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP96RQL/eUUD/3pFAv98RQD/fkYA/35GAP98RQD/fEUA/3xFAP96RQL/ekUC/3pF
+ Av96RQL/fEUA/3xFAP98RQD/eUQB/3FEC/+Sckn////p////+P/9////+v3///r+///9////////////
+ /v////7/////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////v///vn////8//r8/f/7/v//+/7/////+////Of/kHFK/3NF
+ C/98RwT/dkIA/3pHCP91RAb/dEEC/4JIAP9+RgD/dUQG/6mHWf////D////5///++v//////+v3///r+
+ ///9//z//P/9///+/v////7///v1/72hif9yPgn/gUYB/3lFAP94RQD/dkUA/3tHAP+BSAD/fEQA/4FL
+ D/9/WDH/+era/////P////7///z4/////v////7/+/v7///////9//////////////////7////+////
+ /////////f//////////////////////////////////////////////////////////////////////
+ //////////////v+///1/P//+P7////8+f//++j/nH1W/25CDf94RQb/e0QA/3xFAP98RQD/fEUA/3xF
+ Av98RQL/fEUC/3xFAv9+RQD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/fEUA/3xFAP98RQD/fkYA/35G
+ AP9+RgD/fkYA/3xFAP98RQD/ekUC/3lFA/95RQP/fEUA/35GAP+ARgD/gEcA/4BGAP98RQD/ekcI/2o+
+ CP9wUCf/8t7F////9//+/v7/+P7///X8///7/v///f/////////////////////////9/////f//////
+ //////j////z/9/Hqf9yShn/fkoI/4JGAP+GSAD/gEYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35G
+ AP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/3xFAP98RQD/fEUA/35GAP9+RgD/fkYA/35G
+ AP9+RgD/fkYA/3xFAP98RQD/fEUA/3xFAP9+RgD/fkYA/3xFAP99SAX/ckMG/5d0SP///+L////0////
+ /P/3+v//+P7///r+///9/////////////v////7////////////9////////////////////////////
+ ///////////////////////////////////////////////////////////+////+v////z/+P7///j9
+ /////v/////1///x1/90TSD/eEMA/4FHAP97SAn/ckMG/3FCBf96RgT/fkMA/35JBv9oQA//zbOP////
+ 8P////f///76//3////5/f//+P7///j9+//9//7////+///8/P///v7/4Mi2/3hGEv+ARQD/ekYA/3lG
+ AP94RQD/ekYA/4BGAP9+QwD/fEUI/3dMIf/jz73////5///9+v///v3////+///+/f/8/Pz///////3/
+ ///9/////////////v////7////+//3////9////////////////////////////////////////////
+ ////////////////////////////////////////+/7///b9///7/v/////5///95/+Yd1D/ZzwJ/3ZD
+ Bf9/RgH/gEYA/4BGAP+ARQD/fkUA/35FAP9+RQD/fkUA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35G
+ AP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP98RQD/ekQD/3pFAv98RQD/gEYA/4NG
+ AP+DRwD/gUcA/35GAP9yPwD/akAL/3BQJ//x27////7w///++v/6/v//9/3///v+///9////////////
+ /////////f////3+///9////////////+f////L/5Myu/21GGf91RAb/fkQA/4NFAP+ARgD/fkYA/35G
+ AP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35G
+ AP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/fEUA/3RA
+ AP9wQgj/lXJG///83v////D////8//v+///4/v//+v7///v+///////////+/////v////7///7///3/
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7////5/////v/2/f//8/n///39/f////P/5sup/3BGEf9/RwD/gEYA/3dEBf90RQj/dkUH/3pG
+ BP9+QwD/eEME/2tJHv/lz7P////w////9f////7/+v3///j+///2/f//+vz8/////v////7///v4////
+ /P/+6tj/fFAh/3hCAf98RQD/fUcA/3lFAP97RQD/gUcA/39EAP94QgP/bkIT/7ukiv////X////6////
+ /////v///f/////////9/f3//f////3////////////+/////v////7//f////3/////////////////
+ /////////////////////////////////////////////////////////////////////////f/////7
+ +P///u7////j/514TP9wQgz/fUcG/4FGAP+ARgD/gEYA/4BFAP+ARQD/gEUA/4BFAP+ARQD/gEUA/35G
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQL/fEUA/35GAP+ARwD/g0cA/4NHAP+DRwD/gEYA/3xIBv92SRD/dlIk//rfvf///+z////z////
+ /P///////f////3////////////////////9/////f7///3////9/f3///34////8//izbL/Z0Qc/3FF
+ D/99SAX/gEYA/35GAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xFAP98RQD/fEUA/3xF
+ AP98RQD/fEUA/3xFAP96RQL/dkcK/3BIFP+UdEv////n////9f////z/+/7///b8///6/v///f//////
+ /v////z////+/////v///v///f//////////////////////////////////////////////////////
+ /////////////////////////////////v////v///79//j9///z+v///v7+////8v+3mHH/cUQL/31G
+ A/99RQD/eEMA/3lGB/93RAX/eEQC/4JHAf92QwX/fFs0///w1/////D////2/////v/2+f3/+v7///f9
+ ///9///////////+/f///vv////7///45/+PbEH/dUYJ/3tEAP+ASQD/fEUA/3tFAP+CSAD/gEgB/3hE
+ Av9tQQz/kHRR////7f////v//v3///v+///7/v/////////+/f///v///f////3////////////8////
+ /v/9////+///////////////////////////////////////////////////////////////////////
+ //////////////////////7////4////8v///+X/nHlR/25DEP9yQwb/dUAB/3lFA/95RQP/eUQF/3dE
+ Bf93RAX/d0QF/3lEBf95RQP/d0QF/3dEBf93RAX/d0QF/3dEBf93RAX/d0QF/3dEBf93RAX/d0QF/3dE
+ Bf93RAX/d0QF/3dEBf93RAX/dUUF/3VEBv91RAb/d0QF/3lFA/98RQD/fEUA/3xFAv95RQP/cUIF/2Y+
+ Cv9rSR7/9t29////7v////T////5///9/P///////f/////////////////////////9/////f////3/
+ //////z////3/9vKtf9eQh//Yz8R/3JFDP90QwX/d0QF/3dEBf93RAX/d0QF/3dEBf93RAX/d0QF/3dE
+ Bf93RAX/d0QF/3dEBf93RAX/d0QF/3dEBf93RAX/d0QF/3dEBf93RAX/d0QF/3dEBf93RAX/d0QF/3dE
+ Bf93RAX/d0QF/3dEBf93RAX/d0QF/3dEBf93RAX/d0QF/3NEB/9oPgn/Y0AU/4htS////+z////3///9
+ /P/6/f//+f3///v+///9///////+/////P////7///////3////9////////////////////////////
+ ///////////////////////////////////////////////////////////+////+////fz/+P7///f9
+ ///////////v/45qPP91RAb/eEQC/3xFAP97RAD/fkcC/3dDAf93QgD/g0oF/3NDCf+Welf///7p////
+ 8f////n////+//f6/v/6/v//9/3////+///7+/v///79////+/////n////u/7edef9tRRD/d0MA/4NJ
+ AP9/RgH/fUQA/4FGAP9/RwD/eUUC/3BECf9zUCT//+vP////+P/2+f3/9/z///j+///9/P7////+///+
+ ///9/////f////3///////z////8//3////7////////////////////////////////////////////
+ //////////////////////////////////////////////3//////vr////2///y3f+SeVn/ZEQb/2VB
+ E/9oQA//Zz8O/2c/Dv9lPw//ZT8P/2U/D/9lQA7/Zz8O/2dADP9oQAz/aEAM/2hADP9oQAz/aEAM/2hA
+ DP9oQAz/aEAM/2hADP9oQAz/aEAM/2hADP9oQAz/aEAM/2hADP9nQAz/ZT8P/2U/D/9lPw//Zz8O/2hA
+ DP9oQAv/aEAM/2c/Dv9hPhL/YUIb/2pSNP/m1L3////x////9/////z///////3////9////////////
+ //////7///////3////9/////P7////+/f//+/T/08a2/2BLMP9bPhn/ZEEV/2lBEP9oQAz/aEAM/2hA
+ DP9oQAz/aEAM/2hADP9oQAz/aEAM/2hADP9oQAz/aEAM/2hADP9oQAz/aEAM/2hADP9oQAz/aEAM/2hA
+ DP9oQAz/aEAM/2hADP9oQAz/aEAM/2hADP9oQAz/aEAM/2hADP9oQAz/aEAM/2hADP9oQAz/Zz8O/2A+
+ E/9hRSL/h3JX///15f////j//v7+//v+///6/v//+/7///////////7////8/////v///////f////3/
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7////8///+/f/6/f//+v7//////P/148z/cUkV/3ZCAP92QwT/ekYE/35GAP+ARgD/e0QA/3pF
+ Av99RgP/bT8J/8Wrjf////D////1////+///////+v3///v+///6//////7////+/v////7////6////
+ +P////L/3syv/2VEF/93QwH/hEcA/4FGAf99RAD/gEUA/31FAP93RAD/c0UF/21EDf/ewZz////1//j7
+ ///0/f//9v3///38/v////7///////3////7/////f///////P////z//f////3/////////////////
+ ///////////////////////////////////////////////////////////////////9////+v////n9
+ /v////v////1/93Puf/SvaL/2cKi/9vCoP/awZ//2sGh/9jAov/YwKL/2MGh/9jBof/awaH/2sGf/9zB
+ n//cwZ//3MGf/9zBn//cwZ//3MGf/9zBn//cwZ//3MGf/9zBn//cwZ//3MGf/9zBn//cwZ//3MGf/9zB
+ n//awaH/2MCi/9rBof/awaH/3MGf/9zBn//cwZ//2sGh/9S+ov/Vwaj/zb+t///26f////n///38//3/
+ ///4+////f////3//////////////////v////7///////3////7/f7//v7+////+//58Ob/yLmm/9K9
+ ov/ew6H/3sKf/93Bnv/cwZ//3MGf/9zBn//cwZ//3MGf/9zBn//cwZ//3MGf/9zBn//cwZ//3MGf/9zB
+ n//cwZ//3MGf/9zBn//cwZ//3MGf/9zBn//cwZ//3MGf/9zBn//cwZ//3MGf/9zBn//cwZ//3MGf/9zB
+ n//cwZ//3MGf/9zBn//cwZ//176e/9bBpv/by7r////3/////P/9////+/7///X4/P/9////////////
+ /P////z////+///////9////+//////+////////////////////////////////////////////////
+ /////////////////////////////////v////7///////n9///7/v////32/8iylv9tQAf/fEUA/3lG
+ CP93RAX/gEYA/39FAP+CSAD/fkcC/3VAAf9tRBP/893E////9v////n////8//n7/P/7/v//+v3///v+
+ /////f////7//////v/+/vj////2////9P/07NX/dFo1/3ZDBf+ERgD/gEMA/39DAf+BRgH/fUUA/3dF
+ AP94RwH/dUUF/6qGWP///e3//f7///T9///0/f///f///////v///////f////v////9///////+////
+ /v///////f//////////////////////////////////////////////////////////////////////
+ //////////////v+///2/f//9fz///f8//////7////4////8v////P////v////8/////P////0////
+ 9P////T////z////8/////P////2////9v////b////2////9v////b////2////9v////b////2////
+ 9v////b////2////9v////b////2////9P////T////z////8/////P////z////8/////P////3////
+ +P//+/b////+//z9///4/P//9v3///j+///7/v///f////////////7////+/////v////////////3/
+ ///+/v7////+////+P///vH////x////7v///+v////z////9v////b////2////9v////b////2////
+ 9v////b////2////9v////b////2////9v////b////2////9v////b////2////9v////b////2////
+ 9v////b////2////9v////b////2////9v////b////2////9P////H////w///78f////v/+/v7//v+
+ ///7/v//+v3///////////7////8/////P////7///////3////7//////7/////////////////////
+ ///////////////////////////////////////////////////////////+///9/P//////+Pz/////
+ ////9ef/lnpX/3VDB/+BSAP/ekcJ/3NAAf+CSAD/gUUA/4ZJAP9+RQD/c0EF/4hlOf//9+T////5////
+ /P/+/v7/+/3+//3////7/f7//f/////9/////f/////+////+/////f////0////7v+Qfl//ckML/4FF
+ AP9+QgD/f0MB/4NIA/9/RwD/d0YA/3tKAP96QwD/glYh///y3f//////8vn///L7///9/////vz7////
+ /v//////+/////3///////7////+///////9////////////////////////////////////////////
+ ////////////////////////////////////////+/7///L5///2/f//+P7///j8/f////7////7////
+ +/////v////7/////P////z////8/////v////z////8/////P////7/////////////////////////
+ ///////////////////////////////////////////////////////////+/////P////z////8////
+ /P////z////8/////P////7//f39//3////6/f//+v7///f9///1/P//9vz///v+////////////////
+ /v////7////+/////////////P7///3//////////fv6////+/////j////0////9/////z/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////8////
+ +P////b////7/////v/8/v//+/7///r9///9/////////////P////v////7/////v///////f////v/
+ /////v//////////////////////////////////////////////////////////////////////////
+ //////7///79/////v/5/P/////8//7s1f9zUSb/dUIE/3xEAP95RAX/cj0A/4NLBP+DRgD/hUcA/3pB
+ AP91RxH/polk///77f///v3///////39/f/9/////f////v9/v/9/////vr////+///7+/v////7////
+ 9/////X//Pzw/8a5n/9rQA3/e0MC/4BGBf+ARAL/f0YB/31HAP94RQD/ekgA/4JJAP90RAr/0buf////
+ +f/6/v//8/r///3///////7////+///////7////+/////////////7/////////////////////////
+ ///////////////////////////////////////////////////////////////////9////+/7///v+
+ ///9/////f/+/////v////z////8/////P////z////+/////v/9//7//////////v////7////8////
+ /P////z////8/////P////z////8/////P////z////8/////P////z////8/////P////z////8////
+ /P////7////+/////v////7////+/////v////7////+//////////////////3////9/////f////v+
+ ///9/////f///////////////////////v////7////////////9/////f////3////9///////+////
+ /P////v////7/////P////z////8/////P////z////8/////P////z////8/////P////z////8////
+ /P////z////8/////P////z////8/////P////z////8/////P////z////8/////P////z////8////
+ /P////z////8/////P////z////7/////P////7//f////v+///7/v//+/7///3///////7////8////
+ +/////v////+///////9////+//////+////////////////////////////////////////////////
+ /////////////////////////////////v////7////+//v7+/////j/yrGR/2hADP+ASwz/fEMA/3lD
+ Av+BTAn/eUIA/39FAP+ISgD/fEUC/2lAD//bw6X////3///////9/////f////3////9////////////
+ /////P////7///v9/f/9//z//f70////9/////n/7uTS/3RRJf90Qgb/fkYF/3xDAP9/RgH/e0UA/3tI
+ AP9+SgD/f0UA/3dEBf+fg2D///zu//z8/P/6/v///v7+/////v////7////+//v////7/////f//////
+ //////7////+////////////////////////////////////////////////////////////////////
+ /////////////////////////////////v////z////8/////P////z////8/////v////7///////3/
+ ///9/////f///////v////7////+/////P////z////8/////P////z////8/////P////z////8////
+ /P////z////8/////P////z////8/////v////7/////////////////////////////////////////
+ //////////////////////7////+/////v/////////////////////////+/////v////////////3/
+ ///9////+/7///3////9//////////////////7////+/////P////z////8/////P////z////8////
+ /P////z////8/////P////z////8/////P////z////8/////P////z////8/////P////z////8////
+ /P////z////8/////P////z////8/////P////z////8/////v////7///////3////7/v//+/7///v+
+ ///9/////////////v////z////8/////P////7///////3////9////////////////////////////
+ ///////////////////////////////////////////////////////////+/////v//+vf////8///1
+ 5f+aelH/dEYM/3A7AP+ASQT/e0QA/3pDAP99RgH/g0sE/31DAP94RAL/dVIn///24P////v//f////3/
+ ///9/////f////3////////////////9/////v///f////3///////j////2////+////e//lXlW/2tA
+ Df97Rgf/fEMA/4BHAv95QwD/f0oB/39IAP+BRQD/ekQD/3JPJP/z38b////5///////+/v7////+////
+ /P////z//f////v////7/v///f///////P////z////+////////////////////////////////////
+ ///////////////////////////////////////////+/////v////z////8/////P////z////8////
+ /P////z////+/////v////7////+/////v////7////////////9/////f////3////9/////f////3/
+ ///9/////f////3////9/////f////3////9/////f////3////////////+/////v////7////+////
+ //////////////////////7////+/////v////7////+/////P////z////8/////v//////////////
+ ///////////////+///9/////f////3////9/////f////3////9/////f////3////9/////f////3/
+ ///9/////f////3////9/////f////3////9/////f////3////9/////f////3////9/////f////3/
+ ///9/////f////3////9/////f////3////9/////f////3////9/////f////3////9/////f////3/
+ ///9/////f////v+///7/v//+/7///3////////////+/////P////z////8/////v///////f////3/
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7///38////+/////f/6ta9/3VNHP92QwT/dkIA/3xHBP9/RwD/fkYA/3xHBP95RAH/eUEA/3VG
+ Cf+egl/////x/////P/7/v///f////3///////////////////////////////39/f/8/f///f//////
+ +/////n//Pv3///+9P/LtJr/ZEEV/3RCBv99RgH/fkcC/3tEAP98RgD/fUYA/4JHAP94QgH/aUEN/8On
+ hf////L///75///+/f////7////8/////P//////+/////r+///7/v/////8////+/////7/////////
+ //////////////////////////////////////////////////////////////////////7////+////
+ /P////z////8/////v////7////+/////v////7////+/////v////7////+/////////////f////3/
+ ///9/////f////3////9/////f////3////9/////f////3////9/////f////3////9/////f////3/
+ //////////////////////////////3//////v///////////////////////////v////7////+////
+ /P////z////+/////////////////////////////f////3////9/////f////3////9/////f////v+
+ ///7/v//+/7///3////9/////f////3////9/////f////3////9/////f////3////9/////f////3/
+ ///9/////f////3////9/////f////3////9/////f////3////9/////f////3////9/////f////3/
+ ///9/////f////3////9/////f////3////9////+/////3+///9//////////////////7////+////
+ /P////7////////////9/////f//////////////////////////////////////////////////////
+ /////////////////////////////////////Pv////5////7/+1mnj/cEMK/3lEAf9/Sgf/eEMA/39H
+ AP+DSwT/d0IA/3ZCAP98SAb/cEYR/9W/o/////L////+//v////9/////f//////////////////////
+ //////7//P7+//n8///4+f3////+////+////vn////4//jp1v9qTiv/az8E/35IAf97RAD/fkcC/3xD
+ AP99RAD/f0YB/3U/AP9zRQv/jms////y2f////f///38//////////v////7/////v/7////9v7///r+
+ //////v////5/////v//////////////////////////////////////////////////////////////
+ ///////////////////////////////+/////v///f////3////9//////7////+////////////////
+ /////////f////3+///9/v//////////////////////////////////////////////////////////
+ ///////////////////////////////////9/////f////3////9////+/////3+///9/////f////3/
+ ///9/////f/////+//////////////////////7////+/////////////f////3////9/////f//////
+ /////////////////////////f////3////9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////9//////7/////
+ /////////////////v////7////+/////v////////////3////9////////////////////////////
+ /////////////////////////////////////////////////////////////////v////f///LZ/39d
+ Mv91RAb/hU0G/3lAAP98RQD/fEUA/31GAf94QQD/f0sJ/3VHDf95Vir//OnU////+f///////f/////+
+ /////////////////////////////////v/9////+/7///v7/////v/////8////+/////j////1/455
+ Xf9qQgj/fEgB/3lCAP+ASQT/fEIA/35EAv99RQT/dUEA/3tGB/9xRxL/27+g////8v///fz/////////
+ +/////n////+//v+///0/f//+P7/////+/////j////8////////////////////////////////////
+ ///////////////////////////////////////////////+/////v////7///3+///9/v///f7///3+
+ /////v////7////////////////////////9/////f7///3////////////+/////v////7////+////
+ /v////7////+/////v////7////+/////v////7////+/////v////7///////3////9/////f////3/
+ ///9/////f////3////9////+/////3+///9/////f////3////9/////////////v////7///////3/
+ ///9/////f////3////9/////////////v////7////+/////v////////////////////7////+////
+ /v////7////+/////v////7////+/////v////7////+/////v////7////+/////v////7////+////
+ /v////7////+/////v////7////+/////v////7////+/////v////7////+/////v////7////+////
+ ///////////////////////////////////////////+/////v////7////+/////////////f////3/
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+////9//Tupr/a0MS/3pFBv+CSAD/e0AA/4FIA/97RgP/d0IA/3tEAP97Rgf/ZzwJ/6+R
+ bv///Oz////8///////9/////////////////////////////////////f76//3//v/6/f//+/3////9
+ /////vv///76///99v////n/yryl/3dRF/98SAH/eUIA/35HAv9+RAL/fkQD/3lEBf96RQb/fEUA/29A
+ A/+ef1j///fk///9+v///v/////5////+f////7/+/7///T9///2/v/////5////9/////z/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////v///f////3////9//////7///////////7////8/////P////z////+////////////////////
+ /v////7////+/////v////7////+/////v////7////+/////v////7////+/////v////7////+////
+ /v////7////////////////////////////////////////////9//////7/////////////////////
+ ///////////+/////v///////f////3+///7/v//+/7///3////////////+/////v////z////8////
+ /v////7////+/////v////7////+/////v////7////+/////v////7////+/////v////7////+////
+ /v////7////+/////v////7////+/////v////7////+/////v////7////+/////v////7////+////
+ /v////7////+/////v////7////+/////v////7////+/////v////7////+/////v//////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////vXo/45uSv9zRQ//e0UE/3tBAP+FSwD/fkYA/3tH
+ Bf93QwH/gUkC/3Q/AP9yTBz/69O1////9f/9+/r////////////////////+/////v////////////3/
+ //////z//f////b5///7/f////3////8/P////v///76/////P/78t7/f14s/3lKBv95RQD/fUQA/39F
+ BP97QgT/dUAB/35IB/9/RQD/d0IA/3ZPIv/w28D///z1//////////v////7/////P/9////9v3///j+
+ //////z////5/////v//////////////////////////////////////////////////////////////
+ ///////////////////////////////+/////v///f/////+/////////////////v////z////8////
+ /P////7////+//////////////7////////////////+/////P////z////8/////P////z////8////
+ /v////7////+/////v////7////+/////v////7////+/////v////7////+/////P////z////8////
+ /P////7////+//////////////7////+//////7////+///////9////+/7///v+///7/v///f//////
+ //////7////8/////P////z////8/////v////7////+/////v////7////+/////v////7////+////
+ /v////7////+/////v////7////+/////P////z////+/////v////7//////////v////7////+////
+ /v////7////+/////v////7////+/////v////7//////////v////7////+/////v////7////+////
+ /v////7////+///////////////////////////////////////////////////////9/////f//////
+ //////7////+/////v/////////////////////////////////9///////+////+f/j07z/akQU/3hF
+ Bv94QQD/g0gC/39HAP95QgD/e0cF/3RAAP+CSgP/eUYI/45sQf//8dr////7//v//////v//////////
+ /v////7////+/////////////f////3//v/7////+/7///38/////f////7////+//////7//f78////
+ 9P+2nXX/bEYM/3pGA/97QwD/fEQD/3xEA/95QwL/gkoD/4VGAP9/RQD/b0IJ/6eLaP//++/////+//v7
+ +/////7////8//v5+P/7/v//+v////j8/f/9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////v////7////+///////////////////+///9+f////3////+//////7////7///9
+ 9f////b////4////9/////r////8/////v///v3///38//7/+/////z//f/8//z/+//9/vz///79////
+ /v////z////7////+P////j////3////+f/+/vj////+///+///6+v////7//////P////v////+//3/
+ ///7/v//+/7///v+///9/v///////////v////z////6///++f////z////+//3+/P///v3////+////
+ /v///v3//f39/////////////v7+///////6+vr///79/////v////z///34////+/////z///////3/
+ /////v/////////////+/v7//v7+//7+/v////////////////////////////3//////v//////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7///////r+///7/v///////////P////n////7///+/f/9/////P7///39/f////7//v7+//r9
+ //////z////q/6GDWv91SAv/dz8A/4RKAv95QgD/ekcI/3RBA/97RQT/dj8A/4FIA/9vQQf/za+M////
+ 7//7/v//9P3///v+////////////////////////////////////////+/////v////7/v///f3////9
+ /////v////7////+///+/v7////1//Phwv9rSxr/dUcH/4JLBv93PwD/e0UE/31GA/97QQD/hEUA/4lN
+ Af9zQgT/bUoe//fm0f///Pf///////b4+f////7////+//7+/v/5+/z/+v7///j8///9////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////7////9
+ /////f////z+//37+v///vn////5////+f////n////6/////P////7//////////v////7////+//79
+ +f/9/vr//f/8//3//v////7//////////v////z///75////+f///vb////5////+/////7//v3///b5
+ /v/9/v/////8////+/////7//f////v+///7/v///f7////+/////v////79///9+f////z////8//7/
+ /f/+//3//f/////////9/f3//Pz8/////////////v7+//39/f/8/Pz//Pz8/////////////f39////
+ //////7//vz7//r6+v/9/////f////3////9///////////////+/v7//v7+////////////////////
+ ///9/////f////3////9////////////////////////////////////////////////////////////
+ /////////////////////////////////v//////+v7///v+///////////8////+f////n////+//v9
+ /v/9/////P7////+/f/7+/v//f/////+9f/y27v/cksX/3NCAP+GTwb/fkQA/3pDAP98SQv/dUIE/35H
+ BP9+RQD/fEcI/35TIP//6sz////3//b9///x+v//+/7/////////////////////////////////////
+ ///7////+/////3+/////v////7////+/////f////7///7+/v////f////n/6OHXv9uRgz/d0QF/3dB
+ AP99RgP/fEYF/3pDAP+ARgD/hEoC/3ZCAP9hOQX/p49x////8f///v3/+//////+///8/Pz////+////
+ ///7/v//+v3///3/////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////f////b4+f/////////////+/////P3//fv7//j6+v/6////9f39//X9
+ /f/6/////f/////9/P///v3////+/////v/+/Pv/+vz8//v////6////9/z9//j9/v/7//////////r4
+ +P//+/z///z9//78/P//////+/////v///////z////8//3////7/////f////3////////////+///7
+ +v///v3///////3////7////+Pz9//b6+//7////9vr///r+///7/v//+/////r5+//+/v7////+////
+ /v////7///////z+///7/v//+P7///P6///1/P//9v3///v+///9/////f////3////9/////f//////
+ ///+/v7//////////////////////////////////f////3/////////////////////////////////
+ ///////////////////////////////////////////////////////////////////9/////f//////
+ //////7////8/////P///v3///////v+///3+v7/+/3+/////v/9+fT////u/6SGXf9kPAL/dkYE/31J
+ A/96QwD/e0QA/3lEAf9+RwT/fEMA/3pEA/9wQQn/vZpv////7f///PX/+v7///P6///7/v//////////
+ //////////////////////////////v////7/////f/////+/////v////7////+/////v//////////
+ +P///Oj/7dm2/2xLGv9sQAX/fkgH/3xFAv97RQT/fEcE/39HAP96QgD/ekUC/3pMEv9jQxr/89/G///+
+ 9//9////+vz9//r6+v////z////8//38/v/9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////9//7/+fz6/////////v////3////9
+ /////v//+/7///r////4////+v////3//P////r////4////+P////j////4////+P////n////7//v/
+ /v/5//7/9/////n+///9/v////7////9/////f///vv9///////7////9vv5/////v////7/+/////v/
+ ///9/////////////P////v///77/////v/7/v//9Pr///j+///4/v//+/////3////9////+fv8//78
+ +/////z///73////9f////X////0///68P////b////7//39/f/3+///9v3///T8///v+P//+v7///3/
+ ///9/////f////3////9//////7////////////////////////////////////////9/////f//////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////v////////////////////7////+///9/P//////+v3///b6///9///////8///9
+ 7//q1bb/bEcV/3hLDv93SQn/cD4A/31IBf96QwD/fkMA/4BFAP95QgD/eUcL/29IG///5cb///3t///8
+ 9//7/v//+f3///3/////////////////////////////////////////+/////3////////////////+
+ /////v////7////+//////7////3////9P///uf/kHZR/2Y+Df96Rwj/fUQA/3tGA/93QwH/e0cF/3VA
+ AP+BSQL/e0cF/2k/Cv+pjWr////x///9/P/6/P3//////////P///Pf/////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////+//v/
+ +v/9//z//f////n4+v///f////3///v7///6+///+Pr6//r79/////b////0///66P/869b/+OPN//vj
+ zf/95c//+eTO//nr1f//+Ob////z////+P////z//f////f4/P/9/f///f3///39///7/f7//P7+//3/
+ /v/9//z//f////3////7/v//+/7///////////z////5////+f////v///////f9///z/P//9P3///j+
+ ///9/vz//fn0////+P////X////y///45f//7NP//+zQ///qzP/54cP//+nN///w1f//++j////0////
+ +//9/f3/+/7///r+///7/v///f////v+///7/v//+/7///v////9//////////////////7////+////
+ /v////////////3////9////////////////////////////////////////////////////////////
+ //////////////////////////////////////7////8/////v/9/////f////3////////////+//39
+ /f/1+f7/+v7///3////+9+7////r/5x8Uf9zRwr/dEIA/3JDBf90RQf/fEgG/31FAP+HSQD/fkEA/3pE
+ A/9xRxL/mX1a////6/////j////+//j4+P/9////////////////////////////////////////////
+ ///7/////f///////v////7////////+///9/v///f/////+/f////v////5////8f/dyq//Xj4V/3VG
+ Cf99RAD/eUQB/3dDAf9+Sgj/ekUC/39FAP96RAD/dkQI/3RQIv/l0bj////3/////P///fz///z4////
+ /P//////+vz9////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////7/+f34//3//P/9/////f////3+///4+f3//vv9/////P////j////y//Xj
+ zP+0n4D/gGZC/21QK/9nRh//XjsT/147E/9tTCX/fFw4/5F3U//ArI3/+OjR////8P//+u/////8////
+ ///09/v/9/r+//v////7/f3//f/8/////P/9/////f////v+///7/v///////////P////n////4////
+ +v/7+vz/9v3///T9///2/f///f//////+P////H////s//fix//Hro7/k3dU/3JSKf9nRRf/akQU/2dB
+ Ef9hPQ//fVsw/4ptSP+3n4H//+/a////9P/+9+7////7///+/f///////f////3////7/v//+/7///3/
+ ///////////+/////v////z////8/////v///////f////v//////v//////////////////////////
+ /////////////////////////////////////////////////////////////////v////z////+//3/
+ ///7/v//+/7///3///////7//f39//n9///6/v///vz8////9P/kyKX/c0kU/4BMCf9vOwD/eEkM/3VG
+ Cf91QQD/g0gC/4VFAP+ERwD/c0EF/2pFGf/l0bj////z/////P///////f39////////////////////
+ //////////////////////////////3+/////v/////+/////P////////7///3+///9////////////
+ /v/7+/v///75////8f+JcE7/c0YN/3xFAP96QwD/fEcE/31IBf9+RwL/fEIA/4NMA/9zPQD/bkIM/5l9
+ Wv//79r////3//v38v///vr////+//z+///5/P///f//////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////7//f/+//X6+f/7////+v/+//r7
+ 9/////j////v/+7Vu/+phmT/b0Ua/24/DP94SRH/cEII/2s/Av91SQz/dEcK/2o9AP9wQAb/dUgP/2o/
+ DP9wSx//spRx//7pzv///Ov////4//3//v/4/v3/+v////v////9/vz///79///////9////+/7///v+
+ ///9///////8////+f////n////8//r8/f/1/P//9fz///r8/f////j///zn//rhwf+jg1r/dlIk/142
+ Bf9tQw7/eUsR/3FAAv9zPgD/fkoI/3lGB/9wQQT/c0cR/2hCEv9mRh3/p4to//nhw////+r////2////
+ +/////7///////3////7/v///f////////////7////8/////P////z////+///////9////+//////+
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7////8/////v////7//f////v+///9/////f////z8/P/9////+v7///v/////+/T///bf/5Ju
+ QP92RQf/e0MA/31FAP98Sw3/b0AD/3ZBAP+DSQH/gUEA/4VLA/9vQw7/lXlX////8v////v///7+//v7
+ +//////////+/////////////////////////////////////////////f7////+//////z////8////
+ /////v///f7///3/////////+/v7//r////9///////4/9nFrP9rRBD/eUcF/3lEAf98RQD/d0AA/4BI
+ Af+BRwD/e0MA/4BJBP9zRAf/akYY/9rBn////On////3/////P/8/v//+f3///r+///9////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////r8
+ /P/9////+f79//v//v/6/Pb////1///86f/HrY//d08l/3dFEf94PgP/f0IA/4JGAP+ARgD/eUYA/3lI
+ AP99SAD/fkcA/4JIAP+DRwH/fUEA/3U/Av91SBX/d1Uq/9K9nv//+OH////3//v/+f/7//7//P7+////
+ ///////////////////7/v//+/7///3///////7////7////+/////7/+fz///j+///7/v/////5///9
+ 6P/TtZL/dlAg/2xCDf9xQwn/dEUI/3dEBf93QgD/f0cA/4JIAP9+RAD/e0MA/4BJBP90QQL/c0QH/3FF
+ D/9gOAf/hGAy/9G1kv///+/////2////+v////z///////3////9/////////////v////z////8////
+ /P////7///////3////7//////7/////////////////////////////////////////////////////
+ ///////////////////////////+/////P////z////+///////9/////f////3//////////f////3/
+ ///6/f/////8////8v/MsY//b0UQ/3dCAP+ARgD/g0kB/3E+AP91RAb/gEkG/35EAP+DRgD/d0MB/3FM
+ IP/jzbT////3///////+/v7///////39/f/9/f3/////////////////////////////////////////
+ ///9/v////7//////P////z////+///////9/////f/////+/v/9////9/3///n9//////z////t/5Ry
+ R/9wQgj/dkIA/39HAP+CSAD/fEIA/4NLBP97RAD/ekUC/3ZFB/9zRg3/gV0v///11f////H///75//r9
+ ///2/f//9f3///3+////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////9////+/////r//v/9//7/+frx////9P//+uL/s5p4/2hDF/91Qgr/gEMD/4lE
+ AP+KRgD/iUcA/4VHAP+ASAD/fEkA/4BIAP+BSAD/h0cA/4lHAP+KRgD/hUUA/3xEA/9wQwr/bEse/7ej
+ gP///+f////0////+P////7/+fn5///+//////7////+//3////9/////f////////////7////+//r8
+ /f/9////+fv8////+f//8t3/tph1/3FHEv93Rgj/dUQG/3dEBf95RQP/eUUC/3xFAv98RQD/fkYA/35G
+ AP9+RgD/fUYB/3tGA/93RAX/dEMF/3RFCP91Rw3/bkgY/6+Xef///+/////1///99v////z//v7+//3/
+ ///////////+/////P////z////8/////v///////f////v//////v//////////////////////////
+ //////////////////////////////////////////////////////7////6////+///////+/7///3/
+ ///9///////+///////9/////f////////////b//+nP/3tYLP9zRAf/f0gD/4VKAv94PgD/fUcG/3tH
+ Bf98QwD/e0MA/35HBP9uQQj/m4Be///87P////z//P7///////////////////z8/P//////////////
+ //////////////////////////////3+/////v/////8/////P////7///////3////9/////Pz8//3+
+ ///4/v//+P7///////////H/3cOf/3NMGP95SAr/fkYA/4FHAP+BRwD/fUUA/3lEAf98SAb/c0AB/3ZD
+ BP9sPwb/v51y////6v////f/+/7///b9///2/f//+/7/////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////3////4/f7/+/////v79f////X///zl/7ad
+ e/9sShz/cUMN/3xEA/+FRQD/iUYA/4pGAP+HRwD/g0cA/35HAP98SAD/fkcA/4FHAP+FRwD/h0cA/4lH
+ AP+HRgD/gUYA/3lFA/9uQgz/bEsd/7ikgf///+n////1//369f/9////+fv8/////v////7///////3/
+ ///9/////f////3////9/////f////n5+f////n///zq/7mefP9vRxb/g00M/3o/AP98RQD/ekUC/3pF
+ Av96RQL/ekUC/3xFAP98RQD/fEUA/3xFAP99RgH/fUYD/3pFAv95RAH/eUQB/3xHBP91Rw3/bE0m/7ij
+ iP////D////1////+P///v3///7///r8/f/////////+/////P////z////+///////9////+//////+
+ ////////////////////////////////////////////////////////////////////////////////
+ /v////v////7//3////6/v///f////7+/v///v3////+//X3+P/////////5///34v+2l3D/bkQP/3dE
+ Bf97QgD/fkQA/4dMBv91PgD/fUgF/4JJBP97RgP/d0gL/3BMHv/izrX////3/////v/8/v///v7+////
+ ///7/f7//f////////////////////////////////////////////////7////+//////7////8////
+ /v////7//f////3////+/f///f7///n8///6/v///f39////9////+r/oIRb/25CDP92QgD/gUcA/4NJ
+ AP94QQD/ekUC/3lGB/92QgD/fUYB/4FNC/9oPgn/+t24////8v/5+fn/+P7///P6///7/v//////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////f////j/
+ ///0+ff////4////7//ZvZ7/bUgc/2Q1AP94QwT/fkUA/4BGAP+ARgD/fkcA/3xFAP96RQL/eUUD/3lE
+ Bf95RAX/ekQD/3pFAv98RQD/fEcA/3xHAP9+RwD/ekYA/3dEBf9mOgT/ck8j/+HIqP///+7////4//z/
+ /f/2+/z////+/////v////7///////3////7////+/7///v+///9///////7///97f/YwKL/Z0MT/3RD
+ Bf96PQD/iEgA/4BGAP98RQD/fEUA/3pFAv96RQL/eUUD/3lFA/95RQP/ekUC/3pFAv99RgP/fEUA/31F
+ AP9+RAD/f0UA/3pGBP9eNgX/a04p/93Hq/////D////3/////P/+/f///f////////////7////8////
+ /P////7///////3////7//////7/////////////////////////////////////////////////////
+ ///////////////////////////+////+/////z/+/7///n9///8/v///v/9////+/////v/////////
+ +////+//5sup/21FEf9zQgT/dUEA/31GAf99RAD/gkcB/4JJBP91PgD/gEkG/3RDBf9kPAv/q5Ft////
+ 8f///vn///////3///////////////v9/v/9////////////////////////////////////////////
+ /////v////7///////////7////+/////v/9//7//f////3////6+////P3///3+/////fz////5////
+ 8v/p17r/d1Un/2w+BP9+SQb/f0cA/3tEAP96RQL/dkEC/3tHBf+ASAH/eEEA/3BBBP+Tb0H//+7V////
+ +P/6/P3/+v7///3/////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////9////+P////3//P////T/+OHH/4FdNf9wQAz/fEUI/4JJBP98RgD/ekYA/3dG
+ AP91RgL/dUUF/3VEBv93Qwf/d0IJ/3dCCf91Qwf/dUQG/3NFBf9zRgL/dUcA/3pGAP98RgD/e0QA/39K
+ C/9uPwv/h2M7///x1v////P////8//r////9/////////////v////7///////3////6/v//+v//////
+ /v////X///HW/3RUK/9yRQz/fkcC/4dHAP+LSQD/gUcA/35GAP9+RgD/fEUA/3pFAv96RQL/eUUD/3lF
+ A/95RAH/ekUC/31GAf9+RgD/f0UA/4BGAP+CRgD/fUUA/3hKEP9hOwv/iGtG//vmy/////T////7//z8
+ /P/7/v///f////////////7////8/////v///////f////3/////////////////////////////////
+ ///////////////////////////////////////////////////////////+/////v/6/f//+v3////+
+ //////7////8/////P////z////z///s0P+RbkL/ckMG/3Q/AP98RwT/fEcE/31GA/98QwD/gUYA/31G
+ Af94QwT/b0MN/21PJv/55sv////1//j38////////f///////////////f////r8/f//////////////
+ ///////////////////////////////9/////v////7///////////z////8/////v/9/////f7///r7
+ /////v/////+///++/////v/+vjw////8v+0m3n/aUMT/3FCBf97RgP/fUYB/3tFAP94QwD/ekUC/3Y/
+ AP99SAX/ekcI/2g+Cf+8n3r////q////+f/5+fn/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////3////4/fz////5////7f+1mXf/aj4P/3pE
+ CP98QgD/gkgA/3xGAP93RgD/cUYD/3BFBv9xRAf/c0QH/3dDB/95Qwf/d0MH/3VDB/9xRAf/cEQH/3BF
+ Bv9xRgP/d0YA/3xGAP9/RQD/fUQA/3hCBv9pPxD/x6yK////7f////n/+P79//v+///9///////+////
+ /P////z//f////r////7///////6////8f+3m3j/bEQQ/3NAAf99QwD/hUgA/4NGAP+BRwD/gEYA/4BG
+ AP9+RgD/fkYA/3xFAP98RQD/fEUA/3tEAP9+RgD/f0cA/4FHAP+BRwD/gUcA/4NHAP+ARgD/eUQB/3RG
+ DP9kQBL/v6SC////7v////n///////j7///7/v///f///////v////7////+///////9/////f//////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///9/////f////7+/v///////////////v/////////8///58P///un/uJhv/2o+CP+CTQr/e0MA/3xH
+ BP94QwD/fUYD/35FAP99QgD/e0YD/3xMEv9gPAz/wquL////7v////f////7///////5+/v//f////v9
+ /f/9/////f39//////////////////////////////////////////////3////+///9/v///f//////
+ /P////v////8//3////6/f///f7//////v//+/b////5////+//6///////7//np0v+DZD3/YjoG/3RD
+ Bf98RAD/f0UA/4JKA/96QwD/e0YD/3xIBv94RAL/c0UL/3NNHf/ky6v////y////+/////7/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /v////b///Pd/3FRLf91RhL/cTsA/4NJAf99RAD/fEcA/3dGAP9zRQX/cUUG/3NEBv91RAb/ekQD/3xE
+ A/96RAP/d0UD/3NEBv9xRQb/cUUG/3NFBf95RgD/fkcA/4JIAP+CRwD/d0EA/3dIFP93VzP///vk////
+ +P/09vb/+v7///v+//////7////7////+/////7/+/////3///////j///Ha/3lXLP90Rgz/ekMA/39E
+ AP9+RQD/fUQA/4BFAP+ARgD/gEYA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/35GAP9+RgD/f0cA/39H
+ AP9/RwD/gUcA/4FHAP97QQD/fUgF/2xCDf+CYzz///Db////9///////+fz///v+///7////////////
+ /v////7////+///+///9////////////////////////////////////////////////////////////
+ /////////////////////////f////v+///7/v////79/////P////7///////3//////v3////0/9C4
+ mv9yShb/eUYH/3tDAP+DSQH/ekUC/3dBAP98RQL/f0YB/4RJBP9zPwD/bEIN/39hOP//++H////y////
+ +f////z//f////j8/f/7/v//+Pz9/////////v3/////////////////////////////////////////
+ /////f////7///v+///7///////8////+/////z//f////n8///9/v/////8///88/////f////6//T+
+ ///x+v3////0/8uzlf9xTyT/bUAH/31FAP+DRwD/g0kA/35GAP91QgP/d0YI/287AP93RAX/dUgP/4hm
+ O//+7NX////3/////P//////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////7+////9v/RuaH/ZEQb/2c8A/97SAL/hE0C/39HAP9+RwD/fEYA/3lF
+ A/95RQP/ekUC/35GAP+BRwD/gUgA/4BIAP9+RwD/ekYA/3lFAv95RQP/ekQD/35GAP+ARwD/gEQA/39G
+ AP98SQP/aT4F/2JCGf/k0Lf////3///////4/f//+P7///////////v////5////+//9///////+////
+ 9f/Yw6f/aUEQ/3NAAf+CSAD/iE0H/3dCA/93RAb/ekUC/3xFAP98RQD/fEUA/3xFAP98RQD/fkYA/35G
+ AP98RQD/fEUA/3pFAv96RQL/eUUD/3pGBP94RQb/fEUA/4lLAP+ARgD/dEUI/2ZEGf/axq3////1////
+ /v/7/v//+v7///v+/////v///////////v////7///7///3/////////////////////////////////
+ ///////////////////////////////////////////////////9////+P7///n9//////r////5////
+ /P//////+Pz///v7+//26Nb/dFcy/3FDCf98RAD/g0kA/31DAP9+SQb/d0MB/3xCAP+DSAP/f0YB/3lG
+ CP9uSBj/3sOh////7/////f////3////+//7/f3/+/7///j+///6/f/////+////+/////7/////////
+ ///////////////////////////////9/////v///f7///v///////7////8/////P/9////+/7////+
+ /////fr////5////+P////v/8Pr///T//////vn////w/5FzUP9qQg7/fkkG/4JIAP93PQD/gEkE/3xH
+ CP92QwT/f0oH/3pFAv90QwX/a0EM/52AW////+r////5//////////7////+///////9/////f////3/
+ /////////////////v////7////////////9/////f//////////////////////////////////////
+ /////////////////////////////////////////////////v///Pz///3y/6OHaP9oQhL/c0QG/35K
+ A/96RgD/f0gA/35HAP9+RwD/fkYA/35FAP9+RgD/gEYA/4FHAP+BSAD/gEgA/35IAP9+RwD/fkYA/4BF
+ AP+ARQD/gUYA/4FHAP+BSAD/fkcA/3lFAP9yRgf/ZkIS/7mggP//9+v///7///v9///7/f/////+////
+ +/////v////8//3///////7////0/6yTc/9pPQf/e0cB/4NJAP94PgD/fUoM/3E/A/95RAX/ekUC/3xF
+ Av98RQD/fEUA/3xGAP9+RgD/fkYA/39HAP98RQD/eUQB/3lEAf95RQP/d0QF/3dEBv96RQL/f0UA/4FH
+ AP90QQL/akIR/62UdP///+/////8//r9///7/v//+/7///3///////////////////////////////3/
+ ///9/////f////////////7////+/////v////7////////+/////v////7////////////////+//3/
+ ///4/v//+f7/////+v////n////8///+/f/7+/v///rx/493W/9jPQ3/fUkH/4BGAP+BRwD/g0kB/3VA
+ AP98RgX/gEcC/3hBAP9+SAf/bD8G/6yMY////+r///3w////+f////n///76//3////6/v//9vr///v+
+ //////7////8//////////////////////////////////////////////7////+/////v///f//////
+ //////7////+///////9/////////////v////7////8/////v/7////+/7///7+/v////f/9du9/4Rg
+ Mv9sPgT/fEcI/3hDBP91QQD/fUYD/35HAv+CRwH/fEMA/3lEBf9xPwP/eEoU/8uqg////fP/+vz9////
+ /P///vr//f39//r9///4/v//+P7///3///////7////7////+/////7//f////v+///7/v///f//////
+ ///////////////////////////////////////////////////////////////////////////+////
+ /v//9eX/jGlB/3NDCf+BSAP/fkQA/3tEAP98SAL/fkcA/4BHAP+BRwD/gUcA/35GAP98RQD/ekUC/3pF
+ Av95RQL/eUUC/3xFAP9+RgD/g0cA/4VHAP+DRgD/gEYA/3lFAP97RwH/fEUA/4BMBv9rPQP/ooJZ///7
+ 6////v3///7////+//////z////8//3//v/7/////f3////+////9un/jW1K/3VHDf99RgD/hEcA/4dM
+ AP9+RAL/ekMG/3lFA/95RQL/ekUC/3xFAP98RQD/fkYA/4BFAP+ARgD/gEYA/4BGAP9+RgD/fkYA/3xF
+ AP96RgD/ekUC/3pFAv98RwT/d0IA/3xHBP9yQwb/knBF////6v///fb/+/////v+///7/v///f//////
+ ///9/////////////v///////f3///v9///7/v///f//////+/////n////7/////P////////3////9
+ /////f////7///////////v////7//3//v/8//3//vz7/////v////v////4///55/+3ooP/a0QX/3A+
+ Av+DSAL/f0IA/4FIAP9/RwD/fUUE/3lBAP9/SAP/eEQB/29DCP+HZTf//unK////7f////n////+////
+ /v/9/////f////3////9/////f//////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////v///P3//////P///+7/xqiF/3dPH/9rPAT/c0EF/3xGBf95QAD/fEEA/4BFAP9/RgH/gUoH/35I
+ B/9uOQD/gFcm/+HQu/////j///32////+///////+/7///j+///2/P//+/7///////////z////7////
+ /P///////f////v+///9////////////////////////////////////////////////////////////
+ //////////////////////7////8///14/9+Vyr/dkEC/35CAP+FSgL/ekQD/3lEBf98RQD/gEcA/4FI
+ AP+BSAD/fEYA/3pFAv95RQP/eUQF/3dEBf95RQP/ekUC/35HAP+FRwD/hUcA/4FHAP98RQD/d0QF/3hE
+ Av+ESgL/fUYA/3RBAv+QbD7///vp/////P///v////7//////P////z/+/////r////9/f////7////u
+ 3/+KaET/b0AD/4BIAP+GSgD/gkcA/3tBAP9+SAn/ekQD/3pFAv96RQL/fEUA/35GAP9+RgD/gEYA/4BG
+ AP+ARgD/gEYA/4BFAP9+RgD/fkUA/3xFAP98RQD/ekUC/3VCA/96RgT/f0gD/3A9AP+AWir////p////
+ 9//8/v//+/7///3///////////////3////9///////8/////v/9/f//+/3///v+///9///////7////
+ +f////v////8/////////v////3////+/////v//////////+/////v////8//7//f/9//////////36
+ 8v////H/07qa/3NPIf9zQQX/f0YB/4dMBP9+RAD/fkYA/3tEAP9/Rwb/fkgH/3RAAP94Sw7/aEMR/9a7
+ lv///+3////3//38+P/9////+/////3///////////////////////////7///3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////+/f/////+///99P///+z/nHtU/2tADf92QwX/fkUA/4JJ
+ BP9/RgH/f0YB/31EAP96QQD/gUoH/3VCBP9sQAv/gGA8//Tgx/////b////+//r8/f/4+vv//f////3/
+ ///7/v//+/7///3///////7////8/////P///////f//////////////////////////////////////
+ /////////////////////////////////////////////////v////z///Xj/3JOIP92QQL/f0MA/4RI
+ Av97RQb/dkMF/3lFA/96RgD/fkcA/35HAP98RgD/ekYA/3pFAv96RQL/ekUC/3pFAv98RQD/fkYA/4FH
+ AP+BRwD/fEUA/3lFA/91RAb/dEEC/4FJAv97QwD/d0QG/4BcLv//+Ob////8///+/////v/////+////
+ /P/9/////f////3+//////z//enY/4ZkQP9vQAP/fkcA/4NIAP9+RQD/d0ID/3pGCv96RAP/fEUA/3xF
+ AP98RQD/fkYA/35GAP9+RgD/fkYA/35GAP98RgD/fEUA/3pGAP96RQL/ekUC/3pFAv96RQL/d0IA/3xH
+ BP+ASAH/cD8B/2xIGv///+r////5//r9///7/v///f///////////////f////////////7////+//3/
+ ///7//////7///////////7////8/////P////7///////3////9/////f////3////////////+////
+ /v/9/f3//f////T7/v/9//7////1/+vVuf+IXzL/cj4C/3xGAP+DSwD/gUcA/35DAP+ESAb/fEIB/3lD
+ Av9yQgL/cEQJ/2Q/Df+tkGn///vf////8v////n///////v+///7/v///f////////////7////+////
+ /v//////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////+///49/n/////////
+ 9//238X/gVww/3lHC/97QgD/fEMA/3xDAP98RQL/f0gF/3pBAP96QwD/e0gK/3NEDP9lOgf/lXVM//7t
+ 2P//+vH////+/////////fz///////v+///6/v//+/7///3///////7////8/////P////7/////////
+ ///////////////////////////////////////////////////////////////////////////+////
+ /P//9eP/dVIm/3hFB/+DSAL/f0MA/3pEBf90QwX/d0QF/3dGAv96RgD/fEcA/3xGAP98RQD/fEYA/35G
+ AP9+RgD/fkYA/3xFAP9+RgD/gEYA/35GAP96RQL/d0QF/3VEBv92QwT/e0MA/39HAP93Rgj/hGE1///1
+ 4////v3//f7///3+//////7////8/////v//////////////+f/97Nn/gmI+/3VHDf99RQD/f0UA/4BI
+ Af94Rwn/cEEE/3pFAv98RgD/fkUA/35GAP9+RgD/fkYA/35GAP98RQD/fEUA/3pFAv96RQL/eUUC/3lF
+ A/95RQP/eUUD/3pFAv98RQD/f0cA/35FAP93SAv/a0ke////6////fj/+/7///v+///9///////+////
+ /v///////////////v////7////+/////v////7////////+/////v////7//////////////f////3/
+ ///9/////f////3//////v////7////+///9////9fr5////+P//79j/gmE6/3ZDC/+ARQD/h0wA/4BI
+ AP98QgD/gEcC/4FHBv95QQD/e0cF/3BDBv9lQA7/fWA5///w0f////D////2//78+//7////+P3///v+
+ ///9/////////////v////7////+////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////+vz9//v+///1+///////////8f/ixqT/ckYR/3pFBv97RAH/fkUA/3tEAf9+RwT/f0gF/3dC
+ AP95RAX/dUIE/3xJCv9qPgj/n4BZ///34P////X////8//f39//9////+/7///v+///7/v//+/7///3/
+ //////7////7////+/////7/////////////////////////////////////////////////////////
+ //////////////////////7////8///05P99WzD/eEYK/4FGAf+ARAD/d0EA/3lGB/91RAb/dUUF/3lF
+ Av96RgD/fEYA/3xGAP+ARgD/gEYA/4BGAP+ARgD/fkYA/35GAP98RQD/ekUC/3dEBf91RQX/eEUH/3tH
+ Bf99RQD/fkcC/3VGCf+Uckf///bm/////v/7/v//+/7//////v////z////8/////v////7////4///1
+ 3/+BZD//d0oR/3pDAP9/RQD/f0gD/3VIC/9tQAP/ekUC/35HAP+ARQD/fkYA/35GAP98RQD/fEUA/3pF
+ Av96RQL/eUUD/3lFA/95RQP/eUQF/3dEBf93RAX/ekUC/4FHAP+BSAD/ekMA/3RHDv95WjP////t///+
+ +v/7/v//+/7///////////z////8/////////////////////v////v////5/////P////////7////+
+ /////v////7///////////7////+//3//v/9/////f////3+///9/v//+vz9/////v////j///Lf/41x
+ Tv9qQg7/d0MB/4BDAP+ISQD/g0YA/4FGAP+CSQT/dkEA/3hEAv9/Swn/c0YN/2tOJ//Ww6j////w////
+ 9/////z/+/////j+///4/v//+v////3////////////+/////v////7/////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////3////7/v//+f3///b9///7/v/////5////6/+4lmv/bT8J/3pF
+ Bv+ASQb/e0YD/3dCAP97RgP/eEMA/31IBf98RwT/ekMA/3ZDBP9vRRD/spNs///z3P///fP////+//r8
+ /f/9/////f////v+///7/v//+/7///3///////z////7/////v//////////////////////////////
+ //////////////////////////////////////////////////////7///jq/45vSP9zRAz/eUAA/4dM
+ BP94PgD/fUkH/3dEBf91RQX/d0YC/3lGAP98RgD/fkYA/4BGAP+BRwD/gUYA/4BGAP9+RgD/fkYA/3xF
+ AP96RQL/d0QF/3dEBf95RQP/e0YD/4RKAv92PwD/cUQL/6qLZP//+uz///////j////6///////+////
+ /P////z////8/////P////j///3n/5J4VP9uQgz/eUMC/4JHAf98RQD/c0QG/3JGB/96RgD/gEYA/4BG
+ AP9+RgD/fEUA/3xFAP96RQL/ekUC/3lFA/95RQP/eUUD/3lFA/95RQP/eUUD/3lFA/98RQD/gUUA/4NJ
+ AP95RAH/akAL/5Z7Wf////L////+//r9///9/////////////P////v////+///////9////////////
+ +f////n////8///////9////+/7///v+///7/v///f///////v////7////+///////9/v//+/7///v+
+ //////z////1///24f+mh2b/aEAQ/3FEB/9+SwX/gEcA/4JGAP+FRwD/hkgB/4BIAf92QgD/eUcF/3RB
+ A/9rQw//t6KD////8v///vP////7//r+///4/v//9vz///j+///7/v///f////////////7////+////
+ /v//////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////f////r+///x9fr/+f3///v+
+ /////f3////3///x1v+Xd07/cEMK/3RAAP98RwT/ekUC/3tHBf94QwD/f0cA/35EAP96QwD/fkkG/31J
+ B/9uQQj/w6R9////7f///vX///////3////9/////f////v+///7/v//+/7//////v////z/////////
+ /////////////////////////////////////////////////////////////////////////f////z+
+ /v////X/up99/2xCDf96QwD/h0kC/31CAP+ARwL/eUUC/3dGAv95RQL/eUYA/3xGAP9+RgD/gEUA/4BG
+ AP+ARQD/fkYA/35GAP9+RgD/fEUA/3pFAv96RQL/ekUC/3pDAP9+RgD/gUcA/3VAAP9vRRD/0baU////
+ 9f/7////+P////r///////7////8/////v////7//f/+////+f////D/v6uI/2c+Df95Qwb/gUYB/4BF
+ AP91RAD/d0gE/3xGAP+ARgD/fkYA/35GAP98RQD/fEUA/3pFAv96RQL/ekUC/3pFAv96RQL/ekUC/3pF
+ Av96RQL/fEUA/4BGAP+ERgD/gkgA/3dEBf9pQxP/wKqO////9f//////+fz///3///////7////7////
+ +/////7///////v+/////v/////7////+f////z////+//j////2////9v////j////9/v////7////+
+ /////v////7///3////6/////f/+////9f//+d//s49p/3lKF/99Sgz/cT0A/3dHBf92RAL/fEUC/4FG
+ Af+DRQD/fkUA/3xIAf93RwX/c0YN/6OAVf//897////4////+v/9////9vv+//j+///4/v//+P7///v+
+ ///9/////////////v/////////////+/////v//////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///9////+v3///v+///8/v///f////3//////Pv////1//Hcwf+DXjL/b0EH/3dEBf97RgP/e0cF/3tE
+ AP+ESgD/gUcA/31GAf94QwD/f0gD/3M/AP9zSRT/yq2I///96P////j////+//3////9/////f////3/
+ ///9/////f////3/////////////////////////////////////////////////////////////////
+ ///////////////////9////9/z/////+f/kz7P/Z0ER/4FMDf98QQD/g0YA/4BFAP98RgD/ekYA/3pG
+ AP96RgD/fEYA/3xGAP9+RQD/fkUA/3xFAP98RQD/fkYA/35GAP9+RgD/fEUA/3xFAP9+RgD/gEYA/4RK
+ AP96QAD/fEkK/3BJHP/44sb////5//n+///4////+v///////v////z////+///////6////+//8////
+ 9P/q2r3/Z0IW/3VDCf9+QgD/hUoC/3tGAP95RgD/fEYA/35GAP9+RgD/fEUA/3xFAP98RQD/ekUC/3pF
+ Av96RQL/fEUA/3xFAP98RQD/fkUA/35GAP9+RgD/gEcA/4dJAP98RQD/ckML/2xMI//k0rv////4////
+ ///7/v///f///////v////v////7/////P//////+/7///3+/////v7///78/////P/9//7/+P////T/
+ ///0////9v////v+/////f////3////9/////v/////+//3//P////f////o/7mac/90RRH/dkAA/4JH
+ Af+BSQL/dUMB/3JDBf91RAb/e0UE/35DAP99QwD/fEgF/25CBf+FYTP//+nJ////9P////v//P37//3/
+ ///6////+P3///r////6/////f/////////////////+//////////////7////+////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////9/////////////P////7//f////3+///////////1/+bO
+ sP9sSBr/dUcN/3lFA/93QgD/fUUA/4JGAP+GSgD/fUYB/3pGBP94QwD/eUUD/3ZDBP91SRP/tpdw////
+ 6/////f///////3////9/f3////+//v7+//4/P//+v7///3/////////////////////////////////
+ //////////////////////////////////////////////3////3/f/////+////7P+La0L/azsB/4ZL
+ Bf+GSAD/hUcA/35FAP+ASQD/fkkA/3lDAP98RAD/fkcC/35HBP94QgH/eEQC/3pFAv98RQD/fUUA/31F
+ AP+ARgD/gEYA/4FHAP9+QgD/jlIG/31FAP9vQQf/nn1W////6v////7/+P7///r////9//7////8///+
+ /v///v////7///j////4///////4///64v+UdU7/cEEN/3k/AP+KTQP/fUQA/31HAP94QgD/f0gD/35H
+ Av95QgD/ekMA/3tEAP97RAD/fEUA/3tEAP9/RwD/g0sE/4JLAv9+RAD/fkQA/4FHAP9/RgD/f0QA/31J
+ B/9nPw7/lntZ////7f//+/b///////v+///9///////+/////P////z////+///////6/v//+/7////+
+ /////v/////+//3//v/6//7/+P////b////2////+v3///38////+v////3////+/f////n////0////
+ 6f+niGH/d00Y/3NBAP9+RwD/gkUA/4RJAf94QgH/eEcJ/29CBf91Rwf/fkoE/3VAAP95Rwv/d08f//LZ
+ t/////D////4/////P////7//f////3////7////+/////3////9//////////////////////7///3/
+ ///9/v///f//////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////v////z////7////
+ /P/9////+v7///r+//////7///7u/9C3l/9mQBD/dUYJ/31IBf+GTAT/fEIA/3xCAP95RAH/eUUD/3hE
+ Av98SAb/fUYB/3E+AP+KXij/t5hx////7f////j//Pn1///+/f////z///////f7///6/v///f//////
+ /////////////////////////////////////////////////////////////////////////f////b8
+ ///8/v7////0/9nAoP92TRz/cz4A/31CAP+ESAD/gUgA/3tEAP96QwD/gEkA/4JKA/98RQD/eEID/3pE
+ B/93RAb/dUMB/3tEAP+BSQL/gkgA/31DAP99QwD/gkgA/4hMAP92PAD/eEUG/3dPHv/oz6/////0////
+ ///0+v//+//+/////P////z////+///+///9/v//9v////b////6/vn////y/+XJqv9zSxv/dUIE/3k/
+ AP+HTgD/g0sA/31GAf96RgT/eUQB/3pFAv+BSgX/gEkE/3xFAP98RAD/fUUA/3tDAP98QgD/fUMA/35E
+ AP+CSAD/g0kB/31FAP99SAX/ZjkA/21NJP/k0Lf////1///++v/6+vr//f/////+///////////+////
+ /v////7///////v+///7/v////3////9///////////+//3//P/7//7/+v////r////4+///+/z///78
+ /////v/////5////8v//+OH/sZh2/3BIFP9yPwH/fEgB/39IAP+BRQD/g0YA/3tAAP95QwL/dEYG/3BE
+ BP9wQgL/cEII/3FHGP/cvpv////w////9/////v////8/////P////7////+/////v//////////////
+ ///////////////////9/////f////v+///9////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7////7////+f////z////+//3////7/v//+P7///v+/////Pj////y/66Sb/9vRRD/eUUD/3tD
+ AP99RgH/fUgF/3lFA/93RAX/dUID/3lFA/99RgH/d0AA/3NAAf92ShT/x6iB///33v////X///z3///+
+ /f/9/f3//f////b4+f//////////////////////////////////////////////////////////////
+ ///////////////////9////+P7///b6+/////j///3o/6F9V/95Shb/eEIB/4BIAf98RAD/gEgB/4JL
+ Av9/SAD/fkQA/3pDAP95Qwb/d0UJ/3JDBv93Rwf/fEUA/3xCAP9/RQD/hkwE/4JKA/96QgD/fUUA/35K
+ CP9uRA//sZJr///85////vX//f////r9//////7////7/////P////7///7///v+///2/v//9v////v/
+ //////f///ji/6B/WP9qPgn/fEgG/4BJAP97RAD/ekYD/3ZDBP92QgD/eEMA/3pDAP94QQD/e0MA/4BG
+ AP+HTQX/gUcA/39FAP+BRwD/gEgB/35GAP98RAD/eEMA/3RGDP9sSBr/o4tt///25v///vf////+////
+ /v/5+fn///7///3//////////////////v//////+/7///r+///6/f//+v7///3///////7////8////
+ /P////7//f////r+///6/v///f//////+v//++v///vi/7icef9lPhH/bjwA/39IBf98SAL/eEIA/39F
+ AP+DSAD/hEcA/4RJAf99SQP/dUUF/25GDP9qRxv/tZt9////8f///fX////+/////P////z////8////
+ /P////z////8/////v////7////+/////v////////////3////9/////f////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////v////n////5/////P///////f////v////6/v//+v7///v+
+ /////PX////o/558Uf9zRQv/eUUD/3ZDBP91RAb/eEUG/3dFA/95RAX/eEQC/3lEAf9+RwL/fUYB/3VC
+ A/9ySBP/uJhv///54P////X////7/////v////z////8/////v//////////////////////////////
+ //////////////////////////////////////////////3////6////9/z7///++v////X/+eDG/4Je
+ Nv9xQg7/dEMF/3xJCv90QAD/czwA/31GAP+ESgL/f0YB/3hCBf92RAr/ckII/3VEBv9+RwL/g0kB/35E
+ AP91PgD/dUEA/3tICf9zQgT/bUMO/4lpQP//7dH////1//369v/9/f3//f///////v////z////8////
+ /v///v//+/7///j+///4/v//+/////v38v////L//ujM/4dlOv9vQw3/cUEB/3xIBf91QgP/c0MD/3pF
+ Bv9+SQb/f0gD/4BIAf+DSQH/g0kB/3k/AP9/SAD/gUkC/3tEAP94QwD/eEQC/3hFBv90Rgz/ZDwL/39j
+ QP/669j////4//v49P////7///76/////v///////f////v+///9///////////////9////+/7///j+
+ ///4/v///f///////v////z////8/////P///v3/+/39/////v////n////y///94v+qjWj/bkUY/3BB
+ Cf98RgX/gUgD/3hBAP97RAH/g0oF/4JIAP+BRQD/fEIA/3xDAP9uPwL/Z0MV/6OMbP///+///vvz////
+ ///7///////+/////P////z////8/////P////z////8/////P////7////+/////////////f////3/
+ /////v//////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////+////+/////v///////3/
+ ///9/////f////v////7/v//+v7//////v////L///TW/5t4TP9xRxL/bkIM/3FDCf93RAX/eUQB/35H
+ Av99RgH/eEMA/3lFA/97RwX/dkIA/3VBAP95SxH/poZd///33P////T////7////+f////j////+////
+ //////////////////////////////////////////////////////////////////////////////r7
+ +f/9//7//f/////++v////T/9N3D/3JRKv9qQhL/a0EM/3JGC/96SAb/fUcA/4BHAP+BRgD/eUQF/3JA
+ BP9wQQT/dkME/39HAP+CSAD/gEgB/3xIBv9zRQv/a0EM/2lDE/91Vi//++bL////9P/9+fj//f//////
+ /v///Pv////+/////v////7///////3////9/////f7///3+///6+///////////+f////L/8dzA/3pb
+ NP9mPg7/bT8J/3hJDP91RQX/d0ID/3dCAP93QAD/fEQA/4BGAP97QQD/gEgB/4BKA/94QwD/cD0A/3NE
+ B/90Rw7/b0MN/2c/Dv9/Yj3//+3U////9//7+fj////////+/f////v////6///////7/v//+v7///v+
+ ///////////+///////9////+v////r////9/////////////v////z///77///++////vn///zx////
+ 8f//9Nf/m35X/2pCEf9yQgj/fEcI/3tGA/94QQD/ekAA/4FHBv98RQD/eUMA/39IAP9+RwD/fEYH/29C
+ D/+dgV////Th////+P/6/////f////z+///////////+/////v////z////8/////P////7////+////
+ ///9/////f////3/////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////7////8/////P/9////+/////3////9/////f////3////1+Pz////////+9/////H//+rM/45u
+ Rf9oRBb/az8J/3lFA/98RAD/fkYA/31GAf94RAL/dkME/3hEAv93QgD/f0cA/4BLCP9rPwn/k3NK///s
+ 0///+ev////4///9+P////7/////////////////////////////////////////////////////////
+ //////////////////////7////7//7/+//5/f//+Pz/////+/////X/+uPJ/4psSf9iQBX/aEAP/25B
+ BP92QgD/e0IA/35DAP95QwL/eEUH/3dFCf94RAL/fEIA/31DAP95QgD/cEEE/2hAD/9jQRb/iGxJ///z
+ 2P///O/////8//j8///6/v/////7////+////v////7///3////9/////f///////////v////7////7
+ /////v//+vr6////9////+7/9+PK/35iQP9sRxv/b0IJ/3BAAP95RAX/fkkG/3pDAP9+RgD/hUsD/4JI
+ AP99RQD/eEMA/3hFBv96TBL/cEYR/183Bv9tSRv/j3BJ///s0P////D////+//j7///7/v/////////5
+ 8v////n///////r+///4/v//+v7///////////7////+/////v/+//3/////////////////////////
+ /v////v///73////9f///+3/9N7C/4tsRf9jOwr/cEMG/3pFAv94QQD/fUkD/3hDAP9/RQT/f0UD/3hB
+ AP94RAD/fUkC/3lHBf9wQgz/o39X///z3f////j/+//+//T8/P/9////+fn5///////9/////f//////
+ /v////7////+/////v/9/////f////3////9/////f////////////7////+/////v//////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////9/////f////3////9////+/////v////9////////////
+ /v////z//v35///79P////L/++jN/4dnPv90SBL/f0cA/4FFAP99QwD/e0QA/3pGBP94RQb/ekYE/3xH
+ BP9+RwL/dD0A/3ZCAP92SRD/i2k+//Hcwf//+O/////+////////////////////////////////////
+ /////////////////////////////////////////////////P///vX////7/+/3/v/z/P//+v3////7
+ +v////T//+vS/66Vdf9/XzT/ZTwF/3dFA/+ITwT/f0UA/3dAAP+BTA3/fksN/3ZBAP+ARgD/iU8E/3hE
+ Av9pPQf/g2E2/62UdP//8tn///zu/////v/y+P//9P3///X7//////v////2///+/////v//+/////v/
+ ///9//7////+/////v///v////7///r5/f/6/v//+v//////+////fD///De/6mKaf9/VSD/dUUF/3dC
+ A/+ASwj/fkcC/3xEAP9/RQD/ekIA/35HAv94RQb/cEEE/2c9CP9lPw//eFYr/7+gef//9tj////v///9
+ 9P/6/v//9v3///r+///////////5////+f//////+P7///b9///4/v///f///////v////z////7///+
+ +v////z////+//v////4////+f/+//v/+v////b///zr/+LHrP+NaEL/b0ER/3JABP9+SQb/fkoA/31G
+ AP94QQD/eEAA/39IBf99RgH/gUkC/35HAv9zPgD/cEQO/4hqQf//7NH///7x/////P/9/f3/+/39////
+ /P////z//f////v////7/////f////3////9/////f////3////9////+/////3////////////+////
+ /P////v////8/////v//////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////f////v////7/////f////3/
+ ///7////+/////3///////////76/////P/////////+///9+P////T//+/T/4ZjN/92QwT/f0cA/3pF
+ Av96RgT/e0cF/3lFA/94QwD/fEUA/3pDAP+BSgX/fkYA/3hEAv9pPwr/clMs/8u6pf//+vD////5////
+ /P////z////+///////9/////f7///3+///9/////f///////////////f////3////9////////////
+ +f///vn/+P7///L7///0+///+/7/////+/////T////t/+vXuP+xk2r/g1wo/3JECv9zQwn/cUMN/2s+
+ C/9kPAj/cEYR/3VHDf9uQQj/gFgn/7eXbv/x2bv////r////9P////v/+/7///b9///z/P//+v7/////
+ +v////n///7////+///9////+/////3//v////z////+///+/v///v////7///X7///z+f7/+///////
+ /P////j////s//LTrP+0j13/fFQj/21FEP9sQAr/bkEI/3NFC/9wQwr/aT0H/3JKFv9tRhn/d1Qs/7SW
+ c//33b////7k////8P////f////+//r+///4/v///P7////++v////j///73///////6/v//9v3///j+
+ ///9///////+/////P////z///77///+/v///////f////v////8//v////1////7v/MspT/eFQs/2o5
+ B/96RAj/f0UD/4BGAP98RgD/f0kA/4BIAf9/RgH/fkgB/3RAAP96RQL/eEUH/29DDv+LaED/9uXK////
+ 9P////7/+fv8//79//////7///v2////+//9////+/////v////9/////f////3////9/////f////3/
+ ///9/////f////////////7////8////+/////z////+////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////f////3///////////////3////9/////////////////v3////+///////+/v7////+////
+ +///+vH//+/Y/4ZjN/91SA//bj8C/3dEBf96RQL/gUkC/39FAP+BRwD/fkYA/31GAf98RwT/c0AB/3NF
+ C/9lPQn/cU0f/7KWc///+uX////1////9v////z//P7///j8///4/f//8vf///r9///6/f//+/3+//z+
+ /v/5/f7/+f7///j+///5/P/////+/////P///v//+/7///v+///7/////f///////P////j////1////
+ 8P//79j/4s2y/72lif+ghWr/jXRa/4p1Wv+YhGv/uaSJ/97Ksf/+7dj////x////9/////n////8////
+ ///9////+/7///v+///9///////8/////P////////7////////9/////////////v//////////////
+ /////v///f////3////9///////+/////P////n////y////6v/46tT/1MWr/7KfhP+bhmr/jnla/4py
+ VP+ji2//u6SK/+LMs///8Nv////w////9P////X////5///////9/////f///////v////v////5////
+ +P////n////+//v+///6/v//+f3///j6+//////////8///+/f///P///vz////+/////f3///z3////
+ 9P//9Nv/rZJt/29HF/9zQwn/eEMA/4JIAP9/RQD/fkQA/4NLAP9/SQD/gUcA/39HAP99RgD/eEQA/3dI
+ Cv9pQQz/hmdA//jky/////f//f////j9///2/f//+/7///////////v////7/////v/9/////f//////
+ //////////////////////////////////////////////////////7////+/////v//////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////7+
+ /v////////////7+/v///////////////////fP//+zO/5BuQ/9qQhH/ckQK/3pGBP98RAD/gUcA/39F
+ AP99QwD/eUIA/3pGBP91RAb/eUoN/3VGCf9rPAD/c0kU/4xtRv/u173////w///+9P////7/+/7///X7
+ ///4/v//9vn+//z9//////////////3////6////+P7///f7///////////8/////v///////f////v/
+ ///6////+v////n9/v/9///////8////+/////n///70////8v////T////1////9f////b////5////
+ +/////z////+//39/f/9/////f////3////9//////////////////7////+////////////////////
+ ///////////////////////////////////////////////////////////////////+//3////8////
+ /P////j///zz///98/////P////z////9f////X////3////+P////n///34///9+v////7///7///3/
+ //////7////8////+/////v////8/////P/9/f3/+Pr7//r9///7/v///f////7+/v////7///////39
+ /////v////38////+P////H/8dm9/4RkO/9jOwf/ckMG/31JA/+ARwD/gEYA/4FHAP9/RgD/fEUA/3tE
+ AP+ARwD/fkYA/31JAv9zRAb/Z0AM/5J1Tv/76M3////0/////v/6/v//+P3///j9///7/v////7/////
+ /P////z////+////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////v7+/////////////v7+//39/f//////////////+////+//++XJ/51+
+ V/9qQhH/bj0A/4RMBf9/RQD/g0kA/4NLBP97RgP/d0QF/3NCBP90QQL/ekgG/3xGBf9wPQD/aj8G/39b
+ K//Qso/////p///+9P/++vn//f////P49/////7////+///+/f///fz///////j3+f/z9/j/+///////
+ +/////v////8/////v///v///f7///39///9/P///fz///39///+/f///Pz8//z9+//+//v////7////
+ +f////j////4////9////vf///34////+/////7///////3////9/////f////3/////////////////
+ /v////7/////////////////////////////////////////////////////////////////////////
+ //////////7///38/////f////3////+//////7////7////+f////j///73///99v///fX////6////
+ /P/7//7/+v////3//v////v////5/////P///////f////r////6/v//+v7///v+///8/f////7////+
+ ///////////////+/v/9+/v////////9+P////T///bd/8mriP95VSf/bT8J/4BPEf97RgP/fkcC/3lD
+ AP93QAD/f0gD/35JBv96RQL/gEkE/4JIAP95QgD/ckUI/2M9Df+WfFj///jh////9P///fb////8////
+ /v///////////////////////f////3/////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////+/v7//////////////////v7+//z8
+ /P/9/f3////+///99v////T//+7T/5t8Vf9wRhH/dkME/31GAf95QQD/e0QA/3hDAP94RAL/fEgG/3dC
+ AP95QgD/hEwF/4FJAv95RQL/c0YJ/21EE/+hgFn/+OHH////8f///vT////5///++f////v////8////
+ +/////7////+///////5/Pr////8//3/+/////7//f/////+///9/v////z///38///7+v//+/r///v7
+ ///9/v///f////3//v/6//v//P74///+9v////j////5////+/////z///79//39/f/9/f3//f////3/
+ ///9/////f/////////////////+/////v//////////////////////////////////////////////
+ /////////////////////////////////////v///fv///78////+/////r////8/f////7////8///9
+ +v////z////8/////v/7////+v////b////z////9v7+/////P////v////+//3////6/v//+P7///j+
+ ///4/v//+/7///r7///6+fv//fv7///9/f///////////////P////X////u//Ldvv+VeVD/cEgX/29B
+ B/98SAb/dD0A/3tEAP96QwD/e0YD/3xGBf99Rwj/ekQF/3U/AP95QwL/ekQD/3RECv9tRhn/potp///u
+ 2///+vD////8//78+/////z////7////+f////n////8//3////4/v//+P7///3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///9/f3//v7+/////////////////////////////f////369v////H///7j/6WGX/9rQw//eUoN/3hE
+ Av97RgP/fEcE/3tEAP+ASQT/gUkC/3tBAP99QwD/f0QA/3xFAv94QwT/d0YI/21BBv+AWyf/1riP////
+ 5P////H////4//338v////z////8//f49P/8+/f////+/////////v//+/////3////7/////f7///v+
+ ///9/v///f7///3+///9/v////7////////////////+/////P////z///75////+v////v////8////
+ /v////////////3////9/////f////3////9//////////////////7////+////////////////////
+ ///////////////////////////////////////////////////////////////////9//////7////+
+ //////////7+/////v////7////+//7+/v/9////+/////r////4/v//9v3///T9///0/f//+v7///v/
+ ///9/////f////3////9/////f////3////8/v///f////3///////////39//76+f///fr////0///y
+ 1v/dwZj/dVUk/2dCCv9yRQj/d0UD/35KBP98RQD/fEUC/3dBAP9/SQr/ekQF/3M9AP9+RQf/g0kI/35H
+ Cv9wQQv/aEEV/66Sc///9+T///v3///+///7/v//+/z//////v////n////3////9/////v/+/////T+
+ ///0/v//+///////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////+/v7//v7+//////////////////3////z9vr//f//////
+ +///++3///7l/8Ckgf9wTB7/b0MN/3VEBv9+SQb/f0cA/3xCAP+CSAD/gkgA/4FFAP+FSwP/fUYD/3U/
+ AP98RwT/gEwJ/3REBP9uQwr/oXxQ//HUtf////D////1////+//+/fn////8/////P///fr////+///+
+ ///9/v///f7///3////9/////f////3//v/9//7////+/////v////7/////////////////////////
+ /v////z////8/////P///v3//v7+//7+/v/8/v///P7///3////9/////f////3/////////////////
+ /v////7/////////////////////////////////////////////////////////////////////////
+ //////////////n7+//7/vz//f///////v/+//3//v/9///+/f////7//Pz8//3////9/v//+/7///r9
+ ///4/f//+Pz///T6///4/v//+v////v////9/////////////////////f////v+///7/v//+fv8//r4
+ 9/////n////1///35v/s1rr/lXRH/2Q/B/9uRAn/dkoL/28/AP99SgT/eEEA/35HAv9+RwL/ekMA/35I
+ B/91PwD/dD4A/4JJC/98QwX/azoC/25HIP/StZr///7t///78////v//9Pf8//P2/v/7/v//////////
+ +/////j////4////+//7////9v////b////7////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////9/f3//f39//7+
+ /v/+/v7//f39//3////9////9vj5/////v////j////t/9bApP9xUSj/a0EM/3NAAf9/RwD/f0UA/4NH
+ AP+FSwD/fUMA/39IA/94RAH/eUcF/39JCP97QQD/e0EA/3pEA/90RQj/eVIe/7CWbv/y4cf////3///9
+ /P///v/////////8+P////z///7////+/////v/////+/////P////n////4////+P////n////5////
+ /P////7///7////+///9+////Pv////9/f///v3////+/////////////f////3////9/////f////3/
+ ///9/////f/////////////////+/////v//////////////////////////////////////////////
+ /////////////////////////////////////////f/+//v//P/7//7//f/8/////P////z////7///+
+ /f////7////////+/v/9+vz/+/r+//78/////f///f3///3+///9/////////////////////f////r+
+ ///4/v//+P3///r9///////////4////7v/74cP/tpNr/3BIFP9zRgn/bkEA/3tLC/9yQgL/dUUD/3NB
+ AP9/SwX/ekQA/3xEAP99QgD/hEkD/4BHAv9+SAf/eUMG/3JABv+DWi3/3sau///+8v////n////8//36
+ /P/8/f//+/7///r9///9/////////////v////z////+//v////6////+v////3/////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////z8
+ /P////////////////////////////////////////////v9/v/7/v//+/7///r8/f////z////y//Lc
+ wP+EYjf/c0cR/3tHBf98RAD/fkQA/4JKA/94QQD/e0YD/3lFAv95RQL/fEQD/3k/AP+CRwL/gkkE/3M+
+ AP91Rgj/aUIO/31eN//CqpL///Dg///+9v///fj////7///++v////////7///////////7////7////
+ +f////j////4////+P////j///75///+/f///////f////3+///8/f////7///////////////////z+
+ ///8/v///f////3////9/////f////3////9//////////////////7////+////////////////////
+ ///////////////////////////////////////////////////////////////////9////+v/+//n+
+ /f/8//3//f/+/////v////7////+///+/f////7////+/////v////7///7////+/////P3////+////
+ /v////7////+//3////9////+/7///v+///9/v////79////9v/66dT/waWD/4RdMP9wQQn/e0gK/3dD
+ Af98SAX/cz8A/3tJB/95RQP/ekUC/31HAP9/RQD/gkgA/4BGAP+BRwD/eEMA/3NEB/9rQQz/l3BD//nd
+ vv////X///79///+/f///v3///7+//39/f/9////+vz9//v+///7/v//+/7///v////9/////f//////
+ //////7/////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////v////z////+//v+
+ ///6/v//+P7///v+//////z////0///pzf+mhl3/bUMO/3JDBv96Rwj/d0MB/3dEBf97RwX/fUMB/4FI
+ A/99RQD/eUMA/31JA/96RQL/d0EC/3xGCf94Rgz/bT8J/2hBDf+HZzz/yLOT///03v////j//vz7//j8
+ /f/6////+/////f5+f/////////+///8+/////z////8///9+v///vv////8/////P/8/fn/+/78//3/
+ /v/7/f3//f////3////9////+vz9//z+///9/////f////3////9////////////////////////////
+ /v////7/////////////////////////////////////////////////////////////////////////
+ //////////7////+///9/f//+vr///v8///9/v///f7///3////+/f////////3+/P/+//v////7////
+ +//+//b////4////+f////v///76//7//f/9/////P7///////////z////5////9P//8tv/zLCR/4Vi
+ Ov9pQA//ckII/3pFBv95QwL/dUIE/3dEBv96RQb/eEIB/3pDAP+DSQH/iEoA/4REAP+HSAD/f0MA/39I
+ A/9xRAf/a0cX/6qQbP//7NH////0/////v/7/v///f///////v////z////8/////v//////+/7///r+
+ ///6/f//+v7///3+/////v/////+/////P////7/////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+////+/////z///////v+///4/v//+v7///3///////v////y///74P/JrIf/d1Ml/2k+
+ C/9yRQz/b0EH/3dEBf+CRwL/gUYA/31GAP96RAD/d0QA/3tHBP97RQb/eEAA/3pAAP97RAH/e0cF/3FF
+ CP9lQRH/dlw3/76pk///++3////5//v99/////z////8/////v///v////7///34+v///P7///7////+
+ //////7////8////+/////v//f76//v9/f/8/v///P7///3////9/////f////3////6/P3//f////3/
+ ///////////////////////////+/////v//////////////////////////////////////////////
+ /////////////////////////////////////v///fv////9/////f///f3///39///9/f///f3///v+
+ ///5/f7/+/////3//v/9//z////7////+f////f/+/zz//3++v////7////+////+////vf////1////
+ 7///89j/yq6L/49sQP9pQQ3/cEEJ/3dFCf98Rwj/fkgH/3lDAv96RAf/dkAD/3hCA/+BRwX/hEgC/39C
+ AP9/QQD/hEYA/4hOA/98SAX/aTwD/3VUJv/JspL////s////9//6+/f/+v////j////7///////+////
+ /P////v////8/////v/9////+/7///v+///7/v////7////+//////7////8////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////7////8/////P////7///////3////9/////f//////
+ //////z////1////8f/t2Lz/h2pF/2I+EP9xSRX/cEED/3xDAP+DRwD/gkcB/35EAv93QQD/eUMC/35H
+ Av+BSgH/hk4B/4FHAP98QQD/e0MC/3VDCf9qPgn/bUgW/3ZaMf+6qIv/7uDN////7/////P////5///+
+ /f/6+f3/+/7///r8///6/P//+fv///r7///////////8////+/////n////+///////7/f7//P7///3/
+ ///9/////f////3/////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////7////+
+ /////v//+/z///r6///6/f//+v7///r+///6/v//+P3///f8///7////+/////3////7////+P3///X5
+ +v/++/b////1////7P//58X/w6B1/4NbJv9zQwn/eUYH/3tGA/95RAH/eEIB/3dBAP92QQL/ekUG/3hB
+ BP+ARwn/gEUA/31BAP+GRwD/hkkA/4NIAP9/Sgf/az8E/2A8DP+QdlL/7+DG////9P/8+vL/+//+//r/
+ ///6////+v////v////9//7////+/////v////7//////////////v////7////+/////v////7////+
+ /////v//////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////7////+////
+ /P////z////+/////v/9////+/////f6/v/9//////z3////9f//9d7/t5x6/2xKH/9rQQz/dkQC/3xG
+ AP98RQL/fUUE/39HBv98RQL/fEQA/39GAP96QAD/g0kA/4NIAv9+QwD/fUMC/3xGBf95RQL/b0ME/2U9
+ DP95WTD/sJNu/+jQsv//9uH////0////+///////9/z///b8///4/v//+v7///z9///6+fv//vz7////
+ /v///////v7+//z+///8/v//+/3+//r8/f/9/////f//////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+/////P////v///79/////v///////f////v+///7/v//9/r///f6///6/f///f7////+
+ ///+/Pz//vz7/////v////z////5///25v/gy7D/podg/3pSIf9vQQf/eUUD/3lCAP+CSgP/fUUA/3tD
+ AP+ESwb/gEkG/3dCAP99RgP/fkQC/4FGAf99QQD/gEUA/4dLBf95QgD/azkA/2tADf94WTL/uaSI///3
+ 5f////X/+Pn1//v////4////+P3+//3//v/9//z//f/+//v//v/7/////f////3/////////////////
+ /v////7////+///+/////v////7////+////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////3////9///////+/////P////v////7/////v/9////+v3///f9///7/v///fv6///9
+ 8P///+7/586u/45tRv9qQhL/dEYQ/3JDBv9xPQD/ekIA/4VLA/+FSgL/f0QA/4BGBP9/SAX/e0YD/3xF
+ AP+BSgH/gkgA/4NFAP+ERgD/h0kC/4FFA/95Qwb/fE4Y/5Z0Rv/KsIz/8+XJ///96v////f//f/8//v/
+ ///6////+/7///v9///7/f///f3///v6/P/8/Pz//v7+//////////////////7+/v//////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////7////4////+P////n////7/////P/+//3/+fv7//r6
+ +v/////////////+/f///fr////7////+f///fb///rt//fkz/+8por/hGdC/3BMHv9yRhD/d0YI/3hE
+ Av93QgD/fUkH/3I+AP94QwT/fkoI/3lCAP97QAD/hUgA/4ZIAP+GRwD/h0oA/4JIAP99RgH/d0QG/2g8
+ B/9uSyD/hm1N/9nKt/////X////8//f8+//7////+Pz9//z+/v////z////7////+/////7/+/////r/
+ ///6////+/7///3///////7////8////+/////z////+/////////v///f7////+////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////9////+/7///v+///////////8////+f////v////8//3/
+ ///4+///9v3///j+///6/f/////8////9f//++j///Xa/7ibfP9uSyP/YDkF/39SFf96RwH/dj8A/4FG
+ AP97QAD/ekIB/3hDBP93QwH/d0MA/3xHAP+ARgD/hkYA/41LAP+FQQD/i0gA/4BCAP94QQD/c0QG/2Y+
+ Cf90Vif/nodh/9rIqf/z58/////v////+P////r////+///9///8+fv//////////////////v7+////
+ //////////////z8/P//////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////v////v////7////
+ +/////v///76////+/////z////7////+f////f////z////8P///+7//+7W/9G2nP+fgGH/bkwh/21F
+ FP9vQw3/dEUI/3ZCAP94QQD/e0QA/3xHBP94QwT/eUYH/3pHCf95RAX/e0QB/4NJAf+ESAD/fT8A/4FF
+ AP99QwD/eEMA/3NEB/9oQQ3/cVMq/7Segv//9uT////5//n39v/7/v//+v////r9///8/v//+vj3////
+ /P////v////7/////v/9////+v7///r+///7/v///f///////v////z////7////+/////z///////3/
+ ///7//////7/////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////3////7/v//+/7/////
+ //////7////8/////P////7///////v+///6/v//+v7///n8///8/Pz////8////+f////P////w//Da
+ vv+afVj/Yj4Q/3BDCv98SQr/eUIA/4BKA/96QwD/fkoI/31ICf92QwT/eEQC/3lEAf98RAD/fEQA/39L
+ Bf92QgD/ekYA/31JA/96QwD/e0YD/3xHCP9uPAD/ajsD/3tSIf+dek//x6uI//Pdwf///+j////w////
+ 9f/++vX////+/////v///fz//vz7/////v////7///79/////v////7///////////////////////3/
+ ///9////////////////////////////////////////////////////////////////////////////
+ //////////////v9/v/7/f7//P7////+///////////8////+P///vT////x///84//43sD/xaiD/5Fu
+ Qv9zSxr/aT8K/20/Bf97RwX/e0UA/3xFAP9+SAH/gUgD/4BJBP9+RwL/dD8A/3dBAP99SQf/eEIB/3U/
+ AP95RAH/dj8A/3dAAP+JUwz/fUcA/3xIBf9rPwT/a0gW/6GGYf/v3MH////x////+P///fj////+///+
+ /v/8+vr///7+///+/////v////79/////P////z///7////+///7/v//+/7///v+///9////////////
+ /P////v////7/////P////7//f////v/////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////f////v+///7/v///f////////////7////+/////v///////f////n8///7/v//+/7///v9
+ /v/9/f3////+////+/////n////y///86f/gxqj/i2hA/2pCDv91SAv/c0AB/3pGBP94RAL/dkEC/3dC
+ A/97Rgf/eUUD/3lEAf98SAX/c0MB/3hIBv94RAH/ekMA/4NIAv+ARQD/fEEA/4VJA/+CRwL/d0EC/3JA
+ Bv9wRA//b0kZ/31dMv+oi2T/z7iY/+vaxf/98d/////y////8v////P////0////9/////j////5////
+ +/////z////8/////v/////////////////////////+//////////7//////////v////7////+////
+ /v////7////8/////P////z////8/////P////v////7////+/////j////3////8v//7dz/5dC6/9K6
+ nP+egl//hGI3/2xGFv9tRA3/c0cK/3VFBf91RAD/fkgB/4BGAP+DRQD/hEgA/4NJAP9+RAD/e0MA/3xF
+ AP98RwT/e0YD/3hDAP97RgP/fEcE/3pFAv9+SQb/fkkG/3A9AP9sQQj/aEMR/5NzSP/gx6X////l////
+ 8v////b////8///+/f///fz///7//////v///v////7////8/v///v/////+/////v///v////7///3+
+ ///7/v///f7///3////////////+/////P////z////8/////v/9//7//f/+////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////f////3/////////////////////////////////
+ /////////f////3////9/////////////////////f////j+///3/f//////////9///79j/xquJ/4Vi
+ Nv9pPwr/cEII/3RBAv93QwH/ekUC/31GAf98RQD/e0QA/3tEAP98RQD/f0YB/39GAf99RQD/fUQA/35F
+ AP9+RQD/e0QA/3xFAv96RAP/eUQF/3dEBv9zRAf/cUMJ/3FCCv9uQg3/fVQj/4VhMf+efE7/wKB1/+HE
+ nf/6373//+7P///y2P///On////w////9/////j////7///++v///fz////+/////v////z////+////
+ /P////7////8/////P////z////7////+P////b////3////9/////X///ns//7y4P//69L/9Nq8/9i8
+ mv+4mXL/nXpO/4hgL/95TRf/ckQK/3ZFB/93RAX/eEQC/3dDAP94RAH/ekYD/3pGA/97RwH/gEcA/4RK
+ AP+CRQD/fkEA/4FGAP+FSQP/f0YB/3lCAP97RwT/c0EA/3dFA/95RwX/dUEA/3hDAP9/SAX/bj8H/4Fl
+ Qv+8rJX//e/c////8v////f////5/////P///fz//////////////v/////////+/////v////7////+
+ //////////////////////////7///3//////v/////////////////////+/////v////7/////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////7/v//9fz///b9
+ ///6/v///vz7///+9P////D/+ePH/7+jgP97WCz/b0cT/3BDCv93Rgj/d0MB/3lEAf9/SAP/fUQA/4BF
+ AP9+QwD/fEMA/35FAP+BSAP/fkcC/3xFAP97RAD/fEUA/3xFAP98RQL/fEUC/3xFAv98RQL/fkQC/3xF
+ Av90QAD/c0IE/3JDBv9sQAX/aUAJ/3FJGP+AXjD/jG5F/56BXP+mjWv/t5+B/8m0mf/bx67/69nC//no
+ 0///8t3///He///x3v//8d7///He///x3v//8d7///Hc///x3P/z4Mv/6dfA/9rHrP/KtZn/t6KD/6SN
+ bf+Od1f/hWpF/3NQJP91TRn/cEYR/3BDCv9yQwb/d0QF/3tGA/99RgH/fUUA/35GAP9/RwD/f0cA/3xF
+ AP95RAH/eUQB/3pDAP97QwD/gEYA/4FGAP+CRwD/g0gA/39FAP99RQD/gksG/3VAAP97SQf/cEED/3FE
+ B/95TBP/aT0H/4ddKP/OroX//O3a///+9f////n////6///8+P////z////////////9/////f////3/
+ ///9/////f////3////9/////f//////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////v////v////8/////P////z////7////+f////f////x//rp1P+4oob/cVQv/187
+ C/9zRQ//eUYH/3pDAP+FTQb/eEEA/31GA/9+RwT/eUIA/3dAAP95QgD/fEUA/35GAP9+RgD/fkYA/4BG
+ AP+ARgD/gUYA/4FGAP+BRgD/fkYA/3xGBf98SQr/fEsN/3hHCf9xQgT/bUAD/3FEB/90SA3/cEII/3FF
+ Cv9zRQv/c0UL/3FEB/9vQgX/cUIF/29BB/9tQw7/a0MP/2tDD/9rQw//a0MP/2tDD/9rQw//a0MO/21D
+ Dv9uQgz/bUEL/3FEC/90Rgz/d0gL/3ZHCv92RQf/eUcF/3lFA/93QwH/dkIA/3VCA/92QwT/dUQG/3RD
+ Bf90QwX/d0QF/3hFBv94RQb/eUUD/3lEAf96QwD/fUQA/4FFA/+BRQP/fkUA/35IAf9/SQL/eUQA/3hB
+ AP99RgD/gUgD/3lDBP9xQAj/Zj0M/3ZXMP+6pYb/++3W////8v////b////5////+v///vn////8////
+ /P///////////////////////f////3/////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////8////9v////f////4//779///////+fv8//j6
+ +//////////7////9f//7tf/xq2N/4JgNf9tRRH/c0UL/206AP95RAX/eUQF/3lFA/98RgX/fEcE/3xF
+ AP99RQD/fEQA/4BGAP+ARgD/gEYA/4BGAP+ARgD/gEUA/4BFAP9+RQD/d0IA/3VBAP91QQD/eEQC/3xI
+ Bv98SAb/eEQB/3RAAP95RAH/eUUA/3tFAP99RgD/fUYA/39GAP+ARgD/f0UA/3tFAP95RQD/e0QA/3lF
+ AP97RAH/eUUA/3tEAf97RAD/fUYB/3xFAP9+RgD/fUUA/39FAP+ARgD/gEYA/39FAP+ARgD/fUYA/31F
+ AP98RQD/fEcE/3xIBv95Rgf/d0YI/3ZFB/93RAX/d0QF/3dFA/96RAP/ekYA/35FAP+ARwL/fEQD/3pE
+ Bf92QAD/d0MA/35KBP9+SwX/fEgF/3pIBv9yQwb/bEAL/5FrQf/ZvJ3///Tf////8v/+/fn//f/+////
+ +v////v////7////+/////z////+//z8/P/////////////////9/////f//////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////z////4///+
+ 9f////v////+//r8/f/6/v//+P7///L4/f/19vr////8////9/////H///jd/97Dof+be1L/dE4e/3FC
+ Cv94RQf/d0QF/3dDAf94QwD/fEUA/4FJAv+CSgP/fkYA/35GAP9+RQD/fEUA/3xFAv96RAP/eUQF/3lF
+ A/+BSgf/f0gD/3pFAv94QwD/d0IA/3hEAf96RgT/e0kH/3lGB/95Rgf/eEYE/3hGBP93RQP/d0UD/3lF
+ A/94RAH/fUYB/31HAP9/RwD/fUcA/39GAf99RwD/f0YB/39HAP9+RgD/fkYA/35GAP9+RgD/gEYA/4BG
+ AP+BRgD/gUcA/3xFAP95RQD/e0QA/3tEAP99RQD/fUUA/3xEAP97QwD/gEgB/31FAP98RAD/fkYA/39H
+ AP9+RgD/fkYA/3pFAv90RQj/dEYM/3dFCf95Qwb/dkAB/3I8AP9xQgz/d08f/5Z5Uv/axqf///Xh///8
+ 7v////v///////r5+////v////z7///++v/9+vb//Pn1///+/f////7/////////////////////////
+ //////////////////////7////+////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////v////z///34///+/f///////f7///X5/v/0+v//+v7///v+///9/f3////7///+
+ 9f//++3////x///34v/s1rr/sI9o/4VhM/9nPw7/b0UQ/3lKEv9wPwH/bzsA/3xFAP9+RgD/fkYA/35F
+ AP98RQL/ekQD/3lEBf91Qwf/d0QG/3lCAP99RQD/f0cA/35HAv99RgH/ekYA/3pFAv95RQL/eEQC/3ZE
+ Av92RAL/dkQC/3dEBf93RAX/eEUG/3pGBP98RgD/fkcA/35GAP9+RgD/fkYA/35GAP9+RgD/fkYA/39H
+ AP9/RwD/gEcC/39HAP9+RgD/fUUA/39EAP9+RgD/fUYB/31GAf99RgH/f0cA/4JIAP+CSAD/g0kB/4RK
+ AP+CSAD/f0UA/35EAP+BRwD/gkgA/31FAP98RAD/d0MB/21DCP9qQg3/bkIN/3BDEP92Shv/jGQ6/76b
+ ef/s1Lj////r///98P////n/+//+//j8/f/5/P///f7////+//////7////8/////v////7////+////
+ /v/9/f3/+/v7/////////////////////////////////////v////7/////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////f////f6/v/7/v//+Pv///P3+P/9/////f////7+
+ /v/////////+////+/////z////8/////P////v///z4////+/////j///Tm/9G+qf+Lc1f/aUgh/29H
+ Fv94ShD/dkIA/35GAP+ARgD/gEYA/35GAP98RQL/eUQF/3VDB/93RAb/fkcC/4BGAP9+RAD/fUUA/35G
+ AP9/RwD/fkcA/3xFAP9/RwD/gEgB/4BIAf9/RwD/fkcA/35HAP9+RwD/f0gA/39IAP9/SAD/f0gA/39I
+ AP99RwD/fUcA/31GAf99RgH/ekMA/3tEAP97RAH/e0QB/3xFAv98RQL/fUYD/31GAf9/RwD/gUcA/4FH
+ AP+ARgD/f0UA/39FAP9/RQD/fkYA/35GAP98RAD/fUUA/39HAP9+RgD/ekMA/31GAf99Sgv/bUAH/2hA
+ EP9yTyf/mX5c/9G/qP/77t7////4////+//++/f////8////+//8+/f////+/////v//////+/v7//v7
+ +/////7///////39/f/+/v7//f39//7+/v////////////////////7////+/////v////7////+////
+ /v//////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////9////+v7///b8
+ ///6/v//+/7///r8/f/8/Pz////+///++v////z////7/////v//////+fv8//v+///6/v//+Pz///3+
+ /////v7////7////9f//8tv/18Cg/56AV/95VCL/bkIM/3NEB/91RAb/d0QF/3dEBf93RAX/d0QG/3lE
+ Bf97RAD/fkYA/35GAP9+RgD/fUUA/31GAP9+RwD/gEYA/39FAP+ARwD/gUcA/4FIAP+ARgD/f0cA/4FH
+ AP+BSAD/fUYA/31GAP99RgD/fUYA/3tFAP97RQD/e0QA/3tEAP99RgP/e0YD/3pFAv96RQL/ekQD/3pE
+ A/96RAP/ekQD/3tEAP99RQD/fkYA/35GAP9+RgD/fkYA/39HAP99RgH/e0YD/3lFA/91RAb/c0QH/21A
+ B/9sQAr/ckgT/3pSIv+qhl7/4MKf///12/////D////3/////P/7////9vr///v+///9/v/////////+
+ /f////7///76///++v////z////////////9/f3//////////////////Pz8////////////////////
+ /v////7////+/////v////7////+////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////3////7/v//+v7///v+///7/v///f////////////7////+/////v////7////+////
+ ///9////+/7///v+///9///////+///++////fr////7////+/////f///nu//3z4v/Swqv/rZV3/4Vm
+ P/9yTiD/ckYQ/3NCBP93QgD/e0QA/3tHAf96RgD/e0QA/3pDAP96QwD/e0UA/31HAP+ASAH/fkYA/35H
+ AP99RQD/fUYA/4BGAP9+RwD/f0UA/3xFAP9+RwD/fEcA/3xGAP98RgD/fEYA/3xGAP98RQD/fEUA/3tG
+ A/96RQL/eUMC/3lFA/96RQb/ekUG/3hDBP90QQP/e0gK/3ZDBP90QQL/eEQC/3xHBP99RgH/fEUA/3hE
+ Av9zQgT/cEMK/21FFP9wUCf/hWpI/66YfP/fzbb///Df////9P////X////3////9/////j////7////
+ /v/7////+/7///v+///7/v///f7///////////z////5////+f////7//f//////////////////////
+ /////////////////v////7////+/////v////7////+/////v////7/////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////3////7/////f7///3/////////////////
+ /v////7////+/////v////7//////////////////f////////////v////7/////P////7//f////v/
+ ///6/v//+vz8////+/////T///fk//bhwv/XuJH/sY1f/5dtOP+KXyb/cUUP/29EC/9vQgn/b0MI/3FE
+ B/9zRAf/c0IE/3NAAf91QQD/eEMA/3tGA/9+RwL/fkgB/35IAf+BSQL/gEoD/3tFAP95RQD/eUUA/3lF
+ AP95RQD/eUUA/3lEAf95RAH/ekQD/3lFA/96RQb/d0QF/3ZDBf93RAb/dkQI/3VFC/9sPwb/b0MN/3RI
+ Ev9xRQ//aT0H/2o+CP92TBf/glop/5NwRP+qjWj/z7eZ/+/dxv//8+P///3z////+f////z/////////
+ //////7////8////+/////z////+///////9////+/7///v+///7/v///////////v////v////7////
+ ///9///////////////////////////////////////+/////v////7////+/////v////7////+////
+ /v//////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////3/
+ /////v/////////////////////+/////v////7////+/////v////7////+/////v////7////8////
+ +/////v////8///+/f/9/vz//P7+//3////9////+vv5////+/////n////1////8v///+7///Pe//nl
+ zP/exqj/yK2L/6KGY/+BZD3/cFAn/2tIHP9tRxf/cEgU/3BEDv9yRAr/c0IE/3VCA/93QwD/eUUA/3pD
+ AP95QgD/eUUC/3lFA/95RQP/eUUD/3lFA/95RQP/eUUD/3dFA/92QwT/dkYG/3dGCP91RAb/cEEE/3BB
+ BP90RAr/dUcR/3JJGP9sSBr/cU8k/4VmP/+kiWf/xa+T/9/Ntv/r3cv///vt///+9P////n////7////
+ +/////v////7/////P/9//7/+//+//3//////v////7////+/////v///////////v////z//f/8//3/
+ /v/9//////7////+/////v///f////3////9/////f/////////////////+/////v////7////+////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////v////7////8/////v////z////8////
+ /P////z////+/////v////7///z7///+/f////7////+//39/f/7/f3//P7+//3////9/////f////7/
+ /f/7+fj///35////+/////z///73////9P////L////x////7f//+OH/+OPI/9/Hqf/QtZP/uJ14/6+R
+ aP+ffVL/kW9B/4djM/99WCb/ckoZ/2lBEP9pQRD/aUEQ/2lBEP9pQRD/aUEQ/2lBEP9qQRD/aUEQ/3NL
+ Gv96VCT/iWMz/5ZyQv+lgVP/tZNl/8ajd//QrYX/68+s//vjxf///OH////u////8v///fP////7////
+ ///9////+/7///v+///7/v///f////7+/v///v3////8/////P/9//7//f/////+/////v////7////+
+ ///////////+/////P////z////+//3////9/v///f3///39///9/v///f////3////9////////////
+ //////7////+/////v////7/////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////3////9//////////////////7////8////
+ /P////v////8/////P////z////8/////v////////////3////7/v//+/7///v+///7/v//+/////v/
+ ///6//7/+f79//f6+P/7/vz////+/////v///v3////7///+/f////v////+/////P////z////7////
+ +f////n////3////9v////f////1///67f//+Ov///ns///67f//+Ov///bo///35P//9+L///jh///4
+ 4f//+OH///jh///34f//+OH///bf///34v//+uX///3n///+6////+7////x////8v////X////4////
+ +f////v////8/////v/7+/v/9ff4//v+///6/f//+/7///v+///9//////////////////7////8////
+ /P////z////8//3//P/9//7/+/////3////9/v////7////9/////v////7////+/////////f////3/
+ ///9/////////////////////////////v////7////+/////v////////////3////9/////f////3/
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////+/////v////7////+/////P////7////+/////v////7//////////////////f////v+
+ ///6/v//+f7///n+///7////+/////3////9//7//f/+/////v/+//3////+/////v///////v7+//v9
+ /f/6/v//+v3///v+///9/////f////3///////////////z+///9/////f////v////7/v//+f7///r+
+ ///7///////+/////P////v////7////+/////v////5////+f////v////7////+/////v////7///+
+ +v/+/Pv//P37///////9/////f////3////9/////f////3////9/////f////3////9/////f////3/
+ ///8/v//+/3+//z8/P////7////8/////P////z//f/8//v//v/7////+/////3+///9/f////3////+
+ /////v///////////P////z///////3////////////////////////////+/////v////7////+////
+ /////////f////3////7/v//+//////+////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ /////////////////v////z////8/////P////7///////3////9////+/////3+///9/////f////3/
+ /////////////////////////f////z+///9/f3//v7+//7//f////7////8/////P/7/Pj//v/7////
+ /v/9//7/+/39//r8/f/6/f//+/7///r+///9/////f///////////////v/9///++v/+/fn//vv3///+
+ +v////z////+/////v/+//3//v7+///////9/////f7///3+///9/v////7////+//////////////7+
+ /v/8/v7//f////v////7////+v////r////6/////P7///////////////79//78+////fz///76///+
+ +v///vr///38///9/P/9/f3//f////3////9/////f////3//v////7////+//3//v///////f////3/
+ ///9///////////////////////+/////v////7////+/////v///////f/////////////////+////
+ /v////7////+/////v////7////////////9////+/7///v+///7//////7/////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////+////+/////n////8/////v//////+/////v+
+ ///6/v//+v7///r+///7/v//+//////+///////////+/////v/9/f3//////////v////7////8////
+ /P////r////6/////P////z////+//v+/P/5/f7/+/////r+///6/////f7///3////+/v7/////////
+ /v////z////8////+/////v////7///89////fj////8/////P////z////+//v+///6/f//+v3///r9
+ ///7/v//+/7///v+///7/v//+/7///v+///6////+v////f9///3/f//9v7///j+///7/f7/////////
+ /v////7////8/////P////v////7////+/////v////+/////v///v///f////r9///5/f7/+/////v/
+ /v/9/////f/////+/////v////7////////////////+/////P////z////8/////P///v7////+///+
+ ///9//////////////////7////+/////v////7////+/////v///////f////3+///7/v//+/7///v/
+ /////v//////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAA=
+
+
+
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn/UI/ValidationIssuesControl.Designer.cs b/AddIn/EABridge_Example_AddIn/UI/ValidationIssuesControl.Designer.cs
new file mode 100644
index 0000000..3e0eb17
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/UI/ValidationIssuesControl.Designer.cs
@@ -0,0 +1,155 @@
+namespace EABridge_Example_AddIn.UI
+{
+ partial class ValidationIssuesControl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ValidationIssuesDataGridView = new System.Windows.Forms.DataGridView();
+ this.ElementNameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ this.ElementTypeColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ this.IssueCategoryColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ this.SeverityColumn = new System.Windows.Forms.DataGridViewImageColumn();
+ this.MsgColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ this.ValidationInProgressLabel = new System.Windows.Forms.Label();
+ this.AbortValidationButton = new System.Windows.Forms.Button();
+ ((System.ComponentModel.ISupportInitialize)(this.ValidationIssuesDataGridView)).BeginInit();
+ this.SuspendLayout();
+ //
+ // ValidationIssuesDataGridView
+ //
+ this.ValidationIssuesDataGridView.AllowUserToAddRows = false;
+ this.ValidationIssuesDataGridView.AllowUserToDeleteRows = false;
+ this.ValidationIssuesDataGridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
+ this.ValidationIssuesDataGridView.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;
+ this.ValidationIssuesDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ this.ValidationIssuesDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+ this.ElementNameColumn,
+ this.ElementTypeColumn,
+ this.IssueCategoryColumn,
+ this.SeverityColumn,
+ this.MsgColumn});
+ this.ValidationIssuesDataGridView.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ValidationIssuesDataGridView.Location = new System.Drawing.Point(0, 0);
+ this.ValidationIssuesDataGridView.Name = "ValidationIssuesDataGridView";
+ this.ValidationIssuesDataGridView.ReadOnly = true;
+ this.ValidationIssuesDataGridView.RowTemplate.Resizable = System.Windows.Forms.DataGridViewTriState.False;
+ this.ValidationIssuesDataGridView.Size = new System.Drawing.Size(600, 400);
+ this.ValidationIssuesDataGridView.TabIndex = 0;
+ this.ValidationIssuesDataGridView.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.ValidationIssuesDataGridView_CellClick);
+ this.ValidationIssuesDataGridView.SortCompare += new System.Windows.Forms.DataGridViewSortCompareEventHandler(this.ValidationIssuesDataGridView_SortCompare);
+ //
+ // ElementNameColumn
+ //
+ this.ElementNameColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
+ this.ElementNameColumn.HeaderText = "Element name";
+ this.ElementNameColumn.Name = "ElementNameColumn";
+ this.ElementNameColumn.ReadOnly = true;
+ this.ElementNameColumn.Width = 91;
+ //
+ // ElementTypeColumn
+ //
+ this.ElementTypeColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader;
+ this.ElementTypeColumn.HeaderText = "Element type";
+ this.ElementTypeColumn.Name = "ElementTypeColumn";
+ this.ElementTypeColumn.ReadOnly = true;
+ this.ElementTypeColumn.Width = 86;
+ //
+ // IssueCategoryColumn
+ //
+ this.IssueCategoryColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader;
+ this.IssueCategoryColumn.HeaderText = "Issue Category";
+ this.IssueCategoryColumn.Name = "IssueCategoryColumn";
+ this.IssueCategoryColumn.ReadOnly = true;
+ this.IssueCategoryColumn.Width = 94;
+ //
+ // SeverityColumn
+ //
+ this.SeverityColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader;
+ this.SeverityColumn.HeaderText = "Severity";
+ this.SeverityColumn.Name = "SeverityColumn";
+ this.SeverityColumn.ReadOnly = true;
+ this.SeverityColumn.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+ this.SeverityColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
+ this.SeverityColumn.Width = 70;
+ //
+ // MsgColumn
+ //
+ this.MsgColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
+ this.MsgColumn.HeaderText = "Validation message";
+ this.MsgColumn.Name = "MsgColumn";
+ this.MsgColumn.ReadOnly = true;
+ //
+ // ValidationInProgressLabel
+ //
+ this.ValidationInProgressLabel.AutoSize = true;
+ this.ValidationInProgressLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.ValidationInProgressLabel.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
+ this.ValidationInProgressLabel.Location = new System.Drawing.Point(3, 0);
+ this.ValidationInProgressLabel.Name = "ValidationInProgressLabel";
+ this.ValidationInProgressLabel.Size = new System.Drawing.Size(179, 39);
+ this.ValidationInProgressLabel.TabIndex = 1;
+ this.ValidationInProgressLabel.Text = "Validation of [Name] in progress... \r\n\r\nValidation results will be shown here.\r\n";
+ this.ValidationInProgressLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // abortValidationButton
+ //
+ this.AbortValidationButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.AbortValidationButton.Location = new System.Drawing.Point(522, 3);
+ this.AbortValidationButton.Name = "abortValidationButton";
+ this.AbortValidationButton.Size = new System.Drawing.Size(75, 23);
+ this.AbortValidationButton.TabIndex = 2;
+ this.AbortValidationButton.Text = "Abort";
+ this.AbortValidationButton.UseVisualStyleBackColor = true;
+ this.AbortValidationButton.Click += new System.EventHandler(this.AbortValidationButton_Click);
+ //
+ // ValidationIssuesControl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.AbortValidationButton);
+ this.Controls.Add(this.ValidationInProgressLabel);
+ this.Controls.Add(this.ValidationIssuesDataGridView);
+ this.Name = "ValidationIssuesControl";
+ this.Size = new System.Drawing.Size(600, 400);
+ ((System.ComponentModel.ISupportInitialize)(this.ValidationIssuesDataGridView)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.DataGridView ValidationIssuesDataGridView;
+ private System.Windows.Forms.DataGridViewTextBoxColumn ElementNameColumn;
+ private System.Windows.Forms.DataGridViewTextBoxColumn ElementTypeColumn;
+ private System.Windows.Forms.DataGridViewTextBoxColumn IssueCategoryColumn;
+ private System.Windows.Forms.DataGridViewImageColumn SeverityColumn;
+ private System.Windows.Forms.DataGridViewTextBoxColumn MsgColumn;
+ private System.Windows.Forms.Label ValidationInProgressLabel;
+ private System.Windows.Forms.Button AbortValidationButton;
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/UI/ValidationIssuesControl.cs b/AddIn/EABridge_Example_AddIn/UI/ValidationIssuesControl.cs
new file mode 100644
index 0000000..b5a3ad6
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/UI/ValidationIssuesControl.cs
@@ -0,0 +1,317 @@
+using EABridge_Example_AddIn.ApplicationHandlers;
+using EABridge_Example_AddIn.Reports;
+using EABridge_Example_AddIn.Utils;
+using EA;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+
+namespace EABridge_Example_AddIn.UI
+{
+ [Guid("E4F9A26A-5EDF-44BE-98A0-015E3D7C6E7A")]
+ [ComVisible(true)]
+ public partial class ValidationIssuesControl : UserControl
+ {
+ private Repository Repository;
+ IDictionary Issues = new Dictionary();
+ private const string validationInProgressText = @"Validation of [Name] in progress... ";
+ private ExampleHeadlessApplicationHandler HeadlessApplicationHandler;
+
+ public ValidationIssuesControl()
+ {
+ InitializeComponent();
+ }
+
+ public ValidationIssuesControl(Repository repository, SerializableValidationResult displayResult)
+ {
+ InitializeComponent();
+ this.Issues = displayResult.GetAllValidationIssues();
+ this.Repository = repository;
+ ValidationInProgressLabel.Visible = false;
+ AbortValidationButton.Visible = false;
+ ShowValidationResults();
+ }
+
+ private void ShowValidationResults()
+ {
+ foreach (var item in Issues)
+ {
+ AddValidationIssue(Repository, item);
+ }
+ }
+
+ public void UpdateValidationViewState(string guid, ExampleHeadlessApplicationHandler handler)
+ {
+ HeadlessApplicationHandler = handler;
+ Issues.Clear();
+ ValidationIssuesDataGridView.Rows.Clear();
+ ValidationIssuesDataGridView.Visible = false;
+ var guidName = EARepositoryUtils.GetEAObjectSimpleNameFromGuid(Repository, guid);
+ string validationText = validationInProgressText.Replace("[Name]", guidName);
+ ValidationInProgressLabel.Text = validationText;
+ ValidationInProgressLabel.Visible = true;
+ AbortValidationButton.Visible = true;
+ AbortValidationButton.Enabled = true;
+
+ }
+
+ public void UpdateValidationIssues(SerializableValidationResult newResult, Repository repository)
+ {
+ ValidationInProgressLabel.Visible = false;
+ AbortValidationButton.Visible = false;
+ ValidationIssuesDataGridView.Visible = true;
+ ValidationIssuesDataGridView.Rows.Clear();
+ this.Issues.Clear();
+ this.Repository = repository ?? throw new ArgumentNullException(nameof(repository));
+ this.Issues = newResult.GetAllValidationIssues();
+ ShowValidationResults();
+ }
+
+ public void AddValidationIssue(Repository repository, KeyValuePair issue)
+ {
+ DataGridViewRow row = new DataGridViewRow();
+ row.Tag = issue;
+ row.MinimumHeight = row.Height;
+ row.CreateCells(ValidationIssuesDataGridView);
+ UpdateRowCellValues(row);
+ if (ValidationIssuesDataGridView.InvokeRequired)
+ {
+ ValidationIssuesDataGridView.Invoke(new MethodInvoker(delegate { ValidationIssuesDataGridView.Rows.Add(row); }));
+ } else
+ {
+ ValidationIssuesDataGridView.Rows.Add(row);
+ }
+ }
+
+ private void UpdateRowHeight(DataGridViewRow row)
+ {
+ string membersText = row.Cells[MsgColumn.Index].Value as string;
+ if (membersText != "")
+ {
+ int padding = row.MinimumHeight - TextRenderer.MeasureText("|", ValidationIssuesDataGridView.Font).Height;
+ Size size = TextRenderer.MeasureText(membersText != "" ? membersText : "|", ValidationIssuesDataGridView.Font);
+ row.Height = size.Height + padding;
+ }
+ else
+ {
+ row.Height = row.MinimumHeight;
+ }
+ }
+
+ private void UpdateRowCellValues(DataGridViewRow row)
+ {
+ KeyValuePair issue = (KeyValuePair)row.Tag;
+
+ row.Cells[ElementNameColumn.Index].Value = EARepositoryUtils.GetEAElementName(this.Repository, issue.Key.type, issue.Key.id).Value;
+ row.Cells[ElementTypeColumn.Index].Value = issue.Key.type;
+ string issueSeverity = issue.Key.severity;
+ switch (issueSeverity)
+ {
+ case "E":
+ row.Cells[SeverityColumn.Index].Value = new Bitmap(SystemIcons.Error.ToBitmap(), 16, 16);
+ break;
+ case "W":
+ row.Cells[SeverityColumn.Index].Value = new Bitmap(SystemIcons.Warning.ToBitmap(), 16, 16);
+ break;
+ case "I":
+ row.Cells[SeverityColumn.Index].Value = new Bitmap(SystemIcons.Information.ToBitmap(), 16, 16);
+ break;
+ default:
+ row.Cells[SeverityColumn.Index].Value = new Bitmap(SystemIcons.Question.ToBitmap(), 16, 16);
+ break;
+ }
+ row.Cells[IssueCategoryColumn.Index].Value = issue.Value;
+ row.Cells[MsgColumn.Index].Value = issue.Key.msg;
+ UpdateRowHeight(row);
+ }
+
+ private void ValidationIssuesDataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
+ {
+ if (e.RowIndex >= 0 && e.RowIndex < Issues.Count)
+ {
+ DataGridViewRow row = ValidationIssuesDataGridView.Rows[e.RowIndex];
+
+ if (row != null)
+ {
+ KeyValuePair issue = (KeyValuePair)row.Tag;
+ NavigateToElementInProjectExplorer(issue.Key);
+ }
+
+ }
+
+ }
+
+ public void NavigateToElementInProjectExplorer(ValidationIssue issue)
+ {
+ Element element = null;
+ int id = -1;
+ object focus = null;
+ string type = issue.type;
+ int issueId = -1;
+ if (!int.TryParse(issue.id, out issueId))
+ {
+ MessageBox.Show(Win32Window.GetMainWindowHandle(), "This validation issue is not navigable\n\n", "Reported issue is not navigable");
+ return;
+ }
+
+ switch (type)
+ {
+ case "element":
+ element = Repository.GetElementByID(int.Parse(issue.id));
+ id = element.ElementID;
+ focus = element;
+ break;
+
+ case "connector":
+ Connector connector = Repository.GetConnectorByID(int.Parse(issue.id));
+ if (connector != null)
+ {
+ id = connector.ClientID;
+ element = Repository.GetElementByID(id);
+ }
+ focus = element;
+ break;
+
+ case "attribute":
+ EA.Attribute attribute = Repository.GetAttributeByID(int.Parse(issue.id));
+ if (attribute != null)
+ {
+ id = attribute.ParentID;
+ element = Repository.GetElementByID(id);
+ }
+ focus = attribute;
+ break;
+
+ case "operation":
+ Method method = Repository.GetMethodByID(int.Parse(issue.id));
+ if (method != null)
+ {
+ id = method.ParentID;
+ element = Repository.GetElementByID(id);
+ }
+ focus = method;
+ break;
+
+ case "parameter":
+ Method paraMethod = Repository.GetMethodByID(int.Parse(issue.id));
+ if (paraMethod != null)
+ {
+ id = paraMethod.ParentID;
+ element = Repository.GetElementByID(id);
+ }
+ focus = paraMethod;
+ break;
+
+ case "package":
+ Package package = Repository.GetPackageByID(int.Parse(issue.id));
+ if (package != null)
+ {
+ Repository.ShowInProjectView(package);
+ }
+ break;
+
+ default:
+ MessageBox.Show(Win32Window.GetMainWindowHandle(), "The reported issue with severity '" + issue.severity + "' is currently not navigable:\n\n" + issue.msg, "Reported issue is not navigable");
+ return;
+ }
+
+ if (element != null)
+ {
+ Repository.ShowInProjectView(element);
+ Collection elementDiagrams = null;
+ if ("element" == issue.type)
+ {
+ Element parentElement = element;
+ if (element.Diagrams.Count < 1)
+ {
+ try
+ {
+ parentElement = Repository.GetElementByID(element.ParentID);
+ elementDiagrams = parentElement.Diagrams;
+ }
+ catch (Exception)
+ {
+ // If the element is not in a diagram and its parent is not found then we ignore navigation to diagram
+ // MessageBox.Show(Win32Window.GetMainWindowHandle(), "Element: " + parentElement.Name + " can not be identified by its ID");
+ }
+ } else
+ {
+ elementDiagrams = element.Diagrams;
+ }
+ }
+
+ Diagram diagram = Repository.GetCurrentDiagram();
+ if (elementDiagrams != null && elementDiagrams.Count >= 1)
+ {
+ // we'll navigate to the first diagram for now
+ diagram = elementDiagrams.GetAt(0);
+ Repository.OpenDiagram(diagram.DiagramID);
+ Repository.ActivateDiagram(diagram.DiagramID);
+ }
+ if (diagram != null)
+ {
+ for (short i = (short)(diagram.SelectedObjects.Count - 1); i >= 0; i--)
+ {
+ diagram.SelectedObjects.DeleteAt(i, false); // There is no need to update the DescriptionsCache, because it is only a change in the UI.
+ }
+ diagram.SelectedObjects.Refresh();
+ diagram.SelectedObjects.AddNew(id.ToString(), element.Type);
+ diagram.SelectedObjects.Refresh();
+ try
+ {
+ if (!diagram.Update())
+ {
+ throw new Exception("Failed to update diagram '" + diagram.Name + "' with ID " + diagram.DiagramID + ".");
+ }
+ }
+ catch (COMException e)
+ {
+ throw new Exception("Failed to update diagram '" + diagram.Name + "' with ID " + diagram.DiagramID + ": " + e.Message, e);
+ }
+ }
+ else
+ {
+ // do nothing for now !!
+ }
+ }
+ if (focus != null)
+ {
+ Repository.ShowInProjectView(focus);
+ }
+ }
+
+ private void ValidationIssuesDataGridView_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
+ {
+ if (e.Column.Index == SeverityColumn.Index)
+ {
+ // sort based on the severity icon
+ DataGridViewRow row1 = ValidationIssuesDataGridView.Rows[e.RowIndex1];
+ DataGridViewRow row2 = ValidationIssuesDataGridView.Rows[e.RowIndex2];
+ KeyValuePair issue1Entry = (KeyValuePair) row1.Tag;
+ KeyValuePair issue2Entry = (KeyValuePair) row2.Tag;
+
+ string severity1 = issue1Entry.Key.severity;
+ string severity2 = issue2Entry.Key.severity;
+ e.SortResult = ValidationIssueSeverityUtils.CompareSeverityLevels(severity1, severity2);
+ e.Handled = true;
+ } else
+ {
+ // do nothing
+ }
+ }
+
+ private void AbortValidationButton_Click(object sender, EventArgs e)
+ {
+ if (HeadlessApplicationHandler != null)
+ {
+ HeadlessApplicationHandler.KillProcess();
+ ValidationInProgressLabel.Text = @"Validtion aborted";
+ AbortValidationButton.Enabled = false;
+ HeadlessApplicationHandler = null;
+ }
+ }
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/UI/ValidationIssuesControl.resx b/AddIn/EABridge_Example_AddIn/UI/ValidationIssuesControl.resx
new file mode 100644
index 0000000..6ecd3cf
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/UI/ValidationIssuesControl.resx
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn/UI/Win32Window.cs b/AddIn/EABridge_Example_AddIn/UI/Win32Window.cs
new file mode 100644
index 0000000..2bcd44a
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/UI/Win32Window.cs
@@ -0,0 +1,39 @@
+using System.Windows.Forms;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+
+namespace EABridge_Example_AddIn.UI
+{
+ public class Win32Window : IWin32Window
+ {
+ private readonly IntPtr handle;
+
+ public Win32Window(IntPtr handle)
+ {
+ this.handle = handle;
+ }
+
+ public IntPtr Handle
+ {
+ get { return handle; }
+ }
+
+ public static IWin32Window GetMainWindowHandle()
+ {
+ Process process = Process.GetCurrentProcess();
+ process.Refresh();
+ IntPtr handle = process.MainWindowHandle;
+ if (!IntPtr.Zero.Equals(handle))
+ {
+ return new Win32Window(handle);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn/UI/icons/itemis_logo.ico b/AddIn/EABridge_Example_AddIn/UI/icons/itemis_logo.ico
new file mode 100644
index 0000000..fb5883d
Binary files /dev/null and b/AddIn/EABridge_Example_AddIn/UI/icons/itemis_logo.ico differ
diff --git a/AddIn/EABridge_Example_AddIn/Utils/DateTimeUtils.cs b/AddIn/EABridge_Example_AddIn/Utils/DateTimeUtils.cs
new file mode 100644
index 0000000..98d0614
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Utils/DateTimeUtils.cs
@@ -0,0 +1,35 @@
+using System;
+
+namespace EABridge_Example_AddIn.Utils
+{
+ public static class DateTimeUtils
+ {
+ private static long SecInMilisec = 1000;
+ private static long MinInMilisec = SecInMilisec * 60;
+ private static long HourInMilisec = MinInMilisec * 60;
+ private static long DayInMilisec = HourInMilisec * 24;
+ private static long YearInMilisec = DayInMilisec * 365;
+
+ public static long GetTimeDifferenceInMilisec(DateTime date1, DateTime date2)
+ {
+ long difference = date1.GetDateTimeInMilisec() - date2.GetDateTimeInMilisec();
+ return Math.Abs(difference);
+ }
+
+ public static long GetDateTimeInMilisec(this DateTime dateTime)
+ {
+ return (dateTime.Year * YearInMilisec) + (dateTime.DayOfYear * DayInMilisec) + (dateTime.Hour * HourInMilisec) + (dateTime.Minute * MinInMilisec)
+ + (dateTime.Second * SecInMilisec) + dateTime.Millisecond;
+ }
+
+ public static string GetHumanReadableDuration(long durationInMiliseconds)
+ {
+ if (durationInMiliseconds < 2000)
+ return durationInMiliseconds + " ms";
+ if (durationInMiliseconds < 100 * 1000)
+ return (durationInMiliseconds / 1000) + " sec";
+ return (durationInMiliseconds / 1000 / 60) + " min";
+ }
+ }
+}
+
diff --git a/AddIn/EABridge_Example_AddIn/Utils/EARepositoryUtils.cs b/AddIn/EABridge_Example_AddIn/Utils/EARepositoryUtils.cs
new file mode 100644
index 0000000..8aaac25
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Utils/EARepositoryUtils.cs
@@ -0,0 +1,190 @@
+using EABridge_Example_AddIn.ApplicationHandlers;
+using EA;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml.Linq;
+using File = System.IO.File;
+
+namespace EABridge_Example_AddIn.Utils
+{
+ public static class EARepositoryUtils
+ {
+
+ public const string EAPackageType = "Package";
+ public const string EAElementType = "Element";
+
+
+ public static bool IsPackageGuid(Repository repository, string guid)
+ {
+ try
+ {
+ Package package = repository.GetPackageByGuid(guid);
+ return package != null ? true : false;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static bool IsElementGuid(Repository repository, string guid)
+ {
+ try
+ {
+ Element element = repository.GetElementByGuid(guid);
+ return element != null ? true : false;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static string GetGuidOfPackageOrElementOrDiagram(object cxt)
+ {
+ if (cxt is Package)
+ {
+ return ((Package)cxt).PackageGUID;
+
+ }
+ else if (cxt is Element)
+ {
+ return ((Element)cxt).ElementGUID;
+
+ }
+ else if (cxt is Diagram)
+ {
+ return ((Diagram)cxt).DiagramGUID;
+
+ }
+ else
+ {
+ return "";
+ }
+
+ }
+
+ public static bool IsCLIOperationForContextObjectAllowed(object cxt)
+ {
+ if (cxt is Package)
+ {
+ return true;
+ }
+ else if (cxt is Element)
+ {
+ Element cxtCast = (Element)cxt;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+
+ public static string GetAllRootPackageNames(this Repository repository)
+ {
+ var models = repository.Models;
+ List names = new List();
+ if (models == null || models.Count == 0)
+ {
+ return "";
+ }
+ else
+ {
+ // get the model where the requested package is
+ foreach (Package model in models)
+ {
+ names.Add(model.Name);
+ }
+
+ return string.Join(", ", names.ToArray());
+ }
+
+ }
+
+ public static string GetEAObjectSimpleNameFromGuid(this Repository repository, string guid)
+ {
+ if (IsPackageGuid(repository, guid))
+ {
+ var package = repository.GetPackageByGuid(guid);
+ return package.Name;
+ }
+ else if (IsElementGuid(repository, guid))
+ {
+ var element = repository.GetElementByGuid(guid);
+ return element.Name;
+ }
+ else if (string.IsNullOrEmpty(guid))
+ {
+ return GetAllRootPackageNames(repository);
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+
+ public static KeyValuePair GetEAElementName(Repository repository, string type, string id)
+ {
+ Element element = null;
+ switch (type)
+ {
+ case "element":
+ element = repository.GetElementByID(int.Parse(id));
+ return new KeyValuePair(element.FQName, element.Name);
+
+ case "connector":
+ Connector connector = repository.GetConnectorByID(int.Parse(id));
+ if (connector != null)
+ {
+ int connectorID = connector.ClientID;
+ element = repository.GetElementByID(connectorID);
+ return new KeyValuePair(element.FQName, element.Name);
+ }
+ return new KeyValuePair(String.Empty, String.Empty);
+
+ case "attribute":
+ EA.Attribute attribute = repository.GetAttributeByID(int.Parse(id));
+ if (attribute != null)
+ {
+ return new KeyValuePair(attribute.FQStereotype, attribute.Name);
+ }
+ return new KeyValuePair(String.Empty, String.Empty);
+
+ case "operation":
+ Method method = repository.GetMethodByID(int.Parse(id));
+ if (method != null)
+ {
+ return new KeyValuePair(method.FQStereotype, method.Name);
+ }
+ return new KeyValuePair(String.Empty, String.Empty);
+
+ case "parameter":
+ Method paraMethod = repository.GetMethodByID(int.Parse(id));
+ if (paraMethod != null)
+ {
+ return new KeyValuePair(paraMethod.FQStereotype, paraMethod.Name);
+ }
+ return new KeyValuePair(String.Empty, String.Empty);
+
+ case "package":
+ Package package = repository.GetPackageByID(int.Parse(id));
+ if (package != null)
+ {
+ return new KeyValuePair(package.StereotypeEx, package.Name);
+ }
+ return new KeyValuePair(String.Empty, String.Empty);
+
+ default:
+ return new KeyValuePair(String.Empty, String.Empty);
+
+ }
+ }
+
+
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/Utils/FileUtils.cs b/AddIn/EABridge_Example_AddIn/Utils/FileUtils.cs
new file mode 100644
index 0000000..e589e0b
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Utils/FileUtils.cs
@@ -0,0 +1,90 @@
+using Newtonsoft.Json;
+using System;
+using System.IO;
+
+namespace EABridge_Example_AddIn.Utils
+{
+ public static class FileUtils
+ {
+ private static string ConfigurationFilePath = GetConfigurationFilePath();
+
+ public static bool IsPathValid(string path)
+ {
+ try
+ {
+ if (path == null ||
+ !Path.IsPathRooted(path))
+ {
+ return false;
+ }
+ Path.GetFullPath(path);
+ }
+ catch (Exception)
+ {
+ return false;
+
+ }
+
+ return true;
+ }
+
+ public static bool UpadteOrCreateValidationConfiguration(ValidationConfiguration configuration)
+ {
+ try
+ {
+ JsonSerializer serializer = new JsonSerializer();
+ serializer.NullValueHandling = NullValueHandling.Ignore;
+ StreamWriter sw;
+ if (File.Exists(ConfigurationFilePath))
+ {
+ sw = new StreamWriter(ConfigurationFilePath);
+ }
+ else
+ {
+ sw = File.CreateText(ConfigurationFilePath);
+ }
+ using (JsonWriter writer = new JsonTextWriter(sw))
+ {
+ serializer.Serialize(writer, configuration);
+ return true;
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public static ValidationConfiguration ReadValidationConfigurationFile()
+ {
+ try
+ {
+ var config = JsonConvert.DeserializeObject(File.ReadAllText(ConfigurationFilePath));
+ return config;
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ private static string GetUserFolder()
+ {
+ return Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
+ }
+
+ private static string GetConfigurationFilePath()
+ {
+
+ string userPath = GetUserFolder();
+ if (!Directory.Exists(Path.Combine(userPath, ".example-cli")))
+ {
+ // create the config directory if it doesn't exist
+ Directory.CreateDirectory(Path.Combine(userPath, ".example-cli"));
+ }
+ return Path.Combine(GetUserFolder(), ".example-cli", "EA_AddIn_CLI_config.json");
+
+ }
+
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/Utils/HeadlessApplicationUtils.cs b/AddIn/EABridge_Example_AddIn/Utils/HeadlessApplicationUtils.cs
new file mode 100644
index 0000000..60aa3f5
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Utils/HeadlessApplicationUtils.cs
@@ -0,0 +1,70 @@
+using EABridge_Example_AddIn.Utils;
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+
+namespace EABridge_Example_AddIn.Utils
+{
+
+ public static class HeadlessApplicationUtils
+ {
+
+ public const string INI_FILE_NAME = "ExampleCLI.ini";
+ public const string EXECUTABLE_FILE_NAME = "ExampleCLI.exe";
+ public const string CONSOLE_EXECUTABLE_FILE_NAME = "ExampleCLIc.exe";
+
+ public static string GetExecuableInIArguments()
+ {
+ string iniFileLocation = Path.Combine(FindHeadlessApplication(), INI_FILE_NAME);
+ return " --launcher.ini \"" + iniFileLocation + "\"";
+
+
+ }
+
+ static string FindHeadlessApplication()
+ {
+ var config = FileUtils.ReadValidationConfigurationFile();
+ if (config == null)
+ {
+ return "";
+ }
+ string storedPath = config.ValidationCLIPath;
+ if (!string.IsNullOrEmpty(storedPath) && IsHeadlessApplicationDirectory(storedPath))
+ {
+ return storedPath;
+ } else
+ {
+ return "";
+ }
+ }
+
+
+
+ public static string FindExecutable()
+ {
+ string path = Path.Combine(FindHeadlessApplication(), CONSOLE_EXECUTABLE_FILE_NAME);
+ if (File.Exists(path))
+ {
+ return path;
+ }
+ else
+ {
+ return Path.Combine(FindHeadlessApplication(), EXECUTABLE_FILE_NAME);
+ }
+ }
+
+ public static bool IsHeadlessApplicationDirectory(string directory)
+ {
+ if (Directory.Exists(directory))
+ {
+ string exeFile = Path.Combine(directory, EXECUTABLE_FILE_NAME);
+ return File.Exists(exeFile);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn/Utils/ValidationConfiguration.cs b/AddIn/EABridge_Example_AddIn/Utils/ValidationConfiguration.cs
new file mode 100644
index 0000000..9b21da9
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn/Utils/ValidationConfiguration.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EABridge_Example_AddIn.Utils
+{
+ public class ValidationConfiguration
+ {
+ public string ValidationCLIPath { get; set; }
+ // futher configuration options can be added here
+
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn_Setup/AddInDependency.generated.wxs b/AddIn/EABridge_Example_AddIn_Setup/AddInDependency.generated.wxs
new file mode 100644
index 0000000..cb82395
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Setup/AddInDependency.generated.wxs
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn_Setup/Dialog.wxi b/AddIn/EABridge_Example_AddIn_Setup/Dialog.wxi
new file mode 100644
index 0000000..8610af8
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Setup/Dialog.wxi
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+ 1
+
+ 1
+
+ 1
+
+
+ 1
+
+ 1
+
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
diff --git a/AddIn/EABridge_Example_AddIn_Setup/EABridge_Example_AddIn.generated.wxs b/AddIn/EABridge_Example_AddIn_Setup/EABridge_Example_AddIn.generated.wxs
new file mode 100644
index 0000000..ff36655
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Setup/EABridge_Example_AddIn.generated.wxs
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn_Setup/EABridge_Example_AddIn_Setup.wixproj b/AddIn/EABridge_Example_AddIn_Setup/EABridge_Example_AddIn_Setup.wixproj
new file mode 100644
index 0000000..b2ac65d
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Setup/EABridge_Example_AddIn_Setup.wixproj
@@ -0,0 +1,74 @@
+
+
+
+ Debug
+ x86
+ 3.10
+ 788cc963-0bea-4cc6-826c-589aea2ad2db
+ 2.0
+ EABridge_Example_AddIn_Setup
+ Package
+ $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets
+ $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets
+
+
+ EABridge_Example_AddIn_Setup
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+ Debug
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+
+
+
+
+
+
+
+
+
+
+
+
+ $(WixExtDir)\WixUIExtension.dll
+ WixUIExtension
+
+
+ $(WixExtDir)\WixNetFxExtension.dll
+ WixNetFxExtension
+
+
+
+
+ EABridge_Example_AddIn
+ {9865eccc-f07b-447a-bd11-c75b081eeba4}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn_Setup/Product.wxs b/AddIn/EABridge_Example_AddIn_Setup/Product.wxs
new file mode 100644
index 0000000..674961a
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Setup/Product.wxs
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+ Installed OR NETFRAMEWORK45
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn_Setup/packages.config b/AddIn/EABridge_Example_AddIn_Setup/packages.config
new file mode 100644
index 0000000..83c4644
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Setup/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/AddIn/EABridge_Example_AddIn_Tests/AddInTest/AddInTestConstants.cs b/AddIn/EABridge_Example_AddIn_Tests/AddInTest/AddInTestConstants.cs
new file mode 100644
index 0000000..1a146a5
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Tests/AddInTest/AddInTestConstants.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EABridge_Example_AddIn_Tests.AddInTest
+{
+ public static class AddInTestConstants
+ {
+ public const string ReferenceTestModelPath = "TestModels/Example.eap";
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn_Tests/AddInTest/EAAddInTest.cs b/AddIn/EABridge_Example_AddIn_Tests/AddInTest/EAAddInTest.cs
new file mode 100644
index 0000000..742cebe
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Tests/AddInTest/EAAddInTest.cs
@@ -0,0 +1,53 @@
+using EABridge_Example_AddIn_Tests.TestUtils;
+using EABridge_Example_AddIn;
+using EABridge_Example_AddIn.Utils;
+using EA;
+using NUnit.Framework;
+using FileUtils = EABridge_Example_AddIn_Tests.TestUtils.FileUtils;
+
+namespace EABridge_Example_AddIn_Tests.AddInTest
+{
+ [TestFixture]
+ public class EAAddInTest
+ {
+
+ protected Repository Repository;
+ protected ExampleValidationAddIn ValidationAddIn;
+ protected App App;
+
+ [SetUp]
+ public void SetUp()
+ {
+ LoadRepository(AddInTestConstants.ReferenceTestModelPath, true);
+ ValidationAddIn = new ExampleValidationAddIn();
+ }
+
+ private void LoadRepository(string testModelPath, bool loadAddins)
+ {
+ App = new App();
+ Repository = App.Repository;
+ string repoLocation = FileUtils.BackupFile(testModelPath);
+ Repository.OpenFile(repoLocation);
+ if (loadAddins)
+ {
+ Repository.LoadAddins();
+ }
+ }
+
+
+ [TearDown]
+ public void TearDown()
+ {
+ if (Repository != null)
+ {
+ Repository.CloseFile();
+ Repository.CloseAddins();
+ Repository.Exit();
+ Repository = null;
+ App = null;
+ }
+
+ }
+
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn_Tests/AddInTest/HeadlessApplicationHandlerTest.cs b/AddIn/EABridge_Example_AddIn_Tests/AddInTest/HeadlessApplicationHandlerTest.cs
new file mode 100644
index 0000000..7fd1fe4
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Tests/AddInTest/HeadlessApplicationHandlerTest.cs
@@ -0,0 +1,58 @@
+using EABridge_Example_AddIn_Tests.TestUtils;
+using EA;
+using File = System.IO.File;
+using NUnit.Framework;
+using System;
+using Newtonsoft.Json;
+using EABridge_Example_AddIn.Reports;
+using EABridge_Example_AddIn.ApplicationHandlers;
+
+namespace EABridge_Example_AddIn_Tests.AddInTest
+{
+ [TestFixture]
+ public class HeadlessApplicationHandlerTest : EAAddInTest
+ {
+ [Test]
+ public void HeadlessOperation_Should_UseSeparateThread()
+ {
+ ExampleHeadlessApplicationHandler applicationHandler = new ExampleHeadlessApplicationHandler();
+ applicationHandler.StartExternValidationOperationAsync("", Repository.ConnectionString);
+ Assert.IsTrue(applicationHandler.IsThreadRunning(), "Thread could not be started");
+ }
+
+ [Test]
+ public void HeadlessOperation_Should_TerminateWhenPrompted()
+ {
+ ExampleHeadlessApplicationHandler applicationHandler = new ExampleHeadlessApplicationHandler();
+ applicationHandler.StartExternValidationOperationAsync("", Repository.ConnectionString);
+ Assert.IsTrue(applicationHandler.IsThreadRunning(), "Thread could not be started");
+ applicationHandler.KillProcess();
+ Assert.IsFalse(applicationHandler.IsThreadRunning(), "Thread did not terminate successfully");
+ }
+
+ [Test]
+ public void ValidationOperationOutcome_Should_BeValidJson()
+ {
+ ExampleHeadlessApplicationHandler applicationHandler = new ExampleHeadlessApplicationHandler();
+ applicationHandler.OperationComplete += AssertHeadlessOperationOutcome;
+ applicationHandler.StartExternValidationOperationAsync("", Repository.ConnectionString);
+ Assert.IsTrue(applicationHandler.IsThreadRunning(), "Thread could not be started");
+ }
+
+ private void AssertHeadlessOperationOutcome(ExampleHeadlessApplicationHandler sender, ExternApplicationEventArgs e)
+ {
+ string reportFilePath = e.ReportFile;
+ Assert.IsTrue(e.ReturnCode == 0, "Return code of the CLI application is not successful");
+ Assert.IsTrue(File.Exists(reportFilePath), "Report file path does not exist");
+ try
+ {
+ SerializableValidationResult ValidationReport = JsonConvert.DeserializeObject(File.ReadAllText(reportFilePath));
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+ File.Delete(reportFilePath);
+ }
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn_Tests/EABridge_Example_AddIn_Tests.csproj b/AddIn/EABridge_Example_AddIn_Tests/EABridge_Example_AddIn_Tests.csproj
new file mode 100644
index 0000000..7ad3b71
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Tests/EABridge_Example_AddIn_Tests.csproj
@@ -0,0 +1,31 @@
+
+
+
+ net45
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\..\..\..\Program Files (x86)\Sparx Systems\EA\Interop.EA.dll
+
+
+
+
diff --git a/AddIn/EABridge_Example_AddIn_Tests/ReportsTest/ValidationResultTest.cs b/AddIn/EABridge_Example_AddIn_Tests/ReportsTest/ValidationResultTest.cs
new file mode 100644
index 0000000..8ec9080
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Tests/ReportsTest/ValidationResultTest.cs
@@ -0,0 +1,82 @@
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using EABridge_Example_AddIn.Reports;
+
+namespace EABridge_Example_AddIn_Tests.ReportsTest
+{
+ [TestFixture]
+ public class ValidationResultTest
+ {
+
+ private readonly string ExampeleJson = @"
+{
+ ""resourceIssues"":[
+
+ ],
+ ""loadIssues"":[
+
+ ],
+ ""umlIssues"":[
+ {
+ ""severity"":""W"",
+ ""type"":""Model"",
+ ""id"":""1"",
+ ""message"":""msg1""
+ },
+ {
+ ""severity"":""W"",
+ ""type"":""Class"",
+ ""id"":""2"",
+ ""message"":""msg2""
+ },
+ {
+ ""severity"":""W"",
+ ""type"":""Package"",
+ ""id"":""3"",
+ ""message"":""msg3""
+ },
+ {
+ ""severity"":""W"",
+ ""type"":""Class"",
+ ""id"":""4"",
+ ""message"":""msg4""
+ }
+ ],
+ ""customIssues"":[
+
+ ],
+}
+";
+
+ private readonly string EmptyJson = "{\"resourceIssues\":[],\"loadIssues\":[],\"umlIssues\":[],\"customIssues\":[]}";
+
+ [Test]
+ public void ValidationResult_Should_HandleEmptyStrings()
+ {
+ SerializableValidationResult validationReport = JsonConvert.DeserializeObject(EmptyJson);
+ Assert.IsNotNull(validationReport);
+ Assert.IsTrue(validationReport.GetAllValidationIssues().Count == 0, "Validation result of an empty string is not empty!");
+ }
+
+ [Test]
+ public void ValidationResult_Should_DeserializeStrings()
+ {
+ SerializableValidationResult validationReport = JsonConvert.DeserializeObject(ExampeleJson);
+ Assert.IsNotNull(validationReport);
+ Assert.IsTrue(validationReport.GetAllValidationIssues().Count == 4, "Desrialization result of test json is incorrect!");
+ Assert.IsTrue(validationReport.umlIssues.Count == 4, "Desrialization result of test json is incorrect!");
+ }
+
+ [Test]
+ public void ValidationResult_Should_HandleMalformedStrings()
+ {
+ SerializableValidationResult validationReport = JsonConvert.DeserializeObject("");
+ Assert.IsNull(validationReport);
+ }
+ }
+}
diff --git a/AddIn/EABridge_Example_AddIn_Tests/TestUtils/FileUtils.cs b/AddIn/EABridge_Example_AddIn_Tests/TestUtils/FileUtils.cs
new file mode 100644
index 0000000..734aa30
--- /dev/null
+++ b/AddIn/EABridge_Example_AddIn_Tests/TestUtils/FileUtils.cs
@@ -0,0 +1,52 @@
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EABridge_Example_AddIn_Tests.TestUtils
+{
+ public static class FileUtils
+ {
+
+ public static string BackupFile(string testModelFilePath)
+ {
+ string tmpFolder = Path.Combine(Path.GetTempPath());
+ string tempModelFilePath = Path.Combine(tmpFolder, string.Format("Copy-of-{0}", Path.GetFileName(testModelFilePath)));
+ return BackupFile(testModelFilePath, tempModelFilePath);
+ }
+
+ public static string BackupFile(string testModelFilePath, string targetPath)
+ {
+ Assert.IsFalse(string.IsNullOrEmpty(testModelFilePath), "File to backup not defined.");
+ if (testModelFilePath.StartsWith(Path.DirectorySeparatorChar + ""))
+ {
+ testModelFilePath = testModelFilePath.Substring(1);
+ }
+ string assemblyFolder = GetAssemblyFolder();
+ string sourcePath = Path.Combine(assemblyFolder, testModelFilePath);
+ try
+ {
+ Assert.IsTrue(File.Exists(sourcePath), "File '" + sourcePath + "' does not exist.");
+ File.Copy(sourcePath, targetPath, true);
+ }
+ catch (Exception e)
+ {
+ Assert.Fail(e.Message);
+ }
+ return targetPath;
+ }
+
+ public static string GetAssemblyFolder()
+ {
+ var filePath = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
+ var folder = Path.GetDirectoryName(filePath);
+ return folder;
+ }
+
+
+ }
+}
diff --git a/CLI/.mvn/extensions.xml b/CLI/.mvn/extensions.xml
new file mode 100644
index 0000000..63ce35f
--- /dev/null
+++ b/CLI/.mvn/extensions.xml
@@ -0,0 +1,7 @@
+
+
+ org.eclipse.tycho.extras
+ tycho-pomless
+ 2.4.0
+
+
\ No newline at end of file
diff --git a/CLI/.project b/CLI/.project
new file mode 100644
index 0000000..06520b3
--- /dev/null
+++ b/CLI/.project
@@ -0,0 +1,17 @@
+
+
+ eabridge-example
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.feature/.gitignore b/CLI/com.yakindu.bridges.ea.example.cli.feature/.gitignore
new file mode 100644
index 0000000..3523549
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.feature/.gitignore
@@ -0,0 +1,3 @@
+/bin/
+/target/
+/.polyglot.*
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.feature/.project b/CLI/com.yakindu.bridges.ea.example.cli.feature/.project
new file mode 100644
index 0000000..6475a25
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.feature/.project
@@ -0,0 +1,17 @@
+
+
+ com.yakindu.bridges.ea.example.cli.feature
+
+
+
+
+
+ org.eclipse.pde.FeatureBuilder
+
+
+
+
+
+ org.eclipse.pde.FeatureNature
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.feature/build.properties b/CLI/com.yakindu.bridges.ea.example.cli.feature/build.properties
new file mode 100644
index 0000000..64f93a9
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.feature/feature.xml b/CLI/com.yakindu.bridges.ea.example.cli.feature/feature.xml
new file mode 100644
index 0000000..ed4ed23
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.feature/feature.xml
@@ -0,0 +1,34 @@
+
+
+
+
+ YAKINDU EA-Bridge example CLI application.
+
+
+
+ (C) itemis AG 2022
+
+
+
+ Eclipse Public License 2.0
+
+
+
+
+
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.product/.gitignore b/CLI/com.yakindu.bridges.ea.example.cli.product/.gitignore
new file mode 100644
index 0000000..3523549
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.product/.gitignore
@@ -0,0 +1,3 @@
+/bin/
+/target/
+/.polyglot.*
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.product/.project b/CLI/com.yakindu.bridges.ea.example.cli.product/.project
new file mode 100644
index 0000000..754f7f9
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.product/.project
@@ -0,0 +1,11 @@
+
+
+ com.yakindu.bridges.ea.example.cli.product
+
+
+
+
+
+
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.product/com.yakindu.bridges.ea.example.cli.product.product b/CLI/com.yakindu.bridges.ea.example.cli.product/com.yakindu.bridges.ea.example.cli.product.product
new file mode 100644
index 0000000..d748ae5
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.product/com.yakindu.bridges.ea.example.cli.product.product
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+ -consoleLog
+
+ -Xmx2g
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.target/.gitignore b/CLI/com.yakindu.bridges.ea.example.cli.target/.gitignore
new file mode 100644
index 0000000..c50980d
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.target/.gitignore
@@ -0,0 +1 @@
+/.polyglot.*
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.target/.project b/CLI/com.yakindu.bridges.ea.example.cli.target/.project
new file mode 100644
index 0000000..ea8feb5
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.target/.project
@@ -0,0 +1,17 @@
+
+
+ com.yakindu.bridges.ea.example.cli.target
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextNature
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.target/com.yakindu.bridges.ea.example.cli.target.target b/CLI/com.yakindu.bridges.ea.example.cli.target/com.yakindu.bridges.ea.example.cli.target.target
new file mode 100644
index 0000000..af184ee
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.target/com.yakindu.bridges.ea.example.cli.target.target
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.target/com.yakindu.bridges.ea.example.cli.target.tpd b/CLI/com.yakindu.bridges.ea.example.cli.target/com.yakindu.bridges.ea.example.cli.target.tpd
new file mode 100644
index 0000000..9a19039
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.target/com.yakindu.bridges.ea.example.cli.target.tpd
@@ -0,0 +1,40 @@
+/*
+ * This target definition platform is created with: Target Platform Definition DSL and Generator
+ * It can be installed from: https://download.eclipse.org/cbi/tpd/3.0.0-SNAPSHOT/
+ */
+target "com.yakindu.bridges.ea.example.target" with source requirements
+
+location "https://ftp-stud.hs-esslingen.de/Mirrors/eclipse/justj/jres/11/updates/release" {
+ org.eclipse.justj.openjdk.hotspot.jre.full.feature.group [11.0.13,12.0.0)
+}
+
+// Esslingen mirror is much faster than eclipse.org!
+location eclipse-2021-06 "https://ftp-stud.hs-esslingen.de/Mirrors/eclipse/releases/2022-03/202203161000/" {
+ org.eclipse.emf.feature.group
+ org.eclipse.sdk.ide
+ org.eclipse.uml2.sdk.feature.group
+}
+
+location yakindu-ea_bridge "https://updates.yakindu.com/ea-bridge/updates/" {
+ com.yakindu.bridges.ea.core.feature.group lazy
+ com.yakindu.bridges.ea.core.ui.feature.group lazy
+ com.yakindu.bridges.ea.dev.feature.group lazy
+ com.yakindu.bridges.ea.uml.feature.group lazy
+ com.yakindu.bridges.ea.uml.ui.feature.group lazy
+ com.yakindu.bridges.ea.examples.feature.group lazy
+ com.yakindu.licmgmt.feature.feature.group lazy
+ com.yakindu.licmgmt.ui.feature.feature.group lazy
+ com.sun.jna.feature.feature.group lazy
+ com.yakindu.interop.enterprise.architect.feature.feature.group lazy
+}
+
+location eclipse-orbit "https://download.eclipse.org/tools/orbit/downloads/drops/R20220302172233/repository" {
+ // let's add guava here, all other dependencies are automatically loaded via planner
+ com.google.guava
+ com.google.inject
+ com.google.gson
+}
+
+location equinoxexecutable "https://ftp-stud.hs-esslingen.de/Mirrors/eclipse/eclipse/updates/4.23/" {
+ org.eclipse.equinox.executable.feature.group
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/.classpath b/CLI/com.yakindu.bridges.ea.example.cli.test/.classpath
new file mode 100644
index 0000000..a42a828
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/.gitignore b/CLI/com.yakindu.bridges.ea.example.cli.test/.gitignore
new file mode 100644
index 0000000..3523549
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/.gitignore
@@ -0,0 +1,3 @@
+/bin/
+/target/
+/.polyglot.*
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/.project b/CLI/com.yakindu.bridges.ea.example.cli.test/.project
new file mode 100644
index 0000000..b866ef7
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/.project
@@ -0,0 +1,28 @@
+
+
+ com.yakindu.bridges.ea.example.cli.test
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/ExampleCLI.launch b/CLI/com.yakindu.bridges.ea.example.cli.test/ExampleCLI.launch
new file mode 100644
index 0000000..f1ddf4b
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/ExampleCLI.launch
@@ -0,0 +1,318 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/ExampleCLITest.launch b/CLI/com.yakindu.bridges.ea.example.cli.test/ExampleCLITest.launch
new file mode 100644
index 0000000..599d2d2
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/ExampleCLITest.launch
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/META-INF/MANIFEST.MF b/CLI/com.yakindu.bridges.ea.example.cli.test/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e28f252
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Example validation CLI Tests
+Bundle-SymbolicName: com.yakindu.bridges.ea.example.cli.test
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: itemis AG
+Automatic-Module-Name: com.yakindu.bridges.ea.example.cli.test
+Bundle-RequiredExecutionEnvironment: JavaSE-11
+Require-Bundle: org.junit,
+ org.eclipse.equinox.app,
+ org.eclipse.osgi,
+ org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.emf.common,
+ com.yakindu.bridges.ea.core,
+ com.yakindu.bridges.ea.uml,
+ com.google.inject,
+ org.eclipse.xtext,
+ com.yakindu.bridges.ea.example.cli,
+ com.yakindu.bridges.ea.example.cli.validation,
+ com.google.gson
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/Runtime IDE.launch b/CLI/com.yakindu.bridges.ea.example.cli.test/Runtime IDE.launch
new file mode 100644
index 0000000..d789847
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/Runtime IDE.launch
@@ -0,0 +1,300 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/build.properties b/CLI/com.yakindu.bridges.ea.example.cli.test/build.properties
new file mode 100644
index 0000000..e4688e2
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ testModels/
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/ApplicationTestContext.java b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/ApplicationTestContext.java
new file mode 100644
index 0000000..15b56c3
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/ApplicationTestContext.java
@@ -0,0 +1,64 @@
+package com.yakindu.bridges.ea.example.cli.test;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.osgi.framework.Bundle;
+
+public class ApplicationTestContext implements IApplicationContext {
+
+ private String[] args;
+
+ public ApplicationTestContext(String... args) {
+ this.args = args;
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Map getArguments() {
+ return Collections.singletonMap(IApplicationContext.APPLICATION_ARGS, args);
+ }
+
+ @Override
+ public void applicationRunning() {
+
+ }
+
+ @Override
+ public String getBrandingApplication() {
+ return null;
+ }
+
+ @Override
+ public String getBrandingName() {
+ return null;
+ }
+
+ @Override
+ public String getBrandingDescription() {
+ return null;
+ }
+
+ @Override
+ public String getBrandingId() {
+ return null;
+ }
+
+ @Override
+ public String getBrandingProperty(String key) {
+ return null;
+ }
+
+ @Override
+ public Bundle getBrandingBundle() {
+ return null;
+ }
+
+ @Override
+ public void setResult(Object result, IApplication application) {
+
+ }
+
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/ExampleCLITest.java b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/ExampleCLITest.java
new file mode 100644
index 0000000..43a8ce3
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/ExampleCLITest.java
@@ -0,0 +1,66 @@
+package com.yakindu.bridges.ea.example.cli.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+//import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.equinox.app.IApplication;
+//import org.junit.jupiter.api.Test;
+import org.junit.Test;
+
+import com.yakindu.bridges.ea.core.utils.URIToOSPathConverter;
+import com.yakindu.bridges.ea.example.cli.ExampleCLI;
+
+public class ExampleCLITest {
+
+ String PLUGIN_ID = "com.yakindu.bridges.ea.example.cli.test";
+
+ URI TEST_MODEL = URI.createPlatformPluginURI(PLUGIN_ID + "/testModels/Example.eap", true);
+
+ @Test
+ public void helpOutput() throws Exception {
+ final String output = run(IApplication.EXIT_OK);
+ assertEquals(ExampleCLI.HELP, output);
+
+ }
+
+ private String run(Integer expectedExitCode, String... args) throws Exception {
+ // redirect System output (redirect error output if needed, too)
+ final PrintStream defaultOutStream = System.out;
+ try {
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outputStream));
+
+ final ExampleCLI cli = new ExampleCLI();
+ final Object code = cli.start(new ApplicationTestContext(args));
+ assertEquals(expectedExitCode, code);
+ return outputStream.toString().trim();
+ } finally {
+ System.setOut(defaultOutStream);
+ }
+ }
+
+ @Test
+ public void noValidationIssueInRefModel() throws Exception {
+ // given
+ final String eapFile = URIToOSPathConverter.getFileFromURI(TEST_MODEL);
+ final File tmpFile = File.createTempFile(getClass().getName(), ".json");
+ tmpFile.deleteOnExit();
+ final String elementToValidate = "LibraryModel";
+ final String[] args = { ExampleCLI.APP_VALIDATE, eapFile, tmpFile.getAbsolutePath(), elementToValidate,
+ ExampleCLI.VERBOSE_OUTPUT };
+ // when
+ final String output = run(IApplication.EXIT_OK, args);
+ // then
+ for (String segment : List.of(">> Collecting UML Elements DONE.", ">> Validating DONE.", ">> Writing report")) {
+ assertTrue("Missing in console output: \"" + segment + "\"\n\n" + output, output.contains(segment));
+ }
+ }
+}
\ No newline at end of file
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/ModelValidationTest.java b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/ModelValidationTest.java
new file mode 100644
index 0000000..8643201
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/ModelValidationTest.java
@@ -0,0 +1,115 @@
+package com.yakindu.bridges.ea.example.cli.test.validation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.junit.Test;
+
+import com.yakindu.bridges.ea.example.cli.validation.ModelValidation;
+import com.yakindu.bridges.ea.example.cli.validation.ValidationResult;
+
+public class ModelValidationTest {
+
+ @Test
+ public void missingReportFileArgument() {
+ // given
+ final Resource resource = new ResourceSetImpl().createResource(URI.createURI("mem:/test.uml"));
+ try {
+ // when
+ new ModelValidation(resource, Collections.emptyList(), " ");
+ fail("exception expected about missing report file argument");
+ } catch (Exception e) {
+ // then
+ assertTrue("CLI exception expected", e instanceof Exception);
+ assertEquals("exception expected about missing report file argument", "Report file argument missing",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void validationForSingleElementInModel() throws FileNotFoundException, IOException {
+ final Model model = (Model) EcoreUtil.create((EClass) UMLPackage.eINSTANCE.getEClassifier("Model"));
+ final URI uri = URI.createURI("mem:/test.uml", true);
+ final Resource resource = new ResourceSetImpl().createResource(uri);
+ resource.getContents().add(model);
+
+ Package pack = model.createNestedPackage("pack");
+
+ final Class abstractClass = pack.createOwnedClass("someClass", false);
+ abstractClass.setIsAbstract(true);
+
+ final Class childClass = pack.createOwnedClass("childClass", false);
+ final Class anotherChildClass = pack.createOwnedClass("anotherChildClass", false);
+
+ // create inheritance connectors
+ childClass.createGeneralization(abstractClass);
+ anotherChildClass.createGeneralization(abstractClass);
+
+ // when
+
+ ModelValidation validation = new ModelValidation(resource, Arrays.asList(abstractClass),
+ File.createTempFile(getClass().getName(), ".json").getAbsolutePath());
+
+ validation.validate();
+ ValidationResult validationResult = validation.getValidationResult();
+
+ // then
+
+ assertEquals("Unexpected number of warnings reported", 1, validationResult.getCustomWarnings().size());
+ assertEquals("Unexpected number of errors reported", 0, validationResult.getCustomErrors().size());
+ List warning = validationResult.getCustomWarnings().get(abstractClass);
+
+ // validation for the other two classes in this package should report report the same warning
+ // because the validator will validate all elements in the nearest package.
+
+ // when
+
+ validation = new ModelValidation(resource, Arrays.asList(childClass, anotherChildClass),
+ File.createTempFile(getClass().getName(), ".json").getAbsolutePath());
+ validation.validate();
+ validationResult = validation.getValidationResult();
+
+ // then
+
+ assertEquals("Unexpected number of warnings reported", 1, validationResult.getCustomWarnings().size());
+ assertEquals("Unexpected number of errors reported", 0, validationResult.getCustomErrors().size());
+ assertNotNull("warning is not reported to the correct model element",
+ validationResult.getCustomWarnings().get(abstractClass));
+ assertEquals(validationResult.getCustomWarnings().get(abstractClass), warning);
+
+ // validation of a different package should not include issues found in the package `context`
+ // when
+
+ Package pack2 = model.createNestedPackage("pack2");
+ pack2.createOwnedClass("someClass", false);
+ validation = new ModelValidation(resource, Arrays.asList(pack2),
+ File.createTempFile(getClass().getName(), ".json").getAbsolutePath());
+ validation.validate();
+ validationResult = validation.getValidationResult();
+
+ // then
+
+ assertEquals("Unexpected number of warnings reported", 0, validationResult.getCustomWarnings().size());
+ assertEquals("Unexpected number of errors reported", 0, validationResult.getCustomErrors().size());
+
+ }
+
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/RuleAbstractClassPrefixTest.java b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/RuleAbstractClassPrefixTest.java
new file mode 100644
index 0000000..9d6e6e1
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/RuleAbstractClassPrefixTest.java
@@ -0,0 +1,59 @@
+package com.yakindu.bridges.ea.example.cli.test.validation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.junit.Test;
+
+import com.yakindu.bridges.ea.example.cli.validation.custom.RuleAbstractClassPrefix;
+
+public class RuleAbstractClassPrefixTest {
+
+ @Test
+ public void reportAbstractClassesWithoutPrefix() {
+ // given
+ final Model model = (Model) EcoreUtil.create((EClass) UMLPackage.eINSTANCE.getEClassifier("Model"));
+ final URI uri = URI.createURI("mem:/test.uml", true);
+ final Resource resource = new ResourceSetImpl().createResource(uri);
+ resource.getContents().add(model);
+
+ Package context = model.createNestedPackage("pack");
+
+ final Class abstractClass = context.createOwnedClass("someClass", false);
+ abstractClass.setIsAbstract(true);
+
+ final Class childClass = context.createOwnedClass("childClass", false);
+ final Class anotherChildClass = context.createOwnedClass("anotherChildClass", false);
+
+ // create inheritance connectors
+ childClass.createGeneralization(abstractClass);
+ anotherChildClass.createGeneralization(abstractClass);
+
+ // when
+ final List errors = new ArrayList<>();
+ final List warnings = new ArrayList<>();
+ new RuleAbstractClassPrefix().validate(abstractClass, errors::add, warnings::add);
+
+ // then
+ assertEquals("Unexpected number of errors reported: ", 0, errors.size());
+ assertEquals("Unexpected warnings reported", 1, warnings.size());
+
+ final String warning = warnings.get(0);
+ assertTrue("Unexpected validation error: " + warning,
+ warning.startsWith("Abstract class 'someClass' should start with 'Abstract'."));
+
+ }
+
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/UMLValidationTest.java b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/UMLValidationTest.java
new file mode 100644
index 0000000..679754e
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/UMLValidationTest.java
@@ -0,0 +1,58 @@
+package com.yakindu.bridges.ea.example.cli.test.validation;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.junit.Test;
+
+import com.yakindu.bridges.ea.example.cli.validation.ValidationResult;
+import com.yakindu.bridges.ea.example.cli.validation.report.ValidationReport;
+import com.yakindu.bridges.ea.example.cli.validation.uml.UMLValidation;
+
+public class UMLValidationTest {
+
+ @Test
+ public void validationWithoutErrors() {
+ // given: simple UML model without errors
+ final Model model = (Model) EcoreUtil.create((EClass) UMLPackage.eINSTANCE.getEClassifier("Model"));
+ final Package pack = model.createNestedPackage("pack");
+ pack.createPackagedElement("someClass", UMLPackage.Literals.CLASS);
+ final URI uri = URI.createURI("mem:/test.uml");
+ final Resource resource = new ResourceSetImpl().createResource(uri);
+ resource.getContents().add(model);
+ // when
+ final ValidationResult result = new ValidationResult(resource);
+ UMLValidation.validate(resource, result);
+ // then
+ assertEquals("unexpected validation results: " + result, 0, result.count());
+ }
+
+ @Test
+ public void validateWithUmlErrorsAndWarnings() {
+ // given: simple model with two identical classes in the same package
+ final Model model = (Model) EcoreUtil.create((EClass) UMLPackage.eINSTANCE.getEClassifier("Model"));
+ final Package pack = model.createNestedPackage("pack");
+ pack.createPackagedElement("duplicateClass", UMLPackage.Literals.CLASS);
+ pack.createPackagedElement("duplicateClass", UMLPackage.Literals.CLASS);
+
+ final URI uri = URI.createURI("mem:/test.uml");
+ final Resource resource = new ResourceSetImpl().createResource(uri);
+ resource.getContents().add(model);
+ // when
+ final ValidationResult result = new ValidationResult(resource);
+ UMLValidation.validate(resource, result);
+ ValidationReport report = new ValidationReport(result);
+ System.out.println(report.create());
+ // then
+ assertEquals("unexpected validation results: " + result, 4,
+ result.getUmlErrors().size() + result.getUmlWarnings().size());
+ }
+
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/ValidationReportTest.java b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/ValidationReportTest.java
new file mode 100644
index 0000000..1f28a13
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.test/src/com/yakindu/bridges/ea/example/cli/test/validation/ValidationReportTest.java
@@ -0,0 +1,84 @@
+package com.yakindu.bridges.ea.example.cli.test.validation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.yakindu.bridges.ea.example.cli.validation.ModelValidation;
+import com.yakindu.bridges.ea.example.cli.validation.ValidationResult;
+import com.yakindu.bridges.ea.example.cli.validation.report.ValidationReport;
+import com.yakindu.bridges.ea.example.cli.validation.report.ValidationResultsJsonContainer;
+
+public class ValidationReportTest {
+
+ @Test
+ public void emptyReport() {
+ // given
+ final Resource resource = new ResourceSetImpl().createResource(URI.createURI("mem:/test.uml"));
+ final ValidationResult result = new ValidationResult(resource);
+ // when
+ final String report = new ValidationReport(result).create();
+ // then
+ assertEquals("unexpected empty report",
+ "{\"resourceIssues\":[],\"loadIssues\":[],\"umlIssues\":[],\"customIssues\":[]}", report);
+
+ }
+
+ @Test
+ public void jsonReportShouldBeValid() throws FileNotFoundException, IOException {
+ final Model model = (Model) EcoreUtil.create((EClass) UMLPackage.eINSTANCE.getEClassifier("Model"));
+ final URI uri = URI.createURI("mem:/test.uml", true);
+ final Resource resource = new ResourceSetImpl().createResource(uri);
+ resource.getContents().add(model);
+
+ Package pack = model.createNestedPackage("pack");
+
+ final Class abstractClass = pack.createOwnedClass("someClass", false);
+ abstractClass.setIsAbstract(true);
+
+ final Class childClass = pack.createOwnedClass("childClass", false);
+ final Class anotherChildClass = pack.createOwnedClass("anotherChildClass", false);
+
+ final Package pack2 = model.createNestedPackage("pack2");
+ pack2.createOwnedClass("someClass", false);
+
+ // create inheritance connectors
+ childClass.createGeneralization(abstractClass);
+ anotherChildClass.createGeneralization(abstractClass);
+
+ // when
+ ModelValidation validation = new ModelValidation(resource, Arrays.asList(abstractClass),
+ File.createTempFile(getClass().getName(), ".json").getAbsolutePath());
+
+ validation.validate();
+ ValidationResult validationResult = validation.getValidationResult();
+
+ validation = new ModelValidation(resource, Arrays.asList(pack2),
+ File.createTempFile(getClass().getName(), ".json").getAbsolutePath());
+ validation.validate();
+ validationResult = validation.getValidationResult();
+ String report = new ValidationReport(validationResult).create();
+
+ Gson jsonHandler = new Gson();
+ ValidationResultsJsonContainer deserializedJson = jsonHandler.fromJson(report,
+ ValidationResultsJsonContainer.class);
+ assertNotNull("json validation result is not written correctly", deserializedJson);
+ assertEquals(validationResult.count(), deserializedJson.count());
+ }
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.test/testModels/Example.eap b/CLI/com.yakindu.bridges.ea.example.cli.test/testModels/Example.eap
new file mode 100644
index 0000000..232bb5d
Binary files /dev/null and b/CLI/com.yakindu.bridges.ea.example.cli.test/testModels/Example.eap differ
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/.classpath b/CLI/com.yakindu.bridges.ea.example.cli.validation/.classpath
new file mode 100644
index 0000000..e801ebf
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/.gitignore b/CLI/com.yakindu.bridges.ea.example.cli.validation/.gitignore
new file mode 100644
index 0000000..3523549
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/.gitignore
@@ -0,0 +1,3 @@
+/bin/
+/target/
+/.polyglot.*
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/.project b/CLI/com.yakindu.bridges.ea.example.cli.validation/.project
new file mode 100644
index 0000000..bbaf2fd
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/.project
@@ -0,0 +1,28 @@
+
+
+ com.yakindu.bridges.ea.example.cli.validation
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/META-INF/MANIFEST.MF b/CLI/com.yakindu.bridges.ea.example.cli.validation/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..49909df
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Example CLI Validation
+Bundle-SymbolicName: com.yakindu.bridges.ea.example.cli.validation
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: itemis AG
+Automatic-Module-Name: com.yakindu.bridges.ea.example.validation
+Bundle-RequiredExecutionEnvironment: JavaSE-11
+Export-Package: com.yakindu.bridges.ea.example.cli.validation,
+ com.yakindu.bridges.ea.example.cli.validation.custom,
+ com.yakindu.bridges.ea.example.cli.validation.report,
+ com.yakindu.bridges.ea.example.cli.validation.uml
+Require-Bundle: org.eclipse.emf.ecore,
+ org.eclipse.uml2.uml,
+ com.yakindu.bridges.ea.core,
+ com.google.gson
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/build.properties b/CLI/com.yakindu.bridges.ea.example.cli.validation/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/ModelValidation.java b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/ModelValidation.java
new file mode 100644
index 0000000..b0f5bca
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/ModelValidation.java
@@ -0,0 +1,84 @@
+package com.yakindu.bridges.ea.example.cli.validation;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.uml2.uml.Element;
+
+import com.yakindu.bridges.ea.example.cli.validation.custom.CustomValidation;
+import com.yakindu.bridges.ea.example.cli.validation.report.ValidationReport;
+import com.yakindu.bridges.ea.example.cli.validation.uml.UMLValidation;
+
+public class ModelValidation {
+
+ private final Resource resource;
+ private final List elements;
+ private final String reportFile;
+
+ private ValidationResult result;
+
+ public ModelValidation(Resource resource, List elements, String reportFile) throws FileNotFoundException {
+ this.resource = resource;
+ if (elements == null) {
+ this.elements = new ArrayList<>();
+ } else {
+ this.elements = elements;
+ }
+ this.reportFile = reportFile;
+
+ if (resource == null)
+ throw new IllegalArgumentException("Resource argument must not be null");
+
+ if (reportFile == null || reportFile.isBlank())
+ throw new IllegalArgumentException("Report file argument missing");
+
+ final File file = new File(reportFile);
+ if (file.exists() && !file.delete())
+ throw new FileNotFoundException("Failed to delete existing report file: " + file.getAbsolutePath());
+ }
+
+ public List validate() {
+
+ // this already collects all load issues
+ result = new ValidationResult(resource);
+
+ // add uml issues
+ UMLValidation.validate(resource, result);
+
+ // add custom issues
+ new CustomValidation(resource, elements).validate(result);
+
+ return result.asList();
+ }
+
+ public void createReport() {
+ if (result == null)
+ throw new IllegalStateException("Please call 'validate()' first");
+
+ final String content = new ValidationReport(result).create();
+
+ try (FileOutputStream outputStream = new FileOutputStream(reportFile)) {
+ try (final Writer bw = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))) {
+ bw.write(content);
+ }
+ } catch (final IOException e) {
+ throw new RuntimeException("Failed to create report", e);
+ }
+ }
+
+ public ValidationResult getValidationResult() {
+ if (result == null)
+ throw new IllegalStateException("Please call 'validate()' first");
+ return this.result;
+ }
+
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/ValidationResult.java b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/ValidationResult.java
new file mode 100644
index 0000000..7e89c0d
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/ValidationResult.java
@@ -0,0 +1,142 @@
+package com.yakindu.bridges.ea.example.cli.validation;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
+import org.eclipse.uml2.uml.util.UMLUtil;
+
+import com.yakindu.bridges.ea.core.EAModelError;
+import com.yakindu.bridges.ea.core.utils.MapUtils;
+
+public class ValidationResult {
+
+ private static final int DEFAULT_LIST_SIZE = 4;
+
+ private final List resourceWarnings = new ArrayList<>();
+ private final List resourceErrors = new ArrayList<>();
+
+ private final Map> loadWarnings = new HashMap<>();
+ private final Map> loadErrors = new HashMap<>();
+
+ private final Map> umlWarnings = new HashMap<>();
+ private final Map> umlErrors = new HashMap<>();
+
+ private final Map> customWarnings = new HashMap<>();
+ private final Map> customErrors = new HashMap<>();
+
+ public ValidationResult(Resource resource) {
+ resource.getErrors().forEach(error -> addIssue(loadErrors, error));
+ resource.getWarnings().forEach(warning -> addIssue(loadWarnings, warning));
+ }
+
+ private void addIssue(Map> issues, Diagnostic issue) {
+ if (issue instanceof EAModelError) {
+ final EObject element = ((EAModelError) issue).getContextElement();
+ if (element == null) {
+ if (((EAModelError) issue).getSeverity() == IStatus.ERROR) {
+ resourceErrors.add(issue.getMessage());
+ } else if (((EAModelError) issue).getSeverity() == IStatus.WARNING) {
+ resourceWarnings.add(issue.getMessage());
+ }
+ } else {
+ if (((EAModelError) issue).getSeverity() == IStatus.ERROR) {
+ MapUtils.addToListMap(loadErrors, element, DEFAULT_LIST_SIZE, issue.getMessage());
+ } else if (((EAModelError) issue).getSeverity() == IStatus.WARNING) {
+ MapUtils.addToListMap(loadWarnings, element, DEFAULT_LIST_SIZE, issue.getMessage());
+ }
+ }
+ } else {
+ final String msg = String.format("%s while loading '%s' (line %d, column %d): %s", //
+ issue.getClass().getSimpleName(), issue.getLocation(), issue.getLine(), issue.getColumn(),
+ issue.getMessage());
+ resourceErrors.add(msg);
+ }
+ }
+
+ public void addUmlError(EObject object, String message) {
+ MapUtils.addToListMap(umlErrors, object, DEFAULT_LIST_SIZE, message);
+ }
+
+ public void addUmlWarning(EObject object, String message) {
+ MapUtils.addToListMap(umlWarnings, object, DEFAULT_LIST_SIZE, message);
+ }
+
+ public void addCustomError(EObject object, String message) {
+ MapUtils.addToListMap(customErrors, object, DEFAULT_LIST_SIZE, message);
+ }
+
+ public void addCustomWarning(EObject object, String message) {
+ MapUtils.addToListMap(customWarnings, object, DEFAULT_LIST_SIZE, message);
+ }
+
+ public int count() {
+ return resourceWarnings.size() + resourceErrors.size() //
+ + loadWarnings.size() + loadErrors.size() //
+ + umlWarnings.size() + umlErrors.size() //
+ + customWarnings.size() + customErrors.size();
+ }
+
+ public List asList() {
+ final List list = new ArrayList<>(count());
+ resourceWarnings.forEach(issue -> list.add("[W:Resource] " + issue));
+ resourceErrors.forEach(issue -> list.add("[E:Resource] " + issue));
+ loadWarnings.entrySet().forEach(issues -> list.addAll(asString("[W:Load]", issues)));
+ loadErrors.entrySet().forEach(issues -> list.addAll(asString("[E:Load]", issues)));
+ umlWarnings.entrySet().forEach(issues -> list.addAll(asString("[W:UML]", issues)));
+ umlErrors.entrySet().forEach(issues -> list.addAll(asString("[E:UML]", issues)));
+ customWarnings.entrySet().forEach(issues -> list.addAll(asString("[W:Custom]", issues)));
+ customErrors.entrySet().forEach(issues -> list.addAll(asString("[E:Custom]", issues)));
+ Collections.sort(list);
+ return list;
+ }
+
+ private List asString(String prefix, Entry> issues) {
+ if (issues == null || issues.getValue().isEmpty())
+ return Collections.emptyList();
+ final List result = new ArrayList<>(issues.getValue().size());
+ final String objName = UMLUtil.getQualifiedText(issues.getKey());
+ issues.getValue().forEach(issue -> result.add(String.format("%s '%s': %s", prefix, objName, issue)));
+ return result;
+ }
+
+ public List getResourceWarnings() {
+ return Collections.unmodifiableList(resourceWarnings);
+ }
+
+ public List getResourceErrors() {
+ return Collections.unmodifiableList(resourceErrors);
+ }
+
+ public Map> getLoadWarnings() {
+ return Collections.unmodifiableMap(loadWarnings);
+ }
+
+ public Map> getLoadErrors() {
+ return Collections.unmodifiableMap(loadErrors);
+ }
+
+ public Map> getUmlWarnings() {
+ return Collections.unmodifiableMap(umlWarnings);
+ }
+
+ public Map> getUmlErrors() {
+ return Collections.unmodifiableMap(umlErrors);
+ }
+
+ public Map> getCustomWarnings() {
+ return Collections.unmodifiableMap(customWarnings);
+ }
+
+ public Map> getCustomErrors() {
+ return Collections.unmodifiableMap(customErrors);
+ }
+
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/custom/AbstractValidationRule.java b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/custom/AbstractValidationRule.java
new file mode 100644
index 0000000..8a8093b
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/custom/AbstractValidationRule.java
@@ -0,0 +1,31 @@
+package com.yakindu.bridges.ea.example.cli.validation.custom;
+
+import java.util.function.Consumer;
+
+import org.eclipse.uml2.uml.Element;
+
+import com.yakindu.bridges.ea.example.cli.validation.ValidationResult;
+
+public abstract class AbstractValidationRule {
+
+ public final Class applicableTo;
+
+ protected AbstractValidationRule(Class applicableTo) {
+ this.applicableTo = applicableTo;
+ }
+
+ protected void validate(Element obj, ValidationResult result) {
+ if (obj == null || !applicableTo.isInstance(obj))
+ throw new IllegalArgumentException("Parameter has unexpected type: " + obj);
+ try {
+ validate(applicableTo.cast(obj), //
+ e -> result.addCustomError(obj, e), //
+ w -> result.addCustomWarning(obj, w));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected abstract void validate(T obj, Consumer addError, Consumer addWarning);
+
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/custom/CustomValidation.java b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/custom/CustomValidation.java
new file mode 100644
index 0000000..7298b7e
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/custom/CustomValidation.java
@@ -0,0 +1,65 @@
+package com.yakindu.bridges.ea.example.cli.validation.custom;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Package;
+
+import com.yakindu.bridges.ea.core.utils.MapUtils;
+import com.yakindu.bridges.ea.example.cli.validation.ValidationResult;
+
+public class CustomValidation {
+ private static List> VALIDATION_RULES = Arrays.asList(
+ // custom validation rules can be enabled here
+ new RuleAbstractClassPrefix());
+
+ private final Resource resource;
+ private final List elements;
+ private final Map, List>> rules;
+
+ public CustomValidation(Resource resource, List elementsToValidate) {
+ if (resource == null)
+ throw new IllegalArgumentException("Resource must not be null");
+ this.resource = resource;
+ this.elements = elementsToValidate;
+ rules = initRules();
+ }
+
+ private Map, List>> initRules() {
+ final Map, List>> retval = new HashMap<>(
+ VALIDATION_RULES.size());
+ VALIDATION_RULES.forEach(rule -> MapUtils.addToListMap(retval, rule.applicableTo, rule));
+ return Collections.unmodifiableMap(retval);
+ }
+
+ public void validate(ValidationResult result) {
+ if (elements == null || elements.isEmpty()) {
+ resource.getContents().stream() //
+ .filter(Package.class::isInstance).map(Package.class::cast) //
+ .forEach(pack -> doValidate(pack, result));
+ } else {
+ elements.stream().map(Element::getNearestPackage).distinct() //
+ .forEach(pack -> doValidate(pack, result));
+ }
+ }
+
+ public void doValidate(Package pack, ValidationResult result) {
+ for (TreeIterator iter = pack.eAllContents(); iter.hasNext();) {
+ final EObject obj = iter.next();
+
+ for (Entry, List>> classWithRule : rules.entrySet()) {
+ if (classWithRule.getKey().isInstance(obj)) {
+ classWithRule.getValue().forEach(rule -> rule.validate((Element) obj, result));
+ }
+ }
+ }
+ }
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/custom/RuleAbstractClassPrefix.java b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/custom/RuleAbstractClassPrefix.java
new file mode 100644
index 0000000..bf60aa6
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/custom/RuleAbstractClassPrefix.java
@@ -0,0 +1,27 @@
+package com.yakindu.bridges.ea.example.cli.validation.custom;
+
+import java.util.function.Consumer;
+
+import org.eclipse.uml2.uml.Class;
+
+public class RuleAbstractClassPrefix extends AbstractValidationRule {
+
+ private static final String AbstractPrefix = "Abstract";
+
+ public RuleAbstractClassPrefix() {
+ super(Class.class);
+ }
+
+ @Override
+ public void validate(Class obj, Consumer addError, Consumer addWarning) {
+ if (isAbstractClassWithoutPrefix(obj)) {
+ addWarning.accept(
+ String.format("Abstract class '%s' should start with '%s'.", obj.getName(), AbstractPrefix));
+ }
+ }
+
+ private boolean isAbstractClassWithoutPrefix(Class element) {
+ return element instanceof Class && element.isAbstract() && !element.getName().startsWith(AbstractPrefix);
+ }
+
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/report/ValidationIssueJsonContainer.java b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/report/ValidationIssueJsonContainer.java
new file mode 100644
index 0000000..cce9dbc
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/report/ValidationIssueJsonContainer.java
@@ -0,0 +1,34 @@
+package com.yakindu.bridges.ea.example.cli.validation.report;
+
+public class ValidationIssueJsonContainer {
+
+ private final String severity;
+ private final String type;
+ private final String id;
+ private final String msg;
+
+ public ValidationIssueJsonContainer(String severity, String type, String id, String msg) {
+ super();
+ this.severity = severity;
+ this.type = type;
+ this.id = id;
+ this.msg = msg;
+ }
+
+ public String getSeverity() {
+ return severity;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/report/ValidationReport.java b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/report/ValidationReport.java
new file mode 100644
index 0000000..e9f5876
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/report/ValidationReport.java
@@ -0,0 +1,115 @@
+package com.yakindu.bridges.ea.example.cli.validation.report;
+
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.resource.UMLResource;
+
+import com.google.gson.Gson;
+import com.yakindu.bridges.ea.core.EAResource;
+import com.yakindu.bridges.ea.core.utils.EAResourceUtils;
+import com.yakindu.bridges.ea.example.cli.validation.ValidationResult;
+
+public class ValidationReport {
+
+ private final ValidationResult result;
+ private final StringBuilder output;
+
+ public ValidationReport(ValidationResult result) {
+ this.result = result;
+ this.output = new StringBuilder();
+ }
+
+ public String create() {
+ if (output.length() == 0) {
+ List customIssues = createValidationIssuesForElement(result.getCustomErrors(),
+ result.getCustomWarnings());
+
+ List loadIssues = createValidationIssuesForElement(result.getLoadErrors(),
+ result.getLoadWarnings());
+
+ List umlErrors = createValidationIssuesForElement(result.getUmlErrors(),
+ result.getUmlWarnings());
+
+ List resourceIssues = appendResourceIssues();
+
+ ValidationResultsJsonContainer serializableResult = new ValidationResultsJsonContainer(resourceIssues,
+ loadIssues, umlErrors, customIssues);
+
+ // create Json serializer
+ Gson jsonHandler = new Gson();
+ output.append(jsonHandler.toJson(serializableResult));
+
+ }
+ return output.toString();
+ }
+
+ private List createValidationIssuesForElement(Map> errors,
+ Map> warnings) {
+ List retVal = new ArrayList<>();
+
+ for (Entry> elementEntry : errors.entrySet()) {
+ final Entry ids = getIds(elementEntry.getKey());
+
+ for (String error : elementEntry.getValue()) {
+ String type = ids.getKey() != null ? ids.getKey() : "";
+ String id = ids.getValue() != null ? ids.getValue() : "";
+ retVal.add(new ValidationIssueJsonContainer("E", type, id, error));
+ }
+ }
+
+ for (Entry> elementEntry : warnings.entrySet()) {
+ final Entry ids = getIds(elementEntry.getKey());
+ for (String error : elementEntry.getValue()) {
+ String type = ids.getKey() != null ? ids.getKey() : "";
+ String id = ids.getValue() != null ? ids.getValue() : "";
+ retVal.add(new ValidationIssueJsonContainer("W", type, id, error));
+ }
+ }
+
+ return retVal;
+ }
+
+ private List appendResourceIssues() {
+ List retVal = new ArrayList<>();
+
+ for (String error : result.getResourceErrors()) {
+ retVal.add(new ValidationIssueJsonContainer("E", "", "", error));
+ }
+ for (String warning : result.getResourceWarnings()) {
+ retVal.add(new ValidationIssueJsonContainer("W", "", "", warning));
+ }
+
+ return retVal;
+ }
+
+ private Entry getIds(EObject element) {
+ if (element == null)
+ return null;
+ if (element.eResource() instanceof EAResource) {
+ final String objectType = EAResourceUtils.getObjectTypeForElement(element);
+ if (objectType != null) {
+ final Integer id = EAResourceUtils.getIdForElement(element);
+ final String idStr = id == null ? EAResourceUtils.getGuidForElement(element) : String.valueOf(id);
+ if (idStr != null) {
+ return new SimpleImmutableEntry<>(objectType, idStr);
+ }
+ }
+ return getIds(element.eContainer());
+ }
+ if (element instanceof UMLResource || element instanceof Model || element instanceof Class
+ || element instanceof Package) {
+ final String clazz = element.eClass().getName();
+ final String fragment = element.eResource().getURIFragment(element);
+ return new SimpleImmutableEntry<>(clazz, fragment);
+ }
+ throw new IllegalArgumentException("Unexpected element: " + element);
+ }
+}
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/report/ValidationResultsJsonContainer.java b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/report/ValidationResultsJsonContainer.java
new file mode 100644
index 0000000..985c7d1
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/report/ValidationResultsJsonContainer.java
@@ -0,0 +1,42 @@
+package com.yakindu.bridges.ea.example.cli.validation.report;
+
+import java.util.List;
+
+public class ValidationResultsJsonContainer {
+
+ private final List resourceIssues;
+ private final List loadIssues;
+ private final List umlIssues;
+ private final List customIssues;
+
+ public ValidationResultsJsonContainer(List resourceIssues,
+ List loadIssues, List umlIssues,
+ List customIssues) {
+ super();
+ this.resourceIssues = resourceIssues;
+ this.loadIssues = loadIssues;
+ this.umlIssues = umlIssues;
+ this.customIssues = customIssues;
+ }
+
+ public List getResourceIssues() {
+ return resourceIssues;
+ }
+
+ public List getLoadIssues() {
+ return loadIssues;
+ }
+
+ public List getUmlIssues() {
+ return umlIssues;
+ }
+
+ public List getCustomIssues() {
+ return customIssues;
+ }
+
+ public int count() {
+ return resourceIssues.size() + loadIssues.size() + umlIssues.size() + customIssues.size();
+ }
+
+}
\ No newline at end of file
diff --git a/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/uml/UMLDiagnostician.java b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/uml/UMLDiagnostician.java
new file mode 100644
index 0000000..5ec2996
--- /dev/null
+++ b/CLI/com.yakindu.bridges.ea.example.cli.validation/src/com/yakindu/bridges/ea/example/cli/validation/uml/UMLDiagnostician.java
@@ -0,0 +1,86 @@
+package com.yakindu.bridges.ea.example.cli.validation.uml;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.DiagnosticChain;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.Diagnostician;
+import org.eclipse.uml2.uml.Element;
+
+/**
+ * Copy from inner class of UMLActionBarContributor.
+ */
+public class UMLDiagnostician extends Diagnostician {
+
+ private static final String PLUGIN_ID = "com.yakindu.bridges.ea.example.validation";
+
+ public final static UMLDiagnostician INSTANCE = new UMLDiagnostician();
+
+ public Diagnostic validate(Resource resource) {
+ final List diagnostics = new ArrayList<>();
+
+ final Map