diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..d2e130e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,57 @@ +name: Build + +on: + push: + branches: + - main + paths-ignore: + - "README.md" + - "CHANGELOG.md" + - ".gitignore" + tags-ignore: + # This will ignore release versions tagged with a version identifier. We'll + # use a separate workflow for them. + - "v*" + pull_request: + paths-ignore: + - README.md + - "CHANGELOG.md" + - ".gitignore" + +jobs: + build: + name: Build + runs-on: windows-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Setup Dotnet + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.0.x + + - name: Build Mod for 1.5 + env: + RimWorldVersion: 1.5 + run: dotnet build .vscode --configuration Release + + - name: Upload Mod Artifacts + uses: actions/upload-artifact@v3 + with: + name: RealisticOrbitalTrade-${{ github.sha }} + path: | + About/ + 1.5/ + Common/ + Defs/ + Patches/ + LICENSE + LICENSE.Apache-2.0 + LICENSE.MIT + README.md + CHANGELOG.md + !**/.* + !About/*.pdn + !About/*.svg + !About/*.ttf diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ebed9fa --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,103 @@ +name: Release + +on: + push: + tags: + # This will only run the release workflow when it's tagged with a version + # tag. + - "v*" + +jobs: + build: + name: Build + runs-on: windows-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Setup Dotnet + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.0.x + + - name: Build Mod for 1.5 + env: + RimWorldVersion: 1.5 + run: dotnet build .vscode --configuration Release + + - name: Upload Mod Artifacts + uses: actions/upload-artifact@v3 + with: + name: RealisticOrbitalTrade-Release + path: | + About/ + 1.5/ + Common/ + Defs/ + Patches/ + LICENSE + LICENSE.Apache-2.0 + LICENSE.MIT + README.md + CHANGELOG.md + !**/.* + !About/*.pdn + !About/*.svg + !About/*.ttf + + package: + name: Release + needs: build + runs-on: ubuntu-latest + steps: + - name: Set Environment Variables + run: | + echo "MOD_PATH=$HOME/RealisticOrbitalTrade" >> $GITHUB_ENV + echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV + echo "NO_PREFIX_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV + + - name: Create Mod Folder + run: mkdir -p ${{ env.MOD_PATH }} + + - name: Download Mod Artifacts from Build Step + uses: actions/download-artifact@v3 + with: + name: RealisticOrbitalTrade-Release + path: ${{ env.MOD_PATH }} + + - name: Zip Mod + run: | + cd $HOME + zip -r ./RealisticOrbitalTrade.zip ./RealisticOrbitalTrade/* + + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Get Changelog Entry + id: changelog_reader + uses: mindsers/changelog-reader-action@v2 + with: + version: ${{ env.NO_PREFIX_VERSION }} + path: ./CHANGELOG.md + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ env.VERSION }} + release_name: Release ${{ env.VERSION }} + body: ${{ steps.changelog_reader.outputs.changes }} + draft: false + prerelease: false + + - name: Upload Release Asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ${{ env.MOD_PATH }}.zip + asset_name: RealisticOrbitalTrade-${{ env.VERSION }}.zip + asset_content_type: application/zip diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1e2b49e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.vscode/obj + +/*/Assemblies diff --git a/.vscode/build.ps1 b/.vscode/build.ps1 new file mode 100644 index 0000000..041a76d --- /dev/null +++ b/.vscode/build.ps1 @@ -0,0 +1,33 @@ +$ErrorActionPreference = 'Stop' + +$Target = "C:\Program Files (x86)\Steam\steamapps\common\RimWorld\Mods\RealisticOrbitalTrade" + +# build dlls +$env:RimWorldVersion = "1.5" +dotnet build --configuration Release .vscode +if ($LASTEXITCODE -gt 0) { + throw "Build failed" +} + +# remove mod folder +Remove-Item -Path $Target -Recurse -ErrorAction SilentlyContinue + +# copy mod files +Copy-Item -Path 1.5 $Target\1.5 -Recurse + +Copy-Item -Path Common $Target\Common -Recurse +Copy-Item -Path Defs $Target\Defs -Recurse +Copy-Item -Path Patches $Target\Patches -Recurse + +New-Item -Path $Target -ItemType Directory -Name About +Copy-Item -Path About\About.xml $Target\About +Copy-Item -Path About\Manifest.xml $Target\About +Copy-Item -Path About\Preview.png $Target\About +Copy-Item -Path About\ModIcon.png $Target\About +Copy-Item -Path About\PublishedFileId.txt $Target\About + +Copy-Item -Path CHANGELOG.md $Target +Copy-Item -Path LICENSE $Target +Copy-Item -Path LICENSE.Apache-2.0 $Target +Copy-Item -Path LICENSE.MIT $Target +Copy-Item -Path README.md $Target diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..1a3ff64 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Rimworld Mod Project", + "type": "clr", + "request": "launch", + "preLaunchTask": "build dll", + "args": [], + "program": "C:/Program Files (x86)/Steam/steamapps/common/RimWorld/RimWorldWin64.exe", + "cwd": "${workspaceFolder}", + "console": "internalConsole", + "internalConsoleOptions": "neverOpen", + "stopAtEntry": true + }, + { // ignore + "name": ".NET Framework Attach", + "type": "clr", + "request": "attach", + "processId": "${command:pickProcess}", + "symbolOptions": { + "searchPaths": [ + ".vscode/obj/Debug/*" + ], + "searchMicrosoftSymbolServer": false, + "searchNuGetOrgSymbolServer": false + } + } + ] +} \ No newline at end of file diff --git a/.vscode/mod.csproj b/.vscode/mod.csproj new file mode 100644 index 0000000..48771d2 --- /dev/null +++ b/.vscode/mod.csproj @@ -0,0 +1,55 @@ + + + Library + net472 + x64 + 10.0 + enable + + RealisticOrbitalTrade + RealisticOrbitalTrade + 0.1.0 + + false + + + 1.5 + + + + none + false + true + + + + full + false + true + + + + + + + + + + + $(DefineConstants);v1_5 + ../1.5/Assemblies + + + + runtime + + + + + + + + runtime + + + diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..23adc9f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "xml.format.maxLineWidth": 0 +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..0e59931 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build dll", + "type": "shell", + "group": { + "kind": "build", + "isDefault": true + }, + "command": ".vscode/build.ps1", + "problemMatcher": [] + } + ] +} diff --git a/About/About.xml b/About/About.xml new file mode 100644 index 0000000..880fe8b --- /dev/null +++ b/About/About.xml @@ -0,0 +1,37 @@ + + + ilyvion.RealisticOrbitalTrade + Realistic Orbital Trade + ilyvion + Has it ever bothered you how the orbital traders can just magically teleport items right out of your stockpiles? This mod puts an end to that. With <b>Realistic Orbital Trade</b>, your pawns will now have to load up a shuttle with the goods you sold before the orbital trader gets their hands on them AND before you get your hands on the goods you bought. + +The mod will guide you through all the required steps using the RimWorld quest and letter systems once you've made a trade with an orbital trader. + +The mod can be added to a game at any time. Removing the mod should be fine as long as there is no active trading quest at the time. There will be a fairly large list of once-off errors when first loading such a save, however. + +Mod compatibility is probably generally good, but there might be issues with mods that modify how orbital traders work or how vanilla shuttles work. + +<size=24>Version</size> + +This is version 0.1.0 for RimWorld 1.5 + + +
  • 1.5
  • +
    + +
  • + brrainz.harmony + Harmony + https://steamcommunity.com/workshop/filedetails/?id=2009463077 + steam://url/CommunityFilePage/2009463077 +
  • +
  • + Ludeon.RimWorld.Royalty + Royalty +
  • +
    + +
  • brrainz.harmony
  • +
  • Ludeon.RimWorld.Royalty
  • +
    +
    diff --git a/About/LogoText.png b/About/LogoText.png new file mode 100644 index 0000000..6310387 Binary files /dev/null and b/About/LogoText.png differ diff --git a/About/LogoText.svg b/About/LogoText.svg new file mode 100644 index 0000000..d03261b --- /dev/null +++ b/About/LogoText.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + RealisicOrbitalTrade + + diff --git a/About/Manifest.xml b/About/Manifest.xml new file mode 100644 index 0000000..ff7979d --- /dev/null +++ b/About/Manifest.xml @@ -0,0 +1,12 @@ + + + ilyvion.RealisticOrbitalTrade + 0.1.0 + +
  • brrainz.harmony
  • +
  • Ludeon.RimWorld.Royalty
  • +
    + + https://raw.githubusercontent.com/ilyvion/realistic-orbital-trade/main/About/Manifest.xml + https://github.com/ilyvion/realistic-orbital-trade/releases/latest +
    diff --git a/About/ModIcon.pdn b/About/ModIcon.pdn new file mode 100644 index 0000000..c0112c4 --- /dev/null +++ b/About/ModIcon.pdn @@ -0,0 +1,248 @@ +PDN3s&ÿÿÿÿ MPaintDotNet.Data, Version=5.2.8451.6614, Culture=neutral, PublicKeyToken=nullPaintDotNet.Document +isDisposedlayerswidthheight savedWithuserMetadataItemsPaintDotNet.LayerListSystem.VersionæSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]][] SS  PaintDotNet.LayerListparentArrayList+_itemsArrayList+_sizeArrayList+_versionPaintDotNet.Document   +System.Version_Major_Minor_Build _Revision!ÖäSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]øÿÿÿäSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]keyvalue $exif.tag0[0] +Dõÿÿÿøÿÿÿ $exif.tag1[0] /òÿÿÿøÿÿÿ $exif.tag2[0]7ïÿÿÿøÿÿÿ $exif.tag3[0]7      MPaintDotNet.Core, Version=5.2.8451.6614, Culture=neutral, PublicKeyToken=nullPaintDotNet.BitmapLayer +propertiessurfaceLayer+isDisposed Layer+width Layer+heightLayer+properties-PaintDotNet.BitmapLayer+BitmapLayerPropertiesPaintDotNet.Surface!PaintDotNet.Layer+LayerProperties  SS   SS   SS ! " #SS $-PaintDotNet.BitmapLayer+BitmapLayerPropertiesblendOp&PaintDotNet.UserBlendOps+NormalBlendOp %PaintDotNet.Surfacewidthheightstridescan0PaintDotNet.MemoryBlockSSL &!PaintDotNet.Layer+LayerPropertiesnameuserMetadataItemsvisible isBackgroundopacity blendModeæSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]][]PaintDotNet.LayerBlendMode' +Background (ÿ×ÿÿÿPaintDotNet.LayerBlendModevalue__ *SSL +,Transport Ship (ÿÒÿÿÿ×ÿÿÿ / SSL 0!1SmallArrow Down (ÿÍÿÿÿ×ÿÿÿ" 4#SSL 5$6SmallArrow: Background (ÿÈÿÿÿ×ÿÿÿ%&PaintDotNet.UserBlendOps+NormalBlendOp&PaintDotNet.MemoryBlocklength64 hasParentdeferred ¤(äSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]*%+&¤/%0&¤4%5&¤ t,‹ +ì×›Uu–÷(Ä0¡[Û¡™§[%ç$( „* ¨œsÎ9çœsNÉ ¢æ¢ûjþ‡¹¨¾y稫õ~¿kŸ}êT +H*ü-žõœS'ísöföÊ¿9sŒ1bĈ#FŒ1bĈ#FŒ1bĈ#FŒ1bĈ#FŒ1bĈ#ÏS""B焆»:tt¾9FŒ1òØ,} ,½väˆû5ðôm³1bäÑ%--eqrRℯ߄×iïÅf1bÄÈ£KNvöâÌôŒ‰À€  ?ÃR#FŒy ÉÍÎYœ•‘9–úû–1bÄÈoe©ŸŸ±K1òHrÊ?`Ž§€›_H [pDˆ[D\¤[dBŒ[\J¢[LR¼[d<ïÇ»Åã~xt´[@høü—•¥™é™þ†¥FŒy(9îå;ÇÃÛÏ-4*ÜÍ'8xÑé€Àkþ!A÷‚#Bï¥÷"cî¥÷b“îE%Æâ~ü½øäø{‘1Ñ÷‚Â"®‡FFý9<2jþËÊR__c—1bäâå4ÇÛ?È-0$Ôí”_À¢¾þ×B"ÃïÅ%Çÿ=>%i2=+C²r³%·(_òK ¥ ¬H +J‹p¿HïçæKFf¦¤¥§O¦g¤ÿ-*:æz˜ê0ÿåa)rOþ†¥FŒ¹O¼ýBæøø‡ºù†.ò ¾–Þ‹Šþ{bjòdn~ž”–—KUUµÔ5ÔK}Sƒ447JCK“Ô·4H]K=”· ú|MuTãµåeå’™‘5÷7ÿ  ë~‹^.»ÔÄK12%a‘s|BA¯EDÅý=1)u233K + +‹¤º¦F›¤¥¹UZ[Ú¤µÃE;Û¤¹³Eš:›ÚÜÖ¢¯mij‘Ɔ&©©ª‘"|NBbâdpXÈÍ€ÀE³ž¥È= ^êkXjĈ‘9süÃ懻EDE/B\s<66q2+3W*Ê+¥¾®Aš›•Ÿm­íSÚ9]›»ÀÒ.p´ËÁÒÖfiil‘f¼—ï×[0µvmRrxz3 4xÖòÔ°Ôˆ#®‚üÐœÀðE!דþž‘•5YTTÿ¼VšaSÎdh{[ÇYJÛ´¥v(µ6i+ØÚÔŽZJ–¶ÂNåmii™$§¦N"—u30"dVòÔ°Ôˆ#”€ ð9A!n1q±‹¢ãâÆÓ22'KJJ¥¶¶ „M îM³Cíhï´´Ë¡ÝÅýή.iïkÛÀÖVp³ö(´©<…6ósÁg›§qIñ“!ã~aA³®ŸÝ°Ôˆ#!¡sƒÃ‡D^KINý{~~ÁdmM47ßo‡’‹Tò³³£[º:ÚíÒîžéîî‘®®néèè”övð´ 6*â¦ô÷›››ö)yZ_W/Ùù9õè°wgÛQ1,5bä÷-Q±1sÂÂ#…‡G''§N߯¯ox0CÁöŽve#ùÙÝÕ+=Ý}ÒÛÓ'=ý¸ííÇß.ÚÓÓ ¦vKg'xŠ÷¶µ·YLmi±üý‹§´QË«Ê%>-qÒ?ž€ºÎ¢âbih°ìQÖ<1gÏ[æT×dœ”9yª2µ·Gc¡}ƒýðå¾=üúþ¡p¶_Ÿçë:4FÚ¡þ<µ£³C}}2•·ü»µ½UíS椘Ûohh‚‚‰ˆŽž€ÝüH~~VVÆ⌌ô‰°Èè‰àð¨g#0=¤FŒü~ät€÷/ŸE¾þãÑñ±“Yy9RR^&Õìí„VTV:µ¼²B•÷ÙãTSW+uõõ`]£44Â/G­¨SÉÀæ©Çš¬ûõàb=ÞCmhlPVÒ·§Ú‡8A7òWˆÃ¶Óþmely)ØÇU•U¨7M™ë‰‡9ÙY‹333&B#¢&‚BÿUL¼Ôˆ‘߇dæeÎ  \ää79™š™†j¦XŠüSVÖDFzú#²4k1b¦áQ1ðó£ŸC¼Ổ2bäeoo¿9©éïæL°©s KZûÚ¤¶¥Nr‹òÔÏ/**–’ÒRå'¹Z[7å˷–dΩù÷ááQ“3gÎÊçŸ_” .É¥KWäòå+rõú5¹vãú”^¿.7®ßëW¯Ë•+|Íe¼ö’\øü‚œ?{^Æð9ýgg²´¶¦Vr²r&²2²9^š…xiDt,óOϘ¥ŽµóÌ\}#F^:ñô Kýùù¢ö)y²5GýÊÒú¶É/)”œ¼\µ?é“7·¶ ¯Þ¦¶f?|ð!øâgÏœ“ ç/Êe0ó‹k_ʗ׿’›_~-ßÞº ýnJ¿Ãß.úÝ·ßÉ[wä››ßÈW_~%×ÁÖ+W¯(OÈÒöé,ÍK3Ó•¥™.,yæviVF†Y;ψ‘—L<½üÉÒE^¾Aã¡¡“©iéR[_§¾yCG“ÔµÖKYM…–kl”,¥ÝJ¿œu£çÏ}ò’\½tM:þÅMùú«[òõø-ùök°òö]ùî;êùîÎ]¹óƒ¥wøŠûxüÎ7wä6˜ûõW_«zõÊU¹tñ’|ŽÏ>3rfŠ¥ì‡bÏ~›ƒ¥ˆ—2ö˜žšöh,U?,{.,µã¥Ï{’ß›óÙw·  `·ôÌT·üü\·‚‚|hž[>47'Ç-)1Ñ-ÏùìÄK±®#O‘¥oyùŽ‡…EM&%¥J^næáû,.‡?_Yf埪™gÂýŠriF­gï@Ÿœ9{þûE¹rùª|q½q¶è-¹õõ7òí··åöwߟd(ô.ôû;r÷§ïåû{?¨þ½{÷®Ü¾ õëo•¥_‚Ç×/Ã6½xE.ž»h±õ©=}`iìÒ®'K9{?-=m"9%ùÑsOd©ÆKŸ}îI×! šð÷{~k:{ûúÌ9zÌcÑѣ׃§ÜKï¥÷ + +óõ6/7÷^Jrò½Ð°{îÇ=¯Ÿ<áýg¯Ó>†©FŒÌаÈ9!!aEL¤¥fHaA‘—Àw®“òŠ +É+*’Š2).CÍSe¹TÖVãùüêJð´E‡†äüùÏåúµòÕãêÓÛuòÓUÁÒïCÿ{J¿‡}ú˜ëÊÒWnȵ‹×äÒ¹K?ËRÖ—r.@|bâDL|ÜcÅK5ù\X +[o"À?๰4::jŽ€ÿ"ÿÀ€ñøøøÉ‚ü|©ª¨”Ôb4"þMmp(¯WEøÁµb’“’þæçpÝß?ðÏ/Éú[FŒ­ª¯‘ªšjíádÌtdt>ùuùò ÄGé×Ûö(Øy6çïï:Yz÷¿‡]êÊRúù®,ý +qVµK/\Aüõ‚ŒŽMgiçK¹vITL,™øˆ>>ò?¨‰z^µúÊÒçd—²Ÿ-"2bQ\\ìxnnÎd%ZÏÙ³ Mjë»Öðj\ÊY‡|¾××¼'--ío!!!׃C‚ÿ|ü˜§aª‘ßµ„EÇ̉Ox¹¦ Ö3±” e >kGY3Z\Vªm‡-ÈøiMCTÕÖh(kžê륩µYFÆF‘/º*ã_ßœfÞýÜüáGeªÞÿñG¹{|½ÎÚúÃi,ýâúšÏ¿xñ"lÞó`õˆÅRÆK»¦rO¬ï/Ì+”ðȸÿ ‹y¼¾§ðȉ °çæã?õž¼ý}ß +ÏÎËž¬Ãõ°‘µkœ·ÝÜìd)k%lµó|T]ßõõ¨Eƒ-;™’’ü·S§|®Ÿððš•k1ò„XúVT|üxaIñdck“´¶¶i½}QI±³^”,mÀyÆ~z‹iƒ°EÛ57U ®²”q~óÙ³çåÆ/ä«ñqÄ6QC +{’ùú»w¿—ïï²wé¹}ëŽÜ¸úâmcÎx׺g~˜>âÅË5.z ¾ þ~ßD¬€1Ò/¯©e”Ý7:h¯¥×Ý㬃j‡_Úˆ˜CvV®‡ÿ¯o@Èc±¨ ?wqnnöD(ìó ðgk—fçd-NGÌÒ7ÀoÂË×ë™m›ñ„ˆ°ð‰JÔ+KqÒAÔfðÚE_€5hç??¯þÄÅ µ–âüÅórö<®mc\¡_íYƸ¾vUu•æóKJK¤°¨PÊ+ÊÕ¦-))™ + +÷öñšUëÄ1ò,}+$,rœë$Õµ¡–©¯Uç—P¹n=×\æšM:[¯Úb)sõ#ãÊÒ›ðÇo}û•§G©²ôû,Oi£²ÿ¹ s£?ÎÜDsK³ú’³m»ó\|ú”ïDiq©^ãœ,e0üŽk—¯!öØ6bàê;0~sÇ۾˹ +VžLýâË/äÚupùEc®…@û´Œót-ËÿÏÊΚ »h|}#/Kßò +OLJždN‰y¦ÖnøáÐ6hwX +[ÊuC˜ƒÒyø` kŸ/¥}bÛ¤ì­gÍÓO?Ü“{?ü·üøÃòãÝ姻?Éw~T¦ÒÞä¹ÊZpÁAYÓÈsxô쨜¿ Ÿ’z ~ääíÏh ksX{£¾d›•/f×7ILLü?¿€-;v¿ñêëÿì¶àµ7ݾþOn¯¾þ¦Û‚×ßpÃ}Ãm”·Ö߯¹¹½ºÐíõ7ޜϵó¸¶IPxØ?Ü==ÿËíÕWñÚ…ªn ^U]ÀÇ^]à6›ê‚Ž§ð’Wñ¸ÞÇcxÖmþ|ê<µþæÓx)^2ßíÍ7ßp{÷ý÷æ'g¤/Fm§çÄw÷ÅüÃÜb[üÌW.°>Ûù¹óô–.p|•ÿìíòÖV{ûößúžóÝ^{m¡ÛÞ}Ÿ¼{ìø© ÚŽ<¬+ÉRÖR|óÍ7Ú;Á˜6çÎ|Ïëå¼fâ:yûb圡ø­úŒ ÐׯFì,Õ[ÔT ®®¬ñÓ’RÉÉΙ ÷ôôzûÿòý- ¾ªúÎÛ6ý§Ffx.ö ™HÏÈÐþKæ™´FŸÚå`©Ö¿ h½(kK+e(mÖËW¯hͨ+KÙKÿß?þ·ê=e*ô{KÉSÆEi²§žç.×µ§J嚢]ý8—ÏÉè…Q:7$c¨ìÓšqæíYEŠç>óəٙ‚Êäš5ëÿöÇ·ÿíÞÂ7þùXz,½–ÞKï›}ãXª·Ö߯ݬî½öú×>´65=uÂÝãÄäâÿÏ¿½ŠçÀQU@R,….¸Žª‚KøºÐíxgÝÇc`Ö=0 :ÏE­¿Á{@£Þ¾ùæ›÷þó¯¹~ô”çÆØÔ´‰“Þ>ÿضcçÆ·þøÇk¯a»üL°ÔúlççÎÓ[¾_ÃçRAMçvyk«½}ûo}Ï‚ù÷À­{ÿþÿþ÷~<™•›©ù¤fW'KÏ×x5íÍ[8ƬU#GékØ}Ô»ßÝÕcJÛ•1ÖR1×_ƒkã8ô!XPUQ%ÌqU£Þ‚÷S’SþqøÐá`éµ…Ø·üüNoÿñëz{‘±YÌ*  Y>‘—_ ½÷ÓXÚ9ÅR*óú?c¢¶}j×#ÚÚÚÕ*}#}Ò7†ŽôJO®;j×’j̱ԂKXx˜||àcy÷?ÿK^íMYøêëòꫯɫ  +ø'°ÆdÞüùz £lš.ÀóÔ7^ãû÷ïßN–ž8qBþò_pN^{í5<ïúzKaH L)Kq|ºÿñŸQ¾îÕW +laùë²²ãビÁ±ñÿ“’;;ù™»ûÿ¬Z¹zòOoÿI`‘ +8 Åûï·~Ï<™7oÞ¯nëÛwùÿú¯ÿ*ëÖ­“øø¸i,ÕÜÓ™³ê¯Óo¿ùõM‘Ò·ç1UÊûŒá|3þ\üü¢æý'¥ßÀ˜éðà°Æ¹yÌ”¥¨©­ª•úÔ…””MøüÏ{yoòõ×_Çoš+sçÎåñ˜üÃÞºùöÛÿfxjdÖHpDÈâ𘈠®ʺúö.øÏݸu¨Ó.EMg'Î1öÜs”ÍÒ+ˆi’¥S3 ¬Þ%ö19õ{Ø2wpÎÝù^Ï;Ú0TÎ̧Ý3<<¬ö)ëigÒ¦áyÝÖ‰óq íëÖ^Æ©¼=b¤à¾Õ÷.¨o—Óž§•§;wì”ÛwÈŽ–îܹS¶nÝ*k×®•uk×éýx¾N_c½~Ïî=“¾¾¾ÿ“–ž6)Ÿ}ö™ìýh¯ìÚµK¶mß&Û¶=X·:têï­Óþ~ nß.Ûñ½>üè#ñðñ‘€èX KÉ’ÈÌB MͯÈx9rÊ[öï? ßq;^¿m+>{3>ºyãfY·z¬]µV6mØä|œ¿ÛÿÅmÏøîüìC‡IBbbá•ÖZ¯¨Ý`Í søWÇùò«/5.ª¶)§m“â>kiÃvâÿ#gwñ}—/^Öy³Ìa±vͶGÙSÁ5Þ¦&§Ê‘ÃGdåò•òÏøg™ç†kÄ‚y²ðõ×&ÁÒ›ÿöo‹ O¼ðâ4'26æÝø¤„ öÙw¢ö©yûΰëA~§·KYJŽŽ éýzøÕd)çAµ#nyçÊ7ß|;e“ÂÇÿîGÇœ’Ÿ,½ƒ¿íZ|­!e.øÖm¹5~K}ý+—¯h/“öqƒ¥j£‚§Ì]°ß†jçìm›´±†üü|III‘´´4Î|S¥¿Ÿ‘•¡Êûٹْš–*ªééé’“íTäAT323$)%Io3Ò3¬×eãù,ë9*j–ž€âs²2% ß5-?O²ïK/(’Œb9Z*ž)%r"!WNƒ§1ñ±úP_!™xOzÞMNN–ˆ “ÄøDçã¼®<ÊwáoâïÓ߉m°”ñçvø#œcÈþб3cšÿc/k~yìxÉPæèÿ³Ÿ´=Ž:·ËW/««ý8¾ì³èjïÒúSÎ’âL)Ö 0gX^R.I±Ià ×­wþüŽ,ü§…²àµòšÅÓqðÔÔOyÑYú–OHèxrjê$ëºØSÝÛ­ µÕ•¥=ý½šs"Kkë9£õ†—a¯Ð.µæä+KÉP—9%ÊR²6Î+Am 9:þå¸|šªk×®©ȺQí?¬Ÿb)cmv£ÍRÆÞŠÉ ð.33SûkhӺƴß5â´µÊ+Ëõuäs!¬Óa½£ÚÀœÃÊ™5UÊTehV6ë ¿óÉk b•Øwðƒk°ÏËÛº%¡ºKü +›Å3³RŽÆåˆ{H”$$'â;V!¦R«ùÖ½ó{3'ž™ +'¦é÷äïc'×ÌýðkÊšÏ:Ôg°´ °@÷{ò¬•èè“!wÖQpÞ!ë+n}} ÇÚª‰ºzíªòVç p&Øè°ÜøòjŒoOõ¯ÝüZ몛!KéÛÛsûÈÓºª:ÉÏÊ—œŒIJH²jÝ*yó_Þ”¹óæÊÂ…¯M¼öÚëÏuÍ#F~MN,ö +žHIOÓ~&Ë.uؤ¥ϼÓàð®?Âõ˜íÙzõ°a¸¦èøø×ÖÌ|æyi{Ò.ýu¨sæì×[7oY³¿ü +µ©7”£´KÙ×Ä5›YóÄZ~› Ö°FGµmÊ·¯÷i§¥¥¦IAuþÛ¹+*ÙH¶ää)gȾ>''G™I&êã|-ߣ}ã°aÓÈg²ïgí—~&scORq=ªEŒ¸¿«¡XjÏJFûY ©ì“ÓÙ5òYL¶|*1 q–ÞX§ß5/7O¿yš•î'§K)òâd+Ÿ+ã¼û;Ûú+ß…û™×&~fìd~k*h›ÒWgýÄ™³gtýWöò’§7¾¸!ç/œ×çí¼ÿÙsgµ.ê‡ÿ駩¹ +`/óQdgêDê´gƒÊ\?mÔ’ÂÉÏΗâ¢b)@ÜÞ?À_>øàé¾òÊ+ÿ@ ÕÔ¢y¡Å+0p±opðD|=Î,éè„ý‡Xó÷Tíyê±Öåº#ý¨ÁæZ£µz¾6èíðèˆ|¡öÊ7–ÿ‡ú]÷Ρäë7°[éóݼySúÕ Ç¼{-¼óŸË¹±sÊRÖ2¡sò;¦s”ç^cC£ò31)Q2P{Àsßæ¡+Ki«ÒÖ"w¹žmRÆÈ&Ö‹Óž£­GNñ=ìÍÌË•tð653GòŠŠ¬XF3j¶Z§´±µñ±µÁ¡ì»lO[À±Úž!)é¿(ImÄ¿|@<2j哈9ä!шaV³çÝñý¸v¶}m íœ‘fý~þ]„ï[YiÅ;ÚòKßÅñ{ø:G}Qq‘î[ÖòzÆ|üŽ= { x½»xþ¢ÆQy|ÈQ^ûx yŒ¸ûƒÖn0ï¨×Tø"¼~’¥ôÿÉyΗæçj¯…ã:YQ^!YY³¡ß››+Ÿ|ü‰æÅÀÑÉW_}uö©ñó¼°â´Ø/4t" 6g;·ãüpÍáS,Dm8Çz´IÙ÷T‹s|v ײg?¾öÅÜ‚- +e}Œ­´Eí9%d(í›kW®ÉåK—5gÁóttتÅçì“i,u“:úfRRS4¶IV²®`šæPÍc?doMuÅÒ¼e†ÖëQú;À)Ü/€½—ˆ8iBF¦Ä§eIrV®”`[dicxÓþä´ ,kGܹv}M×ô]’¸Ö‹â[6 ÇÒêä@XŽô”¨DøøønöõAk(Àwò†1ÎÌôLµ'5nàx]S+ëÕ,ýÕïç뛧ö?‹ëL•¥°ó¨uÈåÓç?{öœÜ¸zC™© +?ÞÖ×n(CYÃ\½Î{‚-ÊþzÎÏc˜µŒCC>‚ù^{Žží×3Þ™›“ë¬}RÛü»3Õ1'Ž¼!ƒsòs”¿özFMˆ'¶µÖá7€iÝCRÔ{AÒj»$(­XŽ„¦ŠObžÔ4Ì–2þù8ßÉeŸq¿ÒÇçu‡9ºzcúôÌRYŸ624¢,½|ù²UÇ¿ƒ³èëÛó¾l¥_Â9)´=9•óú,ßÃÁRöF1Þ«,ŵ‹¾c¿ž§=åÍ7ßyó^™€–yaÅ'$lApTô‘䌴ÿW?·±,e¨=Ú1 º£ÛÊç÷žpe)g˜êZ%ÈMÐßcüs¦^ºtÉòçÁPöiÛ¶¨ëRÆGk±¹p”ö(ë»s»LIN‘LÄ2Yç¤~=˜økv—ÚZ` ó3¬½$K]ýàfÆ-ÁÒ6²´oT +®Kj]¯ø&Ê¡ dñNÈ—‚Z|Î3ðñãÁÇâ,uýn¸Æp¶3}}æõùù´ï™;bm×Í–±‘1í×çqçõrüƸr“LeŒÜŽ›Ó/a~Š6)mZ®5“¥Œß6KW /aXjd6IxTäâ¨Ø˜‰üâBð…륱æºM×Uå,èNË×'OÉVöäk_>|±zð”sð¸“ιtQÖ%òqÛ¥2L[TsLÌAàsé×»ö4Ùö(×hÏÊÌ’¤Ä$‹£ÈÙ9–'ÅÒ¶®ÇÒ(U½£’ßMªºÄ+!,MÐÛüš'ÄRŸ›,mK[ÁÒª_`it³g){H™×§]H?ŸÊ8*yʸ ¯y½Ý½:jtdTûLéopþ×—×¾”¯®£Nƒ +†RÙûÄ<"mRö–2Ÿ¸Ær‡òqÖЮAmã +<ö†¥Ff“øxù-ö÷ œÈ«hcrmæfاMm8§ MÈת½Ê¼:ò¼ÏúR=ÇÁÖ`ÒV¡½Ifº*ãù¦¾üЀ*ë¿i§èZk´E9;Ï%6jÏ#¥mÄzPö6²~¾¬¤Lmgýä“`)×IÅç´åȧgõ^’ت9 † Šϸl¡þf–âý®9!Ú~:«Û”ü±Ô,g­~Í3e©='Ÿ>¹Öœ¢F—<å6/enŸ¾óù¬—ⵑǚ1ð+®ÈÕ‹WåÚ¥kª¬Ñ?æ¼²‘,e-)câŒç赓ÇÊ|·A–’ÛÜ>Yú||/52䔇÷Ÿ½=ýþ7-5]çDqæ^SG³òC¢ç³òµö)YÊü}%ìC»—”10ί ïNvRyŸçceºÎŠ˜kw¯U[h¯:“¡<¯Ø““#IÉIZ'SR ¿žkL¹Ö¡?)–âù6æ:ÀÒL²´¦,Í“O£åTꨪšž +Kõ:„}Çíþ}S{ ÎÖ'‚#¬­i™âi ŸÇ}æðkñžõ‚d)}>ª½†:U׬DlLíо«Þ‰sœaãÚóžœuôÀÐþLKI“ؘX­}b¯(mTž‹Ó˜Òü˜,å¬T'Óàã³æÑÁҌދWíÊÒLÉ®t±KÛž K™³jFau’¥—Qe×—ÖN±4.Qí´™½LO“¥¬pn ÛeM+{«ÈºÂÂB_3Žmó”×DÚšôÛyÝdìœë>Ÿ>£kÊ°.•ëÇØùyÚ¡ôéùöúRôëÉQ«×̪qãÚ{†¥Ff“üÇ¿ÿ×Ï ›(.)ÑyÏÌ3pVi nÙsßóø¨ÖZMmÎzmr‘>y:Séûk^IûR‘W¢rþìÛi9&|.ëo££?,ZÇÄZJr”~Ïs§>7îc©£&Jk€8ןk­€Õu RÐ1$éÝç%®¦[N#0 ZÜ£R%¥¨RcŒ2߬,|H~*Cy=â÷µ·‰ëO øX]Q.UIiÇ0Xz,=/¾åÝ`i5Xš –†KXD¤æ·Ù»E¦Ùœyª,uÔH9ëÆ`;³n_kÒ²ó$'3GgÚþ¾®µ‡ë"óû<挃óúɸ¨ÆFñ¹É}­³øð2•J–RíØ,ç~1Àmòw–™e,}ë½÷–ŒvôÈdRj²ÎÍoåÿqG¿¥ ÜlW¡­P{Ý_uiÍT»ædíyN®J_žÏ‘Ÿm½øL*×ã뜲EyN2ÏÀØ(çùÉ‘ƒGäÔ‰S:kÄ懳ÿè!ë&Ž¥v­>í$öP±‡½¸µá`iZ×9øøKý£äXD²Äçã5åjsýxòô‘íPØ¿:?¥¶Z{[KËÊQ?Y-ååµRÜ‚x)b ñ­ga—v€¥•`irO¡`i˜³7”ß• }PßÓõñ]¿;ü­‡âq‚ÏR˜S(©ñ©’š”*E…EÚ[Oòº¨<…ÏÏ8¸*â©T>ÆçYçDÕµàëóúÉ÷²€9|æž×Vø'vM”‰—™-òÖ¿¾³ø·þ<±aÝñöó‘¼Ü|Ø!V¿ YÚ +–’¡¶¶5¹ä‰ÈSæbigÒo7gªö‚r½›¥P¾^{ë±Ú8ÌÕÇÇÇ‹¿¿ÞXölÛ#Ç<¦±T}úGµ±f°”½4öŒT>V ßµ¸¼JŠª$§m,=#ÑÕíâÉÜ“ìÒhp£¸,­ÐØ㸺F|Û£±”߃Ûd=YZø`E â RÜÔ'ùÝ%¾ ,-'K+¦Xî–YëzÂ6å Únì¿ÏÉÊyú,ÕZ‡fåUiQ©Î¦Š‹Š“„Ø­ùå5Æöù µç–̬ÖX8l{ÚœZcE®âÚÄš|Æx­ MÊýk÷f8óøsQ_jjõ¼à²ðÕ7¿¾ð͉ÿXôï:ï,uœ´Õ4Ç@V6ã<OjÛ¥¶:lÓ_U—.wâ⬩êZµm2R3$>6^bbbÄÛÓ[|t@voß-'ŽŸ˜biÃìÒ¶Çc)9¤³•pWÁ*FýhAEäÔ¶JjC—„æWÊ øö‡ü"Å="Q2K«`G5©Dž2æpß¼“ßEã\‡Ò–dÝ;9¨5G`IYy5bÁ•RX×!¹m£Ó8,^%mr$¥\gÊaï0 ÕOÚk<|?¿;•×ÎY}Òµú¶­ù|ΪEló›k*k„ë>s>^|L¼øHHpˆ¤¦¤ê|'ÆQÕïGü‡LÙsA–Ò&µíRÆm8cŸ¿v)s‹|œvª±KÌF™;oþâùn &Þyûñóõ—”¤AÄ|@òLz.´¸¨+Gù‡_娣'”ñ2~.J›ŠÛbž‰s-Xûäçç'‡–ý{÷Ë©“÷ûøÓrá·œÉRÎ;¦]ȇÎ,Â÷)®¨–ÌüRIÊ-•¸ìñK•cA‘ò‰oˆœ ‹ÁsÊ~2Üâ{5Nà2·n&Ã4>ÊØ(žã÷ç¼~Æ¡»{«†ý• ?>~VE½¤V4I`I‹ɨ‘ƒ±²/ Y>ó +•è˜hÔ$åëvµï¶<™ÎPjjªÎæsö¬«ÇbéƒòbøÞ:Ö±¾=ç8ÕÕÔYk6Á^ä¾ä±:áqÿgü$>.^ë.h7sF‚ÆF¶ª+KY3ÜPÛ  -*(Òùz:¯ 6»m“2–ÀX*·m||#³IæΟ¿xž›ÛÄ;zGs>äh:ê£ã| ®#A_ÌιڽÙNe}‹ÍÌnËþ´ÿæ|`]kç ýcÆþt~}R’Îýå<ãÂüB­y¢Í¡ =vô˜x{yk=”Î/+žK™&OYжå—KF^±D§Š|Ž‰•>Aðñƒ% :^2±h›±þ€|¡?:s6Õ},ulמBÞ1wÆš0Æ<8*§¼F9šXP!Q9e:ú“Ø"Ùœ.{}ãÄvqâÇì";¹Ÿíu’¹9+ëi°”ßq~®ÎËf½'rOdývúæ쉊ŠŽoU²”ö%×ÞâþáÿÚªä.û©<þeR”×ää+Gy\ìÞ îÃR#³YæΛ·xÞ|7µKCƒCÕ÷åœdún´³3q^Z>ý/ò”çs +¬µ×9”ôß»a7Q;ÁOÔTé¡8YÓÄs‹ç>gŽ’£Ì1e¦eJq~±Ú;Ìao)i)¬õ÷ó·j¢àÿéÎ}jy´H®,å¬S®[RX\(åUåZ[Àú®¼’rÉ/,‘¤ì"ñË–c!q°KÃ% *^R`;sž +í&ÖÅrûd…Ö)=KÉÆyM"CûuNYš–急±9¥˜œ/Çãòä@Hº|ä+û¼cÄ/*|Ê×í“¥ìb­÷;m9®ÍòÄXÊÞÇ\Õšú+®‹}ÆcH¿›>~òs\–ÇžñŠÄäDõñü$!>A9ZU_…8p…^¹ +¯œáÇ}F_„×Mþ_bŒœñ_ö•Úó£¸ÃR#³Ÿ¥óÕ. Ó\µ¸ Xóä)}qÚªùyùSñÿÞžu¡ëÔ³VH{y¬Z–üÂ|IËHÓZ{úîT²Tgˆ"_Ïó«´¤TmÞÎ6+ÿ«³‚Š $>!^ƒ% 0@×cb|’~&c„šç…]¦q7n³½é‘ìRÎÝã9ÍïhÕºvIl¦"œßùÐÔìIÊà,èlð ÏÉ1~7ÖÇr›´·§xX–òÚDv°“3ZY/Ä\R1b¯%œ ;-&)]"âå4b §Ã%÷S³ruý%²Ÿ³›¸ëÙѳ2Ð; k$é1y,µãúáÛóšÆíjÏ(çá¡Þv(¯<ÖŒSpòšh³”>÷+¯9¼fðø­EÊeÆ8è_Ø3cµ¾ño—ÙÔÜža©‘—ÂÇç]™¼ÒÚjä†ÈÍ’¢Íצ§¤[óE`«åfç*Wi¿’5öÚsT®S—” ±q±ÊR>Çz{–=•>#ãiö¼a®{ÏØlYe™¤¦§JpX°øû+ûÈÖž’IÚGZ娛y –’åd!9ÎØùH^8ãwy:û¿IkÓÁÚNä.íXî¾_{Y’¥´IÉRþƳ#gåÌИtáúQ…ßS‚m•‚•ù`6ãܯÜ×ù¨¥(›xm)­,•¦Î&Ð÷s.syXš8ÅÒß’{š9¿Ô^§€3gxLøýyüèÐf­ª­ÒZÐÄ„)»”ÿ7øÿ„>|W[—ö¹Õ6b_•Á§¨­t®GðKsªÕçxP¼”3÷^™35s¢Œ¼ÐòŠm—Ú,­±XJ›‘Jœ±.ò 0¯PòròÔï'S¹®gŽ0®IÒ¥ÝÉX9Ë÷ð½ÌÑ2gbÛ¢­:Ÿ™\eÜ€œamUYU™~Yêä§1ú“Z‹ˆúæ‘ËŠËÔßÔuŠ‘¥´sÉMž÷Ü>c ŒaÒÖÒ^Ô¹ÒþÕõèÀž×ì7 Wh›ò}¥Å¥÷Í“þ¥x©®Ó‡m2o768&çFÎÉèà˜Ó,Ո݂×E°Ó‹àÿÒ>V_û.Ÿœ­*•æ®féî–ÁÑAÕ¸5}eiêo·K,m°ö“æ¹ÀP®'Ê|9JÛ˜±ÞÒçà53&:F‚ƒ¬{F¶^ë:Z:dxdXZ:[ÔÆ­¬©ÔãÄž…Çb)j¢^™;gjXjä…Ïãk¼, ¥{”k—7Ö5*S™7Ò˜{„냲Vœçú¯`y¡ +Û…>9í6퟇MÉÚþÍ×Ò7f ?óù´ùxž’aÌóÓÎ$7i×’¥!Ú¥9w|í±–Fk àʲJeð#÷rüL2“u_Ü6k`ÉJö@Ú=ZTÆG9³˜¶+ýOþN^ ´Ë1ƒZ•>rÛϳTó8`i5êXÃÎÙŸ£ÃÃ2<Ð'ý=`#}ä§X¿ïÄíTáo²»«6ÞÈ€ ÉÐè~G]3tFÿ‰Ø¥8¾¼†p_1þÝ?ܯ±oúŒyó9ÎŽe¬†y'Æah—ÆÅÆYùx\gøýY 52:¢=åÕåÊSõã=`¶>š]ú +ìR3¿ÔÈìññYÏH;²¥¡ÅR°Kã ®ÿïuÞÉŒõÙª¯åüeG>Áæ/ÏO2‘¼¤HNp^sêŒ2ÎF†ÐgP@jCC´‡”¾6yÁž~ò”>>Ï[µŸ[‘¥`sÍg0‚lÔ ®Ú[Î\øÕÙß©y4~¾Öõ;®ÚÇÙTg±óê\]YÊ}@{škm2ÇFnsmOÎÿ¤Ï>24l­fwõuIÏ@ôöêl- ŒžÑœ¹^ßR¯~saI!ê 2Õ'xR,Õµ[iãó:ú:¤o´Oºú»ôø•”è>gìëõ%$'H\Rœ$§%KV^–äæil„×OÖ¥í½íÊRã‡ù^†¥F^.»Ôb©kŸ“Ö–ÿÒÌ£™ +žZ}çÖ9j¯oÉüƒÚz°Çø¼ÍR*çºÑ·gïSph°øúªíõ”¥àD›Ž¾¾²´úñYªì#˜±ûHÉú±|­>~jM©õ·®Í#`ÏL;ôYÊmÁ–d.¼¢´ÂŠôZ¿åìè99eNidlDϪ’ѱQ9?z^9ʼmó¢²")©,Qߟ¹ò'ÉRÝOŽk¯#}c}Ò;Ò«¶)¯Eyˆßæh=SnâºE–æçiŽ‰1æ9Ï„ß½µ»Uãß¼V>Ì÷ø%ßÌÜ32kíRØ£Oš¥ôÿi“2ÇÚN抙ëå-¹Ê¼0ëKéßGFGªêÌßã3èßò<ån³|»ôkçц&ë軳NÇæ(™b¯M?m}¾‡™õgÏZjrlƒyrGmEI…Õ‹ÚlÅbi“r¾ýx›¥ƒgu?qæ2ã!Z3Ï:¥ê2­;*¯)*,eìFãÄ8†½£½Oa#k]iS«æ"YÓÄœXA)bâeV}÷!9Êx.¯ œµÈÏåܼªºª_kÿ*KçÁÇ7k”yÁeî|7°tÁóÔöóA]ÏO§]ŠsžëãÑÎbž—œaŽ±?ÞÒG¤ÝHe]"sÅÌsðœb®~1ç¸1G¾Òß~–* ]âÓ¾»cÝxúÒÔû|ù‡«âòZûóì¹Td6mݼ¢<å#y͘÷s3òQT~G{f÷öUU8Ö ¶ìé'5ÛÄõX9ë%`Ornýüþ‘~Ý÷²‹mü$çD¹+e=^Šú‚êzÔŠöwHÿh¿ iü–LU®"60=3 6´®©†rî3íSö;ñzÇïi¯Íõ›XjìR#³4^ú›XÚvÿùiÏ8b]ÀÐÀæ&hótuk\ù퓇F¿PçXrm9ÇZê}ƒ}ê s] ²ƒÜy,»ô9±´¾uúþ OÌùôûYã óC`k²~ÈV­k¯Ÿ_xÚ,uÌãªmªµr‚à)gÑ0ï588¨Æx…®Ÿc­½j¨ë°çÒü–Zë΀šš(#/´¼ò¤YJ†Ù³s›y>ÙyÖ–+O‡GQå:PºvI7òè\£¯§[}JÚ¢¶²^‰5U:wŽ¶ZCíì±KۦϱflA}z¨³×5ƒPås\®³¯]òYO’¥:ëjÆvxËýËX(mcúëì« ÏcC¿¾g°Gk8ß›ì£-ªñ\u¾ ùéòy¿ö=Œ]jd¶Ë·K¶é´9n°9XÏœóٜęëÌ%1WÁº]ÊáGòÖ®âúÁ==Zã¯9uØ+OjMçgÅÒî—<§Ìý™­Æ ¹¬'> Úu[\ïɱÚÆÎ9¬#+±/µþq*·oÏäkµÞÁ>6cþe»ôØ¥¦¾ÔÈï/^:SÕþÂyÂÏfo ™J“s.¹öÚÈ lTÔY2‡A%OuÍgä04\^­ï£}¤çêÃæÓ_4–þ%cŸKfí<;ÞÍš Îz¢íIÆé Aä§xKßGkoñZ»nìQ÷­É=y)æ—>i»t&K™Ÿfÿ<ì »JsÓ´cð·Îts¬Ä8"ûCÙ3¥=£´EË*4ÿmÛ£¶ÿø{e)÷ÅSc)â&vŒA™ÈÇ g㌿YKPÓP£qÞj«ë<ׇðé K¼lòT|ü©‹¯Ê\óÅÌOhÿüC»ï›¹l»/œÊ\†í7:gØ?æ\ý—…¥O{½§ûb4.½Ÿvÿ§øÙ¸„a©‘ß™<3–> FÈ®â|"úŠ¶’³v¯ç“\ïÉ°ôù_~Nod¶Ëód©kÍ¥«Î¬R›‹ó. KŸ¾]jXjÄÈož¹÷¬Xª>¢kÎCèÃÌÑ7v©a©#Ï}®þ³d© SZÇþ5>þs·7Vod¶ËóðñŸ•–>ÿc`Xjä÷"†¥³äºð;e©ÖêÏ;5=¤F^h1,}þ1,5}OFf¿<~üE?ûíR3 ÚÈl‘WæÎ[<÷yåž K]jXjä%bé¼y†¥/¼ý;—»ÔÈl/}þ1,53÷ŒüN×(™%jâ¥/‰]jæê™bXúü9bìRãã™ýbXúü9iXjXjdö‹aéóç¤a©a©‘Ù//KgÎÓ|P¼”¹pÍAg^Ê3U—Y®³µ~v´=ƒù7Ì0x1ûž^™€š¾'#/´¼L,ÕuíY7äX[ÓžáÇõÜ”¥y9ι¨Ô‡YçäyrÔžY­këáºÀõ—8Ë~fM×ÑuKëôú0g]›uHÌvy™úžœ S¸þ<׈Öuèvivn¶Î™Öõ£KJôþ¯­5ü¢°”ì/**RvÒfËβXÊßÆùÙ|Žë(“\Þ÷R°ÔØ¥Ff‰]ú´×Î{Ö,¥r­ÌüÂ|k·,--+•ÂÂBµï^Øúö,­®«–¼¼siä©®5s­åç}LŒ]jä÷4'ê%™¹§±OÖD9æ)UVVJ~^¾dedIA^TWUKkK«tvtJWG—t¶wJsS³ÔT×HUe•*yEÆÚ{^ʸ¨Ævq-` ¸³«Sz»{U;Û:¥¶ÆÊëÓNÍÉÍÑßêüí¶"îú¼‰a©‘ß‹<—uHŸA¿º¦Zí»ìÌl).,–úºzikkS ÊÐÐ ô(KÓÓÒ%.6Nbcb%"ܹKvíüð>ýºcº:Ÿû™Çîù¾Æe[¶l‘UëWÉÁÏJ^až²ôìèY“¾®>µM{»z¥­¥MíÓŒÌ )((ÐßnÇO•¥³$ŸoXjäe˜_:6æžØ#Ú2½nˆý?e÷$G鳓Ÿ}}Ò?د~r{{» Èèð¨ K{G»$¥$ÉÑ£Geó–ͲrÕ*Y±f½,_·Y–¯wQü½bíFY¹r•¬\±RuŪղQW¬Z3õøj¼-޳ơk7écúürÇkVò½›¦oá+Ö®Çó|Ír9üéa«]:80(]]§êRm¬oÔUZZšäæå:{¡ìú02U÷óüm³qæòøóLßÈ‹-³v´ÃµýYÖ_2ÎÈØhnV®2µµ­Uzz{¤»·[zûgìîTµ§§G}屑1}.§ GN{Ÿ–-Û·‚}ëdÉÖ½òÁîOåƒ=å}è’íûeÙ°,\v.Ýü¡|ðáAù`Û^<¾AV€“+V¬’¥ðøÎOåýGT?Øy¯Ý…÷­’åËWèí2°ùƒ?ÁçæÐO÷—lÿœ]/›7m–ðpéhí³#g•¥½½°EÛÛÔÎæoQÛ´ª¢Jc´O³²³´¦¿¶¶ö~Ÿ–±ÔøøFf‹€£³ÓÇwa)9Z\Z¬±Qr´ª¼JÚ[ÛÕŸg ;óø¬êêîÒ˜)U–ööõJQi‘xùzÉæm° a.[¿E–nÚ ýÐy»,\ºaž_m1·ËÖo•¥ñܦ]z»tãNëï­ÀO0tø»e¿>¾Œ¶+ß·lnWX,^¿Ýz·±ºïÝñ‘Þ.[»N¶oÝ.‰±‰2Ø3(çFÏÉÈЈtvvê5‚LåoèhëÐ\9ZQ^®6,Yʺ)Þ¯­«uöÕr½¨¹}S_jd¶Ë¬©‰¢Oß +?ÕVú÷ŽúÑ¢+^˜ÚÑêÊjÍÏ“1ŒFFEŠ×i/­!¢=×ÑÙ¡þ1ãÌ?õõKKG‹DÇEË®vÁÇ·lËå+×€wk¡ë`CnK÷(—¯\‹çÉCÇëðšv~,=pRþúÉiK?ö’÷xÉû»ŽÈR¼—ïá種tÜ®¦"{v9c +kñšµ°W¡¼]±z¥ìÙ½[ÒRÓ¤¿¯_FFF¤¯¯OƒÆ)7–ºÚ:‰Koo?ILJ²ú¢ÓÏ̶êPÕ>ŵ¦±©Q}þÙf—šZ}#³EfKM”ÎœsñéÉцÆeç|dgåÀ.«CÁÉž©©©[åà§ÕÞ + Ò×Û9(ÚuŒ¡ööI×P—ä–äÊ÷#²fíåä² [ÁÈòþî#òÞ^OðÑ|ô­y tðº1Ó>üχº;õýýÇacîWNÒ~ý`×ayÏý¼÷÷•÷?ò÷>:¡úþGî+XºñƒÕËÁÑå²zÍjñ8á!U UÒ3Ò#ý#ý¯hiC­«[mÒÞ)-+—°°(Ù»ï0b«G$¿™}]œC™“©9~ö}566JKK‹4µ¿˜óN KÌv™-ëºÎïTŸ¹•ÊŠJ­«g )cƒ¬íëîCS‹¤§gŠ»‡‡lÜßzÍ +ùìøgZ[D?ŸvyÄœ”²t¸KòËóå艣S,ݸ ŒûTþzШú—CAxìb£ë,eŽhùZØ–ë™G‚®s¹Eìub«K7í÷>>!=›UŸyÈßù¹=è/ïíó@Lu‹ƒ¥+”¥¾þ¾ÒÞ×.½c¨+îÕÜã½¼0VÊßšžž-ÇÝO˶í{eÓæmòñÇKDT„”V”èïÍÈÊP•óOš››¥¹ýÅ8ž†¥F^6™-¹'W–êœ䪵·’~}uµÆ@»»zPÃ^Û,UŽ/›wìGW*Ÿö: Y¹Yj—Úypæ£úGû¥{¨[ŠªŠÄ7ÈO6£jùê5j{.Ý´]– ¯´dó^pÎq«~þê)–ÚŠèt]é¼Oö2OµtËnÕ%ÔmÍÐ]°_á냣dÿ¶íÛ$:6Z::•÷=ƒ=ZsÀsùôñ««k$44Jöì=,ës]¿q«lB¾ê“O‚§‘’º°bøø´M©ŒyhOØ p< K¼lò¢²´©mÆNÄúìùÎôaÙëÃœ=ëG%KKË%*.I÷’mûÊú=ŸÀW߬¬[<Ž_X$lÒéîìÖZwæó/íìÓm$$%Ⱦ?mjÙ“+V:⦬_ZÕÛUàæ¯(óþ|¯«²žÊ¡+ÀîU°aWSqÍš5r`ÿµ'»»”¥ÝýÝÚ³Õƒës÷¼å>ðöó—í{öÊ +ÔR­Ú¾GÖÀ>Ý°u·l‡Ïï)yÈIqö ë¾h£Ò÷·çe³NêEY[ÀøøFf»¼¨}O®ue)çå±vu”¬b¾ž,-/¯ˆ˜9èá#ëPW´þ#Ä>÷~ª¶årÖ„Â6üôØ ©DŽŸ5îds:Œ™R;º:$=3]:$ëÀRg­(sîȽ/_¶ÜÒåPû¹ÇTnc5øº–…®]³VŽ;&e•eÒ=ŒXÄØKû{ûetùûNINM‘£'dÃNÔ ¬Gœaë.Y…Ú­U;?‘•·ËŽ]IPp°î/ò”¿/??_÷¡×áXJ5¹'#³Pf‹]JŠ (,.”Ü‚\µ¯ÈÑÖæ)E]iLL¼r÷‘µàèÒí°GQÓ¹d÷a­Õ\º µLð?Ú÷‰d¤e*Kµ¯ÝöóÁÒ®Þ.),)”#GÁ`úø6ë–.—¥K–NÓ%K—Lé’%÷=ÿÐúu»lÉ2'S©ë`ŸúùûIsW³ôŽ€ûÃðï»ÚµŽtd`DYÚP×(aðã÷<$k¶n•Õ›7CwȪmûeÕŽergkqMØ¿oŸ„„§yR„}——“7§biCû³¯›2,5ò²±´¶ºVZ›Z¥­©Mýàæ¶'ÏRaÄš¦_P{®3•ñQÖ‰²†’y&ÍK³Æõ3¹ùÅ+ûœ’u;÷É2ø·K·¢~ õ  þ>ìÓ÷÷"§Ž<ù¦»Å>1ãÌAÑ%KYÅ}nË?Ð_víÞ%;>Üaéèö'¬üLèöÛUwìÄß;­ííüp§D¼“óôz{e`d@ºúºôšÆ8ïÐàôöô‚‡…âáã/›ví–Uˆ‘nܽOÖî>$ËÁÒˆ®@ÕŠÕ«eò`Û?Ú/§C$!=K²Qk›››‹8j‘ÆJ”§œõêØï¼nñ˜Û3`ŸÆñ òx£Ö@Ç–ñpSed¶²4,,Lç±Æ}êd)kpžZ}“KÓÏ)gųF2/;Og=1Ís­¾¡AÒs +Å'4^ö{ÊÊaƒnØ‚üûfè&Ô„²i—¼·ÿ$ô”æ|Ö¬[¯=™eÒÙß©ùÆLY¯=E`í·Ø„X‰Iˆ±4>FbãbŸ¬Æ»|þ å¶'eý¹ÉïFîó8°¯ §¯GëïcããeïwY³e‹¬\¿NÖíÚ+«ö¢¶j÷qý­Ë‘¿ZŽ}°| reØkwÃ^þ’”?¿ _'·SXdÍDáö¨MÍM:ï…×TÎÕjÀ~~5©ÊrlßuÃR#³¹ï‰¬b­7ë6yN=5–ÚµM°+k*ÕçÔµA]8Ê™sìÝaý({—øx®ÓvÉÎ-Dn%Fž ’=GýeéŽOå}Ô-ÙÆ|9b¤ë‘‡ß²Ck:—ìøDë“Ö¬Z!‡’‚r°t,²rã}V?&ûŠPwD[ì™hûƒ§½Ì™üNìÃg=,{XÃÕÕÓ¥µNþ²í£}²rÃ:­UXµa½2óýŸÉÛàZ»tÃFY [}Í®e厽²qÏ9íë'iéiN–rßj=¿£?Š±Ê†º­E%gŸK¹}Ö°NŸ}l†¥Ff+KCÂB”]œ7Äó‹ö©ÆK]×zjŸ76/™á¹]US5­î‰kܱî‰ñ½ššåh}SƒÎCŽˆLO…ȇÇdÇa/‘¾{ìƒ]aî‘eðq—®Û KƒYºfƒ¬Z±L>ܾUÂÂÃôÜe ²{°ÛòQO¥y((k7íþç¥Ü>mPöfñ»±¦”µPƒÖl+\Kbbâd7rý«pÍ`Ík©–£6vÉæZcÅ\ÔRöRáú²,]µ³°Mw"çòÄIícÈËÏsÎëç¾æuMYZß k¡°FB×bLõ ÿ¸O±ûÿ_Qq‘³߬Qbd6ÈÜy`é|›¥¡RRZ¢ýÝ<—š›µ¾{æ:n¿Yë0Ù><×/bN‰\åù¬õ£° ò tvcz´áè÷1-ŸzxÉÚ#Þ²âà Yõá^­}Z²~»öÂ/[»]V,]%KÏùë2ä†ÀшEêleÆHYÅ|ÿæ,höb¾HÊÞ^[*ª­5ñØ_ÀZ(ÎìDŽ°V‘£ÿpr÷ëVY<]»µ«;'Þ‡:XÄ:V­„®Ñ<Ô +\c–í {7éÌ”#Ÿ‘Ô(KÙÃÏý«ë Â×æ-mU×ÿ¤ÿ”×I2\gqÃæµÜÛËÛ°ÔÈ,Í=…iŽ‡q2*c¦Œ—éyõ„•|°oíuAÉRÎpæ9Íš'Îå¬m¨•ŽþŸ˜œ(^^^ruK[vî–e"G¿m‡ú³¬s_²e/ôcÔ@¡¦ôƒ•šc_¶j9jÙ÷HXd¸rIgF ôªoÏ­SK¸Ö‡Õ‹ú}Üç~M³áý9ÙZÊkmvÚå½½ÊSÆv9k×ЈPÔÄî“Õë×è~`ßê{ûÜ•§ËQ§jÕÉ®Ñy-ËÖmÑû¬õÚˆ˜rph°îk®qÂõ®³r²ôZªÇå­}œžª2¾P_¯,åÿ;Ö’pΗ¯·¯üÓ›ÿdìR#³BæÂÇçl“?¾õG9åå©>Ÿ®…DÛ€k qlç©´rósUsòr4ŽÇïA¶’£½£½ÒÜѬ½;§N’m[·É:ø°+ÀŽåkÙÃÉžx2äb…Èe¯Ø(+?X%ë‘k:ôé!­Á§-Lÿ˜6ik{«öŸ’c\ƒŽÏÓç}¡× ~/*íǼ¼<©¯©—îönî–3Ãg´þ€×šØÄX9ôÙ!Y¿y#ê¶Éû¨{y¨¥[?Òù)Ú+À9,ì3ÀýU¨·e=ALlŒî—¶Ž6©ª­²x +ûôiï©s .þ¿+,Ñ™_ÇŽ“×_Ý°ÔȬyn 4^ú/ÿúÏz>&&$j?ѳT®·L^$§$£þN¡¦r j*W¢¦³ëV .ºf÷'ˆî“÷VmBÍæJÙ;ì¤û ýlÆ){dÎ^çJ[s¥È¬xäÃãââ$>.^•÷U±Aõ{á;&''kþ×€ÖÖV+75ŠÜÔаÖ5p&”û‰²aÛ6ùñŽå~,÷&k·í”¥`ç¨[] +Ž®_¿Q× Qû„×—–öÝ/©©©–¦YÊõ[232õ8Ù·ÏB¹fÌÞ}{eák Í%Ff…Ì›o±”véi¯ÓšëÑu/ëÇéZ𵟶2ßÀmEÚ¤Œ2ÍyÌ‘Œ2–˜ G—ˆ ®XÍÙ%›d͆m²dùjpt¹l…mæå饳æY×Õ×Ó§uùüLÚ½ä6í½øÄx=g£"£$<,ÜÒð§rí§‡Q×÷Ì|ߣ~Ö´÷…E8¿WTT”Úªôû™Çgm;gðq^ÔÐÀ°öÆfáØÀïÞ¸ãCÄ7Éú»dÝöòþªÕò°t%lùÏ>;*‰ñ‰ÒPÛ ƒ}ƒZWËÚÖ 0¾ÃkLZFšöCP™|Ç_mRÇÿ;ÞfffʧG>•×^ÍØ¥FfÙ%’Щ(ŸŠ—2~UWW§u1OKeÜOã´ˆ_ò<¢?Ë|r_oŸtww+OY·Ä8!gv¶pl$÷SÞ²aË.ئ¡ÈÕ¯\+»?Ü-AAê+²/Š³”8Ë”18Úu´}ÉP[ccc%4$T¼|¼ôZâíãýb¨7ô´¥>Þ>È›©Jž’u¬ e<›=\Ü'Œ£v´wj ¿o@ lÿè#äœ6É’µëå¯ìÿG|ôãã°53¥­¹MÌýIû–5TkΊáõ¦²¶RãËÇÆ1zšÿtÍ¿:ä"¡¬{ã±bê”ç)yã7 K̺ù¥Ìã³Þ¨¬¤L×Jb}©æW9+ô ªk>Ï#Ûöe>,e_YÊZuÚMôCÉUÖZr¦‘áiƒ–ž“'ÇOzÉÖm{dÆíòñƒ “ßv({îi—òú“•£~rB¢eª&À.ŽSözœô#îGåˆÇq¨‡ÞÅßG=ŽÉ1Þ€Úñpw¼Ï]>sÜç{yû™~–û´×?ŒqÇçÇûŽwÜ÷õõÕ~o¡¦¥¨OÎëgµäiwG·”!o%{?9(«6Á>Elôèi/IC]D+xKŸûû“û–³³Kæ>羧-ÊX5óPTÎ7|Òÿf*ÿŸ±9'þÿãÿS_jd¶Î/e})ÏÏ¢Â"©,¯TûµO»¾”¹'úø´…io1ÿÁskxçüèˆ jÏ~Döô‘Ýž!²ÿ„·:~T>AÌ•í=é;¥§,Ýg߂矸{ÈS²ç¤Ÿ|ìqR?&û<=ö™ž:}J¢b¢œßÚ«œËc kb;rBZÃÏÙ#Píõ| +õ¦ŒëÕà(·íéiæê™5Q!vßò9–úfËR(^C]æŸ%¼ÀOoeßf¯XÙÛý°Q7{FË2o¼×¯£:>cµWšlsWy§ãñ|~¶¬ñIÆ6#”£Ëü3e•/xÞÚ,eÌÀÇ×G""#$.!Îbi +òì©é’‘–¡ó +j*j¤«½Kã§ZƒŠ‰îØ ÜO´é™gâ¬r”û’µ\—o&KíëœÚ¤3ç>…žRþ?ã,ö‡Ð>åõÜbé›2wÞ¼ èâç}®1òðýøK9#J>ßS™¹7c<úôé—³ûÄ,=ã`éè°òtøÌ° )Oi[Q9£„ö×3*++ÓÚ{昜M°Øɹ"´E£c¢õºáçç+'Ox &àüèOå°ûqÙ ûp¹LÜïî-;N†à¦Oî”úæÈR?‡âþ¯Dد>ò!|ùõžqz»vé¦S²ì4xé•éò~²4Åb©O†>fñ5E¶y‚¥à2yÍçvž …­l±”k¬¸Ÿp×Y|색‰QžÚµ¨Œ³þ6:k¦XûÀÙûŒ7+C»»ôZø3’áa‹¹?ÇR{]­û|ú§`—òÿYK³e›òvjí<ö‚¥ˆE™3ÙÈl›_jÏ.åì½g2¿ç*ÏYöØLc)øIÿÞUmŸpdPº`‡ö´K[w›ž÷ŒrnÇÌØ(9.Á!Ášç:J§½OƒMÈQÇh÷Aq}(øÖKrd“WâŸ~àY˜,wµ-¡KaKNi¶¬öLÝ>²ÓÃ_VŸŠ“¸Ý8ë&rØ3Åâ©óýY²~=YºrKSeÛÉÙ€xÿ^å);O€¥Ç,–ºò”ßLeßRxT¸Óïçì|ö.io=l}ææ9ûŠ=ýöÌÚ¬WS%C•¥mÏv~)sž†¥Ff›¼ò"Ì‚¦Ú|?K#¥-:rÆb¨«òq]÷n°K{õ™o&GäÓsݤÀÀ@­±9~õ8ªkŽqpÔÖÃÈ—Û,Ý–îKwyÉšS `d¢ê*èrè2‡òþÆá²×ÝS>t÷‘u'£äC_eéæ“!²ïå{ì÷SןŠ‘í°AéãO±4m:K½îg©ÍS~wþ÷Sîâ쯿Ïþ­¼Ž°ï”ó óäÐä¨]‹j3ô…eé}k:ßÈìaé\°ôOúì¶5’¡: Ú¶KŸ´÷3kÝßÇRøòÊQøùj“Òßw('k™Óg¬uœŸl÷]ª:êŸ"£#5ÖèΚ%°ÈÖ™,=–nðŽSß}ãi°ÔÝOö÷‘MîÁ²ºåxlp‘5a²úDnCeÓñÙ‰XÀGˆ­îòð–-'BÀR¼÷·†mn)¸¸ÕuŸÇýÁ\_­®öN›ÎÒS¿ÎRW%O}|§å÷éó³/ÖÙ;ÖÒlõ: ZþüèöŸ‹2ïô\X:3ï©3m¹È©úRãã™=>þÛo¿­¶›ÆK‘ho±ÖÄ`MÔ“Î;ÌÌ=Ùõ¦ÓXŠmÑö´9:|öéyøù=‡|õè9ÚÖÚ¦y|²”¡Ò>ÓQð…¬ñö÷vÚ£Z7JE,Ò•¥‡ÈR0”1ÐMˆ{î‡}¹\\*\mÌmðÝ7"†¹æt”¬†¾¶åîã^²ç˜§l=(<Ã/„ÆÈFäê7ÃþÜr*Ÿ©ÏíDLõ“ãǵ^€uQôëÕ.uUæÌèëÛ,µ9Ê[ÆO9󙌢_OVž;«ûmäÜÔ>äcÏ‹¥®ÿ¯øÿŒÿßìÿ{¬ ö@,ÛêÇ7,52{rO6KÕ.miUëÿ·w¥Mm]i:,’›}`§Á «Ù7 „ÀlBH,  $³x·cOW2Ý“éØÝI¦’TR“Ê$=®¤'™ÌÌïÊǺùðÎû¼WWlcÀîŠM¿OÕSWº’®¤{îyî»s>å¼úSõ0¯JKŸ3‡~²–ÂîLÄJŒëèÿüþ €ßú,-5ç,-½ºIsKs¢¥ eN<¥¥ÑÒÖ7h©/Q]øëç–èiëh-×DÕ„oQýüu¶A—¨wržëž68gtKö×°½YÇñÎKs÷X#ïñûî²?íΈԎqÝ*jIæ_RK9W¶Àù3Øݦ–ŠžÞº%ZŠ¹¶ Q¨½ÄùâófžCœÏj)Ö*ýòﯥƚ3ŸIßÔRĆ¡¥iœÇgjîIñZƒu´Übµ>.,,ä¼ö¢øVÐQäƒÑ§0‡¦ÔgÇ™ÐÓãòZ*ódrc öÇKEGÿûå´ôÊæš7jHÁqÖ2ƒ»ZŠÜ“'¡¥q»”}ün©‰ºÍZ·Íyyhé6¿~›5ðÕÍÝàŽ—úZ(_œ¶óZ:½MC!¶ cüü¾äêólb­ #gô[ÖÒ»Ô5#çDD^Ç>ƒ¬¥ ¬“&ùýulƒv±CK=㬿‹TÏ6k•h)jnSçÔ5Ï\—|3¿¿w6&c§&ƒ4<>Éúɶ3kèÐÈÌÉÚãî‘{æ05ë÷M1W ꣎£¥÷m“õK>ý7úäóx,†·¢ƒ/y ˜s‚›ó‚cì2ƯbrŒÙ®ÃCÔ‘aΕ®v©âðñsssÉ3æ¡wÞyG®çþô‘ÔKCß’mH;ý²Z_ë^Ö÷a»õù²†ÇCJŽ—ŠŽ¢®ôÇgk)rѨÏ?HKQŸ0Æ:„µ>]½.$ÇC^/ÛwãÞ„½ça[µ}vSüóŽà& Ï°åç÷%—ß馦ÙëüüÛŽìÇîRÇÄ +uù‘ë¿)ûÀjäça£.2n³VÞ•úÑnŽà;<¬¿KTÏõR¨·2Ž“:'V©9x5ú>çÀ¸fu6Jý“³ÔïÒåÑ1”yèzz{¨«»‹:44:DÑÕèn¼”ý{s‹ñ +ÇÕRÌ1b®k`®%d=5ý“—ÒÒ¤µäžÊ×Ù‡üP®;ŒÉÇÜîÞ>²Ù ¥éÓù:ýµûŠBq˜<>´tÈ3$ó½ažÊ‡<”1˜ïü“Ow)ZúÅ«ÓR«øá¥ïÂNØ¥fMטJÔß?­¥ßÎ.,GèòåËÔÞÞNí]íäèqˆõ ôÑÀÈy|ÑRÄ&Ýœcw²föM.ÒˆŠú9¯ÔÁöh'çà“ ÔàÜüçïÙ†ì˜\¡î±0“ó÷QÎéû›§ÖéRð +çú¹î‰ÙÂyüîé¨Ø˜^þÏø8õúBüykMŽMvú©k<ÂûWù7Ĩo*$:04Býüû.'uvwR[Wµv¶Ê¿?‹ìúø7ü“Ôîÿó»Çöñe½Žó` )â/‰öÿìåÛŸ-Mº®0æ÷ÒþõÇ…ùU{z\”a³æ1S-U¼)Zš——'þod)"c+1>kÑÃ×GÀ$lUèÖ‹L&â]àþçÉû„üYôO±Yk¡ÃÆwa^ÌE‚¾†z'ÔEaüÓ·?|Kßýø}÷?áó# –¢&êúuZZ2Ö¼onn¦–¶jmgêh£NG'uõt‘{ÐMƒžAa]õ‘×Ç1Jß8Û²~åí ?7ÈÇxëÝåÐ(8¾ûÜ;Éú7InÏT‚—y¿Ç?Î6°_æäôòw {Ï ás8†g’}wÞ2FÆ©p”úú‡©¯·Ÿú»]Ôëpò½ M~;þØÔÒD—/ÓrtYþ'´ôö­Û2æ ÿkãíÑR¾÷ ö ?ÁŒùcpŽQ× [4Û&¹í…¼ïYí$â@û'm¿ÿÊÚZ/Ëå?5Íòë’ýÚ}E¡8)œMMOçxi>yÇd\l‚®5ÝØÜ=‚FíáÝ]bv~÷¾Á;÷é[ïÐÝ›wéî­»tçæº}ó¶øœ’_æÇè/ØoRú?ú MÀÚˆ¡šóq`Ž(ÌkòŸ?ðãÉöÛï¿}±–Þ¸!óÒÏÎÌÊz%ÕUÕT__/[[Z©µ•ÙÑJíÎvÑTW?ûÿÃðÿYSG< Žì{|('Ñüì°q\l±o˜íM<–í ¿Æú92à¡þêíî%W‡‹z:z¨§½›œmùÍÍMÍTW[G••Tj/•çXcîúÕëâÃ5}|Ü “}|œ/h&Æ‚2ÿÖ=’1X æÁ‡Œqcüy³­eÌÿ{»¼}îÜâó|“ÏqœøÎý×Å y'¾ŽBœ°§1æ`muM®¿H$B}}}”‘™I¨ÙC,J{²âuë¨Ì_šÏv©oÌ'c-1Æ«cŽdÌM„xÆ+î'ö#¹¹ºIÛ«Û´µ²• öm®lÒZd–—hiyIôÇDíar}u]öá;#шŒñ„þ»÷'ë}ùÕ—2OÖ}‚ŽŠ–² +m80^ +-e™ä¼MÅo*¨ ¿€ÊËÊ©ººšš›¨¥…í»vfG‹øÌíŽvrö:ÉÕç;öUÐÅt»ÝûsS¯‹·Ì^Woüyoâ¹Aã±³ÛI]]ÔÝÖMŽVu´tP[K;554Ñ… É^b§¬Ì,²Z­Tù›J +NåÞ¸~C4ÉŸ;ï)-ýK’–~÷­ÌeðùןӃнßÞ“ZÕØ·ïZ¼}WWiku+ѾҦÐ;n˥ȅÃÒfѵès¯“ŸÃ|˜g×îáøÞËý—)¹'øøœ#ýµûŠBñâÜ“áã#?ÅܸžES¯¬É5þ<®¯¯ÓÖ:÷µõmÚˆñg¢Wh3fè(žÇb +…(¼–þ'zÊýú)ëoÄuûðìbÔ¹¢I~úÖuúýû¿§?ùXÖÏûú/_‹¦šsÁ.E=,æÌߣ¥l—‰»¹M>¯ÊìedI·ˆþ`Íu»ÝNçΣšúZjlmÜ£©ˆC¾Jvvu’Ãá 'ûé :wã5¼§­³…²?ßÎúÙÜÐ,Ú_QYAÅEÅtúT6ÿ¥¤¤ ¿Mg+ä^quëª1ï~<^Šÿ/5Q_|!ógÿÇzÐXoOæ;ùæÏbÏ?üÓCÑPÌ=…–íoßíµmÑÒ(·ïòZ­Ší8¿0OÁP—iu}Uxеràu„{8×®¡VVæžá}ýýý -U»TñFØ¥¬¥¹y¹R3MÃúGBè)jŠžG¼ný}OìÍU~¾².ó,£5åbçÆãòÞ$Šf'é6ìÝè +Û:1Ã6ÂZ"XëèáÇé‹o¾{ +Ú-ýì³ÏdŽ$Ìí‘x½µ-8,ŸMÖWÖËdB;“¿·©­‰¨êb•Øѹ9¹œÏ¶‘Åb¥S¹…;ùÅgv¬¶¬_ ¥gÊΈ‹87Îþ»ùÿ{F®sæ›óiÃÆG]<æ©EŽñêöU¹§á~f¬wµ¯}¯°¾­m$Ús%ºB±åm¬lˆ¿Z3ø]#‡!®óšÃõ‡{ªËí"[†MµTñÆi)êc±Ø¾5Üâýë(4íÍ•5Y[czfZ45És˜ÐÆø=õ¨4¯9ä>ÑÞ¨µØÕRõñoÆx|SKa˜}Gls}ΣpuWKÑ÷ÐßÂacý7ÑÒÅÅÝ~ûŠm +¿q͈ÙBO¡Á°… ÷ðßß}ï]±¯P›ˆØ ©¥Èa`œºŸóæÃ#ÃÔÙÞIöB;Y¬\[côIÖS6ír|™Ù?s?ýš;µ¨¸ˆJÏ”Riù³i/³Ë{0æv ŸÏ‚B*È)åæä*²óþÒÂ8ù±·Åsrsø·Z0¬§ž¤Y¬ÁÌì|wñÛU{EÕh¹Y[F´´ËÁ¹¬ÑSäôÍñù°KQÏ„üüƒ÷9zëmmlÉ=IbØLØ™ MÖÓg´)46(rìÑ¥¨¬é‡¶[˜“x§´ÇeÄg?Æ5#×[üûagZ +ßÊñR›ÆK¯5‡â¾úý·°_|qhl:}m-Ê~÷a[_Ðì{ˆ•BÓæBsgƒt˜cÂîI&üÊå¥eécÐè1êFábÉon‰í„˜ÂÐÐu»º¥&¶`^nÇ3[,‰>™SXnÍη;Ó­™ŒS9¬©–Îq°ÿoÛá˜db›L‹Õº;qãŸcŽÓfl-¼Ågxk³dîجY²e›’ã xÍ*¯'h‰†·¬¡;9EeONåûYGãú¹‹””TÑRhuCSƒüOøÄÐT¬¹‚{Î â"ÈE!®‚{‘œ7>‡8—Ñ·ïòÁms¿Ḡ¸´"ŠöÃþpˆµtbŠB³!£þû¹ñÚ‘®&Ú ×ÛrlY8;7+µÀ6›•øœ<æû j©âµò£÷dåk¶º¶ZÖ[XfÛ#Nñ­¹ÿ•ËC÷¦ƒÓR03=#ýWúð1ŽgSŽË¿ š07?'s\N¦)0  ?×…z¼’?G?DìñRó%±'k„]j±e>Õ'Oç[9éäóàNIM¦¦¦»SR°3þ¯±’í%¿ÆuºüšÁÔTKü±Å͵»n¶«ÜVK¦ÛjÍt[Ò3ø¹Mö§¤í’ë'…ò™4«›mfwá™ó¶EŸÒQ€_9ó1â¨gÞ>#±Ä]1 +ãK‘G NÅfœ™Ÿ‘Ñüâ¼ÔÚšç|Ñ9-rž=ÌÁùøûùž8?Ë>‡oŠf³Y<Þubmš|Ýù¦|T]WÍ:Ê1n®/ÕÜ“âu‡Å–QÎ6ÑãÔÔTÂØ'ŒQ -„×44 q±£Pì&|Á` Hþ1¿h*ž›<ê1…q¿D¬Z +ö{©¿§ŸN‡h ò9fçüÅót:;[üå̬œÇY§óN„}c±f–³µ;ñ™ªºªDîJjœRÛ5ê¥@(@áH˜–¢K¢¥Éçñ0ç}yžu—™gŸ`žÛ7Ì×Dx‰BÁMZzœëdÏ5Ã1óš› ÏÉý ¤¬Dj8ó“-ãÔ‰h7ÅÉEvQyÙé|ûOè“°qPÈ9ˆ°jÍ\ÑqÍ LhltLj g§g¥~ûçù=&ÃG?6⯡¹Ø^ž!¹œ.jïh7j›˜M­MTUS%9%ü/¶ )·èìOù%'¢Ofå•q¬—Û-]â¼eåeTËõ]¸˜šŠñŒ5LQ·„_hÞQÛpaÞ`x.,÷Äà$Û»3so„}Ž©£ ÃÇoO\g¸ÞfæfÈ3ê¡úÚzù_\ûõ7ö%üYÙÏ´ÏŠ×y¥•ÖSù%~Îçÿ6@qa1566JÜ ýù…—ÑÒ‰ñ 2|Á©YòúiÜ;N‹³Ü·Cl“€s{íÙƒhÚ186úÖÁ8Jä):;;el~?rò%E%”iË›”sMOr +Ïø Ë.œˆ>É÷?+k©/Ý’ñµ^YY’û¿X{Ѩ—e-ut;hp`PæÄ‚V™qæã¶'bÞˆ`¬â*ð70—Sp"H‘PDÚR¶ó‡oO“»…Üæo©¯«—Zµ4n7¾þ¤y'Å›‚<ûÛe9Åå?¥Yd öõ󨲲RÆCûÇijjêèœ4èe›Z:62&zêóøÈ;⥀?°K¶o¦ØV=ÌqaÓ‚˜ÛrlœûõØõö÷ŠM*µGuÆøÊü¼|Ê°dPjJ*q­ÂÖR¿-+÷Dè¨ ‹í”•}}ëÍÄhlY6*°PeU%Õ6ÖÊxýghßäÄäñÚ1‰¨/ÃXè§ßç§QÏ( Ëýñéö<Ú±¡÷]]]töìYÊ>-×!þ×­ùù?ž¨vSœ\q~£ ü¼/»°ô |a©Å±Z¹Ö§˜Î³}WSSskŸÞWż¸»­¾XM5Õ5T[]+Û§x˜cî'µìÏ_¤ó•èlÙY®=*’˜o|.öö‘gÇò3Odä|š•k|)©©?§¤¥ì¤g¤ÿ’•wŠã¹\»ULg*¨ú|µÑà‹Îë ˆ9 ¤=Ñ®Àø±lÏóÜùs”_/õ´|_Ø1u”k,Nd»)N.XK­ìïû² ʶeæìàzfMå: ëÇF®ïÙã~þß“¨Uâº$è'~7kèþKAäØÙ¾q°ÖœèþÈíde:ßJyËýVú[ÖÔŸSÓRå|°áúêÛâïо¬¡»m—’d¿ÞÁZz¢ÛMqr‘_zÁšg?çÌ:]Àu=©\ïÃ}óͤƒùÚñ¿¯A‹¬¥æ?jÛ) +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…B¡P( +…âø#¹çâ‹ +íÁ  ÷Om7 x1¸Wö¤i‹ +íÙ!€0ÀB (Ap$¼‹ÿ?‚+ + =;“ì6Û^)ðmÝ'¤»´Ó§©­éõ)@ªK§ÈmS€¦.­oû%rEfÛ y—Ö=ºEw(€6¯ÿR÷|€\—ºãüt †øB~‹ +ì½piv牪Byï¼HЀ¶é½÷¾i›Þ{ Aïm³}³›­¸¸‹ØÓ®Nw«ˆ½¸Ø;µt+Z±göVr§Ù™žig4#Ít“¨ïþï}™YY…€ A +ÿȬ,ƒ,“¿|ß{ï{¯  ¿t·DJª ÂEn_¨ÀæpKÙ]V‡«ÀbwØ]ÞgÅ>‹Õ}m›Öò9ž«MÙÆsh›ïsÒë8 ,6GþKÈ/ƒz‰”Ö„Šª + +ÍÖ>”~YŒFSÓíèÃ2K(Q^.®Âo¤Âèö‡Mv§ÇšÀRXjKµ}`£ üÄ>‡¶Mk~¼Ãc?•çºy›ïsÒë8M`©‘xMVô[Î/ù¥WKIý˜‚dõˆ‚Ÿ'•F3~˃w jÑâpy!_þÑe%+L°MMž@Ä nª²AV‡§ÐáöÊÛw¡ÕæÄ>§²íšK÷{•mkðTÞvaítZíÄS§ÉŒ"‰Šüw—_Å’¬YP\7º YÕhpù†pIÙl±™q—Ù`0`­“z;{.uõÜ—íËþ?†‚Îåý™ûèXõ¢ãJÍNw ÐTh1 [{ o0ZŒ—‚¥eÄQ{¤¤jž7¹dwyÛÀCXÚ–¶ÙÝÊm‡» ,Å>'¶]Øvñ>íñôXÚ¦µÝÍ÷ÙœîV°´,];¸.2†âe†`´d ?‚ü’_º]’5#˜¥1^Ñ`ˆ–ÕÁÒ»ó ðè) œJK½½?—ºzîËöeÿCAçÇòþÌ}êñ¦»à)Xú%lÒó.OЇsÓ{(ÿ‹è#K!£/³züáYð›ü±Ùjÿ©Élù×)–QQ¡~ŸÉŒµYÞÖo+*䵺_‘©ð[øfþ#Æø¿ã D§ƒ§_(ŽÿÏwùå­\Õ’¥5#ŒØ6DŠ«ƒÃ}àô~b*,üx4ôk³Åþ×.o¨Ùãº/1º}áûÌ?ûo)ÞŒeAÌÅŒø ùI…û«Á*ÜvrÌïok¢ÛxœÜÆã ­ÚóÍf[¾?ܧÛÇÏ“¯SHÂcH6»±"ŠÉxP®%ZRSû‘bCF‡Ûç†ÍxÖh*ü…ÁhüÎh2¾0dÉXåØßéq:iûÁøßÛs“Åò­Ýí;éò…\ä?… ü†¿­ü’_^¾Ä+‡1K!#¶aÖSx‚ßîÏ`W|ï :J++;Êkª;Ê««åZSUÖí«F»MÇ[RQÞQRYÞQ\QÖ‰Ç:¬6ûsØ?ÿ <ÃÒOñ ŠÄâC%K}2æâ”KM`)Å[X`)Ì3« ücŸ!ÅlÀ@¾­‰nãqr[>^}>X +ÓÎŒûtûøyòuÀRÜMϱ!îãD¬ˆâD2æâ)±×Ycqõs¼¬n*®GVÿ6 +uÔ6K5Œ™j9R®;iDÛ9D¯1rDªzXC*‹vXößø"É?K”7¼ST5Ò+­3ÆËêà›Ë/ù%÷­Æ,…Œ1ŒëƒEÁ@¢ô}pô§ÄQ:G&Ïš•Z¿c{jãî]©»v¥ÞÅZÓž¬Û :&©Ýòiÿ®©õ»v¤ÖïÜžZ¹ySjô„ )Ï÷,úÃüïà :½¡Bˆsoºr{ÀØk”§;‘ì<‹µÁi3*v#í7Ó~޶´hku[Ù…NØUà©Ñé p¼î@–q â3°÷ðÒN {m+ö¹xÞßÖdµKa¯]~òó­tÏPqŸ²Ï®<ßêÄcé~Ga¡ÙγãÓ1È8Ϧ)?IüÑÒê‚xy½±¼q¼¥¨ºq‘7ûÞ÷‹ÚaÃÄš­[Ħ=»Å¦Ý»¾ƒW’ú+·lãšRž€ÿE0QòÓdÕð¹¥õM–xE1ZR·Ž¡ûSÛ ó7ð!*ß—]É·òØq=³{ðù¸½Ñ‚@¼¼ ¸ª‘•_òK_X +båõàheÐ+}‚¸8jþ>ŽtÌ\´P¼wø 8pöŒ8ÜÜÌ:D:ÿ–H9¦NºµžšÏŠEkW ئ)‡ËÕNüÄ.ÚæWØݘ cE#˜ièRò«º `©Áêpp>ÀR@ÅÛ,3n›m0EÙ¶”ø¯ÕmU°!›Áå zÁÒ`éyŒ››ñ¹7ƒ¥Í`i3˜× n6ãõ!+¶Øçâ}`!ßÖdµKÙìÍ`i3XÚ Ž²ðšÁR܇}vz åùV'K÷;šÁR~Þk3XŠµ§,²¸KïM=v²Wq­-,kgIÖ4.ò€¥«µcøÈQbÛþ}bÏñãb÷ñcý¦Íûöˆ1“Þ¾` #Oþ,Z^=7QUoñEb°¥-Fƒ„i×ÂXjK•ïËn _9XjK `©,5€¥†@´ÔPT9Ü–à—ÅÓ‘¾b,‹3_/ûG(–|4ð;ø#I¨1¹*äÜCÌ°<Œ~@ åâeÌSŒÛ|ÁDÅv—×GbñŽ%«×Š3W/‹Ö{wDÛ½{ââ½¢ýÞ}qñ> ·y}û^Žûr=æUögÞGǤ×E+sëÝ[bû‘ƒ¢¼¾&euÚR÷çxÛ}ÑÒbj¿0x|!ƒÛèB~ƒÛ0xüAÞ†/Ñ–#f@<Ž·YVܶ: ð!`-E¬«øÜ¥m¹ßóØapàüõø#>œ‡í¸ï?ƒµ?Á¹þc ºŒmß.4ÿñš#ýÛ…ØGk¹­=ç·¼m’¢ÇòãM&<ߨ?Ö"_[ï3+*4ÃGnýCÛt¼?+nã}:ð~ˆCnƒ'3$ªGX"¥5óþÐÏ,kGã¨Ñ⽃žS§Ä¾“'ûE{NœK÷‚¥“„7ìðF¢? —Í”VZœ^/Þ?KPßC!ò +Œ±²:s¹'¾h±1RT…ßkY¡üüé;Ãñã:aÀ5ÌàDžŠ35xqƒ?Tbˆ•5ª'b;Q€œ“N[°_¦ðYÁR#XjÄwh„ÿÝè 'Œ`©1¯4†‹Œ`©Ñ­(p¸È«,ˆãË/C›¥!^V[àÆ…ùBÿ¶GG(M-ZµZ´Ý¹+î~þ™¸÷ô)ô…¸÷ù—R´­îÓ”};—ž¾ä¹=ÝŸã1ê±}.÷ÝþôS\®ŠI³f +»Ë™2™M)o(ú7Áhñ(_0ó…à o_ ñC_(„u˜·5)ûðx(qz¼Ø4œ“ä¢cÛÍ·qÞÉ5í·9X8w#àPÜ€AÊ~g¶_yíÑ`¬¤öèßÂfú®Ð\øÂb³¼°Ø­,«Ý¦È®H½Ýèqúç*²aŸ­ûçÙ°¶i·­/ +-æçÆ÷ðßþoN_p†Ùj á½Déý0îâý†]þðz«Óýs³ÅÒ1¢iŒØyì¨8xîœ8xö,tÛgÅ!Mç²”kŸÜOÏ£× íG‹ Ó¦ 0”rùüßbEÿÆŽ¶X-»Ãõ£ñHiõXiÍg‘âÊeñòºß”Öþ^0Q¾:RT݂Ϻ¶¾‡üΞøÿ"î@4â +ÅñÝ'#Hy$V6,R3rR¶©×|5ÈÌìÔd4Û3Zl.#ìvŠ]½Á˜qZc(YeŒ–6UMÆpi£ö¾Éáò›p,¦hi­ÁKŒFÌÏãÁ~ÍçÉ¥ç;ÉàC,q‡"lÿÆ©ì÷?ÞÚ*î}ñT<|öLˆöÓv¥òÈdù#ÜÿG¸fQ®Ï “Ñ”ryÝ©P"’ +'¢©)Ã:&×/Q4×¾ž<—£ˆÏÏ€–”ÓãJÁ$K Mß#FÿBˆcÿ#í}ò{´bŸåÿ`ž›ÍæÔˆ±cÙ&=ÚÚ"Ž\¸ Ž´HÑí£ø-õL-òù$<÷ÖdŸ¾3s†ð‚¢Ðb¬¿Á÷ùgÚ ý û~Þÿ#ìÏÿßÕwf›Žû?ÑgŒûÿNUå;Àq›­Ê÷éú>•¯­.ï×'ä +|í ľŽ$*þ-lÌxîHc¡u xÚ„÷›–ÑÜ–6ázÒ;¤ ¬nÂø¦)œ,o +U7ÇMÉê±M‰êqɼ|Ø-©3%«F’„æ+˜Ü¾¨ þ08ɾho0^(1Ð8È/¯°X? ^òrŽ"øÔþñÞÔÈqãRg¯]¾ürqTê!ŽùÁ—ÏÄ®ÃGE0§S¸<Ø“€ý™bƒY¢}Ùû•}¡` +¦)X“H9ÜîÎYȬÈÄw¤L…­UÓÛ÷Ó~£0[Ì8¦€H”‹¢ò’7«²L%¡xiÆÓ>a2 +y¼Ê±êߧI}…ò=˜Í¿¶EO¶_'/J€ŽëÖÙÊÞŸ~|ÖmüNŸˆ}ŠH<.¼¿pû¼ˆ!ªòu±ö¦\wÊb³¦`óËï˄—ŽŸöÿ¸²´û -)ø5¾Çãþ¹XgéŸCß`[ÊhÂÚô ®ßÀó û ®Ëß ãø ¾­ûÛûÆ*þÆ,úw›{›ÓZ)©]Y3ffÈ)æÝ…Þ`¢|`1ÅüŒÈÏ3E‹ë Ñ¢zŽ¥Éy$†£ÉÊùiî@>—vаÔK9ŽÌÒ¿"–Ž76uæÚñàÙàd©´M¿;e•UbÊìYbÉÚ5bù†õbÕ¦MbÕæÍbu'mÁ~Òæ ©÷¯Ý²E¬†FŒ .{E ð…(Hq‘>‰žˆ„E¬()ŠËËDIE©"Ú~³*Æÿ-*/e¦ÃnÅq…„?ìúýäÚ‹µתQ`éÄÏ^¹"Î\¾œÖ¥K}×å+âðÙsbêÜ9bäøqbþêbášUÐJe½J,R¤nËûVŠé æ‰ÊºK$D$áxL„¢ø¾ð¾ÂáøC~á…<~¯p¸œÂæ°C¶üˆ½"×ÕÔ¡ +¬pN'cìcHÞëª"KlßÐ÷ð­þ%üªÿøÿ;ø#<ö$XzÚˆŸ %ª&bí°Xìf°Õœ(k4á¶QW‚Ù@·~j·ÁåÂÇRrÜü’c±bŒüî d©5“¥+K¿’ãü‡ ø+ĶÃ8Õ~ÿ¸|ÿ¡¸rÿ‘N³¤ß§<æÔ¹«×ÅDøîÈƉ²ª*p¨B—•ƒ…årÝSÑã¡l—”WàuÊ„¡zçd¯&!b;rº_¸/YRÂöþèñÄqŒË›¯]Ãçt•EÛÍ´î‹®®‰#Èɘ6w.Ø8W¼pVn9/!G#C-Y¾-ö‰±“'‰ê†QCBÎVÍ°QQ_#Ê몠jQQƒ5TZU»ב’b/IˆXq‚Ø›{y<‡S~ËR°ÙSÞÉŸ"™ü3d»Ü.ä‰8Rv'äp¤ÀåRÑ^öûw`ñû÷¿Àçü#³Íõ¿`û°ô | ÇJv‚¯^øÌþh)ìSmÈß3xÃÅx*rï‚Ÿù$¹çQä—[l6É„ ìWâ#žbŒO,½*}¥àÒàd)ìÒC`鈑bDZ#âÚGOÄ>×ÞÒ']}ô¾8v¡çf½pº]¢ )¯ªfSû¤ÊJQZA"–ª"¦Œ˜ +WK++ J>Æ®Žlþ¢²2áõûEÓĉ<6o¹uS\¸qC\¸™V nw+zŒNúçhi3.³›w¤õ‚8ÞŽ±? ¾€vÕ?Ð&Ž¶ÁÇ +Ñš´ýÈ!1qú4Ñ0j$_O‡ÅÛu#†‹ÚÃDm#4\Š¾Óªúzرµ¢¢ß)©Z~¯¥U•¢¤’>›ri»³?ëÒR‘,-‹D¼ÂØ"V«JÆaGR^¿xÛ»·ƒb{ˆÓ½€Oá9üÑßÁøü ù Ø¢¿„ÿõ/áÇý}ø ~,ýÊå‹Ô›ÌöXŠ<Ų€;/Dnò÷|”Ïetäë½U‹Íæ$¥‘‡Ã]„í¿‚ªùK_Ü©3Kë†5Šmö‹öÈ—zø€s¨Úz¤»iݻˌ،<ô8ΠƉĒWâ¨Æ$=S¥Ò\}ó"®GËÀî]Þ¯²”r@O^¾„<´;¢åÎí µÞ~‰²¯=:±þÜ¥KĬŋ8Eü<‡ßæ…[·ðäêݽ‹ÇÝçn\§¯^§®\§p”›J9cšDãØ&1|ÌhÑДf*ñµaäQ1_‡‹p•ìW²e™¯uu`kd+ìײå}ó÷U¡»þ”*¢ëö—˱Ûíe’¹øÝ æO…baøßýߣ¹\È™€?ö«ô©?Á÷`ë¯ÁØ?E>Ö"¯îÞà¿A.ìZìoK‹‘‡Pˆø˜‰rZóËÛ±ØÁRÈñG +\`©Ccéø!ÅÒwwí'/µ#GêŠh¾qMœ¿y½káœ$5³0F…Î]¿*Ž·µŠ9Kãœ(C«Øn‘¢í¾J±}Þ–2Géè:AÇWÓý±“ˆ^€Yz¹ÈtÝ!ž’Ú8/Y^‹.v#õ1ª´çƒ“gà·l©˜µd1³ô¾G²YÛ‘[|õÉûâö'Ÿˆ{Ÿ}.î~ú™¸óÉgâÖÇ‹ëOžàûjÓæÍELl,|­cňñchþ”dk“ÔðÑ£¡QàëHf*«lml„½:œ}ÕÃÀÔ†:Ø­u°[!b«ò½©vk)ìV©ŠNߥ´gá;QüÑßK ¾/IŠhq"FNE0Nyü>ဟ€ãeˆ…[áHÁG@11ä%˜þþ×?Åàÿ_Æm@ìù´å¦p2Ÿ[õ6,vŒñ!CÈ*p‚¥ØZ,…¿´¶a¸X¿}»8ÖÒ"N´¶‰Óí—ØÖéVí2öAÛtî‡w;†±ápŽ'WÖÈ󩢆ì•WÎÇjé¯ÓŸê˜?sìŸ{_wÍdäË9ªmƒÝwÞeM-‹ØáG¾ÒØÉ“ýfÚí_\¤që²îFx|{s1Èï:oÙr…¥-ü´Ü¼%.=x(n|ø!ò‰ŸfýFeÇ…›7Ù/0zÂx1zâh¼EÛÐ(ı(ï`$ò¸F"–8|Þ4Z WÈn…ÍZ?\Ñ›µ‘ý5É«P½´W+kñþ!ú,øsÁ÷¨ñUÇSö§«ö+XÊ~hÕ­clQ™ô / ãž0çvÀK|E<Ìß«¹Ãh0"žeú'§ÛÿûE8˜êÑ“ +ceuÆXiÝ@£ä¿¨c|?XJþRÛPdiýp±në6ŽSƒ|ž/ÎÙã¬Væ/åÚnرC„c1Kéü©¨&ž` ;¥oªÕÆeÕò¼ã±£ê£TÄç¥NÙûº{löcºº_ÿºtîßÓÇ(S•ÊÊØjµu|M „BbÜ”)°áoˆ+‰ËB´Ö‹ö©Ê¾-u)[à0ůæ/O³ô̥ˢõæm…¥ñÜŒìïÿá—_‰Ö[·Å<§é‰bL–È·;jš lOkǃ±ÌWدc¤ÍJþÕ'P?RúÈ^¥Ú¬øê{Uá*ÙëäûQ}7•:ž2K%O»r~ü¥ÒK|¥ù3.—‡rž#—öŸ¼¡Äjëâå#Mȯ2 nõƒçÙ@.vª±fwƒYàpÂ_j"c|ʉúR²”Î÷+VÈz»v‰Í»w¿T›4í[öîƒöŠ©³g äá"¦ÔñçU|¥J|Üb¿üŽ2>Nëù?éxÔcÌuì’’ä¤<ú‰Ó¦³óêûïsœîêc©+‘ÑG]—›¯ß –¯,mmá<«—²ô™ÊÒ%’Ÿð?4)ûNgQ®’šÈŽ_G©|…Ÿ Qµ]»µíVø†7ÊøXÉ Ú¬t­Uý ÒV…Í?@:-W^š>Ÿ‚¤°—òäàK‰'‹)WšÆýß#¦ÿ›Ã»ÂáÚ +Íc¡%ßk øGI†0ü¥rŒ?4X*sõÁÒ#G˜äóÒüc£^®a,ŠSŒT|jMˆÛ– ×'ÃöiHQ8†ÜÅWT(Š×QÂ=QTQOÿr…ð¿µcá÷ÖÝûSîÃcýÁ ˜ß$ù8ÉW™‘ÿŸfŸ&Óó[ÀÍ…+V²y´G,Åuô«gÓšƒ˜UÓ$ðq28‰ü(ÒXâiWÊà«ÊUÉVÉWÕ?¿€Î~eŸD1¬òÀ@’¹uš½JãƒÀ§SR©2TÍ£ÐÇ°Ò¹|ÍÖù(WÖj·R¾ëo‘õµÛ™á ÆBÅ5”'?äEÇwfÄñu,Œ9QÌÒ/¸^ÔØI“¤_ ¿ÿ&Øt{|{݉|”›¨,Stþä¹ÔÉç«·ù¸²¶{.«/Ï}¹²U/Žç°Æ1[h|¼jËfΓ æõ>ÈÔ‡Oz¥k¤°ýäØ—w4–Ҝҳ=béWœ01«&âèt\í$|ßc®’*ýªÝª°•üz›•>“1øœš¶*~WÕ~¥8çW`¯ÖÕ(9”+¡ÄªX2çJÚ¦ÄQyçÝéb]tÍ£0[x×w—÷à?RýDª³3ÐLù¡.6;òKí2¿TæD ©b—žGÓúÛÅÊ­› bõ¶Íbí{Ûz¨­Z­ÚºÚôƒ×j|k¶ma­C©Æè¾S'aK>7‘ÃKŒ“úPê£ÞëºÂä–Û`éʾ±”âÿ|mœMŵq +®SäzL'©×PyUý]Ùªìce;5íЮEÄVEZL \­…ϵ¦ñ«áˆ_ ƒ/ ^ñE³ÝJþÕt>šŒñ)¹"5Ò¤æÐQn+Í“5!Ö¯ôyÙ€ø¾y§&[¾/ä€,v+âøV‡!è 8ìˆ=Y‡K)¼ãè!±ùÀ^±Ú´o·xw﮼^ñ3ظw7×%Ñgº¢ù£×0¾¿õñ'àéÇâ&r“n~üQŸuº¦RžiïYŠ1>žG1« S¦Š S§ŠñÓ¦ˆñS§`[®Çe‰y ©ãiÃ’€ü­[µsüŠýªl§fñTgß«öjýhøF5B#ÀÕF9g€ç +(óÔü€ºZÅ÷*ãY$f)ùÀRŠSÆ“Eì;ÅXÿ{ðôÏì.ïZ—/ìpx&'Îçü2@óž|`éPŠãëXº,Ý´çü=|ÎçYÚO,Ý«²Ÿ+>ßÃγy ùž·>ù¸_DóÔÈ»pÕJ1¾OÉÒ+`é°ôbV`éÔi<ï—DµûÆO#®f‰X«0vüä)i–fùÈNÕÆûìÔñœÇªù?²yÚ$ç +44 £³ ¦‚§¿RòY)7 F›óJùWºüΟ#ß©ÂÓòJª/2[,‹zns¸ÿ_8¹0+³!Æo¢ú~ùeXêj,¥øÓ3ä8ÞÛCqþ³v3òêûg°IߦÏs?nØ<² â懋;Ÿ~.î|ò¹¸ÛºóñgâÒ½bñê5ˆ#-ÇÚZ{ÌÒ6°t!ò7˜£ÓIÓÅ„ééí´$g‰©d¿’;ù]ã¦Â>%;U7öW}ªú8Û¨ç°Ò˜‚ô!wâ)÷G±†5)s¯`ŸÖ‘}Š±?Å­êx^«ä¨d*ÙªõÌSmîóTë—•Rí,Êë§>fÿˆ¸þe‡+àóGJ ¾p±ÁÉ÷¾~Ócü€:Æ¢,}wïNñî¾òÜÏë•?b)Û§z–Âf¼õÑ'âîgOÅÝOûIàéå{Å¥m½déJÉÊ`æ ÉÎwr ù\zÛu‚ÊUÕ^%¶ª,UlT}ìŸx:Z÷S¼_‹õ“s¬O,åøÔhu¾•´Qi.Hm£ž¥4—µÇþ*KÕ¹hjŠòO©÷Ž¬)nûONoèP0Q鬷¨ ¯0`ûñ䇼¨sHƒZìihäDåY:,mka_éÝÏÁ@šÓIú\öiÛÝíWnóó_‘¥Šo@ãèLeÍš!ÞÁzÒôKY*W[UJµWÁS}¬Š™šÉÓ&Jö©6æWxÊuÀRÕ6Ö$mSʧJ×>Ô ž*uWÔygªmJq*ÊûÇ¢‚j§È“rþxZ-k0 _Š4ИùÕ‰ + ±8~Þ.–ÂÇ™›™}Ô§}dé3…¥«W2C©.¿^•õ$0•Ô­ÍJ¾…§2fE1*â©š[ÕÙ>¥˜Ç£&dÆøõ¶©ÊÔtÊO•sVë3}§ªm*}§2¦/ãþ2ç´¹Ïþ ò¤Ì²OUh¶^·X~—7T`¶Ø3?°yOd—æÇøùñ?°ôiÿ²ôÒ}°tÍÚÞùK³Y:k׌ꤙ3Ó,Í’ž¥<ö×ÆüS™§é¸ñtb¦}ªÅø)•í;Ã5«†éYªð”ÇûÌRµ¶Šäiµj›*,•ã|%ç”ãú\{Õíõ +£ÉHõRÿÖbw]±»~œæÆêsøÜ`0þÔjs|â DËBñ2“Û1xÑ×H”î’®¹—÷—æmÒWcé °ô.XJ½´ïC´~K<ýR\}ü,]ßk–^$–®[Ã2· Ñ}ÕS•ÉÔ´O•ÄLÕâQéœTŠIKåx_o›Jž’}ʶi®~ÝX_ó›Rþ¾j›Oi¬ßÉoªÌ;ÕÕ=áÚ~°O©_•ËCyRFäIYþÆæp-r¸¼V»Û_èôócý×]soÈæDP|{Ò¿§æšw§­¾ùM¹gŠ’#¥Ä dþ>õøž¶M³ò£´y¥5•™ù¦Jý~ª's=©Äõm¶ØߌÕU5&+‡JjGõ;O~ÈKÚ.2K‡Ž]Jµ ¿âºì;[í‡pŸ_•«Ý‰k¡Ü'¶€èÿ”zuœ‡ð‘ï›!²K5–öYz–ÒwøŒë¥ô¥ë`ª,×¥²íTâ©«RcTœ@c~ëKUÏSuN?ñ4#OJWE­:r|z¼OsKõ~Sâ©~.Ù§jï©nYZ­ÖíSz¡(=ª½>Õæ{a*´üìÒß+®ÕX?v¦iØņ¦™+AC.W_úK‡R®¾dióµëbù»8ÏpÁªbÞÊebbÞò¥r½b¶Ir{®²þŠåbÁʬù$ÜfáùóWÒZ/Ú§ª—÷)¯Kÿ‡æèÐq¤øý®Pµ<ë}§ß}Ž¬UØ·j¹X¸f¥Ø{êñ%Ëè7Ó})ù©®_…¥í`é² ëÅôùó:)ƒ¥|›|:±ª‹W)6*Ũȇ*s¦ÒþSΗš*sP©W Í‹¢ñþØìyQœÃÿ2–ªµ¥•^~jT]®©6GŸòö‰¥5úÓJTîÓW*" Ê“rqý«Íù‹`¬ôn8YéóGŠ +ýádÞwú&ý¥ƒ¶ô3±ïäIQœæDqâ›Ôÿ‘T,ûš+k½¨wí§~çÑxBÄÔ÷·‹h­ôA§~èÙ¢ýÝÝ×Õ~õu“øßÅ8¶Ut,oVÔ_•Þk"!¥›ú¾õïC½MŸkq±(.)ãú#7?þ¿—gü»é=ÐXº¾W9Qt í÷ŽÎœ¿@̘?_á(­U)\e–æ÷ƒ©j|JoŸNÑ÷õc}ͪÕï{G‹íkq(5ç”óMÇh>ÓácGgð4£çt–ªýû¸W˜Ž¥$¥Ü“úF•p/>ëÏ‘#õÃåŸíöE¬·ßõN~ÐKÚ_—c|»k٥ϸ§s$Ið‰zET5Ô‹jµŸd7¢Þ:.—GaQTR*JÊÊ¥¸ïyßTœk¿Òß)‰ÿ‘ Ž·Á&bT Ó¤Þ¦uWÊõø¢îïëöÑ6ýÿd¢D•ò¼Äž¼ïdQ‰ðûìS¤Zø4žúöK¿ÌbioìRbé»bÆ°”~ê¥ãê´ù¹X*ÇýÒ>Íd)ótÆÌܱ}ÍoúNF\_e©¬Ï§ÌÕïKÕ¼ýô8Ÿ{K©,­Õ³TµKe¿Ùã”®ÍEÂô#Oªð9ìÓ¿G,ê‚Õîò˜Ì“Ùjh ±%ÑÇó—~)v>,’°÷FŒäZj4ãšJü —è~ª‹ +KŽRŸ(5NÝ[¤'ýEôÏÉÙ·ÿ‹r éœIçh¿éÿmSü˜>+êyÅuá{ð>¨Ÿ<õ‰š2k¶¸–Ê°}ãg²ôK¾RŸÉÒ¥l—žê+K.Èdi†ûT/Å6Í°OÕÜ~%¿_¥ùM•¹ûéÚÒéùúéTf-)}?5žß0:s^©¬Ç§·Ma—Ö«s ôu÷Égªç)‰®ãÈ;ÅõÓã÷˾&nÿÀ8n´¤ÆŒ•C‰ŠFÑã†hÒ]‡pÏ;âádØSfÎÓf#Ñ•(71\êóDö!åëQ/£tÏŸ´2úWæèi™ëþ\¯Cç͉¡9Ú,­îśǔ!:Ϲ'gŽc›uìdGEâqäÍ7>ø@<þJ~þ¯òÝ©<¤õ'ŠåK/ô¥ B +7i-ÍVÍd©”’O•ßWòù1ÖÏ5×TúM•Þ(Yùûjm>ªÇÏs¡t¹¦ê÷¯g©–oªôb›”XÚ kG©u÷µ¼}…§²oT…’s*ûðQo‹ÍöÜbuüÜîò­tyCV·?bòøóùû¯ºØ¬°K­`©o(Æž¤]J¿ŸKgƒ™8?pÞgJrT½Mõ*©·1å?Sܕϲ-^ƒ(ÿzIÛ¤I׳nाçîÞ·O¡sŸY:—Xúa?°4So”¥zžæÊ™¢ø>åó+cý\¶©×Çoˆó£ˆ§Ù¹ûJÝúÞsÕ<ÑX:*ƒ’õNä<(¶K•ž&’¥J½fiEK©î ­Én¥çyþŒõåô†n•ÔŽ ÖŽžeŒ•4å#úÁ:ûá.6+âøV¥GÉë÷¤g)Ù§2Gçˆésç‰ó泦³ƒÈÒDØäǤüg²!Æ‘ÏK•SÈ\«Ê¾ÝÕ>ã%{…zsžŒR›k`  (÷Qök¥cÌ~ßJÍNÜæÏ!›_cé‡C€¥O;³TÍçWçGI–"•å7ͶM¹ö‰®Æé(eTö\¨Æ±JmS¥ÞI&KÕZ'õéx>bP”³ŸfiµÆR­—i…Ì=¥¨T±ÂT¡Ùò½7ÿ¿åÃÇ–7L,ŒÕ"ŵ£¡S zHÕ‰ÊÅRiwRL7È!ÜO1Yz^<¥ßþ8•¹˜ø +RóGS-!b)Æ|#ÆÃ6 Ñÿ'[‰®*/s½om?|!Kç !–BzÛTc©Ž§jŠçD)1}Õ>UYJq(²Kå5SWï„mSp4‹¥4.á1~S–fÍJç™ÖæãËx¾ÆRÜW5¼^Œž4>ÖZÄô-NOàÛ@¤x|¤¨ºÐ.2úÃE£!á/ …"ˆã»sÏ{új³ôÈŽ5§T›t&έY8·ri& ÷SŒ–ëî ‡Šì‰4SHŠ¬ŸDçÙèw”ÚpN  xNùJùú‘îÉ™ë¸Ç+=;)FIr–vÁÕlßiOUß)ÇôU–ÎÈš 5U‹AÑuGŽñå8Ô;Yڨğ¨Ç^f>Y'šã„ú<ÓzKkºa)öUÔÕhõÿhœïtû~'çEÄN—w q4¨ŒëI†X(VàFÛCÊ.Ý}ô(û‹h,5 cP×ÏY¸XÌY”[³I qLº c¥"ä;›DÜ=´^•ý(’Í2Šk Éq_·âó¡ÿE~Ř鼧÷Ëý©—\§ãN÷C"D‡KõLUòPÓó£$K§i,UÆúYùQZï(¥tÝÑå™j,Í®5–íü³To—*5Må?“¥t›8K~$ò] ¶Ÿòø߇åÿs²bX¼¤v´!ZRmˆ—Õ 4’~iP™?Är¢$K)~4ý ³,ó/ó–t­¹‹—ˆés汊ú*±tÁòÂã¥yP–_úÂÉöP¢ÜMuM¡FÒ ]`)dˆ‚¥®®X:cO4ïæ{*-¯ãÞ™,惑 V¬è,¥†‰VËdÅr1{ñb°tXZŽ1þäÌ~•ý-œwœ‹¨ÄÅZ”[@ `tsÜê\tãýðXšm—j5ùô9¦ÓzÀR]MSµžiOíÒŒºÐX*ëFi,…]@Û4‡lýöí´¯Ãbµïòÿlj GÊä $Iƒ?Ž”qü¡2ï‰jDQaš_–’Ïséºu¬E«VC«Ä¢Õ¹Eþ¤¹K—Šúa#DIYsŽò^HÙ½_Y +8F7ï"vþ&DþšWÎ1énŽ]­Lq+féü¡ËR5žß•¿Te)÷<ÕÍ%íKÇd²”ó¢FvÍR-_ÿåv©ž¥”ÏBc´+WŠGÓ|‹»ÃõÂfwýy8^1¬¼fœ)^RoH– h, ÊÅ–B†°ÂRÕ.5XúTa)lË àá² ¸þÞâµkÄâ5:Ñí ­ÆX¹hhÉv)Å(¶ YÚß’ö.±‹þÌ<(qüž|¥ÌLõú‘yÜÔ·ƒæãÒçBqꉑgé¬ –Žï!KGôš¥2_¿7,¥¾ÏeÈ1­© 1öÚ{ò„˜µhaÊát>·XìÿŠW<Š•Ôù‰*4ÐXä½ó¤¿T­m2,=wíÚÐ`)ìR²ûÈFY¹q£fŸjZŸÖ’õkÅ’uky¬Oõ=8ö¶PŽÔdÙý#}?!µ¾Ì3¢õëÉ¿êNúÿ;aºdé$­¯|öq“-Fù@²vÕÝ#[íú(>¡¢]ú¦XÚs©ž¥å•Õ¢¦®Yºÿô)¶#¼>ß‹ÂBËo0¶ÿoá’€/˜4A¥Á_'J²ô/Ó,½>xý¥Yv)Õ‡Z¹q“Xµi“XNöi¶ÞMo“?‰ü#ÇŒE~©Ž¥úºý$ÎQÄ98Aç¿-"CeŽ.ŽŸÉTˆü'É¢R1uöÛÎÒo`Œ?ã-bie'–VÕÖ‰™øv?&Ö‘Ï´¢â…ÍfÿÓåÿoܾHÈå æû”ömqûB$C¢¼¡Àˆ¹<ÿÏáp‰á£›R'ÚÚ¸§.Õ㌺÷ô©ØsìÿÖÞ™>ƒ9J"Û´+ѹG¢^ÀTŠòK)&”ž7¨ž?ý#ž× qnâkÌaí­Èï Y?+çqOÑõíd–—¼>–¾ÿAº®~k‹8}ù²h½E,} °ô©RãO¹Žæd))+ž¤W?°Tõ#«qüWñ—뎥}ŒãO+ªkøx·>$¶:DµÀR¯ï…ÛþËhYÝ–xu£#Z^gŒU4ô«ÍöCXÀOÖäÕ; ¢%ÕÑ`´äE®ÄsÄ°ST“þÖÇŸŠ;Ÿ.î>ýl"=} ¥×iÝýâsqû³Oųg¸~9û” ¢ò”¶sI½ŸlSúÝÓRÊ_çy/sçjý*ûKjMLšÏý:ó®z¬irM~µ¯<×òèJsg³µ¨øõØ¥4¾¸öø‰Xºv­˜½t‰8v±Eœ»r,½£c)õ>}–ù\Ä¿.Ý¿/Vl|Wá(lÒ¾²t~K»Í/Ñ«üÒÎ9Q²VT®yOõ9sõ»fiv~iØJó¢è·FÝsâ8ùLE ~ápyÿÑŒ]ñ„W j‚Mƒrq{àiÄ€3«/[îõ~†‹ÔNäÝüðcqû“OÄíO?}»nfëŽûøÅ6¶è·Î¬„ÖlÙ"Öl%mÍ¡-b5î§ÞôÛ§Þ,.ŸdôB….¯¬Óãý6YVÖ±Ÿ7õÓ½‰kÿ 0õ­ÖG8F½>”ësׯ‹™¸ö’]ºvË6pt«X»m›X·í½.´M¬ÝºM¬‚o•r“¨oÕMâsŠó ©¾E?IéƒA5Ûß¡ÜDš3£õ¸©µãÈ÷ǬÔzÉå:vyß›bé\øKO^º(šm¹uK´Ý½Ë¶)1µ ãù Øwæòq²ý¢8ÖÒ*v=&"÷Mó•fÙš¬\,ÍYË4k)÷)Õùе~ziŽNÄ5œby²†iVߧ.çãËÚ&ú9¤²NTóž²æ–ç˜Cªg)ÝG¿çõ;¶‹çΊm‡àqTÏô·V»ë÷£%õ ɪх¡dµ!RRßßfÛ_¼¡É))/ôGãã^ß·¡X´ƒì³K2O£è¼n¹}qË•øMOc>/׿·]lؾ£K­oÛ¦ã'OñD1~{°Kás“s²»ï³Þ[1Kq~NšýrW_AsJ÷BîîøÁÒ©“¹—Ëkã#·‚zÄî?w~›ÓâÈùóâðè|3ûqöž:)v;*Þ;x@lÝ¿_lÙ·OlرC,X±’kåfiVO’ó:qvZ6K›”ìòÌùøYªædpŸªU8)KÇçfiŽš{õ`éð—Ô‰ÊQÛ$›¥Äç•›71Kw8F5S—ó{‡Û÷w¾pñ†@¬Üæ ™ FÓ [±$ɘ¬ª+ •ŽwûƒßºÜîšoI,ºòø‘¸ ¦^yøhÐèò#ïãÇl«,Z½š¯ÅËÖ®gV¾»s§Ø¸sWNÑ}¤µÛ¶2c‰"üÖÇã|’viÿ³TúߤÏTæG¥s:F¿‡ß!ÝS>×±«|™Ë9T¯“¥W¿/–¥Ô“iãþÝbËþ=â½Ã¡Cr}è Ø¦c¨*úiNK2z=é{êÞÇTõ½‘/'{Ÿ²­r4]'JæBu5_Æ›TW[Ÿ{•p?Òìš{²~i®ZÐ*K3{;§Yªï»´K¥(–¿çÄsgÄ~\—¯_#‚ÑÈs›ÃõN·ÛrX¬#ìÔFÓ [B‰2’±¤vDa´¤jœ'þÖj³wP|ö4üüÞm÷÷ï µ)kšo@s™†%–®Y+6íÚ-6ïÙ#6ïέM»w³6ìÜÁ¾ÂH".†ã÷=u¾Ïr­õl{æ$ëø˘–š¥ö0‘ÿo®déô®Ž[×™®9ÔÓ™z¿K÷'Kñ:×ÞŸÇøt<ÛÀNŠAï8|Xì@¾¯Õí,‘OpÉÚ5bÖâE +KÉ“¥éÏj¼MŸÿ&óhÕÞ$”Æâï+mÊùÀé\ŠáËñ½Ò‹@e©V“+»GÉØÌ~OPý¨™µ •9Oëêw®]Ú‰¥¸z?!gzÎ’%ÌуÍçÄú];¸ŸÙbýÎŒüq¬¬vt²jxa¸¨ãüêÆÓ ZÂÉ +’±´¶©0^Z;ÁŒýØbµ½{ì$rùˆ£­wo‹–A¦Ö»wÄyÄ(ש×âËVàüÚ'¶v#:ÿH›öìf{†jÓï;ÍR•#ý#®ñO<ÕÕÃìïÖ^K‰Ýwìé±ðD…¥Óg«½óú“¥ÏÒ,w;‚±ü1ö…¾Lï8Àó/¨¶‚´MÉ.Uša“êX +ÛZý´ùõZÚé\Îw y¶°?iÍJ×&”¹P²¯3÷'™<±K)¦9º–ÖѹG ×Õ×õ(Ñú=)þR]ï<µG‰>'Šæ­Ä‹’üì?sF‚dÇÑ#ü?ÁRªµÿÓ`¬d*rzÌþHÒèçóö{³P?WÈP3z†1^V_êòÿµÙbù b‡©£--¢õÎmÄDop\4C·ÞnQ|¢õÎñ.üf4yöÂÅbÛþŠöçÖ>©ÍûöŠÙKqý#ú}O#–BÒ¶é&Ü‘ÿãÊ·¥t d“Q|)#6“%ê5¯ötygšÂÒ9sûŒ¯c)±pÏÉãìÝwò”Øwª Ñ}ÐŽÃGxÆì%‹‘ûÛtÑé͈%ÑØ]²”ß»îó×ê>)õgˆŸ”µÔš¤Ü·‹úa)óoµ>“4†j6©Ž¥ÄQÙÃ@ÃÏìCJ6©ÚÓYíW£Í•sH+õ,­®VìÒÌÞyz–RŸ(ÆZ“çÌ{OŸb–ÒçIÇh±Z;õ­?œ˜N”™‘+i¤|ÉüÒ;–:Ü~ƒÍá1yQ®O[×û{\ó^ìEÅMsêúÛ­ 7nˆ6°t3Æìñâ">ï·DŽòAøغӃì{£œXJu{¦.˜­°´ÿ9J¢s:3~`XJãVöÒø¾›ëqMÍ5"û¬¸cü×ÅÒ'’¥d[î?sJD¬éйs/Õž'ÄÊM™¥ô\KÂûÒÛ£4ÖÐrE3? šÃ¤rTooJ–*}G¸'^®úÜ°91†g‘ý Q?BUÄQ­>TVÜ)»§3³”cø²§3Û£JÒ +K˪ª»ì鬱´¢’{•Ó5b×É£’¥`êøiS˜¥V»ó[·/8ÕŠšÈíò(íåb4’LÈ1³M…kL&ÓÏ‹ËË^lÞ»GœÆ8ÿÌåˬ³ª®¼Ý:Cë«WÄyðt+â4”â:ïÁ&Ý ÿZWRýo¦•¥ÓŸtîëc)ì@£t^hlÏ,%»´›ãN³t¾ÆÒ鯓¥ëÖÁ﹘cö»?ÖÚµv!º¯…™K9Ãs–.ácÍŽÉ«yœß”uý¢5½M:!ƒ¥²¯ŒjoªýðxÜbV¦ûʪœ¤ßi­ÇŽV¤ôð#ï×XªpTei݈œ[šfi‹úàivi•.·ãû –RÏ'EÅ£½3{†Øyü³tXJy$V»­Ãbw|ëð¦ºÁR»Çg„ò,íå‚]’ÉfwÛÃ[Wh¶ü}¼¨øåbÒïórö›(ÏðôåKÓ¥'Ïh|¿ëèQéS#¿[–È· ÷QÝSªýK&9·Æ‡½šËÝË>¯cNU_¤Æ¨9&ÖM.û›céWâú“'bùú \köäEúnÛÅéK—^ªc-8/jÞ’eÜQ9ÉÙtνÚST“..¯Š|¢ôû¡¸ü8¥G÷˜):(å9i,¥˜Ò¸L{S»k¹NªÝI±¥Q2ÆDþÑ&sJ³TÚ¤µ#†+ã{øI¹ÞìRؤ嵰G)Šó¡dÞÇ—ÀK’ÊRò“Òøžî#ÎN‡]°çä °ôÛúd·»½^ªgú­Ýå›êò…Í6§ÇåYÚËÅáô’Lð=#5·Înwý<‘,zAc¤#È㣹ù,ü–Ú˜§4_Ž~ô»'uÏqøÜŽŸÂ80CÊþ=ÇŽóMf ÅÌ~MZ¼)ƒ¥ð“²M*Yª¯ù”f©:¾WâNº˜“ÆRö‘êcJÄÒ±”òF™§`h=lÔ®XJ=ðÒóF%Ki|_R•‹¥J, +v)ùg‰›4”zPÑÚíÛ(ïŸXú¡xIk¼¬Ö Ÿ!/-ȳ´wK$YI2&ʇY#ÅÕK=È·—+5bܘÍÏ£š2iaÕ+ÏÇšÿ6Åž>äù“§š`w?ÿLÜ}J’µ ; ÷ßn|ô¡Ø±õ•ÕæëfÕÊÓ¤ô®Ò÷¸Ws¡¸çb“Ò\ÐŒ9L¹÷ŠŸT?'”böM`éhé+ÕÇ”´~÷Yœ$Iž6*s(~ŸÛg×3QmR5¯4›¥jN=‡æim?rˆý¤ÏO1ƒÞݽ“ØN,ý.œ(ÿƒdåðDåðw ñ’Zئù'½YÂ`©7˜0¸ýQ³/œLZí®‡È3ýUU}í‹M{w#ú$3‰úÄ(gz÷)ˆÖ==V¯ìûºzNO^7Çþ=د+Åçç.^Âý›Ö½·Mó£êu¢ØÚqu»µã”E¿g'ʹˆ¯‰¥YµÝÞ*–.`–â5‰¥”SB¬¤þ²Të[Ö|Î!ê©€ûï~úûø)þ¯Ží;Åì•ùMTÓSÏÒLŽÂW +›TæA)öh—6izl¯ß«q§Î6)qTÇRªGŠø<­‰§’³j¯<9¶Ï˜ë¤Ìͬ³G"ߨ*‡¢š(+6m{ÏœÌ`)Õ‹ywÏ.>>×—òbˆ””ÇË pÒàåç>õv1›m$r£\…f[3Õ4Œ—½ ú\ÌNøwG¾Ðñ£R'”õKuŒý3,u[{ìÛYÏé´¿‡Á~:V>^ä7Q?ðêÚz± >·ãYùœgÃj×­ÛÙƒ]JqT'Ò\ÄKç¿¥,}Ê,Õ×ÑïÊ7@5LéúH,eŽæ`)ëg©=aU?i:*=ljj=u¶I)æDyPÄÑl?)匪®«EªÅ”8>ßÐ)׉bJ4†WíSž?LWû™bNð{rýg­^i•.??-ylÅ}tìÛŽcû,–n9¸OŒ?V`,*œnÿ<þhÆ©·7Lê5K~è‹©ÐB2£.¬› &Ó/‘ÐsªÌL‚ïiçÑ#ƒFjéÎÃG8×»¢ª†çäŸRç Q*=¶Ï^’ÛT(V’f)Ճȳt`YzOaiOü¬÷ÀÒ“`é|°”ªÎIÈžo¯‹Û«•¶(I­?Jq{°Tᨬ/sôÕyõ]ÅœØ&Uü¤2>†Bud“*,eŽSãó5WRyšQˤ®^‹9ñø>g~~Z4G¥¸¢”ó–nX›ô”ÂQÝqü]'‰±Ó& «Í&lv×\Þ`E´¨Â€üHÒ@£iÐ-F“…d21K­Í£é—¿ïùÊM›RÄ&ê©Mµö‰Mo½pœ»Ž€¥G`›BT·´²¦ŽÇúÄËæ«×Ä9ä*R¿ ¹ÖéêUÑ|íªØqøˆ—$y6c|š‹ø:YúÖj@íÒgxÍ'bE–]Ú3–>K/²]J6©dig{4]ãizFÌ~¼n®¨V4›¥ÊØ>›¥6©n|ϱy¥2JÚ¤ÒOÊ9£u°7k«¤í nÒ¸žÆüÙ5ôµù÷JŸ¼L–ʱ~Qy©H”K›ôðAG3ý¥{Nã§ócÞ|YÓ‰çOª½ØV’uJ9Moús±ôÕš{zÂùik{ºû¹ô—öä¹ÔŸôÔÅK’¥ª_TÕ«óCu5Gµ~wlêz‹ðØ~¢´I'uÎ'å%óEÉ&%†Ž’c{už×Æ—~RßÓø}¸jsÖk¾R¶;™¥’—4O”Æöi?iú(ŠÝóšróaCPümïiÕOšÅShói1iîLfiAáGF£©Âjµ”e Ñ4è‡7D2¹1—Ón.´Ø~i·ÛŸÏZ¸0µeß^±õÀ~Î}&®¾í"îÓ};Dë{vóovò²Ï^º*ZoÞæ¼oU­7o±ZHàèÅ»wy>7]Û©v.Õ«¤ÚoK©î‘^ÄÓ7{Y,EÌXJvaŸøùe¦dN”dé…¥{ÈÒûŸ‰1È®­?e¦ÒŸ°+Žr (}í’4G9/Ø©ã¨:¶çZÎYñ¦N}F´˜“ÊQ™/sJÓã÷j¿ëjä«cxæ)ö©6©ÆR}}=}ÏQmî=ž[Q-ÆLx‡ëb§ý¤Š.¨O/œÓα´,5V`› ši§?J2¹C —Ëm¶Øœ`©ãù¤é3RT™j'iW{£mŠÔíìûºzNO^·«û˜§©æ:XºqJØ“¦Ï§Û.‰¶[wDÛm©ÖÛwEÛn+j¿khÐﶢº–ÏEÊKL÷~ „cx–.àÚZ(bé³~féûOÄò ½g郧Ïૹ!‚¥“gP?­ôx>»W stjš£ãôÜ™££¨(õjšÐ¹Ö“ô“*¶èè´Ÿ4¥ä‹*1'fiN»S©ßÌõðÓL¥±¿–¥Õ|Î]Ç„mÒ%Kyî}w,%ÍY¶˜cOÃw®ty¼à(¥yœöv ÄÊH¦PQµ+/ovx¿t8\/šÆOàÞTGY«¥L} ö÷L[»Pö}]=§'¯Ûù>•ß²V)Í™£üª[|²¥]´ß¹/ÚïA÷ˆ‹X_¼¯ˆ¶!šWC=/0&+Çï—XJvÍ떽غõ‚=¯ôz™àq½±4í×T8Šm:ƾ¼ž&íù/?~ºŸXTDvéÜy`)Æøœ—D9KRˆ«ªÈÚÝí,©½óVô…¥_<0Î »Tí ˜ÍPµ–žÛOÑqTÖjR8ÊRíQ¥~Ép”bß¹û5¥k9gÔ Õæ9é9*cJ•º˜ó’ãJé¼QÚ&žJ?©º¿ëšPåˆí3y€ïi9ù¹YzN‚®ZIõMÆôÿ^©Ãå!”æAÚ‡%V>œdJV7¹båçñ »Íù]mÃðÔBä-^½F,ZµZ,†¨ÕG¢íþP¾–õ¡¤c¥X.åLøŽ8qᢸ|ï¸üࡸüPö²Ru ûH—='.]äó YZÊq…1äükƒè^ã&Mã!Z¿ôñJ,CõÅÅùJܧuwÊ®›I·eœ¹ëÇ¿ì5Õã õ8~]sZÄxQ1¿×CgÏ!OâçJH]§Ið[žFžYz[Õ|ÒßV‡5ù:Ï´_G›/ ‡b±X½es¯ü¥ÌRøkÈ_ÚUïj-‡T©£'Çõ:–fpcz56)±4W]=u|Ÿ“¥<·ž8šÙã^µIËkÀ@žª‹ÑÓ|&ØžjŸ=KilOÍÅÒ*ø 躸ãØîEÒÉWªc)iÉÚµÂç÷§à+ýG_¸èz(Qé±s?_ô·K¢rdõr Ä+ÌáâÚáNoè,VÛ?ûýïKÊÊŸ—–Wv—á„浑]¯ôµ¹³º»ïõh Dõ"Ç(¿ñ1üû³h1âK7ÅÕGïsO6©ÇГ,½ÏµO)§”ú›Ô —}ËTÑ\”ž*k­æ¾(ÛÊyD6HQâ­%%œÃBÛ=Q²´yÅ\ç:VTĽ©¨~@¢¸¸Ç¯ÑIxÍ$ŽƒÎY:¿«•²z¼ªä\Çôû£ÇSmBš›ÉuQ´,ÔÏ +·Yúížícû¯GÜ# åD‘ÍÛ#–®¥ÞÄÒ‰ð‡Ò˜DµCU†ò˜^ßwYés§æägøG!îJ e›tŒäè¸îóòÕÞöªŸ´SÎhF|^ÏÑì1|¹bŸ_•˜“kRãMÒOJj1’ûª}:ÇÒñ'ª½·fÛú¥ + ÍÏ}áâ?ÄÊ#`€Ñ™Ï/íÓHT’LÁ¢j?^~Éæôþ›Ãý[‡Û÷Âîtw˜-Ö”>ª¯»iïAµ¢Iúí\Ú¢¨»Çô—2þÏyl{Úz`çæ'¯ð!Çœyþ6­qûÆ)¢û>äÇEÎÕŒzO×ÚzþXE™·3ïÛzh¿Ø´oX·c›X³c«X³½³hô’ukx®öð±£Åü•ËÄ‚ÕË!ZKÍ_³œµ`MÖþUËÄÜKÄhʼÙl§øCA®KDû¬^¡I{ ~mu;ý¿Ôûf.YÀcÌ 3¦Š•[6ŠÕÛ6‹ÕïmÉ:îmbÝÎ÷Äƽ»Åæ{ù½n¡Ïâ0ò<Ž;úY;‘×Lµt®`¬ mÒžùbiîS+bˆÌRptÆï¦À'ªÆ—[”ç3)õHÕž"iÿè;²Î³2¶W:b\&G3j9Ó|Q%/?sŽ“»¦»¦ª6©Ž¥Uz–’­)íN5ïžöÉ9N™ UU^YÍ~RºþÐï³k†žcÆÊyùçxiYu5ÕÝ{áýI0^uùÂF·/Ÿ«ß—%‚q~¤¼Ñ­a•Ôãš4ÅJ~î&ÿ¥ÕáýsØÿ߃¥)Êß¼†øê5øÇÈGÆùkæÃ?E=uɪj\F|i²Ž£9ü£ÌQê5B1ûLŽÊšøMÍd©Ò_DciV=gž[¯Æ›ªu,Uû2Óžü¡iIž*ë,ÅøQÔ6 cÿçžS'^ÊRUÔ¶t‡Ýî|îö…þ½Ç‰:]>#Ô7Ã,¿Ä0ÖUŽ0„Šk Þp‘%˜¨*󆋇™m΋`é/]n÷‹}'N‚/Ÿñ<=©§o·>ýÇû9¸ø™ÂGœ»zá½èu½ÿéâòj2bÒ”;I¹è/Å\n|ú‘hÿh{ˆw™=#¶¥éž¸„û··!—|¶X²a8wçšh}t[´=Âs^&åuÛÜavÒk¿ŒìÜs·®‹ö‡ˆ­)j{t¯G¯I,'lÒVâeÆñê„×»ˆ×¥ºM÷ž~.ýÞ7©ŸMn½äsíuî¿ü®5lñ§Ëóüü§Ûu8B>Â#ªóù@c÷Ëtìr‹h"–nÝ(Zî#϶‹c!Ž·Þ»#.>¸'n~ò‘Œ×ÕÇ<¨×"°ô+bé#®E>t•£KuuJ(f§rttq¦jœIãhº÷H¶=ªŽë5)÷jjÈš[Ÿ®AÚ)Þ¤Ô)ÑÇ”^ÊRÅWJ>êû˜;7¿k–î?ušüÈnïøù'XêKÝy–öß\¨B³ÅA,=©°ôùÓ§Äý/žB_H}©¬«èøuâúœ—Óûsø>Û·oØn$Þ©ìÓTKÃ.½ÔÆç;Û“·¯¿·»T+ÔöPr™_“töäÅöPühñºÕ<>§ÿ§Ù¥Ø&ž¿ìµ‰Él—nÝÄþif7K2œ˜JïõÎÓÏú`;¾^ÑÿÊãGbúÂy<7IŽï%Cel)CÁµóô¹à¨Ú·I«£§Žé™££™£jÿ&b¨f"Žæ7eŒíÕzPJÜNÎqªM×sVrI3ç×gòRßgD•ž£l“–•ñqoÚ·»sÔK˜ºïôiÊ¡îðúü/lvçŸØlΨÅj5š-–WnQXš“£ék© vê•0Öÿâ󷊧’¥ã/YÈv¦6ŸI­™7©3GYà(³4«©6Ïž:ì¤>w×-Qû3iM瓪vim6K‘BóCÙÕXªäà«s@!5ï^òSé?¢ˆmQî×L÷Q-“Rž‹F5'{ÌQET3¹ÎnŸïy¡Åö¿›­Žü¦&·?’gi?,«ƒ–ºr°´w±€¡.²c)†r郇š?±;‘]Iãpi—Î3ÍÛ»¸Æë‰:ε'O^mWì]è>XF,mkå¹æ”µpíÊN,m‰•‹ÈõÚrÿq±aÏN¶»(—¦1'éçíâ=¨ã}ò¼O\ûäƒç~¾)–R¾õäÈf©¬á,{‡ê{Ú«uHÉ¿š=7t¤’?šÁQ²K‰¥È?"i¥y÷ä#Õr Òv©>ŠìÒ®æÕ3+¹(ùB+r°´"ƒ¥¢\ÕÈmz©Ÿ4‡öŸ=#æ._–¢~¤&³å/BñòÅU#-1ÄM¥ yž¾âb¶ØH&ðÔûô¤Iã§YJ¹~½‹­ÊÇ©¶,Õ)¾òá#éc|©MšÉR²Kç­X&·ÇíVq´ýBçØÐÙÛàä#ŒóÉ6GÛîÁ_Úržó˜â%EœpöÆÕt¼KµK¯]æ111Tí)Bâ>M܇™r‹uB ‰r¹Ues4›¥ä+˜_Ñö#‡{7¾ç1þYæï¢5«iîÓ 8õ~Œ–~MVùC42Vžgi²T{¢~H*Kö5¾øràý¢¯I˾öÑæhÛã;}béÂ5«8wéÂ=ä!ÝGtA‘þvëÃÛü?˜¥àhËÛ\ÿºq\“ˆ'Äìe‹Å‰Ë3XJÌm¹{›sœ.ܧÜ,©ó:Ñí#­ç9C½¼‰¥{ÁÒvÄ·®âZr¹QÒ—®ó§€ÈF¦\¸+WpÞ<ÏÓy é¾!Z^=Í›%ë4˾v’‹õl["v¤›§§×jóÒ’ñwÉÄ‘ÔDó+JÙCßõ¿¡Zãñ¢"î+‰ÇXáxTDb´-ç^¨¢ž¸RIM1R²ˆ_ƒ˜½lÃ:î!ÔiîýK¤öÐ[±é]á ø_M¦ß¸¼ÁÿyQA—7drzCy–¾â„’ +m. ë3¸^ýÂér?߸{Wê"Æ—ÔŸ¬'ºòþ#ÎE¼úáPÔcqåÉcÎo"ß!©/,•~Î+b»³'yQ`$ùA7ìÞÁ ˆ$cbÚ‚9ì 8wã:ÇœXJü‹·9?J¯tŽùM)?HµK»ei.ÿ)Þûeاô™¤5@ß ~o-°Ç×ïÚqþ"öGÓ“¹$äàRßÚ¦}ä ú´³—,³/ä~4Ô/Q«} ÕšUú·pÿ¹Ü;jÒlªå7ƒ×\uÖtñŽV‹jšÔL¹ÖêLOŸ*ÆÑ\ª ¬ÕÞ|ã¦NÒæä”nŽš'K¯AǼíàþÞÛ¤ +K©¾þ²ëi¾Ç øò~ëôøÿ•Û :=¶ó,}Åň’LþH±ÃŒï´9\?³Ûôý‘-DcKM°iŽ¶b¬¨ªí‚8Âj§®^â82ùÕ.‚CN=åM'–*±'ðor¢Î"Ž¯÷sæ’ä¢Ì+m¾ykùÒü)²¯Â°g¦ 7jÛ¡ý܃•ìЗ½ž&¼.Õs‡üõU=‰=uÉÔ·D8–ÖûwÄ™Wĉ+¡6E´C—ÛÙž?ŽmM—ÛºÔ1ü1™BÌ°;µ§E>•£êZ¿­ß§Þîê>øfŽ(>šÃ-ÍÌQšÚ›ø½ÔYøê‹qÓ&§œnW +±fŒñ‹ŸD¾P¬ÔåYúŠ  +–Æ ž`Ü–VÙœÞe6['žÓxâÆúìç&ézÄÒ_µÎ,‰xAñ™Ù7ö EI–^SÁR-¿ôe,UâMçoßàóg牣<¯“ò™¥°•¨í§ø?î=à(³´]²tõÖW`é[#õš£Ìk ¿H—’ã‰A'mLqGœ½yUMÓ;?©ä(ùæ¯\.BÑhÊTXøÏ°™þE0ZÒŽ—›Cñ2C´¨*ÏÒ~Xœ¾(Éè &íNox+|¦m³Û_ .š¢~z*K©}§±³ô /ܹ5ÈÏÍ7ÃÒÖ°ôÂí[œËD}zÈžÈ`é\ÉÒíG‰=gN æt‰í39Oê‡ÄÒ4O¥¯Bú8Ô5ŠÔü®A'Ýû8‡1 +õ'ï-KÉZ·ý=ö[l6²Iÿ‹ÝéçpzMT' +Ês´Ÿw0Yà†mê %Ín´@ý·‹íûŠšÚŽ ;wà»8Ý=K1¥±>ÙQƒÿÜì?¥Çø½µKïŠSW.ñ¼–ÇH–îPY•vé½ÌÒÇŽðçß|ë†f£eóS¯l–Jön–öLƒûýÑ÷ÚW–Rèɳf ·ÇÛaµ;~…œÒ[ðëyŒF“y¦»3ÏÒ~\<þÉŽ•ÚüÁøFÄôÿÎ uÌ\¼ E¹‰]Å e/™3<¥óyðÿv_?KÕ9§DùO8g(¿é|Ð䯦ڔ;ÀÒu;ÞCy“Å"`é,°”ìÒÃ,Ês¢|(™*ůu_Ÿï/­úKW+þRiÇÝô¬šM¿¿¾Ø¥»‡ ´fÛVÊÇJ!®œrû#?&«¦Eˆ™ñrc Q‘çh?/%eÃH†²ŠFw²¸¶¶é?X¬ÖÍ-¦šk]gÒ.%–R½ 5v<ð¿Á·”¥ˆ=¿{ƒýœ‡Ë;ÜÚ¬è<צ¦Ø:1îb{T‹Žû—ëvnçùá¡h„ç?Q–JokêÇ},¥1áy\ÏŽ¶¶àûPâ„ÊüªsׯŠÖ»`4î7YaéÝ¡ÀÒ¡.½]z¿ÓÞØ¤Ô rÁ¬v{ +6èÏ<Ø©pq­ß)6úc¥†PQuž¥¯¥ñdUAQI­9ž¬íò†×bµý1¨Ô"äEr½Ùßõ> ^2’¥T‰|åùó³;–žAŽéƽ»Ä’õkÅ⵫¡5béúuˆÍ@Üþ:Ç’˜¥Gõ,ÝüÒL–Ò}¤= +K)ÿ“½jó&~Ý%ëÖŠ¥ëÖ!'qƒØ{ò8ç©gó,|,¥±ÅùÛ7ÅqŒWzÇßï|β¥)Ä›žÃg÷k‹ÍñÔé –À?j†¿Ôàtçó ^ׂϙ„TÂìòE¦áóþ1Å (¯‘òÚ('÷8¾Ô–sˆ3*óÈó¶Nn–*5I¨)Õ¼£œÆió沨¯ÒzŒãÏÝ€ýHóA{ÁR¶K‘ƒÚŽkØa|GóW,ãù12Or¾˜µh÷km¡x^7ÏÒAÈRèÆ,äï>Ô£¼ü3býÎ÷¨njÊîp<ǹüÝØ*o¤Ø†˜ˆÑ\Èüòú‡;Èš:mNA0”Ø잌&Ó¯ƒ‘pj l'ª@ßÅ T©ß}¿T“˜ãɃ>žñYz,E^#±¾hæèÔ¹s¸¿ÞÚ÷¶Š³È•ÔXz¬ç,¥|þö÷ù{˜·|)Ïÿ§\óió扙z–ÂßF=žòcü¡ËRÊÉßuò¨˜ƒÅæ,Dü)f³»›-Ö_¡ïß™9}§‹à‹#±¯oý®M¼|Ó±ïÔIöÉQ¼xèÅS_¥4‡”ü¢ÄRŠÇ7îÙ%6ìÚ)(ïlãî]È]9®õ:¡±úŽãÝ°>ãWXŠ*úÜO^n›÷ïåñ݆];øõéÿƹÖrï–8 +[~Œ?HYzÿf7,•ãCõ!5q\Êåõ¤pþþÔáò-Š–ÔÙ£%õF4?¿éM.`hÝá5¹ÜA¶×š­?1vø‚ïã%E/Šh»¨¼ôEIU9×°¡Ëg¯]ͳ4'KçJ–"¶Dý”¨ÎÙ’dËÓú̵+JÜéÇâáÜè9K‹Ó—/qš/A¯Å¯­ +ÿƒêð·ÜGL+ÏÒÁÇR¥B˃[Èõhƒo-wn"qt׉£ÜgÑ +¤lÇwpòJWEÉbÍq åÇöotqºÙ7›lÓ(r)[l®Ÿ9ݾï=ðs’Û|îñ‡Ÿ{ƒØöùRn¯‡k7Ðœý¼]Ú KoÓî°Èº¯®o³„üÍÍÈ-;„܈ÞÚ¥ü|ò± ÷©í.ÕÒýEy–B–*uº¨/ÂIü–rõo¦¸Å>øÚ¨lymuÊlµ…ë@Ùœî_ùÃÉQT1,Ö4y‘!QZO˜äئ~’Á㋆ãåž`¸$)® …U¡@¬<Ä:”¬*÷cáãþe$Om>°G™?œ÷—vÇÒ ÔÿY'ÊÑWùG=¢)'‚æ¬K©öïz-W?šf)ìÕÝ'‰#m祾êLÝJÿ¼f D,¥>H”ƒJìý!ú±5K»°K)&¼pÕ*œ›f‹åŸaÿüK_(1²¢~\aim“¡¨òÿoïʃä¸êóôôt÷ôÝÓsßÇîÎÎÞ§ke]–°…n­îÛ€%!äIX,B&ªR)Hò_*$HþI*ùƒP¤ †*BŽ +EbY&²vz:ßïÍÌîìzuÙÒZý«úªgzzº_¿÷ú{¿«ßëóåÚÍIz~Ól ’ôÊi—~è4ÇÚ)f»ïßÃæ6¡yÙiMÓýas©xþy÷ÃÐuOÑçdç=óæóRÁcxþh šWßÃ]Ä¥ŸžKÁ£{\öЃ53l»È¹y]Å>Ëv£é6!šiçÀ§wšB<¹†ð¼Hð ‚,Ò2¿?pNQUgËÞ=—^E/]½y›[„ôȧ‘ïpòàÔ°|)€8´Äãq,=3;ÈÆf\JqZÊÅ>†ü§“ÿ8ãÒ§é3ÎÙ<_óœäS%=vä¾Ež^:‡õÒÖ8>é¤ãûöÐúRŽ¤(UY3ÿY·c}&ÍGIrˆkxÃÚèùKç—6ðQäÍÑøÙÔKû ëS¡h¤†<G·â?¶"™ +âÂàÑ„àÉÝ/ºeïš"ÿW0ìÄ2Ä ÏIàÒ¥hÛ°'gçÒ{ ­kç­ZÎÞ‘ß{äýlÎQ–;Ú +äX×ñ˜ûþ“ÇÜGOŸ¬ã™úœ|?v”ù9c©{ÿðñcl®™£i~3èœôÿÉsͼ°•æ”dó°8~s~Ó» ¾<\»(¿”ÖUc¹¤°Kh®±¶Î2|¤bUVŒÿ´£¹Ñd›¬é6ÜiŠðäÅŽe þx¶S' +Ë43 +½TqhmÆ'Ÿ}¦þNþ=þŒÒœ““\ºr9[ã’x”bó”‡[GãóñŽ=îzúƒî‘SÇ¡{g¼JØ‹¨á… ™Oó ‚NÒ\ˇ­çsò8ôΧ¦Îs|úùi­ÊŸÚö¾n¸t2'ŠÞ÷½ÇÛi®€ò¶é6z¿iÿcGÜùK×4ø¤óÈ·9Šdšã)÷ÆãÒ¹#±t;ÁŸmë¹ÎˆñÿLÕ*éN´f©Ç¥õ¹Ð—bl¡¹ðiÍ`ZW„ñÚ4.mrëãu€2< <Å°ûð!whÁ7ŠØÍ-Ek“nzøØ1¶%ôÿÈ qió¼ 0þ~\ºßí&.…^ŠTKç—Â_z9u¤—ÒÜ·‘D¬Êó7àcû'؇ âÙJÀ §üVÄ‹7Í%‰gʮܿԟ.ôM;ñÇši]š?ß¡y9Z×ȸA¶í¯â:Ï~¶Î¥¤—È_Iñ‚ð›h¬1RßžLö5×!Ùþž‡ÝÑQ¶Þ­Ï¾ûð#îä’ÿ•@ÿ§u¡¦¡qnº0~`¯Û .ݸ{çä<4×k§ÓwQ}^ëúwº ·»Òº'>ö{O£gh°¦hÚ~¿+ÉúšH²M År|(šå¢Þ;÷sŽK-ä\˜á¼ UÑÍCºe½Zéë uöØ:3Öm£øþíÍ;w³ûN_å˜YAñ¤›8ö¹Ï}–­ÉN<ºèeîŽCïq÷9ÔÀa–s_ßbó;MÇAÆ™ä£|ÐÞÁAöéÂåKÜßË~ßsˆÐ8þ8W+çfçÇï„MûwƒKXŸÞÛ¿Ú½_mßÍÝz¼‰º¼n6c}7Ù~Ux+ý²YO§£~o4wÍñçžsW®]ãê–Yeù¢Ž}Ñ´cQÃŽ r¾u+v§©Á“· AE#ðAY“±= jÆ«Ùbab÷¡Gà#ü¨û@:Y§YnÏ­ÄS”[4‰gØ–å]sßé7í{²åû­.#ÍG~ÊÑÅ‹X~ý®í,î³qÏN† 4¿Oß·ÃÝ€ã×ïÚæ®Ú°–ÞkqCÈǘ?â®Ý¹¥~Ìî ÍÿÌDëyé|«·lt˽Ýl­tš‡†æp#\«~fÖÓ›{æÍûnC[×ûQkŸúè´6¦Ü³ë•¿yüÛ-ãÍüwzy¦®½~Éê•ž!z–žýˆû|g{tË==Ž(Iˆ÷þK(šœg†cÅ¡×x<6GE7#Þ +'3;$«ú«†aþ²T.×`ƒÀ/7[¤Ž^ä™÷ŒLb ÙöÍöÛìvûF†(6Mïõ6¯IÛúg¨2ŒÃ„Á*Ž›èûähÛ,Ç[+Ï ŒÖ·½=nñwŠåJ%7ßÖVß´mß«ù¶ÒD®­T%às5W*V³ÍqhØV5¨«v4\Ís8¦Ø:v:òÍs4χó¤ó¹*½³+«]}ÕîÁÔÍ`£^nͺrX½MÕód½7ëñí‚Õ;Õ!@ï)°>5ÍöCyZÊ6‰^´9~¯M–³}Í6½‰ò¼…ß[ëi²¬3ëu¤µ6ïƒÚe°Ú=4€vê¯võ÷Q;N¨†vE’Õÿ³ãÙ/EÓ¥¶þp"w§éÀ“·!‘d‘àOç»ÅXªm%ÆÆ"–YQ5G3Ìšnš®aY f(äZ¶íZЫØvæç«¡yÌÌÿ…îi‡\#„ól«þ×µi-pl­ªa†ªFÈž0ì:Ì +4¡›Vet4”ŸÙ­PýÜW-+»ö ”¯ñ9Ô(§ªë®¢él«b‹:rE«oeÕ•eÕQ}BU`0à?Š^ßJŠ2’>¢6ö7AÇš@Û:ŒÆ¹Œ–ïÆ®hºnáþQ¨ÃB}„°µ ÏïÍúšD(ÌNU7 ‡Ú˜¡ÑÎMX¸çÉzœ­½o¤í'­ŸÇ¤~Ô€öÒ ‹]í‡ÜJË™¼Ö{`S_dý‘Ú¹Ù/q?8oxö²\¯oè·0ë÷¬¬ædYÑçÐ/g«ïiåní«6î0­‰ ¢N€GôÃÉü`=ú¤ |! +Õ ,»™BçV•‘@:ÏÀ¼ÑiúÕEW?+«¦›®(HNPR.€ã~GVôO)ªñ"øﬢY(§yV5hk ªúYIÕØ>‚¬gÃ8«â7ÍÀ½šbŸUú¯ŠãT ¿‡Ø÷æ>`Çáô_ö» ~4“>c@ŸëõÕ„}Ö°Â/b{ÆEÿ +e¸„º›e©–ÊfÝî´3âZÌV¸…uØÚæ}¤ÛAÍæ .Æm—ÚcÌ”ïûîxQ5ëe×,|Æ} ¬ãµ ôIGVUÖÎÝý ;fø¶••@íœJgQV¹h½õ"Êô ŒŸÔ,ëE-Ô¨ojÚÖË=Uç!´+µ µŽA¾ÓY3œ|^5"½4¿p4ÝÆE3ÞÚMïIº.Ó6À§Ký*lþ¸ôQ?ø9/µH"^£9Þh^õÛáûÛ¾­ú¼}ƾ™˜:†Ö<ž}ßÎÖ+^»uk[¶°\¡L±à¢ÏV‘swQV¯ ïê¡HB·#IÕŒ$ñ\%uÍdÍJ½cüçÁ»€“ÈdjcËW°s5ËÕ¼æÕË|­ûØînܹÃÝŒ¸ÅŽôyí¶-.åáÆSéZP’A¾†gýS²¬—ÅH‚ó’຤ªÛIÕ°“œ(à9VfÙ°’ªe'#Ðg‹c +š4éÞèñY7àxÁñªf³}¾ë8}ÆY¿Fó:tHýZýôV_“ˆ$M›ê/œ°£™ù¡Xúˆ\â‰h"挎-bslÜ_íŽ×lÏkÿìØÎÎKëS/YµŠq©€væÁåºýa(žÝ€vMQ]€X}a ¥¶NG“ÅÍÈ3ù1ÆÖ*ý'•ËÖ­XŽ~³å†ûßü¶nÆïkÐÞ¿ÄÅúWUÄØ^üsÔßž³îøÞ=î–}{ÆoøßtìvÇ÷Ðv/ãÔù‹ï'}Ñú¨x<òUÍ àY +@  Ïòè§<¾óà ¼Ä#^&@ìýf@ ^ ÷¶ÈϸpÉÆÏtnvÆun¢Ìt[÷ís·Øïn{ø€»uÿ~<_リ·'?¨JAõ ôç"Ê!¢<è¥<ø”‡ÞÁCE¹±5P^ì—4}¦ý²nâ³ÉC_áÁ¼àyãÁ•žéo +’| uî„ãQ‡r`׌ãÞ÷µ´3êïfÛ›µy½Ý·ì­Ÿ‡øù¾åËÜl¡PƒNJk¾ÃŽý(œ,¬K{Tä“Ðßpõ:—òáxVȶj±tÛ&üÎø”ìøy‹ÇX{°ó7Ûwï[/gõ>³zÓ&wtј›ÊåªhgÄŠ”Kè_³ìø<pÔeú'êÔ®·1k‹z¹ëe§úŽðà[´-Ú…î‹ÚÇ…¢ÊÇgv}¶ˆGé·õÐOéÝiÄåà33ª‚$UÅ ò86½Yè¥~|çÀ¥œZ_#†Ãs†rck ¼Ø.Åw‹í—b¿ÉáäÀ¥¸”ÿqàR\Šóàwœ‡öK9p).eç—²-ÍMË@ßQ?TWt>;êªàRüÄ¥K=\”ÖNçëvâ+¼ ý›Ÿç'4èVz{k˨·ÑxÔhç7á*õ×Ò'hì¡ÿnܹÓ]µnùFjfÈ‚­. ƒoè¡Ø"©âºt{¿Ëtð07üàV?TgàR.Mû“Ån>×9¬AǾ[ÿç¢$Âgi^éèéª=°f»i×®ú¸7­[ÚtZ9[°wª¬Ä£¤.hµÛ^éªÁO +ÞV®`¬ù Tü—Àå£V4 ú£z—¢Níz³¶¨—»^vªïú-Ú€Ú…î‹ÚÇ…bÎŽ{±¦wº„ O +‚´(«VF3c¿T¬×Ñ÷ÿР»Ä(†ÉÞƒ$k3ãÆ©¾9>³ß­ºéæݻٺIÔÿ‡æ/p“éL ñ›+^øe€¿«êá/"6Ds®?hÈ5 ÌôK6ϵ¤èÄY"üOšý´ J ›õü[IØüôÞ檵kÙ32¾§ù¬7ôÎYÊ9í^ Ÿ¬ŸÐºÊýóXž=å²Táû¸(å¿6‰C¯*¡¼"½C [ÏG¸Û…æh'Ä2mœIK¡x¾ãÂCàïÀ(yCÿÒŽDX.¤û1NmŒ+¬®fáÒqÚâ:®ÉKïZ·žÍCýÎQTµÊ„7ÐÇþ œøR,Û±)Ó1¨&K=<ÍÓIcùL!ûàR¥^¢ÐÝ53Œqó¨¤hÿMþ "WSù¬;olÌ]‰>ÅÚ™éÁ6Ü{.m|Þºo¿»™ÚvÌŠÕ«Ù\^ÈÙ¨Á¶ÙeIÖ¾ ¬²ù2®-Â\ç"ˆ¹<ñäzIuød¾/Ïõ¼;-üš$ë_ŸžOAG5ª‰tºÖVé„/u¬¶ü¡‡Üwãy£wÄßÔo wæV®{·;:v_­Tî¨!¿¨¦é:üP‚ù"|~”´¥p#43*B÷àà#có\o@Ò]ÍpJD_Oƒ ïÿl~ð¿Dk¯V“ÙŒCz*ži¦o­ß±mv½ + ±îeñÊ•µ¡… jm]•Z<¬!–®@úèÄ~˜N’xÆædŽu¶½ß»ãTº_6»U‚Îõt¯€¯âÏ(Æï$Ò©Z±££F~ ª;ÖÎ4~Φ«Øçn€þ¾cìï͟Ȥimâj@”(vôšT¿ Y±÷Úñ|w±k¾Rê½zgž¼jYù.¸–Æ)ÖÎðKÄ 'õw1®]$±†˜;»l§ÚèõÉÕîúmÛÝ­{Áí³ôIê«4N.}ðAz·}²Ìú$lø¿EGDèvü[pE/5Â)!ËÁ¦ràR_$~í>é‰'M)tùò•EðåÌç3m#F4]I³$HÊÃà¨/ŠRð5ÆR9CÑÆq'[*9í]]NïàÓ?Jqï:®uôt;…Žv']ÈÖh­Zò3âY­›‘eþöü±Xª´8žn—L;?rxžo¸AÀ½>pt¬O>}|âøîo(/ ‡¤¼«Z2—vŠ•§ÜÛãtÖúGeŶ2ÐWkï®8ùö’Ck_ÁÞ¥²R,Ì¡µÌ`£=¨‡`Ãu ŽÃÛ‰œ6(‡Éœí<à­³‚ÝÖ¿HN{V@g<ü¾_è‚KíeAO¥Xò]´3ò%èp5Ò×)·Ú™ê´XîpÒÐAC‘0t;É¥±^£tÞËšÿ±J‡/-öŽIñ|­ëÛÜÓE=¹yÉu.$.…µßoÇK¼$I1uØÕEè}ëU3ügðǽßæëЫu˜H}Ù¡ù¦Èo(N@ûÙo°»eU;?áy#’ü) ¶']Š¤Ã•¡¥B2Wñ[á´|zÓå`¹|Ç|?|–nÇFá؈çø¨¬™ÿTµË²¦8ÐcÈV§²R ¤ÊÊŠ­”X9éw<›oà¾Î+¸Gpåwà‹Ü0y?â³&öûaßsàRÂœï^Èo„î×ɺæùËCK%Ä‚"°ÿW@;Òûüç‘Sñâ/GwÄF;£Þjͺ£º„³ÑP§ªvÿ»½÷ËÏÖ9øŒtŒqâCð’¿Ð5êë]øàM••øög!¿mŲ)”w=ƺMàÕ—À…¯‹‚ PÌí Û¤¥ONP™é{½OJاQ¾çyø“~Žó}ØIw<NµE*#+À÷£þX¶yK·©ö=¹$]".…ÞRâ`ãsàQß¼åð­‡%ôáNBGCÌ?ç[½û)_$Y‰\'bÓÃà¤!à>ÃN¼€1æ›ÐÍ¿M~9jcè#Cf4ÓNµK‘tÙ‡<Žâƒ¨oŠÒx|KË ¾ý<ÚYg}’Æø)dŒýÐQ‡?B½ãý—ÐÖ‰²ž†º±Ã!-Žç::’…r`ÙÖ#èß*Å9”³¢Y~\Øg÷´¼žxÒ”—úÐq}ô|ꦈct`–‡É”}±¼·†²'¿â÷ùaoŸ‘7.eyŸà&øês|4Ý;©ËOú+é´ô|Ý)ÿ}ºÔ EÅ.å`ã7ÊÙNà#©ŸÈvÐÅ ;KaÃ'}ÐCïHYïF¡| +p)Ë‘—"/Ö†¯8’GÀ¿Ì‡ öJ’µõòñ€K™nMz&ÇX{’ÍŽ\òûÐ|Lü¸vÇ6ãŒ\g¼K]HÔ„ä@J“âPGÊU‚C U) +zìtT:iJBè "ÒÔ;è8¶kEÞû{6g3‘‹š}Ö˜³<ûûYëYçàÄ{²Öo½{¿Ïû¾ÇMJJÊq7Þxcn¸¡f$‰÷üâ(C-KOÐg’²´¿¾_X·nÝñþï€_ +e§e鉪t}/RíUMHJJºðª«®"O  +9ª:QQ-S}­úNõ7ÕDËÓk®¹†<€y®?:GSSS]vv¶Ó3¾Ÿ§èûEéééä)#GUö~´®ò²Är´~ýúnðàÁnúô®cÇŽNïK-O¨&éç.¶y)þ€cæh±Ÿ£C‡Þï*Ö®s»vív‹-v;u²<=ÍÓÉ×_ýÅÉÉÉä)€Ð;VŽÖSŽ±­Xçöí{×½ûÞÿ¸Ý»÷§§pÜqSÚûÑcŽG×T¬u{-Gß}ÿpEótñ⥮k×®GçéoUŒO„2GU'*ëùóLGrtÍZ·gï~·ÿ{n¿Ÿ¥Ñ<ݳgŸ[²¤ÀuíÖíHž*‹ŸÐ|Ô%ª_Åû¾ º(?+çèr?Gí¹¾|M…——û”£V?˜§K¿—§Wžæ«.Q‘§B±.Ôžë•£i•stØ°a®¼¼ÂíVNÚ³½½'ýÉ<Õø´K—.~ž~¨úo]ÿw‘H„ç}‰¾ž©–ê†ÊïG‡ ®ñèZï}è^=Û[–V=O—*O»þ¿<¥ÿ@Ï3ÕRÕV-Q}U¯^=7dÈPW¦ñè;ÊQ{GjÕ{ÌCyyy®dY©Û¹óïÙÞ*–<µÏÍ›·zï 6lèô\o9ºJ•©¿ó$Ëqø¥KJJ²=WÙ6Îú–ÒÒÒõìÕË»oïòžíß±Š!Oíû¦M[ÈQaØ;ïôè{Ëw5ô]‡Ü‚…‹Üö;½5ö–¥±ä©}ßèåèÆ£}ï¼SU]UoÛ~y-Z¶t3fÎvonÛî½#µŠ%OísãÆÍä(€„¦ñ§¿'~åè&}lÒ¤‰›2åY·õõ7ÝÛzGjïIcÉSû¾aã&7˜ñ(€fçÛ)Kk*?¯PŽØœzVV–›4i²2p³÷ŽÔ²4–<µïë7lr÷ ì4`ž @âÒÜR åèÊÐgTŸ{½øC‡z{•Ø;R/KcÈSû\¿a£×÷Ô AƒÊóõ*æë$â\Ó=v–ˆÍÙ÷èÙÓ—,wo½µÃíˆfiÐ<µïõ\oóL•rÔúG3ôý$[ß 4×t’ªµj‡Í5µiÓƽúê<÷æ›oycRo\0O½Õ|½­×?ª”pïH•q5•oWªJõý[Ë9eÊT·yËëî­ío»íVAóTe}ø£Fv5²ýF½ªëôw4`< + çí•oç)çòí©íû4zôƒ®bíz·MÏö–¥±äéåð˜1¹Æ›XŽ~«koÔßÑDŸ'Ûß ‰ÂÞU*ßNUõ°~|Û÷®{÷nÙ²R¯ÔËÒòôõ7¶¹Ç{Üåææú9ºUÕ<99ùT[— +‰BÏÝ–¥Ç+ë®WÎm°>ÒæÍ›»Y³æx}¤Û¢Y4OßÐûÕ^xÑÝÜ¢…³÷®Öë¯j¥ëŸ¦?³‡€„’™™YCÏÚÖÿô²í¡§?»ñ&ºõë7zcRo\0Oíç_yõ5×®];ËQoïðÀƒ~/þWºîLÕŸléxß/üLk›üžü½þ¼½­m²1©Ÿ¥AòÔþ½gž™âš6mæÏÙ¯µ=ñUì‰ !Ùó¶êRU‘õÎ7ÉÉq/½<ÍWÚܽU<}C?3þB׶m;Î~å´Æ£'Óû {òOSõS}dï5‡ ½ß••­ñÆ–~–V5OísµþÝÞ½ó\ZZš?×dûFŸÍœ=€DÝKÏÖ‰n°ù¦ÖmÚ¸ »M›·zY4Om?ç±cÇùïH¿ÐuŸUýAcRæš$ì™Ìª3TclŽ½~ý 7nüo¨­¹÷³´ªyj?g=ý6ÿ¯\¶w¤TÖóÏ;R KZK•¦¬Ûnç6uêÔÉ{cRËÒ yjŸ¥¥+]÷îÝ­ÔúñèÚm-ªÍm@ï§wvtç/³²¸'òŸrk×mø^–V5OmOçãl”õT©&©.´³Ÿã}¯ð3fé ª,›c·qd¯^ÿåJ–-÷æî-Kƒä©ýïsæ¼¢gû›ýþ§5ú¼ZÏùô‘Hô~Ò#cR›'šúìsÞ˜´r–V5OW­.w½óŽÌÛÿÝÎ)U–žb{ @¢RÖÕŠž©´û_cÒRï<ËÒ yjçÞM~ìq—mcÒ/uÍçU¿¥ÿ @Þ“ž¥zÊ{Oª1锩Ïzs÷•³´*yjß +‹\ûöíýžüíº~š¾×Š÷}ÀÏIYWKQî½ccRÿ<_Z–ÉSËß‘£F;Ûs_×ûÔÎ׳}ôx¶‚1陪‰6×nïIŸ~fŠ[S±î{YZ•<µþÚ¼ù®E‹þ|Ó*õ?ýQóöôäHhѳð®PmKM­ûí)ZXTâíeY$OËÊ+Ü Aw»ôÃ{é}d{;Û™Mñ¾Gø9Ùs·Æ§©lmü'nâ#zkç+giUòÔ~fÆÌY.7·©ó|}þž½$:õ+Õ°¼Sî•ÙúÎÖ­[»…‹–x}P–¥AòtuY¹ëׯŸßu@ÕBub¼ï~nž¤ºU™÷¡íuÿ°án媲#9ZÕ<µŸ™1c–ËÉñÎýZ×›­ºHÅú&a˜s:G5Ëò/''ÇÍ™ûŠ7t–þTžZ_~ÿþ\zzºI?PÝĘ@(?WÞ%ÛzQ=—ÊËëã–—®8fŽþXžÚû€ÃïIIUsuÍ‹5ÞeL + ¡Ù>öѽžïµ}õlï‘üü']ùšŠÍÒcå©Iï¾ç^Lú¡²´¥Š÷¤^:uì]©½Ï\isN­ZµvK–|oΩ*yjß,\änºé&î~ kE„…òîU®wosN÷ rÌ9§ŸÊSë3æ!ÓÇÊÓž¶I¼ïªãù>ºoþ£Ê¿/6lè¦MŸá­s +’¥VEÅ%®}û¶îþ ®µI×¼,))‰5N^íÚµk(ó.±ìKMM=Ø©sgW\²,pŽ–¯YëòŸ|ÚÙ>(ºÖçªQÉÉɧÇûþ šŸï?¨W¯ž1r”74KKW¬ry}î´Þ|;{dŸòYQšÌNÂô|ÿ°ícbÏ÷ÓgÌúÁžÒ*ûyÛäY³f~oþ,]ó<ι’ç{þ¾ÂžïÿüçŽzçüùÞæœÆ><Οsú‡®ÙEÅ&BAÏàvÆh–??ôþaçï­l¿ýÎ]º8;§TãÒ×uÝË®½öZ朄Båþü¬¬,÷‹/ž¿·çû3g»FÙ˜ô Õdåó™ñ¾7¨®õ÷ʼsUó¬¯Þök.(( +<&µyªÑ£t6o=¯9kï„…òóWʼ?ªvùëïm.>h–.[¾ÂuéÒÕžï­§t‹²ùÒ:uê°ö@(ØØQÕÚö»·9£qã'Ùó9Èó½í%Õ¸qIo´çû'x¾&ʼÓUc÷Be»Ùsæî…²ì}xÜxþþ#U;wOŠ÷½@uHJJ²qéyªâ”””oÚ¶kS/”½¸ýŽÞ~þN]ë2}gþ@(ØyIÿCù·;-=ýPß~ýÝŠ•«å¨í!µTsUÑ=¡¾ÖõlŸÒsZµjïÛ€j¡ì³u£9¶¿¨=ŸÛszÐw¥Ö;õÜó/:륲sï•¥ƒìÜ=~…BÖWz—e eáK/O ÜWj½PÃGŒt‘H=ÿ’ U­xßTeÞYªç5>ýªiÓfnÉÒÂ*ïûì×òÒ•î¶îÝ]ݺu¿³^(•í5E/€PPÞY¯Z¯<Ø­[7¯G4è¼SAa±kÞ¼¹½+ýJך¦:;Þ÷ÕE™g=úÿ©z×Îdºçž{ÝÊ€óNö>`Úô™®Áá½J?‹®Cå])€PÍ;©ûóNãcèÑ·Ÿ?a¢ßWê­Õ¼çã eÞ)ʾÛUŸdffi.þ…ÀóNÖ?5pà]vÖ¨õ•îW6ÿI½¥ô• åÞÊ¿q¶Þ);;Û;74輓½_íܹ³­ÁÿV×[¥:?‰ÄûÖ ÚX?½ê#¿nݺµ+.YxÞ©°¨ÄßCÿK]ëYë àW ,ìÌCª6Ú~=¼Þ¦ 9jkögÏyÅÙy&6ï¤wCT¿Ž÷½@5Ÿ9ú;ÛÎæðígе£‡Ï}Êeddz瑨nU±Ÿ €ÐÐx´¦ª¶²ï@¬gŽz{??pdïç”Í©*ÎʼTM¬Éú™&>òhà~(ÇÞu× _RRÒ¥W^y%넆²ïdUWÕÇ™™™nêÔç¼gö kG{öìekGmýÊæóã}_Pl'Õݶ§‰­YŠeÿgë‡êpë­ÖõO]g±ê\~‹ÂD¹wºêÈ^ú‹—î-µ=£+õCM¥ +@Ø(÷ÎTå[æääÞKßrwá¢ÅÎzüuÏUc,Ÿã}_Pl/'Õô”””¯Z¶låJ–-¡·t®¿§É§ªìi lìݦj¡½ëìÐáÖÀ{íÙºý_|ÙßKÿcUÕ)ñ¾/¨NÑóòViþÛnÝþxÍ“Íù?ýôg=vî¨æ±Ú©èÓ*Ñ= 7¥¥¥¼ýö;\éŠ`YZV^á&?ö¸ËÈÈðöÚSŽæ&''Ÿïû€ê¤ü»@õ¦²ô»>}îôÎd’¥Ö×oçìE÷-µ3ž"œñ ¤Yú¶gÿ׿ö œ¥¶~t̘‡üõ£4.5¬*Ê¿ U»mýg¿~ýïkâ­Åý@å,­­ªïû€8dé~Û#jÀ€1eéÈ‘£ü,ý›êjY + T”{©Þ³,µýI‚gi™>|„‹Dg©Æ¤W&%%q6 €ðfé ²tU™6l¸²4âK¯°sMã}_‡gü½–¥ýc|Æ1bdågü«xÆÒyüiié‡úöíçVÄ0_i趯tJJ +ïK„Š²ïÕ6ë/ÍëÓ'x©×5VYêõ—Pz¢„qÝÓfoÝÓwü;zõӕ͵â}_P”}¿Q­µ=ñmoü ëñËÊ׸G¤,õÖ~¨ÍÖ3>kH„qo“âÔÔÔo:wéxŸ(ÛÛäÉAú‘ª gåÞ9ª¹K~}Ë-m]ɲÒÀ{î=ÿÂK.3ºçžúKoS±ç€PÑ3ùYª©¶¯~³fÍ]qIð½ gÍþÞ^ÐØ @Ø(÷ÎPM°óž5jä + +‹ŸQ²`áb×°aCÿŒ’‘œQ l”{¿Vݯú¬òðµy ŸWXTârrr,K¿Ðó}¾êÌxßT'=ÛŸªÊS~bçŒL›6Ã{$Kíë-mÛ:½sµ3_³w°ü„‰Í¹«n±9x›‹ÏÏÊ•—WÊR룺í¶îÎúª¬¿Êú¬â}_P¬¯^•f}ö¶v顱{ý÷A²ÔÖð÷ï?ÀÙ¨ºÎ]ï’H$Rƒß$€°ÐX²†²ï2eàû¶×Ó½÷ v+W•Å´¿I$º¿‰®wkò„‰òÓß+Ê;ó©wï¼ÀëH:?Ïúõ[jþéÄxßÄaíS‘­}êرSàµO6W5}úL—•u¸ÇT9:Pu¿Ea¢Ü;K5Åúõs›6UiqàÓ¥K ]nn®Ó5¾Pžæ«è‹ +àÿø§.< ‹ +ítUe¾Å©ŠXì2otž##k)J BK!$¡÷„N D=€„ÐBè-$¡—éèsé Ï5ãè4ëX‡A%ßÛûpN<‘œ››\0û·Ö^÷“sϽÉÚ~åÿí… +Bˆ§Ÿ~ú6(á™gžù¦M›6&m[º9yê5súµÿ)¶ró›ž={š¦M›~‡ëdC÷øú} !DYÒ¸qãjðÒ®ð¿ÏMòÒeæØñ“®¼ôpþoüýý p÷üüüiÞ¼yEý&…å…&MšT†Á?nÑ¢…™1c¦9rô¸+/å÷ÏNšcøó¸Î§¸^+øiU_¿7!„(+š5kVÞWzãÊ #GŽ²Æ™n¼ôÄÉÓfݺ ¦uëÖôÒ¯ Qëުߢ¢<ï«íÇXò|×®]Í¡Üî¼ôÔé×;ýY&,,ÌÀ“ÿƒk­‚jøú} !DYÿ»z þw6((Èl߱˜„?ºÛÊ7ýúõçþÓ¸ÎI¬Ãޯߢ¢<ï»ê}ØÊ,[¶Âw¹ÿôê‘c&aâ$ƒ='î?ýsüFðÓ*¾~oBQVÀ÷*COÁ?‚š)S§ZÞèÆKŸ8e–¯XiZµjÅ5Ó/¡ÁëV×oQQ^hÔ¨ǦB¯c/ꇘ˜“wøU×k¦{öî/ºfšª5S!Dyƒ¾­‡~Û¡C³ÿ@–ånü4ïp¾8p_ÀµÞ‚~©ÎTQn€‡Þ +ß‹ƒ¾fmSêê5Ö¼ÝméÌ™/8u¦Ÿ@í ›|ýÞ„¢ ½´ +|¯)=ðâšé4×k¦¬3ݸi‹áYT\ç_Xƒ ݡߢ¢¼À¹8ôtŠuM}ûö³êœÜx)u0ûéÞ½»ñkÚô{øóQèx³¯ßžB”ðÑ» %𿇄\¬3u™s±ì¤É“YűéG¸V Î“ +!Êoi Y´h±ëœ“+Γ~M…n÷õ{Bˆ²žW ú-ô3ŸFŠs}6Ÿ{ÿYs Ï¢b<ú=®õ*ÖL|ꩧô‹B” à{Ô=Pææç:vìhöî;àº6êâ<Šsêc(LûùBˆrX˼'žaZêAž)çù›·l5íÚµã<ÿßÐb®Åúú½ !DY=|æ™Ö‡÷ýÕß?  >~´ëy>•s(ÏDGÇ8uûoãšuð¼’~“Bˆòë—à{÷Âÿvâñ|§N¬<=·óü£ÇN˜yó˜–-[žÏ‡t>_QÏ@Yóü%ÉîçùôÞÝ{öšŽ;ñ|þwPt¿/kMíõàŠØ £¸ÏV ûc#""|vOBˆŸ/7fnçùïs?Øð®³N¨üWšñ&˜€‹{PášÏB7—µâ5­,,<¿zÏŸZáyKxéÕ¹¶A-Ë{Bü¼©W¯½§–“uf22w¸®Ûwö ˜/k} ­…î.«÷{·ê¼ð^jB½ð|tÜÎ]y:½f¯gpþ+H™«B¯O©ucRf•¼0;ÉuO=ŠýN†c\k÷(ý3äW~ű(^§*<²¡í¡bM¾.ÀX”µ¯–šPXƒÀû;Äuˆå® +!¼|>ÿQŽÛx>¿gÏ^Ø›Ïuí¥ÌšJIIuÎA…æ•v}<’^zäOdÎ +ÞCAHH¨1"ÖÌœ9ËÌ›·À$Í™cž{nœ‰ˆˆd½ïžú&¼tt[iÞ£¢üÀŒ'h6½¨mÛ¶fUêj×9|܃bÞÉ€ÑN}Ô»PcæR•¢—VÂõÃëìæÚ³è¡ëÖo4ûQ“——o'`­×Áì³-=Ó$&ΰÖ"ðsìWuï;ªVZ÷(„(?p.5ãü—sôX«ß³û=(Ö$/]fZ]›¾ÝYŠsû; DÖbaßËŒ3ÖìܵÇZ¿½šßgçäš—.tü”ãÓl\ëÑFi?Já½›{á)›¬=¨Ð0³5m›ë=(çŒ~ÿþاÔ›–Vo={¿ž™àkõèѳXyW¼ÇC¹yfÊ”©¦ys+ËúŸ¸Ö H5±Bˆ½ê oùŒsåI“&»Îˆ.›&/uzëÅ5çA^_7Å5oú2ëŠçæÍ›o(Î=ÒowìÜíÔÄžƒf²ÀÛ÷(„(`lÇ=¨_ÀS²±ù]xxg³k÷^×ç .ŽM³­±©½núG\³TÕ›÷‹ëÝ - _[s{7÷Ê5ÔØØ‘NÝÁŸp­‡•q%„ð’?U‡†qý‘c½¤¤¹ÕG]ìûœâô0±êM±YË›¿%Ö¯BàûßvîÜÙÊpsGŽ3Ó§':óüñ¾ëqÝÀ›÷(„(Ÿ4hРÖ6Íú(xÔ]ºtõ(‹ÏÙãឺ=îû|*›û嶗nÅ}ž‹ŠêbÕ·º¹G®¼øÒ<'GàSÜ[Þ»WÇÎBˆò <å6xËóìSÊÌý9s_4G=›r/}ÃÆÍ&44”k’çq½½ð½ÚX‹õÊ~¹Ý›z÷ʘËâv\ÊuÝE¯,6|ÜÂuB õRBxkÝ”9 OÀ_^·Æ¦]»™}ŒM)ží?~‚“ý4òJm<÷³ džq + 19»]‡X¶|%¼ÔÚ#û׊„Tg*„ð +ÌR‚‡ÞïŒMçÎ}É£±)÷Ë33w˜¨¨(žãdmü[÷úA%®‘‚ïݱ~õ,³¨÷8èÚKW¯YëÔ|ÁšÖxã3Bˆ¢cSxKáØtÏÞýM;n¼¼Ð©ßÿ´†¹©%ÍäcŸ>»_ß7mÚ¶Å>þnW÷Ç5ˆM›·8g^¿‚†+wUáí±)üîv{Ýô+îÏ̘9Ë£zS§~øðáÎ>Ô?ì1`‰jãqf¯ŽáØ™õiÛÒ]-à÷¦glwj ¾†ÆykýA!PÃÄ ;îéaŸQî蠟gº> ui ¸Õ<ûì³Ü‡bÏÒ“Pƒ’äHÙõ[Ìðÿ’cËõ6^õìèÕ<žõ³ÌàØ÷5ÿÿÐ_€ÂÛЯà31Ü› 0ãÆó¨'õê‘£föì$§‰}öRQƒt_ݺuK’Ø“k\óLY•ê:…g +ì¾¥š „(ßØy|ÿeg(Ÿ 3k×mp5þ+:Ü Ë :Ì™ë3k°<=óŠktd=÷Ç–$/uÝ_…{ÿÌÀµèí¬ PU!D©À^#ì9Bïcöç¡C]×r^™¿ß©S8üËÚ× +€—¹®‘ç™T¨5k­8Ö¿àåbŸÇ/ôR¼®]°FÕΑ®QŸ¡B`αéýP +Ço\_\ào9â™Túž]‹tŽc^¼Æc 6tÕšuUøYò ûÌNšãú¼+ÏJñlÏNázÊ7B”&Ìs†ÈøÎÖ‹fnßéÑ>”“=fÌX§×ë‘áÚµÜÔIÙ9ÐOò,=s­x¶žgìÝÜKn^¾éÕ»7ó™cz€÷PŠ£¢œÃ^ kãG9¹ËcÆŽõ¨g)EfÖhß¾ýœ,)ö`ŠuS“„q,û5?‚Ÿù^š0ÑuÍï?::†÷ð=ÞÛèžÒü…Â>bïC  1+V¤¸ÞïqÄ=÷õë7Xë•ö™¨3¸n÷”Šóisÿ^ú ~îÔpœËÞÒn ³ê^ùúo@÷é7-„(m˜ý¿ ¢±G]ïÞ}Ìî=û<:uqíô˜Y¸è§Æ“óì|¼ÆÓÅÝ‹²×qÏÀ /0“Êm½¿?..¾0Ô×+íÏP!0~ä>TMh&ëÛ¹çóüø õ†*Ú/dêÔéNÝ)Ϙî„~ƒ×ºf–(Ï¢B'8G8pë5ŽcÇ=?Þ°v–ë çÖV´¢ŒÎCU†çÔ÷ìcÍ)3š/Iöx®O?Ý·?ËŒ=ÆÉ“ú†gö᥿€Wÿd>¾ï(‡{G}úôµö’ܼ6×W'OžÂ×¥—~=ΚZý% !Êö¤‡Cïùù5½Ðµk7“‘¹Ã£}ý¢ý—8¶´çÛÿ„æÁ#ïm×®ÝU½Í#ï`MïÁm4k¨˜3Àñ5ë úÊÖB”å\>ZÃÎù’sä‘£â<®áwêø·¦¥öµ{˜~ÍÀëÔdŸÔ¾w7´µöáááæË×g,³®[\ÊÖoZ=S…âjÀw*Á…m¡—qÿè…ÙIeIÝÛ_»n½‰ˆŒäÞ>ýôoÐdÔ?ýèy$žù„–ñ|?óûsåºöRæÚkµŸá=µ…—*[_Q¦ÀªBÍXOĺ&æ@­LYåñÚ©ão«RWŽ3m?ý^=÷ÿrG˜E½äi´Õzé²¢}J:·&K!¼üãSæˆöb.)ë¤zôèaÒ3<Ëæ+ºŽ¹beŠ•Ñgûé{Pü•~ÊŒÌúOÖ[……]˲üÏ™¯:ÔÓ}¯õýÏoz;yЫ\æAŸÄõ™ ЦMa¶þ$eë !| Ï 1ë^ +½ãìEqžîi>ߥñé‘¢ãÓ¢ë§÷â1úœûG|-7û^Î9¶m­lýA³¡;ô—$„ðuÝ©'Ž¨¿àyë›Ö¬]çºH1ǧ¡H'zÁ‚…®};;ç qú¦,bm€þŠ„×I?Ï#ÅÓã°·ozöìmõÝó¤·É•ë§ôÓ°ö…ãÓ¿@[éƒ<»”4g®ÕCÚÍuy¾ÀîéÇ,€Teë !®àG¬ãÈÎ@ùÚßßßDGG[k“%©•ræûK–ŽO/Øý˜/4oÞÂLOœáQ¶~dd”•­ëlîöõç'„Wø)÷öSXKÏüÁƒ[}%÷ÓËƧœŸ[ù$ '¹>w•›wØôèi[=õ‚=²õ…×ð¸ÊГð§MÎ<|øðfï¾%ª=-:>uü”u­cÇ>ç:://ßôïßßéS’ÇZY_nBñ#ûûU°ß^•Á5IîÅŽi÷ôŠŸÚûQV¾ÊÈQ®ó Y;xðö)á~Öiè^ý…×#¨­ +mŸÚÃÖ/ÅÅ.ñÙ¨¢~Ê^'C† q}>€ÞKog6?îïeë !®WØ_{;Ì…µÓ›áWŽŸZãÓ¸øxs „~JyRÀþ}Ó¦'ÂK ³õŸd ‚¯?+!„ø)àSÔe~?_âý(OÄzÔÙIsœ>%Ÿ@:?­l}!Ä ì§qeî§Þk{öôÊ›B”;lociÕ ܉ÇßpßëCÇ—Ã_kàñ&ŽÝðÈœ½¢bm¾%ü·J”mJUÄZ©ãÉÖÞ>_“=A f…~jÏ÷½±~Z1seåÊUN¶þçPWÜG5_ÿ>„7dŸ‘Švh|dë– × ·l½a}:jŸÚ‹ïMÃã(zše>3þ[_(×…ZBx©Æuñß~‰¿ãÛ[ñH?fÏ(>oYÙ§eé§Ü÷gŽU«V³õ¡¸×[|ý{BÜ8À3¨ÊÐ/á!slÏüœ™v2ïã25¡š4qô=Ç‘Ìч˜/ò…½Þø¡Ý?ô};ÿ]è ô&ô:t:åC‹îÄãf<®µÿý<¯_Vë§ôÒÍ[¶:}J¾‚b•­/„(.ö›óñ:ðž—ÿ ìß»w3~B‚™5ëKS§M7 ­šö±#Í ÁƒM¿~ý­^ö‘‘‘Vf3@¹æÈL(æìQ?æÇ~—ûñŽCy +b3Åšyë¿—Åú)ë¨22wö‹bæ^w¦k·n¦Sx¸ ³<õIŽóëøÑ£­×. ?å5÷ìÝgØÇÔöò²õ…ׄ{ñ\£ä|–õéÍüý bbbLZZz‰ú‰ëqO‡×â¹"žyÏÍË·r—f²ÖAÙdÏÞýf×î½fÇÎÝ&sû«tÚ¶t³ekšÙ¸i³Y½f­Y¾b¥IY•jýLI²ú~Jôé   zéYh¤l}!Dq³ï…gœb_¦pŒ é_%ɽ/ñâÉS§­š%få—¤Çɵ”s(×É–f¶þ +è.ý !®öšªAÝXOÉùôŒ™³\g(ÿœt(7ÏtîÁµÜoñ™lT¶¾¢8`üu'ôç´œÛr若æÏ7‚¸Ü­[wzéy|&; šúKBÃKkBéìqeÍq}íg¾×rû`ŒÙú¯gCÊÖB\Îa¡4z)ûÆq\æk?ó¥X«ƒšÔ2|Ï帲õ…ÅûÔÐËìÁRâþK7ºXgÀ>TÌÖÇxý-è>ý% !®æ°Õ¡A<3Éúzf{p¿Üמæ+1—?~ôã1[ÿÏÐú+B\ Œ»¬þ ÐY£ß¿ÿ€R«…¿”q)ûOùû[^Ês¯÷ë¯HQÌó£506å<ÿ,3’¦'&ºîáùsZ/t©)3\4ÇB·7håÆÿžõúÌ)áºibâ ëlRy«â˜¼S§pcgµ¤³ÎAFBˆâP·n]úé-›†ÃOÿ—ÙPíÚµ³zÅó=Ïx²ÏBQô×+Å5“¯½Ñ¸N¼|ùJ''ŠyWã!e›!Š ¼”™ùÜÓâø”ywX34¡aa&*ª‹éÞ½‡Uw9pà@kÆŒk&a=`†™3w®yyá"³tÙr“ºzÙ´i‹ÉÈØnå„dç²ÎQ]ï>Ì×;uÐ 0€ó{®•¾±ú3ø\ÔïIá +öá8 žê-´³G¿ƒ¸vÈ¡ ¨a¿Àþñ-Z´( lUÀì&Ža¹.ßíСƒéر“éܹ³a½j—.]-fvë6Yo4ûä&šéÓMRÒ\+?*yé2“šºÚlظÉÊ5aö³OسþÄÉSWõá«y±[åzÆ„ Næš,ÂgP“ýR…“ù~ƒ ªÀGjÃ;ðÈü¨EÐzh;”Ãq+þý<þÝÎL>o{.ëÛѸ҇¹?~ч ZÛ>̼ÓÐBîhÂ-Ž´|¸[÷î†ùÑÑ1fØðá&>~Œ?~‚™6mº™”dæÏ_`­C0?jÆM&m[†ÙµkÉÊʶöϘƒòScbÎë·nÝfe£òÿ ¸O¾—|??¿ßã~+ë/HQ‚‚‚*`üÉ=©»à-ÛYRCO@õà¥Ü«j±Ts»ÿHW| ÅA“ì|þ%sò3y&Óîmò6ôW;ÿš>L]ôaÿ‚æÍmÆšf[ˇƒMhh¨iïøpxgaùpë\}Oøð€ÑfÈÐa¨uŠ7ÏǧLffÎzÁLž2ÕÊNe– s]裸ÇÓx Á<¿?!„( """*À×*b,[¾Ë>Q·³ÆŠ}œàKàymè|ý{ðÙµ¬õmfú<sßÃþJ#ñ<š ½bçS§CY<Ó‰ïù?°{Û+Žûù9>ܼ ¥ãÃmÛZ}øïö÷r¯) ï¡«ÃK+ê/Hq£P§N®ÑVa¿OèvxY |] Ï€jÃ[Á×A–ãßèà éÃvè |O$ž÷ƒF@ YöºD*´ ß³Gì>SïãëOm/þ z?¿êŽç¿nØ°áMìe-„åéœÆ•Uà¿Ì`½ yT ÏïçºÄ>€ÿ«ƒÇßB¿ƒ°=µíÅ|üûâÕYËàë÷$„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„Bˆëƒÿ8ݺ5¤–‹ +íx”eº†iŠbY ŠîWwz,ËêR¢1$H •Þƒ¡CèQª‘¦Ô„’„К4Û9{V«îñØ×ÞVA)ßyž?ÿ‚äŸLfp繯ë½& 3ÿÌ$s=|ß÷¾ïóV©"„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!D`ѨQ£*AAAU|ðÁê=ôP Ä%Œ‡~øû{+ð=ÿ݉j¸5üŒÁÇVÅuª†„„øûí!„O©W¯^•† V^ +-½·ý ‘O#rÛ¡‘¼]‡x1 ßOÄíHD_DÜ¿-~Šh„¯ïÁ5ê6iÒäZ|©­ÇÔ_G‹- ¦^Ûú[zL oܸqUê1¾×'@ñ«¢iÓ¦U4hP kÉ¡cÔÇýˆwßàû'ìÛïßàç_ >A|hßïo ^Cüñ2â(âyÄÄ6D» ·éˆÉˆQÐÒþøYWD ¾Ç÷âëû¿Ã÷×á5ÕÄÎXÛúû³õ0¾¦þV¥ãqUýýkB-[¶¤–R~]âšó]|}?3QQѦ{÷î&9¹éÑ£§éر“‰‹‹3­Zµ6aaá†÷ÁÚÓ4nÌhü³Àu§m->†ø×ÿñi9tø b/bbbb.^ã\g ¾€èŽïãñ} |ý0âÐÒÛ°¾®|™s.ûœ±¶µØZóý !DE ¯ +=¼Ú²ñ¾>`žzj¦Ù¸)ËlÛ¾ÓìØ™oÝænÝnr¶äšÍY9Ö¿edn4«V¯1K—.3ó,43gÍ6S§¦™'Æ7£F1)))¦o¿~¦g¯^¦S§N&>>úeš7oþ“7ùE6çÑáï!ÞF¼‰øÄ#^A¼`ëð>Db´t%nç!¦"Rq­Aö¹D^ÇÕx¾ê÷Þ{¯>LB¨_¿~èJ-ÏF߇®œîÑ£‡Y»n½Ù·ÿyó‹/›_zåãè /™C‡šç6û4{÷î7EÅ{Máî"“¿«ÐìÌÛe¶ïptx«ÉÊÎ1› Ã™Ðáիך¥ËV˜… ›Y³ÓÍÔ´43~ü3&5Õ¤ fú÷`zõJ2»t1Ôw®“›7oayäK‡›\X‡O"Žã½ýñÕY:Ìõð"² ©]±–½¿ªú( !ÜÂ3Rìsÿ=9 :kéèá#/\PC½Ôa>W©ïÛoŠ-.6» + +Mž¥Ãyfë¶2:¼:¼:¼fY¾:¼h±™>Ǥ¥M7ã'L4©©cÍ°aÃÍ€LRRoÓ¥KW“˜hÚ´icZ´øI‡mÍ=÷~Ì>c`žínžè“$„pÖc—#ºq½Ö¬Y33eÊTKÓ|¡£ÞÒჇ>PF‡w›¼üŸtxKîV“½ÅÖáMfÍÚõæé%ϘÑcR­µ.tõ´OãyÀ=ÈÁIO…åë²kÏ0?Ï|5‡åo¬ìàÙÅ¡ÃGLAa‘uÎÀÜrUÔÓ¯Ïa­^Gç§Bˆòݸ¹rìydž¾xÏ>¿ëœ¯ƒk[®YûöíçèéG¬­EÔÒ'IQN-½‰9phÈ©!CR¬|“¿µÍqäè‹Öl\\<ÎPŸ`}-Öê·„„„(%„(–Þ̺"äcN1òWsVZÁ÷>qâdý4ø|Œui ¢¦>FBˆ µ×Mˆ×¹.MI°ëRω7mÎ6ÔRöv±Gö*}Š„åX—ÖA¼„ºÒ“ýúõ·ráþÖ4Æî¢=ö>ÿácX“®F\«O‘âB@+n@ìCîéDRR’Ugïo=óg0÷Æ>YÔHý@Ohêõú !ʱ.­Ø -ý¡K×®fOk)ë¤Ø§Õ¦M[c{¸¬Dh]*„(–^Çút¬ÃŽ·oß! k¢œ8|ä¨Yºt¹ 7v¿épÄú !Ê¡¥×²6ë°˜˜X«¾²×~þÖÌó½.ž•²fŸž¶U#zKéS$„(‡–^ƒXˆø®uëÖГâJÓ*®yé7UP¸õ,?Öu2˜C?Wðqç +o¿6Ö/Lš<ÙY“~‡X‚¸gú !Ê£¥W#fÐG)22ç…•²vä5óò Ìðá#L§Î-ÿ=zŽÐ‹¯OŸ>fРÁÖ¿¥Ž}ÌL˜8ÑLM›fù÷ÍŸ¿Àê›_±òYËs…>[r·YÞS\CxþP©{¢É|Ìμ|3nÜã¦e«V–¿ýSqû Î=´&B” hÆUˆñ¬§lÑ"ÂänÝViûðƒ‡Ž˜çV­6íÚ··|šðœ–W¿~ätHHÈéа°Óô6mÏ–-[®•£¢£M›¶m =¬âããMbb¢iktìØÑt†.wëÖÝôîý¨é?` I:ÔŒ5Úø„™c†IŸ3×,Zü´Y¶|…嵺>#Ó +žN˜0Ñ0çÆõ¨í“ú:^W}5«JQ^ W FÐÓƒ~t\÷U¦·É¹ôÁµàëx¯âöÜ~jï³´ƒÿîÄɳâî +š|Š½ôÔãfÍBO‡……C“[˜¬µ¹Þ¤ÿ4=÷bbb ÉqVDG·†6§žŸÂu¾·=üÛ°>Ÿ³ÿô)B”èF-} ¿äzûhî{+3ÏS¢§k¬µ¥­§Ç¡‡yˆHæ{¸¿ÆmD"ÑÚ–„‚‹ï§ Òq?ži®Fd# +ìÙRôv~ÿö¾íÁÿÃ9ôØ þükÜ÷nG# aPP>@BW@?.Gпô îsW>ûœO| ©§« §öú”ë¡iœmÊ>,k4Ö™ÕìyMÔ·+¡s× j#êàç¿EÜŠ»q‡íá|â~D}ÎBµç?#Zqߎènÿ¿1 ÿ> ·=q­æœÕÇ<¢š>>BO€~ÔDÄ#> 3K–,µòë•­¥çØïÿLO½ñeÁYÒ|ŸW@;¯f_(kðq{傾ú¡¡afòæôHö…–žGO9‹i–í 3K!į{ÖqSÄ'ÍBCÍS3gYúæ+-•ž +!þ€†rNüŸÿ༧'§¦Ysì|©¥çÈG±>UN]q±ƒsÃjЫ;©]ô@æOÖ¿»ÑAÖ£ò1­KµòQ¨ÿìСcY= -½©Q£FÚï !.Zî¿ÿ~îóëB³Þç¬ã1©c]{ëSGg̘i¶mßYáÚTêéêŸëéL|}cdd¤ôTqÑbÏ)y‹µîÆwí­Oÿè™þX}S• § ž¤—(Âß¿.!„8'vÎü¿ ¥'©‰ôq£}Ô^öÓ³‡ˆ½õÞÒSæ÷Û9}IïAGŸÀ^_~¢Bˆ‹èÔˆƒM›6=‘œœìzNÉþÏ[¾$<#à™k2ô”þ#ÞÐSö°ßÖÓÿÃyÄhèéoüý;Bˆ³±{‰ +°Ÿþ±{®½õy¾J'j)û뽩§¬) ' ûèm=ý;Ö§ƒWê/)„¸˜°û'³é­ß¡cG×ÞúÌ=M˜8É™…Ì Çöû}M®ô”×_üôM/'ú™¼†hÇÞRÿî„ÂÁöÖ_ÃÙ›ÜO»ôÖçÚ1mÚtÃúTÛK„þ"ÇJô´âëSÇ«yÁ‚…–Ÿí1ú"œ}[úK +!.loý%ШïèZT¼Çõ¹æìÙsLhh(µô D +Î ²è›Wº>ÝZq=åÙCZÚtCß[³ ñšÿ,Ïf!ÄÅ4é7¬‰/ñÖoiÍq£sôBY¸p±£qŸAGcôiZëè©u~ºek…õ´ °ÈŒ{ü g ü´t3âè©<ž„ƒ·þdhÓ·Vͽ›&zô1?dÏJúÑ‘Lˆ?!2½¹>åcwîÌ7))C™ë:m{”.ÄóÜP¿~}}’„þÔÒ+coý¬ìWzwäè Vï'ëKmm{Q«Aƒ5 q÷{{}ÊÇælÉ5II½™¡¬åçl€«ô1BøyNÉ hÑWôÖÏÈÜàÊ[Ÿ÷ÍÜ°Ép&¯ýŠ°æÊ7lØzZï =M®x=?×ÂëÖg˜„„ÖJ1·ÿº}¶p™>IB?iéåˆ^\SrmI¿û#.¼õKÖ‰[ ×´¸Æ7ˆÇynà\ÿ\zÚ¯_³}G^…ô”õœ‰gçö9od?=õš*„ð9X×]-j_â­n–.[îjN ÏV9c™g­â -BˆÊk¸K qÍè­O}›>ǵ·~Qñ^«Ïö=®õ,g*ë¹ §œ…×±÷=ÎÜÿèÑc\÷Z}Æ°9+ÛtìØÉé3ýÿo@ÔÔ§Gá+ 9Õízй÷ž6mºko}ja»ví©eÇqMˆëÎõ\œ/Šû\ +åŒÐ"ÜüÀ³ÉاïwéõW68£Šsÿ"##­:~\wâ.z]ë“$„ðœeŒ¸ÇñÖŸ4i²ko}ö$uíÚ~£ìGÊGÔ>ßó!WTµL5¡sì}™=¡QQQ&}Î\ç£p¯O=7î bÕñÅ'XsË£Oá8ÿëÒÛ8Sùhéc㇖ºóÖ§O_ïÞ²Þó´ñâ†_zN{}z…=OúMîÍãââÌòå+=ž)ͽþ¶m;LÏž½é·ñ¾:!ä"„¨tØ/Ýù-ýAÙK4bä(×sJöAK - >i{›Ô¹ÐóBo«"®±kû?„þîÔ©“Ù´9ËU}kÙ`ý=¤£¢¢:©}Üë«ÇTá  97!^ >5dHŠë9%¼ÿ°aÑKf.ýM^¯<Ïkë)½¨c}+oÕžîÚUèqnŸ¯…ç¯vÏþ×v–ü£…•õ q{ô“}ûöóÀ[ÿ IMëøA¿sʺ÷Þ{oyŸ›çµ·#V°¦ŠuY=6Îõk({vÊ>€nÝ»;{ý7ñÌyUò¯Qàð|QLoýž½z¹öÖ·ü 'Ltü ?µþ×*w÷¯Ç±öt÷æ¬U3gj³<ËEñÌué²&"ÂÊëÇ5su¡§ªáBT¶·þ6hÍ;w1{\Ö{2ÿ>5mš³¯þÑÚU½¼ÏÏ\Sy¢Ö¬e.Š½ö™6ztvêäõY»Šk;5üÃ5ÛDQ™°”ýаc ‰Ð!wÞú¬íŸ5;ÝéåüšÂ7¯¡aƬ' —êö`á¼Á𼡰°È£³Sæõ³s¶8u¯Ì‰½Â>V¼®rk¼Bxà­¿œ}KmÛ¶µú˜Üî©Ù{êøA#Ø“êú|’¹(<îhÞ2žÒkeÊ“S]×»–]/[_òºè»2“ïUŸ!D%zëÏ£·>Ï*w»®E¢'JØO~ЗyXïZkGú=fÛ¶1V“¿•²{ý¼üÓ gÀN +‚pµfBˆò@/Dšã­ïÖ¿él?h¬+{{Z#Ïü?´´®Ó™y,ú='õîí± +×ÌÏ,]jèÍJ*Äs¸þõúd!¼ ôåJÄ8îƒéCº%×÷}‰ôFG¯Ø¿™‚¸¢¯‡{ý:öªoéòäÔ4öúÔ_®³ ìÔ¿¾ “÷‰ÂÛP÷Ã,o}héÆM›]i©å“[Öšº|eE^òEÕ±V¦‡ô!|}"6.εçY­_».ôjÕšýP¬‘ÊÁžÿÆÄÄDoý +…‚{üZˆdîϹ¶\³v+Í*ñƒÎ/õƒÆµ¦UÔCÔ®“â^¿'kšØ5pà@×y1'X3;rä(gæÞx} ùò !¼4…Þú<Ÿü‚ûéå+VºÎõКóB˜ǵæ#*Ü·‰}8÷úÿ†x–5Ôêùó¸öW-=‡ÈÜhZ·.Y›Ò“ë]­M…^šB¼Ç[ñÓK\û5q½Èz*j®³á¿;öDÙ~§¯1Ï^Og›ìݷߌ8sm¯µ©Â[`ýGoýæÜK³Þ~ÎÜy®×~ì3Jl׎uñÇp çóƒöd¯Ï5.®÷½J¨õS‘‡zÞƒ<צg­MQƒõ‹þ€BQ^ £5ÎðÖŸ>Ã#oýöíÛ;Zšé--µ{¢ª¡Žén'oõ4y2Çt/ÎMGŒé¬MßÇûnÅ™Wú´!¼äý{j ½žÆŽ}ÌpéaZPXdÚ´iãÌ|Zq¾™OxÌCõá™.=TRñÝú¬:kÓuÈéÛóLøZ—{ûµ +!×zRqg’'ºtíŠóÏ=å×'ä©V­ZƒúÒŽg蘊ÖD ^½ùnƒVoçœ(êöÆîj·J×Ð8Ûí׿?ç°êï¸^Þw o¾^!D`­º1ƒ5M-/ç,ºòæŸXo4tè0ÖÂSK?D4«Œ>Mö¥"Úó\—ëç1cR±6u?sïkÉ3Ë kø~ñ¾§ðý{ûõ +!œGòÌ´1´å-Î éÜ¥‹5+ùBu¦õ§lP¿¸5+ÝÄÄÄ:³ééMª´\ΙkÓËÏß“sS¾§§fÎr|¿À{UY¯[8Øg’@<ý/=Dãââ‘÷eÕœnظ ùó\³n}¦IOŸcÍf*éË´tôÄ@zNU¦½íËW—ÞÕ\›ÒG*;Û}NŸÿlÛ¾ÿÄp=ÍYÔ[iµB¸Ô*öÁßeÏœû_Ÿdg{Æ¡‰^ѱ±±ÖžÞö +á¼Ï¿Ù9ö+cožµ)û´> if&Mšì‘ï çì•é+}ŒPJáxnˆà¹d;»îþ[3y¶È8`­û[ÐÎEÌ5q>3׌¾øØ>R¿CìÅøÇÄÄD³sg¾ë^(öÉ>ûÜjÇßê[Ä“å „^Ãî…§çÉ¿#‚½ðýXÛŠžRp¿º¬õÇ×>ýíã9K½­Ø •>g®ë^-j/ëbYfç ^D~ëÖzõêiÆž«ЗZU ë?zœÖ††Õ¶sT—s}è¯_7ž›g»÷@ãÿÊ>ý=zxä!Å:z£Úsÿ¸þNT¾"P(Ó§ÏNÿ¤‡”'³L˜³Úœ•Sêq…XŒÐL(!DÀ€µò%ÐÓGØÀÚ}Îpö¤>Š^II½±ÏoÊ}þ_pÝÛ ÕÚç !ÔlU…–Þý³úJccãÌŽy®sPÜçÓÏÅÞçŠkÅiŸ/„$lï}Öµ~É{°Üæ JöùÙŽß ÷ùóY'ëï÷&„>î/¸‡5®ô*éÓ·¯Ù»ï€û}>òV½z%•í)½ÕŸ¹5!„ðµÇ½RéåO¿¿ÖQQ&g‹»9ª¥ùü'Kóù#"ò5BÚ¼ª.оÏÙ_Ÿžî¾ÖÔò5]Ÿáør–êxÄUþ~oBá+°/gŸÖ]ˆ7¸Ï§O€'û|ÖíÛsVØŸ¿CýùBˆ@žÿÌ}þjúþEGG›Ü­Û]çóé…:lølõç¿mŸÃVó÷ûB_a÷a±Ïõ æó.\ìz–ê¡ÃG̼ù Lhh˜åÃÇ9×CD©ÎTH4hРjPPÐíì +>5xðË;ßmiFæÆÒùÔXëŽExu>µBü +Ö¦×sN)ÏLé·ïÉ™iAánk =Wu=ë­üý¾„—pÎ=‚³F¾¥WIVVŽë~RÖù''÷1M›6= =} QGE!Dö“v`?©UgºÈ})çð÷¸ á>ÿ=\ïnèªjö…5ûû?rÆ4µšèvF©•š3×É?}ŠunKæµüýÞ„ÂdzKnæ<îÑ“““]÷æ3ÿ´fí:g>éWÐÑAˆZú+ +! »7?“¹£øøxSTì.ÿÄ>þ;óKûŸ £sò†Bbþ)ÍÉ?mñÀÏ”ýO:t`ÿÓq\g âz¿/!„ð%ÐÑËIœ[nV¬xÖõ|Rž ôíÛ×Êåó¼¡\¾" ÀÞþh_3λoÖ,Ô<5s–kohö’Ž5Úé%}×¼U³I…8ŸôNÎzö4—_2³dª3³ä¸^}ì÷«ûû½ !„½¡™Ë•½¤ƒ vÝKÊšÔù šPÔ¨Ú}ùÑêËBôÊCìnÒ¤Éݺw7{öîwW…óÕU«Ö˜ðp«.êK¬K“ª‹BÈ=]‹X˺¨˜ØX+/ïFK™÷ÏÊÎ1-Z”xœ Rò8BôÃGÌf}hKÔ‰æï*p5ÿ‰÷ÍËße"""©¥ß"¦#®ö÷ûB_Â5$âqúBsm™ãA)=¦¢¢¢èõb âý…{>ÙûÉPö‚®Ïpï±_¼g¯IHHd½>½÷2ä½'„й¤Ý8OÔª×_é¾^Ÿùªnݺä¯~à)Dm¿/!„ð%Ø×D´a=½÷-~Úµ÷^Ó¸ÎAÎæÓ_Qh½OˆPö>Ñ;zn{Ÿöí?` hš³ôeõ‘ +! è^ D«Z:Óƒ>RÖ÷2Ä°ÞºüWùë ! ä‹j@ûAK?fè´é3\Ï$¥–:ŒZÊžü77ùû} !„/ŽV‡öÝÏ^zj){ëÝj)ýMFŒåø›¼Í¾TýÿõùNmf‹ +íÝ pVÕÆq@ÁZ±hQ:ZºMí´c;•$ˆ$!Ãé´$©Ð*j!RkMLP©:­ìJ±"-!ì$$„°# û"‚K[µUke‘Óç½ùnŒ]sSÉ7ýîÿ7óÎt¸Ìí7óÌ9÷¼çœFø:tèÐäÆoü–ê›o¾Ùåå廊ŠJ·eëö:×úò .ûž{\çΞsBu5ÿ“øøø&íÛ·ÿŸ³ôžñãý,=©jí÷€†¤½@Ù÷mËÒ.]º¸üü ®bÃÆàãÒlÆ¥…=K¿ëgéƒ>T¯,;vœKÏé9¯0Ç6 M•§ñÊ¿7-K'NüUð,]_áî¾ûg®S'/K“¥ÂF¹×T•¨úC—®]Ý#>æ6TVÊÒ2eé˜1?U–vúHÏÙ§º*Úï IcÒ‹TÉÊ¿?vU–>>ir½²4+k”Ÿ¥»T­ù„‰r´™j€òï­nݺ¹'žœé*7n +”¥¥eånĈ»Ž;žÕs6©>í÷€†¤Ük®ªzû–[nq³gÏq«6ÊÒ’ÒõnȺÄÄÄÓzN±ê +~Ea¢Ü»D5ZõçîÝ»»ù ^pU›¶ÊÒu%enРAnúPÏyQÕ*Úï I¹w©*WõnRR²[R¸ÔmÞ²-P–®]Wêz÷îã:tèðž3[u9¿"€0QîµTMSý555Õ­^S(G­V¯YëRRRlÏÓ_U“U—Eû½ !Ù|\µÐæçé·ÝæÍ׃ä¨a ‹œiõœ÷´Ž•§º”_@˜Øš»ªBkðgn6Lkòëe©}[-(xÎÙ·VûæªÊ²o°Ñ~/h(-[¶´³MÚ(ûª7ôœõÛ[¯h,µþ©O<鬟Êúª4&MW]̯ ,âââ.HHH°sM^·3¢rrr]yÀ3¢6Tnt¿zäQgûOm“Ö .Œö»@CQî5S¥©þd{ž&Mžâ6l ¶çɲ÷¾û~é,‹-“5&ýºò¹ ¿"€°Pî]¢ªé-WðlàÞRû&0jÔhoÿ¨Æ£ûíìÒn¸!Ú¯ Æz—T“Tï÷ìÙÓ-_±*po©íyœ‘áïyZ«º’Ÿ@XhNn÷“\¡*R?Ô)Û·´®¤4poéªÕÅ®W¯[½>}Õ,UËh¿4”Î;7Vî]«qä~›Ÿ™x Óæ­îù~¯ÞÒ$ûVú®ê^Õgø„…¾“Ú¹¥ý3 ó'<ø h뇚>㉚~(Õ÷TôC e^ ÕÕ;v>Ô¬§ž|>”e¯Ýé‡zS•`gKGûݠצØz[w*Z¶<ðºS­3 ín’ªkTù„òÎß;ZvSbâ™ïÿà÷áûçC¥§ßfgíÒ³–qn)€0QæÙÝ£ßQ·»CÇeg{w‰]wzqÑ×£G›ß¿¯zDõÙh¿4àºSsÕí,}[7š:uzà{IþaþÛªLõ4çW´,m©šnßJSRzº%…E¿•ÚÞÑûsrköŽªnÐ3/ˆöû@CHMMm¤ï›W+û¶$&&ž2dH½¾•––®wÃ~t‡_ÞvÕâããù„‚á¤ê⟠õËûsŸ ecØeËWº[ÓÒl¿Óß4£â^¡aû’T÷Ù>%;Ïä™g渪€}¥Ö‡úÛYO9ëKœÿ<’óŸ„EÛ¶m%$$X/T±æù§L÷öÓ×ç[i­söÞPµ§G@XXÞErïUë…Êξ'p/”U‰¾¯fTŸ uFsûvΞæúÑ~=hÈùý8Õ_l~nóô ûF­¯tÑâBg{¥"÷ŽNµ»Lù „A›6ml~ßZãGo~ßÀ·båêÀóû •Uî7Orv¿õ•j\:˜û„…rôBe^wåßI›ßÿózÍïKËÊÝ]wô÷àÒ3¿¡^(î$óìÎÈY&Ú~O»Ë~À÷‘ضhÙ +×»wo¿j¾ªw’ƒvíÚ5Ö¸ôKÊÑÖŸŸ™9Ä­)^xLjûF§N›îï}'rf_‹h¿4å]s•í¿ËÎ}øá‰Ï}®¹'oô~LcÒë•Ñìó®¹æšFúži=¥K5/?•––æ/Yê­Ç×k~ߧÍï?TŽ.R]Éü@(÷.RõP–ž°5§±cÇiÍ©Âmݶ£~ë÷Ïïïd~ ¬^yw¹j†õ‚&''»‚‚g½1©ei<µ»›‡ û‘eò‘Ý·§ú¦Æ¥¬ßC–6UÅÙý!–wÜ1Ü;ÊÏѺ橭÷Ï_ð|¤?¿ÃzÞ,Ëhæ÷bÆŒ–¥—©&*÷Þ³}Nvg¨åâ¶í;½ªkžÚþûÜòüý÷RõÓs›Eûà|³s™•yßUíUÔGvN©õAù9Z×<µ5';ÿdРïÙ½Ngô¼JÕ•¥Ü‘ wã}VõIý{Hì;éö/yU×<µžÒiÓg8;ŸÏÎéSF߯º4Úï t7žI÷ؘ433ÓkLêçh<-)-söUß[­§ô°Æ£íTô”ˆiš‡[–¶T=æI§LæIwìÜåU]óÔ¾­Î[àRRRlLúÆ£3õg+}7ökÀùÎR»ƒ¤³2ï I‡½Ý¯-©ÉÑ yj}¨ãÆe;õ¥úg>'«.â'Ë®»î:;ª•òn¶#“’’ܬY¿óƘ;_ÚíU]óÔÖœ^\´ØßçtJÏ+T]Íš€Xfóne]3U_ÕqÛ3?rd–+[_^“£Aò´bC¥w¯^¤ê-Õåhóh¿'œOš‡7Öü¾­2o…#{¦¦ºçæ/ð2ò¥]{¼ªkžÚ8Ööì÷íÛ×Ƥ§õÌuª/1&‚½¢—ª²­—^cÉs÷Þû õ3UÕäh<µ½÷99øcÒ·Uw°÷@¬Ïí#wÞ'*ïvklzvРAÞ™N–—»v¿ìU]óÔ¾•.),Ò˜´Ÿ?&-Q}YEo>€˜¥¾OËR;SoŽ­7Ù^Q;¯Ù2q÷ž½5YZ×<µ±lNî'Ƥ#ô|Î{³´fo9z‰j¸2ï5[oÊÊåÙlÙiY$O·mßᾸØõíW3&-S}EÿÍyPbvŸ¨²´i{ÑoUÞíÓ§¯[¸p‘—“{^ÞW“¥uÍSûNZ«ŸÔÖî‡êñ¬ÝˆYöýÒú=UþÜþñÇ'{s{ËQ¿êš§ö÷ + +žs½zÝꟛ¿DõEßIÄìyz‘uû»UovêÔùÜèÑc¼}J–Ÿ/ïÝï^§–¥v¿ówÞåï»M•fgòGû]à|õ?)K›©Rìì[·OO¿Íjíݲr¯å¨_uÌSë'}âÉ™®G6&µ³žŸÒŸ­“ˆÕ{îí ¨o©Ö¨NÛ]÷O*wjíhï¾Õ OmLºjõ78#ÃÙþ}=óª“êÂh¿/œqqq5m£œ{Ú΀²û™srrÝƪÍ^†îó³4@žÚùQ¹êêÚµ«­7ýE•9gŠ@,ß9ò‹êo¤Îýä'wz÷7YnîÛ°ºä©õA<;ߥõî]³WTÿÎuê  +@̱1¢2®…*ÓæàúFú‘ÝbßH-'÷8äöûYZÇ<µ1ézõ¡>¢f½IÏÏ=Nbõlg;ÿÉÖš¶[ijj/7û™9n·òð€å¨_òÔz yô1ÿî‘÷UÓ”¥­•¥¬7ˆ¹5ûÈÙÎ ‘=H§-û&Mžâ¶oßéå烇çéKZoZðü ®_¿þvÞY=w›Ý=¢µ'îsãQ»WI9÷ ÕÕßl}(·iÓ/CZŽúUÇ<µ1iiYyí;œÞÔ¿3T9Ú"%%%Ú¯ Ÿjï“å¨ê«‘}MïÚ9zã²³]EEeuŽ:R]ót«zIóòòÝes{Íë§éÏ6Ênæöb†Æ‡ÖûÔDkém#½Oïøkök×–x™yèðQwÈÏÒyj}ùsçÎsiiiÞº½r´\õëYö{À§9¯W5Q¶]«Œ›egÞYŽÚ||åª5^V¶õ+@žÚšÓÊ•«]FF¦õäÛÜþ¸j€êbîcßG›¨¾ |›jçãÛ÷L»GtùŠUÊÈCîð‘cÕ0OmLZYYåÆŒãŸe=ùyª+¸w@ æ¨íiš¬úƒåhff¦+*Zæeã‘£¯¸#~–ÌS[óŸðàC^ÿSd¿ýÕ×Tô䈥óœýñè?GÎpK +—zãÑ£–£~ÌSëÉŸõÔïÜ­ÕßHÏèùUúóFUÓh¿;|Z9jû5õmô“9ša9Zä+;^]õÈSë%]¼¸ÐÙ)Û+¥çS†Ð7ç)€XÎQ[²½¡6¦<¦ µªOžÚzÓêÕÅnØ°aÖGꟓÿ3eéç8K@ æèÔÚßG—.]æeá±W^ý¸æ©åp¹úP³Fòךދ|‡½–»›Ä|ŽjÉÆ•¯?Q]õÈSËá-[¶¹ñãî÷ãÛZÓ³‘ýSô‘ˆéµõzSW†ZÕ+Oõ÷íLè‡'NtÉÉɶÖtJÿF±ªþMÖšÄtŽ.[¶ÜËÂ㯞ü¸æ©ý}[³ÿõ¯ãzõêå¯ÙoUuÓ¿y‘íK€ÿwÊQÿL|/Gmï‘Ÿ£6®|õÄkÕUÏ<µ3K¦M›áÒÒ¼sí짪þvî©å8ÄåÚgTc#w|žKIIq .Ts'”¡~ÎӣǽóŸfÎü­ëÛ·ŸßûtDš¡ºŒ;™Ä/TÆuTUÚ9¤vWSnn®ÛµkOuŽž|½^yºoÿ÷ôÓ³]ÿþüµ}ö·+C/·±p´ß>íóŸ¬G^™š¤¬Ûhç4ÙÊyyyn÷îúå©í3wž80ÝrÔÎ+9©çþX¶R‘£b’í5R¦úyZéçéÏS/GçÌséé59úºj”žy%g‘CžÚøT¹—¬Ü«ªŸæç{÷7Õ%O-Gí¾§Z9ú†æôwÛ}M|¦{E•¡-Tç©Ö¢òò'ü×<µ=MÏ(GkÍë½Õ·Ñ«ø> + ŒßO•¡6>í®ª¨ÉÓ¼ü;ß?øÏ9j=YÊRr@hYߧrÐòôU¹íS²ù~NN®wWhí<µ½¥ÿ*Gõw>ÏyήVžvóóÔöÞŸ“£<ÝU£‡*Gç’£ð_òÔî]úWyºyóƣ잒‹U]•§e–§IIInøðá®OŸ>µûžÆèkͼþ}¿”å©æü7+3KU§"ç8×ä¨ê*úðà?»þúëÅÅÅùyZ¢ú€ú婾¡Ú|ßòôÛʼê½?ª™Ý½¬mɾPaòwßѪƤ \ No newline at end of file diff --git a/About/ModIcon.png b/About/ModIcon.png new file mode 100644 index 0000000..00180ef Binary files /dev/null and b/About/ModIcon.png differ diff --git a/About/Preview.png b/About/Preview.png new file mode 100644 index 0000000..9c8ab19 Binary files /dev/null and b/About/Preview.png differ diff --git a/About/PublishedFileId.txt b/About/PublishedFileId.txt new file mode 100644 index 0000000..3f6e37f --- /dev/null +++ b/About/PublishedFileId.txt @@ -0,0 +1 @@ +3236257897 diff --git a/About/QuarterArrow.png b/About/QuarterArrow.png new file mode 100644 index 0000000..c8f65ad Binary files /dev/null and b/About/QuarterArrow.png differ diff --git a/About/QuarterArrow.svg b/About/QuarterArrow.svg new file mode 100644 index 0000000..b427cd7 --- /dev/null +++ b/About/QuarterArrow.svg @@ -0,0 +1,350 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/About/RimWordFont.ttf b/About/RimWordFont.ttf new file mode 100644 index 0000000..e2c1e18 Binary files /dev/null and b/About/RimWordFont.ttf differ diff --git a/About/SmallArrow.png b/About/SmallArrow.png new file mode 100644 index 0000000..566dfd5 Binary files /dev/null and b/About/SmallArrow.png differ diff --git a/About/SmallArrow.svg b/About/SmallArrow.svg new file mode 100644 index 0000000..364ce67 --- /dev/null +++ b/About/SmallArrow.svg @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3a63ba5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.1.0] + +### Added + +- First implementation of the mod. + +[Unreleased]: https://github.com/ilyvion/realistic-orbital-trade/compare/v0.1.0...HEAD +[0.1.0]: https://github.com/ilyvion/realistic-orbital-trade/releases/tag/v0.1.0 diff --git a/Common/Languages/English/Data.xml b/Common/Languages/English/Data.xml new file mode 100644 index 0000000..ff3d55b --- /dev/null +++ b/Common/Languages/English/Data.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Common/Languages/English/Keyed/RealisticOrbitalTrade.xml b/Common/Languages/English/Keyed/RealisticOrbitalTrade.xml new file mode 100644 index 0000000..b4062e1 --- /dev/null +++ b/Common/Languages/English/Keyed/RealisticOrbitalTrade.xml @@ -0,0 +1,35 @@ + + + + Minimum time until departure before adding grace time: {0} hours + If a trade is made when there is less time left before an orbital trader leaves than this setting, the orbital trader will extend their stay with an additional amount of time configurable below. For the sake of balance, the orbital trader will still stop accepting new trades once the original departure time is reached. + Grace time added if below minimum time: {0} hours + If a trade is made when there is less time left before an orbital trader leaves than the amount of time configurable above, the orbital trader will extend their stay with this additional amount of time. For the sake of balance, the orbital trader will still stop accepting new trades once the original departure time is reached. + + {0} is only waiting around to finish an already started agreement and is not interesting in initiating any new trades. + {0} reminds you to finish up your current trade agreement before starting another. + + Required specific items + + Cancel trade agreement + Cancels the trade agreement associated with this shuttle. Any partially loaded items will be unloaded first, then the shuttle will leave. + + {0} reminds you that you're already in the middle of amending your blacklisting status. + You were blacklisted from trading with orbital traders for destroying one of our shuttles. In order to have your good standing with us reinstated, you will have to pay us back for the parts it takes to produce a shuttle plus the cost of the labor, and finally we charge a nominal fee for the inconvenience you have caused us. The fixed costs are:\n\n{0} + Labor: {0} + Nominal fee: {0} (1% of player wealth) + You've chosen to pay us back in the following manner: + {0}: {1} + Returning + Paying for with {0} + How would you like to pay for the {0}? + Return the {0} + Pay for the {0} ({1}) + You've made your choices, are you ready to pay us back? + I'm ready + I'd like to choose differently + + Cancel amendment offer + + Cancels the amendment offer associated with this shuttle. Any partially loaded items will be unloaded first, then the shuttle will leave. + diff --git a/Defs/QuestScriptDefs/Script_TradeShipMakeAmends.xml b/Defs/QuestScriptDefs/Script_TradeShipMakeAmends.xml new file mode 100644 index 0000000..fe7642c --- /dev/null +++ b/Defs/QuestScriptDefs/Script_TradeShipMakeAmends.xml @@ -0,0 +1,35 @@ + + + + ROT_TradeShipMakeAmends + true + + +
  • questName->Making amends with the orbital trade guild
  • +
    +
    + + +
  • questDescription->After having destroyed the shuttle of an orbital trader, your faction was blacklisted from trading with the orbital traders. You've contacted one of them and promised to make amends. They'll be sending a shuttle for you to load the items and silver you have chosen to pay back into.
  • +
    +
    + + +
  • introLetterLabel->Amends offer accepted
  • +
  • introLetterText->We've sent a shuttle for you to load the items and silver you have chosen to pay us back into. Once we've received our things, your blacklisted status will be lifted.\n\nMake sure you don't take too long, the shuttle will leave when we do, and if you have not sent off the items owed to us by then, the amendment offer will be annulled.\n\nBecause you have betrayed us in the past, we've taken steps to discourage you from doing this again by strapping explosives to the shuttle.
  • +
  • graceTimeLetterLabel->Amends offer grace period
  • +
  • graceTimeLetterText->We were originally going to be leaving comms range in only [graceTimeTimeLeft], but since we like to provide at least [graceTimeTimeMinimum] to load up the shuttle, we'll wait around in orbit for up to [graceTimeTimeExtra] to let you fulfill this amendment offer.
  • +
  • expiredOfferLetterLabel->Amends offer expired
  • +
  • expiredOfferLetterText->Due to tardiness, you've unfortunately left us no choice but to leave without concluding the amends offer. Try to be more prompt next time!\n\n[partialLoadReturned]
  • +
  • shuttleKilledLetterLabel->Amends shuttle destroyed
  • +
  • shuttleKilledLetterText->There's something extraordinarily depraved about destroying the very means by which you were intended to make amends. However, since we're used to dealing with unscrupulous blacklisted factions, we use our most dilapidated, barely functioning shuttles for this purpose, which only contain a few metal scraps of useful materials at best, so you gain very little by doing this.
  • +
  • successLetterLabel->Amends made
  • +
  • successLetterText->The orbital traders guild thanks you for reimbursing us the reparations requested. You are once again in good standing, and you'll find that our traders are willing to make trades with you again.\n\nWhile we may forgive, we do not forget, thus all future shuttles involved in orbital trades with you will come with explosives strapped to them.
  • +
  • cancelledLetterLabel->Amends offer cancelled
  • +
  • cancelledLetterText->Contact one of us again if you change your mind.\n\n[partialLoadReturned]
  • +
  • partialLoadReturned->If you had partially loaded something onto our shuttle, it has been returned to you.
  • +
    +
    + +
    +
    diff --git a/Defs/QuestScriptDefs/Script_TradeShipTransportShip.xml b/Defs/QuestScriptDefs/Script_TradeShipTransportShip.xml new file mode 100644 index 0000000..6a42069 --- /dev/null +++ b/Defs/QuestScriptDefs/Script_TradeShipTransportShip.xml @@ -0,0 +1,35 @@ + + + + ROT_TradeShipTransportShip + true + + +
  • questName->[traderName] trade agreement
  • +
    +
    + + +
  • questDescription->You have entered into a trade agreement with the orbital trade ship [traderName]. They'll be sending two shuttles for you to complete the deal. The first one you will load your sold items into, and the second will unload your bought items upon arrival.
  • +
    +
    + + +
  • tradeAcceptedLetterLabel->Trade accepted
  • +
  • tradeAcceptedLetterText->[traderName] appreciates your business!\n\nWe've sent a shuttle down for you to load the things you sold to us into. Once we've received our things, we will send another shuttle down with the things you bought.\n\nMake sure you don't take too long, the shuttle will leave when we do, and if you have not sent off the items owed to us by then, the trade agreement will be annulled.\n\nYou can betray the orbital trader by destroying their shuttles, but this will have consequences for your future ability to trade with orbital traders.
  • +
  • tradeShuttleKilledLetterLabel->Trade shuttle destroyed
  • +
  • tradeShuttleKilledLetterText->Due to your vandalism of our property, your faction has been blacklisted in the orbital traders' guild. Because we believe in giving second chances, you may at any future time contact an orbital trader in range of your comms and offer to pay compensation for the damages caused plus a nominal fee for the inconvenience you have caused us. Until such time, the trading services of orbital traders will be unavailable to you.
  • +
  • graceTimeLetterLabel->Trade grace period
  • +
  • graceTimeLetterText->We were originally going to be leaving comms range in only [graceTimeTimeLeft], but since we like to give our patrons at least [graceTimeTimeMinimum] to load up the trade shuttle, we'll wait around in orbit for up to [graceTimeTimeExtra] to let you complete this trade.
  • +
  • expiredTradeLetterLabel->Trade expired
  • +
  • expiredTradeLetterText->Due to tardiness, you've unfortunately left us no choice but to leave without concluding the trade agreement. Try to be more prompt with your next trade!\n\n[partialLoadReturned]
  • +
  • tradeSuccessLetterLabel->Trade succeeded
  • +
  • tradeSuccessLetterText->[traderName] thanks you for your patronage!
  • +
  • cancelledTradeLetterLabel->Trade cancelled
  • +
  • cancelledTradeLetterText->Changed your mind, huh? That's okay, it happens.\n\n[partialLoadReturned]
  • +
  • partialLoadReturned->If you had partially loaded something onto our shuttle, it has been returned to you.
  • +
    +
    + +
    +
    diff --git a/Defs/ShipObjectDefs/TransportShipDefs.xml b/Defs/ShipObjectDefs/TransportShipDefs.xml new file mode 100644 index 0000000..a5a3a21 --- /dev/null +++ b/Defs/ShipObjectDefs/TransportShipDefs.xml @@ -0,0 +1,7 @@ + + + + ROT_CancelLoad + RealisticOrbitalTrade.ShipJobs.ShipJob_CancelLoad + + diff --git a/Defs/ThingDefs_Buildings/Buildings_CustomTransportShips.xml b/Defs/ThingDefs_Buildings/Buildings_CustomTransportShips.xml new file mode 100644 index 0000000..fc6e7a7 --- /dev/null +++ b/Defs/ThingDefs_Buildings/Buildings_CustomTransportShips.xml @@ -0,0 +1,40 @@ + + + +
  • + RealisticOrbitalTrade.Comps.CompTradeShuttle +
  • +
    + +
  • RealisticOrbitalTrade.ITabs.ITab_ContentsTransporterCustom
  • +
    +
    + + ROT_TradeShuttle + + + ROT_ExplosiveRiggedTradeShuttle + +
  • + true + 6.9 + Flame + 1 + 0.6 +
  • +
  • + This shuttle is very obviously rigged with some kind of improvised explosive device. +
  • +
    +
    + + ROT_ExplosiveRiggedAmendmentTradeShuttle + + + 2 + + +
    diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..953327c --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +Apache-2.0 OR MIT \ No newline at end of file diff --git a/LICENSE.Apache-2.0 b/LICENSE.Apache-2.0 new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE.Apache-2.0 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE.MIT b/LICENSE.MIT new file mode 100644 index 0000000..12e4ae6 --- /dev/null +++ b/LICENSE.MIT @@ -0,0 +1,19 @@ +Copyright (c) 2019 Alexander Krivács Schrøder + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Patches/Patches.xml b/Patches/Patches.xml new file mode 100644 index 0000000..1646ae9 --- /dev/null +++ b/Patches/Patches.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e78f1be --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +[![RimWorld 1.5](https://img.shields.io/badge/RimWorld-1.5-brightgreen.svg)](http://rimworldgame.com/) [![Build](https://github.com/ilyvion/realistic-orbital-trade/actions/workflows/build.yml/badge.svg)](https://github.com/ilyvion/realistic-orbital-trade/actions/workflows/build.yml) + +Has it ever bothered you how the orbital traders can just magically teleport items right out of your stockpiles? This mod puts an end to that. With **Realistic Orbital Trade**, your pawns will now have to load up a shuttle with the goods you sold before the orbital trader gets their hands on them AND before you get your hands on the goods you bought. + +The mod will guide you through all the required steps using the RimWorld quest and letter systems once you've made a trade with an orbital trader. + +The mod can be added to a game at any time. Removing the mod should be fine as long as there is no active trading quest at the time. There will be a fairly large list of once-off errors when first loading such a save, however. + +Mod compatibility is probably generally good, but there might be issues with mods that modify how orbital traders work or how vanilla shuttles work. + +## License + +Licensed under either of + +- Apache License, Version 2.0, ([LICENSE.Apache-2.0](LICENSE.Apache-2.0) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE.MIT](LICENSE.MIT) or http://opensource.org/licenses/MIT) + +at your option. + +`SPDX-License-Identifier: Apache-2.0 OR MIT` + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/Source/RealisticOrbitalTrade/Comps/CompTradeShuttle.cs b/Source/RealisticOrbitalTrade/Comps/CompTradeShuttle.cs new file mode 100644 index 0000000..349500b --- /dev/null +++ b/Source/RealisticOrbitalTrade/Comps/CompTradeShuttle.cs @@ -0,0 +1,467 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using HarmonyLib; +using RimWorld; +using RimWorld.Planet; +using UnityEngine; +using Verse; + +namespace RealisticOrbitalTrade.Comps; + +public class CompTradeShuttle : ThingComp +{ + internal bool cancelled = false; + internal bool isToTrader = false; + internal TradeAgreement? tradeAgreement; + internal List requiredSpecificItems = new(); + + private CompShuttle? _cachedCompShuttle; + private CompShuttle Shuttle + { + get + { + _cachedCompShuttle ??= parent.GetComp(); + return _cachedCompShuttle; + } + } + internal bool ShuttleAutoLoad + { + get => Traverse.Create(Shuttle).Field("autoload").Value; + set => Traverse.Create(Shuttle).Field("autoload").Value = value; + } + + private CompTransporter? _cachedCompTransporter; + private CompTransporter Transporter + { + get + { + _cachedCompTransporter ??= parent.GetComp(); + return _cachedCompTransporter; + } + } + + public override void CompTick() + { + base.CompTick(); + if (isToTrader && parent.IsHashIntervalTick(120)) + { + if (!parent.Spawned || cancelled) + { + return; + } + + ShuttleAutoLoad = true; + if (!Shuttle.LoadingInProgressOrReadyToLaunch) + { + TransporterUtility.InitiateLoading(Gen.YieldSingle(Transporter)); + } + } + } + + private static readonly List tmpRequiredLabels = new(); + public override string CompInspectStringExtra() + { + StringBuilder stringBuilder = new StringBuilder(); + + CalculateRemainingRequiredItems(); + + tmpRequiredLabels.Clear(); + foreach (var item in tmpRequiredSpecificItems.Where(i => i.count > 0)) + { + tmpRequiredLabels.Add(item.Label); + } + if (tmpRequiredLabels.Any()) + { + stringBuilder.AppendInNewLine("RealisticOrbitalTrade.RequiredThings".Translate() + ": " + tmpRequiredLabels.ToCommaList().CapitalizeFirst()); + } + return stringBuilder.ToString(); + } + + private void CalculateRemainingRequiredItems() + { + tmpRequiredSpecificItems.Clear(); + tmpRequiredSpecificItems.AddRange(requiredSpecificItems); + + ThingOwner innerContainer = Transporter.innerContainer; + foreach (var storedItem in innerContainer) + { + if (storedItem is Pawn) + { + continue; + } + int stackCount = storedItem.stackCount; + for (int i = 0; i < tmpRequiredSpecificItems.Count; i++) + { + ThingDefCountWithRequirements requiredSpecificItem = tmpRequiredSpecificItems[i]; + if (requiredSpecificItem.Matches(storedItem)) + { + int additionalItemsNeeded = Mathf.Min(requiredSpecificItem.count, stackCount); + if (additionalItemsNeeded > 0) + { + tmpRequiredSpecificItems[i] = tmpRequiredSpecificItems[i].WithCount(tmpRequiredSpecificItems[i].count - additionalItemsNeeded); + stackCount -= additionalItemsNeeded; + } + } + } + } + } + + public override void PostExposeData() + { + base.PostExposeData(); + Scribe_Values.Look(ref isToTrader, "isToTrader"); + Scribe_References.Look(ref tradeAgreement, "tradeAgreement"); + Scribe_Collections.Look(ref requiredSpecificItems, "requiredSpecificItems", LookMode.Deep); + } + + internal bool IsRequired(Thing thing) + { + if (!isToTrader) + { + return false; + } + foreach (var item in requiredSpecificItems) + { + if (item.Matches(thing)) + { + return true; + } + } + return false; + } + + private static readonly List tmpRequiredSpecificItems = new(); + private static readonly List tmpAllSendableItems = new(); + internal void CheckAutoload() + { + if (!isToTrader) + { + return; + } + + if (!ShuttleAutoLoad || !Transporter.LoadingInProgressOrReadyToLaunch || !parent.Spawned) + { + return; + } + + CalculateRemainingRequiredItems(); + + tmpAllSendableItems.Clear(); + tmpAllSendableItems.AddRange(TradeUtility.AllLaunchableThingsForTrade(parent.Map, tradeAgreement!.tradeShip)); + tmpAllSendableItems.AddRange(TransporterUtility.ThingsBeingHauledTo(Shuttle.TransportersInGroup, parent.Map)); + + foreach (var requiredItem in tmpRequiredSpecificItems) + { + if (requiredItem.count <= 0) + { + continue; + } + + int numberOfMatches = 0; + foreach (var sendableItem in tmpAllSendableItems) + { + if (requiredItem.Matches(sendableItem)) + { + numberOfMatches += sendableItem.stackCount; + } + } + if (numberOfMatches <= 0) + { + continue; + } + TransferableOneWay transferableOneWay = new TransferableOneWay(); + foreach (var sendableItem in tmpAllSendableItems) + { + if (requiredItem.Matches(sendableItem)) + { + transferableOneWay.things.Add(sendableItem); + } + } + int count = Mathf.Min(requiredItem.count, numberOfMatches); + Transporter.AddToTheToLoadList(transferableOneWay, count); + } + } + + public bool AllRequiredThingsLoaded + { + get + { + CalculateRemainingRequiredItems(); + return tmpRequiredSpecificItems.Sum(t => t.count) == 0; + } + } +} + +internal struct ThingDefCountWithRequirements : IExposable +{ + public ThingDef def; + internal int count; + public bool healthAffectsPrice; + public int hitPoints; + public int maxHitPoints; + public bool hasQuality; + public QualityCategory quality; + + public string Label + { + get + { + return GenLabel.ThingLabel(def, null, count) + LabelExtras(); + } + } + + private string LabelExtras() + { + string text = string.Empty; + bool reducedHealth = healthAffectsPrice && hitPoints < maxHitPoints; + if (reducedHealth || hasQuality) + { + text += " ("; + if (hasQuality) + { + text += quality.GetLabel(); + } + if (reducedHealth) + { + if (hasQuality) + { + text += " "; + } + text += ((float)hitPoints / maxHitPoints).ToStringPercent(); + } + text += ")"; + } + return text; + } + + public void ExposeData() + { + Scribe_Defs.Look(ref def, "def"); + Scribe_Values.Look(ref count, "count"); + Scribe_Values.Look(ref healthAffectsPrice, "healthAffectsPrice"); + Scribe_Values.Look(ref hitPoints, "hitPoints"); + Scribe_Values.Look(ref maxHitPoints, "maxHitPoints"); + Scribe_Values.Look(ref hasQuality, "hasQuality"); + Scribe_Values.Look(ref quality, "quality"); + } + + internal bool Matches(Thing thing) + { + QualityUtility.TryGetQuality(thing, out var thingQuality); + return def == thing.def && count != 0 && (!healthAffectsPrice || thing.HitPoints == hitPoints) && (!hasQuality || thingQuality == quality); + } + + internal ThingDefCountWithRequirements WithCount(int count) + { + return new() + { + def = def, + count = count, + healthAffectsPrice = healthAffectsPrice, + hitPoints = hitPoints, + hasQuality = hasQuality, + quality = quality + }; + } +} + +[HarmonyPatch(typeof(CompShuttle), nameof(CompShuttle.IsRequired))] +internal static class Rimworld_CompShuttle_IsRequired +{ + private static void Postfix(Thing thing, CompShuttle __instance, ref bool __result) + { + var compTradeShuttle = __instance.parent.TryGetComp(); + if (!__result && compTradeShuttle != null && compTradeShuttle.IsRequired(thing)) + { + __result = true; + } + } +} + +[HarmonyPatch(typeof(CompShuttle), "CheckAutoload")] +internal static class Rimworld_CompShuttle_CheckAutoload_SpecificItems +{ + private static void Postfix(CompShuttle __instance) + { + var compTradeShuttle = __instance.parent.TryGetComp(); + if (compTradeShuttle != null) + { + compTradeShuttle.CheckAutoload(); + } + } +} + +[HarmonyPatch(typeof(CompShuttle))] +[HarmonyPatch(nameof(CompShuttle.RequiredThingsLabel), MethodType.Getter)] +internal static class Rimworld_CompShuttle_RequiredThingsLabel +{ + private static void InjectThingsLabel(CompShuttle __instance, StringBuilder stringBuilder) + { + var compTradeShuttle = __instance.parent.TryGetComp(); + if (compTradeShuttle != null && compTradeShuttle.requiredSpecificItems.Count > 0) + { + foreach (var requiredItem in compTradeShuttle.requiredSpecificItems) + { + stringBuilder.AppendLine(" - " + requiredItem.Label.CapitalizeFirst()); + } + } + } + + private static MethodInfo _methodInjectThingsLabel = SymbolExtensions.GetMethodInfo(() => InjectThingsLabel(new(), new())); + + private static IEnumerable Transpiler(IEnumerable instructions) + { + try + { + return Utils.InjectCallBeforeReturn(instructions, _methodInjectThingsLabel, i => i.IsLdloc(), new[] { + new CodeInstruction(OpCodes.Ldarg_0), + new CodeInstruction(OpCodes.Ldloc_0), + }); + } + catch (InjectCallBeforeReturnException e) + { + RealisticOrbitalTradeMod.Error("Could not patch CompShuttle.RequiredThingsLabel, IL does not match expectations"); + return e.Instructions; + } + } +} + +[HarmonyPatch(typeof(CompShuttle))] +[HarmonyPatch(nameof(CompShuttle.AllRequiredThingsLoaded), MethodType.Getter)] +internal static class Rimworld_CompShuttle_AllRequiredThingsLoaded +{ + private static void Postfix(CompShuttle __instance, ref bool __result) + { + var compTradeShuttle = __instance.parent.TryGetComp(); + if (__result && compTradeShuttle != null) + { + __result = compTradeShuttle.AllRequiredThingsLoaded; + } + } +} + +/* +*/ + +/* + private static readonly List tmpAllSendableItems = new(); + internal void CheckAutoload() + { + tmpAllSendableItems.Clear(); + tmpAllSendableItems.AddRange(TransporterUtility.AllSendableItems(Shuttle.TransportersInGroup, parent.Map, autoLoot: false)); + tmpAllSendableItems.AddRange(TransporterUtility.ThingsBeingHauledTo(Shuttle.TransportersInGroup, parent.Map)); + + // foreach (var transferableOneWay in exactThingsToLoad) + // { + // if (tmpAllSendableItems.Contains(transferableOneWay.AnyThing)) + // { + // Transporter.AddToTheToLoadList(transferableOneWay, transferableOneWay.CountToTransfer); + // } + // } + } + +[HarmonyPatch(typeof(CompShuttle), nameof(CompShuttle.CompGetGizmosExtra))] +internal static class Rimworld_CompShuttle_CompGetGizmosExtra +{ + private static IEnumerable Postfix(IEnumerable values, CompShuttle __instance) + { + var compExactThingsRequired = __instance.parent.TryGetComp(); + if (compExactThingsRequired != null && compExactThingsRequired.exactThingsToLoad.Count > 0) + { + return values.Where(g => !(g is Command_Toggle commandToggle && commandToggle.defaultLabel == "CommandAutoloadTransporters".Translate())); + } + else + { + return values; + } + } +} + + +[HarmonyPatch(typeof(CompShuttle))] +[HarmonyPatch(nameof(CompShuttle.RequiredThingsLabel), MethodType.Getter)] +internal static class Rimworld_CompShuttle_RequiredThingsLabel +{ + private static void InjectThingsLabel(CompShuttle __instance, StringBuilder stringBuilder) + { + var compExactThingsRequired = __instance.parent.TryGetComp(); + if (compExactThingsRequired != null && compExactThingsRequired.exactThingsToLoad.Count > 0) + { + for (int i = 0; i < compExactThingsRequired.exactThingsToLoad.Count; i++) + { + stringBuilder.AppendLine(" - " + compExactThingsRequired.exactThingsToLoad[i].AnyThing.LabelCap); + } + } + } + + private static MethodInfo _methodInjectThingsLabel = SymbolExtensions.GetMethodInfo(() => InjectThingsLabel(new(), new())); + + private static IEnumerable Transpiler(IEnumerable instructions) + { + try + { + return Utils.InjectCallBeforeReturn(instructions, _methodInjectThingsLabel, i => i.IsLdloc(), new[] { + new CodeInstruction(OpCodes.Ldarg_0), + new CodeInstruction(OpCodes.Ldloc_0), + }); + } + catch (InjectCallBeforeReturnException e) + { + RealisticOrbitalTradeMod.Error("Could not patch CompShuttle.RequiredThingsLabel, IL does not match expectations"); + return e.Instructions; + } + } +} + +[HarmonyPatch(typeof(CompShuttle))] +[HarmonyPatch(nameof(CompShuttle.CompInspectStringExtra))] +internal static class Rimworld_CompShuttle_CompInspectStringExtra +{ + private static List tmpRequiredLabels = new List(); + + private static void InjectCompInspectStringExtra(CompShuttle __instance, StringBuilder stringBuilder) + { + var compExactThingsRequired = __instance.parent.TryGetComp(); + if (compExactThingsRequired != null && compExactThingsRequired.exactThingsToLoad.Count > 0) + { + tmpRequiredLabels.Clear(); + for (int i = 0; i < compExactThingsRequired.exactThingsToLoad.Count; i++) + { + if (compExactThingsRequired.exactThingsToLoad[i].AnyThing.holdingOwner != __instance.Transporter.innerContainer) + { + tmpRequiredLabels.Add(compExactThingsRequired.exactThingsToLoad[i].AnyThing.Label); + } + } + if (tmpRequiredLabels.Any()) + { + if (stringBuilder.Length == 0) + { + stringBuilder.Append("Required".Translate() + ": "); + } + stringBuilder.AppendInNewLine(tmpRequiredLabels.ToCommaList().CapitalizeFirst()); + } + } + } + + private static MethodInfo _methodInjectThingsLabel = SymbolExtensions.GetMethodInfo(() => InjectCompInspectStringExtra(new(), new())); + + private static IEnumerable Transpiler(IEnumerable instructions) + { + try + { + return Utils.InjectCallBeforeReturn(instructions, _methodInjectThingsLabel, i => i.IsLdloc(), new[] { + new CodeInstruction(OpCodes.Ldarg_0), + new CodeInstruction(OpCodes.Ldloc_0), + }); + } + catch (InjectCallBeforeReturnException e) + { + RealisticOrbitalTradeMod.Error("Could not patch CompShuttle.CompInspectStringExtra, IL does not match expectations"); + return e.Instructions; + } + } +} +*/ diff --git a/Source/RealisticOrbitalTrade/Constants.cs b/Source/RealisticOrbitalTrade/Constants.cs new file mode 100644 index 0000000..1546335 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Constants.cs @@ -0,0 +1,6 @@ +namespace RealisticOrbitalTrade; + +internal static class Constants +{ + internal const string Id = "RealisticOrbitalTrade"; +} diff --git a/Source/RealisticOrbitalTrade/Core/DefOfs.cs b/Source/RealisticOrbitalTrade/Core/DefOfs.cs new file mode 100644 index 0000000..fae119b --- /dev/null +++ b/Source/RealisticOrbitalTrade/Core/DefOfs.cs @@ -0,0 +1,27 @@ + +using RimWorld; +using Verse; + +namespace RealisticOrbitalTrade; + +#pragma warning disable CS8618,CS0649 +[DefOf] +internal static class QuestScriptDefOf +{ + public static QuestScriptDef ROT_TradeShipTransportShip; + public static QuestScriptDef ROT_TradeShipMakeAmends; +} + +[DefOf] +internal static class ThingDefOf +{ + public static ThingDef ROT_TradeShuttle; + public static ThingDef ROT_ExplosiveRiggedTradeShuttle; + public static ThingDef ROT_ExplosiveRiggedAmendmentTradeShuttle; +} +[DefOf] +internal static class ShipJobDefOf +{ + public static ShipJobDef ROT_CancelLoad; +} +#pragma warning restore CS8618,CS0649 diff --git a/Source/RealisticOrbitalTrade/Core/RealisticOrbitalTradeGameComponent.cs b/Source/RealisticOrbitalTrade/Core/RealisticOrbitalTradeGameComponent.cs new file mode 100644 index 0000000..12aea39 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Core/RealisticOrbitalTradeGameComponent.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; +using RimWorld; +using Verse; + +using VerseCurrent = Verse.Current; + +namespace RealisticOrbitalTrade; + +internal enum Standing +{ + Good, + Blacklisted, + Forgiven, +} + +internal class RealisticOrbitalTradeGameComponent : GameComponent +{ + public static RealisticOrbitalTradeGameComponent Current => VerseCurrent.Game.GetComponent(); + private int _nextTradeID; + + private bool _wasLoaded; + + private List _tradeAgreements = new(); + + private int _standing; + public Standing Standing { get => (Standing)_standing; set => _standing = (int)value; } + + public RealisticOrbitalTradeGameComponent(Game _) + { + } + + public int GetNextTradeId() + { + if (Scribe.mode == LoadSaveMode.LoadingVars && !_wasLoaded) + { + RealisticOrbitalTradeMod.Warning("Getting next unique ID during LoadingVars before RealisticOrbitalTradeGameComponent was loaded. Assigning a random value."); + return Rand.Int; + } + if (Scribe.mode == LoadSaveMode.Saving) + { + RealisticOrbitalTradeMod.Warning("Getting next unique ID during saving. This may cause bugs."); + } + int result = _nextTradeID; + _nextTradeID++; + if (_nextTradeID == int.MaxValue) + { + RealisticOrbitalTradeMod.Warning("Next Trade ID is at max value. Resetting to 0. This may cause bugs."); + _nextTradeID = 0; + } + return result; + } + + public TradeAgreement StartTradeAgreement(TradeShip tradeShip, Pawn negotiator) + { + var tradeAgreement = new TradeAgreement(tradeShip, negotiator); + _tradeAgreements.Add(tradeAgreement); + return tradeAgreement; + } + + public void EndTradeAgreement(TradeAgreement tradeAgreement) + { + tradeAgreement.tradeShip.GetData().activeTradeAgreement = null; + _tradeAgreements.Remove(tradeAgreement); + } + + public override void ExposeData() + { + base.ExposeData(); + + Scribe_Values.Look(ref _nextTradeID, "nextTradeID", 0); + Scribe_Collections.Look(ref _tradeAgreements, "tradeAgreements", LookMode.Deep); + Scribe_Values.Look(ref _standing, "standing"); + + if (Scribe.mode == LoadSaveMode.LoadingVars) + { + _wasLoaded = true; + } + } +} diff --git a/Source/RealisticOrbitalTrade/Core/RealisticOrbitalTradeMod.cs b/Source/RealisticOrbitalTrade/Core/RealisticOrbitalTradeMod.cs new file mode 100644 index 0000000..0bf5d02 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Core/RealisticOrbitalTradeMod.cs @@ -0,0 +1,64 @@ +using HarmonyLib; +using Verse; +using System; +using UnityEngine; +using System.Reflection; + +namespace RealisticOrbitalTrade; + +internal class RealisticOrbitalTradeMod : Mod +{ + private readonly ModContentPack content; + + public RealisticOrbitalTradeMod(ModContentPack content) : base(content) + { + this.content = content; + + // if (!ModsConfig.RoyaltyActive) + // { + // Error("Realistic Orbital Trade requires the Royalty DLC to be active to work. The mod's functionality has therefore been disabled and trade will behave as in vanilla."); + + // } + // else + // { + new Harmony(Constants.Id).PatchAll(Assembly.GetExecutingAssembly()); + //} + + GetSettings(); + } + + public override void DoSettingsWindowContents(Rect inRect) + { + base.DoSettingsWindowContents(inRect); + Settings.DoSettingsWindowContents(inRect); + } + + public override string SettingsCategory() + { + return content.Name; + } + + public static void Message(string msg) + { + Log.Message("[Realistic Orbital Trade] " + msg); + } + + public static void Warning(string msg) + { + Log.Warning("[Realistic Orbital Trade] " + msg); + } + + public static void Error(string msg) + { + Log.Error("[Realistic Orbital Trade] " + msg); + } + + public static void Exception(string msg, Exception? e = null) + { + Message(msg); + if (e != null) + { + Log.Error(e.ToString()); + } + } +} diff --git a/Source/RealisticOrbitalTrade/Core/Settings.cs b/Source/RealisticOrbitalTrade/Core/Settings.cs new file mode 100644 index 0000000..e4d66ae --- /dev/null +++ b/Source/RealisticOrbitalTrade/Core/Settings.cs @@ -0,0 +1,42 @@ +using UnityEngine; +using Verse; + +namespace RealisticOrbitalTrade +{ + internal class Settings : ModSettings + { + private static int _minTicksUntilDepartureBeforeGraceTime = 20000; + private static int _departureGraceTimeTicks = 40000; + + internal static int MinTicksUntilDepartureBeforeGraceTime { get => _minTicksUntilDepartureBeforeGraceTime; set => _minTicksUntilDepartureBeforeGraceTime = value; } + internal static int DepartureGraceTimeTicks { get => _departureGraceTimeTicks; set => _departureGraceTimeTicks = value; } + + public override void ExposeData() + { + base.ExposeData(); + + Scribe_Values.Look(ref _minTicksUntilDepartureBeforeGraceTime, "minTicksUntilDeparture", 20000); + Scribe_Values.Look(ref _departureGraceTimeTicks, "departureGraceTimeTicks", 40000); + } + + public static void DoSettingsWindowContents(Rect inRect) + { + Listing_Standard listingStandard = new(); + listingStandard.Begin(inRect); + + var minHoursUntilDepartureBeforeGraceTime = _minTicksUntilDepartureBeforeGraceTime / 2500f; + listingStandard.Label(string.Format("RealisticOrbitalTrade.MinTimeUntilDepartureBeforeGraceTimeLabel".Translate(), minHoursUntilDepartureBeforeGraceTime), -1f, "RealisticOrbitalTrade.MinTimeUntilDepartureBeforeGraceTimeTooltip".Translate()); + minHoursUntilDepartureBeforeGraceTime = listingStandard.Slider(minHoursUntilDepartureBeforeGraceTime, 1, 16); + _minTicksUntilDepartureBeforeGraceTime = (int)(minHoursUntilDepartureBeforeGraceTime * 2500f); + + listingStandard.Gap(4); + + var departureGraceTime = _departureGraceTimeTicks / 2500f; + listingStandard.Label(string.Format("RealisticOrbitalTrade.DepartureGraceTimeLabel".Translate(), departureGraceTime), -1f, "RealisticOrbitalTrade.DepartureGraceTimeTooltip".Translate()); + departureGraceTime = listingStandard.Slider(departureGraceTime, 4, 24); + _departureGraceTimeTicks = (int)(departureGraceTime * 2500f); + + listingStandard.End(); + } + } +} diff --git a/Source/RealisticOrbitalTrade/Core/TradeAgreement.cs b/Source/RealisticOrbitalTrade/Core/TradeAgreement.cs new file mode 100644 index 0000000..8d21ec1 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Core/TradeAgreement.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using RimWorld; +using Verse; + +namespace RealisticOrbitalTrade; + +internal class TradeAgreement : IExposable, ILoadReferenceable, IThingHolder +{ + protected int loadID = -1; + + public TradeShip tradeShip; + public Pawn negotiator; + + public ThingOwner thingsSoldToPlayer; + public List thingsSoldToTrader = new(); + public List pawnsSoldToTrader = new(); + + public IThingHolder ParentHolder => tradeShip.Map; + +#pragma warning disable CS8618 // Required by savegame logic + public TradeAgreement() +#pragma warning restore CS8618 + { + } + + public TradeAgreement(TradeShip tradeShip, Pawn negotiator) + { + this.tradeShip = tradeShip; + this.negotiator = negotiator; + + thingsSoldToPlayer = new(this); + + loadID = RealisticOrbitalTradeGameComponent.Current.GetNextTradeId(); + } + + public void ExposeData() + { + Scribe_Values.Look(ref loadID, "loadID", 0); + Scribe_References.Look(ref tradeShip, "tradeShip"); + Scribe_References.Look(ref negotiator, "negotiator"); + Scribe_Deep.Look(ref thingsSoldToPlayer, "thingsSoldToPlayer", this); + Scribe_Collections.Look(ref thingsSoldToTrader, "thingsSoldToTrader", LookMode.Deep); + Scribe_Collections.Look(ref pawnsSoldToTrader, "pawnsSoldToTrader", LookMode.Reference); + } + + public string GetUniqueLoadID() + { + return "TradeData_" + loadID; + } + + public void GetChildHolders(List outChildren) + { + ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, GetDirectlyHeldThings()); + } + + public ThingOwner GetDirectlyHeldThings() + { + return thingsSoldToPlayer; + } +} diff --git a/Source/RealisticOrbitalTrade/Core/TradeShipData.cs b/Source/RealisticOrbitalTrade/Core/TradeShipData.cs new file mode 100644 index 0000000..efb90c5 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Core/TradeShipData.cs @@ -0,0 +1,36 @@ +using System.Runtime.CompilerServices; +using RimWorld; +using Verse; + +namespace RealisticOrbitalTrade; + +internal class TradeShipData : IExposable +{ + // Used by the various patch methods to get a trade agreement started + public static TradeAgreement? tradeAgreementForQuest; + + public int ticksUntilCommsClosed = -1; + public TradeAgreement? activeTradeAgreement; + + public void ExposeData() + { + Scribe_Values.Look(ref ticksUntilCommsClosed, "ticksUntilCommsClosed", 0); + Scribe_References.Look(ref activeTradeAgreement, "activeTradeAgreement"); + } + + public override string ToString() + { + const string Null = ""; + return $"{{ticksUntilCommsClosed={ticksUntilCommsClosed}, activeTradeAgreement={activeTradeAgreement?.GetUniqueLoadID() ?? Null}}}"; + } +} + +internal static class TradeShipExtensions +{ + private static ConditionalWeakTable _tradeShipExtra = new(); + + public static TradeShipData GetData(this TradeShip tradeShip) + { + return _tradeShipExtra.GetValue(tradeShip, (tradeShip) => new()); + } +} diff --git a/Source/RealisticOrbitalTrade/Dialogs/Dialog_PayBlacklistRemovalFee.cs b/Source/RealisticOrbitalTrade/Dialogs/Dialog_PayBlacklistRemovalFee.cs new file mode 100644 index 0000000..0bed0d8 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Dialogs/Dialog_PayBlacklistRemovalFee.cs @@ -0,0 +1,215 @@ +using System.Collections.Generic; +using RimWorld; +using Verse; +using UnityEngine; +using System.Linq; +using RimWorld.QuestGen; + +using RwThingDefOf = RimWorld.ThingDefOf; + +namespace RealisticOrbitalTrade.Dialogs; + +public class Dialog_PayBlacklistRemovalFee : Dialog_NodeTree +{ + private enum PayWith + { + Parts, + Silver + } + + private const float LaborCost = 350f; + + private readonly TradeShip _tradeShip; + private readonly Pawn _negotiator; + private readonly List _thingDefCounts; + private readonly Dictionary _payForPartsWith = new(); + + private ThingDefCountClass? CurrentThing => _thingDefCounts.Where(t => !_payForPartsWith.ContainsKey(t.thingDef)).FirstOrDefault(); + private IEnumerable<(ThingDefCountClass thingDefCount, PayWith payWith)> ThingDefPayments => + _thingDefCounts.Select(t => + { + var contains = _payForPartsWith.TryGetValue(t.thingDef, out var payWith); + return (t, contains, payWith); + }).Where(c => c.contains).Select(c => (c.t, c.payWith)); + + public Dialog_PayBlacklistRemovalFee(TradeShip tradeShip, Pawn negotiator) + : base(new("")) + { + _tradeShip = tradeShip; + _negotiator = negotiator; + + _thingDefCounts = ThingDefOf.ROT_TradeShuttle.killedLeavings.Select(i => + { + if (i.thingDef == RwThingDefOf.ChunkSlagSteel) + { + return new ThingDefCountClass(RwThingDefOf.Steel, i.count * 15); + } + else + { + return i; + } + }).ToList(); + + SetupNextText(); + SetupNextOptions(); + } + + private float CalculateCostOf(ThingDefCountClass thingDefCount) + { + float marketValue = thingDefCount.thingDef.BaseMarketValue; + float totalCountMarketValue = marketValue * thingDefCount.count; + PriceType priceType = _tradeShip.TraderKind.PriceTypeFor(thingDefCount.thingDef, TradeAction.PlayerBuys); + float priceGainNegotiator = _negotiator.GetStatValue(StatDefOf.TradePriceImprovement); + + var partsCost = totalCountMarketValue * 1.4f * priceType.PriceMultiplier() * (1f + Find.Storyteller.difficulty.tradePriceFactorLoss); + partsCost *= 1f - priceGainNegotiator; + partsCost = Mathf.Max(partsCost, 0.5f); + if (partsCost > 99.5f) + { + partsCost = Mathf.Round(partsCost); + } + + return partsCost; + } + + private List GetThingsToReturn() + { + var nominalFee = WealthUtility.PlayerWealth * 0.01f; + var totalSilver = LaborCost + nominalFee; + + Dictionary thingsToReturn = new(); + foreach (var (thingDefCount, payWith) in ThingDefPayments) + { + if (payWith == PayWith.Parts) + { + thingsToReturn.Add(thingDefCount.thingDef, thingDefCount.count); + } + else + { + totalSilver += CalculateCostOf(thingDefCount); + } + } + thingsToReturn.Add(RwThingDefOf.Silver, (int)totalSilver); + + return thingsToReturn.Select(t => new ThingDefCount(t.Key, t.Value)).ToList(); + } + + private void SetupNextText() + { + var nominalFee = WealthUtility.PlayerWealth * 0.01f; + + var fixedCostsText = "RealisticOrbitalTrade.LaborCost".Translate(LaborCost.ToStringMoney()) + "\n" + "RealisticOrbitalTrade.NominalFeeCost".Translate(nominalFee.ToStringMoney()); + + curNode.text = new("RealisticOrbitalTrade.PayBlacklistRemovalFeeDialogText".Translate(fixedCostsText)); + + var payments = ThingDefPayments.ToList(); + if (payments.Count > 0) + { + curNode.text += "\n\n" + "RealisticOrbitalTrade.CostOfParts".Translate(); + foreach (var (thingDefCount, payWith) in payments) + { + curNode.text += "\n - " + "RealisticOrbitalTrade.PayForWith".Translate( + thingDefCount.LabelCap, + payWith == PayWith.Parts + ? "RealisticOrbitalTrade.PayWith.Parts".Translate() + : "RealisticOrbitalTrade.PayWith.Silver".Translate(CalculateCostOf(thingDefCount).ToStringMoney())); + } + } + + var currentThing = CurrentThing; + if (currentThing != null) + { + curNode.text += "\n\n" + "RealisticOrbitalTrade.HowPayForParts".Translate(currentThing.thingDef.label); + } + else + { + curNode.text += "\n\n" + "RealisticOrbitalTrade.AreYouReadyToPay".Translate(); + } + } + + private void SetupNextOptions() + { + curNode.options.Clear(); + var currentThing = CurrentThing; + if (currentThing == null) + { + curNode.options.Add( + new("RealisticOrbitalTrade.IAmReadyToPay".Translate()) + { + action = () => + { + Slate slate = new(); + slate.Set("thingsToReturn", GetThingsToReturn()); + slate.Set("tradeShip", _tradeShip); + + QuestUtility.GenerateQuestAndMakeAvailable(QuestScriptDefOf.ROT_TradeShipMakeAmends, slate); + }, + resolveTree = true, + dialog = this + } + ); + curNode.options.Add( + new("RealisticOrbitalTrade.ResetPaymentChoices".Translate()) + { + action = () => + { + _payForPartsWith.Clear(); + SetupNextText(); + SetupNextOptions(); + } + } + ); + } + else + { + curNode.options.Add( + new("RealisticOrbitalTrade.PayForPartsWithParts".Translate(currentThing.Label)) + { + action = () => + { + _payForPartsWith.Add(currentThing.thingDef, PayWith.Parts); + SetupNextText(); + SetupNextOptions(); + } + } + ); + curNode.options.Add( + new("RealisticOrbitalTrade.PayForPartsWithSilver".Translate(currentThing.Label, CalculateCostOf(currentThing).ToStringMoney())) + { + action = () => + { + _payForPartsWith.Add(currentThing.thingDef, PayWith.Silver); + SetupNextText(); + SetupNextOptions(); + } + } + ); + } + + curNode.options.Add( + new("(" + "Disconnect".Translate() + ")") + { + resolveTree = true, + dialog = this + }); + } + + + + public override void DoWindowContents(Rect inRect) + { + Widgets.BeginGroup(inRect); + Rect rect = new Rect(0f, 0f, inRect.width / 2f, 70f); + //Rect rect2 = new Rect(0f, rect.yMax, rect.width, 60f); + Rect rect3 = new Rect(inRect.width / 2f, 0f, inRect.width / 2f, 70f); + //Rect rect4 = new Rect(inRect.width / 2f, rect.yMax, rect.width, 60f); + Text.Font = GameFont.Medium; + Widgets.Label(rect, _negotiator.LabelCap); + Text.Anchor = TextAnchor.UpperRight; + Widgets.Label(rect3, _tradeShip.GetCallLabel()); + Text.Anchor = TextAnchor.UpperLeft; + + Rect rect5 = new Rect(0f, 80f, inRect.width, inRect.height - 80f); + DrawNode(rect5); + } +} diff --git a/Source/RealisticOrbitalTrade/ITabs/ITab_ContentsTransporterCustom.cs b/Source/RealisticOrbitalTrade/ITabs/ITab_ContentsTransporterCustom.cs new file mode 100644 index 0000000..70db4ed --- /dev/null +++ b/Source/RealisticOrbitalTrade/ITabs/ITab_ContentsTransporterCustom.cs @@ -0,0 +1,12 @@ + +using RimWorld; + +namespace RealisticOrbitalTrade.ITabs; + +internal class ITab_ContentsTransporterCustom : ITab_ContentsTransporter +{ + public ITab_ContentsTransporterCustom() + { + canRemoveThings = false; + } +} diff --git a/Source/RealisticOrbitalTrade/Patch/Rimworld_Dialog_Trade_Close.cs b/Source/RealisticOrbitalTrade/Patch/Rimworld_Dialog_Trade_Close.cs new file mode 100644 index 0000000..4015dea --- /dev/null +++ b/Source/RealisticOrbitalTrade/Patch/Rimworld_Dialog_Trade_Close.cs @@ -0,0 +1,17 @@ +using HarmonyLib; +using RimWorld; + +namespace RealisticOrbitalTrade.Patch; + +[HarmonyPatch(typeof(Dialog_Trade), nameof(Dialog_Trade.Close))] +internal static class Rimworld_Dialog_Trade_Close +{ + private static void Postfix() + { + if (TradeShipData.tradeAgreementForQuest != null) + { + RealisticOrbitalTradeGameComponent.Current.EndTradeAgreement(TradeShipData.tradeAgreementForQuest); + TradeShipData.tradeAgreementForQuest = null; + } + } +} diff --git a/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeDeal_TryExecute.cs b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeDeal_TryExecute.cs new file mode 100644 index 0000000..d0f4a95 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeDeal_TryExecute.cs @@ -0,0 +1,36 @@ +using HarmonyLib; +using RimWorld; +using RimWorld.QuestGen; + +namespace RealisticOrbitalTrade.Patch; + +[HarmonyPatch(typeof(TradeDeal), nameof(TradeDeal.TryExecute))] +internal static class Rimworld_TradeDeal_TryExecute +{ + private static void Postfix(bool __result, bool actuallyTraded) + { + var tradeAgreementForQuest = TradeShipData.tradeAgreementForQuest; + if (tradeAgreementForQuest == null) + { + return; + } + + + if (__result) + { + if (actuallyTraded) + { + Slate slate = new(); + slate.Set("tradeAgreement", tradeAgreementForQuest); + slate.Set("traderName", tradeAgreementForQuest.tradeShip.TraderName); + + QuestUtility.GenerateQuestAndMakeAvailable(QuestScriptDefOf.ROT_TradeShipTransportShip, slate); + } + else + { + RealisticOrbitalTradeGameComponent.Current.EndTradeAgreement(tradeAgreementForQuest); + } + TradeShipData.tradeAgreementForQuest = null; + } + } +} diff --git a/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_ExposeData.cs b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_ExposeData.cs new file mode 100644 index 0000000..6177acd --- /dev/null +++ b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_ExposeData.cs @@ -0,0 +1,16 @@ + +using HarmonyLib; +using RimWorld; +using Verse; + +namespace RealisticOrbitalTrade.Patch; + +[HarmonyPatch(typeof(TradeShip), nameof(TradeShip.ExposeData))] +internal static class Rimworld_TradeShip_ExposeData +{ + private static void Postfix(TradeShip __instance) + { + var extra = __instance.GetData(); + Scribe_Deep.Look(ref extra, "realisticOrbitalTradeData"); + } +} diff --git a/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_GiveSoldThingToPlayer.cs b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_GiveSoldThingToPlayer.cs new file mode 100644 index 0000000..6d84bb5 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_GiveSoldThingToPlayer.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using HarmonyLib; +using RimWorld; +using Verse; + +namespace RealisticOrbitalTrade.Patch; + +[HarmonyPatch(typeof(TradeShip), nameof(TradeShip.GiveSoldThingToPlayer))] +internal static class Rimworld_TradeShip_GiveSoldThingToPlayer +{ + private static bool Prefix(TradeShip __instance, Thing toGive, int countToGive, Pawn playerNegotiator) + { + Thing thing = toGive.SplitOff(countToGive); + if (thing is Pawn item) + { + Traverse.Create(__instance).Field("soldPrisoners").GetValue>().Remove(item); + } + TradeShipData.tradeAgreementForQuest!.thingsSoldToPlayer.TryAddOrTransfer(thing); + + return false; + } +} diff --git a/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_GiveSoldThingToTrader.cs b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_GiveSoldThingToTrader.cs new file mode 100644 index 0000000..ddd7b86 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_GiveSoldThingToTrader.cs @@ -0,0 +1,25 @@ + +using HarmonyLib; +using RimWorld; +using Verse; + +namespace RealisticOrbitalTrade.Patch; + +[HarmonyPatch(typeof(TradeShip), nameof(TradeShip.GiveSoldThingToTrader))] +internal static class Rimworld_TradeShip_GiveSoldThingToTrader +{ + private static bool Prefix(Thing toGive, int countToGive, Pawn playerNegotiator) + { + var tradeAgreement = TradeShipData.tradeAgreementForQuest!; + if (toGive is Pawn pawn) + { + tradeAgreement.pawnsSoldToTrader.Add(pawn); + } + else + { + tradeAgreement.thingsSoldToTrader.Add(new(toGive, countToGive)); + } + + return false; + } +} diff --git a/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_PassingShipTick.cs b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_PassingShipTick.cs new file mode 100644 index 0000000..2d8479e --- /dev/null +++ b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_PassingShipTick.cs @@ -0,0 +1,18 @@ + +using HarmonyLib; +using RimWorld; + +namespace RealisticOrbitalTrade.Patch; + +[HarmonyPatch(typeof(TradeShip), nameof(TradeShip.PassingShipTick))] +internal static class Rimworld_TradeShip_PassingShipTick +{ + private static void Postfix(TradeShip __instance) + { + var tradeShipExtra = __instance.GetData(); + if (tradeShipExtra.ticksUntilCommsClosed > 0) + { + tradeShipExtra.ticksUntilCommsClosed--; + } + } +} diff --git a/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_TryOpenComms.cs b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_TryOpenComms.cs new file mode 100644 index 0000000..7159681 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Patch/Rimworld_TradeShip_TryOpenComms.cs @@ -0,0 +1,47 @@ +using HarmonyLib; +using RimWorld; +using Verse; +using RealisticOrbitalTrade.Dialogs; + +namespace RealisticOrbitalTrade.Patch; + +[HarmonyPatch(typeof(TradeShip), nameof(TradeShip.TryOpenComms))] +internal static class Rimworld_TradeShip_TryOpenComms +{ + private static bool Prefix(TradeShip __instance, Pawn negotiator) + { + TradeShipData tradeShipExtra = __instance.GetData(); + if (tradeShipExtra.ticksUntilCommsClosed == 0) + { + Messages.Message("RealisticOrbitalTrade.NotAnsweringForGraceTime".Translate(__instance.TraderName), MessageTypeDefOf.NeutralEvent, historical: false); + return false; + } + else if (Find.QuestManager.QuestsListForReading.Any(q => q.root == QuestScriptDefOf.ROT_TradeShipMakeAmends && !q.Historical)) + { + Messages.Message("RealisticOrbitalTrade.NotAnsweringForActiveAmendment".Translate(__instance.TraderName), MessageTypeDefOf.NeutralEvent, historical: false); + return false; + } + else if (RealisticOrbitalTradeGameComponent.Current.Standing == Standing.Blacklisted) + { + Find.WindowStack.Add(new Dialog_PayBlacklistRemovalFee(__instance, negotiator)); + + float level = negotiator.health.capacities.GetLevel(PawnCapacityDefOf.Talking); + float level2 = negotiator.health.capacities.GetLevel(PawnCapacityDefOf.Hearing); + if (level < 0.95f || level2 < 0.95f) + { + TaggedString text = (!(level < 0.95f)) ? "NegotiatorHearingImpaired".Translate(negotiator.LabelShort, negotiator) : "NegotiatorTalkingImpaired".Translate(negotiator.LabelShort, negotiator); + text += "\n\n" + "NegotiatorCapacityImpaired".Translate(); + Find.WindowStack.Add(new Dialog_MessageBox(text)); + } + return false; + } + else if (tradeShipExtra.activeTradeAgreement != null) + { + Messages.Message("RealisticOrbitalTrade.NotAnsweringForActiveTrade".Translate(__instance.TraderName), MessageTypeDefOf.NeutralEvent, historical: false); + return false; + } + + tradeShipExtra.activeTradeAgreement = TradeShipData.tradeAgreementForQuest = RealisticOrbitalTradeGameComponent.Current.StartTradeAgreement(__instance, negotiator); + return true; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestNode_Root_TradeShipMakeAmends.cs b/Source/RealisticOrbitalTrade/Quest/QuestNode_Root_TradeShipMakeAmends.cs new file mode 100644 index 0000000..87c308e --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestNode_Root_TradeShipMakeAmends.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using System.Linq; +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +public class QuestNode_Root_TradeShipMakeAmends : QuestNode +{ + protected override void RunInt() + { + var quest = QuestGen.quest; + var slate = QuestGen.slate; + + var tradeShip = slate.Get("tradeShip")!; + var thingsToReturn = slate.Get>("thingsToReturn"); + + var questTag = QuestGenUtility.HardcodedTargetQuestTagWithQuestID("ROT_TradeShipMakeAmends"); + var cancelAmendmentSignal = QuestGenUtility.HardcodedSignalWithQuestID("CancelAmendment"); + + var shuttle = QuestUtils.SetupShuttle("shuttle", slate, questTag, out var signalShuttleSentSatisfied, out var signalShuttleKilled, true); + var compShuttle = shuttle.TryGetComp(); + compShuttle.requiredItems = thingsToReturn; + + var transportShip = quest.GenerateTransportShip(TransportShipDefOf.Ship_Shuttle, Enumerable.Empty(), shuttle).transportShip; + slate.Set("transportShip", transportShip); + QuestUtility.AddQuestTag(ref transportShip.questTags, questTag); + + var map = tradeShip.Map; + IntVec3 landingSpot = QuestUtils.FindLandingSpot(map); + + quest.Letter(LetterDefOf.PositiveEvent, text: "[introLetterText]", label: "[introLetterLabel]"); + quest.AddShipJob_Arrive(transportShip, map.Parent, null, landingSpot, ShipJobStartMode.Queue); + quest.AddShipJob_WaitForever(transportShip, true, true); + + quest.CancelAmendment(shuttle, outSignalCancelled: cancelAmendmentSignal); + quest.Signal(cancelAmendmentSignal, () => + { + quest.CancelTransportShip(transportShip); + quest.Letter(LetterDefOf.NeutralEvent, text: "[cancelledLetterText]", label: "[cancelledLetterLabel]"); + quest.End(QuestEndOutcome.Fail, signalListenMode: QuestPart.SignalListenMode.OngoingOnly); + }); + + // What to do if the player fails to load the shuttle on time + var ticksUntilShuttleDeparture = QuestUtils.CheckTradeShipRequiresGraceTime(quest, slate, tradeShip); + quest.ShuttleLeaveDelay(shuttle, ticksUntilShuttleDeparture, null, Gen.YieldSingle(signalShuttleSentSatisfied), null, () => + { + quest.CancelTransportShip(transportShip); + quest.Letter(LetterDefOf.NeutralEvent, text: "[expiredOfferLetterText]", label: "[expiredOfferLetterLabel]"); + quest.End(QuestEndOutcome.Fail, signalListenMode: QuestPart.SignalListenMode.OngoingOnly); + }); + + // What to do if the player destroys the shuttle + quest.Signal(signalShuttleKilled, () => + { + quest.Letter(LetterDefOf.NegativeEvent, signalListenMode: QuestPart.SignalListenMode.OngoingOnly, text: "[shuttleKilledLetterText]", label: "[shuttleKilledLetterLabel]"); + quest.End(QuestEndOutcome.Fail, signalListenMode: QuestPart.SignalListenMode.OngoingOnly); + }); + + // What to do when the player has loaded the shuttle appropriately + quest.Signal(signalShuttleSentSatisfied, () => + { + // Put in a small delay so the quest finishes slightly later than immediately after the + // shuttle starts taking off + quest.Delay(500, () => + { + quest.ExtendTradeShipDepartureIfVeryShort(tradeShip); + quest.Letter(LetterDefOf.PositiveEvent, text: "[successLetterText]", label: "[successLetterLabel]"); + quest.ForgivePlayerFactionInOrbitalTrade(); + quest.End(QuestEndOutcome.Success, signalListenMode: QuestPart.SignalListenMode.OngoingOnly); + }); + }); + } + + protected override bool TestRunInt(Slate slate) + { + return true; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestNode_Root_TradeShipTransportShip.cs b/Source/RealisticOrbitalTrade/Quest/QuestNode_Root_TradeShipTransportShip.cs new file mode 100644 index 0000000..52f4524 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestNode_Root_TradeShipTransportShip.cs @@ -0,0 +1,181 @@ +using System.Linq; +using RealisticOrbitalTrade.Comps; +using RimWorld; +using RimWorld.Planet; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +public class QuestNode_Root_TradeShipTransportShip : QuestNode +{ + protected override void RunInt() + { + var quest = QuestGen.quest; + var slate = QuestGen.slate; + + var tradeAgreement = slate.Get("tradeAgreement")!; + + var questTag = QuestGenUtility.HardcodedTargetQuestTagWithQuestID("ROT_TradeShipTransportShip"); + var cancelTradeSignal = QuestGenUtility.HardcodedSignalWithQuestID("CancelTrade"); + + (var toTraderShuttle, var toTraderTransportShip) = SetupToTraderTransportShip(quest, slate, tradeAgreement, questTag, + out var signalToTraderShuttleSentSatisfied, out var signalToTraderShuttleKilled); + + (var toPlayerShuttle, var toPlayerTransportShip) = SetupToPlayerTransportShip(quest, slate, tradeAgreement, questTag, + signalToTraderShuttleSentSatisfied, out var signaltoPlayerShuttleSentSatisfied, out var signalToPlayerShuttleKilled); + + quest.CancelTrade(toTraderShuttle, outSignalCancelled: cancelTradeSignal); + quest.Signal(cancelTradeSignal, () => + { + quest.CancelTransportShip(toTraderTransportShip); + quest.ReturnBoughtItemsToTradeShip(tradeAgreement, toPlayerTransportShip); + quest.Letter(LetterDefOf.NeutralEvent, text: "[cancelledTradeLetterText]", label: "[cancelledTradeLetterLabel]"); + quest.EndActiveTradeShipTradeAgreement(tradeAgreement); + quest.End(QuestEndOutcome.Fail, signalListenMode: QuestPart.SignalListenMode.OngoingOnly); + }); + + // What to do if the player fails to load the shuttle on time + var ticksUntilShuttleDeparture = QuestUtils.CheckTradeShipRequiresGraceTime(quest, slate, tradeAgreement.tradeShip); + quest.ShuttleLeaveDelay(toTraderShuttle, ticksUntilShuttleDeparture, null, Gen.YieldSingle(signalToTraderShuttleSentSatisfied), null, () => + { + quest.CancelTransportShip(toTraderTransportShip); + quest.Letter(LetterDefOf.NeutralEvent, text: "[expiredTradeLetterText]", label: "[expiredTradeLetterLabel]"); + quest.ReturnBoughtItemsToTradeShip(tradeAgreement, toPlayerTransportShip); + quest.EndActiveTradeShipTradeAgreement(tradeAgreement); + quest.End(QuestEndOutcome.Fail, signalListenMode: QuestPart.SignalListenMode.OngoingOnly); + }); + + // What to do if the player destroys the first shuttle + quest.ReturnBoughtItemsToTradeShip(tradeAgreement, toPlayerTransportShip, signalToTraderShuttleKilled); + + // What to do if the player destroys either shuttle + quest.AnySignal(new[] { signalToTraderShuttleKilled, signalToPlayerShuttleKilled }, () => + { + quest.Letter(LetterDefOf.NegativeEvent, signalListenMode: QuestPart.SignalListenMode.OngoingOnly, text: "[tradeShuttleKilledLetterText]", label: "[tradeShuttleKilledLetterLabel]"); + quest.BlacklistPlayerFactionInOrbitalTrade(); + quest.EndActiveTradeShipTradeAgreement(tradeAgreement); + quest.End(QuestEndOutcome.Fail, signalListenMode: QuestPart.SignalListenMode.OngoingOnly); + }); + + // What to do when the player has loaded the shuttle appropriately + quest.Signal(signalToTraderShuttleSentSatisfied, () => + { + quest.TransferItemsToTrader(tradeAgreement, toTraderTransportShip); + quest.ExtendTradeShipDepartureIfVeryShort(tradeAgreement.tradeShip); + }); + + // What to do when the trader has dropped off the items to the player + quest.Signal(signaltoPlayerShuttleSentSatisfied, () => + { + // Put in a small delay so the quest finishes slightly later than immediately after the + // shuttle starts taking off + quest.Delay(500, () => + { + quest.Letter(LetterDefOf.PositiveEvent, text: "[tradeSuccessLetterText]", label: "[tradeSuccessLetterLabel]"); + quest.EndActiveTradeShipTradeAgreement(tradeAgreement); + quest.End(QuestEndOutcome.Success, signalListenMode: QuestPart.SignalListenMode.OngoingOnly); + }).debugLabel = "toPlayerTransportShip departure delay"; + }); + } + + private static (Thing shuttle, TransportShip transportShip) SetupToTraderTransportShip( + Quest quest, + Slate slate, + TradeAgreement tradeAgreement, + string questTag, + out string signalToTraderShuttleSentSatisfied, + out string signalToTraderShuttleKilled) + { + var shuttle = QuestUtils.SetupShuttle("toTraderShuttle", slate, questTag, out signalToTraderShuttleSentSatisfied, out signalToTraderShuttleKilled); + var compTradeShuttle = shuttle.TryGetComp(); + compTradeShuttle.isToTrader = true; + compTradeShuttle.tradeAgreement = tradeAgreement; + var compShuttle = shuttle.TryGetComp(); + compShuttle.requiredPawns = tradeAgreement.pawnsSoldToTrader; + foreach (var thingCount in tradeAgreement.thingsSoldToTrader) + { + var thing = thingCount.thing; + bool healthAffectsPrice = thing.def.healthAffectsPrice; + bool hasQuality = QualityUtility.TryGetQuality(thing, out var quality); + if (healthAffectsPrice || hasQuality) + { + compTradeShuttle.requiredSpecificItems.Add(new ThingDefCountWithRequirements + { + def = thing.def, + count = thingCount.Count, + healthAffectsPrice = healthAffectsPrice, + hitPoints = thing.HitPoints, + hasQuality = hasQuality, + quality = quality + }); + } + else + { + compShuttle.requiredItems.Add(new ThingDefCount(thingCount.thing.def, thingCount.Count)); + } + } + + var transportShip = quest.GenerateTransportShip(TransportShipDefOf.Ship_Shuttle, Enumerable.Empty(), shuttle).transportShip; + slate.Set("toTraderTransportShip", transportShip); + QuestUtility.AddQuestTag(ref transportShip.questTags, questTag); + + var map = tradeAgreement.tradeShip.Map; + IntVec3 landingSpot = QuestUtils.FindLandingSpot(map); + + quest.Letter(LetterDefOf.PositiveEvent, text: "[tradeAcceptedLetterText]", label: "[tradeAcceptedLetterLabel]"); + quest.AddShipJob_Arrive(transportShip, map.Parent, null, landingSpot, ShipJobStartMode.Queue); + quest.AddShipJob_WaitForever(transportShip, true, false).showGizmos = false; + + return (shuttle, transportShip); + } + + private static (Thing shuttle, TransportShip transportShip) SetupToPlayerTransportShip( + Quest quest, + Slate slate, + TradeAgreement tradeAgreement, + string questTag, + string signalToTraderShuttleSentSatisfied, + out string signalToPlayerShuttleSentSatisfied, + out string signalToPlayerShuttleKilled) + { + var shuttle = QuestUtils.SetupShuttle("toPlayerShuttle", slate, questTag, out signalToPlayerShuttleSentSatisfied, out signalToPlayerShuttleKilled); + + foreach (var thing in tradeAgreement.thingsSoldToPlayer) + { + if (thing is Pawn pawn) + { + if (!pawn.IsWorldPawn()) + { + Find.WorldPawns.PassToWorld(pawn); + } + pawn.PreTraded(TradeAction.PlayerBuys, tradeAgreement.negotiator, tradeAgreement.tradeShip); + pawn.psychicEntropy?.SetInitialPsyfocusLevel(); + } + } + + var transportShip = quest.GenerateTransportShip(TransportShipDefOf.Ship_Shuttle, tradeAgreement.thingsSoldToPlayer, shuttle).transportShip; + slate.Set("toPlayerTransportShip", transportShip); + QuestUtility.AddQuestTag(ref transportShip.questTags, questTag); + + var map = tradeAgreement.tradeShip.Map; + IntVec3 landingSpot = QuestUtils.FindLandingSpot(map); + + // Put in a small delay so the shuttles don't come back to back + quest.Delay(500, () => + { + quest.AddShipJob_Arrive(transportShip, map.Parent, null, landingSpot, ShipJobStartMode.Queue); + quest.AddShipJob_Unload(transportShip); + quest.AddShipJob_WaitTime(transportShip, 0, true); + }, signalToTraderShuttleSentSatisfied).debugLabel = "toPlayerTransportShip arrival delay"; + + return (shuttle, transportShip); + } + + protected override bool TestRunInt(Slate slate) + { + var tradeAgreement = slate.Get("tradeAgreement")!; + + return tradeAgreement.tradeShip.GetData().ticksUntilCommsClosed != 0; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestPart_BlacklistPlayerFactionInOrbitalTrade copy.cs b/Source/RealisticOrbitalTrade/Quest/QuestPart_BlacklistPlayerFactionInOrbitalTrade copy.cs new file mode 100644 index 0000000..7547d33 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestPart_BlacklistPlayerFactionInOrbitalTrade copy.cs @@ -0,0 +1,42 @@ +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +internal class QuestPart_ForgivePlayerFactionInOrbitalTrade : QuestPart +{ + public string? inSignal; + + public QuestPart_ForgivePlayerFactionInOrbitalTrade() + { + } + + public override void Notify_QuestSignalReceived(Signal signal) + { + base.Notify_QuestSignalReceived(signal); + if (signal.tag == inSignal) + { + RealisticOrbitalTradeGameComponent.Current.Standing = Standing.Forgiven; + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref inSignal, "inSignal"); + } +} + +internal static class QuestGen_ForgivePlayerFactionInOrbitalTrade +{ + public static QuestPart_ForgivePlayerFactionInOrbitalTrade ForgivePlayerFactionInOrbitalTrade(this Quest quest, string? inSignal = null) + { + QuestPart_ForgivePlayerFactionInOrbitalTrade questPart = new() + { + inSignal = inSignal ?? QuestGen.slate.Get("inSignal") + }; + quest.AddPart(questPart); + return questPart; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestPart_BlacklistPlayerFactionInOrbitalTrade.cs b/Source/RealisticOrbitalTrade/Quest/QuestPart_BlacklistPlayerFactionInOrbitalTrade.cs new file mode 100644 index 0000000..74d7961 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestPart_BlacklistPlayerFactionInOrbitalTrade.cs @@ -0,0 +1,42 @@ +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +internal class QuestPart_BlacklistPlayerFactionInOrbitalTrade : QuestPart +{ + public string? inSignal; + + public QuestPart_BlacklistPlayerFactionInOrbitalTrade() + { + } + + public override void Notify_QuestSignalReceived(Signal signal) + { + base.Notify_QuestSignalReceived(signal); + if (signal.tag == inSignal) + { + RealisticOrbitalTradeGameComponent.Current.Standing = Standing.Blacklisted; + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref inSignal, "inSignal"); + } +} + +internal static class QuestGen_BlacklistPlayerFactionInOrbitalTrade +{ + public static QuestPart_BlacklistPlayerFactionInOrbitalTrade BlacklistPlayerFactionInOrbitalTrade(this Quest quest, string? inSignal = null) + { + QuestPart_BlacklistPlayerFactionInOrbitalTrade questPart = new() + { + inSignal = inSignal ?? QuestGen.slate.Get("inSignal") + }; + quest.AddPart(questPart); + return questPart; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestPart_CancelAmendment.cs b/Source/RealisticOrbitalTrade/Quest/QuestPart_CancelAmendment.cs new file mode 100644 index 0000000..5e65b88 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestPart_CancelAmendment.cs @@ -0,0 +1,36 @@ +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +internal class QuestPart_CancelAmendment : QuestPart_CancelShuttle +{ + protected override string DefaultLabel => "RealisticOrbitalTrade.CancelAmendmentLabel".Translate(); + + protected override string DefaultDesc => "RealisticOrbitalTrade.CancelAmendmentDesc".Translate(); +} + +internal static class QuestGen_CancelAmendment +{ + public static QuestPart_CancelAmendment CancelAmendment( + this Quest quest, + Thing shuttle, + string? inSignalEnable = null, + string? inSignalDisable = null, + string? outSignalCancelled = null) + { + QuestPart_CancelAmendment questPart = new() + { + inSignalEnable = QuestGenUtility.HardcodedSignalWithQuestID(inSignalEnable) ?? QuestGen.slate.Get("inSignal"), + inSignalDisable = QuestGenUtility.HardcodedSignalWithQuestID(inSignalDisable), + shuttle = shuttle + }; + if (outSignalCancelled != null) + { + questPart.outSignalsCompleted.Add(outSignalCancelled); + } + quest.AddPart(questPart); + return questPart; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestPart_CancelShuttle.cs b/Source/RealisticOrbitalTrade/Quest/QuestPart_CancelShuttle.cs new file mode 100644 index 0000000..13b529d --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestPart_CancelShuttle.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using RimWorld; +using UnityEngine; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +[StaticConstructorOnStartup] +internal abstract class QuestPart_CancelShuttle : QuestPartActivable +{ + private static readonly Texture2D Cancel = ContentFinder.Get("UI/Designators/Cancel"); + + public Thing? shuttle; + + protected abstract string DefaultLabel { get; } + protected abstract string DefaultDesc { get; } + + public override IEnumerable ExtraGizmos(ISelectable target) + { + if (target == shuttle) + { + Command_Action commandActionCancel = new() + { + defaultLabel = DefaultLabel, + defaultDesc = DefaultDesc, + icon = Cancel, + activateSound = SoundDefOf.Tick_Low, + action = () => + { + Complete(); + }, + hotKey = KeyBindingDefOf.Designator_Cancel, + }; + return new[] + { + commandActionCancel + }; + } + else + { + return base.ExtraGizmos(target); + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_References.Look(ref shuttle, "shuttle"); + } + + public override void Cleanup() + { + base.Cleanup(); + shuttle = null; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestPart_CancelTrade.cs b/Source/RealisticOrbitalTrade/Quest/QuestPart_CancelTrade.cs new file mode 100644 index 0000000..03c6785 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestPart_CancelTrade.cs @@ -0,0 +1,37 @@ +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +[StaticConstructorOnStartup] +internal class QuestPart_CancelTrade : QuestPart_CancelShuttle +{ + protected override string DefaultLabel => "RealisticOrbitalTrade.CancelTradeAgreementLabel".Translate(); + + protected override string DefaultDesc => "RealisticOrbitalTrade.CancelTradeAgreementDesc".Translate(); +} + +internal static class QuestGen_CancelTrade +{ + public static QuestPart_CancelTrade CancelTrade( + this Quest quest, + Thing shuttle, + string? inSignalEnable = null, + string? inSignalDisable = null, + string? outSignalCancelled = null) + { + QuestPart_CancelTrade questPart = new() + { + inSignalEnable = QuestGenUtility.HardcodedSignalWithQuestID(inSignalEnable) ?? QuestGen.slate.Get("inSignal"), + inSignalDisable = QuestGenUtility.HardcodedSignalWithQuestID(inSignalDisable), + shuttle = shuttle + }; + if (outSignalCancelled != null) + { + questPart.outSignalsCompleted.Add(outSignalCancelled); + } + quest.AddPart(questPart); + return questPart; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestPart_EndActiveTradeShipTradeAgreement.cs b/Source/RealisticOrbitalTrade/Quest/QuestPart_EndActiveTradeShipTradeAgreement.cs new file mode 100644 index 0000000..c154318 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestPart_EndActiveTradeShipTradeAgreement.cs @@ -0,0 +1,48 @@ +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +internal class QuestPart_EndActiveTradeShipTradeAgreement : QuestPart +{ + public string? inSignal; + + public TradeAgreement? tradeAgreement; + + public override void Notify_QuestSignalReceived(Signal signal) + { + base.Notify_QuestSignalReceived(signal); + if (signal.tag == inSignal) + { + RealisticOrbitalTradeGameComponent.Current.EndTradeAgreement(tradeAgreement!); + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref inSignal, "inSignal"); + Scribe_References.Look(ref tradeAgreement, "tradeAgreement"); + } + + public override void Cleanup() + { + base.Cleanup(); + tradeAgreement = null; + } +} + +internal static class QuestGen_EndActiveTradeShipTradeAgreement +{ + public static QuestPart_EndActiveTradeShipTradeAgreement EndActiveTradeShipTradeAgreement(this Quest quest, TradeAgreement tradeAgreement, string? inSignal = null) + { + QuestPart_EndActiveTradeShipTradeAgreement questPart = new() + { + inSignal = inSignal ?? QuestGen.slate.Get("inSignal"), + tradeAgreement = tradeAgreement + }; + quest.AddPart(questPart); + return questPart; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestPart_ExtendTradeShipDepartureIfVeryShort.cs b/Source/RealisticOrbitalTrade/Quest/QuestPart_ExtendTradeShipDepartureIfVeryShort.cs new file mode 100644 index 0000000..f39804b --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestPart_ExtendTradeShipDepartureIfVeryShort.cs @@ -0,0 +1,58 @@ +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +internal class QuestPart_ExtendTradeShipDepartureIfVeryShort : QuestPart +{ + private string? inSignal; + + private TradeShip? tradeShip; + + public QuestPart_ExtendTradeShipDepartureIfVeryShort() + { + } + + public QuestPart_ExtendTradeShipDepartureIfVeryShort(string? inSignal, TradeShip tradeShip) + { + this.inSignal = inSignal ?? QuestGen.slate.Get("inSignal"); + this.tradeShip = tradeShip; + } + + public override void Notify_QuestSignalReceived(Signal signal) + { + base.Notify_QuestSignalReceived(signal); + if (signal.tag == inSignal) + { + // If the trade ship was leaving in less than an hour, make it an hour. + if (tradeShip!.ticksUntilDeparture < 2500) + { + tradeShip.ticksUntilDeparture = 2500; + } + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref inSignal, "inSignal"); + Scribe_References.Look(ref tradeShip, "tradeShip"); + } + + public override void Cleanup() + { + base.Cleanup(); + tradeShip = null; + } +} + +internal static class QuestGen_ExtendTradeShipDepartureIfVeryShort +{ + public static QuestPart_ExtendTradeShipDepartureIfVeryShort ExtendTradeShipDepartureIfVeryShort(this Quest quest, TradeShip tradeShip, string? inSignal = null) + { + QuestPart_ExtendTradeShipDepartureIfVeryShort questPart = new(inSignal ?? QuestGen.slate.Get("inSignal"), tradeShip); + quest.AddPart(questPart); + return questPart; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestPart_ReturnBoughtItemsToTradeShip.cs b/Source/RealisticOrbitalTrade/Quest/QuestPart_ReturnBoughtItemsToTradeShip.cs new file mode 100644 index 0000000..c2faa88 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestPart_ReturnBoughtItemsToTradeShip.cs @@ -0,0 +1,63 @@ +using System.Linq; +using HarmonyLib; +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +internal class QuestPart_ReturnBoughtItemsToTradeShip : QuestPart +{ + public string? inSignal; + + public TradeAgreement? tradeAgreement; + public TransportShip? toPlayerTransportShip; + + public override void Notify_QuestSignalReceived(Signal signal) + { + base.Notify_QuestSignalReceived(signal); + if (signal.tag == inSignal) + { + // Give the things the player bought back to the trader + var things = Traverse.Create(tradeAgreement!.tradeShip).Field("things").Value; + foreach (var thing in toPlayerTransportShip!.TransporterComp.innerContainer.ToList()) + { + if (!things.TryAddOrTransfer(thing)) + { + RealisticOrbitalTradeMod.Warning($"Failed returning {thing.Label} to orbital trader {tradeAgreement.tradeShip.TraderName} in QuestPart_ReturnBoughtItemsToTradeShip"); + thing.Destroy(); + } + } + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref inSignal, "inSignal"); + Scribe_References.Look(ref tradeAgreement, "tradeAgreement"); + Scribe_References.Look(ref toPlayerTransportShip, "toPlayerTransportShip"); + } + + public override void Cleanup() + { + base.Cleanup(); + tradeAgreement = null; + toPlayerTransportShip = null; + } +} + +internal static class QuestGen_ReturnBoughtItemsToTradeShip +{ + public static QuestPart_ReturnBoughtItemsToTradeShip ReturnBoughtItemsToTradeShip(this Quest quest, TradeAgreement tradeAgreement, TransportShip toPlayerTransportShip, string? inSignal = null) + { + QuestPart_ReturnBoughtItemsToTradeShip questPart = new() + { + inSignal = inSignal ?? QuestGen.slate.Get("inSignal"), + tradeAgreement = tradeAgreement, + toPlayerTransportShip = toPlayerTransportShip + }; + quest.AddPart(questPart); + return questPart; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestPart_TransferItemsToTrader.cs b/Source/RealisticOrbitalTrade/Quest/QuestPart_TransferItemsToTrader.cs new file mode 100644 index 0000000..ed59278 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestPart_TransferItemsToTrader.cs @@ -0,0 +1,73 @@ +using System.Collections.Generic; +using System.Linq; +using HarmonyLib; +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +namespace RealisticOrbitalTrade.Quests; + +internal class QuestPart_TransferItemsToTrader : QuestPart +{ + public string? inSignal; + + public TradeAgreement? tradeAgreement; + + public TransportShip? toTraderTransportShip; + + public override void Notify_QuestSignalReceived(Signal signal) + { + base.Notify_QuestSignalReceived(signal); + if (signal.tag == inSignal) + { + var things = Traverse.Create(tradeAgreement!.tradeShip).Field("things").Value; + var soldPrisoners = Traverse.Create(tradeAgreement.tradeShip).Field("soldPrisoners").GetValue>(); + + // Give the things the player sold to the trader + foreach (var thing in toTraderTransportShip!.TransporterComp.innerContainer.ToList()) + { + thing.PreTraded(TradeAction.PlayerSells, tradeAgreement.negotiator, tradeAgreement.tradeShip); + + if (thing is Pawn pawn && pawn.RaceProps.Humanlike) + { + soldPrisoners.Add(pawn); + } + if (!things.TryAddOrTransfer(thing)) + { + RealisticOrbitalTradeMod.Warning($"Failed transferring {thing.Label} to orbital trader {tradeAgreement.tradeShip.TraderName} in QuestPart_TransferItemsToTrader"); + thing.Destroy(); + } + } + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref inSignal, "inSignal"); + Scribe_References.Look(ref tradeAgreement, "tradeAgreement"); + Scribe_References.Look(ref toTraderTransportShip, "toTraderTransportShip"); + } + + public override void Cleanup() + { + base.Cleanup(); + tradeAgreement = null; + toTraderTransportShip = null; + } +} + +internal static class QuestGen_TransferItemsToTrader +{ + public static QuestPart_TransferItemsToTrader TransferItemsToTrader(this Quest quest, TradeAgreement tradeAgreement, TransportShip toTraderTransportShip, string? inSignal = null) + { + QuestPart_TransferItemsToTrader questPart = new() + { + inSignal = inSignal ?? QuestGen.slate.Get("inSignal"), + tradeAgreement = tradeAgreement, + toTraderTransportShip = toTraderTransportShip + }; + quest.AddPart(questPart); + return questPart; + } +} diff --git a/Source/RealisticOrbitalTrade/Quest/QuestUtils.cs b/Source/RealisticOrbitalTrade/Quest/QuestUtils.cs new file mode 100644 index 0000000..523adf7 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Quest/QuestUtils.cs @@ -0,0 +1,97 @@ +using RimWorld; +using RimWorld.QuestGen; +using Verse; + +using RWShipJobDefOf = RimWorld.ShipJobDefOf; + +namespace RealisticOrbitalTrade.Quests; + +internal class QuestUtils +{ + /// + /// How much longer after the shuttle leaves the orbital trader will leave. + /// This is just to give the illusion of shuttles taking a moment to get + /// to orbit. 2,500 ticks is 1 in-game hour. + /// + private const int AdditionalTicksAfterDeparture = 2500; + + public static Thing SetupShuttle( + string shuttleName, + Slate slate, + string questTag, + out string signalshuttleSentSatisfied, + out string signalshuttleKilled, + bool isForAmends = false) + { + signalshuttleSentSatisfied = QuestGenUtility.HardcodedSignalWithQuestID($"{shuttleName}.SentSatisfied"); + signalshuttleKilled = QuestGenUtility.HardcodedSignalWithQuestID($"{shuttleName}.Killed"); + + Thing shuttle; + if (RealisticOrbitalTradeGameComponent.Current.Standing == Standing.Good) + { + shuttle = ThingMaker.MakeThing(ThingDefOf.ROT_TradeShuttle); + } + else if (!isForAmends) + { + shuttle = ThingMaker.MakeThing(ThingDefOf.ROT_ExplosiveRiggedTradeShuttle); + } + else + { + shuttle = ThingMaker.MakeThing(ThingDefOf.ROT_ExplosiveRiggedAmendmentTradeShuttle); + } + slate.Set(shuttleName, shuttle); + QuestUtility.AddQuestTag(ref shuttle.questTags, questTag); + + return shuttle; + } + + public static int CheckTradeShipRequiresGraceTime(Quest quest, Slate slate, TradeShip tradeShip) + { + // Possible scenarios: + // * TUD is [some_value], TUCC is -1 => No trade agreements made in grace period yet + // * TUD is [some_value], TUCC is < [some_value] => Grace period has already been extended; + // it can be extended again, but the comms + // should close just as early. + + int originalTicksUntilCommsClosed = tradeShip.GetData().ticksUntilCommsClosed; + int originalTicksUntilDeparture = tradeShip.ticksUntilDeparture; + bool tradeRequiresGraceTime = originalTicksUntilDeparture < Settings.MinTicksUntilDepartureBeforeGraceTime; + bool tradeShipWasAlreadyInGraceTime = originalTicksUntilCommsClosed != -1; + + if (tradeRequiresGraceTime) + { + slate.Set("graceTimeTimeLeft", originalTicksUntilDeparture.ToStringTicksToPeriod()); + slate.Set("graceTimeTimeMinimum", Settings.MinTicksUntilDepartureBeforeGraceTime.ToStringTicksToPeriod()); + slate.Set("graceTimeTimeExtra", Settings.DepartureGraceTimeTicks.ToStringTicksToPeriod()); + quest.Letter(LetterDefOf.NeutralEvent, text: "[graceTimeLetterText]", label: "[graceTimeLetterLabel]"); + + if (!tradeShipWasAlreadyInGraceTime) + { + tradeShip.GetData().ticksUntilCommsClosed = originalTicksUntilDeparture; + } + tradeShip.ticksUntilDeparture = Settings.DepartureGraceTimeTicks + AdditionalTicksAfterDeparture; + } + + return tradeShip.ticksUntilDeparture - AdditionalTicksAfterDeparture; + } + + public static void CancelTransportShip(Quest quest, TransportShip transportShip) + { + quest.AddShipJob(transportShip, ShipJobDefOf.ROT_CancelLoad, ShipJobStartMode.Instant); + quest.AddShipJob(transportShip, RWShipJobDefOf.Unload, ShipJobStartMode.Queue); + quest.AddShipJob(transportShip, RWShipJobDefOf.FlyAway, ShipJobStartMode.Queue); + } + + public static IntVec3 FindLandingSpot(Map map) + { + return DropCellFinder.GetBestShuttleLandingSpot(map, null); + } +} + +internal static class QuestUtilsExtensions +{ + public static void CancelTransportShip(this Quest quest, TransportShip transportShip) + { + QuestUtils.CancelTransportShip(quest, transportShip); + } +} diff --git a/Source/RealisticOrbitalTrade/ShipJobs/ROT_ShipJob_CancelLoading.cs b/Source/RealisticOrbitalTrade/ShipJobs/ROT_ShipJob_CancelLoading.cs new file mode 100644 index 0000000..50e620a --- /dev/null +++ b/Source/RealisticOrbitalTrade/ShipJobs/ROT_ShipJob_CancelLoading.cs @@ -0,0 +1,48 @@ +using RealisticOrbitalTrade.Comps; +using RimWorld; +using Verse; +using Verse.AI; + +namespace RealisticOrbitalTrade.ShipJobs; + +public class ShipJob_CancelLoad : ShipJob +{ + private bool done; + + protected override bool ShouldEnd => done; + public override bool Interruptible => false; + + public override bool TryStart() + { + if (!transportShip.ShipExistsAndIsSpawned) + { + return false; + } + return base.TryStart(); + } + + public override void Tick() + { + base.Tick(); + if (!done) + { + // Stop autoloading and remove any things from leftToLoad + CompTradeShuttle compTradeShuttle = transportShip.shipThing.TryGetComp(); + compTradeShuttle.cancelled = true; + compTradeShuttle.ShuttleAutoLoad = false; + transportShip.TransporterComp.leftToLoad.Clear(); + + // End any jobs currently involved in loading the transport ship + foreach (var humanLike in transportShip.shipThing.Map.mapPawns.AllHumanlike) + { + if (humanLike.CurJobDef == JobDefOf.HaulToTransporter && humanLike.CurJob.targetB == transportShip.shipThing) + { + humanLike.jobs.EndCurrentJob(JobCondition.Incompletable, true, true); + } + } + + // We only need to do this once + done = true; + } + } +} diff --git a/Source/RealisticOrbitalTrade/Utils.cs b/Source/RealisticOrbitalTrade/Utils.cs new file mode 100644 index 0000000..e9699b8 --- /dev/null +++ b/Source/RealisticOrbitalTrade/Utils.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using HarmonyLib; + +namespace RealisticOrbitalTrade; + +internal static class Utils +{ + public static IEnumerable InjectCallBeforeReturn( + IEnumerable instructions, + MethodInfo methodToCall, + Func matchInstruction, + IEnumerable? additionalInstructionsBeforeCall = null) + { + var codeMatcher = new CodeMatcher(instructions); + codeMatcher.End(); + if (codeMatcher.Instruction.opcode != OpCodes.Ret) + { + throw new InjectCallBeforeReturnException(codeMatcher.Instructions()); + } + while (codeMatcher.Pos > 0) + { + codeMatcher.Advance(-1); + if (matchInstruction(codeMatcher.Instruction)) + { + codeMatcher.Insert((additionalInstructionsBeforeCall ?? new CodeInstruction[] { }).Concat(new[]{ + // new CodeInstruction(OpCodes.Ldarg_0), + // new CodeInstruction(OpCodes.Ldloc_0), + new CodeInstruction(OpCodes.Call, methodToCall) + })); + + return codeMatcher.Instructions(); + } + } + + throw new InjectCallBeforeReturnException(codeMatcher.Instructions()); + } +} + +[Serializable] +public class InjectCallBeforeReturnException : Exception +{ + public IEnumerable Instructions { get; } + + public InjectCallBeforeReturnException(IEnumerable instructions) + : base() + { + Instructions = instructions; + } +} + +[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method)] +public class ReloadableAttribute : Attribute { }