From 52e82e23976bec24f6143d558a195e713eb2d496 Mon Sep 17 00:00:00 2001 From: pointfeev Date: Wed, 29 Mar 2023 23:02:19 -0400 Subject: [PATCH] v4.7.1.3 - More fixes related to locked DLLs - Converted from DLLImport to LibraryImport --- CreamInstaller/Components/CustomTreeView.cs | 2 +- CreamInstaller/CreamInstaller.csproj | 215 +++++++++--------- CreamInstaller/Forms/InstallForm.cs | 29 ++- CreamInstaller/Forms/SelectForm.cs | 30 ++- .../Platforms/Paradox/ParadoxLauncher.cs | 30 +-- CreamInstaller/Resources/Koaloader.cs | 35 ++- CreamInstaller/Resources/Resources.cs | 31 ++- CreamInstaller/Resources/ScreamAPI.cs | 22 +- CreamInstaller/Resources/SmokeAPI.cs | 34 +-- CreamInstaller/Resources/UplayR1.cs | 22 +- CreamInstaller/Resources/UplayR2.cs | 30 +-- CreamInstaller/Utility/NativeImports.cs | 11 + CreamInstaller/Utility/ProgramData.cs | 5 +- CreamInstaller/Utility/SafeIO.cs | 60 +++-- preview.png | Bin 23258 -> 43647 bytes 15 files changed, 278 insertions(+), 278 deletions(-) create mode 100644 CreamInstaller/Utility/NativeImports.cs diff --git a/CreamInstaller/Components/CustomTreeView.cs b/CreamInstaller/Components/CustomTreeView.cs index 2da011e..36e1ad3 100644 --- a/CreamInstaller/Components/CustomTreeView.cs +++ b/CreamInstaller/Components/CustomTreeView.cs @@ -206,7 +206,7 @@ internal sealed class CustomTreeView : TreeView foreach ((string directory, BinaryType _) in pair.Key.ExecutableDirectories) { string path = directory + @"\" + proxy + ".dll"; - if (!path.FileExists(form: form) || path.IsResourceFile(ResourceIdentifier.Koaloader)) + if (!path.FileExists() || path.IsResourceFile(ResourceIdentifier.Koaloader)) continue; canUse = false; break; diff --git a/CreamInstaller/CreamInstaller.csproj b/CreamInstaller/CreamInstaller.csproj index 2bb0308..3e7e6aa 100644 --- a/CreamInstaller/CreamInstaller.csproj +++ b/CreamInstaller/CreamInstaller.csproj @@ -4,7 +4,7 @@ net7.0-windows True Resources\ini.ico - 4.7.1.2 + 4.7.1.3 2021, pointfeev (https://github.com/pointfeev) CreamInstaller Automatic DLC Unlocker Installer & Configuration Generator @@ -21,6 +21,7 @@ $(DefineConstants) False latest + True $(Company) @@ -29,118 +30,118 @@ $(Company)-debug - False + False - False + False - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CreamInstaller/Forms/InstallForm.cs b/CreamInstaller/Forms/InstallForm.cs index 5eeea56..5107abc 100644 --- a/CreamInstaller/Forms/InstallForm.cs +++ b/CreamInstaller/Forms/InstallForm.cs @@ -80,9 +80,9 @@ internal sealed partial class InstallForm : CustomForm if (Program.Canceled) throw new CustomMessageException("The operation was canceled."); directory.GetKoaloaderComponents(out string old_config, out string config); - if (directory.GetKoaloaderProxies().Any(proxy => proxy.FileExists(form: this) && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) - || directory != selection.RootDirectory && Koaloader.AutoLoadDLLs.Any(pair => (directory + @"\" + pair.dll).FileExists(form: this)) - || old_config.FileExists(form: this) || config.FileExists(form: this)) + if (directory.GetKoaloaderProxies().Any(proxy => proxy.FileExists() && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) + || directory != selection.RootDirectory && Koaloader.AutoLoadDLLs.Any(pair => (directory + @"\" + pair.dll).FileExists()) + || old_config.FileExists() || config.FileExists()) { UpdateUser("Uninstalling Koaloader from " + selection.Name + $" in incorrect directory \"{directory}\" . . . ", LogTextBox.Operation); await Koaloader.Uninstall(directory, selection.RootDirectory, this); @@ -95,9 +95,8 @@ internal sealed partial class InstallForm : CustomForm if (Program.Canceled) throw new CustomMessageException("The operation was canceled."); directory.GetKoaloaderComponents(out string old_config, out string config); - if (directory.GetKoaloaderProxies().Any(proxy => proxy.FileExists(form: this) && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) - || Koaloader.AutoLoadDLLs.Any(pair => (directory + @"\" + pair.dll).FileExists(form: this)) || old_config.FileExists(form: this) - || config.FileExists(form: this)) + if (directory.GetKoaloaderProxies().Any(proxy => proxy.FileExists() && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) + || Koaloader.AutoLoadDLLs.Any(pair => (directory + @"\" + pair.dll).FileExists()) || old_config.FileExists() || config.FileExists()) { UpdateUser("Uninstalling Koaloader from " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); await Koaloader.Uninstall(directory, selection.RootDirectory, this); @@ -115,9 +114,9 @@ internal sealed partial class InstallForm : CustomForm directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config, out string config, out string old_log, out string log, out string cache); if (uninstallProxy - ? api32_o.FileExists(form: this) || api64_o.FileExists(form: this) || old_config.FileExists(form: this) || config.FileExists(form: this) - || old_log.FileExists(form: this) || log.FileExists(form: this) || cache.FileExists(form: this) - : api32.FileExists(form: this) || api64.FileExists(form: this)) + ? api32_o.FileExists() || api64_o.FileExists() || old_config.FileExists() || config.FileExists() || old_log.FileExists() + || log.FileExists() || cache.FileExists() + : api32.FileExists() || api64.FileExists()) { UpdateUser( $"{(uninstallProxy ? "Uninstalling" : "Installing")} SmokeAPI" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name @@ -132,8 +131,8 @@ internal sealed partial class InstallForm : CustomForm { directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); if (uninstallProxy - ? api32_o.FileExists(form: this) || api64_o.FileExists(form: this) || config.FileExists(form: this) || log.FileExists(form: this) - : api32.FileExists(form: this) || api64.FileExists(form: this)) + ? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists() + : api32.FileExists() || api64.FileExists()) { UpdateUser( $"{(uninstallProxy ? "Uninstalling" : "Installing")} ScreamAPI" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name @@ -148,8 +147,8 @@ internal sealed partial class InstallForm : CustomForm { directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); if (uninstallProxy - ? api32_o.FileExists(form: this) || api64_o.FileExists(form: this) || config.FileExists(form: this) || log.FileExists(form: this) - : api32.FileExists(form: this) || api64.FileExists(form: this)) + ? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists() + : api32.FileExists() || api64.FileExists()) { UpdateUser( $"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name @@ -161,8 +160,8 @@ internal sealed partial class InstallForm : CustomForm } directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config, out log); if (uninstallProxy - ? api32_o.FileExists(form: this) || api64_o.FileExists(form: this) || config.FileExists(form: this) || log.FileExists(form: this) - : old_api32.FileExists(form: this) || old_api64.FileExists(form: this) || api32.FileExists(form: this) || api64.FileExists(form: this)) + ? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists() + : old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() || api64.FileExists()) { UpdateUser( $"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R2 Unlocker" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name diff --git a/CreamInstaller/Forms/SelectForm.cs b/CreamInstaller/Forms/SelectForm.cs index e13ebb4..73dfc7e 100644 --- a/CreamInstaller/Forms/SelectForm.cs +++ b/CreamInstaller/Forms/SelectForm.cs @@ -126,7 +126,7 @@ internal sealed partial class SelectForm : CustomForm if (uninstallAll || programsToScan.Any(c => c.platform is Platform.Paradox)) { AddToRemainingGames("Paradox Launcher"); - List dllDirectories = await ParadoxLauncher.InstallPath.GetDllDirectoriesFromGameDirectory(Platform.Paradox, this); + List dllDirectories = await ParadoxLauncher.InstallPath.GetDllDirectoriesFromGameDirectory(Platform.Paradox); if (dllDirectories is not null) { if (uninstallAll) @@ -183,7 +183,7 @@ internal sealed partial class SelectForm : CustomForm { if (Program.Canceled) return; - List dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Steam, this); + List dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Steam); if (dllDirectories is null) { Interlocked.Decrement(ref steamGamesToCheck); @@ -386,7 +386,7 @@ internal sealed partial class SelectForm : CustomForm { if (Program.Canceled) return; - List dllDirectories = await directory.GetDllDirectoriesFromGameDirectory(Platform.Epic, this); + List dllDirectories = await directory.GetDllDirectoriesFromGameDirectory(Platform.Epic); if (dllDirectories is null) { RemoveFromRemainingGames(name); @@ -520,7 +520,7 @@ internal sealed partial class SelectForm : CustomForm { if (Program.Canceled) return; - List dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Ubisoft, this); + List dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Ubisoft); if (dllDirectories is null) { RemoveFromRemainingGames(name); @@ -858,10 +858,10 @@ internal sealed partial class SelectForm : CustomForm string appInfoVDF = $@"{SteamCMD.AppInfoPath}\{id}.vdf"; string appInfoJSON = $@"{SteamCMD.AppInfoPath}\{id}.json"; string cooldown = $@"{ProgramData.CooldownPath}\{id}.txt"; - if (appInfoVDF.FileExists(form: this) || appInfoJSON.FileExists(form: this)) + if (appInfoVDF.FileExists() || appInfoJSON.FileExists()) { List queries = new(); - if (appInfoJSON.FileExists(form: this)) + if (appInfoJSON.FileExists()) { string platformString = selection is null || selection.Platform is Platform.Steam ? "Steam Store " @@ -870,7 +870,7 @@ internal sealed partial class SelectForm : CustomForm : ""; queries.Add(new($"Open {platformString}Query", "Notepad", (_, _) => Diagnostics.OpenFileInNotepad(appInfoJSON))); } - if (appInfoVDF.FileExists(form: this)) + if (appInfoVDF.FileExists()) queries.Add(new("Open SteamCMD Query", "Notepad", (_, _) => Diagnostics.OpenFileInNotepad(appInfoVDF))); if (queries.Any()) { @@ -908,9 +908,8 @@ internal sealed partial class SelectForm : CustomForm { directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config, out string config, out string old_log, out string log, out string cache); - if (api32.FileExists(form: this) || api32_o.FileExists(form: this) || api64.FileExists(form: this) || api64_o.FileExists(form: this) - || old_config.FileExists(form: this) || config.FileExists(form: this) || old_log.FileExists(form: this) || log.FileExists(form: this) - || cache.FileExists(form: this)) + if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() || old_config.FileExists() + || config.FileExists() || old_log.FileExists() || log.FileExists() || cache.FileExists()) items.Add(new ContextMenuItem($"Open Steamworks Directory #{++steam}", "File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory))); } @@ -919,8 +918,7 @@ internal sealed partial class SelectForm : CustomForm { directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); - if (api32.FileExists(form: this) || api32_o.FileExists(form: this) || api64.FileExists(form: this) || api64_o.FileExists(form: this) - || config.FileExists(form: this) || log.FileExists(form: this)) + if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists()) items.Add(new ContextMenuItem($"Open EOS Directory #{++epic}", "File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory))); } @@ -929,15 +927,13 @@ internal sealed partial class SelectForm : CustomForm { directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); - if (api32.FileExists(form: this) || api32_o.FileExists(form: this) || api64.FileExists(form: this) || api64_o.FileExists(form: this) - || config.FileExists(form: this) || log.FileExists(form: this)) + if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists()) items.Add(new ContextMenuItem($"Open Uplay R1 Directory #{++r1}", "File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory))); directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config, out log); - if (old_api32.FileExists(form: this) || old_api64.FileExists(form: this) || api32.FileExists(form: this) - || api32_o.FileExists(form: this) || api64.FileExists(form: this) || api64_o.FileExists(form: this) || config.FileExists(form: this) - || log.FileExists(form: this)) + if (old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() || api32_o.FileExists() || api64.FileExists() + || api64_o.FileExists() || config.FileExists() || log.FileExists()) items.Add(new ContextMenuItem($"Open Uplay R2 Directory #{++r2}", "File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory))); } diff --git a/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs b/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs index 5953443..327cf16 100644 --- a/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs +++ b/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs @@ -80,7 +80,9 @@ internal static class ParadoxLauncher { InstallForm installForm = form as InstallForm; if (!Program.AreDllsLockedDialog(form, selection)) - return form is InstallForm ? throw new CustomMessageException("Repair failed! One or more DLLs crucial to unlocker installation are locked!") : RepairResult.ProgramRunning; + return form is InstallForm + ? throw new CustomMessageException("Repair failed! One or more DLLs crucial to unlocker installation are locked!") + : RepairResult.ProgramRunning; bool smokeInstalled = false; byte[] steamOriginalSdk32 = null; byte[] steamOriginalSdk64 = null; @@ -90,27 +92,27 @@ internal static class ParadoxLauncher foreach (string directory in selection.DllDirectories) { bool koaloaderInstalled = Koaloader.AutoLoadDLLs.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) - .Any(pair => pair.path.FileExists(form: form) && pair.path.IsResourceFile()); + .Any(pair => pair.path.FileExists() && pair.path.IsResourceFile()); directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config, out string config, out _, out _, out _); - smokeInstalled = smokeInstalled || api32_o.FileExists(form: form) || api64_o.FileExists(form: form) - || (old_config.FileExists(form: form) || config.FileExists(form: form)) && !koaloaderInstalled - || api32.FileExists(form: form) && api32.IsResourceFile(ResourceIdentifier.Steamworks32) - || api64.FileExists(form: form) && api64.IsResourceFile(ResourceIdentifier.Steamworks64); + smokeInstalled = smokeInstalled || api32_o.FileExists() || api64_o.FileExists() + || (old_config.FileExists() || config.FileExists()) && !koaloaderInstalled + || api32.FileExists() && api32.IsResourceFile(ResourceIdentifier.Steamworks32) + || api64.FileExists() && api64.IsResourceFile(ResourceIdentifier.Steamworks64); await SmokeAPI.Uninstall(directory, deleteOthers: false); - if (steamOriginalSdk32 is null && api32.FileExists(form: form) && !api32.IsResourceFile(ResourceIdentifier.Steamworks32)) + if (steamOriginalSdk32 is null && api32.FileExists() && !api32.IsResourceFile(ResourceIdentifier.Steamworks32)) steamOriginalSdk32 = api32.ReadFileBytes(true); - if (steamOriginalSdk64 is null && api64.FileExists(form: form) && !api64.IsResourceFile(ResourceIdentifier.Steamworks64)) + if (steamOriginalSdk64 is null && api64.FileExists() && !api64.IsResourceFile(ResourceIdentifier.Steamworks64)) steamOriginalSdk64 = api64.ReadFileBytes(true); directory.GetScreamApiComponents(out api32, out api32_o, out api64, out api64_o, out config, out string log); - screamInstalled = screamInstalled || api32_o.FileExists(form: form) || api64_o.FileExists(form: form) - || (config.FileExists(form: form) || log.FileExists(form: form)) && !koaloaderInstalled - || api32.FileExists(form: form) && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32) - || api64.FileExists(form: form) && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64); + screamInstalled = screamInstalled || api32_o.FileExists() || api64_o.FileExists() + || (config.FileExists() || log.FileExists()) && !koaloaderInstalled + || api32.FileExists() && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32) + || api64.FileExists() && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64); await ScreamAPI.Uninstall(directory, deleteOthers: false); - if (epicOriginalSdk32 is null && api32.FileExists(form: form) && !api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32)) + if (epicOriginalSdk32 is null && api32.FileExists() && !api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32)) epicOriginalSdk32 = api32.ReadFileBytes(true); - if (epicOriginalSdk64 is null && api64.FileExists(form: form) && !api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64)) + if (epicOriginalSdk64 is null && api64.FileExists() && !api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64)) epicOriginalSdk64 = api64.ReadFileBytes(true); } using DialogForm dialogForm = new(form); diff --git a/CreamInstaller/Resources/Koaloader.cs b/CreamInstaller/Resources/Koaloader.cs index 5752cb7..650a17f 100644 --- a/CreamInstaller/Resources/Koaloader.cs +++ b/CreamInstaller/Resources/Koaloader.cs @@ -60,9 +60,9 @@ internal static class Koaloader private static void CheckConfig(string directory, InstallForm installForm = null) { directory.GetKoaloaderComponents(out string old_config, out string config); - if (old_config.FileExists(form: installForm)) + if (old_config.FileExists()) { - if (!config.FileExists(form: installForm)) + if (!config.FileExists()) { old_config.MoveFile(config!); installForm?.UpdateUser($"Converted old configuration: {Path.GetFileName(old_config)} -> {Path.GetFileName(config)}", LogTextBox.Action, false); @@ -85,7 +85,7 @@ internal static class Koaloader writer.Flush(); writer.Close(); } - else if (config.FileExists(form: installForm)) + else if (config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); @@ -137,23 +137,23 @@ internal static class Koaloader { directory.GetKoaloaderComponents(out string old_config, out string config); foreach (string proxyPath in directory.GetKoaloaderProxies().Where(proxyPath - => proxyPath.FileExists(form: installForm) && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader))) + => proxyPath.FileExists() && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader))) { proxyPath.DeleteFile(); installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(proxyPath)}", LogTextBox.Action, false); } foreach ((string unlocker, string path) in AutoLoadDLLs.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) - .Where(pair => pair.path.FileExists(form: installForm) && pair.path.IsResourceFile())) + .Where(pair => pair.path.FileExists() && pair.path.IsResourceFile())) { path.DeleteFile(); installForm?.UpdateUser($"Deleted {unlocker}: {Path.GetFileName(path)}", LogTextBox.Action, false); } - if (deleteConfig && old_config.FileExists(form: installForm)) + if (deleteConfig && old_config.FileExists()) { old_config.DeleteFile(); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false); } - if (deleteConfig && config.FileExists(form: installForm)) + if (deleteConfig && config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); @@ -172,13 +172,12 @@ internal static class Koaloader { string proxy = selection.KoaloaderProxy ?? ProgramSelection.DefaultKoaloaderProxy; string path = directory + @"\" + proxy + ".dll"; - foreach (string _path in directory.GetKoaloaderProxies() - .Where(p => p != path && p.FileExists(form: installForm) && p.IsResourceFile(ResourceIdentifier.Koaloader))) + foreach (string _path in directory.GetKoaloaderProxies().Where(p => p != path && p.FileExists() && p.IsResourceFile(ResourceIdentifier.Koaloader))) { _path.DeleteFile(); installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(_path)}", LogTextBox.Action, false); } - if (path.FileExists(form: installForm) && !path.IsResourceFile(ResourceIdentifier.Koaloader)) + if (path.FileExists() && !path.IsResourceFile(ResourceIdentifier.Koaloader)) throw new CustomMessageException("A non-Koaloader DLL named " + proxy + ".dll already exists in this directory!"); path.WriteProxy(proxy, binaryType); installForm?.UpdateUser($"Wrote {(binaryType == BinaryType.BIT32 ? "32-bit" : "64-bit")} Koaloader: {Path.GetFileName(path)}", LogTextBox.Action, @@ -206,7 +205,7 @@ internal static class Koaloader path = directory + @"\SmokeAPI32.dll"; if (rootDirectory is not null && directory != rootDirectory) { - if (path.FileExists(form: installForm)) + if (path.FileExists()) { path.DeleteFile(); installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); @@ -223,7 +222,7 @@ internal static class Koaloader path = directory + @"\SmokeAPI64.dll"; if (rootDirectory is not null && directory != rootDirectory) { - if (path.FileExists(form: installForm)) + if (path.FileExists()) { path.DeleteFile(); installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); @@ -246,7 +245,7 @@ internal static class Koaloader path = directory + @"\ScreamAPI32.dll"; if (rootDirectory is not null && directory != rootDirectory) { - if (path.FileExists(form: installForm)) + if (path.FileExists()) { path.DeleteFile(); installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); @@ -263,7 +262,7 @@ internal static class Koaloader path = directory + @"\ScreamAPI64.dll"; if (rootDirectory is not null && directory != rootDirectory) { - if (path.FileExists(form: installForm)) + if (path.FileExists()) { path.DeleteFile(); installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); @@ -285,7 +284,7 @@ internal static class Koaloader path = directory + @"\UplayR1Unlocker32.dll"; if (rootDirectory is not null && directory != rootDirectory) { - if (path.FileExists(form: installForm)) + if (path.FileExists()) { path.DeleteFile(); installForm?.UpdateUser($"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, @@ -303,7 +302,7 @@ internal static class Koaloader path = directory + @"\UplayR1Unlocker64.dll"; if (rootDirectory is not null && directory != rootDirectory) { - if (path.FileExists(form: installForm)) + if (path.FileExists()) { path.DeleteFile(); installForm?.UpdateUser($"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, @@ -322,7 +321,7 @@ internal static class Koaloader path = directory + @"\UplayR2Unlocker32.dll"; if (rootDirectory is not null && directory != rootDirectory) { - if (path.FileExists(form: installForm)) + if (path.FileExists()) { path.DeleteFile(); installForm?.UpdateUser($"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, @@ -340,7 +339,7 @@ internal static class Koaloader path = directory + @"\UplayR2Unlocker64.dll"; if (rootDirectory is not null && directory != rootDirectory) { - if (path.FileExists(form: installForm)) + if (path.FileExists()) { path.DeleteFile(); installForm?.UpdateUser($"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, diff --git a/CreamInstaller/Resources/Resources.cs b/CreamInstaller/Resources/Resources.cs index 95b4c8a..0bbb4a7 100644 --- a/CreamInstaller/Resources/Resources.cs +++ b/CreamInstaller/Resources/Resources.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; -using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; @@ -480,10 +479,7 @@ internal static class Resources } } - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode), DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - private static extern bool GetBinaryType(string lpApplicationName, out BinaryType lpBinaryType); - - internal static bool TryGetFileBinaryType(this string path, out BinaryType binaryType) => GetBinaryType(path, out binaryType); + internal static bool TryGetFileBinaryType(this string path, out BinaryType binaryType) => NativeImports.GetBinaryType(path, out binaryType); internal static async Task> GetExecutableDirectories(this string rootDirectory, bool filterCommon = false, Func validFunc = null) @@ -535,7 +531,7 @@ internal static class Resources || subPath.Contains("ANTICHEAT"); } - internal static async Task> GetDllDirectoriesFromGameDirectory(this string gameDirectory, Platform platform, Form form = null) + internal static async Task> GetDllDirectoriesFromGameDirectory(this string gameDirectory, Platform platform) => await Task.Run(() => { List dllDirectories = new(); @@ -549,36 +545,35 @@ internal static class Resources if (dllDirectories.Contains(subDirectory)) continue; bool koaloaderInstalled = Koaloader.AutoLoadDLLs.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) - .Any(pair => pair.path.FileExists(form: form) && pair.path.IsResourceFile()); + .Any(pair => pair.path.FileExists() && pair.path.IsResourceFile()); if (platform is Platform.Steam or Platform.Paradox) { subDirectory.GetSmokeApiComponents(out string api, out string api_o, out string api64, out string api64_o, out string old_config, out string config, out string old_log, out string log, out string cache); - if (api.FileExists(form: form) || api_o.FileExists(form: form) || api64.FileExists(form: form) || api64_o.FileExists(form: form) - || (old_config.FileExists(form: form) || config.FileExists(form: form) || old_log.FileExists(form: form) || log.FileExists(form: form) - || cache.FileExists(form: form)) && !koaloaderInstalled) + if (api.FileExists() || api_o.FileExists() || api64.FileExists() || api64_o.FileExists() + || (old_config.FileExists() || config.FileExists() || old_log.FileExists() || log.FileExists() || cache.FileExists()) + && !koaloaderInstalled) dllDirectories.Add(subDirectory); } if (platform is Platform.Epic or Platform.Paradox) { subDirectory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); - if (api32.FileExists(form: form) || api32_o.FileExists(form: form) || api64.FileExists(form: form) || api64_o.FileExists(form: form) - || (config.FileExists(form: form) || log.FileExists(form: form)) && !koaloaderInstalled) + if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() + || (config.FileExists() || log.FileExists()) && !koaloaderInstalled) dllDirectories.Add(subDirectory); } if (platform is Platform.Ubisoft) { subDirectory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); - if (api32.FileExists(form: form) || api32_o.FileExists(form: form) || api64.FileExists(form: form) || api64_o.FileExists(form: form) - || (config.FileExists(form: form) || log.FileExists(form: form)) && !koaloaderInstalled) + if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() + || (config.FileExists() || log.FileExists()) && !koaloaderInstalled) dllDirectories.Add(subDirectory); subDirectory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config, out log); - if (old_api32.FileExists(form: form) || old_api64.FileExists(form: form) || api32.FileExists(form: form) || api32_o.FileExists(form: form) - || api64.FileExists(form: form) || api64_o.FileExists(form: form) - || (config.FileExists(form: form) || log.FileExists(form: form)) && !koaloaderInstalled) + if (old_api32.FileExists() || old_api64.FileExists() || api32.FileExists() || api32_o.FileExists() || api64.FileExists() + || api64_o.FileExists() || (config.FileExists() || log.FileExists()) && !koaloaderInstalled) dllDirectories.Add(subDirectory); } } @@ -597,7 +592,7 @@ internal static class Resources #pragma warning disable CA5351 private static string ComputeMD5(this string filePath) - => filePath.FileExists() && filePath.ReadFileBytes() is { } bytes + => filePath.FileExists() && filePath.ReadFileBytes(true) is { } bytes ? BitConverter.ToString(MD5.HashData(bytes)).Replace("-", "").ToUpperInvariant() : null; #pragma warning restore CA5351 diff --git a/CreamInstaller/Resources/ScreamAPI.cs b/CreamInstaller/Resources/ScreamAPI.cs index 6be7eb7..95fd015 100644 --- a/CreamInstaller/Resources/ScreamAPI.cs +++ b/CreamInstaller/Resources/ScreamAPI.cs @@ -46,7 +46,7 @@ internal static class ScreamAPI writer.Flush(); writer.Close(); } - else if (config.FileExists(form: installForm)) + else if (config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); @@ -105,9 +105,9 @@ internal static class ScreamAPI => await Task.Run(() => { directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); - if (api32_o.FileExists(form: installForm)) + if (api32_o.FileExists()) { - if (api32.FileExists(form: installForm)) + if (api32.FileExists()) { api32.DeleteFile(); installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); @@ -115,9 +115,9 @@ internal static class ScreamAPI api32_o.MoveFile(api32!); installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, false); } - if (api64_o.FileExists(form: installForm)) + if (api64_o.FileExists()) { - if (api64.FileExists(form: installForm)) + if (api64.FileExists()) { api64.DeleteFile(); installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); @@ -127,12 +127,12 @@ internal static class ScreamAPI } if (!deleteOthers) return; - if (config.FileExists(form: installForm)) + if (config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } - if (log.FileExists(form: installForm)) + if (log.FileExists()) { log.DeleteFile(); installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false); @@ -143,22 +143,22 @@ internal static class ScreamAPI => await Task.Run(() => { directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _); - if (api32.FileExists(form: installForm) && !api32_o.FileExists(form: installForm)) + if (api32.FileExists() && !api32_o.FileExists()) { api32.MoveFile(api32_o!); installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false); } - if (api32_o.FileExists(form: installForm)) + if (api32_o.FileExists()) { "ScreamAPI.EOSSDK-Win32-Shipping.dll".WriteManifestResource(api32); installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); } - if (api64.FileExists(form: installForm) && !api64_o.FileExists(form: installForm)) + if (api64.FileExists() && !api64_o.FileExists()) { api64.MoveFile(api64_o!); installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false); } - if (api64_o.FileExists(form: installForm)) + if (api64_o.FileExists()) { "ScreamAPI.EOSSDK-Win64-Shipping.dll".WriteManifestResource(api64); installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); diff --git a/CreamInstaller/Resources/SmokeAPI.cs b/CreamInstaller/Resources/SmokeAPI.cs index bc47de9..185a22c 100644 --- a/CreamInstaller/Resources/SmokeAPI.cs +++ b/CreamInstaller/Resources/SmokeAPI.cs @@ -51,7 +51,7 @@ internal static class SmokeAPI extraApps.Add(newExtraPair); } injectDlc = injectDlc.ToList(); - if (old_config.FileExists(form: installForm)) + if (old_config.FileExists()) { old_config.DeleteFile(); installForm?.UpdateUser($"Deleted old configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false); @@ -68,7 +68,7 @@ internal static class SmokeAPI writer.Flush(); writer.Close(); } - else if (config.FileExists(form: installForm)) + else if (config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); @@ -155,16 +155,16 @@ internal static class SmokeAPI => await Task.Run(() => { directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig); - if (oldConfig.FileExists(form: installForm)) + if (oldConfig.FileExists()) { oldConfig.DeleteFile(); installForm?.UpdateUser($"Deleted old CreamAPI configuration: {Path.GetFileName(oldConfig)}", LogTextBox.Action, false); } directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config, out string config, out string old_log, out string log, out string cache); - if (api32_o.FileExists(form: installForm)) + if (api32_o.FileExists()) { - if (api32.FileExists(form: installForm)) + if (api32.FileExists()) { api32.DeleteFile(); installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); @@ -172,9 +172,9 @@ internal static class SmokeAPI api32_o.MoveFile(api32!); installForm?.UpdateUser($"Restored Steamworks: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, false); } - if (api64_o.FileExists(form: installForm)) + if (api64_o.FileExists()) { - if (api64.FileExists(form: installForm)) + if (api64.FileExists()) { api64.DeleteFile(); installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); @@ -184,27 +184,27 @@ internal static class SmokeAPI } if (!deleteOthers) return; - if (old_config.FileExists(form: installForm)) + if (old_config.FileExists()) { old_config.DeleteFile(); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false); } - if (config.FileExists(form: installForm)) + if (config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } - if (cache.FileExists(form: installForm)) + if (cache.FileExists()) { cache.DeleteFile(); installForm?.UpdateUser($"Deleted cache: {Path.GetFileName(cache)}", LogTextBox.Action, false); } - if (old_log.FileExists(form: installForm)) + if (old_log.FileExists()) { old_log.DeleteFile(); installForm?.UpdateUser($"Deleted log: {Path.GetFileName(old_log)}", LogTextBox.Action, false); } - if (log.FileExists(form: installForm)) + if (log.FileExists()) { log.DeleteFile(); installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false); @@ -215,28 +215,28 @@ internal static class SmokeAPI => await Task.Run(() => { directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig); - if (oldConfig.FileExists(form: installForm)) + if (oldConfig.FileExists()) { oldConfig.DeleteFile(); installForm?.UpdateUser($"Deleted old CreamAPI configuration: {Path.GetFileName(oldConfig)}", LogTextBox.Action, false); } directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _, out _, out _, out _); - if (api32.FileExists(form: installForm) && !api32_o.FileExists(form: installForm)) + if (api32.FileExists() && !api32_o.FileExists()) { api32.MoveFile(api32_o!); installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false); } - if (api32_o.FileExists(form: installForm)) + if (api32_o.FileExists()) { "SmokeAPI.steam_api.dll".WriteManifestResource(api32); installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); } - if (api64.FileExists(form: installForm) && !api64_o.FileExists(form: installForm)) + if (api64.FileExists() && !api64_o.FileExists()) { api64.MoveFile(api64_o!); installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false); } - if (api64_o.FileExists(form: installForm)) + if (api64_o.FileExists()) { "SmokeAPI.steam_api64.dll".WriteManifestResource(api64); installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); diff --git a/CreamInstaller/Resources/UplayR1.cs b/CreamInstaller/Resources/UplayR1.cs index ab867dd..026a571 100644 --- a/CreamInstaller/Resources/UplayR1.cs +++ b/CreamInstaller/Resources/UplayR1.cs @@ -39,7 +39,7 @@ internal static class UplayR1 writer.Flush(); writer.Close(); } - else if (config.FileExists(form: installForm)) + else if (config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); @@ -75,9 +75,9 @@ internal static class UplayR1 => await Task.Run(() => { directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); - if (api32_o.FileExists(form: installForm)) + if (api32_o.FileExists()) { - if (api32.FileExists(form: installForm)) + if (api32.FileExists()) { api32.DeleteFile(); installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false); @@ -85,9 +85,9 @@ internal static class UplayR1 api32_o.MoveFile(api32!); installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, false); } - if (api64_o.FileExists(form: installForm)) + if (api64_o.FileExists()) { - if (api64.FileExists(form: installForm)) + if (api64.FileExists()) { api64.DeleteFile(); installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false); @@ -97,12 +97,12 @@ internal static class UplayR1 } if (!deleteOthers) return; - if (config.FileExists(form: installForm)) + if (config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } - if (log.FileExists(form: installForm)) + if (log.FileExists()) { log.DeleteFile(); installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false); @@ -113,22 +113,22 @@ internal static class UplayR1 => await Task.Run(() => { directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _); - if (api32.FileExists(form: installForm) && !api32_o.FileExists(form: installForm)) + if (api32.FileExists() && !api32_o.FileExists()) { api32.MoveFile(api32_o!); installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false); } - if (api32_o.FileExists(form: installForm)) + if (api32_o.FileExists()) { "UplayR1.uplay_r1_loader.dll".WriteManifestResource(api32); installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false); } - if (api64.FileExists(form: installForm) && !api64_o.FileExists(form: installForm)) + if (api64.FileExists() && !api64_o.FileExists()) { api64.MoveFile(api64_o!); installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false); } - if (api64_o.FileExists(form: installForm)) + if (api64_o.FileExists()) { "UplayR1.uplay_r1_loader64.dll".WriteManifestResource(api64); installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false); diff --git a/CreamInstaller/Resources/UplayR2.cs b/CreamInstaller/Resources/UplayR2.cs index 649da2b..1099fd3 100644 --- a/CreamInstaller/Resources/UplayR2.cs +++ b/CreamInstaller/Resources/UplayR2.cs @@ -41,7 +41,7 @@ internal static class UplayR2 writer.Flush(); writer.Close(); } - else if (config.FileExists(form: installForm)) + else if (config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); @@ -80,10 +80,10 @@ internal static class UplayR2 { directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); - if (api32_o.FileExists(form: installForm)) + if (api32_o.FileExists()) { - string api = old_api32.FileExists(form: installForm) ? old_api32 : api32; - if (api.FileExists(form: installForm)) + string api = old_api32.FileExists() ? old_api32 : api32; + if (api.FileExists()) { api.DeleteFile(); installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); @@ -91,10 +91,10 @@ internal static class UplayR2 api32_o.MoveFile(api!); installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api)}", LogTextBox.Action, false); } - if (api64_o.FileExists(form: installForm)) + if (api64_o.FileExists()) { - string api = old_api64.FileExists(form: installForm) ? old_api64 : api64; - if (api.FileExists(form: installForm)) + string api = old_api64.FileExists() ? old_api64 : api64; + if (api.FileExists()) { api.DeleteFile(); installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); @@ -104,12 +104,12 @@ internal static class UplayR2 } if (!deleteOthers) return; - if (config.FileExists(form: installForm)) + if (config.FileExists()) { config.DeleteFile(); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } - if (log.FileExists(form: installForm)) + if (log.FileExists()) { log.DeleteFile(); installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false); @@ -121,24 +121,24 @@ internal static class UplayR2 { directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32, out string api32_o, out string api64, out string api64_o, out _, out _); - string api = old_api32.FileExists(form: installForm) ? old_api32 : api32; - if (api.FileExists(form: installForm) && !api32_o.FileExists(form: installForm)) + string api = old_api32.FileExists() ? old_api32 : api32; + if (api.FileExists() && !api32_o.FileExists()) { api.MoveFile(api32_o!); installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false); } - if (api32_o.FileExists(form: installForm)) + if (api32_o.FileExists()) { "UplayR2.upc_r2_loader.dll".WriteManifestResource(api); installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); } - api = old_api64.FileExists(form: installForm) ? old_api64 : api64; - if (api.FileExists(form: installForm) && !api64_o.FileExists(form: installForm)) + api = old_api64.FileExists() ? old_api64 : api64; + if (api.FileExists() && !api64_o.FileExists()) { api.MoveFile(api64_o!); installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false); } - if (api64_o.FileExists(form: installForm)) + if (api64_o.FileExists()) { "UplayR2.upc_r2_loader64.dll".WriteManifestResource(api); installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); diff --git a/CreamInstaller/Utility/NativeImports.cs b/CreamInstaller/Utility/NativeImports.cs new file mode 100644 index 0000000..168b0b4 --- /dev/null +++ b/CreamInstaller/Utility/NativeImports.cs @@ -0,0 +1,11 @@ +using System.Runtime.InteropServices; +using static CreamInstaller.Resources.Resources; + +namespace CreamInstaller.Utility; + +internal static partial class NativeImports +{ + [LibraryImport("kernel32.dll", SetLastError = true), DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static partial bool GetBinaryType([MarshalAs(UnmanagedType.LPStr)] string lpApplicationName, out BinaryType lpBinaryType); +} \ No newline at end of file diff --git a/CreamInstaller/Utility/ProgramData.cs b/CreamInstaller/Utility/ProgramData.cs index 2578a0b..65f8add 100644 --- a/CreamInstaller/Utility/ProgramData.cs +++ b/CreamInstaller/Utility/ProgramData.cs @@ -35,15 +35,14 @@ internal static class ProgramData DirectoryPathOld.MoveDirectory(DirectoryPath, true, form); } DirectoryPath.CreateDirectory(); - if (!AppInfoVersionPath.FileExists(form: form) || !Version.TryParse(AppInfoVersionPath.ReadFile(), out Version version) - || version < MinimumAppInfoVersion) + if (!AppInfoVersionPath.FileExists() || !Version.TryParse(AppInfoVersionPath.ReadFile(), out Version version) || version < MinimumAppInfoVersion) { AppInfoPath.DeleteDirectory(); AppInfoPath.CreateDirectory(); AppInfoVersionPath.WriteFile(Program.Version); } CooldownPath.CreateDirectory(); - if (OldProgramChoicesPath.FileExists(form: form)) + if (OldProgramChoicesPath.FileExists()) OldProgramChoicesPath.DeleteFile(); }); diff --git a/CreamInstaller/Utility/SafeIO.cs b/CreamInstaller/Utility/SafeIO.cs index 8fa811b..4712866 100644 --- a/CreamInstaller/Utility/SafeIO.cs +++ b/CreamInstaller/Utility/SafeIO.cs @@ -26,16 +26,7 @@ internal static class SafeIO return false; } - internal static bool DirectoryExists(this string directoryPath, bool crucial = false, Form form = null) - { - while (!Program.Canceled) - { - bool exists = Directory.Exists(directoryPath); - if (exists || !crucial || directoryPath.IOWarn("Failed to find a crucial directory", form) is not DialogResult.OK) - return exists; - } - return false; - } + internal static bool DirectoryExists(this string directoryPath) => Directory.Exists(directoryPath); internal static void CreateDirectory(this string directoryPath, bool crucial = false, Form form = null) { @@ -49,13 +40,15 @@ internal static class SafeIO } catch { - if (!crucial || directoryPath.IOWarn("Failed to create a crucial directory", form) is not DialogResult.OK) + if (!crucial || directoryPath.DirectoryExists() || directoryPath.IOWarn("Failed to create a crucial directory", form) is not DialogResult.OK) break; } } internal static void MoveDirectory(this string directoryPath, string newDirectoryPath, bool crucial = false, Form form = null) { + if (!directoryPath.DirectoryExists()) + return; while (!Program.Canceled) try { @@ -64,7 +57,7 @@ internal static class SafeIO } catch { - if (!crucial || directoryPath.IOWarn("Failed to move a crucial directory", form) is not DialogResult.OK) + if (!crucial || !directoryPath.DirectoryExists() || directoryPath.IOWarn("Failed to move a crucial directory", form) is not DialogResult.OK) break; } } @@ -81,7 +74,7 @@ internal static class SafeIO } catch { - if (!crucial || directoryPath.IOWarn("Failed to delete a crucial directory", form) is not DialogResult.OK) + if (!crucial || !directoryPath.DirectoryExists() || directoryPath.IOWarn("Failed to delete a crucial directory", form) is not DialogResult.OK) break; } } @@ -89,6 +82,8 @@ internal static class SafeIO internal static IEnumerable EnumerateDirectory(this string directoryPath, string filePattern, bool subdirectories = false, bool crucial = false, Form form = null) { + if (!directoryPath.DirectoryExists()) + return Enumerable.Empty(); while (!Program.Canceled) try { @@ -98,7 +93,8 @@ internal static class SafeIO } catch { - if (!crucial || directoryPath.IOWarn("Failed to enumerate a crucial directory's files", form) is not DialogResult.OK) + if (!crucial || !directoryPath.DirectoryExists() + || directoryPath.IOWarn("Failed to enumerate a crucial directory's files", form) is not DialogResult.OK) break; } return Enumerable.Empty(); @@ -107,6 +103,8 @@ internal static class SafeIO internal static IEnumerable EnumerateSubdirectories(this string directoryPath, string directoryPattern, bool subdirectories = false, bool crucial = false, Form form = null) { + if (!directoryPath.DirectoryExists()) + return Enumerable.Empty(); while (!Program.Canceled) try { @@ -116,22 +114,14 @@ internal static class SafeIO } catch { - if (!crucial || directoryPath.IOWarn("Failed to enumerate a crucial directory's subdirectories", form) is not DialogResult.OK) + if (!crucial || !directoryPath.DirectoryExists() + || directoryPath.IOWarn("Failed to enumerate a crucial directory's subdirectories", form) is not DialogResult.OK) break; } return Enumerable.Empty(); } - internal static bool FileExists(this string filePath, bool crucial = false, Form form = null) - { - while (!Program.Canceled) - { - bool exists = File.Exists(filePath); - if (exists || !crucial || filePath.IOWarn("Failed to find a crucial file", form) is not DialogResult.OK) - return exists; - } - return false; - } + internal static bool FileExists(this string filePath) => File.Exists(filePath); internal static void CreateFile(this string filePath, bool crucial = false, Form form = null) { @@ -150,6 +140,8 @@ internal static class SafeIO internal static void MoveFile(this string filePath, string newFilePath, bool crucial = false, Form form = null) { + if (!filePath.FileExists()) + return; while (!Program.Canceled) try { @@ -158,14 +150,14 @@ internal static class SafeIO } catch { - if (!crucial || !filePath.FileExists(true) || filePath.IOWarn("Failed to move a crucial file", form) is not DialogResult.OK) + if (!crucial || !filePath.FileExists() || filePath.IOWarn("Failed to move a crucial file", form) is not DialogResult.OK) break; } } internal static void DeleteFile(this string filePath, bool crucial = false, Form form = null) { - if (!filePath.FileExists(form: form)) + if (!filePath.FileExists()) return; while (!Program.Canceled) try @@ -175,13 +167,15 @@ internal static class SafeIO } catch { - if (!crucial || filePath.IOWarn("Failed to delete a crucial file", form) is not DialogResult.OK) + if (!crucial || !filePath.FileExists() || filePath.IOWarn("Failed to delete a crucial file", form) is not DialogResult.OK) break; } } internal static string ReadFile(this string filePath, bool crucial = false, Form form = null) { + if (!filePath.FileExists()) + return null; while (!Program.Canceled) try { @@ -189,7 +183,7 @@ internal static class SafeIO } catch { - if (!crucial || !filePath.FileExists(true) || filePath.IOWarn("Failed to read a crucial file", form) is not DialogResult.OK) + if (!crucial || !filePath.FileExists() || filePath.IOWarn("Failed to read a crucial file", form) is not DialogResult.OK) break; } return null; @@ -197,6 +191,8 @@ internal static class SafeIO internal static byte[] ReadFileBytes(this string filePath, bool crucial = false, Form form = null) { + if (!filePath.FileExists()) + return null; while (!Program.Canceled) try { @@ -204,7 +200,7 @@ internal static class SafeIO } catch { - if (!crucial || !filePath.FileExists(true) || filePath.IOWarn("Failed to read a crucial file", form) is not DialogResult.OK) + if (!crucial || !filePath.FileExists() || filePath.IOWarn("Failed to read a crucial file", form) is not DialogResult.OK) break; } return null; @@ -227,6 +223,8 @@ internal static class SafeIO internal static void ExtractZip(this string archivePath, string destinationPath, bool crucial = false, Form form = null) { + if (!archivePath.FileExists()) + return; while (!Program.Canceled) try { @@ -235,7 +233,7 @@ internal static class SafeIO } catch { - if (!crucial || archivePath.IOWarn("Failed to extract a crucial zip file", form) is not DialogResult.OK) + if (!crucial || !archivePath.FileExists() || archivePath.IOWarn("Failed to extract a crucial zip file", form) is not DialogResult.OK) break; } } diff --git a/preview.png b/preview.png index cd9e9b952e0ce3436fc01bb2e3e65564e0926cfd..4d45881c57915c61adb4a91786592e3bf2894b9f 100644 GIT binary patch literal 43647 zcmb4q1yEeg*6rYs!6CQ>cL*f71cGaDcXxLuI0S+_1Pc({Ex3o^?iSqLnRm!{?_ck? zSM`dTVmQ*LPxqF!*4~7Fk`qUHMeqs)0-;Dsh$ww`c%DIgH8eMYkaA8-QRP+D9B1bO-S)>;@396_>| z&~O5QPBqvguv|}Nf9As_l3hJA7!H1%oDI5O8r+VE&3tF&qv%OEpS~$!`a>6-f9ZiC(}om9(U=)B&L{tv&@N`Ry)PDVqVW`ks!kOdzaZ;ewbT9&49Na zP2>rnKNjSB7a{VesR)9-%Wlj0N#uxuWQZHl6p(U!b&{V!W+eBpZp#HoRJ2L?{l_iv zphoE`&c6c*Eg8@f?B=|lJ?q&o=|KM4u%Bh|*qbIjCL{Cm93gZ!Hue;uyR;$oI%@(C zKi^dq7dcFgxR>Dr$$$wCw1aQm7%C`Y=u*Dpy!m@LY&~F$)BXl{OZJgZi`%`whtnIm z**~Xq+J!)}n>?^Mr$;ZRhi}TG0#P=vc@uVNP?x3>leDH@( zwCZRN?lU3xR(KFY;Q4*+b3rGMvq}wew8QxrQiL4V9cpdoudSDx-%}_QR26UE*&`s) z2zJ!)wzsc+fs~yzodTcjE6%LtJD;h@e%#BO>qha7`q{|-yag?;JE1OTg5rA-y%{&( z$Ai)Z-f25#j_NYITn^vE!O`Fw!RtReaY@O8ci%{*QxovDd^vnxyXD-URlGcj+e&Nw z55mQYpVtz_`gL~6>g0_=`KDpLxsgeX*Po;;rP1TZ=bx8(s zxS^D6eDNnw*PWZQy8Gk~J73yIkNlpW`S2RK=`)5Mk5NqP*K)R2%3ctMOSe-|wwSSrAxmlxn z=*#FcFYk#sSA%SwblUlvk1RI+VILLA1Q(Z!Hf%K8x1f7JpgfL3u3@zACj0R`Hepw? zZ~2c~?XGgmN*>w|qp+mYBpe~hnTTyqePviug}zT#k9vaKL2dCgXQ6_R7?4@NCnR0| z6+)UgQ&UrWr)|>^n)}tBO#RFy)n=IA0dRlN0s^9#-K|L9ZcO{#J>&<{zqTWKP`HK2 zuoy1HKi!`ALS3-GcN6jZ>2N6SUgjjPcqX;eJ+b-dW!425QaTCl{kq~8Q#`gEy}(hHR}C=aN6B|C(VP4lhR)MbmHE4D+#-@t2Nan z$C9+ILrotfzY5bDQw4gLIq zuS-Ze?rs7dXmY99Kx?D2iRxARP}=vm!ncw~TB}YuhkL{8s~&bsq|AVEL+KtYeXfh) zBUyn5Rk$37V`7Jo?dNNd>pms7_X8dhBQEt@{UHn^S)d7BW%lIpb`}q^%+dwD1I$o- z&@8JH4YJL0HW#1W-7GGB`b+SM__?N-ZR^DMOmK##mU^oz&m>!DHAYuTy?t&q<9?It zW#Ab0Sul-Y80M>mo0kz^#@8$HL(+Se_X|xvBm^AC!@KOcfEFBm?Uj1n(k2M??SS{a zdt)P?cDX7lh)>ZFHKxRPlQmO)VwQ99;>{w>GvpCXu#*%TW_?qd1NEvuw=VHnd+eNs zN3ZQ-Q_raP2@NnpF+RXmUu?Iip6}sdm69(;DHGvY&%NvEyL^S9_{&NZW#%X@r!ddv;&1Yd4(+E82;lD%%6zuI)ZP z>LAvV(dwbr$mRJ|{Z=!dH1ED1&*y?tmCb5=&_=Y?o#^DtL-*D}d;fJJ-<9rC-QiRC zy1gK<6dk}wZ_j4v_?`|Mx{orgWh`cEU$${UJj!8Hw);^ArO)psvi1h8%=X@@*7a!o zdT(@8=0VHLe4Lcizwsb&#JvSy4@wD%cIZ#91f&JEa&6QTub=KPzTUg6<=U+w#G{ZeBUefD!b#b`c9f1GPD&>3 zYd!~F%-;0bXnqyAF-A(m7w(&LF}ZRaHUeGqs}O4M&zqcr*sfF-xTpNbvG&jEfTa@2 z-DHwN2!OyQu=2cBqHr~y*Zu(tQ7?#NnlI*MeWh|PUoH@YoItSUYWn#xMbFQb_^O{ba+^1i^m@?Do3DQm8b6161s)g;0 z_QKIbKQ5*w5gR{gbu~v3r=;)2$9-8UUm{=NolDiPK1}uc#CXB7%yVu4Zey^VMrXoyznvuQ zddv@)-su+P(rw+-=7$H#)yA1Uq>$&@?r~W#xHnYSyrK~j(CDN>k-9~bUiI_E0qy`_ zdT|ysa5v;SX0`8Sy=|ki{8+-|yhPraSe|`3Dw(sIfAPQZt4xB&9lu-2#@4IjQDq~k zmhTq1t-w_6d`1&L@f|R^E_{xAHV`AES+Lt3dMjuIKA9Xv`~AHgi`ebZph$4pO zH~anepnY?(VDx8=8;RQ&A3La(N2rpoFCNQ^xRU2t2;PawYnOJ9YXze5?YSQi>)`YO zFAiei102@=`lemd<6{;BxR0>k7rQORN6Tgj1@g>6F@umuBZWW~rRNPn zKEhd!Ji9EBvv!DZqd@AlSLu5;VjvHgGKye@CoB8JAA1j|CRlJrH~8II3OB3*fh?Di zxZ-(ewHrv8)`>Eva31&bcH&KOwP$J8!gd_0Lu$`^CtXhkNJHTba_d%CECsKpJsCby z8<_*)KX>1IZxgJ5MiG8HbEBPdzvmMBLW29G>ffW;nS+fqTc^ISKNw zuzRvhIAFqxoLFr4e!m&1NzXac(6-YhWon~7J-U;Qkv1d_z#YZpA(9)3IpKW%FZmSX z@m9^@?S6>JYmtyD0dEJd7n27P&>HX&sk18Om9~SsfNacV)P31Tl?=X1O=|>aTr2bA z;$qvBOMKsDl1(f2ZhLW7r4{pPZqkupJ&3fxGA+__^gr$j;8bE>De9P}2@Uc}cZg2Jwd|)qug$ z5Lc!R38%wyWxoK0-FrFNIc)FeR(6N>;?#Ne)KcKPzMNhAV zs^KSH;ku?M_36QzewG(}II6winaF%WoWAPT1w5<1&#Mq5U}uARC35e7BV;bkRMt_s z%Iq@1E=a%HBbhSn|HN$b{R@Aq2~$${s?*;c&)kXOzvK2k@G9pf9$I(3{UbbOw^tSp zB#b-~#LEjS%-CH`*B9^f%#?lqoox$%T3)35pk8_E0PN z=9gEUG}-udx4!ylGSy6fA0EDEdkO%Xuajp2KzQEH&%9*r7L0yo-onZIIBhR$G+Ty_rEd)!fM{9SH>>aS#o*)s+P2EWjSE%SDZ6 ztZH_2dpZaAJblqfM|{nIoz&XqzF6Rj_f@}w5iJ&jX!QZQzr7!2HKPR!Hl^i36W&m9 zIo*OcecAK9PjR_IakyZBtQAsx46xJAf#+LUE}I2G_Eg!H+6XQbI@*49cvb8@uT zB)HLG*6~qeYgQj}&|Kv6BnZi-)og&z_Vq;4^SibJ`3D9<6Y=hMYL$zwGZ zU(pJo_b_c&(FlfC7jn|n$zb*<8s>;9_6bXFZV#vL@;}q7GPV$kh6oe6K+yhdZEbc< zaWDPk{+yc5>7exR`|BrwN;kglX@h$NK*fk9Ikylx2AgB+zsPg=9|f$xG+yZMg)iJP zN93Oa!r?D}AqECv{^ilINK}70Ga{zcUv`Qfnb`uRe>1w0ll0GZV^t^V@?S;&xr-d1 zGU4ytWD>OhJnH{@{Qo+@68@5`><9E7Z>P;Zlng;XlG$>d?%{M!_FpxIy{}3&YT(^g zWs~Uw|31-yFf#vU)sOUGrmTCR&MG!JdF89m#kQ>X<+!*zPp69ax$m%qr(O zw++9X3)~(1v-2aPG}NgYmZweh-}5ZQk4#X&G^I1a)b4`0mhE=%-3SK+r@aX(zUw(7?k$}bSEi9{LHREdzwt?85MGu-@UdHPZN=+EmhSZ7 z{@(ulkEHd=&s2hA)Hb!>7skiHvyBI;k@di1hld|d>+#`*oNM97su@xx&O5%7v@j0Y zr?2$xEv^;$@qAsDExEuYr9>Y?##;`JzkDd&{q6D9I8N~T#_YnYK_s(KpiiHs^nSC( zl{vzRSx``L$2)bzf;>#-_Q=jJvch|dfld??^s*(R{5M3;N2||F!`yfxg^5sDO<#w* zT@F-}+)9pLd!~!zUQd(mJd#`lwqBW9yF*0_p~)>VOVPPQlT3n<7>$LTxzY_B#kEG& z6=1yxiCpQiEH^GEk?K{2$3*hwJHj$Q*M1Ynxbw*do$@+jV1eK4R};r)R`$KR{9+WT z_AOh$pXJXEg&+jXWlsQGMF#8-zST_WAnj4>%}V+Nf8kOO)9IXdI6v5p)yb*iQ@NE5 z1uB==f^F(;i|7!H#2OwBQGcMpRJw5`jI}Vs$4i0wJQ$+xT#A%NqVP$6*-)^;go{M1 zBNq~)Yvp>awKyxe^Bm<>*n}iW%8&UTXv?txOPu2Av(kOMMcuTqfzsoP;cFJYxZptM zKCvkM4V+9+-#s-KJReunA2@IHOkQ_uXD@|z5!m~^GZe0O{9pFm+QVaY6{UJG`3`u> zD!WnaT4M=}vW{PO#*=i^gIlcqcW`uyoYL|VEJr#3JI5lm7H80Y&2ihcX@MSqA}~;` zfPs``nzF=3srniU2ZvYy38in>rxO(i2gD?yj0#c+VYKYZdrjP;K3&ZowyjF&U5%XA z6HvvDSX*>Qi5m3;%7@1&bp{Pna~g-s(p{pyOaH_~Gp|zxb_6_(a6yTJI7B zD_2J(AqK)ksHZ@zr}S7h;~k~YXz$zbY$JL)@lFXgJq{ikhn-LPE!<`F;c4G~D2%Tb zZrq~IpH!k&-b#yC8`TX*-V>ASJBmGsc~-2^1jD+EXLoy51MhUfPNcwv_6}=i8fC6# zpkh&%4skB!))IQuA4b*!wt4xr0D7HHf)TUJ;#w6$`?~$m+c94Fk?ud`zHfm>toIBt3jeAMxe(?9}N*~dd z+h__9g6>#fR238pS6U9AaWuuJ@jzzP#Vcr{;WAGZOgeFVN&PO0Vquyh`mu?EX8|n~ z1n9YMTSg`89~k;RgIauH=(Sxd3BA9@4f7>?Vwlgvz1=flxQLAcMWJB+ffq#|)*yZx z4T4{P)xZQ2e}9_z$0hqB64sv}5~|-jr!l~9ck02y5!Jteb*+0dP?k}Xk&mO<#9iaa zxFL6PN3>O;>8+Qwz<{oi;X%YSYNN@3bu&#DM@eA`W^Wg@B17jB%!A-<^d}qBRZw`i!f`8 zxp4Pk=oDiId2pV}#F1$JtGgkG!=0`!h6v{|)B5*oOwIEcB67(7I|ys`LvJ~clxNG7 zch;=WrRmBs1}mh;XPfW%+a24~VCB1D2vG^3^x3WF0^&P8jSV}bof(^6b;70pW*P#o zK_j~Q*TL9ogfKpgDaL-p?}L}9j$-DDZ>&g=TvFIzr1wLTLDc8tig7^(M-6CWYZ$W^ zJuG#VHX;amJP$I8Vxsel7h~ImZ|}p>utH~oC)H!9`$2tj2c*YK!SM?MH zt>Lg5#x%JWw3t%zBbdbsPQNFg=O*+jOE+_DRim|S7~a2{4;$w27py#WlEM*3#4zY;Z2Qt+&%FLd! zPD3^Dn6)IEkO%XAQN5a#IBQGu=-YColl9~i?T%DZ@3-JsY_0j>N)>7hQf`4gsKn+- zA%Yx^LTG^icb%fgy=_l8UV~{Q=Nw07I8Xkc)lr}4V(UIYesz8(OBG?1oSE%DSV3Hg zTOXpW;YV;95nMc&C~H=e;Oaor_iqT=S=PLT>X?oUPLhhGoFN2{&j$MIsI=msSqmJ& z_X#`mt|{Jd8%RHk3?B=F(+mvoSV!Cpe)Vc%sU9LT4paX`&kKu_+la=XuO_SvrO{f% zFyB+`nbw|Cuwi+pl}i&`Sp49f36l4@`LZN}`R?EomDDUv^VvbK6U{=`h6lTKB6BTO zt-f-X>lm2RvBut5JCxF5b3dWFJoOJtUmujf`M0t8q(4Fdz06R9EDMGGtlyfp18LUr z2U_{#h$Dfm&HfY~%V@ftJr^58OtYIM&8VP`Az%ROYJ(rGJR2o5(y4u3*esUMZHBAK zXyQ`w)pPv^_S$45-#kK&;;aC;hmVLP3l$^Bk9@oj=DgIDVyTH=) zA$Lk3cQW7T{RS!thRT!f|6!wk;$jq4<-a~{_B{our*yYFXd1eYqGP9Q)FEe7*+pOB zsIt2}J*q7K%amlgb!uaI>JIKQDyu6zGcDG8;#11k^o~{JN!`^7r$X0<{KQAFVEzrE(?0m zl*sIiX1ANf(^EwU@Y{QpI<{iZ1Mtj1Zx!;3%je0DHt=-GXv*G=)$ehW^sEO<{!i`h zpUca4Vq#*By7TE|hTI$-=a}Q1YnB5Dnk-Ox#}`RQW!6 zS|SIMC1HC^!Ty8L|0{z24HxMdJs~iAup|4N$M$UP*no95aiT*0s z{`t{EMqZvqHaHA6as5I@+*6&8fWN4dUqZFbR8}7dF*kz-7I=2*#sYWZ8^F)&{kRb z%allcZwRXu45Q_HY{8andCDJ5#tfi7iYH_ginZ$T2p2pgT@J zea69T@PDOFXo46RCC0GEKM_#isF#(MHR4X3{qyI~gkx^dS5L;%6rZnF8U#4N`cWoq zCm-p#Q|3AU3!+I%?Ijr%c|vVVqCvZTgQJ)m?Ly_ur+?M)5#US07FiDbdZ_x;g+DP1 zorWCJz#>3lG~+dLw~$mC>W4}!RhO1JC-QAuy!n1s{1fq|ObjktIdPNH&-%rU$Ui9Ml#YD5kT9;A%mezAt?6EZ$~AsS`p2jgsijF#7# zLKOS0w$^{pJ_N#!paOEN2Hdr*?v66DKWT~Tc@r_-8d?!&6B$n#j=Qx$oeVyC$W8W^geGEQ+q2Rk_FBJ`IwA4;fc z--dlKz%_p3Ly83paAi&Xl-D z-u`kdZqO&Fnn661*l=lFg8rs19Phz=@At~Bpc-FNB3iYZ&M`o02pgm;V6i;#w_QP< zq7%0EE&d>_QyVtEkLM3F-OSUbPtwz(6lqeES111tLalylEG>aeq=}R?PrYBmv_YU;P<65MKdK`ItQywF6 zr=0qczgE(lApyih$>C3_1zLzWvN}YT#8WXT#Y>Sg+cS(JzrHlV7;=8189;|6Egf9> zG5T)V&{PK|p9d>#k=4Nwc&jjIW9q z?iHW3#a6X2(E*A3lSahV7$bwmcXk}3O;8L>+;@Woa`}TkL+c=LtD?wSZPPn&{JvxS zvOoWj2Z`jtPm+SfwBA?#Q|YO7gN^w0QpqDONs=U6a|_#!NB+fbZ#5dB4nSni&;WXz z#FzT?Za&ISWoIksUW;Oe`Xf@rT9-W;IT2;Msez)7Z6M*U>h=dFL~0BHE0Al|$JA_7 z+5jZx%l-YieKjT#r4z$S`_B_QIasHZmg(B(gi`ux)_qX#RskTyQTz83Q{GPlcmvZ|=esbjUQ@hZ9l$DuVq)CTab;)h#T zwBKLIWe{`qYBw`naAow*sH{NCbkt5eJ3BAB6h83?(AV%aJ3G61tAw&KGR**k7abN{ zRRtGdJ3T#p98jiE=bPr5124h?&f+)3rZcqEue!49Gp&K(dB| zgLA)K4=r8?^e7zsCi7&URd2)fk12=qH8jOuvZFx$ayUD;;$mx~w<&G7KbNn1Sfq># zYbva)L_cYV2ngJ+eNIR!_(%Ck>PiNp{gNr8=1W=!(nODTY>BAF_y~}80w1 zmA_vB9jf;O&Of4A(krk)YC0pJoGnS^XG1IpXMCog7|sT|L!y#P2Zn~a)81QE0xH(N zd!RbKFx_Os3dkhff22X}yU&4*)?k0_JCG2F>v9`g_sl0uP$yF^ZM!Yd+nS@SZ^VqG z*=TW3P@us@a^|6|VWn#`MlgD7DA_FG89*dlPTRW&d`!%#BI=-j;s zdJj2Pm!gA5g7 zK>Wh27TuUi?8|d?8dSSQMd&i=xB%l>QqIR-p6a`AbzfVNQv{*DtT*1HzO9cuV&MU7#GXd2 zQ^JHs+{R?TfQgFmsfU7J3mhNkOgFL(Qn4gdJr;1yLVXg)vRV9|>VsZL)dc1m*& zQDaQ)9jN?)NRt5W9p2>@sE~$cy$Fje4LzR39t^E6QW!&(NkzAKsTc!CQiJ9=edLM> zh@gz*Iqz6+wW6Xa8{iUb-sMzp)Nm)ZK7nJ_#)@x>aFbuXaKrsz%4#V-Hi=yq?ynLw zqHtYsppV^MukzH9Rd^h#Q3<=i_URp#U48ogNbv>%lU^ecFoDa7v&H%6)tJ zih~EUVAB@xuwSFIsGPjFH(|i1a66v-;fk3m+{hH4 zOO>fTJ`y#WP-O?m<8PTo!(sB^7Qg&x@#J&pFG|4h^4>eBuxscsp{y6N2`QTh)}^zS z3mj4?i};QwGtDZ`u_>WU>4n7qlh_xzYjMPXR$Dj+H4I7HIe>(EqZ!;1LwR}1cn=fH z#}7p|H5xJ*@wDe1q2%sXjYt*JlN&Pq%#zjvHJnI&&G2N%+6gZx7o_}li!)F2ZK}cJ z5@p(Ao{n|r7`HOE*i`)Zr=ZTk;*610n`}Qs_S6hEC{&zwl(vPGEF>5I>A}p zSo_wD_85ICpsIW^V9TX#!#zSn01{L!OW1VP_ZLKWLKd6ip_;GiUbET6s`e%z_dQSfI(w8!;WKSYCK{brDkpXEw| zyoxe4{bLJntb@+NBnOrHBvxa%mkv_%upu&W`-ciSOVUi1K%{0C4q*{wRLW&*7g8)2 z!Z`4iPz!xG`Zunj)$~yyA*!EMVDnC#AdfsQpS@_}4v-^;)eve!;Eu_lgLS^bVI1=5 zjYc#$2P{^f;vOH&R%`+xT=FKH-wS89La&gQNQm)ujzK39xkETeOqV7FL^jXNgBsEnN6FUN{-#f9%moFv}7S5$6345v{y(}WnCP`;<1 z2aQU?V)XP#0IEYFj;cxqa!wW8PV@UJY^wsie(vF}9`>~sos1;hm~OL_CXGJ>bCaYybQ42?*U4bNp5Jp0qiEa&2b0Sa_2&khVSzVPL!VIig0pe{6dzLCOTNZX)@>f6M1v<^*ZFr+^(C- zlVQYVpa1bZ6U=q-nZ=Yg4kwL_TCCQO*Wh0gADJ?>GA`|xWs-~zM2=jpk^|mIoi4-$ zp3jJ`^#(ol8fI|zMJ}HN!)5sUJl#$35vnLQIEIRzEq+OqCFp-fpecwy?Fbo8C924Q zS}c8iiblh*6u=`?LsFbXy=-hRblR!OwJ3m^^N|nQ8Y@>sv9_%^c##jk>5hhg4oXm; zBlsbliL?8C#+p3KE=NK7Yg-4i^E{}C6k}hp#&;{b7QDKlerR0OzZ<{p2D`M=uKfUfrire@Cv*uQG z5e||-a7U(0uZW)!b^;;r5sv4#ZWPY6GAS|0x8e#2xrCc2L*AL>%Y_5NWy8gXgv!V_ zV>wQVa2Tg(xs|K|cY~h-$s4sjvy*8ngqKjMgv@cepM)cSGJG{9d@26pT~jm9|r z*ZQgS4;AVl)Il`yCP@r|=MVX-p-*RBG*dCEWf?BPMW<*b?HCRgCy z(lZRs*acoC;Fvu--Cu6z<#DTcZ2d}9FqCA8Q!Uq)bmI(6p};Zr@Rv?zE_}=io4!-q zOhWw1vMdq%EOlrD{WBPCNkBReLq3_n>WehZ zM<2Vw>(&qoGes`+;e;LGoa*WFeYTrryO5r>bjx+{% zhn2WN+y&jiBV!K_LW=E{cUfh92b8>w2M%kquUeAbfFxZGHp{yDFyR^qn=^5Ju3^ES z-vp1CK~&9x(j-bK&y zI&R8;h#}#RI9hDzw^`lsBz_2)G1e};r}>V<8Wj#3ZSisMs8J59%9#6dTUoWlM(}3p z^X=k~T;B4`zjPpk6`zD8WY9Qb(RVB2{9B6o^zjEWe{oWu1UdALXd1#J%o%ckwLCLP znGnhXdZziWr|`L>TY6?)Ulj2^wSq5Ks(R0Ku72r;tr%_`i`lwBr$}aBcn6%f=ldoq z3lkxdHUkgz=t7h!^9H2(p!aVO$$7VRXjN3bIdiJ&;7 zv+?tPVNfeKevQq^!V*IeO@>qRDZ=E1=ZC)4_*sc=k|c&E#HgSv;OQ+n#Szkq}qY7gpG@<6pGcOh$$tlM~MMjl~3x__NX?62rFd#J8;n$t1SMXE`ut(H!nmg z2z76#U9;Ln&jljIcV78sQ>E$R{Jhe1n4na>Dv&3O3@7r_FVlZ(mnI7hD}ZYG(_b0} zy=P);EM3XH_r_q!Q`!@-q<+&$%R}$&9NzlOr2TU!yVffl62Hf@QfjYkZl@5SnIYfv zoBA&4Z)M7(V|Nr_pYpLKLG}*Kpv;rfZa^EIN{5XN^gD)tLRXLrfK#W1C6mDL3aVCY z7?GbJA0JDTUa13h{@x&puwLo}w#>ZC$#4~o#Kk+;Kj9J^DLnzY+>+rYed^=*+Q`GC zB84g_+C!}RrJ530NK3iJMvRzTVrpg~gIr{`rn0#w+3$|fQ9XzJcer6~U55Tehx#L< z^xF}|4#imwNOV}2Kge%5Rxgu$cB5?hL|t(!5OLzAOUlR@h8hbsNwFo6bepo)QbU~n zSN!ZDucs}jq3kV;;S;TzMnw*SX)aD4)5Rs4E+y!3!6+>vJ`75%(k}&U{hG{PQS(*z zcg#Tfk_JLTk4SRi$ycSwJ$m1tuwGxPhKw~r<@lfT0)pdnaGOTR{aan;4>+&`!o)Hw z6mK~XL8$IDn?Wj826<_rO2Y9$_tT)Nsx83es{|2jCUqEcVZeWX*@k=jp?a_svH?vF#maXsnaM= zD`Y?{GN=F-Q#71`({Q}u2KpPCCm0k0ue|&#_&bV9GoJN9V}QdQ+!imu|D zjMqAKf2vZQO}LW3nfz{eHh-3v-5Psdptiy^q=MzE?EOYY*G%SbZ zD~V<{^-BbD4^QY1McF8YuP4Pyv%6a2MQPuPl**1s;^Ycw%Io8m=SmWN(lM=KZfbmk z&J!BZm&i~puUi~lnXs^;b7Sfqc;mNRlYzGPb^fzV;+9IB%i;X)H8R{}?p z&SKgEJF*cV>%`p@P=C7Y4V0e|-VBkegG%unq`9?i!tL%83)Hj6$7vwTf7;nWzNMP7 zCmkR^vTnkzzx?TiO@Z1eLOm42_ghGE4?{jW%@>>2MlH|qp;KK z+a$c1s*X6dxan9bYTo@%?B|EmEJ_yx)FLdta3;*NExh()3!E3k7mI1Jtp9BWail52@LlD;U;2k#_? zjd=LKGBZa9-r~v8FzfW-S2%n}BQW%G?47W6S+kCP_qv_z8p&@eKj$oF_q7Q6Q5dbf zvW~RB;{122^NG?z43%(=JDe;q1+Q4df?TD# z4Lgz9t9DDI?)qKteMcY`-Z&#UG7JC)hClxZvZ-Ni&DU@`YzDiPQsZ~;MU_g@`Eu@^ zC<_CEHT0Y%7i(a6l!ydX(C4dPC}aOBk((_HSrQgn7tVPZ!5<|wCoA+0q7!J@muq23 zSE)ugWK1&3@WHe#1`iHS8VrRQQdM`8CKf}_*r2eQCow2@ShI;SY9Nv&*pqxhB+g|! zkx+c{?|h~>O=;L$a^(4K?ar%ZtI89IF@N0OpWWT)4TBY5glnGvBwRy97oEe8FO_R1H0$6^-4nmA zOs#gpzvj-2P(kpq=Xvl)!jLOORB-O1lLPt4Sv!h7yG8h*_X^0E&yX_tWS_eU*P+`u zMxZ}r%wb!RD^A{olP~xt`9MZ~|JH{*Kj9G&L@aW?dl&Tda5K4R3&c4_sd{3TZh++A zkyao=D#QV_J^l~c{&$I;A~v6%YHqDla*vX)(!eSAAh(J{SEEnpFwCKqsvD}IG~Jtt z+MNW&waYRzZ3H2QO>+6Noc_;gOX}lDDWahvWXiJo1VaakH3U)Pjr0-(aQ?uDx{BsBrdW)GNJ$CgxGoK!<{m zy#iyUprBCE1~MGlg7dPGNq7P@yc(e)5!>V(eU8R~wB~kQNM8xdifC)Q`c*p3=|j6& zid9q5c_;;mw%#5$eLy?hDUIkg)_Ft!*!_bQY0V$EG8K8S!K|YrHS)Iez^ocea{c4K zxD58V+23LUJo(1==?cxT?<>9f>+l5?A8FPkr)HY|a3*vB#R(Y8EPX#KW4@BDy6e&L ziPu_|pE#&DZq4!QabPy{KFrTxCL~ykDq$h`%*`8?gLSm}$Lk02aRh;L7C2QFS9|^9 z;!Z!#0R=g)Cr+2LOuH%W*cUeT4Y-=^ra(Gb$ydH-|FOhD8g?MrHebSzDqy`YM2ckG zwyMaB?=RO7N^ri?col-Dm- z9@U8Q35j0<2AAsiY0V(Yl&}2bJ3VJ{%=WS-_B^6d ziC+wz8YeHPo4#0!_Pv^pkfNJ5{bn3sDm!JkE$fpQiT2 zlXwhC@Ac8*X8nm%YqZZtE4Ff_CoCoGK4VphwU@52pVIc>(ByeeXT!y%s*AqI#Rz8& zDxz*HsizluO!Mf}-QC@+sT+DkjgF!oUu9}7-N?{8@?r#}Xb>G1irs*r9FgVvt**rvxEhL-O?@#G&d+#J?**NPEK27AZm9Ms>N%? zsp9-uCrm!hj<#UlyUcqS=p% z#AEL3*^e0y4-fSkQxw%wbs=JTprL?`BAr_bs9NP+93@(;dM>J-zhy%C!1xNal{;9? zo3yV?Eq~`fm31tN+k7E2T6XJa{iLIo)t9O4WiBy+FJ`ddE4OA$XbyGY2g`cI1aU}z73 zOnH-D-0Rl}Ifo&qkkHNIMAF&K@U!-By%b4&agK-zoRjizFNZeaVqRJcqE59=EE(%O z>q&H*bZI^~Gbj>XJ#2$?PSsS^5L`LzHbz~Dv2wr!|Fxb2ZXz)#BHi2yBnTu2MGFR^ zVuixP*n2u+M)N=!{$40RYEX0dT7phhopFn)9yIo*KCfwj2y2E4R89y~apqE1WsT{6 zg*fjOkbwD2N&nDm(q{t2$okj+qA`wIBJ*NOBVa{aNEZc{^M0$yK5Qm0b}aVm#ufGU z({=94PCYvnVn-p;cQ_zq6fi@S;alaso_e)v}E`{S8e_< zJ7E@6tXkPJA`uydN~4_rvd7%eHUzeEbIEj^nV*Uf*WqZ-pky6yt%{-`TL!wHRliZr zS#$cls|7Q$q$2O$&#b4_Y#O5a{VJwc8Rf#5Jz7LmFL|tcalN1H=Ml2|FctQ`e@cfa z?ydoOc}wMkgfQA@t|0p0Bo;{c$(pMyg=6CZdnJ=mI2;Njj3>w$zJ0Aet6qH+hA9L9 z>aV{Vagj4WiW-R6;G>A*Wn}!a_-*^}_%S7Qkj%jUbFba!3Xbol|Ix3~dPP^wUtGeR z{MgKA4RMb+cV;%pf}8E$uOBAG@{tSksbTzxop@X8BgggN><9cSzCC!GHc?A&fJgpI zFFH-!{puZhs9bCI#<-4IujDJRf@^nx6ruor^*|pOFA{+x8(AaiO-n%i2pJhMsC~T5 zI^L*M70Is~A-z9NBms83_;#Bt@~X(rv16K0lJcr~&HRVBWedPTsx0fGQISs($T`b0 z4n}kTSIR;A5#1Qk#XtWQu~J#HtbO;Pov26&^8Zdcv}o*+&DUTD0zn!@p9j4}GC#&! zd)+d}pzaY_f4_Shp9q=vaUi$wKF5R~&99+G$(=t4{A?4p=Y*u~#V+H*W-Ju4G#B{6 z&A1I+tHc&}$^KRg>o>)(|D9@(Z+n&9Y%uAp)iXW@UjUtCTwd4K6Hh=-NAK0a>>ldJ zm&mob{afZXe%FiV-)%2VK&3d~ZAO+&?`MEil*+!4iY}m8gVZ1+7{>`mhSnd>7}OBFV0iVfi0*H zC*xqIN3k@~kZ9)}7;Du3#MQv@+)NLFG6Lj3Q*~EyvYXHlf~*TV+e&cXesFH&JpOM zG#MMPV>><6W`Fz&=MWSQyMs)h#wTv*{AiTHpk+_znzmZQzkUO%8 ztQM<-H#RMUsD%YSt0xf_=$BRVSnq2iLu8OtW#S?vJ}$I? zwTE4-#;seo+Lt>5D_uV7;o#tSLD(R|PrW_(_6>1eUAU=0_$!~o;mAUO+=*K1 z&bYhlcC&2`zDzQFelN6o*s+xRDw9!I*A!C1N||hd`>O-wID#Z3+LzhXPTP8`=qov9 zP;t3C9r5I|qO5a4b^8Rovrxm(#0OAygVir&rpJZjMFNK&;z_g$2er4u4aq~epc~Dz z?VEJIfr_odclt$fPSv^ctD*eQMz@vNyajCBk?1b&agJ(ZGhb~nd}zF2^^AARi1-{a zg7Vn%fhB&s54QG%>7nDkxuC}wUp zHsOcO=T=V-O3WbP)&F81xX*|>nTN$mRvNI7s+BQh@>=uzI449IAX3-3$m`pBev z$KN#N^<$)hqUsxTep1hQkUWoJp*hY|Ct_9a^<{f(a^L4+RYsaE!VMC(;jt_n)HK)& zPd0usJ^xzF`x7{PuLYjLx{MOG9=$vV-Zik~wPm^l zqikU94V#|$nMwc2Wf{}riM7XBXlcF(wACQ>TQ!H}p0O6=F;D=9e64|I<)V^P zt05HG8^@1)?WCQgG1AmfP9gtlvpz0t%k3F53#m9vqO=H_josQZ*J*U1Db8pBS$o_L zaJUSP*ZDq10NsSp+sy)Lg=gd6=X(%>iLqqh?9Dnnzm^wZf~Ua2)S$pO$}a<`BJe8| zvkFug?Ptj^FVyAg_KWu)1xu6i7{AJL(bFTHEYbAEy{)F)gWb6YerzXY*9;%?^DpWp zos`yF(~vEyffa=WnI$;MWec zLIQp|vFKa`fXVL23a4qrJ#0*~l}<0BR=f#AbSOg#rv}rb5#{Pq6YdV|C6TdCh*zz8MXkCI> zaC+(b!d{MELnIOS)@v)ufsFH+{L;d7MB5$aNPwsZ-^i6`mfd2K`Lso)WLQ!F@9lII z!#*_Ed%jkqO-9Vb-1VD?xF@3hh=G>60NT2x;L(9({Q3bwHq3e-#w}iQ9A(e!K(o;| zBfS0BjMi`YsKo%W)#;_UoYAhc z&p(~_+g8FDY$fdJ*giVOA|N~u9gSK$@%ecxQExV!O4=b}!q9H;IQ+O?gm@79%&QSf z|FOtKsZP#}a&G8i9U4)MhFK;CjKAqF2MFvF>o!M<&}?ucS6J4REYZksp}t;F=B$-X zXWb!4xo^=VZVA%$tpKc^BeFj~Ij!9&yjx<>4$H34edhb#_tMj$Ft*J)%)4qv_v5@8X%L_gu&oYO z{Va61k5g2v@53vOQlk~HaDt6h-~E^z^njtvEH);51FoxuL;j(`>;_r8JZ--CRlaAP zjKgUuSN5>!0en~kS)3oi-Ti)Ms5}8l0L?j;K9S#*HxTq%R;uyXzvOUS1J$0g@Ov7%Jt)0tCg6UEcdXs=`)N7g9rU7A^KM09+1=@z zHBM!L1umb0OOhkNk#d~}o6WG^^s6?L#573ySX5#wR?bmXb6^gL>b#VpC5(u03ah!O zyfPa!xJ4i>i!K%~*(u zx!JpE=56Kauz`5?N|_@-tK>IW2Y5V+95;veL$PI6V-nb0Y16pPF$TdR&q`e0mH6L; z{RTwGUb3`&6w-#QzQfkZg7soptqvF$4DWW9w_;iL-1RuNTQKz|%dCBXn(CRZHjCL8 zc0XY%d-O)ph1I7a&2MZlDd~W2^ve^r+xu-w>CYV|DP_153h*$R_uEmS;xN!AZ}Vap z2__T65(to3DkQfCnLY$nEx<*sV3}_b7fhC|*?%xO(3S<^pBpn;o@uMkuy|R7#wsNo zvlvH;4KuZvr*EI2<5*nfQMqf;e;qz>X4AWnBO}FF`P8J5Nr`Z zKcz-}PctNws6@w3K9-hS%)dxeW|l}vrR)@<uOo@W)@j~eB8!i%b8#K3&(KQF zqV+x3XHK=I5!=LwgqrmWx(9=SdJ0|5VC7-ZKWKMzc>erpWm%nuy3T!~mH$z;*Ocd9 zybnvf154X!L~l9c6AWg^nhdgX{a&N1iBQUV@BCTH2(XQylzmF)@E&8%&_+aNl?21q z`-`g&($755eW2IjJv-(v2x7^Du`%0aJ}wW=^D`FhI#e+E?*fTFyK`)01OtssD6GZ( zOIAh(6c~O;{c;rmQ~vWRK$jYN6g$TkY)gWgE?XV%bGJZh6&cm>ejlws%*US@YdOo! zL)l5zr<>6^`^<65T&TLyed9;aHycISQPC=_KE2lxTnfuDOP^vSFPb5~!H7b+L?&Ti z;A6xYn}JkT(aap?$>F*QcM(%foZ)_Jva?~*oO5BY{|~!N96x7h59RODeza=5@Dpp)6z@Fqgz|?w_?MC z`Gm9rO1oMCWmZ=UM?<4MI^HQtR#lg{BldpMzQ)=iplcZXzhp@rZI820qob)suN*$~ z(N}`Q5P&{%1n@wa*!kw7b32!~z62R}zkiI-5t zT`&RfNuSNXki?rn6WGN=cy*>L)8nPmkM~SZ_bK58o^}|!RDbz5#TLxgEuB4lFkSJg z%Gexj(B1gRzh@WwRuWF%AEb-!^VdS4h+9_wru zN$Wjc?l|odX~o#5ZNE&^qBM}Fwv#84^;nqQaC&aI@b76PobrZp9Tid-?9v$$B)Egk z?8q@>F$~8N-FB_D6s3VTl7&{;$Y5ol&?t=AO!BC!tG|5t?P*a><-&HqaM!-AY6@t{Zozitvw!!lnPon(E-6jmRQEyLMewn(PEeH z$(6}4;h^-v5Pu2)N!*>*eW2i323AlHmFGYW!-CI8V_S?NUeNu-n7DiG#Lu5zbqdKR zk@Y{oNPD!g`&Ln)!thEc;MsN5PgKR5vq^cJ1}J#Y*$C=F(gfBLjR*IHzfVM$o)?{~ zuS5mjBrH!&OGpUhww%=O3c(%!1Wp+;6n~!Nf5Otd<<;;GyrPhf20=Y-bo%*?&y~|P zw*+23-Hfo#&piwIu5H`m-$VBNZZYz-*-$D4Fs+0p!n?GXFh)DOyb1sdm-`{qPz`*# zUPCUE2H>6BRxngK9KIx58cE57O!>b(ak>TgpFWFuYD0TSxn^SL0u(dy8>}HGpX5J` z@=Kpn#^shL!STis4I&?%eqwr*o@BHNmsuXagSJc6S-Dc(!ZB8IvjS*H{R7q6iDIsjluc2rjw(rrDm z5uP6y(!!T#@?LY(5xG~1e+3OkHc9KckHLDBW#!1wL~ZAcPYgKtdeVA}Hk-N`Z|}-Y z42JvVC=n9Sb6GI&e#HEUTu97c;_YXMt$;BW^_qJunb9nbnULwpO<#OH6Qy34B5j5K zXnf}I08+;&*v01Kp1TL7)AyMwr<&R%MQ^*Z)#zl9QJ)DM;G&YBzRdoucfk#M7av}c ze*h8=AMyN!W`(9Ktm=@b0{A7YlDWnB(Qk{`XQ_{xhzszrx3F~ewV>FzGPdJc5UgQ} znLpdGwZchWz`=U9HYo^_VmoWn@WE1W5ybW(oYS;gNcsyq-4TIm*(lj83cvIAI_%5z z4ZGnGs2hH8Th#a=`6s1De@HrSqD-itxRfN_-JDq z4hmL}=7fiH0~^#rRxWbZyIZ{pBigvf?pn8yQ_GkvWwGO4qgi-h#}mrTPWSqM(R`Qm z=6W{B`|NFt-JK$A#3t?^Q6F>R@1lO0^jKWmPg8uBqF0Q1V>6m!mv)L(7z%{3*aQK^ zkFgLR;HRt?p+F+Ooo){Dj}boK)d;`W_#Wb)8mF7{0r!=R-S4aGvV3)VI`!=n&Ij|2 zgq8GF&^WF8YLqpMTxlC`5|o7nTR)6!_Hv)~s(I_{u!EwxQCLZ^B60t_0NDyC$f!P0L(&ORRAfda2ul>p^_#`gSqSjX(`tYTQ|hntBO6V^UN zrq7Fqba|1=;jFO1xF7AbnUGjCA$ieT=A*aYVW!Vz7Nuc8KgIiG%J#1F@@@M-yY_O; zAhAupmB2l@ys$oKsO$6}4@v*2{?98fewqBkLe*g2FQBTXp=!RM;H@JcAxUEGoGhA! z=Oz9&3AYdQ1E9C+Lw9yz@#Rm+-zVs+^DVp|$-m^U$)6mEpK|PeQJxr)2rK#Cu#B{L zla4J5U)5RN*fWBsl3!MX!DNPq4wK_bXhBy$0}*K;wl{TLVM2y^a3)@5Xy*MTpi42| zdo|wA`9np5-z5X{pB5ybd`%n0;0I`pI-~ue#E`i{DnnG)(c{piX|+=B@; zqz`OVG8qFRT8$R+hB*5&h@sf3myfI(@0j&tLe04=34J>|L^olGj;%8<48>#D5hu$2EbH+pH`E^!L!)Lj>ekXbHM12Q3oru0e1l`xksr4h z?QH4E2{blksv>6Ark`pm)LH7(TG+)$oOALJkHnD@VXZTv4D`#WQ}pv z<4Lxi$^80ILpeapt)DN5q*vEg4jK^Pzq3WOUpW7D5^((KB+y~RHqmaKj=H$k(JsBD z94?cHs>-*N)|pYSTS;8&&d#^xPjj)Zz2bnyqaIewJc*ky&hqaFq0IkJgb-!se}fPr z&xC_IU0V(1o9ly6LQ6?)2j5>lBW}C{shPN6)lBXl&-1P;QWJ(&VnUMpz!p2|gLp$h zD9FL!g-PYH-l<>EIpfKf_QU5sX^$PZN<^#q0`4$lOIg)Hze+>2N{M;njlVh4*yn?E zim0NI*m_}1FN&#S;G#`%X?!q(d`f3F{SuTHxIlSt6~E#-F2}6SwlVO#`lV3I6Fq`x4R8yy#T4H=-AnVcr>Yq7^*#xh%!BjM37w{7zij zRhf%mVni7c8E;_8&IZZ~*36)n7X8w@d6GQwyZfTX%_+5 z^68tI@sQqer!$IcIg9lkiv|tK%vaNl5$HoJX4xIF#~+#v-n(Te2EBSc>{85Y$2lkV zaQg#(bi9$z6amcaP&OgdfYS>FC}sFUMNMf2evi9faMyZTK0p8J=J2K81O98_d7-S2 zd$hMC+%p~6&ThPly%~)H5xMM~F!*;YHTUo|#_ODMXbI&sH_Rv|@3cPQw1Y1AL;E1X z(os#8zDtfz?GS+vs!PFy@1&GRUx`qvM|Sk#EtzRLes(o2gxG{kxRAHgV-FDW-vw7D zbA*xJ7FWghg2S$&J4@x$8-p(^L{-cWs;p88Lrch{?a{I{-0H%A1P29%)0J?I|2uNW zPh*_e&5^NqqVA>pw&;cR!%>p=ietmiYmLPdQPI&mj6!Hn)eogiWEAd zPa}t8A2!bZr!ha~9wi>{KdBrT+OvNYD}=OOS?L+ZpWlQz#DB1s=bAM1gRz_ZW2AMHT@B5aHm%n7=>y2h6w z2^a=aXT9I{+Z>;ZsbP@!=Q(~SNyMKp9me-RV>+EHII`0NDl?$Ok!D*ie?B=|7aeJC z4n;{3xRBa@`!)LNBq(v17**+3E}M7{F% zKV*B#kYCmeh=0@!^jaQ4Y6coqNQU+(xqry^Bu~X+`DlgsNPTz@1CdsNEX&U3PEJ6wV<3FFE)xI$9KGhRV<|J2@!** zdfwrutA;!zf^-uBTf^Gk*%z8tLfY!)iJaF&$c;C7F;@lau-kNhE>^EGQt5Jomu#Q> zmq9Vf&x^ z(kj8~zZC_LR-AEUD`Wo(=1>PhG*DpAUUVkz)Z8_TJYrtkYIMj@#;O_cwh9CIW(xe4 zVkkmO9I7i1rZy*=-yRuSUe^T-Q{Ng$a!2lhhHm^w8vbq#qgYYB)@4g)eEwfkd+~Vf z|0uP?9cBU!2diP~h@AOk@C-?$FDg8Gxp-Ii ze-+wcv#e#X8cs|Tw~gQWpf&;n#{S!96m@FzEDg&C^|W^A>;I7iZi+Gv=+F`)Su$VE z?}OwaEda-84r;|(`e`TL+Qg-PPX00yG zY zcSxKcl$clCduYc(s2?)41(5JDK$A|{9jM7OBLkuzajps#57?hvaukO{>;wpo(h*)1 zy$(RIs&*R@V#?&nZ0iEuWQlPW&`iem*~CwC^lYH@6~&d2_Ogb_A&4?6Ss_<9pQI%X zN>ev3@}C{Zc472#X^A0_5FoHMt_KOm3KJnPA4+nvu&jYKw{+HvF$9#91r=X;2#H^V zI`hr?Gk0Q*4dalV3b5bDd47C*#p!qnlzBGZnFTfFA)yT8T~JeQVza*>P*(FDyRUyV zWiKBK^MM->BQWwokXgPCd&qeNL(|47J@|vIxUgQ7=}n->Y`0VgmD`iL*@5@Cn~wQ1 z-Y^4>vb(zEW0gsN1t4=?ovwsJdF7|OF)~H}G||Th9m_iU1+7y()~QlezoL`B(4o5M zLB$!BqxFbq7HVM#wr()kDUd&*ka>Q`8shb_8B(plwq{B5XCV9`05aHlNEsTF(;O$W z=|ofM3D5tetco1wnr9La)V4Ae)VdIKXDfzK%h5oYMSrOiT}y>{jf1zbUUS@-|#Ij z-CgB)2DaE%ID9u)O#63#u>X9#vj6P-Z2vK|zTa=T_cGgwwQfAaO1|^cD2Ej@LN};Z zl+w^MOo!yrqMfmob?M+Y)kS1m$C&!xA4@RB+f7}X977|(p)u=)!l*ird)FC zSGipTaay^Ts!<#0Cfw%X=9<~r8e3F6IV#;cf|dty?rE@`=uwl2xr)b+uFm+SPZ~{u1EhgK&p-1OCt0`(%?~2~cpY z{_t0Y5vQ#C<_N{zFLRDEU&sXAaAxamBWGU&e&pn4X>Wt#v68$B0XC)EZp)px35(fb z!DI4obw!&ImULHLSqk}pz(50zuJf0WA$=;=PeXbag6YQz6?k9Qu@7xk7-t{1k7i4& z?kjcvjqB)fop1}<^CtdqY;Tm)BMS$)u|A)>&pJMn6DtuFjM`vVAzO-pNovSbeAzhM zmxE75Wq>dcqaZR!69VG=U3|v~m8S2C-Yf++D;s83GQro>J1yJa;!f9M7MFp+i7@vO zsQZM3h8A`p`)IrpgS<{mEK{uCak*hcF(k0?<`7!UhDj})u4eQ1=xKZ){v<%;FyZ1I z6X$xAy$9bZeKoc%*0;YV#v_1mDnXCa4q6TDf`VyW3Z9-qK(q*b_h>|XT>pw2kj$er z|673}vLW6@f+XRZwrQ3=SUN{SMG#Hr4=+Ay58F#$pG7 zMZL^(T5lr)Zi3R!mCmLZGZa(EmVFsD)0EzF5A?d<#85w{eKTNUx4Z1sf=Uq3&(5g9 zay)$5u%2eOq>ljneRiS6*t_^`2d~byRL<`q^Osm}z{q?KzLafTwg!@U5(wkDdbBQ+^GhJeN5-Bft{TA*3_GI^Lrh43kPy$q z%YCq4*STf%UZoI{p87eAr^CZv!J{UuuUM7@s-MuJQE(&-^nT32AZk;Tf3OqjA#GTh zhp-!GLReLfgFQxx&wd!rVpjolF<0=-Ob(dJKS!~Nzfv8&TUnSWGH}dOZkJkFf^Tv+ zl&}E_{S3;nckCL*$^HQ^_Hf^gh~R=*N;+CNA>pSPeLs0FRHg3t zK8lEj03{AvWb@T<-lAfeUS7Wze(xqiA_j>Q?-VPv+HJ-Q^ReIjNI8X9ex%m%D-_3K z;YYL&_-Y-dFN`8E_o8_J$on2fr=j5jvurjM^zK|E=N4UDkgWgCR|hCg&7eS_#%&t8 z4b0Uh7$!Q=d~9H`l3l{E{XI>`5MQkVd-C99h^dr~T`lE_N!sK`^rEkOb_P(d{AG+7 z1i~x5!|5YhzEn)up&m?O9*YO}Pc(muwJw}t(>7$*Kt2-*Ar_{CZd0^u7YZ&nL%1Z! z6~2!7-!^%+miG>fFczE4|1`T4T1yR#d!JDWjQnYqh^&#fyvJ&V6>(;gcexMcLB~Er%k+-3W;S-SZ(?u?M{DaWJBfoc_<+jwE zE1EhHzprLpCXL%`f{v-`$K{)=F4Kg&t!;1~(FN&SXY8*PEa1roJmoY7=x67ESZ7j- zP>i`4=_SNiR}@-?_ToXNQPIPCWQa(T-({Zs6;_493ySeOOCL?`;B+lK5oucxu?7M; zGQ8i-*^IJO9L(h|JG`yUtEkw%p4P)nCQEGHd^}|uke`Ow;R5SaTmN>3KghHk1+9+4 z^y1#qOo~BK3EX2y)d1x6@%**8FCJnc1h@FpLLt@2EOwcBQAz}wZ6&H0EVkvd7POSm% zGrocw7#<{J_+g5-ee3R%y^`^;_?^QiK*2ODk*tKFOW{Es#(jsJ#B|1Vc6!@j)++2{ zjPbGjM5N42PDl&|SKX3MJ#D;UDb6ZizGk8;!n1mmn3(*Ic+4(Y<3M3XRrr$GTlynR z>IGiY#$g&&7$Wo^i0QG524fE3VkNp66)}}Rbm+Tcl2DLOJ%=Mb{M1$Q^ts^7tX=Rzh~pn@l#QV|OERwQEcAHIewZ~*2$;K89YNNd zHsx|U7-^Fvt)h4Q?~N@=?$|3AgjHckhKwnloro5MX*|MvNJLv|7V)EHYsYcC86hs`?@O+(dXJB6b^9+ z5eGTeb~UZ6`#aryu`U1DW_ZL2cN=QAH#+J?DHo{ zVjB~HuuC2c=%0R95_(Ob2qA<1(03h;&S|WtG__wf1xG$FSW*cloFqf0?rvyOMCv`# z`S|7?YnJ{SWcxrFmU3TdD4yS`tdLyM4MAD6Nk}NobIb)I_-QH{&b!%BB5nQws=Ef! zv5>cZRY_$y4Ef2Xj)^GTg)cpm{0MCT7ET+kbG`ql5(0Xf*K-Fnr7UG(t;_AseGw5l zTA0mae8UcYYza}vcMP`m4{@}XSBv!J6ZO*E*URH+q$rJ8Zj2Kw^FeGho3R ze4q(i5lSMP_AAuo$Ym4mZtx6fbO&H1(x%vp3}WxvhKEVlzMA|d@F`B&r@>M41w0+A zZd2-KcS^O5N8#F(BCnrNNuJ$i*N$yuzY8^ZiA_TscKmqeExqluu}7pCMH7ksE~*X` zBRn*kYjn=Ud)NYqeP=^U?a6D4KoVyZ*oEbY6i?V%@X~Qsf)Wied zDk5-kiWhs{+`j;rY=^QLHXWqx6v`g-Kq_8d+LWwx!o>nPwqEJ88xUkYSK%KJ>oZw6 zP(3bzw&M}}qE5wEQXSHI!K7MR88`7OkIo)Bm|z#9LZQCcj&+J1ivzp=NN^!(p6-=( zdti82N$}QRx~K21x~Clx=J;CFC`=aG0ykn(^M9LR-(Ib3pUDy+tGzBI@`;pt2 z?ax>|DK$Y*CIZ{aR4#B{zd73NTPTxSFePXQ1^xCWRX)D4)Kae_RFk zwX_01cT8SC&})LY$?yyrc(@~ejFA&jO0L8Xq@4$e zsZ#rTn`G1wy-nlK?08P<0qHSZ${&#u`+VeFt9AN4(7XMY^;47erU=FrrN4~37zo<1 zTRG-G8*aX>I%Z02Y^WAT!tH4Y1RB8+CZG1S*hQNh8L6WUmY1uW+tK1L<=svh2 zt!oSB$?Iw~@b;3{wFfl&J;5StGA-Ou}1_?;Af zDzijT%pxJ(v?u3JbN{=YzQ$Fk?cd2R;TSx)JN0d(bP*_P)(q7G4?{j?pW3(W!1i6w zlyl~K2+6QBoaF#E_Len|SdRud z#>)|eami7f*q%nx^X?kYVnQVxpEy1?AK>!1`vp@=V*z)3uhcs#C~dO3T}6G z`3bRI&3#Q8oFOrqFkq*(mW~vPp;`E zZWFFzt`qL9@7Awc@$#YJ$A_aF8Q?8#`G!vo*!t`7LX~*z8apHCak--mnx(i zCP_bqT->C(LivGX8CBLTqPpmO*RD|1F^&t2hhoO*ij9^jM^|Eqr9bmiiVDVlRFMJq zvD9MQceAN-55x@eVc{C+ilN&ElKCFgaV~KuC>OvQ!r<#>1O_+kyHV>B{-n-y#F!8y zfM{SU27Iq&m^rfsSJKP^wH&=SgcEsdAJ*FIhK2o-YsJLm<7;R`fy z&4}6;6YR%oFlL`x*Hxdt1GG1SDk*s37?)-4^1Lh~1v<^G2qG^?8f8!^z{RWeK{tIv z!(=I@`IrAB zBCaaJyoYF#|ER$9|B8;J`zjY@F5dsmlHMCn67a)Fq3Ju&U^aMO^3NwBttf&Uqs>g) zUrH>#Yy0iC6A3IR1+TYfkwg&{Tlz3mb{SgDl)uR@ogU?S>6X+LGep~h;-)k$1{^sM zJx?0L-lfBoz@QWKvaV(~v=7EMlWl1?H`II-BAY-mX+_5j4}n1f0P@|fm@gDz?1Y-` zXV&VScb3RsHDTA_)}i#hg(}Knl|Ac!7bQ=mY=0gZ7uK7}U4z~j!`(ZpZUoNQ@Q%&cd#S5N8?z`c+USXN%H^Hd%6E0G}^kSACgkLdv3RX-x&oR#G|VY z;^_wge7kkTM+3^#gH+vv6>YvTqR1^&JXWT>9RcjAXz6~4JXSnn_Ab-V^-SXN9vFEbX9BStr)h#Lq9C*NT(=smKx((->a-T>vNS=?nTUj%Q5X`k*sU*EtP+C9xnq<_wkD_{SwrA47#N{{<&ZL&q;A zmkJ_3OD<3 zD9yjzmUbR6m=FKxwtPEH6<=W^Sn;wtfSCljzWla?|8ou8TUUeQ7>X_D>`WwIfQy&K zbL~c_5F$W9F{sE$h(1tk*`(Eo$c5?+sgQ$jFHG2Or{Yt4jsbwA|AIUAy@>B*Umm^4pG&nx5SG@I|6z z=*_Kq39n~cQXxm`RVBE;4UCm_ob;S*;7~^Qpp48wKav5-t`(b^z!lvJF?{(W)hkfF zXC(atNuJH|l;rp3sDl$LL9?70g)Frc4nENjL#AbqA$0bhT?0iZLj;vMNqE7RCiZTL zK8J>hulKv%xU7w1>x-h3V&nlhPIc@HppibL)*y#!lKDNE$17DF7UuA_%<{WQNFK7(4XoU8Rb+UnZ#A`J1ocp<<-QBT_x__I>CXOZ|d zqB+Dtdr`>T`2=dBKh2*jGydEd-M9kA?QLfK@p@rGXC@=ssW)UMziI|Kp|Q>PH56CW zZ4Qx@-bEqMebZli=Qd633Jr1bQ&?iJl{^mOb2XxheAH~C+)c*toL%fRg4@inef`QX zl51AxjK1%-IyDpsr6S`p3sFRTkf(tNftYm*<~=}5R68}M>7@eum1B%bxhs!WLRn#; z02QIpIafQY#Z`T7_R%*DL7MzgcElsP&Hzu!i>JImI$Z0ShD^OHUM*)NTHJ+Cvl z3Evlf3oiVMVuS^Xc^m<>PruP64c&IMBgX2DuAqaz>#;ihjIaNNC% z8q66t>)^oJjn@NPjxddmW9#96p$T@U7uE@_&bWA8udk~VPvsY@!C zEcsM29etSDp_Tc)(H8SEuX;~rTy_JUIYURI*}vn>;Rc#_n12xGe&k4E;#Wo4d5AOS z3(FfKaQ|XI{Uz9ODeLHj{pf=dS3cIYtpwT~Buf0>rrIb&KC{k$Hpj>%=k7TLL;rZ?0-FuZC0ah>Hc2!TtYW^9r2SeGK9dHVY2N+)`J)BS-RDYfDL^|OQ0e&z zITRJySu2jfGV~JaNYom-b;PSkyXi#@^vzT+1i03(ft*ulQ2tXDENZs?81!653D8jT z1=phgHaInHodw8c0EPYNs2wIOfk?TjzfHC0ZWWF-+=6X8iqF>Ech8=MebTVb?UwCW1*OWLo1dTN_u)ZTw)OD8d zAbE#w9Gcxblx3ttLdV5`H_9UFhQ#M1I4@;kBE{Q7G7@JP-NOo5je_0Wrq^D7oMPqj z#jx$EO@SgLS(EY~m`eK(Oy$A5E2}>zAvLO9#i{i{msT{8P&`ElI~#4jnVbIhB&V!N z=kw0zipy1ozISP4cTvg$C#+M1Y0pwI&P_D~=o#&u&QtA9w!UFOCfeA4ooFk4D$q@) z&6|dj0!>gwd~!8@D9>zx-PiAGZrrwD5d>Ev)dlHS(#JDt#@l0%a`U&;4Fg;M;0D4> zyCLmEU4+&{7QW;$e^Nq-<3D~6;<0qdmQl;6?%@&mRi{)9Q)rJgk?0}5E(v*|SkHrE z8|*o@b8V;nreCW12il&|cVSWYG%T%%#0O5J{{9{$ zZ+EtYi_xb|hQpE0=vLttulX~$nVunH((n2(4Ln!g{>>S4`WI(Rgd|3Nv2xQLPV8^g zXX$9BU4o~*hf1a_V4k3lny*S*0H6~Do1o*|f+y42%v>QdGPRvkRQTsha8iu$yZ6i2 zyU+68Uc`dmLOKsxcDpQqGaJfaiNlx!N5w5#8+EY}&&1LISgJ&%yh7C~qZDqb2Y>L! zaR1301M|1un8B^zhSp*tKZ>Lh5034OSLy&|?)UI38-ZSGLT~RMd!&QcJ<@N`e3WYJ z;;?#b=qvMuLAbJ&yPMs-rb)tF5h4aC&Pg@S?i3t&f4nqF)cS75|FK`+#^pbsGvuiW zc_B92k2+IZ;l~Gk9B78por1XFpLuX2C}GvEuX2*P0UCGYS?{=C^=neSFH#5bcbo;O z`Rf`xN4%^jZ=43^=ImjnA2Aoi=N0rW32C6%UdkA95d7$q#$EMEd+0?}ndjDfgEa1q zud!bjOXr{e+Az5aejd~T=N5-?TVTA^Ir+u~n z)zqL82u2`7L0FWP5O#J1D4MB0YthO)_y0z(H1C(aQp2BnrT18)AB0MI#K5w+4-5(e zYown`$T58>vB*>_)p56=BoV|o2|?OmuC9uchi6wR8FYuAR5EWh9zYHcR6FZ`*DLjh$ArT9 zlS(F(^ZT7&6-%3OMdv8-j7|1`rNd9H_{jt5V9+&1_@RBzPC^If+F$P%2IVaJxVp9d zKqMD7qCzs*e={Oh_3B_Ty@9P?tI>L(We)_CJP72hb4I94YONcCM~vxNipY`Hb?XUO z@}E&_#Qpy9!2rcZ<%ZX4a|f^8^*P{r692N0w-p4e8Vup^*N)9e3=zDAw?pedZt2DYx$$d*t zLI`dXb#2-aS~!%{(#GpO`y>fP4!V$`UjG}747hEJ1K=B3)F5A0f*^TDh_g9*SZNCGbzvH}_ulG4+=!AZC3Mo3CR zg7i&kjQSX5N*iv->U3OH9HXB7KQJu7Esr5#TJh-HZ3{Rb^7Wfl%OFpHMF1GYgY5wL z1^S*>9{`E`>I0C!0Qms8pzG=bSl4_D*a2VvdEk2d_Yd&jf5hLOlIVZ!IsW#DzkQKD zfBwM#_^bZA2l(H=j(_)ve|{tW`8)GZAMy9^jsN&w|9Hes%B6iB&UE4D=~_Un1HNyt zWGlgzE?z4F^1Gl}Qm~=?_un-C)2G(J+2GETWINa34Y{rsY|N@ z|N7i!TVVV43f>n@N>fu)yVdTS1Hg`LY8sF}cKF#2f-RLb?`NH4pJ;LI@#Kqbfs0{X z0c%xhGtUp6I^NT##;HvY=UzRj3ef>`Cv{($82A z`HunDaVs0Dt|UGt@N0E}mVLp;g7P5kDYIb6s}RquEfr26E-ET2WkX>hY*Ft2xc&~l zEEK3_D+yKvy&WDNc11%uCOO7sf9?^#yA}VoMWNubpv7jQQM&Hg_0o`fPVi0F%hres zi;Kl3=I`zwxzIdKDA4xcoYy{fb-O5mW)l=&IP9Y-uWmYb_B2&^!~T?=GiEWxT@laP zN%!vpZu#gdx5w2(E3?-tJ$w7|gi_qQKWP;sW;ZdL)Zu^ozL%yXPo$aNBba)9 zD2>B8qt;t7+N4@MHre=$>XRgHJ0VQ-?bg)!$_Om@7Rwu4p!cvpzc{}~O#j~f;m33E zpZ1$CI(hG#czbxhpgNTH=bS$yJzU~;NU4i5wzr6GbS-1^ec!}3q1&$c47wE8d2T_k zBuhP*Czih_QsqnA_~7X$-_gND=jt0zm32tZEO?gGJULOHTFHNrzDJhYyuN^SxN0ZL zmNwMQxZXnsV@4uh*15ez!Cs7O>Q*C4$sfwf*58e(MjkR`|SVC>Y7!7{X4X@dq!R_31-w7@73P`k^h?5DEH%+)~4^H=B$VnI; zlOB>ZAaStre$t&&P0-xjpK21-4j^=vErAQxoUcglQ1q!?OD9fUXd@k1#+Q(b)MFCr zL(`k>zN4ysiFjGdXJ4I!?e2hvs9b(I+KcXIbIdK9Nl4ptZm;=76Gc)~1qY`~oW2?J zjreTd5;E?rddj4>erI0Bn)3kFW*g7E67_R_eQl4XRVa$#$&;*OHB~+J?&ZkX0;PA9 ze$w_!pZJtq9Cu8yuKnh~bWkI~PbfE)6RgN9a8w5T;7?1<;7H|~a)i@aeh_%Otw z8fqCwwga`PhM1jmi%?QDX^TowI83q`Xt=f_b7b=0<@nn5kok^0c1{!LZx(d_&RkO- z_vy(CiYCI)oY0a`4Si!{pUl}AcE@_HyLFiSz7`%)?D0BiTuMvC>h<})s0woi`RWCE z7bhI(iIb)Cj9LCO0l5)~Iqz1T_HQY6zr#Gsw-!JsO53Yud*&V#ob+M{+p;OaBBgVi zN;qk}VGpZ1GSb5Mnb0%Vq2+{Qs=$-SMt#aeaMTX+E*wcfI3@i%IRr+buHUQ?LHkJqUY3j{yhtCr!m z0pAH|1yZ!n`6(Nv#B8%*3|2mI^BHs#qp{_Zy$#*d{_r)iKV0z>pXIrfFt+adnl@dt z_^fIRJc;@jQ*LPPimUXjSc1GbeBd^?m0R*?xLw*vX{&m6n^(+=~rIn zT?gOaTq%Z+cTrEy_3el)u2eY;&PqDi-+0NIei=U(Yu+RL9`S9IHyqHw|biYf^ z`TG2#)9yLZ$>J3r7QE5V;@flInNTViKncr zI*;$VqiAe}oKR;fRcb3$|7~l??+mW^Q7179M~m|2S`oc%Y`{R4J9n5yjPsL}y zup@nS()1x{+k$TrD4{v7Y&bJ;iyhrkw6QdGt+$TRm^kn$wx6Xjbt2s%sTmgRQ?yQ0 z98ql8#CcJ;bIVuI6w9)=>Rc^=C+_|bQ-P|6_p4)}?fR%~*(Xt@v~B%G@SJa>EtuvO0eRidKVx6R4`}%nEdmBZoh672zh8+imaZ zZ3-o_|*C_7$gR@kh>Zw+f@k zJKXLE{u(_dMWX(YNulFs0n8%E9!xA}ga$dBZ%@%mox2qcAIep!%FQr1MM@@;l{w8u zB~HXybsK#irL42mJwiKSdOK-wm#!4+wwTa6DV&PGRG6KM?FJ| zye6T>`B3$5q(r_q?qBjw>b>$c&7<`=ee3adsn)IE$)`cd1f!i{{dT%PIHQ0+J4uOzyt7-Nta&Ed^LG9WD8$`_ijwKd^Uo0i3&B*-K_$@Ru)l- zw__tg(NyTAXXTC$>!a6eF-k(BQ;+UG|CahLUrBD4TCJV5s|2I)fvjhBInvI~PEB21 zh-cRO^c}UJ#gmsYFWIg$9en@+&DD{?Pm3rwFOPO?tA@TIvVe;eOCUJz;FF;ml5d*` zZ44&nVZj6JQKh4zKpSpeS!QNtYAod7R-qNZLlFx&%Nx>FVx6#=b|I8KV5Fg3uWW1# zZqvuOlqmPe)E*4K@9r)TEa4+TNul)Wd`ZT|$tiAP;-NfkOsAqD&91?~4Fj%QGP(D2 z?lU|cQ-68D%fmA@HI>oWsCk6la^i0zd0f(zG5WSpHQ)7k8~4%k%UYca_n<6#Vqs6n z7i+|Ii^du2wgI}4+Ai{&#>S)vj9sAkK%}R-xAnTQv2g`ehH8h-Z9=*}>-fRB8`Sle z+Y$DPROITclnG}TdzEi7I_ZJ!8@|+IeRCPFny(nw@-*Z%7Hp>dnbxR8PvBfeB=Md0C@N{=C05@y{fye$ zI4bFggZ+5{Oo;+Q@YiDKls>MkT-KnOKb{f8SwU{q@-k(cZ$4teex*`i#&;XRBj59K7^9;L8fM| zrLM%IVDAw=k5UY&s0w!1i&J(-M@O3HGH08k*%ucZ!ujRpN^szkdknuz%h+fpMFkFg z_3zwY*j!6dRCOarOeT3FpB~)O&FjEi6CrN}uiBe$$K`jxopkmSF*4sydxSrqellWt z^qNUsx&x~{yCHGJn(#&*p-Tuy?Yl2%BvDTTm~-oJ$=7=fQu5x+d2$Q9xiP$x0n%JW zctytLqM($qCxKkY7isHrRF5tDR4(U7v(Im@g4p(zHdx@5Ys>bc8Afp5Uai*ai_dbY z|F5n)kA}MY;{dLoERV(`A!K<RkjWm`ggBZ&+!;~Uf%T{AzvJ8(H z8rw|7R1zYx&eIq%7^1Po*q7h8<@Y=1_dDnL>wC^U=l%WOd;j^q&gXmY_uBfLOWTQn z5LUR__*OQX-626@Kc!G?HtSxeW#w?B0>-8~wgw|Ez*m)Ga)R=w_bfXVNbqt3-l_O? zPwGz&@0QY%I3S6frGoTGWnue&%c&Utr^%O5HptBGY5UfG3V&RHnSwl@{;)T?v zvmsS=^@~^d2P0(NoL-cbaDgNL9$ROSo0FAcwIMeHxXO>pUN!PV`FfTlU_O4jNh=(M-&!1HIwp=L;XI3rd)r6dZzNv=NEgwy7t4 zc%nW}t#&4+hImPIR&wu+v^RAkjY9_Rcfu|v*@e|R{C(;%@qL?jNnX2cELGwe|Al81 z@x`8CSG4XNZ*Pw2(LX)%n$nq={L@8^2C-g?`Z1P*kfx1nHjhD z#8_h9c^B5?E%mZ~4je$AFP4}&>?7>)1Hc-26|6V26=$@|Tu!qG?8gv>M7 zgB_xF9n2Spa-EBRhc69CN~n!a?l)tlKid~Ka>G}k*6{f_?v9z#+t9;R=Z&@HiQULd zsPY3R<~pyp{yfgIuc$M6dg+Q7hnnbV(c>NMQ7oGlR9*gB$_b&+sUGxcO?Zb{45z-f<-bmp9_X%sN z-sZ>wC7O{?(TY|SwINh%`7AAaf?_Y{;o-B%5m+v-;+Vi@?+F^!ah=7xqynBu4EGm` z{_*BZuA2b)^O%Yk+OFMSyqhX&byJF)h44Hn*8h90nk&YR@~LQPAZBmx-6}N)=g&5^ zL@F_h_~+OWhGnRFg-33Lw6(N!g4w}{E(+fwle5Yba4#c0>V9cWh(D#4m*Od^%3=V79Sfg-U_SM;+H$` zHIRO^gRx_o1^#k!HSYKe}2L1fkIGz4MUuJ4X@{H-7t7^xsrbnEP zD<>(6BqViI9DaG)Sldbn8Aiqu)|Sjb3Qx2@%|Vs}fqGDIvEXmP7@EQ_Rm^lA9`7H620Cw-n`$4v&q?CH@_cBUV}) zPnf-Te1<*5zbIt}3@t{|Jf!XEOs{HV$m4a^7V&1~(ufl8faFI_R@BbpV8mv+^7!M$ z)j3#vkGs8j>lx-TgXxeoOu`EaK)720b%9R6Ke5JIVT1a8Vkv^1^q~Gct=a~=4m}Fn zYq3GA(NPne@|#iJtIG-FME35vQHk@Ou~Q&s^K1nU{^(@4wuJ}Adie4&VXcABU9s4q zThPB;`BIIo5!XQG{sXe!u{C=!EOThz4=^!3{i7V8SrYir7x zadf?+)%BYe;qAo2JaK5ld^Vk)ODfwJLC-jM`9(8%f!4B?yo0%2E8t8eyXXxi!@P z*%Vc*{fnXxca?|%6~&Ipo+3D4gZ+^db;h)@nt8EgV)tls3T9zkoUziRZP{Qq3B2t# zI1+e3EHbo#dPeFM1D0rQzuzr_maZkl!V07+{N@zI@|#Pb_$#2kMj#M4;f!@91qB88 zvSIL;C=3QWk-g5#xDH;Hb8Bc@k=j>7ucV6#5>SS>^?Ng=KGM}&X z>W{jMjY-m%7bNR~J*K%$y85Exvw6Su-mUJqq%lG>&q8F=Ee9{-a&+Wcj zf6Qucf>1(}%GEf)hbDjN+Nj+Aq1NbM(%-3T`Satz|Ff5O+uo8aj(g-PbLgjs9UH95 zzHJ%`+RW3$O2Bv-_^;+INf#Ar*O?xoqf~j*FEjhglNs8TH9+eS<2uK0cv;nhA${>j zz&9eb++$vU4(lH2Q!q&)+Td0tVvLPfDC)pUePHENt8E@D<$Zf0!a5sY{al10axIAMR>KYw zuCr(cKQYz`J>fSwcD4{N$^FrV6Y0RPkfGf2m+q@zJ3+<-!$aYc?LG{tb*m87p^g-Q z1ij?KjMwK4qq^6W7rOK*@f#N^e@xrGwAmqf3x9oTP1oC!*~AS!qyXqz3qnV31%FSX z4E*xkxQl>*z#%mJ68f4a8VU6ZMgkWBhz>+gQ%6rzPsdS552~XJ)z<~<=seZT)d|Gnp& zwJvM1X78Tey{o&cx}JKfCPYp~6#g^TX8-^IFD@pe004ZD001CDK79bUJkEuQgFhhb z6+{I972`NZ;G2)e{L=gYKy}oYXI&`pJ*lYM7hJ(FxEUy zwpfx<3JNpRjHcV?qfwuyEAphU((_>P!4E}qMf@1%aFKj%ygfeiD2h@;RrFoCg zN%O6|4?-=~Ew*)Sq@5iS546St5C7wC7ashDn4L(%R9`JkOkMuFjL)vv+brN_@d;u> zg=6Bq$h08E>4L~XE^u2XdY)_>i|I^~mHjJxr(ZpcsP$?i{qWls@~O`F;M_>%#lyO& z=f!Xi_*uRWHb-s}$LMJ5go-REUPsR6DL+b89*9eEC5A8Eg0qx}SafcP`b z?pZ%PyW#eq1)aAuYwyxLnHW>>7eoDJO_{5$2XFH@e|=u@mR>7oteTX^gHbmg1{P|0 zU)WP7`BUDn4G8VJM^=g=TKD$%6XWB{)NA|s-#%snpMp);9-oFmZxZ`%!>n&PA+H8{ z9&+%kvu#qy>lHUw`!wJYuxl(5AHrTs2SJ(=qdB}O4ZalCO)gZniZJC!z4&J>gN3j+ zH3$c>PMaSS!^|h$+HYhlNBqAO(NPm3BMB%cDDDK_iPcRk&KEPMORZ$_5;BZ1Zv*7H zbKM@Ns__KZZiAVFI}Ya<)d^hPZ#GijuFYL}A4jaI)vh0Ssb2BzM9NHD-RvLUZtkH2 za)}KaxY~pZhz8C!^EMv`2QQgfsK_z)YJcxV$mBk;JZC+wuk>!5u}kiT|J6N&(eI3< zjUOV%%|Xaf_j@BID;2ah^vu+l`_S!g0$|U{4oyEv} zR+z8B(ZZ9L*bHvR>V0uHVT|k~D$fpbtv_1(Vz`_L-2BQ$;WP$POktvUN}qH4eqc!)ZVY)M2i^0vb0dcB*V^E@5!1zo27 zzGW`|{^e1%BTq_tWwC?x*H$`2v&Q<#>sPSuIm_aIO&`(mqFoc4{v#+prKqTDTVhJ| z^%1A}J`W+Xpg1b`iH$?_s6o;@_1m^l9I@~IbO6OUK6zY&FmhePy*o#*gh{|`+<4Q= zSE1OfJVaDRJ$oj8M*_#}mz+u8+Ykq_Qh*~GF{yxi5nv5(n(CN`EcEeejF_hF%L>*u<7>9+Zp9@I*B89onPH+<;%l{*~(nw!3nm>kNDzx zV*Z)sz+R@gl)GOnR~v5!nTo)vgi1@9(_*rt$!m?3Zw|G*)?0ej(A6l?a)Kd5COpH5 z7*6Uv=bE3tFe3@~I0St^Hsu-C==)UeS@**5TYpw>)(<>}8TlkiO5KhF8=P@{a(+;1 z#ZD4+&X0PAWp+N)+(}VywmS9w8%;s)L7~0kK!?L(tYsvW*6SX8xqxCi%VnDelSy&+ zzl9Tn{*hIrfrBWh1?9nCq&aVwBPR>2WzqywW>u8<%0$!VSqWgPUb~5hP|BsT^P5Q5 z-6EDH>OvkaLq_5n#3G6f%_iaTwP+cTK2wvilsMvU=b)u5yPmA>$ImYOenkxswhvjW zE33-p4dM1~JoYXte)fL*V_m|-wnSd57gk`y#O-BC^g9Ps9B^;AdP7RiTFok2q1i;m z@b**pocGMNLHC|FwgJ|)#kS`tXv?8}xL8ii_i%C=Rp#YWLbj=G-qCEfw{Yz1VYE4G zvIDdnLb`!N&hsH{hw#koRPeRiAu+Q3k!JQyAR78g4lf7i(QQs#xQc-I@je;3QOLM( z1tAKDv-hj_s|w1@hc6ubrj(ENF^^EkxV?4r(sBb5%Oni&!OW8!M|SzrgPKuUS_PMp zBqp-ONJ0geCA^O5br(4u1t-yNX4QobA!e2*lh+O(gBvv>uY43}Fcb({YeGSr0)F&q^L861D5KMR<@lDDS(EEhI~ z8%UOwK1XOO5*{)|=#Z!o%OccFIWH(($cw|2^om+*vh0z8JS#!$p94qz11kkFVFAR; zpOD8GfsnJv#19jrq%LKitY2A03T>&OiLRt;hEGw<+p9!r%QJ~zA2nLfZ_d{fApR$B zZhE*+Q+;{=63M}K3Q8=cu0u)0z|2IRO3T?nVg~<==q#R%<5tx9`?5lvIbqzqcwcuz zQ}%u!Wp{RW;4AT6{OgfU`|970x1G(7L5J%dVrzUYT&ie$>hI41G6eMeg-}}7+r+v0Qq^A!r^N~Ega(Ka z7vRJKmItHEnH(lnVFpD;}F^t-p9z2?4FE~hZkS&8|L(Cl10`sCS#htKw-{hL-V&E z2}_(hSEJ5m$vfmH>E@5HSTb=sP*9`sbm6}Z>3F%%#7a$-;ic9_8WRhW%`E=zAkP%Q z2GbiEHy%RfJ2`H~+1rM2hN~RHA|(GQ{n_arKc1E)yLnxh$?_hC;%R6F0|m$)h}k6T*hWHVu8hv`&V z?6cW?^B{x3NGRzU8F^)4{pleob2P)lc@?QicG-xXf-zjPb2;4+d!9t8x86~gKFbf5 zQVQ7l@r?bUajp3o9(#pv*HqF5hNG{!sFc^&*X_4`359O5?f2(Ll@$*RdqENFMXcZZ zVqx76-H<_yx1y>9TA>aip?PdK{jh6F)8xXWznx0+`AKtvM~e^`Mn219UXjvZOBQv! zA99CL6$%{YrW;2b*=Gu0$!K8JBR6=L|9ldJyf9BfbIf&+4>A3fI88%ptE{H|?cJNS z$n~L;eHIOM5!ivV6j)uDDK8qu!k;}mc2*}kZ89)XI1UlpF(mwU>V`QjTz&;xlJ{B` z-Gn4?@QqrM9+5dWS_<9_hB~>*0ujP7EC=o-BzfW+N3NJeACqOgj1mXqAKhpl;>ocd z4OY^?40?xE8d@nvU6AlEW9J^x;d15zL4v*2{g`>K^OAyU_nQTp+m}MAUYwU3mKS?A zc6TYZp_RFKpjCR`>gMAk%%RS=+SgZK)0x7;F$wR|9Z)<9n~=4`?x9lF4)x42K>}WL z&S>s0J&aHqm!OvJ;4H~hH{B_2%twBDtQ{L=#e;=_8^EA|zw)Z>i9yVD${#b?D0 zpCg6gy&Q=G(L+sKWfU@n;b{UP;8w6mQ6Npf$2hU|GQCKO3jGEd!3B*%^x%bDiQB)3 zUz!9gFUgn}9MNZDd@xh63|L;|(b^Y?DZS&pRvJb4F<=`E|jS0>( z?8alYv?^+P4aE=)&=E-H-gg$~l4m1zecEl?pn3SriF+{K;(5XQCb@YK z1RY4T?zGaXUTgFx9UEm?#Qw|+gEUJri318rd{SqCc5lW7-u6o|YSvAl(64dE)Pfs6 z&8;0@6|#A$@9`MMh@QxMlY7#RxgM!#0o2(~Z1VVzGtQMphoAFq=C-tfU)NUUO@vSK zIL+w?bNOrQG(wQzBJf}KKy~?}&Kn=K7?mKtvwt}IBN$2U z)kLG?8>g6^kn5RPNIqGR8KK>$W&YzdA#wW&LOsn#Il$kDRP!`z)b3%t~TBZYAioF2Ev>qJR%9kla&Fk(2;XEt(s#n}1k-p?<_ zr{iR1WS>*(1@~=`NmOV;r|_BM=T&lipzC>+MNo33XMX8((lgyAMKyjWGO5?QIE<3{ z9#cGU-JR!@h4W%%ChGrM*MpAsx#_kru~EASn3V=ct>}Gs47;+wpBlFR?F0uHpx@)I zbDuupRjf&(H<%|LH~hNb)Ybs&-<|MMsgV--TO6orI3$jYUO3vuW4eqhe4pU0pFXM( zFUb1_Dht1j;%&d3t6UWwDpo8!cdy;K-Vi#eSGY=E4PyVRyGW^Wf*UaoiBdnXL#`un#-Utbo&Q)^_0n1YdCUS3R1O>2!O5=}+L z)_K5@WLX(i3iMFFFC>h%=byQeB-)X>$fKD;T4004*>XJtH-uOx!Z4-l7p43J)}bRq z*#;QAk;D*xKeJ^G4kcBpxL@n(eUcztq#0QCmvY(+tLOV#2Hl?dIcE#%CP5NDE;i3c z2Y!BjGqVyYP6h^s>v7JDRo8=b2Kd;}#Kgp{t*x3G1_g$ce7~F(x&GCUFvcF^_XAJMvTGF`>F^+4sCSo)FzNlT)lyqg>L=)vcG)(&!V z^6FU@LT>Jt*QblZMVSK3N5%Neq+`RQUt*P-+&k*?)G^L--{zzI>-m(Y zmc?w-HN3;+>>_UWAQUTD_%S!HfuESy*o`i(LNel^X8uN?1&0Jt zn;%Ug6&-CN#T5>&cp`4Ykryb1JVM?(3N};-tTd!2s?m}86-Bb0X(V(AG&=24SR}|Q z(bwvcz;C`3UfLvjvWz1Av;5VRbq%FCIi*g|3`U~2UKo6yinhwi)k?;nV|TUcWXk78 zx6?U`>ApS+B$pTB&)H+f&Rg{vO6R-q8FVvzGaIU`wSuNKa6%AXr zw@^VNp<{vZ;s(TbjHb)Dy-`faUy9 zE{&QNp&Dm3D?{4WwJOKGuYs?fQ@mJGLgBdB*9e;mT+gdhrd3uotY-F147)ZPF9}2@ zB>JSqVR>$?slxnmw}eb~MTX9f$!b{>)f_E8zN)rVl$;FJIEDH8C)l&%)mGd3IDdO= zCwHNMn)oq8UeaUeTCX;kughh*ltN3R#^X+PkgYa}Fn|zRy3)3^bRW3D+C-0QC&EVP zLhCyIo84~s7tu;$fu%k&>X_iNTqcD>8+W=yADXSy(&ZkD7wyVS)9H{FSKNW6v0``@ zSIu40MH!WQ>|2!d>GlaNO}QM0y|6e-TU((jxps6*S#c}d!tq%&pZP%?_KAVO0McDm zgoH6K8ireVL!k=MwDin5nP{p3ksM<@#SgRuTZ^8{GOg66$~GOTnPU6H^c#0=PNG@8y^H4%btF{_UndY4JYH+F$6aabZo~lqnnWvNbKG*^}_=6`O>HTUoQ#8 zPxFyX!|^|MxG4EzCsnl8L{xL#ypR)BbN0w7Y}9$wq?}EYD+z{YY1I1vPV{`@Agi#7 zuo%g+PJnS^J#?B0&el8M8{1Kpq{=Cv7ra8bP*v{*N$m&tnxgdmI;np`M!i!Imt$tG zvHzSP^No~9f04;gMhn#pdSy5~y$+L=`(}_Z^;4mx|J^Bd<^1Kx(t9EFp-MIx4~rP? zgzc?J@?k{{iX~=UM>$u`gv9;|qVIg+gw446Z=h9wJQcnQUn`@Rkc2PB#kc zSP}<6CQqWwF)cV8$>Ow(^lqcYtPEZK3Rikg7i+Pxyu+l}V_j;vlmp#EL{vpjWJlElY8>`bKwYUbhz z43@EbdF+ANs-jUg6SuP$Z|{Td;*NIG-wj7uafM>sDMW!#+$>*8ui5XgQzu(|FNGA= z&qIjT#!6Uen1vZ8paQYcNs=QZemJ7&T5C#ReYfH>>oFD$t8OPQDVI> zk9rL)#|Vu!p{NS6R2@k7SY~;h*x2FZG`iP(MF&r|a zKealXKvQy*7c62>X;K$-s0qw?dHc4Q#UHD|Tcb^2U_Xy4S54MYl_kA?1Kt%b+&*k` zlrXQ|UHT=AGIb#pw$Zfx=ze+UZ+H3WU`0%L+G7HgWljpPjg0hep*X6qUr$%DM{o}) z!=Rd2PFqD`I{Xk8-r$M>Z8v|vnW>nR;!zlwGOVH3&rr^Bpa@{6(&>nAmddK2Az=7p zUtTbW8o2)Z<1uhpsK`p%hTJkD#ya)WInhSDqhWvd=+XBmu^<|CFRaeXFv>sc!E3S~ zMZdCdf1cS7J(hPKv!Zgf5|b0iAJIs}f@bT{Z3@|*{;W;e;H2Vn8FYY4 zvc?)-HKL^R&h(Fd{D5P5k-h2AYe;S0;$ENiO{4ZHKzrbBK(;rXxa0-@JsaSvB8 z@W^o6a|ZkWz_&zY`!|miz}05k{d&tuMa!ypeO_s)`Kt#`P2O&&FC;pRrdpd@{a)pU z*n_smRUa59CMF~dQRyJ>APnbY2w%!qkPQMW&w*;FWAa#VcVFgc+n+R7eAYd)AI5%m=GeI;V6(!bDH43kB^ti zs^U(>RZ;+Bv33DA=;+q5ROXTIfw_$l6(k=bApqeJNqQe$Av-0-w$?rG*Sfm8rsP*L zSK_Y6ezV)ZK0i#d0Qv#{B1KzT>*@zxFr)(@D*nG9V8}!*s4&%Q{&FRaHc~3V6qix4 zk|+K~cP#M90E?I!jK3U~!^4w3GX9>R)*6j9pEax)U;zNDF_RPP4d)(5#jG>b^$}Um zfzAwKZ{QxJ#^b*q{_aE_jHTU^Q`Xeffaf&5us{l?{CyUB`PW|`dduyGGXgipqZOCY zqcM=YpC&(RY%R_+?n7xYjQ@ejsFW#9^zIAFqwI6ZLXGs~78Dc&V@N6SYMw3<*$kV9Bls<++brDZq6I_bfzOX5PX-!> zOn-hHsW+I-$Vrb)7AOyQ9c-`aM}>#8y;X$8PuQ)-e&Xt=GZcTC^!pnL5BPaXJYV_) zVSMkSGh1keZIkz)W|N_~j-;`j2yt6b@`CoyAML!K0T}48#MY7Hdm_IC6R&3$EDU5Z zN)?xxlGp{=nrp*;QBe=TtVN(`s0eCFrR^ib*A!Wmca53PDan}qQ3}J9tgbh8$4VSO zm_w3epC1Us$@Fe-Y;G=@(W}V0y(rsZcMNhfK*%4gGn^}^ps8?cSCjq#hz)TWURloX zx)^G%$}I3|SGkdwTQf?f{DmiCspT5c?b*+y+FXkqArW>Ak2Z=Eizd}wl9QpHA@@x`1qQ#qN1t^J?rIjq^0_a+Pw?l~WY?E78q>tn~Vj>es+Zn9p z-J36{f5O~fZmun5N#i%Z-{vs-CbGR>AzE7$_~Up#Op?++jOhlijIJpF6;_o&t2&r! zHwtI9>q8kX%oo2{!70?R=3(V>!bECvC3M!&vkP|4`ytxc^AIGNi~)v(&^|83A&)Yb zp_q1vR0=Pf^cqmJruu-vG*KdV6HSqL_-lp?hsbdOh>G3rw`Hnw+JIVtk+XV6=$NM+ z5p80dT^JYsVvT6S+2+*BdI6DVPH|F#sU;LZj3S57I*RwTv8MwIJRfF#Rb@M}Yuig5 z=Zur@^vluiUtAx|LV`yzUN}$4n)TSvN=JF9$L)6n`t^Ms16G{a5TNfasMbrFYE8;s z#98Mevpk?^``<40z5v8!ly=Wxc>ntLbhv4L;Jf2#Z_j9wvz-qMLl)|p=x#HD@uU`G{Vie?V zv#Y#~^92R({;e{QuB}mZ@7_ZSa6BvJ7&&pO@f;r|&(qJda&w1?8ikI;Pe~g|ZS(dH z(=F6YEY$N{Id-jH7hKuX-5x2?j|B(7q@h!3?`P96d1Sr4Ye|6kPejrVr;( zh2y!{+1XiaR;xjO)P+hN5To#jHm1q=azi}1rY)|!e?JV|k{>-@8=94e!cs%LT?VJN z$tro$Uf9XJGSijb$)AIs0@4IO$p<oz6|M zsqO9Ul1Vh+V|?a%!8*?a?0b?q9FJRFZw$}?fJTCG{5`wK^#&D>l-Uu)9#gs3`3X3I zmDuzq`-50F&&w{D3ymvqfH;v%54j8t2*#^o1gFxYnTQ>3!4v^ND2=S09Tt4i`$gzq zHX)-8;wSOtjm}W<$IW@!Rgb4usRJGLJn&y(;Y4!wk{HA$aFy3REVNbrcAtv}7G#BA zb#U1kwKDPcS`tt^My;rLLH+yTjFz|*lXYli;X;Q9`D(u$v_3pGmd+w=jbykxoIqJ9 zlis`&$q9BJZ{H47C4bk$TdnbIULbf@9oTf_Hz38o?cDKG5X}6<$tx(}FvsSH`rX3` zAR(}Ixnn^9S+%7}<mCt%L)lJuIU8K!bs!_~u* z>(}BX_-Uc<#dGJ`*o8tcS^@Z^LIiJFj6mnv-(OKn#dxJqoqy@j;FT=JuS}o>q*SOE z_ctE#_VVIO0X0;~a9f&^ap%0hTM!f`FBr{~jJF9Gj2d#3hM&N8(OAvst3n&C0(>ww zQ(EhBAI9(~$#fEJd~1QMPZU4hrDGm3ck}q4?C4`279}3&--;$zma@wp2^Zk+_{Gl` z(;w87$0q&49z6JUtBVAU3N+9aQ^s?pCDDQ^2B?LX8292)>2{z2z0ec81-Ly`WOnp7*12A004)V3hP$kk)gajb+{F4&G0r+%#zsV zn3n9R4r%J(sKj8;OAte4knYKKaSh`RT$JzAeAA((%OF0BUL*;#L-B!LXEKYx~z!oCX}o<@d-zAx}$kAJSp4IOeY$1 zJUlXz=jC?By8WR*%AQO-#l`p=K$0tReVF1c;kD-NXG(H(({W3DAS;Ddi{r`9{%oi( zhEXVH`eUQZ{k!SuZCeCiS}DW_1VoDaTLm~7@ZC-3Y9e#@W2!zsY{S0DbD?{n8d8xg zD>R#xNF=m(kN)(q;NS8alYGn*@Xx`Ip8cwnYRc(&Ww4Py(9ulryTLYgCfxmxh9Uk; zz2`%kYNksQaA;y=WJI-DhvZ13)oG!kB!DzhzW6t@aw+=twGxT9z4F{~iI#bbc~cIx zw&ajjRPCIYP|BRLavFX#`?ypJ!(Iq!hRfZOF>^pJtc1e;Z1L8{+=rhZw)0y(Z@2o4 zLFh9&7sW(+zwCOcu4wWfB8ES$HTTgG;7c&9sI@R1HTW_`3WW#hQ;cV9V(EgWn-p<> zo}QhuF*wrz4H3@+sQZb3jH9j49C>K}jnJ4}DlU;UHV?X+mL$WpSH?Xr<1LCu5M__v8KM2*PL6=Db{a`dhGxN2cYEe&JNkhPSmGxAZ5*<$ z+3wUcwR34VEgkAlb`vA@v@oJrI>kVp1$!y=-CIPK)`q1zX_D5`xBSsapU7)TC`P>1aL`v&O4mYtk*?NIs7JNv}k`c z{o~+k1Aw zfmBM3&6WVhwoeG(@4ffhs9@;xJ!%RaYFj5b@EsrrK8F<$`}J>#AFSkW7}6ddcRwI& zFvKNt6uip=RBtTXR~fKlT5aZs^T~7>^~q!tliI#KwdAr|%V1CP4|3o5$h&1A7T67E zdwLN0#j$0JmH&tO4F)AetzbyDyUV6)(~r51IfJ(z`LN@GlsH5SMTogg#~wu*@DDc5c}g3=K&45F6QWGl|M|MULF~rdm#XkE+p3U zb|*%MK^t|ZEb_|r5|KJ3cT4^p3u;c)3=eLR9xHkHhPh2MAw21ilte}~ zm}bh<`{Ln$sZsu-IOe6zZo z->`3p@;258Ou0nH$G${{K@KW{lW{wnFK35l)7gCwSUjE?OftD=wP#QrC@f1Wl#4zZ zQp_a~&J0I!QW^DFLD)0SeIPBM8ujVyR_0Puj+1x!`?%;HR!ZlIJkFDNEP@@9;@&8- z`OubL+D=xYw}rZH%aQ~yJkMl|t2x0E{jew~sgay~raTW@3D)k&j@l{alpOJM?-p1N5F_s{Gi>bb4pXrhR4LR}6 zWCM`2#GPViR)v6ZZ zuZzI%Xxdu=j%mGd4Y(^c^K&tHC_H4D@G7cFlqW8`g|7>k|B6)5hb_5M9}ju0R;xecv{IKi}Jq=#Yx`-XR@BlGckKv zNxRrwU0nMY635$JOa5TWJZxxY#N;g}{*A7}tb_MiWVFSBL~Mh2^O2?SgAIE+q~-zh zJU&+dURyfdklOcjA7HApt=09ph1IuK|NY29v;;rD$!#+OO(49RyC2nj9KE((&3vd}X3*bpez<3%h8wese{E%B4K<}xx$S}iw48uPg6(+}V zx;)FUvs<(rgO+tA}mpF!Yne5A)!VrvZZ162SKyEO?7n4P;e}%pYL6k^P1oF${4$ z|Lc5?1L?Do2!f@s*SL#G5%-1vQ-&g4hBS6?ZCb+;`bshp@598~vg(*t|8J{C(N*~u z)@iUPfM8Pa*)+S_?2b*5(xrYG7PW-UB9sf9;W3sHGDW5dsZC=+Iu0A7JNU$L^3}*v zcf)_z%i=3d;?l>}ItYMmAERqnA`o=v=uJdulIuN^*2|i-5M_rKx>J6Ls0nRLspL8Va{Y%QkPp4H`cN*qyUB>B*r1>7uPseDw0 z3~i?MK~|iSG9tEXa`pk2obV4h9YaK%twYS^C2eH^o|U|Hl?tNNCoF0ywm`jxo5&)b zE5{j@C%qMR!}|-k-;Pc>wvelJe>$bH0hM5AdW*33Xv(?T>}YPaa!&7VfGt%aK0=id zUkzg-xGE*8*qA7hUKqI)zJe8(?!5Sj5mK1e5W0lU$yC@;+qb#LLIRcxy#6`915;`D zR%@e;QeRRC31^AYC{;1y%=zyE`>`zJEc28(TYMq^@T$20_f z6ZhOcDJVy9fcC7Ww)=FZjDii;*AL)r4rb2qj5n9fX>oLihE+5#UV9?%q_&xf!~|=+ z7a;=vUMiW@+G%xKkK~Vk+KGrQpe-Rgy*ueUx!d4N6IDQ{bDh`N{*akUU<>&VF7WAi z7hIlj{5@w55Q4nF-oLt7|2PgdHgLYYj{g>#@7ISBYryFLvZzX*J!gx~CvpP*;G507 z+J>%jY!@i14t;2<4*qGRAY*H!CdX3z`%ij*F!gRo8$OLlMSW5U^QH_)SqV1=P8FMJ zQg=|7H_z!gc3Bf*!?lkY{(OK3U?AHDuM^sx&{QDfe^=464&z%mftgVtdTAb)1#7J*8~vZXCzT zIi3GGR=%ckJ!Mpb-rqs{R_YFXjp=SpxI2myCCnqXw2?qc^VC{|3J^B2qhkMOHLsKR z>G>yJ7dRiz%dTwAm#>6}+umxAg7a0+Tj;exU+V8!I1Nv9?I|UMJHFMFy?n-8jbNHx z019hGt2?5L1KGwJIH}ND3iNc8v2U9Gs(UGBk@i&;+!kTs(ZuxIjjj#QAlU!&svhv{ zAi>^v9XvbO_N6IpMdBL=IwU%z<9J-mM9N+Nzi#gQ$y(URS5?pFXQy&`7!28F9A=oO z0WgUhZeSJQ6Z+R6S+d)fx-{#B(ZH!}9~e<8MR?nfEHX>qcvLBrz}`Hr0W4*?XPZ_H zn2U>O{!rdu)#fY2oA_SmLV(qn#2V#&Ph#^wAiEw6Tq6VqsV&}bxTjMvt<(vDVKV^TO8p@==D#4j zFC^V&BqrS^^eYL%#JkDuUmRj<>W{KdiFzEd8Pvw_{hbm34gSHnAGZ5b&A7?(u!qRf zztk3VtQ3V^ns1`|vlHyF*#9-xJCxjCjU;l)>%Hy6IAi$T)s@yq;jkad3#=ueJKS(Q zA*~F-)RDF6J9VT<^Z4~j7Fw~Oi>;;hHS11VWJaMi6f6j!7jI&B?80gd$&1|;j%skG z>8n~1Pzt^=pcv10 zxJExS1L3#qKc0PP8=~`xzaUsMdA-2%|7H`P05e*IwSCf8H z?f-H+O-3m*9XCypHMD`jX}aXlaE)yM=v9CaIG+BGjV_m`nJXZE!;Z{{2f=OJB8;dQ z&07%Dk@4_b;8v&0v+7zGY1PIYa4b8;wUdt;M$YT8qG54DTD9k=X7`EiQGO5j+EB?c z(q@`xD07j0pph8t2t`jL-08D|$6T=e76icx$k?{MMf(CeM-;GZTx-!Xwq|2vnk}Le zWu54c>W`WPb^4<93B>sIcKZPHFT3`Cc;-|lO)D!Zm)xQnAQ>(tZs!HZFxx1|0(yH>AGG* zN3=3Kj4#;1#XVSBBe>?Eg%CAB?P&hy^{&N{{-I~mS#EG^okTfpQ8Tx(D$mygvh?j! zpxbnUeqZA+6FkH917QA;z^c=S)2P!2o0#bT5VTK}{C|S>8-wrTp%c5BTrWlw0Yj>y zq$5kftpy zG)R3wSA?zY;U-nZLpc#Kh$d2%7O=6VuJy1-D-1>o0@3) zwqCXHU6TPaz2hW_K!?@urfd49zHrS~+^>|fmbHE?M7@UC;8_ATw!nUUq&&@2fALhe z{Oi=MUr;=4di|c5o=pKu-C&~fSiRp#HhIV&#Jq?GaM4vu$AJa@n@9~i7jeqiuV!75>VwMQJHr>s5lz31f+h##ka4OvSazc!zpT7A@6H@$dKYnH~2>qICX;WyW#bZiv)9T-oAcLqwg)_jc;V=V3NsY zGYcHDWx@L}+MGalQvc0k0Eqkl$0rga*i1qbgarSum{54H^v8bz*pSdxT?25zD4&Nf zkQER!wXq?a)H4_y03l~)b`1U*oK*|8dc+8Xn8&xrrIq<~T4uc3m(#ePC&n-!6%Tb1 zfEWh2>dXGmvGR0PJW5zh6u8<`r`5%_KOEEkfaGL?7$9Z??g}GXU>=a5?z4^gZjnEDwBj}?@3scZ43qntGirzIgCF*6#5P1&P+7;SXim- z_66X?PaLT%$sVWoYpWFFPfY|qkKmqKQ1EIq`|4(3S4W2->BovPkQQTNy*jysbx(*w z`E|l~d%q1^JS?*b&MqfPywqLPu1ev7p2pP#@}?%Ke|fMRsWE-BaNCE$!Qcncc{i~K zssU z_s-*53f(;4y14?Ax5nARN78+5*#Y$Z{|25AR!EarKLvxj$YlDtG!A=6v347E=&!2ZrmsaABc`gb7H5hC3dK0dK3Z;z&hUq=aC8~~y2 ztx?___FedgU8x6>eW@97ux(QtxhrD1)W7@~jAc2lq{Np2D@{D;4(uezXrFgatq8J` zOlB`e>!U}v&doOk{-Ng~S(N&$Kuc>n*VICPcytQg0<{80+x?p)a3WhGAC&jBn6U+o zCkf9CsYi=^oEiI>{jq{u77ZIn;J@h1%l-OeP4N!8kK5_WPDjSdOGwB2_pGFbqz&Km z3*ukmhT4Xk58<&MHyUw#KKA|xPM+Bu&0GG8I+Q;o;(X#O6=z-C;fN9Li?2X-5N52j zP8sn3^|FE6@C9v-$2(z2za=blTQk(N-eOn@GNHXQ3?(-TC0dj(T2N50b zISa84+Q4!~sd6*ojDIA6H&k;W`%zbLYjV3DB(Ab!2Z+Ur$^{iQI-ck{4ZtT}+FG*;7l@MXL*q zmou7KaHvz{B{;Is#KRmi1uLM!PX2o!1r!WN9!5gl-&#}9+0fJ7w&cI-{@}C{gcv)(is#Ga=|q%u69b zG20xk(IG`}ZX74DJT0F+tqD(mVfAt3+K69-&#3z)5h=Bs=qts8+KR1G*?QL*E)7_0`bmsYVAi` zqsi#E;nm>bqroLV(ShpyHsFe9hm_4QO@L4o+aSECtFJu? z?5`RDm$tKRQ(5cczW=h=hkjFgJ?FaC$^=}*?(_E>s;m8fVg>0~9(Tx2&_}OVO7;Z6 z>SIWnb!O7hGcY(lKK}Oh7L$<)nG%pAmc#qb`(u#0BYb^se0jd8)KHsPWnliZ-kq}X zDo~?g6xZtc^2*GBWWDZoQog#nYC3ZZtt%BL-!F74A1Xt7Hr=_4cuMf#K79KLEk0 zFsQZ?-LQQ0k-xBwtjSx4BR9>;u!@+K6rv~S8$9%~{@(=sETC_yU|-IKO(KVcfG9uN zOY9>e${TdY`tt?Y7Ju;G?E}bv|JLhd!1jR^#mNB$uQjJwR7C}dVI@GGw-g*A7ilaj z^mm}{muod*>zPH586FkA)@twL)P^)HA*@)WSZd2+j99cZN=Ip7su@Aj@n1@<=j_j~ zt;h|X&j0EtkRjGLS6H_b_MlzyS?1D0_&suf`D;|P=@4p;

Xuq+Ot4YahSeAk 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 aOqbW)Y$-5Caz6K)E67SINtQ^w_x}(1$n4($