From c9cd24caec286b53a9136a8c32e681fadf3c53e1 Mon Sep 17 00:00:00 2001 From: Kemal Fadillah Date: Sun, 5 Nov 2023 12:30:45 -0800 Subject: [PATCH 1/2] feat(life-index): Displays stress, fatigue, and life index --- MRDX.Base.Mod.Interfaces/Definitions.cs | 71 ++- MRDX.Base.Mod.Interfaces/IHooks.cs | 18 + .../.github/workflows/reloaded.yml | 149 +++++++ MRDX.Ui.ViewLifeIndex/BuildLinked.ps1 | 9 + .../MRDX.Ui.ViewLifeIndex.csproj | 55 +++ MRDX.Ui.ViewLifeIndex/Mod.cs | 322 ++++++++++++++ MRDX.Ui.ViewLifeIndex/Preview.png | Bin 0 -> 79448 bytes MRDX.Ui.ViewLifeIndex/Publish.ps1 | 408 ++++++++++++++++++ MRDX.Ui.ViewLifeIndex/Reloaded.Checks.targets | 7 + .../Reloaded.Trimming.targets | 149 +++++++ MRDX.Ui.ViewLifeIndex/Template/ModBase.cs | 65 +++ MRDX.Ui.ViewLifeIndex/Template/ModContext.cs | 36 ++ MRDX.Ui.ViewLifeIndex/Template/Startup.cs | 77 ++++ mrdx_reloaded.sln | 20 +- 14 files changed, 1378 insertions(+), 8 deletions(-) create mode 100644 MRDX.Ui.ViewLifeIndex/.github/workflows/reloaded.yml create mode 100644 MRDX.Ui.ViewLifeIndex/BuildLinked.ps1 create mode 100644 MRDX.Ui.ViewLifeIndex/MRDX.Ui.ViewLifeIndex.csproj create mode 100644 MRDX.Ui.ViewLifeIndex/Mod.cs create mode 100644 MRDX.Ui.ViewLifeIndex/Preview.png create mode 100644 MRDX.Ui.ViewLifeIndex/Publish.ps1 create mode 100644 MRDX.Ui.ViewLifeIndex/Reloaded.Checks.targets create mode 100644 MRDX.Ui.ViewLifeIndex/Reloaded.Trimming.targets create mode 100644 MRDX.Ui.ViewLifeIndex/Template/ModBase.cs create mode 100644 MRDX.Ui.ViewLifeIndex/Template/ModContext.cs create mode 100644 MRDX.Ui.ViewLifeIndex/Template/Startup.cs diff --git a/MRDX.Base.Mod.Interfaces/Definitions.cs b/MRDX.Base.Mod.Interfaces/Definitions.cs index eb17b07..0b210d4 100644 --- a/MRDX.Base.Mod.Interfaces/Definitions.cs +++ b/MRDX.Base.Mod.Interfaces/Definitions.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.InteropServices; namespace MRDX.Base.Mod.Interfaces; @@ -283,4 +284,72 @@ public enum ErrantyType : byte Withering, Skill, Special -} \ No newline at end of file +} + +[StructLayout(LayoutKind.Explicit)] +public struct Box +{ + [FieldOffset(0x0)] + public nint Next; + + [FieldOffset(0x4)] + public nint Previous; + + [FieldOffset(0x8)] + public nint Attribute; + + [FieldOffset(0xC)] + public short XCopy; + + [FieldOffset(0xE)] + public short YCopy; + + [FieldOffset(0x10)] + public short X; + + [FieldOffset(0x12)] + public short Y; + + [FieldOffset(0x1E)] + public short Z; + + [FieldOffset(0x2C)] + public short XOffset; + + [FieldOffset(0x2E)] + public short YOffset; + + [FieldOffset(0x40)] + public int unk1; + + [FieldOffset(0x44)] + public int unk2; + + [FieldOffset(0x48)] + public int unk3; +} + +[StructLayout(LayoutKind.Explicit)] +public struct BoxAttribute +{ + [FieldOffset(0x0)] + public byte unk1; + + [FieldOffset(0x10)] + public ushort Width; + + [FieldOffset(0x12)] + public ushort Height; + + [FieldOffset(0x14)] + public byte R; + + [FieldOffset(0x15)] + public byte G; + + [FieldOffset(0x16)] + public byte B; + + [FieldOffset(0x17)] + public byte IsSemiTransparent; +} diff --git a/MRDX.Base.Mod.Interfaces/IHooks.cs b/MRDX.Base.Mod.Interfaces/IHooks.cs index 95f7cdf..9bb3a10 100644 --- a/MRDX.Base.Mod.Interfaces/IHooks.cs +++ b/MRDX.Base.Mod.Interfaces/IHooks.cs @@ -81,6 +81,24 @@ namespace MRDX.Base.Mod.Interfaces; [Function(CallingConventions.Fastcall)] public delegate int DrawIntWithHorizontalSpacing(short x, short y, int number); +[HookDef(BaseGame.Mr2, Region.Us, "55 8B EC 83 E4 F8 56 57 8B 7D 08 6A 03")] +[Function(CallingConventions.Cdecl)] +public delegate int DrawLoyalty(nint unk1); + +[HookDef(BaseGame.Mr2, Region.Us, "55 8B EC 83 E4 F8 81 EC ?? ?? ?? ?? A1 ?? ?? ?? ?? 33 C4 89 84 24 ?? ?? ?? ?? 53 56 8B 75 08 8D 44 24 14")] +[Function(CallingConventions.Fastcall)] +public delegate int DrawTextWithPadding(short x, short y, nint text, short padding); + +// Function that is called every tick while you're in the farm. +// Hooking this causes various UI elements in the Farm to not function for some reason. +[HookDef(BaseGame.Mr2, Region.Us, "55 8B EC 6A FF 68 ?? ?? ?? ?? 64 A1 ?? ?? ?? ?? 50 53 56 57 A1 ?? ?? ?? ?? 33 C5 50 8D 45 F4 64 A3 ?? ?? ?? ?? 8B 75 08 8B 7D 10 F6 46 0C 03 0F 84")] +[Function(CallingConventions.Cdecl)] +public delegate void DrawFarmUiElements(nint unk1, nint unk2, nint unk3); + +[HookDef(BaseGame.Mr2, Region.Us, "80 79 38 01 75 38")] +[Function(CallingConventions.MicrosoftThiscall)] +public delegate void RemovesSomeUiElements(nint self); + /** * Called when setting up the battle controls. CCtrlBattle seems to store things like the battle timer among other things. * Its heap allocated so we can't just use a fixed memory address. diff --git a/MRDX.Ui.ViewLifeIndex/.github/workflows/reloaded.yml b/MRDX.Ui.ViewLifeIndex/.github/workflows/reloaded.yml new file mode 100644 index 0000000..ff8ff0a --- /dev/null +++ b/MRDX.Ui.ViewLifeIndex/.github/workflows/reloaded.yml @@ -0,0 +1,149 @@ +# Script to build and publish a Reloaded Mod. +# by Sewer56 + +# Produces: +# - Build to Upload to GameBanana +# - Build to Upload to GitHub +# - Build to Upload to NuGet +# - Changelog + +# When pushing a tag +# - Upload to GitHub Releases +# - Upload to Reloaded NuGet Repository (if GitHub Secret RELOADED_NUGET_KEY is specified) + +name: Build and Publish Reloaded Mod + +on: + push: + branches: [ main ] + tags: + - '*' + pull_request: + branches: [ main ] + workflow_dispatch: + +env: + PUBLISH_COMMON_PATH: ./Publish/ToUpload/ + + PUBLISH_GAMEBANANA_PATH: ./Publish/ToUpload/GameBanana + PUBLISH_GITHUB_PATH: ./Publish/ToUpload/Generic + PUBLISH_NUGET_PATH: ./Publish/ToUpload/NuGet + + PUBLISH_CHANGELOG_PATH: ./Publish/Changelog.md + PUBLISH_PATH: ./Publish + + RELOADEDIIMODS: . + + # Default value is official Reloaded package server. + NUGET_URL: http://packages.sewer56.moe:5000/v3/index.json + + IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/') }} + RELEASE_TAG: ${{ github.ref_name }} + +jobs: + build: + runs-on: windows-latest + defaults: + run: + shell: pwsh + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + submodules: 'recursive' + + - name: Setup .NET Core SDK (5.0) + uses: actions/setup-dotnet@v1.8.2 + with: + dotnet-version: 5.0.x + + - name: Setup .NET Core SDK (6.0) + uses: actions/setup-dotnet@v1.8.2 + with: + dotnet-version: 6.0.x + + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: Setup AutoChangelog + run: npm install -g auto-changelog + + - name: Create Changelog + run: | + [System.IO.Directory]::CreateDirectory("$env:PUBLISH_PATH") + if ($env:IS_RELEASE -eq 'true') { + auto-changelog --sort-commits date --hide-credit --template keepachangelog --commit-limit false --starting-version "$env:RELEASE_TAG" --output "$env:PUBLISH_CHANGELOG_PATH" + } + else { + auto-changelog --sort-commits date --hide-credit --template keepachangelog --commit-limit false --unreleased --output "$env:PUBLISH_CHANGELOG_PATH" + } + + - name: Build + run: ./Publish.ps1 -ChangelogPath "$env:PUBLISH_CHANGELOG_PATH" + + - name: Upload GitHub Release Artifact + uses: actions/upload-artifact@v2.2.4 + with: + # Artifact name + name: GitHub Release + # A file, directory or wildcard pattern that describes what to upload + path: | + ${{ env.PUBLISH_GITHUB_PATH }}/* + + - name: Upload GameBanana Release Artifact + uses: actions/upload-artifact@v2.2.4 + with: + # Artifact name + name: GameBanana Release + # A file, directory or wildcard pattern that describes what to upload + path: | + ${{ env.PUBLISH_GAMEBANANA_PATH }}/* + + - name: Upload NuGet Release Artifact + uses: actions/upload-artifact@v2.2.4 + with: + # Artifact name + name: NuGet Release + # A file, directory or wildcard pattern that describes what to upload + path: | + ${{ env.PUBLISH_NUGET_PATH }}/* + + - name: Upload Changelog Artifact + uses: actions/upload-artifact@v2.2.4 + with: + # Artifact name + name: Changelog + # A file, directory or wildcard pattern that describes what to upload + path: ${{ env.PUBLISH_CHANGELOG_PATH }} + retention-days: 0 + + - name: Upload to GitHub Releases (on Tag) + uses: softprops/action-gh-release@v0.1.14 + if: env.IS_RELEASE == 'true' + with: + # Path to load note-worthy description of changes in release from + body_path: ${{ env.PUBLISH_CHANGELOG_PATH }} + # Newline-delimited list of path globs for asset files to upload + files: | + ${{ env.PUBLISH_GITHUB_PATH }}/* + + - name: Push to NuGet (on Tag) + env: + NUGET_KEY: ${{ secrets.RELOADED_NUGET_KEY }} + if: env.IS_RELEASE == 'true' + run: | + if ([string]::IsNullOrEmpty("$env:NUGET_KEY")) + { + Write-Host "NuGet Repository Key (GitHub Secrets -> RELOADED_NUGET_KEY) Not Specified. Skipping." + return + } + + $items = Get-ChildItem -Path "$env:PUBLISH_NUGET_PATH/*.nupkg" + Foreach ($item in $items) + { + Write-Host "Pushing $item" + dotnet nuget push "$item" -k "$env:NUGET_KEY" -s "$env:NUGET_URL" --skip-duplicate + } diff --git a/MRDX.Ui.ViewLifeIndex/BuildLinked.ps1 b/MRDX.Ui.ViewLifeIndex/BuildLinked.ps1 new file mode 100644 index 0000000..245ac33 --- /dev/null +++ b/MRDX.Ui.ViewLifeIndex/BuildLinked.ps1 @@ -0,0 +1,9 @@ +# Set Working Directory +Split-Path $MyInvocation.MyCommand.Path | Push-Location +[Environment]::CurrentDirectory = $PWD + +Remove-Item "$env:RELOADEDIIMODS/MRDX.Ui.ViewLifeIndex/*" -Force -Recurse +dotnet publish "./MRDX.Ui.ViewLifeIndex.csproj" -c Release -o "$env:RELOADEDIIMODS/MRDX.Ui.ViewLifeIndex" /p:OutputPath="./bin/Release" /p:ReloadedILLink="true" + +# Restore Working Directory +Pop-Location \ No newline at end of file diff --git a/MRDX.Ui.ViewLifeIndex/MRDX.Ui.ViewLifeIndex.csproj b/MRDX.Ui.ViewLifeIndex/MRDX.Ui.ViewLifeIndex.csproj new file mode 100644 index 0000000..2920b08 --- /dev/null +++ b/MRDX.Ui.ViewLifeIndex/MRDX.Ui.ViewLifeIndex.csproj @@ -0,0 +1,55 @@ + + + + net7.0-windows + false + true + 10.0 + enable + True + $(RELOADEDIIMODS)/MRDX.Ui.ViewLifeIndex + enable + + + false + + + + + + + + + + + + + + + + + + + + + + Always + + + PreserveNewest + + + + + + + + + + + + + + diff --git a/MRDX.Ui.ViewLifeIndex/Mod.cs b/MRDX.Ui.ViewLifeIndex/Mod.cs new file mode 100644 index 0000000..d102e88 --- /dev/null +++ b/MRDX.Ui.ViewLifeIndex/Mod.cs @@ -0,0 +1,322 @@ +using MRDX.Base.Mod; +using MRDX.Base.Mod.Interfaces; +using MRDX.Ui.ViewLifeIndex.Template; +using Reloaded.Hooks.Definitions; +using Reloaded.Mod.Interfaces; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Threading; +using IReloadedHooks = Reloaded.Hooks.ReloadedII.Interfaces.IReloadedHooks; + +namespace MRDX.Ui.ViewLifeIndex +{ + /// + /// Your mod logic goes here. + /// + public class Mod : ModBase // <= Do not Remove. + { + /// + /// Provides access to the mod loader API. + /// + private readonly IModLoader _modLoader; + + /// + /// Provides access to the Reloaded.Hooks API. + /// + /// This is null if you remove dependency on Reloaded.SharedLib.Hooks in your mod. + private readonly IReloadedHooks? _hooks; + + /// + /// Provides access to the Reloaded logger. + /// + private readonly ILogger _logger; + + /// + /// Entry point into the mod, instance that created this class. + /// + private readonly IMod _owner; + + /// + /// The configuration of the currently executing mod. + /// + private readonly IModConfig _modConfig; + + private IHook? _loyaltyHook; + private DrawTextWithPadding? _drawText; + private IHook? _removeUiHook; + + private IMonster monster; + + private List allAddresses = new List(); + private List allBoxes = new List(); + + private nint rootBoxPtr; + private Box rootBox; + + private bool initialized = false; + + private nint stressTextAddr; + private nint fatigueTextAddr; + private nint lifeIndexTextAddr; + + public Mod(ModContext context) + { + _modLoader = context.ModLoader; + _hooks = context.Hooks; + _logger = context.Logger; + _owner = context.Owner; + _modConfig = context.ModConfig; + + _modLoader.GetController().TryGetTarget(out var hooks); + + hooks!.AddHook(RestoreUiLinkedList).ContinueWith(result => _removeUiHook = result.Result.Activate()); + hooks!.AddHook(DrawLifeIndex).ContinueWith(result => _loyaltyHook = result.Result.Activate()); + hooks!.CreateWrapper().ContinueWith(result => _drawText = result.Result); + + WeakReference _game = _modLoader.GetController(); + _game.TryGetTarget(out var g); + g!.OnMonsterChanged += MonsterChanged; + } + private void MonsterChanged(IMonsterChange mon) + { + monster = mon.Current; + + if (stressTextAddr != 0) + { + Marshal.FreeCoTaskMem(stressTextAddr); + Marshal.FreeCoTaskMem(fatigueTextAddr); + } + + AllocateText(monster); + } + + private void AllocateText(IMonster monster) + { + byte[] stress = $"Stress:{monster.Stress}".AsMr2().AsBytes(); + + stressTextAddr = Marshal.AllocCoTaskMem(stress.Length); + Marshal.Copy(stress, 0, stressTextAddr, stress.Length); + + byte[] fatigue = $"Fatigue:{monster.Fatigue}".AsMr2().AsBytes(); + + fatigueTextAddr = Marshal.AllocCoTaskMem(fatigue.Length); + Marshal.Copy(fatigue, 0, fatigueTextAddr, fatigue.Length); + + byte[] lifeIndex = getLifeIndexText(monster).AsMr2().AsBytes(); + + lifeIndexTextAddr = Marshal.AllocCoTaskMem(lifeIndex.Length); + Marshal.Copy(lifeIndex, 0, lifeIndexTextAddr, lifeIndex.Length); + } + + private int getLifeIndex(IMonster monster) + { + return monster.Fatigue + (monster.Stress * 2); + } + + private string getLifeIndexText(IMonster monster) + { + int lifeIndex = getLifeIndex(monster); + int lifespanHit = getLifespanHit(monster); + + return $"LI:{lifeIndex}({lifespanHit}w)"; + } + + private int getLifespanHit(IMonster monster) + { + int lifeIndex = getLifeIndex(monster); + + if (lifeIndex >= 280) + { + return -7; + } + + return -1 * ((lifeIndex - 70) / 35 + 1); + } + + private void RestoreUiLinkedList(nint self) + { + nint CSysFarmPtrPtr = Marshal.ReadInt32((nint)Base.Mod.Base.ExeBaseAddress + 0x372308); + + if (CSysFarmPtrPtr != 0) + { + nint CSysFarmPtr = Marshal.ReadInt32(CSysFarmPtrPtr + 0x3C); + byte isDisplayed = Marshal.ReadByte(CSysFarmPtr + 0x38); + + if (initialized == true && isDisplayed == 1) + { + rootBox.Next = allBoxes.Last().Next; + Marshal.StructureToPtr(rootBox, rootBoxPtr, false); + + allBoxes = new List(); + + for (int i = 0; i < allAddresses.Count; i++) + { + Marshal.FreeCoTaskMem(allAddresses[i]); + } + + allAddresses = new List(); + + initialized = false; + } + } + + _removeUiHook!.OriginalFunction(self); + } + + private void PrependToBoxList(Box box, nint boxAddr) + { + var rootBoxNext = rootBox.Next; + rootBox.Next = boxAddr; + box.Next = rootBoxNext; + box.Previous = rootBoxPtr; + + var next = Marshal.PtrToStructure(rootBoxNext); + next.Previous = boxAddr; + + Marshal.StructureToPtr(next, rootBoxNext, false); + Marshal.StructureToPtr(rootBox, rootBoxPtr, false); + Marshal.StructureToPtr(box, boxAddr, false); + } + + private BoxAttribute GetBackgroundBoxAttribute(ushort width, ushort height) + { + BoxAttribute backgroundAttr = new BoxAttribute(); + backgroundAttr.unk1 = 5; + backgroundAttr.Width = width; + backgroundAttr.Height = height; + backgroundAttr.R = 128; + backgroundAttr.G = 128; + backgroundAttr.B = 128; + backgroundAttr.IsSemiTransparent = 0; + + return backgroundAttr; + } + + private BoxAttribute GetForegroundBoxAttribute(ushort width, ushort height) + { + BoxAttribute backgroundAttr = new BoxAttribute(); + backgroundAttr.unk1 = 5; + backgroundAttr.Width = width; + backgroundAttr.Height = height; + backgroundAttr.R = 64; + backgroundAttr.G = 64; + backgroundAttr.B = 128; + backgroundAttr.IsSemiTransparent = 1; + + return backgroundAttr; + } + + private Box GetBox(short x, short y, short z, nint boxAttrPtr) + { + Box box = new Box(); + box.Attribute = boxAttrPtr; + box.X = x; + box.Y = y; + box.XCopy = box.X; + box.YCopy = box.Y; + box.Z = z; + box.XOffset = 0; + box.YOffset = 0; + + return box; + } + + private void DrawBox(ushort width, ushort height, short x, short y) + { + BoxAttribute backgroundAttr = GetBackgroundBoxAttribute(width, height); + + nint backgroundAttrPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(backgroundAttr)); + Marshal.StructureToPtr(backgroundAttr, backgroundAttrPtr, false); + + allAddresses = allAddresses.Prepend(backgroundAttrPtr).ToList(); + + Box box = GetBox(x, y, 2, backgroundAttrPtr); + + nint boxAddr = Marshal.AllocCoTaskMem(Marshal.SizeOf(box)); + + PrependToBoxList(box, boxAddr); + + allBoxes = allBoxes.Prepend(box).ToList(); + allAddresses = allAddresses.Prepend(boxAddr).ToList(); + + + BoxAttribute foregroundAttr = GetForegroundBoxAttribute((ushort)(width - 4), (ushort)(height - 4)); + + nint foregroundAttrPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(foregroundAttr)); + Marshal.StructureToPtr(foregroundAttr, foregroundAttrPtr, false); + + allAddresses = allAddresses.Prepend(foregroundAttrPtr).ToList(); + + Box foregroundBox = GetBox((short)(x + 2), (short)(y + 2), 3, foregroundAttrPtr); + + nint foregroundBoxAddr = Marshal.AllocCoTaskMem(Marshal.SizeOf(foregroundBox)); + + PrependToBoxList(foregroundBox, foregroundBoxAddr); + + allBoxes = allBoxes.Prepend(foregroundBox).ToList(); + allAddresses = allAddresses.Prepend(foregroundBoxAddr).ToList(); + } + + private void DrawStressBox() + { + DrawBox(75, 18, -130, 56); + } + + private void DrawFatigueBox() + { + DrawBox(78, 18, -52, 56); + } + + private void DrawLifeIndexBox() + { + DrawBox(100, 18, 29, 56); + } + + private void Init() + { + nint rootBoxPtrPtr; + // There can be up to 4 pointers stored in an array, where each element + // will point to a linked list of UI elements to draw. + // We're reading the array from behind as a hack to get around an issue + // with the item shop, where if you back out of the item shop + // the linked list that we're interested in would be stored at the back + // of the array because for a split second multiple linked list of UI + // elements are rendered. + for (int i = 3; i >= 0; i--) + { + rootBoxPtrPtr = (nint)Base.Mod.Base.ExeBaseAddress + 0x369900 + 4 * i; + rootBoxPtr = Marshal.ReadInt32(rootBoxPtrPtr); + + if (rootBoxPtr != 0) + { + break; + } + } + + rootBox = Marshal.PtrToStructure(rootBoxPtr); + DrawStressBox(); + DrawFatigueBox(); + DrawLifeIndexBox(); + initialized = true; + } + + private int DrawLifeIndex(nint unk1) + { + if (initialized == false) + { + Init(); + } + + _drawText!(-92, 57, stressTextAddr, 0); + _drawText!(-14, 57, fatigueTextAddr, 0); + _drawText!(74, 57, lifeIndexTextAddr, 0); + + return _loyaltyHook!.OriginalFunction(unk1); + } + #region For Exports, Serialization etc. +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public Mod() { } +#pragma warning restore CS8618 + #endregion + } +} \ No newline at end of file diff --git a/MRDX.Ui.ViewLifeIndex/Preview.png b/MRDX.Ui.ViewLifeIndex/Preview.png new file mode 100644 index 0000000000000000000000000000000000000000..7cdba80fce34ee2be1052820cf28bcf88be8ef8c GIT binary patch literal 79448 zcmV(>K-j;DP)K1q|L70o(L~ud1u)HG0tmB1xdoyf(=qL}=w+@g zM7@#x%;ip&CxTo8CC7)cKC;k+JynBPa$^wWjs!a4RQ_Wz65csh}Ya$d$X!jsZyJWl!VuirYm1LMb8!a1H*=xGFIqrzmkcN$_4t~A86c1;OF-I8s0G&RjrvId@I@d_ z23yX|f31xO)yWk6B@z~29KgEo%!mPJH=ozXxk+@Ww&wHsMQ~;KC7R;*(8S7gG8Q&g z8E}>yMO6JE8R3WzsyM1*)ZAa6pUeZNSjPn3gf^GZrz#OQ5%@5M=MsiU@>2N@i?G8r z_!q@+fT|qB=I98?2%Pu#_bNHuSOoIRAcWR)@?)&+4;c?Q@u0bK4;z@nFdN%z_yXI0 zesxtBf)%jUDBIL}0@^b^*Bh)6Yn9#vRrLMy(^GmZ$tw#xtu-!Fc=i+3s_=nJ@l1C}b`MGK~YM=94?o zA(lH~K3}BiY$mc6r>3M5j(12G5*HM&7-Hu4K&8cu@AG%pGi%33;xNX{!SM{>voqg# zOexN|+sTi)c)PhzsK&51U`?#(KPuHsc=ye8=N^8J=k@dWYn_uej&%&UdoAYtx1d+s zer*wY`nv#1e3(a>n6orII|pls0^nstPr&XjlkM|`MgG;im|>0 z4)dbAzE?j7ea#98SZi8m36?ST296jkU8IvuG_*aglO^W9n2527k{AKwC;yB z(nfX4nkZ3~7E;c~iaU1-5(EGy`Dg>0f&8{ljn8CZz4_$v)^f)?Xh{PS&FWFyr6+?01o{ z)K^iHnj6ig%<=M5!x2AjB8=+S7?5;y!M`O6uH%6TE+~Y z5ETfX;dhTySQL22cGP=$|LXORVT^K4bgcZQ0_5my#OV*y#=eKlwE}@IZr>9%H6;OZ zQut(@D?XsYf~mD2Z#)=jLK%J{p^D$zxg*Rg;E?jYz>u&2-DVEZ;vn~%=W$}WB!Lr< z1hed{c_8~}-vhur!;p=e#rvjJe(^~2-=9Kp1E{;dC;uV$68p``3T`u*%=1nH+-V_h zwRfrNS_N5xG4oWc{Q<-IUi)Q+FO9)nzenBAo<0MtE&%`tI2~N;Q&@QT9ZNW#XV~%X z?zR9xOg5ggkZC&F>^o3YK*$XfwA#t?03(!9n9!C((n`PQ0FSL13%c%2>YZtMHtPw} zF@ChX{Njk`uOXxXh$aF(=eX;?LzVdb#WXN~OGj3o&2|K~gfJ%Wv7S6q?m=J-P9#cy zVZ{6vNJDK5?m*eANVzJMhxx61?8ZQ|_3{{(Q9WRMh0#d>u$XL?A<{_VMS?~ioc(7e zlts&MU$sSo5feiCZ6?#8z1f(h4Qdff3smOag{-SnkkqrP4&XJSqCdzW(jyXTtN?Dzajam;8t$68<>Lb&t$ottruLdN<7I5b#q<~I&< z`S|9|4}LM42wR)$*gqfg3$dCvFrXcyy4x`z> zb2cCO3y%F3;y;@3vA^AbOD3}X5S%kwQ-~TbG3aR&e5_4|!aczyCl$f`CC6UlV5^A^!B0luwn>Cdr(8eJ7VH=OqPguQ|ZM z8QMNKT@mKEY0q9f$HK4~PgI73J*E9;8qryXv^v9QOfF_E?y(J{Nodz~7%B(z34stv zY$m>EO$s)*4SA^6@p>AB{y9C95SIA>GXmAzMIR@sI=)4e1Hldl*rwlvdB%T=v zjh>*OC(-ol=g(p)Ht1{)c$Px4XIue$jP=(qG8YvR3m>0_6eBrlXWX~U>T4LLs{tW> zftk+n^D@a<2+It|nS3@PLyLgIjAd)$@LTMi$C9xu1kA;zH2Lde4Qb$YRjRF{M5#oI zR{rgMaEDOs5)Z?&&Kn@yiXuUoR7B)irTK)jiB~W1Y8St9ZXS zEXltJ_Djr%_Y_Z+fjA@ALqx*yc7c+OP{R6d-0)l{lv~anmejKf89%K4g@{a2-vWNk*?cN?a z{y)#06EHVM67SWAdkpI5JPTm$h~yth<2En<>651!mYVryCY$;s!ysU&(;00}=1IQ_ zbGx^2sN=qu+>|M4YyskvXx^BFXT11s1In>oHb9+LaA3muNU%Xw=lEL-SV(gCBs2YN z%I7+`P5a|RkoV~c2;MV3Y2rM5RzFw2eE$F!lvwkpIlk*S_C1P#_GB?!ndLW}i+sM{ z19mE7RpjI$3wIKLtdQzVO#$Y07-~Dg)!IK;$$;?DCQ5H80H%oX-5GkrgjOnJ14#Ur z48I!S>^)DUC1rx0F#j-ZG7r84ad|||LEcv5)MtEWo21I2Fm|xBU?dZJa$x zeALIsW~=XLe)@rrN(NnO_{@oS*v|sZ#5`i<_k^deV%o$ ziCv#zG8H)`(D8c-;*ns(!Z45U`jr?lt7>K-%WG@L{#Z-3;{|0474#mZL3z zo_ej=#I@zxJLWxaW6aoR@=ks1Gfv5-q9X(dtvE&-rYU}#7Z~t|Y&7+!6{s+BF>f)S z5{BBNwdq$U$}HSrNSqT$5G&5#uQmRxFN2NM$GC1P%Iox=WASKk7lCn#mGKfG*bo$_KzLev0wGBQKElpCjJz+xeaXmRV~<8ocGfzS zmn@cy#zb8QucW&$!1i`hfhE0pX&mw>?Ux(F%&(48Uo3_O3$@2&AKE%LtTaQMh?0a9{fB&PqhX z$-U@7IKE#e>Bn|iwzzXqt{2voaDri)Z;qkOFUZJ8S}GX<=#RqpxI{hY=<=2dN9*eO zup0}%*+R|oNE)Ium(wyJWx6F?yJ@bysj|$TKP$fjppK9Yn|WvgbAbl`LR#E577NgL z!-Aam0bWCF5+;^|9o9OBzdujWHR$IJfcEuwb^($BVVYd@Hte{`A~NCkCCEyfFgF*g z7A4}JNj?sZvVm=md(JFS%bEZXoxnm7Sqg>}v9AzPSr!Jc)tabyp08gA7+9{C`$0Bi zX?Fxix)Sxhx}8GFf_0dZj!$17zQ=lkz-^X2Kt+UiSZk^Iq083~AAVq#&U}(0Ou}0< z$3E7y>lWY?h0z>wf@_jdh%fAW)cE&0!s=MJGVeIaSQjv4Iy3hpjszp)a54>A!S9Za z!`k#WR^ayyBH84%58Amw(s((B!_P0~aoaG8>w7F6xmm+I1kDr^E+#Gn{ph1Yu~Bs+ zcoqIsD)lH6&}0|aSjy!Pln+8im=0$is@g>BNy0I0Ht((J#a9R~u&2CT3&wx@_HF&l zg{sPaRi@+juiti^pc+kpC&<2=CUf`TsLLkMs2wJgw9%3I*!7*?J+Xj(L1DdATi z=ga$YQ!b#i->pe*`godgNM#-HfhpXkF$;r8oHLAUu-o}hU@T7Kfk@OCFkaJ+5h1#jBlerQ;5c=7cwH@Jqf!^oxujt zq_i1z!_>$L@jjpODQhyg|Ddk+M)T`#e_v{G;n~o?H1iv@;^NC%ywY%hZp3Ya9%X*J z1VK}fG*8pfWe{&D#8@(a`tzNMKV|*|i!C@`y?(vCe)EP{_-WQw7GC{}hRr%1etwb{ z&f2x|K5}{7wNxrFcomOZh1R_08!RW?-Q*1)(QUIbIn2Xt!Y^LFENm&?p=|A;+ONg@ zrwg+z@7}*(V1D{#jE$SJt>7+ip1&Xy&`dfN1YTsvjk8mWEehA+eDprg9&iZDVsi6I zXy7W7QrTzK^SEsn(hDuKQ*H!wW{PNNQZyTz9Q2luO&4h}c|%!i`BDe<83Z~rpotC!1*^ZrIIhpoE3cDRu# zoGUvm(^6Agt$I$(KA5YtEOVH9%lm?U^=|Aw-?JvCoU>kQ_}nqqCu4-4wxC1D5HD)I}K~Vih*x7l;9AFK_XCD0IPkh4- zb-YefMu#2iBq2|! z6>HY4^_`RRs7(pZ+C~DIZwkW*uYzWWN+1O3H7kx?irQ3&qQrg$zIY9% zUy-?BYu>n;=fhOK>J_vew437J)4UzL_ZzL61L9&tt4=Z!1L!Qs1PtT50=MG5YZ4J` z^Uys9@<}2g(Z$=50L^O+g$~60c#d(=(#zf9$dN_48tEBD?tF5Zha37xOD|M$XB#$( zJI`YGqwByGa%@WH|LX-I(Ct&P6@;luRO?OSPSej(lJ?>A?qEg<|E?i_JO0>J2( z>fbAgyK#7WIp^i(V7W ziJlkur)Or;+=B<{pcq1%7{v5)H4TZewacsDA?DUer=~;?L1Sq8*C*4W?m8N|9FpKn zEjtMrTCq9shY)6b`GgyH45V>0^KxZ1p?5%voHn<*BXX7SYRuG3t5xoDPeMUe-Zjgc zOQr#^v!@vDiwO-uJ)<@`JhT|@L*hC0rj3!~Zlv!Mcot`$rn~wb zqX!P8`#S#8!a}Y+)dY-G@OuD=ss7zEO^)bzTlD!`qAAfUqT8bLfI0#GU81eL2mI-r z=)MF08POq8FMuBu?G?Q(T4bM5(N#WQ5M9)@@0gQGAs@qp7($mcgtZ+ygP1{2zf1<* zQ_BZo8Zy<0VsaL;3yf4+CK^{Qd7lpJPsi)_ZRBz@q$u;yYhSXz^P(eKp_>-P{DYX~ z=>%i*W+Ogo)7&A6Hj?Lg`1OOJY?7o_tX&)MIeyDPx3vT-cAPY#=a9uNDivi<6(&6R zhLyQC;3VRTtg8U3;6#i!&K8nT@{QFT;AGQH3C${y{>A{xHbk{rbj;9*1PwuCK9#h7 zXvie}KH1INCMVN}Mz5uxxN|2h$j*K!d-DX+`HX0r7W*5+Tho)7r^y7RsNrf8SQz2F z6#;DRh7IY+nbT>PQ~O^Q-9hrdi!{)$1ODxRzYQRdAo<@7_|GBvdpO>D(QeFxCCr1{ z&Qw?yo#D7^*r!#rUm%;*@2<(8us36LW!+nu3*|~hOl~oe`!8Cy=ipvG%Pl6LIZ5n6 z!Qwu0AOsy^{jT#b5uO0@qU^|^^}6rPPr|@n-;dGzRYDju_C*N$gs7Y^1}X-y zmt?X2I-E=w9};)GitaO*QY_F39@>I1WwA4*-qe~Tgxjn7(4T!<)*YOW(zYO3{k>Ynn7evQJB}{@HNdDK5{Liw@xagQ@5@v7! zwf`-^zY~BjiH-pNJG@^Oo#WW+*sdEB$V! zyItk?vA8Wb8DjkKB9DJ$8a#lSbJTe!9pDL^wkTO5XeUix{J6qn`s)>=^81CF{Cwc4 zcRH5XHddO2e1Z*|Hl<-n;=OX@?G_+^`10x!roMxsTXOROKR4$zWe_~N}W?p|?_lvh~nTs9H#P6@9L;F5Q4Q>1C9Gq>Up&-BM5r|O<1E{3ju0Yl z?gVVCR&mzwfC|zN4}6$TBMRVe(qFLo4UMh5BRKtZ6+f<<2tc&?bLZm9ob?IU%-MyQRE-aWT{O?G^mr#o*L?46+yot&^B>GoL{u`S%rxv_W3~_n$dq$C~7L_W<@$fc^%~zAc=y1t4GIdY%_e@&7#l z_%y2gPME?H{(yUc{~+K$&#~9RBsu~A6~KQ4lVX(fJQ~`N=Hv^Qo}M;vS$AM+2KaqV zn~ugdTcW@qFqwSEDLxPTx||aql?avXF)tuoW6{f}(bFTcIOnE7^0U2{{Bc%9T~sjq z)-?nvw)#*OK*n83pP zVoHR=mPtDe^A!@g^F!;?;oG;U;~5`>N<60G)wh>=ku8 z@NY+pr~>%ANdH5k8sBYq;P2uXS2^Zkz<-1NJ9O>i2M;OtVxD|@o>N`q7#!d)22wOt z0YGtjyOo%usg?)_`}ITmZ0<3yR4}z-IPDu>zs06VbMQAWJNK9?+@JaY7(hXucA2!q zdhT%YXU!dBAq_OxP5{hfNRcT;hg@^;7kAW-;E#!Vew{Wmt&0=J+l68 z4FiU>fP63{tSR%LTb_U0#R~?^qk!`g(z(HTHj6eQ`Lox4z(3A*lYoC0;6KfEZvo(o z>~lwS3+Z0vyUl?549>)z9D53e@z8<4Tl8ke{5Nb=&cIai`4-6ntO%T7UIsxGn|uOP zUxLm4J}J$wRSyZk|OYX^Q^e^JKFHgC4Y=E@$w05&BKwr@{Yol zz=2%F8(?94mzxyiB)m11h(kpRT81@zFFQ-SEgm5iugN#2%+D8Mv`t1TV?+CM_(Y%B zJFuQNC)F!co2(Y0N1D%b6BFszm127q_5Q=6IzWC7AbnEQi{yVDN&6AN{}$ly5q(ay zn|=PQzaPe`YcPix-EvtQ7UtxA<{0c!OuZuQV{v&om(EuJbs0z8Cea4ow}=inwf`_c zz3RY!7C>*odAA67#~{F;t^)ow*#Dh?{~FPUgGl~c?BB|FRWYniF@f3n1+6vbxQm{2 zmlYTt&roPpCW>LdP*xsmH$1p~j=u+WDLCK|eoVXq6HZbSjflxR(T@=OY3BRED4k~8 zRKsX4T)EKDw9qB?gzmb4C^U#HE_>ug6}3Z(8Bm@>ha?-`H-C|&!?}vRvC-z|GfPZL zogE!^{k^j9H%e_iBG3E}y!l4@d8yl9A|vjjfd5mX=K;ZgJMe!MhuH`D`vx|82in4R z%!NPKc_wroa}2rAQz_X3h0scp{wmq0TZu&7ay0G)oRjstbTl1YTr??r9qC>YodKYmkj@oA zc}w(|?dAaNR+!NR)c(zUUKQjh>n|$%q3jL@p=Xt|zmttv-H>RO}yDTz#+N_)~hoCy;*U zk^Elm-!1xtsMmpi0wyu$;{4r!e=AP9&y-5W92&~sUzQ25C+edyO#1N3bmLS=oBFBpU zTH%Iur&%{NnBFU?^P7sRkIv2I*?QNUnN@9PBEqoSGv|0CYlMK{@Ifcww^ zu;nAv*rx)M7=+nfRj9PHf55W->^Ww?i?m;%IPVJ(lYl~3+|c#brERbFteXsY zt@}(r&J#OXl_?|F=K*A`?d^G{A1DoAdHsVDlfNup~ zVWUvpm)MAt=MJ(uom#lqFl3`(RvKZm*cXo;@!{qgg9*|Z@E6pF;|(or8AgxyJnc6& z*QndM)fd3(+rQ`9_4Gb9%lHo@+ecB6M{wjVImy4>f&V4v?f(eic#F?l*=IYBv{wPk zK3&hHtgV)8-G&|{J#k$#R2U?VtcvXZfo#N+fIDIiKkRbtGbAAO>ll}{U0b7JTFG7g zt!3xb-#Hy)Y{!n&-`8)Eh9!mK+7-GS);?DO`Ys%VkI`zD(J(eU$=}KExSaq$e;@IA z8S`L0+Q>*2`jzc(QcC||Y$p91%WhqSczDp}Y|Zrc^w_a{OE*8SAv%%C4JptJXgcDH zjKY*>=0|X?b(6dcoZp+fmCR}0FbyZPEoaSwk5mZ$*b=T0hRc*!nz~Ig5Z>zLg^Nof1h1DHi1u~n5MGuD1d(m0sb`Vy!}^@{9f(f&EK11 zpzGV(Q?KsfxPH@G_PH;b+`KsrD!cKiG9=6OWRl;e1y`%0B?AkowO+F4fXpQu3^7Pa zoN|oNvNgxCd^*g}xGz7dfrBwtxemZ**w z>uoqMl7EFZ5Y_BLo85yRuIPJ|7xp`cQ~4b4qWOY;9J4n;EWD!g1n~2>=@@YD39iRR z9M-sESh@S}R?hzS2>hD~;Z;Q+1Y9G$uL0!40PNF%|ApxA%R_zb?6U*O|5YC87SXvz z!?x}2=~ZUhaxxL@2B+$RsWVSTtzuLideBn>{}zsO0ZH4(`x;XB77}?I2|2geZnL`m z%+1VLd#@J#om*J2efG2cW8Nn~PI_;;j&pMt5rKKOn}@Nq>mFA3>`r%g?@qO?TT@kL z#x337c|Di)Qvc1DVIF@{erqCM-RGXW&r0>Z|58CJHf`d}SCk(srp@}MG*AG4(|9`T zJbae?826ZaVArp#QG~3W!!*tn!pqv!Yg@1tFj~;30B2%BrzndYtjuB+g@FNpq^PWs z#Gj&9EVh7xq<2|)Ag$XG>PAY0Tw!6iWXx60zdI&F`I+>2B z5yv2E`U0JEE&~4d@Y(0^pbsPYJI$+4dM|#0+x-7s27bK#Fn}+K%1Go_8x7lMdv;Gc zJ5d?)+HptBn#&f9Jm^!`uNlDWq7gv721b>fT|Nm|7ex0sXFJ!~e($c;7fen~>3Rs; zxd=fWz;DNfzlO7Lw^REMie@-ZtL|a9%!#^1E;>_}IvOQ0g36&osYfZl)#aKcGFiwE z--h`BaQuZfYWx8hwr^GI!Atx&d%x}{412$c|17TWnByOu$51>cj}{e=UfE*yU3+im2Sk(#h+9zizHwv$3!30GD~tDQ9sJl36`G>Sy zUY>geiR2P>eCVcWMU;=(D&5kzS@xO&oGXM~ibiXBDG)vXkRPu-v}r^7!F%`8@TE(s zh6MaN((?TP>N0kHl|21}NY~FH4Uc2vPrxL`0ROuH{}Ygi zV||5+YJfp=6^^W5;9A-KGs;H1C7;12RP(!ldm9pbu3R=L-f)t?2PW04g*LZmZ|c~! zE0rESOviQq$6PT`-DL$1!DRZlKQ~eLpM}AUVFEms>ffeCza)^CN$4#n(??BeFNx&n zBhGJLf0J7HHCBwVE>742CqgI@xySy548SFHTHt@DceaXuZ^12()I0P(CBIoAsF`*TJj z!r>7n__*WQc4{GI8F{1>`&VF0Xe3d4kS)~F*OR_e@$=b|cX1yrpY+oBd~C1a10Vr3N7(5zRk*;fXo_N-~Eg z2iBySXAY$``}U`j@&@i?W1?g;mbYw??Y$>WWoq}{ed+G@9cfGp?hxR=FREl_hE(#p z)b(jKb+n=Ea`6Yw zo=Fc~J^u*W!XUq|8^(88G>z#p$M3M{gU)e9OsA#2BP}SlUrxrjO}giG{l4TnXV4;S zb-emHCS6;$=4H1<;j@AwnmmVo<#1Te>!Mf%V2r@@rUn8itVKqT+i|HE$QcMtL)}o% zTI_mV5FX5^o%UffGc$${OPSU)CMsg47g|Wvto(nJ^2(5h;v|ITollzQBm3jnjaezR z3mzV-RaVItviQP+Sdj-#NYEB}w?beY4<^iRK8$L<0N}4WwSO7#?h|cx;6I9*e?Qxf zzo+=To$ZkPIryK&1An$uvSU?|u3IrBW(>e)>*Mh^8`%vrEm;nMQiN?@Ub&Ghw|@TV ztf`H2N)w*d`$c`<(vXSM+Gf93D=XdKu`@kYkQ+^0)0 ztc@f(+5Leb&SARDYEhk3EPqZRz0sXJ)8+jKbQ}g~WC*V1;5X@C%ZM=Mau(KHt`hr) z3B=iX{}=dIP2jQ+SaT+Uc5CLJjYil1Gw>MMi*r-B)4U{oWz)~%^$Sx06DbNu13qo$ zeRN9NYGLUy^*N>q=>8kRutK{Ve z0K;rTyproH%Jzy6yI@YeflBW;460kt)vHqzHK4*bsn_6MRD zQJv2?@PCc%ci=>I(rA0%`BNaZ&P+uLjQc{P&^+`o2Z3=WH#^ys;tGDb(mAmD!nrZ9`f zGq3$lil4+V&v+iT&Ho4dF(zNUpT5VjX5mC*0I0yxhlM{t z*IKB07r&Y}_Nb8DBZ{52`2ULVWp3xgye-wcLR0}CT_RI9nCzi*bZ!pA0Ai23VyWo^4o4LrU%E1uDfo56WE z>cC(3YCqub0{rI^LoxvLS%A`sGjIbj^OH{U-+)o>*v_tSaQBxto)$ z)G*0!ZL(cfne&yDEK#JhtJ9pK8pUOdZCVb^XQbIwwBc#Ocl*Qy?)CSZ*&`J^@9tD< zU}s7*IG~0mLuf4hd0TK=iNnY~zj32Ue&u9XK~JyFrxIOL?>m({F`(?elC+q{a^_#C z8hBa|5*brt?wy^x6{bbFFsjzPUxh-Md6VHEcFr1%Dc?WLWQ1@y^9tu};v|d>cB1nz zfZtEq78N%qb-&eDKjxZqXd2=$P~td#kZ71_>++0!rXK*0bpx*5x92!)Z}tfjcS01P z2>hbL#+)46+DC_YY{5g5TACfmVyqi0t!6_%1n^e@C6YgV)!D&c0o;e3ooy?Rzxnqjv6mTCdpyC+^-!JxVGn={y-zs<6l!$rf1fh%YTJ zMerAoHTT_o!UX0P)*e-XP`)17#~j?I`uqL-b|u~$z&K}nXNUR4q{Xu6c?M02$_l|> z;LiwnfXRe#Jf+Xx?gv-qQz0xG1R!$`wQYs<<;-h;F?H<7ZklHL#vC5-z8L~_`j*hs zz$7pay~}wP`GSqut1oC&#STS396}UYdHa{I>#yl=rxIvd)v$8`z+X=c$#81_9>D)) zYE)?g7OW)(oX zY1a6nPocl6dJ^o{|1Aqo4$VVS@hfO4Lol%mqIs@$>&=^%bKg>Gk@Tm6OpIV&4LL^? z!rSPk0Zlsae^Q!8*YH+pBTFXvJ5(I?!r9ZQOU!1?(;54%7rB>*vdBcnTx>{&xdcZ1HAMj`!i-&|y?Cg-Y0@{)SR@=hSX$uy!^D?PJ>o1Bmv>!c|Xh=$JA+q`G%V!VhSH-_&!QBCNS2`id4z>#p5q>sM>lRMD^Q*8a1Z^fAqb zo`Rg``ZEVpov~f=VHn8k05^Zd?$Q9qssqC!R(#xwm9&5j=tPbT*e(fYMYUZ5ERAG> zhfLSTs#00|kf$$ic=~{}nirouHlIjc4DgPMm>!7flIY~Zea?|dm{V_X*A(Z%xCyjD zkQHU(s^@`WNZU7!t}$VWJP7rEkk;#~5IJzF@FTqXo;MXp#XrF8xfa3>9-#W`!Dl%I z+9rTmlsiOFZ$cqay;;X#z@Lgzf%TSinffmaHGO1$-azeb{?~G~AMgX@5pv_72mF`W zuHC>-jXNrH%}M?-K)HCU2_Q162{Jz_$^Q}q>5)?8(u;?{dW2m z%$Bnmb65U;o4__N$*v`3&c6o&!nDF}AJ8~6Rr?tu_?T!y_jgIYh?%jwx%sl}8dt!) zc{ZUG+svA3tsXM(Iy*8oyeqXW%$u*IYFbz$ZPFpS39a^|hB4IJ+3z8V>G4u2J=Ev> zS&pNwQt}GVaF^{*%5-)O>P|d=<&sjvtM=XB;UxTpJGaxHX6sv;()iezfVgZ-C@tsN zny$PzsP6@NFpVa;3t`b)oj`SI5dgnzTo(qydPoGSb*YX4Qh+UEM~4LeDD0Px@E{Tz#{)s@rsz%Xue?tLu22fD_7(Xv3Pxq~J} zBoS?jZm$x3HVJ@_u8RFkP36~f8428r=YBKSchZ6X1`KSi9Dwt~ThfyD&m?MTxoTy` zIz?)iW+e64?%Tw(&!w@E^JzS*x>UkYMPWNd2uy-jbkrq%KBHsQr6PY`X~~$F6M*wx= zeT|xpkGaOI`zho8GEDe8@ypcNu2b|+Jo{nM-@qikS@d6`UTFmTvrbs5XnZg+Vb^Pe zL$k0Z_#htCP;w?PYb@96b(S>GRLi#L!Ko6rI}SWp)L z4pVH>6~Nk#bY16KWiRucrPK0$9>A~Bxo1ST@UCxTyCs;!6q?1B%n_%BRYRL9(+s3d z4z&$ZN4u5DH!iL089eisVNCrnqs=VbQ!M_MU_Lil^cMvFn&S4$*#h!_tK)Ibv;aBy zssh`+EE_Qcv;07_vhmB=Kh*OQwd;#>^X3q&XHr|U|EIG4e&rVW7}iCE=KKVs;&5MN z>a2%_x_lneem3j*4Xa_vf5Ld5p-;mMH5(_n4lk{JJFv1gpq%X=mP)$ zAlL9`qJ3z4{|Mv$b_B#lxNwu331E?-6QVJ}PNe%7RFwx5Bs7d4_Xcd>ZwgDvn z7LIp{>vTaSB&5%lTPhYIAjV5pA2IwA z{rVdgAu|7uLY7&A4=KGYR@d4~pBI5YM0fnyE`@DP?d_AvG5+L98btDch2Q#dfP7K( zt!P!BfdTFo{hMfz?LLQg_Jc6zFQWx?i~d1$6ld^1JMe#<=l|WTh5r_Pm!cnIN+hdy z^(frAK-Q!CE&K*gR{k3pfD@LU`T4Ba7}+8#RQtgw@=$0QMuXN%3UuhCcGvv%XLHURz_i|m#I|2zw35665<=O5%;w^*Qu&?@fnz5-)NxmVh} zw3*l0)VJEgf-U-4uJ3uk|Aqtqn-2Upa16f3IXB;}V;mGnXWH9vp0Qv7t7#oNm+rcS z=w$N??A1g$ujQ3fmykEgH1B@io~l98j4=k=hRn7C$=@V-2GYL9WG0nryn*}mMegH= z(Z)sq|GelEfPW`izn1Z{(VMd2a|+=b(4#$SJ1c>%48QmPY4kt=M_+?B^Mdu_>yK zL+2owf%$p71`s%f<2oVhswmypbMYLw*fgjuMOj^;0Eu%KjVKR}$DA9wn^x1`p|xw$ z$8X-WW}9y!oi_raHo$)oU^2NjT?5n=C;2zoc7PuckF#AB@a=%Hd6Z-PfS-GM94!FJZ|AwpJ`XTAJ|Nn} zKEt99sfzO4&K+4!1(5-l^6La62~YMnd zBCQRqmjJVcryL=q;U3KtyDMVQE_rJ&Nv&J|LU zGaz*;gw!tw(peVBpaBAJKN5WsP(EZ~?H08-@NYl@R{{SR4C5IOegJxvhdT@)t1gUq z*Ma{6*CVN7;k5R)4omW>TQ?b9vsKP5=iu)Xy~=S9p}o{u_@f;E{ap7+I}crp&;TlO zg4XJ^lm?UubHm;uLGlEv2Jh=4G==4A4X2&n3+xMX^LbnEYIV{405tkQ>Ul;@--vn~ zCgcC#A!faaK|I{5C(JiqT}-%r9wh5-K#nC)j^xId=R?Sr>(q=9v7X!M~wTPY_4Y@U_q zT5w~t7exu6Q0G81m4t&Y_yi!|vd@zFl&BY?D;zUVI2 z4^x1%QEO1tdJJ2WZCu|%{YdNJGAV#(KZau&2TnB5=u?{OoMP6)WbD1g1K$q_C%xM5 zZ2oiDkb`Il4Za&^pF>EW>wteP#~ToJlZ#(N3O{g?U&qdw(H5ADWUzs#O%ktFp5-2S z|H~If(mCht|EdH3s~r1%uFxpU>Hmy!@h6qo^Gy>IrkQ*iO`%8kW_Zra5i7+xBR_zeAlp1y)rgd#YI>s}qZTLc# z!n$dbJ^TMqu0mBBOrMVP>ca=t)bs@4|2M$@KGgn4qVFvPzX-|S#&=)JB|qTDf3Sgl zcED`^3&!*99CtwB$vHJvt*iOzL;0D?4Hw1h!125P1i+PYpbr8vCM zw5(=>Zo_dDnVZpB$$`(rUuPfW7f<4WfsCDlX29PFVqLr+?kK5d9)Cp?>>^2VwD0Mm z<}3aDF&Wp~$RrJ|kE=$eTKeLlY#(y}d-MWGE2Q8q)b~^$8X|Ct}l62=!oiyoxxL&t&jGE^k$&VC2 zgwwKtw7-e{o0$uj)!s`F%o=mPu8`kJd8_*+IiAV`{q=3z&97k7hUrLS%}0^!W^20n z52g*6ImMtBN>@n{x5g8!72C(y1dBegV1r;N5*WVQ4;n|GdLwR9eZv=Z%pS$x4=5Mm ztojWui#aap*+0!{7X-MM)W`AA(xQNjIscIjUqJ7JlcGcziRvP39K*7aA3T-MaqaJ0%u@#rUD z4hGmFp{IEfQeNR0dsqe(ng0Mw|_j+<8Fe$;sKF?(mi z@oe77Qz)3)gr6t$!ZQy!j=hxv!Zbn>pL)e$1{4lmBY({;B^)iIrau+)Y9AlBp(%AS zx5r8hYLowAO20EHU3VLj{|%n!w{UM><9(OtUtz*Wi4e3oZ~s;2@cXm_|34owqsi9P8ySFe;<{jj=cM*C6xOK3-U6@KVj#fI0^0JYZ((16Ps0X&KarqcjV6~2_zQ>2227j zszmpJ%80AfxL3+8^0g#OOi|jfX-ejx%CZZc(+{an0!s@092?mAVGd+ywdR;I5gOYW z@YBaXp^XIrVnP9%wyeKB1AXbljnOpq=#e>2U)1p~b5Bl)wuzCS?e7z#kffcPHD++D ztJ8{y>?oaim04>i7f zCflx7v(GE*2Q7?hQ5DAOn}e{)7<(|`!B38h$5HbansN}zB9CEAW%(_3tRHM>Q#VZ{ zjQkFNIiRygA`>Vlwu$@si}H;~^9yA7L&!5IXyP9H6n0Gc2KGpm+9mPr5=8}9aq4qz_ZGJ+1*!=G$ z`R6J7oJaD1vjhJzgv5Ws;762BJ)yjbNks_C*>9!4Bg0Tv19D&hrhT_o?0GqC`j_u$ zgixiwAi|u{d!Z#iyQY@jw)VUuPy}po?|n85;3wH9=U!eS_?K_?;XRY&L5KQ+2>#-_ zY8}g_=L~8AZJL-cP>nk9KjHs?KV1a;n^%DUzEk_FNd5qRKA#nBVxKz(ew>LcreWuU zcpe5ZjR$*?#n`6s*Vyh|X(o%;x3-!Dm!E`8yA15sn<0z0;|p1~#ZkuQNoYt(gd@&P z7NP?${rD+8_QN7_%_Xk?Dj#88*^SrnMdnZr+|w+95E z&mKFL#>E7GP^!O8J8m>gGy0&8bGnhN9-)MHT+R)P#kY1SilXQJE%d?rZ=S>R0JIIs z{i^f!ljH;VQTxrzifaEUObU)|OlBWUriZlRC(2lSD4$DBzrlPi6bCheYF_vXrgObG zv({_Xp|>L6`_lW+grsFa(}6?QUGW(2rnARM`anGl!#!iz!+)QVV?Mr8k-b(wH;&9~ zuO2zWcBnYz(9Dd1YYJ8Eu>*grll+XtW`du;&*}YwK))=FrCKUkb59MAu)6)y%1$`|u~x0wwbECgFkaqD zT|npmW{3OaoOiZ~Rh0TX*?*t}v8iQ;=5_k-jEHkJ<_+I&+cSt*uFdwz!k-D}a!KjR z7kYcr6aD^PeZEuvfUo1P*@%;G$K0G%CC+J^N+viO4SR5X+Wu#>eZM~YgpPekbPz`# z;J0I4Awu9Bet7!=qvCgy^A5^6?XLM&R~)_E$DIKI`|u2kuHJLsbB*RXsfzogDcZ)weK z!zugUlq`RcB%cd_e>x`l*go%Z-hP1}Z$FYB@E>KJ{5wfSALiNLW}l}SGkN~`RGV8! z(=t^`_^J{n7=El!?F#r;o1_&09opbE^%sCSwzDXJQ|p4`t}xCI2#GtIs*{TC!x%Co z(jXfS8-;-hFb^gJQzx(#%#ot;WEQc|={Cth)T=t~alk(X$agvL4*>ofqKX6mBlf8x zEq1c)1;D=>wSUfq5l`xxw!4bKZ7i%a&Ph0;aL^?U%4am9#3a8-e2!x!(guFmMSc&pr8V$KCY|)2Xb{>4(jP))H|OBe zGPMi*-}U$R+=D7luMu#ZT(uxkjP3MZsRh<~_&J3DkLdn<8pr4dFxgHkTCk-3EUh^u zD^*VFa{O4^zBoUh&tU8&BzQ$M2KXm+&QFTohgLzTFTEGFf7Yx0Nd5+lA-DNC_D5h$ zciHDIrrse%F&?OqNOduf3XmHS`VdCRA9Di?3xsLCCLX&eiHaEj&iK{}nuzw>zIL5$ zO#+QCB#0N|lYv~4j?F>`#7O1fOmv_PKOPmvn1M?OqH~a&=pyRt>$7kdp$ybW=C)^& zBhwt@Io~T9964`5eB!e8T16KDSHq%C9_%1?;$@h_5yx06NR>;X zEiRHUpx@so;NOwW+B&et!dLpesM2UYt|6>GcRBjR;obfAQlBqU;uz%?Yqo)pfX!2O zu8MWlnVoy;2UKuQn@3>YYGb?^pdu5u;v^l{n28+&tt32K*LEwbE?lOd$m$%>1R7{D z{1h0Cev17y$Crge+f@y@Pob*k74Pqd*?w73kS{4GU`Y&TUNQGNsmt>^M_GQKz0v@G z=j<8F#b`nDpBCLhbC@PY_ylX)=|1#h|j^>BWFYN*F6B4|GCh$Sl z&>t&2TUIZI$B!Nh7>q<)1|O_**U7hVzNI&ZTL8H=S#=>?-!oFj4*R*#xph4HE-e0OaRU+)`{ThhPnkLGAArBk_3Y7gzF$tK+fplAWHPMFZlY+8R^IbE=eU@YrBCYEdlX;q zT3WKU+Y|ck#NeRy^_vpVzh8`Jpjx#78uR)MQySuVOWz$3<7z{-pPrgFQ>8--Rtw(1 z@pNW}c5KV`w_ED0hF72g8IX)YE-fvZqp367zoS#vWMH)WQetvaschPuZ6^n!Np}I* zG>DpIhqW4WQ7W%3fHi%62D%yf9+Z1;*Vf96f-JWJX>G?*gAjYB{eAtke7Dx+*)>|x z4(YEp$!JF5ys=xit+H_H$+Q^IY?{@+i}MTk6_{CXH3r@{l&i135}9sY&3sSUVkt$~Zjhy7n)^=--Ppz5)23XxlI8xxB3Xh5_}V0wYjthH-bs-R*vJ{d0GBvvGID-3t_H zp)ORYCbejD-`|t>S5qQ2Y*g9tUM)op>mL5@AOErR zD0A$k*IZNPs(0VR4?kRMj5-(5! z)e_A;()vk1=a*WeyH|6uPRx#_+M6r{E+J+>&z#@aIhNxteRqwY|Ba62SZ4db&659K zOZ-<@Q@ql7}j0|V;vO@oIx`ic6v1oJ3C}++we$x@Q3EW_Z79@`@qlx zqt)~H{5~e9XJ;p1<-p{8sPy-@9gv-JNCYHKIQ~*rU+tzN6Lx!ykLZ;t?SSQ76IZ+Jri*Z>15eakJk6u<|-In!z=?=NIdq(JJn^`Id6aPkvf6L`NHV>ZRv%x;uOk%Ok!&|($`*Y4zek{J@`GOG(XnqeLKn0u=^!K00Y4NSHD`Qp1Vs`dWeT7Qw`AHbI&~mKmlZ=^$TD4!m>(GO-Dw3a%ITDxe8m6|j|GK&M z^NBOI(_-A;pLe)ot-USzYcY$7n=_8s9?~{h#64LAxKse;uAZ{wpW|h_lCt^^`u!P6 zwrd2g1p)|Me215Jt|wT;_G7ai;FD5~cO%UOEL3+M0$>G<2c_ZxL_mb(L`uR8_~W~4 zWC9?GIS%QG^adm_03HSa1{8b`@L>qNN4f&I-rin77EV^c2x!0f#V;1X3h*{<+Ef5N zDnHVC#flXL@M4z1us8;_{n~4mfR~%8~4~rc)4inHiQ4wNkfETbXo0R>Q#bYM9DJOY(Q(% zybfsI2+b}QYym{=;~bb;nm3@&(UrA2b&VUMpE2U*C%(3Qd3=}vz?FuANLue-v-qd? zOZH3sL~+mg5Af$3;CKdHt9AgDO}u)Ld=h%4j5NtVjetKD^VsZ%lEJ^s8p30m{B3xx zZ5mw4l8#lp^SsX?N>d34fDK~iVL|kO{EefHU?_WaJV zFaekW4?ZFwk?;T!2C!qtj)Lg`SO6i?`{zIZIr~L?K7fO%aNQ@Le6qlJ03XbR>!1lR zUKj`J{+04`$kyjQpoeKOZuSG@(Hb6b@*VpyHWV!#oszg6HUKI}A zt+_gD){HV=sy^%e=O}Mru}JHRM;|S#4;+Z@w4t`-h@{*X-GJwPwo4dvI1HoC zAX}AdRU-YyD-Obqc-6p5kydM(8pZIIi@x_giG5Xn?Rp*gFIu2%<-z0UQwfZMWT4P<0`40Lgffes6ipTgpl~4Uw2P z%UK9`cxV9Vjyvw)Gr$R(pFgYiFb!1qQ0F-}j0UX$jRPV;HHX0fc76v~sOjgOcU}R2 zm?kh0RD3{=TF<_K8De9sI0E?{ropuUCC7bLrj9fdeh-Fz)m2v&d;v4G;sL{BjEtKx z{p@Ey<29HX3~-W@v)IrcxE|lZ)VKzWi7_!2;s>siNy2vrb^omLGzcJ*G+(SXOj)>~ zESNK^y!`(AN~;>8Ttc|7%&k*;rEus)R{M8ao$tw#-(kCF@mcr6O2SElKTG~$mIrO~ zFSHiW!7=vk@3-22Qgd;S&T}bC(i!}|&afr_!=}5}nTCGYAyZ3*UWWSZ+(y$SkSb{c z6G(GoY$8FOg|an^2|E~j|M47jnVawsT>~I96&`rR-sg(GS^XH!pM8E;|H%O%M1s}y zKXAUR7UgkfCPzXE9cr88XnBGzwvtBkE%{4|?LU~xeLX0U5q{gK^Gw$9UAF6Xr%XZq zAQ8t)K#3a8{NPUjbg1)u z27E|;7)Eqw;t#bP#=vvt{EQ!Fa_+h3mV58Lx4^{so%zSx&u@(L$67Ukxp6%Mn$MUk zaZenJ_QO4M+>#|r7!&sr&P9&VG3$Y&53BD%(6DpziQ)i&IMPa!d3Lq#f(QG!cQ~@9NC8|Hg6QgB)*15*pAF0qTT^ z8sGwEmc(EL0L{Qfy#};MXNVtL872^FJ%oR;9E#ivpE=K?Qey!*QWDUx42PuW7@h-w z0N6-Y7$*{x-l-9gs2>BsL7?`*MJ?yoa^`!$Q(? zA20*<<5)KK$M)yGIWNqd@nRA%-XHzwM=T2lfug~{U|#vkR~DS4To<#4`{BHd5&r~C z;Sc`c56a8mtkr}ii_009y(0VOY9E|mJLOF6(Y&3O|KbrpuPboWCbj>V3#MF%7G^1o z5Ljb?_lyDmx(OuzWi}}eSk*shU|)h+pl5f#wsrOm{Ky*S%RQchjt#g&^Y_mRTIwe} zy|>rhk)M;dIZ+P`wp_my|Vq@2%H2{9pWtdE;+8hHTV156mKm94!!p4WeurJqOZ2S%oVI=V2SE24{D-Zo zU&D8*81&o9Dm?eugXO))d&>rZZt(Af$)~dEci85ikNxgverYN$a;2~FsF^~WHG~Cd z3?n0vpKy_$8)e{6U=Ha0zbOFdfV9xzeo1{KKTCf6t23yR)J`3?`5YQIG-<#G4jK)1 z{$MC|5y3n3TyRfNirwZo*B#9Ue9n(a>T=@NmR2rQGmJOa-*W;_?fPcbF-(}<$3!%E zo!#-}<4S%r7&kl^jj%#ppP`V}m6DXZ4ESZKboW_E3v6jEAz_cTiC|_*dpV7R$|0w( zH}E%_X#P}^@iu{Gxg;XsfxsbR-s7Ny&{1iTj4%UKd!#Os9YW`OtJz3O)N(+BIe{cZ zg~pDK^?uH0`yR>3zAy~ba?A|?#c?>^!Ysff;63N!m2okbNZU&U=FhQ=z{c>KI1k8c+u>{Ke@WV6K1Q5@BAx9iy+sFP~0ah%qep4RiYEWmHcZ!Mt1;9sALtR6tB`}+>>wtH559pXR0^Jf3tcV#2$r4yB z;o}&DF7!0VtXQ>N=7ViH}bq$~6Hh)M_u|aSoh%oFAY8dX5Pv9@3n1 z!7Px}oCA&G{`>DQI2v!f@y3FQz;S2>%q`jm07Uu&WWI-qKv;kbrUKyK_{KM~Y5)TZ z&%GD}zKpmI8V&abqku7C>%(YZB>Zu&Xaj(nx#2!BiO>u%F_=Hh2d;r;z`2-5n8qb9 zeo>h%21B=`LESIcBTI0R=46XLKcsuQ#@_yW?1YYdljbcz=cPdZWdX`6S7-<><3-R}u8@^H`$N3?vlyo42$K~YO;j}qVAYSi z!&`CMiswYZNR8?uK79V3>>!E(41O=zh4q%i3q&kk#Z0>fI(e;&1+tR3Jc*v z%&5hH1*ry@QRe_bsBr-A`s=R;Xra2pI5>uThPeQ8GzGphzyG3y#5L zU@TmR&j1b2J&r*%5C9JY3Uffr14$jrNiYGVJ#)!%#3aDTV0NhgFb?hofP1+xY~KAChx zn4YCEAJq8+`_p1pkJ&DtYWsZ}U{xm}o@)~;SmaTh&{%biovI;lM5_uL=@Wt4 zZ*_i(!GFKOe}$dFk65c{whv)}!GEVUh!+*phv?yUJ^zg}XO%W`IRsR)J5j^W0Cp0r z2Hj)9m6(($6~3{+lO1z>$DDhuKUd8LxZ{TT8eeD(d6lgC7uS^L+}YBSOn|JmJH&Q^ zuD#wWA&FkLs9x8g4^dum@>P~7s+vRfy!;pqD2NiDtjMblm5pBLKK9%Fu)6@i$1x-c zG{pWSlBllSdo;1@wA9w;)q+DNj82;mmkS(+73)4jlK6Z{Wk3v2k<8VXWN5Y~u z0zCG!D$ZCK8~Xxgq&E_paUtE&Dqsv82f(>6m<{(y+yP(?e*#(xV}$uQRG9mM*}&9b zOpF_IgH;ahk?VwM0HMP$0X_E&qvBj#gE8&UGwC^UwBTT-);>-In#`lcw_bQly zrT84DUEif=+s7&sNou4SBPawuB=2yYn7p3(6?!H&`T1U)G(AB5Yytds_*tu%ZwK-{ zsTm7S$D1@ik7*_8*kq~vN^)wFR@vmnx7;TyOgN`W2IBf;FV>|ZEjGQFBcyg@fF{8h zv~SFe3x1=3>sGKd4t{I52E&GckS&GBU3$o%hmb6hd4Sk2<7fnN@miqI?{o4(rCvdW z0k9u8&vKrK@?6zuCr5m10{>Hf;7EJYb4Q$A*R1u~HI4Fj;Gi?Z7_>B5;H_6czDH{3 zh=_ZERB{nNVCK4EzcW{;&`4jTDf7T@JWRf4j*yH2T*7csQQ4L{QxQ( z;DxCmX?cb5u$;zm*x{TDRU0+=o$q`nQHKB!Cn7+C0bz5)D7X&Gaa;>6g7Kl=GZw(i zSR=+?D*|Xam=FLT`#vN&*G7%!JuwQL2j;;F0k%Bn^pYu>02&1I#k??nK6CysN4O76 z13=Hb;cpxCgCG2ab|#)ic37>9@?B!8tABd;YSekJ$cYJN@d`{P75e{J6x41fW^eRA7j zSKOU2uHUwNCBes1uBOxP`9vN%{4pM0ZLOnP7?D>VK&u{1nhJ@!k zK#O(|HZA}(BZG+`2??r!fdrF-32;0QAMj%TIWv%Jg`b3T=4d?t2eSbDfSG+cmUF={ zkmPI*DPLkI-iSJ6 z%rGJt2lvj{@G)>+?v?X(W3uSEoD%q3q}rd5IuB!?r|S&q_+w(G7f7?1jT$aSe&6&N zgmx25gk6rhZS}ce9_o9gYU?~bEZOSI@9P@RP@M^&Yg}8*6gsTx&xamTKZYx8B7RY( z!~s1&(I>>D^SdJ!wHx(HT?N#Cd>9n8A?POXGOlDtoCOoM5Q;pH}cVO?6GI4Nqk?^ z37KmY;J4(4NhzKtn^sb(1-0Lje^Dync_AKr5pj=fHrjBlCaX?TZziB;b41|ZIss&| zh_on0cafx^#zZt6s%uOz;DfM{+|JsAu<_0#eE|f-k4hY-0M5D}{_uwdyO=+I2k5Bj z9BZEek{8JdG4MO*LqY>8)ObL|^^nLg5~33$8OTw2Xa`7Km<`Usi2vt!0FNX_Dm!8^ zm>OCF_XD%xJMIt7f-!R*YowVB99je_Gc#Nz3vfF=N0# z!tykdnfImO8(>MdM~=cLRG?+Aj^*CyrLbSsd#=+Q_pyv8dwv;l9J=1U7Hn7AJp2cG zF6j3`uTqPwrHM1WAVhjU_CA|_riZfl#PLGWkF%v7BTc4S@;BQ9 z{3R!Ybm$tliYT8DfUwsA8br(3Aw<+zRBVXcOpW~jP^{mw0a6|+HZMzYsM|0E&cntz zAbiwnq_%^GkcNPWYw|!z=poKNatQz?00%f6$M^UPcx9ddB!4g@&d>L#?MQ3P3hv>q zyYAvU=9BS3#Aqq;-1v*dI*+4Fe`~wiw^u9i#OFs9wbC5Oo#?PU{)#JwY}nB>C%_TuRIFXSL@^XJiJ@VE6ahxf3!R6;BmXRophrw=t{D1OVoMzGgJbaDFfXP} z$I<6l{^C9i+J@|};k})GZuK2Ye+Fjmw_uzx@-TZNhJ$%xznXP4%y`CYsmFQQ7?W{U zaTqpW0$B3Lm$s>EF@T!kisnWWRsE@a4}htZ(xHcqv?Fk*UEpbxLypNI{s1CF8-Q5p z6w7Z&4H|y7u#6X>$L?2`BA*6P)#uME?NXtai(ps<=ri~a+YDG>Nxx6mJx2t4NK$Z# zZ9knVBF^577NF}sqVa5#)ITh+=)RC}0EdSKupnHdVfaK~5=cv!0)I}xfia*huz!T* z0ulfL;j;mJB(y_n0XO@zg|EP^)c`uzfk8x0KSaat?2moTHMl+|0(Lob3zI==qfKxf z?uq+hKbQih1mVcgf!CnXE~1_Q=jYno3+LfEat>5~u8(t({a|!RbwJMdT#I{TUl!jXDJ{+zu#cMI5c+Qj&EkE8)NumS-%lnpppV;CTyNzYN;XOAS^|hXAUIj6SAhqZ2X_kj^`Ft%VX07b6Tb2md*LK^er^CwrgY zt=3b+0DGU!#XiJz4E{3)e{PqLX~OlWlK@R)nvf3d-hUx5!n6;6n1%CrW%{eB^?5a* zR!oi=K-D>rm*mE^*Q49dn0+(&eG3&e9s*u0;#{N2T1Bvmwwc=JV$^AE?UZ!JE3U0Y z5B?l|w^Un)w%K@l#kmiO2>Qfn?fS@IXa573L%{Kcq^ zVgNe?4!X$>nF(~TnPL2si2ZDV@>(scIes697eo((LaO1w!kHGn6M*aF7;IYrgWVfp zup9#sFz(5k3+4zF9d-ZZl7@hFx3rROqW%mvt_MSzh8ZDHqAj6i?9_f-A5Gv1jnB4r zK}F|!ND`I+`JO-aff=!c2|=ybbpabH_=x=z8e`-*@SItSYor2_oSZOR0)JpG3v_>r zaY}0cv$esr>4(QTFqL2=zw}GL#Msd|I2Viw#se*&EkF-w4k58{0`fgE5C@*wTl!Bb zx>L`)u|=APz}=>O2jsXVNazaEu65u2V)ic*^O-@Zw*C9c0=4VnISxy!Xcy2X%lX$b zb&9S%SteZ@%~*9kika$(yAHu1O;PD*z_POT8`AI4(QUfVI$eK2j>2JRgs#0vdKdR# zgSqh8;5Xo+s3)(n8rCHfb*{1-m-i`&Z1NN}Iz16FE&Ta-JI_P)cj44=a|y<)yUA+v^wG*2$LVcey zz~>5JSLj@el&QDezct!q_==r?rzEAeD&S?l!1Snynt&YEy#W-G(Sb6Q;ezlXXn+sk zA$-6FIKvYUsG79l?EJY@=gm@uVHOYv9(M@;kd6`KU|$$SluP4$NJoeYZ2;RHrnE#- zmeA%6Qp4Hjg<1++Bc`QuM$5I^1S}ZKbX|*Q$ngiH_Vb+H_ulswvQ}x} zj);-0(EZNPeRYtEjaI06*sif5ji-pQFs^nqI^EwR0{NHz{Ljlgjako{xgy{PhKR}^ z%Z6MFdf}BhM9V=FKtm#*fHA-Bb+0Q=Xuj{fp_6r7(RSuVgsvPXNZB!S)&S&bhq3%U<0ywz6%(iI?#LhWU z??PJ`(Qy~enO#1l2Ya_c{{pYW!VFe(oSkoT{2W?J3&X=nCjEQK-QGs7~fXO>`y{F#u zo^qE|VA^cITlN1$h}^3qgGo;$w?hrl9SWyje2g=CDBJz1!;?%m~G@D=vqj>6FUC^X(4?w z8@?>5{3DqWtMvT8@TpIgDPjzmN%n;>{wQz)^I)~Zxdcdm#uX*fc%Co>-ZMYY9DlO} z{!`qK5|CEvo*JCMv)BUT{?v~Fx;m!ozETX}=*UR)V8p+3nv1|^9>aPdMijcrB<^bq(`!6=10pA6TlIPW~>P2&#>dRu{IGo3DiyWQ1RW!9% z<_621_!7Kam}6!lyDv%lO5RMZKd+F*d9wcv)Mt)Rso_U8Sx&$WMw(%=FWk8ou)vjl z{B!rob_ibj4uNrj9ykx>h=VT<@Q_mE)!mNSKid!Wj3xgL7ywLZs+>#!2uW{8NV7oF zH^6$Ur(S;mr=DdlJ=`<;?FAD^^Y6G(Sw%dPCVF$cKH-W z#Vfz@ZYWoaWls2(x!3*Mlywk^YbFHw_%|ZI;D^-RhhT$1Mo&9fu>&PNO~(AzsO$Vh z0GuH^`F#`^A!1UIe-ArRX{!N-YXa&Cjjz;DIO@sMk zz7QOIk3-N)r#JzLJVYB}L@=qSpoHcE(*U&RlRsfPS!%ku+u^$xrVPESYyv)N@YlKY z+qrTUU%v5)^8G~$j1rUU?Kw7T?zkPj72hc7UBJQc=+b#-Yn!nWpsb|7Q_y4*+J?SZ zy=_aGLhOW7mUl2V-FIvEbP0k}j=(j8N#J*w@3@Ucp_}wKQ5(Oi2{0xlF~U3fjQWY% z;$ok%`LwwaVP&~5^#lw?G03u(s`kEEKpN0PU&93Wq3|A1-eJkV#OmCzA0(63>kh2j z^stU7+Hb@T6?ZvH`y=dl_HFMHgJayr8NAek%1~yGH;JPA!63?vo?y+u#0nK~q5bHrpdVAj#H2 zuY1jJfAW)pe*{wi&|@w!cQ8qoQ<3h_9oh(H4<-$a z^V6UHH2bi$80E^CU$g_jKVOWXRVLKKGOw2KEFG}ZYE5z@ptpv3Qnb2L8o?o^rdsiL?2u1~Po>EpXizf&Zj zjwyCwt^5&;VT1ccUhVz91H;m|c3iMp=Ipc337Q0}7tz>-4e-|hckbd{JKjHK_ts(p z^#*CI8Ad~nB0)Q( z?eoJrqKDK!I6#P{vjFSOg$Gn3VyDx=r@pE^gk-gQ$e3F@v02eyQ#L zhfT=++?gKIRaah#-H*h=p2q=(rysi(I~T%6DutK+l{yvepm*rHkjKm1mLf|C1A!se;$*w5t`(f?7wtlTF z%@X)=Xg`?Bj~y|6zgpj~WMzbk%@5Hv^h2aG7&zavqOCE{58KHkbrQ zwaHJT)%{Ar!BSZXFsLS|1Uymt;fN(zizc;O1OVW7q~7l>=E!F`_Wpi@pZ&I?YWm@w z)EG|5!8NRN=x_M8t`4xd)7b>GUNR2+Jtee6Q!ac%04lV1=I^j zlK(vDDmj)9!3=nx=nU{LHTXxYA#6f&>)u`}Rs6Vuk8YEeNdi)z7!J~yJsU^lf6@4k zYwK^5-$(7swjVoMUT7xr6VuCVHx6yq*e)PQ49L>BOHPn0q+S8whb`UPoMdrU3cDPFF&Ln`4SxRamP8qxHiNa;06ac`@Vxr< zjJFt%6Mqn`z6F`DIdqAFY3S2UM0Dj2TkQkpNDbfXqp%E}fFZ?=sjQjDHgGqvU*iqzt z^gcdEt^N3o6YJHHbaIlq2Vopzrb6#Q_qAtkeNFzwwXM9MO<}?uk@KoszK?oI`9IJK z#70TxjRO8-DxmU|OsyFLD?vu6`5*Ye2Ux*i{s4Yd6?UQ$pvQlLuK;F>RuzF!5HjG$ zQOGzB$??~%=hiL8`>^(DHu#;!e(ok0J#T~ly>Cm zGtk5}Rhej(?tcM}RL$FzW__OAUTFKZyXR=R>coj?BC^8U4M<>1`$sM8E;EC9SR3C@ zVLuDJnVQe-B&ZGa@$AFF=ps9TKX=`VRh?Q(e$XesTVoGgvbk=j+lbi-=o4qaSM&cZ znrwH#fgpA-Z8TK+n0dd^{ADfy2V#9+18X2H)Bw-w*pl>6E=l0$LH2tR&xipKy%my@ z5=#|L#KfA$Gi*PEP$LPh;+fw*uH+ntKS>!u{Q zBpi+@oL0_ggILi5Fa=l*A)*b?p`vNfsl=Ik#0{f$$&3NS*}emK+)XvzVVwGooU=xB zWyO)e-*CL8rFQrgM%-7h@l2yu8HSMdUg=KBzauH$D1obfYfSo^J_4=tX^N_*QX5r7HbGAl5Yu$y)=RUMRo)~>4e=1cyDam~l5T3Hktmc4+PXw4_%H zrisS&v?SBD=GskuU?~1$nb>0SX1PPzd(ohC`rEYo?20$gC?x!DhS*u?N=5#&PI ztJJ2$?qvl4Lhf`ZGp}d_EC*uGq9G7_pxLvE%{VCu1^5XU9n@;TfVjRZA{RO=>wC|A z-AFy)P5l}5$~nBD=8Y4n$u)J1O`=kQnV9oeyusBzi>b&7+ru z%l?JSO|LgWzus=NPgQG^<|MCO;s+Ve7tyX>xlK_c?#^B%-a^8tr<30BUVZ#K7TqB&8$Unx) zHEp9aZjF_gacut~q$q_Vl$df7NlczQ1a4>RNRsTsL|l$8x%xBb;T4GU8rv|E14-+c zbZL;MB^by=OH0s0P{#ZFWxc>k|h&s>uJ^2i@ zAOql0GXTks4e}7oARpUe-sfUJxILEqr+6sdXPV!ikjIrZej?KbhfLI7mKFs zCYuBrCiv(%$91_DkDdw}xOkkUZO0$>!W?0L7 z!k|4jEh+PCPy08H@3t_S>ir&u4h{aj_9tBGF!4Kl%q(jGEtc?)Sb$w^P2>TF_1$Nsn%0{;FZ6>yVf*iZ)coTL?y1v6 zACdHuss&L-$6x2aM>#7}br0*e{bCTd!2$hfrk(>m!aldApbxgm(PmJ$d36hHv<4TG zEM|HUB;xPzZG;x&-~7tPZ)yMP_nZ@eJNO`eHv{4|7%cDe(i9`@lDfX;1(!vUQ)f%U z002GD24M3&^M$DtQGbr~BYBB{DuB*s)P45FuK=S!3y5T*<6a;N zJm6!dz$B97$Gqsbwy@b+FUK>-8>a{(Fw>K#Y9`lZoH7qq^DEkWbQK%5n z)x7?EQtaxAjZ)puL}%mq1)0E_{7>`#(hW9i@SWyno_zmEqcXU|GWp017#9EpHD z(r?`a1f~FCvMk8&UW!b;7VL;C91L8qO3NKDox96@%fVy#*ta~H|7=2(45zU!s zwIau2AA-J|W?fS|7?hMJScUgGd*q{&cQI8ykwcnC3Z1Zw=cQ48=M~A#EB6}h$x-L| zV-C@xTy7oz3g!^6Xat-qzz=f){AhtQ&gR&IY(Js0=GcHyu(6~9aB)s*eD9>rQT=Hv(H?BeoTsGkrpfX71(L3=fTWi7rBN#Ejzkh-e*jyZD~acU=-W}Yj)bCE~` za4h&MgkbQ;eOAFean5-DKIUo6@inT^#QnhJ$z`W#=Tu2(vLSKkp#?A(m`KbG$2o3- zB~qMxESm=CF{zO71pW{m$UIZGfIpb2V^pGP38Cqj0H^hOKyy9M;D6dco{3;F_?H;S z`%GJXfZy6emj%vb@Ass^zuNn6#Z*Y(U+C=~3yVw4FrG1}k6LK0G40-JE#y2OGhoTT zjdNSe9JE$(Hv9I&VBJ)A;_lkDlJ;t80uyTX^%D?BrK*qDv9l*~{F2{nz8nM&QMZV@ zJ(|G3#awf(C;bsSV!AwuQ~B(Nby(mU5!hY)a}-n#^Mx4m%~{F^FnE)fPuQPh`31EX zqK9Fj4zeL3+N?@0vOTwu^idHeM2rKAC_u9RoL?WEfgn(r0!(0XmmG{D-j1$Lsk3c_ zWn$y=piICZ#6$Kgw^r%aRAuCuIk44w=Hpg!w)x}}MLdZ1_xS2H zU&>TmDfOMP6B)_#wl9Et!b~DY0-K)Le*%Hf2rv=w1>o(60l*+|taAS(14RWSK4TIv zuV@G`l>z2T=bhuhJ#ElUw_q7ISfQ~4)+$dM8z1Tg+{x{3CiA02%)W z3;=KkLqm#FaD+Yu%n?$arBt^>V`C0kE`*7~T+t?C3XH0?|S zxCZ}x)7Z0?uBQN>LEK^Rx0y+7vJg6#V|c{>C4f*7maGtx<7y?XS zAIoV{FTWtBIIdYlH4`b2BtPIkWff|mT zUC$F`+Z(@tv##Vl!|Hm6wpUoSo5y=U#O-i)5#B7Rr4-U=5i#@-NN|Tl7ynF&I~zcY41&+L5iMYqjTRZ>9HZT zaqhVuBFlqRQzGP-TmaVnVFUo0^AbmZA0es*+b0rz1YrU&gHB8f!m{=KbU&+IOp5{k ztflfIgKfLL@SUcu4uk(GgMXEe*=gX`Suoje1;7LRFpT{M@=YAQMNlmw=2b*%8T_j~=^MwW{hi4cJ7pVdBSk_R#Q^#T$mpZ` z4{R_Rk`8P0*sP)!gTJ9xt-~na+$`y#)pV^ajK%@1^n*ESZamxONjJ<<(&?C-Rzs5b zs*wN?kyJ=a2pBsyRtC@r90>>EMxjrBpL>p4WlLhRf^md&Q_PxF{rHSuBi0%t6>+x6WZy*K#FX(rf{FeQ6o4gTXPo_lL^OKyS)c~;& z;?RoL>PR{K1a8E^?`Q-NKl_a`R@I}Ms*+GmlCV8uD5te{K0MIxC&P7RmW;r7BcEH} zaG!P@rmo6K0$78mL;dHOA<=m@d}l8|@dF$aaRM*}m@Vgp8Nh6r zM^*wlb$o~R*=UE>Vu0-Dx5QxEV=3EVfVH6s7?cAB{6QRfem??jnnBDoz?)60TdY;A z@ipwUj#TzJIiW3qf4e3BKq^@_(@dhxjO8(pw?(UEr>$)pTT%F?j8ksRnDpy};D7?MECna%)T`cjGi0@fHfDVKHs5$ct9-yv| z-P$b1cJ}=Fc&S;Rj>@=5FNoCLbb0Tw4B;n$F$D3mUVhGn7nD9ARsv2-^{n7`aQP^#Y9WF)&$JfACGbe{c1}}ozsoKy z%N6(kJ>7%Ue9R!`A-V-|tq*?igN1qciHdS=LNEc>{ zPC?cLLh^GAor7RTyNK*G@b&>rzaKQH=NV)>EOF2B`+o0t&`e{A=X0ZhJkxf56Z;v+ zM=b4oZO<>W_HnQ2QTsiv6$by&;$!;za%(WtY-rRuJFph$ z^Y0Zi0rSpzAT9}JfMjq)VGpaMX)xodosk@rbCl~HsK5iQ7jd8Khw~H@m6l+pCNJy> zmP`!%UFM8EEv=jqNcw;I zmw&-=hl(FH{QxU-;;K^IKc)db0EiAvD0Lz_V)BhrYLPufuF9j6Wv18^iA0E?b|03PB-I`SSV$9@CkMKm{$5++2g z!Xi7h&pT0hJ-4lFI&ZgB>z{w}lVt;`$nuKsQW@~AsK+`7QkA>}_xY!19_9z2<9g(? zGgeHEsQyd%?0hBZkf+aj`VhGq&MgO6fGn?YFn+e~Su@LaRm;Kj;WPKhT0YBtMD5`E`N7`RJjPaeu^HbnYVgaB9hS6yNJKj6!+$RR}RxK<3 zrovyppmW?K)p(%^kyi+%N8otPU;IVc_l|dzA1bh>PGPasRy<$e!0s+o2Bu%1Q)zLO z-l33N#(}3DFmhcaERvh{2BlmiOhR`!vt^- zL#_jJ;C>kk$4A`=m=tjV4*dn>9LroXRx$^X`YUNtA)x`gVGMaa1t&D{Aqcx-p9=JF`EFgf7_W7jZUOogSKMrRnK9*eE|dZTkT@= z`vLYdolmp<-C2z>J-&E`>qPJr4aa01dsN$nqN0%vMz zs?)?NB4&-6SG?H(5yEAX0X;+-#VwGOfQ9`T#{z*L)s?z>FG2F?S|`*x>tCfN|AWTW zBh%n=&&yF0$5ctj_y6-hmq*pR|4{+yrMljET6^ajJ7g>47(>#|)%bD9xri%Wj7GH) ztKP?TO~CKIg&Y@MegHV;1z-lOFf7*&hzLAD>1asq7tIFH^E=-G)+i0n@c@?dVHWX+ z-^ABIJD`4I^h>~0;ylc$vn$!6)}mtsB4d*C^PGCccmV$yfSe-y5ICLw{ItQi*5Kc7 z`l|+2LBENx!vdPV!yOp4UnJlapzmIKkj{I*raSVeLwAUGw!3s z{shzgcKQP}*VSytm+9NfGWj>BP3xIO{Z2I9$o|XcwA0wlJiNq{6A>xt}K*G$|fZE}d0e;&)o`eIQ{FRBj4l_BFeC8&+cF(y6wR}cxe$-oYrt!j;$8TBY z&)gdY7>^u161nLt^U;lGiPYO=BKAHVzX7kcYq2RYC8Qysa8LXwaRo5!n2e4*fFDpG z<&a(nMBtaA68m1MaJxm4d6lH%YB8KSjLl52%|r#5|A!oE@73D*r7D=&p>YCU#tf)< z_<)**qjc>-#Rlk%0r0@2knU(H02h#PJY&OjajGq%uHyHtfs1aSh@ENFVkpNpzQHvqKOkA!7{(Bj7)-=P{sbD@P-8 zHx?UgPp0tRZ8k5@GwAkMg`ec#W?A}gHA7fnZQ*FD^1IdFw^@L7`ty@!)aUxVJBp>a zwcPnB(Wsg0TJj(AF^6FW{=Uhy(BdW{38>@7^c$-(XJG6hV0kBsD0E`Kv^<@*2sg%jC zOvps7lUP!7rxg+FG$asTLx9o7n^lk@5$qxXs9j)kv>IwP?;&hdS)$*Nv?R4)8br-I zh~BNVv6n}so21~`lGLXKxVw4y4vP9uforccffvc7XvV+baZd7_H6bOm&&U7zugj36 z{7I?Pv&EnQCDDnf@PHnz17KZ!_0<44nvQA?0D0u!^BZG?DX~BMaX;J#5*z;l$DmPg zU%cm@0j67m$5J21F$XvVan^CqFglnaYCZRFErH_!G@1mU=2*T5+(>-h!(a&ohGD>D zxkgC-h^r72ny2IYk)WQ(=}E&}Zh)UklJ=QYD1>8XreLp0))w}%ujl-Pf13v|lU6Yo zhLd6l_L*s{F!(q4m~JzIN!A{o;@qbDLmtCoKikKwRh%^@O?$k=EjI6I{~d){`jP(H z!C2DuT(`f*Q|nH-)DxVGx>PmCw&QLOot$mR)7=&1}H)B5FL^YAn+SZ z05Ab0z6VTvrVB2N5(WX$L$rLxQHC1Ju?qw^#`LhRwajyJtBI;p*Zf2I9rlQ+bkNhz zgvaZ26W0_;)$3F*f3lo`w@L!;7fA3!xbiDwrv84||6CUdjik3q&6vZ}fw3`njE`$XN-yV4E#;UW7!Kca zPR7AG!^gsN;JNU59*kIH+7#Y(gUF!VYRSJETRW{PwOHz&4gRQ46{wzV0$#`>|BJV7KvQ+Rj^T5RVmb20yr= zV2jNGzN=)B)*D3e1sexIAo-%cNbXBk=_Zs1;W+ZhA@A0{i;~R`_@DIzuQpHl9_ONQ zhzle%;5cCki*^502QVim`Lmbxnktom;_tck4?o&z*QpfaUOe%12;#n@=psZ2!2={f zj{Qn-itS@S70xe+)~&CibvA0bYv9F_Akqrn6 zia95Fh-VSt*G5|~99>*@36k7k>o&kPC-5HuRHnHmYoGJHJaJ3H(pn zq?i-nciaK{rMQD9lG^{MZT=-5PcIB8fuHXi%`hCwER%w9SAibdxx?NA%=})h1LHLL z=M)jizA?Yg*?VaR8b=U%BH5TA)T72iL68}epp;`mHMg{k*3}Rr63yy7 zvFj{NLC63ABF09gj1>SxYC_-;FxP}p1cCD#=iR02&1989V7$Xb^5Rrb;tkA=i2Q#@ z6DZOICX0a_wJQ6Y+J4oH^epYO^gsWzY}7K@-SY0kWB?uDw{sGJ0xYCIS_>OM3I`qg zUvtehQHM`sjuj5-8}jE~|D1zHr1%T4`=k6h*TCmM(+?O3^Tgc2Xpr{I4;_r{AdOWL z7zM}OeDlp{A<;lnpyzwW$}7ik&IqT584rJ- zYQ!xYUyybU-YQx^#XN98Si)pY2VNjP)$gyV_77L{#Q6)2A#<0oTasgN8}0HVD1+H2X6ph#AL0#V~=BkL`aV%#k#N{G!6__{^VECB-k%S|x*oO*o7 z46~Yry)vyYlb~qYNh>=kjU-3@|b_Q)5)5H4>iB zNO!cP7$rq4xuXNEk-;D0=&l5aL+S#Bn<>@n@_R939862Brq&01se~VFK39D>U!dD6AUrc2UrrFPy<2YP=4L?4hyQgLV+s zY>b#McE)Pf{$z^{>BpaF>oiy1l!7nzSY?_Vq5Zr>mP$CSe4UttRDU0akUgcoDfo;@G_O0Y0;?Ci6}^(aANTt`$4QY%}{v(Iv_*kcTx-Bh~+fE!h5ue zt&+}NIvzq@Z}4B6(n>G3rgVb{|1YHp42ua|p!0s-#PmfsExFmtO}`~Z@j~4rHS&*J z+h80pF2E0H>0yW@c6>byE$Zw$su9hF-_Rl$C-y%KAw2vr0nW?4aZU#yF&E(zfw_3C zKR^xBNzE#d=Df#&3cy2C;aJ9t8AHqh`!Y7pk4At{IiP2ISsIz+IFIzFwHT{k#YKJ3POg2Jf`AD!|{ev@{Ey4tc*BK4v4}_A%ScSeE*j9ln0O z_nYeDo(4l6-#(wa#-DNM0=O0CP+jWFnz-q;(qE$92i2$`nrqYruqIrapy8wdUQymFyYrY(Y!^n?f_Lk;!xaRJa$v!Ief)JU|OZn~+^4jjUSK>!$}C@TP{w9E@mEXIJe z#K{I&cIv#86KZkn-B_G0prIs;NHUy zhuJYlFbXsTn26hX@fpSw&OEM7YOe!|SY=_QAPT5(eHT}al4^|S6|ZGEQ0z?e) zy1yO2L%2BBC}@eA5AeeY2Us{C;KweXB#Agrs_eu1jZwYCbMt`X#@k(Eexc{&UI<9z z_zOwI*Gbb@48ahzWRj*cP;`UO z024{f`acpMPy=}Oqs)2A?&CNZ92x@q#kl}Jpk;ozPn?T(JaS%E0+^FnHDFH6l$mE3 zK{#FCp@_%7(LIQ9z%(Nc;V2oE8s}N^d90Tv13=f9X`Z(EwA=LbB7^a6&(VA{g6UTE zbML^O6nfsuT&6w(fOW*b?N96X!#-xd!T)p$H{M}}vef6csSqX0rXl%#eBl_M`-q=6 zo~%k>o56p^np$}A>(J5@1}8>B1)~lHcIIl+l9r*DD)YU-zByppMC5f-2eb} z6Aw(s64E=%YFgu%$g8EEz(d|2urroyUU0SgN|TGqU#O7zGiQJ>Y3u6purO==l?=&2hn#0Fsnspoe4_S4;Y8>z{^<3U*a9?6j zA2G8%isUxH+lxC0St37S$ea&At(vbg_&2jp3LS1wp~C}a6348KEHNE#Nr^@~JjO*S zeR-LWRlF$9$E=x$V9x37#>DgK&tc!0P4mnEvO4cQ9b#AkQYFU?NI9LxU9zt0T=KpTh}0bKv}uYY|(EBTJviNkDRP7wYvT7e7vGsIw@RFq@4 zf&734#kI^s>ey2Z_+D5NkZKSVia>*r;=TG}E%&0&6vpTcqGO<%VecuV}=l0VvqU1{(?X8%E_wS~DpW_>DL3oRZn zBN$5HpPsoO1X=xF?nmqrfL~;Z)+F8RiA807k=Sv;nRIu+a!$Hh126XQ=%IQT^$k{%Jw# zV{#NEzqAP?|4dzbvkHVx1^fo+X@h?cQrzHgF_2fKO1y2J$4v(EHPD&o@sh~UbLnn_ zdc@|~K5uKySe`P2I4e2wxYiDz^P;4^@(kKj5z>WzmQ6n9Kx$;lv)-OE26vm@!@N$F zxSuch`OA{u*sj#btPdNX4{l|hI8V){1i25{u!-OG_Qw_#jnC7tJ(DUsFR4En{Bu*B zb_d*$>x^|j)Z}!PAf-ygqEd%rT#UP35}a$|k?)f|`?SDdpaWEh8=^*n0bYJXlHcJz6J273bJ=t8eDFo-DVSDAeBvThiTAN zcgObfz>b~edfCtikj_5OkX6+UNF`}B7k%ne<**!Q9po#xz=lh5bAL!_mfRx4@pjes zW3>Y(Cvyr&VT7-G)vEw7_sQx<^gzJjM{p45<#%j)v;!CO457g9%onBuPDbYC0y#A? zGydTp{sBfZ+5y;7lst!7(nK}^e$69*eaN(OU4dTA5Dlzb4ZP)^#}>eE2C?7Z?=b_p z)KdK30KXfDn%O?X=KV%e9g8`>W+%ra@UJl~Z%^&WH=0?@H}hyrCC3l@_#vNTvHb~K zI9BsU-Am?ulD4$WUg^j*aRZT94v!N0q}Atr>b<9H=v6wx4(#{c*6I2!WMc0bJ*opOU3E@Mn@lWF3#sUs8tF(e;<;_HhhXVcP~LEWs)3JQtM}9 z$`Fqrf`nKBI#M0bW}C~czmW3b&_d<6GYw!6I{*lBz!1PfBBByUP|jRw1hlF8s_#34 z{{;sBmee%{!e43c^kXKb*U2`1eBa*kGlBO{1-k!N{9^vlQ0U>Wjp3S2_08rS_U@dfywHWPf2=jT2on;GI=sb>NN)5U!1 zy#FML`r9%GCPT0q*9>e`1Lp79N9TT_RP1(*f4dxPBO2=zG8@IL_yfe;69C4^XAgcb zG_(Z9jt>F#AFT(#Ge^!EM5Exo0XsebK66}TP~segv2=(rZjvVO;QbF2IwE5dar|*H z)Moh`7Hj_7G{+mv@GeV@I$xf;^j>Gb#|;M5atBAX=jh7RpZ_5?3U6wIL^r4`_6m=^`0d0d=kokV}PIwWxHQsdH#yZ|zg6wJArz=ey_nH9DF#(?PZ_gslbpHP)HT?GlQ08_-OrY6LrUMQkzEIbH@2~%Q z`N8k~UO6N%wjMZu?Tu$1@H1`z9xFMR05CXIQJy<$y>s#L(nl#Y_5t+nZ-@gChDe@4 z^h-Rc-**VuTcoXQdFttMin3xY##cbyue75Yd#J$LX>NEIv8Z0kM z!DJT#B!j;LwciqbulGCTdA!^<_RR+WdCA#&6^z$&f2FUt-uuillbFh9gZg-J#G&S6 zo3(%@UuO{vzzk-)aQslzc>C|1jbIn+CH(W z20()W>}T7n0d}j-;pobPNPqlZ8CX`oQ7uv5TS<_~sg|i?YpcQEY4Gn%p^*ov@GG=Z z;1bYM;IculsNV_j69)n1Dk|QeiDF4`K+F2}4mroH6XzF`eYYYae@@%PgJuF3-=}1pXB!j=OCZ zEjIv8BxlkyCdM7Q&WEH4d{NG~V{DnLhDaYzLkGJ#&}ZVmtReG12pqLI zgFo+xYGKD;*!up1@Wa8A7)UG!Qk|rph&tLuqvBX{?Ke?2TQ%zR#O>z#=Aeh1q%+<9 z=je&w+$5&NtqQF1=YE7<7OdGwA^+7mw3tq}ol-xGh@Of+TV=;yDDVHJa^RguCYmJR zog!|Ui0lzTzFh0wfPBZ!oiLy%SIxa&rBYo028Y-Yue*D0LJbCBd{4_TY~Br|9itL@ z4z_E|Z}UpYeI}Bu_OFDPlK1$434KYbad1dX;MXM4UnPg%cXYlr(gfb5@6j%bC1w-q z^%uTSHmX(ETVDIxa!5?$8Qs608O#6^2Tg!@e6$!g7zEl6_ei0UDA|Qmlh1@0!{{&< zIDWpm1$|cmJxG4`YqBQMAYs7!-k#pkVy^a7H|YU0mwm4E)FX4|>)NMH+Q93n#B6Qx zt;yzJXUXrr`;k$3+WYOY*0j#j`$o^xqpiJ zrTB)nI}QHDW;py^n%dr9np)tk^mraf)v+E+8H}4FE+^I8v?Fl*zYuT}#KlyZN5j;X z)?ZIG{UFlHLIM&2i8)EqHvuXVa)u0iSCb9L8Gi$k;PvF8OR~T8E-eBU~Z6*5ej=) z*Q*nQS)z08NlQmZQeDJuOQMccM6%bC=@4^g0MuKhoND#+HqHGJUF$7!?#&Z(T12-Z zv@T1TXMLWFb#Lto1Kv%Pp2oaH_rbGf9^d@tH}f8|2G2bVEDD=w!&eaT9`=s}!y}D& zi8O@k#7H+j{zSpo(%RO_vlsiUmpXUuNJQH8VMAMtmtfE2VbdNs(88?dvq5arimzHDl@nn0K|h2iIq>zC#T231A8w4EP}k z|DIBTy@crHqRJXP;leP82JLj*T-@vYq4v*7;9q1A9I_VB$mH}h_=duTc%>J8{)1qK zAeb@sQen#zV=pRin_wKYnL4gkRRYR;Wquf>bpq4>6abb< zJD4+fE}^}sz(_paBmE=d4~H1`G@xM|E-eONq6Z&6^s##v=rbVRX@Cz|dN9B)gTFcT ztUnxTznfQjex5Q>&GNYxFrNbbf68oG!E&6`@@G>Q9Kio-ZNH*1z5U<*t*jM@R=n|z zG}>g$fS;9tNY;U2A^jOU!8>4WEO-wi80LF=HXw+2rl(c>L&aK7@$9G1C_6Q`_n))4oR*XF*uq6+qqK|@ zvu2lOG1voQLPz!5sMj6y7na*stSmh`<~(Z)+oyDuCNbX!4aV!tG&kD3C_b?b;y3D3@BiIq82#2BE<(`xxlT)Q2dC}xaYgJ=oUvS2{)>OE z^y?KklHf-BSJ+Qevn-w^Bm3v1gKQ4Kv7^gtR{xOz#f-xNB*A5nuneYfEQ25^rnx!5 zzts~w*Q(ku6PdED7IAHx3L|}|ePeX~(W}FX(-_%2{%B8LWs+>{<19neP8i34UXL_2 zMdjBA4XQyun0Es~X)W`Eg#iwWpW1dMY4cT9`#0K8FkQe9U?RtwAH-ab zr@bVWfnaSvs(MA#5qpMg9t zm9sv|z3U#fry`OE0l$f^m@&*WL2WiSU+8)4G4tB0alJ>Hz$7uI6|B!AVbU`kU{g@j zWoqNKLd;;2Kt1H8OBd<@_{8Z`^8h9Wg9r_gjr)fAaepwsmn-6sxq(R#CvZgHU;lyk zm8ny@FyDd+3|s0qLN_DU4Dcll42lWpH-UIW??(nD4KW>tM1wfO00;D#wtCD6Z3wGL zP>0S9vl#B2B1zaPUxetR;%Aj4E||e30UvBe?u!qPQ(OOvP}DqGi=Uu9 z_?WWZem`L>Kwe{~tu?KvV*Nc2K1Cu8vk5>u%w6Z1n1@WzM^cf65rcoW?cW}00L8uV z)oIA>%D8s(bL*vH!f@l?i`6v`)+#vF~2Yf0)^0isNnM#N=YW6hZO=C29bq*qJy`+ z|Gi>c)B^>aB9xTw#47L$bvHlF#(88x5nY_ zw&X=~PRAYONaT@Z+erO7PBFJuP1&V=gvC7_IP`4z_=#Y+IuKPPm5m6*g zicFhjN%f=|!lI~a=jcikZnw{Ozpnc>Ey;aCOzfxZtMPr%1m9pn{Gz}=RhqzLEfM}$ z;9nvepE2t%QiyX96ea@T#}tAg{`ki~E_C`~?g<3KG-6)@i@x-wFBL+Gum9+W%UAyX zAIdQu?`+Z><%T2BOdJ}5&W80}1N-p_6OUGI)dw4ysr=4!<(01}9cLhk!5r2#-fV$$ zLz4VIVm=N2I}QFl+_ic_fSZ-(D&35=*YsS6ZT178ffk8dnjAf3&e^;tqumkYh z1gQ5CBQ+{VQU&bVs(&;KW#0*x!*eul`U{NKC*bFnTH}E~dbIK9rXjU#@z{{c{E9Se zrJ@XyELB)JY_;2JZIof|29yTk0>C~zWZR!}MhGMT<8v*02Vxj^Vr)W;w$j!)+jXv^ zR-N0K3j=71i*)wso^O&m`!}k|f9tKcMoBD~00A@KR{E{%;K&&CiU|Ah8uj@3OiOEs zd^Z6@TrahwI?MOnYrt=!a<9g=IJK>w=53R|Gx(#5Qa^xBEwK;tJ@xmbt^Bnl=x@q# z_i{NkzohTUBK#cB#OJsRJ6jU`XJ7eB`KG|!?tFgT7g`OBkCg#dHZXNq^#Jr}126%! z1T;hD26G5gAnG8nBC>epit_dkf2eeIPvyKk({RiJ)}pO}J`kgApk$8NK?n^D59(FH zF537GO(8aG3HpuKFdz7S1kC_pF(M#KvJM;kmzf5C0=-#O=lK);~pevT#&(y5%S3{UjY$hb_zGhS3 zl(qHPye!zr&2EzAbO|=wmv#D^Dr8j{G2Vjm! ztg8&RD*5fytV{|UYA8Ugm#BEi55Jp-?J=CoL$!0~Yc$)?xh{~Z3((1VXBm+DL&Cf8 z2$_UPKOzSKdt}MsjfDv!QIT%FI%c-(A#SzgpKs^UDXaP?QfPEDfUo3~yEJubVKtOi zS~@(xTw_??@~*m3qW)c;h=QEa+XZ0F1CUnIS!%d@{~#R`DTJOXYc zKF%geensB^%pz6-$f9Il_Q3~0DlyJLVhZS0@Smz;JZ0vL^0p6uI5B~S=wOqx)d=!# zgP{t%tb^kVpg$bG0{jGOvdAXD18_SLVFbJqfoevpi~nAl&H>r)w<@ynpp%~L|0`k4zv$WV3-5`1f2nDDb$W6n5|O`c$1FfIWIH#yHVi{{sREn zO!yv4>d6kH0C+%$zh05RUkv08Fk&Bb+P__4Aj4$l`Sa~OBbx_1QU+s#ue*|s_qz8% zVjtY#w(7xGY=C?tb+xe<$8daZgo8%vaPEpJ0J3vKjSTMUMF^s)or+imf4C)y{L+O{ z=V+bM;oWWr+q!ttK0 zVG#`gc&{ZuugBNq*SnAkQh66kvJ(~OYCv#fBs%Ia!9dvkm;x{W(rc0Uv0MuHU3!Zs zK#nC)CHmLxGow2X@F(WjjzmU!F(;m%=2XkR$Hxqra2Ff=dkp>_jqSu-NpE}WVfHO@ zsy?e{@yGJXJS$1PSAk&cGu5-R@O_(Z( z4gT}&E4aa+eGPsX)9sr~qc@t7oNdN3-ypw@-_0bp`?!~zf#2?PFZXJ}anS^3vT54F zEHOSaLeq9lE!{Y9G2BTZ*u7O&0$>?9Osq}e;AlvuV1|j1$4wcQtp!rNq^Mi`& zI+EHbJ)OY+ls(|*Bvp8s9a~2Q93(Xa?CQQ%^?qdh@?ge$+{2l|razYm>*nG56fO4R zcAF?x*bJe+{#^=gG2j6+k{(+Z?>|W}sJ&bRjvHaZI0pH{RN#H99yCj1UD^-u?@rZZ zkQ93j@V1mLI@wO5_LNr2z7TYO3MT3@p>=9*_R)y+thrt`gags_-*fUj3Aq zz;f;PMk@O%3=+ooYQ+@599;%2 zItIZ&Fc&zM<|E55IKRCA^Pf|k59=;^PG|w-pwu@OG=U}&u}jxSigCp@_N!?%9K!ez z24V1oAB(BHMLrD7r|&15|8|4_4W7e$4bTpNY&yNz&c6mb2D93Kf_XC77s6PqIbLIP z;5g^D*7m3wOC!If48~i`d}k507xDiY=*H%RQGp0WN5xu;AH)X&@_fdqb=^ic z3$@pX@lKq!oZnlEiR!{GE;@{4=Dn}|_c&}U318?=JZEY0wn+*ulEg&iN3{nC0Gy?- ze^%>mImsY)?BA#y>}CwHWXR_u+K=R@g?hg;wMXyeUQsUUf_QWe%Bo#dqn3S6 zE8S=(>M)&jBw0t$LaY^`LJqK|ZdJJfO+a({W$FUbpc5^{bN*3n|6pIpB?A9PRqJrM z0Q`XNYx7UpO`N+As9uh zl2C^H*`8zNO&|JTnNHIWo{gK+q6we{)Vm$l7*noR73xa)xd%HI+E;!<6yB zBn3~1c(-``20AqmIkzxeQP{kG|8f~#<7n2ni#AwMMo^+1y zmfC$1iI%{>+ft#;K%Q>~xycM+krRfF*b{x)#I+&?5X~?#9-cheo^S5Ar0UIRC31}E zwE;Cz4B{DuLw{7`+vav>|4YYz)#F-dM!Z0Py;ODk77EM*+J}(eFMjch1o|M^QTNFK zz$74GC{n1k5l0Y3Noh`khQNNz2O7g~{nl@l!wS@S@8>>KX3mBQ6xy~4_}Hyz0u?6U zlGrr`R7EOwXuKCoWBI1l{+Aj22MqpQw)tOW@c+=y;bNNrP5fpJY>OrTsigMvT)ykq zml)u^)*hcmy*I;X;Cw#sxn>d_KF34ULuhM9N++Q;VH9BAf>%uGnhG8&^bhuu@Q(NO zQ$>h8kSxJ7a3}bya3&L(+ip8M&m(Ja+`s^tb&`bVq;>3$1pbpqz$6XXuh~+r>3A=M zfNjG#z0TeYbD3~_zUfNOz@Q&ViJekS|5COp68Q=P>q{^JtKTrmg|c}S`yPcoND-zN zKN6qFKPDNqmULj4AfMef4A2Mone&6xyzlRiD6?G#Tq{5}@D?TTui-rjE)@0v{3)k= zY6=Wm!F&4m%hyszjJ>-c1AO8p@R2}dLqynN7O=dkaNPqv$ICBC0^KD|V1YpUxAszh zF=e++rA~rUiJw-O@ZN(5i3x~AAQ%Vt`8^fxyy1o$qPeOIf-*nshZYd=BhUvyROA=1 zI&g=U6W{QG_m>%B0`-m3P*DG20*z(@yh2yDUu${6{TIn%XUJL5^WGr_(`>K4ZT>9z zL+$^u!N1yG{0#oBUKKiFwf!nH=eyhR%P+Ca>{A&&VpIc+Q)|%eqTK{j- zd<}WUf|ZZTs$8`UUKYkkdU7t1{6X_RwhDZQ*4G36Tori0%T??+jyhdAd2Z0@oPbK_ z5*xoJzgWuDyQwr_h3h^0{<&`Cp5KUsxvG7!Wt8X9b=UK!`O>5$eQOeA;| z=4j%-Ce`-uH8I~eA>8aW^55s7N-Nr_RNtRTf?@NL_WN&2qyg+C!Lam&T1>FaSG0yM zlK|p}=y8DYebf;+ruP6~In6du{WOmAJQt6qh9DbK7n@y{SSu*FY2sRyy3kJde8IrB zOA0hJ=}3Xz(O3YV)NEqp@t8wkqh-<10CoTLD0oH;_V<-x_olh?$~$G^OtmBIFAbL0 z$?x%R^7h~I{qL8DRVoa79$>p>0GW|24Kgoi2b4$$*f0i`O_>Ao3Q#?xM;6`uR=dQLC43D97*{Xx(7YoSp~{>!bQecP`uwW-i!@IPfU^7TH?4-@z~cf0)r z_uKJ2U$oQU6|U6%x|Wucg)Q?DS(tox0*nwP>7{c2RhfX%TaWtY9rKANj6;T|(k~p3 zYVQj?x6eTC-Op8E07C-7CWCsZCD}>aTt`jp%M$o!n!pdDP9HmpH{Z*XT+_i3wZT7* zQ!{L%xTEbN$i0$4&j_#-3Hi7ma*GM(Cz5!8`WNzuW6z`FW77j@RD4umGy~VW$0Hs- z00^H~_T@bs`YiJ1>6$|@i3#vw1Aj4~PLh9nYGeTuc+662YILzlOjP$v;txw-xYnx<`NE4mIqlb^s+NF5e+}-yYT5xe|of`spkJ}$|9Vh z@9WSeY5lJA5GB`uMxf83<|fUKEq_1ED`3+uS6XUkhu>WZ{6F%XUgY&RztCg}l3!p@M_%y}Idj&^PSj^#4# zKT?`Vla_|CTjt3Z0Q-OYr7}y+MOI2WUm-@oO2Clr2Wd?%1LhBT53C5F?Eqx%owxwU z2e2fFkAV09d?w5tS`mzr{Ucl$p8(8*`9q6n?wnlS@rjQsPGAN|0Qj`0M|EX&AfiG2 zoU7)5Lx~}DvORBuc^dqCF>4I|$w+6@-&(8vlMMLvfIkKK+-mU8PfLBM@W1d%)!Qtv z9svA)9zXDNyuinF8vOSmSbXkh3HO%f#S*5Ms$8u%;moEh%+T$@BhMdAE|u-e3?X;? zt_XRq)zGbiAmw@faT0T-$O3}{IjXMK{*@}h!)HeA_HNw_J^7EOPAcxq>ek6A>MbR^ z^awbjDml1_;=`Hc`h=+r8L!##=WF}DwHFi58EsVPIVKyiU0nEF+4;>P@QpOLl+Avd zRYlr!&sEMm$v{-J!Knoiv$6E&YPs~t$2S0R^KilpfDs^t0Y8mFj_Ug>wW`oAyZSyr zTvr!msv*Ej%m5Dneyg638|<^RuhW3b3NwWvAM=pLc|y)4Q3au|NP00~GXOLn&6l$^ zQ$!^5rS}BU=%+q01sHXY=HS&=t}EE}4@twJs3#6SRzP5cXh3e04%lG~+%GEwga>0D z@tIzKBuil$;yVHKe9s(4<4~4S39IJ3_yveATtQT&n8sEy*HfoY!t5C*_+Y5jPB&5e z(L4cwh%P75^FY_WUURUMf*`i}+YVGTICs6UX__Stel(#$<0Y&ffmFeEd8RuReT<>iO)wkc-)UP-MM5h>-! z&f{Up#-F6fwdINgoThbuq(8PV!7#)D00a_)&0`mIK8Bh*^??}We>=iJMtjDjgH`|h|7 zXPg0kTBhrD$V`C8(+?9kb)xK4-+_0$>z!qjBt3;sxmT7rVR+mRsyq(BSHALPU#&v(F?NV(Q;ZxGqq3xAqBWl~L?RDA?YkN%FNyR`63AC)*v`EVtM#v>6 zV2TTHscpRlBH;d^!c}qgls?qs5<>1c!S?+W3^Q>Dkww@q24R$ z)sM%W>NpOOJtD%nM?|{$kw*Y8z=v?7PznqHa63W}^%!*@Nr%mgNf4ER(E{*jZ`AQf z^o0iXOkH!8ncjYg%;4Vuk)}L!=4ZLTAA~qPH+Rodxo_?dpj$K28{WIcx`SlmIl%xi z3&<ohkUVSe~M>LWr2oQM5*g^}P~C94nyfyuzi2^z+`Kl_>TrN8{Ea!BW?*LAeS!E@C- zQrNP@%7QyTMm6Y3q+BcBVUxx&*=m1B0{g~&_fp>&n}2SS{8!kY(5v%bFW_!A z-M+*0`a?gvbNzm{{RDTTO|YMz?wbn6~x(2E!ZIJ9ZI_}60@1fZwlHZd!JGEY_Goe3| zda^T72kFqGno>nNa2DfYjaXJ9eO!j_xO${Tw;^u9DQ_ z5uB77zg^C)eyQ>hq3@MEc?g-$p&BCzk&+wSV^GY6eP9%$Qd9fv)%R7?Bn?PyzRBt%+!-y1d*yRv0s>}KP&Pt@VR(SwQVC}uz7k9#0;qU} z*rRqG<`i=Wvw)GpSULY$3+9(4(gt?Aq&VgP0>CReUWJM>TDE-~M!P#x;kvD(TqZ`q zDhi(a^OEFm%#t7Q8>lxWwI3kQH~4S#oWC}$^P|q!b3UJUCC?i!;^K0{K!k5b@h0n|dE?g8^vS=lflSBmoRjWL^nUIBm2nt)MVXMzNu^k>f_Tg5{; zZhQdW@PedfxdX0zQUtp+sr|FfVK=3W!My<98bW{S$zFf(Kxt`fWhDUcMc=bh$^NUh zHS@j37+DJ3w|`$@84AxeM1G;9PrameF9gVP56%`btI6%{5G%Rx*t5|ypFVfQx3d}m zQA50J?!L>uQ5=+OOx5?Z+u9&Hz#k1kjysaM0`pWuxeRLfSZo+1@r8dK`=TRGynrA|i z2Z0`^Q6D|Qi&Ax)RhInEnp+RpBfh}FGCh(wNK%TGazYc>M0M1%3RM{+(hJWuL`me@ zGg=mWQbf8z*SMVrFCsi8byQhxkqwAs$KFLPcMwJI66Oev>XgS0{0C<)M|627D z04t^s^T2YbO$C6@cSv}cEKWuID7+QrPz%#&I$hX$A z{b-CpOY?Kpe&c!)xf|qMR2*g#Civv#K0A_Ym*3)jWoxjP9&SlEYM&&_)@jqCjnd=3 z=6MGH!36%TW)M?sBX?3INJQ4s+RSL|`QblqyvZth#53eE)${>$SarpL$3~zENjpcy z7$Bw=JojP(a9qyKvfnqp@eTGxQblhBK!zQQ^mAJ<9A^Q32pt=Ek4%fndhnM)e7@gx zHp3sI-n=EmoeBI9+-Vc%QSF0|Vm}>v2qC3;3tAS>0+0WYoq%4UDKG@*eZ<{EbUAs3 zk6tOz2~bBVwlP|~ljk6xz#%ckpQu^qT7j1U9<&@@(Q*JP_ssnPWcvr$2LNLZFn>7u z*dGZE!v*j#k*FfXGs0A2>6CM#1#k|EkP=G#@Wv<0Yv22Bsw#~>Urbmp5f*JQ0se?_ zC@wY5QYVaHnV0(NGx)9c_X6^?&i`G%u1nx&zb#%Rc(t|HAN%>NG9&0n;75afQ}X5T z{Y>gh=$UPrqneV$vVa|Ebx7MFOn9V%qjB4RL+8mHNWZz-dX4^`Zj1wN;)v%BeuFAi zEoI9bDZj5a>acUBLFehi(=JYrUHhbeJ3mFe0sejf?b`p)Oqs#yjJKTV|V3a}qzEmy?)1Len)_(Bs5!d+2YA@pPe zqpanFwa>02&T$KpU@)&?FYa%R_wj#)nuvF%z-#iDQS@Mv1bSC`2)|eVX@g zed){PfBujEQIOsQNOAv^NBENG=a!8WbTV3+nZHhY}$vbI0@!{Ijb;)TCCNY8TEPRR;VU(c+XVK1*0b*ueLOBLN>*}2}v#2P@XhVWM_5C|qd?DXhN|ISb)Gna61IRR_O0r=!q$)Eqi zqwWjj#sk@b5q<^$X}m}b0WK18f19vN zNxB)*6o_o|Iyh2|S5#t-h1em|s1%$#1F@k6V5`p4xlbvk{+NIP(VYb3R!_S%CI}10 z_+m51Ge{VH|A@wV*X%i^Q8xcbOPk7I_gM>zw(WqHSJcTwOkVA&)XH{frc1_ssdDquuBZ#Rgz3I;Ore8l*U3rg-y#c72qfI z)kQE^yJkHbwLg-E*av4I1kAk6mAZSF#2SKuQ0q-tmlWIl8qZuuncXKMx?L50b|^mo z2fE(o#Y@U$q{k3({W60B{G*|r27i==w#UB${!{=aeRd^h)W*;X3Mr#Jw^5av4pG_{ z335Q*{9pXwhvl`eel-<>koIBf;3P%0$Lr4=;N1u0Fh^AR52*q%QlB|wPGA%S5200I z>oZg)qQT*sA$I zU*mm|#{Q7O|0W0G{46E*0RH)2w)=Tx_1WQP>E7XGz$?tKZ{s_iw^wxW+e*RyqP9(P zaQ}xG^*vL&M@ya!i)kVpki7IU!0vZlLn2Uz`$mCZ?5v%z*{yL`bG5Fn+7p9)YL~}z zYcQAi&QU|r`PE*;#8#>&uJ<5NyDF)-)e>P*od>|8u6774r{zpLWNv!eQg5kk{znt| zH(4_{*D4nE_1i=Y4tI^~GU^oX%oyL4ALg zw3BP(yjmylH-G9=r5(xN+KTjo*pYY;X4Gnf*l~v01J1m{P@Ug zLBJSTLWOA}y#xHH{5%7sJo5`9;kY*_NQ-%9eEiO_Fa^wlxeFJR#dA+NON zM%pLIpTQ5;?z3;;VCtuLO4n2kNC)eHK$_Dpi#f|ODjN{J$T>!irQOIkmvxMIUxd& z&)=2PkktV|OJI<-gIFzL6@__6-RF0hBus>TaLm3@A=s=KaGakHTWBvZ>q}qs!m@PL zxkL;~tCT_Ie0s7XXDnS@Ui8wJl&^A11LK8np9nQ1kMy9TE^S zX?DwWy`q>+4(o%aM;84ny<8}&?5&M*KBQRCK3+y4+l_X>|EDNChVW{7jSN2 z+eb4`)KpB1RRU}SOvX!k5G?Edt^&+^z#ozdRhRZy#LV-V{apud6#O&GJ^L{Kmh2PO+?=>!=)_gL z!0jnB(t4j5t{>fgt4_a(D+5JVlD6lef)JeH8ycb1_Nc>5hde35xyYb@*tzbGdUM$< z)P5)Da6G@+TiYb*Lgg23>U3W}&L1=kt~YifVikjBGXD?+h{QsD-787aBVwB&VDmRw zgiXiWB_bd<`@rK5fkU83DCUoq1V9f1i9T%tM1UVH13>H+5wFp`Pba24E%jmg+$935 z(|$0Ra>ftI(xbq@T>g594d9EQQjEVV=2pNT(%(J;o^>UI(^5v8H3t}9I2Cm*uMV(e zm6-shz!9y{|NgK2hKf>*CIm@xvs6mCa8_1$Wim#MkK9*(CEoXPSpDX=`89_OzbuTxql4mxTX`n9p%NyKS=VACR_pL{gr` zR_1;Z<{joGj2X?0XXUnLMH}EQJb%8&6R&4J+;6*IpV>x+ZS&iAlaqfk$o(uP5X8a2 zYyMtAbJCvby#r*x!>z{nPpnSFQd`mlCd?toPNrd0ReSD_t7}c099>fk{w{OnCk_6K z68O*My7mXm_tML05#OLDw7s=0*EFn5oF@tCZxd%!HAW4E2m$Eh3U1j!n{YjtTLe^c z0g%=$8na{IIS;lzQVIuOG)Zwl6a*VyZwMYc7bb&NuwRU2zKFP`y**k+U1W{t00}bc zd`prNDnF786%t|zmC;LcmKa{^b)Xd+AG5?y(VBU+hBz?_KQh4>SGqQ6)f#Bf zxo;Cwh6y|=GwaW0&MrUJ_NW|p|E}$RN&YjGBcs8HwtDhc2+?KE`OX06ec?S)zTe>I z8RJy`cpVpuxkV4fNgOwDYXqKW>NL#RmT#I|=K}7#7-Q-sm;i&K=va z=c8amJsbDuNf01Yc%*GBGe3xxJalYN_M0Rr+#=QVR`T~@0FoHrR+Qh}stOG85&HWd zN{(Tvi}#oS4fZX-4A}T=0tfsMY~;ST>HM_oV*Hn-G~m5b`%e=WkLu6(cqRfJ1c$Q- z;(;-oaUl;E`H1Ej!N8LgiFWVi{5eQUf2hhVkye&;{g>ke%mf@;07Du?f{jKDwpbI` zr$C>deee6_H-G&%aNM!p4`T()QBn0 zGE&fHN0;bWPR4nsSN9(bwSKs7U=;WU|HyzPJHST8*ET%B_b}_x5f7XxXP7GS#*@NoWI3MrRMlB7kdca%NP9wCtJ+^3nCja zQ(#D`f=(=pj#vQr`y3;{HfAM<>+p_OM-8A&QRPSD#0)r~CE8bLiI5U#EZ+fGLWh}q zBtBr}J4`N20qlR<`uxtk;qj-rC@I8z&ojad2#u!Sj8e=c8nSRs3bn$_Kc)mG`~xr{ zOg5ZfJH#lu^t?Ld%>C)U{bh(458AomVC6OX4va2a+mQzY<`oSrq9pxXYz~PL^SxJQ zpu6H4jC^)>W=MJ`Vdb3v3}AkL9^kL3X;->^RqA4b0U~C*CN=*$U(~YuO$-_QmF_yv zt4Entacyy<4n_5P{OETC2DRt`?ZYEXYOS4p+im}|FN|T4!T*>m=K#=c_T0{uq#l-s zeHhz#^dWdD3owOU6)^xP?QO~xKcaeg*N6z0YALHD z>)a4xNEnv7kZ$^eAt3pQW{ZX(_y7Pu1iVWUa*EX0%f&<|?*01AB(pHy6{%Ha?#-o+>7Q1!hVH`mZ_uylh)@pZf8@Z*#F93a!|$6;c!ko(ps(K*x~#GDgd$CYX5ed01cM>XQTF~f}$%OO55wD!zN93 zkD~fIyQYjT_3;o2?3=P%0Lh%bpT)h5L^Hb!en2Fo$rxqbEG9aNMML_)W0SVb1z}TXfBKqB4Uip z4^d*MqQ+TC$yyowCa}tLFcCOH@f72#dXf{fuVE|Z{QyX0c-kkxt0f~KQ6L#vgyarL zv-;0}{3o&rxo_qU8$L>av78FvnKR}IW=bpo(i^*|`g4Uiy};^Y zoFBq5W(uJRG)Sv+^xLCa9hs|~{_`|%`OozO(3nv3(V74$+EOeB0&qgJ0XX3I@@mvu zbW3*jiw?%jGfacu@C`t>?|ILAV(IaaRR1PcM)2SZ%#0Oni(;n@W^#l5r_I<#C41o& zU)hkgGDk>yIXeoju!Z&n9^9QLYtepo(aduwmGW+=YS>A5mZ$>kwB8C1{hTb}qiSx= zrNjD(8W1?B2ZHB>k?rQvPF1xZt}+4mlMR`E$0m2gxl;hL9CI+mD-74+e-Lvz zp|P!yL+Xuc3c6U5h$uIRY0K8Fym~cEAT%)|6miPzKSI z^4<^jod)>Q0;J*C@yfjN%BByaTd48FRe<@qINLt%U(cZSeGUgc<~cYmS0kAd9T;y zn;jw6;ITd})v`s6GS{hQ04oiXMR?08kg3<(M6|5yPm^7_5K}CVs({d;ltH;{fCL@*5feub!m{W-=J_gU$q&`~wy5aJCOC zfhU$873ohRP`-wV)$TuQ3ohK57hsvg{xedE6`!$Qz&=MyaOX;!;yOQ&#-*h~G5`TN zv<7oPy3;d&oB`B+K1ZKLv?_qjd~ytGKlhK?f1!L0tL3YiDrPW?9)$XxqM$e;AC<%Q z94!Z4tMjhE=iZ2{EX=o5{vklm@*H!Ioo|0jIPN^hsS?ll(RO2j?0u8XpB=Fk20un4 zt5o%|=2r>fjOrC5LKVG7}Ixnp~pq|A3{AmB*1PV3E>adnNHlkX*IV75-t?Z=dAQ%7Yv zSzj!N>v6LD4vv-!Yj10ZA#+ar1b`gB3V@fyKUz@L=?KLizYze%A1f+NO`{>sn0qrP zD?D5Kk!W>-)ge8LBIf!ynS>hKG2Qtd9si_Ek|Eac1$1oudR`^zc|UBYU%lsOINR}+ z82xJhK0l+Rl~tKS2BJBC&3F~pX{fojj|6v{^of?~E5|10UYh}!K&pBEW(pnvYo$zl zoY=$^QlbL>@uQXOpBt^{LKI)WD6UHZ8r_QPZl)!-0lyKo-;Tk<2LDQf|53-(FEAr$ z!G;%s99ngLIVPK%0wfw?ftW}Vnba_;u>8o_S$&w)f~nJBhoK~`lS!JiTs0zMo$Teh z{dNw{cAj`W0EgM6{`^zCf&uu?_qe+pQTS5@nj8{g3e>2afHc6*17~~#sQ-HJ&n)3Z zg<*i`T#c|r4aQ3UH_lyyImhpg42;iyj+{4ve*%e@{RP;w&9s_t(8?u=WcFTjPFlo^ zu|ukK{B73#K)@rRMKD&^a^SNUi^9oSy>NOz3KaSV9NoL8%wm}_G!B+o zo8@D|FVV`FQ2A*=ZuMTazKe1U2S7c?dA01ZkJT>D6Z2}@|M{-|CvfvkCC)x3#>cyn$97x1I-{DhmziyX7z`qVgnBJEfKrvyLj)Ozk)k zDHGC6_%ma{w(G;=D``wPCtw746q=CQzEJPyxI|gIeGtb}W+H^W)68hL$2ODScyESr zK!qTFM#7N@u#P|z6TZP8vHV_34o%BtoSexxIyYv@ky&Y9#(4D*$8YE6V=|FswGxG% z@6h%pT6eZa;VMLcA3HNN6^7T1$NhPJdbXeZ2gg%m89ww&|-Xp-XSO+Dx?$Szec(fLQ!{wj(1-jZ8iVm52!- znOMso?Z`7*Huh;3SsbwxruYJ(oLjUlb)e8L19YA4;}jiN{~v2-p(HoMBI8tK>rQ)O<&djOCAgAq5}j0- zO)=uI#b-(@4JI)41ek%#+W3%K8k5GM;+6=Vy&Nj#hiDbAQH^*Ptz?f-NUtIm^m|HY&aRasb>BV8guZ9;bd0Vjt1ECnP|n`z%YQW@-_GAATB~m z^I+H~Z(Q$QBtkR?%=2%;?AUtv5ypjYhdhhPphjm*e{!I9^L^2jMKi0w(MdZte}LQn z*zSe+D?{!xV&KeKg>HqoUvTAG`i$N|{=zZL$AhsoJ51bod}H;CTERLWLhf>}N1Tp3r_U zqm8()|BCBgiR!*3#a-t;niM@4A^aH`eh@zroqgO9ggQB?PS=*?=Qw+>_Ux-&s`Ep9 zo=eW^6Pg%yRV;8ZWpYLhcR$cSOFALL=_6Ah02J4*U+X?sC=Ofv&&ddU5k#FGNn{A}6C==n zAW29QNRLmO(Q|)xFD$FxKFYBzsVrW-a_)r40)We z@VNK)ks4=6drxOqmP3@eHQP0N~-e|grf;XRdEpMyf7Nqf)~-S>T|6QL4OwY+2SOf z>u(qVJ{WBu@&Tmrb&HHz;m!_i%X|$@hdWNf>HuEM^c#UjPi!h4!W8Dnz`zJ5H)LjoXakfME6gQT551o9k~UekKZM&SyB4m+<~C>$B+^1Nu9j6IH8h>k(92!BiCfn|=OS z_rnog_)uMYUV3GS_QbPXLQS54#?uczi1>sFRP}$KIXqHtaX^z7AD0MSW6lmq6q3m~ zSL5($KkLtx6Be~*g)jpPD+1|yiEj=zFa?(ebRze~0FI_42|>)GT1(K1a}w3g5c7)BPyZ&jzlO?#YtO3lp&$J{~BiWHE0{h6b%RviSuD|F2}evel2^NXmcEW z6p_&2bl46e&uU1qm>><}hqxO~B2u;ovko=d7wph_?7Vjetw(f*3B|T58EXt2|Bf*a z-ZA+O6C9iqzUvwErt;Tycs_Ha_QXqEb)1lYk00&6;e+?P+i~w7zVVird=P)&Lx|X7 zKO{enKXCY{qQs9i?yQ>>)Sc#n#P?@Nf8{DT7e?{c+Y_)nY`2`tKkY|^$oK)p|k=*gr^&8zc#{~Fe2>n}4?f)hu z|35(dkI|XsxTH1O!s(5`9*7CDdHReRlnjY06TmUBvw0vxM_oZEMg01Q0?cAVT165+ zz4{>jzro{tPEgQKJ~iA2rPdI??ptah%qS9Uct<&&~l7Tg}tER-AmS#C6!AA@XXJAdDn-}w~ z_~USxC(dPK8BNN=7pKpG0k~T4DWEOJP`9)fclyEU$^*^>2kh1bkEJ}TiV7%y`-#W9 zc_eo9fN6e!7yeshs$h%14q^T!&cd%jYTv>{9zd@0say=-L~fsFTHpWIZtPGf|4| zSCdi5Lr0=7NC~e4sPBF(P1ye~*CJXZ&2JbR4$!II>9V9bT23}FA?|N>fAEV~@i}SR z-moqG0P+>+{NcQNT+y0y&x9(iUX1s|WVA2XdzA0Sb6@Jw`bc-jiB>%E;A1fMN{~)e z%e3e+^;_GMwm{p~Dz$%6i^J?WlmknDP!lk7vkpsIkLnQ68sF}|5lUy zuR{EPU5I~(5S)ie{Per;bWemdS&xjv$rR^id=CFG323lzKPKS6#{*sL*h5c#i2sN1 zK?p-Ga(N}+$nYb~1o7{ohV~{Qi;X^S+IL>yQ_O+1`9}aEsFK9n&4lG@R(k4V8^f0? zDA2&lrId?e9f79~aAebAjxED%_O`Q5zJmwgCuzk0`JAG`&`N8-IEcCN`P!jw>)vLR zU*7_fYk=Sy?0u>HL|anz4`x{J&j@PbOxn?vN}~=QNG5MN!z3&xQ&yRd`ny1SVP<)y zZFZbW&%S<}=5LO|<;<(5B7@q!8sINl5Juzyppvh`!N~3_9G(Z^6Uii1-e|QAJ?3nK zDj_Skub6<|RAf2UIC}60L?+z@AqvOCeAD{ry#ew6xe>pJ{T3miixx&))^U+FHjDWD zUNqU*BvGgn6M#I$1a^gb9R7!|iG1`I1TJZk|1a?gd@rHF{~O6ZyJ4nu0Fulyu?OT{ z5Ps6ss48A;uc|2OqNM}d@3kFzks1XTz$VV}bU+9SVjU(a4k{*-OBIf_aaeIu{H3s9 zmL5}dLLu2sc7>XwZCRhjVKrDR{^mQ;0!%8co~R>5Kuje@CdX-9dz;(~{sL-0?475mQc?!WuQ z%VxH2u@h#jVIq8BJP(0j=QQxj<)dQQAcE3FOQdJ#y zv3l68z{i#nhpt+aSNM56pZ8IY&wB6)W*6$Z2$#^5@9%c*sJc&{zUGl9l*P83ydL8= zRojYX8i=^uV1}#Nk76?NHrPgsD6}vTeF*=7NIiNVtc=N>n+~D^BeU)JTl`$!7`NEq zI3BA5*O@Gl0%-wDT*Kc93?Nae-C^ij2Ig3hMMa-j?A;tkr5*#4sb&_E2%>MHGXn_?vp_1l>MmvumfoUT$(5H; zX=fJVM7wY%1Hr^9CDEpDjk$)^++-{vXl>+)0zNY&5kdToP-t=b6`uy0gFCTn zKff9+siz<5sp;=d&sUP2L?F&n$K=HC?}|v9R*TN0`Cts7BrTL=pi*)g{|cwci#cFL z4Ik-CllZGQn$%K#CGkkodV47dDpdGy4yT|9`KYP=cffwX2=RXllK(GA40;h$VM-Wr zCC+jA^r>zd`QkggHKAoN8S1N2eT1l*`Rma2LbUk4$CqrxX#gd5r1>?l+sb< zT%tkaUON5u0Pu7W2R<`tYB|-zepE8WuHN^(NPd236I9<7$6;^B!N`kLnV2VgEUg#@ zhZbPH?fX=J-P!r&aVR|;YQzuNEC+fvVexB}>PgqGTocZ$ybyMnI0x$9TgOd~%%b)% z3Ys%Dfza>;6|G>+@E?sS>&o6-RO_T%xZ;Mvwd>$?;vtPy9M(9rg+)qa0mn-5ERSNF zWyaZ1qdh~VTUF`s-AE6PQ~l4V8Gk~AY{dT^M*QDIi0;qmGV~IRU=;`A-$Km)BLF0y zi!3rVmspM@D2-LcL-HKo2x9m@0SopJ&O|5vU2q7FhNOp>u@f`DJyV@&ypc&qFxQll zvd^;6%Irn&;SZyAV%K*MDUOGd3^qK^OIoeNhaq_uiQOE-*vG{atrA`m$p(+Jd)CPo z)%CtS@w;%qW_Kb$V942*op$Cq_A$mJEzESl|*mpD4@0+oNp zv4ZptZY(^#co?gJCUj*``-|lNbEN(&5dVty!!K}wzi;Z)ktKL6CjMqrkLlb?OsZ{} z9jDH8Z$=)0LVW*(383YVVLtamLR^T{-}#_A1C6yT$6A^6AhQlR2#euAkLT+p^9<+J z=|>%hIqK>J;ye!+!gagAspSyuF#3 zjA(~|%+Mb)u1A7Zyc<{5E09esmv-#{#+VIOvcBHO%5_GnPuhNcZdujafT^8pAaKAkfa>1RN1jfs%kbFz}fXE4=T;ar&y?GI%XF3GQ_NzUZS z^SF8>N7F`BeBF%Sel9WvKP4p>n?Ke5m(T)MU=05bqxf#LhQDQ>uML#oOS5p?sq3$_ z8yMhjXdf41+ghZWes_G|}1Mv4T&O2c$sKk}fl|0}>E3IU}_jR$L^&lypu) zX9hSjcRx|S3!hC3>f#Q0=mndsPaHEF2!$d#eyLQdao*b1)Q|0LE%<@hqSVX}oo{JM zDOKlC+_=&_@7%r}RbNkazYzp@O%mDEei7#jWbQ3n-~IEb@V9UVehm?X-%zM9DhPk! zzy6~;6LknjL#jU{Fh-%##`176&&>-sr3ROth*; zq&W&rGwR)s;U(Od0H}958B(f*@5IqHtT9jI)Fxb&zH@BbV)f+rMxh;jZ$6an4eksUwu?vvy>94fPbEK|Ce z2i_+>Ww@C7bNeZM&QP)SZ_q?>1FkccswtOii#p&fZb`DcrFe5lL&BZ#6+fv=v z*5X-jsJnU|&L9USRB`qyaXMgXmG-GF=eCl9TVeBSII*{!e@p%;LbA?@cJB?3{B+6i za?x*=R8sS8@BtJ@k)OoUcMI{eEK}U$6QUA-4KH>rytF=5&H_X^H^?Y`%Db+~CZB+u zWP+l;6R_atH=`spB-J@1{%^rAa2`kA9h`<=2l4+INj`58>buJ^4~NQsA+($2DDc^f z=OJ9cJ~V?nK_HVzD?UuE!KX2x_hX+Ol`(J1A=qIC47l+Y2QQN|ewY0`;38V1RefKJ z90mL-X(Gr>OO1dB;^qLL4|13$gCGu^OaNjU1HM4Y7x0PV%g}fxMj#F1ZxX!wf(Rj| zufd5D1R^H_JI`RkR(ro_Qdy`)Xt1j8dQO&DWsbP2w(EP%j%|T+wnCm>l+-$o_s?o{ zH7Q`Q)i03@fE^XPuSg>O7gRhk0gQl~;R=^1wv=tIQ8-AcbLKrV*mzOF1SXwS?oHL% zha^4|D(fAE3yB0c@!wV&FX_Cet+3}U@(Fg)5Z=L8@NhjZ}4g8BFG~vMw zll-Ug;y;EI|7(cwqo05o7q7U^ut? zxK88)>;&WSdVDQX)5f~Jda{QO^B1h*7FSW3+{J|GDmHyGNSKgodu`%x#I+ltvsg>% zcs)-RrznEKxk?2a^U?(Y*PEeHbv&=EDVUF=>n>sD215=_>+sN9kT`h~qdy<7;pg3$ zs_M1WU{}qvl^C6Ay5IUuir}8Ay?wd3S12B@hxU_E)FRC#f zf5KGhBx@~RdFk)2jX_|ENQAi#c%AeqEV)Fq->lh8d0t|O(~?EVxvOR=ts%!L$uDQ7 z7~+bB#H3~EdSv=}w81l5#drpoF2aKQ5n3HfdvUXewRr!%sK+A?wLr@nyjJ9*1ZYVU zfHYrsRJi>z8lN0rN{)I>w&-JNAz%e=08zWM^|;?pdnnE@Q^~8dPsvGHj8&vJ-xWd>Q;<0^H^QPNp602eVEMTk zlKi2Kh12bG-Uik`bqjmG<&?u5SopQu@?ZVBw&uq7D zMCxTc++oG4hN0Yp^f23lF(RqNA|{~o3Kix~qzwN@jOB;JmY3xJeI)-^yUkB@;3L%j z-Pr$E&YTUq|IzMBeEw}n{1ajO|9EhInGH8$9KS5U(C`gh4<;~uXidN+sO>x11$oTT z#@x2p;sS>@0pwh_mB7FOMF@!?7J zCp8Pu1gW&r1i~kvOulFWdPz0Ww{B+B4w(aj5I+$Py}ya|ZzJ5d91`PF;P?MclpSwG zmZ7wOn?caq!f<>1iEcXpN>y9_HDnQ9iLw1y)Cs7v{r2f#FND!{wzh@*BhEbdDaII} zFV<(lz3`P7s`;RBA1Z5c__4H{w3rGRV;{>6&~Gj*8ekb5XN5|6Kc@0B{+7pkq~;+d zC&aU_?aMW|*J66wy_rYf6Q9xsFFpV47)$h-Hqv{?kb2xn?B6~88WMx}t-}*F7cAq< zm?S@GrWOStQ;C~s5}Cnzl?#CW>JJSkjwfK0M4x@RKj0GHxkhVi0Z9mi*jdD|4`tV# zwbf-|><0wcR<{x1yDL%j^R-dm|9+hNW;~E%BK`>9eG&ve3kGoeNHp#Y2Cx~-LMoX; zjZ69r+w*SN^%tYT$9D%r*isPppW{DRi}iZM`oAX30>#hog~p&~qKB>O#rdLh%lpoGz#CRwfOV% zv6JanOonQHr8zi+?@wD}5LaP1!6@isog9%yhm%eChXf5Tva;zAP7ZthFZ{Gy7I%cG4I~HH! z`-<|IFJRn@Kd4|6^y{<{p1)W_^fr8`{*8!QUoadrN6;t+24G+mquEYvzEonq z<+wRq)CMPFDu5O2Ki;sSs;^a*V&Vx3TIx5IggQZ7lYRxt6Hus7ZNI}ow>gK{#Q?yb z19ev8=EcQ>BQsawqpf)IcO%!}^Uq!D-2CQp{T7m&%Z~1|FQLiK#J>!I+E(6S1_;B2-7(GG*&*&rqvL&}!n$9{_s$fT2EvFfW=y=ggvQM)~-|yer>MfV zzN=^`etRhjQqD&r(TeQL&hPP~W%cSjFP!{BmF< z2aEMTIEH_7EDlAM+Ju#ckEG}~O_VfE&a5dB$kglym;80GHH9%NvL&UsX@5fWN$}DLhJJlC?HF+U`yQlV5!Phjs?r2DhrELfJswr_lKc0%8_FmQOvAHk{TbzokSR!NK=7PND;sifIzo zE>WciMj~p*`rVn^==9sju552#jG746dv&E$VwQ-{Vg+yQ5s|6DtMUQZfz{hOW@oh$ zgi4heDoE*ZJ_TgL2Bw9~x$LA`9Yl2^qwc%O%Z51vj@V(|CFPR1cAPdhG&-=Ve&+*n;z=va zG>Jcs)dL@nWg=jP@WN1yoNK3)92iDsC)$gNXQ7v%eKSvdPx%3H%%R9JUytIT7ykP{ zyE_pQd^BqfAbv`Z?@9|G>F6CY5m)G6@N!(|nNVT>GNKc59I8|8cBCEeY;F!~L@{PN z0}PuJPy8#4G{bGH8Z&+MYo31TVrvLFF8$lN>}Y&$dQ94p9B*aq@7U)NXhh2ilIcXk zb+o-WDvOh^cDE`-)5utD&ST91kh7|W;!Gme=t@+2Y4Yq_4m{@l2m{jfQ^I?Qv=-aB zFs%&0?XKz|5n(tt^v0g;9PqxuVcSV0W7@z!1KgNb*hx&vCyz?R4d}km5(f$@l07?{(iEH3I?{IVK{9_-|2} zc)_|0PpM3N1O}k$!>zdXtExwcXS@~W!P&@B*a_y+3kq#l_=r2Y*P+EY$U`$ijr-<_ zH&ox6Kfh;;w%`bs&{zo_7A9>=l~kn(CjKMv6Ze<686Na-YVA?z*DBxL;hDcTwStDq zUcp$38PSNgm?kh1(!}X!8n(WVGBF}0Zu%v?BFqN{;6(@3u69nG5?LX(Y;zAkW=UAcz+nP?RnxkOx+@2d-iDaQvp%s3N?JMetvwpmrM5o%< z18w*mwFVm?6@6xse**D8q10qD6MLGRd`vs?*JwcUDZYfIU| z2~Ws%FP;T2THDNgsmyvx|9)~hvWijJm%=je>O4VZT$^c5bc8Tlz_b&x#+E^%cmZ{d&XBr!`GtdOU z(?)7}@llu=Y&a0|0jzzcppn!C-~>~p3@}3L*h2#$_x~I5lO5(2Vn_~D919~ZnImdM z%kb}o_*+Y6O-d&8BnO~13$;ktf!nG!3+G-RFKsKdkh@eMeol$;*BJ4ig8}?ArobB% zBwdI2Z=)?d4#4S0L72xQlkr4E9?nPR;YRon*5mU=fTG^n4pd`F&d^9^hk_9W8quMn zhr89|$GT&Y_;fUw$7(RA!|`2hyACN55ufYPS$FNoA^9PqdFpbv8jN5yw2o;^wjHV7 z=%DExFbHv?J=J;EPGK&79q*$zchnrze-XVjyN-Rx;ZI3O^vDy5)YL`$ws0ql+1r%- zRl6v^**IFx#Cm-zuXp0lrCo0T4KL&!__5VL@Zzx(eM4PKrwZzG3G3-7+E2TB!VAcZ zC5~$nf7=UMA3kIC&bSHkXtnbNSg{iQBJ!;_MF{>X>(ewb z`5YoXL1p7ZTz!=C7fG^mfTeWE0Kkk_BVOJJU6$kePR4L@45FnpDOrH zWh#{cjLv1|xyD?5Ip9*%0Kf?-qZ2mXOtuq(F_iZzPhYub8%D767 zdWQqayyaCTZ&dg-(m>0DFps6y%#oj zK>}JdWmF0-Hn~)|&wA&Vcc=5&h)EVL_L4=c=9Bc zZN537n`5;4=t?_qnZK6v;LNA(P(LdMFj;VOP!N%2xZ=vLqK)O=^I6ej>i%tRNah-T ziK;E+3$-u@_PC?AjM;0>=}RfBLvvThj-m97ELpz|Q7n;|q!+Y0T^17zZ2TZ z=>QY`YV7)JLtNm{}#t=bG}DJ+~I884LpS7hYr(@nuK2|RZw5k zf#O&Ot%{6!APr&DJ2$NtXG=bF^ z_t9`}?rZ{hV!fQ1&^6}m>8kbllFjJaTYFgs=rovy2%?yj4X{*C&M8DYQZ_xBa_a&_ z_W+|Q$M2*4IKq{A{6WA92dw3uc>G@57(W@H^_g+~W;lId0L1^>NWQT)!aF0eevh>d zYD#|qm8xC0&F^!|vSNR)3iCR2wlf9`k1)1^T2v?JVi?j2nJQCr?k{4elaWcTHD^Wu!T zjC)!8;uo2aH8|;!fN~0oYfEA&iDo(^5~+G^OLH)9|7U6Q4X){u|A_YE^D(yXqJ7*5)T8xq4sKn)+1(15 zH9d|g5{d{xyLVpKMj`TTB7Ty8B=xI=^5$&6IxmM@FdqxSs-p6PAiqT*k+gt?)k0bs|=u2o`JgR#9s?QNXVG!C3~1qOhBJfV>KZn zmVHbKI?-6OfB*gNY)rOCvHv%X_|FrXo1qmviRAw;i2rF~{&y|Z_c;=MSsH>7|A&n8 z8HoR;{vILz!+bxl-?`3hn2f3!AA0@G$aRQDDK~Bmu-df4lC;(LlFzZo0E*gN89+9! zNqmV(E8n2PX76XK7Y5+(8HZX;6?YA{Mws&Y&_R*RjC+w$Al$xSF|5eFQiz1_YTqhB zudH~{f@OY+>l(!bqVs{nxdGt^EMY8-**$0Qy=i!N6!0#E@xYq710h0+E&%A>tc29k-46kD)CbbG6@0itEN$KIh!0BQ5!c;`A$Ps#%TC z<$O*byV;wgj+KSkz_s@GXsB52O#t<#4;OWlQj2gDXbY>!o9#}Lv znZ$fzEFzdrj#6E7i5T$;O**u1lmXuhXW=xQg=a$hxEY^I>Vg~&xXY;HFGKvF;0Rp7 zPjJ$Re=mujFd|yThZafDen%{lup^BF$$yEk;Z%$%nwG9b3ADn3%R=GVj*QVLU7l@i z>NyNHuGDp_AEAqFtKms9f6UU-xyqKx09U8)LW`_jWtRc0!$(gBfkC4B3{- zaGYzbx*6H{ajlr$Vx~e}9*AD4(s5nyhp4dC9+ht88CBu#=+bh+6(@2r0gRYN%vatQ z=uoKmYQmy1kc89(_7JX~#v>pZIo{BY74juiH~)W~oriMcJQ9RK%D>a)l-}STb07PH zES@#hh3@0G18Wym+F+3;2@Ylk6S|3HWm&1u=gIaItnhsN%43T8kQ{@lxhkda?0emWe!+FLB;G&uUA8#74&N&HkrK~9tk-fpw078qr11x4jj5UQpc(#@&p15nr z3YmBXc{R`8b%p`^Wu1a-qC69A6ZHQIB!1kkqr`icMcOY3cqtMN_n0{a)U(j?+MB*=Blei?oUV&Zl**h>;GU;UMP^6*H$+V}3+8z^DNazaIdfIO30};=#WBd5@wg!$MssGX{`k4IJ@bEoN+u+VeD6 zakgsdG@$DJQx^BXwwnEY(xrAex9}J>cc`~$_K8`c*)Tw(hr*SVl%LhSl5Lo1y=cU_ z{~d;eUMyR86P3EF7G>nVf0ti@t1^H%jzlQ7$4iKG!1b?zcW97}wxy2VQ&wh2$}Bb2 zzC+N-=*x!|lvjObWuAUt023}3zqQ_;#U82Qoa5KadU<>M)XcTzK#c%~V6yJ#WJI?< zT-+1iPKN^g0)s;EASlEJo&X3n?h}h&^Q3mzrzbSA_`S9C?zS?T=heMS5u3{Fv6fmG zhs&kBm+TPCD10be-LJl1v=`(1)5d^a$*$}4o&;hMl99H$)x~Aju&$*(#UKI)Dup_{lZ(q;O)&20Z8*05=S+CyiOf81)g{ zRW1&>k;Mcw@dGccz8dse#&l&HWr2l*7i0_7k$9jhaXS_s2?fl&{yeScqT9x7k|_ZY zHiN3m>?tj&+K)#S7v^NK;8G^Q-KXXlM#g`NXP>$7eZSy)miG1@A3K$dY4ob=eb1?xH$4adP&9S-UEPvQX3)4PV1eR8E9Gm;OXx3Kd8 z2zlJ10lmJxjknjA3QiOr+Eo^d?(;ZKKnhJW5w4-!ua6VVw3HJ1u^I5|Tz@YHwiVaU ze9y*4@Hvu<1$=b|!Vr{HI&_KT>tSn?R#D?2@X+MBQ;md$9_PgU>6n>Qhb&mZ+s$3x z2kGlq@r9AkmPJ84-X1N1V|ni!%q)GN!%#9!MJGPa-&b4g<2fz;2{JC$4q*+%F8d=a}LBaSi*a2w^F2qm(tD=zyBgH&%@SR zs8;rTP9?*qs#Ji8#@~<4r#_Lzz~b);nlec1ip2W9Wa4r+2oYEmEWEl;Zv{VBiq=`A z>N5#)-utH-&@O-bi~$^^5JrVnx#Z1)?5eux8jhKxmQrzpPX+n3KmBTw4ZD;UD22<6 zI!&}ZvmGzbFJlDxq)0{-)Hu7g33_Bep1DZLLN%T7h|s*Fm&Y|)Ckc?J3YIJR|T zH^wk}ciXNdyeI&A#^TW&>pCEL!NR?N*+d?JVaH_S{x=VM>d?zMB<@mkS}&|0G!O+~ICqX_R|?RO4N= zCzMcI(DGPAd?`J14PhyZ=pq~pX#GSELa>7#!~mq1CUB-Il`@)(A3@6THw;FKhT3}>vDvzh;A6q9VZU|q;J@4;&wp=P7$pst9#ZqY#3yV1A|V|68#tGzOvAN6_JU9R=fFYhip;ri48SlBuT36vx?v8m0x`9S7+Y z%AL@qtaNR|uh&{j-rChioE%%l=SrzrL8j|JYew=qdRLA~RsWL|Ku*lZbuM%V1!WQI z=W7mfxat>CXGLCKw_sOXntHwX*ZWuid-U+mjxVHz$&yKWvPUu=uK*XZ_%#^$7P2i; zVfPO!El~jEtjNcy;b^x4mgSQrFn<3TTaMSr9*5rgdAp*3-J@iqh}pOrP`^`xTm&nd z5q9;RydW8Y(~#kT;^`^D=Hw-8*gWnk-kEj$#rmV(_p#L;th%164%x0sTHO*fRcF=lVvmU+ z#tqvCYu|^*!{xW)lus*OwcoiXvL*gV)|<>=%o0#(-ae1dpdYdfBDw_l!==xGXKwxk zkfL!AzDlky0#5Zl1yrJ+L0GW(b3s8Vecvi#u+lGs$n-p{@N&+*?_IOv*n6}0ftK7@ zoXoBuE3&3I-xz#Z1EL-ygL$Osj~<%r*?9s7hvb~N1}S@>LEF#FCrSfS`zURZ)m|6x zr|eRP>#FLbQX&zkl1l{8&>!Dp`N3?>8EmRtv|91o&NB)w@euT$G`YYTtQdwZKL*ow zQS_6Dw+G8h+s~MPpVE)2i%@e*1`?(H2Z1k7G}pM6hS-R0mHvCpSiq{Ij*CB|^gOqo zL2-~WP9kPqVKp1)47_Fgt_RnXY*}3Fg%sqaR zgcK_FzE>bHvS^Y!TuUB+?nC+i3^IL}hhG*2u4Gnl<%JV9XEXT1a`ErR6m z?s&zR@r(Vm&*UI-aBdAm&CD`Tc}t~)t{>~@a4Hun8d?cbQ*$BN@@HjPOCll5;;ja; z?%7tWu@gVh*Z2FP&~x$kCFMQ!I~HYAacFl}|Gp6c${ryXa~7O24#43S;h%s8A5?rf z|L~MG+CZh^Sj<|mk6>K>@tfa#lO~#ioB<0iP}UsF?U$C~%}Ay+u}o(vM!?C1md15a za_pBbXH3fGVg_2=qr2=PSmFkl2|t}>xr4pcT>N}F4ggxwExRctSWU5y`4?pYYHRap zCDGOjOUKsP|L>b`=&FIRo348VFj=Z9&x9qcb-#9RiOQ1%u(x2RV)iATD;bCG z^I&yGMZh>)fdKdb| zRbh;zl4T|LEqBzRihM4x;8SpG(zKYEwmQ=zTM^Ak<)F1p>nPy^_=sZ#d+xisf*pXR zPEQAzgZi5S2rDX9q`XdgHymd1>Gtc0KI1%38{e7dENlELnD_Rp_hS92Yw~*TQj8(x z0IvzctOcd-QSli7GAylLH@D&0nAzCQ3KaA9^zwqfnz&cM%^7!snWa4lMYb~zhLmb# z=ax`>l?4EnU03hi!*;260Gi3#KOP}nNg@BxBFQx(jWro#vJt`)W@MCgPzv=5ozla1 z@|a4vkE&lNi*@%B>Ti)|A}|+Rbto!ok(3laVbIUy61p!aI?VfnEz*qmXJB+45jTr- zWq%5PvEoPak_^pO=uE7O&^%pLthMIsZ!=Tb51-pqDBJMLel*wLZQW3UeREwxbO#>k zJ!SV^6YRF1|7Rt4+JpI4i4jx;uK|y7J&fCijK4bB>7!M=_;k)H|4=cy5=~cjUFjnGV ztQ1u7_gjWA|6Pl^*3(z9hqVIGMUV%TOVm+qq4kn4a_DBAjye$K=GbPGxe6pQR}DDt zyruvig|@?DplrjuR_X4?&n|v@D#vKLAJHVmY=aknVH4awT-ivrp-AnFP|kg8?}La% zo>vZ@!~8OF`D{F#X8T3`3@XT>w_q5nm`7x8ddqKb&?&>?0NT*rD6HlDWhbSAz{%jl zVX{*_v+FbV9p&y&h+n6<(Hj7~M9S)t9JJ3ndvT#uQi~F0zER_CvISax1jgcKGd%TK^7>Sf>p-^Boq`PLLnhz@=(M%C zYR|8q&B$g{Au-rR7j$e)ZB)!*wkv11RJ0PO%f<;|GmF;_ww4wiZaOcpEOCQ zK*Ryde-VuFAvX^bU@E76p%}BEK3UTG`to|Gsz%!6lx~}4zUi{=D~m^~QLfl-X~ zZdv$Z*NZ=eSifWP;5|v{?c2^w%*hQ+$~2WMv%-!6D#Rw}`rGr%cmv&Dq+|QJY~1^^ z(jvD5Bi~jm^5asO`I@18_N=%h*hh!*G!E1Q(5)w!C*wdINm|0-@L+EOy|rGMakv}s zudjs(So5Zd02reS7?_So?eDHszRYx=1_OR}v2v@ia6f&`O7Y~ec(IY|C#&z;#e`5O zn3ZL_4|B1%L(1xDW&+g4dA-&<@Zx82%|)J;y3Ra@jPUzB_c9{YSd@!Br9e2Y*}t9C;_If5FEt;o z%>WZ!c9e|@H&M8Qx;$~?5Hv-ci4krCL?2wCb-%zqxn>O5jifG8zi) zoF^Ui`uZ|E+2YvQNT<s#F9w-@_b~9Gv?>=y0a+SOG~yq`0q$gSkSoJTw(u0S&2u zJH$Hm`ONU1n3m2UW`l_IFet1kAzIcidjN0WR7Euf=)?;Ew@`cf+KYb%Ju385VSsUNWoY(p|#>6Qmeo0jEI) z!rLbKgFUJgOrjJsU(Z%oBGOtp_!{Qclf0-vsh&MzFxZc4`<4*jUCe=sba2kHHMpNY zDE`(^XzmD^wbc*unN!YOb!oZOGnW-Fi@rZyK#a3d9udS`c&0W=3Qz{vE8fA%BmE!O WoJ= 150118 + +.PARAMETER NuGetPackageId + [Use if UseNuGetDelta is true] + Example: reloaded.sharedlib.hooks + + The ID of the package to use as delta. + +.PARAMETER NuGetFeedUrl + [Use if UseNuGetDelta is true] + Example: http://packages.sewer56.moe:5000/v3/index.json + + The URL of the NuGet feed to download the delta from. + +.PARAMETER NuGetAllowUnlisted + [Use if UseNuGetDelta is true] + Default: $False + + Allows for the downloading of unlisted packages. + +.PARAMETER PublishGeneric + Default: $True + + Publishes a generic package that can be uploaded to any other website. + +.PARAMETER PublishNuGet + Default: $True + + Publishes a package that can be uploaded to any NuGet Source. + +.PARAMETER PublishGameBanana + Default: $True + + Publishes a package that can be uploaded to GameBanana. + +.PARAMETER Build + Default: $True + + Whether the project should be built. + Setting this to false lets you use the publish part of the script standalone in a non .NET environment. + +.PARAMETER RemoveExe + Default: $True + + Removes executables from build output. Useful when performing R2R Optimisation. + +.PARAMETER UseScriptDirectory + Default: $True + + Uses script directory for performing build. Otherwise uses current directory. + +.EXAMPLE + .\Publish.ps1 -ProjectPath "Reloaded.Hooks.ReloadedII/Reloaded.Hooks.ReloadedII.csproj" -PackageName "Reloaded.Hooks.ReloadedII" -PublishOutputDir "Publish/ToUpload" + +.EXAMPLE + .\Publish.ps1 -MakeDelta true -BuildR2R true -UseGitHubDelta True + +.EXAMPLE + .\Publish.ps1 -BuildR2R true + +#> +[cmdletbinding()] +param ( + $IsPrerelease=$False, + $MakeDelta=$False, + $ChangelogPath="", + $ReadmePath="", + $Build=$True, + $BuildR2R=$False, + $RemoveExe=$True, + $UseScriptDirectory=$True, + + ## => User Config <= ## + $ProjectPath = "MRDX.Ui.ViewLifeIndex.csproj", + $PackageName = "MRDX.Ui.ViewLifeIndex", + $PublishOutputDir = "Publish/ToUpload", + + ## => User: Delta Config + # Pick one and configure settings below. + $MetadataFileName = "Sewer56.Update.ReleaseMetadata.json", + $UseGitHubDelta = $False, # GitHub Releases + $UseGameBananaDelta = $False, + $UseNuGetDelta = $False, + + $GitHubUserName = "", # Name of the GitHub user where the mod is contained + $GitHubRepoName = "", # Name of the GitHub repo where the mod is contained + $GitHubFallbackPattern = "", # For migrating from legacy build script. + $GitHubInheritVersionFromTag = $True, # Uses version determined from release tag as opposed to metadata file in latest release. + + $GameBananaItemId = 333681, # From mod page URL. + + $NuGetPackageId = "MRDX.Ui.ViewLifeIndex", + $NuGetFeedUrl = "http://packages.sewer56.moe:5000/v3/index.json", + $NuGetAllowUnlisted = $False, + + ## => User: Publish Config + $PublishGeneric = $True, + $PublishNuGet = $True, + $PublishGameBanana = $True +) + +## => User: Publish Output +$publishBuildDirectory = "Publish/Builds/CurrentVersion" # Build directory for current version of the mod. +$deltaDirectory = "Publish/Builds/LastVersion" # Path to last version of the mod. + +$PublishGenericDirectory = "$PublishOutputDir/Generic" # Publish files for any target not listed below. +$PublishNuGetDirectory = "$PublishOutputDir/NuGet" # Publish files for NuGet +$PublishGameBananaDirectory = "$PublishOutputDir/GameBanana" # Publish files for GameBanana + +## => User Config <= ## +# Tools +$reloadedToolsPath = "./Publish/Tools/Reloaded-Tools" # Used to check if tools are installed. +$updateToolsPath = "./Publish/Tools/Update-Tools" # Used to check if update tools are installed. +$reloadedToolPath = "$reloadedToolsPath/Reloaded.Publisher.exe" # Path to Reloaded publishing tool. +$updateToolPath = "$updateToolsPath/Sewer56.Update.Tool.dll" # Path to Update tool. +$changelogFullPath = $null +$readmeFullPath = $null +if ($ChangelogPath) { $changelogFullPath = [System.IO.Path]::GetFullPath($ChangelogPath) } +if ($ReadmePath) { $readmeFullPath = [System.IO.Path]::GetFullPath($ReadmePath) } + +## => Script <= ## +# Set Working Directory +$UseScriptDirectory = [bool]::Parse($UseScriptDirectory) +if ($UseScriptDirectory) { + Split-Path $MyInvocation.MyCommand.Path | Push-Location + [Environment]::CurrentDirectory = $PWD +} + +# Convert Booleans +$IsPrerelease = [bool]::Parse($IsPrerelease) +$MakeDelta = [bool]::Parse($MakeDelta) +$Build = [bool]::Parse($Build) +$BuildR2R = [bool]::Parse($BuildR2R) +$RemoveExe = [bool]::Parse($RemoveExe) +$UseGitHubDelta = [bool]::Parse($UseGitHubDelta) +$UseGameBananaDelta = [bool]::Parse($UseGameBananaDelta) +$UseNuGetDelta = [bool]::Parse($UseNuGetDelta) +$NuGetAllowUnlisted = [bool]::Parse($NuGetAllowUnlisted) +$PublishGeneric = [bool]::Parse($PublishGeneric) +$PublishNuGet = [bool]::Parse($PublishNuGet) +$PublishGameBanana = [bool]::Parse($PublishGameBanana) +$GitHubInheritVersionFromTag = [bool]::Parse($GitHubInheritVersionFromTag) +$TempDirectory = [System.IO.Path]::GetTempPath() + [System.IO.Path]::GetRandomFileName() +$TempDirectoryBuild = "$TempDirectory/build" + +function Get-Tools { + # Download Tools (if needed) + $ProgressPreference = 'SilentlyContinue' + if (-not(Test-Path -Path $reloadedToolsPath -PathType Any)) { + Write-Host "Downloading Reloaded Tools" + Invoke-WebRequest -Uri "https://github.com/Reloaded-Project/Reloaded-II/releases/latest/download/Tools.zip" -OutFile "$TempDirectory/Tools.zip" + Expand-Archive -LiteralPath "$TempDirectory/Tools.zip" -DestinationPath $reloadedToolsPath + + # Remove Items + Remove-Item "$TempDirectory/Tools.zip" -ErrorAction SilentlyContinue + } + + if ($MakeDelta -and -not(Test-Path -Path $updateToolsPath -PathType Any)) { + Write-Host "Downloading Update Library Tools" + Invoke-WebRequest -Uri "https://github.com/Sewer56/Update/releases/latest/download/Sewer56.Update.Tool.zip" -OutFile "$TempDirectory/Sewer56.Update.Tool.zip" + Expand-Archive -LiteralPath "$TempDirectory/Sewer56.Update.Tool.zip" -DestinationPath $updateToolsPath + + # Remove Items + Remove-Item "$TempDirectory/Sewer56.Update.Tool.zip" -ErrorAction SilentlyContinue + } +} + +# Publish for targets +function Build { + # Clean anything in existing Release directory. + Remove-Item $publishBuildDirectory -Recurse -ErrorAction SilentlyContinue + New-Item $publishBuildDirectory -ItemType Directory -ErrorAction SilentlyContinue + + # Build + dotnet restore $ProjectPath + dotnet clean $ProjectPath + + if ($BuildR2R) { + dotnet publish $ProjectPath -c Release -r win-x86 --self-contained false -o "$publishBuildDirectory/x86" /p:PublishReadyToRun=true /p:OutputPath="$TempDirectoryBuild/x86" + dotnet publish $ProjectPath -c Release -r win-x64 --self-contained false -o "$publishBuildDirectory/x64" /p:PublishReadyToRun=true /p:OutputPath="$TempDirectoryBuild/x64" + + # Remove Redundant Files + Move-Item -Path "$publishBuildDirectory/x86/ModConfig.json" -Destination "$publishBuildDirectory/ModConfig.json" -ErrorAction SilentlyContinue + Move-Item -Path "$publishBuildDirectory/x86/Preview.png" -Destination "$publishBuildDirectory/Preview.png" -ErrorAction SilentlyContinue + Remove-Item "$publishBuildDirectory/x64/Preview.png" -ErrorAction SilentlyContinue + Remove-Item "$publishBuildDirectory/x64/ModConfig.json" -ErrorAction SilentlyContinue + } + else { + dotnet publish $ProjectPath -c Release --self-contained false -o "$publishBuildDirectory" /p:OutputPath="$TempDirectoryBuild" + } + + # Cleanup Unnecessary Files + Remove-Item $TempDirectoryBuild -Recurse -ErrorAction SilentlyContinue + if ($RemoveExe) { + Get-ChildItem $publishBuildDirectory -Include *.exe -Recurse | Remove-Item -Force -Recurse + } + + Get-ChildItem $publishBuildDirectory -Include *.pdb -Recurse | Remove-Item -Force -Recurse + Get-ChildItem $publishBuildDirectory -Include *.xml -Recurse | Remove-Item -Force -Recurse +} + +function Get-Last-Version { + + Remove-Item $deltaDirectory -Recurse -ErrorAction SilentlyContinue + New-Item $deltaDirectory -ItemType Directory -ErrorAction SilentlyContinue + $arguments = "DownloadPackage --extract --outputpath `"$deltaDirectory`" --allowprereleases `"$IsPrerelease`" --metadatafilename `"$MetadataFileName`"" + + if ($UseGitHubDelta) { + $arguments += " --source GitHub --githubusername `"$GitHubUserName`" --githubrepositoryname `"$GitHubRepoName`" --githublegacyfallbackpattern `"$GitHubFallbackPattern`" --githubinheritversionfromtag `"$GitHubInheritVersionFromTag`"" + } + elseif ($UseNuGetDelta) { + $arguments += " --source NuGet --nugetpackageid `"$NuGetPackageId`" --nugetfeedurl `"$NuGetFeedUrl`" --nugetallowunlisted `"$NuGetAllowUnlisted`"" + } + elseif ($UseGameBananaDelta) { + $arguments += " --source GameBanana --gamebananaitemid `"$GameBananaItemId`"" + } + + Invoke-Expression "dotnet `"$updateToolPath`" $arguments" +} + +function Get-Common-Publish-Args { + + param ( + $AllowDeltas=$True + ) + + $arguments = "--modfolder `"$publishBuildDirectory`" --packagename `"$PackageName`"" + if ($ChangelogPath) { + $arguments += " --changelogpath `"$changelogFullPath`"" + } + + if ($ReadmePath) { + $arguments += " --readmepath `"$readmeFullPath`"" + } + + if ($AllowDeltas -and $MakeDelta) { + $arguments += " --olderversionfolders `"$deltaDirectory`"" + } + + return $arguments +} + +function Publish-Common { + + param ( + $Directory="", + $AllowDeltas=$True, + $PublishTarget="" + ) + + Remove-Item $Directory -Recurse -ErrorAction SilentlyContinue + New-Item $Directory -ItemType Directory -ErrorAction SilentlyContinue + $arguments = "$(Get-Common-Publish-Args -AllowDeltas $AllowDeltas) --outputfolder `"$Directory`" --publishtarget $PublishTarget" + $command = "$reloadedToolPath $arguments" + Write-Host "$command`r`n`r`n" + Invoke-Expression $command +} + +function Publish-GameBanana { + Publish-Common -Directory $PublishGameBananaDirectory -PublishTarget GameBanana +} + +function Publish-NuGet { + Publish-Common -Directory $PublishNuGetDirectory -PublishTarget NuGet -AllowDeltas $False +} + +function Publish-Generic { + Publish-Common -Directory $PublishGenericDirectory -PublishTarget Default +} + +function Cleanup { + Remove-Item $PublishOutputDir -Recurse -ErrorAction SilentlyContinue + Remove-Item $PublishNuGetDirectory -Recurse -ErrorAction SilentlyContinue + Remove-Item $PublishGenericDirectory -Recurse -ErrorAction SilentlyContinue + Remove-Item $publishBuildDirectory -Recurse -ErrorAction SilentlyContinue + Remove-Item $deltaDirectory -Recurse -ErrorAction SilentlyContinue +} + +# Build & Publish +New-Item $TempDirectory -ItemType Directory -ErrorAction SilentlyContinue +Cleanup +Get-Tools + +if ($MakeDelta) { + Write-Host "Downloading Delta (Last Version)" + Get-Last-Version +} + +if ($Build) { + Write-Host "Building Mod" + Build +} + +if ($PublishGeneric) { + Write-Host "Publishing Mod for Default Target" + Publish-Generic +} + +if ($PublishNuGet) { + Write-Host "Publishing Mod for NuGet Target" + Publish-NuGet +} + +if ($PublishGameBanana) { + Write-Host "Publishing Mod for GameBanana Target" + Publish-GameBanana +} + +# Remove Temp Folder +Remove-Item $TempDirectory -Recurse -ErrorAction SilentlyContinue + +# Restore Working Directory +Write-Host "Done." +Write-Host "Upload the files in folder `"$PublishOutputDir`" to respective location or website." +if ($UseScriptDirectory) { + Pop-Location +} \ No newline at end of file diff --git a/MRDX.Ui.ViewLifeIndex/Reloaded.Checks.targets b/MRDX.Ui.ViewLifeIndex/Reloaded.Checks.targets new file mode 100644 index 0000000..71a17e8 --- /dev/null +++ b/MRDX.Ui.ViewLifeIndex/Reloaded.Checks.targets @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/MRDX.Ui.ViewLifeIndex/Reloaded.Trimming.targets b/MRDX.Ui.ViewLifeIndex/Reloaded.Trimming.targets new file mode 100644 index 0000000..b4a56d8 --- /dev/null +++ b/MRDX.Ui.ViewLifeIndex/Reloaded.Trimming.targets @@ -0,0 +1,149 @@ + + + + + + + + false + + + false + + + + + + + + + + + + + <__PDBToLink Include="@(ResolvedFileToPublish)" Exclude="@(ManagedAssemblyToLink->'%(RelativeDir)%(Filename).pdb')" /> + <_PDBToLink Include="@(ResolvedFileToPublish)" Exclude="@(__PDBToLink)" /> + + + + <_LinkedResolvedFileToPublishCandidate Include="@(ManagedAssemblyToLink->'$(IntermediateLinkDir)%(Filename)%(Extension)')" /> + <_LinkedResolvedFileToPublishCandidate Include="@(_PDBToLink->'$(IntermediateLinkDir)%(Filename)%(Extension)')" /> + + + + + + + true + + + + + link + + copy + $(TreatWarningsAsErrors) + <_ExtraTrimmerArgs>--skip-unresolved true $(_ExtraTrimmerArgs) + true + + + + + + + + + + + + + + + + + + + + + $(TrimmerDefaultAction) + + + + $(TrimMode) + + + + + + + + Input Assembly: %(filename) [Mode: %(ManagedAssemblyToLink.TrimMode)] + + + + + + + + + + + + + + + + <_LinkedResolvedFileToPublish Include="@(_LinkedResolvedFileToPublishCandidate)" Condition="Exists('%(Identity)')" /> + + + + + + + \ No newline at end of file diff --git a/MRDX.Ui.ViewLifeIndex/Template/ModBase.cs b/MRDX.Ui.ViewLifeIndex/Template/ModBase.cs new file mode 100644 index 0000000..f3aeb82 --- /dev/null +++ b/MRDX.Ui.ViewLifeIndex/Template/ModBase.cs @@ -0,0 +1,65 @@ + +namespace MRDX.Ui.ViewLifeIndex.Template +{ + /// + /// Base class for implementing mod functionality. + /// + public class ModBase + { + /// + /// Returns true if the suspend functionality is supported, else false. + /// + public virtual bool CanSuspend() => false; + + /// + /// Returns true if the unload functionality is supported, else false. + /// + public virtual bool CanUnload() => false; + + /// + /// Suspends your mod, i.e. mod stops performing its functionality but is not unloaded. + /// + public virtual void Suspend() + { + /* Some tips if you wish to support this (CanSuspend == true) + + A. Undo memory modifications. + B. Deactivate hooks. (Reloaded.Hooks Supports This!) + */ + } + + /// + /// Unloads your mod, i.e. mod stops performing its functionality but is not unloaded. + /// + /// In most cases, calling suspend here is sufficient. + public virtual void Unload() + { + /* Some tips if you wish to support this (CanUnload == true). + + A. Execute Suspend(). [Suspend should be reusable in this method] + B. Release any unmanaged resources, e.g. Native memory. + */ + } + + /// + /// Automatically called by the mod loader when the mod is about to be unloaded. + /// + public virtual void Disposing() + { + + } + + /// + /// Automatically called by the mod loader when the mod is about to be unloaded. + /// + public virtual void Resume() + { + /* Some tips if you wish to support this (CanSuspend == true) + + A. Redo memory modifications. + B. Re-activate hooks. (Reloaded.Hooks Supports This!) + */ + } + + } +} \ No newline at end of file diff --git a/MRDX.Ui.ViewLifeIndex/Template/ModContext.cs b/MRDX.Ui.ViewLifeIndex/Template/ModContext.cs new file mode 100644 index 0000000..b06243d --- /dev/null +++ b/MRDX.Ui.ViewLifeIndex/Template/ModContext.cs @@ -0,0 +1,36 @@ +using Reloaded.Mod.Interfaces; +using IReloadedHooks = Reloaded.Hooks.ReloadedII.Interfaces.IReloadedHooks; + +namespace MRDX.Ui.ViewLifeIndex.Template +{ + /// + /// Represents information passed in from the mod loader template to the implementing mod. + /// + public class ModContext + { + /// + /// Provides access to the mod loader API. + /// + public IModLoader ModLoader { get; set; } = null!; + + /// + /// Provides access to the Reloaded.Hooks API. + /// + public IReloadedHooks? Hooks { get; set; } = null!; + + /// + /// Provides access to the Reloaded logger. + /// + public ILogger Logger { get; set; } = null!; + + /// + /// Configuration of this mod. + /// + public IModConfig ModConfig { get; set; } = null!; + + /// + /// Instance of the IMod interface that created this mod instance. + /// + public IMod Owner { get; set; } = null!; + } +} \ No newline at end of file diff --git a/MRDX.Ui.ViewLifeIndex/Template/Startup.cs b/MRDX.Ui.ViewLifeIndex/Template/Startup.cs new file mode 100644 index 0000000..064ab15 --- /dev/null +++ b/MRDX.Ui.ViewLifeIndex/Template/Startup.cs @@ -0,0 +1,77 @@ +/* + * This file and other files in the `Template` folder are intended to be left unedited (if possible), + * to make it easier to upgrade to newer versions of the template. +*/ + +using Reloaded.Hooks.ReloadedII.Interfaces; +using Reloaded.Mod.Interfaces; +using Reloaded.Mod.Interfaces.Internal; + +namespace MRDX.Ui.ViewLifeIndex.Template +{ + public class Startup : IMod + { + /// + /// Used for writing text to the Reloaded log. + /// + private ILogger _logger = null!; + + /// + /// Provides access to the mod loader API. + /// + private IModLoader _modLoader = null!; + + + /// + /// An interface to Reloaded's the function hooks/detours library. + /// See: https://github.com/Reloaded-Project/Reloaded.Hooks + /// for documentation and samples. + /// + private IReloadedHooks? _hooks; + + /// + /// Configuration of the current mod. + /// + private IModConfig _modConfig = null!; + + /// + /// Encapsulates your mod logic. + /// + private ModBase _mod = new Mod(); + + /// + /// Entry point for your mod. + /// + public void StartEx(IModLoaderV1 loaderApi, IModConfigV1 modConfig) + { + _modLoader = (IModLoader)loaderApi; + _modConfig = (IModConfig)modConfig; + _logger = (ILogger)_modLoader.GetLogger(); + _modLoader.GetController()?.TryGetTarget(out _hooks!); + + // Please put your mod code in the class below, + // use this class for only interfacing with mod loader. + _mod = new Mod(new ModContext() + { + Logger = _logger, + Hooks = _hooks, + ModLoader = _modLoader, + ModConfig = _modConfig, + Owner = this, + }); + } + /* Mod loader actions. */ + public void Suspend() => _mod.Suspend(); + public void Resume() => _mod.Resume(); + public void Unload() => _mod.Unload(); + + /* If CanSuspend == false, suspend and resume button are disabled in Launcher and Suspend()/Resume() will never be called. + If CanUnload == false, unload button is disabled in Launcher and Unload() will never be called. + */ + public bool CanUnload() => _mod.CanUnload(); + public bool CanSuspend() => _mod.CanSuspend(); + + /* Automatically called by the mod loader when the mod is about to be unloaded. */ + public Action Disposing => () => _mod.Disposing(); + } +} \ No newline at end of file diff --git a/mrdx_reloaded.sln b/mrdx_reloaded.sln index 8b541b8..b7058ea 100644 --- a/mrdx_reloaded.sln +++ b/mrdx_reloaded.sln @@ -23,11 +23,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MRDX.Base.Mod", "MRDX.Base. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MRDX.Game.MonsterEditor", "MRDX.Game.MonsterEditor\MRDX.Game.MonsterEditor.csproj", "{B684E5AF-F799-4417-BD7D-F5FE089DC011}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MRDX.Ui.RawTechValues", "MRDX.Ui.RawTechValues\MRDX.Ui.RawTechValues.csproj", "{F318C5F6-4AF7-467D-B877-927AED7F02AA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MRDX.Ui.RawTechValues", "MRDX.Ui.RawTechValues\MRDX.Ui.RawTechValues.csproj", "{F318C5F6-4AF7-467D-B877-927AED7F02AA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MRDX.Qol.TurboInput", "MRDX.Qol.TurboInput\MRDX.Qol.TurboInput.csproj", "{E23A6883-BCDF-4386-87F7-49DCE0085E9B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MRDX.Qol.TurboInput", "MRDX.Qol.TurboInput\MRDX.Qol.TurboInput.csproj", "{E23A6883-BCDF-4386-87F7-49DCE0085E9B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MRDX.Qol.BattleTimer", "MRDX.Qol.BattleTimer\MRDX.Qol.BattleTimer.csproj", "{9F9B2A4D-0C39-473B-9CCA-09EF5854F697}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MRDX.Qol.BattleTimer", "MRDX.Qol.BattleTimer\MRDX.Qol.BattleTimer.csproj", "{9F9B2A4D-0C39-473B-9CCA-09EF5854F697}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MRDX.Ui.ViewLifeIndex", "MRDX.Ui.ViewLifeIndex\MRDX.Ui.ViewLifeIndex.csproj", "{9C0AF1A7-4D8B-414F-AC5B-5FC34C6CFB6A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -75,18 +77,22 @@ Global {B684E5AF-F799-4417-BD7D-F5FE089DC011}.Debug|Any CPU.Build.0 = Debug|Any CPU {B684E5AF-F799-4417-BD7D-F5FE089DC011}.Release|Any CPU.ActiveCfg = Release|Any CPU {B684E5AF-F799-4417-BD7D-F5FE089DC011}.Release|Any CPU.Build.0 = Release|Any CPU - {E23A6883-BCDF-4386-87F7-49DCE0085E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E23A6883-BCDF-4386-87F7-49DCE0085E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E23A6883-BCDF-4386-87F7-49DCE0085E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E23A6883-BCDF-4386-87F7-49DCE0085E9B}.Release|Any CPU.Build.0 = Release|Any CPU {F318C5F6-4AF7-467D-B877-927AED7F02AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F318C5F6-4AF7-467D-B877-927AED7F02AA}.Debug|Any CPU.Build.0 = Debug|Any CPU {F318C5F6-4AF7-467D-B877-927AED7F02AA}.Release|Any CPU.ActiveCfg = Release|Any CPU {F318C5F6-4AF7-467D-B877-927AED7F02AA}.Release|Any CPU.Build.0 = Release|Any CPU + {E23A6883-BCDF-4386-87F7-49DCE0085E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E23A6883-BCDF-4386-87F7-49DCE0085E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E23A6883-BCDF-4386-87F7-49DCE0085E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E23A6883-BCDF-4386-87F7-49DCE0085E9B}.Release|Any CPU.Build.0 = Release|Any CPU {9F9B2A4D-0C39-473B-9CCA-09EF5854F697}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9F9B2A4D-0C39-473B-9CCA-09EF5854F697}.Debug|Any CPU.Build.0 = Debug|Any CPU {9F9B2A4D-0C39-473B-9CCA-09EF5854F697}.Release|Any CPU.ActiveCfg = Release|Any CPU {9F9B2A4D-0C39-473B-9CCA-09EF5854F697}.Release|Any CPU.Build.0 = Release|Any CPU + {9C0AF1A7-4D8B-414F-AC5B-5FC34C6CFB6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C0AF1A7-4D8B-414F-AC5B-5FC34C6CFB6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C0AF1A7-4D8B-414F-AC5B-5FC34C6CFB6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C0AF1A7-4D8B-414F-AC5B-5FC34C6CFB6A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From cc32006b43a0df27c6a454e972340d300e0ad523 Mon Sep 17 00:00:00 2001 From: Kemal Fadillah Date: Mon, 6 Nov 2023 19:17:01 -0800 Subject: [PATCH 2/2] fix(base): Fixes offset arithmetic --- MRDX.Base.Mod/BaseObject.cs | 18 ++++++++++++------ MRDX.Base.Mod/Game.cs | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/MRDX.Base.Mod/BaseObject.cs b/MRDX.Base.Mod/BaseObject.cs index f9f057e..bc6485f 100644 --- a/MRDX.Base.Mod/BaseObject.cs +++ b/MRDX.Base.Mod/BaseObject.cs @@ -37,12 +37,7 @@ protected BaseObject(int baseOffset = 0) // If no base is provided, check the class for the offset attribute for static memory locations if (baseOffset == 0) - foreach (var offset in typeof(TParent).GetCustomAttributes().OfType()) - { - if (offset.Game != Base.Game || offset.Region != Base.Region) continue; - baseOffset = offset.Offset; - break; - } + baseOffset = BaseOffset(); BaseAddress = Base.ExeBaseAddress + baseOffset; @@ -217,6 +212,17 @@ protected void WriteStrOffset(string val, int offset) _memory.WriteRaw((nuint)(BaseAddress + offset), bytes); } + public static int BaseOffset() + { + foreach (var offset in typeof(TParent).GetCustomAttributes().OfType()) + { + if (offset.Game != Base.Game || offset.Region != Base.Region) continue; + return offset.Offset; + } + + return 0; + } + public static int Get([CallerMemberName] string propName = "") { diff --git a/MRDX.Base.Mod/Game.cs b/MRDX.Base.Mod/Game.cs index ac833ee..6c4da88 100644 --- a/MRDX.Base.Mod/Game.cs +++ b/MRDX.Base.Mod/Game.cs @@ -19,7 +19,7 @@ public Game(ModContext context) } [BaseOffset(BaseGame.Mr2, Region.Us, 0x97A0C)] - public IMonster Monster { get; set; } = new Monster(Get()); + public IMonster Monster { get; set; } = new Monster(Get() + BaseObject.BaseOffset()); public event IGame.MonsterChange? OnMonsterChanged;