diff --git a/Doxyfile b/Doxyfile index bff5c6d8..1d9d8dd8 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "SuiteCRM Outlook Add-in" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 3.0.17.0 +PROJECT_NUMBER = 3.0.18.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/README.md b/README.md index 07c611e9..96afd88a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ### What's in this repository -SuiteCRM Outlook Plug-In v 3.0.17.0 +SuiteCRM Outlook Plug-In v 3.0.18.0 This repository has been created to allow community members to collaborate and contribute to the project. diff --git a/SuiteCRMAddIn/BusinessLogic/AppointmentSyncState.cs b/SuiteCRMAddIn/BusinessLogic/AppointmentSyncState.cs index 7c871cf0..1d39a931 100644 --- a/SuiteCRMAddIn/BusinessLogic/AppointmentSyncState.cs +++ b/SuiteCRMAddIn/BusinessLogic/AppointmentSyncState.cs @@ -37,7 +37,6 @@ public abstract class AppointmentSyncState: SyncState { public AppointmentSyncState(Outlook.AppointmentItem item, CrmId crmId, DateTime modifiedDate) : base(item, crmId, modifiedDate) { - this.outlookItemId = item.EntryID; } /// @@ -47,13 +46,7 @@ public AppointmentSyncState(Outlook.AppointmentItem item, CrmId crmId, DateTime private string crmType; - public override Outlook.OlDefaultFolders DefaultFolder - { - get - { - return Outlook.OlDefaultFolders.olFolderCalendar; - } - } + public override Outlook.Folder DefaultFolder => (Outlook.Folder)MapiNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar); /// @@ -125,5 +118,25 @@ internal override void SaveItem() { this.OutlookItem?.Save(); } + + protected override bool VerifyItem() + { + bool result; + try + { + result = !string.IsNullOrEmpty(this.Item?.EntryID); + } + catch (Exception ex) when (ex is InvalidComObjectException || ex is COMException) + { + result = false; + } + + return result; + } + + protected override void CacheOulookItemId(Outlook.AppointmentItem olItem) + { + this.outlookItemId = olItem.EntryID; + } } } diff --git a/SuiteCRMAddIn/BusinessLogic/AppointmentsSynchroniser.cs b/SuiteCRMAddIn/BusinessLogic/AppointmentsSynchroniser.cs index 973b55e2..3be2946b 100644 --- a/SuiteCRMAddIn/BusinessLogic/AppointmentsSynchroniser.cs +++ b/SuiteCRMAddIn/BusinessLogic/AppointmentsSynchroniser.cs @@ -189,7 +189,7 @@ protected override void SaveItem(AppointmentItem olItem) { try { - olItem.Save(); + olItem?.Save(); try { LogItemAction(olItem, "AppointmentSyncing.SaveItem, saved item"); @@ -900,6 +900,8 @@ protected override void SyncFolder(MAPIFolder folder, string crmModule) AddOrUpdateItemsFromCrmToOutlook(records, folder, untouched, crmModule); + /* You can add invitees to Appointments in Outlook, so this is not just for + * Meetings. */ var invited = RestAPIWrapper.GetRelationships("Users", RestAPIWrapper.GetUserId(), crmModule.ToLower(), RestAPIWrapper.GetSugarFields(crmModule)); diff --git a/SuiteCRMAddIn/BusinessLogic/ContactSyncState.cs b/SuiteCRMAddIn/BusinessLogic/ContactSyncState.cs index e7fa5344..2d0f129c 100644 --- a/SuiteCRMAddIn/BusinessLogic/ContactSyncState.cs +++ b/SuiteCRMAddIn/BusinessLogic/ContactSyncState.cs @@ -20,6 +20,10 @@ * * @author SalesAgility */ + +using System.Threading; +using SuiteCRMAddIn.Exceptions; + namespace SuiteCRMAddIn.BusinessLogic { using System; @@ -36,18 +40,41 @@ namespace SuiteCRMAddIn.BusinessLogic /// public class ContactSyncState: SyncState { + private ILogger Log = Globals.ThisAddIn.Log; public ContactSyncState(Outlook.ContactItem oItem, CrmId crmId, DateTime modified) : base(oItem, crmId, modified) { } - public override Outlook.OlDefaultFolders DefaultFolder + public override Outlook.Folder DefaultFolder => (Outlook.Folder)MapiNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts); + + protected override bool VerifyItem() { - get + bool result; + try { - return Outlook.OlDefaultFolders.olFolderContacts; + result = !string.IsNullOrEmpty(this.Item?.EntryID); } + catch (Exception ex) when (ex is InvalidComObjectException || ex is COMException) + { + result = false; + } + + return result; } + /// + /// If transmission was successful, clear the manual override if set. + /// + internal override void SetTransmitted() + { + base.SetTransmitted(); + this.OutlookItem.ClearManualOverride(); + } + + /// + /// True if the Outlook item wrapped by this state may be synchronised even when synchronisation is set to none. + /// + public override bool IsManualOverride => this.OutlookItem.IsManualOverride(); public override string CrmType => ContactSynchroniser.CrmModule; @@ -119,5 +146,10 @@ internal override void SaveItem() { this.OutlookItem?.Save(); } + + protected override void CacheOulookItemId(Outlook.ContactItem olItem) + { + this.outlookItemId = olItem.EntryID; + } } } diff --git a/SuiteCRMAddIn/BusinessLogic/ContactSynchroniser.cs b/SuiteCRMAddIn/BusinessLogic/ContactSynchroniser.cs index 331f897a..28442c84 100644 --- a/SuiteCRMAddIn/BusinessLogic/ContactSynchroniser.cs +++ b/SuiteCRMAddIn/BusinessLogic/ContactSynchroniser.cs @@ -65,7 +65,7 @@ protected override void SaveItem(Outlook.ContactItem olItem) { try { - olItem.Save(); + olItem?.Save(); } catch (System.Exception any) { @@ -73,6 +73,16 @@ protected override void SaveItem(Outlook.ContactItem olItem) } } + /// + /// You can manually override the disablement of the contact synchroniser for particular items, but only for limited time. + /// + /// The Outlook item + /// True if the item has had manual override set recently. + protected override bool IsManualOverride(Outlook.ContactItem olItem) + { + return olItem.IsManualOverride(); + } + /// /// Synchronise items in the specified folder with the specified SuiteCRM module. /// diff --git a/SuiteCRMAddIn/BusinessLogic/CrmId.cs b/SuiteCRMAddIn/BusinessLogic/CrmId.cs index c741a8cb..0dda4833 100644 --- a/SuiteCRMAddIn/BusinessLogic/CrmId.cs +++ b/SuiteCRMAddIn/BusinessLogic/CrmId.cs @@ -96,7 +96,10 @@ public override string ToString() /// public static bool IsValid(string id) { - return !string.IsNullOrEmpty(id) && Validator.IsMatch(id); + bool result = !string.IsNullOrEmpty(id); + result = result && Validator.IsMatch(id); + + return result; } /// @@ -148,11 +151,26 @@ public override int GetHashCode() /// Get the single CrmId instance for this value. /// /// The value to seek. - /// A CrmId instance - /// if `value` does not appear to be a valid CRM id. + /// A CrmId instance, or Empty if the offered value is invalid. public static CrmId Get(string value) { - return string.IsNullOrEmpty(value) ? Empty : Issued.ContainsKey(value) ? Issued[value] : new CrmId(value); + CrmId result = Empty; + + if (IsValid(value)) + { + if (Issued.ContainsKey(value)) + { + result = Issued[value]; + } + else + { + result = new CrmId(value); + } + } + // This breaks, and I can't understand why: + // return IsValid(value) ? Empty : Issued.ContainsKey(value) ? Issued[value] : new CrmId(value); + + return result; } /// diff --git a/SuiteCRMAddIn/BusinessLogic/ErrorHandler.cs b/SuiteCRMAddIn/BusinessLogic/ErrorHandler.cs index 8d99e80b..149d74e5 100644 --- a/SuiteCRMAddIn/BusinessLogic/ErrorHandler.cs +++ b/SuiteCRMAddIn/BusinessLogic/ErrorHandler.cs @@ -20,6 +20,10 @@ * * @author SalesAgility */ + +using SuiteCRMAddIn.Daemon; +using SuiteCRMAddIn.Exceptions; + namespace SuiteCRMAddIn.BusinessLogic { using SuiteCRMClient.Logging; @@ -45,7 +49,7 @@ public static void Handle(Exception error) /// public static void Handle(BadCredentialsException badCredentials) { - if (Globals.ThisAddIn.ShowReconfigureOrDisable("Login failed; have your credentials changed?")) + if (Globals.ThisAddIn.ShowReconfigureOrDisable("Login failed; have your credentials changed?") == DialogResult.Cancel) { Globals.ThisAddIn.Disable(); } @@ -53,16 +57,67 @@ public static void Handle(BadCredentialsException badCredentials) public static void Handle(string message) { - Handle(message, null); + Handle(message, (Exception)null); + } + + public static void Handle(OutOfMemoryException error) + { + Handle( "SuiteSRM AddIn recovered from an out of memory error; no work was lost, but some tasks may not have been completed", error); + } + + public static void Handle(string contextMessage, OutOfMemoryException error, bool notify = false) + { + Globals.ThisAddIn.Log.Error(contextMessage, error); + MessageBox.Show(ComposeErrorDescription(contextMessage, error), "SuiteCRM AddIn ran out of memory", MessageBoxButtons.OK, MessageBoxIcon.Error); } - public static void Handle(string contextMessage, Exception error) + public static void Handle(string contextMessage, NeverShowUserException error, bool notify = false) { Globals.ThisAddIn.Log.Error(contextMessage, error); - var errorClassName = error?.GetType().Name ?? string.Empty; + } + + /// + /// Handle this error in the context described in this contextMessage. + /// + /// A message describing what was being attempted when the error occurred. + /// The error. + /// If true, notify the user anyway, overriding the ShowExceptions setting. + public static void Handle(string contextMessage, Exception error, bool notify = false) + { + Globals.ThisAddIn.Log.Error(contextMessage, error); + + if (notify) + { + MessageBox.Show(ComposeErrorDescription(contextMessage, error), "SuiteCRM Addin Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + else + { + switch (Properties.Settings.Default.ShowExceptions) + { + case PopupWhen.Never: + break; + case PopupWhen.FirstTime: + var errorClassName = error?.GetType().Name ?? string.Empty; + + if (!SeenExceptions.Contains(errorClassName)) + { + SeenExceptions.Add(errorClassName); + MessageBox.Show(ComposeErrorDescription(contextMessage, error), "SuiteCRM Addin Error", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + break; + default: + MessageBox.Show(ComposeErrorDescription(contextMessage, error), "SuiteCRM Addin Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + break; + } + } + } + + private static string ComposeErrorDescription(string contextMessage, Exception error) + { StringBuilder bob = new StringBuilder(contextMessage); - for (Exception e = error; e != null; e = e.GetBaseException()) + for (Exception e = error; e != null; e = e.InnerException) { if (e != error) { @@ -71,24 +126,32 @@ public static void Handle(string contextMessage, Exception error) bob.Append(e.GetType().Name).Append(e.Message); } string text = bob.ToString(); + return text; + } - switch (Properties.Settings.Default.ShowExceptions) + /// + /// Do this action and, if an error occurs, invoke the error handler on it with this message. + /// + /// + /// \todo this method is duplicated in Robustness, but the copy in ErrorHandler is preferred; + /// in the next release it is intended to remove the Robustness class and move its functionality + /// to ErrorHandler. + /// + /// The action to perform + /// A string describing what the action was intended to achieve. + public static void DoOrHandleError(Action action, string message) + { + try + { + action(); + } + catch (Exception problem) { - case PopupWhen.Never: - break; - case PopupWhen.FirstTime: - if (!SeenExceptions.Contains(errorClassName)) - { - SeenExceptions.Add(errorClassName); - MessageBox.Show(text, "SuiteCRM Addin Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - break; - default: - MessageBox.Show(text, "SuiteCRM Addin Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - break; + ErrorHandler.Handle(message, problem); } } + public enum PopupWhen { Never, diff --git a/SuiteCRMAddIn/BusinessLogic/LicenceValidationHelper.cs b/SuiteCRMAddIn/BusinessLogic/LicenceValidationHelper.cs index 62501383..6fb7f7dd 100644 --- a/SuiteCRMAddIn/BusinessLogic/LicenceValidationHelper.cs +++ b/SuiteCRMAddIn/BusinessLogic/LicenceValidationHelper.cs @@ -97,7 +97,8 @@ public bool Validate() parameters["public_key"] = this.applicationKey; parameters["key"] = this.licenceKey; - using (var response = this.service.CreateGetRequest(parameters).GetResponse() as HttpWebResponse) + using (var response = + this.service.CreateGetRequest(parameters).GetResponse() as HttpWebResponse) { result = InterpretStatusCode(response); } diff --git a/SuiteCRMAddIn/BusinessLogic/SyncStateManager.cs b/SuiteCRMAddIn/BusinessLogic/SyncStateManager.cs index 60cc120e..5bc1c008 100644 --- a/SuiteCRMAddIn/BusinessLogic/SyncStateManager.cs +++ b/SuiteCRMAddIn/BusinessLogic/SyncStateManager.cs @@ -144,9 +144,9 @@ public void BruteForceSaveAll() break; } } - catch (Exception) + catch (Exception ex) { - // should log it but not critical. + Globals.ThisAddIn.Log.Warn("Exception during save all (probably not important)", ex); } } } diff --git a/SuiteCRMAddIn/BusinessLogic/SyncState{1}.cs b/SuiteCRMAddIn/BusinessLogic/SyncState{1}.cs index 679703d7..1883c743 100644 --- a/SuiteCRMAddIn/BusinessLogic/SyncState{1}.cs +++ b/SuiteCRMAddIn/BusinessLogic/SyncState{1}.cs @@ -20,6 +20,8 @@ * * @author SalesAgility */ + + namespace SuiteCRMAddIn.BusinessLogic { using Exceptions; @@ -27,8 +29,8 @@ namespace SuiteCRMAddIn.BusinessLogic using SuiteCRMClient.Logging; using System; using Outlook = Microsoft.Office.Interop.Outlook; - using System.Collections.Generic; - using SuiteCRMClient; + using System.Runtime.InteropServices; + using System.Threading; /// /// The sync state of an item of the specified type. @@ -50,7 +52,7 @@ namespace SuiteCRMAddIn.BusinessLogic /// If a state is created from a CRM record, it is set to /// When a change has been made to it Outlook side, the relevant /// sets it to , and passes it to an - /// . + /// . /// The AbstractTransmissionAction sets it to , and in due course) sends it back to /// the same Synchroniser. /// The Synchroniser sets it to and transmits @@ -64,6 +66,7 @@ namespace SuiteCRMAddIn.BusinessLogic /// these are items which had presumably failed to be synced earlier. /// /// + /// /// The type of the item to be/being synced. public abstract class SyncState : SyncState where ItemType : class @@ -71,26 +74,70 @@ public abstract class SyncState : SyncState /// /// Underlying store for my property. /// - private ItemType item; + protected ItemType Item; + + /// + /// Handle onto the MAPI namespace. + /// + private static Outlook.NameSpace mapiNs = null; - public abstract Outlook.OlDefaultFolders DefaultFolder { get; } + /// + /// Handle onto the MAPI namespace, guaranteed to exist. + /// + protected static Outlook.NameSpace MapiNs => mapiNs ?? (mapiNs = Globals.ThisAddIn.Application.GetNamespace("MAPI")); - int getItemFails = 0, getItemSuccesses = 0; + public abstract Outlook.Folder DefaultFolder { get; } /// /// The outlook item for which I maintain the synchronisation state. /// - public ItemType OutlookItem { + public ItemType OutlookItem + { get { - return this.item; + if (!this.VerifyItem()) + { + this.Item = null; + + for (var i = 0; this.Item == null && i < 10; i++) + { + try + { + this.Item = MapiNs.GetItemFromID(this.outlookItemId, this.DefaultFolder.StoreID) as ItemType; + } + catch (Exception any) + { + Globals.ThisAddIn.Log.Error($"Failed to open item with id {this.outlookItemId} at attempt {i}", any); + Thread.Sleep(10000); + } + } + + if (this.Item == null) + { + throw new MissingOutlookItemException(this.outlookItemId); + } + } + + return this.Item; } - private set + protected set { - this.item = value; + this.Item = value; + this.CacheOulookItemId(value); } } + /// + /// Varify that item has not become detached (does not throw a COMException when interrogated). + /// + /// false + protected abstract bool VerifyItem(); + + /// + /// Cache the entry id of my outlook item on me. + /// + /// + protected abstract void CacheOulookItemId(ItemType value); /// /// A lock that should be obtained before operations which operate on the TxState or the @@ -129,6 +176,14 @@ public SyncState(ItemType item, CrmId crmId, DateTime modifiedDate) /// public abstract string IdentifyingFields { get; } + /// + /// True if the Outlook item wrapped by this state may be synchronised even when synchronisation is set to none. + /// + /// + /// At present, only Contacts have the manual override mechanism. + /// + public virtual bool IsManualOverride => false; + /// /// Delete the Outlook item associated with this SyncState. @@ -204,6 +259,7 @@ internal bool ShouldPerformSyncNow() log.Debug(reallyChanged ? $"{prefix} has changed." : $"{prefix} has not changed."); log.Debug(isSyncable ? $"{prefix} is syncable." : $"{ prefix} is not syncable."); + log.Debug(IsManualOverride ? $"{prefix} is on manual override." : $"{prefix} is not on manual override."); bool result; @@ -211,7 +267,7 @@ internal bool ShouldPerformSyncNow() { /* result is set within the lock to prevent one thread capturing another thread's * state change. */ - result = isSyncable && reallyChanged && this.TxState == TransmissionState.Pending && modifiedSinceSeconds > 2; + result = (IsManualOverride || (isSyncable && reallyChanged)) && this.TxState == TransmissionState.Pending && modifiedSinceSeconds > 2; if (result) { this.OModifiedDate = utcNow; @@ -228,20 +284,17 @@ internal bool ShouldPerformSyncNow() /// /// Set the transmission state of this SyncState object to . + /// If the synchroniser starts (or restarts) when a sync has already been done, e.g. a manual sync, some + /// sync states will be active. Those should be left in the state in which they were found. Those which are + /// genuinely fresh, however, should be set to 'present at startup'. /// internal void SetPresentAtStartup() { lock (this.txStateLock) { - switch (this.TxState) + if (this.TxState == TransmissionState.NewFromOutlook) { - case TransmissionState.NewFromOutlook: - case TransmissionState.PresentAtStartup: - case TransmissionState.Pending: - this.LogAndSetTxState(TransmissionState.PresentAtStartup); - break; - default: - throw new BadStateTransition(this, this.TxState, TransmissionState.PresentAtStartup); + this.LogAndSetTxState(TransmissionState.PresentAtStartup); } } } @@ -334,7 +387,7 @@ internal void SetQueued() /// /// Set the transmission state of this SyncState object to . /// - internal void SetTransmitted() + internal virtual void SetTransmitted() { lock (this.txStateLock) { @@ -479,11 +532,19 @@ internal bool MayBeUpdatedFromCRM() private void LogAndSetTxState(TransmissionState newState) { #if DEBUG - if (this.Cache == null) + try + { + if (this.Cache == null) + { + this.Cache = this.CreateProtoItem(this.OutlookItem); + } + Globals.ThisAddIn.Log.Debug( + $"{this.GetType().Name} '{this.Cache?.Description}': transition {this.TxState} => {newState}"); + } + catch (InvalidComObjectException) { - this.Cache = this.CreateProtoItem(this.OutlookItem); + // ignore. It doesn't matter. Although TODO: I'd love to know what happens. } - Globals.ThisAddIn.Log.Debug($"{this.GetType().Name} '{this.Cache?.Description}': transition {this.TxState} => {newState}"); #endif this.TxState = newState; } diff --git a/SuiteCRMAddIn/BusinessLogic/Synchroniser.cs b/SuiteCRMAddIn/BusinessLogic/Synchroniser.cs index 2fe3ab37..bd4ac29f 100644 --- a/SuiteCRMAddIn/BusinessLogic/Synchroniser.cs +++ b/SuiteCRMAddIn/BusinessLogic/Synchroniser.cs @@ -445,16 +445,16 @@ protected void EnsureSynchronisationPropertiesForOutlookItem(OutlookItemType olI { try { - EnsureSynchronisationPropertyForOutlookItem(olItem, SyncStateManager.ModifiedDatePropertyName, - modifiedDate); - EnsureSynchronisationPropertyForOutlookItem(olItem, SyncStateManager.TypePropertyName, type); - if (CrmId.IsValid(entryId)) { EnsureSynchronisationPropertyForOutlookItem(olItem, SyncStateManager.CrmIdPropertyName, entryId); SyncStateManager.Instance.SetByCrmId(entryId, SyncStateManager.Instance.GetOrCreateSyncState(olItem)); } + + EnsureSynchronisationPropertyForOutlookItem(olItem, SyncStateManager.ModifiedDatePropertyName, + modifiedDate); + EnsureSynchronisationPropertyForOutlookItem(olItem, SyncStateManager.TypePropertyName, type); } catch (Exception any) { @@ -543,7 +543,7 @@ protected List> FindMatches(EntryValue crmItem) } catch (Exception any) { - ErrorHandler.Handle($"Failure while checking for items matching id '{crmItem.id}'", any); + ErrorHandler.Handle($"Failure while checking for items matching id '{crmItem.id}' {Environment.NewLine}", any); result = new List>(); } @@ -664,15 +664,20 @@ protected virtual IList MergeRecordsFromCrm(MAPIFolder folder, strin thisOffset = nextOffset; var entriesPage = GetEntriesPage(thisOffset); + var entryList = entriesPage.entry_list; /* get the offset of the next page */ nextOffset = entriesPage.next_offset; - result.AddRange(entriesPage.entry_list); + if (entryList != null && entryList.Length > 0) + { + /* it should not be, but it has happened that entry_list has been null */ + result.AddRange(entryList); + } } /* when there are no more entries, we'll get a zero-length entry list and nextOffset * will have the same value as thisOffset */ - while (thisOffset != nextOffset); + while (thisOffset != nextOffset); return result; } @@ -1024,7 +1029,11 @@ protected virtual bool ShouldAddOrUpdateItemFromOutlookToCrm(OutlookItemType olI } else { - if (SyncDirection.AllowOutbound(Direction)) + if (IsManualOverride(olItem)) + { + result = true; + } + else if (SyncDirection.AllowOutbound(Direction)) { if (permissionsCache.HasImportAccess(DefaultCrmModule)) { @@ -1063,6 +1072,21 @@ protected virtual bool ShouldAddOrUpdateItemFromOutlookToCrm(OutlookItemType olI return result; } + /// + /// Returns true if this `olItem` has a manual override allowing it to be synced while synchronisation + /// is disabled. + /// + /// + /// #4754: We need to allow Contacts (but not, at present, other items) to be manually synced even when + /// synchronisation is otherwise disabled. + /// + /// The outlook item + /// true if this `olItem` has a manual override. + protected virtual bool IsManualOverride(OutlookItemType olItem) + { + return false; + } + /// /// Should the item represented by this sync state be synchronised now? /// diff --git a/SuiteCRMAddIn/BusinessLogic/TaskSyncState.cs b/SuiteCRMAddIn/BusinessLogic/TaskSyncState.cs index 634a8a03..b3965823 100644 --- a/SuiteCRMAddIn/BusinessLogic/TaskSyncState.cs +++ b/SuiteCRMAddIn/BusinessLogic/TaskSyncState.cs @@ -43,6 +43,21 @@ public TaskSyncState(Outlook.TaskItem item, CrmId crmId, DateTime modifiedDate) public override string OutlookItemEntryId => OutlookItem.EntryID; + protected override bool VerifyItem() + { + bool result; + try + { + result = !string.IsNullOrEmpty(this.Item?.EntryID); + } + catch (Exception ex) when (ex is InvalidComObjectException || ex is COMException) + { + result = false; + } + + return result; + } + public override Outlook.OlSensitivity OutlookItemSensitivity => OutlookItem.Sensitivity; public override Outlook.UserProperties OutlookUserProperties => OutlookItem.UserProperties; @@ -74,13 +89,7 @@ public override string IdentifyingFields } } - public override Outlook.OlDefaultFolders DefaultFolder - { - get - { - return Outlook.OlDefaultFolders.olFolderTasks; - } - } + public override Outlook.Folder DefaultFolder => (Outlook.Folder)MapiNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts); public override void DeleteItem() { @@ -117,5 +126,10 @@ internal override void SaveItem() { this.OutlookItem?.Save(); } + + protected override void CacheOulookItemId(Outlook.TaskItem olItem) + { + this.outlookItemId = olItem.EntryID; + } } } diff --git a/SuiteCRMAddIn/BusinessLogic/TaskSynchroniser.cs b/SuiteCRMAddIn/BusinessLogic/TaskSynchroniser.cs index 9c0e448a..12dcc39d 100644 --- a/SuiteCRMAddIn/BusinessLogic/TaskSynchroniser.cs +++ b/SuiteCRMAddIn/BusinessLogic/TaskSynchroniser.cs @@ -97,7 +97,7 @@ protected override void SaveItem(Outlook.TaskItem olItem) { try { - olItem.Save(); + olItem?.Save(); LogItemAction(olItem, "TaskSyncing.SaveItem, saved item"); } catch (System.Exception any) diff --git a/SuiteCRMAddIn/Daemon/AbstractDaemonAction.cs b/SuiteCRMAddIn/Daemon/AbstractDaemonAction.cs index 4df95a78..710f6bd5 100644 --- a/SuiteCRMAddIn/Daemon/AbstractDaemonAction.cs +++ b/SuiteCRMAddIn/Daemon/AbstractDaemonAction.cs @@ -20,6 +20,9 @@ * * @author SalesAgility */ + +using System.Windows.Forms; + namespace SuiteCRMAddIn.Daemon { /// @@ -29,13 +32,13 @@ namespace SuiteCRMAddIn.Daemon public abstract class AbstractDaemonAction : DaemonAction { /// - /// backing store for the MaxAttempts property. + /// If true, in the event of total failure, notify the user. /// - private int maxAttempts; + public bool NotifyOnFailure { get; protected set; } = false; - public AbstractDaemonAction(int maxAttempts) + protected AbstractDaemonAction(int maxAttempts) { - this.maxAttempts = maxAttempts; + this.MaxAttempts = maxAttempts; } /// @@ -46,25 +49,14 @@ public AbstractDaemonAction(int maxAttempts) /// /// Get a description of this action. /// - public virtual string Description - { - get - { - return this.GetType().Name; - } - } + public virtual string Description => this.GetType().Name; /// /// The maximum number of times this action can be attempted before /// being abandoned. /// - public int MaxAttempts - { - get - { - return this.maxAttempts; - } - } + + public int MaxAttempts { get; } /// /// Perform this action. diff --git a/SuiteCRMAddIn/Daemon/DaemonAction.cs b/SuiteCRMAddIn/Daemon/DaemonAction.cs index 0fded348..800dd5cf 100644 --- a/SuiteCRMAddIn/Daemon/DaemonAction.cs +++ b/SuiteCRMAddIn/Daemon/DaemonAction.cs @@ -28,9 +28,14 @@ namespace SuiteCRMAddIn.Daemon /// (intended to be limited) in case, for example due to network problems, the first attempt(s) fail. /// However, DaemonActions are not intended for things which are to be run repeatedly. For that, /// specialise [RepeatingProcess](class_suite_c_r_m_add_in_1_1_business_logic_1_1_repeating_process.html). - /// + /// public interface DaemonAction { + /// + /// If true, in the event of total failure, notify the user. + /// + bool NotifyOnFailure { get; } + /// /// The number of times this item has been attempted. /// diff --git a/SuiteCRMAddIn/Daemon/DaemonWorker.cs b/SuiteCRMAddIn/Daemon/DaemonWorker.cs index 175bea8b..6453c2d7 100644 --- a/SuiteCRMAddIn/Daemon/DaemonWorker.cs +++ b/SuiteCRMAddIn/Daemon/DaemonWorker.cs @@ -117,12 +117,14 @@ internal override void PerformIteration() } else { - ErrorHandler.Handle($"{task.Description} failed with error {retryable.GetType().Name}: {retryable.Message}; too many retries, aborting", retryable); + ErrorHandler.Handle($"{task.Description} failed with error {retryable.GetType().Name}: {retryable.Message}; too many retries, aborting", + retryable, task.NotifyOnFailure); } } catch (Exception any) { - ErrorHandler.Handle($"{task.Description} failed with error {any.GetType().Name}: {any.Message}; Not retryable, aborting", any); + ErrorHandler.Handle($"{task.Description} failed with error {any.GetType().Name}: {any.Message}; Not retryable, aborting", + any, task.NotifyOnFailure); } } } diff --git a/SuiteCRMAddIn/Daemon/FetchEmailCategoriesAction.cs b/SuiteCRMAddIn/Daemon/FetchEmailCategoriesAction.cs index 165f1669..8fb09182 100644 --- a/SuiteCRMAddIn/Daemon/FetchEmailCategoriesAction.cs +++ b/SuiteCRMAddIn/Daemon/FetchEmailCategoriesAction.cs @@ -55,37 +55,45 @@ public FetchEmailCategoriesAction() : base(5) /// public override string Perform() { - try + if (Globals.ThisAddIn.HasCrmUserSession) { - Field field = RestAPIWrapper.GetFieldsForModule("Emails").moduleFields.FirstOrDefault(x => x.name == "category_id"); - - if (field != null) - { - Properties.Settings.Default.EmailCategories.IsImplemented = true; - Properties.Settings.Default.EmailCategories.Clear(); - Properties.Settings.Default.EmailCategories.AddRange(field.Options.Keys.OrderBy(x => x)); - } - else + try { - /* the CRM instance does not have the category_id field in its emails module */ - Properties.Settings.Default.EmailCategories.IsImplemented = false; - } + Field field = RestAPIWrapper.GetFieldsForModule("Emails").moduleFields + .FirstOrDefault(x => x.name == "category_id"); - Properties.Settings.Default.Save(); + if (field != null) + { + Properties.Settings.Default.EmailCategories.IsImplemented = true; + Properties.Settings.Default.EmailCategories.Clear(); + Properties.Settings.Default.EmailCategories.AddRange(field.Options.Keys.OrderBy(x => x)); + } + else + { + /* the CRM instance does not have the category_id field in its emails module */ + Properties.Settings.Default.EmailCategories.IsImplemented = false; + } - return "OK"; - } - catch (WebException wex) - { - if (wex.Status == WebExceptionStatus.Timeout) - { - throw new ActionRetryableException("Temporary network error", wex); + Properties.Settings.Default.Save(); + + return "OK"; } - else + catch (WebException wex) { - throw; + if (wex.Status == WebExceptionStatus.Timeout) + { + throw new ActionRetryableException("Temporary network error", wex); + } + else + { + throw; + } } } + else + { + throw new ActionRetryableException("No user session (yet?)"); + } } } } diff --git a/SuiteCRMAddIn/Daemon/TransmitNewAction.cs b/SuiteCRMAddIn/Daemon/TransmitNewAction.cs index 9c801d2a..894b9bc2 100644 --- a/SuiteCRMAddIn/Daemon/TransmitNewAction.cs +++ b/SuiteCRMAddIn/Daemon/TransmitNewAction.cs @@ -33,6 +33,7 @@ namespace SuiteCRMAddIn.Daemon /// does not already have a valid CRM id. /// /// The type of item I transmit. + /// The type of sync state which is appropriate to my item type. public class TransmitNewAction : AbstractDaemonAction where OutlookItemType : class where SyncStateType : SyncState @@ -40,6 +41,11 @@ public class TransmitNewAction : AbstractDaemonA private SyncState syncState; private Synchroniser synchroniser; + /// + /// Create a new instance of the TransmitNewAction class, wrapping this state. + /// + /// The synchroniser I will call to perform this action. + /// The sync state on which this action should be performed. public TransmitNewAction(Synchroniser synchroniser, SyncStateType state) : base(1) { /* step the state transition engine forward to queued */ @@ -50,6 +56,7 @@ public TransmitNewAction(Synchroniser synchronis } this.syncState = state; this.synchroniser = synchroniser; + this.NotifyOnFailure = state.IsManualOverride; } public override string Description diff --git a/SuiteCRMAddIn/Daemon/TransmitUpdateAction.cs b/SuiteCRMAddIn/Daemon/TransmitUpdateAction.cs index 1706a3d8..79f72833 100644 --- a/SuiteCRMAddIn/Daemon/TransmitUpdateAction.cs +++ b/SuiteCRMAddIn/Daemon/TransmitUpdateAction.cs @@ -34,6 +34,7 @@ namespace SuiteCRMAddIn.Daemon /// already has a SyncState. /// /// The type of item I transmit. + /// The type of sync state which is appropriate to my item type. public class TransmitUpdateAction : AbstractDaemonAction where OutlookItemType : class where SyncStateType : SyncState @@ -58,6 +59,7 @@ public TransmitUpdateAction(Synchroniser synchro state.SetQueued(); this.synchroniser = synchroniser; this.state = state; + this.NotifyOnFailure = state.IsManualOverride; MeetingSyncState meeting = state as MeetingSyncState; diff --git a/SuiteCRMAddIn/Dialogs/AddressBook.Designer.cs b/SuiteCRMAddIn/Dialogs/AddressBook.Designer.cs index 2025bfa4..2ec0f376 100644 --- a/SuiteCRMAddIn/Dialogs/AddressBook.Designer.cs +++ b/SuiteCRMAddIn/Dialogs/AddressBook.Designer.cs @@ -404,7 +404,6 @@ private void InitializeComponent() this.MinimizeBox = false; this.MinimumSize = new System.Drawing.Size(624, 431); this.Name = "frmAddressBook"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "SuiteCRM Address Book"; this.Load += new System.EventHandler(this.frmAddressBook_Load); this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.frmAddressBook_KeyPress); diff --git a/SuiteCRMAddIn/Dialogs/AddressBook.cs b/SuiteCRMAddIn/Dialogs/AddressBook.cs index 605cad82..2a86bfe1 100644 --- a/SuiteCRMAddIn/Dialogs/AddressBook.cs +++ b/SuiteCRMAddIn/Dialogs/AddressBook.cs @@ -93,8 +93,8 @@ private void btnRemoveTo_Click(object sender, EventArgs e) private void btnSearch_Click(object sender, EventArgs e) { - string[] strArray = new string[2]; - string str = "OR"; + string[] tokens = new string[2]; + string logicalOperator = "OR"; using (WaitCursor.For(this)) { if (this.txtSearch.Text == string.Empty) @@ -104,41 +104,36 @@ private void btnSearch_Click(object sender, EventArgs e) else { this.lstViewResults.Items.Clear(); - string[] strArray2 = new string[] { "Leads", ContactSynchroniser.CrmModule }; + string[] moduleNames = new string[] { "Leads", ContactSynchroniser.CrmModule }; if (this.txtSearch.Text.Contains(' ')) { - strArray = this.txtSearch.Text.Split(new char[] { ' ' }); + tokens = this.txtSearch.Text.Split(new char[] { ' ' }); } else { - strArray[0] = this.txtSearch.Text; - strArray[1] = this.txtSearch.Text; + tokens[0] = this.txtSearch.Text; + tokens[1] = this.txtSearch.Text; } - if ((strArray[1] != string.Empty) && (strArray[0] != strArray[1])) + if ((tokens[1] != string.Empty) && (tokens[0] != tokens[1])) { - str = "AND"; + logicalOperator = "AND"; } - foreach (string str2 in strArray2) + foreach (string moduleName in moduleNames) { - string query = "(" + str2.ToLower() + ".first_name LIKE '%" + strArray[0] + "%' " + str + " " + str2.ToLower() + ".last_name LIKE '%" + strArray[1] + "%')"; - bool flag1 = str2 == ContactSynchroniser.CrmModule; + string query = "(" + moduleName.ToLower() + ".first_name LIKE '%" + tokens[0] + "%' " + logicalOperator + " " + moduleName.ToLower() + ".last_name LIKE '%" + tokens[1] + "%')"; + bool isContacts = moduleName == ContactSynchroniser.CrmModule; if (this.cbMyItems.Checked) { string str8 = query; - query = str8 + "AND " + str2.ToLower() + ".assigned_user_id = '" + Globals.ThisAddIn.SuiteCRMUserSession.id + "'"; + query = str8 + "AND " + moduleName.ToLower() + ".assigned_user_id = '" + Globals.ThisAddIn.SuiteCRMUserSession.id + "'"; } - foreach (EntryValue _value in RestAPIWrapper.GetEntryList(str2, query, 0, "date_entered DESC", 0, false, new string[] { "first_name", "last_name", "email1" }).entry_list) + foreach (EntryValue value in RestAPIWrapper.GetEntryList(moduleName, query, 0, "date_entered DESC", 0, false, new string[] { "first_name", "last_name", "email1" }).entry_list) { - string str4 = string.Empty; - string str5 = string.Empty; - string valueByKey = string.Empty; - string str7 = string.Empty; - valueByKey = RestAPIWrapper.GetValueByKey(_value, "first_name"); - str7 = RestAPIWrapper.GetValueByKey(_value, "last_name"); - RestAPIWrapper.GetValueByKey(_value, "id"); - str5 = RestAPIWrapper.GetValueByKey(_value, "email1"); - str4 = valueByKey + " " + str7; - this.lstViewResults.Items.Add(new ListViewItem(new string[] { str4, str5, str2 })); + string primaryEmail = RestAPIWrapper.GetValueByKey(value, "email1"); + string firstName = RestAPIWrapper.GetValueByKey(value, "first_name"); + string lastName = RestAPIWrapper.GetValueByKey(value, "last_name"); + string fullName = firstName + " " + lastName; + this.lstViewResults.Items.Add(new ListViewItem(new string[] { fullName, primaryEmail, moduleName })); } } } diff --git a/SuiteCRMAddIn/Dialogs/AddressBook.resx b/SuiteCRMAddIn/Dialogs/AddressBook.resx index 251fb0c5..87d9aedf 100644 --- a/SuiteCRMAddIn/Dialogs/AddressBook.resx +++ b/SuiteCRMAddIn/Dialogs/AddressBook.resx @@ -120,99 +120,289 @@ - AAABAAEAJCQAAAEAIACIFQAAFgAAACgAAAAkAAAASAAAAAEAIAAAAAAAQBQAAMMOAADDDgAAAAAAAAAA - AADt7/z/v8X3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ - 9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ - 9//Eyff/xMn3/8TJ9//Eyff/v8T3/+vt/P/Eyvj/P1Dm/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ - 6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ - 6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/PU7m/7/E9v/Jzvj/S1vo/1Vk + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXoskoZ31JGF + d/6RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXfzkYV3vo+GeTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAkoV4sZGFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf7kYV2QQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGFd9aRhXf/Xmna/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1lm + 5f93d6v/kYV3/5GGd9IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXfXkYV3/19q2f9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/V2bo/42Df/+RhXf/joBxEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV315GF + d/9gatj/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/9lfa+PqV2jd6ldo3elW + aJoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQhHZskIZ4kZCG + eJGQhniRkIZ4kZGFd+6RhXf/e3qh/3d4qf93eKn/ZG3N/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ - 9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GF + d//bXmv/6lZo/+pWaP/pVmjVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAkoZ3v5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/3Fztv9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk + 6v9WZer/VmXq/4aAi/+RhXf/215r/+pWaP/qVmj/6VZo1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJKGd7+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/9xc7b/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/9tea//qVmj/6lZo/+lWaNUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACShne/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/cXO2/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GFd//bXmv/6lZo/+pW + aP/pVmjVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkoZ3v5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/3Fztv9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aA + i/+RhXf/215r/+pWaP/qVmj/6VZo1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJKGd7+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/9xc7b/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ - 9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v+GgIv/kYV3/9tea//qVmj/6lZo/+lWaNUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACShne/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/cXO2/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GFd//bXmv/6lZo/+pWaP/pVmjVAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkoZ3v5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/3Fztv9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aAi/+RhXf/215r/+pW + aP/qVmj/6VZo1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJCG + eTeShXdLkoV3S5KFd0uShXdLkYV345GFd/9vcrv/aG7I/2huyP9eadv/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl + 6v+GgIv/kYV3/9tea//qVmj/6lZo/+lWaNUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGFd9eRhXf/YGrY/1Zl6v9WZer/VmXq/1Zl 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ - 9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/TFzo/0ZW6P9GVuj/Rlbo/0ZW6P9GVuj/Rlbo/0ZW6P9GVuj/Rlbo/0ZW6P9GVuj/Rlbo/0ZW - 6P9GVuj/Rlbo/0ZW6P9GVuj/Okvm/73D9v/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9MXOj/qrH0/+Pm+//d4Pr/3eD6/93g+v/d4Pr/3eD6/93g - +v/d4Pr/3eD6/93g+v/d4Pr/3eD6/93g+v/d4Pr/3eD6/93g+v/d4Pr/2t36//T1/f/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/wsf4//// + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GFd//bXmv/6lZo/+pWaP/pVmjVAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXfXkYV3/2Bq + 2P9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9da+v/hpHw/6uy + 9f/Bxvf/1dj6/+bo/P/j5fv/3eD7/9rd+v/Fyvj/r7b1/5Od8v9pd+z/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aAi/+RhXf/215r/+pWaP/qVmj/6VZo1QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAkYV315GFd/9gatj/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/3F9 + 7f+/xff/9/j+/////////////////////////////////////////////////////////////////+jq + /P+rsvX/aXbs/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/9dg + bMfrVmi761Zou+tWaH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGFd9eRhXf/YGrY/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/WWfq/6+39f/8/f////////////////////////////////////////////////////////// + //////////////////////////////r6/v+fp/P/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/hoCL/5GFd/+TgnctAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXfXkYV3/2Bq2P9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/6619f////////////////////////////////////////////// + /////////////////////////////////////////////////////////v7//2Nx7P9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aAi/+RhXf/k4J3LQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV315GF + d/9gatj/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v/Y2/r///////////////////////// + //////////////////////////////////////////////////////////////////////////////T1 + /v9YZ+r/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/5OCdy0AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJGFd9eRhXf/YGrY/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/tbz2//// //////////////////////////////////////////////////////////////////////////////// - ///////////////////Fyvf/Slro/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////88Hyb/TzU8/081PP9PNTz/TzU8/081PP9PNTz/TzU8/081 - PP9PNTz/TzU8/081PP9PNTz/TzU8/081PP9PNTz/RCgv/8G3uf/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nB - wv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//// - //9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nB - wv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//// - //9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nB - wv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//// - //9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Eyvj/P1Dm/0lZ6P9JWej/SVno/0lZ - 6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P89Tub/usD3//////9EKC//Vz9F/1c/ - Rf9XP0X/Vz9F/1c/Rf9XP0X/Vz9F/1c/Rf9XP0X/Vz9F/1c/Rf9XP0X/Vz9F/1c/Rf9XP0X/TDI4/8S7 - vf/t7/z/v8X3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ - 9/+/xPf/6ev8///////At7n/yMDC/8jAwv/IwML/yMDC/8jAwv/IwML/yMDC/8jAwv/IwML/yMDC/8jA - wv/IwML/yMDC/8jAwv/IwML/xLu9/+3q6v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAA= + //////////////////+5wPb/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GF + d/+TgnctAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXfXkYV3/2Bq2P9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/2d17P/4+f7///////////////////////////////////////////////////////// + ///////////////////////////////////19v7/ZXPs/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/4aAi/+RhXf/yLZkc+rYV1Xq2FdV6NdVLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV315GFd/9gatj/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/kpvx//7+//////////////////////////////// + ///////////////////////////////////////////////////+/v//jZfx/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/9vJXP/q2Fb/6thW/+rXVc4AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQhnk3kYZ5SpGGeUqRhnlKkYZ5SpGF + d+ORhXf/bnK8/2dvyf9nb8n/XWnc/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+krPT//v7///// + ////////////////////////////////////////////////////////////////////////oqrz/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GFd//byVz/6thW/+rY + Vv/p11bVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkoZ3v5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/3Fztv9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/46Y8f/4+P7///////////////////////////////////////////////////////// + ///+/v//nKXz/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aA + i/+RhXf/28lc/+rYVv/q2Fb/6ddW1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJKGd7+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/9xc7b/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/cH3t/9DU+f////////////////////////////// + ///////////////////q7Pz/gYzv/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v+GgIv/kYV3/9vJXP/q2Fb/6thW/+nXVtUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACShne/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/cXO2/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hpHw/83S + +f/9/f////////////////////////Dy/f+qsvT/YG7r/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GFd//byVz/6thW/+rYVv/p11bVAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkoZ3v5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/3Fztv9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/anfs/6uy9f/L0Pj/y9D4/6Os9P9ca+v/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aAi/+RhXf/28lc/+rY + Vv/q2Fb/6ddW1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJKG + d7+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/9xc7b/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hpHw/+vt/f//////////////////////4eT7/3eD + 7v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v+GgIv/kYV3/9vJXP/q2Fb/6thW/+nXVtUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACShne/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/cXO2/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/ipXx//39//////////////// + ///////////////////4+P7/doPu/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GFd//byVz/6thW/+rYVv/p11bVAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkoZ3v5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/3Fztv9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/Xmzr//Dy + /f///////////////////////////////////////////9/h+/9XZur/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aAi/+RhXf/28lc/+rYVv/q2Fb/6ddW1QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJCEdmyQhniRkIZ4kZCG + eJGQhniRkYV37pGFd/97eqH/d3ip/3d4qf9kbc3/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/5Gb8f//////////////////////////////////////////////////////eITu/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/9vJ + XP/q2Fb/6thW/+nXVtUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGFd9eRhXf/YGrY/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+utfX///////////////////////////////////////// + /////////////5ag8v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/hoCL/5GFd//byVz/6thW/+rYVv/p11bVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXfXkYV3/2Bq2P9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/rLT1//////////////////// + //////////////////////////////////+UnfL/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aAi/+RhXf/28lc/+rYVv/q2Fb/6thWzQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV315GF + d/9gatj/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4mU + 8P//////////////////////////////////////////////////////cX3t/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/8KzZWXp2lZE6dpWROrW + UyUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJGFd9eRhXf/YGrY/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9ZaOr/5uj8////////////////////////////////////////////z9T5/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GF + d/+TgnctAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXfXkYV3/2Bq2P9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/3eD7v/29/7///////////////////////// + ////////7O39/2h17P9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/4aAi/+RhXf/k4J3LQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV315GFd/9gatj/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/cX3t/9LW + +f/+/v/////////////9/f//xcr4/2Zz7P9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/5OCdy0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGF + d9eRhXf/YGrY/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/aHXs/4SP8P+BjO//Y3Hs/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GFd/+TgnctAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACRhXfXkYV3/2Bq2P9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aA + i/+RhXf/ZNOex1brqbtW66m7VumpggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV315GFd/9gatj/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v+GgIv/kYV3/2HYoP9W6qn/Vuqp/1bpqdUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgIACgICABICAgASAgIAEgICABJCEdtiRhXf/YGrX/1dl + 6P9XZej/V2bp/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GFd/9h2KD/Vuqp/1bqqf9W6anVAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkoZ3v5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/3Fztv9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aAi/+RhXf/Ydig/1bq + qf9W6qn/Vump1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJKG + d7+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/9xc7b/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v+GgIv/kYV3/2HYoP9W6qn/Vuqp/1bpqdUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACShne/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/cXO2/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GFd/9h2KD/Vuqp/1bqqf9W6anVAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkoZ3v5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/3Fztv9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aAi/+RhXf/Ydig/1bqqf9W6qn/Vump1QAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJKGd7+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/9xc7b/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/2HY + oP9W6qn/Vuqp/1bpqdUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACShne/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/cXO2/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/hoCL/5GFd/9h2KD/Vuqp/1bqqf9W6anVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkoZ3v5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/3Fz + tv9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/4aAi/+RhXf/Ydig/1bqqf9W6qn/Vump1QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGEeKCRhXfXkYV315GFd9eRhXfXkIV3+ZGF + d/+JgYb/h4CJ/4eAif9scb//VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v+GgIv/kYV3/2HYoP9W6qn/Vuqp/1bp + qdUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJGFd9eRhXf/YGrY/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/hoCL/5GF + d/9h2KD/Vuqp/1bqqf9W6anVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXfXkYV3/2Bq2P9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/4aAi/+RhXf/Y9Se1VbqqcxW6qnMVuqpkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV32pGFd/9fadn/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1dm6P+Ng4D/kYV3/46AcRIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGF + d9eRhXf/X2rZ/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hn5f91dqv/kYV3/5GFdtMAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACQhnamkYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/uTg3hCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk4N0IZGFd8+RhXf9kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV39JKGd7+Thnk7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA////////////////////////////////////////////4AAAAAAH///gAAAAAAP//+AAAAAA + A///4AAAAAAB///gAAAAAAA//AAAAAAAAD/8AAAAAAAAP/wAAAAAAAA//AAAAAAAAD/8AAAAAAAAP/wA + AAAAAAA//AAAAAAAAD/8AAAAAAAAP/wAAAAAAAA//+AAAAAAAD//4AAAAAAAP//gAAAAAAA//+AAAAAA + Af//4AAAAAAB///gAAAAAAH//+AAAAAAAf//4AAAAAAAP//gAAAAAAA//AAAAAAAAD/8AAAAAAAAP/wA + AAAAAAA//AAAAAAAAD/8AAAAAAAAP/wAAAAAAAA//AAAAAAAAD/8AAAAAAAAP/wAAAAAAAA//+AAAAAA + AD//4AAAAAAAP//gAAAAAAA//+AAAAAAAf//4AAAAAAB///gAAAAAAH//+AAAAAAAf//4AAAAAAAP//g + AAAAAAA//AAAAAAAAD/8AAAAAAAAP/wAAAAAAAA//AAAAAAAAD/8AAAAAAAAP/wAAAAAAAA//AAAAAAA + AD/8AAAAAAAAP/wAAAAAAAA//+AAAAAAAD//4AAAAAAAP//gAAAAAAH//+AAAAAAA///4AAAAAAD///g + AAAAAAf///////////////////////////////////////////8= \ No newline at end of file diff --git a/SuiteCRMAddIn/Dialogs/ArchiveDialog.Designer.cs b/SuiteCRMAddIn/Dialogs/ArchiveDialog.Designer.cs index 28c66513..6496cd40 100644 --- a/SuiteCRMAddIn/Dialogs/ArchiveDialog.Designer.cs +++ b/SuiteCRMAddIn/Dialogs/ArchiveDialog.Designer.cs @@ -51,11 +51,14 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ArchiveDialog)); this.txtSearch = new System.Windows.Forms.TextBox(); this.btnSearch = new System.Windows.Forms.Button(); this.lstViewSearchModules = new System.Windows.Forms.ListView(); this.colList = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.searchModulesContextStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.selectFieldsItem = new System.Windows.Forms.ToolStripMenuItem(); this.tsResults = new System.Windows.Forms.TreeView(); this.btnArchive = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button(); @@ -63,6 +66,7 @@ private void InitializeComponent() this.categoryInput = new System.Windows.Forms.ComboBox(); this.legend = new System.Windows.Forms.TextBox(); this.instructionLabel = new System.Windows.Forms.Label(); + this.searchModulesContextStrip.SuspendLayout(); this.SuspendLayout(); // // txtSearch @@ -94,6 +98,7 @@ private void InitializeComponent() this.lstViewSearchModules.CheckBoxes = true; this.lstViewSearchModules.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.colList}); + this.lstViewSearchModules.ContextMenuStrip = this.searchModulesContextStrip; this.lstViewSearchModules.Location = new System.Drawing.Point(304, 60); this.lstViewSearchModules.Name = "lstViewSearchModules"; this.lstViewSearchModules.Size = new System.Drawing.Size(156, 250); @@ -101,12 +106,27 @@ private void InitializeComponent() this.lstViewSearchModules.UseCompatibleStateImageBehavior = false; this.lstViewSearchModules.View = System.Windows.Forms.View.Details; this.lstViewSearchModules.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.lstViewSearchModules_ItemChecked); + this.lstViewSearchModules.MouseClick += new System.Windows.Forms.MouseEventHandler(this.searchModules_MouseClick); // // colList // this.colList.Text = "Modules"; this.colList.Width = 129; // + // searchModulesContextStrip + // + this.searchModulesContextStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.selectFieldsItem}); + this.searchModulesContextStrip.Name = "searchModulesContextStrip"; + this.searchModulesContextStrip.Size = new System.Drawing.Size(148, 26); + // + // selectFieldsItem + // + this.selectFieldsItem.Name = "selectFieldsItem"; + this.selectFieldsItem.Size = new System.Drawing.Size(147, 22); + this.selectFieldsItem.Text = "Select Fields..."; + this.selectFieldsItem.Click += new System.EventHandler(this.showSelectFieldsDialog); + // // tsResults // this.tsResults.AccessibleName = ""; @@ -217,10 +237,10 @@ private void InitializeComponent() this.MinimumSize = new System.Drawing.Size(481, 404); this.Name = "ArchiveDialog"; this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Archive to SuiteCRM"; this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.frmArchive_FormClosed); this.Load += new System.EventHandler(this.frmArchive_Load); + this.searchModulesContextStrip.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -239,5 +259,7 @@ private void InitializeComponent() private System.Windows.Forms.ComboBox categoryInput; private System.Windows.Forms.TextBox legend; private System.Windows.Forms.Label instructionLabel; + private System.Windows.Forms.ContextMenuStrip searchModulesContextStrip; + private System.Windows.Forms.ToolStripMenuItem selectFieldsItem; } } diff --git a/SuiteCRMAddIn/Dialogs/ArchiveDialog.cs b/SuiteCRMAddIn/Dialogs/ArchiveDialog.cs index 68ca37cd..f187ac38 100644 --- a/SuiteCRMAddIn/Dialogs/ArchiveDialog.cs +++ b/SuiteCRMAddIn/Dialogs/ArchiveDialog.cs @@ -44,7 +44,18 @@ namespace SuiteCRMAddIn.Dialogs public partial class ArchiveDialog : Form { - public readonly List standardModules = new List { "Accounts", "Bugs", "Cases", ContactSynchroniser.CrmModule, "Leads", "Opportunities", "Project", "Users" }; + public static readonly List standardModules = + new List + { + "Accounts", + "Bugs", + "Cases", + ContactSynchroniser.CrmModule, + "Leads", + "Opportunities", + "Project", + "Users" + }; /// /// The emails to be archived. @@ -56,7 +67,8 @@ public partial class ArchiveDialog : Form /// /// Chains of modules to expand in the search tree. /// - private IDictionary> moduleChains = new Dictionary>(); + private IDictionary> moduleChains = + new Dictionary>(); /// /// The reason for archiving. @@ -74,7 +86,9 @@ public ArchiveDialog(IEnumerable selectedEmails, EmailArchiveReason re } catch (Exception any) { - ErrorHandler.Handle($"Failed to parse Archiving Search Chains value '{Properties.Settings.Default.ArchivingSearchChains}':", any); + ErrorHandler.Handle( + $"Failed to parse Archiving Search Chains value '{Properties.Settings.Default.ArchivingSearchChains}':", + any); } this.archivableEmails = selectedEmails; @@ -83,9 +97,9 @@ public ArchiveDialog(IEnumerable selectedEmails, EmailArchiveReason re var alreadyArchived = selectedEmails.Where(x => !string.IsNullOrEmpty(x.GetCRMEntryId())); var anyArchived = alreadyArchived.Any(); - this.legend.Text = anyArchived ? - $"{alreadyArchived.Count()} message(s) have already been archived; rearchiving will remove any existing relationships. You must select all contacts, accounts, leads, etc that you wish to archive the message(s) to." : - ""; + this.legend.Text = anyArchived + ? $"{alreadyArchived.Count()} message(s) have already been archived; rearchiving will remove any existing relationships. You must select all contacts, accounts, leads, etc that you wish to archive the message(s) to." + : ""; this.legend.Visible = anyArchived; if (!anyArchived) @@ -103,10 +117,10 @@ private void AddCustomModules() { if (Properties.Settings.Default.CustomModules != null) { - // StringEnumerator enumerator = .GetEnumerator(); + // StringEnumerator enumerator = .GetEnumerator(); foreach (string key in Properties.Settings.Default.CustomModules) { - string[] strArray = key.Split(new char[] { '|' }); + string[] strArray = key.Split(new char[] {'|'}); ListViewItem item = new ListViewItem { Tag = strArray[0], @@ -124,16 +138,18 @@ private void AddCustomModules() private void AddStandardModules() { AvailableModules allModules = RestAPIWrapper.GetModules(); - foreach (string moduleKey in this.standardModules.OrderBy(x => x)) + + foreach (string moduleKey in ArchiveDialog.standardModules.OrderBy(x => x)) { var module = allModules.items.FirstOrDefault(x => x.module_key == moduleKey); if (module != null) { - this.lstViewSearchModules.Items.Add(new ListViewItem + var listViewItem = new ListViewItem { Tag = module.module_key, Text = module.module_label - }); + }; + this.lstViewSearchModules.Items.Add(listViewItem); } else { @@ -149,10 +165,10 @@ private void frmArchive_Load(object sender, EventArgs e) if (Properties.Settings.Default.AutomaticSearch) { - this.BeginInvoke((MethodInvoker)delegate - { - this.Search(this.txtSearch.Text); - }); + this.BeginInvoke((MethodInvoker) delegate + { + this.Search(this.txtSearch.Text); + }); } } @@ -162,7 +178,8 @@ private void frmArchive_Load(object sender, EventArgs e) private void PopulateUIComponents() { this.txtSearch.Text = ConstructSearchText(); - if (Properties.Settings.Default.EmailCategories != null && Properties.Settings.Default.EmailCategories.IsImplemented) + if (Properties.Settings.Default.EmailCategories != null && + Properties.Settings.Default.EmailCategories.IsImplemented) { this.categoryInput.DataSource = Properties.Settings.Default.EmailCategories; } @@ -181,7 +198,7 @@ private void PopulateUIComponents() } try { - foreach (string str in Properties.Settings.Default.SelectedSearchModules.Split(new char[] { ',' })) + foreach (string str in Properties.Settings.Default.SelectedSearchModules.Split(new char[] {','})) { int num = Convert.ToInt32(str); this.lstViewSearchModules.Items[num].Checked = true; @@ -234,15 +251,15 @@ private string ConstructSearchText() } else { - ICollection addresses = + ICollection addresses = new HashSet($"{ConstructInboundSearchTest()},{ConstructOutboundSearchText()}" - .Split(',')); + .Split(',')); addresses.Remove(currentUserSMTPAddress); result = string.Join(",", addresses.OrderBy(address => address) - .GroupBy(address => address) - .Select(g => g.First())); - } + .GroupBy(address => address) + .Select(g => g.First())); } + } else { result = ConstructInboundSearchTest(); @@ -270,17 +287,17 @@ private string ConstructOutboundSearchText() addresses.Add(recipient.GetSmtpAddress()); } result = string.Join(",", addresses.OrderBy(address => address) - .GroupBy(address => address) - .Select(g => g.First())); + .GroupBy(address => address) + .Select(g => g.First())); return result; } private string ConstructInboundSearchTest() { return string.Join(",", this.archivableEmails.Select(email => email.GetSenderSMTPAddress()) - .OrderBy(address => address) - .GroupBy(address => address) - .Select(g => g.First())); + .OrderBy(address => address) + .GroupBy(address => address) + .Select(g => g.First())); } @@ -331,9 +348,9 @@ public void Search(string allSearchText) this.txtSearch.Enabled = false; foreach (string searchText in - allSearchText.Split(new char[] { ',', ';' }) - .OrderBy(x => x) - .GroupBy(x => x).Select(g => g.First().Trim())) + allSearchText.Split(new char[] {',', ';'}) + .OrderBy(x => x) + .GroupBy(x => x).Select(g => g.First().Trim())) { try @@ -341,7 +358,8 @@ public void Search(string allSearchText) this.tsResults.CheckBoxes = true; if (searchText == string.Empty) { - MessageBox.Show("Please enter some text to search", "Invalid search", MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBox.Show("Please enter some text to search", "Invalid search", MessageBoxButtons.OK, + MessageBoxIcon.Information); } else { @@ -460,7 +478,8 @@ private EntryList TryQuery(string searchText, string moduleName, List fi } catch (Exception secondFail) { - ErrorHandler.Handle($"Failure when custom module included (2); Query was '{searchQuery}'", secondFail); + ErrorHandler.Handle($"Failure when custom module included (2); Query was '{searchQuery}'", + secondFail); queryResult = null; throw; } @@ -549,15 +568,13 @@ private void PopulateTree(EntryList searchResult, string module, TreeNode parent EntryValue entry = searchResult.entry_list[i]; string key = RestAPIWrapper.GetValueByKey(entry, "id"); - ICollection links = moduleChains.ContainsKey(module) ? moduleChains[module] : new List(); + ICollection links = moduleChains.ContainsKey(module) + ? moduleChains[module] + : new List(); if (!parent.Nodes.ContainsKey(key)) { - TreeNode node = new TreeNode(ConstructNodeName(module, entry)) - { - Name = key, - Tag = key - }; + TreeNode node = ConstructNode(module, entry, key); parent.Nodes.Add(node); foreach (var relationship in entry.relationships.link_list) @@ -571,11 +588,12 @@ private void PopulateTree(EntryList searchResult, string module, TreeNode parent { var targetId = link != null ? link.TargetId : "id"; - TreeNode memberNode = new TreeNode(member.data.GetValueAsString(link != null ? link.Label : "name")) - { - Name = member.data.GetValueAsString(targetId), - Tag = member.data.GetValueAsString(targetId) - }; + TreeNode memberNode = + new TreeNode(member.data.GetValueAsString(link != null ? link.Label : "name")) + { + Name = member.data.GetValueAsString(targetId), + Tag = member.data.GetValueAsString(targetId) + }; chainNode.Nodes.Add(memberNode); } } @@ -593,9 +611,10 @@ private void PopulateTree(EntryList searchResult, string module, TreeNode parent /// The name of the module. /// The value in the module. /// A canonical tree node label. - private static string ConstructNodeName(string module, EntryValue entry) + private static TreeNode ConstructNode(string module, EntryValue entry, string key) { StringBuilder nodeNameBuilder = new StringBuilder(); + StringBuilder toolTipBuilder = new StringBuilder(); string keyValue = string.Empty; nodeNameBuilder.Append(RestAPIWrapper.GetValueByKey(entry, "first_name")) .Append(" ") @@ -604,30 +623,44 @@ private static string ConstructNodeName(string module, EntryValue entry) if (String.IsNullOrWhiteSpace(nodeNameBuilder.ToString())) { nodeNameBuilder.Append(RestAPIWrapper.GetValueByKey(entry, "name")); + toolTipBuilder.Append("Name "); + } + else + { + toolTipBuilder.Append("First Name | Last Name "); } switch (module) { case "Bugs": keyValue = RestAPIWrapper.GetValueByKey(entry, "bug_number"); + toolTipBuilder.Append(" | Bug Number"); break; case "Cases": keyValue = RestAPIWrapper.GetValueByKey(entry, "case_number"); + toolTipBuilder.Append(" | Case Number"); break; case "Contacts": - keyValue = string.Empty; + keyValue = " 5462 | True | 21/01/2019"; + toolTipBuilder.Append("Sample | Field | Names"); break; default: keyValue = RestAPIWrapper.GetValueByKey(entry, "account_name"); + toolTipBuilder.Append(" | Account Name"); break; } - if (keyValue != string.Empty) + if (!string.IsNullOrEmpty(keyValue)) { - nodeNameBuilder.Append($" ({keyValue})"); + nodeNameBuilder.Append($" | {keyValue}"); } - return nodeNameBuilder.ToString(); + return new TreeNode(nodeNameBuilder.ToString()) + { + Name = key, + Tag = key, + ToolTipText = toolTipBuilder.ToString() + }; } private List GetSelectedCrmEntities(TreeView tree) @@ -642,7 +675,8 @@ private List GetSelectedCrmEntities(TreeView tree) private void GetSelectedCrmEntitiesHelper(TreeNode node, List selectedCrmEntities) { - if (((node.Tag != null) && (node.Tag.ToString() != "root_node")) && ((node.Tag.ToString() != "sub_root_node") && node.Checked)) + if (((node.Tag != null) && (node.Tag.ToString() != "root_node")) && + ((node.Tag.ToString() != "sub_root_node") && node.Checked)) { selectedCrmEntities.Add(new CrmEntity(node.Parent.Text, node.Tag.ToString())); } @@ -690,7 +724,8 @@ private void tsResults_AfterExpand(object sender, TreeViewEventArgs e) private void tsResults_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { - if (((e.Button == MouseButtons.Right) && (e.Node.Tag.ToString() != "root_node")) && (e.Node.Tag.ToString() != "sub_root_node")) + if (((e.Button == MouseButtons.Right) && (e.Node.Tag.ToString() != "root_node")) && + (e.Node.Tag.ToString() != "sub_root_node")) { this.tsResults.SelectedNode = e.Node; } @@ -745,7 +780,8 @@ private void btnArchive_Click(object sender, EventArgs e) { try { - IEnumerable itemsToArchive = ConfirmRearchiveAlreadyArchivedEmails.ConfirmAlreadyArchivedEmails(archivableEmails); + IEnumerable itemsToArchive = + ConfirmRearchiveAlreadyArchivedEmails.ConfirmAlreadyArchivedEmails(archivableEmails); using (WaitCursor.For(this)) { @@ -771,7 +807,8 @@ private void btnArchive_Click(object sender, EventArgs e) var archiver = Globals.ThisAddIn.EmailArchiver; bool success = this.ReportOnEmailArchiveSuccess( itemsToArchive.Select(mailItem => - archiver.ArchiveEmailWithEntityRelationships(mailItem, selectedCrmEntities, this.reason)) + archiver.ArchiveEmailWithEntityRelationships(mailItem, selectedCrmEntities, + this.reason)) .ToList()); string prefix = success ? "S" : "Uns"; Log.Debug($"ArchiveDialog: {prefix}uccessfully archived {selectedEmailsCount} emails"); @@ -884,7 +921,8 @@ private void categoryInput_SelectedIndexChanged(object sender, EventArgs e) { mail.UserProperties.Add(MailItemExtensions.CRMCategoryPropertyName, OlUserPropertyType.olText); } - mail.UserProperties[MailItemExtensions.CRMCategoryPropertyName].Value = categoryInput.SelectedItem.ToString(); + mail.UserProperties[MailItemExtensions.CRMCategoryPropertyName].Value = + categoryInput.SelectedItem.ToString(); } catch (COMException) { @@ -893,6 +931,7 @@ private void categoryInput_SelectedIndexChanged(object sender, EventArgs e) } } } + private void RemoveSelection(Object obj) { TextBox textbox = obj as TextBox; @@ -950,6 +989,21 @@ public LinkSpec(string linkName, string targetName, ICollection fieldNam } + + private void searchModules_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right && lstViewSearchModules.FocusedItem.Bounds.Contains(e.Location)) + { + searchModulesContextStrip.Show(Cursor.Position); + } + } + + private void showSelectFieldsDialog(object sender, EventArgs e) + { + new ArchiveModuleSelectFieldsDialog(lstViewSearchModules.FocusedItem.Text).ShowDialog(); + } + + /// /// A query to search the server side database in response to a client /// side (at this state, ArchiveDialog) query; a testable bean. @@ -960,18 +1014,22 @@ internal class SearchQuery /// The text we're seeking. /// private string searchText; + /// /// The name of the module within which we're seeking it. /// private string moduleName; + /// /// The fields within which we're seeking. /// private List fieldsToSeek; + /// /// The chains of modules we should traverse. /// private IDictionary> moduleChains; + /// /// A collection of substitutions to make in the constructed search text. /// @@ -980,17 +1038,16 @@ internal class SearchQuery /// /// A collection of modulename, fieldname pairs to order by. /// - private ISet> fieldsToOrderBy = new HashSet>(); + private ISet> fieldsToOrderBy = new HashSet>(); + - /// /// An arguably redundant property wrapped around /// ConstructSearchText, mainly for tesstability. /// - public string QueryText { get - { - return this.ConstructQueryText(); - } + public string QueryText + { + get { return this.ConstructQueryText(); } } /// @@ -998,11 +1055,13 @@ public string QueryText { get /// /// Note that the `order_by` clause of `get_entry_list` /// doesn't work reliably, because of deduping. - public string OrderClause { get + public string OrderClause + { + get { - return this.fieldsToOrderBy.Any() ? - String.Join(",", this.fieldsToOrderBy.Select(x=> x.Item2)) : - "date_entered DESC"; + return this.fieldsToOrderBy.Any() + ? String.Join(",", this.fieldsToOrderBy.Select(x => x.Item2)) + : "date_entered DESC"; } } @@ -1012,7 +1071,9 @@ public string OrderClause { get /// The text entered to search for. /// The name of the module to search. /// The list of fields to pull back, which may be modified by this method. - public SearchQuery(string searchText, string moduleName, List fieldsToSeek, IDictionary> moduleChains) + /// Any chains to follow. + public SearchQuery(string searchText, string moduleName, List fieldsToSeek, + IDictionary> moduleChains) { this.searchText = searchText; this.moduleName = moduleName; @@ -1046,7 +1107,9 @@ private string ConstructQueryTextWithFirstAndLastNames( fieldsToOrderBy.Add(new Tuple(moduleLower, "first_name")); fieldsToOrderBy.Add(new Tuple("ea", "email_address")); - result = $"({moduleLower}.first_name LIKE '%{firstName}%' {logicalOperator} {moduleLower}.last_name LIKE '%{lastName}%') OR ({moduleLower}.id in (select eabr.bean_id from email_addr_bean_rel eabr INNER JOIN email_addresses ea on eabr.email_address_id = ea.id where eabr.bean_module = '{moduleName}' and ea.email_address LIKE '%{emailAddress}%'))"; ; + result = + $"({moduleLower}.first_name LIKE '%{firstName}%' {logicalOperator} {moduleLower}.last_name LIKE '%{lastName}%') OR ({moduleLower}.id in (select eabr.bean_id from email_addr_bean_rel eabr INNER JOIN email_addresses ea on eabr.email_address_id = ea.id where eabr.bean_module = '{moduleName}' and ea.email_address LIKE '%{emailAddress}%'))"; + ; } return result; @@ -1063,7 +1126,7 @@ private string ConstructQueryTextWithFirstAndLastNames( /// The list of field names. private void AddFirstLastAndAccountNames(List fields) { - foreach (string fieldName in new string[] { "first_name", "last_name", "name", "account_name" }) + foreach (string fieldName in new string[] {"first_name", "last_name", "name", "account_name"}) { fields.Add(fieldName); this.fieldsToOrderBy.Add(new Tuple(this.moduleName, fieldName)); @@ -1083,7 +1146,7 @@ private void AddFirstLastAndAccountNames(List fields) private string ConstructQueryText() { string queryText = string.Empty; - List searchTokens = searchText.Split(new char[] { ',', ';' }).ToList(); + List searchTokens = searchText.Split(new char[] {',', ';'}).ToList(); var escapedSearchText = RestAPIWrapper.MySqlEscape(searchText); var firstTerm = RestAPIWrapper.MySqlEscape(searchTokens.First()); var lastTerm = RestAPIWrapper.MySqlEscape(searchTokens.Last()); @@ -1100,24 +1163,28 @@ private string ConstructQueryText() AddFirstLastAndAccountNames(fieldsToSeek); break; case "Cases": - queryText = $"(cases.name LIKE '%{escapedSearchText}%' OR cases.case_number LIKE '{escapedSearchText}')"; - foreach (string fieldName in new string[] { "name", "case_number" }) + queryText = + $"(cases.name LIKE '%{escapedSearchText}%' OR cases.case_number LIKE '{escapedSearchText}')"; + foreach (string fieldName in new string[] {"name", "case_number"}) { fieldsToSeek.Add(fieldName); fieldsToOrderBy.Add(new Tuple(this.moduleName, fieldName)); } break; case "Bugs": - queryText = $"(bugs.name LIKE '%{escapedSearchText}%' {logicalOperator} bugs.bug_number LIKE '{escapedSearchText}')"; - foreach (string fieldName in new string[] { "name", "bug_number" }) + queryText = + $"(bugs.name LIKE '%{escapedSearchText}%' {logicalOperator} bugs.bug_number LIKE '{escapedSearchText}')"; + foreach (string fieldName in new string[] {"name", "bug_number"}) { fieldsToSeek.Add(fieldName); fieldsToOrderBy.Add(new Tuple(this.moduleName, fieldName)); } break; case "Accounts": - queryText = "(accounts.name LIKE '%" + firstTerm + "%') OR (accounts.id in (select eabr.bean_id from email_addr_bean_rel eabr INNER JOIN email_addresses ea on eabr.email_address_id = ea.id where eabr.bean_module = 'Accounts' and ea.email_address LIKE '%" + escapedSearchText + "%'))"; - foreach (string fieldName in new string[] { "name", "account_name" }) + queryText = "(accounts.name LIKE '%" + firstTerm + + "%') OR (accounts.id in (select eabr.bean_id from email_addr_bean_rel eabr INNER JOIN email_addresses ea on eabr.email_address_id = ea.id where eabr.bean_module = 'Accounts' and ea.email_address LIKE '%" + + escapedSearchText + "%'))"; + foreach (string fieldName in new string[] {"name", "account_name"}) { this.fieldsToSeek.Add(fieldName); this.fieldsToOrderBy.Add(new Tuple(this.moduleName, fieldName)); @@ -1130,7 +1197,7 @@ private string ConstructQueryText() { /* This is Ian's suggestion */ queryText = ConstructQueryTextWithFirstAndLastNames(escapedSearchText, firstTerm, lastTerm); - foreach (string fieldName in new string[] { "first_name", "last_name" }) + foreach (string fieldName in new string[] {"first_name", "last_name"}) { fieldsToSeek.Add(fieldName); fieldsToOrderBy.Add(new Tuple(this.moduleName, fieldName)); @@ -1140,7 +1207,7 @@ private string ConstructQueryText() { queryText = ConstructQueryTextForUnknownModule(moduleName, escapedSearchText); - foreach (string fieldName in new string[] { "name", "description" }) + foreach (string fieldName in new string[] {"name", "description"}) { if (fieldNames.Contains(fieldName)) { @@ -1179,7 +1246,7 @@ private object ConstructLinkNamesToFieldsArray() foreach (var link in chain) { - links.Add(new { @name = link.LinkName, @value = link.FieldNames }); + links.Add(new {@name = link.LinkName, @value = link.FieldNames}); } result = links.ToArray(); @@ -1231,9 +1298,9 @@ public SearchQuery Replace(string pattern, string substitution) /// The pattern to replace. /// The substitution to replace it with. /// Myself, to allow chaining. - public SearchQuery Replace(Regex attern, string substitution) + public SearchQuery Replace(Regex pattern, string substitution) { - this.replacements.Add(new Tuple(attern, substitution)); + this.replacements.Add(new Tuple(pattern, substitution)); return this; } } diff --git a/SuiteCRMAddIn/Dialogs/ArchiveDialog.resx b/SuiteCRMAddIn/Dialogs/ArchiveDialog.resx index 251fb0c5..79a28605 100644 --- a/SuiteCRMAddIn/Dialogs/ArchiveDialog.resx +++ b/SuiteCRMAddIn/Dialogs/ArchiveDialog.resx @@ -117,102 +117,295 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + - AAABAAEAJCQAAAEAIACIFQAAFgAAACgAAAAkAAAASAAAAAEAIAAAAAAAQBQAAMMOAADDDgAAAAAAAAAA - AADt7/z/v8X3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ - 9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ - 9//Eyff/xMn3/8TJ9//Eyff/v8T3/+vt/P/Eyvj/P1Dm/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ - 6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ - 6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/PU7m/7/E9v/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ - 9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ - 9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ - 9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/TFzo/0ZW6P9GVuj/Rlbo/0ZW6P9GVuj/Rlbo/0ZW6P9GVuj/Rlbo/0ZW6P9GVuj/Rlbo/0ZW - 6P9GVuj/Rlbo/0ZW6P9GVuj/Okvm/73D9v/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9MXOj/qrH0/+Pm+//d4Pr/3eD6/93g+v/d4Pr/3eD6/93g - +v/d4Pr/3eD6/93g+v/d4Pr/3eD6/93g+v/d4Pr/3eD6/93g+v/d4Pr/2t36//T1/f/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/wsf4//// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////Fyvf/Slro/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////88Hyb/TzU8/081PP9PNTz/TzU8/081PP9PNTz/TzU8/081 - PP9PNTz/TzU8/081PP9PNTz/TzU8/081PP9PNTz/RCgv/8G3uf/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nB - wv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//// - //9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nB - wv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//// - //9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nB - wv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//// - //9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Eyvj/P1Dm/0lZ6P9JWej/SVno/0lZ - 6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P89Tub/usD3//////9EKC//Vz9F/1c/ - Rf9XP0X/Vz9F/1c/Rf9XP0X/Vz9F/1c/Rf9XP0X/Vz9F/1c/Rf9XP0X/Vz9F/1c/Rf9XP0X/TDI4/8S7 - vf/t7/z/v8X3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ - 9/+/xPf/6ev8///////At7n/yMDC/8jAwv/IwML/yMDC/8jAwv/IwML/yMDC/8jAwv/IwML/yMDC/8jA - wv/IwML/yMDC/8jAwv/IwML/xLu9/+3q6v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAA= + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAQEAIZU5TaGJNUpxkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RL + U6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RL + U6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RL + U6NkS1OjZEtTo2RLU6NiTVKcYEtTYoBAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhTVFuY01S+WNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL4ZExTawAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjSlVdY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2JL + Uv5hTVNZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0tT7mNM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01S6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2JMUfIAAAACAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + UvVsTU0hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0xUQ2NN + VHQAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUvNeTEwbAAAAAF1GXRZsTU0hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGNNU1BjTFL/YUxSdgAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY01TUAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NN + U1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NN + VHQAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1L6Y0tS+mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvNeTEwbAAAAAF1G + XRZjTVLwY0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNN + U1BjTFL/Y0xS/2NMUv9jTFL/Y01UdAAAAAAAAAAAY01SqGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFLnVVVVDFVVVQxiS1PnY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + UvNeTEwbAAAAAF1GXRZjTVLwY0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAA + AAAAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NN + VHQAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFLnVVVVDAAAAABYWKFUWFihVAAAAABVVVUMYktT52NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvNeTEwbAAAAAF1GXRZjTVLwY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/YUxSdgAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAAAABdXZ9NV2HU/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZN + TRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2FM + UnYAAAAAAAAAAGNMUKJjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAAAABdXZ9NV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + UvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/YUxSdgAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jS1PqbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2FM + UnYAAAAAAAAAAGNMUKJkTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01UdAAAAAAAAAAAAAAAAgAAAABZWZxQV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1v9cVqZWAAAAAFVVVQxmUlIZAAAAAF1G + XRZjTVLwY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9gTVJaAAAAAAAAAABZWZxQV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLW/1xW + plYAAAAAAAAAAF1GXRZjTVLwY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NN + U1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNN + U1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpkTVLlY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmRNUuVjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKZE1S5WNMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9kTVLpbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpkTVLlY0xS/2NM + Uv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NM + Uv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmRNUuVjTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAY01TUGNMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKZE1S5WNMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BkTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpkTVLlY01TUAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmUlIZZjNmCgAAAABZWZxQV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLW/1xW + plYAAAAAZjNmCmZSUhkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgL8IV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/V2HU/4CA + vwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhfyv5WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1lgyv0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABbWqWXVmTk/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zk5P9bW6eUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFpaqK1YYtX/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9aWqitAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZk2zFFxZpqFaXLDYW1uy3ltb + st5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltb + st5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltb + st5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeWlyw2FxZpqFmTbMUAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + ////////////////////////////////////AAAAAAAA//4AAAAAAAB//AAAAAAAAD/8AAAAAAAAP/wA + AAAAAAAf/gAAAAAAAD//AAAAAAAAf/mAAAAAAACf+MAAAAAAAR/4YAAAAAACH/gwAAAAAAQf+BgAAAAA + CB/4DAABgAAQH/gGAAJAACAf+AMABCAAQB/4AYAIEACAH/gAwBAIAQAf+ABgIAQCAB/4ADBAAgQAH/gA + GIABCAAf+AANAACQAB/4AAYAAGAAH/gABAAAIAAf+AAIAAAQAB/4ABAAAAgAH/gAIAAABAAf+ABAAAAC + AB/4AIAAAAEAH/gBAAAAAIAf+AIAAAAAQB/4BAAAAAAgH/gIAAAAABAf+BAAAAAACB/4IAAAAAAEH/hA + AAAAAAIf+IAAAAAAAR/5AAAAAAAAn/4AAAAAAAB//AAAAAAAAD/4AAAAAAAAH/wAAAAAAAA//AAAAAAA + AD/+AAAAAAAAf/8AAAAAAAD///////////////////////////////////////////////////////// + //////////////////////////////////////////////////8= \ No newline at end of file diff --git a/SuiteCRMAddIn/Dialogs/ArchiveModuleSelectFieldsDialog.Designer.cs b/SuiteCRMAddIn/Dialogs/ArchiveModuleSelectFieldsDialog.Designer.cs new file mode 100644 index 00000000..14fa175d --- /dev/null +++ b/SuiteCRMAddIn/Dialogs/ArchiveModuleSelectFieldsDialog.Designer.cs @@ -0,0 +1,142 @@ +namespace SuiteCRMAddIn.Dialogs +{ + partial class ArchiveModuleSelectFieldsDialog + { + /// + /// 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(ArchiveModuleSelectFieldsDialog)); + this.fieldsToDisplayLabel = new System.Windows.Forms.Label(); + this.modulesSelector = new System.Windows.Forms.ComboBox(); + this.okButton = new System.Windows.Forms.Button(); + this.cancelButton = new System.Windows.Forms.Button(); + this.fieldsList = new System.Windows.Forms.ListView(); + this.fieldName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.valueType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.SuspendLayout(); + // + // fieldsToDisplayLabel + // + this.fieldsToDisplayLabel.AutoSize = true; + this.fieldsToDisplayLabel.Location = new System.Drawing.Point(13, 13); + this.fieldsToDisplayLabel.Name = "fieldsToDisplayLabel"; + this.fieldsToDisplayLabel.Size = new System.Drawing.Size(133, 13); + this.fieldsToDisplayLabel.TabIndex = 0; + this.fieldsToDisplayLabel.Text = "Fields to display for module"; + // + // modulesSelector + // + this.modulesSelector.FormattingEnabled = true; + this.modulesSelector.Location = new System.Drawing.Point(153, 13); + this.modulesSelector.Name = "modulesSelector"; + this.modulesSelector.Size = new System.Drawing.Size(121, 21); + this.modulesSelector.TabIndex = 1; + this.modulesSelector.SelectedValueChanged += new System.EventHandler(this.moduleSelector_SelectionChanged); + // + // okButton + // + this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this.okButton.Location = new System.Drawing.Point(118, 232); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(75, 23); + this.okButton.TabIndex = 3; + this.okButton.Text = "OK"; + this.okButton.UseVisualStyleBackColor = true; + // + // 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(199, 232); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 4; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + // + // fieldsList + // + this.fieldsList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.fieldsList.CheckBoxes = true; + this.fieldsList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.fieldName, + this.valueType}); + this.fieldsList.Location = new System.Drawing.Point(16, 40); + this.fieldsList.Name = "fieldsList"; + this.fieldsList.Size = new System.Drawing.Size(256, 186); + this.fieldsList.TabIndex = 5; + this.fieldsList.UseCompatibleStateImageBehavior = false; + this.fieldsList.View = System.Windows.Forms.View.Details; + // + // fieldName + // + this.fieldName.Text = "Field Name"; + this.fieldName.Width = 129; + // + // valueType + // + this.valueType.Text = "ValueType"; + this.valueType.Width = 122; + // + // ArchiveModuleSelectFieldsDialog + // + this.AcceptButton = this.okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(284, 262); + this.Controls.Add(this.fieldsList); + this.Controls.Add(this.cancelButton); + this.Controls.Add(this.okButton); + this.Controls.Add(this.modulesSelector); + this.Controls.Add(this.fieldsToDisplayLabel); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(300, 300); + this.Name = "ArchiveModuleSelectFieldsDialog"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Select Fields to Display"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label fieldsToDisplayLabel; + private System.Windows.Forms.ComboBox modulesSelector; + private System.Windows.Forms.Button okButton; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.ListView fieldsList; + private System.Windows.Forms.ColumnHeader fieldName; + private System.Windows.Forms.ColumnHeader valueType; + } +} \ No newline at end of file diff --git a/SuiteCRMAddIn/Dialogs/ArchiveModuleSelectFieldsDialog.cs b/SuiteCRMAddIn/Dialogs/ArchiveModuleSelectFieldsDialog.cs new file mode 100644 index 00000000..1bb587e2 --- /dev/null +++ b/SuiteCRMAddIn/Dialogs/ArchiveModuleSelectFieldsDialog.cs @@ -0,0 +1,70 @@ +using SuiteCRMClient; +using SuiteCRMClient.Logging; +using SuiteCRMClient.RESTObjects; +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 SuiteCRMAddIn.Dialogs +{ + public partial class ArchiveModuleSelectFieldsDialog : Form + { + private readonly AvailableModules _availableModules; + + public ArchiveModuleSelectFieldsDialog() + { + InitializeComponent(); + + _availableModules = RestAPIWrapper.GetModules(); + this.AddStandardModules(); + } + + /// + /// Add the standard modules to the list view. + /// + private void AddStandardModules() + { + this.modulesSelector.Items.Clear(); + + foreach (var module in ArchiveDialog.standardModules) + { + if (module != null) + { + this.modulesSelector.Items.Add(module); + } + } + } + + + public ArchiveModuleSelectFieldsDialog(string text) : this() + { + var selectedIndex = modulesSelector.FindString(text); + + if (selectedIndex >= 0) + { + this.modulesSelector.SelectedItem = this.modulesSelector.Items[selectedIndex]; + } + } + + private void moduleSelector_SelectionChanged(object sender, EventArgs e) + { + this.fieldsList.Items.Clear(); + + foreach (var fieldName in new string[] {"Sample", "Field", "Names"}) + { + fieldsList.Items.Add( new ListViewItem + { + Tag = fieldName, + Text = fieldName, + Checked = false + }); + } + } + } +} diff --git a/SuiteCRMAddIn/Dialogs/ArchiveModuleSelectFieldsDialog.resx b/SuiteCRMAddIn/Dialogs/ArchiveModuleSelectFieldsDialog.resx new file mode 100644 index 00000000..710554de --- /dev/null +++ b/SuiteCRMAddIn/Dialogs/ArchiveModuleSelectFieldsDialog.resx @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAQEAIZU5TaGJNUpxkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RL + U6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RL + U6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RL + U6NkS1OjZEtTo2RLU6NiTVKcYEtTYoBAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhTVFuY01S+WNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL4ZExTawAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjSlVdY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2JL + Uv5hTVNZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0tT7mNM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01S6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2JMUfIAAAACAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + UvVsTU0hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0xUQ2NN + VHQAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUvNeTEwbAAAAAF1GXRZsTU0hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGNNU1BjTFL/YUxSdgAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY01TUAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NN + U1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NN + VHQAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1L6Y0tS+mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvNeTEwbAAAAAF1G + XRZjTVLwY0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNN + U1BjTFL/Y0xS/2NMUv9jTFL/Y01UdAAAAAAAAAAAY01SqGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFLnVVVVDFVVVQxiS1PnY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + UvNeTEwbAAAAAF1GXRZjTVLwY0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAA + AAAAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NN + VHQAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFLnVVVVDAAAAABYWKFUWFihVAAAAABVVVUMYktT52NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvNeTEwbAAAAAF1GXRZjTVLwY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/YUxSdgAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAAAABdXZ9NV2HU/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZN + TRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2FM + UnYAAAAAAAAAAGNMUKJjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAAAABdXZ9NV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + UvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/YUxSdgAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jS1PqbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2FM + UnYAAAAAAAAAAGNMUKJkTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01UdAAAAAAAAAAAAAAAAgAAAABZWZxQV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1v9cVqZWAAAAAFVVVQxmUlIZAAAAAF1G + XRZjTVLwY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9gTVJaAAAAAAAAAABZWZxQV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLW/1xW + plYAAAAAAAAAAF1GXRZjTVLwY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NN + U1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNN + U1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpkTVLlY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmRNUuVjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKZE1S5WNMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9kTVLpbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpkTVLlY0xS/2NM + Uv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NM + Uv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmRNUuVjTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAY01TUGNMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKZE1S5WNMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BkTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpkTVLlY01TUAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmUlIZZjNmCgAAAABZWZxQV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLW/1xW + plYAAAAAZjNmCmZSUhkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgL8IV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/V2HU/4CA + vwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhfyv5WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1lgyv0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABbWqWXVmTk/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zk5P9bW6eUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFpaqK1YYtX/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9aWqitAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZk2zFFxZpqFaXLDYW1uy3ltb + st5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltb + st5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltb + st5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeWlyw2FxZpqFmTbMUAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + ////////////////////////////////////AAAAAAAA//4AAAAAAAB//AAAAAAAAD/8AAAAAAAAP/wA + AAAAAAAf/gAAAAAAAD//AAAAAAAAf/mAAAAAAACf+MAAAAAAAR/4YAAAAAACH/gwAAAAAAQf+BgAAAAA + CB/4DAABgAAQH/gGAAJAACAf+AMABCAAQB/4AYAIEACAH/gAwBAIAQAf+ABgIAQCAB/4ADBAAgQAH/gA + GIABCAAf+AANAACQAB/4AAYAAGAAH/gABAAAIAAf+AAIAAAQAB/4ABAAAAgAH/gAIAAABAAf+ABAAAAC + AB/4AIAAAAEAH/gBAAAAAIAf+AIAAAAAQB/4BAAAAAAgH/gIAAAAABAf+BAAAAAACB/4IAAAAAAEH/hA + AAAAAAIf+IAAAAAAAR/5AAAAAAAAn/4AAAAAAAB//AAAAAAAAD/4AAAAAAAAH/wAAAAAAAA//AAAAAAA + AD/+AAAAAAAAf/8AAAAAAAD///////////////////////////////////////////////////////// + //////////////////////////////////////////////////8= + + + \ No newline at end of file diff --git a/SuiteCRMAddIn/Dialogs/ConfirmRearchiveAlreadyArchivedEmails.Designer.cs b/SuiteCRMAddIn/Dialogs/ConfirmRearchiveAlreadyArchivedEmails.Designer.cs index e3d73e37..74f324ea 100644 --- a/SuiteCRMAddIn/Dialogs/ConfirmRearchiveAlreadyArchivedEmails.Designer.cs +++ b/SuiteCRMAddIn/Dialogs/ConfirmRearchiveAlreadyArchivedEmails.Designer.cs @@ -154,7 +154,6 @@ private void InitializeComponent() this.MinimumSize = new System.Drawing.Size(620, 250); this.Name = "ConfirmRearchiveAlreadyArchivedEmails"; this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Confirm Rearchive Already Archived Emails"; ((System.ComponentModel.ISupportInitialize)(this.alreadyArchivedEmailsGrid)).EndInit(); this.ResumeLayout(false); diff --git a/SuiteCRMAddIn/Dialogs/ConfirmRearchiveAlreadyArchivedEmails.resx b/SuiteCRMAddIn/Dialogs/ConfirmRearchiveAlreadyArchivedEmails.resx index 000e0cb8..6077f3a3 100644 --- a/SuiteCRMAddIn/Dialogs/ConfirmRearchiveAlreadyArchivedEmails.resx +++ b/SuiteCRMAddIn/Dialogs/ConfirmRearchiveAlreadyArchivedEmails.resx @@ -132,99 +132,289 @@ - AAABAAEAJCQAAAEAIACIFQAAFgAAACgAAAAkAAAASAAAAAEAIAAAAAAAQBQAAMMOAADDDgAAAAAAAAAA - AADt7/z/v8X3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ - 9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ - 9//Eyff/xMn3/8TJ9//Eyff/v8T3/+vt/P/Eyvj/P1Dm/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ - 6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ - 6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/PU7m/7/E9v/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ - 9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ - 9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/SVno/8TJ - 9//Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/TFzo/0ZW6P9GVuj/Rlbo/0ZW6P9GVuj/Rlbo/0ZW6P9GVuj/Rlbo/0ZW6P9GVuj/Rlbo/0ZW - 6P9GVuj/Rlbo/0ZW6P9GVuj/Okvm/73D9v/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9MXOj/qrH0/+Pm+//d4Pr/3eD6/93g+v/d4Pr/3eD6/93g - +v/d4Pr/3eD6/93g+v/d4Pr/3eD6/93g+v/d4Pr/3eD6/93g+v/d4Pr/2t36//T1/f/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/wsf4//// - //////////////////////////////////////////////////////////////////////////////// - ///////////////////Fyvf/Slro/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////88Hyb/TzU8/081PP9PNTz/TzU8/081PP9PNTz/TzU8/081 - PP9PNTz/TzU8/081PP9PNTz/TzU8/081PP9PNTz/RCgv/8G3uf/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nB - wv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//// - //9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nB - wv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//// - //9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nB - wv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk - 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9JWej/v8T3//// - //9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Vz9F/8nBwv/Jzvj/S1vo/1Vk6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl - 6v9WZer/VmXq/1Zl6v9JWej/v8T3//////9PNTz/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM - Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Vz9F/8nBwv/Eyvj/P1Dm/0lZ6P9JWej/SVno/0lZ - 6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P9JWej/SVno/0lZ6P89Tub/usD3//////9EKC//Vz9F/1c/ - Rf9XP0X/Vz9F/1c/Rf9XP0X/Vz9F/1c/Rf9XP0X/Vz9F/1c/Rf9XP0X/Vz9F/1c/Rf9XP0X/TDI4/8S7 - vf/t7/z/v8X3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ9//Eyff/xMn3/8TJ - 9/+/xPf/6ev8///////At7n/yMDC/8jAwv/IwML/yMDC/8jAwv/IwML/yMDC/8jAwv/IwML/yMDC/8jA - wv/IwML/yMDC/8jAwv/IwML/xLu9/+3q6v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAA= + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAQEAIZU5TaGJNUpxkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RL + U6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RL + U6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RLU6NkS1OjZEtTo2RL + U6NkS1OjZEtTo2RLU6NiTVKcYEtTYoBAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhTVFuY01S+WNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL4ZExTawAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjSlVdY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2JL + Uv5hTVNZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0tT7mNM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01S6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2JMUfIAAAACAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + UvVsTU0hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0xUQ2NN + VHQAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUvNeTEwbAAAAAF1GXRZsTU0hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGNNU1BjTFL/YUxSdgAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY01TUAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NN + U1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NN + VHQAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1L6Y0tS+mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvNeTEwbAAAAAF1G + XRZjTVLwY0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNN + U1BjTFL/Y0xS/2NMUv9jTFL/Y01UdAAAAAAAAAAAY01SqGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFLnVVVVDFVVVQxiS1PnY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + UvNeTEwbAAAAAF1GXRZjTVLwY0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAA + AAAAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NN + VHQAAAAAAAAAAGNNUqhjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFLnVVVVDAAAAABYWKFUWFihVAAAAABVVVUMYktT52NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvNeTEwbAAAAAF1GXRZjTVLwY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/YUxSdgAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAAAABdXZ9NV2HU/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZN + TRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2FM + UnYAAAAAAAAAAGNMUKJjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAAAABdXZ9NV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + UvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/YUxSdgAAAAAAAAAAY0xQomNMUv9jTFL/Y0xS/2NMUv9jS1PqbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9hTFJ2AAAAAAAAAABjTFCiY0xS/2NM + Uv9jS1PqbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2FM + UnYAAAAAAAAAAGNMUKJkTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUvVsTU0hAAAAAGZNTRRkTVPuY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01UdAAAAAAAAAAAAAAAAgAAAABZWZxQV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1v9cVqZWAAAAAFVVVQxmUlIZAAAAAF1G + XRZjTVLwY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9gTVJaAAAAAAAAAABZWZxQV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLW/1xW + plYAAAAAAAAAAF1GXRZjTVLwY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NN + U1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNN + U1BjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpjS1LmY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmNLUuZjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKY0tS5mNMUv9jTFL/Y0xS/2NMUv9jTFL/Y0xS/2NM + Uv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NM + Uv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpkTVLlY0xS/2NM + Uv9jTFL/Y0xS/2NMUv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABjTVNQY0xS/2NMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmRNUuVjTFL/Y0xS/2NMUv9jTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAY01TUGNMUv9jTFL/Y0xS/2NMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKZE1S5WNMUv9jTFL/Y0xS/2NMUv9jTVNQAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BjTFL/Y0xS/2NMUv9kTVLpbUlJDgAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpkTVLlY0xS/2NM + Uv9jTFL/Y01TUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjTVNQY0xS/2NM + Uv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLV/1xZ + oFkAAAAAZjNmCmRNUuVjTFL/Y0xS/2NNU1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAY01TUGNMUv9kTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAABmM2YKZE1S5WNMUv9jTVNQAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGNNU1BkTVLpbUlJDgAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAGYzZgpkTVLlY01TUAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmUlIZZjNmCgAAAABZWZxQV2HU/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/WGLW/1xW + plYAAAAAZjNmCmZSUhkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9YYtX/XFmgWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABdXZ9NV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9cWaBZAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgL8IV2HU/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/V2HU/4CA + vwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhfyv5WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1lgyv0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABbWqWXVmTk/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zk5P9bW6eUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFpaqK1YYtX/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1hi1f9aWqitAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZk2zFFxZpqFaXLDYW1uy3ltb + st5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltb + st5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltb + st5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeW1uy3ltbst5bW7LeWlyw2FxZpqFmTbMUAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + ////////////////////////////////////AAAAAAAA//4AAAAAAAB//AAAAAAAAD/8AAAAAAAAP/wA + AAAAAAAf/gAAAAAAAD//AAAAAAAAf/mAAAAAAACf+MAAAAAAAR/4YAAAAAACH/gwAAAAAAQf+BgAAAAA + CB/4DAABgAAQH/gGAAJAACAf+AMABCAAQB/4AYAIEACAH/gAwBAIAQAf+ABgIAQCAB/4ADBAAgQAH/gA + GIABCAAf+AANAACQAB/4AAYAAGAAH/gABAAAIAAf+AAIAAAQAB/4ABAAAAgAH/gAIAAABAAf+ABAAAAC + AB/4AIAAAAEAH/gBAAAAAIAf+AIAAAAAQB/4BAAAAAAgH/gIAAAAABAf+BAAAAAACB/4IAAAAAAEH/hA + AAAAAAIf+IAAAAAAAR/5AAAAAAAAn/4AAAAAAAB//AAAAAAAAD/4AAAAAAAAH/wAAAAAAAA//AAAAAAA + AD/+AAAAAAAAf/8AAAAAAAD///////////////////////////////////////////////////////// + //////////////////////////////////////////////////8= \ No newline at end of file diff --git a/SuiteCRMAddIn/Dialogs/CustomModulesDialog.Designer.cs b/SuiteCRMAddIn/Dialogs/CustomModulesDialog.Designer.cs index ce5d2c7d..0b12d4a7 100644 --- a/SuiteCRMAddIn/Dialogs/CustomModulesDialog.Designer.cs +++ b/SuiteCRMAddIn/Dialogs/CustomModulesDialog.Designer.cs @@ -133,7 +133,6 @@ private void InitializeComponent() this.MinimumSize = new System.Drawing.Size(331, 321); this.Name = "CustomModulesDialog"; this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "SuiteCRM Custom Modules"; this.Load += new System.EventHandler(this.frmCustomModules_Load); this.ResumeLayout(false); diff --git a/SuiteCRMAddIn/Dialogs/ManualSyncContactForm.Designer.cs b/SuiteCRMAddIn/Dialogs/ManualSyncContactForm.Designer.cs new file mode 100644 index 00000000..3e9e32f7 --- /dev/null +++ b/SuiteCRMAddIn/Dialogs/ManualSyncContactForm.Designer.cs @@ -0,0 +1,139 @@ +namespace SuiteCRMAddIn.Dialogs +{ + partial class ManualSyncContactForm + { + /// + /// 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(ManualSyncContactForm)); + this.useLabel = new System.Windows.Forms.Label(); + this.resultsTree = new System.Windows.Forms.TreeView(); + this.cancelButton = new System.Windows.Forms.Button(); + this.saveButton = new System.Windows.Forms.Button(); + this.searchText = new System.Windows.Forms.TextBox(); + this.searchButton = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // useLabel + // + this.useLabel.AutoSize = true; + this.useLabel.Location = new System.Drawing.Point(12, 9); + this.useLabel.Name = "useLabel"; + this.useLabel.Size = new System.Drawing.Size(230, 13); + this.useLabel.TabIndex = 0; + this.useLabel.Text = "Use the form below to find records in SuiteCRM"; + // + // resultsTree + // + this.resultsTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.resultsTree.CheckBoxes = true; + this.resultsTree.Location = new System.Drawing.Point(15, 56); + this.resultsTree.Name = "resultsTree"; + this.resultsTree.Size = new System.Drawing.Size(257, 165); + this.resultsTree.TabIndex = 3; + this.resultsTree.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.resultsTree_ItemClick); + // + // 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(197, 227); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 5; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + this.cancelButton.Click += new System.EventHandler(this.cancelButton_click); + // + // saveButton + // + this.saveButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.saveButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this.saveButton.Enabled = false; + this.saveButton.Location = new System.Drawing.Point(116, 227); + this.saveButton.Name = "saveButton"; + this.saveButton.Size = new System.Drawing.Size(75, 23); + this.saveButton.TabIndex = 4; + this.saveButton.Text = "Save"; + this.saveButton.UseVisualStyleBackColor = true; + this.saveButton.Click += new System.EventHandler(this.saveButton_click); + // + // searchText + // + this.searchText.Location = new System.Drawing.Point(15, 30); + this.searchText.Name = "searchText"; + this.searchText.Size = new System.Drawing.Size(176, 20); + this.searchText.TabIndex = 1; + this.searchText.Leave += new System.EventHandler(this.searchButton_click); + this.searchText.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.seachText_PreviewKeyDown); + // + // searchButton + // + this.searchButton.Location = new System.Drawing.Point(197, 30); + this.searchButton.Name = "searchButton"; + this.searchButton.Size = new System.Drawing.Size(75, 23); + this.searchButton.TabIndex = 2; + this.searchButton.Text = "Search"; + this.searchButton.UseVisualStyleBackColor = true; + this.searchButton.Click += new System.EventHandler(this.searchButton_click); + // + // ManualSyncContactForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(284, 262); + this.Controls.Add(this.searchButton); + this.Controls.Add(this.searchText); + this.Controls.Add(this.saveButton); + this.Controls.Add(this.cancelButton); + this.Controls.Add(this.resultsTree); + this.Controls.Add(this.useLabel); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(300, 300); + this.Name = "ManualSyncContactForm"; + this.Text = "Manually Sync a Contact"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormClosingEvent); + this.Load += new System.EventHandler(this.manualSyncContactsForm_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label useLabel; + private System.Windows.Forms.TreeView resultsTree; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Button saveButton; + private System.Windows.Forms.TextBox searchText; + private System.Windows.Forms.Button searchButton; + } +} \ No newline at end of file diff --git a/SuiteCRMAddIn/Dialogs/ManualSyncContactForm.cs b/SuiteCRMAddIn/Dialogs/ManualSyncContactForm.cs new file mode 100644 index 00000000..90601907 --- /dev/null +++ b/SuiteCRMAddIn/Dialogs/ManualSyncContactForm.cs @@ -0,0 +1,270 @@ +/** + * Outlook integration for SuiteCRM. + * @package Outlook integration for SuiteCRM + * @copyright SalesAgility Ltd http://www.salesagility.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU LESSER GENERAL PUBLIC LICENCE as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENCE + * along with this program; if not, see http://www.gnu.org/licenses + * or write to the Free Software Foundation,Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA + * + * @author SalesAgility + */ + +#region + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; +using Microsoft.Office.Interop.Outlook; +using SuiteCRMAddIn.BusinessLogic; +using SuiteCRMAddIn.Extensions; +using SuiteCRMAddIn.Helpers; +using SuiteCRMAddIn.Properties; +using SuiteCRMClient.RESTObjects; +using System.Text; + +#endregion + +namespace SuiteCRMAddIn.Dialogs +{ + public partial class ManualSyncContactForm : Form + { + /// + /// The key for the create node. + /// + private static readonly string CreateNodeKey = "Create"; + + /// + /// The key for the contacts node. + /// + private static readonly string ContactsNodeKey = "Contacts"; + + private Dictionary searchResults = new Dictionary(); + + private bool dontClose = false; + + /// + /// The contact we're going to operate on. + /// + ContactItem contactItem = Globals.ThisAddIn.SelectedContacts.First(); + + public ManualSyncContactForm(string searchString) + { + if (contactItem != null) + { + InitializeComponent(); + this.Text = $"Manually sync {contactItem.FullName}"; + searchText.Text = searchString; + } + else + { + throw new System.Exception("No contact selected in ManualSyncContactForm"); + } + } + + private void ClearAndSearch(string target) + { + using (WaitCursor.For(this, true)) + { + searchResults = new Dictionary(); + + resultsTree.Nodes.Clear(); + resultsTree.Nodes.Add(CreateNodeKey, "Create a new Contact"); + + if (!string.IsNullOrWhiteSpace(target)) + { + var contactsNode = resultsTree.Nodes.Add(ContactsNodeKey, "Contacts"); + + SearchAddChildren(target, contactsNode); + + if (contactsNode.Nodes.Count == 0) + { + resultsTree.Nodes.Remove(contactsNode); + resultsTree.Nodes[CreateNodeKey].Checked = true; + saveButton.Enabled = true; + } + } + } + } + + private void SearchAddChildren(string target, TreeNode contactsNode) + { + var tokens = target.Split(" ;:,".ToCharArray()); + + foreach (var token in tokens.Where(x => !string.IsNullOrEmpty(x))) + foreach (var crmContact in SearchHelper.SearchContacts(token)) + searchResults[crmContact.id] = crmContact; + + foreach (var result in searchResults.Values.OrderBy( + x => $"{x.GetValueAsString("last_name")} {x.GetValueAsString("first_name")}")) + { + TreeNode node = contactsNode.Nodes.Add(result.id, CanonicalString(result)); + var contactItem = Globals.ThisAddIn.SelectedContacts.First(); + + if (IsProbablySameItem(result, contactItem)) + { + node.BackColor = ColorTranslator.FromHtml("#a9ea56"); + } + else if (IsPreviouslySyncedItem(result)) + { + node.BackColor = ColorTranslator.FromHtml("#ea6556"); + } + else if (SyncStateManager.Instance.GetExistingSyncState(result) != null) + { + node.BackColor = ColorTranslator.FromHtml("#ea6556"); + } + + contactsNode.Expand(); + } + } + + private bool IsPreviouslySyncedItem(string crmId) + { + return !string.IsNullOrEmpty(crmId) && + searchResults.ContainsKey(crmId) && + IsPreviouslySyncedItem(searchResults[crmId]); + } + + private bool IsPreviouslySyncedItem(EntryValue result) + { + return !string.IsNullOrEmpty(result.GetValueAsString("outlook_id")) || + !string.IsNullOrEmpty(result.GetValueAsString("sync_contact")) || + SyncStateManager.Instance.GetExistingSyncState(result) != null; + } + + private bool IsProbablySameItem(EntryValue result, ContactItem contactItem) + { + return result != null && + (result.id.Equals(contactItem.UserProperties[SyncStateManager.CrmIdPropertyName]?.Value) || + result.GetValueAsString("outlook_id")?.Equals(contactItem.EntryID)); + } + + private static string CanonicalString(EntryValue result) + { + return + $"{result.GetValueAsString("first_name")} {result.GetValueAsString("last_name")} ({result.GetValueAsString("email1")})"; + } + + private void searchButton_click(object sender, EventArgs e) + { + ClearAndSearch(searchText.Text); + } + + private void saveButton_click(object sender, EventArgs e) + { + var crmId = contactItem.GetCrmId().ToString(); + string selectedId = resultsTree.GetAllNodes().FirstOrDefault(x => x.Checked)?.Name; + EntryValue selectedItem = searchResults.ContainsKey(selectedId) ? searchResults[selectedId] : null; + List problems = new List(); + + if (contactItem.Sensitivity == OlSensitivity.olPrivate) + { + problems.Add($"Contact {contactItem.FullName} is marked 'private'. Are you sure?"); + } + + if (resultsTree.Nodes["create"].Checked && IsPreviouslySyncedItem(crmId)) + { + problems.Add($"A record for contact {contactItem.FullName} already exists in CRM. Are you sure you want to create a new record?"); + } + if (selectedItem != null && + !IsProbablySameItem(selectedItem, contactItem)) + { + problems.Add($"The record for {selectedItem.GetValueAsString("first_name")} {selectedItem.GetValueAsString("last_name")} will be overwritten with the details of {contactItem.FullName}."); + } + if (IsPreviouslySyncedItem(crmId) && selectedItem != null) + { + problems.Add($"Contact {selectedItem.GetValueAsString("first_name")} {selectedItem.GetValueAsString("last_name")} has previously been synced and will be overwritten."); + } + + if (resultsTree.Nodes["create"].Checked && + IsPreviouslySyncedItem(crmId) ) + { + problems.Add($"Contact {contactItem.FullName} has previously been synced. Are you sure you want to create another copy?"); + } + + if (problems.Count == 0 || MessageBox.Show( + string.Join("\n", problems.Select(p => $"• {p}\n").ToArray()), + "Problems found: are you sure?", + MessageBoxButtons.OKCancel, + MessageBoxIcon.Warning) == + DialogResult.OK) + { + if (resultsTree.Nodes["create"].Checked) + { + contactItem.ClearCrmId(); + contactItem.SetManualOverride(); + } + else + { + try + { + contactItem.ChangeCrmId(resultsTree.GetAllNodes().FirstOrDefault(x => x.Checked).Name); + } + finally + { + contactItem.SetManualOverride(); + } + } + } + else + { + dontClose = true; + } + } + + private void cancelButton_click(object sender, EventArgs e) + { + Close(); + } + + private void resultsTree_ItemClick(object sender, TreeNodeMouseClickEventArgs e) + { + var contactsNode = resultsTree.Nodes[ContactsNodeKey]; + var createNode = resultsTree.Nodes[CreateNodeKey]; + + if (e.Node == contactsNode) + { + e.Node.Checked = false; + // You can't check the 'Contacts' node. + } + else + { + foreach (var node in resultsTree.GetAllNodes().Where( n => n != e.Node)) + node.Checked = false; + } + + saveButton.Enabled = resultsTree.GetAllNodes().Any(x => x.Checked); + } + + private void manualSyncContactsForm_Load(object sender, EventArgs e) + { + if (Settings.Default.AutomaticSearch) + BeginInvoke((MethodInvoker) delegate { ClearAndSearch(searchText.Text); }); + } + + private void seachText_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + { + if (e.KeyCode == Keys.Enter && !string.IsNullOrWhiteSpace(searchText.Text)) + ClearAndSearch(searchText.Text); + } + + private void FormClosingEvent(object sender, FormClosingEventArgs e) + { + e.Cancel = dontClose; + dontClose = false; + } + } +} \ No newline at end of file diff --git a/SuiteCRMAddIn/Dialogs/ManualSyncContactForm.resx b/SuiteCRMAddIn/Dialogs/ManualSyncContactForm.resx new file mode 100644 index 00000000..45f9e24c --- /dev/null +++ b/SuiteCRMAddIn/Dialogs/ManualSyncContactForm.resx @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADqVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOpWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADqVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAOpWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADqVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOpW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADqVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADqVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADqVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+lWaL0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADqVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAOpWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP9VAFUDAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADpVmib6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOpW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAE6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/pVmi9AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADqVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAOpWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/4AA + gAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOpWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADqVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pWaP/qVmj/6lZo/+pW + aP/qVmj/6lZo/1UAVQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXf/kYV3/5GFd/+RhXf/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABWZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/AAD/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV3/5GF + d/+RhXf/kYV3/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAFZl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/AAD/AgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJGFd/+RhXf/kYV3/5GFd/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAD/AVZl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXf/kYV3/5GFd/+RhXf/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV3/5GFd/+RhXf/kYV3/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/AAD/AgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGF + d/+RhXf/kYV3/5GFd/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACRhXf/kYV3/5GFd/+RhXf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABWZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/AAD/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV3/5GFd/+RhXf/kYV3/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACRhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/wAAAAAAAAAAVmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/8AAAAAAAAAAFZl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/AAAAAAAAAABWZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACRhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/wAAAAAAAAAAVmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GF + d/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/+RhXf/kYV3/5GFd/8AAAAAAAAAAFZl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAkYV3/5GFd/+RhXf/kYV3/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAVmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGFd/+RhXf/kYV3/5GFd/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXf/kYV3/5GFd/+RhXf/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV3/5GF + d/+RhXf/kYV3/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJGFd/+RhXf/kYV3/5GFd/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAVmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/AAD/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRhXf/kYV3/5GFd/+RhXf/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWZer/VmXq/1Zl6v9WZer/VmXq/1Zl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkYV3/5GFd/+RhXf/kYV3/wAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZl + 6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/VmXq/1Zl6v9WZer/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJGF + d/+RhXf/kYV3/5GFd/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWZer/VmXq/1Zl6v9WZer/VmXq/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/////////////////////////////////////////////////////////gAAAP/////AAAAA + A////gAAAAAAf//8AAAAAAAf//gAAAAAAA//+AAAAAAAD//4AAAAAAAP//gAAAAAAA//+AAAAAAAD//4 + AAAAAAAP//wAAAAAAA///AAAAAAAH//8AAAAAAAf//4AAAAAAB///gAAAAAAP///AAAAAAA///8AAAAA + AH///4AAAAAA////wAAAAAD////AAAAAAf///+AAAAAD////8AAAAAf////4AAAAD/////4AAAA///// + /wAAAH//////wAAB///////4AA////////////////D//4B/////8P/+AB/////w//gAD/////D/+AAH + ////8P/wAAP////w/+AAA/////D/4AAB////8P/gAAH///AAAMAAAf//8AAAwAAB///wAADAAAH///AA + AMAAAf//8AAAwAAB////8P/gAAH////w/+AAA/////D/4AAD////8P/wAAf////w//gAB/////D//AAf + ////8P/+AD/////w///B//////////////////////////////////////////////////////////// + //////////////////////////////////////////////////8= + + + \ No newline at end of file diff --git a/SuiteCRMAddIn/Dialogs/ReconfigureOrDisableDialog.Designer.cs b/SuiteCRMAddIn/Dialogs/ReconfigureOrDisableDialog.Designer.cs index 69cf297d..0b616883 100644 --- a/SuiteCRMAddIn/Dialogs/ReconfigureOrDisableDialog.Designer.cs +++ b/SuiteCRMAddIn/Dialogs/ReconfigureOrDisableDialog.Designer.cs @@ -56,6 +56,7 @@ private void InitializeComponent() this.question = new System.Windows.Forms.TextBox(); this.DisableButton = new System.Windows.Forms.Button(); this.ReconfigureButton = new System.Windows.Forms.Button(); + this.retryButton = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.icon)).BeginInit(); this.SuspendLayout(); // @@ -79,6 +80,9 @@ private void InitializeComponent() // // question // + this.question.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.question.BorderStyle = System.Windows.Forms.BorderStyle.None; this.question.Enabled = false; this.question.Location = new System.Drawing.Point(80, 36); @@ -92,25 +96,36 @@ private void InitializeComponent() // // DisableButton // + this.DisableButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.DisableButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.DisableButton.Location = new System.Drawing.Point(455, 85); + this.DisableButton.Location = new System.Drawing.Point(455, 84); this.DisableButton.Name = "DisableButton"; this.DisableButton.Size = new System.Drawing.Size(75, 23); - this.DisableButton.TabIndex = 2; + this.DisableButton.TabIndex = 3; this.DisableButton.Text = "Disable"; this.DisableButton.UseVisualStyleBackColor = true; - this.DisableButton.Click += new System.EventHandler(this.DisableButton_Click); // // ReconfigureButton // + this.ReconfigureButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.ReconfigureButton.DialogResult = System.Windows.Forms.DialogResult.OK; this.ReconfigureButton.Location = new System.Drawing.Point(374, 84); this.ReconfigureButton.Name = "ReconfigureButton"; this.ReconfigureButton.Size = new System.Drawing.Size(75, 23); - this.ReconfigureButton.TabIndex = 1; + this.ReconfigureButton.TabIndex = 2; this.ReconfigureButton.Text = "Reconfigure"; this.ReconfigureButton.UseVisualStyleBackColor = true; - this.ReconfigureButton.Click += new System.EventHandler(this.ReconfigureButton_Click); + // + // retryButton + // + this.retryButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.retryButton.DialogResult = System.Windows.Forms.DialogResult.Retry; + this.retryButton.Location = new System.Drawing.Point(293, 84); + this.retryButton.Name = "retryButton"; + this.retryButton.Size = new System.Drawing.Size(75, 23); + this.retryButton.TabIndex = 1; + this.retryButton.Text = "Retry"; + this.retryButton.UseVisualStyleBackColor = true; // // ReconfigureOrDisableDialog // @@ -118,6 +133,7 @@ private void InitializeComponent() this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoSize = true; this.ClientSize = new System.Drawing.Size(542, 116); + this.Controls.Add(this.retryButton); this.Controls.Add(this.ReconfigureButton); this.Controls.Add(this.DisableButton); this.Controls.Add(this.question); @@ -145,5 +161,6 @@ private void InitializeComponent() private System.Windows.Forms.TextBox question; private System.Windows.Forms.Button DisableButton; private System.Windows.Forms.Button ReconfigureButton; + private System.Windows.Forms.Button retryButton; } } \ No newline at end of file diff --git a/SuiteCRMAddIn/Dialogs/ReconfigureOrDisableDialog.cs b/SuiteCRMAddIn/Dialogs/ReconfigureOrDisableDialog.cs index 92b937e0..a0830653 100644 --- a/SuiteCRMAddIn/Dialogs/ReconfigureOrDisableDialog.cs +++ b/SuiteCRMAddIn/Dialogs/ReconfigureOrDisableDialog.cs @@ -45,20 +45,12 @@ public ReconfigureOrDisableDialog() /// taken from this summary. /// /// Summary of the problem. - public ReconfigureOrDisableDialog(string summary) :this() + /// True if the action is retryable. + public ReconfigureOrDisableDialog(string summary, bool allowRetry) :this() { + this.retryButton.Enabled = allowRetry; this.heading.Text = $"{summary} for the SuiteCRM add-in"; this.Text = summary; } - - private void DisableButton_Click(object sender, EventArgs e) - { - this.DialogResult = DialogResult.Cancel; - } - - private void ReconfigureButton_Click(object sender, EventArgs e) - { - this.DialogResult = DialogResult.OK; - } } } diff --git a/SuiteCRMAddIn/Dialogs/SettingsDialog.Designer.cs b/SuiteCRMAddIn/Dialogs/SettingsDialog.Designer.cs index 05771143..4ceee013 100644 --- a/SuiteCRMAddIn/Dialogs/SettingsDialog.Designer.cs +++ b/SuiteCRMAddIn/Dialogs/SettingsDialog.Designer.cs @@ -101,6 +101,7 @@ private void InitializeComponent() this.syncContactsLabel = new System.Windows.Forms.Label(); this.syncLabel = new System.Windows.Forms.Label(); this.InformationTabPage = new System.Windows.Forms.TabPage(); + this.dotNetVersionLabel = new System.Windows.Forms.Label(); this.AddInVersionLabel = new System.Windows.Forms.Label(); this.groupBox4 = new System.Windows.Forms.GroupBox(); this.crmIdValidationSelector = new System.Windows.Forms.ComboBox(); @@ -117,7 +118,6 @@ private void InitializeComponent() this.AddInTitleLabel = new System.Windows.Forms.Label(); this.btnCancel = new System.Windows.Forms.Button(); this.btnSave = new System.Windows.Forms.Button(); - this.dotNetVersionLabel = new System.Windows.Forms.Label(); this.tabPage3.SuspendLayout(); this.EmailArchiveAccountTabs.SuspendLayout(); this.tabPage2.SuspendLayout(); @@ -626,6 +626,16 @@ private void InitializeComponent() this.InformationTabPage.Text = "Information"; this.InformationTabPage.UseVisualStyleBackColor = true; // + // dotNetVersionLabel + // + this.dotNetVersionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.dotNetVersionLabel.Location = new System.Drawing.Point(13, 77); + this.dotNetVersionLabel.Name = "dotNetVersionLabel"; + this.dotNetVersionLabel.Size = new System.Drawing.Size(332, 16); + this.dotNetVersionLabel.TabIndex = 7; + this.dotNetVersionLabel.Text = ".Net version 0.0.0"; + this.dotNetVersionLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; + // // AddInVersionLabel // this.AddInVersionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); @@ -779,16 +789,6 @@ private void InitializeComponent() this.btnSave.UseVisualStyleBackColor = true; this.btnSave.Click += new System.EventHandler(this.btnSave_Click); // - // dotNetVersionLabel - // - this.dotNetVersionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.dotNetVersionLabel.Location = new System.Drawing.Point(13, 77); - this.dotNetVersionLabel.Name = "dotNetVersionLabel"; - this.dotNetVersionLabel.Size = new System.Drawing.Size(332, 16); - this.dotNetVersionLabel.TabIndex = 7; - this.dotNetVersionLabel.Text = ".Net version 0.0.0"; - this.dotNetVersionLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // // SettingsDialog // this.AcceptButton = this.btnSave; @@ -808,7 +808,6 @@ private void InitializeComponent() this.Name = "SettingsDialog"; this.Padding = new System.Windows.Forms.Padding(3); this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Settings"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmSettings_FormClosing); this.Load += new System.EventHandler(this.frmSettings_Load); diff --git a/SuiteCRMAddIn/Dialogs/SettingsDialog.cs b/SuiteCRMAddIn/Dialogs/SettingsDialog.cs index 3082e49a..954ae2ac 100644 --- a/SuiteCRMAddIn/Dialogs/SettingsDialog.cs +++ b/SuiteCRMAddIn/Dialogs/SettingsDialog.cs @@ -424,7 +424,7 @@ private void btnSave_Click(object sender, EventArgs e) try { - CheckUrlChanged(true); + ErrorHandler.DoOrHandleError(() => CheckUrlChanged(true), "checking whether CRM URL has changed"); string LDAPAuthenticationKey = SafelyGetText(txtLDAPAuthenticationKey); if (LDAPAuthenticationKey == string.Empty) @@ -435,7 +435,7 @@ private void btnSave_Click(object sender, EventArgs e) /* save settings before, and regardless of, test that login succeeds. * Otherwise in cases where login is impossible (e.g. network failure) * settings get lost. See bug #187 */ - this.SaveSettings(); + ErrorHandler.DoOrHandleError(() => this.SaveSettings(), "saving settings"); Globals.ThisAddIn.SuiteCRMUserSession = new SuiteCRMClient.UserSession( @@ -519,55 +519,55 @@ private string SafelyGetText(TextBox box) /// private void SaveSettings() { - Properties.Settings.Default.Host = SafelyGetText(txtURL); - Properties.Settings.Default.Username = SafelyGetText(txtUsername); - Properties.Settings.Default.Password = SafelyGetText(txtPassword); - Properties.Settings.Default.IsLDAPAuthentication = chkEnableLDAPAuthentication.Checked; - Properties.Settings.Default.LDAPKey = SafelyGetText(txtLDAPAuthenticationKey); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.Host = SafelyGetText(txtURL), "Saving Host"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.Username = SafelyGetText(txtUsername), "Saving Username"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.Password = SafelyGetText(txtPassword), "Saving Password"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.IsLDAPAuthentication = chkEnableLDAPAuthentication.Checked, "Saving IsLDAPAuthentication"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.LDAPKey = SafelyGetText(txtLDAPAuthenticationKey), "Saving LDAPKey"); - Properties.Settings.Default.LicenceKey = SafelyGetText(licenceText); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.LicenceKey = SafelyGetText(licenceText), "Saving LicenceKey"); - Properties.Settings.Default.ArchiveAttachments = this.cbEmailAttachments.Checked; - Properties.Settings.Default.AutomaticSearch = this.checkBoxAutomaticSearch.Checked; - Properties.Settings.Default.ShowCustomModules = this.cbShowCustomModules.Checked; - Properties.Settings.Default.PopulateContextLookupList = this.checkBoxShowRightClick.Checked; + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.ArchiveAttachments = this.cbEmailAttachments.Checked, "Saving ArchiveAttachments"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.AutomaticSearch = this.checkBoxAutomaticSearch.Checked, "Saving AutomaticSearch"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.ShowCustomModules = this.cbShowCustomModules.Checked, "Saving CRM URL"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.PopulateContextLookupList = this.checkBoxShowRightClick.Checked, "Saving PopulateContextLookupList"); - Properties.Settings.Default.ExcludedEmails = this.SafelyGetText(txtAutoSync); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.ExcludedEmails = this.SafelyGetText(txtAutoSync), "Saving ExcludedEmails"); - Properties.Settings.Default.AutoArchiveFolders = new List(); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.AutoArchiveFolders = new List(), "Saving AutoArchiveFolders"); - SaveAccountAutoArchivingSettings(); + ErrorHandler.DoOrHandleError(() => SaveAccountAutoArchivingSettings(), "Saving AccountAutoArchivingSettings"); - Properties.Settings.Default.SyncCalls = (SyncDirection.Direction)this.syncCallsMenu.SelectedValue; - Properties.Settings.Default.SyncMeetings = (SyncDirection.Direction)this.syncMeetingsMenu.SelectedValue; - Properties.Settings.Default.SyncTasks = (SyncDirection.Direction)this.syncTasksMenu.SelectedValue; - Properties.Settings.Default.SyncContacts = (SyncDirection.Direction)this.syncContactsMenu.SelectedValue; + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.SyncCalls = (SyncDirection.Direction)this.syncCallsMenu.SelectedValue, "Saving SyncCalls"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.SyncMeetings = (SyncDirection.Direction)this.syncMeetingsMenu.SelectedValue, "Saving SyncMeetings"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.SyncTasks = (SyncDirection.Direction)this.syncTasksMenu.SelectedValue, "Saving SyncTasks"); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.SyncContacts = (SyncDirection.Direction)this.syncContactsMenu.SelectedValue, "Saving SyncContacts"); - Properties.Settings.Default.ShowConfirmationMessageArchive = this.chkShowConfirmationMessageArchive.Checked; - if (this.txtSyncMaxRecords.Text != string.Empty) - { - Properties.Settings.Default.SyncMaxRecords = Convert.ToInt32(this.txtSyncMaxRecords.Text); - } - else - { - Properties.Settings.Default.SyncMaxRecords = 0; - } + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.ShowConfirmationMessageArchive = this.chkShowConfirmationMessageArchive.Checked, "saving ShowConfirmationMessageArchive"); + ErrorHandler.DoOrHandleError(() => SaveSyncMaxRecords(), "saving SyncMaxRecords"); + + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.LogLevel = (LogEntryType)logLevelSelector.SelectedValue, "Saving LogLevel"); + ErrorHandler.DoOrHandleError(() => Globals.ThisAddIn.Log.Level = Properties.Settings.Default.LogLevel, "Setting active log level"); - Properties.Settings.Default.LogLevel = (LogEntryType)logLevelSelector.SelectedValue; - Globals.ThisAddIn.Log.Level = Properties.Settings.Default.LogLevel; + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.ShowExceptions = (ErrorHandler.PopupWhen)showErrorsSelector.SelectedValue, "Saving ShowExceptions"); - Properties.Settings.Default.ShowExceptions = (ErrorHandler.PopupWhen)showErrorsSelector.SelectedValue; + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.CrmIdValidationPolicy = + (CrmIdValidationPolicy.Policy) crmIdValidationSelector.SelectedValue, "Saving CrmIdValidationPolicy"); - Properties.Settings.Default.CrmIdValidationPolicy = - (CrmIdValidationPolicy.Policy) crmIdValidationSelector.SelectedValue; + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.DaysOldEmailToAutoArchive = + (int)Math.Ceiling(Math.Max((DateTime.Today - dtpAutoArchiveFrom.Value).TotalDays, 0)), "Saving DaysOldEmailToAutoArchive"); - Properties.Settings.Default.DaysOldEmailToAutoArchive = - (int)Math.Ceiling(Math.Max((DateTime.Today - dtpAutoArchiveFrom.Value).TotalDays, 0)); + ErrorHandler.DoOrHandleError(() => Properties.Settings.Default.Save(), "Storing all settings to disk"); - Properties.Settings.Default.Save(); + ErrorHandler.DoOrHandleError(() => Globals.ThisAddIn.StopUnconfiguredSynchronisationProcesses(), "stopping sync processes which are no longer required"); + ErrorHandler.DoOrHandleError(() => Globals.ThisAddIn.StartConfiguredSynchronisationProcesses(), "starting sync processes which are now required"); ; + } - Globals.ThisAddIn.StopUnconfiguredSynchronisationProcesses(); - Globals.ThisAddIn.StartConfiguredSynchronisationProcesses(); + private void SaveSyncMaxRecords() + { + Properties.Settings.Default.SyncMaxRecords = this.txtSyncMaxRecords.Text != string.Empty ? + Convert.ToInt32(this.txtSyncMaxRecords.Text): + 0; } private void btnCancel_Click(object sender, EventArgs e) diff --git a/SuiteCRMAddIn/Exceptions/BadStateTransition.cs b/SuiteCRMAddIn/Exceptions/BadStateTransition.cs index 372a15d1..716ebada 100644 --- a/SuiteCRMAddIn/Exceptions/BadStateTransition.cs +++ b/SuiteCRMAddIn/Exceptions/BadStateTransition.cs @@ -30,7 +30,7 @@ namespace SuiteCRMAddIn.Exceptions /// An exception thrown when an unexpected transition is made on a syncstate. /// [Serializable] - internal class BadStateTransition : Exception + internal class BadStateTransition : NeverShowUserException { public TransmissionState From { get; private set; } = TransmissionState.Invalid; diff --git a/SuiteCRMAddIn/Exceptions/MissingOutlookItemException.cs b/SuiteCRMAddIn/Exceptions/MissingOutlookItemException.cs new file mode 100644 index 00000000..a2ea2882 --- /dev/null +++ b/SuiteCRMAddIn/Exceptions/MissingOutlookItemException.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SuiteCRMAddIn.Exceptions +{ + public class MissingOutlookItemException : Exception + { + /// + /// Construct a new instance of a MissingOutlookItemException. + /// + /// The entry id which was searched for but not found. + public MissingOutlookItemException(string entryId) : base( + $"An outlook item with entry ID '{entryId}' could not be found") + { + + } + } +} diff --git a/SuiteCRMAddIn/Exceptions/NeverShowUserException.cs b/SuiteCRMAddIn/Exceptions/NeverShowUserException.cs new file mode 100644 index 00000000..3e8b56c6 --- /dev/null +++ b/SuiteCRMAddIn/Exceptions/NeverShowUserException.cs @@ -0,0 +1,46 @@ +/** + * Outlook integration for SuiteCRM. + * @package Outlook integration for SuiteCRM + * @copyright SalesAgility Ltd http://www.salesagility.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU LESSER GENERAL PUBLIC LICENCE as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENCE + * along with this program; if not, see http://www.gnu.org/licenses + * or write to the Free Software Foundation,Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA + * + * @author SalesAgility + */ +using System; + +namespace SuiteCRMAddIn.Exceptions +{ + /// + /// Abstract superclass for exceptions which may be logged but should never appear + /// in a pop-up. This implies that they are exceptions we are confident the system + /// can recover from without problems. + /// + public abstract class NeverShowUserException : Exception + { + protected NeverShowUserException() : base() + { + } + + protected NeverShowUserException(string message) : base(message) + { + } + + protected NeverShowUserException(string message, Exception cause) : base(message, cause) + { + } + } +} diff --git a/SuiteCRMAddIn/Extensions/ContactItemExtensions.cs b/SuiteCRMAddIn/Extensions/ContactItemExtensions.cs index ea2a498b..09f245d1 100644 --- a/SuiteCRMAddIn/Extensions/ContactItemExtensions.cs +++ b/SuiteCRMAddIn/Extensions/ContactItemExtensions.cs @@ -20,10 +20,15 @@ * * @author SalesAgility */ + +using System.Xml.Serialization; + namespace SuiteCRMAddIn.Extensions { using BusinessLogic; using SuiteCRMClient; + using System; + using System.Globalization; using Outlook = Microsoft.Office.Interop.Outlook; /// @@ -34,6 +39,16 @@ namespace SuiteCRMAddIn.Extensions /// public static class ContactItemExtensions { + /// + /// Name of the override property. + /// + private const string OverridePropertyName = "UserOverride"; + + /// + /// The duration of the override window in minutes. + /// + private const int OverrideWindowMinutes = 10; + /// /// Remove all the synchronisation properties from this item. /// @@ -68,5 +83,88 @@ public static CrmId GetCrmId(this Outlook.ContactItem olItem) return result; } + + /// + /// True if the override window is open for this item. + /// + /// In order to allow manual sync, we need to be able to override the disablement of syncing - + /// but only briefly. + /// The item which we wish to sync. + /// True if the manual sync window is open for this item. + public static bool IsManualOverride(this Outlook.ContactItem olItem) + { + bool result = false; + if (olItem.UserProperties[OverridePropertyName] != null) + { + DateTime value = olItem.UserProperties[OverridePropertyName].Value; + + if ((DateTime.UtcNow - value).Minutes < OverrideWindowMinutes) + { + result = true; + } + else + { + /* no point holding on to a timed-out manual override property */ + olItem.ClearManualOverride(); + } + } + + return result; + } + + /// + /// Set this item as manually syncable, briefly. As a side effect of making the change triggers sync. + /// + /// In order to allow manual sync, we need to be able to override the disablement of syncing - + /// but only briefly. + /// The item which may be synced despite syncing being disabled + public static void SetManualOverride(this Outlook.ContactItem olItem) + { + var p = olItem.UserProperties.Add(OverridePropertyName, Outlook.OlUserPropertyType.olDateTime); + p.Value = DateTime.UtcNow; + olItem.Save(); + } + + /// + /// Clear the manually syncability of this item; does not break is manual sync was not set. + /// + /// In order to allow manual sync, we need to be able to override the disablement of syncing - + /// but only briefly. + /// The item which may be synced despite syncing being disabled + public static void ClearManualOverride(this Outlook.ContactItem olItem) + { + olItem.UserProperties[OverridePropertyName]?.Delete(); + } + + public static void ClearCrmId(this Outlook.ContactItem olItem) + { + var state = SyncStateManager.Instance.GetExistingSyncState(olItem); + + olItem.ClearUserProperty(SyncStateManager.CrmIdPropertyName); + + if (state != null) + { + state.CrmEntryId = null; + } + + olItem.Save(); + } + + public static void ChangeCrmId(this Outlook.ContactItem olItem, string text) + { + var crmId = new CrmId(text); + var state = SyncStateManager.Instance.GetExistingSyncState(olItem); + var userProperty = olItem.UserProperties.Find(SyncStateManager.CrmIdPropertyName) ?? + olItem.UserProperties.Add(SyncStateManager.CrmIdPropertyName, + Outlook.OlUserPropertyType.olText); + userProperty.Value = crmId.ToString(); + + if (state != null) + { + state.CrmEntryId = crmId; + } + + olItem.Save(); + } } } diff --git a/SuiteCRMAddIn/Extensions/TreeNodeExtensions.cs b/SuiteCRMAddIn/Extensions/TreeNodeExtensions.cs new file mode 100644 index 00000000..1f081c33 --- /dev/null +++ b/SuiteCRMAddIn/Extensions/TreeNodeExtensions.cs @@ -0,0 +1,48 @@ +/** + * Outlook integration for SuiteCRM. + * @package Outlook integration for SuiteCRM + * @copyright SalesAgility Ltd http://www.salesagility.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU LESSER GENERAL PUBLIC LICENCE as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENCE + * along with this program; if not, see http://www.gnu.org/licenses + * or write to the Free Software Foundation,Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA + * + * @author SalesAgility + */ + +#region + +using System.Collections.Generic; +using System.Windows.Forms; + +#endregion + +namespace SuiteCRMAddIn.Extensions +{ + /// + /// Stolen shamelessly from + /// https://stackoverflow.com/questions/4702051/get-a-list-of-all-tree-nodes-in-all-levels-in-treeview-controls + /// + public static class TreeNodeExtensions + { + public static List GetAllNodes(this TreeNode _self) + { + var result = new List(); + result.Add(_self); + foreach (TreeNode child in _self.Nodes) + result.AddRange(child.GetAllNodes()); + return result; + } + } +} \ No newline at end of file diff --git a/SuiteCRMAddIn/Extensions/TreeViewExtensions.cs b/SuiteCRMAddIn/Extensions/TreeViewExtensions.cs new file mode 100644 index 00000000..4d92a7ef --- /dev/null +++ b/SuiteCRMAddIn/Extensions/TreeViewExtensions.cs @@ -0,0 +1,47 @@ +/** + * Outlook integration for SuiteCRM. + * @package Outlook integration for SuiteCRM + * @copyright SalesAgility Ltd http://www.salesagility.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU LESSER GENERAL PUBLIC LICENCE as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENCE + * along with this program; if not, see http://www.gnu.org/licenses + * or write to the Free Software Foundation,Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA + * + * @author SalesAgility + */ + +#region + +using System.Collections.Generic; +using System.Windows.Forms; + +#endregion + +namespace SuiteCRMAddIn.Extensions +{ + /// + /// Stolen shamelessly from + /// https://stackoverflow.com/questions/4702051/get-a-list-of-all-tree-nodes-in-all-levels-in-treeview-controls + /// + public static class TreeViewExtensions + { + public static List GetAllNodes(this TreeView _self) + { + var result = new List(); + foreach (TreeNode child in _self.Nodes) + result.AddRange(child.GetAllNodes()); + return result; + } + } +} \ No newline at end of file diff --git a/SuiteCRMAddIn/Helpers/SearchHelper.cs b/SuiteCRMAddIn/Helpers/SearchHelper.cs new file mode 100644 index 00000000..7c9c9057 --- /dev/null +++ b/SuiteCRMAddIn/Helpers/SearchHelper.cs @@ -0,0 +1,85 @@ +/** + * Outlook integration for SuiteCRM. + * @package Outlook integration for SuiteCRM + * @copyright SalesAgility Ltd http://www.salesagility.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU LESSER GENERAL PUBLIC LICENCE as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENCE + * along with this program; if not, see http://www.gnu.org/licenses + * or write to the Free Software Foundation,Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA + * + * @author SalesAgility + */ + +#region + +using System.Collections.Generic; +using System.Linq; +using System.Text; +using SuiteCRMAddIn.BusinessLogic; +using SuiteCRMAddIn.Exceptions; +using SuiteCRMClient; +using SuiteCRMClient.RESTObjects; + +#endregion + +namespace SuiteCRMAddIn.Helpers +{ + /// + /// We do search (differently) in too many places. This is an attempt to rationalise it. + /// + public class SearchHelper + { + public static IEnumerable SearchContacts(string token) + { + return Search(ContactSynchroniser.CrmModule, token, + new[] {"first_name", "last_name", "email1" , "sync_contact", "outlook_id" }); + } + + public static IEnumerable Search(string module, string token, IEnumerable fields, + string logicalOperator = "OR") + { + var bob = new StringBuilder("("); + var fieldsArray = fields.ToArray(); + + foreach (var field in fieldsArray) + { + switch (field) + { + case "first_name": + case "last_name": + case "name": + if (field != fieldsArray.First()) + bob.Append($"{logicalOperator} "); + bob.Append($"{module.ToLower()}.{field} ").Append(token.Length < 4 + ? $"= '{token}' " + : $"LIKE '%{token}%' "); + break; + case "email1": + if (field != fieldsArray.First()) + bob.Append($"{logicalOperator} "); + bob.Append( + $"({module.ToLower()}.id in (select eabr.bean_id from email_addr_bean_rel eabr INNER JOIN email_addresses ea on eabr.email_address_id = ea.id where eabr.bean_module = '{module}' and ea.email_address "); + bob.Append(token.Length < 4 ? $"= '{token}'))" : $"LIKE '%{token}%'))"); + break; + } + } + bob.Append(")"); + + var result = RestAPIWrapper.GetEntryList(module, bob.ToString(), 1000, "date_entered DESC", 0, false, fieldsArray) + .entry_list; + + return result; + } + } +} \ No newline at end of file diff --git a/SuiteCRMAddIn/Images/AddressBook.ico b/SuiteCRMAddIn/Images/AddressBook.ico new file mode 100644 index 00000000..81f0209c Binary files /dev/null and b/SuiteCRMAddIn/Images/AddressBook.ico differ diff --git a/SuiteCRMAddIn/Images/Archive.ico b/SuiteCRMAddIn/Images/Archive.ico new file mode 100644 index 00000000..f4b000ed Binary files /dev/null and b/SuiteCRMAddIn/Images/Archive.ico differ diff --git a/SuiteCRMAddIn/Images/manualSyncContact.ico b/SuiteCRMAddIn/Images/manualSyncContact.ico new file mode 100644 index 00000000..44b282ec Binary files /dev/null and b/SuiteCRMAddIn/Images/manualSyncContact.ico differ diff --git a/SuiteCRMAddIn/Images/manualSyncContact.svg b/SuiteCRMAddIn/Images/manualSyncContact.svg new file mode 100644 index 00000000..33120e44 --- /dev/null +++ b/SuiteCRMAddIn/Images/manualSyncContact.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/SuiteCRMAddIn/Images/manualSyncContact.svg.png b/SuiteCRMAddIn/Images/manualSyncContact.svg.png new file mode 100644 index 00000000..e361909d Binary files /dev/null and b/SuiteCRMAddIn/Images/manualSyncContact.svg.png differ diff --git a/SuiteCRMAddIn/Images/manualSyncContact.svg.xcf b/SuiteCRMAddIn/Images/manualSyncContact.svg.xcf new file mode 100644 index 00000000..dbb75773 Binary files /dev/null and b/SuiteCRMAddIn/Images/manualSyncContact.svg.xcf differ diff --git a/SuiteCRMAddIn/Menus/ContactInspect.xml b/SuiteCRMAddIn/Menus/ContactInspect.xml new file mode 100644 index 00000000..7ac6ef89 --- /dev/null +++ b/SuiteCRMAddIn/Menus/ContactInspect.xml @@ -0,0 +1,30 @@ + + + + + + + /// A summary of the problem that caused the dialogue to be shown. + /// if true, the action may be retried. /// true if the user chose to disable the add-in. - internal bool ShowReconfigureOrDisable(string summary) + internal DialogResult ShowReconfigureOrDisable(string summary, bool allowRetry = false) { - bool result; + DialogResult result; - switch (new ReconfigureOrDisableDialog(summary).ShowDialog()) + result = new ReconfigureOrDisableDialog(summary, allowRetry).ShowDialog(); + switch (result) { + case DialogResult.Retry: + Log.Info(catalogue.GetString("User chose to retry connection")); + break; case DialogResult.OK: /* if licence key does not validate, show the settings form to allow the user to enter * a (new) key, and retry. */ Log.Info(catalogue.GetString("User chose to reconfigure add-in")); this.ShowSettingsForm(); - result = false; break; case DialogResult.Cancel: Log.Info(catalogue.GetString("User chose to disable add-in")); - result = true; break; default: log.Warn(catalogue.GetString("Unexpected response from ReconfigureOrDisableDialog")); - result = true; + result = DialogResult.OK; break; } @@ -402,7 +403,7 @@ private IEnumerable GetLogHeader() private IEnumerable GetKeySettings() { - yield return catalogue.GetString("Auto-archiving: ") + + yield return catalogue.GetString("Auto-archiving: ") + (Settings.Default.AutoArchive ? catalogue.GetString("ON") : catalogue.GetString("off")); yield return catalogue.GetString("Logging level: {0}", Settings.Default.LogLevel); } @@ -452,12 +453,12 @@ public void StopUnconfiguredSynchronisationProcesses() /// The synchroniser to start. private void StartSynchroniserIfConfigured(Synchroniser synchroniser) { - if (synchroniser != null && + if (synchroniser != null && synchroniser.Direction != SyncDirection.Direction.Neither && !synchroniser.IsActive) { - DoOrLogError(() => - synchroniser.Start(), + DoOrLogError(() => + synchroniser.Start(), catalogue.GetString("Starting {0}", new object[] { synchroniser.GetType().Name })); } } @@ -559,16 +560,29 @@ internal void ManualArchive() private void ReconfigureOrDisable() { + DialogResult result; if (!HasCrmUserSession) { - if (this.ShowReconfigureOrDisable(catalogue.GetString("Login to CRM failed"))) + for (result = this.ShowReconfigureOrDisable(catalogue.GetString("Login to CRM failed", true)); + result != DialogResult.Retry; + result = this.ShowReconfigureOrDisable(catalogue.GetString("Login to CRM failed", true))) + { + this.Authenticate(); + } + if (result == DialogResult.Cancel) { this.Disable(); } } else if (!IsLicensed) { - if (this.ShowReconfigureOrDisable(catalogue.GetString("Licence check failed"))) + for (result = this.ShowReconfigureOrDisable(catalogue.GetString("Licence check failed", true)); + result != DialogResult.Retry; + result = this.ShowReconfigureOrDisable(catalogue.GetString("Licence check failed", true))) + { + this.VerifyLicenceKey(); + } + if (result == DialogResult.Cancel) { this.Disable(); } @@ -661,7 +675,7 @@ private void UnregisterEvents() try { Log.Info(catalogue.GetString("{0}: Removing context menu display event handler", methodName)); - this.Application.ItemContextMenuDisplay -= + this.Application.ItemContextMenuDisplay -= new Outlook.ApplicationEvents_11_ItemContextMenuDisplayEventHandler(this.Application_ItemContextMenuDisplay); } catch (Exception ex) @@ -676,7 +690,7 @@ private void UnregisterEvents() { Log.Info(catalogue.GetString("{0}: Removing new mail event handler", methodName)); - Outlook.ApplicationEvents_11_NewMailExEventHandler handler = + Outlook.ApplicationEvents_11_NewMailExEventHandler handler = new Outlook.ApplicationEvents_11_NewMailExEventHandler(this.Application_NewMail); if (handler != null) @@ -819,7 +833,7 @@ private void Application_NewMail(string EntryID) if (item is Outlook.MailItem && Properties.Settings.Default.AutoArchive) { - ProcessNewMailItem( EmailArchiveReason.Inbound, + ProcessNewMailItem(EmailArchiveReason.Inbound, item as Outlook.MailItem, Settings.Default.ExcludedEmails); } @@ -880,10 +894,7 @@ protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtens return new SuiteCRMRibbon(); } - public bool SuiteCRMAuthenticate() - { - return HasCrmUserSession ? true : Authenticate(); - } + public bool SuiteCRMAuthenticate() => HasCrmUserSession ? true : Authenticate(); public bool Authenticate() { @@ -892,12 +903,12 @@ public bool Authenticate() { if (Properties.Settings.Default.Host != String.Empty) { - SuiteCRMUserSession = + SuiteCRMUserSession = new SuiteCRMClient.UserSession( Properties.Settings.Default.Host, Properties.Settings.Default.Username, - Properties.Settings.Default.Password, - Properties.Settings.Default.LDAPKey, + Properties.Settings.Default.Password, + Properties.Settings.Default.LDAPKey, ThisAddIn.AddInTitle, log, Properties.Settings.Default.RestTimeout); @@ -922,10 +933,7 @@ public bool Authenticate() } catch (Exception any) { - ShowAndLogError( - any, - catalogue.GetString("Failure while trying to authenticate to CRM"), - catalogue.GetString("Login failure")); + Log.Error("Failure while trying to authenticate to CRM", any); } } else @@ -933,10 +941,10 @@ public bool Authenticate() // We don't have a URL to connect to, dummy the connection. SuiteCRMUserSession = new SuiteCRMClient.UserSession( - String.Empty, - String.Empty, - String.Empty, - String.Empty, + String.Empty, + String.Empty, + String.Empty, + String.Empty, ThisAddIn.AddInTitle, log, Properties.Settings.Default.RestTimeout); @@ -982,6 +990,22 @@ public IEnumerable SelectedEmails } } + public IEnumerable SelectedContacts + { + get + { + var selection = Application.ActiveExplorer()?.Selection; + if (selection == null) yield break; + foreach (object e in selection) + { + var contact = e as Outlook.ContactItem; + if (contact != null) yield return contact; + Marshal.ReleaseComObject(e); + } + } + } + + /// /// True if this is a licensed copy of the add-in. /// diff --git a/SuiteCRMAddIn/packages.config b/SuiteCRMAddIn/packages.config index 198bf02a..751a44b3 100644 --- a/SuiteCRMAddIn/packages.config +++ b/SuiteCRMAddIn/packages.config @@ -2,7 +2,7 @@ - + - + \ No newline at end of file diff --git a/SuiteCRMAddInSetup/SuiteCRMAddInSetup.isl b/SuiteCRMAddInSetup/SuiteCRMAddInSetup.isl index 37d476d6..24dc99f5 100644 --- a/SuiteCRMAddInSetup/SuiteCRMAddInSetup.isl +++ b/SuiteCRMAddInSetup/SuiteCRMAddInSetup.isl @@ -4423,7 +4423,7 @@ RABlAGIAdQBnAAEARQB4AHAAcgBlAHMAcwA= PROGMSG_IIS_ROLLBACKWEBSERVICEEXTENSIONS##IDS_PROGMSG_IIS_ROLLBACKWEBSERVICEEXTENSIONS## ProductCode{3BFCFDAB-2396-46E0-A826-0F142CA288EB} ProductNameSuiteCRMAddIn - ProductVersion3.0.17.0 + ProductVersion3.0.18.0 ProgressType0install ProgressType1Installing ProgressType2installed diff --git a/SuiteCRMAddInTests/SuiteCRMAddInTests.csproj b/SuiteCRMAddInTests/SuiteCRMAddInTests.csproj index 8d2103c6..d6b87a1d 100644 --- a/SuiteCRMAddInTests/SuiteCRMAddInTests.csproj +++ b/SuiteCRMAddInTests/SuiteCRMAddInTests.csproj @@ -38,7 +38,7 @@ - ..\packages\NGettext.0.6.3\lib\net45\NGettext.dll + ..\packages\NGettext.0.6.3\lib\net46\NGettext.dll True diff --git a/SuiteCRMAddInTests/packages.config b/SuiteCRMAddInTests/packages.config index 0758d1f0..d7778fb2 100644 --- a/SuiteCRMAddInTests/packages.config +++ b/SuiteCRMAddInTests/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/SuiteCRMAddInWixSetup/Product.wxs b/SuiteCRMAddInWixSetup/Product.wxs index a8d24ec3..b9e58209 100644 --- a/SuiteCRMAddInWixSetup/Product.wxs +++ b/SuiteCRMAddInWixSetup/Product.wxs @@ -4,7 +4,7 @@ Id="A784C437-58CF-4495-BE4A-F77657600001" Name="SuiteCRMAddIn" Language="1033" - Version="3.0.17.0" + Version="3.0.18.0" Manufacturer="SalesAgility" UpgradeCode="F50E9CEB-D641-4FC6-8E16-483505C3455A"> diff --git a/SuiteCRMClient/Properties/AssemblyInfo.cs b/SuiteCRMClient/Properties/AssemblyInfo.cs index 0b555680..8587b5e8 100644 --- a/SuiteCRMClient/Properties/AssemblyInfo.cs +++ b/SuiteCRMClient/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // 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("3.0.17.0")] +[assembly: AssemblyVersion("3.0.18.0")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SuiteCRMClient/SuiteCRMClient.csproj b/SuiteCRMClient/SuiteCRMClient.csproj index 2525ef76..fa51c442 100644 --- a/SuiteCRMClient/SuiteCRMClient.csproj +++ b/SuiteCRMClient/SuiteCRMClient.csproj @@ -48,7 +48,7 @@ True - ..\packages\NGettext.0.6.3\lib\net45\NGettext.dll + ..\packages\NGettext.0.6.3\lib\net46\NGettext.dll True diff --git a/SuiteCRMClient/packages.config b/SuiteCRMClient/packages.config index 1bacc8cf..89e5015a 100644 --- a/SuiteCRMClient/packages.config +++ b/SuiteCRMClient/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/SuiteCRMOutlookAddIn.sln b/SuiteCRMOutlookAddIn.sln index fdcb8ffb..3c89d300 100644 --- a/SuiteCRMOutlookAddIn.sln +++ b/SuiteCRMOutlookAddIn.sln @@ -7,11 +7,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SuiteCRMAddIn", "SuiteCRMAd EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SuiteCRMClient", "SuiteCRMClient\SuiteCRMClient.csproj", "{383E8EE7-604D-447D-A2C2-C50080D28F69}" EndProject -Project("{6141683F-8A12-4E36-9623-2EB02B2C2303}") = "SuiteCRMAddInSetup", "SuiteCRMAddInSetup\SuiteCRMAddInSetup.isproj", "{068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}" - ProjectSection(ProjectDependencies) = postProject - {8EF51293-040D-4A83-AFC3-9EA8C328B653} = {8EF51293-040D-4A83-AFC3-9EA8C328B653} - EndProjectSection -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SuiteCRMAddInTests", "SuiteCRMAddInTests\SuiteCRMAddInTests.csproj", "{245DBFF1-8518-4EC9-9AB4-E00392396485}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5848B79C-184D-414E-9E67-038D47F56C65}" @@ -100,36 +95,6 @@ Global {383E8EE7-604D-447D-A2C2-C50080D28F69}.SingleImage|Mixed Platforms.ActiveCfg = Debug|Any CPU {383E8EE7-604D-447D-A2C2-C50080D28F69}.SingleImage|Mixed Platforms.Build.0 = Debug|Any CPU {383E8EE7-604D-447D-A2C2-C50080D28F69}.SingleImage|x86.ActiveCfg = Release|Any CPU - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.CD_ROM|Any CPU.ActiveCfg = CD_ROM - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.CD_ROM|Any CPU.Build.0 = CD_ROM - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.CD_ROM|Mixed Platforms.ActiveCfg = CD_ROM - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.CD_ROM|Mixed Platforms.Build.0 = CD_ROM - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.CD_ROM|x86.ActiveCfg = CD_ROM - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.CD_ROM|x86.Build.0 = CD_ROM - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Debug|Any CPU.ActiveCfg = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Debug|Any CPU.Build.0 = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Debug|Mixed Platforms.ActiveCfg = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Debug|Mixed Platforms.Build.0 = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Debug|x86.ActiveCfg = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Debug|x86.Build.0 = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.DVD-5|Any CPU.ActiveCfg = DVD-5 - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.DVD-5|Any CPU.Build.0 = DVD-5 - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.DVD-5|Mixed Platforms.ActiveCfg = DVD-5 - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.DVD-5|Mixed Platforms.Build.0 = DVD-5 - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.DVD-5|x86.ActiveCfg = DVD-5 - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.DVD-5|x86.Build.0 = DVD-5 - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Release|Any CPU.ActiveCfg = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Release|Any CPU.Build.0 = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Release|Mixed Platforms.ActiveCfg = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Release|Mixed Platforms.Build.0 = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Release|x86.ActiveCfg = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.Release|x86.Build.0 = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.SingleImage|Any CPU.ActiveCfg = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.SingleImage|Any CPU.Build.0 = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.SingleImage|Mixed Platforms.ActiveCfg = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.SingleImage|Mixed Platforms.Build.0 = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.SingleImage|x86.ActiveCfg = SingleImage - {068824B4-9D40-4ACB-B21A-1F0BFA9C0D74}.SingleImage|x86.Build.0 = SingleImage {245DBFF1-8518-4EC9-9AB4-E00392396485}.CD_ROM|Any CPU.ActiveCfg = Release|Any CPU {245DBFF1-8518-4EC9-9AB4-E00392396485}.CD_ROM|Any CPU.Build.0 = Release|Any CPU {245DBFF1-8518-4EC9-9AB4-E00392396485}.CD_ROM|Mixed Platforms.ActiveCfg = Release|Any CPU