From f123087611543b82348e553a969c03a0f9c9d94e Mon Sep 17 00:00:00 2001 From: "Hong Jing (Jingles)" Date: Thu, 5 Sep 2024 10:44:29 +0800 Subject: [PATCH 01/17] init giftcard upgrade --- packages/mesh-contract/src/common.ts | 5 + .../.gitignore | 0 .../aiken.lock | 0 .../aiken.toml | 0 .../plutus.json | 0 .../readme.md | 0 .../validators/oneshot.ak | 0 .../giftcard/aiken-workspace-v2/plutus.json | 138 ++++++++++++++++++ .../mesh-contract/src/giftcard/offchain.ts | 33 +++-- 9 files changed, 167 insertions(+), 9 deletions(-) rename packages/mesh-contract/src/giftcard/{aiken-workspace => aiken-workspace-v1}/.gitignore (100%) rename packages/mesh-contract/src/giftcard/{aiken-workspace => aiken-workspace-v1}/aiken.lock (100%) rename packages/mesh-contract/src/giftcard/{aiken-workspace => aiken-workspace-v1}/aiken.toml (100%) rename packages/mesh-contract/src/giftcard/{aiken-workspace => aiken-workspace-v1}/plutus.json (100%) rename packages/mesh-contract/src/giftcard/{aiken-workspace => aiken-workspace-v1}/readme.md (100%) rename packages/mesh-contract/src/giftcard/{aiken-workspace => aiken-workspace-v1}/validators/oneshot.ak (100%) create mode 100644 packages/mesh-contract/src/giftcard/aiken-workspace-v2/plutus.json diff --git a/packages/mesh-contract/src/common.ts b/packages/mesh-contract/src/common.ts index c577de45..4b4522a4 100644 --- a/packages/mesh-contract/src/common.ts +++ b/packages/mesh-contract/src/common.ts @@ -13,6 +13,7 @@ export type MeshTxInitiatorInput = { wallet?: BrowserWallet | MeshWallet; networkId?: number; stakeCredential?: string; + version?: number; }; export class MeshTxInitiator { @@ -21,6 +22,7 @@ export class MeshTxInitiator { wallet?: BrowserWallet | MeshWallet; stakeCredential?: string; networkId = 0; + version = 1; constructor({ mesh, @@ -28,6 +30,7 @@ export class MeshTxInitiator { wallet, networkId = 0, stakeCredential, + version = 1, }: MeshTxInitiatorInput) { this.mesh = mesh; if (fetcher) { @@ -47,6 +50,8 @@ export class MeshTxInitiator { if (stakeCredential) { this.stakeCredential = this.stakeCredential; } + + this.version = version; } protected signSubmitReset = async () => { diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace/.gitignore b/packages/mesh-contract/src/giftcard/aiken-workspace-v1/.gitignore similarity index 100% rename from packages/mesh-contract/src/giftcard/aiken-workspace/.gitignore rename to packages/mesh-contract/src/giftcard/aiken-workspace-v1/.gitignore diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace/aiken.lock b/packages/mesh-contract/src/giftcard/aiken-workspace-v1/aiken.lock similarity index 100% rename from packages/mesh-contract/src/giftcard/aiken-workspace/aiken.lock rename to packages/mesh-contract/src/giftcard/aiken-workspace-v1/aiken.lock diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace/aiken.toml b/packages/mesh-contract/src/giftcard/aiken-workspace-v1/aiken.toml similarity index 100% rename from packages/mesh-contract/src/giftcard/aiken-workspace/aiken.toml rename to packages/mesh-contract/src/giftcard/aiken-workspace-v1/aiken.toml diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace/plutus.json b/packages/mesh-contract/src/giftcard/aiken-workspace-v1/plutus.json similarity index 100% rename from packages/mesh-contract/src/giftcard/aiken-workspace/plutus.json rename to packages/mesh-contract/src/giftcard/aiken-workspace-v1/plutus.json diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace/readme.md b/packages/mesh-contract/src/giftcard/aiken-workspace-v1/readme.md similarity index 100% rename from packages/mesh-contract/src/giftcard/aiken-workspace/readme.md rename to packages/mesh-contract/src/giftcard/aiken-workspace-v1/readme.md diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace/validators/oneshot.ak b/packages/mesh-contract/src/giftcard/aiken-workspace-v1/validators/oneshot.ak similarity index 100% rename from packages/mesh-contract/src/giftcard/aiken-workspace/validators/oneshot.ak rename to packages/mesh-contract/src/giftcard/aiken-workspace-v1/validators/oneshot.ak diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/plutus.json b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/plutus.json new file mode 100644 index 00000000..e0dd61ff --- /dev/null +++ b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/plutus.json @@ -0,0 +1,138 @@ +{ + "preamble": { + "title": "meshjs/giftcard", + "description": "Aiken contracts for project 'meshjs/giftcard'", + "version": "0.0.0", + "plutusVersion": "v2", + "compiler": { + "name": "Aiken", + "version": "v1.0.29-alpha+unknown" + }, + "license": "Apache-2.0" + }, + "validators": [ + { + "title": "oneshot.gift_card", + "redeemer": { + "title": "rdmr", + "schema": { + "$ref": "#/definitions/oneshot~1Action" + } + }, + "parameters": [ + { + "title": "token_name", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "utxo_ref", + "schema": { + "$ref": "#/definitions/aiken~1transaction~1OutputReference" + } + } + ], + "compiledCode": "5901f5010000323232323232322322232323225333009323232533300c3007300d3754002264646464a666026602c00426464a666024601a60266ea803854ccc048c034c04cdd5191980080080311299980b8008a60103d87a80001323253330163375e603660306ea800804c4cdd2a40006603400497ae0133004004001301b002301900115333012300c00113371e00402029405854ccc048cdc3800a4002266e3c0080405281bad3013002375c60220022c602800264a66601e601260206ea800452f5bded8c026eacc050c044dd500099191980080099198008009bab3016301730173017301700522533301500114bd6f7b630099191919299980b19b91488100002153330163371e9101000021003100513301a337606ea4008dd3000998030030019bab3017003375c602a0046032004602e00244a666028002298103d87a800013232323253330153372200e0042a66602a66e3c01c0084cdd2a4000660326e980052f5c02980103d87a80001330060060033756602c0066eb8c050008c060008c058004dd7180998081baa00337586024002601c6ea800858c040c044008c03c004c02cdd50008a4c26cac64a66601060060022a66601660146ea8010526161533300830020011533300b300a37540082930b0b18041baa003370e90011b8748000dd7000ab9a5573aaae7955cfaba05742ae89", + "hash": "0c0d17d9095fe6b07a2727403e2c6f2dff8042ed7c300cb67a2577a2" + }, + { + "title": "oneshot.redeem", + "datum": { + "title": "_d", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "redeemer": { + "title": "_r", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "parameters": [ + { + "title": "token_name", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "policy_id", + "schema": { + "$ref": "#/definitions/ByteArray" + } + } + ], + "compiledCode": "5901320100003232323232323223223222253330083232533300d3010002132533300b3370e6eb4c034009200113371e0020122940dd718058008b180700099299980499b8748008c028dd50008a5eb7bdb1804dd5980718059baa001323300100132330010013756601e602060206020602060186ea8c03cc030dd50019129998070008a5eb7bdb1804c8c8c8c94ccc03ccdc8a45000021533300f3371e91010000210031005133013337606ea4008dd3000998030030019bab3010003375c601c0046024004602000244a66601a002298103d87a8000132323232533300e337220140042a66601c66e3c0280084cdd2a4000660246e980052f5c02980103d87a80001330060060033756601e0066eb8c034008c044008c03c00452613656375c0026eb80055cd2ab9d5573caae7d5d02ba157441", + "hash": "39faa048196bb6b30f50815475e9d16b22e7a0ef6de5935b408ca617" + } + ], + "definitions": { + "ByteArray": { + "dataType": "bytes" + }, + "Data": { + "title": "Data", + "description": "Any Plutus data." + }, + "Int": { + "dataType": "integer" + }, + "aiken/transaction/OutputReference": { + "title": "OutputReference", + "description": "An `OutputReference` is a unique reference to an output on-chain. The `output_index`\n corresponds to the position in the output list of the transaction (identified by its id)\n that produced that output", + "anyOf": [ + { + "title": "OutputReference", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "transaction_id", + "$ref": "#/definitions/aiken~1transaction~1TransactionId" + }, + { + "title": "output_index", + "$ref": "#/definitions/Int" + } + ] + } + ] + }, + "aiken/transaction/TransactionId": { + "title": "TransactionId", + "description": "A unique transaction identifier, as the hash of a transaction body. Note that the transaction id\n isn't a direct hash of the `Transaction` as visible on-chain. Rather, they correspond to hash\n digests of transaction body as they are serialized on the network.", + "anyOf": [ + { + "title": "TransactionId", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "hash", + "$ref": "#/definitions/ByteArray" + } + ] + } + ] + }, + "oneshot/Action": { + "title": "Action", + "anyOf": [ + { + "title": "Mint", + "dataType": "constructor", + "index": 0, + "fields": [] + }, + { + "title": "Burn", + "dataType": "constructor", + "index": 1, + "fields": [] + } + ] + } + } +} \ No newline at end of file diff --git a/packages/mesh-contract/src/giftcard/offchain.ts b/packages/mesh-contract/src/giftcard/offchain.ts index 50de3d35..53a6d8ca 100644 --- a/packages/mesh-contract/src/giftcard/offchain.ts +++ b/packages/mesh-contract/src/giftcard/offchain.ts @@ -19,9 +19,8 @@ import { import { applyParamsToScript } from "@meshsdk/core-csl"; import { MeshTxInitiator, MeshTxInitiatorInput } from "../common"; -import blueprint from "./aiken-workspace/plutus.json"; - -export const MeshGiftCardBlueprint = blueprint; +import blueprintV1 from "./aiken-workspace-v1/plutus.json"; +import blueprintV2 from "./aiken-workspace-v2/plutus.json"; export class MeshGiftCardContract extends MeshTxInitiator { tokenNameHex: string = ""; @@ -32,18 +31,34 @@ export class MeshGiftCardContract extends MeshTxInitiator { utxoTxHash: string, utxoTxId: number, ) => { + let scriptCbor; + switch (this.version) { + case 2: + scriptCbor = blueprintV2.validators[0]!.compiledCode; + break; + default: + scriptCbor = blueprintV1.validators[0]!.compiledCode; + } + return applyParamsToScript( - blueprint.validators[0]!.compiledCode, + scriptCbor, [builtinByteString(tokenNameHex), txOutRef(utxoTxHash, utxoTxId)], "JSON", ); }; - redeemCbor = (tokenNameHex: string, policyId: string) => - applyParamsToScript(blueprint.validators[1]!.compiledCode, [ - tokenNameHex, - policyId, - ]); + redeemCbor = (tokenNameHex: string, policyId: string) => { + let scriptCbor; + switch (this.version) { + case 2: + scriptCbor = blueprintV2.validators[1]!.compiledCode; + break; + default: + scriptCbor = blueprintV1.validators[1]!.compiledCode; + } + + return applyParamsToScript(scriptCbor, [tokenNameHex, policyId]); + }; constructor( inputs: MeshTxInitiatorInput, From cfdb3c5489c6fcfd478d1996af8881f6143ee0da Mon Sep 17 00:00:00 2001 From: "Hong Jing (Jingles)" Date: Thu, 5 Sep 2024 12:08:19 +0800 Subject: [PATCH 02/17] add docs link --- apps/playground/package.json | 8 +- .../button/button-float-documentation.tsx | 14 ++++ .../src/components/button/button.tsx | 36 ++++++--- .../pages/apis/transaction/basics/index.tsx | 2 + .../pages/apis/transaction/minting/index.tsx | 2 + .../apis/transaction/smart-contract/index.tsx | 2 + .../pages/apis/transaction/staking/index.tsx | 3 + .../src/pages/apis/txbuilder/basics/index.tsx | 4 +- .../pages/apis/txbuilder/minting/index.tsx | 2 + .../apis/txbuilder/smart-contract/index.tsx | 2 + .../pages/apis/txbuilder/staking/index.tsx | 3 + .../pages/apis/wallets/appwallet/index.tsx | 2 + .../apis/wallets/browserwallet/index.tsx | 5 ++ .../pages/apis/wallets/meshwallet/index.tsx | 2 + .../src/pages/providers/blockfrost.tsx | 2 + apps/playground/src/pages/providers/koios.tsx | 2 + .../src/pages/providers/maestro.tsx | 2 + .../playground/src/pages/providers/ogmios.tsx | 2 + apps/playground/src/pages/providers/yaci.tsx | 2 + .../pages/smart-contracts/escrow/index.tsx | 2 + .../pages/smart-contracts/giftcard/index.tsx | 2 + .../smart-contracts/marketplace/index.tsx | 3 + .../payment-splitter/index.tsx | 2 + .../src/pages/smart-contracts/swap/index.tsx | 2 + .../pages/smart-contracts/vesting/index.tsx | 2 + apps/playground/src/styles/globals.css | 4 + apps/playground/tailwind.config.js | 7 +- package-lock.json | 74 +++++++++---------- 28 files changed, 138 insertions(+), 57 deletions(-) create mode 100644 apps/playground/src/components/button/button-float-documentation.tsx diff --git a/apps/playground/package.json b/apps/playground/package.json index 2d7a48ba..549ed060 100644 --- a/apps/playground/package.json +++ b/apps/playground/package.json @@ -21,17 +21,17 @@ "@next/mdx": "^14.2.3", "@next/third-parties": "^14.2.5", "copy-to-clipboard": "^3.3.3", - "flowbite": "^2.3.0", + "flowbite": "^2.5.1", "flowbite-react": "^0.9.0", "flowbite-typography": "^1.0.3", + "json-bigint": "^1.0.0", "next": "^14.1.1", "persist-and-sync": "^1.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-highlight": "^0.15.0", "react-scroll": "^1.9.0", - "zustand": "^4.5.4", - "json-bigint": "^1.0.0" + "zustand": "^4.5.4" }, "devDependencies": { "@meshsdk/configs": "*", @@ -51,4 +51,4 @@ "typescript": "^5.3.3" }, "prettier": "@meshsdk/configs/prettier" -} \ No newline at end of file +} diff --git a/apps/playground/src/components/button/button-float-documentation.tsx b/apps/playground/src/components/button/button-float-documentation.tsx new file mode 100644 index 00000000..3e1814c0 --- /dev/null +++ b/apps/playground/src/components/button/button-float-documentation.tsx @@ -0,0 +1,14 @@ +import { DocumentTextIcon } from "@heroicons/react/24/solid"; + +import Link from "../link"; +import Button from "./button"; + +export default function ButtonFloatDocumentation({ href }: { href: string }) { + return ( + + + + ); +} diff --git a/apps/playground/src/components/button/button.tsx b/apps/playground/src/components/button/button.tsx index f035f8ad..4fe0cea6 100644 --- a/apps/playground/src/components/button/button.tsx +++ b/apps/playground/src/components/button/button.tsx @@ -4,6 +4,8 @@ export default function Button({ style, onClick, disabled, + id, + tooltip, }: { children: React.ReactNode; className?: string; @@ -15,8 +17,10 @@ export default function Button({ | "info" | "light" | "dark"; - onClick: () => void; + onClick?: () => void; disabled?: boolean; + id?: string; + tooltip?: string; }) { const styles = { primary: @@ -36,24 +40,32 @@ export default function Button({ let _style = style && styles[style] ? styles[style] : styles.primary; if (className) { - style += ` ${className}`; + _style += ` ${className}`; } if (disabled) { _style += ` cursor-not-allowed`; } - style += ` not-format`; + _style += ` not-format button-with-tooltip`; return ( - + <> + + ); } diff --git a/apps/playground/src/pages/apis/transaction/basics/index.tsx b/apps/playground/src/pages/apis/transaction/basics/index.tsx index dc0e7c3f..05218de2 100644 --- a/apps/playground/src/pages/apis/transaction/basics/index.tsx +++ b/apps/playground/src/pages/apis/transaction/basics/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; @@ -66,6 +67,7 @@ const ReactPage: NextPage = () => { sending assets and various options to customize the transaction.

+ diff --git a/apps/playground/src/pages/apis/transaction/minting/index.tsx b/apps/playground/src/pages/apis/transaction/minting/index.tsx index b348f370..5a392a02 100644 --- a/apps/playground/src/pages/apis/transaction/minting/index.tsx +++ b/apps/playground/src/pages/apis/transaction/minting/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; @@ -44,6 +45,7 @@ const ReactPage: NextPage = () => { minting and burning assets.

+ diff --git a/apps/playground/src/pages/apis/transaction/smart-contract/index.tsx b/apps/playground/src/pages/apis/transaction/smart-contract/index.tsx index 54c88300..4d0212b5 100644 --- a/apps/playground/src/pages/apis/transaction/smart-contract/index.tsx +++ b/apps/playground/src/pages/apis/transaction/smart-contract/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; @@ -48,6 +49,7 @@ const ReactPage: NextPage = () => { smart contracts.

+ diff --git a/apps/playground/src/pages/apis/transaction/staking/index.tsx b/apps/playground/src/pages/apis/transaction/staking/index.tsx index 8df2b89f..4cf2adcc 100644 --- a/apps/playground/src/pages/apis/transaction/staking/index.tsx +++ b/apps/playground/src/pages/apis/transaction/staking/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; @@ -42,6 +43,8 @@ const ReactPage: NextPage = () => { staking process.

+ + diff --git a/apps/playground/src/pages/apis/txbuilder/basics/index.tsx b/apps/playground/src/pages/apis/txbuilder/basics/index.tsx index 1db052e1..62d79334 100644 --- a/apps/playground/src/pages/apis/txbuilder/basics/index.tsx +++ b/apps/playground/src/pages/apis/txbuilder/basics/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import Link from "~/components/link"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; @@ -11,11 +12,11 @@ import TxbuilderCip20 from "./cip20"; import TxbuilderCoinSelection from "./coin-selection"; import TxbuilderInitializeTxbuilder from "./initialize-txbuilder"; import TxbuilderMultisig from "./multisig"; +import TxbuilderMultisigNativeScript from "./multisig-native-script"; import TxbuilderSendValues from "./send-values"; import TxbuilderSetNetwork from "./set-network"; import TxbuilderSetRequiredSigners from "./set-required-signers"; import TxbuilderSetTime from "./set-time"; -import TxbuilderMultisigNativeScript from "./multisig-native-script"; const ReactPage: NextPage = () => { const sidebarItems = [ @@ -65,6 +66,7 @@ const ReactPage: NextPage = () => {

+ {/* */} diff --git a/apps/playground/src/pages/apis/txbuilder/minting/index.tsx b/apps/playground/src/pages/apis/txbuilder/minting/index.tsx index 9a3662dd..e2b3b1f2 100644 --- a/apps/playground/src/pages/apis/txbuilder/minting/index.tsx +++ b/apps/playground/src/pages/apis/txbuilder/minting/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; @@ -47,6 +48,7 @@ const ReactPage: NextPage = () => {

+ diff --git a/apps/playground/src/pages/apis/txbuilder/smart-contract/index.tsx b/apps/playground/src/pages/apis/txbuilder/smart-contract/index.tsx index 58441a9a..c0511613 100644 --- a/apps/playground/src/pages/apis/txbuilder/smart-contract/index.tsx +++ b/apps/playground/src/pages/apis/txbuilder/smart-contract/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; @@ -53,6 +54,7 @@ const ReactPage: NextPage = () => { + diff --git a/apps/playground/src/pages/apis/txbuilder/staking/index.tsx b/apps/playground/src/pages/apis/txbuilder/staking/index.tsx index 84012996..ec98f2a5 100644 --- a/apps/playground/src/pages/apis/txbuilder/staking/index.tsx +++ b/apps/playground/src/pages/apis/txbuilder/staking/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; @@ -33,6 +34,8 @@ const ReactPage: NextPage = () => { > <> + + diff --git a/apps/playground/src/pages/apis/wallets/appwallet/index.tsx b/apps/playground/src/pages/apis/wallets/appwallet/index.tsx index faba4f39..5632baca 100644 --- a/apps/playground/src/pages/apis/wallets/appwallet/index.tsx +++ b/apps/playground/src/pages/apis/wallets/appwallet/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; @@ -39,6 +40,7 @@ const ReactPage: NextPage = () => { fully customed applications's backend.

+ diff --git a/apps/playground/src/pages/apis/wallets/browserwallet/index.tsx b/apps/playground/src/pages/apis/wallets/browserwallet/index.tsx index e15d2eec..a98b0e14 100644 --- a/apps/playground/src/pages/apis/wallets/browserwallet/index.tsx +++ b/apps/playground/src/pages/apis/wallets/browserwallet/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import Link from "~/components/link"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; @@ -78,12 +79,16 @@ const ReactPage: NextPage = () => { are useful for building dApps.

+

Check out the full documentation on

+

In this section, you can connect wallet and try APIs for dApps to communicate with your wallet.

+ + diff --git a/apps/playground/src/pages/apis/wallets/meshwallet/index.tsx b/apps/playground/src/pages/apis/wallets/meshwallet/index.tsx index 680e2f34..f6dc6ade 100644 --- a/apps/playground/src/pages/apis/wallets/meshwallet/index.tsx +++ b/apps/playground/src/pages/apis/wallets/meshwallet/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; import Metatags from "~/components/site/metatags"; @@ -63,6 +64,7 @@ const ReactPage: NextPage = () => { get started.

+ diff --git a/apps/playground/src/pages/providers/blockfrost.tsx b/apps/playground/src/pages/providers/blockfrost.tsx index b507a2c5..0786ade9 100644 --- a/apps/playground/src/pages/providers/blockfrost.tsx +++ b/apps/playground/src/pages/providers/blockfrost.tsx @@ -2,6 +2,7 @@ import type { NextPage } from "next"; import { BlockfrostProvider } from "@meshsdk/core"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import Link from "~/components/link"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; @@ -69,6 +70,7 @@ const ReactPage: NextPage = () => {

+ { + { const sidebarItems = [ @@ -75,6 +76,7 @@ const ReactPage: NextPage = () => {

Get started:

+ {

Get started:

+ {

Get started:

+ { const sidebarItems = [ @@ -86,6 +87,7 @@ const ReactPage: NextPage = () => { + diff --git a/apps/playground/src/pages/smart-contracts/giftcard/index.tsx b/apps/playground/src/pages/smart-contracts/giftcard/index.tsx index 768fbf1c..fa713bb0 100644 --- a/apps/playground/src/pages/smart-contracts/giftcard/index.tsx +++ b/apps/playground/src/pages/smart-contracts/giftcard/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import Link from "~/components/link"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; @@ -82,6 +83,7 @@ const ReactPage: NextPage = () => {

+ diff --git a/apps/playground/src/pages/smart-contracts/marketplace/index.tsx b/apps/playground/src/pages/smart-contracts/marketplace/index.tsx index f7f98a4d..4e60d9ce 100644 --- a/apps/playground/src/pages/smart-contracts/marketplace/index.tsx +++ b/apps/playground/src/pages/smart-contracts/marketplace/index.tsx @@ -13,6 +13,7 @@ import MarketplaceBuyAsset from "./buy-asset"; import MarketplaceCancelListing from "./cancel-listing"; import MarketplaceListAsset from "./list-asset"; import MarketplaceUpdateListing from "./update-listing"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; const ReactPage: NextPage = () => { const sidebarItems = [ @@ -112,6 +113,8 @@ const ReactPage: NextPage = () => { + + diff --git a/apps/playground/src/pages/smart-contracts/payment-splitter/index.tsx b/apps/playground/src/pages/smart-contracts/payment-splitter/index.tsx index 4c4691b1..59f10f1a 100644 --- a/apps/playground/src/pages/smart-contracts/payment-splitter/index.tsx +++ b/apps/playground/src/pages/smart-contracts/payment-splitter/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import Link from "~/components/link"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; @@ -102,6 +103,7 @@ const ReactPage: NextPage = () => {

+ diff --git a/apps/playground/src/pages/smart-contracts/swap/index.tsx b/apps/playground/src/pages/smart-contracts/swap/index.tsx index 72864e3e..cffbf8f3 100644 --- a/apps/playground/src/pages/smart-contracts/swap/index.tsx +++ b/apps/playground/src/pages/smart-contracts/swap/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import MintMeshToken from "~/components/cardano/mint-mesh-token"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import Link from "~/components/link"; @@ -86,6 +87,7 @@ const ReactPage: NextPage = () => { + diff --git a/apps/playground/src/pages/smart-contracts/vesting/index.tsx b/apps/playground/src/pages/smart-contracts/vesting/index.tsx index 555d3e1a..933bd34a 100644 --- a/apps/playground/src/pages/smart-contracts/vesting/index.tsx +++ b/apps/playground/src/pages/smart-contracts/vesting/index.tsx @@ -1,5 +1,6 @@ import type { NextPage } from "next"; +import ButtonFloatDocumentation from "~/components/button/button-float-documentation"; import SidebarFullwidth from "~/components/layouts/sidebar-fullwidth"; import Link from "~/components/link"; import TitleIconDescriptionBody from "~/components/sections/title-icon-description-body"; @@ -84,6 +85,7 @@ const ReactPage: NextPage = () => {

+ diff --git a/apps/playground/src/styles/globals.css b/apps/playground/src/styles/globals.css index b5c61c95..404c03a1 100644 --- a/apps/playground/src/styles/globals.css +++ b/apps/playground/src/styles/globals.css @@ -1,3 +1,7 @@ @tailwind base; @tailwind components; @tailwind utilities; + +.button-with-tooltip:hover .button-with-tooltip-content { + visibility: visible; +} diff --git a/apps/playground/tailwind.config.js b/apps/playground/tailwind.config.js index 6255a9d6..17994b23 100644 --- a/apps/playground/tailwind.config.js +++ b/apps/playground/tailwind.config.js @@ -1,11 +1,12 @@ +const flowbite = require("flowbite-react/tailwind"); + /** @type {import('tailwindcss').Config} */ module.exports = { darkMode: "class", content: [ - "./node_modules/flowbite/**/*.js", - "./node_modules/flowbite-react/**/*.js", "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", "./src/components/**/*.{js,ts,jsx,tsx,mdx}", + flowbite.content(), ], theme: { extend: { @@ -73,5 +74,5 @@ module.exports = { ], }, }, - plugins: [require("flowbite-typography"), require("flowbite/plugin")], + plugins: [require("flowbite-typography"), flowbite.plugin()], }; diff --git a/package-lock.json b/package-lock.json index 984b0b97..b5465bd4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -276,7 +276,7 @@ "@next/mdx": "^14.2.3", "@next/third-parties": "^14.2.5", "copy-to-clipboard": "^3.3.3", - "flowbite": "^2.3.0", + "flowbite": "^2.5.1", "flowbite-react": "^0.9.0", "flowbite-typography": "^1.0.3", "json-bigint": "^1.0.0", @@ -22364,7 +22364,7 @@ }, "packages/mesh-common": { "name": "@meshsdk/common", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { "bech32": "^2.0.0", @@ -22381,14 +22381,14 @@ }, "packages/mesh-contract": { "name": "@meshsdk/contract", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "1.7.0", - "@meshsdk/core": "1.7.0", - "@meshsdk/core-csl": "1.7.0", - "@meshsdk/core-cst": "1.7.0", - "@meshsdk/transaction": "1.7.0" + "@meshsdk/common": "1.7.2", + "@meshsdk/core": "1.7.2", + "@meshsdk/core-csl": "1.7.2", + "@meshsdk/core-cst": "1.7.2", + "@meshsdk/transaction": "1.7.2" }, "devDependencies": { "@meshsdk/configs": "*", @@ -22399,16 +22399,16 @@ }, "packages/mesh-core": { "name": "@meshsdk/core", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "1.7.0", - "@meshsdk/core-csl": "1.7.0", - "@meshsdk/core-cst": "1.7.0", - "@meshsdk/provider": "1.7.0", - "@meshsdk/react": "1.7.0", - "@meshsdk/transaction": "1.7.0", - "@meshsdk/wallet": "1.7.0" + "@meshsdk/common": "1.7.2", + "@meshsdk/core-csl": "1.7.2", + "@meshsdk/core-cst": "1.7.2", + "@meshsdk/provider": "1.7.2", + "@meshsdk/react": "1.7.2", + "@meshsdk/transaction": "1.7.2", + "@meshsdk/wallet": "1.7.2" }, "devDependencies": { "@meshsdk/configs": "*", @@ -22419,10 +22419,10 @@ }, "packages/mesh-core-csl": { "name": "@meshsdk/core-csl", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "1.7.0", + "@meshsdk/common": "1.7.2", "@sidan-lab/sidan-csl-rs-browser": "0.8.0", "@sidan-lab/sidan-csl-rs-nodejs": "0.8.0", "json-bigint": "^1.0.0" @@ -22438,7 +22438,7 @@ }, "packages/mesh-core-cst": { "name": "@meshsdk/core-cst", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { "@cardano-sdk/core": "^0.35.4", @@ -22447,7 +22447,7 @@ "@harmoniclabs/cbor": "1.3.0", "@harmoniclabs/plutus-data": "1.2.4", "@harmoniclabs/uplc": "1.2.4", - "@meshsdk/common": "1.7.0", + "@meshsdk/common": "1.7.2", "@stricahq/bip32ed25519": "^1.1.0", "@stricahq/cbors": "^1.0.0", "pbkdf2": "^3.1.2" @@ -22464,11 +22464,11 @@ }, "packages/mesh-provider": { "name": "@meshsdk/provider", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "1.7.0", - "@meshsdk/core-cst": "1.7.0", + "@meshsdk/common": "1.7.2", + "@meshsdk/core-cst": "1.7.2", "axios": "^1.7.2" }, "devDependencies": { @@ -22480,12 +22480,12 @@ }, "packages/mesh-react": { "name": "@meshsdk/react", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "1.7.0", - "@meshsdk/transaction": "1.7.0", - "@meshsdk/wallet": "1.7.0", + "@meshsdk/common": "1.7.2", + "@meshsdk/transaction": "1.7.2", + "@meshsdk/wallet": "1.7.2", "react": "^18.2.0" }, "devDependencies": { @@ -22500,12 +22500,12 @@ }, "packages/mesh-transaction": { "name": "@meshsdk/transaction", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "1.7.0", - "@meshsdk/core-csl": "1.7.0", - "@meshsdk/core-cst": "1.7.0", + "@meshsdk/common": "1.7.2", + "@meshsdk/core-csl": "1.7.2", + "@meshsdk/core-cst": "1.7.2", "json-bigint": "^1.0.0" }, "devDependencies": { @@ -22518,13 +22518,13 @@ }, "packages/mesh-wallet": { "name": "@meshsdk/wallet", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { - "@meshsdk/common": "1.7.0", - "@meshsdk/core-csl": "1.7.0", - "@meshsdk/core-cst": "1.7.0", - "@meshsdk/transaction": "1.7.0", + "@meshsdk/common": "1.7.2", + "@meshsdk/core-csl": "1.7.2", + "@meshsdk/core-cst": "1.7.2", + "@meshsdk/transaction": "1.7.2", "@nufi/dapp-client-cardano": "^0.3.1", "@nufi/dapp-client-core": "^0.3.1" }, @@ -22538,7 +22538,7 @@ }, "scripts/mesh-cli": { "name": "meshjs", - "version": "1.7.0", + "version": "1.7.2", "license": "Apache-2.0", "dependencies": { "chalk": "5.3.0", From 5d0fbb5709a67a23a37b232bdaeac0df45fd1ca5 Mon Sep 17 00:00:00 2001 From: "Hong Jing (Jingles)" Date: Thu, 5 Sep 2024 17:09:51 +0800 Subject: [PATCH 03/17] update checkSignature guide --- .../src/pages/guides/prove-wallet-ownership/index.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/playground/src/pages/guides/prove-wallet-ownership/index.mdx b/apps/playground/src/pages/guides/prove-wallet-ownership/index.mdx index dc548e82..cc28230d 100644 --- a/apps/playground/src/pages/guides/prove-wallet-ownership/index.mdx +++ b/apps/playground/src/pages/guides/prove-wallet-ownership/index.mdx @@ -132,7 +132,7 @@ import { checkSignature } from '@meshsdk/core'; async function backendVerifySignature(userAddress, signature) { // do: get 'nonce' from user (database) using 'userAddress' - const result = checkSignature(nonce, userAddress, signature); + const result = checkSignature(nonce, signature); // do: update 'nonce' in the database with another random string @@ -206,7 +206,7 @@ async function backendGetNonce(userAddress) { async function backendVerifySignature(userAddress, signature) { // do: get 'nonce' from database - const result = checkSignature(nonce, userAddress, signature); + const result = checkSignature(nonce, signature); if(result){ // create JWT or approve certain process } From 42b575e3f412a05f44be8a16c1683f5fd24103ad Mon Sep 17 00:00:00 2001 From: SIDANWhatever Date: Thu, 5 Sep 2024 17:49:03 +0800 Subject: [PATCH 04/17] fix: fixing contracts for mainnet --- packages/mesh-contract/src/escrow/offchain.ts | 8 ++++---- packages/mesh-contract/src/marketplace/offchain.ts | 2 +- packages/mesh-contract/src/swap/offchain.ts | 4 ++-- packages/mesh-core/src/utils/serializer.ts | 8 ++++++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/mesh-contract/src/escrow/offchain.ts b/packages/mesh-contract/src/escrow/offchain.ts index f3309e57..b391c9f3 100644 --- a/packages/mesh-contract/src/escrow/offchain.ts +++ b/packages/mesh-contract/src/escrow/offchain.ts @@ -112,8 +112,8 @@ export class MeshEscrowContract extends MeshTxInitiator { recipientAmount, ] = inputDatum.fields; - const initiatorAddress = serializeAddressObj(initiatorAddressObj); - const recipientAddress = serializeAddressObj(recipientAddressObj!); + const initiatorAddress = serializeAddressObj(initiatorAddressObj, this.networkId); + const recipientAddress = serializeAddressObj(recipientAddressObj!, this.networkId); const initiatorToReceive = MeshValue.fromValue(initiatorAmount).toAssets(); const recipientToReceive = MeshValue.fromValue( @@ -220,8 +220,8 @@ export class MeshEscrowContract extends MeshTxInitiator { recipientAddressObj, recipientAmount, ] = inputDatum.fields; - const initiatorAddress = serializeAddressObj(initiatorAddressObj); - const recipientAddress = serializeAddressObj(recipientAddressObj); + const initiatorAddress = serializeAddressObj(initiatorAddressObj, this.networkId); + const recipientAddress = serializeAddressObj(recipientAddressObj, this.networkId); const initiatorToReceive = MeshValue.fromValue(recipientAmount).toAssets(); const recipientToReceive = MeshValue.fromValue(initiatorAmount).toAssets(); diff --git a/packages/mesh-contract/src/marketplace/offchain.ts b/packages/mesh-contract/src/marketplace/offchain.ts index 85a01f2b..d2466138 100644 --- a/packages/mesh-contract/src/marketplace/offchain.ts +++ b/packages/mesh-contract/src/marketplace/offchain.ts @@ -183,7 +183,7 @@ export class MeshMarketplaceContract extends MeshTxInitiator { (inputDatum.fields[1].int as number) + Number(inputLovelace); if (sellerToReceiveLovelace > 0) { - const sellerAddress = serializeAddressObj(inputDatum.fields[0]); + const sellerAddress = serializeAddressObj(inputDatum.fields[0], this.networkId); const sellerToReceive = [ { unit: "lovelace", diff --git a/packages/mesh-contract/src/swap/offchain.ts b/packages/mesh-contract/src/swap/offchain.ts index 0d6c254b..e0c9c9ef 100644 --- a/packages/mesh-contract/src/swap/offchain.ts +++ b/packages/mesh-contract/src/swap/offchain.ts @@ -76,7 +76,7 @@ export class MeshSwapContract extends MeshTxInitiator { const inlineDatum = deserializeDatum( swapUtxo.output.plutusData!, ); - const initiatorAddress = serializeAddressObj(inlineDatum.fields[0]); + const initiatorAddress = serializeAddressObj(inlineDatum.fields[0], this.networkId); const initiatorToReceive = inlineDatum.fields[2]; await this.mesh @@ -112,7 +112,7 @@ export class MeshSwapContract extends MeshTxInitiator { const inlineDatum = deserializeDatum( swapUtxo.output.plutusData!, ); - const initiatorAddress = serializeAddressObj(inlineDatum.fields[0]); + const initiatorAddress = serializeAddressObj(inlineDatum.fields[0], this.networkId); await this.mesh .spendingPlutusScriptV2() .txIn( diff --git a/packages/mesh-core/src/utils/serializer.ts b/packages/mesh-core/src/utils/serializer.ts index d22c2b5e..325cf53b 100644 --- a/packages/mesh-core/src/utils/serializer.ts +++ b/packages/mesh-core/src/utils/serializer.ts @@ -63,10 +63,14 @@ export const serializePlutusScript = ( /** * Serialize address in Cardano data JSON format into bech32 address * @param address The Cardano address in data JSON format + * @param networkId 0 (testnet) or 1 (mainnet). Default to be 0 (testnet). * @returns Bech32 address */ -export const serializeAddressObj = (address: PubKeyAddress | ScriptAddress) => { - return core.serializeAddressObj(address); +export const serializeAddressObj = ( + address: PubKeyAddress | ScriptAddress, + networkId = 0, +) => { + return core.serializeAddressObj(address, networkId); }; /** From 14c433ae79b3c4b29a7aedd2ba042d895588708c Mon Sep 17 00:00:00 2001 From: SIDANWhatever Date: Thu, 5 Sep 2024 17:50:40 +0800 Subject: [PATCH 05/17] feat: expose lower level api utxo selection for tx class --- packages/mesh-transaction/src/transaction/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/mesh-transaction/src/transaction/index.ts b/packages/mesh-transaction/src/transaction/index.ts index e678f0e1..6300f8ca 100644 --- a/packages/mesh-transaction/src/transaction/index.ts +++ b/packages/mesh-transaction/src/transaction/index.ts @@ -633,8 +633,10 @@ export class Transaction { } private async addTxInputsAsNeeded() { - const utxos = await this.initiator.getUtxos(); - this.txBuilder.selectUtxosFrom(utxos); + if (this.txBuilder.meshTxBuilderBody.extraInputs.length === 0) { + const utxos = await this.initiator.getUtxos(); + this.txBuilder.selectUtxosFrom(utxos); + } } private async addChangeAddress() { From 041463de73981caf51854ed258d2da74f311a481 Mon Sep 17 00:00:00 2001 From: "Hong Jing (Jingles)" Date: Thu, 5 Sep 2024 19:31:03 +0800 Subject: [PATCH 06/17] init governance --- .../public/{drep => governance}/meshjs.jsonld | 0 .../public/governance/network-3524352_640.jpg | Bin 0 -> 117567 bytes .../layouts/image-header-and-body.tsx | 28 +++-- .../src/components/layouts/markdown.tsx | 1 + .../layouts/sidebar/sticky-sidebar.tsx | 97 ++++++++++++++++++ .../playground/src/pages/governance/index.mdx | 29 ++++++ apps/playground/src/pages/guides/nextjs.mdx | 5 + 7 files changed, 151 insertions(+), 9 deletions(-) rename apps/playground/public/{drep => governance}/meshjs.jsonld (100%) create mode 100644 apps/playground/public/governance/network-3524352_640.jpg create mode 100644 apps/playground/src/components/layouts/sidebar/sticky-sidebar.tsx create mode 100644 apps/playground/src/pages/governance/index.mdx diff --git a/apps/playground/public/drep/meshjs.jsonld b/apps/playground/public/governance/meshjs.jsonld similarity index 100% rename from apps/playground/public/drep/meshjs.jsonld rename to apps/playground/public/governance/meshjs.jsonld diff --git a/apps/playground/public/governance/network-3524352_640.jpg b/apps/playground/public/governance/network-3524352_640.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e6af8b201b86c34df8398737ffd96b5372f9338 GIT binary patch literal 117567 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�XtWOLsH!Vq;f z;wbQXG2I;nV*tP)=ye{gm=YSDvn*yrlM!_XzlLs0wliV;S-LOzG-$>4j_8x_K!<5x?#af^_I28{K)P|g$3 zgkK!_!gBM24~vA&zOZKgO5fLAIdYCTEtKlG%L9&j*caWM?{h*$Wix?!wwt9Ad^9>_D`(Gqg5X zuTsYIpDLn3xkiwf=C}~Z6)oh*L za`S!rDh555#^;i3r84l`+zJbiHB&iCinXdQNt_o{H2{*-i+w~g2^OB3LXjLUXGJGP z4puqW0SfL73f7AZ+uKk>@Q)1`Y5PnlbLy#(9GWCw;+sq5-FKROxuL3z{QX@b%ay9V zUz&`1Z(;kVRjQ*Kzgf=u^N9m@F9z8_u!5cBJ5sunDZRiAB*5kS?tdzweeYm20;uSq z`{HC1fqY6odK`8gemR~i?4NMxw7xvN=ulb~vMe%g$*siQ^c*gy&&}en!nIaK-5jWXr}nr6vCgY_O=TPK(4pS)iB~xP zn@8rj$Q7A%s2K@{CEA#jlW2?XRlL=&cu=A+td-6 z=UlA$Y$UsJnXiBoXKHG@bQtMsPs`9IQ{3~KG3Ipw{Jv@5gi1iA9+cF00Xdl@g|N;S zI!8jBUKTm+cJU@HTjEKsV5h4oJQn=?Z`&p4{zRLg+*O1Gn`lHP&GUH9G8sJduvv`eq7aH`bY)4;l7;D z$DtePQ#Zec_9~w00sszlO2wmUW0fJ-p;d{;xQ3PDCJR;^hbVLM6m6T2i?fUe>(mPe zj3&ICGY7Ef8KnKqtE`(PRTg%O3Ox;!Mw1%xs zZX-dHnUOqvN|q@T4(HsQSxOOo{|rK{lM5H!{9HotUg`714xD>R2d{oMvbAQe+03{^_r~VV4-f+bB zKZ;^>#2UO~D5-=$0{kg0aK6VbnrNrt&23c;l6j1}DCydu7z^&-SbtK|AN*tC{7v9O zIj^5FUIdF&PS*nvfqv|iT|iiCAO3w9+Pu2xb*NcU$_&|!gl@vbK-p`P;WcOb!I;Ua zcm>63Q)=7}-r1yCOHqn_M2RX4;LbHPEf)yEnmrFxq3cJof=0nA87r)90TjMC%DUUp^zxb>+8? zVL+;IJu_)ZBr;r}ppl~g_Uj-HkE9JGcT;(GcVpl%A`^()-E8jo$rO^0)DW&R0hd#GLh7MD9NBe{-muR#Ft$?tk!OCgx8_ zotvPQV}%vf@=hyMCH-9CMDGqY`2HH5CR2Qn<`#{^9-^6iZp_0zxhAqyu95NQiv&~7 zVqYHYARzce5x`)0)okAn@$j>4RSDU?j+%m}9?{qoT=595^_Q#zfp8;i6iYp4dghes zZ~Lsdjzzu2Hb~HDQ`Io*Z}#+(RrXk1gqx#rG9^5Li&>OLs(o9-;l52hJ^^cNhKXx~M zT&&yw*=Z9dbl{|^+mS7O-wL_Dds44p_kLn5d*aYbCgcWDEORJ3Av-0HrEpvYy_}aA zRGuQ{jx>I(?f~?++%jdA9lF${$hje&P9FRWNnS8A zg|~_p&KnMfw!6j5S%W+282ZaQb*E8<1o=)1k*54DE4M4m- zfQ=q|u0l1fswKHP!}|)?$$?(_T-Ye5yV4vAi)Nafervj(lQucL`RWO7 z2gV5p%?d)4FF6Sz-%Rw#Yh)Ap^>p)xYYzh!WvV*a6(wipciR-V&QY8+-{*)8lL)fZ zg-sKo)IU0w1$`Hg8l>s!oFT&mrX>PX*Bik)S3+m3bt8HSitXo(50-Y8V!BuTfer~I zZQXUR`kgMfyQ4U!LGKZT`&(r3VZj?+glc^2;mzRg66OidoXi5tvpLwa!dN+?J>w&Z zywTO4digx3+I()5WE!Kn&U94#-^RbX`LP>{BTRXG-~R{DL{c0Nl+`n2)cKC%Ti#%w z_-XxNbN;a$T4E6!{Gb(&PJHzM9eXYoanIy*3?_0Wz5Dl;f#qA}#d2}gE7qi9gZ09G zXzr;QuL|t$nH*nlslM9rr0sk{+oLRd1G|n48LB8J;C2kx@(8Hja>)dSu=aMMINz1c z85O#Odc@L>5T5G?iIMVe%v+%;E+dr~x+u?Zjb&9?EsnLBEGwM`vBI;eAHs!TzD!uc z3(M1chr0QseEg2vaEuuxa#38H=^f_G z!dqPwPspDeh?+Ni@uYav@FzII74zJ+>upi@`@{^;NsW2`vyU)>*FoU5kxsu|U2Mqm z%Q08yPUs57KsFf5R{?z(eC+CEL!T*^TD`I!exi&T4IF*636NFGC-5yacw6jM+E@QN z9&n2eY#(>vQ3B27Az+yPCG8j{B30^okL#L@x{ZZUC1#7>+VOdG!dzlPZdZ%r_a|cr z4|GjMwaIdk(ely4^`!cJC-T(xjkqtV9Ufs4BrKM&oNYr&6;`U#{`gjoQ4laSL*XC5 z5Ce{N@jn=;vB&D6f9PY({sBC4P#_w#Pf(JREw2g~6gL&ZTCmseW)oKRN#*nN zIic<^Sm|7L6ykA_-?1sDD6HpnwCR4bQUHe9&%?K^ExUVJEyG;0apM3{W@_d;R!&I_ zWGh2d5`g~%XQY2;&jAkx@V1Zfm*$9f+c*cFinpvi3MyVat*6Z_adJpWN`C zqvI^!b;kXQ7c14Y5R-4Qh%z+c%h8oSGqR|Z)6aLEzB?Q|cEF`%e5a-+sb~>jKWtj1 zRsE)>^kK8%pZ6kp8LU(OD=!4e?%S2OCGzBwCfPk*kpRgVel`N_fc^pOQ)5Mz?6e@t z7CH+b?WdG&6Ynv;6T!n9EA(=N4!05%O)1Es(4?F}0qOhL-^$j?-&0RVB{MSA9w}wH zB#lX1p{lZ-l8W^(PZ_V{NLp4X0E|zbY&q9tl5ftjbtqL&Mt#kGR9aLgUfQnh?!577 zQ&>epm(A^I-sbye<$g*R1pt>t#@B#CLyELiuglmx;Cnt zrA-r_{3ykcqg^n7$4UN0FNYPc-DFsHdI#Z>mEddD&y|bF$zCg6Ui0|=f|7!dMeCh~ z%$^63N0OwNh9U_7h~NzEv5#Z2PH8Ya&>hJhl(+@ZPNZpQzJ$vuj-SW4??IS+N*)*| zj=rg1&$8Q2iM$H`f@BaOt|-uEP17)kt0Td{3a!f?`$7$wZytMEZ!|l7y-?)@=OW#g z4ryK}W^x;5eVT+9`3)9S3<}T)Hx5hQRj(@=(_vGp=`5HSrlh*6i!eL?T`cl5uMWGd3mn8H{+6&oXHnBBHT!tfzWn6Ku z>FWY|fWp7z0V;cdMJnaHoi$u2tJ8xP?51FLL>=t@JgwpF-akfPdAr8TWJ97wz_$FC@!JZ-WDY0N zKIVk(_y+gwJX+Z>A61-r+o(<=!Sm~2j+m8Zl?p!yvfYVG{qgh1?UYb7tJ~r}fjz`{ z*1U#k{j_+NqpeL;K(5*U(CJ)=@ua5zp>$d6XqZ;pG zu0I14X<$Q$-}6$9(}0icy-0A0`kGa{e{NAr)+TNzTZz4(Mk8M*1}(sI%laDLeQ@He z6S-F!BuVhCdT&u$a?4$j38fUU8j;)f98bt~nRdWEzof0XPt+^g16)KkNA)kUz?z+G z`Z{B|4{xVrRGh5&m{o*TlWU+oTP+wjgb$Ns+8ETXRqK*{;YKwo@32ZHTIS*+QTS+# z<8g-`PwcE?@piJU#Lx^v$LgiKYYHoKg1oMTk8_oEGs;^^V0r{ecAX7IsrD{0GoI z1zU^2KMyRx-w; z=c8DCK18Txwxe$flC(up0j$7T>=3f>*l@IyzhB2xF4q^WyInVBYh4SNveC(=OwFue z&~Gq;RtToN(vs72(wG+=*LNlHdu$s0#zNsI9bLpBBFn9r*0aLsD&VH(9sqj^%2PQV z90!dm{Fv8tfK)6`P@j0>#CJWkq(Kw+-N*rDfV04|Uqf1O})gNe_ zp0)x%_$FK5ua0s+d%W{~sb7#P%=FDxXo4d!s|wOFn5#^~S>3Ww>23({if&vE=`ELsiE>oq&~I5?m+leyy^UJDX<~6ynstkfwo@MW)D z!x6&nn7HQ{aq4m4EvdLWoZVc5blEo9w=v^le_uQ{JCy9MA9!$aVxupi6Ko>q>nifW z5#6!|$>W8_O90YTd)LZKaStTN+@$%@i{U^7wC#&CDWT3uTU-uDTfD_evg^VCe|GrI zsHP_Mr@5y^q0Ri@Z>^sNjGXnrKsT#7fT8LePOLJ@;R8BxB#~mX8u^?l9zg}hoKaGh zm$hYd>o*+)nluXJnODe6`9-xYCt5@@I#DP8OgND-w2qhRXI^*GAVo1n;Y23q(9LkE z8hIVKPwMT|rv)H2p5hO~Ei%g%DKptzIokjUH%cF25}{SPpKqOO757>SD%rw`BOL-n zC;}_|EzsFhEEW}Ab+-m!xw**6+bu)=10-OeLx77|uuQ%K0ZQmNVsk63NPjXMpwZd* zli{a}UD`*(m8|GULpz)BZjuN!oLtU&-4DDbAA-qm9;Let6ZG6*?G+yV2Ih(q3iEIF zM5`4!iL4pb9eH~=i^-;3>@~B${!C2w%ObEtc(a2Bt2l~eH0e}%@E+aR_RdricATX9 zHem@U$teV%>{W-8&+3bqEbdj*TX!~A>&ZGN91y(Pkp9xTtaHdp9~*`OsXr2SmDzJz z3KOc!BE(n+>ThIpZg^>!bBc~90y&6aTqsAOuB@Q>5{LcK^LI`oih+gYGUD%?A(G} znE`WzIQUJ{HbxB71a(24>+UqoS0u6)3U)&F_bhd^UdU=lQK;7`1W^1M+k3IK@NEMh zcB30KWn+lk?dIF@5r)Ofi2d#--PygYw7?up`5$?~C)Aw}h>?OWA`f2~eq6Qvt!{C= zvz{KMP28^f9Ou>>6khr+ncccN_qj^?82om|6pIr4ar-xJQmR77f0{S_y;?J89^MXn zh>~>Wb6`l{rUH@r`}Yef9NHm9i=1c`g**jvau1UHkiIgXES-Cy;Il!BwlsDh+l+%f zMdvxV!htcvBujsXkU5Iqtm~LQuB_}+vsJpn*U-4t9daQX52xC!%qq;I9YHQ75s!o6 z*m+oVD6|-}9W5rK`3e*61Ah~1welR zZ2F!_2|7rx^wuoXUJyQ5gXM;be0uO_@;DFuu+c3O)OEk(HhaMIkQU_kvkjS>Dc`Y6 zX*AV=C}XWshnd?|5UOo$!dZZcaf`{*e*gyK0BMXcr3ShJyq&}_xhotjxXS;p-aO|xpD#T3e z@z|T1k=P?}m0sN(QpPx>Gzne3|p7#B6n)i6eJwBVlP3iajN)|w! zNaUtI-1DoEP+xyri9lO#{Tb2g6Y>p@^)KaC2H+hwJ;KG_BK~K-Cs1w|f9v0%q zpwk!987+^RSZYtpV0gvY_4nKtR;QxUZvZGHz#oUhhZ}O!jJJJ$P)?2kvMJeh7u4d| zg^MlFviJlTcO+s|QBe8PEa3vSikIFLCunP6qYQ9`2_xr&r^rc(D&i9PY?n<2Juk!)gOsJmP{W_y4 zm_Siy-!i_!sHznGDb1@Q-xP_hPA>fq&~OWd=?W&9YY>lsN^!y#tvJ)?4}VSAdX|FW z92~Awk0k{Yv$*trel6CjX@ZVk@kDt3Oy%rJJ=J+cvN^Y|cq0*s5B#xEoIw>R30hFU^)kXR#pdx>?75rZQbs8jvBJ zDRi@OOW__5(?I;>_rP&I(#)vzd6L(31r?^u@*hh_%kFKFfI^Ho7!WeR%gr^?R#kmL zFAA>$NBw?a%*;Od^xg7Rm9DMm2qes4`g4Cy!FTX5hw;gevgf`bmUryeubvop23T)k z5x1K=4Q7VX_G?+Y^`oO(mCs$0eEod=-1t-O0WXxLFp0I=vC6Ncb|c(NtNtdRkn32H zT={Lo1W)uFP)6b%eK<}1MQ>r%ckUw_R>?LgSsfS#4YRyd1F0~&!GH%|J0D~J16=$E z`25`73i_4uar{P_vAKF#I{qSKjnS>~xJZhWvQg^*${lIcbd=p2M!0J)f_x7y| zd!eaN7#XY9bW=%N+!&&?l4no~__8ar7MA#WQnaUKTs1R7^*?}r+XD)YL`OXM;K%ZK zP0F!u=qEnlE)4$+DI>5m!WFUmMsHrnqNe`1D9K3F1S8(xwaael*urpT1ZK#o#K!lg z@_0-MqM}HtA8^WE9@KSmBaRt7qbw{82CHl6(}aTwf)y+Rlj+cct2W*k(^Y+)sp?ofpFLJgf7=EhnV!9O29%*T4*02#4M-uDUo=q^xyoRly zfi6HL{$3I3?J}x4a=@Mo#;4s1M^^tLX7i$Yp%82f2zAsH8ET--)Ffrh)}*NNSm~ru z9^I`7&-mwE=(mp6wM_o|?S=G{D>|Me@>(KEAOK+K@O>jWBDZJqToo!Wy6O8xjC<*9 z-|;+gNeJH_o8WDi*E#;GGDaK-Lk%!hn@@>KEKd&{s4YICB@h8ZqHB$ZQ6pBl4&4qr zX}OQ1nlO@)yhW=EqIJ){U-&uhdxUWa&P9Qj9A2-f@irr_6l$LqvDYwt>CB-uFGv?Q z*P3kX9pMU`$VnhNd~e&BPM-vRgRb|yZDg-4mUW!5704ej@8_YG{T=k+L&k>6v(N)kKAlR2=J@WZ!PLBbaTL{C zyyA77;?zM?b+Q^x6)s5z2o{iZc|=5ZLTpohAR__zbVU4@>Dn9o5eFY9Jy zmQoL2$0M_)10D*VE)cf+>Xb*Tb&t$iqS(K2)k?^^#Wou7{7tK;tp}ebG#fm?Zf)ecMl9- zL6<_kO;~G4I6jF8xoM4#Um1P_I`?F7-}-Gq66jAZRln^fRC~1QFm!0TG~=>WkR#Cm zmBw)Hz$p^%18Tr#W^VnFk+N5jU$LK6N4Fr$M=x5-PaM_guEb8}pxFqLd0l`whqdfh z_7Qu`s}}eER6ev+FPleBNmlMM6{TtYYd{Ym#M&2`AeE&W@imQGm+mY7G6wFCRd-8J z;Y`kU{0`aNiX5I>!gH%J^Ll1oAJeg!!oMqhtxoN#5267`2O`UAn;@Nn22v2i!+v5L zbHr!;l7@u3gutBPVNhI@5Yeec6w}6%--?+x@LDD{JZ##ZHqlFH2&HszdA@%sW%N3i z;F0+L9w%!7x5~?6fsN*}RXVp$^qR^r-dYp-aOe3XQ^z3*eG8>uGRoj7X>|DvzP#v? zDWLh7eu*$y%*Os+W*QskrdD;jZU3>e+*mW>v_ZqwxOX-SZd?14ptL33S+W_!K>@4j8< zX;LSQ@++M$Fn@&e476aijm*0vopW3t+8pzpCWQ$T4UP>5HM~&r&8E@RGhXQAPqbt3 zF-^lwewe=E+WhI7`dBz`6y`a@oFo5zdYS`yN%tS1s^|{Wu^EKGKrYn0FHAl}I7{e5 z7a97en~8ksMmm}p#@;`Z+y^8!H^ z3@0*gL?B||HE4%_Lnm-dFsnKpzbAM-~XI^$i$JCtTU|%e3nQzPY zk`f!%F?$xyA`vt}mcj-AsC6v$%l>_Ntn$I+@75LPVCi2%x2$h#{%QBtox|zYU#W$t z%yJ*&e?5!`AK{!kGMI4`_i!(B2y6G>Ovi*yBibos%8BNOWHZ8O~yEttg1UJ~kf&GE>Pej6lwZGKYY!JGh5m{9c#D z4wbzW383QA`xR0z79Y2TB$|WI|BC&frepmd0KcSEVMm@+FHxO4#n!gKepcI0#o^o? z7&e8r%x2lHc}y}1t}uk!GAWYGKx&{XS=;tmho&-R#^kDZeW-XHa~NoXqbI}Q&5EEm z(zPT4lu4*3$cB2Vqy4x03erww)-tJ|7@uA-_GC{921HwQnM-wC?94rcAA5f6^!7Yj z%Z#ioXk;8?Z&yJD)H4UcA%K4c8*5*A>%4il5#O=?J9o@IB>BnD21Xq{-s*rk=`%SEwJ5=;lN{-XaOd8SvLF?5AF!hqZPeTp`)>e!7X6~fg7+x25miAvW^`Do3 zJU9V*hH{T&TQ+Y?Rp9A{Nw1UC%YfBr?M7IOz#)}ye*+8}K$HDih@`?-KiBv|k5rOe ziBY!{Gcn|B@~bR<<7Ml=Gpm)0@ivARa@kLMc|=}AcTbBE%^#B}2#BU5UC5pM-~r>B$1WrZe-@ zR@m70^^MyAIA99*-I4|RUQ%X`qRb@spj!G7dmx6Tx}UcxtO?z`yq`K+j^BlkKXBp0 zm2kN#147)}^$e=`Ef+gGmh-&>OjN|f({U;iu5mB9K4qM4tJO{7Uz6QM*Dd>c zm6ffA+8wiI9I+?UAe;#+y_D-7p{_kG=Rm&1LDED(R!}*o=t{*>gZC@Z!w1#%zHCLffYN9X=k6L{4B2mB-Os#le>8G}y&QAsaQe3TyP=6NmW&7L=2G z8JIzi2^y@Iu{B|6Y>``3A4?R|GS<0WHAw$ml(tx=K){Km4Hy!E6!|0>*n{H@=l0Yf ze4c;*MoAv`wZ9|1ehT+$u#)}Aic?IZYpj%Gaup&f_NVA5K{DLaV1K-{+D~M4`QW{E z+Gv{h;+qToZ6@OI-c8?yQ1sXLpXUH1F@!42`<2!UjVD;Jya)crHQJn@`XQiFD}sK~)?|_%`EOrY z1>}Yk;E0Og^sVC52iIMCe~Qeg5~kz!3>%GLbNt=*NG0CB2SAcrLgKRIz0S(j)np^? zowLq2?j#M<7u97u2o?^CB|^C4*$z{v1tLn_GSd1a-N1W^*-@`Hgo?aA=MKyQH8iwQ z#-Ap@-21^dN0RC{ho#Jm9MI)A&E`c3onh63$&N=fKjULRVWY#!%w`zlyHPeY%Z>@q z=iIT~G`YWTj-$@UAm`N=1yvrV7o;C>gmp<4A>{crp|^}PfUS|$W0zOGS6Y9A`)SkZ z>W6s^D*Jj!op3!2f%BYF{(jGOiYh97-dSx7)-|1TiW+$BJ&C<4;F|J@$1{O zQnN~pFe$=k53b}4sq36p++@UEf?E>k&cvuAraC_p+e_xjk) zoM3gp*Rk{Ybga%*)JR)rMk!!tWSgiPv#<4*b!r`G3ijD(?o0wU=8br5=t!U{FoHZw zW^F^jrA7Mf=QK%Vva3_vZ#YM!sRmE!TV4`X2&^VA1F4}n#U*n-9;JSA`|RqH5S!v0 zyjKhrAo(8)eGPVU636@X+(>;>w`PJGH-0+OV`1Yk;G8;PJCGo!rvJCIeto6WfH*p= zKy@)}QEgPnH0-q{NC-rPuV)agcXJ%N;o0ZvavSwK5l>QI*#D~>jh$C}j@Vg-tX$5U z8s-;S_peJ^4a_P9f^ZdXQ>xPcfC-HG>-%!<$y#kXjFaZiToZ`69+HOGi*z=o3qQ5E z<+p2_;c`M5|G`RUXOvg>LMWbk|5DRs){;d$iARC-0BEZ6owM}PSyw_4gY|) z76z=-uLcjfzs)*lP!185E3)ib^)v275e%0$4PoPe%`nopg4Df}Kkt_-L8gl=?X7>Q z7gow`Ts3LUtd>!&viZD>Wb~n|@gff=SDB4xF_wf)u`eu+P5Mn2C9ye_h`V&U2i`YK zqjCa1_4)UZSoNFp?)!j1&|9VJteRvw8-RWiQ)Tmut=>*S z?BC8du}=bX+4k|GbH) zFFiZE&^HO9OXM)#+o1*n&lj#^(`-aki4VKLfuSe*&6ywPpLWLgB6M3BMoWkABmgaE zG3sVbFaSUN`|>NL6<>fNcQ4?1;a;d(pOJoe{FfFfUFZk9&?0Fd39T{{6;Z3k_o2i| zHJdL9eiFeg+&V^34i+!F#f|DB{i|w;S{2f1P7hlnAGS2@j&)*{JrXWMbsDI|v&Lr_6k}pR8y5*^9zmHY>hyD&+pJcOatcBf2FV%9)LhRLQ34!JNnsEkXVD~&=~qjuo04OUiX$&yLmzjC8jKkk#~ z?klTIX500|=Q~WxUr{of?q+Y}Kot7SXpCbTz!2^tPHD zS!`U7a{ec5s*D@Q{Mm$kZN^0H6gV~VF1@LQvx!SVidA^0Hdz0Dq?Af{lxd5OKsisJ#rv7+vb80#NzN{x& zm<=#s0$LAXv%1V#hWysuCVE^YD29PY6x%qKsjbqRiAhqAI}?-YrI4rtcu`EG*hrYf z)jG!dd3~i$W5#_dE$EzOIL2B?TLPv;X^unY)=PivN#WI*g4$>rrPjUPV-g`m2`r6^Ec-1wdL-$s~(Cr{zC z)QsOlDTNAnHKu<52e|wbipeVH6rqt@sa!&R3F-H9evl00%wVZ!a?dctHG0p=SLK@y zWqj23d%UL++ZNTjEb+mBGqJUmhRJ}(H0Wjs!dGTO1m7dH$ESGP&SjNjq7szPHD-u{ z_(LAcHVqbh3qJF83jU~pum6kvUb$(v+a|1f?1fD&Zd<}K+Zsl0J_buCk83!~BraC0 zciABQ7f_96X{bgv5XhBrm^NVP$wyzzHH{6g-E|* zZo=joO zDmk~_Co01p3}5nC{%0HQ)L=)6M7yJv%uFsvFMk`rANA1=!;6*XQ;p^^L2FGKVTn_B13NEYU=4*eT=ASx~JcGw`^G>dorJI%-rnQ$~Z{h7N{oMX-V@Vlt zQ|guJ(sP*RFwkmvm<?Ry(75wDSUU*xs>dHJ(6nW_C} z^wsTZcMh{ptlb}36nw-0^9{388bC0r@7M~&GXRCz5&CrPUw?7fKP#Ft6N=LySfeGb zdo$8v`ux2lA2}uX?pX-5Mpb^3#z1ZA)PT{a&DL?OZud{coc_t_-{#l#s+RcX0;3R{N1|(<-CY#;G3kR5H1NK0%t1$hyNrV%)=Z{lm*TD>3&t^b4u4R zaz;2xt={Y0R9vC`-$NUu&_!uK8^G*Hbwy%65V*7yN+oWM67tn|#qtR|PJGjxVZs^+ z`Npl!QDnZ7zD#tElu+?HKfFu(=u!lKQOUsXJdH*Ci>h+hx*^5=QUku`l!Mj?)YXW8 zwpaI`R8CltoDIMT&C9Tem%aa-{0v}X6k~Ek&Hm=)YtLKtsv{uJlGVq*k7C{OJIV9I z0y+x=Y@|s&_!(Z!lR946v+gpBT8F4jMq41@CA1DRg`E>OvFivf`N>83 zLQA`x{{dwW8`p~21ad$77BCeq1QyfBKqMka@q%|0zd}3S0*0)^L)UvH;*C$}MgV0* zlN9@odlBTvKRcTAEPU)FQi_Z$n1w`|UY1bUpj~6Wo&D@<#}9poAL9JyE76Jk{YCbY z2OUiYx~r~H4j=jNVG?AVyVjtYvzmsuaNBS)URRBC+}nR)fF7pD*A2FZY_KUKv!#`yaee+O4aybQtq+>#und$ zV3#a^si}FWSAK(e+tSve_mNb`{kJ@A7g*5&!&D)uzOJtuFVd(sZ2^umX!R__Akzn( zcAT6n<0cU^6|;UDexl>4uKISwM5gj6uak|x7`i&N_&>l%U%sM!BaJYJzI-5Z|6?0q zSPXg&XW<}*S#hMVi|D2uczUEXM8hwT6FxC3kGMG%5;c|g8O<+uv%j37t8JI%ytWW& zumjkP;o^8TPnN4VJKG3sY$0X;lw_s7Vzbz$yV;_vZM{jh=vkCg8l_XuVuN5H(BzUh zoP2b|!=0XpH1bd}f#yE|e5=W=lviA2(g4Z~{{?DQjXxk!oYz_=Zk#{-<-KdyC%*ZU z{|#y>`-m9kv$Q2}!%6E@lZ{JB4R0ov6bg3>Z_s~JYV1=~i}uSn8a)iAe7lO$^Rj*nZ+f=0=0k;Ayt}6RMPN4f}+O1oDyUAosE4O1zqikIRfz%c3ecEK%>AFIGIv zT_Wrg$cZ54NGhKAY}kBxw;D&)@|v%=<>d}}SB*pkCabE&0U0EF{bIz!i&1Tng0%TP z{a#?=d)$m{Ae`DrL{EPAlW2CEpOXDhz`82(MqOFX--OvNrs&5q#yMR!K+bUFX+W?L zdLzIl;kV_F9#Wbi(xLz~#ig0jhpDexi97>Is(#lqjFIxttE-<3{oHn0Tjxw}qv_}x!Y7cUjqzMH${cGu^Yg8JPO6AEQSyW46gT9)Y(_hK{|Z`J-t>SDTyyzM8+4fhq{wj|x+W z_6Hm!n-Z*3VQ4CiPa4(rgtx~{2o=ksszs&NBX)A$Cu?cn!%RQ#zNb^)WfGCUh7aEt%Vt>G;0%!<;^4${LRj*s@wtCD?6%P52qiGN`Vggz zcKH+XR*$aQqUldjqhY=nOpc6+>IB1>xrF*m4Mm_g(>8M2Y+OiAC~LY1&K#(|2>z99`USMjs+F3S^ z&bLqzIg1La9zl(5M008r4+(;vk;_HB8n~B)QQfP!%|tW#231?ybP6_v`TVUhm2&{4 z5{vUZMOi7pq^{%Uiu1YQQgwyq_~=xjJ5nJx=;G;FjZ- zA>S58{EE@nJ=A%&KVCDL1YDbqq*E|F@%GYxmySZ5ydz88YPvsM+LoWDz5UN1p1K}B z6vmUOp~XjjLfF4EUY=xH#?c}Xdx;5(s+kXGFq^qU=Z#0;vvCw=@~I0g<~sNM{NRj& zkR;=PRSEhzCL+V4)onU$k{LVNWbS6ej=(s(C47mrm)Q!MPkLPpQ?0J|8XJ|_rUTC367^F2I!56AmXOr7u2mZ!Xpq%p@!uF)q zVM@(!lVpl;u}5Y)!=)wAy#l=1{63Y|gnYxNu^(l#!4`LfV5t7s;|5{jLB7<&*~YUu zp<#cJmk5ScZ~6C!*Zgg@!eAVzT8~ttHTRhl{pna0QM$yUs{ENi8m0c!Hafd85=r^< z>9hEbl8h>{%*bpv9o`N=BDNH6Z+nYxFv;z`=DhY-%rf?M*_6o>%2bO10;Va+jT1x72xg z0O$w7u0T@hmTY$_?rVKLBnCruo%#d!_i0^_ zvB3v-${u#juO!iOqVI_B#9Aozch2_r+!a&A`Yp3w9Xu_qtB-yNpnc|2l_v%mEg_!j zDIuHh`5SnBEMt++Q1MY{o_&Tb5Lrdr5Ia$u>bxIPyJQ~5;yc59G~(f@=L;?mpt21L$#)}E|1JB-&R2Hwuu;=Bt8ysXllcGdmFVGy7;-9-w%Up zf~NASJc!kjkx)1zDMJV=LgGO$Oahw>m;+P!&y+Q(D}}^Sj1OU40dG|A5vI5ryJfcs zk!nqRi+I&;DKBTw`+f#jH_}s!B+_;e8ELk10;Q--_ll92*Jd^*Q*wWjInSI%g1L)G zX_7RXUTQ%b=QB#eP`H)btsZz@K5tg=7k_X)Z%C^bA3tGM@CIL_>6mXNEM~wTb(d1Q zQI#_3dWun%z|S}a5+G3W^z(%;+^rL49kc*`V~%Xtc;p0kESi3Z9eloqDlJ^~;%Sg= za8M_J!G@oNev<9(6SIU%BTHyoxnPHV+)W$iCZ8=?MV?X?*^ow3+L;<)QSL5xlKZX+ z^)OJp=;olgsN~Y1`#^ZbZM4~l4BtHc=h*FdV@?G=`PIp3%(%v(>DW_l0+&|h`4?YR z^sw7*hFKriHf_ItpYH_hw59aHtTlIL4{wSh6=CmQ{Kf>{`&OSZG)3Dsc8GRWO)NQ%_JwtB(c{atSH%aIU8=v zlNm!Qo#JD-GHCqh#dyno?y$F#c+mZ9>cWatpwvNT-D_DwOy_Y$UmO-CB%>D9E^fQ8 z^`gR-6GU&z!B39}+-DT;wZlW&5Ev3l-Xv59pR5WPv8{1&+8wNLQ_%kGs^)k26)>q( z|Ef5bvg!rg*&RI^_!_np%oK(d!DbO5h~ktHvcvU8bt}o57|;IzPgKSyk^ZW}Kq=*y zn~7pp&`izz;ZwAuHWSY){bk-opW`;uwmvt^mnO2+lob9VerUdI?qxd9Ms50u04Vor!J#}aNVSr1TZ|=fHhW9~N|65mpQ7@U8Ka(<$Y<4B zE?pj{*6V`iW4CkZ+NS3Qdlsd#`E<;+15Oqt)mI$4nyNg-<&)*^S+6E=8o5TFk_jKg z2wUmt+FHN+n zh2{uk9e91wWZA;k$ zl8d)d_@7;>6!_WKZ3Z7yNZ1s8e%Y=>_JM@D-x5J9Qh#F!0H^~}DutNUl5P|jrKB&&YNZOA`xQA-9M#u>>GA|6w< zeP53C?3kH@7F%rVT9dMUgN$v)PGv^HU{LcUs|Er9Gad1A>U_zwPwUMZZe_3D)NcYM zUed`WGe-@0@;fr;OleT4COzKU50wSbM~c1MCkV=;0&8zeyskTn@83SvTm~=t%-cJ5 z8ffivs{RppfK3R!P8-x3YT$c9XfIPhP^t6{X3{_$sJAX?rg?4m%q= zbpL$y`frw04AUHio66u9i^9Nfq8<1ApOMUez{u`Mi|cu#xyrq^GcZ2nbQ*`C z6S5ihFZ#1O_UWai5-mET^*hNc%->;y;v9tc!ZLcpA?fk+emy>P2tVv0Y2ZqQT#sM6dc#`hug@z7Edu2Z zZ_0Tw&P<*7OeHryt|g6yZ^+8loUW2RP#e%1CWulJ$b8`WY5bZR_PB($99dSh(Ow@l zZ{J<-t>8nLVwT;Qh&EwNk^4E;p6jfN$!uN5D?}!l%Jg?IVevp~o2C%k=3M>GRm&44 zLCJpuA4v3&qPGW-QU^qr0K>a?(0BdlkgH_Xj#HLU7ZBy6p(%)v7&EIN9#WQkG*dZ$ zL}z?@r||yMcz(C6E#Gp3)iOJz+p2>`t?V$IXeGl%Dg~t=l4P!xiCS20@j}hs`fXI) zhrXZc*fU@R3mt#V+jBG4oX{YSU&|8YbS*3V%JB8t*Ff89=l-@%i}{w_$*{hAk?Oo6 z36K(l#8g64tIooP;JxZUOaY*KgbSK0K$Z4tl5rx;bplVok>$UmYH;;opb! z2lK6WbUJ)kd=2U`{O12G4jO#()#ijw(Hmi|tiU=QBUv)~#L+hAcXqoYMs2_YD0Ctz zvzjmad)cagyT-Y1>xE6+%zd7GJ{Wx=Nf4@0T5<@VS57i?6Rw9xGjOK=kJg8si#^*x-47Q0q~re0`rfHKapiE_snJ2^uWS+m8;BNgtH1KUlP^)(wFw#dr~s^U!)<|Ykg%e_Uyv!3<0^*{LI5FizQ zGm(W16*JrUm(My`STF>-!R%9t#oA7q;giHB4oJ%iyl(&2>1nRSD6#Y!7dNPRomk#) zgRb)YvtEELkLH_^j@za`R1aLL0L+-b^Ivbb^Nhw-FZ=|%e&C3G^*9sphjIAkc-WaE ztacSl59j)ko0Zi?F^~Ln#kbaWRkSzm|EWeF&`A^k2jp@SH7uX)tT!w_~w zi30vc<8!X78+g`FYARK7f+i8@X%r&cQ-Oz4j|_%a&C1ML66htdW&T?%ZCU8{ZGwh= zcl=&=A3e91O4#oo83XaFn}{M2Z{`mU6|rNalii%6>C6``il+l9M=zqG)U87g1>>Ee zn}f5gL-Si|vM)B;>ORy(@qfk`SS^V^((erQ7Hbl`C}^62WcTD#;=@O*tqWNkY_@nc zNhPPz0Dv@%J9i=4XMpj#iV@D_thLw!wQLVJr(Q7bJdRR5eyP_?i9B<_ko$ z1#1+e9%N^3=~}}UXzlf?3v|Fs!$1WHWeFjewxspl-Xf9oCf9fj)@!X<+j~r()guk5 zHHP6$Dis~IH&sOvQTFdV2zK;$NHB z(}XRH1LVFA%y88rDJxZKH@2FyoWQnp3=PTal1{w zxQcRZleR^^5f@5lGj^24l0gr2A3K`ZmoxEl94^*qpBY4pGIG}|8qE-E>&@AZwJ-QJ z_3LQyzPm^mAC5WSCq_qqXuy7n>->6K>B)A;YHdNtj(qdK^=4HVi#Od~6AS}ZFfkE7 zTYgwd#H0iy@Z8;2C%FpcuoVYQ?QBzLkGOAx z5~NBFKnLRy=L;yrQm%2GGaVG(JOerQuE3i4RH9EMUj;HfCA%QbC?*dsQ{x8;&-23* zDB@@RI#-q%0s^M>TmK|ze(jg_)@D%>@fP)~YiwJ$Y=JyCkn$iWew0dSX|?@k>0grU zD8eiEb+yR%t6Cf#i?uB;V!hCIDzw8^eGq~XXB&3fK#WBYL*?TTaX1g8hngWSRvGPl zxFGL+x!(d3RkKd5)l~H#jXRfoo2|ZKb#U-Iw12gQY1C(aM_Px=Y*TnEJ2&s(%8^Xv zC57V6kI)Z~$SAx6rqEq2Lh_FUU`XWcY5$Bb%}o*AN*Mp$kiA!i1%ZM#rZkn<7>Eu8+?&m$+>V0w>~)MpnTmVPq6#AlL6%#%Jl zU;f0P_!Voqcpp*}SGbo6n;E0p{2_3)o6bw-;#ZvF+$c>!NZoNRQ0Cq}Z0_WF{EvCX zyIbMQsfHQn!4r$30sFa?7dc#7VcBW&-^ZQ=?8L`K?z?;Oz4#ez+GD;y%K1~e)|kW* zFhLfH&yF}qUW^LDVE)WKG_#cD&tC~GZ|5yia)EkU*^t{t4?`DeL=JXG*a*e@M^b@j z8aA*{x$=_bytvKl_6RZk|{QBFdM%1b~MVBy??5*AVX;{O_Nq!iQy-&1%&L2 z>4{mou&-lw7^+8&ijJoCK6Zj5Y_AY3a|USak$CNTHpg5>F`-MAp#9vu#p+J^6(pg# zp3z^El}Tv@a>j=S`B@XifoSQIBsq)Q-UN0Z{JiT^s|t4~+&Po#?i@*Anf~7SiCNAD zTw7UY3*Ubbpe_GN(-a^gf64|aNeE5=2wBlF)NmDhD|HNu7w*42Y>KgcQb(1`R}eSy zjW#jZ#eY{Ceyk~FFV#V4@LUp1-)_F??)R?aJAt$Y0?&6!x6<%eA|>aUX?8&aL54X} zu&$qM&tC=(&7VblJ?x}B{fY>QcK$72;5TS}JC5SrjVSKoed;ShJvlpd78W{reQA2q zG7Bm9h}C=5mChc{*0ua(u}U3qLlVC_qXEA^osaz@q%)T#Fh2Lam|0%oU*6W<>-|5V z`&*_PLn<(S6P~~KYzj$H0||#(OAF%z)>2@T9?b0p!T;!fI z#P$qrS!m zT^r5;1H!a0ij#*XhP+O85pJFpg)V4_ZqLw)*{< z*Ni8uuO!g2I-1$T!~HgPB}wG1I=R|cDET7_OvQ$c=grLl=G)gF<^(@)mN#!ccVq|T`m!>@DFnB8{6TO zzr=@>0Is=67f4yIu1(`xnD}1Iq~e?mGOKK01$@ieebxE9GLRA*{?k^U^(@Q(U0mG1 z4PmfrykOO$N)RG{AXs6^dhAtd9d+>_?i(d+`^Hg`3|Af(z)`o&Rhvxht(t7r!n~wM z>h8tqtUftT6gD1KFGl_;aPpw6vr9OIC$rky0NOSM?mE;d4(kg{qUsG78upc(;U=n4 z>NH}t2^~}q9uLp_eBKeo`TD09|57P7a|gtf;QM+sGc08avkTAHaY=LT9<5)2dZ` zYDaU!gOqY8qx5I%@agH0m{dOHEJ7OfMnehw^GGo3+oER}`T2M}{pq&bFqy`|xaRL? zS^wfOaxK-l<{g)pT}#f=Qp}sydDbdfmm`Y1mJuYek4U!RM>fZ)2bsP3Y%kix+~LK( zUMTV}z96AF`0x-#MNJCv%&9Mvv=ZGf?!aYPNnz2XXH)bWfN|S^A+FfSiNw|TFE1mL zy}%L~9Bk_tSEpo)1Zm2PdxY@I&&YW>Lk;t#%p6NINg$6+v4o}u;ofILA&T?9d@l6i z=j?YFxPwo-^hQxs(`EMX4g!wPp;0}|JdCNAFSu^LFlN-a?Y;bC^^}hKZ@-h{Ktqjf zPmacT+RI@yZR=T$#Z_+taX_{M3>>2bm)<=8G4L^60!3u4Qd zzAW@rTNgRlBYtQdju$nhbb{#)CX^f754Ab+UC} zeGs0?gU8%vS~3v^rk1BRzCRu9+a88Vy%;I&Z=Xhn@W)%}Bpv^ZUi4=g@>$uk5_`03s6TfBJ8^uS+1+UJ#>XGAHWreQcFw-P**LBGi1xGX^OoPIvF$Gf6qS|TQ)uZ zS!coDYJL5pKgakU(CqqHOFc@|yuEh4sjjxXx>KnEar!uW!%MgKcbh_lFiH2Fe1<$N za{Q6{Ct??Y%hilpA1m>d^uJT6f<&TKeqylihth?t* zq1H5Z!-}73oXQ-kNt!{~e9Vi3V72aZjnegANYcZG#v_3@_-bjc!R1cx`LJcgvA{3) zfRtVm2;rVDlKMUk=*8{JuMSz5{n$lH>UGJDn>_3}re>!Cy6b6gDUt$WW+o``q}*E*8uW57-&;3{ zTZgBWsM*Z>X12oPKP+&hZNh0vlMs3$7Y;v14W+F`w2cbst5*XcKtJ?dfs)c(a7iH2 z<)AV&!}-f#OsD9=61+^YQq;Ue&Up*u!~RLp(v-7aT4P4uwrw=GQ@Pb!ApeyyFUzl! zj;GG=);~2*Z;?8FqsIC1&ZsDnN`LQ%yT71RJ*W~tvdgbTTbL2p7(2_=Cd)GSY)#^J z$qbVFokZ@uP;#4+;N|p+BM(ikn%j`SkNsor1rKta{e0Tn-Q6E6|D)gk1M(oVO0F{f z5RyOpl=B5s-_US%YBaLO1_ZdVABrh7jyz1+GGUKsGseiJG^Et>zm6A(x$8R3Xq=XO z;wY$OY5*7|lRhev$5b52%i2d9v}>Ez@FtHLm==6a*8FU14L7*AIm=Qr zXE`g)J`dmD!@>V>aNOL-eZ8;O>pXXbIIk~Pk4^chGDOpwUIwI>Vz6G-ti0h9E|8OWhcQ?=tiXSHM7RK_mauoO-gtF>rh1Z5`A z2ZMI)4USfTZ}r$Q&3s@WC60s5m^#p3^BFFs$jGsc*TS#v-nad6?|ZB0c#+jbr3q=J zW34~Cp!*o&Mpcoj;(vfUJb@g)VnVk6>VTZmV*eG$3y&2ecYp}@aH0E=9+I4a1617b zcI4;iVHg-9=~p0DGn-JD^?m zUANkrq5o>Pt6AUY)vV5ntyLI{>+D^s)}qaoC3RK;`gAt7txS_&g?%OCg!!tpGTZL~&lv%XdJynIQuUZ`>Sp`k+Fsd389Xm(wCW7ZdOpn@d9g5J!d4hTQfW^&>{^8j4~ zFbb{oA3!$pOsPR!Pz{etl9t4hw8#oWaT5j#kXvMohDvFY&schK#q6lrMgbh}Aw|UZ z(3qxS%y~rAwz;{ty@sr`e5(JYGXu}}1aB*w(psd;D#MCNO%WlXPfiw}&4pmQp>Dr{ z8NYeWb(@uDH7h-_OaZv$h&0MRyJBZ~ggdQx7g>NVZ64CmdTC4pVpHa2t<>h87pZeF zzR*}LX0G6RU*VHXsUh@p$)5;I3!&hr^gnZNkk9;vEo~$pEato08Pja+YwyNIl;RgK zeD<09&l6CH3GO(lGToH6m!C=x?{2y=#3=2=3>H0+bdjlk_p!3KSGrc>;fI5jtz150 z{=w5P{{i9xB^iDyWr>LHqDTp z>Uig6V6^T-if=u?l!-{uU%6aqDZA;KAl*A z)}*R_G?|yMQM~u&W04EY_*&MY6)q&)8pUb*gT5`MnZz`-$`ikVIe9xhC-XQ0D!0eEsA8}&UGye=t1J&bpfibWLtaL+G3gvKeX&n|cQDnU=KYK4(u=5|_ zgL$bFFmvMR(=`LU=SDRu4|Wl%RaWfIq$t3DnSdf`!uYZOn9WNWb_e|xu*X_z`ToqW z)Y&Pk8)XsAQME;m*{=LiVX$7+sH0cP(BRwNffJ4{R>De!9;>_W=O7Q~kj5Hdksi<) zn%#{7uc}(BUVE^ZJWzSL*(7pu`KrSld0ouhdmPS&w89e*5L=2v25Id{a(8#mKsZ+S zr@>2e$6>*OVM#ZDRkX%ERlY(bJTJ@~JW4XEzrKx$N%~+Y6iB7G|5|AVreiWGhHJ}5iMI69m z6j~U9@NefeUUnO=@r{$*+=2w9(*tGW*yENhUqMt8HF?pC&?P#Az~7O|B* z>+eR-=FuFX*Yb(xOzZxT(2rkMmb9VJxL#!=-(Dr7F8ldWEh??yk}jj`#`|0pY1i6CqZU299T$uGPzPAQLfEMTYEn@Vu4T8bN0)H z?~dZcamlZk=e7_$*PVH21K0Gm5J|u)hmy)ruaYDWzi(`6RYM?Cxgpu?bl^TOx zTO=)@iH@EH3BTB=`>i z&yPGdaUddL1`qnp8=zB$bVAmLv}K>)zBCfMQ`Hpe9{sDHVw;L8xmL~qy@(&EJ%Bza zXiD(OgbWi8(HoOyG_bKd@RAOJ(GZe{)mkhOy3R%&zJZ?=Zh-5#n=6TreAfXiGHxHr z%4#s*3-I20x%$nn-teUeU>K$mnNN|W8GZG}k}^l&&cTZ0aOZ)fG-?t8R8sm|SnTzI zSLH(m(Rgx3Ij@`f^gu%JnQ^d(9jieL*ep7MG^yqaN**8rtWtscB4MbSq@XCu!%3Vh zcy+r>OVW!&OcnRDhiYX=d3chjv~lu#@1y5~m}Yrt;%O$KIR;w!a4;K+ zdfRjp#NgkZc-OP+As;n4Tv?taG04-bulU4<$DQ>BW6$t%IP~c1&Ad+t8|%GykD5Sf zBG0G_`o*JaYYm+JQRlHQl|_JT)7Bzk|7iB+#Xh!RB$nrPcaD?-eeBq{=i)p7=ks}z zT4uy7NY5}sgU##O=f=7HgDY6h=HzBtRc|+q)%x+RnEXR=3MXcrg_aB>PacNilGi1wn<%3AqqL4?DSH2qbubc$l!8i* zrs19;lh0LNA$pI=+MVf=a)seTqc)-5ZerYoVN(m5=8f+fG=QA*=Fs(e%Jzm`J zzZN_i@&yZj@G9PH{i%vOqj!r?d0V7)*n`&eTh5yoNjjpe?qNn%9-lra5+N%*mJhRT4{JE;lZLs_xz;%Zd8t5ad72Wee@XPlMxAg+gaPYL;JxNk zrz}I(c}#X6p;Ir^a$;%>hGnBh>4AI5Yh@>TMog{ zL9}0P;jsQ<+4^g5L7O-D?Q_3AS~u1os+Ou<6b_JI{%BsKdHP?9A=>rj2tGYN8t%KV zf*!w>GM0@5PXD++cfl0XAy^pk#-v7K)DEk_QnpxQhYTyVf>)slBFjBDruz9~+^a=R zs#C>16;6+xFeH4{%@ErfE>B^l&2ZiVQ<@%+UkV$qX0vQZ3sc>J%BEqk{G&hL!>@VW zjPaL?KAC$F;VAgmUibRmAa|Mf++1;hi{Ljef}+1G@9`8<6rF&T^HpAh>bRQ2TaY%f8WSDsbyJ6Hoq2Ns)VuKfO84u0Y!Rx*re&xkRC~= z7tPw-4QwQM)2GkUTJUt4QuXI|%#~M$G?nj*6Ydz$*32Y` ze!DY+ysqTDm{@L`BTczM)%etECe|dg{CdI8uK0W|%INmvZ-x}K$%2aY^B#RKx4pI> zkQx0X`2vI^k9A3{wsmHX{H4qij(*;J9s}W4SQ1F*z|-<=I_WSmYc;~jxHEV<0N}Y# zzI%L6xUYV#;^LXjeD!#c@$5}U+%*~5c}g_!+$~SN>7{5>Kdgmnx%xRgV8)e$a~s5$ zv-EtX-DfJzxTSI~4%6F!4z_mun5F1p8^_PeP6nSXxvv`fs|-HeYWeF=h;1w_AJrYGISL|qCoLaDr__}n2iKO zv3tsnX5TUbbj|gmiGpwk45r1kEt*~RFuKj1+ws75=~DwY<~%b2bYV%@Iu zn|fEFhKa~O%k?U0x;_p;9H}JeLyl`pSt3~iRotQWKdOcB8pRGLX2lbHgH2Z|nZ;i$ zNBWoX^_*ZO3ah6o*K8V?UIi}X*sncK*Hb=N(z{D~?Tq5jr=%H)(b5#*A)W?#d031 z1pk2>82ijRzGLrJG6DHP!PFZ$32J_9j2dhH)rV)i0(pB8d`&y=v`xSx(Gp$&&Vli9xTLBgEZb@+l22JJ+0qKEn1t7%M z!4k(3V+TxS*>=pJ@|P9!zP=&zuEZ`kr|BeJ9}+;aTFYI@nd*L-g+K?iK0%RA&_52{ zx(`neENUcoOiAPzbTrEibrb-e{u+36P7YZ3l~lcL!nEFW2;sm3+>=bJbJYpV%G%Okvy%tq}^nH#RNtWbH$VU~9B zZ@d$#gvYQDJth(~o!%F=%=E**XP8%U=In;i@a}YVM9QozFWqDFVU3riYu*P8vVMIw zS$;db??!C8KBxkGm(+#W3|v?scL(a-EG0t{_$hnBCIFDXOr@w5@2>j~*eL#DJ^z)I z^H-}pTo|SD3cfBOnfa|y$HUnXCR5XeICeIaB_03@#&%;@1LiISzmEreC@i|Lsd1A? zEJP-|(x2ZIS7Fo5Q!5~oAbL2JW^TXpL=fiQNL6{qeyY%T<<={pbKCBvTVux>Zy0Pd zI90<-Viaaqc5lQG)QCGKt(6B0xSQfCBA}eZ60gMjak&UaY=4bZp1#59fXqq*!q!JV zq&%csT6V;zF?1P=&vZ5%Tj6XeZs**+|IEBSjCn140z zEBW^y8#$n5LlymXoI`wn1{KOIaE9%9{~Q*T>17|;M{;sB@l%rX#p{&MoJ<^$va-rx zqID9yfngSvuER47udPf>wkybvss?NlPyptPX=|^$v-OL!ZP$b5I?O#AT;3kZ2lk80 z*ytkxH4>CGFfysuwnDT)z$H-!w<443IF07XRbK@U`F{o(@k5_c0veL~VZ;qx~t5I(t$xK*px)-rqL-2TQ^F6&&!-Rku8vS`!MgXO#qR3K_- z>EVtFE+u3lvkr59O4ePBQ{{#@$=so@5}2NEw91U8LY>S(4#l4#;Ri$PGW9cy@I$|F zzsP^!m16O##{qIZzFax|XU1M(hg^7a;HIEqLCi4ned%@T<%?h#a7OPp$%+?6k zIr%Z0F>edHZI}>}x0g!726FtjyV^qZMO52kpc1z*uJ~c#swI2JQvjU#V0!|vOJGeb zK93g%3`wg!G78x4i_#d8)@h?7?E09+yZL$7p+t{F^6QXr`9^H)Z1CFgi zMy|C^_qhk?im}X`SlgJp;P{y1kwwV;d?vD#_RX~icW$SdT2!cP>fH14a8>oCdRAHO zie(Eq3<0=`;3DXhE(BmhGC#qVcm)?xQ0fXMOD2J50tIFN$(*r~27h|RUEeNDFC}4( zQB4qyZ4D@R&BoEB%ukWO{kLiE0Uvb$S+zQgI_-Q)cA42uECiwu{>-Tpcsc0e7_Jh}j)K3F8H2?ojoE!qMSt zvSEOXbKw6S*9?m8KuQdEq@&)uMXW;*>pzPU?<m(LiWPp=K)>RGW)Iup$#@(DD3%&7&MF01LM z7e)#rDLGlLZwB@D{@z7>(F@8v6eW?RPZP|18q62LmJ)(#yW`3d@Z&4-k(RgWGq6La z;`d|g?X*0ND9~@-2&E;a%@AvT@~Z0px9C7mK0M9e`SeQhYjWuPX+*%VTIPx0IueO8 z>dpa3vNkn2aLcm14gVhDnEfsJF-O*z6WbJNKf1XBBC5?z4wVk6d6uWwQbou^=s+AWVd<7RWa0n^iGsFq3@#kc-Fwb&k{7S=>I+fFl@G7{$zC)b2+Hm-Sm=9A;axq?HunEL> z1gNWUCbnJ)p4a%@R5dKSU1RZZi9?IasoHk^DW~nLo?TFqtpo$hBL6=X{|lkTs*hv< zX_g+3!U87%fnc-D+WtWl#ob$A z_~!4PjpAj-YBU(&iNh^C*u6g?d8c-wy?$cUJ6v~9G_%YqLuhK90QCgN;(K|aMJ^Go zo*mAj3t`i>jV8NeO~?S!>KG!LNLCf;b?LaqP+UIx8Zp)Ccou9Ep8rG%DZma$SPg^0 z>*ZegnG`;k<|Ffya@A#)UwYSd_UWcP%E=sSe&{=StrbK?7gg5{Vk3VOG{3nml`2{d z>UpCuhg);&&&gaM;+oJ~rc9>61OPQ<6gUcuYpV6TL>+8t=3KdB#dgY@spLtT9HOsJJZ{~kxU&NzQ6T-;Qa*iDHB2hi$` z`fhXc-eHt68izE1SgiJCk*?3v{+&EFz}Qxq&BEuIrD3r86$ON225Y5H zyIdA9=qVnXfg|JTasf&AyzE>3W_-lRA&3;Ph!;p~RY^6P+>@Hr;WkC7M(4;KF7*=s z$LLDY$R@2=zFsFd_5lFH!)lSw3c+TBcj{bJHiy-4NgT91a--cEGDL1@xN7Im2ycRV zXoI@fjPf3;ISJ_yBtdO%)m#Az8)7D@>sNk^&J~-va3IVf2BR9~9dmN>9_jN_!vKf( zA9hl#pUKMz#J#5!a~U9i68twH@(kMGTvLWDM8=4O!xB5%9AgrkG-zpF|Ia{gyIoct z;W3d>JM}?Qc9cUUlYU;cF?-W`yM4bpbWohb!zk*zKM}HXGuuP=$0)So&2>Ewi>rGm zIQzxBo|vb9$Wx@tku}ELCK((YuS#gH5@7dt98UvEmWXVoeL%d`xuHCX4VZnWZ-gsb zsur$5E)NvNCr|ufh%0WN7t$t)U`W8g!hjgmFX@Ac=!uSM55!N2v~W8 zTi9Mq#$xdIE;un$1j8Q~cC=B$_>MZlDsH(T`SjBh4PJv6K35A}9L*rpcXfRVJ)we# zI1mgXPBZt2{>^#SecdVN2j_J$f>;XH5Y~smzZ&_b8iv&lNXKB)X>^j)OdGFuMRLL` z@6m;Zn_Y1%a@ns_L(vidra7z4rgbJ0(>nY;jQbspSXw8-2R|>>%Djz5M;$iZ*fR;w z<<+$4S@EEIuS{bGJ=vEUN0QDMYMXyhAU^mXh-(9$pKn0cAMqxm&F3;D?UELFN8IYa zKJuXNu?A6t*15nq6Q$mSB-G2qRloF^);< z;W~l_3~bjdSBu)&w0=p2H2!u9*NC8<52Ij@!n@l|mOs7>$ze}W6LPsu5J^#VhnJ0A;3$=#i zMO+}vL-TwlMt&s8rQDJEm`;33NKKJ#h9+HULCH~}+?2UsrZPALsqy(gz>OPwbMj^& zX3ocA>d9s+sj~JE-ue5>`a(3$G1}`mtw{*=b(>o|)?eP0?{azHZ5RuY7@IbTt1`EG z5z__2Y0&a=3YMPBKDJswYXE()>{lyZ|F(gfr)uST7I%&A!SOj-A{Y%tz|(bRm=e)K zkKf>INAhRcb7`AUZTWOv-Wl~C89IXmr!E0QhINKCL9vC~x!U*i!{!%}hk1|;^2Ng5 zijP5(*S8uGFd=#tjzepmE**dUp~xFe#~Lc*RiXv5G!mFYsghx#6gCt$dh&Go8qhoX zBGyl+3&i};e2VmS`dbrK_}33*{{dR{z0G)b$x+G&l!wlOO+1ECj~{%~>5K7KnXy-i z@v^!dP*!Wjx0Q?kY*b4aT}~?GQhh6~f{zDY)Y3krsHlC2Q7P>9{+A{<$=U8;VIrKv zRPbgDUt)}3h+h^hvU?mOU1U7QcI`Cz5}DWGbNBaz@_zu0(h|=4PqSlnh=b(vFnFC< zjCEQUJyy-PHI>v)CSj`Kied`7Qw3*h)Dx0L3bi?WwqV*XLx}Na!y-{CQcG3xw^O~3 zti5V{@*!)>;Z_r5S+;raOByBsf(%wY77~C;w%B1H@E;8rE3;+*swXi@Ff>$^X`^r6}3@?oqo-LY^Tm3G4nAYF#@{Q3}2EmL#ike zbtpLYN9oB7jJGn|kukDnFS`%PDbe1r8R>Sri`V0x4| zKN+O@Wvdtha89)Dr8=;?uqs|~za5ug6-RpPf}qTz&-Wugx_JT~sZyNZ*qU(_bjIcE zUZgTw(`D#uug@V~v>%M}D z=`pYjGz}Ea_X#4ClL0*drq{D)2M#75^vxO`4Qu3fi__Dzv%yDsW0ZA-SG##Thivmb zUr#v!R9rlUNnq|t^Pv*|jm_XP`aw(!x6L)^AG|Pr@t~ZBSzD&lJNyQIgo4H3sNK#X)3#vcHQrW^P0om zOC7r$EFI?CHcE_V6b`h72owOk*L~ zVlH7MM9qN}*e`$(Q7Y)mmudL%Yt=KGSi|Un__|4k=2CZ84^wL)Pt|O3N@@y!V*uRb z!JQU_il*gU%H1-~P0oFNIdMZmjZ|L`knri;dZfX~&%4k8tdcEXlj?t24P!+3$i^j@@Chs0J)eNYel1j`QMxQ|M3mZS|3 z@p5lywS~*Ql&tteVI>;?-y>O3 z_2iZ2%qmX$+R^07kcmEK*X3Cq+FN4QYa3N7e56WyZIPwQ=CZk+!t_(*b%esdyB5ZE zRafrUaAPMnEJV!p0T2GTRy^>Hyx;orfOGPDP4rH|xWKHzY%rPZHFA0r>D_uRNfe(9 zkqljyF0z;ZMT~bsZGZXD-hQo51-};c+S+MqAs6mM3cQC2ZL%?E_9^ zq75z2OMX5@hCjT#ep^@8E1&13#{I|`v2QsYsvxao+P~!LUJtLAaO+u7nNZcIR;FVe zdV?XQweuhDh>$AZBm%YZ{Di*>p8aUP)X;-XLq&nw%QaVqgFz(K42zd&28=8rkfvK& zq;0C_F%f;%&TPg8oFVQ2m8_8s<-42A{=G18ewaEm_tCL!Laj_vX=9?R?IPRCb0B2> zXP6TC_z2Ciq>)o(7&s{3<=38Ry_QySv9guLjnWI8V71rkc4R`Zgfe*MGt*tOg0tfD zZ{R8j4{XZ04()Tt);hnkjl)#WrxC@6F2?hw)nIae3|EG`MYP5XHzAaVi6ER@#!t=5 z(>qW1nb#8R1S4e+Q%BmlIbpDT7L=wxYENb$LR^VS(HHIsAwn*LF?5r_fSp15Nma`R zi9}Zn8mA1UTw%!ddoqRqbB@Qm5_K>l$Z zYDRGD-d)1*(0WC`9CY*SdjBh2?VG20)jMbVIuB=;Lz`oFoj#Y>$@Qu^c79T8ZZhTR zECn___s0TfJ~r6tQnqF&OIPJ}aXU6|ZrLz|N-2E7(ZYYqjEiPCOsverCQRn>*! zTX;Gs4kwg$Q9I)g`7FNf*v?ZbWS@D~ZxTK_gJ@y`M zdE?q{UY+XAD#@sS2}0LaJK+rMSX_bSn+AqQw}UY|3sv59)s00FKLn(B(M0tgS=%PM z@#ytOfLNdi@W(lsFHfsVYSDwvh%XYuIZ15J9gJi^gdZ}JFJjGHfFf!xab%_@Y1nu7 zHH#_3K`)#QHDT!#oo@S4P%-u$cgsC7-SX~kaWrX_)|_UQgHjvJr*ayAR&b72l=_z8 zhUu(?7KZx(G)w?N(<2gGI!FgOeS30C+-UDQ|1sIZ@+>eyaA?o_{5Jjh{ypBxbaW0N zmEunAexO1;Ruq5@z(>(0A!nuHSDInA&-lVKerS8=S8z zk!7>OBLfU@l52Y!biRpuc5ymhle!w4R#=8#?r$*>dBCYlfBI7#O!Hc>)BN?e*D4YI zDquB288P6&@QPRWXJFW$ovPUUjmpiqj7cIe4M(1Q&rU}b5A<~IRH)}{KS}RpaNoqg zr>s6UIhYz>3o~bzPo--?;a>`IW&><*MWL*Qq4~@mMq>^%?n1WE1W=4hd~qs7XPqG$ zyG}lGu;)$Ay+Jgav>jMMBb6*(`1hwX$!di6-T=ck${zwQgMq!hM?F8EM!aM#XI7VZ zqoQ(e#_HY~hE21!IxuN$wQl4)dwHEwJs~NdQeANWa!%}3Y761@)K;jRA^T{UnTOe!xYuT5~aZV zE8Sr_^NvSavyT@PMDr|T5B;mU`woXm+~2_|Ft}?C5ThW8j&PK!t7-j?^chv0 zZT78&vnJi83=#9t-i)$kD9l3NP3+%RJ8+^nze-Xfs%_-|j7W&GoGKnd{0z-#yamNM zXhudKU0p;G?Utyrb&n)s;g8$1plounI1T@RSsAGM;=kAEJ}K@`cKd~qgXTy1 zo^@y3H*ZG}LL~LeAwI;4Q4h{L-{B1Fq-tREOUD6Ej1o6Dua2HD{KZH4tj6Nv09BOF zue&WsGp!WQ?*QqWos7f~X22r`lK-GhzQ2m6tc0Ab@E|`dC|C z>d_@GXPlK`q@V0ZDjE#;NY`Vy1MBLm#%2sX`>v8@eoeZE+blikmF5bc%9(`O6!~^F zv*S(kZhXETmVLKbb~DahW2W~d2r$w`TA$#Tt;r1QL5&suqVIHLka}hj)B`Pix<)T* zX&plLls$7MC&8()#h_u|Y6_9zzh}^ZzLSA0cQ0oQ2U?K$wwO&(`flm~*^%MNO*)x< z5{jHt*Q{QhI#c>$*qYxjnmlF=v*}Sov&$;=LTgz6Y}D>v&q{%te=OOtpGv6W^{U7k zYfuXWvdeEfqn3uzHZO*TaXPX!RRl>XS#$%o33VIL z)QeEc>Oh5Kxir!xpBfonKjKf%0Ch`i+T+C7%}ISMG7u0-ku8-G2);8hK*f_C55*6Y z#gFDA;5WH0Wyo3IrGih*ZN2ie*9ScxC*Wl3SEfX<&wWd?oLimP*l+2twt4L7o|m%8 zv*_7ty41r`Ly9l8CICam=s)n2sZoxM;gw|du~2ENO8{A5$ItvHSdyluKn*f@*1Xgp z;-vMx^iFi+`}H8cpiTzGMO>`&tSHr9dVwsDlNO|oMyR=IXoiYDlR-F2L08YORBnG)D&s5m ztY}7mYBZ_TQOUG&8D~))2y+5%U<9Hz`Qp@*z^zJX)b>htu~F`fM?hP+iV<9whtWu+_N zmYFR-@%oy}gryu?NW58J)U^?-{5MDzPXTQ>#npuhJy-7Zg)*%61o5Eh5M*th=Mbda zvnp2@Stzqn6)bU~UMGUC(ATmL#Smpbb>2h^yd4*FbLDyLvKS|PEf!m7VlI2%sP~!K z+Y82<82K+X#M9sqM`;Yq~K@O5OJ*Rn6a1#R8ko*eL5>#x$>%E)Iz5e>FP1r3IZOPf?*W(0Bh2SjNr0h~5~1*_Y*7B(^> z!+ZShErSXw^p`1)xm|zE$$zap9?Gh< zMRohQh1DeS+KQ=(Ipfo11Epz|HmJEv31GH?OWQ!^bp6HH-W#z*3*<>JjDvtG6~Lbp zo-@$6D-l6#G)J+x>{Kgbjz$%)=Bwz!>`?>8Teck)pX@)5D|=Q8Rruax z7bm312fmh&bdGYy@dl8<>hgk|$+T_>qP9c#lNk0XCAgIOnSaKw5Rl|OB(527=??(b zxpI$ETtq&-LZxJ2gHc9nA;cdc0A_eT#pP*mO~5Lr9a(74)n>cLZmwWbDV9GjYWPP7;A;OZl{|gb%R>|;J~^+hDQmoe#VO_$1U4o zVH3i3R;5#VH2t77 z*reWQL`p5%5K&>ut0Ha<`D7?;*H3vqM|xHQb7HJIFzci^RM)A%g#6I1MBD15sx)=G zcDX1WvArqbVCwH&DZMM`o;VBye3dsMsJT`nTp8J|=HwZTd0h>1Tsmwuy>-~$_Z_vm zMfF65bUXdAh>_M(*JB76TwxKTzg`cD;?sg`Y`TSM@0q(A{JWjPeW8D zDu3^0JX@&ffU^vpyUS)fMY|>$5(dq##hDsYMn_45afvDBZM+l}7G?%wPWz6xOYu+N z>8@?c#SGqe^`!#t)0%c&p++!PEtmwijlgIqkI1b_?500CBRUTk?q%yd!BybcI4Viz+WdU9e6%-K z{{y_zExoZ)HN)Jv`#nz}$K0yE#{4Z(luN-Y)Wf0+_ea*`0|UhnHAg^xMtnoQ8xxkr zpG?aL`<~;i$8oI3u%iNFX|8U5e#4)eQuBjxyvx5nDvOMK-jyhz^6!6(WJ`T%5}ydp zOWO|Szq`sp!`}dMjnN2Hd0b@kj(4cr`0op@YLCH6(q{%XR{BPxgp4E_(YNU)(FE$0 zI|Nki9Xp0}OL2I*ldrXJB}xP)0wwDZYhGAW^7yy=SS4V5o#Q4u7VuBl84-l_wke1A0ZUW&j0CZd3I5YiCP5U66l1vW$49xf# z2gPZS=bIi4oQ#zRS31c})M;@g6A^PGL}8tPlq;kiBD=J$auw+OQT#VLc;zkvwMg(V zFj*=iaX*c`cXV3LKl5C0n`>QDP-*<-N)Vr@5|o<1M?=RM?G8`vRPLQr2TPi&*|DP9 zuiJz=k@@4%QI*t|vEAF;`~aCzuGm-L+Tz47xiEWLhLP8(UBkfy#uxlpb}TfuS3~VI zFg_`_g~~=0(WFFvoy4Ay{bsZM4Az?|J_`0`><`TyTmh>~ITE;@{QiYx=O3cBONn%f9@2Ew0G%L32%ils2KC>B7*mv^;@Aq#;@+A-` zHRR@6Rk`j`hHn)}^aJptG)3kxqral?{HNPhXTHLPIo|iyGF(JfgizaQ9rA6ZNSTSR zitb4X9Op|NZrB*PX?F7!khSWR;-k)k+8n&X#>@LZV_!WaCuZhC>Kt3l+vvFp4Nf1I zzxBoHuR2Y}V#)Hnj14ldmm@oRT_lS3>bcG+E!4GQK3BZi5S~7=RWl0pP-UdmcVE6C z&a^HYm`@FgiMS8fOgsMHxcB5r!5&E=*;aayJZ-N78Wpulca!kFl9EZ#8F{5n0gnVw zfC7ypPd^zPC3ZX%bo_m=zu`xg?EabLCT^>1nTK!S^8F<;J%g8M4%xIOY#GM@Mp0pW zU&%y7Uyf`wbjZKF%AD4k>(x6Kkr<8xkGmMNCkD>*+RIkCI(!S~u`*6_lLnGvDP8w? z?!YBSh<;n-&IMb=rk@k-jmYrtf1Itiy)<2?X7sjkMa3E5x2!kwYpBCEmZz=sQ*O>iyp>HoG%UY@su=I4GZf}d(s-((fjZePDo+Brj}3qD zH)EYRmNxz}B(203L{QpONH(Gx(e=RUKvVcva#;NCN-JCZV;`c0kl>N0;zUY;tYDlE zTS3f3=@t*0J5stX7JKY3gFSsTo&V}{t)X?|toiy}$32By;bQN0E{f}!dG87;r0f)2 zVSfATXN+9gS$gNSqz%S*8nWa@N60+ zT#ut0pH9n>t|$d$U?ojxUq*%RP3^QDNXnw?F!P}1QC7QU$7xWaQYbBt^WB1Er18%{ zj>m5j%v}^xS$wVNGyvSZ+JaDO{&j3@8mzpvVfVUYW!p`utz_#G#%3=!F~NrjECruz z?Z`6_?q#d9CI1&oC*~-PHA6j$_&8L;2x;p1z3l|sY75Eq&B9x5m8`xsts!)L;|x3;W!`8Ive#wtEQST#>Meh_`5 zKOy@9Qx5rP6g}Gfj1N{U7BkxM&vQNSF@o`WqikAMrmrIbfF59_mlvhiyfK?Le~&;6 zenJ^~_4biuB{$0mjfOUqFMq9DqxP&Q_np!hdKo)AyOFf1%4sQ`q>aZ7LX?#~)UuRq zzfH4lKUqXL;9=!;eUe}TB&;?1DSDcuYA_BXR0Lx6DP*U+@B02@Mj!uGDv}2 z1M&&W4gtH%DJHdQRvQHi=)yMtg11ym(*xb6-Bc4yQ{%(#o2Q(=t3b))XijrikxS+D zVK@a1pxYOawH3t&Ucr?**@zFDd)7Gf3ManE6%+LOBt{`n;_jRuBmHc2{ZuVLvPGZ% z4pjWG(k(*(28!-#q+M3ar}S3>6D>%!ym8SThpHW(Awd&C6VIN$Q!ZMfXMCW(!ST2d zJy)5|zA9csZJGL-GEf>VLNp(WcH!jw#&tPXECxbSz8%F1`1YTAPDn2v;S$mVk!sQZ z0kr4#0Wg0O2{ndPQf0_$W~qbvstJ&VR)&nhoB2|Gz` zzZ1JMiu$I)VV5+iZ}f?C!2GA>n*kZWzdvSOjDMfo6YTXCrVz4Ss6hsqlm@)((`Th> zuhbjm@&o@MJk?a<)q_8zZ#9AZ&*&l%Q_80eP7hSk;defn`}Jt4%Bmy~y{qCaEq_!? zX5FLa-NQ(k99c;x5P`dtmNgV@(K6E8Ra87C2uD3}TkolHD4Q`%7>=JGfhk6f!2-b~ zMpOq}tK5l5NUd6%I*SOjd{?nZD62lks>vY-dATE5dSWkwzd3~1 zKM17#Cf-|-6RQEi$sYU?*(@~C{XS(rcgrfxaiO$KPq+azQ+w0H>p@HU4-REB;U2s8 zhen%#@C}yPw+k6Yp119n(o$rfsQINnPx>6tV@}s70!t4%nT7M}zar|-)IZIA+&9ke z61JBu6fB1lVt$!QqfFnj+7nZj!54wUK7uEYtP;Yuz2@d%PAT21j%#0u;_u#nQ-}%m zorHYP{V=kfaVNgG&EX>ZgHnLPne3)~fOAM@T58$EH*zM7GX9&^`>D5-k?BaJ3Az53 z?RBAd6=WJ~Fe6cyVm`EAwTcQ2*$9Vb;bVSQ65-f&fUK6v$C-Wa+}hlbSgJa$?y>ov zSfA!WZqHAqa=z-VlE@7#pRwG+qdyWlDt50-8X|5}WJyqU8!b^8Qt>w*jcmHzfK?+D zI?8ud+=lO4&eoY1d`a#b^Z+M~nGZGV34a6}gsnN6Bv^y|BgO(UhBUwq?2HiNl;>-cMSkKtrIAQff?Dwaoq4#YI^?d z%hO@ZASY^HsL~yS&)G=jH3G>=4UNPP1EiNx{n6=xRDu*c+V-A#yMA;<`~=&i_|ijE z&5M+ki%>pAzH7r9#e&IQ4Y1bz76}nQ0WPb#!&SrWl@9vo*zSNMT(I{J#0uyBg2Q^G zhC#;E;4(@X923c=1P_`U<|8NMqBof@eyU8fJ!G&jwx)?~5}~OfghH9XtNBcM!}fQA zEavLIYZMaNyk;I873G0u(Fv7M#PZolA?Nil_hjOa4E6NJwJPKrH2N)^# znHK#vAvp6vv~0}d=c{NDb$U9HPL-yS^iHK-(h2!Zya7F$7m!~3GUJ*ITkDo@?kjg{ zsztng_Z6Zo)Lqg{0bY6@$%44VJ&q!%Czb#=d7K7a<+I18rAz~oCLL)Wpl%&lj9N6T#& zI880<)U51ApH{gsjMNZCyyb3i1GisqSiCy>o;}0A%l$e~T5kJ>W??HTtM7XLe7EE8 zzF$S?*-v#Zd=Avu)4;JY8d~48qgk`t%OSCBrhX)F?=e^ewvGMGi-)^W-1GT_!uYT%PX$50t{TY%yHEj_UBnBz zZvRkeWf3Y%y-w4=h%6B`C5Pav6j&2uo#4BF1`_pM!C@xZ*Z2b6G z9Je80tYNZJ{$gR!V8*_tipHK8_@YryuC#%k|7NEsU|>}Yl#eG7)xGdHqlsWBHjS4R zO5fo}ErWF}#^>#5B-%6#tR4RH3JvP;Tl*Ihd2o3$-C|1M8~c{m%UIdn=$Eds1uAli z{MYJ7b7L#US5Pw1#KYDtIRLu0@X0MpdM2R{`&{D(9kncyb|e2(&-;OgD%*GjxBXj+ zX^&fP0wI?Ad>pBZE}yLy98E$aYK~W zFw`*o0kLTR)CPHyj}m(0WboWL!7@{@(65I+ul(1YT!GNvCzE<}xHm$0vK7fQs#LFF zjwrnKtNs)Bx^(|ze-jcfnm6cJ1#U^_kGl~SNCAY0^N=>^CWsk*1Prowg&TH#z_#Mh{;|DJBw#z47fy-xKqyP_p;8e=k z9Iok8LNd!xp9ujl){NL=I6dC@T%8-*&<-mxRGu^TXO^%iIHLOF^XC;|~7{+LVBTaj#P0a0XE zl7RefR|zQS712c092d@4k{ggSOYbs=O`-lAz>kwf9Q1-!8>Pc{xog;vvT~bGE|d|y zqUJ4;#NreJ+?+I{L;G;&HX+YOHODHb@1;oeRO81~J9sV(?%i7eJdo_#^y?kchx8JS z{~twX8P;UOhT##?Aqc!1j7}+O>5>@T4N7-+ry$@MFhW2W(v6Hp1PNhugGlIfLmFu% z{r3IgFC5!(JUsV(o%eY;EMgGODPA-dnlsM1qGo7>YGQ;mi(>4i+m-EaP8B=FvNy35 zfNuMD@L}lT0IxKd0yi7x{i>z;WoNLcBTlpi3!il}#8~>D}(R#>~5@9s9Z<8Ba6xNIqETA3$dQ-qiiHSL7 zwn4iaW3xu=QM6qStLmh-t581U6BN~N6*wH8=g3wlF?dvg0jw!zU@s@OZ7 zG_AD$+_9e`rvJ&QI3*y;JFFq-_dWZ$d5mVTr{>`^hc6*Y#>lTFm4Dgd#TT_6HVClu zO(s_9lW<~VV+0C(wbib}^3*Jf994<)IEl$Dw~CX&1lW6dTt)|Urm9F3livN9 zH>ts(Zq7!z;cqbeOkSDAf>S;dbQ^*jaysv%_w~NQwxV>_Gj8%G=_c76`?pMbwAMD9 z{H3`9HG8XdtUJ66gd#Y*Ve^+Y7A|Y+ma^2rZi)nWrJS6ILS1Abb1#9D-;kfTunJ0M zd_8-6MrOy#68N0Ds*!wx`zRI3Hk7wY6|NryjR0&nu00mzLdG{*CbU1wx!e;tZ(Im% z@@>!7dn6LR;gB#O&3VaLvGw{$eC13bidR3X$kQC>moy&sI41dKYVsz~GSB0yPM|-j z(J0=&)N5TUmITkcx_yt!TK$eP8`@PbEkgd6!ZC~9;}kzc@Z>%^2Q5T!7n{RLHd3nu zIN8zSd_I-8Cq18LtKS&ET`%+uqYx0dR2$JPS3vpRee_+2VxZgLV7jqh1LDx=ZK%`X zpIO6so!Rjn8=_z<#6HC@m`4A)aJ` z8=I$QNUwrok=~Ui1=pXBY%0gh9|?5Fw8}6mE}d^Wsax(nfA3hdXD0BSrp>`y851q` zkP7I;9W=I`u;B3@E3@mQF21@EEwA4iXEK-)8Uadla+Eaa^=6kl3CX(r+?3ir`;xmzVTeBvpQjQpYoH;te>%%)Y%K#u)M z_BYKwrJhx`q$y-=2Wxg8QmNQ0iYWt159fbLPx3?VIs~7#*o|mJW45uFcbkFYOUS~- zhBYC@D)Wt{QeCLEjytyzT|CZi5|v#iI(C3Rs%6wWNtHLX0HM;UBq}+4#SkncuX{JOHl6%at?N%|-bwd{%uoviRD`%KAEl+%L2}cc4p4u;6pLVY^DgI&be9 z+SeG*_93e{*aM8P8&DWWheOmFy@B1NHRvzIvZNJK+sj4l(FP*&Yg zySC!ZJsDt{w(ybO)U=M?`7wnKBOF)JzEEHq{al=?tC81fxCFDB+E}}3tU93S;_C5?% zHF|0Jrbj*i`HVyJz}(*1XW>Z)ft1+lTH`Zj0j<8e29rfkE!WSzm+HVt5mUj{yFAPL zfeWtxoSP~w=bg&HV%9D2S$8e5X+eHG>!aQqSCJnsAieeYKTfblU2}H3p0$Vppgi>_ z+$@;ZKts`edIY#@`v*AQgOqKabhG;Djus}iE$8$S3K9Aq;L7@z;AJ`t4tW9H6#n8} zY{8%TAu2B-@fAP2Rf`+tSN7H2L_q__Cdy{H+^IK%6t*NsYCPSl>ySOI)6w9 zT=vV%eT_CPp6ZfV3*LUJY4wfqr{ezMn6i!Mky6gUY|b(}VPs5(^>x$E zdykf}b{4*$y#{-VwR(5Fu!l||TB?wlR;lS;QgiBdX5;=f-up|XFNn+}ouWRH3sR@| zTvB0|U-}yd%AC39nWEhS9)#ibfhdAMxl zGg|Xzw`^LW#+gBj4ZutQ_E_fT?@npeI#`z{ZA}$DTKNWAhw6m}VeJv}n2MwIu14J_ z--F>6DZnH_n$KjKw4;b6Gus1oLJSuc$pzP5uxJ;4TxyWuS|uU)hg0M7c=feEx2qgL zwc8tx2U2i$QUSrHQKHJ#{+m= zTrFQ?+ym>U{*z(X`n&J*Zn*vTM31kf4n&fBl{Tm2-yavMaV!*aXuXMYK$^$8q{I;@YcVbvcOoS|uL{#5;DjJ&tSq z$m5(!*2^4>p_umzn$$5rJ&%?iD3d1qPF(BKf#gT*X8eTzgpxQ4UFAm5JB zn@fI6)?t?a50k=rk!Kb?k?S)Q0?!G!ld~}?4>@7tFjM~chAc56O=c!KS?|_`%&tJm zhyMVbBJihz!vUMLS!Ej2NnWB{DQu?ze3HI*xPU>{>HH|OV=l$8hj{G&)b3Z|JnPE* zcY69$9bTgN5e~0D?sT8lT7?C{#ALZp8JAM^7TgiyX4mL|3Q z>HU>5d9iVaHF6;?QhaqPc2g|mH})967!PihiJoJ}* zOteraYT7)r$qGQJ59`tr(FdKzo$M{}3_4T@)*ga|_i29z)2on+AlKcsqV}2Iz!~YA3)}KvbVBmcAsJ^Qy=P>5suv*<-Ec zNOF!u0_sFDJe<{T<#^G*v9A_izYlS~r#c$$ox)nx(tY(K6MVk9AY+>ei~O9Y@D{== z57WoH!CYd>U%A9I)V}Ej#g`CZ+;Y>GA% z?-H9ZKfz#uKoUl2{$Yts^z3%UU`sFd#yxW%J1n#}2`b;%RjgV%&1@70l_HW52)pio z0Gj_#T5|`@lQzB)tlml6W!80}G^5a&ZCrP7&Lto)vTfF27fy;Pl7g#;vRf+o1X@s3 z`lE8r22Hl#p*{Guq4`b9oB?8zVQc&Rb*lqd`^4yN=^2?l_sY*K6U%RRUxN;~S}bW* znAlQt`JH$LS@{F~Nif7Y3%mA1`5PphT#xT~6-jO|_kBvvhbRd>LMm4?yHlQRC@z?k zK^NO2!nuMu%QT)J#4M}1kWFcbSpQRe;^b zZ85;Ibda~qxJrOV9WU3sWdSnl7@<_QPLudL*?4f02!v&x5Rp-Mre1B~^176nRM7J8 z_T}zYy&s<08&_+IT*B-ZuM7uhE93nmSX9QO6$meirslph5VW__r}B9hatS5Ch{Ur* z@B3VF7k16AxB#;vjiPzRn2Y3fPBA}>E++nDPHbrK*?~_b8aJ+Dy0N zkTft$yYg(Ni4VmO;~YtLK#o4WHh~Nlk?zpSDHDo&9sZ<;)zIM9VoG5m9#d3ds$k{?h+7huc-p`nv<&JqxdxBCaE-4@ib z$4CPR;izSVEFELj&6#o&1qVBwL5zKi8XQe$_j2;3Ib}PbH}77=!nP=5-OTE|n@>5} zI6yPPgRb9dAaB)=%wIHF8pL8?IPb1uOkKC`vTaGuvh9xl_f&)waF)s2zu4BzY`Oh6R} zEZj&wr=7QiqByQJje$-BC{*#q+h@A8YaVA`%3kO#@}{7zXfbbbe4V)VsFd1jUn9Gz zKu@bhs0L(*aPj>{`bK-*q(}vUb&IL9`a>7h!%MrFB&AShQHgwOb05hM9_NR&mt0wC z)!!^1F=8nG^R?l!7rUBO9Z~J8ZJL%U(?`~k6iFaIg`|jag#KJ>d>TJ;H=?oR8x$Yp z-i}vGsYsrATUUdq%P^JPJ9)J+kH_0#mFqBhATxvCMI0~FgiA&w?F_#tX>AngAhReF zO6F1P-z-_(&FvL~x(I~8yUPv@&qs6HW+~eoKi7pHw%NhOvH(ff&W@_Kv|n=w@k@je zLYjJl%)GU}=7a+HC2I@u17};H(5zS-r|GUIHR8?iT>rmfx62)m|ElXeH!YjgtwUjQ zND@Ilz#mSkW;$%Z(f=d)%dy?y*N8Ic)Vas*!fvS0dQIJzF2XQDi!$%Vmb&b`hKW&m zb*V@4!~j{Apm=Wc`MkQj7#$eH@Y@ubH`I9KNGDtTW~x)mekzOP!5L@cNM02r7vud~ z-X)L6>ji49ULvGBpBq78dLWAjM5l3DgM$Q|xVidquXdC55@UbUgRg>1R*fh++EI_` zzNLYYC1QK}7lAGTY@jhV^{SOcAJ22oec2q3wdfT`oiGNXl7=Bm;w+8+ZT3J_n1SUg z0~dijAGjC+IJ?>-C6Z0CmRey_&p&8&r@LTW!a-{R-;m&iMptuD{BcJ7A>magn58J5 z3fX@w!>SNBaZ&&}BS9pnwB#!a1G?HB(V;*1QnPzgp;uw8rzfaakE?B6qG@f^1?31I zm;cgVfaVjz^kvCSmw1<~=@1ZR4+|KSn%?=PgedL9too{gZSGQG9H9%Vbj@d5IKMg{ z|M`guNtdPKxfKHQ+^l|Z}aB1|_n zI_H$fu^3)N>oBanrT>;S@5Mhra0mf+)$U!CNmsSeV!O?Xx0gx!2k!ujKwn*3%~oMi zPCs`4okYnzfCHaDaVW zoH!m}>R=kv*6iNuO!V)OFOHB$q;@g9jn!U0w`$a&O>EDovraSA&HA0^#0H=nnHdF>@00T41hw~qj4B^-XkC4VM)knHC zR)wy4kI>@v@0_m4lzfxd5sF$Uh|}s%RjX(C0|d}hr87i{-n$nSm5WP)Bj(cYQJgC4 zNTw+>p0!cS<=3cjrm*@WTQO|Ve13=A%AHbmq}RS*3{mlA6Ss$}d5WA#-q9p&@`I zcBSBaQ~#DToJaSGhl(Ls&{_B=T?!THA6ku{)GFLU1O9ltN}o(QJ?h_B#WvVg`81d` z2#VneHg0#O=b265S4#$x6|;$C0e=MbDbR)_l6RFM&HM7Q+piE61xNCM3%R#uskK_pe0fv^pRHDhz{1B zm+0g|m}aneFly42kH)t>N;U)V%_alz2EbGWW@SLt&7=)3AN~PA(2=9)OmqZL{%rnu zS6myeLq2N7B764^)5o4AC8c>?9OVx=w$l9j%9IDM(*2^zu7RqiZlubz1gp_2L953| zull{5&8{`{2|)%Lfw#Y0KYBsX9bliG%O_QjW?e4cmI026h?l~OA9Soetc5*fyVfG~ zZ}j0Hr6|aXC+|E6-1uP{ZYZ0tps0XM-TJn`cSQB|`MR$Iv~+oZnDcigtd4fpgYNu0 zcCDv}dDt06ZXzP#K=}4<)P4Y||2>GwKa74B#O!#;#=r3Loy@BU!kClA5?NBFXUlX* z8g?!GQoQuM+28TRHlAjkR*9mFUA`Z^Qb2^+m-lzp+^N`j#tYLX2c+|?PXPPmwis*9 zY}dUJ3>t4<=hAuYOPOV z{Xm~ZQD!XLuJiEO3w>n0rnyb0`>yf2-DyG8ES+3unl+aTEu=P3H9MypA8%jVK(WM^ zd>Kr-uiZ8@P1`~N1!-wKFkp+aq&W_h72UloZfN)G@|f~v)?x!Y$Np7vB-x8>P{)6r z>zw;%xiXt)@ZgX=+cdHF^ck@t2?1e9Id_5;90aGQcZAt5d|Z5Ne+l{?))Rybb*^2d zvp+jo;mrI!-=gP8;%%Ps%5mUx>P{0z+97)wpbxZ%7Dw#6)^G_sA$T%INzIK(#t8jm z(MdNnE2+~(D%Q9FuEN+{EVvGC%rT$arUta+x;CqWgv0p;Yw*nQL%?3?yflMb)wtw6mw>DY{x&H& z?3Fea5h2;eMX>N`ve%v=i{C)Q5{eS|ieC?ku$_F40$Vpm;XX7li2SQfc0D$a}$JV&6${v3;-_{eYnq^A#GmlOI)zLv%t?BJAXAIO|A7#bLjVT<71W-+jA((Pi>!W75!$93t~@51ShNGwMiX$l^%0kQE0 z&|=opy>Z9Ck58$-mv@S4F}aL}9p&2-HrRv84Q zH-Eq+JvKv)jlPde_jKvpBJS`Pc^7bXdmo96AvvOw{jy_JdYznzKCR%D#@q$WF_i=7N=f=u=6sJISewGbu;(1+QBly-dg&%i?hGONdZCr6(C&|O6&`whQfIgOy z4}u~B=8R0>Z z^S)5^Nwp~zN2!)S)L^(Yb{n;hco`#eOtlD89+RG(QCh5X;W2Y-;D6N!l~ax%5`39k zjc!&sjX}YQO9`sZ3q;cFuP&uFFD zPKijaUbyBWr!L%*%d;&dm*KK<+f7jevx^XTI578;lF>)8g~;9c%m?aZi!j6_5=Zka2t`w6O|AB<|r z09j>#`;Qr3t|hG@35k{qYedzuG@Jw1Ih0k|W|NHu2ykJQBi<11DinY)u%I;1Nt5`H z&vxCFXSMLN&j+de`5yp6Di+3I7N|m=SV?iU8`H4zE%$@>L(>NHfrf7|vOT%?_$^xG zQrlEvNT0^CG^{^hIzPRnfHd#R(dW4L%6dR9G_C=}vgu1Uqv}(Kf@5kzEatWcrv%9} zFpD3zb*ptr^H%L^cgYc4@8VgILZ8egA)>=k%8(i$3ek8DYG0@E5@0BF+0}0Bcry4M z7X50g+@WL6-i<5J1aQmg{tm*-D3v|&4yK-y47h0(33Cp>{@)ojT~_A(n|9@)pq%qJ ztEwZ`$gFO?ej*ZHMg4%2m6qMJ7iI1y3*0$ZfgS5_9Ic!mT3l)nruUfY@4x$|{0H)` zIC!+PkUK-kcnQ--=u^WbxICflQY7=DbE?Ylohf(Ne=c{P{{=|zy7VbtSYI@)R=G0% z$^O>fsy2~N1Fpz*6!~GNUF=K*l!vvsw+n1IQ6+PHo}ekjP#F3W2bS`OpUMn!ZkIKG zNg+4)TIqX!Uzij&LA0Y`=X9Ar1v8I5(TZQlLzm^Ixm9MFA!K0z6 ziPp!s2XL-G^=4#>Xux}}j$b9ZQTA(=66uX$V9I)Zn^HNI0W3NM-$Linpq=*!O7f4Ax!Y=Ys_!4@u z5+T)*0)2>|#%+wn8&w`3HE6Qzapk`_uylhJyE5*res;Gjt{wOXNLxKCRq{=8{)0mg z_)_@u8w<^=w6+ga&u}`N(k@!+;EZ*5n4Nz*H zk<*)DCQFi^j4eCr_pILpTKUYn^fo!H##zl!;Se_Indp<1{JBOCpnY$cJvyK?=g)3h z$GhEp>uDc`l&0sGu;Z$z{6?8FPYBf2XQ$;T|0yNEFr#Q6o|un}uDbd>G;J*XeF#;B$~)le?o>y<{l8fq`>X8r%>?7*Tyj-!{$O#O$BSx zCVPm_^;_G6-`m{robIFv8Ngea!0b2I5}ZXtnu5D_Omdakmi5PwJ2r&D|FIYOx!T4e zpHl%s(Ph=??vm{&Fv4Gi1ROAMHNNlJ{*AOE+bnE!pW{dwXK5BA83c#Rvm%;`%shUt zTqxY&D;~@-(T4uCT#TB~T1&-$HwosC2cQAcJNU@R#{w$GjX}VCYj-$cJ*vlk-C)DT z6mx|4cTYNaD?-kS<-3;?8gKSq!FIf-X0wM9v_{|Y>?$T6z>a1I&0)dL<)HeM>7=0$REuF@Nw>Un2|`<5B| z5jZ~K0Z3)@E1R4B@i#PXGIoO9H*ps&Jz&gm_}0ON&?>JZhgdmeRC1>`AK>d7;40^K z^I`<$=ZCbb|CqVj`xi=&58&)u#keQ-edaE?EUdw?2~X%yNhen)^iFm`J8S7tqmQ?S z>X^v}P?*3TnlJ-QhZ{Bip{X4d(_FW0oM~Pk0^HWu;;3!{5FlQQ4X#@hQ*=~##PRgv z=WsOZ2?Yyvdu%wf<-U74lkN#APyIAo;;`y`+WZTqctu4qG3}hBrIfl7fx2Wfj?7kO z(=FI9ZzL~a#@_){JC&jyJE=rbk*-B~Ok_td9g;VIe-+~D%C}C|+kp3*U*8mqPee)> z*@-YG3iI2G`VTK$F${bg9aoBJa4lp#9rm?Gj$i0KvPe=cBh@ZJ%0TLn^O> zl$}yc9=%E9p#<0ect&y4nUhG2o7;|+6|8)gtc*XXtA13{1HIIu6^SD36^S6_5(liS z04U2eNXOax5%XF2&_vR)F$|^@2XLy9JvOVl2*ECucb_{Up43~Hsg)#tyMqnX_W+VN zNM^(_%ql|RP?$hNqxa$ZQFb>ErYisl8Wqz7&7usR7q|ApMK=SdYRl+~x6fe!5ZZ|V z^IkarRfHpkEGo)Gt`vt*iijd2PA~{bNXqB)^S56b8H-{-hck6tDY7RLO|6o`hslJ8 zX6BC308;so-1nQNYw-`2%zuWRp-M-IS$z?M)jCxBG}KN`3e`xDW zo%2TtQ8ZkEa9+jZ-Aq^{yVe>Qa*q4)|HQ4oT~tWRi;?Ezf)-O1{D_6y@T&ZOWbG)fLtva@u!OEIi{-1CP|q3iEO`j+eDg|IVCTSJ>g;ki&j)z) zAj>)CdR{GMkWr2?Z?}W#F-g%DuO}N>#Q_~aw%u@%yT`TI-228cUD`=3 zkQ0hO7>-MtZ=)|16lfnn))XN=6(T$Rm) zq4=ouZ&P{1;{>Dr;iuH98B$Zfn59_G4;CI#x(|j5uM&I00&yhnvF!ezJ|UJIe#@f# zDo-_q5eJIAh6XClkB_r^SecY!v&I7lmGlKwo_CVrGX(v{k&qENz#b<>)or>nW$!813RfF6Y%-hafW7qOVEGOR0eS1Vl zdkbouP7U~DDj2849Q>HCNw=u0%wn-#kKmJ|o8Hd6jH*TC(+39V+oZ)cS?{+}w1edM z7Q7zzRHQ888{tbc7AeosCPVg zBXvE8Q$EF;P#$4qdLJ2B;+=GJN|B};Y28X7&aB`;Mt1lu&0_ut1)&t9-5C3Cu?OTG~ye~R|eD#J^DoL5n^- zK19`hRCRlAgF8qF+SXI$W(7B*(SQIPzH@mK{JgGur#-|g$nsG4jRTHIxQ-_qqRnz}IjYIAH;dkzwF(q!wB3+>7z z40*ucx(?Z!T#dz1%R7M)$?$ds;E022cTt-*hE;%5G+6%1Saz}GT&=deWi9rwAiVE) z8^!86Cg&1-b<2_*$@y{E9*xBO*_)d4X#MnB;w>lY;^#lWAnG6Bsk%zVuAlagyrXGv zshyfiPQ*u#vyDvVlQVS8#|yDB_)-P=!+CEOGjW6o;qAqu}pJRi{u((lr8 zVg5@S@X~&j=}iglP8}srRXkk<$&NAbm1*#=9tk@d>AiQ_qW%%D1goqbP0V}mt(*Zg zOr7AAKj|ak|E{Pxw&%ig$*5Cjs|SSm*A<^&Dt6r&JavVZg}_LjbN_dA0Wi%{;)drr z##KM*cJ-ZSZ}!Lr;=)sL)5MTPbN24{AB%grTX0_J!2{)NUB6Ok{^;0yS@i5@!MKBv zpP#ppXZkg}U*c&^E-~Bn{T0=?CZAmQ3indSf>ptuI~AD1cWKHSs{Yp(VefubSlj&J zY~e@ox)hP9d`6Jv2LiUC@sYn;t(wa0Y>L9F&KtydRPO!Due%jhUatf12FCs>JeU8t zhpDZive5mxFrP?nq~}?>v|@!99+jeqX0hFAHinN29|*=#%ZHow2G(_5MewXNra5 z&$yG7ouKtS8)BpVKF$w-I5mS6y=+uL(<-TXkeaq z9r~&jR{7KXh?7sRkyVD!-hLZO-DTbr{3^R-mDZs9V6P>>5|awI3}!&8!}-nlIxLB_ys5|$Oo9NO?LmuG3pB!1)M@*iM) zkDR6CQ~CE~SP8|`;9cM$Qv2yv!dM;`p`w@wFrak3@!*5BPzF7mIMl$y?p@sPxXWGh zkKTJyO?zw5453LAiL)^dHFMs4IYR(dEP$YSzV7;&YYAB%-}`QSBFLcM{icaz$$ud| zLX2jHa&JVqY#dlmlZlgAy)T|RRlN1O=0WcEJ`HZNZb}y)e6nDh@pkR~FiBxAEswI-=F7o*)0EYu z5P=5WWo){LldIXVUaHV+nz5TnA_wz^_otCo?nEGX+2Uj>k0 zW~s`cAAeJP(Iji#RLFy@T<#Gp3Kpu>;WiCic1+7HT&>}&)n>j0K(GPxzjAqWXskbQ zh>UP*%#XTSxfmTl>Dd6NjN625;;PmL&2Dx-fBsc2XI8d56#C+=dWFbd(as90PGGG= zvFZ8X(zm6w3$ZY>n+*B4!^D503X2~G>bNOz2IHlX;c?{;5b$D87K@&8m-&645N@Fh(h``B$JNcKS&=1bsNl3j z^OKCPEh}x*n%I07{)m}U_>CTZbn}B^uXbFa5h%k64dJgfjb5Q4Ov?fuW{2Zk(?mHC zK@r*-PjzzXwYP~-Uo?Y!cH$$$Mu~zB)?dqd)t$@V^=T%*K|Xs91#U&TfC{q!>!&aC z0Ew2Ho|HJ>No^=^qRfNwsm9o{HFN$@xEX$#*=0g8tww~1>B8Y&U^|_Y7MGc^Sv5>) zX)m7g08g$Y9E{FE)3WEj{QVz7K2~;m!P|hW;D@>P@n=FKeg-qcry?(wHcoLY&0=An zLZfCysbPN!-=bn)`)vJ0?sXY!@W{5zYM2`kHERhwT;0QCfxl7*n6jorx6j3$_XA&fatk6ud;<>V)M(Rrh!{{2fMFY}E)(y! z*#ZNK(SfnD9UhSihcE1M^cT)$E^IOhH&fYj95gH^!(ibKEaY^4UU=guvm2Wl-?Kc| z?2>|7fUof9V`=a$6|u2lGbEeGA5Kau)gQ~rbQoxbE z3v9^oR^u@XKxp%W6W8xH3Bcb{=eY`yIIz z`^-rF1H1-ds%2TLF{Q?dGA@S#-DHP{WQ0@kdUd4vOcXsl&~ z&?g=>ST7ft>pD+NL(0^)-We>0QH{KDfBx$`Q)hfHvN&LQ?}@?XkM1aSEoWU!`Qu2R zPv*0$35X^&^Yjn}ypmUK=TY&f>`Pq4fgd5z~{r9LeZv;}-SwF2N zDT@l0&#%{Hb#uavwmP2ILGmuoaT>1xh-n?oKs)2ryuaL9Le8kh=gNHVf7roFq*nZ zR02HP&XGb{xv9YOh!Z9hX_)q1_vh|w^ z$+#Dhh{~{zY02MT&zqRr_Wx9IV?`)Z^+83pTZswdf)R=l(f#>N5|8Broj>xZQfT6x z`X~L)&I}_cc7k=Hn8b1_GMis2Z&D_x7*A!y^vs6hRd~0Pc5q;$F6JCm!w}iZAX2>ZbRk*>L}e zMM|}!w7^Mni7GT}t8A1D_~OM+Kzv*0cRKmKA5is`MN>}hQW9S$H54Z*<6r*;P<6bT z>VGlJVUV|H(tanWJl`Q5!Zqh{9iPkc{89&qky*~ti;^)v@PloFQS8CUQ0*;} zS*m8&z~GrobBNn=leiDWesTNS^*Dk*3VwFnYmvF6X)#fLeK+1YA(gb_<7Sb5Q9`cX zQ@gUTH0~SDaXD1L`y>ZNrZ0aS+2wvMU?Bg{yxO&-jP|i{VC^Gfr61(zeCbj7i^%!7 zSJy-x)}a?}C;0q2s!!oUVkKZ%je4uGmr)i8mx2NL@*!#Gd+Unu<~nUM4MGkEtt{Ly zMy|b1>WbPxvjRfE8#8ZyTux}`wJGK*ooaY z)pWjoE;|JAVf&-SbVwLYS+SluD*8pfO1+E>xhLy&RxC8|DU*U&7b}&{|1MphiZIkM zQ1gIE!9kwiSg*};Ys)mD!^S7P!1E)0bFbe)Yoq^H2NW{L17@JOpjvvI70$U^)KwMy zA*kkrV9~m1KQwN`Eb$y_EErqIk=F(il-~GUDyIy9`|Q4{SL;0RF!|a69VTsF7_p2) z@c~levO(wwzrT?xkxQYhU3;W%Re}G{T`H9lfl}{j+Z(S*T+FGkxvEq@xIR^9{$vUB$%v^anA; z(1#?PWtbylBLnji*F;64w;ZpZJPvXlzi@a<9tyOqHX!?CK(W0&xIBC(6bh+&VfSj+Z^gsu)?S zbI;+~UwEF(%)0moeSW$rHcK}B-xA6GD;Ema(JkSdV=EGJAQoR%&$_>?Y|_SjsiY46 zHN|b@Raf?yQAs0|iZl?9@(fd(GtRZRI6V7F;4xo)Q`GN)z1X6*@?9yX^y!F$vA8=+ zkWT59=|8}^-}kaRy*OR3CxUbAS^f`cB;sSzyvt)(c~6!-LOhqwQ{TIP*xT*!nV1(Y zJwG$xZ_SL<;*omzl(JqlmklGcYu4nX9YXFrn=fZpXC^BC2uZYh<2qC5+!qIwP6_ zum4*-b3fgy`3wDJN!ECtf?x>8^4qk=U>of=peKXDb=bn`4Q}&oeBRb<;JSIGSfdSFtV0H|{p8Kd{V39lx4t%EyJbPPo*enYJhH(!>uc{` zj8@f_HW5vuCGYAZpdppUci5|BY?N8J)F<*!1Fd{dm`)(wUa`o!#=XSvmBDsmh5VfP zgbM2#>X(_jkb2X2{6pn$vL;XJLOggpS32a3v`d?bQ`IJK>I^m2cNDuXC?x*@-g>U> zwI3{)E^dEBj=gav$dzpK3J=<*ip@2Gnwk}qVv*TSUX<_f&=;RW70F&pr- zJ-;NXqQif#R43>osL3K``p4;R&|Y!4Iuf^PC*2bWlzO#4+0H*m6Y3R`?~@`J4AIf=)iQP0x*mO96ka}Ldr+~&P0wSy z?T$C_z4)Ot=q8xzK_vk8z9fw(p#VCHa-c%6o#m<*VU(?W9@2N3d zi0N5C>Xw`3+ki~N;^T#iPRqEV*SyL901Q?i%ol5SFW!GTmDRIR;36kX5Za?dyRfxp zi;LZ(HU9xJ)vXsj&1lz_LMkf;M0502L~p!}CorWs?Xi)5yR7EdnRAy!89~<8rrWt; z?vo^K65Inuyu}*C9W9nv>cv^@4jE%gjq71+1;%T;Y~I2zA1UICe;n(||6Qw$)ztZ^ zH}N6-@)Lt1r1tys+kb$B<~$rx@MNQ?_?KxlPo~i_r)lv|$kGAHdZEa63N1lG&dK}- zzgneN^NZIy2*k%XtMu19>85F=aNtW2)D2MbiUqP)q2E`)wbb7%^UP+x=`iUoF6UsZND zMMHOB?R9gpY5B#{_Lxx@0bJ|H=uG%V_-@TzZRcFUiplebA}yao>odoJ8?jj2H65%W zWNWEIUbAjxiI*@=`{zR7avYG1;MqSw8*9ykQ&xaubDbW7DMZbi>S-Z{rsXgH)WE~I zvl&gRj{!M#X1O(7?OZF8e8P#6BnS=O*GBfb#Q|C2S+Tgee(!Cg$7$mWvrQXGQ0Hq= zY^~G%f5Zjr$E&w)HD_vA#MZQw_*wt0ZQOCroLxtgfWeC;MsG2(T*nN-gfClGYA#j= ztJsiswhCl%RaBmIj8NmAPJdj4a>iSO_gh~z7v*dFavxzg?< zy6n1g*ec(%UTeJgHR{!oznbws!0D%r3mpz0)MX4(y8Znhb$r&X7n8fYMQS+`Hll2EnP;?|Q*{}g34~`~Ii*MOR-M6aoG3dg z18p(ZHBemgePgq@Ts2&uxE?NFA*u8!g_k3g!^goMW>H-}C6-ePg2B z&G5niA!8WJdv#apfA^tl{8s3^T~)sW1r~~t&2YdfRU+Aoof`VnZh1e2=Ipia{pt$4WN*!nw4v7)aO5qSM^_sq_3-52tTEv)aEKFq(qD}l`oI0R}5p+hEO+;-$X zNRID#TKg24I}W%Ds?Lw~fVM30rEzG}i=gYyS2c~1f}8&XJ3++0gjYv}UMEJMWYRu7 zpvO4KCkL)0{9x0@tLl65+`DSa*H|G&u_1D(Awm=q4;dum?oZ#N6LNGZr4!?SPhvq564kveGg;+H zph=XN$v+YSkZ^I4j~#RwLW#XrLyFO$KVeio|a9fji7+p$pmA7ILANd{#|w5 zThj|-#PiY9rGmODu|VxFXkk|+@Hj2^1N8y+=|#Uryhvh@$hv~rYVSp>I>?|X_mW04 zxRu%Zfn4}KOtCSkqnF*%6)Qm^T!vP#j$Syo@2*3Y0rw~wAO;&t3=y0hfgSLd^%?F> zO0_ubNL`?z2#y%I;6{Xy7bC`gPgkk^IKUrg&p_Gq^nn>@y{U+z7br5|&CcCEESZ7tUGm7)i zPRt-ED4FetuPX){+%mtwIO?+Ao|Hl)TIFKh+g8ULfX?6YBdlCmYDHqrd%A7-tV2?5 zGQ>*^u?^3;35`gQ7v~L~lFiha!3NG!I_sORRCA1OLJ1NmMzR?nd3;eumJ5qBSF9e z0aZtjkMGm>)8jKRGJu12B-ltkaB=68kMrnhwD=cKNyM`YTiQO?WOl@4XMX+J-JQd3 z-xxc-I)*VL*RiF~OH-drt6~cX(^iVoiDI5G&lXt~f#H?7B~DZxMlza60>`%`?I2|N zJbCH#wSvYFK?R8XvT_e&)T1g_&Ko(-H zFk`ruP(oukz}n0R9!UiF9bI%kNi=n?6AnW{oDaWnANuuh^q-^z>LhqnoP^FmIXv<_ z_#S+C>#gX&!>G=kB;B0I+f^e8#?V15#Qy-01OA<9LbK!@%Mq?jGBg3IsYCnNq)P6^|pbiYioy;PXL{Kdx~p1QMoP`2E}J%ecWh50^l z=g*VVT?f&MY}U7GPp7Ng+N_}WCtydmA@X_TpJ@5X;Oe1D%=yl3OVB#S`dXd6J4m%+ zzMlR2lE#@xBLMQ}!0>qU!TWVKo#}{3!HLV@Z7YBQ&pH0zw_R)g&P{$9Y6%}s(c+n! zWQeg=Z2NLE{dtZ!-Q&--M@;W&aB9~Q)lW{*(xHkW3~UPskh9fbVm0hDkeT0q8<0At<<|Nl^Y$G~;L^}>l5bIM zFGt>*?yW44OI0;EXMvHJ#scj$lRgr^JsfhRU2v-fl?;#!uhK{>Q4%sRox-&(YKlmJ?$Z9^P)6dp;{WaRYwH-@n)@~$l9^FaQ{{UD4{{ZQe?@}@XwlnQLbUTtpne8oDyyIj_gnx3U z{=E}7to>1@=(M!Bo9ZK)vq<5#F<4lYjxbaMf{UE_!w$Qn89^>heNI;;Ci#vUeG@#W zCwSHv4BcjAd51N>2P%E$hHBg&}# zU3RI(f3eEq-o;8iE?QfStWfTN!j7JwPb{F046+Q!iI4c0vG@b^b-taZ!#=&D#Wuv* zsMQd`66}g0-a>Y#$>SxCSp1XIi=LldDLdMP@!2vG+t%tu1D}#-IWPNwGxzAvO4ik; z*L2Br_R}iUOZCjnR@_Lef<+`WrHeTr9yc8L1FLd^i;^WNT1>6k^z12i#f#Baqa)dx zMSBm4h%zw*Mu5rl=Ky|svHE6zq?I*EA-Ap5sLTXfh*Jd41~w`=VgSe`+0|DAAez9@XRD^!OQ}ZXf~e8Fb}UAb z%@YhfY!wbe56=e&$Q@5{bXpT2uMKCXVj*Ir)^12k#7P{5WgC@)D-ZaT^)Q5S{HbZv zzW&8ZPJc6GdRCz>m2$PoE7JOSWF6#65GiO+wn31&9qNzs9vZ@7Zl<5 zsLmT3ent=X=vA>t>3*=qqt>c&7I&`BBtK}w7HJRt&_~>ko$LOwt)gmDY4r>ON`fdF zcd7%kM-WquyK%@olEi!wj-p!6NcW)Q{<^R#^)Sm6$I>UiAs*p#!{^GKRZ~A_E zZKV3j-=*F|q|c+1AjFbQSGyx%ae)9;QO}L-`}Iw;>N-~@X^*Dt-kr``NTi#4vHO;1 z&r!*!U6cbKqWw=AlGtx!ugCmopY`aLH6>G8dw(Gr^6MYmf350ubvbSNi7SgnNd%VT zT2MgM$-oRq48}5e5BK4@Ae9q(g5s{qx^-AaLCaaPyBV2*^gnx(*&y+5n^HDPigv0Uo?!B)uyyK$Zjit4P$4jDqS zu{%RG!DEh%>EC_p5^{RcW3lSZW?xC#rzLu6Uhb;3+B(7D1S|#I?owaNN1t~%=gG}> zjS5)C~ zEz<{vy2i0?cio+jhQ;O+KRwOz1%KRw{kp5cKk+t%j%ez7l`ze@>%k3JA(P_|8h{(g z9OU!os7Ir9{{T|nj7O#F^|f0rB8oX~H1zC9P5@SCGC)Z`JJa%`t5U}mPG0-|Nqo)P zkL+}fHXl#UmNd(LqSJKKc~w9g-ZZce^kfRV`$Q5{`^uGe9C3~H4I)oS52^J7OQ*#l zWQJnH>vaqq9?FB7@t^G>2Mo*Os!p@~AN60PboJD~h{+X7v$%?_NOeVXG`mY4N;A^m#0gv(vDY|EX!uuoe6?yqi7>>8t;!GVF}Eb=d9C& z3??@r#|N_^2@G->zWL!iRrR?~HDGt^e$^v01DYWHD7U8Z=JDb-6f2t%+UY-EL8 zka^_wT#Hey>3eQj{!8t9XHEO(RP+CrXjKN7IIVFkD zN?X%f9V_$E(Y-rybp1{!#f=A1of_4Rx!XNi!0pQ-x-`H>-2hb zP?^MaDCw|HWf3B-1ZY_28QjF5lEnO;n4MomgHK;g&8x!5V-QKJB!Pe-w+ie2DJm)R zj!E|@+5#H){g{hPqcv*lQoOfARlBM<+`CWerBEhXWAQ6S2x2y5ASItuq3K^tnNv*B ztZ1K6U$JBPj8!!YlP(SdR&>M)e4Wgv$2b@{OC~mwSLNQnznO82uHV0Z^T>Ij>FcId z)ipTv%GLF#sF)U+k8EA3rHvz*Y?IoNSQgqo=k5+As_^R5{{SnoS_&Gih7M@j%2vGR zfar6Wd|6%K(vq#CTBL1}UIH!7`*HDm-ZXuEQSRPGJNFuamZOLe@S zkC#nU(Po=Wnkj;{dbcXr6|8RqYs4Nr0NEI1WjyoG9b(*De9vB*bnmC!(KeE$r>}kV zE^>NmkEf!T>sr9mwF|MdG10J3)K`ZkWgXO0AHM+vgZw3iHxqyknK6Z+(_V2|_;~cX zt0!=O&nJ7h{{XST{{WPA>wbyT{Zp?004LH#VW?6;r_z(^QbnC%Q@Lb2xAMY949Zv& z%P`YK z20&b}Y;MT;=|oy@scS+g>Fa+^slaGrv|PwP_KzbH{C|f5f92|FJvr(%)EeCnPfIk5 zBkYn09UldV#$jLxBgiU2`5g{%=2E}7E9I&P^p>e-NY(^8MM&zlp$&*hGrXajvh1g8 zdvm#0oM+=bFNf5+gvk`fj-Dei{{XvBsE9Us$?eJpdHZz7K=gI_y-PyuIwz>KyEU#P zuTfmRW{<-Z5`fFWB%vpd)8lVdm-HX1=&V#E^(|^LB4DniVPKXtRow2$?#|T(h|X{i zRHcSeZM}5;{Y2JC#c8Mf8%1I*Qg@C`HW&nH-JW(SJWxmAyZ2O)=Ky4qP6kQo{{a60 z%!_g8G5TtZnoDW1!`Q|BDWQ26BCKc?+YA} z*_zb2{{Ve9HZI~a6$5QSz{%Xk0YlWN1|imU0r!JXf;B(gUPJz!Hw-hbXYKz0P)1o7 z`l7@1*Y9(pSktVx{{Z6{shNLdV4y$u3g3g$i#Kh-A%g62R+Ju6eKr`|{E7~eUc0MR z%UbkPU~#)pn$JJkBaC!KFXCsY>cEtnO3@~%9(LAwrITR$A(fwR?Si@T4_c+C%TMY3 zktY2&joIteTwpp#d9M_TU)VjO<5m+D@XWdi7U!s3^zW;nZo+Y=8U9 zw+;QrT57t*-AY|P_MM^Wwx0f*R&h>v;z`#EVr7hlRgeaWy{JPE0eVM-Ag{-sX2_0~pUl5^>pmf!cfiOJ}ETM4GHNhMA^QY6nKFz#>|g^Q(%BelZOwB*qrcOJ zh3KS$Rg+M7rYsGRKizI*ZNe;-`)@9O$Ej*+8Us4X9;bG+s(r4}DP{iv-d0oA62_$Y z>(JISlGp6T)6C9Dx0Sa!{ZB;rn#vT5?p;^mLvVtt3)i*iW>By+|rY z@8on%X3@3NwtZH+YBDwjj2N21KN2a*7yRUI@J@Lxmq^qh(JDnk-D#o|S}utqYl%M|qrLe8f<}y$E5z&jHSgj7rceK{3 zrvVMMS)wHQRphBZ@bVAO->l^*mlVL|fLWA^^CaYF*^QEa@Si`}o`;b{;xYt8_}%vT{==q|=~U}PE?BTE*OZh-5-H08lAW|9?jM&?$n&1PSJt|ggyZ>i zQNc}FJE-fu*$0vd{Ui+FbN%|ATKN@^ME+(e)Y6rGO0d;pN7D5F0O<;IF(&i2?n z%3XZP~Gg+R#z3J$+nqubYtj6&qvBfGXgy`AaL2M0YQ=?i)V3n)1k-;3&I<#^X-IDQTM(mHj zRKHq(4mI`k{(=5VusD6j_98F5Em$d`Bw(0EPa?^tY8h zKv6fP>B>P7qhW(>k#enr;E%EJdh7TKOGBUHwDmYeFX2z9b^4mFqoI0!<;prNCdKP0 zfUQ_aavDq?G9zw4KcxJ1T$9pKt!bidJswF+WhN}aq5zV>0Cu+EKsg5(;~e$%maU?$ zwW&$!Z%9$8>8(yG9Gsm$= z*sYvwZNQL0$yMZFg1b@ly;)_BN))A!FvhY6aUp4fj^il+VOg?5^S3z3>*%XKfo-e} zQV3>J8AvLAK?jgW+n{9hh4`)|=%t!D<7Fu-9gd|y0D`!|0DN_vxN}J6K6w8Cu=lM& zEt+)NZo;$5v4YHq2IC_r9@xhKx#K)}>2=>q!jiD8UE%>qX;346k-H!gI5`8JKnINA zeF}XQED_j>Hl8(}KHCV%3o7nYwZ?g0ZgI~be*FP2qt>_5&r++$X1f-5lWd6W8z@2* zzyNST+zI~xF1e+GjiZ$_=gS_GpxR8$B(@FTs94sxtPC$)#@pPpG`w>6l7(y{fAgf6*@JJO%IwskVPDd)}VKUFy4sU z8Pp7r8wYN98NtWfr5AK30=x}{I02cnfLV@7#!djneE2{d}20F#!G+7QI zs^|+=^_r1euWmZ>$r9PGxWzK75!_A6t+la{l?Mc51II}1X{TohKnwsMj2^o!k4@?E z*1ET$xMnbavKR^k6ZaSW?%|Uj&gbdFZrkt=RV(@%M;reDOdPfjN8tYeuUX0rwKRUQ z`a+a%Fqz_xJ?*%xXcb57qrmIvA5TZ6ri!K7xp_tvH-N(j9R0fD-k7Aw6!!2xZn`d; zeW+}nDT2I2GMoYd{`_^c@HerXa-?Hg(L2(+ttoTnimY;W(NSJzV%yoc0B#|8 z3`hsybJa#J3u`5{CRCf#dTleh{aM;Tc&f#!OeG*@klCOa%5C>~zN z=^6H-C>Z^ea5*Q8^=YYUoy|m9*KJk(25;BC-<$@S@c4FJLQzw#3V=Qr!-#@Se zuT|0QSaO0|kR)StlFelTp!=K>f3`AuHd<99W_#K|ffV4hlD6hPcBsJIf6#pN4ZTlK ziB>PCp$uqASlGLePs#Uke>ndD>DH;YqVMiz(ps~^Wf7Pl+^~`hmOkl7@LTLY%klX< z^lcd$NepqwiU8c~$J-i@EPwOK!09?`P{}e^r&g?zvB=v^Z~z>$7T_oxl6sp{^$w+0 zC(#C&@Isp=~S{p@m{CH&{eZ?g_ZRr&ROMW7gHW88Sclg3ZypySrHYKdiGx`*nO zQQ7N8xJYX+K3?X`wabm*~(IjGUD}+ zq{&M~u3?j0&}q}C+eN40am!7WMTJ6S28#5LXXc^&s0z8 zsq{@2_oTEvGfki)bgt6t5mwZjF5*rcHWWIXw(OEe#~o7t0Fzgd-JsF#NhF7M=ymFH zvlI8q<&Rop;vm)4dbQu=iQoXHld;eL0O(9d{{Y5craqn4 z?(1Hp)9L!hOslEZlX|JF&rVcijh%hbox6RQASgV8o;lUMIb^Z_0Mve{3!Vx?1lb=M z*^Zq0H_~_Y9db9LM_zZS4Toi)N)d%GUQ}Gaa~!h_4=1IQh=(hCI^VCS;NK^>&1ahp3Iq`$@(yq*7-EO76ej8h`Gya`)>VLz% z6HfGE*!7pJW75uE#L1XGrVQ)7j)9Q6sEnW9X66# zdyzpfnkJG(0zr|NX21jBarWrjH8q=(z1R|H`=rQPI3tXEj(=HE{{UXCdNW;k#C5EX z=8z@?u_9x(1`KLI!#a-*;~4`u2dQ-}6k8urco91cnT}alU4Y> zS{&ZypQtz@->BI~f~#g(&-o{}{d!4nM$*EGCyxEnbIa_7Px#YEEs*9<6a*fTFWFA$RILF7Y!x>1nlL{sQM9$K1SA8*4m*2@&->y=2+9G&8iRZhgjd%lyE{{nfP4b8l4F#w8@O2sBn9i)^lp#olWR-X z^()%Gg{g*uSgJzlLQ85r%KgPz8Ct0-!`iYwa7Y9!g2L$*(rq4$6{#zeVwN{O_(&@x zRwN@X84E7Z0xohFBRx;2`d{hndWS%xYAY3N=;^4^wLTS1c&tStq{{RqR zGI%w&T|2UAH@2ebwS7W)cg^b0T3WYd)c|IWXO+(ZcC@Tmp8#O=cClAX)2q-kdWJ1y zQ=fO%>EFqzG_)8D?UG=jSo4AvxH%m2)cS6zqv(;|t6M@En7v)ANvpH87NQN1&rvc2 zW5xrW&yR6Xc7?F|Zv1T=dR2I?Rh3U_>|?hAs*iVjcl&~)mR9lcxDZYA+t)?y+7}@` z4PK-QG^l+gYRX$}t4282w>*c(^hAYo`Bemc$6bfh`q%I(4Jz-}+STQsPKj)44Pr@b zH9gpm2{PnJ13zRkGm;oCO7+I%m1sjX9VO-w%Na|Wlg3f(ra6u!JjDm!{7?QY4`4ID zXVUek(pqAE>MiYVuv~ZHl?umD{kGS3e0)hTK2UXzSbSZrdzxea0MByE>K$X!l<#-_ zF;7#mLgYa!>T=KhS-=^1cW+jVAvo;~m;e&EAe7o{x*^mn)t(WfR+c~{xcXIj)-3sE z$#*~b_~|rSez)n}M&^?lhf$=(OC-REwF<;;f?TgDA&r%l#u-T?k&s+NrfTf5+0deU z@JS$z5R6%ckBFvG?av1i3?l)bY080IRUz`JYC4{2Xx;jF{X?wHPEy9Dx^Tf17NZ~H zP^C!5a8&XS2dDm*)M?tg5%mtKu3U#niS-K7SwxlV7?d^?nF-o(pr_m>G3TWEMxr#z z_cU{)Y1-S{+V&)8k~k`r2OX9lu1|v?z~BYkGD}LetJcu;^a~_S>1O_a#@1Q4>`!VOGd|E%uwXYI zjPz*!XQ@8zPfCMTjI%!O`MBuE$wp^wzxQ_SI2jxQA&Y*Rk?D~W9K#b{Qh}A`VZ=-i z1V)Dhf5gxB>5V-;m6lTsX$-7!+IIFa{{Y#!k`+@tl11c+%?J1jQVZ9i%J6F)XJa z46W3fu8#^UOen%vIdBO_k3Vv}5%xI!`j3rIQvMaAo9Q}5c=i1;{+(B4w2+)<0dmLx z0Nv}i1!htsyoTBKd<*Oj4pyD}^Yt^=|-1TN_pllISAtf}whX7M$#M!im1 zmRlmepQ~3uT0<=bN#Y-Q6*jOR^McFy9Vt3yhbZ3KES1X+8l{lK{{V(XC;tGOt6aK9 zswPS5)RajX+>%wAHg!L6RkAvQ-3cB-x|W+g3t0aE@hMfr5`X(eQH4MAr}tl;x+9%z znUlizp%is%R*W4#)jEY)NBArx&@Mj@6S)5XFghYQ{Yxqy)v52GAFc@_yMg;1%s;s5 zcc)^pD>X@n>Gwv4NZUW8hFq!7$30BiMJn?v>gdM8o+&`eB_D3=fDsq{(U<%$o|~HS zv8c7OBD}rbBS&kr^wxE2wOMUZL^xSiMIPOxf4y!8PBg33D5Y&%UiAHYc19aa5!se0 z&@M-OyBGE;9>Bq}!y^H5P1E(QMe0fX;%AdWq{^vIJRHt)Ryd1gvx3a!iT39_l^|>O z?$2adx|(gMtaA;Ipg^((0Bsn-LZb__KF|lo3FmTeLsXXFm9$?^$Q3D4?m6=u_ueT9 z{2$QA`+|Pm84i^}BoIxZJTea}CCNh%>_?8Lt|>?dcT1^*=d~=6{{W$8AL-NGIrQ@y z!J8%_{{ZDm={#fh$Wp)9j+4nH;x!1pfT8sEpFDo;B)8dqt&Z>WUaZ=;r|3yay8i$x z5?i4s(X8@Xb_4|s#DR^+b1=?%z$ZOA^v;!|+muNa=ZaWJbcR9gBzQR|Bxf9Fr|+O7 zbPDb*i4296bCZk{*F5-%TG#Sx95HKSm|BlmWiU@^Hp z;_2#$mk(=3bBnr})gq&E8j~!K9F;7yl?fA9#w3yRg;NtD$^QU^{PERx@2q_@T_n@! zYUqY_G1#>-G;&!VD1nA!i}CuK{9JoQuT;ISX}Vp%Ovg&CeLl>BYZV@*@XiX5-_#`e zMeuRQRBQTCJ!BDou+%poSZIIBS|QRWdA+?Q&ppxgiVeUrUGqyli|7E=lVePO-20164ZagE6ZzK=4T&m^;wR3t+N5 zZ;^wvaxi${_1dKb+l$x1_uDy|oi1geXNJVJW;4~1GU`%D+-{C!K2g{FN`KJuFhD&V zo}O(-PnTKIr=}o8rSk`?@d)9uPmK$$g7%AEzg?(E= zuidEb2@yH%sbwHBjzR5p2g56XzPIrMUZ*s6ThqRql4yx3EHF)3!NxzqCO?0_&mC-= zn&yLD{S2)|)RQhTX!_d89Q5hU-HC*eOIE~A=);h}qml^6M%vKz3-C**9Rl5JF@}4! zg*Qm#QTnHdV*~zp$B)#$+=Z&u^^d2uhG^vU98l_{mij7|!J? z5zmdWU6n{U006U$W!KUK1*Q0uyOrEh${KyNaKK;wHMf4ZlfU^y~_>sfnvc za%mo88Zh2OiWejyEUcgbwBvvWT#@1>B%C3qgVX8VdL0iGV(L=*YI7JpCc2mZ0D{vk zSRe62U7bhw106{R@V#!^hPB(;c9N44z1y}B0De8HOJg`0#s+!n-1qG2gncZPx1Sa6 zMkJ8`0Ni<5k^ca1Y5X3gwSQW_Qnrn%S!Rb$W-!3@(jyk{BLP7J@#Ci{N?r@{5lI}n z@9^NqEYKB(QxiO8qHyTjPBNr<2OJ;Uqv-kqZ9~-hN;a*gY0XqYHF>pE?o<*+o7Oi| z#@1qT4;-JIX8M%4;d&~B}Stl`=w?@qZ#G99P{uGkg3xav%@I2=| zeQP$82CdqK^A@9DXr*K}){rmgh_}OxdmsM*bn&!`-m&QFn(1jFg(1|=?&Ki?Eusm@ zQQ;-?mEbqV8-tg^TNlpHjdia@vPb^ppY7EfR`i)wY`{nk2?LHX&pmy6>Q6>i%gE8k z2;}X-P@w!^_#IO9ui-wWdrcaZI^Ru2msD$MkO9b2LW)JLYY1qkO-5I1YAT0hye@GyHebh{f0k&s(OVDMs^J} zGDs7IRb<$og-~!mu<1iBtpZq*dWrQ2;L;L0x;3$BZbT)L`Gt|+3`cDN{VJpaeslW{ zlS{dtS?td8%J^q_7`w6jlgaAHx=x{PwAyLY>=#08)xs9{fCIaZYOYBC0P^QiENA}!jV2%8rE*n|AJ&Q?xZ~WJ$@^og6%8|2k~?)T z)t-f2Vy60X*o=cb@R2eYlZKNjBwjf8jz)S*TKkAi>Qhgq(aDebjD=q1md7!|JR$L& zxC{O_JOhmQiN@4Xyf}D0WNRLSBr}+-ymc8+%FsrNCs_XgB^9Iia1WBO_M4&USJnad>q z0NEWe$Bk^ucCD%EZBJLdTUgY7p6#77%^3xmGAc+c`!k=^tgNn2CDDoV&{cJhQ2~e7 zbtYa1zFpt-&tB1O{a>SX%^gu#>91c_hi-Q*aW=`<{^)5D{{R_pzgtnh0)a*^H*jz@5wqWG1ocB1mm^{z$ZC4AZIw~hM!`*HY1Bo zgjuxg5hp4BBk>Zq{{X(+{D8iCYBGD7N>N&*Up*x)SS4E)sn&%fPUut&jkn>ko(4$9 zK+nfd_1#vyyI`wHB$H?$6dZy9{e}Vg@zoBlq+W03)TCK?FEr)&mO-4kWBvsh!9SDo zIzLy{Pjl(3zp%jpl0Xh+%xXsmkiIzi@_z$`$b~%vQ`YaGMI;m{!9HZ(@7pRFxZ!q= zMhBDR{9~$quVTf3mVT(uUewOW?P5s1`N>9H;aGpdIL9L+sVz$EOGx+_*i2M>xwKN&ErTMt@hsQNS9tQ-Q)@v19h*J#8DF#xFyu`am1fPouPv8nV@P32J?b z8CO;X8_M!LFCQcxuet`8Pg2t+gH1@MfM5o9JG-BDAYqO?V}K9&@Vz%$j?6-BNc}Z* ze$j1)Mrm=A97s8l{@`#tv0j~@;w`Nv9>#}q-k$?9VRs|5mH>$zfg{EAK z!Y{yguh!8t+q1!GEZDaTlsJhyQ84=}5*Yqi75pB#{;v*`VtFmiLfxt4IeBbqWm*3K zeX)XnZ1pa`>Y6qy{{TCwJbzCl-HVZ{?iH;NNEzq)a$vF(@)-{+%^KgXw8`Z#q_S=# z3;+k7x^YUCm`)A4NNX%L<7R69n$kmLf4*xIpZ;k!{{W{>^lww^Hz9-4cXZtywB)I% z6pA_mB1x+|fLRDQ+*sp|Njc64=UR`gbm}frYYNz6p^`wsh&VVSgU{Qi-^0&W{{Rnc z-Ll^@lNp< z2M0R<+9UF(c39V=_1~bZ7^p6T>N_>5{{Z+}(^`&=agl=|?WB@O>@m5^gYYl_0i}Oc z_LsY)dUHaeoMJ{vr+odlyJw`^-Jz(_WzanhCckDonnYs$kzKp`gfLl2q=qyF%xc^j zRrZxrv^O|q`6?d#_iaymQI2J|a%ZtBv<$dsIUrTX>}OQCh4>1}sj&?{c6 zM`GzOB{}D^owOBC^&@U@TVZJz3JJp}QO9DYl+Om8s?vx!G0s*qVrxo#q^hG}kN*H= zyB-S?c?eV0n&DDxYt3LdSqPV8`?1JwMo;h2ar(~m$FpL-n}1^NDPp@5j~U5sI?CT& zjS^i45k;WbX0@k9s7N5o%Tc6QyD5%c1|8l!=jSRhoc^wj(zU^)Qj<{A=-00Q0Lq0PE9Qm)I`;!-Xdq$Uoa7 zq%`#0>E55zDo3?uj$#mDOodpe`v$<{@zZ@qm5Z?d05GSpC{oINdwy~-axwAq*FDoU zAv-N}lWUMkEZ{6?23gzW069GoFRJB@S{*M?u?_tLPut*e))IqnLs-g| zp&E-)rKVifG|8X^+BggMw>o9PI}+4{cQx~^E3I~-#?@NI4X36 zV~tc-eq>K1r>vW0heiG=YF?Ss7t{3?zOxiX`;*G-a?IIfL(g$WNDSUd{{V*_Ru*Wq z`D zE6!FGS)H1!Dgzi_?Ej2ZiqPj zF1Z|Fs{*Z#c!@wbCB8c5ATzo->!K^ z*}8rM%PR!n%^U3lgSefe_xWGnk@@IS3D6~t z)IOjwXK>BQ1bm*F_QcUylCX0mxUP}6>Li`a6#oE=fCfDKx<_`js9qV-<8|SY#?n8} zrxdpnlVxjAu;M<ZmT+mnKCZ;*qy%M!LU@1kbI81Bc{euZRk}sO%gw+H)441(@)hj zN<&Bg0PR!tNBf+q_+!!=ns|~es7T$w131T5-F915YiUZgtHG^D7u8zSVq%lXl9nk9 zfO}l_$}wUxaskgdtxVc~!{>5jAfJoN6LYW!ZC)~tHSX|Cx#I_xM| ztPtV5iH4SNq!46)ZQ$gNoo(W}Z1 zS4u$~tUk><6ElDDj;vR;Xrs~eX=A4PKBuZ_&o-s3>9B!j;T9!;cfmW3Rvf!V>dsh_ z8^=XOqw3n7l>Y#=G~tP+bx-EWa;i@jNE@t0+}k>jB>QB*Cv$k|_pN_~Ua0iFZ3cO1 z)4xUyF=`D%PqL{OaM+q*`pWqe3?6gOR`W*EZ@&CY{uQRuDLST&T9$$7dkB!rQ8eo+ zZdC+Bz39Eo|t-nUeXVlEtLFZqUZEle*=WD&a{CFh>U<^&DQDw;s`FM4p7i5+#a+!n2%z zjv%DP`=(d^LDq{mGx7eX zGM%guxxn4ijXTtrRlbK-(OJX?X@%U0A^Z*4WIv4K@zVM9i=WB#>lbw7My;JTSz;yQ zk}h5b1aRCL6Ye%B$4)eqw=T+-bo*D}kJ^QykV_EzB%4kL{H>Mz4zYQie9Fz1G@gvG zY3runA!%4}=l=ld>@LYaWk03=0Jaa~qvg|)`9cX*P)Eo(9!JMaG!IG1VbwblOBv%5 zL$TNJ%75w!AGc4n?@1M}nP5p35PwmoSlvF}@_*3hu2;mREzQ;z(a){W1QcZBh|@z&;=4xtuToL z5&_=BCtxR?xNLLz6p6iE>uSvfiiAPh$$~0jp^7Y@0Y*X387-22N$Y6k_>2DlH&4Zx z$|?`%S{J`rYgP67jZW-zbgxlqOh?tsVx7cGp5er5?3v++11dQLfO_KItn_}1X4$o` zYI?q{Xl--bt}`Tm^35~nVHv|JpT|~>W7N^u)T-)sD%;a+-XBw5`CZX0>UPNt=lm?M zz>^p#$-9HNFV(euDwR1N((KdB#yM!nOmfk)w{s+C%I+TYBP#31yJzkG^jT`ehJ1vzxW3JWHlvjH2zNDe{Bxea(cm%Ox z*>(rydsjc=>RNiGyNG2q>dh25P6z-S!LCE-7q{6q`B*k~HtBtrg0! zJd?EsmHRSJbHjn+(+xr$hV<_9y)-JX! zI+nI1$^MByn8E)5uT|OZ+n+NmmEwg?(<|4EAU|R4%OAkW=ou!CA9Sv^W%)&H#Gm(= zezW)-eosp->XNw&8Nl50{rfXx~V z`%rsREwm3Ok^6M6eOFw(C%tOMuCHZ8tNjLO$R{4mE((tvbS9-&SJAyQVCq$dpC+#? zaS1JZHb8{2Tyn&cpp^qSE5`?_=l!I!FqtF0ZrqWiF)a5Sl~fIYBZnna54+_42Tdz> zgzad{M0IujM$Cj=`f9-Ytlp`J@&-bvDV8VfI?*&gR_mUgZD46SbYn|N~=N#hS)$4kLMck6zyHfVirj+C4lFUvO6ar7c0QApC*XM~>N3W?# zC#Cf0WuDb3h!Nh5ezNL(ccgVyU+{)gjDmWmp6HcNaE*5LRINi!ka~YjwFE+YZwQh} z+DQiC8CdrW1S!Tq-JD~p^!kR91Bor_HdHHTvtByujDN)J$NvDAs}8lH#*|~%?E0Hd z5oXyuxm@&zDdFoS4cKk=6R zheT$UbiH0RHd#|lZ9`M^{{a56(>}iZ(=^b;L(N|+v-F~O5pYMcL4&vssJic| zt?Igjnys4fz_Wk3uTcU)S}*X&68`{&2ixS5e4e@#DL1ISc~4N)eR`1UQdvtpe@WB6I=nJ7P_HBENxH`>X0YR?RnH!F|n$0IJ#S3H0l z3RmtktXx!*eN5z}m7<|XP}MZO3eT@()9*)KIe(Vv7M>C!YtjY=K;92(G?0#e-W10m z;(sxmS(XT7IV?m`EGVSp_|KE~ zJq@P%s&s+Ahf2{YE;A%h>2bd7A0g%v79;PTx>PjS$DQ8g$I!pUsC_@I&ab3W)avTc zCYy6A^2rTJBm!d)L;8yT4=TUj$Mn+rM&#N@tCi`=4DSSRyqhfBRALrf5r|>{2SND0 zU@|0NNgt(8IOY%QKT=ShFg;JIM;I#V@k(o~cp#|)BB}_$I0K?!*BevU8(EW9)b3nq z1g7=LJI>@|k{F!$7zMF_2ji?V;7?eu$3XwK75R))ro_iWwM=+dw6hOn@y9&mlb zdEX;oV6$?5F~I6y=i@|+>8FsUp>=a9117C@84>;@aB{=SsRPRpD$v>Vl}}GY>u4p0 zTk9g%ucbBhvpJnx4{704+L5j|s<#Y4&mPi}o~FAy_9w9O+?k~BOEQwc@=I~SB;=BO z^~=NKmA5Yb?B6`%=|jK4)?oFux|&s;BBas%CB{c}5rWKkz|Jy1NaOF(o}|_6Qq~@w zh~|ZswNMsBWnw;^Il&q72+!Oexpt9$X|2a0u{;k08AGmkamujA$Rj!Zy0P8WZfY`{ zcW+p;c4*YeVWcl10Y}O4jQHanYbYYnh5na6v zXkIStOB68ncJp$_~iA3F zbSV8baTC>atS+O4nKb2>WQ7Shd88OvlY{MFdtm;b)zc=`{YS6Bw4=AE%d|22C~UkC zU=l=xsmg%B9G{V#`RcJ~>UyM-Th{K4MtSoZ8!wgw6M(Wg$@7j$@zrqh%G+5QUY-8{ z0iGD(lY+kc@iTYTWv-;MZnrW=*g1kWs{#%}#}jx!Nb!vMr!V4u=9mHy=ZdV%z)*j7tgd@nSt*@iUBvEYORo_HU(R&6#aRWy+Xp&S)mmt$A$ zji9OH4V;2`Bms^GTeXiGQcBr^l;!fbNFPbDrfB!g&3{KahLJrfD&Eszo3gXUKxHM# zW^Jyh*#rg{#(>ry*L zc6W#h`NJUE1{XZ?R31(_JaiM*uBk8?+df)WWx;=+>^}p?$55c8nvs7Sk@F(Cuj;9< zNfx0OrF6Oz${D1Nh>#eVe(D1K@Bus@93GQtP*i|NBgp}1nMp~Dxnh4&7{d_Q`9J5? zhWgjjppwEwU|%KDGQ)8MX9FH{&(8y@`difOy4R-F-Q28hvBbo)5O4!|{{X||t#IOo z2)M@U)Xy$_ndQwb{R;zXm42F7>D!VxcLmC*i89N%wvFVG;0*Eo`pRnlo73%Axh}90 z=HT6ihx$r9B9>xMj!E|c{+a5#3^GVyk+iv1$9a^-#0OPD?K+GQn%;ym&OJ)oaH4?Q;sRbG$KN^?(|jK8YsR*|&$Yl$U|RhULgsKDegJpH*D zAGqhCWc3sh&Kj*)(jcw8MvBa`4+IgzE>DAl$2~Lu0JHUKq!p5cw)Y*&-Vp|c6rMq0 zk>~s;?VhYLdTT_jryWJ39mkQPKuZO2j4!-ogOYsn^YhbA5UagOcPB_uqH8g>pc_?d zGtyvIP0|QJx!-* z8fdmCXqP(?ZyRAV~$fP#tLg3RlTz z424&53JV^2zPAj!5z6XeT~8276FO zHxBBqPdga=^a^T|BxKr*SLCPk{1OQHI2q?S^VasQxN?kSL<0p}@_uui^y5Uerlz*# zM?%}AB#&uTZ)y9F&qMuXU0y*Rqj9TVJSEnQg_rCmA3y%kbN>JkK1L?GJ-ci(eh)l< zZiTfpeZBF@S&miEs|6oo58VDb(2EJx^bK!DoI$I>HAz`_sF6VqKH!cI`Shkr*BFp2 zs{Na`IQ);#Q{U8Ew*kLm#LE~EL?o5pU_KE+JbniqEql_(yJ&C+KK@33Wj}tLWYV@w zmAwag=Buh}mlFP>G~r=l5xIh(i@${ z6z0FAQ-Wo&R~w@+MhfA_!BhTSDblB*R6RQi?Mh&xa0Xcl{+U<)Wy$@)EA!QI{{X2j z>SDOm{Xt??tev=pjLEh?vYheb?eWst{coYrPTjp#12b&|0zmv6XQY;z1C_I(h<=9n z*(gg90MSbc_Q;Gqtfcu?AAiU{Bc>2Xr&?}dtyXYySRhy&{{a60Hva(S{{Xwy3)7yw z^scjFKTcZpMwO==7t^iZc35L_ebF?Z2>hI$6_+FR5MZhNMq4&soocITqmhx#Y1PNH zk+^U&yl_Xx4@s#$g<3l-)+f;PW24;D;)-2JeMH7|D$xaeMYQ<;01Kb};n2~%QeX=s z?ZN%J=kR|QZA#Erj`fKhS7JhDlh`xhV>rj#rYHED6tXN5$g?pdg_e+Fe*Bf)$KR~^ zW#DOR#OeN>xpp^tRgZkQGQ|*6%P99R<17BEI$~rN^NQz_jjW(Dk@23n)`jb6Wtu4< zr5Kd9)oRj76M}fgH*x-7J#8q>NTg<7C4g2&f-lybo5&)zjX~Cy+GrGkOx)UqtpapUsjF3Kvkwt z^YMUy^**6ijgS3f3n_-&jlE7uhJVz^N#ui_%1h}d5)G@F-Z`Tm zWRx6_*@F+qT@f&BWp~#8w;qO@LAxx|zMFk2-j38oW;J9}+RI=%GRlQ>f_=&7oYN2U zJ51lpruwcj)h4A}+eP`nG2&(Xr@QW>tAD53#~)iga*NVoi}T&E>_aPkA81%NmXhrtIN5!FMLIup4o5To0&JCRh^i+JKM#y*bkLU2?9QX0<9*W1CJ^xdbZ|i4)gg7R+WbAVwJ3CI}-4{BzL@D6;$Y z7MxDF*?PMF09b$fL69XMl0$#Ye00TitxrxhuUh(TN*G`Ib9TclqZoMiU=?DehS$O8 z!RbxUXr#)=9Bo{kKd3FK{WYrST0NWomeaJ`QHwNpMAC|(l0hPXoyFOaF>YHP;xaG? zQH7p_#tNE6HfRttipJAP8lRSk%p4ES(!Z0@mS{x{En`Zl9#X8aYIOtS#{U-$c<0Gc2tJrB?uAvNd=Y_jcJaH_kxN*upPxn^&&N`^}4ZYKVHF(i; zCv*B&p;7+;6EFL~KjI_&N3433BW2y?)H`$8(q4qU7iVADD^rq(6_yn z1PAZNGz@Q$6Bc;gV#^WD+;5e?1}7y+x-jQ>W`Up6-uj1#;*yW}@dRR1@!1Z*W8UPIi&Gm7iPL zR;$MxUE1BzAcc!BZcjbPoO2X|0PbIqG8l2v-D^URS0DD0h}%N+toKv44Akv~26D)} z7}&D7a50Az)3t;*qNnNoGD$8wD#q>p(`@s`&<4ndQ1s;VC)FvWG^yLC7G#t(RpVazF~~_#%i)i-a=p4K=GwR~CDukN}M2u_u54 z@_clWAh+pR<3sAZ0txc<8%mLn)gU+|ox&*C5r#rpl<+~|mXP|_Q>!#q;HyDptaqgL zE3DSC4nZ=2q#g(91E`aeUn!(HdYwWaN=c(>RSv&N>Q=ElmaGO~&$c+pR3K*uV36eS z3y+>U4ZTTMP@Yt!SQ#uga!8{0yOMM7Ba#Q(g&ic-zlqUdlhhDuw(eS`r?`6eyK&Y@ zB92)K0fyX8+@|2H6lAIAs_v`ne^F2owas3={X0?r0Pt`0$knVOo<_zQS6tzh^2&VV z5KkM$IeMKj$r9IdQ>qIsoAB2u<|v1LU)u}qQ~S5}=vunv3R+Js;L=iPxGDga^WS`8hs0)H;P~ zf%Khz+E>xFcM-IrMRn7sOo;C71dtT5S6(+p&*ZA$-&5IVqEi+KkuRfEh>C#lR3kgF4s8kZW(T)U& zNH}H4Bf;qpayV=%S76d$g)4!QKYxyz`is^6to6mF*Zo(k+SF|-ECOlOLZXb2suTrL z%N!^Jl6>`3w|#rNCe)fPeW#EYpT|9PLz=1XV&wxo~%243Ce1 zKi8{uYZL07=`}TZELf3b@5;C*oRRUt@`z+gDX zfD8gYZE4^T6wgHrLGc@;aM}l|>9_*3c_cD`E@qO3bBARZ@X~ z{X~{Kjyw+@f3{)t#i!8SAeT-%CX!-jvK54DjiYV{KP3F0$4vB}PsH!o5eX!09qX1S z_8{Y{WBNuYbme(qF3FM*fsT6S_-Y!dZq22Y%SkQ0jyHEl>@k}2$2&p(=eFUIlpF$} zWC8o&^U}*vt(IvcNo0~$B*hd(!zlj%2^jq3obisjMzc~l70hr$8@I@eF;R?oBZ5ft z{+(2HNcBrHw2e|$MpB#JK^$y{;DAO?9!EdFT~U_5+;;n20~dY;`YN=W2pj$QVpRc8Qh0hFUASYzAC!W{TW{ctXS6 zc*CazkGDDMSbZVrTk7%I(Ww={4$`s!CGojCU^8Hx@<2Ri$5!igv@23HjXZOTvl6h- zfKJ7TAc+~3lbzYy$B*BjyP6MXO$MK(BD*YA*=OGzH5a#?$9aelxg6s=i99b_#x}aI zdNFxg+N;n-qWT-szMr!ep?gQLuq@^}vBhR)Vgl~kQC*o^CxyuTjAy1%=(>)jtjVa{ z^xTzJC_b7oR4FnnYzAa!<9Cl31S#O2qrDu@EoklfaxE@0L(;8YtdcMr2vEX29FlU< z4{!qiq%@&OhAzoq)1zgfW<&!PBZ7n_UmaL!`zCVn>|A( zbO!ohOJrwsW=37U&^#|AKOJuc%T^LIeQZ^D_p9$6vVY~?qyfmzPmp|ceRYsYyFrSi zNf=dFVz3#fZ1^ar0CL2f=jZ3CveGouJt1y3ix;hiuOU}SrQI7Y50n_rbDhDn&yJ0o z)3l^uwzRmbG6V)nqu9zmGv#xE=bz73Z90djXNWwt>Z2Tz1HMPtV;}hRmtC#uI&Zlw zqF@kXjXTHp=V-|Mo~N0%S1lsBZln}e$*Xd@BqO)CZ+1l_WV4b9Q=b7qAD(!v4RXCF zEp7?#RFB=o^c*!J>9A&Z6zg16S^|!64%`J;u3ZG4}nI!V%!k`V{3~o65 z^o4y(>rF#ZlUAc+Pg$x)Orp%@C7i^pOky@*ONBYun8^U+jw_Zixkx@~R92{b%q*O#&xa~v#NVR682I9~(w@s4^^Z`QhHYp68p%XT2l9Ksq|js|iR0K5Q6}I(K5#3%PPDC z1tAM75Uin&TgQQ)J#EX$xtjTls(%o@CmNmhgj*a4SlAg~1B0th`-{XwpO*{~zh;jv=7d)(JyAOV5gR$!%b zfKD=3C*!Jx{{T{dv_kbQu$U_&10a$`VUhxj02BrQ0;dN!KLCnPT|vi6FHihM)G0c= zZx*c-(RW2rrCWwrz1bO*qed7EeTT^EyQ+T_^@!xDZ%xv~C}k#UT7{^{kp>17g#}!L zkarRH8RM!AjZ)m@;u@v+OeGhz^E%g^jBl*zs93t+_PWSC)4Xp+pE;6rFW%_=NnpPDjj}L zw}Fm&QLKL)%QD7YZtV;i#4SXe5lGB{yGv2E9q2`vClQz2u5vOIouewl2M2Y*n7WMjFac0D?OEM%R7URttQs}9&$5`@q_WwoeR{uA9GKwscAwA6w+3f z2j-u7|N>*>j{GFt&L@Moy#fc}7j11+BYl3m{$J?hDCiz)1 zjAN=gb!c^6CseN2D~YQ~7?o1Q*)F649dJR;PoIPF(_J@Ib&Sl z&ODFre0UWxMU?P$+DtF2*%{uG>0b{_7YFqgTegt%Tx8HzpB|w zUZd3Q-?Ib)uxVLxQF6dD3>LS4e9XsKi(5RS=nJoPUfFmXGZq7(NaTGtBOKf|Syb46!PMyT>CZ z<(Pgr=va07T6FbwJs(nf_u$AS-~=f7Qg;y|k-<_hMn(@q!j{|m0-NeyEqeP!(|s~y zN7QTUv&`#a+qmosEs{idAfvanPZ=OE&Kn&%^w;r9zo2f*2d!d0p!&M#he~+XTN-o+ z-b{}u0Sje+pn2h0wr~$Om(+ffp`rf(+kFqzG@uvM%U%BEqEx$Yw6GRtU)@xc+`xCXa4{K zkTMAaBgT5-S{Aip7*2y_gljyG+I^x_R;OvWWOf9Ff?NRHdl)PD51S?5<3FqQw5O+f zs*IJV^!#R$M+`xoR)ogJwUDh0!O(^TAL%wY+^TWU zT&9Qd1vLdjs=*GRNXF|CkuEV9Z$^H5wIySW6ZDX>Mjg2a@ z%U)&w0EN7x55ed5=xLswn{H|q^r&qJa8kvqQcNX{fMk#=Y+N#se0<}gwC#6QieVm_ zk=L5R5h_roh|&|lUIAv#d=u4kK8AF!Qp2E7ePy(#(x8mbR(7E^VCQ7jom`!ae@F;r z05SLg9|NSC-i54am)lO(t27d>N;_bQkQ@gD93PL{=c`qJP{*fKm-)1oZ(U&M^3t3} zwdGJ5asCHoE6acYB;$57)O!B_skLkO#1@v7nCm1h3fX{8KzNbQFZUvW5)rQ}-Kr2dg)x^xN8os}7s5Q#x{9-CA2yMzO5w!}PKe4(x?0 z%0Ey9gXgTvb?)tfwHvjIkgEziG%QKr0GMHu@rLU*G>CMX@~T3n)acP!yAcksso=t{ zGwwbajt}@p878GG&{5M<8s3Ag`cB$u8pw|10RzD!g77+j%KS7;55Pa>IvS-IH3~QB zR&!oY_IpvsYDEYgTepRmfOiRSHvn=6C!?)FVJ@Z0)@6*%LcD`xtprWG%`QxBMR)dRL+!Qn9G%7h#OGy*@yIkXvr#4ffo*0O#|b zm}wfM$Y7~ENoqOhS;k}nR%pXWiX6|quEDTm9k(2jstt7!HmlG4W#2rRe;dNVWq9hBYLl!ZIc0$Cq& zk7Krcbn54)DblklP`@P^tGm}^w-)4OQ?#jd1zAo!Iswr4v{^MuX2s|prPN@s-hunk zJ_Z2pDLEeiG2T84j3B6`9Z)$rDrYd$>1jGXp;t!LzOKdF62)9WEK*Z|Z*@;D1hWr! zl?bQqM_c-**27TOb;YrLW2SX0II9p5L_nF87FGRc1IuLf$~_nSUcc!bV^4i{)~Bmz zRBol4S~}Q_!yrIe0{4~HGrS=s0Bi$>2M4S{uKxfJ{Y|P^wRcC=JuNNU1*0^tHQGod zl$8@C>?K@o8>C4Hz$a(NT?+*6<*}QbQmF2A9Y5C;Xw{aMrCw?DD-IrJh_7;-xWKUn zfBe8WDZr6N(}ES1&!{wSRQg$tnXWB=sIvf?uhPrhX`_6I*stnFeh5YzuzKaXrOiLl zy7c-aI-Y~BMP4)wcSdO^s$?ML7D*LEn{YDVVCRnqqCF$(e@~xVX!@V1Eb6JI(z3Q% zzMBF(vdJ4OBx}8u2I4SSo(K9Tjjd2A#`#PC0IB_I^u2Yg!BPs=qN!u~bYjFJR00Ur z41u0bV?3YVrMeHPV5tjJ)}wnGHl;ahk;BWt>NcgQGx}sq=N=t*A>i@PwGDa=Q&zjF zq%y>9T6vWuV9cPgBXcNKEzcwX3C~8yZJru&Jgj%_EThf~b)+ywE3H~Y&ogh8Jr1h+ zZ>W7Atx}U!qZNmaM7Kfbi+yX*2KLAih+`WJ5T^&69!E{iyQu0~^^JE?HI4fdiRDy< zRX2S1*Exq)y?y?w{p)t@GO8JDT4@+6fCA--I0Jw@4y<~1rQMP?kYQJ7 z;g2Iea(anF#3Pfzoi>X;t8mz}FjtYuc2Ec(*+>04yXd}`uQ2+JMzxC-uv$psV2u9& zAQt!;^NxPqbDvDxkGig>dhYX&KW@8ri|SesXw3rzX$T4wDJ|C?Mex-`>Wg!CBa`}` ztc`BP$&{-*U?QAsLBb$7z*PVMG2nGZ)J&{iNf7}oS)Bj`bswlMwOHRshf2^SO6{|` zLgO>c-#L_#xO2ul4m@>8)FrWADWy+O*orr1kGuUxQUdtM$RGLf)~-L~Lsv`5{{20H zHG*4P@1VogI`*4pNu|;tk{ZTQ+gYX)XAABPjjRTKcKF6leAabXmZS|O%N15+*pf#f zUh^?I_D30Q$`p)~wETJLRQiQEUkd`#h!xySnJM=^;tOY<2TNwtYgv*y)UMUHV(4rwwuV24QBwWi)Xn7hiOsLseF5jyOpokVILP;qtAq2&C4ax) zrg}ZOA+WlPdPP-^5UnKd8cP#y{R8@hC%ch?4+HLcNSYq0e%aHZlieDubF?G-d9n&zY;yJ8)Q zEKH!P!3Ywai%4pJ>lLS9Dl3 zSgKc_{>A#b#fCs&No&=HzU<+SUQ+%59E{|j9b0Sbc63IHO<&RX>Z~fU_vD@#{4fQb zV~}kdPI3U}IQ#X^o!jNVr}ApoD@&MvPM51S7^41WL@x4Yw2=syVDK{8XFTUWW6xHN zBSq7p5g?W4u*w!(DI5=-+2mvJG5z{U>F-jt$b^FAqU%i}$f#HqLUzUwa0;*^@^Ulw z>fqLC>F*qNwMw<59`4s~a}cNxY@(8L^U36nvwX?;dIOS5i&v-Ql7lIM!j*03{6w$8 z2jkCIYr4|5np6c=+FK-JKcBuoJ#%_`#-9y}NfbBannfL*bkuk_>y)bX@2Yx z4ms;tWUop+mg_QefJ@-W$KY~#I6P;rG3vkKqSARrjZU3;=2H}6syn-5g~1HCVo%wR zKc1-4?W?0%KA$d4r0dI}No~>h)v~OSFnpJCK zuX>;Of$0xVPbR9+*7~>#)qeX+B#~jUg9yqa%?(EDxsttj zZ8F-GQFjLsPKn6ILht7TkGBBzPp>r{UTF-5k&C>}uMA>IHynGF-}-|X;{T$~sR_msl^)$(YCN!JseF5qZ;&zjx zYBsIf^uDn0>E#`DI^=?`?SUC-SPYHKq$y$ZfsUQ&-^5yaKZ&0 zQ^h#cjMpKZyjoV1#|eX>3ceJ*stpC zF5lF~K&URHaub|jDFlYc$??$?zl$0q+7!YY^XYdcW>}(@q}Et2;qPx~QoC|^I0O8; z;@+M0eyB=WgVUN^b!E0#G*zByA}Jn1=1De_=f(*+I6gYM&-_B4Ri^TKQk!Y1QYhBd z>1vr8HBd^!EP%GvDI;42<<@(7j7GpK2&C!1G(QV=Qed#S~kCG3<{8&}|1KoN#gHJ#wghaqA6R z=+i`+TB%)u60L_dnB-(M)ArUlob1th%iCSfhhATI=-cWCL+UV6Oa( z24>EA0QEXa(%-%O3Q%xgG4*GrwR+~Tb)LNc00E+Gsp^~S{{T~Ir6*Q}<}m=pM7)Ad z1^`o^zn=j0&DZ#+4E3O+PMge;)+!5@R_`2P)Plqec?9#-XH@lEvx4zlHVXiWb%4hsB37Nb&maUYTM!{XZpz$)z7$vOl)R2 zKWtV)C4}~Y5lKP6=mL;uTY2}4uUG3ThV^{DtqKpH9jy(Q4 zvU+3Fu}=bOcD1^CGfxzbl1-+IE=rS*-uU}yJ_z1ed=HMco><_Do>y<*`+sIeJTlKG z3~NsP7u>5=^=_}Iy410#Y7$qk6G0zp<3QV9MLXG)Z6|6d%z%u19tTH?iK?U{Q`YOt z2`^wlTe)g@!1I>_Zd=Yr$jQf6$bW_rC=y!M668vcHH&rQ+qiBUyK37;GmQTLiyZ9( z&GSR_ckuS5c#fGFp>5O#mr%4Av2XC9#^lM!0Dk#CdgROcrU?H4rTZ`EZ>61B{{T(N zUp;%i@9J}%D?^IqE0B6~LA7D+MzHs8Oj{AQ4#kWgeoh-WIKU$Zo|$WZ!jDvH;LoK} zqFSU;D^}j;x3nKCCO}+dWcd7b-n})T>Go6T%lEr-7GlC+%BL8_n}I*E&NJhyKELU` z6HZB>X>CnXRaSqcbG@ASIo+0Vk>vglSWAwYPb3%C-|lH18V#sV?V<9nf&4P1PI+Xr zs@7X%?cSAQxQUU<>>-H8eXOLCM}dx!U-Xrt^k86$vF5=Klb(ZTl@k zX)IdRYTR(~1(GVvu#kQ15V20%E=m>JGxzx}FM69p*Qv)2z37UO+b<#uc{5=QT7$B~|?cE5-a zNp%LG*0suUBx)AZeKWSy+7uKl$QR&-&jW$uuR{mv^Wu`owXUhZ>3XZHIP?CYkA}EO z)%f<`xz#m4Md_N0!!(`h61TJ28o>$=0gQVUw(cMoP(kuDEv|9i0cul77dogX^#29WPMndT!rKQLCs`mPMBRIMxpK540>%w$%3Ew;oBy zM-e=jvqu_Nd+WEi_v}{>7-quqJwEr}p*D@{9a}<^>U29vr&vgbeWI8Nn~?PY$_FFXL* zDf(OxmO6lC%P8*|!eb_YWT{jQ;@V9YdvQI*z$5wb80pktwpu@*AsA z#D%b>`-~SXNKt}DNFO~JsrnDq8hvwqJr7ra??ST08qNX78SFD)`N`+O=Yx!Y%E1@# z59eB{SwTcF}dP^3}<$|nTuVM~!htHp!WBc?Z+W!E3bDhjr1mI_%fzatz+{W9sprBUmmQAO8`OEIZ{!c1ZrLIRc zdD&da98AF&{(n|LCpZ}RzYi0l$^ zg+|HTN1TvH1ohE$k5YdI8ak1BzfAQD`huQfYle7bj>Ia>+YW*7tckKUVhLqYl6dQY z>9!1RU8AvPLdrWUkgt+PSoy|C;19ner&_MMwxfcstE0yi+MA&^LOQzu*a*O!5}*(c zGx_7MJBa-~Wt&lLDQ{2jsp)Y1dyX{ZlX2SD@%B3oqv|h3UCh3oxUmK&Y&OuxF3>Z$ z@KhY}w|06DPxWCI8Yxwd2@HG>IN**v^~K*&YZ4X?v7-Kv$0YdUj+trF86Gx>v}6Ih za3K#rKL_ugw86kW9yQG0sfQ89$B32krRn@1OxN|D?Rut@rO#fge=m$ws_@qdEQ&}9 zj==k|@xbJh$vNuS%V*PyXw3t|tk{n>Hw~{&1{_AeXK~9g@T4g6-F)$(dV*~+QW)j$ zf){(rjfEpQ0A~eH9GT6YU-V&qKvD_Rz)3K02K) zvm#Mg_61du$J>pAqb@2+DOv=7UWIT;Uphea^FQXSkdI5HXcVWvvqqJ8V3=5AlD5 z91ck#ZE4MCSt`7cJ}^vY8T=o({2rJ05wqHq#^7XN`RU@))97~E#;}^Fc{{4KTLT_3 zBRI+*`9hQV9UCn{D;PGRT3UL1*5WAgS9rUS0HhV2!1jKVyY*1P{mBZ8`;x!cJMA zkR&JGT@UI9KdU1?dWU6@ny@o%lM2Xlh8QY;>N-8C%+(cjM2yvx5`Lp_mAN=*_WSn^ zFvpL%$4`3;5eH3nvj~4=wwHUxeiQ;dzk}rC$myS2u0YR_cn3autxKiaty)`9!!#SDP;6IxtA6Z+ zf(#Ydb0t+40T_`XIC8)DNXS2K2>rn$r8YFEV^@-c3iC@cvi8`)_S{{V&l z3}oXzI3RU#ooGy>XXj>|e}|PLwGFxTy+U`|)MBiO1Y1bUcO-1F$KiP$0aIO}5S8Gh zc~DheP0A0CfzRxEsouFA%}UMMS|w^Q+L}pYsR?$Dy0aD$p<-KT;BraEIqF*LW#Y>M zqi6tUA3b{b_-;#blXqLc<3p1-70>dRKb!T1Je>NmAdX4srVee?PZRw7pnq zr6jQg6C;0Hvmg>Hk@{8kkXPry{@qjPL?tNQsbnA$`%ZEP+m1T2X!?q2pHOXRm8}bP z-WW}Q{{YcqNA*_(dzS|Q@y{cx%^#AIzalYB^CxxYSa0jkuG#v-r&OggyU6CEc4A^j z03kRS=O@X}O^nrq^~GnM!p4h-z&X!8I2`p!uQM|Z#9+2Fk3KrK(XI7UiC)UYtG9!X zp0ilvjwvk?9H#O&DQ?F#EId>8T>?5BHaR2b1m~+(mu4X!apsG1l>u4(><)QR@;>LP zl_=)Z0@_7U+h8L&$vpYv$4)9XL%=(yqINq z4mip8AGd?~>ZPgKmW7Ee>In?2(a0GlVhiLDK{(tSCnMvJj+kEcB%Yj(O4?nR+RR7U zZ0wLI=O#8e0O$NeC!PrEm96XdtVi_|zkW6w#FHifWaWSvKP}FDLq@)57fX>j_ z&yaJU2d8>3sl7p^>PUS#R-E@8mJ{_g;*}j-gM|(Xf=&i`BjX38zM`H=n%#=x#b=dR zER#hPW)$OdlncX^IUDnj7(H(sl6f8`m2S1S^dsS}MUvlx2+}kw8kcWS)Qw4LMGt;N z?v&n0!Ye4rKu;vMC!7p)yVNsFQg+ec)^z6QYYPDq3gA?`0>FPrw|WjUxs6)pePot*2@N zH+QdVZpD-WyMp8+3=FQ^jC1gMwt9w_q^Vca6VjG7}2 zt!dNNuUb|sks7h~l>m}hcx5^9)xS>BCZk$yCZDJED%ILn5YYZt%|aEjZf$Cez2-+eD!iM=D!5N^`P;@i>GZV?OIonHeYo`s z(MZuO^&_V_l!J^%ESTI^2LvX}1IQgeg5s+0)qcvC;K}g{TJqPwf4G;^IwDP8-m|3W zC?RL;M?y9_Wsuk+O0gSpp~Lr5H3jYAigDh5OW-3nIxqowq!6*m>?f@RFI;38csbb!d zr(U;qYfhGasyQO5A!a+@a;ltVFh{&7&*vQ?({)+2)v+8`AvEPfE5__>Dk;fOy};Nc z3^Deee2$4{mT0#HT6NL-_^(E_HjXIaX-VJRdU!DSy*aB;s5D(-Ee}nzEtuZTUd%`) zK_S?i{2^dV0FH>*1eV4+u=;n<)b)F?$EWC%JXLKa8)>KN1^aUX0!J)?gDD_0a6k+W z0U-5Hh7CO=gF~NQ5@^;`N|P8Rc;c5C2!)3K0MvP948G%xj;)gV%R$ntfBmoO-D6ah z>PE9nnro$Nb|NYi$y>Ut#X%uk05Z1LssPcx4$H>=laCGY$ zwW#uv!0#H|k%zDo8446&kJZ&{(|^R9)oa|lElpZoCYS2<3cZ-9f}kGU@We~RcVKqa z#tG+xkz(|J{*czR$f2K5(`o8Ddss@f+&WZ2g$3QryU7_K1_R`bgV)aFhw5wn8@TmN z>-XQu)A2o(mw~O5zKwrheOH-mAHl6RMy*r%FQzn!-mF48(kyHZDYmgP4aA(2x86=l zh0c1d>wm)yKGCaZ)K?{!R#fd-)S7jUS;)t*uo;j5LXy}ZAsP7U->v@u=_l#)2h&p1 zw9y<&iDEfHh1Ya!#$e|v(XP-jjm&rhj=7Gt>q{Q2qiU@kcHi|xlh|otkVu08v+a|& zwNy9!KRNti!{g)J)aKe=F7ICb8Kcj`$}TdBzKc)!{1*rGkMNGI39Q)k)YsOXhDp*1 z?1gh5zqsTt^&1D2_yi7>>Qy} zizy3+;j%$Hf%DEid>j6h50HXZ{wq~b4sgV-I!J%0x=0=nT++)E0qW#7;fylw+ z@%s1m2$*SgrICb^i0##es)j;9TqsO4a6re)az=W!Ek9LJuPm1R7jn7)YuBDg2xyZB zjqWy~9sy7eS-x?O?6Aog^88k>&3@+`GDdB+kL~;x`hJ+K!c!Nis@al}`DA`8$^TAva22bXMzNB=PDe|&O zI1wQ-ZbAJrrMBcC;Ey>x4t_eCzp3rTq`&0kxaM7I$x~oFxR_otxIC%J&`&Q?0(7+ zLb1tU**~N)BPX1768eKvn^bmPCI+;zyz#+)X(dD2QdS_Uq01kIIm!HIq_O7sRXMpT z>r3|iiujoRCBiiQ*<-oueM3Z}9bZCQ)3ivA<+dS;HhCSe=&t8;V2t<*2MTkJvk$AJ zSfRD3S*31gjo`5=2!WZnbbYD;LyTbK_xw>G)S9lO>jg^wo2r3b%rG-lBl=^PcOah! z0G>%B_5T2;VxuLST3({FS3@L;By#RZo7ks&6XcPOa8HBQ{-ORQX~tDBR-S}% zMk~i^VJxwe=OB)MIl&{Zp6Gg_QMIAJtc3zGYI#dEdkePjW&zuPzb6?y6C0JNOs#zGawq!tXcJ9FTk-;4G$GuT=)z>sAJw+sQE|E0G zwY8@-P%GMxa~6^~NOj7#cNGi40P)e2>y_!tevYA1)5kdN6jo^EjaLk$j@jH-!5AN& zmDJWfGW70gXGfZIdIo~5iD0Dh*+vZ?Tn3AK!1m%EYL1oX3@H&LrsM;U&nl9v%fWc#B zELS9ka(^QMMn3%YZoB*@hgFG%26|RN_U^++EDJ zs^nUPx@D0q8&cPjCOxTZvqVqiFu@=7=cm4)*D66xsQQD^mMZHDGd#MLTR_JoZTeNB zAgZwUd$$sEj1H*Ru2pL?EjE@)+s|#MP_k{$845@T@Hp!DTynW7rmxYjXZ-yM<1<5+ zKMkhWs($PEFA@5}ThVuQSla!Xst9SLR*SM1XcA>fW60!@ob!{8wx3g@HOE@8X+TaH zVv427qevUtK_X4SgOV^Y?g#DF1}j4t=L|4FCz0nJ8U$9~Y;iKX{(#sy{{TVu`0Gc( z!ZPMsehlNsWR^ZxtNZ;+gtujm(v3zq;AM+?Jd+{z4oA3T20Y+f*}B1aej&kju28Q{aP-{+)5sx#gzU|AV63TxX)G^cPqtJB05|jP>22d z7CV>hP@TE^AGgO@NnXa0bhRwnC4^T9#6CvWUpXIR)uQ!S{)uFc79fo0?fdmftEpQ6 zDX`%`;Y=d`0FvXTb@iF+5M!E6hxM*=k^3Gx%1QJsGzou8nsjMJe`52!q(uY!lhk^3 z9WbPoy+?98m1Sir62iY>z&`E3=f@Zs>rFs3@|Tswo4v^Y00mEi2gmL4&OOJU+oSBmN|X;wP^!#U#%Clu7aXwiFgjIh)ZUuYl4#V%^2VjRXuHTc{{XK&dXVBiKC#stv*F$* z)P(vDwWLFBX;_kabzE(ldeJLNQ|vRq=N#vynwGgz#j>=WnzUnVWsmkP&&l~cM+6pi zinE$>+ zwt`A-Y=@*25G_e9%2A{4NebWs7uu)JKhX8i{ScznqHIR;NgMDbU;`ci8OH=*{{Wv< zJsob})~V?Xv81vxLc8TyQa#wuzrY8cPhA^Ec_Fv_nKbK5X1$)$L0L@sZ07-&JMsv@ z&spcq6uBFxSL|zt4F3SyD*Ahu8=6AvHo=ESI&?6?6s#7SN3kG3sfh!RjsWT15noTG z{JL6=Sryowk#1>89D9%F@Nv>9wW)M{Np#BzD$NR$JV=|~6#$>=ZO8|2xZs=*IPuck zo}{#F%c&YxD{0LXPxX3~{{Tk|XFs5_?_ux)1C!UE9I$XnJw1P&{Eo+mFEi$jzLogc zzTdG$>J2jesK zM+h{kgm_)!1GY__$Vx9H;c>vu?D6LQp^u2p);u2f)7bPl8DYZ*JdU1~-(RWFyRx461O!ORwsFDEKg-Wt%hcYL^!|lz&YNZn5YI_frkx>{%h*hQ zrO8!5eC{CpZ3jIe*L_v0)|SPOQu>ZvTGjShB&%M_F=+`nl$JXa0F?j?V?1=TOZC^U zEn7`Ouc`HT=2+(u?$xDYsDpc{8OazKZvB*v75<`4&ato{Zg(fQ8ew=0eYqsy z0o9jD^w+4pNoFY{mKxe^YfD~^p>T;|E>wb%uv7I?oaJ_9eZ29WpAmUr;TdwzORn7~ z?WdVIU&E4|qj2-@SNoMK7wGABW4CY9wqY+L?RjMqi9o_{VplAigD}A7BLwFiHHz=7 zuH1*v+GR+fYY!3nW>)~LqXW9~va$ylB|scEpN_j%q5lAadPk;f$*XJgN2_YCp;*lZ zYO4p_uiM%Tk^_%-#s<)!b*=vZ;bost`kPR-M$Nh@EbV6AtuTm7C52Kp!w^Cd6@Vp= zx%Q8CGuDqXjB9qjh6zS<@Lqm`&r^Q}(k&xPrClM2*N-yCS|pphZQL_RxlqKW2oCLl zyaD&K(y#nPw_Zf`4N)a3$dQVaFQrznt+koiu+P9b3Z($X4?J||Lm$LQVa>f;)AG#> zj~ota$fO`3D-jzIatDpW2hMt3sCuhc(v0>!N$UMRI+dZ{JL%d}ZcqtQTYIoX2LLex zC$39xXQ!uI`s!-sS~YTBcc*;|K9Y$AXzpK*YI50x23r?5zl?2SPS*4Nv-ate*wLUb zG;1Aw!Z9IPeY=N-+xH_LFfa$6xqEuk(B{Y1)AbGi08w6ncP(o0t>UG!Ktfc<7qsJt z91)!3JyNyrQ2M&gr#+GCOBxjgk(pzT2Dt8?*4rpdp(ETdt%3N)I;9l1(2JAP{vEeo z^(L31)M+kBB1RKqGR&yV*x^*S$31dSTK@nNSzIM5@y#CC(Nt=TBn6k`M)}4GKc_hB zpX;B+J5tEEt@`e3mR3;74NX41LyUV!j%beT5P!r+j~;plP1UqdRBAEF>OFf`v>-*6 zdUX~gnpm^%3bDnvBguXE$LEfzu0-b~>3Wq6eA4Aj4(Z$1JymiVT73JfiTCzDo4d!f zE=j|XN|FaT`TqbXbbTZIu8m{rPe9sk9eAb|RUEceSg^<|laRk|htf4$8eQs|)|+fgsKqgw zH!v}dyRSIf$%z>7O5m;!BR&by^mzS8s?*XeNv2a9i%DwLkg+;|zVK2u!(;v>@_FZ_ z+WJ+gb>pk3Qk83#MX;#p8VJeSsva~fNWuG@fsT0Y_^^NYrPE*S`J77}m;SAc{Z(IC zwvhUY?y*ANp=lmRYO*58tG|VvFsl(Kg#Z9NAJxTvpQ$bBm!`gv(fZ^FtSwXp5HoWj zRsNXTa6!QXj12f+HJU1ZiFJ07cB00@FQ*G3KII|CcKd;0z#losR~^hLGm zC}Ne~?bL?M4+nMEj>JJhj21=(n>>{PanDKK7%Xy+GJaJ{datzte-ch{bl08h-%t%N zP?K2Hds@e-D?uEQ7PVq((#sPxM3})y)H^pJRe%5n0RA&uNY$C{+0cC>sCHliTN2bV zh}8+m45&y*$svGpPaaQ9Jv-@(mE(`qSA93GYm_ZnuC(e=VF8-SCv!*;8I&OQKVNnm(T+-Ve*W_Q7pIXGX_?F4c>s=4bQ zPP`12H7j-^o*v(FTGgUem@pxg04E16$-{Z%at|6htaa?6le-&8dyTcW@JE1H92|b* zpPr#zQP2c|5z(Ex1!$v0Dp6uTy&=IrrrMl!@O$# zveOpr9Y0Ogwc4=4sBR&Z5#nGD@*DDU*asYe=c|{e{bA`O(l4&Qn$EFWSbnaeO|2OB zq*#nH<}!2c!tsDkJgIKJVuH;xVm`#7;}NWqyvejHg zwrSO;D&-V}&$O=44-(%cCABD^zBPB+0ao^ zA|{F%F3K(Kl}-VTP^lPPVc9u37~meK)$De4zvXdi)9RJ$;s{zBp;)m}K-g74UgI%k zDoFPX=bpIbEn%w6bqYP?M2oVrGR9d;CNYNK;O7mDf%ZKcLt52ntg=+r?L{q=5I1T^ z-0`2(nIEVUM;|!(2dZ2Yqt@wl?(`w?ae7zNzNchwPWplwsA+FWVV*^n!$TaQ+yXGF zq&shvuOc=3f#<6yroVSs?yT+DWj^StWw1jfil7wQd~F)GlgT2dB>1PTz5nD z4LuAeZoJc9XiC8B>l{!sXM3HblEj<>2*AnDJX^gn{8Q9xY4Ft+CDDai)*9uyjU)>4 z81Wo^h=$hik*l{XNi1+P*9RMqjf@(_TX=ijU$=?Z!%u~qx#`__d-xB2f}Nz7Pt~+p z;JFNJb2)qqoFOG8q9U{N>fzUq?A>8#errn-q6gc+XRz_ zEaaa6j1H@?e-&X?Y4s>>NhBT3)r%4J8QKTETy2!ANtfDjjt9G@x<~$ymi;eIX=wU# z6^6n+NUKQ zZI_vM4a+)6I0Pu%pb$<7AY{Yozf<~4)E8#2sn?zmAduR#X1WSAWaqZUl0*o>fy0nV zBr2nMHtS!+&*61CcC_mLuk@a`^#)k&&v(-EC7By=F}!>L!yB{6C9vEN99gpG$0vHh#uJwBDC0~^DpYBHMbAh{CTjd)fb<^8gLNX`hz z=;{>c4^OtKp))4ervt`qkg*2-4ip!i=I6WyfiviAym!88P#> zk>vI0Pm0MXXr$@uqkVR+zm?!|!-j-qx>vTTd*5iA(jKmx(K?k&T6USH%+l3)t=E}W z!Wu0b7VfzvgOCZr0fiuN-Yc5Vs@ql7r!;*uG>bM$l&_~pEG&`uQi-^^W+WVQ$RB); z(W-ir_$hvcT?0_{->Ss=7Mj=L)P|l|O-4_2E?Eh37rlaTtQS5p*8ue$pG`p@{@KJ`(#QW073 z6-mz5*aq@^c?YLf{Q;;=u0^HjM#i%=!n&(h*)u(f<5@NeWA|DM745 zpnAJldK1!E=vqOi_tu+7g5k3+ScoDuEZIP2H{05=XKl6=Xlt!}*+@OjIG%ay$; zr(HGo{?2s;hlbrdf>U8xe^J>&H%Uru8 zR?JSRAvq+1!^!01&s~>R&^aoKlGDHz(j6O;b{ z4?RBgZJ*%%9Rt)lR=w$cOI_D>dY?&BSynkI!tBHPp;7lEj|(O^$>e7pRzKCFfHk8Tk8kaMgVY zsOnd&%jnHA+?Aq3B#`%#XAh9Bkp;ub26zE?V?KQKM-j^lvbN>h?LI~b_&;OU(qQ6o z=Z(SZ;njMdJH&94!2V_E`aeUbdRlEFUc{CX2SoC!*kaxeM_qeO)O6;r3@HL+0W|RpBdxv(H^GP?Kh;X$EHBCUUbNYGm_akB;*hVJpBE+J#vcPuhaDi zq>{Ym7an2`c9HUMe1C5}PWOFPsm=VdGaWjnBZnDO{XlcH^T*?^Pk~O~L$Bhh(_1Rq z)}3Qt)UI2xq#Yu7$u?8mh?qX@%EKW1PmmZon{3|q_7cIK(a>2>9l>%0OJGTb7Itx3aFSxJm5ZVMES zNe2ThxDY-`9TR)e+Dve)^(w+pwjFH8+>AC30r2baGrRA{T)*VP_BwtHno7=br%kA7 zZQQST#w1TMKN5gPw;wp;f;zZqTK$;9#VbZvfLn14>OR;R8T;csR`oQ~XxW;by&_#M z&^RkvQt@-h{alg#`eUT&^Gc#v989cvSeys`>GA$u6O3o8L&rJ8M0L+c>N9G0qpv{; zl;omH=tc*DxZwW))2^}UZEjjt0=$3J1eU>Jw;p-_0LQPMwC>q4h~|XnKhtyw!H37# zo;tc{exk8JtX=t$3gD{Alwf}zG4uVi*PE9MZr6V2emwM&m)H6}oj=4L?M1B7#)}{Xf-uEVLCb$8D@^W{s;#rG3NOxf`4V&j+Y3YPVs- zC5D(c>6C&8{V+Jk$?J+Sag|jat*0AK!>ns}5r5jNSFoIdjGI|;^OeEqXgyO|n1W}o zjGV0GkJ|(umK}TsRYvdI_*6~H?%l7`S|IYSH4(0httZe4i#0KkNS0EqpPdPi!jDP zCnxjPOr%_DcI*$Pu`g~iODpnwZI3*B9|!#YI`sNkT~LlHYb+Mpevl8G%S+QQ(!yB;(*7mwj}W zRj*mK8)ue{4{sSb0YDh(1)AHXR*A!JZN*2G=kJfdT|d$v!{oQ7!D?m*)_EdC=Wq7^ z06hJ=`UM<#ppQAubDM03(${qT5}RvPnAz5>Bdjri9y+U>86^9+;Ql%@O}l9#5m%aN zwF`0{<|AVAJLKg@gN&YjKi8{fpXeV=>6DrE!z>F4-;pySh0n_jdB={HXT(SxO0Iv{mtW|OZSS;R1EsXQ~{0^@kkI}V1Q+le8rZmc} zdUI*gRp$@L~>y~~p#4K$l0pUq1xHtr6wW?}uMdy|}sU3!M5uafMFu}qr zdBWq|2RZopxBBzZ)ihsN8pLST&5q3R*3xXG#|WH>n6UtiV1P>z;AG^lv+7IUo6#&r z{+`e@g_Zl!Skx-3-jE3}uKTx2cM!N4QN}PwTpR{SP75X#eD2>(>+xRacN-TL;gVI# zsdx7T^v|b#ZR$&>U3~(3YQ##@+n?!RX9vmoKiFgK*1oD;VxF&CM76EfxioQ^rJ<(6 z@x@v%C3}Emj02Yc0A8%Rx2m3>r)ki;uH1@S;aXcQ3d<@x06;K}y`=zyz-(j=bDouY zV?~QrTZ2f{BV7thTkKqvs@l|JPxpw<+ju8AQrJ>JCyaIJ#jV<;ygU3+*qC-W3XghWO^1jx`-d8v3uN%sMm^_PCZ$=|njV9uz3X0Kf;q zB%eK5zlSxoO>)Md-kX}npXo{v$gwoAh^1m!9^ZHk#z#3I1CXa5J#z7!EO@+bIUbgu z(`|fu^g4KMCGhg*j`d$&=(kVl`SqPvdp@eZwx~oFcUqO9jL;_NYLOOaN}8OHDAMC70=x!70h>FH?`ZfKG4Ea)fMspOEOo#!>V*{LXlhHrSZ7pxEoX#RBN{4U@ z1LPbJfDhltL1@>~&B>yQmaO`2-SOYBjs(tmSn&A3_}z?jZ>hDtA4Aht*Qh0EAd?XY zlDV*CIl?NUf?VW}3V&{*`XX9)Y(+n;{XW)f=^A#u6|GWPo*K~_>|Qws19}3ktH|W} z!RRkfEt9KimUXJDRO+$?s>+BW%wd(KRhtf~#AF9t^O5t{HKXahbJbp`wd$|o`s*5d zP;+2MG-N%O7*~w;%CU`rI9%|2fzE9|$vtQ5C?mD}O1Dyyw2IMbutpX?Y5fk!?Ifgq zf&SRfO=C&_0JpdC{{Tyrxl*O?`#<|?3YMC#xvI4lY}KHw6_X%rX*2BP^TQvu2R(Kl_ANS;l_+V695JVL zB8fywRN#^n<3D_#7#(oW;#cuU)Lxm_W7ACfGQ{yT#-#FQM@GmCD?+3W0Xt8e{yMBl z^V~_CoR+65t9WTT)RPylq-pE@NorlL_n~mP{+y~;E%Wx|kDjkkYC0~1=~}v8nWE{r zxmGKZ-l4R?Noi5miewP22{$Na%nbFdKu;Kf}?Q zRjpDuOaA~bmN+gV$1S0w7D)y{%QGBg9p9sGgMu@~aXdQ6l;rDOyld|F>wme^!{>3h zCGX*XgQ@8H{q09exK6Jav}HCPykx|)qu^{Q9uV>wh+%*MIT^v9OVp~+vh!5a5!NZ| zEou{17Sh({;mSAx%0}5mRBnC5V>w*X$EkXEOVcXJr^2w)z_A=L_a0fMZtm13LdIEnA=n%ffJV?wDmf&b#dxhr9qD^U zBJ%AwmGwEcxZE74`4TX=BztorakU@%yM@0J+TdO)B+UMv}bJfE|k%<&P+Yj_Frb+N9?h+W{z@@*PcYdRAUP$e0exN zK6pI!WA$h8yHfS8u)5y2=NX`y1$6XMI9I>u^TJ=e<<#*7+dH5fQ)N*Oj z)BePjtZkiUoIhq%KrI}NE- zMKT;^*AW-m6a(^09Ajwe=`g~OT|6Z=2E{0=vCGiPcGh>90_ zJj#uX{*uK3PBZXMdd+E`Z9z2MEn-)gp1}INY$uflM%oGRGsng}qHI(b?w+)sRW7d$Lh+dPyhi=NFLFixG?cNKNV^+ zT6i`4>UCw|^5Le|{rVUB`fig7)sa>^v9xOH_9Sy(aDAkZa2a;)_T*<7<2_?l(yrLj zVZ36lYe-~BqN&@C720=p@T9qHki-&50|4WWsx)b7+ImSs?xR{ZnT)893q3mk3^Iw; zjxZ0%@-Tc3gG*3Dr_60@S81t+N2x3^?}~dE7>$?}!m#IX4S|n6Q;xjXefP0E&bd)x z)G0WGRV%UP2F-<87^)0yRUq+$`hx?)pBcdDSiY-bNhNC+sJC_mLfadDb0=Ys_`w6< zlbi)UdK&V2-%PI#rD8f>qtoS3(a&DkmD7Gx8HKX1fPM}D`~$pzSIfWQ)TUVV1`{d~_)D$K+}E^%|3dsV0qTOKR-Gkcvqx9nmZ%ypuCZQ)boK zf~ROF>^Ag0s*=pI$!(_1bd01c#F8*zs$EVBs7#EHl^Ea?)VDRty1f*N7-`UxVRtmD zJZ--`1|fnFa2FwX!SR#Q+xLA>9c{X#mdY(?)g_uf;q8I77r1!wp<$X)BSNu>7$;{S73~!m37!WzAZ_U$rE?u}&arKbV6h1Nwqy4Vy!&!<(|6Ex z#{NqcFIRTt)M`d-Nm@BjR%drvBAM7>wkQljE()^_eDu`ghFZSs%j`D?nm1k8qfGTZ zsth2b1DU4gY0x)*DETb09N`IEcLS@bTEURa++_4bi)PVPaPf2YJ_^t6iD*|~6WxbcDW)mqIhPCBs5K3bu7ju{n6 zg`0xmSa3)L6Y?@M*6>_E5%VR#ji>iH=Ck3``&~Q^ldk^&6#Yf&y=n`7tJkE}<*yuT zHL0T7-KE;ad@B&X06tHTIqRe8AH{Fs)}!fqo|?7%J<*jVwQ9k>(@K_AkyxlZ8JSB* zj2syEV32Tn`LaDu%6&uklMIDRNk6-s0tq~~9Ao_YE)8P5dTYXDbhc#u|(YUiuF^xv#P{0MoH-ZQtDfz(ZjXQtAuU^FVyPRE>$gg0~igu?Rwp%WV zDzY{mGuxA4C72P&8+PDz6(3(~r55g=95I-kEzcyD8T)?qKtJAYs?B%j8~k;$1M{KpX_?QOZ-ap536UAFH`!PQMILu4=UB8myRf!LhT|)A;oY8-*F^- zoa3PVNBmaPb&WbtNNE0v(W&Wi;1JaywPEH=1bHom5}nF9E4TGGzyNl`^)4b+9GG?M zPei@d-+&!6d7qjJTTmrGi|qu8_hOV?hMo~*B}dY07o_Y%=d{Wr#cz&TU?dFu06 z=+~RQr|O|MF62-F_nv+@{@-r6%$}a~9Das|eO`^4{-nJuv(kE3)#7+ng5r3b4&R4h zR1!f^ft>WdA4*qE7Phyidh(PJS+dpE3qoqdGA`o9!m`IR5=~w?o3}Kn2E%MIc6iaH zib(g9$0d#k_!tEIj+1I$qN$}Ssv$MlGPA0`WJX8;4mOjXKel?IR{kaG(K9xuRvRqX z1Ssv2yK&CZ`yBo{DEhzCc53zxoi%)orYM4hWeb1~2qVYG&+XRH!qfScnaeV3L6)Jc z=@zOy6eWq(P_Tw7*WnhGu#H0GTSp8I@Er$mD^LI3xVW->#TS5LDTWl;-UcXkMm` z2p8*%86Hbv)p77~)z?Yaa;R#;vH&+2<&b9{7XS?W{{XLC`dto6h+~SyYbx$H0-GEG zf=*9?=lr^kEmqwp3L$jvGVMt+2Gihxe{qhcSmQtSDNVyk9m=(;(>5MtuIhM+hX)Ec z$?G@o*l3DE3}MCs?)LNY2+u!**DHTp$=qmWWt|M~fa4``f%?4X`}D_8^@JdWNnc?; z^mz*=3HT?U^Xrx2lGU9nDtZ=MHg#&y$pq$gh_bVUY@-qSSb^sRo`bEbkEmCgL~;&X z0#Tcsk&-w++m4!Pn*9lmM5?48(0#-A>6E%&m8dYWVgTfWwYH1`f7G9!Jw?T7Bwx(+ zix#H7u=XKUu@sBT_Zuosaxss_JpH=1Y1-8Wo;7Rev1}jJXpVEY{t=Vss+GS>SVbnZ z>pXZkQg)I3kDv4DMU59$uFLf4Ay5HgMmCZM&r>Wgn$gjuc!|SStn8Y0v0ZFNpHi>1 z@Kohb8OZtR^&MeAMmWYZ?L7HEez-=Ht6!yMndKlNG0FD<@zt+O^&{C>o4p=Dw z+pHzSxa?@Nscxw68b-Sp1tlZ!dUYnQB#()RC+vFSbiG8Cw#d)8WCM)yPmlahO;grU z#}c`fj^VfhKYVr1EK=xhrxbp8P}7S@5-S^KSj6lkz(M%je4qZ^c27q7imm#wy5AAm zuYkbH0|w6o=l=jBs-*D1-kFj!1bbkvraxfHoc;XuLW;!cMdnEgySCC-jtTL{Ud-3V zRB%V+XJPeTm+J3PY9c#!RB4iBS>uzs*v}=8!8!5cj(Vv2w#0fxICLLPY8p*I$j@aa zxFng%_REJ8PPU;kR}A=$tru{ap};2xFe z@2jEeL7;yQwHsPbcDpRr6Kt#%_bB({b{ShA;XHnY9S15$qELN5NsTJQTfJdSY6HBT z!Z%3&0IE_419@$~80yWX>K8PPA3AKmPSb~ZT@-JTgnSlkWS`vg*P7riyjPvKNWgfh`KBk(! zyA_+-pmQXK=`u#-H?Z!1aOPLh}q6C#ndn*$Gz zjoIsxdfw%!_4_i*JC?8_67zt-07gfSy0~>ukmSoJ{>-u5{vvv&yz|d?^bES1u}5Tt z<8}t{$TtEufD3cSBdV0z{;PT_ntb}5hKjjlh)*u?itbswj|IKh=bn7@wn-crJ;&LM zXP-WQ>(LagODUMju{masJEBAO@sY=mj=EGMADJT-+?^&~$Egrr1LL4*-nDMW)7hBG7zE*ftpW>`xArB;)Aoged}|suFyb01d?B%VhN1Mbs_o zex}oXKWar9cYZZBp+$uV^Tb<;TJ=_kJ6BeOUf0{(pTAouqp2_=l)z zbo9SV)46ImqgGmTYB5@O+NJkxbs5jNggHC`@;ZO%O=r`Jw@p1))Dg{IHipG9>DFu1 zmGDU18KN7TXl76xgMp55&$X(Rs_UQ2>OinV6{!_FLt`jL1u)~?!6zK`^~RG%j1=Vc z3>0g}sJgj(2@I;wzuzFvS8%j%KO`)&ooa}=^mS_Vwa|U z1+Kr-pp`zVXyIukEXGL!9nToa@>J*To}BteMfGf&rTur+7Lnt(D%q@ysH}{M!R;!D z@B-tUo_+x84^7vizNU3eD^6bIyWFi9L3UtE79ny;!1K}Gp=EDM+1(5TLo~@6m{V#2 z;|q)qvvO(Ih*GOYp0a~a)^zCZQqoggNcYyn60~+dRvar2Zb9IKkO=F8YWj!p#*U?G z74#;o_N$jdzgHc^ihN^Z1^)mM$z!>*?K$c%QCPG5H}#&HzKgX!oR*?-I(J%RlP>w( zvK9pJImcG7;J>N$pH=#=P}B9vtIJZAlME0=QWzsek~iOliBx5_jGSbSGu2lt9!=uC zi;dcX-JCaHruN_JW6|EMEc@fI%zGWbf_5j2oPrNn(RFQaNRm5{-(y}jjK>VBX0P0J zYyy&;5HXN3=Lh4jr~N_ceFDzA>Bwf%;%F;bnmDWSAXSbcQF~e0fO*C|^VJqFM0#4+ zukPvgw3ME-wes;xBf7J8QG*aq>dPK{{CMfS(a9cJEe96h`H-4#<1UTq{{T$Mr}{tB z@x*l~mK&1&G)W+mCIym3A;^aWxFD7%8<=BgrAx1CS91klPQ7Z4D?I(E%Lj{k`<>Y` zSn_wK4miO16ZnB@Z%*12bTYJ|Fc_FbiVLRVcC%wF3GXsAt<{z)aM-f75(4s9jI}D! zPa=TkBo4(k?ND1ekb+1Vz@o({wR&XLZNjj#O=;fKm+#1`StD(#d1k;T13Bc6Ar_cS z)6LvsaSW1q$GK3IKavO?5G0nvTYECR&B5Ix7h+qIa(T%=K6>oO!ovb_g0C~3@iWa% zOx@k?)@wbvezE1upr`cQ5u7du80R3L7{||73ZKIZr_!5VNr3R0uqeDke(C9@{xOOqXjD?v{6NLr2IP!TtV7Qra9CF|>zE@n$(t0f^dHxM@ zVq8B6_{@u&TCKI--+Gm~KZ_PUCFu=c&|ZqvQRCKU+o)<$MA4b6CN`u+)n<&d46(=s zcq{YQG@8T6+nu)(IT`-|UZL=(A00&CDawp^{{XLFOT%z@xK#NTuU7iE=6uf)#bx4J z=Xx!dM2(ECk_!xee*XX+c*%g-3RsLTN#pkX@&5o`p&%B)?^49d&GS^EJ3! z77vpAuiu0C9d7nFIV!^^9zJ>riBJIX$6f@sGy8OP4Tcr0_GVUn#X;qB`iGo#^gp3} zSLn!nIad`Tj=U90&XEuu3H?gNfpfWu`|t)%Fgp3L0l0p8zkd#O3zTELDo$e!3lcC6 zf2Swk{{TD=xp=%wBs~tE7bhgCEzh9n`pZQ6xU~I3y?8X45XBvIrgy0W^q;WCPI=E; zYhI4gtvp)4qbf~9QH6!7uU71^NgRN1(ctiK2aJ4k*8Y>JU9^YPo;~)SFbu9sF&}K6 zqK@62LPf1+#DXXSh~tTjN~1miOmX<@!=$D1`}v--cO6B7KV5pPYBKtt)f&r`Q5-R> zi(soJ3XlT;&$wi_9_+Sr(2e|8{w{wH^r=3x)RpCjSFzh@FI0ljvZ@Nm9c5B*KpTKN zPH<0EZ(rK8qx!B*M@q9TJ20_ik_RYrfO*HBe);N)uKJT(^$fAt)~~g>LZXL}7a()M zAaT~Q{W}hHl;Ia0>XC+CKQD;fEgr);B_yp{{Vu1n5*em^>?Lzh*dS6GEUs^-G+5_tqZdPmXTrZKtHCV ze4$hkw;4Tf7h}23d^QK|)b-|_Ysm^&l_QsFkrG0o$UGJR^N-J5xqn7jrm}Fk92Zr* zYso#Irk*J1;r{?yoYTj|#ZS*?wQF1S+`alA(<(KyEEjz@N_gfqMxm-|5k#>}N44RR zTq$K3D%^~KKs|M@Qh(^_=&dVOy)CcemYHi%Lhp8^y+wJI<1!pt3P53y5sCm=dGZ0* z_M-bws;MSTX@2>A|yB|x71Tf*gRV4M+)ob9l_b!wA zC-@PhXqJ6NsV29peS9l5T6%uB6poBGqqDli3aKH&h6D93e+6hBwASGCr1~z2u2;Y5 z`xd*jJw2$_5ZHzHt_WzuEQy&0=W+%;!wttq$^1U_dG$HdhK#FLZ9bIpLX$|S?jT7y z0l6E=Y#s?Gj(Y7M#&{`!x|-><7S5dwmZs}YCHiJqg9eNR!W`q3!Qg$m@i?wB5pcyW zY4dCIJ*uj=*Tt%TgVDjl$;why6tvT;{yd-dP_$p;zMHGl)=#THgspm{by^gX#*!}8 zuMBYkB8yNW6%Xfk_;~s2I*+IS0Q4l+sx3W3T>k*F7IgZ<>DNuUYDuK>=h-T-kdjJ) zfN`AuIM=Mdh(5RVmXGwFr1e&%a;k}fRx`3dfGXiuB*H3!0SW*a=N(n<6E2yhiCLfO zXPy~%F*}krj3WL33`ZY+x^RAulT(D{j^5Cdt-RK~ey2WuJK`r9MN7@CclsSG_{sb% z{t{?SCZp+(;&eLPT5=>8G|6ZfEHUlnjB`0D&QM`nZkt@+ zyrtn24(GJ75uMV<8UVWv7#SI`0X=4Wwya#8B$)Qv)3e<~C$mc3~;|GE;0Kpi?9ysgV;P7XL9$92^YgK=ZKRUlt z%Hne3_=)n;dU^NsLaFq*eJ`lN7NZdFg^t86G*Qh2u{g@H_cFFrj48+G9CZHxNU!`n zyK$%1h217bk+#WFNNlV`hE#QpKqXcCZL@L64ekdSzUuouMd_V)Qq>@Vr8W^lK?>J} zMlrfH$%|68B(-bN zJwClmXMu3_%S|_>{WbaswH+dD6aArX86&W(ELLi`%d6mrai3^7VYK0a#~A0Wg2dET zNVNeptsw~z4TN9Sm0)({u{lBp3WJ_{d+1i(CakhY9G%TNXiG^NyDGPBPSQatalm1M zJ_zY9wO$$;!$na$YLAcsC&(G({^$Jq>xO46j}zT>IcEiq3UTTWay>>K-P@W>&{dNW ztg=GpCv0TxcHp0$4}ypK>KS(uN$+4gnvu|KtHGBp+Aqlll14O^*S=>nnV=7uTQT$sR$~D zLlR|z4{GPn0CUe=`1sWG$A`-rZt9E*WRXEvoO#r|H`7&~|LouO6K`!omAC z=8W5ok0F%hb`{E%$PA~DdM?%YHTi7o^qQSbPP2@l7<0UPlCy6^3@PC9p{YKfg_C`iUCXYqn}th6v(kp9SN{+6wJVC?$&& zQOABi{{WfK0GdFMyKDi7+kx@;;BnQ)oE7hSDz(dXV3u~(3}#n}OO@>dg4oZV zxpU);5^`ESH0X8UoTjvUYwB6_dRoV;u3FV0gHK208rRgVL;;Nha{O5cASuWjp9%=a z7za5gJ#^n#e-al>^#1^-{U1lwNvK@1R@SV|7FHKle$-0xZdS~1jy=35ByuzPxX$eSFZm6npLUUi-?{$Jb3q(?)=w%PRURBgQt4tg|b@t!lb1rJ-Ck zbqLHdC>tFnSz~p^LnMewu;=_Itt)E!l_qgs%&3l?xfGn`G7dTXf!9OylO1!_4W{at zo~64947KsLGKX_uD&P)J7{)$2Mf_0o_L1q&RL!O6)eIGcaX3RGza?^cVo&zZUcU|c zlFOBF`4`Psrr*!!)bV(~(`CbAd`3BZw_bPOp#>jb-R?^!uN+p^e`p1LsJ|p2;Qs*i z>El`SF1bB_rzVAhNt1dJv;Yc$jD{`l;~a6w>zh~rD&vkmIQczEqq~1IPEVIVDBA`^J3uGK ze#f7ll~TWUj>{D7Neq$i+Q`^G2l@X1ey%B~S&?N&?2#lv9QG3|838#s$;l_FeDQTH zONTB>tqf?I>`+RJs3}I{5B?MTE*vgB)I+O5#w_XfBW>tIi-feBvKVqfJT2EaX8bXsXY@j zYtxX(w&$*$w=wO)gSE1HKy-`s3dm5XP*1euCvocc43F59=bUvXW+!wEfR3qVYepv& zRbsJzIB_kB7^;_H<2nBT?0VJp$!4yQ%Or~!5vb<`oxlD1lhv?9q4uuaH^C#N7LgM> SR1Q>skmIXMnOLr!AOG2%FVo-v literal 0 HcmV?d00001 diff --git a/apps/playground/src/components/layouts/image-header-and-body.tsx b/apps/playground/src/components/layouts/image-header-and-body.tsx index e5c6c74a..cc36613f 100644 --- a/apps/playground/src/components/layouts/image-header-and-body.tsx +++ b/apps/playground/src/components/layouts/image-header-and-body.tsx @@ -1,5 +1,6 @@ import Metatags from "~/components/site/metatags"; import Markdown from "./markdown"; +import StickySidebar from "./sidebar/sticky-sidebar"; export default function LayoutImageHeaderAndBody({ children, @@ -7,12 +8,16 @@ export default function LayoutImageHeaderAndBody({ description, image, cover, + sidebarItems, + authors, }: { children: React.ReactNode; title: string; description: string; image: string; cover: string; + sidebarItems?: { to: string; label: string }[]; + authors?: { url: string; image: string; name: string; about: string }[]; }) { return ( <> @@ -34,16 +39,21 @@ export default function LayoutImageHeaderAndBody({
{children}
- {/* */} + + )} diff --git a/apps/playground/src/components/layouts/markdown.tsx b/apps/playground/src/components/layouts/markdown.tsx index 5566f7eb..e92c4ac1 100644 --- a/apps/playground/src/components/layouts/markdown.tsx +++ b/apps/playground/src/components/layouts/markdown.tsx @@ -16,6 +16,7 @@ export default function Markdown({ children }: { children: React.ReactNode }) { components={{ //@ts-ignore pre: (props) => , + h2: (props) =>

{props.children}

, }} > {children} diff --git a/apps/playground/src/components/layouts/sidebar/sticky-sidebar.tsx b/apps/playground/src/components/layouts/sidebar/sticky-sidebar.tsx new file mode 100644 index 00000000..a3c1c117 --- /dev/null +++ b/apps/playground/src/components/layouts/sidebar/sticky-sidebar.tsx @@ -0,0 +1,97 @@ +import { Link } from "react-scroll"; + +export default function StickySidebar({ + sidebarItems, + authors, +}: { + sidebarItems: { to: string; label: string }[]; + authors?: { url: string; image: string; name: string; about: string }[]; +}) { + return ( +
+ ); +} diff --git a/apps/playground/src/pages/governance/index.mdx b/apps/playground/src/pages/governance/index.mdx new file mode 100644 index 00000000..cb10eaaf --- /dev/null +++ b/apps/playground/src/pages/governance/index.mdx @@ -0,0 +1,29 @@ +import { useState } from "react"; + +import { checkSignature, generateNonce } from "@meshsdk/core"; +import { CardanoWallet, useWallet } from "@meshsdk/react"; + +import Button from "~/components/button/button"; +import LayoutImageHeaderAndBody from "~/components/layouts/image-header-and-body"; + +export default function MDXPage({ children }) { + return ( + + <>{children} + + ); +} + +## Intro + +With the adoption of Voltaire, we have created and followed certain guidelines and directives that will help us make our decision regarding governance actions as a dRep at the Cardano Ecosystem. This is NOT a document aimed at becoming a large set of strict rules for the whole community through social contract and to dictate how they make their decisions. It simply contains some guidelines we thought are important and we abide by them to the extent that it’s possible. Meaning, it’s a subjective assessment which we use and participants of Cardano's governance and its partner chains are free to adopt in order to make their own decisions. + +## Principles on Treasury Proposals at CardanoGov + +### 1. On-Chain Identity Verification + +Whenever possible, proposers must verify their on-chain identities to enhance trust and transparency. In cases where full on-chain verification isn’t available, proposers should make efforts to prove their web2 or web3 identities through alternative means. The reason for this, is that a lack of a verified ID, makes it difficult for all proposals to prove on-chain and to people without first-hand knowledge of the team, whether or not they are legitimate. Also, it perpetuates the risk of unknown malicious actors pretending to be other characters with a better reputation in future referendums. diff --git a/apps/playground/src/pages/guides/nextjs.mdx b/apps/playground/src/pages/guides/nextjs.mdx index 8f302173..a24b8f7b 100644 --- a/apps/playground/src/pages/guides/nextjs.mdx +++ b/apps/playground/src/pages/guides/nextjs.mdx @@ -2,12 +2,17 @@ import LayoutImageHeaderAndBody from "~/components/layouts/image-header-and-body import { guidenextjs } from "~/data/links-guides"; export default function MDXPage({ children }) { + // const sidebarItems = [ + // { label: 'System setup', to: 'systemsetup' }, + // ]; + return ( {children} From 8567f7194b8e89866f16ddde583eacb4f74ac2d5 Mon Sep 17 00:00:00 2001 From: SIDANWhatever Date: Thu, 5 Sep 2024 21:07:55 +0800 Subject: [PATCH 07/17] feat: plutus v3 giftcard --- .../giftcard/aiken-workspace-v2/.gitignore | 6 + .../giftcard/aiken-workspace-v2/aiken.lock | 27 +++ .../giftcard/aiken-workspace-v2/aiken.toml | 23 +++ .../giftcard/aiken-workspace-v2/plutus.json | 77 +++++--- .../src/giftcard/aiken-workspace-v2/readme.md | 55 ++++++ .../aiken-workspace-v2/validators/oneshot.ak | 164 ++++++++++++++++++ 6 files changed, 324 insertions(+), 28 deletions(-) create mode 100644 packages/mesh-contract/src/giftcard/aiken-workspace-v2/.gitignore create mode 100644 packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.lock create mode 100644 packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.toml create mode 100644 packages/mesh-contract/src/giftcard/aiken-workspace-v2/readme.md create mode 100644 packages/mesh-contract/src/giftcard/aiken-workspace-v2/validators/oneshot.ak diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/.gitignore b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/.gitignore new file mode 100644 index 00000000..ff7811b1 --- /dev/null +++ b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/.gitignore @@ -0,0 +1,6 @@ +# Aiken compilation artifacts +artifacts/ +# Aiken's project working directory +build/ +# Aiken's default documentation export +docs/ diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.lock b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.lock new file mode 100644 index 00000000..a985644d --- /dev/null +++ b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.lock @@ -0,0 +1,27 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +[[requirements]] +name = "aiken-lang/stdlib" +version = "v2" +source = "github" + +[[requirements]] +name = "sidan-lab/vodka" +version = "0.1.0-beta" +source = "github" + +[[packages]] +name = "aiken-lang/stdlib" +version = "v2" +requirements = [] +source = "github" + +[[packages]] +name = "sidan-lab/vodka" +version = "0.1.0-beta" +requirements = [] +source = "github" + +[etags] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1725541389, nanos_since_epoch = 166667000 }, "d79382d2b6ecb3aee9b0755c31d8a5bbafe88a7b3706d7fb8a52fd4d05818501"] diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.toml b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.toml new file mode 100644 index 00000000..e63c5800 --- /dev/null +++ b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.toml @@ -0,0 +1,23 @@ +name = "meshjs/giftcard" +version = "0.0.0" +compiler = "v1.1.0" +plutus = "v3" +license = "Apache-2.0" +description = "Aiken contracts for project 'meshjs/giftcard'" + +[repository] +user = "meshjs" +project = "giftcard" +platform = "github" + +[[dependencies]] +name = "aiken-lang/stdlib" +version = "v2" +source = "github" + +[[dependencies]] +name = "sidan-lab/vodka" +version = "0.1.0-beta" +source = "github" + +[config] diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/plutus.json b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/plutus.json index e0dd61ff..69d6487a 100644 --- a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/plutus.json +++ b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/plutus.json @@ -3,16 +3,16 @@ "title": "meshjs/giftcard", "description": "Aiken contracts for project 'meshjs/giftcard'", "version": "0.0.0", - "plutusVersion": "v2", + "plutusVersion": "v3", "compiler": { "name": "Aiken", - "version": "v1.0.29-alpha+unknown" + "version": "v1.1.0+unknown" }, "license": "Apache-2.0" }, "validators": [ { - "title": "oneshot.gift_card", + "title": "oneshot.gift_card.mint", "redeemer": { "title": "rdmr", "schema": { @@ -29,15 +29,34 @@ { "title": "utxo_ref", "schema": { - "$ref": "#/definitions/aiken~1transaction~1OutputReference" + "$ref": "#/definitions/cardano~1transaction~1OutputReference" } } ], - "compiledCode": "5901f5010000323232323232322322232323225333009323232533300c3007300d3754002264646464a666026602c00426464a666024601a60266ea803854ccc048c034c04cdd5191980080080311299980b8008a60103d87a80001323253330163375e603660306ea800804c4cdd2a40006603400497ae0133004004001301b002301900115333012300c00113371e00402029405854ccc048cdc3800a4002266e3c0080405281bad3013002375c60220022c602800264a66601e601260206ea800452f5bded8c026eacc050c044dd500099191980080099198008009bab3016301730173017301700522533301500114bd6f7b630099191919299980b19b91488100002153330163371e9101000021003100513301a337606ea4008dd3000998030030019bab3017003375c602a0046032004602e00244a666028002298103d87a800013232323253330153372200e0042a66602a66e3c01c0084cdd2a4000660326e980052f5c02980103d87a80001330060060033756602c0066eb8c050008c060008c058004dd7180998081baa00337586024002601c6ea800858c040c044008c03c004c02cdd50008a4c26cac64a66601060060022a66601660146ea8010526161533300830020011533300b300a37540082930b0b18041baa003370e90011b8748000dd7000ab9a5573aaae7955cfaba05742ae89", - "hash": "0c0d17d9095fe6b07a2727403e2c6f2dff8042ed7c300cb67a2577a2" + "compiledCode": "5901ae01010032323232323232232225333005323232323253323300b3001300c3754004264646464a66601e600a0022a66602460226ea801c540085854ccc03cc00c00454ccc048c044dd50038a8010b0b18079baa006132323232533301430170021323253330133009301437540162a666026601260286ea8c8cc004004018894ccc0600045300103d87a80001323253330173375e603860326ea80080504cdd2a40006603600497ae0133004004001301c002301a00115333013300700113371e00402229405854ccc04ccdc3800a4002266e3c0080445281bad3014002375c60240022c602a00264a666020600860226ea800452f5bded8c026eacc054c048dd500099198008009bab3015301630163016301600322533301400114c103d87a80001323232325333015337220140042a66602a66e3c0280084cdd2a4000660326e980052f5c02980103d87a80001330060060033756602c0066eb8c050008c060008c058004dd6180980098079baa007370e90011bae3010300d37540046e1d200016300e300f002300d001300d002300b0013007375400229309b2b1bae0015734aae7555cf2ab9f5740ae855d11", + "hash": "401c967008d42885400991f9225715e1c3a8e43757b1fd36a1328195" }, { - "title": "oneshot.redeem", + "title": "oneshot.gift_card.else", + "parameters": [ + { + "title": "token_name", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "utxo_ref", + "schema": { + "$ref": "#/definitions/cardano~1transaction~1OutputReference" + } + } + ], + "compiledCode": "5901ae01010032323232323232232225333005323232323253323300b3001300c3754004264646464a66601e600a0022a66602460226ea801c540085854ccc03cc00c00454ccc048c044dd50038a8010b0b18079baa006132323232533301430170021323253330133009301437540162a666026601260286ea8c8cc004004018894ccc0600045300103d87a80001323253330173375e603860326ea80080504cdd2a40006603600497ae0133004004001301c002301a00115333013300700113371e00402229405854ccc04ccdc3800a4002266e3c0080445281bad3014002375c60240022c602a00264a666020600860226ea800452f5bded8c026eacc054c048dd500099198008009bab3015301630163016301600322533301400114c103d87a80001323232325333015337220140042a66602a66e3c0280084cdd2a4000660326e980052f5c02980103d87a80001330060060033756602c0066eb8c050008c060008c058004dd6180980098079baa007370e90011bae3010300d37540046e1d200016300e300f002300d001300d002300b0013007375400229309b2b1bae0015734aae7555cf2ab9f5740ae855d11", + "hash": "401c967008d42885400991f9225715e1c3a8e43757b1fd36a1328195" + }, + { + "title": "oneshot.redeem.spend", "datum": { "title": "_d", "schema": { @@ -64,8 +83,27 @@ } } ], - "compiledCode": "5901320100003232323232323223223222253330083232533300d3010002132533300b3370e6eb4c034009200113371e0020122940dd718058008b180700099299980499b8748008c028dd50008a5eb7bdb1804dd5980718059baa001323300100132330010013756601e602060206020602060186ea8c03cc030dd50019129998070008a5eb7bdb1804c8c8c8c94ccc03ccdc8a45000021533300f3371e91010000210031005133013337606ea4008dd3000998030030019bab3010003375c601c0046024004602000244a66601a002298103d87a8000132323232533300e337220140042a66601c66e3c0280084cdd2a4000660246e980052f5c02980103d87a80001330060060033756601e0066eb8c034008c044008c03c00452613656375c0026eb80055cd2ab9d5573caae7d5d02ba157441", - "hash": "39faa048196bb6b30f50815475e9d16b22e7a0ef6de5935b408ca617" + "compiledCode": "59011501010032323232323232232232253330063232323232533300b3370e900118061baa001132323232325333013301600213253330113370e6eb4c04c009200113371e00201e2940dd718088008b180a00099299980799b8748008c040dd50008a5eb7bdb1804dd5980a18089baa001323300100137566028602a602a602a602a60226ea8020894ccc04c004530103d87a80001323232325333014337220200042a66602866e3c0400084cdd2a4000660306e980052f5c02980103d87a80001330060060033756602a0066eb8c04c008c05c008c054004c048c04c008c044004c034dd50008b1807980800118070009807001180600098041baa00114984d958dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "b2386630f1b210c58d0e46f132e931b362c3f373685118018e4d956f" + }, + { + "title": "oneshot.redeem.else", + "parameters": [ + { + "title": "token_name", + "schema": { + "$ref": "#/definitions/ByteArray" + } + }, + { + "title": "policy_id", + "schema": { + "$ref": "#/definitions/ByteArray" + } + } + ], + "compiledCode": "59011501010032323232323232232232253330063232323232533300b3370e900118061baa001132323232325333013301600213253330113370e6eb4c04c009200113371e00201e2940dd718088008b180a00099299980799b8748008c040dd50008a5eb7bdb1804dd5980a18089baa001323300100137566028602a602a602a602a60226ea8020894ccc04c004530103d87a80001323232325333014337220200042a66602866e3c0400084cdd2a4000660306e980052f5c02980103d87a80001330060060033756602a0066eb8c04c008c05c008c054004c048c04c008c044004c034dd50008b1807980800118070009807001180600098041baa00114984d958dd70009bae0015734aae7555cf2ab9f5740ae855d101", + "hash": "b2386630f1b210c58d0e46f132e931b362c3f373685118018e4d956f" } ], "definitions": { @@ -79,7 +117,7 @@ "Int": { "dataType": "integer" }, - "aiken/transaction/OutputReference": { + "cardano/transaction/OutputReference": { "title": "OutputReference", "description": "An `OutputReference` is a unique reference to an output on-chain. The `output_index`\n corresponds to the position in the output list of the transaction (identified by its id)\n that produced that output", "anyOf": [ @@ -90,7 +128,7 @@ "fields": [ { "title": "transaction_id", - "$ref": "#/definitions/aiken~1transaction~1TransactionId" + "$ref": "#/definitions/ByteArray" }, { "title": "output_index", @@ -100,23 +138,6 @@ } ] }, - "aiken/transaction/TransactionId": { - "title": "TransactionId", - "description": "A unique transaction identifier, as the hash of a transaction body. Note that the transaction id\n isn't a direct hash of the `Transaction` as visible on-chain. Rather, they correspond to hash\n digests of transaction body as they are serialized on the network.", - "anyOf": [ - { - "title": "TransactionId", - "dataType": "constructor", - "index": 0, - "fields": [ - { - "title": "hash", - "$ref": "#/definitions/ByteArray" - } - ] - } - ] - }, "oneshot/Action": { "title": "Action", "anyOf": [ diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/readme.md b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/readme.md new file mode 100644 index 00000000..2c92a664 --- /dev/null +++ b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/readme.md @@ -0,0 +1,55 @@ +# giftcard + +Write validators in the `validators` folder, and supporting functions in the `lib` folder using `.ak` as a file extension. + +For example, as `validators/always_true.ak` + +```gleam +validator { + fn spend(_datum: Data, _redeemer: Data, _context: Data) -> Bool { + True + } +} +``` + +## Building + +```sh +aiken build +``` + +## Testing + +You can write tests in any module using the `test` keyword. For example: + +```gleam +test foo() { + 1 + 1 == 2 +} +``` + +To run all tests, simply do: + +```sh +aiken check +``` + +To run only tests matching the string `foo`, do: + +```sh +aiken check -m foo +``` + +## Documentation + +If you're writing a library, you might want to generate an HTML documentation for it. + +Use: + +```sh +aiken docs +``` + +## Resources + +Find more on the [Aiken's user manual](https://aiken-lang.org). diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/validators/oneshot.ak b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/validators/oneshot.ak new file mode 100644 index 00000000..4089af17 --- /dev/null +++ b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/validators/oneshot.ak @@ -0,0 +1,164 @@ +use aiken/collection/dict +use aiken/collection/list +use cardano/assets.{PolicyId, from_asset, zero} +use cardano/transaction.{Input, OutputReference, Transaction, placeholder} as tx +use mocktail.{complete, mint, mocktail_tx, tx_in} +use mocktail/virgin_address.{mock_pub_key_address} +use mocktail/virgin_key_hash.{mock_policy_id} +use mocktail/virgin_output_reference.{mock_tx_hash, mock_utxo_ref} + +validator redeem(token_name: ByteArray, policy_id: ByteArray) { + spend(_d: Option, _r: Data, _input: OutputReference, tx: Transaction) { + let Transaction { mint, .. } = tx + expect [Pair(asset_name, amount)] = + mint + |> assets.tokens(policy_id) + |> dict.to_pairs() + amount == -1 && asset_name == token_name + } + + else(_) { + fail + } +} + +pub type Action { + Mint + Burn +} + +validator gift_card(token_name: ByteArray, utxo_ref: OutputReference) { + mint(rdmr: Action, policy_id: PolicyId, tx: Transaction) { + let Transaction { inputs, mint, .. } = tx + expect [Pair(asset_name, amount)] = + mint + |> assets.tokens(policy_id) + |> dict.to_pairs() + when rdmr is { + Mint -> { + expect Some(_input) = + list.find(inputs, fn(input) { input.output_reference == utxo_ref }) + amount == 1 && asset_name == token_name + } + Burn -> amount == -1 && asset_name == token_name + } + } + + else(_) { + fail + } +} + +type TestCase { + is_mint_info_correct: Bool, + is_token_name_correct: Bool, +} + +fn get_mint_test_tx(test_case: TestCase) -> Transaction { + let TestCase { is_mint_info_correct, is_token_name_correct } = test_case + + let token_name = + if is_token_name_correct { + "hello world" + } else { + "goodbye" + } + + mocktail_tx() + |> tx_in(True, mock_tx_hash(0), 0, zero, mock_pub_key_address(0, None)) + |> mint(is_mint_info_correct, 1, mock_policy_id(0), token_name) + |> mint(!is_mint_info_correct, 2, mock_policy_id(0), token_name) + |> complete() +} + +test success_mint() { + let test_gift_card_name = "hello world" + let utxo = mock_utxo_ref(0, 0) + let test_case = + TestCase { is_mint_info_correct: True, is_token_name_correct: True } + let tx = get_mint_test_tx(test_case) + gift_card.mint(test_gift_card_name, utxo, Mint, mock_policy_id(0), tx) +} + +test fail_mint_with_more_than_1_mint() { + let test_gift_card_name = "hello world" + let utxo = mock_utxo_ref(0, 0) + let test_case = + TestCase { is_mint_info_correct: False, is_token_name_correct: True } + let tx = get_mint_test_tx(test_case) + !gift_card.mint(test_gift_card_name, utxo, Mint, mock_policy_id(0), tx) +} + +test fail_mint_without_param_name_minted() { + let test_gift_card_name = "hello world" + let utxo = mock_utxo_ref(0, 0) + let test_case = + TestCase { is_mint_info_correct: True, is_token_name_correct: False } + let tx = get_mint_test_tx(test_case) + !gift_card.mint(test_gift_card_name, utxo, Mint, mock_policy_id(0), tx) +} + +fn get_redeem_test_tx(test_case: TestCase) -> Transaction { + let TestCase { is_mint_info_correct, is_token_name_correct } = test_case + + let token_name = + if is_token_name_correct { + "hello world" + } else { + "goodbye" + } + + let mint = + if is_mint_info_correct { + from_asset(mock_policy_id(0), token_name, -1) + } else { + from_asset(mock_policy_id(0), token_name, -2) + } + + Transaction { ..placeholder, mint: mint } +} + +test success_redeem() { + let test_gift_card_name = "hello world" + let utxo = mock_utxo_ref(0, 0) + let test_case = + TestCase { is_token_name_correct: True, is_mint_info_correct: True } + let tx = get_redeem_test_tx(test_case) + redeem.spend(test_gift_card_name, mock_policy_id(0), None, "", utxo, tx) && gift_card.mint( + test_gift_card_name, + utxo, + Burn, + mock_policy_id(0), + tx, + ) +} + +test fail_redeem_without_correct_name() { + let test_gift_card_name = "hello world" + let utxo = mock_utxo_ref(0, 0) + let test_case = + TestCase { is_token_name_correct: False, is_mint_info_correct: True } + let tx = get_redeem_test_tx(test_case) + !(redeem.spend(test_gift_card_name, mock_policy_id(0), None, "", utxo, tx) && gift_card.mint( + test_gift_card_name, + utxo, + Burn, + mock_policy_id(0), + tx, + )) +} + +test fail_redeem_without_correct_mint_info() { + let test_gift_card_name = "hello world" + let utxo = mock_utxo_ref(0, 0) + let test_case = + TestCase { is_token_name_correct: True, is_mint_info_correct: False } + let tx = get_redeem_test_tx(test_case) + !(redeem.spend(test_gift_card_name, mock_policy_id(0), None, "", utxo, tx) && gift_card.mint( + test_gift_card_name, + utxo, + Burn, + mock_policy_id(0), + tx, + )) +} From ffe5f6fcde8840d549e91da57b6208c51200a0fc Mon Sep 17 00:00:00 2001 From: SIDANWhatever Date: Thu, 5 Sep 2024 21:13:46 +0800 Subject: [PATCH 08/17] feat: update v3 validator index --- packages/mesh-contract/src/giftcard/offchain.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mesh-contract/src/giftcard/offchain.ts b/packages/mesh-contract/src/giftcard/offchain.ts index 53a6d8ca..c8914a19 100644 --- a/packages/mesh-contract/src/giftcard/offchain.ts +++ b/packages/mesh-contract/src/giftcard/offchain.ts @@ -51,7 +51,7 @@ export class MeshGiftCardContract extends MeshTxInitiator { let scriptCbor; switch (this.version) { case 2: - scriptCbor = blueprintV2.validators[1]!.compiledCode; + scriptCbor = blueprintV2.validators[2]!.compiledCode; break; default: scriptCbor = blueprintV1.validators[1]!.compiledCode; From 3f3c2676cfbb1acc25287a1b622a904a60c09032 Mon Sep 17 00:00:00 2001 From: SIDANWhatever Date: Thu, 5 Sep 2024 21:22:29 +0800 Subject: [PATCH 09/17] feat: version agnostic giftcard --- .../mesh-contract/src/giftcard/offchain.ts | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/packages/mesh-contract/src/giftcard/offchain.ts b/packages/mesh-contract/src/giftcard/offchain.ts index c8914a19..a59c2106 100644 --- a/packages/mesh-contract/src/giftcard/offchain.ts +++ b/packages/mesh-contract/src/giftcard/offchain.ts @@ -91,11 +91,14 @@ export class MeshGiftCardContract extends MeshTxInitiator { firstUtxo.input.outputIndex, ); - const giftCardPolicy = resolveScriptHash(giftCardScript, "V2"); + const giftCardPolicy = resolveScriptHash( + giftCardScript, + this.langaugeVersion(), + ); const redeemScript: PlutusScript = { code: this.redeemCbor(tokenNameHex, giftCardPolicy), - version: "V2", + version: this.langaugeVersion(), }; const redeemAddr = serializePlutusScript( @@ -104,14 +107,14 @@ export class MeshGiftCardContract extends MeshTxInitiator { this.networkId, ).address; + this.mesh.txIn( + firstUtxo.input.txHash, + firstUtxo.input.outputIndex, + firstUtxo.output.amount, + firstUtxo.output.address, + ); + this.mintPlutusScript(); await this.mesh - .txIn( - firstUtxo.input.txHash, - firstUtxo.input.outputIndex, - firstUtxo.output.amount, - firstUtxo.output.address, - ) - .mintPlutusScriptV2() .mint("1", giftCardPolicy, tokenNameHex) .mintingScript(giftCardScript) .mintRedeemerValue(mConStr0([])) @@ -156,12 +159,16 @@ export class MeshGiftCardContract extends MeshTxInitiator { paramTxId, ); - const giftCardPolicy = resolveScriptHash(giftCardScript, "V2"); + const giftCardPolicy = resolveScriptHash( + giftCardScript, + this.langaugeVersion(), + ); const redeemScript = this.redeemCbor(tokenNameHex, giftCardPolicy); - await this.mesh - .spendingPlutusScriptV2() + this.spendingPlutusScript(); + + this.mesh .txIn( giftCardUtxo.input.txHash, giftCardUtxo.input.outputIndex, @@ -170,8 +177,10 @@ export class MeshGiftCardContract extends MeshTxInitiator { ) .spendingReferenceTxInInlineDatumPresent() .spendingReferenceTxInRedeemerValue("") - .txInScript(redeemScript) - .mintPlutusScriptV2() + .txInScript(redeemScript); + + this.mintPlutusScript(); + await this.mesh .mint("-1", giftCardPolicy, tokenNameHex) .mintingScript(giftCardScript) .mintRedeemerValue(mConStr1([])) From 0b09f54c911b0b897e6d2ed20687844935c9fe47 Mon Sep 17 00:00:00 2001 From: SIDANWhatever Date: Thu, 5 Sep 2024 23:20:43 +0800 Subject: [PATCH 10/17] feat: add dynamic script version api at txbuilder --- packages/mesh-contract/src/common.ts | 9 +++++ .../mesh-contract/src/giftcard/offchain.ts | 13 +++---- .../src/mesh-tx-builder/tx-builder-core.ts | 34 +++++++++++++++++++ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/packages/mesh-contract/src/common.ts b/packages/mesh-contract/src/common.ts index 4b4522a4..d8eeb668 100644 --- a/packages/mesh-contract/src/common.ts +++ b/packages/mesh-contract/src/common.ts @@ -1,6 +1,7 @@ import { BrowserWallet, IFetcher, + LanguageVersion, MeshTxBuilder, MeshWallet, UTxO, @@ -23,6 +24,14 @@ export class MeshTxInitiator { stakeCredential?: string; networkId = 0; version = 1; + langaugeVersion = (): LanguageVersion => { + switch (this.version) { + case 1: + return "V2"; + default: + return "V3"; + } + }; constructor({ mesh, diff --git a/packages/mesh-contract/src/giftcard/offchain.ts b/packages/mesh-contract/src/giftcard/offchain.ts index a59c2106..4a2dc0f6 100644 --- a/packages/mesh-contract/src/giftcard/offchain.ts +++ b/packages/mesh-contract/src/giftcard/offchain.ts @@ -113,8 +113,8 @@ export class MeshGiftCardContract extends MeshTxInitiator { firstUtxo.output.amount, firstUtxo.output.address, ); - this.mintPlutusScript(); await this.mesh + .mintPlutusScript(this.langaugeVersion()) .mint("1", giftCardPolicy, tokenNameHex) .mintingScript(giftCardScript) .mintRedeemerValue(mConStr0([])) @@ -166,9 +166,8 @@ export class MeshGiftCardContract extends MeshTxInitiator { const redeemScript = this.redeemCbor(tokenNameHex, giftCardPolicy); - this.spendingPlutusScript(); - - this.mesh + await this.mesh + .spendingPlutusScript(this.langaugeVersion()) .txIn( giftCardUtxo.input.txHash, giftCardUtxo.input.outputIndex, @@ -177,10 +176,8 @@ export class MeshGiftCardContract extends MeshTxInitiator { ) .spendingReferenceTxInInlineDatumPresent() .spendingReferenceTxInRedeemerValue("") - .txInScript(redeemScript); - - this.mintPlutusScript(); - await this.mesh + .txInScript(redeemScript) + .mintPlutusScript(this.langaugeVersion()) .mint("-1", giftCardPolicy, tokenNameHex) .mintingScript(giftCardScript) .mintRedeemerValue(mConStr1([])) diff --git a/packages/mesh-transaction/src/mesh-tx-builder/tx-builder-core.ts b/packages/mesh-transaction/src/mesh-tx-builder/tx-builder-core.ts index a2b2c766..52d7903e 100644 --- a/packages/mesh-transaction/src/mesh-tx-builder/tx-builder-core.ts +++ b/packages/mesh-transaction/src/mesh-tx-builder/tx-builder-core.ts @@ -413,6 +413,20 @@ export class MeshTxBuilderCore { return this; }; + /** + * Set the reference script to be attached with the output + * @param languageVersion The Plutus script version + * @returns The MeshTxBuilder instance + */ + spendingPlutusScript = (languageVersion: LanguageVersion) => { + // This flag should signal a start to a script input + // The next step after will be to add a tx-in + // After which, we will REQUIRE, script, datum and redeemer info + // for unlocking this particular input + this.addingPlutusScriptInput = true; + this.plutusSpendingScriptVersion = languageVersion; + return this; + }; /** * Set the instruction that it is currently using V1 Plutus spending scripts * @returns The MeshTxBuilder instance @@ -525,6 +539,16 @@ export class MeshTxBuilderCore { return this; }; + /** + * Set the minting script for the current mint + * @param languageVersion The Plutus script version + * @returns The MeshTxBuilder instance + */ + mintPlutusScript = (languageVersion: LanguageVersion) => { + this.addingPlutusMint = true; + this.plutusMintingScriptVersion = languageVersion; + return this; + }; /** * Set the instruction that it is currently using V1 Plutus minting scripts * @returns The MeshTxBuilder instance @@ -720,6 +744,16 @@ export class MeshTxBuilderCore { return this; }; + /** + * Set the instruction that it is currently using V1 Plutus withdrawal scripts + * @param languageVersion The Plutus script version + * @returns The MeshTxBuilder instance + */ + withdrawalPlutusScript = (languageVersion: LanguageVersion) => { + this.addingPlutusWithdrawal = true; + this.plutusWithdrawalScriptVersion = languageVersion; + return this; + }; /** * Set the instruction that it is currently using V1 Plutus withdrawal scripts * @returns The MeshTxBuilder instance From bdb0287451d37f1f0515eaec05d31b010beaffd3 Mon Sep 17 00:00:00 2001 From: "Hong Jing (Jingles)" Date: Thu, 5 Sep 2024 23:32:47 +0800 Subject: [PATCH 11/17] rename correct spelling languageVersion --- .../src/pages/smart-contracts/giftcard/common.tsx | 1 + packages/mesh-contract/src/common.ts | 2 +- packages/mesh-contract/src/giftcard/offchain.ts | 12 ++++++------ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/playground/src/pages/smart-contracts/giftcard/common.tsx b/apps/playground/src/pages/smart-contracts/giftcard/common.tsx index 40b3a4e0..ddc71a29 100644 --- a/apps/playground/src/pages/smart-contracts/giftcard/common.tsx +++ b/apps/playground/src/pages/smart-contracts/giftcard/common.tsx @@ -17,6 +17,7 @@ export function getContract(wallet: BrowserWallet) { fetcher: blockchainProvider, wallet: wallet, networkId: 0, + version: 2, }); return contract; diff --git a/packages/mesh-contract/src/common.ts b/packages/mesh-contract/src/common.ts index d8eeb668..9d1367cf 100644 --- a/packages/mesh-contract/src/common.ts +++ b/packages/mesh-contract/src/common.ts @@ -24,7 +24,7 @@ export class MeshTxInitiator { stakeCredential?: string; networkId = 0; version = 1; - langaugeVersion = (): LanguageVersion => { + languageVersion = (): LanguageVersion => { switch (this.version) { case 1: return "V2"; diff --git a/packages/mesh-contract/src/giftcard/offchain.ts b/packages/mesh-contract/src/giftcard/offchain.ts index 4a2dc0f6..e1643506 100644 --- a/packages/mesh-contract/src/giftcard/offchain.ts +++ b/packages/mesh-contract/src/giftcard/offchain.ts @@ -93,12 +93,12 @@ export class MeshGiftCardContract extends MeshTxInitiator { const giftCardPolicy = resolveScriptHash( giftCardScript, - this.langaugeVersion(), + this.languageVersion(), ); const redeemScript: PlutusScript = { code: this.redeemCbor(tokenNameHex, giftCardPolicy), - version: this.langaugeVersion(), + version: this.languageVersion(), }; const redeemAddr = serializePlutusScript( @@ -114,7 +114,7 @@ export class MeshGiftCardContract extends MeshTxInitiator { firstUtxo.output.address, ); await this.mesh - .mintPlutusScript(this.langaugeVersion()) + .mintPlutusScript(this.languageVersion()) .mint("1", giftCardPolicy, tokenNameHex) .mintingScript(giftCardScript) .mintRedeemerValue(mConStr0([])) @@ -161,13 +161,13 @@ export class MeshGiftCardContract extends MeshTxInitiator { const giftCardPolicy = resolveScriptHash( giftCardScript, - this.langaugeVersion(), + this.languageVersion(), ); const redeemScript = this.redeemCbor(tokenNameHex, giftCardPolicy); await this.mesh - .spendingPlutusScript(this.langaugeVersion()) + .spendingPlutusScript(this.languageVersion()) .txIn( giftCardUtxo.input.txHash, giftCardUtxo.input.outputIndex, @@ -177,7 +177,7 @@ export class MeshGiftCardContract extends MeshTxInitiator { .spendingReferenceTxInInlineDatumPresent() .spendingReferenceTxInRedeemerValue("") .txInScript(redeemScript) - .mintPlutusScript(this.langaugeVersion()) + .mintPlutusScript(this.languageVersion()) .mint("-1", giftCardPolicy, tokenNameHex) .mintingScript(giftCardScript) .mintRedeemerValue(mConStr1([])) From 17cb01ebf9aa5b825b5c2a64dc5483c7ac1de4fc Mon Sep 17 00:00:00 2001 From: SIDANWhatever Date: Fri, 6 Sep 2024 00:07:19 +0800 Subject: [PATCH 12/17] fix: fixing plutus v3 giftcard --- packages/mesh-common/src/data/json/aliases.ts | 16 +++++++++++----- .../giftcard/aiken-workspace-v2/aiken.lock | 2 +- .../mesh-contract/src/giftcard/offchain.ts | 19 ++++++++++++------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/packages/mesh-common/src/data/json/aliases.ts b/packages/mesh-common/src/data/json/aliases.ts index 9d3a9c59..e0e89c9d 100644 --- a/packages/mesh-common/src/data/json/aliases.ts +++ b/packages/mesh-common/src/data/json/aliases.ts @@ -52,7 +52,7 @@ export type AssetClass = ConStr0<[CurrencySymbol, TokenName]>; * Aiken alias * The Plutus Data output reference in JSON */ -export type OutputReference = ConStr0<[ConStr0<[ByteString]>, Integer]>; +export type OutputReference = ConStr0<[ByteString, Integer]>; /** * PlutusTx alias @@ -166,7 +166,9 @@ export const assetClass = ( conStr0([currencySymbol(currencySymbolHex), tokenName(tokenNameHex)]); /** - * The utility function to create a Plutus Data output reference in JSON + * The utility function to create a Plutus Data output reference in JSON. + * Note that it is updated since aiken version v1.1.0. + * If you want to build the type before Chang, please use txOutRef instead. * @param txHash The transaction hash * @param index The index of the output * @returns The Plutus Data output reference object @@ -178,7 +180,7 @@ export const outputReference = ( if (txHash.length !== 64) { throw new Error("Invalid transaction hash - should be 32 bytes long"); } - return conStr0([conStr0([byteString(txHash)]), integer(index)]); + return conStr0([byteString(txHash), integer(index)]); }; /** @@ -187,8 +189,12 @@ export const outputReference = ( * @param index The index of the output * @returns The Plutus Data TxOutRef object */ -export const txOutRef = (txHash: string, index: number): TxOutRef => - outputReference(txHash, index); +export const txOutRef = (txHash: string, index: number): TxOutRef => { + if (txHash.length !== 64) { + throw new Error("Invalid transaction hash - should be 32 bytes long"); + } + return conStr0([conStr0([byteString(txHash)]), integer(index)]); +}; /** * The utility function to create a Plutus Data POSIX time in JSON diff --git a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.lock b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.lock index a985644d..efe3a839 100644 --- a/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.lock +++ b/packages/mesh-contract/src/giftcard/aiken-workspace-v2/aiken.lock @@ -24,4 +24,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1725541389, nanos_since_epoch = 166667000 }, "d79382d2b6ecb3aee9b0755c31d8a5bbafe88a7b3706d7fb8a52fd4d05818501"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1725550729, nanos_since_epoch = 704384000 }, "d79382d2b6ecb3aee9b0755c31d8a5bbafe88a7b3706d7fb8a52fd4d05818501"] diff --git a/packages/mesh-contract/src/giftcard/offchain.ts b/packages/mesh-contract/src/giftcard/offchain.ts index e1643506..4cac8d0f 100644 --- a/packages/mesh-contract/src/giftcard/offchain.ts +++ b/packages/mesh-contract/src/giftcard/offchain.ts @@ -5,6 +5,7 @@ import { List, mConStr0, mConStr1, + outputReference, PlutusScript, stringToHex, txOutRef, @@ -32,17 +33,21 @@ export class MeshGiftCardContract extends MeshTxInitiator { utxoTxId: number, ) => { let scriptCbor; + let utxo; switch (this.version) { case 2: scriptCbor = blueprintV2.validators[0]!.compiledCode; + utxo = outputReference(utxoTxHash, utxoTxId); break; default: scriptCbor = blueprintV1.validators[0]!.compiledCode; + utxo = txOutRef(utxoTxHash, utxoTxId); + break; } return applyParamsToScript( scriptCbor, - [builtinByteString(tokenNameHex), txOutRef(utxoTxHash, utxoTxId)], + [builtinByteString(tokenNameHex), utxo], "JSON", ); }; @@ -107,13 +112,13 @@ export class MeshGiftCardContract extends MeshTxInitiator { this.networkId, ).address; - this.mesh.txIn( - firstUtxo.input.txHash, - firstUtxo.input.outputIndex, - firstUtxo.output.amount, - firstUtxo.output.address, - ); await this.mesh + .txIn( + firstUtxo.input.txHash, + firstUtxo.input.outputIndex, + firstUtxo.output.amount, + firstUtxo.output.address, + ) .mintPlutusScript(this.languageVersion()) .mint("1", giftCardPolicy, tokenNameHex) .mintingScript(giftCardScript) From 6947c4ff71c92e04789a546d6e927ccbc5d77b75 Mon Sep 17 00:00:00 2001 From: SIDANWhatever Date: Fri, 6 Sep 2024 00:09:02 +0800 Subject: [PATCH 13/17] feat: updating mOutputReference --- packages/mesh-common/src/data/mesh/aliases.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/mesh-common/src/data/mesh/aliases.ts b/packages/mesh-common/src/data/mesh/aliases.ts index 59af2590..942552e4 100644 --- a/packages/mesh-common/src/data/mesh/aliases.ts +++ b/packages/mesh-common/src/data/mesh/aliases.ts @@ -11,7 +11,7 @@ export type MAssetClass = MConStr0<[string, string]>; * Aiken alias * The Mesh Data output reference */ -export type MOutputReference = MConStr0<[MConStr0<[string]>, number]>; +export type MOutputReference = MConStr0<[string, number]>; /** * PlutusTx alias @@ -63,7 +63,7 @@ export const mOutputReference = ( if (txHash.length !== 64) { throw new Error("Invalid transaction hash - should be 32 bytes long"); } - return mConStr0([mConStr0([txHash]), index]); + return mConStr0([txHash, index]); }; /** @@ -72,8 +72,12 @@ export const mOutputReference = ( * @param index The index of the output * @returns The Mesh Data TxOutRef object */ -export const mTxOutRef = (txHash: string, index: number): MTxOutRef => - mOutputReference(txHash, index); +export const mTxOutRef = (txHash: string, index: number): MTxOutRef => { + if (txHash.length !== 64) { + throw new Error("Invalid transaction hash - should be 32 bytes long"); + } + return mConStr0([mConStr0([txHash]), index]); +}; /** * The utility function to create a Mesh Data tuple in Mesh Data type From b7979b3f7afcb8a6309644e8790ec35b37fad3d7 Mon Sep 17 00:00:00 2001 From: SIDANWhatever Date: Fri, 6 Sep 2024 00:45:38 +0800 Subject: [PATCH 14/17] feat: update vesting contracts --- packages/mesh-contract/src/common.ts | 15 +- .../mesh-contract/src/giftcard/offchain.ts | 12 +- .../.gitignore | 0 .../README.md | 0 .../aiken.lock | 0 .../aiken.toml | 0 .../lib/vesting/types.ak | 0 .../plutus.json | 0 .../validators/tests/vesting.ak | 0 .../validators/vesting.ak | 0 .../src/vesting/aiken-workspace-v2/.gitignore | 6 + .../src/vesting/aiken-workspace-v2/README.md | 24 ++++ .../src/vesting/aiken-workspace-v2/aiken.lock | 27 ++++ .../src/vesting/aiken-workspace-v2/aiken.toml | 23 +++ .../vesting/aiken-workspace-v2/plutus.json | 76 ++++++++++ .../aiken-workspace-v2/validators/vesting.ak | 134 ++++++++++++++++++ 16 files changed, 303 insertions(+), 14 deletions(-) rename packages/mesh-contract/src/vesting/{aiken-workspace => aiken-workspace-v1}/.gitignore (100%) rename packages/mesh-contract/src/vesting/{aiken-workspace => aiken-workspace-v1}/README.md (100%) rename packages/mesh-contract/src/vesting/{aiken-workspace => aiken-workspace-v1}/aiken.lock (100%) rename packages/mesh-contract/src/vesting/{aiken-workspace => aiken-workspace-v1}/aiken.toml (100%) rename packages/mesh-contract/src/vesting/{aiken-workspace => aiken-workspace-v1}/lib/vesting/types.ak (100%) rename packages/mesh-contract/src/vesting/{aiken-workspace => aiken-workspace-v1}/plutus.json (100%) rename packages/mesh-contract/src/vesting/{aiken-workspace => aiken-workspace-v1}/validators/tests/vesting.ak (100%) rename packages/mesh-contract/src/vesting/{aiken-workspace => aiken-workspace-v1}/validators/vesting.ak (100%) create mode 100644 packages/mesh-contract/src/vesting/aiken-workspace-v2/.gitignore create mode 100644 packages/mesh-contract/src/vesting/aiken-workspace-v2/README.md create mode 100644 packages/mesh-contract/src/vesting/aiken-workspace-v2/aiken.lock create mode 100644 packages/mesh-contract/src/vesting/aiken-workspace-v2/aiken.toml create mode 100644 packages/mesh-contract/src/vesting/aiken-workspace-v2/plutus.json create mode 100644 packages/mesh-contract/src/vesting/aiken-workspace-v2/validators/vesting.ak diff --git a/packages/mesh-contract/src/common.ts b/packages/mesh-contract/src/common.ts index 9d1367cf..234dc23b 100644 --- a/packages/mesh-contract/src/common.ts +++ b/packages/mesh-contract/src/common.ts @@ -24,14 +24,7 @@ export class MeshTxInitiator { stakeCredential?: string; networkId = 0; version = 1; - languageVersion = (): LanguageVersion => { - switch (this.version) { - case 1: - return "V2"; - default: - return "V3"; - } - }; + languageVersion: LanguageVersion = "V2"; constructor({ mesh, @@ -61,6 +54,12 @@ export class MeshTxInitiator { } this.version = version; + switch (this.version) { + case 1: + this.languageVersion = "V2"; + default: + this.languageVersion = "V3"; + } } protected signSubmitReset = async () => { diff --git a/packages/mesh-contract/src/giftcard/offchain.ts b/packages/mesh-contract/src/giftcard/offchain.ts index 4cac8d0f..8c23fea1 100644 --- a/packages/mesh-contract/src/giftcard/offchain.ts +++ b/packages/mesh-contract/src/giftcard/offchain.ts @@ -98,12 +98,12 @@ export class MeshGiftCardContract extends MeshTxInitiator { const giftCardPolicy = resolveScriptHash( giftCardScript, - this.languageVersion(), + this.languageVersion, ); const redeemScript: PlutusScript = { code: this.redeemCbor(tokenNameHex, giftCardPolicy), - version: this.languageVersion(), + version: this.languageVersion, }; const redeemAddr = serializePlutusScript( @@ -119,7 +119,7 @@ export class MeshGiftCardContract extends MeshTxInitiator { firstUtxo.output.amount, firstUtxo.output.address, ) - .mintPlutusScript(this.languageVersion()) + .mintPlutusScript(this.languageVersion) .mint("1", giftCardPolicy, tokenNameHex) .mintingScript(giftCardScript) .mintRedeemerValue(mConStr0([])) @@ -166,13 +166,13 @@ export class MeshGiftCardContract extends MeshTxInitiator { const giftCardPolicy = resolveScriptHash( giftCardScript, - this.languageVersion(), + this.languageVersion, ); const redeemScript = this.redeemCbor(tokenNameHex, giftCardPolicy); await this.mesh - .spendingPlutusScript(this.languageVersion()) + .spendingPlutusScript(this.languageVersion) .txIn( giftCardUtxo.input.txHash, giftCardUtxo.input.outputIndex, @@ -182,7 +182,7 @@ export class MeshGiftCardContract extends MeshTxInitiator { .spendingReferenceTxInInlineDatumPresent() .spendingReferenceTxInRedeemerValue("") .txInScript(redeemScript) - .mintPlutusScript(this.languageVersion()) + .mintPlutusScript(this.languageVersion) .mint("-1", giftCardPolicy, tokenNameHex) .mintingScript(giftCardScript) .mintRedeemerValue(mConStr1([])) diff --git a/packages/mesh-contract/src/vesting/aiken-workspace/.gitignore b/packages/mesh-contract/src/vesting/aiken-workspace-v1/.gitignore similarity index 100% rename from packages/mesh-contract/src/vesting/aiken-workspace/.gitignore rename to packages/mesh-contract/src/vesting/aiken-workspace-v1/.gitignore diff --git a/packages/mesh-contract/src/vesting/aiken-workspace/README.md b/packages/mesh-contract/src/vesting/aiken-workspace-v1/README.md similarity index 100% rename from packages/mesh-contract/src/vesting/aiken-workspace/README.md rename to packages/mesh-contract/src/vesting/aiken-workspace-v1/README.md diff --git a/packages/mesh-contract/src/vesting/aiken-workspace/aiken.lock b/packages/mesh-contract/src/vesting/aiken-workspace-v1/aiken.lock similarity index 100% rename from packages/mesh-contract/src/vesting/aiken-workspace/aiken.lock rename to packages/mesh-contract/src/vesting/aiken-workspace-v1/aiken.lock diff --git a/packages/mesh-contract/src/vesting/aiken-workspace/aiken.toml b/packages/mesh-contract/src/vesting/aiken-workspace-v1/aiken.toml similarity index 100% rename from packages/mesh-contract/src/vesting/aiken-workspace/aiken.toml rename to packages/mesh-contract/src/vesting/aiken-workspace-v1/aiken.toml diff --git a/packages/mesh-contract/src/vesting/aiken-workspace/lib/vesting/types.ak b/packages/mesh-contract/src/vesting/aiken-workspace-v1/lib/vesting/types.ak similarity index 100% rename from packages/mesh-contract/src/vesting/aiken-workspace/lib/vesting/types.ak rename to packages/mesh-contract/src/vesting/aiken-workspace-v1/lib/vesting/types.ak diff --git a/packages/mesh-contract/src/vesting/aiken-workspace/plutus.json b/packages/mesh-contract/src/vesting/aiken-workspace-v1/plutus.json similarity index 100% rename from packages/mesh-contract/src/vesting/aiken-workspace/plutus.json rename to packages/mesh-contract/src/vesting/aiken-workspace-v1/plutus.json diff --git a/packages/mesh-contract/src/vesting/aiken-workspace/validators/tests/vesting.ak b/packages/mesh-contract/src/vesting/aiken-workspace-v1/validators/tests/vesting.ak similarity index 100% rename from packages/mesh-contract/src/vesting/aiken-workspace/validators/tests/vesting.ak rename to packages/mesh-contract/src/vesting/aiken-workspace-v1/validators/tests/vesting.ak diff --git a/packages/mesh-contract/src/vesting/aiken-workspace/validators/vesting.ak b/packages/mesh-contract/src/vesting/aiken-workspace-v1/validators/vesting.ak similarity index 100% rename from packages/mesh-contract/src/vesting/aiken-workspace/validators/vesting.ak rename to packages/mesh-contract/src/vesting/aiken-workspace-v1/validators/vesting.ak diff --git a/packages/mesh-contract/src/vesting/aiken-workspace-v2/.gitignore b/packages/mesh-contract/src/vesting/aiken-workspace-v2/.gitignore new file mode 100644 index 00000000..ff7811b1 --- /dev/null +++ b/packages/mesh-contract/src/vesting/aiken-workspace-v2/.gitignore @@ -0,0 +1,6 @@ +# Aiken compilation artifacts +artifacts/ +# Aiken's project working directory +build/ +# Aiken's default documentation export +docs/ diff --git a/packages/mesh-contract/src/vesting/aiken-workspace-v2/README.md b/packages/mesh-contract/src/vesting/aiken-workspace-v2/README.md new file mode 100644 index 00000000..a0ec1de0 --- /dev/null +++ b/packages/mesh-contract/src/vesting/aiken-workspace-v2/README.md @@ -0,0 +1,24 @@ +# Vesting - Specification + +## Scripts - VestingValidator + +The validator of locking vesting value. + +### Parameter - no parameter + +### Datum + +- `lock_until`: POSIX time in second at locking end, e.g. 1672843961000 +- `owner`: Owner's pub key hash +- `beneficiary`: Beneficiary's pub key hash + +### User Action + +1. Unlock by owner + + - Signed by `owner` + +2. Unlock by beneficiary + + - Signed by `beneficiary` + - Only valid after `lock_until` diff --git a/packages/mesh-contract/src/vesting/aiken-workspace-v2/aiken.lock b/packages/mesh-contract/src/vesting/aiken-workspace-v2/aiken.lock new file mode 100644 index 00000000..a89d05d9 --- /dev/null +++ b/packages/mesh-contract/src/vesting/aiken-workspace-v2/aiken.lock @@ -0,0 +1,27 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +[[requirements]] +name = "aiken-lang/stdlib" +version = "v2" +source = "github" + +[[requirements]] +name = "sidan-lab/vodka" +version = "0.1.0-beta" +source = "github" + +[[packages]] +name = "aiken-lang/stdlib" +version = "v2" +requirements = [] +source = "github" + +[[packages]] +name = "sidan-lab/vodka" +version = "0.1.0-beta" +requirements = [] +source = "github" + +[etags] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1725554519, nanos_since_epoch = 649340000 }, "d79382d2b6ecb3aee9b0755c31d8a5bbafe88a7b3706d7fb8a52fd4d05818501"] diff --git a/packages/mesh-contract/src/vesting/aiken-workspace-v2/aiken.toml b/packages/mesh-contract/src/vesting/aiken-workspace-v2/aiken.toml new file mode 100644 index 00000000..d539e9a8 --- /dev/null +++ b/packages/mesh-contract/src/vesting/aiken-workspace-v2/aiken.toml @@ -0,0 +1,23 @@ +name = "meshjs/vesting" +version = "0.0.0" +compiler = "v1.1.0" +plutus = "v3" +license = "Apache-2.0" +description = "Aiken contracts for project 'meshjs/vesting'" + +[repository] +user = "meshjs" +project = "vesting" +platform = "github" + +[[dependencies]] +name = "aiken-lang/stdlib" +version = "v2" +source = "github" + +[[dependencies]] +name = "sidan-lab/vodka" +version = "0.1.0-beta" +source = "github" + +[config] diff --git a/packages/mesh-contract/src/vesting/aiken-workspace-v2/plutus.json b/packages/mesh-contract/src/vesting/aiken-workspace-v2/plutus.json new file mode 100644 index 00000000..901f57a3 --- /dev/null +++ b/packages/mesh-contract/src/vesting/aiken-workspace-v2/plutus.json @@ -0,0 +1,76 @@ +{ + "preamble": { + "title": "meshjs/vesting", + "description": "Aiken contracts for project 'meshjs/vesting'", + "version": "0.0.0", + "plutusVersion": "v3", + "compiler": { + "name": "Aiken", + "version": "v1.1.0+unknown" + }, + "license": "Apache-2.0" + }, + "validators": [ + { + "title": "vesting.vesting.spend", + "datum": { + "title": "datum_opt", + "schema": { + "$ref": "#/definitions/vesting~1VestingDatum" + } + }, + "redeemer": { + "title": "_redeemer", + "schema": { + "$ref": "#/definitions/Data" + } + }, + "compiledCode": "5901a7010100323232323232322533300232323232325332330083001300937540042646464a66601666e1d2000300c37540022646464a66601c660026eb0c008c040dd50059bae3013301430103754006294454ccc038cc004dd6180118081baa00b375c60266028602860206ea800c4c8cc88c8c8c8c8c94ccc058c03cc05cdd5001099299980b802099b88007001002375a603660306ea80080044c94ccc058c03cc05cdd5001099299980b802001099b89007001375a603660306ea8008004528180c8011806180a1baa3018301900133016301700133016333012300b30133754602e603000298103d87a80004c0103d87980004bd7018099baa3003301337540046028602a602a602a602a602a602a602a60226ea8030dd6980098089baa0042301400114a044646600200200644a66602800229404c94ccc048cdc79bae301700200414a2266006006002602e00246024602660266026602660266026602660260026020601a6ea800458c03cc040008c038004c028dd50011b874800858c02cc030008c028004c028008c020004c010dd50008a4c26cacae6955ceaab9e5573eae815d0aba21", + "hash": "d13324c13a48b69d67ccfc88e3e87f046f4417f57f5c740d515249fb" + }, + { + "title": "vesting.vesting.else", + "compiledCode": "5901a7010100323232323232322533300232323232325332330083001300937540042646464a66601666e1d2000300c37540022646464a66601c660026eb0c008c040dd50059bae3013301430103754006294454ccc038cc004dd6180118081baa00b375c60266028602860206ea800c4c8cc88c8c8c8c8c94ccc058c03cc05cdd5001099299980b802099b88007001002375a603660306ea80080044c94ccc058c03cc05cdd5001099299980b802001099b89007001375a603660306ea8008004528180c8011806180a1baa3018301900133016301700133016333012300b30133754602e603000298103d87a80004c0103d87980004bd7018099baa3003301337540046028602a602a602a602a602a602a602a60226ea8030dd6980098089baa0042301400114a044646600200200644a66602800229404c94ccc048cdc79bae301700200414a2266006006002602e00246024602660266026602660266026602660260026020601a6ea800458c03cc040008c038004c028dd50011b874800858c02cc030008c028004c028008c020004c010dd50008a4c26cacae6955ceaab9e5573eae815d0aba21", + "hash": "d13324c13a48b69d67ccfc88e3e87f046f4417f57f5c740d515249fb" + } + ], + "definitions": { + "ByteArray": { + "dataType": "bytes" + }, + "Data": { + "title": "Data", + "description": "Any Plutus data." + }, + "Int": { + "dataType": "integer" + }, + "vesting/VestingDatum": { + "title": "VestingDatum", + "anyOf": [ + { + "title": "VestingDatum", + "dataType": "constructor", + "index": 0, + "fields": [ + { + "title": "lock_until", + "description": "POSIX time in milliseconds, e.g. 1672843961000", + "$ref": "#/definitions/Int" + }, + { + "title": "owner", + "description": "Owner's credentials", + "$ref": "#/definitions/ByteArray" + }, + { + "title": "beneficiary", + "description": "Beneficiary's credentials", + "$ref": "#/definitions/ByteArray" + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/packages/mesh-contract/src/vesting/aiken-workspace-v2/validators/vesting.ak b/packages/mesh-contract/src/vesting/aiken-workspace-v2/validators/vesting.ak new file mode 100644 index 00000000..7ea75b4f --- /dev/null +++ b/packages/mesh-contract/src/vesting/aiken-workspace-v2/validators/vesting.ak @@ -0,0 +1,134 @@ +use cardano/transaction.{OutputReference, Transaction} +use mocktail.{complete, invalid_before, mocktail_tx, required_signer_hash} +use mocktail/virgin_key_hash.{mock_pub_key_hash} +use mocktail/virgin_output_reference.{mock_utxo_ref} +use vodka_extra_signatories.{key_signed} +use vodka_validity_range.{valid_after} + +pub type VestingDatum { + /// POSIX time in milliseconds, e.g. 1672843961000 + lock_until: Int, + /// Owner's credentials + owner: ByteArray, + /// Beneficiary's credentials + beneficiary: ByteArray, +} + +validator vesting { + spend( + datum_opt: Option, + _redeemer: Data, + _input: OutputReference, + tx: Transaction, + ) { + // In principle, scripts can be used for different purpose (e.g. minting + // assets). Here we make sure it's only used when 'spending' from a eUTxO + expect Some(datum) = datum_opt + or { + key_signed(tx.extra_signatories, datum.owner), + and { + key_signed(tx.extra_signatories, datum.beneficiary), + valid_after(tx.validity_range, datum.lock_until), + }, + } + } + + else(_) { + fail + } +} + +type TestCase { + is_owner_signed: Bool, + is_beneficiary_signed: Bool, + is_lock_time_passed: Bool, +} + +fn get_test_tx(test_case: TestCase) { + let TestCase { is_owner_signed, is_beneficiary_signed, is_lock_time_passed } = + test_case + + mocktail_tx() + |> required_signer_hash(is_owner_signed, mock_pub_key_hash(1)) + |> required_signer_hash(is_beneficiary_signed, mock_pub_key_hash(2)) + |> invalid_before(is_lock_time_passed, 1672843961001) + |> complete() +} + +fn vesting_datum() { + VestingDatum { + lock_until: 1672843961000, + owner: mock_pub_key_hash(1), + beneficiary: mock_pub_key_hash(2), + } +} + +test success_unlocking() { + let output_reference = mock_utxo_ref(0, 1) + let datum = Some(vesting_datum()) + let test_case = + TestCase { + is_owner_signed: True, + is_beneficiary_signed: True, + is_lock_time_passed: True, + } + + let tx = get_test_tx(test_case) + vesting.spend(datum, Void, output_reference, tx) +} + +test success_unlocking_with_only_owner_signature() { + let output_reference = mock_utxo_ref(0, 1) + let datum = Some(vesting_datum()) + let test_case = + TestCase { + is_owner_signed: True, + is_beneficiary_signed: False, + is_lock_time_passed: False, + } + + let tx = get_test_tx(test_case) + vesting.spend(datum, Void, output_reference, tx) +} + +test success_unlocking_with_beneficiary_signature_and_time_passed() { + let output_reference = mock_utxo_ref(0, 1) + let datum = Some(vesting_datum()) + let test_case = + TestCase { + is_owner_signed: False, + is_beneficiary_signed: True, + is_lock_time_passed: True, + } + + let tx = get_test_tx(test_case) + vesting.spend(datum, Void, output_reference, tx) +} + +test fail_unlocking_with_only_beneficiary_signature() { + let output_reference = mock_utxo_ref(0, 1) + let datum = Some(vesting_datum()) + let test_case = + TestCase { + is_owner_signed: False, + is_beneficiary_signed: True, + is_lock_time_passed: False, + } + + let tx = get_test_tx(test_case) + !vesting.spend(datum, Void, output_reference, tx) +} + +test fail_unlocking_with_only_time_passed() { + let output_reference = mock_utxo_ref(0, 1) + let datum = Some(vesting_datum()) + let test_case = + TestCase { + is_owner_signed: False, + is_beneficiary_signed: False, + is_lock_time_passed: True, + } + + let tx = get_test_tx(test_case) + !vesting.spend(datum, Void, output_reference, tx) +} From 199338e155b14572122c716aafae7ac555e9bb17 Mon Sep 17 00:00:00 2001 From: "Hong Jing (Jingles)" Date: Fri, 6 Sep 2024 00:54:24 +0800 Subject: [PATCH 15/17] migrate vesting offchain --- .../pages/smart-contracts/giftcard/common.tsx | 1 - packages/mesh-contract/src/escrow/offchain.ts | 21 +++++++--- .../mesh-contract/src/giftcard/offchain.ts | 1 - .../mesh-contract/src/hello-world/offchain.ts | 1 - .../mesh-contract/src/marketplace/offchain.ts | 6 ++- .../src/payment-splitter/offchain.ts | 2 - packages/mesh-contract/src/swap/offchain.ts | 11 ++++-- .../mesh-contract/src/vesting/offchain.ts | 39 +++++++++++++------ 8 files changed, 56 insertions(+), 26 deletions(-) diff --git a/apps/playground/src/pages/smart-contracts/giftcard/common.tsx b/apps/playground/src/pages/smart-contracts/giftcard/common.tsx index ddc71a29..8ada0da9 100644 --- a/apps/playground/src/pages/smart-contracts/giftcard/common.tsx +++ b/apps/playground/src/pages/smart-contracts/giftcard/common.tsx @@ -9,7 +9,6 @@ export function getContract(wallet: BrowserWallet) { const meshTxBuilder = new MeshTxBuilder({ fetcher: blockchainProvider, submitter: blockchainProvider, - verbose: true, }); const contract = new MeshGiftCardContract({ diff --git a/packages/mesh-contract/src/escrow/offchain.ts b/packages/mesh-contract/src/escrow/offchain.ts index b391c9f3..e9f0795c 100644 --- a/packages/mesh-contract/src/escrow/offchain.ts +++ b/packages/mesh-contract/src/escrow/offchain.ts @@ -68,7 +68,6 @@ export class MeshEscrowContract extends MeshTxInitiator { constructor(inputs: MeshTxInitiatorInput) { super(inputs); - this.mesh.setNetwork(inputs.networkId === 1 ? "mainnet" : "preprod"); } initiateEscrow = async (escrowAmount: Asset[]): Promise => { @@ -112,8 +111,14 @@ export class MeshEscrowContract extends MeshTxInitiator { recipientAmount, ] = inputDatum.fields; - const initiatorAddress = serializeAddressObj(initiatorAddressObj, this.networkId); - const recipientAddress = serializeAddressObj(recipientAddressObj!, this.networkId); + const initiatorAddress = serializeAddressObj( + initiatorAddressObj, + this.networkId, + ); + const recipientAddress = serializeAddressObj( + recipientAddressObj!, + this.networkId, + ); const initiatorToReceive = MeshValue.fromValue(initiatorAmount).toAssets(); const recipientToReceive = MeshValue.fromValue( @@ -220,8 +225,14 @@ export class MeshEscrowContract extends MeshTxInitiator { recipientAddressObj, recipientAmount, ] = inputDatum.fields; - const initiatorAddress = serializeAddressObj(initiatorAddressObj, this.networkId); - const recipientAddress = serializeAddressObj(recipientAddressObj, this.networkId); + const initiatorAddress = serializeAddressObj( + initiatorAddressObj, + this.networkId, + ); + const recipientAddress = serializeAddressObj( + recipientAddressObj, + this.networkId, + ); const initiatorToReceive = MeshValue.fromValue(recipientAmount).toAssets(); const recipientToReceive = MeshValue.fromValue(initiatorAmount).toAssets(); diff --git a/packages/mesh-contract/src/giftcard/offchain.ts b/packages/mesh-contract/src/giftcard/offchain.ts index 8c23fea1..26fa6157 100644 --- a/packages/mesh-contract/src/giftcard/offchain.ts +++ b/packages/mesh-contract/src/giftcard/offchain.ts @@ -77,7 +77,6 @@ export class MeshGiftCardContract extends MeshTxInitiator { if (paramUtxo) { this.paramUtxo = paramUtxo; } - this.mesh.setNetwork(inputs.networkId === 1 ? "mainnet" : "preprod"); } createGiftCard = async ( diff --git a/packages/mesh-contract/src/hello-world/offchain.ts b/packages/mesh-contract/src/hello-world/offchain.ts index a275194a..0932d417 100644 --- a/packages/mesh-contract/src/hello-world/offchain.ts +++ b/packages/mesh-contract/src/hello-world/offchain.ts @@ -25,7 +25,6 @@ export class MeshHelloWorldContract extends MeshTxInitiator { constructor(inputs: MeshTxInitiatorInput) { super(inputs); - this.mesh.setNetwork(inputs.networkId === 1 ? "mainnet" : "preprod"); } getScript = () => { diff --git a/packages/mesh-contract/src/marketplace/offchain.ts b/packages/mesh-contract/src/marketplace/offchain.ts index d2466138..3f0fdbff 100644 --- a/packages/mesh-contract/src/marketplace/offchain.ts +++ b/packages/mesh-contract/src/marketplace/offchain.ts @@ -70,7 +70,6 @@ export class MeshMarketplaceContract extends MeshTxInitiator { ], "JSON", ); - this.mesh.setNetwork(inputs.networkId === 1 ? "mainnet" : "preprod"); } listAsset = async (asset: string, price: number) => { @@ -183,7 +182,10 @@ export class MeshMarketplaceContract extends MeshTxInitiator { (inputDatum.fields[1].int as number) + Number(inputLovelace); if (sellerToReceiveLovelace > 0) { - const sellerAddress = serializeAddressObj(inputDatum.fields[0], this.networkId); + const sellerAddress = serializeAddressObj( + inputDatum.fields[0], + this.networkId, + ); const sellerToReceive = [ { unit: "lovelace", diff --git a/packages/mesh-contract/src/payment-splitter/offchain.ts b/packages/mesh-contract/src/payment-splitter/offchain.ts index 476f78bd..3a99c8ab 100644 --- a/packages/mesh-contract/src/payment-splitter/offchain.ts +++ b/packages/mesh-contract/src/payment-splitter/offchain.ts @@ -48,8 +48,6 @@ export class MeshPaymentSplitterContract extends MeshTxInitiator { "Wallet not provided. Therefore the payment address will not be added to the payees list which makes it impossible to trigger the payout.", ); } - - this.mesh.setNetwork(inputs.networkId === 1 ? "mainnet" : "preprod"); } sendLovelaceToSplitter = async (lovelaceAmount: number): Promise => { diff --git a/packages/mesh-contract/src/swap/offchain.ts b/packages/mesh-contract/src/swap/offchain.ts index e0c9c9ef..2a0c4afe 100644 --- a/packages/mesh-contract/src/swap/offchain.ts +++ b/packages/mesh-contract/src/swap/offchain.ts @@ -37,7 +37,6 @@ export class MeshSwapContract extends MeshTxInitiator { undefined, inputs.networkId, ).address; - this.mesh.setNetwork(inputs.networkId === 1 ? "mainnet" : "preprod"); } initiateSwap = async ( @@ -76,7 +75,10 @@ export class MeshSwapContract extends MeshTxInitiator { const inlineDatum = deserializeDatum( swapUtxo.output.plutusData!, ); - const initiatorAddress = serializeAddressObj(inlineDatum.fields[0], this.networkId); + const initiatorAddress = serializeAddressObj( + inlineDatum.fields[0], + this.networkId, + ); const initiatorToReceive = inlineDatum.fields[2]; await this.mesh @@ -112,7 +114,10 @@ export class MeshSwapContract extends MeshTxInitiator { const inlineDatum = deserializeDatum( swapUtxo.output.plutusData!, ); - const initiatorAddress = serializeAddressObj(inlineDatum.fields[0], this.networkId); + const initiatorAddress = serializeAddressObj( + inlineDatum.fields[0], + this.networkId, + ); await this.mesh .spendingPlutusScriptV2() .txIn( diff --git a/packages/mesh-contract/src/vesting/offchain.ts b/packages/mesh-contract/src/vesting/offchain.ts index 28d85c56..c1f325b9 100644 --- a/packages/mesh-contract/src/vesting/offchain.ts +++ b/packages/mesh-contract/src/vesting/offchain.ts @@ -16,22 +16,37 @@ import { import { applyParamsToScript } from "@meshsdk/core-csl"; import { MeshTxInitiator, MeshTxInitiatorInput } from "../common"; -import blueprint from "./aiken-workspace/plutus.json"; - -export const MeshVestingBlueprint = blueprint; +import blueprintV1 from "./aiken-workspace-v1/plutus.json"; +import blueprintV2 from "./aiken-workspace-v2/plutus.json"; export type VestingDatum = ConStr0< [Integer, BuiltinByteString, BuiltinByteString] >; export class MeshVestingContract extends MeshTxInitiator { - scriptCbor = applyParamsToScript(blueprint.validators[0]!.compiledCode, []); - constructor(inputs: MeshTxInitiatorInput) { super(inputs); - this.mesh.setNetwork(inputs.networkId === 1 ? "mainnet" : "preprod"); } + getScriptCbor = () => { + let scriptCbor; + switch (this.version) { + case 2: + scriptCbor = applyParamsToScript( + blueprintV2.validators[0]!.compiledCode, + [], + ); + break; + default: + scriptCbor = applyParamsToScript( + blueprintV1.validators[0]!.compiledCode, + [], + ); + break; + } + return scriptCbor; + }; + depositFund = async ( amount: Asset[], lockUntilTimeStampMs: number, @@ -40,7 +55,7 @@ export class MeshVestingContract extends MeshTxInitiator { const { utxos, walletAddress } = await this.getWalletInfoForTx(); const scriptAddr = serializePlutusScript( - { code: this.scriptCbor, version: "V2" }, + { code: this.getScriptCbor(), version: this.languageVersion }, undefined, this.networkId, ).address; @@ -67,8 +82,10 @@ export class MeshVestingContract extends MeshTxInitiator { const { utxos, walletAddress, collateral } = await this.getWalletInfoForTx(); const { input: collateralInput, output: collateralOutput } = collateral; + + const scriptCbor = this.getScriptCbor(); const scriptAddr = serializePlutusScript( - { code: this.scriptCbor, version: "V2" }, + { code: scriptCbor, version: this.languageVersion }, undefined, this.networkId, ).address; @@ -87,7 +104,7 @@ export class MeshVestingContract extends MeshTxInitiator { ) + 1; await this.mesh - .spendingPlutusScriptV2() + .spendingPlutusScript(this.languageVersion) .txIn( vestingUtxo.input.txHash, vestingUtxo.input.outputIndex, @@ -96,7 +113,7 @@ export class MeshVestingContract extends MeshTxInitiator { ) .spendingReferenceTxInInlineDatumPresent() .spendingReferenceTxInRedeemerValue("") - .txInScript(this.scriptCbor) + .txInScript(scriptCbor) .txOut(walletAddress, []) .txInCollateral( collateralInput.txHash, @@ -113,6 +130,6 @@ export class MeshVestingContract extends MeshTxInitiator { }; getUtxoByTxHash = async (txHash: string): Promise => { - return await this._getUtxoByTxHash(txHash, this.scriptCbor); + return await this._getUtxoByTxHash(txHash, this.getScriptCbor()); }; } From ccef1e3f1c704905b6d79458fc4f34706e164b7b Mon Sep 17 00:00:00 2001 From: "Hong Jing (Jingles)" Date: Fri, 6 Sep 2024 01:09:48 +0800 Subject: [PATCH 16/17] add break and default v2 --- packages/mesh-contract/src/common.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/mesh-contract/src/common.ts b/packages/mesh-contract/src/common.ts index 234dc23b..8f15b432 100644 --- a/packages/mesh-contract/src/common.ts +++ b/packages/mesh-contract/src/common.ts @@ -23,7 +23,7 @@ export class MeshTxInitiator { wallet?: BrowserWallet | MeshWallet; stakeCredential?: string; networkId = 0; - version = 1; + version = 2; languageVersion: LanguageVersion = "V2"; constructor({ @@ -32,7 +32,7 @@ export class MeshTxInitiator { wallet, networkId = 0, stakeCredential, - version = 1, + version = 2, }: MeshTxInitiatorInput) { this.mesh = mesh; if (fetcher) { @@ -57,6 +57,7 @@ export class MeshTxInitiator { switch (this.version) { case 1: this.languageVersion = "V2"; + break; default: this.languageVersion = "V3"; } From da1dfb7cdee37d1e1c4addf095dd664aafac4d11 Mon Sep 17 00:00:00 2001 From: "Hong Jing (Jingles)" Date: Fri, 6 Sep 2024 01:11:50 +0800 Subject: [PATCH 17/17] bump version --- packages/mesh-common/package.json | 2 +- packages/mesh-contract/package.json | 12 ++++++------ packages/mesh-core-csl/package.json | 4 ++-- packages/mesh-core-cst/package.json | 4 ++-- packages/mesh-core/package.json | 16 ++++++++-------- packages/mesh-provider/package.json | 6 +++--- packages/mesh-react/package.json | 8 ++++---- packages/mesh-transaction/package.json | 8 ++++---- packages/mesh-wallet/package.json | 10 +++++----- scripts/mesh-cli/package.json | 2 +- 10 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/mesh-common/package.json b/packages/mesh-common/package.json index 8bcde54c..dcdae5d5 100644 --- a/packages/mesh-common/package.json +++ b/packages/mesh-common/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/common", - "version": "1.7.2", + "version": "1.7.3", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", diff --git a/packages/mesh-contract/package.json b/packages/mesh-contract/package.json index ddef3309..756481b4 100644 --- a/packages/mesh-contract/package.json +++ b/packages/mesh-contract/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/contract", - "version": "1.7.2", + "version": "1.7.3", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -33,11 +33,11 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "1.7.2", - "@meshsdk/core": "1.7.2", - "@meshsdk/core-csl": "1.7.2", - "@meshsdk/core-cst": "1.7.2", - "@meshsdk/transaction": "1.7.2" + "@meshsdk/common": "1.7.3", + "@meshsdk/core": "1.7.3", + "@meshsdk/core-csl": "1.7.3", + "@meshsdk/core-cst": "1.7.3", + "@meshsdk/transaction": "1.7.3" }, "prettier": "@meshsdk/configs/prettier", "publishConfig": { diff --git a/packages/mesh-core-csl/package.json b/packages/mesh-core-csl/package.json index c12da575..c0d0d514 100644 --- a/packages/mesh-core-csl/package.json +++ b/packages/mesh-core-csl/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/core-csl", - "version": "1.7.2", + "version": "1.7.3", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -38,7 +38,7 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "1.7.2", + "@meshsdk/common": "1.7.3", "@sidan-lab/sidan-csl-rs-browser": "0.8.0", "@sidan-lab/sidan-csl-rs-nodejs": "0.8.0", "json-bigint": "^1.0.0" diff --git a/packages/mesh-core-cst/package.json b/packages/mesh-core-cst/package.json index a2ef47a2..f8cf429f 100644 --- a/packages/mesh-core-cst/package.json +++ b/packages/mesh-core-cst/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/core-cst", - "version": "1.7.2", + "version": "1.7.3", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -41,7 +41,7 @@ "@harmoniclabs/cbor": "1.3.0", "@harmoniclabs/plutus-data": "1.2.4", "@harmoniclabs/uplc": "1.2.4", - "@meshsdk/common": "1.7.2", + "@meshsdk/common": "1.7.3", "@stricahq/bip32ed25519": "^1.1.0", "@stricahq/cbors": "^1.0.0", "pbkdf2": "^3.1.2" diff --git a/packages/mesh-core/package.json b/packages/mesh-core/package.json index 04edf735..c97ac433 100644 --- a/packages/mesh-core/package.json +++ b/packages/mesh-core/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/core", - "version": "1.7.2", + "version": "1.7.3", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -32,13 +32,13 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "1.7.2", - "@meshsdk/core-csl": "1.7.2", - "@meshsdk/core-cst": "1.7.2", - "@meshsdk/provider": "1.7.2", - "@meshsdk/react": "1.7.2", - "@meshsdk/transaction": "1.7.2", - "@meshsdk/wallet": "1.7.2" + "@meshsdk/common": "1.7.3", + "@meshsdk/core-csl": "1.7.3", + "@meshsdk/core-cst": "1.7.3", + "@meshsdk/provider": "1.7.3", + "@meshsdk/react": "1.7.3", + "@meshsdk/transaction": "1.7.3", + "@meshsdk/wallet": "1.7.3" }, "prettier": "@meshsdk/configs/prettier", "publishConfig": { diff --git a/packages/mesh-provider/package.json b/packages/mesh-provider/package.json index 9452f5f9..6185a574 100644 --- a/packages/mesh-provider/package.json +++ b/packages/mesh-provider/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/provider", - "version": "1.7.2", + "version": "1.7.3", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -33,8 +33,8 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "1.7.2", - "@meshsdk/core-cst": "1.7.2", + "@meshsdk/common": "1.7.3", + "@meshsdk/core-cst": "1.7.3", "axios": "^1.7.2" }, "prettier": "@meshsdk/configs/prettier", diff --git a/packages/mesh-react/package.json b/packages/mesh-react/package.json index 67daff57..22637bbf 100644 --- a/packages/mesh-react/package.json +++ b/packages/mesh-react/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/react", - "version": "1.7.2", + "version": "1.7.3", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -29,9 +29,9 @@ }, "dependencies": { "react": "^18.2.0", - "@meshsdk/common": "1.7.2", - "@meshsdk/transaction": "1.7.2", - "@meshsdk/wallet": "1.7.2" + "@meshsdk/common": "1.7.3", + "@meshsdk/transaction": "1.7.3", + "@meshsdk/wallet": "1.7.3" }, "devDependencies": { "@meshsdk/configs": "*", diff --git a/packages/mesh-transaction/package.json b/packages/mesh-transaction/package.json index b0c42275..407e31e5 100644 --- a/packages/mesh-transaction/package.json +++ b/packages/mesh-transaction/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/transaction", - "version": "1.7.2", + "version": "1.7.3", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -34,9 +34,9 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "1.7.2", - "@meshsdk/core-csl": "1.7.2", - "@meshsdk/core-cst": "1.7.2", + "@meshsdk/common": "1.7.3", + "@meshsdk/core-csl": "1.7.3", + "@meshsdk/core-cst": "1.7.3", "json-bigint": "^1.0.0" }, "prettier": "@meshsdk/configs/prettier", diff --git a/packages/mesh-wallet/package.json b/packages/mesh-wallet/package.json index 45b05494..374e15d9 100644 --- a/packages/mesh-wallet/package.json +++ b/packages/mesh-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@meshsdk/wallet", - "version": "1.7.2", + "version": "1.7.3", "description": "", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -34,10 +34,10 @@ "typescript": "^5.3.3" }, "dependencies": { - "@meshsdk/common": "1.7.2", - "@meshsdk/core-csl": "1.7.2", - "@meshsdk/core-cst": "1.7.2", - "@meshsdk/transaction": "1.7.2", + "@meshsdk/common": "1.7.3", + "@meshsdk/core-csl": "1.7.3", + "@meshsdk/core-cst": "1.7.3", + "@meshsdk/transaction": "1.7.3", "@nufi/dapp-client-cardano": "^0.3.1", "@nufi/dapp-client-core": "^0.3.1" }, diff --git a/scripts/mesh-cli/package.json b/scripts/mesh-cli/package.json index 4599d416..72463fb9 100644 --- a/scripts/mesh-cli/package.json +++ b/scripts/mesh-cli/package.json @@ -3,7 +3,7 @@ "description": "A quick and easy way to bootstrap your dApps on Cardano using Mesh.", "homepage": "https://meshjs.dev", "author": "MeshJS", - "version": "1.7.2", + "version": "1.7.3", "license": "Apache-2.0", "type": "module", "main": "./dist/index.cjs",
+
+ {authors && ( + + )} + + + {/* */} +
+